summaryrefslogtreecommitdiff
path: root/storage/ndb/src
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2014-08-21 18:11:46 +0200
committerSergei Golubchik <serg@mariadb.org>2014-10-11 18:53:06 +0200
commit7f5e51b940d65cf541403a50af74163b9aed5cb8 (patch)
treee540d3cd4d678cd276a9d496490ac5e527f30a78 /storage/ndb/src
parent57dd1f6f3fcbc7a46e1b3e71257987315f7aa687 (diff)
downloadmariadb-git-7f5e51b940d65cf541403a50af74163b9aed5cb8.tar.gz
MDEV-34 delete storage/ndb and sql/*ndb* (and collateral changes)
remove: * NDB from everywhere * IM from mtr-v1 * packaging/rpm-oel and packaging/rpm-uln * few unused spec files * plug.in file * .bzrignore
Diffstat (limited to 'storage/ndb/src')
-rw-r--r--storage/ndb/src/Makefile.am51
-rw-r--r--storage/ndb/src/common/Makefile.am31
-rw-r--r--storage/ndb/src/common/debugger/BlockNames.cpp42
-rw-r--r--storage/ndb/src/common/debugger/DebuggerNames.cpp154
-rw-r--r--storage/ndb/src/common/debugger/EventLogger.cpp1155
-rw-r--r--storage/ndb/src/common/debugger/GrepError.cpp133
-rw-r--r--storage/ndb/src/common/debugger/Makefile.am38
-rw-r--r--storage/ndb/src/common/debugger/SignalLoggerManager.cpp507
-rw-r--r--storage/ndb/src/common/debugger/signaldata/AccLock.cpp75
-rw-r--r--storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp35
-rw-r--r--storage/ndb/src/common/debugger/signaldata/AlterTab.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/AlterTable.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp51
-rw-r--r--storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp134
-rw-r--r--storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp133
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp52
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CntrStart.cpp53
-rw-r--r--storage/ndb/src/common/debugger/signaldata/ContinueB.cpp35
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp58
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp55
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp120
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp310
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp220
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp48
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp30
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DropIndx.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DropTab.cpp50
-rw-r--r--storage/ndb/src/common/debugger/signaldata/DropTrig.cpp89
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FailRep.cpp31
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp56
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp38
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp41
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsConf.cpp33
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp59
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp95
-rw-r--r--storage/ndb/src/common/debugger/signaldata/FsRef.cpp46
-rw-r--r--storage/ndb/src/common/debugger/signaldata/GCPSave.cpp78
-rwxr-xr-xstorage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp31
-rwxr-xr-xstorage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp31
-rw-r--r--storage/ndb/src/common/debugger/signaldata/LCP.cpp89
-rw-r--r--storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp63
-rw-r--r--storage/ndb/src/common/debugger/signaldata/LqhKey.cpp183
-rw-r--r--storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp40
-rw-r--r--storage/ndb/src/common/debugger/signaldata/Makefile.am59
-rw-r--r--storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp87
-rw-r--r--storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp44
-rw-r--r--storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp50
-rw-r--r--storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp41
-rw-r--r--storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp106
-rw-r--r--storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp50
-rw-r--r--storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp52
-rw-r--r--storage/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp40
-rw-r--r--storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp42
-rw-r--r--storage/ndb/src/common/debugger/signaldata/ScanTab.cpp158
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp212
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp34
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SignalNames.cpp649
-rw-r--r--storage/ndb/src/common/debugger/signaldata/StartRec.cpp77
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp218
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SystemError.cpp40
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TcIndx.cpp74
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp69
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp28
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp115
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp28
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp53
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TupCommit.cpp28
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TupKey.cpp50
-rw-r--r--storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp45
-rw-r--r--storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp65
-rw-r--r--storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp59
-rw-r--r--storage/ndb/src/common/debugger/signaldata/UtilLock.cpp158
-rw-r--r--storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp64
-rw-r--r--storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp67
-rw-r--r--storage/ndb/src/common/debugger/signaldata/print.awk71
-rw-r--r--storage/ndb/src/common/logger/ConsoleLogHandler.cpp68
-rw-r--r--storage/ndb/src/common/logger/FileLogHandler.cpp251
-rw-r--r--storage/ndb/src/common/logger/LogHandler.cpp208
-rw-r--r--storage/ndb/src/common/logger/LogHandlerList.cpp181
-rw-r--r--storage/ndb/src/common/logger/LogHandlerList.hpp94
-rw-r--r--storage/ndb/src/common/logger/Logger.cpp398
-rw-r--r--storage/ndb/src/common/logger/Makefile.am38
-rw-r--r--storage/ndb/src/common/logger/SysLogHandler.cpp159
-rw-r--r--storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp164
-rw-r--r--storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp40
-rw-r--r--storage/ndb/src/common/logger/listtest/Makefile14
-rw-r--r--storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp189
-rw-r--r--storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp49
-rw-r--r--storage/ndb/src/common/logger/loggertest/Makefile16
-rw-r--r--storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp391
-rw-r--r--storage/ndb/src/common/mgmcommon/IPCConfig.cpp370
-rw-r--r--storage/ndb/src/common/mgmcommon/Makefile.am41
-rw-r--r--storage/ndb/src/common/mgmcommon/printConfig/Makefile16
-rw-r--r--storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp89
-rw-r--r--storage/ndb/src/common/portlib/Makefile.am56
-rw-r--r--storage/ndb/src/common/portlib/NdbCondition.c142
-rw-r--r--storage/ndb/src/common/portlib/NdbConfig.c145
-rw-r--r--storage/ndb/src/common/portlib/NdbDaemon.c171
-rw-r--r--storage/ndb/src/common/portlib/NdbEnv.c34
-rw-r--r--storage/ndb/src/common/portlib/NdbHost.c34
-rw-r--r--storage/ndb/src/common/portlib/NdbMem.c83
-rw-r--r--storage/ndb/src/common/portlib/NdbMutex.c91
-rw-r--r--storage/ndb/src/common/portlib/NdbPortLibTest.cpp603
-rw-r--r--storage/ndb/src/common/portlib/NdbSleep.c43
-rw-r--r--storage/ndb/src/common/portlib/NdbTCP.cpp132
-rw-r--r--storage/ndb/src/common/portlib/NdbThread.c193
-rw-r--r--storage/ndb/src/common/portlib/NdbTick.c104
-rw-r--r--storage/ndb/src/common/portlib/memtest.c243
-rw-r--r--storage/ndb/src/common/portlib/mmstest.cpp76
-rw-r--r--storage/ndb/src/common/portlib/munmaptest.cpp246
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbCondition.c178
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbDaemon.c44
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbEnv.c31
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbHost.c52
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbMem.c283
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbMutex.c73
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbSleep.c32
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbTCP.c71
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbThread.c114
-rw-r--r--storage/ndb/src/common/portlib/win32/NdbTick.c64
-rw-r--r--storage/ndb/src/common/transporter/Makefile.am48
-rw-r--r--storage/ndb/src/common/transporter/Packer.cpp517
-rw-r--r--storage/ndb/src/common/transporter/Packer.hpp85
-rw-r--r--storage/ndb/src/common/transporter/SCI_Transporter.cpp910
-rw-r--r--storage/ndb/src/common/transporter/SCI_Transporter.hpp384
-rw-r--r--storage/ndb/src/common/transporter/SHM_Buffer.hpp233
-rw-r--r--storage/ndb/src/common/transporter/SHM_Transporter.cpp377
-rw-r--r--storage/ndb/src/common/transporter/SHM_Transporter.hpp177
-rw-r--r--storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp126
-rw-r--r--storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp178
-rw-r--r--storage/ndb/src/common/transporter/SendBuffer.cpp89
-rw-r--r--storage/ndb/src/common/transporter/SendBuffer.hpp190
-rw-r--r--storage/ndb/src/common/transporter/TCP_Transporter.cpp436
-rw-r--r--storage/ndb/src/common/transporter/TCP_Transporter.hpp234
-rw-r--r--storage/ndb/src/common/transporter/Transporter.cpp237
-rw-r--r--storage/ndb/src/common/transporter/Transporter.hpp193
-rw-r--r--storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp298
-rw-r--r--storage/ndb/src/common/transporter/TransporterRegistry.cpp1448
-rw-r--r--storage/ndb/src/common/transporter/basictest/Makefile15
-rw-r--r--storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp512
-rw-r--r--storage/ndb/src/common/transporter/buddy.cpp325
-rw-r--r--storage/ndb/src/common/transporter/buddy.hpp172
-rw-r--r--storage/ndb/src/common/transporter/failoverSCI/Makefile18
-rw-r--r--storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp863
-rw-r--r--storage/ndb/src/common/transporter/perftest/Makefile15
-rw-r--r--storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp712
-rw-r--r--storage/ndb/src/common/transporter/priotest/Makefile15
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioSCI/Makefile17
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp29
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioSHM/Makefile13
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp26
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioTCP/Makefile13
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp26
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp708
-rw-r--r--storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp34
-rw-r--r--storage/ndb/src/common/util/BaseString.cpp553
-rw-r--r--storage/ndb/src/common/util/Bitmask.cpp118
-rw-r--r--storage/ndb/src/common/util/ConfigValues.cpp803
-rw-r--r--storage/ndb/src/common/util/File.cpp199
-rw-r--r--storage/ndb/src/common/util/InputStream.cpp81
-rw-r--r--storage/ndb/src/common/util/Makefile.am62
-rw-r--r--storage/ndb/src/common/util/NdbOut.cpp173
-rw-r--r--storage/ndb/src/common/util/NdbSqlUtil.cpp1016
-rw-r--r--storage/ndb/src/common/util/OutputStream.cpp95
-rw-r--r--storage/ndb/src/common/util/Parser.cpp356
-rw-r--r--storage/ndb/src/common/util/Properties.cpp1136
-rw-r--r--storage/ndb/src/common/util/SimpleProperties.cpp530
-rw-r--r--storage/ndb/src/common/util/SocketAuthenticator.cpp91
-rw-r--r--storage/ndb/src/common/util/SocketClient.cpp203
-rw-r--r--storage/ndb/src/common/util/SocketServer.cpp357
-rw-r--r--storage/ndb/src/common/util/basestring_vsnprintf.c71
-rw-r--r--storage/ndb/src/common/util/filetest/FileUnitTest.cpp237
-rw-r--r--storage/ndb/src/common/util/filetest/FileUnitTest.hpp41
-rw-r--r--storage/ndb/src/common/util/filetest/Makefile14
-rw-r--r--storage/ndb/src/common/util/getarg.cat3237
-rw-r--r--storage/ndb/src/common/util/md5_hash.cpp239
-rw-r--r--storage/ndb/src/common/util/ndb_init.c54
-rw-r--r--storage/ndb/src/common/util/ndb_rand.c41
-rw-r--r--storage/ndb/src/common/util/new.cpp58
-rw-r--r--storage/ndb/src/common/util/random.c284
-rw-r--r--storage/ndb/src/common/util/socket_io.cpp333
-rw-r--r--storage/ndb/src/common/util/strdup.c28
-rw-r--r--storage/ndb/src/common/util/testConfigValues/Makefile12
-rw-r--r--storage/ndb/src/common/util/testConfigValues/testConfigValues.cpp138
-rw-r--r--storage/ndb/src/common/util/testProperties/Makefile9
-rw-r--r--storage/ndb/src/common/util/testProperties/testProperties.cpp195
-rw-r--r--storage/ndb/src/common/util/testSimpleProperties/Makefile12
-rw-r--r--storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp95
-rw-r--r--storage/ndb/src/common/util/uucode.c234
-rw-r--r--storage/ndb/src/common/util/version.c255
-rw-r--r--storage/ndb/src/cw/Makefile.am19
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp215
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsp216
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsw29
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h40
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.icobin1078 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.rc193
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.sln21
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.suobin8704 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.vcproj240
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/Closed.ICObin1078 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp436
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/Open.ICObin1078 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp24
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h69
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp19
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/TreeView.h19
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/bmp00001.bmpbin622 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/resource.h90
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/small.icobin318 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/C++/toolbar.bmpbin622 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/App.icobin1078 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs1416
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs272
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs258
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs244
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/DATABASE.ICObin1078 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/Database.cs178
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj240
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj.user48
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.ncbbin19456 -> 0 bytes
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.sln21
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs1899
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/Process.cs160
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs451
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs57
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs376
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs223
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs42
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs267
-rw-r--r--storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs424
-rw-r--r--storage/ndb/src/cw/cpcd/APIService.cpp401
-rw-r--r--storage/ndb/src/cw/cpcd/APIService.hpp65
-rw-r--r--storage/ndb/src/cw/cpcd/CPCD.cpp435
-rw-r--r--storage/ndb/src/cw/cpcd/CPCD.hpp390
-rw-r--r--storage/ndb/src/cw/cpcd/Makefile.am32
-rw-r--r--storage/ndb/src/cw/cpcd/Monitor.cpp79
-rw-r--r--storage/ndb/src/cw/cpcd/Process.cpp486
-rw-r--r--storage/ndb/src/cw/cpcd/common.cpp98
-rw-r--r--storage/ndb/src/cw/cpcd/common.hpp36
-rw-r--r--storage/ndb/src/cw/cpcd/main.cpp183
-rw-r--r--storage/ndb/src/cw/test/socketclient/Makefile24
-rw-r--r--storage/ndb/src/cw/test/socketclient/socketClientTest.cpp64
-rw-r--r--storage/ndb/src/cw/util/ClientInterface.cpp185
-rw-r--r--storage/ndb/src/cw/util/ClientInterface.hpp49
-rw-r--r--storage/ndb/src/cw/util/Makefile10
-rw-r--r--storage/ndb/src/cw/util/SocketRegistry.cpp213
-rw-r--r--storage/ndb/src/cw/util/SocketRegistry.hpp290
-rw-r--r--storage/ndb/src/cw/util/SocketService.cpp60
-rw-r--r--storage/ndb/src/cw/util/SocketService.hpp46
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/SISCI_LIBRARY_WIN32.TXT77
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/scilib.libbin17918 -> 0 bytes
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/scilib_md.libbin18000 -> 0 bytes
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/scilib_mt.libbin17924 -> 0 bytes
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api.libbin264284 -> 0 bytes
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_md.libbin265578 -> 0 bytes
-rw-r--r--storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_mt.libbin264386 -> 0 bytes
-rw-r--r--storage/ndb/src/kernel/Makefile.am73
-rw-r--r--storage/ndb/src/kernel/SimBlockList.cpp136
-rw-r--r--storage/ndb/src/kernel/blocks/ERROR_codes.txt565
-rw-r--r--storage/ndb/src/kernel/blocks/Makefile.am68
-rw-r--r--storage/ndb/src/kernel/blocks/NodeRestart.new.txt82
-rw-r--r--storage/ndb/src/kernel/blocks/NodeRestart.txt80
-rw-r--r--storage/ndb/src/kernel/blocks/OptNR.txt49
-rw-r--r--storage/ndb/src/kernel/blocks/Start.txt97
-rw-r--r--storage/ndb/src/kernel/blocks/SystemRestart.new.txt61
-rw-r--r--storage/ndb/src/kernel/blocks/SystemRestart.txt61
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.cpp5144
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.hpp752
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.txt427
-rw-r--r--storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp197
-rw-r--r--storage/ndb/src/kernel/blocks/backup/BackupInit.cpp259
-rw-r--r--storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp360
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Makefile.am26
-rw-r--r--storage/ndb/src/kernel/blocks/backup/read.cpp523
-rw-r--r--storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp1453
-rw-r--r--storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp118
-rw-r--r--storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp1106
-rw-r--r--storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp220
-rw-r--r--storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp8549
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/CreateIndex.txt152
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/CreateTable.new.txt29
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/CreateTable.txt35
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp16702
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp2707
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.txt88
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/DictLock.txt98
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/DropTable.txt140
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Event.txt102
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Makefile.am33
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Master_AddTable.sfl765
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp90
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Slave_AddTable.sfl436
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp285
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp1673
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp333
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp15878
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/LCP.txt35
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Makefile.am27
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp275
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp160
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/printSysfile/Makefile12
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp158
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp3029
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp415
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp19357
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Makefile.am29
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/redoLogReader/reader.cpp416
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp336
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp250
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp1978
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp378
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp13612
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp136
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp3070
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp423
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp275
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp749
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp450
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp1893
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp3205
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp285
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp749
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp737
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp1486
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp390
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp602
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp1687
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp1209
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp238
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp317
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp1291
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp420
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Makefile.am26
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Notes.txt198
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp116
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp57
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp297
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp480
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp266
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp1208
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp175
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp417
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp338
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp182
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp512
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp590
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp1123
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp432
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxStat.cpp159
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp717
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/Times.txt151
-rw-r--r--storage/ndb/src/kernel/blocks/dbtux/tuxstatus.html120
-rw-r--r--storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp2608
-rw-r--r--storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp485
-rw-r--r--storage/ndb/src/kernel/blocks/dbutil/DbUtil.txt68
-rw-r--r--storage/ndb/src/kernel/blocks/diskpage.cpp90
-rw-r--r--storage/ndb/src/kernel/blocks/diskpage.hpp242
-rw-r--r--storage/ndb/src/kernel/blocks/lgman.cpp3209
-rw-r--r--storage/ndb/src/kernel/blocks/lgman.hpp367
-rw-r--r--storage/ndb/src/kernel/blocks/mutexes.hpp39
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp388
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp121
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp3094
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp102
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp1387
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp252
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp695
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/Makefile27
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp20
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp116
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp192
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp98
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp18
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp179
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/Makefile13
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp193
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp1109
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp131
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp120
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp261
-rw-r--r--storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp215
-rw-r--r--storage/ndb/src/kernel/blocks/new-block.tar.gzbin1816 -> 0 bytes
-rw-r--r--storage/ndb/src/kernel/blocks/pgman.cpp2514
-rw-r--r--storage/ndb/src/kernel/blocks/pgman.hpp682
-rw-r--r--storage/ndb/src/kernel/blocks/print_file.cpp417
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp471
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp145
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp5268
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/timer.hpp72
-rw-r--r--storage/ndb/src/kernel/blocks/record_types.hpp59
-rw-r--r--storage/ndb/src/kernel/blocks/restore.cpp1286
-rw-r--r--storage/ndb/src/kernel/blocks/restore.hpp159
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp5202
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.hpp635
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.txt192
-rw-r--r--storage/ndb/src/kernel/blocks/suma/SumaInit.cpp136
-rw-r--r--storage/ndb/src/kernel/blocks/trix/Trix.cpp997
-rw-r--r--storage/ndb/src/kernel/blocks/trix/Trix.hpp189
-rw-r--r--storage/ndb/src/kernel/blocks/tsman.cpp2224
-rw-r--r--storage/ndb/src/kernel/blocks/tsman.hpp453
-rw-r--r--storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp57
-rw-r--r--storage/ndb/src/kernel/error/ErrorReporter.cpp406
-rw-r--r--storage/ndb/src/kernel/error/ErrorReporter.hpp57
-rw-r--r--storage/ndb/src/kernel/error/Makefile.am38
-rw-r--r--storage/ndb/src/kernel/error/TimeModule.cpp109
-rw-r--r--storage/ndb/src/kernel/error/TimeModule.hpp46
-rw-r--r--storage/ndb/src/kernel/error/ndbd_exit_codes.c275
-rw-r--r--storage/ndb/src/kernel/main.cpp653
-rw-r--r--storage/ndb/src/kernel/vm/Array.hpp165
-rw-r--r--storage/ndb/src/kernel/vm/ArrayPool.hpp985
-rw-r--r--storage/ndb/src/kernel/vm/CArray.hpp149
-rw-r--r--storage/ndb/src/kernel/vm/Callback.hpp24
-rw-r--r--storage/ndb/src/kernel/vm/ClusterConfiguration.cpp484
-rw-r--r--storage/ndb/src/kernel/vm/ClusterConfiguration.hpp105
-rw-r--r--storage/ndb/src/kernel/vm/Configuration.cpp902
-rw-r--r--storage/ndb/src/kernel/vm/Configuration.hpp152
-rw-r--r--storage/ndb/src/kernel/vm/DLCFifoList.hpp119
-rw-r--r--storage/ndb/src/kernel/vm/DLCHashTable.hpp82
-rw-r--r--storage/ndb/src/kernel/vm/DLFifoList.hpp475
-rw-r--r--storage/ndb/src/kernel/vm/DLHashTable.hpp519
-rw-r--r--storage/ndb/src/kernel/vm/DLHashTable2.hpp515
-rw-r--r--storage/ndb/src/kernel/vm/DLList.hpp438
-rw-r--r--storage/ndb/src/kernel/vm/DataBuffer.hpp533
-rw-r--r--storage/ndb/src/kernel/vm/DynArr256.cpp1021
-rw-r--r--storage/ndb/src/kernel/vm/DynArr256.hpp85
-rw-r--r--storage/ndb/src/kernel/vm/Emulator.cpp292
-rw-r--r--storage/ndb/src/kernel/vm/Emulator.hpp109
-rw-r--r--storage/ndb/src/kernel/vm/FastScheduler.cpp500
-rw-r--r--storage/ndb/src/kernel/vm/FastScheduler.hpp345
-rw-r--r--storage/ndb/src/kernel/vm/GlobalData.hpp123
-rw-r--r--storage/ndb/src/kernel/vm/KeyDescriptor.hpp43
-rw-r--r--storage/ndb/src/kernel/vm/KeyTable.hpp52
-rw-r--r--storage/ndb/src/kernel/vm/KeyTable2.hpp115
-rw-r--r--storage/ndb/src/kernel/vm/KeyTable2Ref.hpp65
-rw-r--r--storage/ndb/src/kernel/vm/LinearPool.hpp656
-rw-r--r--storage/ndb/src/kernel/vm/LongSignal.hpp80
-rw-r--r--storage/ndb/src/kernel/vm/Makefile.am86
-rw-r--r--storage/ndb/src/kernel/vm/Mutex.cpp287
-rw-r--r--storage/ndb/src/kernel/vm/Mutex.hpp267
-rw-r--r--storage/ndb/src/kernel/vm/NdbdSuperPool.cpp228
-rw-r--r--storage/ndb/src/kernel/vm/NdbdSuperPool.hpp55
-rw-r--r--storage/ndb/src/kernel/vm/Pool.cpp44
-rw-r--r--storage/ndb/src/kernel/vm/Pool.hpp341
-rw-r--r--storage/ndb/src/kernel/vm/Prio.hpp32
-rw-r--r--storage/ndb/src/kernel/vm/RWPool.cpp230
-rw-r--r--storage/ndb/src/kernel/vm/RWPool.hpp78
-rw-r--r--storage/ndb/src/kernel/vm/RequestTracker.hpp58
-rw-r--r--storage/ndb/src/kernel/vm/Rope.cpp189
-rw-r--r--storage/ndb/src/kernel/vm/Rope.hpp117
-rw-r--r--storage/ndb/src/kernel/vm/SLFifoList.hpp343
-rw-r--r--storage/ndb/src/kernel/vm/SLList.hpp402
-rw-r--r--storage/ndb/src/kernel/vm/SafeCounter.cpp159
-rw-r--r--storage/ndb/src/kernel/vm/SafeCounter.hpp307
-rw-r--r--storage/ndb/src/kernel/vm/SectionReader.cpp143
-rw-r--r--storage/ndb/src/kernel/vm/SectionReader.hpp49
-rw-r--r--storage/ndb/src/kernel/vm/SignalCounter.hpp166
-rw-r--r--storage/ndb/src/kernel/vm/SimBlockList.hpp48
-rw-r--r--storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp223
-rw-r--r--storage/ndb/src/kernel/vm/SimulatedBlock.cpp2082
-rw-r--r--storage/ndb/src/kernel/vm/SimulatedBlock.hpp824
-rw-r--r--storage/ndb/src/kernel/vm/SuperPool.cpp750
-rw-r--r--storage/ndb/src/kernel/vm/SuperPool.hpp592
-rw-r--r--storage/ndb/src/kernel/vm/ThreadConfig.cpp183
-rw-r--r--storage/ndb/src/kernel/vm/ThreadConfig.hpp39
-rw-r--r--storage/ndb/src/kernel/vm/TimeQueue.cpp208
-rw-r--r--storage/ndb/src/kernel/vm/TimeQueue.hpp62
-rw-r--r--storage/ndb/src/kernel/vm/TransporterCallback.cpp512
-rw-r--r--storage/ndb/src/kernel/vm/VMSignal.cpp34
-rw-r--r--storage/ndb/src/kernel/vm/VMSignal.hpp208
-rw-r--r--storage/ndb/src/kernel/vm/WOPool.cpp137
-rw-r--r--storage/ndb/src/kernel/vm/WOPool.hpp123
-rw-r--r--storage/ndb/src/kernel/vm/WaitQueue.hpp35
-rw-r--r--storage/ndb/src/kernel/vm/WatchDog.cpp200
-rw-r--r--storage/ndb/src/kernel/vm/WatchDog.hpp56
-rw-r--r--storage/ndb/src/kernel/vm/al_test/Makefile12
-rw-r--r--storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp317
-rw-r--r--storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp298
-rw-r--r--storage/ndb/src/kernel/vm/al_test/main.cpp69
-rw-r--r--storage/ndb/src/kernel/vm/bench_pool.cpp608
-rw-r--r--storage/ndb/src/kernel/vm/mem.txt34
-rw-r--r--storage/ndb/src/kernel/vm/ndbd_malloc.cpp65
-rw-r--r--storage/ndb/src/kernel/vm/ndbd_malloc.hpp26
-rw-r--r--storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp1016
-rw-r--r--storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp200
-rw-r--r--storage/ndb/src/kernel/vm/pc.hpp237
-rw-r--r--storage/ndb/src/kernel/vm/testCopy/Makefile9
-rw-r--r--storage/ndb/src/kernel/vm/testCopy/rr.cpp32
-rw-r--r--storage/ndb/src/kernel/vm/testCopy/testCopy.cpp341
-rw-r--r--storage/ndb/src/kernel/vm/testDataBuffer/Makefile10
-rw-r--r--storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp188
-rw-r--r--storage/ndb/src/kernel/vm/testLongSig/Makefile9
-rw-r--r--storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp333
-rw-r--r--storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile10
-rw-r--r--storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp171
-rw-r--r--storage/ndb/src/kernel/vm/testSuperPool.cpp364
-rw-r--r--storage/ndb/src/libndb.ver.in18
-rw-r--r--storage/ndb/src/mgmapi/LocalConfig.cpp319
-rw-r--r--storage/ndb/src/mgmapi/LocalConfig.hpp68
-rw-r--r--storage/ndb/src/mgmapi/Makefile.am45
-rw-r--r--storage/ndb/src/mgmapi/mgmapi.cpp2866
-rw-r--r--storage/ndb/src/mgmapi/mgmapi_configuration.cpp209
-rw-r--r--storage/ndb/src/mgmapi/mgmapi_configuration.hpp48
-rw-r--r--storage/ndb/src/mgmapi/mgmapi_internal.h79
-rw-r--r--storage/ndb/src/mgmapi/ndb_logevent.cpp519
-rw-r--r--storage/ndb/src/mgmapi/ndb_logevent.hpp34
-rw-r--r--storage/ndb/src/mgmapi/test/Makefile13
-rw-r--r--storage/ndb/src/mgmapi/test/keso.c470
-rw-r--r--storage/ndb/src/mgmapi/test/mgmSrvApi.cpp126
-rw-r--r--storage/ndb/src/mgmclient/CommandInterpreter.cpp2744
-rw-r--r--storage/ndb/src/mgmclient/Makefile.am72
-rw-r--r--storage/ndb/src/mgmclient/main.cpp199
-rw-r--r--storage/ndb/src/mgmclient/ndb_mgmclient.h33
-rw-r--r--storage/ndb/src/mgmclient/ndb_mgmclient.hpp33
-rw-r--r--storage/ndb/src/mgmclient/test_cpcd/Makefile17
-rw-r--r--storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp157
-rw-r--r--storage/ndb/src/mgmsrv/Config.cpp181
-rw-r--r--storage/ndb/src/mgmsrv/Config.hpp82
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.cpp3827
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.hpp152
-rw-r--r--storage/ndb/src/mgmsrv/ERROR_codes.txt29
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.cpp953
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.hpp145
-rw-r--r--storage/ndb/src/mgmsrv/Makefile.am73
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp3017
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.hpp648
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp76
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp22
-rw-r--r--storage/ndb/src/mgmsrv/Services.cpp1818
-rw-r--r--storage/ndb/src/mgmsrv/Services.hpp136
-rw-r--r--storage/ndb/src/mgmsrv/SignalQueue.cpp104
-rw-r--r--storage/ndb/src/mgmsrv/SignalQueue.hpp100
-rw-r--r--storage/ndb/src/mgmsrv/convertStrToInt.cpp43
-rw-r--r--storage/ndb/src/mgmsrv/convertStrToInt.hpp25
-rw-r--r--storage/ndb/src/mgmsrv/main.cpp382
-rw-r--r--storage/ndb/src/mgmsrv/mkconfig/Makefile13
-rw-r--r--storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp61
-rw-r--r--storage/ndb/src/mgmsrv/ndb_mgmd_error.h34
-rw-r--r--storage/ndb/src/ndbapi/API.hpp26
-rw-r--r--storage/ndb/src/ndbapi/ClusterMgr.cpp909
-rw-r--r--storage/ndb/src/ndbapi/ClusterMgr.hpp259
-rw-r--r--storage/ndb/src/ndbapi/DictCache.cpp470
-rw-r--r--storage/ndb/src/ndbapi/DictCache.hpp104
-rw-r--r--storage/ndb/src/ndbapi/Makefile.am87
-rw-r--r--storage/ndb/src/ndbapi/Ndb.cpp1920
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.cpp298
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.hpp225
-rw-r--r--storage/ndb/src/ndbapi/NdbBlob.cpp2029
-rw-r--r--storage/ndb/src/ndbapi/NdbBlobImpl.hpp43
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionary.cpp2047
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp5319
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp1221
-rw-r--r--storage/ndb/src/ndbapi/NdbErrorOut.cpp45
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperation.cpp219
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp3007
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp655
-rw-r--r--storage/ndb/src/ndbapi/NdbImpl.hpp304
-rw-r--r--storage/ndb/src/ndbapi/NdbIndexOperation.cpp191
-rw-r--r--storage/ndb/src/ndbapi/NdbIndexStat.cpp493
-rw-r--r--storage/ndb/src/ndbapi/NdbLinHash.hpp455
-rw-r--r--storage/ndb/src/ndbapi/NdbOperation.cpp438
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationDefine.cpp795
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationExec.cpp576
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationInt.cpp1187
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationScan.cpp16
-rw-r--r--storage/ndb/src/ndbapi/NdbOperationSearch.cpp646
-rw-r--r--storage/ndb/src/ndbapi/NdbPool.cpp71
-rw-r--r--storage/ndb/src/ndbapi/NdbPoolImpl.cpp528
-rw-r--r--storage/ndb/src/ndbapi/NdbPoolImpl.hpp166
-rw-r--r--storage/ndb/src/ndbapi/NdbRecAttr.cpp533
-rw-r--r--storage/ndb/src/ndbapi/NdbReceiver.cpp314
-rw-r--r--storage/ndb/src/ndbapi/NdbScanFilter.cpp838
-rw-r--r--storage/ndb/src/ndbapi/NdbScanOperation.cpp1858
-rw-r--r--storage/ndb/src/ndbapi/NdbTransaction.cpp2221
-rw-r--r--storage/ndb/src/ndbapi/NdbTransactionScan.cpp122
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.cpp65
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.hpp104
-rw-r--r--storage/ndb/src/ndbapi/NdbWaiter.hpp105
-rw-r--r--storage/ndb/src/ndbapi/Ndberr.cpp89
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp1481
-rw-r--r--storage/ndb/src/ndbapi/Ndbinit.cpp219
-rw-r--r--storage/ndb/src/ndbapi/Ndblist.cpp592
-rw-r--r--storage/ndb/src/ndbapi/ObjectMap.cpp63
-rw-r--r--storage/ndb/src/ndbapi/ObjectMap.hpp114
-rw-r--r--storage/ndb/src/ndbapi/ScanOperation.txt56
-rw-r--r--storage/ndb/src/ndbapi/SignalSender.cpp283
-rw-r--r--storage/ndb/src/ndbapi/SignalSender.hpp83
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp1538
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.hpp418
-rw-r--r--storage/ndb/src/ndbapi/ndb_cluster_connection.cpp694
-rw-r--r--storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp86
-rw-r--r--storage/ndb/src/ndbapi/ndb_internal.hpp27
-rw-r--r--storage/ndb/src/ndbapi/ndberror.c837
-rw-r--r--storage/ndb/src/ndbapi/ndberror_check.c39
-rw-r--r--storage/ndb/src/ndbapi/signal-sender/Makefile19
-rw-r--r--storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp237
-rw-r--r--storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp82
599 files changed, 0 insertions, 290683 deletions
diff --git a/storage/ndb/src/Makefile.am b/storage/ndb/src/Makefile.am
deleted file mode 100644
index 33bad49575d..00000000000
--- a/storage/ndb/src/Makefile.am
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = common mgmapi ndbapi . kernel mgmclient mgmsrv cw
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-
-ndblib_LTLIBRARIES = libndbclient.la
-
-libndbclient_la_SOURCES =
-
-libndbclient_la_LDFLAGS = -version-info @NDB_SHARED_LIB_VERSION@ @NDB_LD_VERSION_SCRIPT@
-
-libndbclient_la_LIBADD = \
- ndbapi/libndbapi.la \
- common/transporter/libtransporter.la \
- common/debugger/libtrace.la \
- common/debugger/signaldata/libsignaldataprint.la \
- mgmapi/libmgmapi.la \
- common/mgmcommon/libmgmsrvcommon.la \
- common/logger/liblogger.la \
- common/portlib/libportlib.la \
- common/util/libgeneral.la
-
-windoze-dsp: libndbclient.dsp
-
-libndbclient.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndblib_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ dummy.cpp
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(libndbclient_la_LIBADD)
- @touch dummy.cpp
diff --git a/storage/ndb/src/common/Makefile.am b/storage/ndb/src/common/Makefile.am
deleted file mode 100644
index d9d55b26eed..00000000000
--- a/storage/ndb/src/common/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = portlib debugger util logger transporter mgmcommon
-
-noinst_LTLIBRARIES = libcommon.la
-
-libcommon_la_SOURCES =
-libcommon_la_LIBADD = \
- transporter/libtransporter.la \
- debugger/libtrace.la \
- debugger/signaldata/libsignaldataprint.la \
- mgmcommon/libmgmsrvcommon.la \
- portlib/libportlib.la \
- logger/liblogger.la \
- util/libgeneral.la
-
-windoze-dsp:
diff --git a/storage/ndb/src/common/debugger/BlockNames.cpp b/storage/ndb/src/common/debugger/BlockNames.cpp
deleted file mode 100644
index b9e1b5bb617..00000000000
--- a/storage/ndb/src/common/debugger/BlockNames.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <BlockNumbers.h>
-
-const BlockName BlockNames[] = {
- { "CMVMI", CMVMI },
- { "DBACC", DBACC },
- { "DBDICT", DBDICT },
- { "DBDIH", DBDIH },
- { "DBLQH", DBLQH },
- { "DBTC", DBTC },
- { "DBTUP", DBTUP },
- { "NDBFS", NDBFS },
- { "NDBCNTR", NDBCNTR },
- { "QMGR", QMGR },
- { "TRIX", TRIX },
- { "BACKUP", BACKUP },
- { "DBUTIL", DBUTIL },
- { "SUMA", SUMA },
- { "DBTUX", DBTUX }
- ,{ "TSMAN", TSMAN}
- ,{ "LGMAN", LGMAN }
- ,{ "PGMAN", PGMAN }
- ,{ "RESTORE", RESTORE }
-};
-
-const BlockNumber NO_OF_BLOCK_NAMES = sizeof(BlockNames) / sizeof(BlockName);
diff --git a/storage/ndb/src/common/debugger/DebuggerNames.cpp b/storage/ndb/src/common/debugger/DebuggerNames.cpp
deleted file mode 100644
index 3c0b113d2f4..00000000000
--- a/storage/ndb/src/common/debugger/DebuggerNames.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <BaseString.hpp>
-
-#include "DebuggerNames.hpp"
-
-#include <BlockNumbers.h>
-#include <GlobalSignalNumbers.h>
-#include <signaldata/SignalDataPrint.hpp>
-
-static const char * localSignalNames[MAX_GSN+1];
-static SignalDataPrintFunction localPrintFunctions[MAX_GSN+1];
-static const char * localBlockNames[NO_OF_BLOCKS];
-
-static
-int
-initSignalNames(const char * dst[], const GsnName src[], unsigned short len){
- unsigned i;
- for(i = 0; i<=MAX_GSN; i++)
- dst[i] = 0;
-
- for(i = 0; i<len; i++){
- unsigned short gsn = src[i].gsn;
- const char * name = src[i].name;
-
- if(dst[gsn] != 0 && name != 0){
- if(strcmp(dst[gsn], name) != 0){
- fprintf(stderr,
- "Multiple definition of signal name for gsn: %d (%s, %s)\n",
- gsn, dst[gsn], name);
- exit(0);
- }
- }
- dst[gsn] = name;
- }
- return 0;
-}
-
-static
-int
-initSignalPrinters(SignalDataPrintFunction dst[],
- const NameFunctionPair src[]){
- unsigned i;
- for(i = 0; i<=MAX_GSN; i++)
- dst[i] = 0;
-
- unsigned short gsn;
- for(i = 0; (gsn = src[i].gsn) > 0; i++){
- SignalDataPrintFunction fun = src[i].function;
-
- if(dst[gsn] != 0 && fun != 0){
- if(dst[gsn] != fun){
- fprintf(stderr,
- "Multiple definition of signal print function for gsn: %d\n",
- gsn);
- exit(0);
- }
- }
- dst[gsn] = fun;
- }
- return 0;
-}
-
-static
-int
-initBlockNames(const char * dst[],
- const BlockName src[],
- unsigned len){
- unsigned i;
- for(i = 0; i<NO_OF_BLOCKS; i++)
- dst[i] = 0;
-
- for(i = 0; i<len; i++){
- const int index = src[i].number - MIN_BLOCK_NO;
- if(index < 0 && index >= NO_OF_BLOCKS || dst[index] != 0){
- fprintf(stderr,
- "Invalid block name definition: %d %s\n",
- src[i].number, src[i].name);
- exit(0);
- }
- dst[index] = src[i].name;
- }
- return 0;
-}
-
-/**
- * Run static initializer
- */
-static const int
-xxx_DUMMY_SIGNAL_NAMES_xxx = initSignalNames(localSignalNames,
- SignalNames,
- NO_OF_SIGNAL_NAMES);
-static const int
-xxx_DUMMY_PRINT_FUNCTIONS_xxx = initSignalPrinters(localPrintFunctions,
- SignalDataPrintFunctions);
-
-static const int
-xxx_DUMMY_BLOCK_NAMES_xxx = initBlockNames(localBlockNames,
- BlockNames,
- NO_OF_BLOCK_NAMES);
-
-const char *
-getSignalName(unsigned short gsn, const char * defVal){
- if(gsn > 0 && gsn <= MAX_GSN)
- return (localSignalNames[gsn] ? localSignalNames[gsn] : defVal);
- return defVal;
-}
-
-unsigned short
-getGsn(const char * signalName){
- return 0;
-}
-
-const char *
-getBlockName(unsigned short blockNo, const char * ret){
- if(blockNo >= MIN_BLOCK_NO && blockNo <= MAX_BLOCK_NO)
- return localBlockNames[blockNo-MIN_BLOCK_NO];
- if (ret == 0) {
- static char buf[20];
- BaseString::snprintf(buf, sizeof(buf), "BLOCK#%d", (int)blockNo);
- return buf;
- }
- return ret;
-}
-
-unsigned short
-getBlockNo(const char * blockName){
- for(int i = 0; i<NO_OF_BLOCKS; i++)
- if(localBlockNames[i] != 0 && strcmp(localBlockNames[i], blockName) == 0)
- return i + MIN_BLOCK_NO;
- return 0;
-}
-
-SignalDataPrintFunction
-findPrintFunction(unsigned short gsn){
- if(gsn > 0 && gsn <= MAX_GSN)
- return localPrintFunctions[gsn];
- return 0;
-}
diff --git a/storage/ndb/src/common/debugger/EventLogger.cpp b/storage/ndb/src/common/debugger/EventLogger.cpp
deleted file mode 100644
index cb42250dbd8..00000000000
--- a/storage/ndb/src/common/debugger/EventLogger.cpp
+++ /dev/null
@@ -1,1155 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <EventLogger.hpp>
-#include <TransporterCallback.hpp>
-
-#include <NdbConfig.h>
-#include <kernel/BlockNumbers.h>
-#include <signaldata/ArbitSignalData.hpp>
-#include <NodeState.hpp>
-#include <version.h>
-
-#include <ndbd_exit_codes.h>
-
-//
-// PUBLIC
-//
-EventLoggerBase::~EventLoggerBase()
-{
-
-}
-
-#define QQQQ char *m_text, size_t m_text_len, const Uint32* theData
-
-void getTextConnected(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node %u Connected",
- theData[1]);
-}
-void getTextConnectedApiVersion(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node %u: API version %d.%d.%d",
- theData[1],
- getMajor(theData[2]),
- getMinor(theData[2]),
- getBuild(theData[2]));
-}
-void getTextDisconnected(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node %u Disconnected",
- theData[1]);
-}
-void getTextCommunicationClosed(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT communication to node closed.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Communication to Node %u closed",
- theData[1]);
-}
-void getTextCommunicationOpened(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT communication to node opened.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Communication to Node %u opened",
- theData[1]);
-}
-void getTextNDBStartStarted(QQQQ) {
- //-----------------------------------------------------------------------
- // Start of NDB has been initiated.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Start initiated (version %d.%d.%d)",
- getMajor(theData[1]),
- getMinor(theData[1]),
- getBuild(theData[1]));
-}
-void getTextNDBStopStarted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "%s shutdown initiated",
- (theData[1] == 1 ? "Cluster" : "Node"));
-}
-void getRestartAction(Uint32 action, BaseString &str)
-{
- if (action == 0)
- return;
- str.appfmt(", restarting");
- if (action & 2)
- str.appfmt(", no start");
- if (action & 4)
- str.appfmt(", initial");
-}
-void getTextNDBStopCompleted(QQQQ) {
- BaseString action_str("");
- BaseString signum_str("");
- getRestartAction(theData[1], action_str);
- if (theData[2])
- signum_str.appfmt(" Initiated by signal %d.", theData[2]);
- BaseString::snprintf(m_text, m_text_len,
- "Node shutdown completed%s.%s",
- action_str.c_str(),
- signum_str.c_str());
-}
-void getTextNDBStopForced(QQQQ) {
- BaseString action_str("");
- BaseString reason_str("");
- BaseString sphase_str("");
- int signum = theData[2];
- int error = theData[3];
- int sphase = theData[4];
- int extra = theData[5];
- getRestartAction(theData[1],action_str);
- if (signum)
- reason_str.appfmt(" Initiated by signal %d.", signum);
- if (error)
- {
- ndbd_exit_classification cl;
- ndbd_exit_status st;
- const char *msg = ndbd_exit_message(error, &cl);
- const char *cl_msg = ndbd_exit_classification_message(cl, &st);
- const char *st_msg = ndbd_exit_status_message(st);
- reason_str.appfmt(" Caused by error %d: \'%s(%s). %s\'.",
- error, msg, cl_msg, st_msg);
- if (extra != 0)
- reason_str.appfmt(" (extra info %d)", extra);
- }
- if (sphase < 255)
- sphase_str.appfmt(" Occured during startphase %u.", sphase);
- BaseString::snprintf(m_text, m_text_len,
- "Forced node shutdown completed%s.%s%s",
- action_str.c_str(), sphase_str.c_str(),
- reason_str.c_str());
-}
-void getTextNDBStopAborted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node shutdown aborted");
-}
-void getTextNDBStartCompleted(QQQQ) {
- //-----------------------------------------------------------------------
- // Start of NDB has been completed.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Started (version %d.%d.%d)",
- getMajor(theData[1]),
- getMinor(theData[1]),
- getBuild(theData[1]));
-}
-void getTextSTTORRYRecieved(QQQQ) {
- //-----------------------------------------------------------------------
- // STTORRY recevied after restart finished.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "STTORRY received after restart finished");
-}
-void getTextStartPhaseCompleted(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Start phase completed.
- //-----------------------------------------------------------------------
- const char *type = "<Unknown>";
- switch((NodeState::StartType)theData[2]){
- case NodeState::ST_INITIAL_START:
- type = "(initial start)";
- break;
- case NodeState::ST_SYSTEM_RESTART:
- type = "(system restart)";
- break;
- case NodeState::ST_NODE_RESTART:
- type = "(node restart)";
- break;
- case NodeState::ST_INITIAL_NODE_RESTART:
- type = "(initial node restart)";
- break;
- case NodeState::ST_ILLEGAL_TYPE:
- type = "";
- break;
- default:
- BaseString::snprintf(m_text, m_text_len,
- "Start phase %u completed (unknown = %d)",
- theData[1],
- theData[2]);
- return;
- }
- BaseString::snprintf(m_text, m_text_len,
- "Start phase %u completed %s",
- theData[1],
- type);
-}
-void getTextCM_REGCONF(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "CM_REGCONF president = %u, own Node = %u, our dynamic id = %u",
- theData[2],
- theData[1],
- theData[3]);
-}
-void getTextCM_REGREF(QQQQ) {
- const char* line = "";
- switch (theData[3]) {
- case 0:
- line = "Busy";
- break;
- case 1:
- line = "Election with wait = false";
- break;
- case 2:
- line = "Election with wait = false";
- break;
- case 3:
- line = "Not president";
- break;
- case 4:
- line = "Election without selecting new candidate";
- break;
- default:
- line = "No such cause";
- break;
- }//switch
-
- BaseString::snprintf(m_text, m_text_len,
- "CM_REGREF from Node %u to our Node %u. Cause = %s",
- theData[2],
- theData[1],
- line);
-}
-void getTextFIND_NEIGHBOURS(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node Restart copied a fragment.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "We are Node %u with dynamic ID %u, our left neighbour "
- "is Node %u, our right is Node %u",
- theData[1],
- theData[4],
- theData[2],
- theData[3]);
-}
-void getTextNodeFailCompleted(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node failure phase completed.
- //-----------------------------------------------------------------------
- if (theData[1] == 0)
- {
- if (theData[3] != 0) {
- BaseString::snprintf(m_text, m_text_len,
- "Node %u completed failure of Node %u",
- theData[3],
- theData[2]);
- } else {
- BaseString::snprintf(m_text, m_text_len,
- "All nodes completed failure of Node %u",
- theData[2]);
- }//if
- } else {
- const char* line = "";
- if (theData[1] == DBTC){
- line = "DBTC";
- }else if (theData[1] == DBDICT){
- line = "DBDICT";
- }else if (theData[1] == DBDIH){
- line = "DBDIH";
- }else if (theData[1] == DBLQH){
- line = "DBLQH";
- }
- BaseString::snprintf(m_text, m_text_len,
- "Node failure of %u %s completed",
- theData[2],
- line);
- }
-}
-void getTextNODE_FAILREP(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node %u has failed. The Node state at failure "
- "was %u",
- theData[1],
- theData[2]);
-}
-void getTextArbitState(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT arbitrator found or lost.
- //-----------------------------------------------------------------------
- {
- const ArbitSignalData* sd = (ArbitSignalData*)theData;
- char ticketText[ArbitTicket::TextLength + 1];
- char errText[ArbitCode::ErrTextLength + 1];
- const unsigned code = sd->code & 0xFFFF;
- const unsigned state = sd->code >> 16;
- switch (code) {
- case ArbitCode::ThreadStart:
- BaseString::snprintf(m_text, m_text_len,
- "President restarts arbitration thread [state=%u]",
- state);
- break;
- case ArbitCode::PrepPart2:
- sd->ticket.getText(ticketText, sizeof(ticketText));
- BaseString::snprintf(m_text, m_text_len,
- "Prepare arbitrator node %u [ticket=%s]",
- sd->node, ticketText);
- break;
- case ArbitCode::PrepAtrun:
- sd->ticket.getText(ticketText, sizeof(ticketText));
- BaseString::snprintf(m_text, m_text_len,
- "Receive arbitrator node %u [ticket=%s]",
- sd->node, ticketText);
- break;
- case ArbitCode::ApiStart:
- sd->ticket.getText(ticketText, sizeof(ticketText));
- BaseString::snprintf(m_text, m_text_len,
- "Started arbitrator node %u [ticket=%s]",
- sd->node, ticketText);
- break;
- case ArbitCode::ApiFail:
- BaseString::snprintf(m_text, m_text_len,
- "Lost arbitrator node %u - process failure [state=%u]",
- sd->node, state);
- break;
- case ArbitCode::ApiExit:
- BaseString::snprintf(m_text, m_text_len,
- "Lost arbitrator node %u - process exit [state=%u]",
- sd->node, state);
- break;
- default:
- ArbitCode::getErrText(code, errText, sizeof(errText));
- BaseString::snprintf(m_text, m_text_len,
- "Lost arbitrator node %u - %s [state=%u]",
- sd->node, errText, state);
- break;
- }
- }
-}
-
-void getTextArbitResult(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT arbitration result (the failures may not reach us).
- //-----------------------------------------------------------------------
- {
- const ArbitSignalData* sd = (ArbitSignalData*)theData;
- char errText[ArbitCode::ErrTextLength + 1];
- const unsigned code = sd->code & 0xFFFF;
- const unsigned state = sd->code >> 16;
- switch (code) {
- case ArbitCode::LoseNodes:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration check lost - less than 1/2 nodes left");
- break;
- case ArbitCode::WinNodes:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration check won - all node groups and more than 1/2 nodes left");
- break;
- case ArbitCode::WinGroups:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration check won - node group majority");
- break;
- case ArbitCode::LoseGroups:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration check lost - missing node group");
- break;
- case ArbitCode::Partitioning:
- BaseString::snprintf(m_text, m_text_len,
- "Network partitioning - arbitration required");
- break;
- case ArbitCode::WinChoose:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration won - positive reply from node %u",
- sd->node);
- break;
- case ArbitCode::LoseChoose:
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration lost - negative reply from node %u",
- sd->node);
- break;
- case ArbitCode::LoseNorun:
- BaseString::snprintf(m_text, m_text_len,
- "Network partitioning - no arbitrator available");
- break;
- case ArbitCode::LoseNocfg:
- BaseString::snprintf(m_text, m_text_len,
- "Network partitioning - no arbitrator configured");
- break;
- default:
- ArbitCode::getErrText(code, errText, sizeof(errText));
- BaseString::snprintf(m_text, m_text_len,
- "Arbitration failure - %s [state=%u]",
- errText, state);
- break;
- }
- }
-}
-void getTextGlobalCheckpointStarted(QQQQ) {
- //-----------------------------------------------------------------------
- // This event reports that a global checkpoint has been started and this
- // node is the master of this global checkpoint.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Global checkpoint %u started",
- theData[1]);
-}
-void getTextGlobalCheckpointCompleted(QQQQ) {
- //-----------------------------------------------------------------------
- // This event reports that a global checkpoint has been completed on this
- // node and the node is the master of this global checkpoint.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Global checkpoint %u completed",
- theData[1]);
-}
-void getTextLocalCheckpointStarted(QQQQ) {
- //-----------------------------------------------------------------------
- // This event reports that a local checkpoint has been started and this
- // node is the master of this local checkpoint.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Local checkpoint %u started. "
- "Keep GCI = %u oldest restorable GCI = %u",
- theData[1],
- theData[2],
- theData[3]);
-}
-void getTextLocalCheckpointCompleted(QQQQ) {
- //-----------------------------------------------------------------------
- // This event reports that a local checkpoint has been completed on this
- // node and the node is the master of this local checkpoint.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Local checkpoint %u completed",
- theData[1]);
-}
-void getTextTableCreated(QQQQ) {
- //-----------------------------------------------------------------------
- // This event reports that a table has been created.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Table with ID = %u created",
- theData[1]);
-}
-/* STRANGE */
-void getTextLCPStoppedInCalcKeepGci(QQQQ) {
- if (theData[1] == 0)
- BaseString::snprintf(m_text, m_text_len,
- "Local Checkpoint stopped in CALCULATED_KEEP_GCI");
-}
-void getTextNR_CopyDict(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node Restart completed copy of dictionary information.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Node restart completed copy of dictionary information");
-}
-void getTextNR_CopyDistr(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node Restart completed copy of distribution information.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Node restart completed copy of distribution information");
-}
-void getTextNR_CopyFragsStarted(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node Restart is starting to copy the fragments.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Node restart starting to copy the fragments "
- "to Node %u",
- theData[1]);
-}
-void getTextNR_CopyFragDone(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Node Restart copied a fragment.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Table ID = %u, fragment ID = %u have been copied "
- "to Node %u",
- theData[2],
- theData[3],
- theData[1]);
-}
-void getTextNR_CopyFragsCompleted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node restart completed copying the fragments "
- "to Node %u",
- theData[1]);
-}
-void getTextLCPFragmentCompleted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Table ID = %u, fragment ID = %u has completed LCP "
- "on Node %u maxGciStarted: %d maxGciCompleted: %d",
- theData[2],
- theData[3],
- theData[1],
- theData[4],
- theData[5]);
-}
-void getTextTransReportCounters(QQQQ) {
- // -------------------------------------------------------------------
- // Report information about transaction activity once per 10 seconds.
- // -------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Trans. Count = %u, Commit Count = %u, "
- "Read Count = %u, Simple Read Count = %u, "
- "Write Count = %u, AttrInfo Count = %u, "
- "Concurrent Operations = %u, Abort Count = %u"
- " Scans = %u Range scans = %u",
- theData[1],
- theData[2],
- theData[3],
- theData[4],
- theData[5],
- theData[6],
- theData[7],
- theData[8],
- theData[9],
- theData[10]);
-}
-void getTextOperationReportCounters(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Operations=%u",
- theData[1]);
-}
-void getTextUndoLogBlocked(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Undo Logging blocked due to buffer near to overflow.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "ACC Blocked %u and TUP Blocked %u times last second",
- theData[1],
- theData[2]);
-}
-
-void getTextTransporterError(QQQQ) {
- struct myTransporterError{
- Uint32 errorNum;
- char errorString[256];
- };
- int i = 0;
- int lenth = 0;
- static const struct myTransporterError TransporterErrorString[]=
- {
- //TE_NO_ERROR = 0
- {TE_NO_ERROR,"No error"},
- //TE_ERROR_CLOSING_SOCKET = 0x1
- {TE_ERROR_CLOSING_SOCKET,"Error found during closing of socket"},
- //TE_ERROR_IN_SELECT_BEFORE_ACCEPT = 0x2
- {TE_ERROR_IN_SELECT_BEFORE_ACCEPT,"Error found before accept. The transporter will retry"},
- //TE_INVALID_MESSAGE_LENGTH = 0x3 | TE_DO_DISCONNECT
- {TE_INVALID_MESSAGE_LENGTH,"Error found in message (invalid message length)"},
- //TE_INVALID_CHECKSUM = 0x4 | TE_DO_DISCONNECT
- {TE_INVALID_CHECKSUM,"Error found in message (checksum)"},
- //TE_COULD_NOT_CREATE_SOCKET = 0x5
- {TE_COULD_NOT_CREATE_SOCKET,"Error found while creating socket(can't create socket)"},
- //TE_COULD_NOT_BIND_SOCKET = 0x6
- {TE_COULD_NOT_BIND_SOCKET,"Error found while binding server socket"},
- //TE_LISTEN_FAILED = 0x7
- {TE_LISTEN_FAILED,"Error found while listening to server socket"},
- //TE_ACCEPT_RETURN_ERROR = 0x8
- {TE_ACCEPT_RETURN_ERROR,"Error found during accept(accept return error)"},
- //TE_SHM_DISCONNECT = 0xb | TE_DO_DISCONNECT
- {TE_SHM_DISCONNECT,"The remote node has disconnected"},
- //TE_SHM_IPC_STAT = 0xc | TE_DO_DISCONNECT
- {TE_SHM_IPC_STAT,"Unable to check shm segment"},
- //TE_SHM_UNABLE_TO_CREATE_SEGMENT = 0xd
- {TE_SHM_UNABLE_TO_CREATE_SEGMENT,"Unable to create shm segment"},
- //TE_SHM_UNABLE_TO_ATTACH_SEGMENT = 0xe
- {TE_SHM_UNABLE_TO_ATTACH_SEGMENT,"Unable to attach shm segment"},
- //TE_SHM_UNABLE_TO_REMOVE_SEGMENT = 0xf
- {TE_SHM_UNABLE_TO_REMOVE_SEGMENT,"Unable to remove shm segment"},
- //TE_TOO_SMALL_SIGID = 0x10
- {TE_TOO_SMALL_SIGID,"Sig ID too small"},
- //TE_TOO_LARGE_SIGID = 0x11
- {TE_TOO_LARGE_SIGID,"Sig ID too large"},
- //TE_WAIT_STACK_FULL = 0x12 | TE_DO_DISCONNECT
- {TE_WAIT_STACK_FULL,"Wait stack was full"},
- //TE_RECEIVE_BUFFER_FULL = 0x13 | TE_DO_DISCONNECT
- {TE_RECEIVE_BUFFER_FULL,"Receive buffer was full"},
- //TE_SIGNAL_LOST_SEND_BUFFER_FULL = 0x14 | TE_DO_DISCONNECT
- {TE_SIGNAL_LOST_SEND_BUFFER_FULL,"Send buffer was full,and trying to force send fails"},
- //TE_SIGNAL_LOST = 0x15
- {TE_SIGNAL_LOST,"Send failed for unknown reason(signal lost)"},
- //TE_SEND_BUFFER_FULL = 0x16
- {TE_SEND_BUFFER_FULL,"The send buffer was full, but sleeping for a while solved"},
- //TE_SCI_LINK_ERROR = 0x0017
- {TE_SCI_LINK_ERROR,"There is no link from this node to the switch"},
- //TE_SCI_UNABLE_TO_START_SEQUENCE = 0x18 | TE_DO_DISCONNECT
- {TE_SCI_UNABLE_TO_START_SEQUENCE,"Could not start a sequence, because system resources are exumed or no sequence has been created"},
- //TE_SCI_UNABLE_TO_REMOVE_SEQUENCE = 0x19 | TE_DO_DISCONNECT
- {TE_SCI_UNABLE_TO_REMOVE_SEQUENCE,"Could not remove a sequence"},
- //TE_SCI_UNABLE_TO_CREATE_SEQUENCE = 0x1a | TE_DO_DISCONNECT
- {TE_SCI_UNABLE_TO_CREATE_SEQUENCE,"Could not create a sequence, because system resources are exempted. Must reboot"},
- //TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR = 0x1b | TE_DO_DISCONNECT
- {TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR,"Tried to send data on redundant link but failed"},
- //TE_SCI_CANNOT_INIT_LOCALSEGMENT = 0x1c | TE_DO_DISCONNECT
- {TE_SCI_CANNOT_INIT_LOCALSEGMENT,"Cannot initialize local segment"},
- //TE_SCI_CANNOT_MAP_REMOTESEGMENT = 0x1d | TE_DO_DISCONNEC
- {TE_SCI_CANNOT_MAP_REMOTESEGMENT,"Cannot map remote segment"},
- //TE_SCI_UNABLE_TO_UNMAP_SEGMENT = 0x1e | TE_DO_DISCONNECT
- {TE_SCI_UNABLE_TO_UNMAP_SEGMENT,"Cannot free the resources used by this segment (step 1)"},
- //TE_SCI_UNABLE_TO_REMOVE_SEGMENT = 0x1f | TE_DO_DISCONNEC
- {TE_SCI_UNABLE_TO_REMOVE_SEGMENT,"Cannot free the resources used by this segment (step 2)"},
- //TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT = 0x20 | TE_DO_DISCONNECT
- {TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT,"Cannot disconnect from a remote segment"},
- //TE_SHM_IPC_PERMANENT = 0x21
- {TE_SHM_IPC_PERMANENT,"Shm ipc Permanent error"},
- //TE_SCI_UNABLE_TO_CLOSE_CHANNEL = 0x22
- {TE_SCI_UNABLE_TO_CLOSE_CHANNEL,"Unable to close the sci channel and the resources allocated"}
- };
-
- lenth = sizeof(TransporterErrorString)/sizeof(struct myTransporterError);
- for(i=0; i<lenth; i++)
- {
- if(theData[2] == (Uint32) TransporterErrorString[i].errorNum)
- {
- BaseString::snprintf(m_text, m_text_len,
- "Transporter to node %d reported error 0x%x: %s",
- theData[1],
- theData[2],
- TransporterErrorString[i].errorString);
- break;
- }
- }
- if(i == lenth)
- BaseString::snprintf(m_text, m_text_len,
- "Transporter to node %d reported error 0x%x: unknown error",
- theData[1],
- theData[2]);
-}
-void getTextTransporterWarning(QQQQ) {
- getTextTransporterError(m_text, m_text_len, theData);
-}
-void getTextMissedHeartbeat(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Undo Logging blocked due to buffer near to overflow.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Node %d missed heartbeat %d",
- theData[1],
- theData[2]);
-}
-void getTextDeadDueToHeartbeat(QQQQ) {
- //-----------------------------------------------------------------------
- // REPORT Undo Logging blocked due to buffer near to overflow.
- //-----------------------------------------------------------------------
- BaseString::snprintf(m_text, m_text_len,
- "Node %d declared dead due to missed heartbeat",
- theData[1]);
-}
-void getTextJobStatistic(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Mean loop Counter in doJob last 8192 times = %u",
- theData[1]);
-}
-void getTextSendBytesStatistic(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Mean send size to Node = %d last 4096 sends = %u bytes",
- theData[1],
- theData[2]);
-}
-void getTextReceiveBytesStatistic(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Mean receive size to Node = %d last 4096 sends = %u bytes",
- theData[1],
- theData[2]);
-}
-void getTextSentHeartbeat(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node Sent Heartbeat to node = %d",
- theData[1]);
-}
-void getTextCreateLogBytes(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Log part %u, log file %u, MB %u",
- theData[1],
- theData[2],
- theData[3]);
-}
-void getTextStartLog(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Log part %u, start MB %u, stop MB %u, last GCI, log exec %u",
- theData[1],
- theData[2],
- theData[3],
- theData[4]);
-}
-void getTextStartREDOLog(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Node: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]",
- theData[1],
- theData[2],
- theData[3],
- theData[4]);
-}
-void getTextUNDORecordsExecuted(QQQQ) {
- const char* line = "";
- if (theData[1] == DBTUP){
- line = "DBTUP";
- }else if (theData[1] == DBACC){
- line = "DBACC";
- }
-
- BaseString::snprintf(m_text, m_text_len,
- " UNDO %s %d [%d %d %d %d %d %d %d %d %d]",
- line,
- theData[2],
- theData[3],
- theData[4],
- theData[5],
- theData[6],
- theData[7],
- theData[8],
- theData[9],
- theData[10],
- theData[11]);
-}
-void getTextInfoEvent(QQQQ) {
- BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]);
-}
-const char bytes_unit[]= "B";
-const char kbytes_unit[]= "KB";
-const char mbytes_unit[]= "MB";
-static void convert_unit(unsigned &data, const char *&unit)
-{
- if (data < 16*1024)
- {
- unit= bytes_unit;
- return;
- }
- if (data < 16*1024*1024)
- {
- data= (data+1023)/1024;
- unit= kbytes_unit;
- return;
- }
- data= (data+1024*1024-1)/(1024*1024);
- unit= mbytes_unit;
-}
-
-void getTextEventBufferStatus(QQQQ) {
- unsigned used= theData[1], alloc= theData[2], max_= theData[3];
- const char *used_unit, *alloc_unit, *max_unit;
- convert_unit(used, used_unit);
- convert_unit(alloc, alloc_unit);
- convert_unit(max_, max_unit);
- BaseString::snprintf(m_text, m_text_len,
- "Event buffer status: used=%d%s(%d%) alloc=%d%s(%d%) "
- "max=%d%s apply_gci=%lld latest_gci=%lld",
- used, used_unit,
- theData[2] ? (Uint32)((((Uint64)theData[1])*100)/theData[2]) : 0,
- alloc, alloc_unit,
- theData[3] ? (Uint32)((((Uint64)theData[2])*100)/theData[3]) : 0,
- max_, max_unit,
- theData[4]+(((Uint64)theData[5])<<32),
- theData[6]+(((Uint64)theData[7])<<32));
-}
-void getTextWarningEvent(QQQQ) {
- BaseString::snprintf(m_text, m_text_len, (char *)&theData[1]);
-}
-void getTextGCP_TakeoverStarted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len, "GCP Take over started");
-}
-void getTextGCP_TakeoverCompleted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len, "GCP Take over completed");
-}
-void getTextLCP_TakeoverStarted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len, "LCP Take over started");
-}
-void getTextLCP_TakeoverCompleted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "LCP Take over completed (state = %d)",
- theData[1]);
-}
-void getTextMemoryUsage(QQQQ) {
- const int gth = theData[1];
- const int size = theData[2];
- const int used = theData[3];
- const int total = theData[4];
- const int block = theData[5];
- const int percent = total ? (used*100)/total : 0;
-
- BaseString::snprintf(m_text, m_text_len,
- "%s usage %s %d%s(%d %dK pages of total %d)",
- (block==DBACC ? "Index" : (block == DBTUP ?"Data":"<unknown>")),
- (gth == 0 ? "is" : (gth > 0 ? "increased to" : "decreased to")),
- percent, "%",
- used, size/1024, total
- );
-}
-
-void getTextBackupStarted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Backup %d started from node %d",
- theData[2], refToNode(theData[1]));
-}
-void getTextBackupFailedToStart(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Backup request from %d failed to start. Error: %d",
- refToNode(theData[1]), theData[2]);
-}
-void getTextBackupCompleted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Backup %u started from node %u completed."
- " StartGCP: %u StopGCP: %u"
- " #Records: %u #LogRecords: %u"
- " Data: %u bytes Log: %u bytes",
- theData[2], refToNode(theData[1]),
- theData[3], theData[4], theData[6], theData[8],
- theData[5], theData[7]);
-}
-void getTextBackupAborted(QQQQ) {
- BaseString::snprintf(m_text, m_text_len,
- "Backup %d started from %d has been aborted. Error: %d",
- theData[2],
- refToNode(theData[1]),
- theData[3]);
-}
-
-void getTextSingleUser(QQQQ) {
- switch (theData[1])
- {
- case 0:
- BaseString::snprintf(m_text, m_text_len, "Entering single user mode");
- break;
- case 1:
- BaseString::snprintf(m_text, m_text_len,
- "Entered single user mode "
- "Node %d has exclusive access", theData[2]);
- break;
- case 2:
- BaseString::snprintf(m_text, m_text_len,"Exiting single user mode");
- break;
- default:
- BaseString::snprintf(m_text, m_text_len,
- "Unknown single user report %d", theData[1]);
- break;
- }
-}
-
-void getTextStartReport(QQQQ) {
- Uint32 time = theData[2];
- Uint32 sz = theData[3];
- char mask1[100];
- char mask2[100];
- char mask3[100];
- char mask4[100];
- BitmaskImpl::getText(sz, theData + 4 + (0 * sz), mask1);
- BitmaskImpl::getText(sz, theData + 4 + (1 * sz), mask2);
- BitmaskImpl::getText(sz, theData + 4 + (2 * sz), mask3);
- BitmaskImpl::getText(sz, theData + 4 + (3 * sz), mask4);
- switch(theData[1]){
- case 1: // Wait initial
- BaseString::snprintf
- (m_text, m_text_len,
- "Initial start, waiting for %s to connect, "
- " nodes [ all: %s connected: %s no-wait: %s ]",
- mask4, mask1, mask2, mask3);
- break;
- case 2: // Wait partial
- BaseString::snprintf
- (m_text, m_text_len,
- "Waiting until nodes: %s connects, "
- "nodes [ all: %s connected: %s no-wait: %s ]",
- mask4, mask1, mask2, mask3);
- break;
- case 3: // Wait partial timeout
- BaseString::snprintf
- (m_text, m_text_len,
- "Waiting %u sec for nodes %s to connect, "
- "nodes [ all: %s connected: %s no-wait: %s ]",
-
- time, mask4, mask1, mask2, mask3);
- break;
- case 4: // Wait partioned
- BaseString::snprintf
- (m_text, m_text_len,
- "Waiting for non partitioned start, "
- "nodes [ all: %s connected: %s missing: %s no-wait: %s ]",
-
- mask1, mask2, mask4, mask3);
- break;
- case 5:
- BaseString::snprintf
- (m_text, m_text_len,
- "Waiting %u sec for non partitioned start, "
- "nodes [ all: %s connected: %s missing: %s no-wait: %s ]",
-
- time, mask1, mask2, mask4, mask3);
- break;
- case 0x8000: // Do initial
- BaseString::snprintf
- (m_text, m_text_len,
- "Initial start with nodes %s [ missing: %s no-wait: %s ]",
- mask2, mask4, mask3);
- break;
- case 0x8001: // Do start
- BaseString::snprintf
- (m_text, m_text_len,
- "Start with all nodes %s",
- mask2);
- break;
- case 0x8002: // Do partial
- BaseString::snprintf
- (m_text, m_text_len,
- "Start with nodes %s [ missing: %s no-wait: %s ]",
- mask2, mask4, mask3);
- break;
- case 0x8003: // Do partioned
- BaseString::snprintf
- (m_text, m_text_len,
- "Start potentially partitioned with nodes %s "
- " [ missing: %s no-wait: %s ]",
- mask2, mask4, mask3);
- break;
- default:
- BaseString::snprintf
- (m_text, m_text_len,
- "Unknown startreport: 0x%x [ %s %s %s %s ]",
- theData[1],
- mask1, mask2, mask3, mask4);
- }
-}
-
-#if 0
-BaseString::snprintf(m_text,
- m_text_len,
- "Unknown event: %d",
- theData[0]);
-#endif
-
-/**
- * This matrix defines which event should be printed when
- *
- * threshold - is in range [0-15]
- * severity - DEBUG to ALERT (Type of log message)
- */
-
-#define ROW(a,b,c,d) \
-{ NDB_LE_ ## a, b, c, d, getText ## a}
-
-const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
- // CONNECTION
- ROW(Connected, LogLevel::llConnection, 8, Logger::LL_INFO ),
- ROW(Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT ),
- ROW(CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO ),
- ROW(CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO ),
- ROW(ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO ),
- // CHECKPOINT
- ROW(GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO ),
- ROW(GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO ),
- ROW(LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO ),
- ROW(LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO ),
- ROW(LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT ),
- ROW(LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO ),
- ROW(UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO ),
-
- // STARTUP
- ROW(NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
- ROW(NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
- ROW(STTORRYRecieved, LogLevel::llStartUp, 15, Logger::LL_INFO ),
- ROW(StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO ),
- ROW(CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO ),
- ROW(CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO ),
- ROW(FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO ),
- ROW(NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
- ROW(NDBStopCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
- ROW(NDBStopForced, LogLevel::llStartUp, 1, Logger::LL_ALERT ),
- ROW(NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
- ROW(StartREDOLog, LogLevel::llStartUp, 4, Logger::LL_INFO ),
- ROW(StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO ),
- ROW(UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO ),
- ROW(StartReport, LogLevel::llStartUp, 4, Logger::LL_INFO ),
-
- // NODERESTART
- ROW(NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO ),
- ROW(NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO ),
- ROW(NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ),
- ROW(NR_CopyFragDone, LogLevel::llNodeRestart,10, Logger::LL_INFO ),
- ROW(NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO ),
-
- ROW(NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT),
- ROW(NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT),
- ROW(ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO ),
- ROW(ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT),
- ROW(GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
- ROW(GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
- ROW(LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
- ROW(LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO ),
-
- // STATISTIC
- ROW(TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ),
- ROW(OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO ),
- ROW(TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO ),
- ROW(JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ),
- ROW(SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ),
- ROW(ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO ),
- ROW(MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO ),
-
- // ERROR
- ROW(TransporterError, LogLevel::llError, 2, Logger::LL_ERROR ),
- ROW(TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING ),
- ROW(MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING ),
- ROW(DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT ),
- ROW(WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING ),
- // INFO
- ROW(SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO ),
- ROW(CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO ),
- ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ),
- ROW(EventBufferStatus, LogLevel::llInfo, 7, Logger::LL_INFO ),
-
- //Single User
- ROW(SingleUser, LogLevel::llInfo, 7, Logger::LL_INFO ),
-
- // Backup
- ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ),
- ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ),
- ROW(BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT),
- ROW(BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT )
-};
-
-const Uint32 EventLoggerBase::matrixSize=
-sizeof(EventLoggerBase::matrix)/sizeof(EventRepLogLevelMatrix);
-
-EventLogger::EventLogger() : m_filterLevel(15)
-{
- setCategory("EventLogger");
- enable(Logger::LL_INFO, Logger::LL_ALERT);
-}
-
-EventLogger::~EventLogger()
-{
-}
-
-bool
-EventLogger::open(const char* logFileName, int maxNoFiles, long maxFileSize,
- unsigned int maxLogEntries)
-{
- return addHandler(new FileLogHandler(logFileName, maxNoFiles, maxFileSize,
- maxLogEntries));
-}
-
-void
-EventLogger::close()
-{
- removeAllHandlers();
-}
-
-#ifdef NOT_USED
-
-static NdbOut&
-operator<<(NdbOut& out, const LogLevel & ll)
-{
- out << "[LogLevel: ";
- for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
- out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
- out << "]";
- return out;
-}
-#endif
-
-int
-EventLoggerBase::event_lookup(int eventType,
- LogLevel::EventCategory &cat,
- Uint32 &threshold,
- Logger::LoggerLevel &severity,
- EventTextFunction &textF)
-{
- for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){
- if(EventLoggerBase::matrix[i].eventType == eventType){
- cat = EventLoggerBase::matrix[i].eventCategory;
- threshold = EventLoggerBase::matrix[i].threshold;
- severity = EventLoggerBase::matrix[i].severity;
- textF= EventLoggerBase::matrix[i].textF;
- return 0;
- }
- }
- return 1;
-}
-
-const char*
-EventLogger::getText(char * dst, size_t dst_len,
- EventTextFunction textF,
- const Uint32* theData, NodeId nodeId )
-{
- int pos= 0;
- if (nodeId != 0)
- {
- BaseString::snprintf(dst, dst_len, "Node %u: ", nodeId);
- pos= strlen(dst);
- }
- if (dst_len-pos > 0)
- textF(dst+pos,dst_len-pos,theData);
- return dst;
-}
-
-void
-EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId,
- const LogLevel* ll)
-{
- Uint32 threshold = 0;
- Logger::LoggerLevel severity = Logger::LL_WARNING;
- LogLevel::EventCategory cat= LogLevel::llInvalid;
- EventTextFunction textF;
- char log_text[MAX_TEXT_LENGTH];
-
- DBUG_ENTER("EventLogger::log");
- DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
-
- if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF))
- DBUG_VOID_RETURN;
-
- Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat);
- DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set));
- if (ll)
- DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat)));
-
- if (threshold <= set){
- getText(log_text,sizeof(log_text),textF,theData,nodeId);
-
- switch (severity){
- case Logger::LL_ALERT:
- alert(log_text);
- break;
- case Logger::LL_CRITICAL:
- critical(log_text);
- break;
- case Logger::LL_WARNING:
- warning(log_text);
- break;
- case Logger::LL_ERROR:
- error(log_text);
- break;
- case Logger::LL_INFO:
- info(log_text);
- break;
- case Logger::LL_DEBUG:
- debug(log_text);
- break;
- default:
- info(log_text);
- break;
- }
- } // if (..
- DBUG_VOID_RETURN;
-}
-
-int
-EventLogger::getFilterLevel() const
-{
- return m_filterLevel;
-}
-
-void
-EventLogger::setFilterLevel(int filterLevel)
-{
- m_filterLevel = filterLevel;
-}
diff --git a/storage/ndb/src/common/debugger/GrepError.cpp b/storage/ndb/src/common/debugger/GrepError.cpp
deleted file mode 100644
index 8bb2bce64ed..00000000000
--- a/storage/ndb/src/common/debugger/GrepError.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <GrepError.hpp>
-
-/**
- * Error descriptions.
- */
-
-const GrepError::ErrorDescription GrepError::errorDescriptions[] = {
- { GrepError::GE_NO_ERROR,
- "No error" },
- { GrepError::SUBSCRIPTION_ID_NOMEM,
- "Not enough resources to allocate the subscription" },
- { GrepError::SUBSCRIPTION_ID_NOT_FOUND,
- "The requested subscription (id, key) does not exist"},
- { GrepError::SUBSCRIPTION_ID_NOT_UNIQUE,
- "A subscription with (id, key) does already exist"},
- { GrepError::SUBSCRIPTION_ID_SUMA_FAILED_CREATE,
- "Suma failed to create a new subscription id"},
- { GrepError::NULL_VALUE,
- "NULL"},
- { GrepError::SEQUENCE_ERROR,
- "Error when creating or using sequence."},
- { GrepError::NOSPACE_IN_POOL,
- "No space left in pool when trying to seize data"},
- { GrepError::SUBSCRIPTION_ID_ALREADY_EXIST,
- "A subscription for this replication channel does already exist"},
- { GrepError::SUBSCRIPTION_NOT_STARTED,
- "No subscription is started"},
- { GrepError::SUBSCRIBER_NOT_FOUND,
- "The subscriber does not exist in SUMA."},
- { GrepError::WRONG_NO_OF_SECTIONS,
- "Something is wrong with the supplied arguments"},
- { GrepError::ILLEGAL_ACTION_WHEN_STOPPING,
- "Action can not be performed while channel is in stopping state"},
- { GrepError::SELECTED_TABLE_NOT_FOUND,
- "The selected table was not found. "},
- { GrepError::REP_APPLY_LOGRECORD_FAILED,
- "Failed applying a log record (permanent error)"},
- { GrepError::REP_APPLY_METARECORD_FAILED,
- "Failed applying a meta record (permanent error)"},
- { GrepError::REP_DELETE_NEGATIVE_EPOCH,
- "Trying to delete a GCI Buffer using a negative epoch."},
- { GrepError::REP_DELETE_NONEXISTING_EPOCH,
- "Trying to delete a non-existing GCI Buffer."},
- { GrepError::REP_NO_CONNECTED_NODES,
- "There are no connected nodes in the node group."},
- { GrepError::REP_DISCONNECT,
- "Global Replication Server disconnected."},
- { GrepError::COULD_NOT_ALLOCATE_MEM_FOR_SIGNAL,
- "Could not allocate memory for signal."},
- { GrepError::REP_NOT_PROPER_TABLE,
- "Specified table is not a valid table. "
- "Either the format is not <db>/<schema>/<tablename> or "
- "the table name is too long "},
- { GrepError::REP_TABLE_ALREADY_SELECTED,
- "The specified table is already selected for replication" },
- { GrepError::REP_TABLE_NOT_FOUND,
- "The specified table was not found" },
- { GrepError::START_OF_COMPONENT_IN_WRONG_STATE,
- "Component or protocol can not be started in the current state."},
- { GrepError::START_ALREADY_IN_PROGRESS,
- "Start of replication protocol is already in progress."},
- { GrepError::ILLEGAL_STOP_EPOCH_ID,
- "It is not possible to stop on the requested epoch id."},
- { GrepError::ILLEGAL_USE_OF_COMMAND,
- "The command cannot be executed in this state."},
- { GrepError::CHANNEL_NOT_STOPPABLE,
- "It is not possible to stop the in this state."},
-
- /**
- * Applier stuff
- */
- { GrepError::REP_APPLY_NONCOMPLETE_GCIBUFFER,
- "Applier: Ordered to apply an incomplete GCI Buffer."},
- { GrepError::REP_APPLY_NULL_GCIBUFFER,
- "Applier: Tried to apply a NULL GCI Buffer."},
- { GrepError::REP_APPLIER_START_TRANSACTION,
- "Applier: Could not start a transaction."},
- { GrepError::REP_APPLIER_NO_TABLE,
- "Applier: Table does not exist"},
- { GrepError::REP_APPLIER_NO_OPERATION,
- "Applier: Cannot get NdbOperation record."},
- { GrepError::REP_APPLIER_EXECUTE_TRANSACTION,
- "Applier: Execute transaction failed."},
- { GrepError::REP_APPLIER_CREATE_TABLE,
- "Applier: Create table failed."},
- { GrepError::REP_APPLIER_PREPARE_TABLE,
- "Applier: Prepare table for create failed."},
-
- { GrepError::NOT_YET_IMPLEMENTED,
- "Command or event not yet implemented."}
-};
-
-
-
-
-
-const Uint32
-GrepError::noOfErrorDescs = sizeof(GrepError::errorDescriptions) /
- sizeof(GrepError::ErrorDescription);
-
-
-/**
- * gets the corresponding error message to an err code
- */
-const char *
-GrepError::getErrorDesc(GrepError::GE_Code err) {
-
- for(Uint32 i = 0; i<noOfErrorDescs; i++){
- if(err == errorDescriptions[i].errCode){
- return errorDescriptions[i].name;
- }
- }
- return 0;
-}
-
-
-
diff --git a/storage/ndb/src/common/debugger/Makefile.am b/storage/ndb/src/common/debugger/Makefile.am
deleted file mode 100644
index fa6df2a2626..00000000000
--- a/storage/ndb/src/common/debugger/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = signaldata
-
-noinst_LTLIBRARIES = libtrace.la
-
-libtrace_la_SOURCES = SignalLoggerManager.cpp DebuggerNames.cpp BlockNames.cpp EventLogger.cpp
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-windoze-dsp: libtrace.dsp
-
-libtrace.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libtrace_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/debugger/SignalLoggerManager.cpp b/storage/ndb/src/common/debugger/SignalLoggerManager.cpp
deleted file mode 100644
index a5a4f8a1f89..00000000000
--- a/storage/ndb/src/common/debugger/SignalLoggerManager.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "SignalLoggerManager.hpp"
-#include <LongSignal.hpp>
-
-#include <DebuggerNames.hpp>
-
-SignalLoggerManager::SignalLoggerManager()
-{
- for (int i = 0; i < NO_OF_BLOCKS; i++){
- logModes[i] = 0;
- }
- outputStream = 0;
- m_ownNodeId = 0;
- m_logDistributed = false;
-}
-
-SignalLoggerManager::~SignalLoggerManager()
-{
- if(outputStream != 0){
- fflush(outputStream);
- fclose(outputStream);
- outputStream = 0;
- }
-}
-
-FILE *
-SignalLoggerManager::setOutputStream(FILE * output)
-{
- if(outputStream != 0){
- fflush(outputStream);
- }
-
- FILE * out = outputStream;
- outputStream = output;
- return out;
-}
-
-FILE *
-SignalLoggerManager::getOutputStream() const
-{
- return outputStream;
-}
-
-void
-SignalLoggerManager::flushSignalLog()
-{
- if(outputStream != 0)
- fflush(outputStream);
-}
-
-void
-SignalLoggerManager::setTrace(unsigned long trace)
-{
- traceId = trace;
-}
-
-unsigned long
-SignalLoggerManager::getTrace() const
-{
- return traceId;
-}
-
-void
-SignalLoggerManager::setOwnNodeId(int nodeId){
- m_ownNodeId = nodeId;
-}
-
-void
-SignalLoggerManager::setLogDistributed(bool val){
- m_logDistributed = val;
-}
-
-int
-getParameter(char *blocks[NO_OF_BLOCKS], const char * par, const char * line)
-{
- const char * loc = strstr(line, par);
- if(loc == NULL)
- return 0;
-
- loc += strlen(par);
-
- int found = 0;
-
- char * copy = strdup(loc);
- char * tmp = copy;
- bool done = false;
- while(!done){
- int len = strcspn(tmp, ", ;:\0");
- if(len == 0)
- done = true;
- else {
- if(* (tmp + len) != ',')
- done = true;
- * (tmp + len) = 0;
- blocks[found] = strdup(tmp);
- found ++;
- tmp += (len + 1);
- }
- }
- free(copy);
- return found;
-}
-
-
-#define SLM_OFF 0
-#define SLM_ON 1
-#define SLM_TOGGLE 2
-
-int
-SignalLoggerManager::log(LogMode logMode, const char * params)
-{
- char * blocks[NO_OF_BLOCKS];
- const int count = getParameter(blocks, "BLOCK=", params);
-
- int cnt = 0;
- if((count == 1 && !strcmp(blocks[0], "ALL")) ||
- count == 0){
-
- for (int number = 0; number < NO_OF_BLOCKS; ++number){
- cnt += log(SLM_ON, number, logMode);
- }
- } else {
- for (int i = 0; i < count; ++i){
- BlockNumber number = getBlockNo(blocks[i]);
- cnt += log(SLM_ON, number, logMode);
- }
- }
- for(int i = 0; i<count; i++){
- free(blocks[i]);
- }
-
- return cnt;
-}
-
-int
-SignalLoggerManager::log(int cmd, BlockNumber bno, LogMode logMode)
-{
- // Normalise blocknumber for use in logModes array
- const BlockNumber bno2 = bno-MIN_BLOCK_NO;
- assert(bno2<NO_OF_BLOCKS);
- switch(cmd){
- case SLM_ON:
- logModes[bno2] |= logMode;
- return 1;
- break;
- case SLM_OFF:
- logModes[bno2] &= (~logMode);
- return 1;
- break;
- case SLM_TOGGLE:
- logModes[bno2] ^= logMode;
- return 1;
- break;
- }
- return 0;
-}
-
-int
-SignalLoggerManager::logOn(bool allBlocks, BlockNumber bno, LogMode logMode)
-{
- if(!allBlocks){
- return log(SLM_ON, bno, logMode);
- }
- int cnt = 0;
- for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
- cnt += log(SLM_ON, i, logMode);
- return cnt;
-}
-
-int
-SignalLoggerManager::logOff(bool allBlocks, BlockNumber bno, LogMode logMode)
-{
- if(!allBlocks){
- return log(SLM_OFF, bno, logMode);
- }
- int cnt = 0;
- for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
- cnt += log(SLM_OFF, i, logMode);
- return cnt;
-
-}
-
-int
-SignalLoggerManager::logToggle(bool allBlocks, BlockNumber bno, LogMode logMode)
-{
- if(!allBlocks){
- return log(SLM_TOGGLE, bno, logMode);
- }
- int cnt = 0;
- for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
- cnt += log(SLM_TOGGLE, i, logMode);
- return cnt;
-}
-
-void
-SignalLoggerManager::executeDirect(const SignalHeader& sh,
- Uint8 prio, // in-out flag
- const Uint32 * theData, Uint32 node)
-{
- Uint32 trace = sh.theTrace;
- Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- (logMatch(senderBlockNo, LogOut) || logMatch(receiverBlockNo, LogIn))){
- const char* inOutStr = prio == 0 ? "In" : "Out";
-#ifdef VM_TRACE_TIME
- fprintf(outputStream, "---- Direct --- Signal --- %s - %d ----\n", inOutStr, time(0));
-#else
- fprintf(outputStream, "---- Direct --- Signal --- %s ----------------\n", inOutStr);
-#endif
- // XXX pass in/out to print* function somehow
- printSignalHeader(outputStream, sh, 0, node, true);
- printSignalData(outputStream, sh, theData);
- }
-}
-
-/**
- * For input signals
- */
-void
-SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio,
- const Uint32 * theData, Uint32 node,
- const SegmentedSectionPtr ptr[3], Uint32 secs)
-{
- Uint32 trace = sh.theTrace;
- //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
- Uint32 senderNode = refToNode(sh.theSendersBlockRef);
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- (logMatch(receiverBlockNo, LogOut) ||
- (m_logDistributed && m_ownNodeId != senderNode))){
-#ifdef VM_TRACE_TIME
- fprintf(outputStream, "---- Received - Signal - %d ----\n", time(0));
-#else
- fprintf(outputStream, "---- Received - Signal ----------------\n");
-#endif
-
- printSignalHeader(outputStream, sh, prio, node, true);
- printSignalData(outputStream, sh, theData);
- for (unsigned i = 0; i < secs; i++)
- printSegmentedSection(outputStream, sh, ptr, i);
- }
-}
-
-void
-SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio,
- const Uint32 * theData, Uint32 node,
- const LinearSectionPtr ptr[3], Uint32 secs)
-{
- Uint32 trace = sh.theTrace;
- //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
- Uint32 senderNode = refToNode(sh.theSendersBlockRef);
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- (logMatch(receiverBlockNo, LogOut) ||
- (m_logDistributed && m_ownNodeId != senderNode))){
-#ifdef VM_TRACE_TIME
- fprintf(outputStream, "---- Received - Signal - %d ----\n", time(0));
-#else
- fprintf(outputStream, "---- Received - Signal ----------------\n");
-#endif
-
- printSignalHeader(outputStream, sh, prio, node, true);
- printSignalData(outputStream, sh, theData);
- for (unsigned i = 0; i < secs; i++)
- printLinearSection(outputStream, sh, ptr, i);
- }
-}
-
-/**
- * For output signals
- */
-void
-SignalLoggerManager::sendSignal(const SignalHeader& sh,
- Uint8 prio,
- const Uint32 * theData, Uint32 node,
- const LinearSectionPtr ptr[3], Uint32 secs)
-{
- Uint32 trace = sh.theTrace;
- Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- (logMatch(senderBlockNo, LogOut) ||
- (m_logDistributed && m_ownNodeId != node))){
-#ifdef VM_TRACE_TIME
- fprintf(outputStream, "---- Send ----- Signal - %d ----\n", time(0));
-#else
- fprintf(outputStream, "---- Send ----- Signal ----------------\n");
-#endif
-
- printSignalHeader(outputStream, sh, prio, node, false);
- printSignalData(outputStream, sh, theData);
- for (unsigned i = 0; i < secs; i++)
- printLinearSection(outputStream, sh, ptr, i);
- }
-}
-
-/**
- * For output signals
- */
-void
-SignalLoggerManager::sendSignal(const SignalHeader& sh, Uint8 prio,
- const Uint32 * theData, Uint32 node,
- const SegmentedSectionPtr ptr[3], Uint32 secs)
-{
- Uint32 trace = sh.theTrace;
- Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- (logMatch(senderBlockNo, LogOut) ||
- (m_logDistributed && m_ownNodeId != node))){
-#ifdef VM_TRACE_TIME
- fprintf(outputStream, "---- Send ----- Signal - %d ----\n", time(0));
-#else
- fprintf(outputStream, "---- Send ----- Signal ----------------\n");
-#endif
-
- printSignalHeader(outputStream, sh, prio, node, false);
- printSignalData(outputStream, sh, theData);
- for (unsigned i = 0; i < secs; i++)
- printSegmentedSection(outputStream, sh, ptr, i);
- }
-}
-
-void
-SignalLoggerManager::sendSignalWithDelay(Uint32 delayInMilliSeconds,
- const SignalHeader & sh, Uint8 prio,
- const Uint32 * theData, Uint32 node,
- const SegmentedSectionPtr ptr[3], Uint32 secs)
-{
- Uint32 trace = sh.theTrace;
- Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
-
- if(outputStream != 0 &&
- (traceId == 0 || traceId == trace) &&
- logMatch(senderBlockNo, LogOut)){
-#ifdef VM_TRACE_TIME
- fprintf(outputStream,
- "---- Send ----- Signal (%d ms) %d\n",
- delayInMilliSeconds,
- time(0));
-#else
- fprintf(outputStream, "---- Send delay Signal (%d ms) ----------\n",
- delayInMilliSeconds);
-#endif
-
- printSignalHeader(outputStream, sh, prio, node, false);
- printSignalData(outputStream, sh, theData);
- for (unsigned i = 0; i < secs; i++)
- printSegmentedSection(outputStream, sh, ptr, i);
- }
-}
-
-/**
- * Generic messages in the signal log
- */
-void
-SignalLoggerManager::log(BlockNumber bno, const char * msg, ...)
-{
- // Normalise blocknumber for use in logModes array
- const BlockNumber bno2 = bno - MIN_BLOCK_NO;
- assert(bno2<NO_OF_BLOCKS);
-
- if(outputStream != 0 &&
- logModes[bno2] != LogOff){
- va_list ap;
- va_start(ap, msg);
- fprintf(outputStream, "%s: ", getBlockName(bno, "API"));
- vfprintf(outputStream, msg, ap);
- fprintf(outputStream, "\n");
- va_end(ap);
- }
-}
-
-
-void
-SignalLoggerManager::printSignalHeader(FILE * output,
- const SignalHeader & sh,
- Uint8 prio,
- Uint32 node,
- bool printReceiversSignalId)
-{
- Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
- Uint32 receiverProcessor = node;
- Uint32 gsn = sh.theVerId_signalNumber;
- Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
- Uint32 senderProcessor = refToNode(sh.theSendersBlockRef);
- Uint32 length = sh.theLength;
- Uint32 trace = sh.theTrace;
- Uint32 rSigId = sh.theSignalId;
- Uint32 sSigId = sh.theSendersSignalId;
-
- const char * signalName = getSignalName(gsn);
- const char * rBlockName = getBlockName(receiverBlockNo, "API");
- const char * sBlockName = getBlockName(senderBlockNo, "API");
-
- if(printReceiversSignalId)
- fprintf(output,
- "r.bn: %d \"%s\", r.proc: %d, r.sigId: %d gsn: %d \"%s\" prio: %d\n"
- ,receiverBlockNo, rBlockName, receiverProcessor, rSigId,
- gsn, signalName, prio);
- else
- fprintf(output,
- "r.bn: %d \"%s\", r.proc: %d, gsn: %d \"%s\" prio: %d\n",
- receiverBlockNo, rBlockName, receiverProcessor, gsn,
- signalName, prio);
-
- fprintf(output,
- "s.bn: %d \"%s\", s.proc: %d, s.sigId: %d length: %d trace: %d "
- "#sec: %d fragInf: %d\n",
- senderBlockNo, sBlockName, senderProcessor, sSigId, length, trace,
- sh.m_noOfSections, sh.m_fragmentInfo);
-}
-
-void
-SignalLoggerManager::printSignalData(FILE * output,
- const SignalHeader & sh,
- const Uint32 * signalData)
-{
- Uint32 len = sh.theLength;
- SignalDataPrintFunction printFunction =
- findPrintFunction(sh.theVerId_signalNumber);
-
- bool ok = false; // done with printing
- if(printFunction != 0){
- ok = (* printFunction)(output, signalData, len, sh.theReceiversBlockNumber);
- }
- if(!ok){
- while(len >= 7){
- fprintf(output,
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
- signalData[0], signalData[1], signalData[2], signalData[3],
- signalData[4], signalData[5], signalData[6]);
- len -= 7;
- signalData += 7;
- }
- if(len > 0){
- for(Uint32 i = 0; i<len; i++)
- fprintf(output, " H\'%.8x", signalData[i]);
- fprintf(output, "\n");
- }
- }
-}
-
-void
-SignalLoggerManager::printLinearSection(FILE * output,
- const SignalHeader & sh,
- const LinearSectionPtr ptr[3],
- unsigned i)
-{
- fprintf(output, "SECTION %u type=linear", i);
- if (i >= 3) {
- fprintf(output, " *** invalid ***\n");
- return;
- }
- const Uint32 len = ptr[i].sz;
- const Uint32 * data = ptr[i].p;
- Uint32 pos = 0;
- fprintf(output, " size=%u\n", (unsigned)len);
- while (pos < len) {
- printDataWord(output, pos, data[pos]);
- }
- if (len > 0)
- putc('\n', output);
-}
-
-void
-SignalLoggerManager::printDataWord(FILE * output, Uint32 & pos, const Uint32 data)
-{
- const char* const hex = "0123456789abcdef";
- if (pos > 0 && pos % 7 == 0)
- putc('\n', output);
- putc(' ', output);
- putc('H', output);
- putc('\'', output);
- for (int i = 7; i >= 0; i--)
- putc(hex[(data >> (i << 2)) & 0xf], output);
- pos++;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/AccLock.cpp b/storage/ndb/src/common/debugger/signaldata/AccLock.cpp
deleted file mode 100644
index 918e1dd4e8a..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/AccLock.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/AccLock.hpp>
-#include <SignalLoggerManager.hpp>
-
-bool
-printACC_LOCKREQ(FILE* output, const Uint32* theData, Uint32 len, Uint16 rbn)
-{
- const AccLockReq* const sig = (const AccLockReq*)theData;
- Uint32 reqtype = sig->requestInfo & 0xFF;
- switch (sig->returnCode) {
- case RNIL:
- fprintf(output, " returnCode=RNIL");
- break;
- case AccLockReq::Success:
- fprintf(output, " returnCode=Success");
- break;
- case AccLockReq::IsBlocked:
- fprintf(output, " returnCode=IsBlocked");
- break;
- case AccLockReq::WouldBlock:
- fprintf(output, " returnCode=WouldBlock");
- break;
- case AccLockReq::Refused:
- fprintf(output, " returnCode=Refused");
- break;
- case AccLockReq::NoFreeOp:
- fprintf(output, " returnCode=NoFreeOp");
- break;
- default:
- fprintf(output, " returnCode=%u?", sig->returnCode);
- break;
- }
- switch (reqtype) {
- case AccLockReq::LockShared:
- fprintf(output, " req=LockShared\n");
- break;
- case AccLockReq::LockExclusive:
- fprintf(output, " req=LockExclusive\n");
- break;
- case AccLockReq::Unlock:
- fprintf(output, " req=Unlock\n");
- break;
- case AccLockReq::Abort:
- fprintf(output, " req=Abort\n");
- break;
- default:
- fprintf(output, " req=%u\n", reqtype);
- break;
- }
- fprintf(output, " accOpPtr: 0x%x\n", sig->accOpPtr);
- if (reqtype == AccLockReq::LockShared ||
- reqtype == AccLockReq::LockExclusive) {
- fprintf(output, " userPtr: 0x%x userRef: 0x%x\n", sig->userPtr, sig->userRef);
- fprintf(output, " table: id=%u", sig->tableId);
- fprintf(output, " fragment: id=%u ptr=0x%x\n", sig->fragId, sig->fragPtrI);
- fprintf(output, " tuple: addr=0x%x hashValue=%x\n", sig->tupAddr, sig->hashValue);
- fprintf(output, " transid: %08x %08x\n", sig->transId1, sig->transId2);
- }
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp b/storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp
deleted file mode 100644
index 12bfe687366..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/AlterIndx.hpp>
-
-bool printALTER_INDX_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterIndxReq * const sig = (AlterIndxReq *) theData;
- return false;
-}
-
-bool printALTER_INDX_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterIndxConf * const sig = (AlterIndxConf *) theData;
- return false;
-}
-
-bool printALTER_INDX_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterIndxRef * const sig = (AlterIndxRef *) theData;
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/AlterTab.cpp b/storage/ndb/src/common/debugger/signaldata/AlterTab.cpp
deleted file mode 100644
index a2ea11249a7..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/AlterTab.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/AlterTab.hpp>
-
-bool printALTER_TAB_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTabReq * const sig = (AlterTabReq *) theData;
-
- return false;
-}
-
-bool printALTER_TAB_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTabConf * const sig = (AlterTabConf *) theData;
-
- return false;
-}
-
-bool printALTER_TAB_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTabRef * const sig = (AlterTabRef *) theData;
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/AlterTable.cpp b/storage/ndb/src/common/debugger/signaldata/AlterTable.cpp
deleted file mode 100644
index e58338122af..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/AlterTable.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/AlterTable.hpp>
-
-bool printALTER_TABLE_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTableReq * const sig = (AlterTableReq *) theData;
-
- return false;
-}
-
-bool printALTER_TABLE_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTableConf * const sig = (AlterTableConf *) theData;
-
- return false;
-}
-
-bool printALTER_TABLE_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const AlterTableRef * const sig = (AlterTableRef *) theData;
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp b/storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp
deleted file mode 100644
index 467ebdbe12c..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/AlterTrig.hpp>
-
-bool printALTER_TRIG_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const AlterTrigReq * const sig = (AlterTrigReq *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printALTER_TRIG_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const AlterTrigConf * const sig = (AlterTrigConf *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printALTER_TRIG_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const AlterTrigRef * const sig = (AlterTrigRef *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Error code: %u, ", sig->getErrorCode());
- fprintf(output, "\n");
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp b/storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp
deleted file mode 100644
index c399959830d..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <trigger_definitions.h>
-#include <signaldata/BackupImpl.hpp>
-
-bool
-printDEFINE_BACKUP_REQ(FILE * out, const Uint32 * data, Uint32 len, Uint16 bno){
- DefineBackupReq* sig = (DefineBackupReq*)data;
- fprintf(out, " backupPtr: %d backupId: %d clientRef: %d clientData: %d\n",
- sig->backupPtr, sig->backupId, sig->clientRef, sig->clientData);
- fprintf(out, " backupKey: [ %08x%08x ] DataLength: %d\n",
- sig->backupKey[0], sig->backupKey[1], sig->backupDataLen);
- char buf[_NDB_NODE_BITMASK_SIZE * 8 + 1];
- fprintf(out, " Nodes: %s\n", sig->nodes.getText(buf));
- return true;
-}
-
-bool
-printDEFINE_BACKUP_REF(FILE * out, const Uint32 * data, Uint32 len, Uint16 bno){
- DefineBackupRef* sig = (DefineBackupRef*)data;
- fprintf(out, " backupPtr: %d backupId: %d errorCode: %d\n",
- sig->backupPtr, sig->backupId, sig->errorCode);
- return true;
-}
-
-bool
-printDEFINE_BACKUP_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- DefineBackupConf* sig = (DefineBackupConf*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
-}
-
-bool
-printSTART_BACKUP_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- StartBackupReq* sig = (StartBackupReq*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
-}
-
-bool
-printSTART_BACKUP_REF(FILE * out, const Uint32 * data, Uint32 len, Uint16 bno){
- StartBackupRef* sig = (StartBackupRef*)data;
- fprintf(out, " backupPtr: %d backupId: %d errorCode: %d\n",
- sig->backupPtr, sig->backupId, sig->errorCode);
- return true;
-}
-
-bool
-printSTART_BACKUP_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- StartBackupConf* sig = (StartBackupConf*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
-}
-
-bool
-printBACKUP_FRAGMENT_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- BackupFragmentReq* sig = (BackupFragmentReq*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- fprintf(out, " tableId: %d fragmentNo: %d (count = %d)\n",
- sig->tableId, sig->fragmentNo, sig->count);
- return true;
-}
-
-bool
-printBACKUP_FRAGMENT_REF(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- BackupFragmentRef* sig = (BackupFragmentRef*)data;
- fprintf(out, " backupPtr: %d backupId: %d nodeId: %d errorCode: %d\n",
- sig->backupPtr, sig->backupId, sig->nodeId, sig->errorCode);
- return true;
-}
-
-bool
-printBACKUP_FRAGMENT_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- BackupFragmentConf* sig = (BackupFragmentConf*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- fprintf(out, " tableId: %d fragmentNo: %d records: %llu bytes: %llu\n",
- sig->tableId, sig->fragmentNo,
- sig->noOfRecordsLow + (((Uint64)sig->noOfRecordsHigh) << 32),
- sig->noOfBytesLow + (((Uint64)sig->noOfBytesHigh) << 32));
- return true;
-}
-
-bool
-printSTOP_BACKUP_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- StopBackupReq* sig = (StopBackupReq*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
-}
-
-bool
-printSTOP_BACKUP_REF(FILE * out, const Uint32 * data, Uint32 len, Uint16 bno){
- StopBackupRef* sig = (StopBackupRef*)data;
- fprintf(out, " backupPtr: %d backupId: %d errorCode: %d\n",
- sig->backupPtr, sig->backupId, sig->errorCode);
- return true;
-}
-
-bool
-printSTOP_BACKUP_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
- StopBackupConf* sig = (StopBackupConf*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
-}
-
-bool
-printBACKUP_STATUS_REQ(FILE *, const Uint32 *, Uint32, Uint16){
- return false;
-}
-
-bool
-printBACKUP_STATUS_CONF(FILE *, const Uint32 *, Uint32, Uint16){
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp b/storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp
deleted file mode 100644
index 04d84cc5b34..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/BackupSignalData.hpp>
-
-bool
-printBACKUP_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 bno){
- BackupReq* sig = (BackupReq*)theData;
- fprintf(output, " senderData: %d DataLength: %d flags: %d\n",
- sig->senderData,
- sig->backupDataLen,
- sig->flags);
- return true;
-}
-
-bool
-printBACKUP_DATA(FILE * output, const Uint32 * theData, Uint32 len, Uint16 bno){
- BackupData * sig = (BackupData*)theData;
- if(sig->requestType == BackupData::ClientToMaster){
- fprintf(output, " ClientToMaster: senderData: %d backupId: %d\n",
- sig->senderData, sig->backupId);
- } else if(sig->requestType == BackupData::MasterToSlave){
- fprintf(output, " MasterToSlave: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- }
- return false;
-}
-
-bool
-printBACKUP_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 bno){
-
- BackupRef* sig = (BackupRef*)theData;
- fprintf(output, " senderData: %d errorCode: %d masterRef: %d\n",
- sig->senderData,
- sig->errorCode,
- sig->masterRef);
- return true;
-}
-
-bool
-printBACKUP_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 bno){
- BackupConf* sig = (BackupConf*)theData;
- fprintf(output, " senderData: %d backupId: %d\n",
- sig->senderData,
- sig->backupId);
- return true;
-}
-
-bool
-printBACKUP_ABORT_REP(FILE * out, const Uint32 * data, Uint32 len, Uint16 bno){
- BackupAbortRep* sig = (BackupAbortRep*)data;
- fprintf(out, " senderData: %d backupId: %d reason: %d\n",
- sig->senderData,
- sig->backupId,
- sig->reason);
- return true;
-}
-
-bool
-printBACKUP_COMPLETE_REP(FILE * out, const Uint32 * data, Uint32 len, Uint16 b){
- BackupCompleteRep* sig = (BackupCompleteRep*)data;
- fprintf(out, " senderData: %d backupId: %d records: %llu bytes: %llu\n",
- sig->senderData,
- sig->backupId,
- sig->noOfRecordsLow + (((Uint64)sig->noOfRecordsHigh) << 32),
- sig->noOfBytesLow + (((Uint64)sig->noOfBytesHigh) << 32));
- return true;
-}
-
-bool
-printBACKUP_NF_COMPLETE_REP(FILE*, const Uint32*, Uint32, Uint16){
- return false;
-}
-
-bool
-printABORT_BACKUP_ORD(FILE * out, const Uint32 * data, Uint32 len, Uint16 b){
- AbortBackupOrd* sig = (AbortBackupOrd*)data;
-
- AbortBackupOrd::RequestType rt =(AbortBackupOrd::RequestType)sig->requestType;
- switch(rt){
- case AbortBackupOrd::ClientAbort:
- fprintf(out, " ClientAbort: senderData: %d backupId: %d\n",
- sig->senderData, sig->backupId);
- return true;
- break;
- case AbortBackupOrd::BackupComplete:
- fprintf(out, " BackupComplete: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- case AbortBackupOrd::BackupFailure:
- fprintf(out, " BackupFailure: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- case AbortBackupOrd::LogBufferFull:
- fprintf(out, " LogBufferFull: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- break;
- case AbortBackupOrd::FileOrScanError:
- fprintf(out, " FileOrScanError: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- break;
- case AbortBackupOrd::BackupFailureDueToNodeFail:
- fprintf(out, " BackupFailureDueToNodeFail: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- break;
- case AbortBackupOrd::OkToClean:
- fprintf(out, " OkToClean: backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- return true;
- break;
- case AbortBackupOrd::AbortScan:
- case AbortBackupOrd::IncompatibleVersions:
- return false;
- }
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp b/storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp
deleted file mode 100644
index 771f3d884f7..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <kernel_types.h>
-#include <BlockNumbers.h>
-#include <signaldata/CloseComReqConf.hpp>
-
-bool
-printCLOSECOMREQCONF(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 receiverBlockNo){
-
- CloseComReqConf * cc = (CloseComReqConf*)theData;
-
- fprintf(output, " xxxBlockRef = (%d, %d) failNo = %d noOfNodes = %d\n",
- refToBlock(cc->xxxBlockRef), refToNode(cc->xxxBlockRef),
- cc->failNo, cc->noOfNodes);
-
- int hits = 0;
- fprintf(output, " Nodes: ");
- for(int i = 0; i<MAX_NODES; i++){
- if(NodeBitmask::get(cc->theNodes, i)){
- hits++;
- fprintf(output, " %d", i);
- }
- if(hits == 16){
- fprintf(output, "\n Nodes: ");
- hits = 0;
- }
- }
- if(hits != 0)
- fprintf(output, "\n");
-
- return true;
-}
-
-
diff --git a/storage/ndb/src/common/debugger/signaldata/CntrStart.cpp b/storage/ndb/src/common/debugger/signaldata/CntrStart.cpp
deleted file mode 100644
index cc092b478a5..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CntrStart.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#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/storage/ndb/src/common/debugger/signaldata/ContinueB.cpp b/storage/ndb/src/common/debugger/signaldata/ContinueB.cpp
deleted file mode 100644
index c00f9ce274e..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/ContinueB.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <kernel_types.h>
-#include <BlockNumbers.h>
-#include <signaldata/DihContinueB.hpp>
-#include <signaldata/NdbfsContinueB.hpp>
-
-bool
-printCONTINUEB(FILE * output, const Uint32 * theData, Uint32 len,
- Uint16 receiverBlockNo){
- if(receiverBlockNo == DBDIH){
- return printCONTINUEB_DBDIH(output, theData, len, 0);
- } else if(receiverBlockNo == NDBFS) {
- return printCONTINUEB_NDBFS(output, theData, len, 0);
- }
-
- return false;
-}
-
-
diff --git a/storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp b/storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp
deleted file mode 100644
index 1bce63a3d0f..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/CopyGCIReq.hpp>
-
-static
-void
-print(char * buf, size_t buf_len, CopyGCIReq::CopyReason r){
- switch(r){
- case CopyGCIReq::IDLE:
- BaseString::snprintf(buf, buf_len, "IDLE");
- break;
- case CopyGCIReq::LOCAL_CHECKPOINT:
- BaseString::snprintf(buf, buf_len, "LOCAL_CHECKPOINT");
- break;
- case CopyGCIReq::RESTART:
- BaseString::snprintf(buf, buf_len, "RESTART");
- break;
- case CopyGCIReq::GLOBAL_CHECKPOINT:
- BaseString::snprintf(buf, buf_len, "GLOBAL_CHECKPOINT");
- break;
- case CopyGCIReq::INITIAL_START_COMPLETED:
- BaseString::snprintf(buf, buf_len, "INITIAL_START_COMPLETED");
- break;
- default:
- BaseString::snprintf(buf, buf_len, "<Unknown>");
- }
-}
-
-bool
-printCOPY_GCI_REQ(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
- CopyGCIReq * sig = (CopyGCIReq*)theData;
-
- static char buf[255];
- print(buf, sizeof(buf), (CopyGCIReq::CopyReason)sig->copyReason);
-
- fprintf(output, " SenderData: %d CopyReason: %s StartWord: %d\n",
- sig->anyData,
- buf,
- sig->startWord);
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp b/storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp
deleted file mode 100644
index 49cf2d8d4f3..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/CreateEvnt.hpp>
-
-bool printCREATE_EVNT_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateEvntReq * const sig = (CreateEvntReq *) theData;
-
- return false;
-}
-
-bool printCREATE_EVNT_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateEvntConf * const sig = (CreateEvntConf *) theData;
-
- return false;
-}
-
-bool printCREATE_EVNT_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateEvntRef * const sig = (CreateEvntRef *) theData;
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp b/storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp
deleted file mode 100644
index 524b2678c74..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/CreateFragmentation.hpp>
-
-bool
-printCREATE_FRAGMENTATION_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const CreateFragmentationReq * const sig = (CreateFragmentationReq *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " fragmentationType: %x\n", sig->fragmentationType);
- fprintf(output, " noOfFragments: %x\n", sig->noOfFragments);
- if (sig->primaryTableId == RNIL)
- fprintf(output, " primaryTableId: none\n");
- else
- fprintf(output, " primaryTableId: %x\n", sig->primaryTableId);
- return true;
-}
-
-bool
-printCREATE_FRAGMENTATION_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const CreateFragmentationRef * const sig = (CreateFragmentationRef *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " errorCode: %x\n", sig->errorCode);
- return true;
-}
-
-bool
-printCREATE_FRAGMENTATION_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const CreateFragmentationConf * const sig =
- (CreateFragmentationConf *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " noOfReplicas: %x\n", sig->noOfReplicas);
- fprintf(output, " noOfFragments: %x\n", sig->noOfFragments);
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp b/storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp
deleted file mode 100644
index 46ea8e27449..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/CreateIndx.hpp>
-
-bool printCREATE_INDX_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateIndxReq * const sig = (CreateIndxReq *) theData;
-
- return false;
-}
-
-bool printCREATE_INDX_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateIndxConf * const sig = (CreateIndxConf *) theData;
-
- return false;
-}
-
-bool printCREATE_INDX_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const CreateIndxRef * const sig = (CreateIndxRef *) theData;
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp b/storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp
deleted file mode 100644
index 1ed3b940f29..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/CreateTrig.hpp>
-
-bool printCREATE_TRIG_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const CreateTrigReq * const sig = (CreateTrigReq *) theData;
-
- //char triggerName[MAX_TAB_NAME_SIZE];
- char triggerType[32];
- char triggerActionTime[32];
- char triggerEvent[32];
-
- //sig->getTriggerName((char *) &triggerName);
- switch (sig->getTriggerType()) {
- case(TriggerType::SECONDARY_INDEX):
- BaseString::snprintf(triggerType, sizeof(triggerType), "SECONDARY_INDEX");
- break;
- case(TriggerType::SUBSCRIPTION):
- BaseString::snprintf(triggerType, sizeof(triggerType), "SUBSCRIPTION");
- break;
- case(TriggerType::ORDERED_INDEX):
- BaseString::snprintf(triggerType, sizeof(triggerType), "ORDERED_INDEX");
- break;
- default:
- BaseString::snprintf(triggerType, sizeof(triggerType), "UNKNOWN [%d]", (int)sig->getTriggerType());
- break;
- }
- switch (sig->getTriggerActionTime()) {
- case (TriggerActionTime::TA_BEFORE):
- BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "BEFORE");
- break;
- case(TriggerActionTime::TA_AFTER):
- BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "AFTER");
- break;
- case (TriggerActionTime::TA_DEFERRED):
- BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "DEFERRED");
- break;
- case (TriggerActionTime::TA_DETACHED):
- BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime), "DETACHED");
- break;
- default:
- BaseString::snprintf(triggerActionTime, sizeof(triggerActionTime),
- "UNKNOWN [%d]", (int)sig->getTriggerActionTime());
- break;
- }
- switch (sig->getTriggerEvent()) {
- case (TriggerEvent::TE_INSERT):
- BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "INSERT");
- break;
- case(TriggerEvent::TE_DELETE):
- BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "DELETE");
- break;
- case(TriggerEvent::TE_UPDATE):
- BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "UPDATE");
- break;
- case(TriggerEvent::TE_CUSTOM):
- BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "CUSTOM");
- break;
- default:
- BaseString::snprintf(triggerEvent, sizeof(triggerEvent), "UNKNOWN [%d]", (int)sig->getTriggerEvent());
- break;
- }
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- //fprintf(output, "Trigger name: \"%s\"\n", triggerName);
- fprintf(output, "Type: %s, ", triggerType);
- fprintf(output, "Action: %s, ", triggerActionTime);
- fprintf(output, "Event: %s, ", triggerEvent);
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "Monitor replicas: %s ", (sig->getMonitorReplicas())?"true":"false");
- fprintf(output, "Monitor all attributes: %s ", (sig->getMonitorAllAttributes())?"true":"false");
- const AttributeMask& attributeMask = sig->getAttributeMask();
-
- char buf[MAXNROFATTRIBUTESINWORDS * 8 + 1];
- fprintf(output, "Attribute mask: %s", attributeMask.getText(buf));
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printCREATE_TRIG_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const CreateTrigConf * const sig = (CreateTrigConf *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printCREATE_TRIG_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const CreateTrigRef * const sig = (CreateTrigRef *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "Error code: %u, ", sig->getErrorCode());
- fprintf(output, "\n");
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp b/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp
deleted file mode 100644
index 264997d7766..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/DictTabInfo.hpp>
-#include <ndb_limits.h>
-
-//static
-const
-SimpleProperties::SP2StructMapping
-DictTabInfo::TableMapping[] = {
- DTIMAPS(Table, TableName, TableName, 0, MAX_TAB_NAME_SIZE),
- DTIMAP(Table, TableId, TableId),
- DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE),
- DTIMAP(Table, PrimaryTableId, PrimaryTableId),
- DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1),
- DTIMAP2(Table, TableTemporaryFlag, TableTemporaryFlag, 0, 1),
- DTIMAP2(Table, ForceVarPartFlag, ForceVarPartFlag, 0, 1),
- DTIMAP2(Table, TableKValue, TableKValue, 6, 6),
- DTIMAP2(Table, MinLoadFactor, MinLoadFactor, 0, 90),
- DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor, 25, 110),
- DTIMAP2(Table, FragmentTypeVal, FragmentType, 0, 3),
- DTIMAP2(Table, TableTypeVal, TableType, 1, 3),
- DTIMAP(Table, NoOfKeyAttr, NoOfKeyAttr),
- DTIMAP2(Table, NoOfAttributes, NoOfAttributes, 1, MAX_ATTRIBUTES_IN_TABLE),
- DTIMAP(Table, NoOfNullable, NoOfNullable),
- DTIMAP2(Table, NoOfVariable, NoOfVariable, 0, 0),
- DTIMAP(Table, KeyLength, KeyLength),
- DTIMAP(Table, TableVersion, TableVersion),
- DTIMAP(Table, IndexState, IndexState),
- DTIMAP(Table, InsertTriggerId, InsertTriggerId),
- DTIMAP(Table, UpdateTriggerId, UpdateTriggerId),
- DTIMAP(Table, DeleteTriggerId, DeleteTriggerId),
- DTIMAP(Table, CustomTriggerId, CustomTriggerId),
- DTIMAP2(Table, FrmLen, FrmLen, 0, MAX_FRM_DATA_SIZE),
- DTIMAPB(Table, FrmData, FrmData, 0, MAX_FRM_DATA_SIZE, FrmLen),
- DTIMAP2(Table, FragmentCount, FragmentCount, 0, MAX_NDB_PARTITIONS),
- DTIMAP2(Table, ReplicaDataLen, ReplicaDataLen, 0, 2*MAX_FRAGMENT_DATA_BYTES),
- DTIMAPB(Table, ReplicaData, ReplicaData, 0, 2*MAX_FRAGMENT_DATA_BYTES, ReplicaDataLen),
- DTIMAP2(Table, FragmentDataLen, FragmentDataLen, 0, 6*MAX_NDB_PARTITIONS),
- DTIMAPB(Table, FragmentData, FragmentData, 0, 6*MAX_NDB_PARTITIONS, FragmentDataLen),
- DTIMAP2(Table, TablespaceDataLen, TablespaceDataLen, 0, 8*MAX_NDB_PARTITIONS),
- DTIMAPB(Table, TablespaceData, TablespaceData, 0, 8*MAX_NDB_PARTITIONS, TablespaceDataLen),
- DTIMAP2(Table, RangeListDataLen, RangeListDataLen, 0, 8*MAX_NDB_PARTITIONS),
- DTIMAPB(Table, RangeListData, RangeListData, 0, 8*MAX_NDB_PARTITIONS, RangeListDataLen),
- DTIMAP(Table, TablespaceId, TablespaceId),
- DTIMAP(Table, TablespaceVersion, TablespaceVersion),
- DTIMAP(Table, MaxRowsLow, MaxRowsLow),
- DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
- DTIMAP(Table, DefaultNoPartFlag, DefaultNoPartFlag),
- DTIMAP(Table, LinearHashFlag, LinearHashFlag),
- DTIMAP(Table, TablespaceVersion, TablespaceVersion),
- DTIMAP(Table, RowGCIFlag, RowGCIFlag),
- DTIMAP(Table, RowChecksumFlag, RowChecksumFlag),
- DTIMAP(Table, MaxRowsLow, MaxRowsLow),
- DTIMAP(Table, MaxRowsHigh, MaxRowsHigh),
- DTIMAP(Table, MinRowsLow, MinRowsLow),
- DTIMAP(Table, MinRowsHigh, MinRowsHigh),
- DTIMAP(Table, SingleUserMode, SingleUserMode),
- DTIBREAK(AttributeName)
-};
-
-//static
-const Uint32 DictTabInfo::TableMappingSize =
-sizeof(DictTabInfo::TableMapping) / sizeof(SimpleProperties::SP2StructMapping);
-
-//static
-const
-SimpleProperties::SP2StructMapping
-DictTabInfo::AttributeMapping[] = {
- DTIMAPS(Attribute, AttributeName, AttributeName, 0, MAX_ATTR_NAME_SIZE),
- DTIMAP(Attribute, AttributeId, AttributeId),
- DTIMAP(Attribute, AttributeType, AttributeType),
- DTIMAP2(Attribute, AttributeSize, AttributeSize, 3, 7),
- DTIMAP2(Attribute, AttributeArraySize, AttributeArraySize, 0, 65535),
- DTIMAP2(Attribute, AttributeArrayType, AttributeArrayType, 0, 3),
- DTIMAP2(Attribute, AttributeKeyFlag, AttributeKeyFlag, 0, 1),
- DTIMAP2(Attribute, AttributeNullableFlag, AttributeNullableFlag, 0, 1),
- DTIMAP2(Attribute, AttributeDKey, AttributeDKey, 0, 1),
- DTIMAP2(Attribute, AttributeStorageType, AttributeStorageType, 0, 1),
- DTIMAP(Attribute, AttributeExtType, AttributeExtType),
- DTIMAP(Attribute, AttributeExtPrecision, AttributeExtPrecision),
- DTIMAP(Attribute, AttributeExtScale, AttributeExtScale),
- DTIMAP(Attribute, AttributeExtLength, AttributeExtLength),
- DTIMAP2(Attribute, AttributeAutoIncrement, AttributeAutoIncrement, 0, 1),
- DTIMAPS(Attribute, AttributeDefaultValue, AttributeDefaultValue,
- 0, MAX_ATTR_DEFAULT_VALUE_SIZE),
- DTIBREAK(AttributeEnd)
-};
-
-//static
-const Uint32 DictTabInfo::AttributeMappingSize =
-sizeof(DictTabInfo::AttributeMapping) /
-sizeof(SimpleProperties::SP2StructMapping);
-
-bool printDICTTABINFO(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
-// const DictTabInfo * const sig = (DictTabInfo *) theData;
-
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- return true;
-}
-
-void
-DictTabInfo::Table::init(){
- memset(TableName, 0, sizeof(TableName));//TableName[0] = 0;
- TableId = ~0;
- memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index"
- PrimaryTableId = RNIL;
- TableLoggedFlag = 1;
- TableTemporaryFlag = 0;
- ForceVarPartFlag = 0;
- NoOfKeyAttr = 0;
- NoOfAttributes = 0;
- NoOfNullable = 0;
- NoOfVariable = 0;
- TableKValue = 6;
- MinLoadFactor = 78;
- MaxLoadFactor = 80;
- KeyLength = 0;
- FragmentType = DictTabInfo::AllNodesSmallTable;
- TableType = DictTabInfo::UndefTableType;
- TableVersion = 0;
- IndexState = ~0;
- InsertTriggerId = RNIL;
- UpdateTriggerId = RNIL;
- DeleteTriggerId = RNIL;
- CustomTriggerId = RNIL;
- FrmLen = 0;
- FragmentDataLen = 0;
- ReplicaDataLen = 0;
- RangeListDataLen = 0;
- TablespaceDataLen = 0;
- memset(FrmData, 0, sizeof(FrmData));
- memset(FragmentData, 0, sizeof(FragmentData));
- memset(ReplicaData, 0, sizeof(ReplicaData));
- memset(RangeListData, 0, sizeof(RangeListData));
- memset(TablespaceData, 0, sizeof(TablespaceData));
- FragmentCount = 0;
- TablespaceId = RNIL;
- TablespaceVersion = ~0;
- MaxRowsLow = 0;
- MaxRowsHigh = 0;
- DefaultNoPartFlag = 1;
- LinearHashFlag = 1;
-
- RowGCIFlag = ~0;
- RowChecksumFlag = ~0;
-
- MaxRowsLow = 0;
- MaxRowsHigh = 0;
- MinRowsLow = 0;
- MinRowsHigh = 0;
-
- SingleUserMode = 0;
-}
-
-void
-DictTabInfo::Attribute::init(){
- memset(AttributeName, 0, sizeof(AttributeName));//AttributeName[0] = 0;
- AttributeId = 0xFFFF; // ZNIL
- AttributeType = ~0, // deprecated
- AttributeSize = DictTabInfo::a32Bit;
- AttributeArraySize = 1;
- AttributeArrayType = NDB_ARRAYTYPE_FIXED;
- AttributeKeyFlag = 0;
- AttributeNullableFlag = 0;
- AttributeDKey = 0;
- AttributeExtType = DictTabInfo::ExtUnsigned,
- AttributeExtPrecision = 0,
- AttributeExtScale = 0,
- AttributeExtLength = 0,
- AttributeAutoIncrement = false;
- AttributeStorageType = 0;
- memset(AttributeDefaultValue, 0, sizeof(AttributeDefaultValue));//AttributeDefaultValue[0] = 0;
-}
-
-//static
-const
-SimpleProperties::SP2StructMapping
-DictFilegroupInfo::Mapping[] = {
- DFGIMAPS(Filegroup, FilegroupName, FilegroupName, 0, MAX_TAB_NAME_SIZE),
- DFGIMAP2(Filegroup, FilegroupType, FilegroupType, 0, 1),
- DFGIMAP(Filegroup, FilegroupId, FilegroupId),
- DFGIMAP(Filegroup, FilegroupVersion, FilegroupVersion),
-
- DFGIMAP(Filegroup, TS_ExtentSize, TS_ExtentSize),
- DFGIMAP(Filegroup, TS_LogfileGroupId, TS_LogfileGroupId),
- DFGIMAP(Filegroup, TS_LogfileGroupVersion, TS_LogfileGroupVersion),
- DFGIMAP(Filegroup, TS_GrowLimit, TS_DataGrow.GrowLimit),
- DFGIMAP(Filegroup, TS_GrowSizeHi, TS_DataGrow.GrowSizeHi),
- DFGIMAP(Filegroup, TS_GrowSizeLo, TS_DataGrow.GrowSizeLo),
- DFGIMAPS(Filegroup, TS_GrowPattern, TS_DataGrow.GrowPattern, 0, PATH_MAX),
- DFGIMAP(Filegroup, TS_GrowMaxSize, TS_DataGrow.GrowMaxSize),
-
- DFGIMAP(Filegroup, LF_UndoBufferSize, LF_UndoBufferSize),
- DFGIMAP(Filegroup, LF_UndoGrowLimit, LF_UndoGrow.GrowLimit),
- DFGIMAP(Filegroup, LF_UndoGrowSizeHi, LF_UndoGrow.GrowSizeHi),
- DFGIMAP(Filegroup, LF_UndoGrowSizeLo, LF_UndoGrow.GrowSizeLo),
- DFGIMAPS(Filegroup, LF_UndoGrowPattern, LF_UndoGrow.GrowPattern, 0,PATH_MAX),
- DFGIMAP(Filegroup, LF_UndoGrowMaxSize, LF_UndoGrow.GrowMaxSize),
- DFGIMAP(Filegroup, LF_UndoFreeWordsHi, LF_UndoFreeWordsHi),
- DFGIMAP(Filegroup, LF_UndoFreeWordsLo, LF_UndoFreeWordsLo),
-
- DFGIBREAK(FileName)
-};
-
-//static
-const Uint32 DictFilegroupInfo::MappingSize =
-sizeof(DictFilegroupInfo::Mapping) / sizeof(SimpleProperties::SP2StructMapping);
-
-//static
-const
-SimpleProperties::SP2StructMapping
-DictFilegroupInfo::FileMapping[] = {
- DFGIMAPS(File, FileName, FileName, 0, PATH_MAX),
- DFGIMAP2(File, FileType, FileType, 0, 1),
- DFGIMAP(File, FileId, FileId),
- DFGIMAP(File, FileVersion, FileVersion),
- DFGIMAP(File, FileFGroupId, FilegroupId),
- DFGIMAP(File, FileFGroupVersion, FilegroupVersion),
- DFGIMAP(File, FileSizeHi, FileSizeHi),
- DFGIMAP(File, FileSizeLo, FileSizeLo),
- DFGIMAP(File, FileFreeExtents, FileFreeExtents),
- DFGIBREAK(FileEnd)
-};
-
-//static
-const Uint32 DictFilegroupInfo::FileMappingSize =
-sizeof(DictFilegroupInfo::FileMapping) /
-sizeof(SimpleProperties::SP2StructMapping);
-
-void
-DictFilegroupInfo::Filegroup::init(){
- memset(FilegroupName, 0, sizeof(FilegroupName));
- FilegroupType = ~0;
- FilegroupId = ~0;
- FilegroupVersion = ~0;
-
- TS_ExtentSize = 0;
- TS_LogfileGroupId = ~0;
- TS_LogfileGroupVersion = ~0;
- TS_DataGrow.GrowLimit = 0;
- TS_DataGrow.GrowSizeHi = 0;
- TS_DataGrow.GrowSizeLo = 0;
- memset(TS_DataGrow.GrowPattern, 0, sizeof(TS_DataGrow.GrowPattern));
- TS_DataGrow.GrowMaxSize = 0;
- LF_UndoFreeWordsHi= 0;
- LF_UndoFreeWordsLo= 0;
-}
-
-void
-DictFilegroupInfo::File::init(){
- memset(FileName, 0, sizeof(FileName));
- FileType = ~0;
- FileId = ~0;
- FileVersion = ~0;
- FilegroupId = ~0;
- FilegroupVersion = ~0;
- FileSizeHi = 0;
- FileSizeLo = 0;
- FileFreeExtents = 0;
-}
-
-// blob table name hack
-
-bool
-DictTabInfo::isBlobTableName(const char* name, Uint32* ptab_id, Uint32* pcol_no)
-{
- const char* const prefix = "NDB$BLOB_";
- const char* s = strrchr(name, table_name_separator);
- s = (s == NULL ? name : s + 1);
- if (strncmp(s, prefix, strlen(prefix)) != 0)
- return false;
- s += strlen(prefix);
- uint i, n;
- for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
- n = 10 * n + (s[i] - '0');
- if (i == 0 || s[i] != '_')
- return false;
- const uint tab_id = n;
- s = &s[i + 1];
- for (i = 0, n = 0; '0' <= s[i] && s[i] <= '9'; i++)
- n = 10 * n + (s[i] - '0');
- if (i == 0 || s[i] != 0)
- return false;
- const uint col_no = n;
- if (ptab_id)
- *ptab_id = tab_id;
- if (pcol_no)
- *pcol_no = col_no;
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp b/storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp
deleted file mode 100644
index 67c6dc2afd0..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/DihContinueB.hpp>
-
-bool
-printCONTINUEB_DBDIH(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 not_used){
-
- (void)not_used;
-
- switch (theData[0]) {
- case DihContinueB::ZPACK_TABLE_INTO_PAGES:
- fprintf(output, " Pack Table Into Pages: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZPACK_FRAG_INTO_PAGES:
- fprintf(output, " Pack Frag Into Pages: Table: %d Fragment: %d PageIndex: %d WordIndex: %d\n",
- theData[1], theData[2], theData[3], theData[4]);
- return true;
- break;
- case DihContinueB::ZREAD_PAGES_INTO_TABLE:
- fprintf(output, " Read Pages Into Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZREAD_PAGES_INTO_FRAG:
- fprintf(output, " Read Pages Into Frag: Table: %d Fragment: %d PageIndex: %d WordIndex: %d\n",
- theData[1], theData[2], theData[3], theData[4]);
- return true;
- break;
-#if 0
- case DihContinueB::ZREAD_TAB_DESCRIPTION:
- fprintf(output, " Read Table description: %d\n", theData[1]);
- return true;
- break;
-#endif
- case DihContinueB::ZCOPY_TABLE:
- fprintf(output, " Copy Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZCOPY_TABLE_NODE:
- fprintf(output, " Copy table node: TableId: %d NodeId: %d\n",
- theData[1], theData[2]);
- fprintf(output, "PageIndex: %d WordIndex: %d NoOfWords: %d\n",
- theData[3], theData[4], theData[5]);
- return true;
- break;
- case DihContinueB::ZSTART_FRAGMENT:
- fprintf(output, " Start fragment: Table: %d Fragment: %d\n",
- theData[1], theData[2]);
- return true;
- break;
- case DihContinueB::ZCOMPLETE_RESTART:
- fprintf(output, "Complete Restart\n");
- return true;
- break;
- case DihContinueB::ZREAD_TABLE_FROM_PAGES:
- fprintf(output, " Read Table From Pages: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZSR_PHASE2_READ_TABLE:
- fprintf(output, " Phase 2 Read Table: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZCHECK_TC_COUNTER:
- fprintf(output, " Check Tc Counter from place %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZCALCULATE_KEEP_GCI:
- fprintf(output, " Calc Keep GCI: Table: %d Fragment: %d\n",
- theData[1], theData[2]);
- return true;
- break;
- case DihContinueB::ZSTORE_NEW_LCP_ID:
- fprintf(output, " Store New LCP Id\n");
- return true;
- break;
- case DihContinueB::ZTABLE_UPDATE:
- fprintf(output, " Table Update: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZCHECK_LCP_COMPLETED:
- fprintf(output, " Check LCP Completed: TableId %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZINIT_LCP:
- fprintf(output, " Init LCP: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZADD_TABLE_MASTER_PAGES:
- fprintf(output, " Add Table Master Pages: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZDIH_ADD_TABLE_MASTER:
- fprintf(output, " Dih Add Table Master: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
- fprintf(output, " Add Table Slave Pages: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
- fprintf(output, " Add Table Slave: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZSTART_GCP:
- fprintf(output, " Start GCP\n");
- return true;
- break;
- case DihContinueB::ZCOPY_GCI:
- fprintf(output, " Copy GCI\n");
- return true;
- break;
- case DihContinueB::ZEMPTY_VERIFY_QUEUE:
- fprintf(output, " Empty Verify Queue\n");
- return true;
- break;
- case DihContinueB::ZCHECK_GCP_STOP:
- fprintf(output, " Check GCP Stop\n");
- if (len == 6){
- fprintf(output, "coldGcpStatus = %d\n", theData[1]);
- fprintf(output, "cgcpStatus = %d\n", theData[2]);
- fprintf(output, "coldGcpId = %d\n", theData[3]);
- fprintf(output, "cnewgcp = %d\n", theData[4]);
- fprintf(output, "cgcpSameCounter = %d\n", theData[5]);
- }
- return true;
- break;
- case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
- fprintf(output, " Remove Node From Table: Node: %d Table: %d\n",
- theData[1], theData[2]);
- return true;
- break;
- case DihContinueB::ZCOPY_NODE:
- fprintf(output, " Copy Node: Table: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZSTART_TAKE_OVER:
- fprintf(output, " Start Take Over: TakeOverPtr: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZCHECK_START_TAKE_OVER:
- fprintf(output, " Check Start Take Over\n");
- return true;
- break;
- case DihContinueB::ZTO_START_COPY_FRAG:
- fprintf(output, " To Start Copy Frag: TakeOverPtr: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZINVALIDATE_NODE_LCP:
- fprintf(output, " Invalide LCP: NodeId: %d TableId %d\n",
- theData[1], theData[2]);
- return true;
- break;
- case DihContinueB::ZINITIALISE_RECORDS:
- fprintf(output, " Initialise Records: tdata0: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::ZSTART_PERMREQ_AGAIN:
- fprintf(output, " START_PERMREQ again for node: %d\n", theData[1]);
- return true;
- break;
- case DihContinueB::SwitchReplica:
- fprintf(output, " NodeId = %d TableId = %d FragNo = %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZSEND_START_TO:
- fprintf(output, " Send Start Take Over: TakeOverPtr: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZSEND_UPDATE_TO:
- fprintf(output, " Send Update Take Over: TakeOverPtr: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZSEND_END_TO:
- fprintf(output, " Send End Take Over: TakeOverPtr: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZSEND_ADD_FRAG:
- fprintf(output, " Send Add Fragment: TakeOverPtr: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3]);
- return true;
- break;
- case DihContinueB::ZSEND_CREATE_FRAG:
- fprintf(output, " Send Create Fragment: TakeOverPtr: %d, storedType: %d, start Gci: %d, startNode: %d, toNode: %d\n",
- theData[1], theData[2], theData[3], theData[4], theData[5]);
- return true;
- break;
- case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:
- fprintf(output, " Wait drop tab writing to file TableId: %d\n", theData[1]);
- return true;
- case DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:
- fprintf(output, " Wait drop tab FailedNodeId: %d TableId: %d\n",
- theData[1], theData[2]);
- return true;
- default:
- fprintf(output, " Default system error lab...\n");
- break;
- }//switch
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp b/storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp
deleted file mode 100644
index 6dc5fb17b26..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/DihSwitchReplicaReq.hpp>
-
-bool
-printDIH_SWITCH_REPLICA_REQ(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
-
- DihSwitchReplicaReq * req = (DihSwitchReplicaReq *)&theData[0];
-
- const Uint32 requestInfo = req->requestInfo;
-
- switch(DihSwitchReplicaReq::getRequestType(requestInfo)){
- case DihSwitchReplicaReq::RemoveNodeAsPrimary:{
- fprintf(output, " RemoveNodeAsPrimary: Node=%d", req->nodeId);
- if(DihSwitchReplicaReq::getAllTables(requestInfo))
- fprintf(output, " All Tables");
- else
- fprintf(output, " TableId=%d", req->tableId);
-
- if(DihSwitchReplicaReq::getDistribute(requestInfo))
- fprintf(output, " Distribute");
- fprintf(output, "\n");
- return true;
- }
- break;
- default:
- fprintf(output, " Unknown request type:\n");
- }
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp b/storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp
deleted file mode 100644
index 5fe3d62c22a..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/DisconnectRep.hpp>
-
-bool
-printDISCONNECT_REP(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const DisconnectRep * const sig = (DisconnectRep *) theData;
-
- fprintf(output, " NodeId: %d, ErrorCode: %d\n",
- sig->nodeId, sig->err);
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DropIndx.cpp b/storage/ndb/src/common/debugger/signaldata/DropIndx.cpp
deleted file mode 100644
index 3c2dd03aafc..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DropIndx.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/DropIndx.hpp>
-
-bool printDROP_INDX_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const DropIndxReq * const sig = (DropIndxReq *) theData;
-
- return false;
-}
-
-bool printDROP_INDX_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const DropIndxConf * const sig = (DropIndxConf *) theData;
-
- return false;
-}
-
-bool printDROP_INDX_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
-// const DropIndxRef * const sig = (DropIndxRef *) theData;
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DropTab.cpp b/storage/ndb/src/common/debugger/signaldata/DropTab.cpp
deleted file mode 100644
index 0666c6ae5c9..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DropTab.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/DropTab.hpp>
-
-bool
-printDROP_TAB_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTabReq * const sig = (DropTabReq *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d requestType: %d\n",
- sig->senderRef, sig->senderData, sig->tableId, sig->requestType);
- return true;
-}
-
-bool printDROP_TAB_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTabConf * const sig = (DropTabConf *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d\n",
- sig->senderRef, sig->senderData, sig->tableId);
-
- return true;
-}
-
-bool printDROP_TAB_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTabRef * const sig = (DropTabRef *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d errorCode: %d\n",
- sig->senderRef, sig->senderData, sig->tableId, sig->errorCode);
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/DropTrig.cpp b/storage/ndb/src/common/debugger/signaldata/DropTrig.cpp
deleted file mode 100644
index 6127d7c8d7a..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/DropTrig.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/DropTrig.hpp>
-
-bool printDROP_TRIG_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTrigReq * const sig = (DropTrigReq *) theData;
-
- //char triggerName[MAX_TAB_NAME_SIZE];
- //char triggerType[32];
- //char triggerActionTime[32];
- //char triggerEvent[32];
-
- //sig->getTriggerName((char *) &triggerName);
- //switch(sig->getTriggerType()) {
- //case(TriggerType::SECONDARY_INDEX):
- //strcpy(triggerType, "SECONDARY_INDEX");
- //break;
- //case(TriggerType::SUBSCRIPTION):
- //strcpy(triggerType, "SUBSCRIPTION");
- //break;
- //default:
- //strcpy(triggerType, "UNSUPPORTED");
- //}
- //strcpy(triggerActionTime,
- //(sig->getTriggerActionTime() == TriggerActionTime::BEFORE)?
- //"BEFORE":"AFTER");
- //switch(sig->getTriggerEvent()) {
- //case (TriggerEvent::TE_INSERT):
- //strcpy(triggerEvent, "INSERT");
- //break;
- //case(TriggerEvent::TE_DELETE):
- //strcpy(triggerEvent, "DELETE");
- //break;
- //case(TriggerEvent::TE_UPDATE):
- //strcpy(triggerEvent, "UPDATE");
- //break;
- //}
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- //fprintf(output, "Trigger name: \"%s\"\n", triggerName);
- //fprintf(output, "Type: %s, ", triggerType);
- //fprintf(output, "Action: %s, ", triggerActionTime);
- //fprintf(output, "Event: %s, ", triggerEvent);
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printDROP_TRIG_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTrigConf * const sig = (DropTrigConf *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "\n");
-
- return false;
-}
-
-bool printDROP_TRIG_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const DropTrigRef * const sig = (DropTrigRef *) theData;
-
- fprintf(output, "User: %u, ", sig->getUserRef());
- fprintf(output, "Trigger id: %u, ", sig->getTriggerId());
- fprintf(output, "Table id: %u, ", sig->getTableId());
- fprintf(output, "Error code: %u, ", sig->getErrorCode());
- fprintf(output, "\n");
-
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FailRep.cpp b/storage/ndb/src/common/debugger/signaldata/FailRep.cpp
deleted file mode 100644
index f5f053d8ddb..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FailRep.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FailRep.hpp>
-
-bool
-printFAIL_REP(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const FailRep * const sig = (FailRep *) theData;
-
- fprintf(output, " FailedNode: %d, FailCause: %d\n",
- sig->failNodeId, sig->failCause);
-
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp b/storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp
deleted file mode 100644
index 8584003a601..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/FireTrigOrd.hpp>
-#include <RefConvert.hpp>
-
-static
-const char *
-trigEvent(Uint32 i){
- switch(i){
- case TriggerEvent::TE_INSERT:
- return "insert";
- break;
- case TriggerEvent::TE_UPDATE:
- return "update";
- break;
- case TriggerEvent::TE_DELETE:
- return "delete";
- break;
- }
- return "UNKNOWN";
-}
-
-bool
-printFIRE_TRIG_ORD(FILE * output, const Uint32 * theData, Uint32 len,
- Uint16 receiverBlockNo)
-{
- const FireTrigOrd * const sig = (FireTrigOrd *) theData;
-
- fprintf(output, " TriggerId: %d TriggerEvent: %s\n",
- sig->getTriggerId(),
- trigEvent(sig->getTriggerEvent()));
- fprintf(output, " UserRef: (%d, %d) User data: %x\n",
- refToNode(sig->getUserRef()),
- refToBlock(sig->getUserRef()),
- sig->getConnectionPtr());
- fprintf(output, " Signal: PK=%d BEFORE=%d AFTER=%d\n",
- sig->getNoOfPrimaryKeyWords(),
- sig->getNoOfBeforeValueWords(),
- sig->getNoOfAfterValueWords());
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp b/storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp
deleted file mode 100644
index ea00573afbf..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsAppendReq.hpp>
-
-bool
-printFSAPPENDREQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- bool ret = true;
-
- const FsAppendReq * const sig = (FsAppendReq *) theData;
-
- fprintf(output, " FilePointer: %d\n", sig->filePointer);
- fprintf(output, " UserReference: H\'%.8x, UserPointer: H\'%.8x\n",
- sig->userReference, sig->userPointer);
-
- fprintf(output, " varIndex: %d offset: %d size: %d\n",
- sig->varIndex,
- sig->offset,
- sig->size);
- return ret;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp b/storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp
deleted file mode 100644
index 44ae70096fa..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsCloseReq.hpp>
-
-bool
-printFSCLOSEREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const FsCloseReq * const sig = (FsCloseReq *) theData;
-
- fprintf(output, " UserPointer: %d\n",
- sig->userPointer);
- fprintf(output, " FilePointer: %d\n",
- sig->filePointer);
- fprintf(output, " UserReference: H\'%.8x\n",
- sig->userReference);
-
- fprintf(output, " Flags: H\'%.8x, ", sig->fileFlag);
- if (sig->getRemoveFileFlag(sig->fileFlag))
- fprintf(output, "Remove file");
- else
- fprintf(output, "Don't remove file");
- fprintf(output, "\n");
-
- return len == 4;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsConf.cpp b/storage/ndb/src/common/debugger/signaldata/FsConf.cpp
deleted file mode 100644
index 338920dffb6..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsConf.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsConf.hpp>
-
-bool
-printFSCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const FsConf * const sig = (FsConf *) theData;
-
- fprintf(output, " UserPointer: %d\n", sig->userPointer);
-
- if (len > 1){
- // Only valid if this is a FSOPENCONF
- fprintf(output, " FilePointer: %d\n", sig->filePointer);
- }
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp b/storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp
deleted file mode 100644
index 4c270fee211..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsOpenReq.hpp>
-
-bool
-printFSOPENREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const FsOpenReq * const sig = (FsOpenReq *) theData;
-
-
- fprintf(output, " UserReference: H\'%.8x, userPointer: H\'%.8x\n",
- sig->userReference, sig->userPointer);
- fprintf(output, " FileNumber[1-4]: H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
- sig->fileNumber[0], sig->fileNumber[1], sig->fileNumber[2], sig->fileNumber[3]);
- fprintf(output, " FileFlags: H\'%.8x ",
- sig->fileFlags);
-
- // File open mode must be one of ReadOnly, WriteOnly or ReadWrite
- const Uint32 flags = sig->fileFlags;
- switch(flags & 3){
- case FsOpenReq::OM_READONLY:
- fprintf(output, "Open read only");
- break;
- case FsOpenReq::OM_WRITEONLY:
- fprintf(output, "Open write only");
- break;
- case FsOpenReq::OM_READWRITE:
- fprintf(output, "Open read and write");
- break;
- default:
- fprintf(output, "Open mode unknown!");
- }
-
- if (flags & FsOpenReq::OM_CREATE)
- fprintf(output, ", Create new file");
- if (flags & FsOpenReq::OM_TRUNCATE)
- fprintf(output, ", Truncate existing file");
- if (flags & FsOpenReq::OM_APPEND)
- fprintf(output, ", Append");
-
- fprintf(output, "\n");
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp b/storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp
deleted file mode 100644
index b146b150baf..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsReadWriteReq.hpp>
-
-bool
-printFSREADWRITEREQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- bool ret = true;
-
- const FsReadWriteReq * const sig = (FsReadWriteReq *) theData;
-
- fprintf(output, " UserPointer: %d\n", sig->userPointer);
- fprintf(output, " FilePointer: %d\n", sig->filePointer);
- fprintf(output, " UserReference: H\'%.8x", sig->userReference);
-
- fprintf(output, " Operation flag: H\'%.8x (", sig->operationFlag);
- if (sig->getSyncFlag(sig->operationFlag))
- fprintf(output, "Sync,");
- else
- fprintf(output, "No sync,");
-
- fprintf(output, " Format=");
- switch(sig->getFormatFlag(sig->operationFlag)){
- case FsReadWriteReq::fsFormatListOfPairs:
- fprintf(output, "List of pairs)\n");
- break;
- case FsReadWriteReq::fsFormatArrayOfPages:
- fprintf(output, "Array of pages)\n");
- break;
- case FsReadWriteReq::fsFormatListOfMemPages:
- fprintf(output, "List of mem pages)\n");
- break;
- case FsReadWriteReq::fsFormatGlobalPage:
- fprintf(output, "List of global pages)\n");
- case FsReadWriteReq::fsFormatSharedPage:
- fprintf(output, "List of shared pages)\n");
- break;
- default:
- fprintf(output, "fsFormatMax not handled\n");
- ret = false;
- break;
- }
-
- fprintf(output, " varIndex: %d\n",
- sig->varIndex);
- fprintf(output, " numberOfPages: %d\n",
- sig->numberOfPages);
- fprintf(output, " pageData: ");
-
- unsigned int i;
- switch(sig->getFormatFlag(sig->operationFlag)){
- case FsReadWriteReq::fsFormatListOfPairs:
- for (i= 0; i < sig->numberOfPages*2; i += 2){
- fprintf(output, " H\'%.8x, H\'%.8x\n", sig->data.pageData[i],
- sig->data.pageData[i + 1]);
- }
- break;
- case FsReadWriteReq::fsFormatArrayOfPages:
- fprintf(output, " H\'%.8x, H\'%.8x\n", sig->data.pageData[0],
- sig->data.pageData[1]);
- break;
- case FsReadWriteReq::fsFormatListOfMemPages:
- for (i= 0; i < (sig->numberOfPages + 1); i++){
- fprintf(output, " H\'%.8x, ", sig->data.pageData[i]);
- }
- break;
- case FsReadWriteReq::fsFormatGlobalPage:
- for (i= 0; i < sig->numberOfPages; i++){
- fprintf(output, " H\'%.8x, ", sig->data.pageData[i]);
- }
- break;
- default:
- fprintf(output, "Impossible event\n");
- }
-
- fprintf(output, "\n");
- return ret;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/FsRef.cpp b/storage/ndb/src/common/debugger/signaldata/FsRef.cpp
deleted file mode 100644
index de48b36855e..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/FsRef.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/FsRef.hpp>
-
-bool
-printFSREF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- bool ret = true;
-
- const FsRef * const sig = (FsRef *) theData;
-
- fprintf(output, " UserPointer: %d\n",
- sig->userPointer);
-
- fprintf(output, " ErrorCode: %d, ", sig->errorCode);
- ndbd_exit_classification cl;
- switch (sig->getErrorCode(sig->errorCode)){
- case FsRef::fsErrNone:
- fprintf(output, "No error");
- break;
- default:
- fprintf(output, ndbd_exit_message(sig->getErrorCode(sig->errorCode), &cl));
- break;
- }
- fprintf(output, "\n");
- fprintf(output, " OS ErrorCode: %d \n", sig->osErrorCode);
-
- return ret;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/GCPSave.cpp b/storage/ndb/src/common/debugger/signaldata/GCPSave.cpp
deleted file mode 100644
index c0a13acf783..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/GCPSave.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/GCPSave.hpp>
-#include <RefConvert.hpp>
-
-bool
-printGCPSaveReq(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 receiverBlockNo){
-
- GCPSaveReq * sr = (GCPSaveReq*)theData;
-
- fprintf(output, " dihBlockRef = (%d, %d) dihPtr = %d gci = %d\n",
- refToBlock(sr->dihBlockRef), refToNode(sr->dihBlockRef),
- sr->dihPtr, sr->gci);
-
- return true;
-}
-
-bool
-printGCPSaveRef(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 receiverBlockNo){
-
- GCPSaveRef * sr = (GCPSaveRef*)theData;
-
- fprintf(output, " nodeId = %d dihPtr = %d gci = %d reason: ",
- sr->nodeId,
- sr->dihPtr, sr->gci);
-
- switch(sr->errorCode){
- case GCPSaveRef::NodeShutdownInProgress:
- fprintf(output, "NodeShutdownInProgress\n");
- break;
- case GCPSaveRef::FakedSignalDueToNodeFailure:
- fprintf(output, "FakedSignalDueToNodeFailure\n");
- break;
- default:
- fprintf(output, "Unknown reason: %d\n", sr->errorCode);
- return false;
- }
-
- return true;
-}
-
-bool
-printGCPSaveConf(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 receiverBlockNo){
-
- GCPSaveConf * sr = (GCPSaveConf*)theData;
-
- fprintf(output, " nodeId = %d dihPtr = %d gci = %d\n",
- sr->nodeId,
- sr->dihPtr, sr->gci);
-
- return true;
-}
-
-
diff --git a/storage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp b/storage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp
deleted file mode 100755
index 39197fae04a..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/IndxAttrInfo.hpp>
-
-bool
-printINDXATTRINFO(FILE * output, const Uint32 * theData, Uint32 len,
- Uint16 receiverBlockNo)
-{
-// const IndxAttrInfo * const sig = (IndxAttrInfo *) theData;
-
- Uint32 i = 0;
- while (i < len)
- fprintf(output, " H\'%.8x", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp b/storage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp
deleted file mode 100755
index 24abc4e9a1d..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/IndxKeyInfo.hpp>
-
-bool
-printINDXKEYINFO(FILE * output, const Uint32 * theData, Uint32 len,
- Uint16 receiverBlockNo)
-{
-// const IndxKeyInfo * const sig = (IndxKeyInfo *) theData;
-
- Uint32 i = 0;
- while (i < len)
- fprintf(output, " H\'%.8x", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/LCP.cpp b/storage/ndb/src/common/debugger/signaldata/LCP.cpp
deleted file mode 100644
index 7c39322cdf0..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/LCP.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <RefConvert.hpp>
-#include <signaldata/LCP.hpp>
-#include <DebuggerNames.hpp>
-
-bool
-printSTART_LCP_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- const StartLcpReq * const sig = (StartLcpReq *) theData;
-
- char buf1[8*_NDB_NODE_BITMASK_SIZE+1];
- char buf2[8*_NDB_NODE_BITMASK_SIZE+1];
- fprintf(output,
- " Sender: %d LcpId: %d\n"
- " ParticipatingDIH = %s\n"
- " ParticipatingLQH = %s\n",
- refToNode(sig->senderRef), sig->lcpId,
- sig->participatingDIH.getText(buf1),
- sig->participatingLQH.getText(buf2));
-
- return true;
-}
-
-bool
-printSTART_LCP_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- const StartLcpConf * const sig = (StartLcpConf *) theData;
-
- fprintf(output, " Sender: %d LcpId: %d\n",
- refToNode(sig->senderRef), sig->lcpId);
-
- return true;
-}
-
-bool
-printLCP_FRAG_ORD(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- const LcpFragOrd * const sig = (LcpFragOrd *) theData;
-
- fprintf(output, " LcpId: %d LcpNo: %d Table: %d Fragment: %d\n",
- sig->lcpId, sig->lcpNo, sig->tableId, sig->fragmentId);
-
- fprintf(output, " KeepGCI: %d LastFragmentFlag: %d\n",
- sig->keepGci, sig->lastFragmentFlag);
- return true;
-}
-
-bool
-printLCP_FRAG_REP(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- const LcpFragRep * const sig = (LcpFragRep *) theData;
-
- fprintf(output, " LcpId: %d LcpNo: %d NodeId: %d Table: %d Fragment: %d\n",
- sig->lcpId, sig->lcpNo, sig->nodeId, sig->tableId, sig->fragId);
- fprintf(output, " Max GCI Started: %d Max GCI Completed: %d\n",
- sig->maxGciStarted, sig->maxGciCompleted);
- return true;
-}
-
-bool
-printLCP_COMPLETE_REP(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo){
-
- const LcpCompleteRep * const sig = (LcpCompleteRep *) theData;
-
- fprintf(output, " LcpId: %d NodeId: %d Block: %s\n",
- sig->lcpId, sig->nodeId, getBlockName(sig->blockNo));
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp b/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp
deleted file mode 100644
index 94d83a58d61..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/LqhFrag.hpp>
-
-bool
-printLQH_FRAG_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 recB){
- LqhFragReq* sig = (LqhFragReq*)theData;
-
- fprintf(output, " senderData: %d senderRef: %x",
- sig->senderData, sig->senderRef);
- fprintf(output, " tableId: %d fragmentId: %d tableType: %d",
- sig->tableId, sig->fragmentId, sig->tableType);
- if (sig->primaryTableId == RNIL)
- fprintf(output, " primaryTableId: RNIL\n");
- else
- fprintf(output, " primaryTableId: %d\n", sig->primaryTableId);
- fprintf(output, " localKeyLength: %d maxLoadFactor: %d minLoadFactor: %d\n",
- sig->localKeyLength, sig->maxLoadFactor, sig->minLoadFactor);
- fprintf(output, " kValue: %d lh3DistrBits: %d lh3PageBits: %d\n",
- sig->kValue, sig->lh3DistrBits, sig->lh3PageBits);
-
- fprintf(output, " noOfAttributes: %d noOfNullAttributes: %d keyLength: %d\n",
- sig->noOfAttributes, sig->noOfNullAttributes, sig->keyLength);
-
- fprintf(output, " maxRowsLow/High: %u/%u minRowsLow/High: %u/%u\n",
- sig->maxRowsLow, sig->maxRowsHigh, sig->minRowsLow, sig->minRowsHigh);
- fprintf(output, " schemaVersion: %d nextLCP: %d\n",
- sig->schemaVersion, sig->nextLCP);
-
- return true;
-}
-bool
-printLQH_FRAG_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec){
- LqhFragConf* sig = (LqhFragConf*)theData;
-
- fprintf(output, " senderData: %d lqhFragPtr: %d\n",
- sig->senderData, sig->lqhFragPtr);
- return true;
-}
-
-bool
-printLQH_FRAG_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec){
- LqhFragRef* sig = (LqhFragRef*)theData;
-
- fprintf(output, " senderData: %d errorCode: %d\n",
- sig->senderData, sig->errorCode);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/LqhKey.cpp b/storage/ndb/src/common/debugger/signaldata/LqhKey.cpp
deleted file mode 100644
index 9db9d47d6ac..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/LqhKey.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/LqhKey.hpp>
-
-bool
-printLQHKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const LqhKeyReq * const sig = (LqhKeyReq *) theData;
-
- fprintf(output,
- " ClientPtr = H\'%.8x hashValue = H\'%.8x tcBlockRef = H\'%.8x\n"
- " transId1 = H\'%.8x transId2 = H\'%.8x savePointId = H\'%.8x\n",
- sig->clientConnectPtr, // DATA 0
- sig->hashValue, // DATA 2
- sig->tcBlockref, // DATA 4
- sig->transId1, // DATA 7
- sig->transId2, // DATA 8
- sig->savePointId // DATA 9
- );
-
- const Uint32 reqInfo = sig->requestInfo;
- const Uint32 attrLen = sig->attrLen;
-
- fprintf(output,
- " Op: %d Lock: %d Flags: ",
- LqhKeyReq::getOperation(reqInfo),
- LqhKeyReq::getLockType(reqInfo));
- if(LqhKeyReq::getSimpleFlag(reqInfo))
- fprintf(output, "Simple ");
- if(LqhKeyReq::getDirtyFlag(reqInfo))
- fprintf(output, "Dirty ");
- if(LqhKeyReq::getInterpretedFlag(reqInfo))
- fprintf(output, "Interpreted ");
- if(LqhKeyReq::getScanTakeOverFlag(attrLen))
- fprintf(output, "ScanTakeOver ");
- if(LqhKeyReq::getMarkerFlag(reqInfo))
- fprintf(output, "CommitAckMarker ");
- if(LqhKeyReq::getNoDiskFlag(reqInfo))
- fprintf(output, "NoDisk ");
- if(LqhKeyReq::getRowidFlag(reqInfo))
- fprintf(output, "Rowid ");
- if(LqhKeyReq::getNrCopyFlag(reqInfo))
- fprintf(output, "NrCopy ");
- if(LqhKeyReq::getGCIFlag(reqInfo))
- fprintf(output, "GCI ");
-
- fprintf(output, "ScanInfo/noFiredTriggers: H\'%x\n", sig->scanInfo);
-
- fprintf(output,
- " AttrLen: %d (%d in this) KeyLen: %d TableId: %d SchemaVer: %d\n",
- LqhKeyReq::getAttrLen(attrLen),
- LqhKeyReq::getAIInLqhKeyReq(reqInfo),
- LqhKeyReq::getKeyLen(reqInfo),
- LqhKeyReq::getTableId(sig->tableSchemaVersion),
- LqhKeyReq::getSchemaVersion(sig->tableSchemaVersion));
-
- fprintf(output,
- " FragId: %d ReplicaNo: %d LastReplica: %d NextNodeId: %d\n",
- LqhKeyReq::getFragmentId(sig->fragmentData),
- LqhKeyReq::getSeqNoReplica(reqInfo),
- LqhKeyReq::getLastReplicaNo(reqInfo),
- LqhKeyReq::getNextReplicaNodeId(sig->fragmentData));
-
- bool printed = false;
- Uint32 nextPos = LqhKeyReq::getApplicationAddressFlag(reqInfo) << 1;
- if(nextPos != 0){
- fprintf(output,
- " ApiRef: H\'%.8x ApiOpRef: H\'%.8x",
- sig->variableData[0],
- sig->variableData[1]);
- printed = true;
- }
-
- if(LqhKeyReq::getSameClientAndTcFlag(reqInfo)){
- fprintf(output, " TcOpRec: H\'%.8x", sig->variableData[nextPos]);
- nextPos++;
- printed = true;
- }
-
- Uint32 tmp = LqhKeyReq::getLastReplicaNo(reqInfo) -
- LqhKeyReq::getSeqNoReplica(reqInfo);
- if(tmp > 1){
- NodeId node2 = sig->variableData[nextPos] & 0xffff;
- NodeId node3 = sig->variableData[nextPos] >> 16;
- fprintf(output, " NextNodeId2: %d NextNodeId3: %d",
- node2, node3);
- nextPos ++;
- printed = true;
- }
- if(printed)
- fprintf(output, "\n");
-
- printed = false;
- if(LqhKeyReq::getStoredProcFlag(attrLen)){
- fprintf(output, " StoredProcId: %d", sig->variableData[nextPos]);
- nextPos++;
- printed = true;
- }
-
- if(LqhKeyReq::getReturnedReadLenAIFlag(reqInfo)){
- fprintf(output, " ReturnedReadLenAI: %d",
- sig->variableData[nextPos]);
- nextPos++;
- printed = true;
- }
-
- const UintR keyLen = LqhKeyReq::getKeyLen(reqInfo);
- if(keyLen > 0){
- fprintf(output, " KeyInfo: ");
- for(UintR i = 0; i<keyLen && i<4; i++, nextPos++)
- fprintf(output, "H\'%.8x ", sig->variableData[nextPos]);
- fprintf(output, "\n");
- }
-
- if (LqhKeyReq::getRowidFlag(reqInfo))
- {
- fprintf(output, " Rowid: [ page: %d idx: %d ]\n",
- sig->variableData[nextPos + 0],
- sig->variableData[nextPos + 1]);
- nextPos += 2;
- }
-
- if (LqhKeyReq::getGCIFlag(reqInfo))
- {
- fprintf(output, " GCI: %u", sig->variableData[nextPos + 0]);
- nextPos++;
- }
-
- if(!LqhKeyReq::getInterpretedFlag(reqInfo)){
- fprintf(output, " AttrInfo: ");
- for(int i = 0; i<LqhKeyReq::getAIInLqhKeyReq(reqInfo); i++, nextPos++)
- fprintf(output, "H\'%.8x ", sig->variableData[nextPos]);
- fprintf(output, "\n");
- } else {
- fprintf(output, " InitialReadSize: %d InterpretedSize: %d "
- "FinalUpdateSize: %d FinalReadSize: %d SubroutineSize: %d\n",
- sig->variableData[nextPos+0], sig->variableData[nextPos+1],
- sig->variableData[nextPos+2], sig->variableData[nextPos+3],
- sig->variableData[nextPos+4]);
- nextPos += 5;
- }
- return true;
-}
-
-bool
-printLQHKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-// const LqhKeyConf * const sig = (LqhKeyConf *) theData;
-
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
-
-bool
-printLQHKEYREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-// const LqhKeyRef * const sig = (LqhKeyRef *) theData;
-
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp b/storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp
deleted file mode 100644
index 5f72b6a056d..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/LqhTransConf.hpp>
-
-bool
-printLQH_TRANSCONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const LqhTransConf * const sig = (LqhTransConf *)theData;
- fprintf(output, " tcRef: %x\n", sig->tcRef);
- fprintf(output, " lqhNodeId: %x\n", sig->lqhNodeId);
- fprintf(output, " operationStatus: %x\n", sig->operationStatus);
- fprintf(output, " transId1: %x\n", sig->transId1);
- fprintf(output, " transId2: %x\n", sig->transId2);
- fprintf(output, " apiRef: %x\n", sig->apiRef);
- fprintf(output, " apiOpRec: %x\n", sig->apiOpRec);
- fprintf(output, " lqhConnectPtr: %x\n", sig->lqhConnectPtr);
- fprintf(output, " oldTcOpRec: %x\n", sig->oldTcOpRec);
- fprintf(output, " requestInfo: %x\n", sig->requestInfo);
- fprintf(output, " gci: %x\n", sig->gci);
- fprintf(output, " nextNodeId1: %x\n", sig->nextNodeId1);
- fprintf(output, " nextNodeId2: %x\n", sig->nextNodeId2);
- fprintf(output, " nextNodeId3: %x\n", sig->nextNodeId3);
- fprintf(output, " tableId: %x\n", sig->tableId);
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/Makefile.am b/storage/ndb/src/common/debugger/signaldata/Makefile.am
deleted file mode 100644
index b6d7dd6736d..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/Makefile.am
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libsignaldataprint.la
-
-libsignaldataprint_la_SOURCES = \
- TcKeyReq.cpp TcKeyConf.cpp TcKeyRef.cpp \
- TcRollbackRep.cpp \
- TupKey.cpp TupCommit.cpp LqhKey.cpp \
- FsOpenReq.cpp FsCloseReq.cpp FsRef.cpp FsConf.cpp FsReadWriteReq.cpp\
- SignalDataPrint.cpp SignalNames.cpp \
- ContinueB.cpp DihContinueB.cpp NdbfsContinueB.cpp \
- CloseComReqConf.cpp PackedSignal.cpp PrepFailReqRef.cpp \
- GCPSave.cpp DictTabInfo.cpp \
- AlterTable.cpp AlterTab.cpp \
- CreateTrig.cpp AlterTrig.cpp DropTrig.cpp \
- FireTrigOrd.cpp TrigAttrInfo.cpp \
- CreateIndx.cpp AlterIndx.cpp DropIndx.cpp TcIndx.cpp \
- IndxKeyInfo.cpp IndxAttrInfo.cpp \
- FsAppendReq.cpp ScanTab.cpp \
- BackupImpl.cpp BackupSignalData.cpp \
- UtilSequence.cpp UtilPrepare.cpp UtilDelete.cpp UtilExecute.cpp \
- LqhFrag.cpp DropTab.cpp PrepDropTab.cpp LCP.cpp MasterLCP.cpp \
- CopyGCI.cpp SystemError.cpp StartRec.cpp NFCompleteRep.cpp \
- FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \
- SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \
- UtilLock.cpp TuxMaint.cpp AccLock.cpp \
- LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp \
- ScanFrag.cpp
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-
-windoze-dsp: libsignaldataprint.dsp
-
-libsignaldataprint.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libsignaldataprint_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp b/storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp
deleted file mode 100644
index 77f348a63e0..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/MasterLCP.hpp>
-#include <RefConvert.hpp>
-
-static
-void
-print(char *buf, size_t buf_len, MasterLCPConf::State s){
- switch(s){
- case MasterLCPConf::LCP_STATUS_IDLE:
- BaseString::snprintf(buf, buf_len, "LCP_STATUS_IDLE");
- break;
- case MasterLCPConf::LCP_STATUS_ACTIVE:
- BaseString::snprintf(buf, buf_len, "LCP_STATUS_ACTIVE");
- break;
- case MasterLCPConf::LCP_TAB_COMPLETED:
- BaseString::snprintf(buf, buf_len, "LCP_TAB_COMPLETED");
- break;
- case MasterLCPConf::LCP_TAB_SAVED:
- BaseString::snprintf(buf, buf_len, "LCP_TAB_SAVED");
- break;
- }
-}
-
-NdbOut &
-operator<<(NdbOut& out, const MasterLCPConf::State& s){
- static char buf[255];
- print(buf, sizeof(buf), s);
- out << buf;
- return out;
-}
-
-bool
-printMASTER_LCP_CONF(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
-
- MasterLCPConf * sig = (MasterLCPConf *)&theData[0];
-
- static char buf[255];
- print(buf, sizeof(buf), (MasterLCPConf::State)sig->lcpState);
- fprintf(output, " senderNode=%d failedNode=%d SenderState=%s\n",
- sig->senderNodeId, sig->failedNodeId, buf);
- return true;
-}
-
-bool
-printMASTER_LCP_REQ(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
-
- MasterLCPReq * sig = (MasterLCPReq *)&theData[0];
-
- fprintf(output, " masterRef=(node=%d, block=%d), failedNode=%d\n",
- refToNode(sig->masterRef), refToBlock(sig->masterRef),
- sig->failedNodeId);
- return true;
-}
-
-bool
-printMASTER_LCP_REF(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
-
- MasterLCPRef * sig = (MasterLCPRef *)&theData[0];
- fprintf(output, " senderNode=%d failedNode=%d\n",
- sig->senderNodeId, sig->failedNodeId);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp b/storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp
deleted file mode 100644
index 74735546320..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <DebuggerNames.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-
-bool
-printNF_COMPLETE_REP(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
-
- NFCompleteRep * sig = (NFCompleteRep*)theData;
- const char * who = getBlockName(sig->blockNo, 0);
-
- if(who == 0){
- fprintf(output,
- " Node: %d has completed failure of node %d\n",
- sig->nodeId, sig->failedNodeId);
- } else {
- fprintf(output,
- " Node: %d block: %s has completed failure of node %d\n",
- sig->nodeId, who, sig->failedNodeId);
- }
-
- fprintf(output, "Sent from line: %d\n",
- sig->from);
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp b/storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp
deleted file mode 100644
index 480ee078d2e..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/NdbSttor.hpp>
-
-bool
-printNDB_STTOR(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const NdbSttor * const sig = (NdbSttor *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- fprintf(output, " nodeId: %x\n", sig->nodeId);
- fprintf(output, " internalStartPhase: %x\n", sig->internalStartPhase);
- fprintf(output, " typeOfStart: %x\n", sig->typeOfStart);
- fprintf(output, " masterNodeId: %x\n", sig->masterNodeId);
-
- int left = len - NdbSttor::SignalLength;
- if(left > 0){
- fprintf(output, " config: ");
- for(int i = 0; i<left; i++){
- fprintf(output, "%x ", sig->config[i]);
- if(((i + 1) % 7) == 0 && (i+1) < left){
- fprintf(output, "\n config: ");
- }
- }
- fprintf(output, "\n");
- }
- return true;
-}
-
-bool
-printNDB_STTORRY(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const NdbSttorry * const sig = (NdbSttorry *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp b/storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp
deleted file mode 100644
index 190e755c731..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <signaldata/NdbfsContinueB.hpp>
-
-bool
-printCONTINUEB_NDBFS(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 not_used){
-
- (void)not_used;
-
- switch (theData[0]) {
- case NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY:
- fprintf(output, " Scanning the memory channel every 10ms\n");
- return true;
- break;
- case NdbfsContinueB::ZSCAN_MEMORYCHANNEL_NO_DELAY:
- fprintf(output, " Scanning the memory channel again with no delay\n");
- return true;
- break;
- default:
- fprintf(output, " Default system error lab...\n");
- return false;
- break;
- }//switch
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp b/storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp
deleted file mode 100644
index 62de2a04f08..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright (c) 2003, 2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/PackedSignal.hpp>
-#include <signaldata/LqhKey.hpp>
-#include <debugger/DebuggerNames.hpp>
-
-bool
-printPACKED_SIGNAL(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- fprintf(output, "--------- Begin Packed Signals --------\n");
- // Print each signal separately
- for (i = 0; i < len;) {
- switch (PackedSignal::getSignalType(theData[i])) {
- case ZCOMMIT: {
- Uint32 signalLength = 4;
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"COMMIT\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- fprintf(output, "Signal data: ");
- for(Uint32 j = 0; j < signalLength; j++)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- break;
- }
- case ZCOMPLETE: {
- Uint32 signalLength = 3;
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"COMPLETE\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- fprintf(output, "Signal data: ");
- for(Uint32 j = 0; j < signalLength; j++)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- break;
- }
- case ZCOMMITTED: {
- Uint32 signalLength = 3;
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"COMMITTED\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- fprintf(output, "Signal data: ");
- for(Uint32 j = 0; j < signalLength; j++)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- break;
- }
- case ZCOMPLETED: {
- Uint32 signalLength = 3;
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"COMPLETED\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- fprintf(output, "Signal data: ");
- for(Uint32 j = 0; j < signalLength; j++)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- break;
- }
- case ZLQHKEYCONF: {
- Uint32 signalLength = LqhKeyConf::SignalLength;
-
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"LQHKEYCONF\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- printLQHKEYCONF(output, theData + i, signalLength, receiverBlockNo);
- i += signalLength;
- break;
- }
- case ZREMOVE_MARKER: {
- Uint32 signalLength = 2;
- fprintf(output, "--------------- Signal ----------------\n");
- fprintf(output, "r.bn: %u \"%s\", length: %u \"REMOVE_MARKER\"\n",
- receiverBlockNo, getBlockName(receiverBlockNo,""), signalLength);
- fprintf(output, "Signal data: ");
- i++; // Skip first word!
- for(Uint32 j = 0; j < signalLength; j++)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- break;
- }
- default:
- fprintf(output, "Unknown signal type\n");
- i = len; // terminate printing
- break;
- }
- }//for
- fprintf(output, "--------- End Packed Signals ----------\n");
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp b/storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp
deleted file mode 100644
index df2f3323795..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/PrepDropTab.hpp>
-
-bool
-printPREP_DROP_TAB_REQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const PrepDropTabReq * const sig = (PrepDropTabReq *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d\n",
- sig->senderRef, sig->senderData, sig->tableId);
- return true;
-}
-
-bool printPREP_DROP_TAB_CONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const PrepDropTabConf * const sig = (PrepDropTabConf *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d\n",
- sig->senderRef, sig->senderData, sig->tableId);
-
- return true;
-}
-
-bool printPREP_DROP_TAB_REF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo)
-{
- const PrepDropTabRef * const sig = (PrepDropTabRef *) theData;
-
- fprintf(output,
- " senderRef: %x senderData: %d TableId: %d errorCode: %d\n",
- sig->senderRef, sig->senderData, sig->tableId, sig->errorCode);
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp b/storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp
deleted file mode 100644
index cf4afae6bc2..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <kernel_types.h>
-#include <BlockNumbers.h>
-#include <signaldata/PrepFailReqRef.hpp>
-
-bool
-printPREPFAILREQREF(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 receiverBlockNo){
-
- PrepFailReqRef * cc = (PrepFailReqRef*)theData;
-
- fprintf(output, " xxxBlockRef = (%d, %d) failNo = %d noOfNodes = %d\n",
- refToBlock(cc->xxxBlockRef), refToNode(cc->xxxBlockRef),
- cc->failNo, cc->noOfNodes);
-
- int hits = 0;
- fprintf(output, " Nodes: ");
- for(int i = 0; i<MAX_NODES; i++){
- if(NodeBitmask::get(cc->theNodes, i)){
- hits++;
- fprintf(output, " %d", i);
- }
- if(hits == 16){
- fprintf(output, "\n Nodes: ");
- hits = 0;
- }
- }
- if(hits != 0)
- fprintf(output, "\n");
-
- return true;
-}
-
-
diff --git a/storage/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp b/storage/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp
deleted file mode 100644
index 6457e2795c9..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#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/storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp b/storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp
deleted file mode 100644
index f4a63dbdf0c..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <BlockNumbers.h>
-#include <signaldata/ScanTab.hpp>
-#include <signaldata/ScanFrag.hpp>
-
-bool
-printSCAN_FRAGREQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const ScanFragReq * const sig = (ScanFragReq *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " resultRef: %x\n", sig->resultRef);
- fprintf(output, " savePointId: %x\n", sig->savePointId);
- fprintf(output, " requestInfo: %x\n", sig->requestInfo);
- fprintf(output, " tableId: %x\n", sig->tableId);
- fprintf(output, " fragmentNo: %x\n", sig->fragmentNoKeyLen & 0xFFFF);
- fprintf(output, " keyLen: %x\n", sig->fragmentNoKeyLen >> 16);
- fprintf(output, " schemaVersion: %x\n", sig->schemaVersion);
- fprintf(output, " transId1: %x\n", sig->transId1);
- fprintf(output, " transId2: %x\n", sig->transId2);
- fprintf(output, " clientOpPtr: %x\n", sig->clientOpPtr);
- fprintf(output, " batch_size_rows: %x\n", sig->batch_size_rows);
- fprintf(output, " batch_size_bytes: %x\n", sig->batch_size_bytes);
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/ScanTab.cpp b/storage/ndb/src/common/debugger/signaldata/ScanTab.cpp
deleted file mode 100644
index ca531c2863c..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/ScanTab.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright (c) 2003-2005, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <BlockNumbers.h>
-#include <signaldata/ScanTab.hpp>
-#include <signaldata/ScanFrag.hpp>
-
-bool
-printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const ScanTabReq * const sig = (ScanTabReq *) theData;
-
- const UintR requestInfo = sig->requestInfo;
-
- fprintf(output, " apiConnectPtr: H\'%.8x",
- sig->apiConnectPtr);
- fprintf(output, " requestInfo: H\'%.8x:\n", requestInfo);
- fprintf(output, " Parallellism: %u Batch: %u LockMode: %u Keyinfo: %u Holdlock: %u RangeScan: %u Descending: %u TupScan: %u\n ReadCommitted: %u DistributionKeyFlag: %u NoDisk: %u",
- sig->getParallelism(requestInfo),
- sig->getScanBatch(requestInfo),
- sig->getLockMode(requestInfo),
- sig->getKeyinfoFlag(requestInfo),
- sig->getHoldLockFlag(requestInfo),
- sig->getRangeScanFlag(requestInfo),
- sig->getDescendingFlag(requestInfo),
- sig->getTupScanFlag(requestInfo),
- sig->getReadCommittedFlag(requestInfo),
- sig->getDistributionKeyFlag(requestInfo),
- sig->getNoDiskFlag(requestInfo));
-
- if(sig->getDistributionKeyFlag(requestInfo))
- fprintf(output, " DKey: %x", sig->distributionKey);
-
- Uint32 keyLen = (sig->attrLenKeyLen >> 16);
- Uint32 attrLen = (sig->attrLenKeyLen & 0xFFFF);
- fprintf(output, " attrLen: %d, keyLen: %d tableId: %d, tableSchemaVer: %d\n",
- attrLen, keyLen, 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, " batch_byte_size: %d, first_batch_size: %d\n",
- sig->batch_byte_size, sig->first_batch_size);
- return false;
-}
-
-bool
-printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const ScanTabConf * const sig = (ScanTabConf *) theData;
-
- const UintR requestInfo = sig->requestInfo;
-
- fprintf(output, " apiConnectPtr: H\'%.8x\n",
- sig->apiConnectPtr);
- fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n",
- sig->transId1, sig->transId2);
-
- fprintf(output, " requestInfo: Eod: %d OpCount: %d\n",
- (requestInfo & ScanTabConf::EndOfData) == ScanTabConf::EndOfData,
- (requestInfo & (~ScanTabConf::EndOfData)));
- size_t op_count= requestInfo & (~ScanTabConf::EndOfData);
- if(op_count){
- fprintf(output, " Operation(s) [api tc rows len]:\n");
- ScanTabConf::OpData * op = (ScanTabConf::OpData*)
- (theData + ScanTabConf::SignalLength);
- for(size_t i = 0; i<op_count; i++){
- if(op->info != ScanTabConf::EndOfData)
- fprintf(output, " [0x%x 0x%x %d %d]",
- op->apiPtrI, op->tcPtrI,
- ScanTabConf::getRows(op->info),
- ScanTabConf::getLength(op->info));
- else
- fprintf(output, " [0x%x 0x%x eod]",
- op->apiPtrI, op->tcPtrI);
-
- op++;
- }
- fprintf(output, "\n");
- }
- return false;
-}
-
-bool
-printSCANTABREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const ScanTabRef * const sig = (ScanTabRef *) theData;
-
- fprintf(output, " apiConnectPtr: H\'%.8x\n",
- sig->apiConnectPtr);
-
- fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n",
- sig->transId1, sig->transId2);
-
- fprintf(output, " Errorcode: %u\n", sig->errorCode);
-
- fprintf(output, " closeNeeded: %u\n", sig->closeNeeded);
- return false;
-}
-
-
-bool
-printSCANFRAGNEXTREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- const ScanFragNextReq * const sig = (ScanFragNextReq *) theData;
-
- fprintf(output, " senderData: H\'%.8x\n",
- sig->senderData);
-
- fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n",
- sig->transId1, sig->transId2);
-
- fprintf(output, " Close scan: %u\n", sig->closeFlag);
-
- return false;
-}
-
-bool
-printSCANNEXTREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- if(receiverBlockNo == DBTC){
- const ScanNextReq * const sig = (ScanNextReq *) theData;
-
- fprintf(output, " apiConnectPtr: H\'%.8x\n",
- sig->apiConnectPtr);
-
- fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x) ",
- sig->transId1, sig->transId2);
-
- fprintf(output, " Stop this scan: %u\n", sig->stopScan);
-
- const Uint32 * ops = theData + ScanNextReq::SignalLength;
- if(len > ScanNextReq::SignalLength){
- fprintf(output, " tcFragPtr(s): ");
- for(size_t i = ScanNextReq::SignalLength; i<len; i++)
- fprintf(output, " 0x%x", * ops++);
- fprintf(output, "\n");
- }
- }
- if (receiverBlockNo == DBLQH){
- return printSCANFRAGNEXTREQ(output, theData, len, receiverBlockNo);
- }
- return false;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
deleted file mode 100644
index 276090f33d7..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <GlobalSignalNumbers.h>
-#include <signaldata/SignalData.hpp>
-#include <signaldata/SignalDataPrint.hpp>
-
-/**
- * This is the register
- */
-
-const NameFunctionPair
-SignalDataPrintFunctions[] = {
- { GSN_TCKEYREQ, printTCKEYREQ },
- { GSN_TCINDXREQ, printTCKEYREQ },
- { GSN_TCKEYCONF, printTCKEYCONF },
- { GSN_TCKEYREF, printTCKEYREF },
- { GSN_LQHKEYREQ, printLQHKEYREQ },
- { GSN_LQHKEYCONF, printLQHKEYCONF },
- { GSN_LQHKEYREF, printLQHKEYREF },
- { GSN_TUPKEYREQ, printTUPKEYREQ },
- { GSN_TUPKEYCONF, printTUPKEYCONF },
- { GSN_TUPKEYREF, printTUPKEYREF },
- { GSN_TUP_COMMITREQ, printTUPCOMMITREQ },
- { GSN_CONTINUEB, printCONTINUEB },
- { GSN_FSOPENREQ, printFSOPENREQ },
- { GSN_FSCLOSEREQ, printFSCLOSEREQ },
- { GSN_FSREADREQ, printFSREADWRITEREQ },
- { GSN_FSWRITEREQ, printFSREADWRITEREQ },
- { GSN_FSCLOSEREF, printFSREF },
- { GSN_FSOPENREF, printFSREF },
- { GSN_FSWRITEREF, printFSREF },
- { GSN_FSREADREF, printFSREF },
- { GSN_FSSYNCREF, printFSREF },
- { GSN_FSCLOSECONF, printFSCONF },
- { GSN_FSOPENCONF, printFSCONF },
- { GSN_FSWRITECONF, printFSCONF },
- { GSN_FSREADCONF, printFSCONF },
- { GSN_FSSYNCCONF, printFSCONF },
- { GSN_CLOSE_COMREQ, printCLOSECOMREQCONF },
- { GSN_CLOSE_COMCONF, printCLOSECOMREQCONF },
- { GSN_PACKED_SIGNAL, printPACKED_SIGNAL },
- { GSN_PREP_FAILREQ, printPREPFAILREQREF },
- { GSN_PREP_FAILREF, printPREPFAILREQREF },
- { GSN_ALTER_TABLE_REQ, printALTER_TABLE_REQ },
- { GSN_ALTER_TABLE_CONF, printALTER_TABLE_CONF },
- { GSN_ALTER_TABLE_REF, printALTER_TABLE_REF },
- { GSN_ALTER_TAB_REQ, printALTER_TAB_REQ },
- { GSN_ALTER_TAB_CONF, printALTER_TAB_CONF },
- { GSN_ALTER_TAB_REF, printALTER_TAB_REF },
- { GSN_CREATE_TRIG_REQ, printCREATE_TRIG_REQ },
- { GSN_CREATE_TRIG_CONF, printCREATE_TRIG_CONF },
- { GSN_CREATE_TRIG_REF, printCREATE_TRIG_REF },
- { GSN_ALTER_TRIG_REQ, printALTER_TRIG_REQ },
- { GSN_ALTER_TRIG_CONF, printALTER_TRIG_CONF },
- { GSN_ALTER_TRIG_REF, printALTER_TRIG_REF },
- { GSN_DROP_TRIG_REQ, printDROP_TRIG_REQ },
- { GSN_DROP_TRIG_CONF, printDROP_TRIG_CONF },
- { GSN_DROP_TRIG_REF, printDROP_TRIG_REF },
- { GSN_FIRE_TRIG_ORD, printFIRE_TRIG_ORD },
- { GSN_TRIG_ATTRINFO, printTRIG_ATTRINFO },
- { GSN_CREATE_INDX_REQ, printCREATE_INDX_REQ },
- { GSN_CREATE_INDX_CONF, printCREATE_INDX_CONF },
- { GSN_CREATE_INDX_REF, printCREATE_INDX_REF },
- { GSN_DROP_INDX_REQ, printDROP_INDX_REQ },
- { GSN_DROP_INDX_CONF, printDROP_INDX_CONF },
- { GSN_DROP_INDX_REF, printDROP_INDX_REF },
- { GSN_ALTER_INDX_REQ, printALTER_INDX_REQ },
- { GSN_ALTER_INDX_CONF, printALTER_INDX_CONF },
- { GSN_ALTER_INDX_REF, printALTER_INDX_REF },
- { GSN_TCINDXCONF, printTCINDXCONF },
- { GSN_TCINDXREF, printTCINDXREF },
- { GSN_INDXKEYINFO, printINDXKEYINFO },
- { GSN_INDXATTRINFO, printINDXATTRINFO },
- { GSN_FSAPPENDREQ, printFSAPPENDREQ },
- { GSN_BACKUP_REQ, printBACKUP_REQ },
- { GSN_BACKUP_DATA, printBACKUP_DATA },
- { GSN_BACKUP_REF, printBACKUP_REF },
- { GSN_BACKUP_CONF, printBACKUP_CONF },
- { GSN_ABORT_BACKUP_ORD, printABORT_BACKUP_ORD },
- { GSN_BACKUP_ABORT_REP, printBACKUP_ABORT_REP },
- { GSN_BACKUP_COMPLETE_REP, printBACKUP_COMPLETE_REP },
- { GSN_BACKUP_NF_COMPLETE_REP, printBACKUP_NF_COMPLETE_REP },
- { GSN_DEFINE_BACKUP_REQ, printDEFINE_BACKUP_REQ },
- { GSN_DEFINE_BACKUP_REF, printDEFINE_BACKUP_REF },
- { GSN_DEFINE_BACKUP_CONF, printDEFINE_BACKUP_CONF },
- { GSN_START_BACKUP_REQ, printSTART_BACKUP_REQ },
- { GSN_START_BACKUP_REF, printSTART_BACKUP_REF },
- { GSN_START_BACKUP_CONF, printSTART_BACKUP_CONF },
- { GSN_BACKUP_FRAGMENT_REQ, printBACKUP_FRAGMENT_REQ },
- { GSN_BACKUP_FRAGMENT_REF, printBACKUP_FRAGMENT_REF },
- { GSN_BACKUP_FRAGMENT_CONF, printBACKUP_FRAGMENT_CONF },
- { GSN_STOP_BACKUP_REQ, printSTOP_BACKUP_REQ },
- { GSN_STOP_BACKUP_REF, printSTOP_BACKUP_REF },
- { GSN_STOP_BACKUP_CONF, printSTOP_BACKUP_CONF },
- { GSN_BACKUP_STATUS_REQ, printBACKUP_STATUS_REQ },
- //{ GSN_BACKUP_STATUS_REF, printBACKUP_STATUS_REF },
- { GSN_BACKUP_STATUS_CONF, printBACKUP_STATUS_CONF },
- { GSN_UTIL_SEQUENCE_REQ, printUTIL_SEQUENCE_REQ },
- { GSN_UTIL_SEQUENCE_REF, printUTIL_SEQUENCE_REF },
- { GSN_UTIL_SEQUENCE_CONF, printUTIL_SEQUENCE_CONF },
- { GSN_UTIL_PREPARE_REQ, printUTIL_PREPARE_REQ },
- { GSN_UTIL_PREPARE_REF, printUTIL_PREPARE_REF },
- { GSN_UTIL_PREPARE_CONF, printUTIL_PREPARE_CONF },
- { GSN_UTIL_EXECUTE_REQ, printUTIL_EXECUTE_REQ },
- { GSN_UTIL_EXECUTE_REF, printUTIL_EXECUTE_REF },
- { GSN_UTIL_EXECUTE_CONF, printUTIL_EXECUTE_CONF },
- { GSN_SCAN_TABREQ, printSCANTABREQ },
- { GSN_SCAN_TABCONF, printSCANTABCONF },
- { GSN_SCAN_TABREF, printSCANTABREF },
- { GSN_SCAN_NEXTREQ, printSCANNEXTREQ },
- { GSN_LQHFRAGREQ, printLQH_FRAG_REQ },
- { GSN_LQHFRAGREF, printLQH_FRAG_REF },
- { GSN_LQHFRAGCONF, printLQH_FRAG_CONF },
- { GSN_PREP_DROP_TAB_REQ, printPREP_DROP_TAB_REQ },
- { GSN_PREP_DROP_TAB_REF, printPREP_DROP_TAB_REF },
- { GSN_PREP_DROP_TAB_CONF, printPREP_DROP_TAB_CONF },
- { GSN_DROP_TAB_REQ, printDROP_TAB_REQ },
- { GSN_DROP_TAB_REF, printDROP_TAB_REF },
- { GSN_DROP_TAB_CONF, printDROP_TAB_CONF },
- { GSN_LCP_FRAG_ORD, printLCP_FRAG_ORD },
- { GSN_LCP_FRAG_REP, printLCP_FRAG_REP },
- { GSN_LCP_COMPLETE_REP, printLCP_COMPLETE_REP },
- { GSN_START_LCP_REQ, printSTART_LCP_REQ },
- { GSN_START_LCP_CONF, printSTART_LCP_CONF },
- { GSN_MASTER_LCPREQ, printMASTER_LCP_REQ },
- { GSN_MASTER_LCPREF, printMASTER_LCP_REF },
- { GSN_MASTER_LCPCONF, printMASTER_LCP_CONF },
- { GSN_COPY_GCIREQ, printCOPY_GCI_REQ },
- { GSN_SYSTEM_ERROR, printSYSTEM_ERROR },
- { GSN_START_RECREQ, printSTART_REC_REQ },
- { GSN_START_RECCONF, printSTART_REC_CONF },
- { GSN_START_FRAGREQ, printSTART_FRAG_REQ },
- { GSN_NF_COMPLETEREP, printNF_COMPLETE_REP },
- { GSN_SIGNAL_DROPPED_REP, printSIGNAL_DROPPED_REP },
- { GSN_FAIL_REP, printFAIL_REP },
- { GSN_DISCONNECT_REP, printDISCONNECT_REP },
-
- { GSN_SUB_CREATE_REQ, printSUB_CREATE_REQ },
- { GSN_SUB_CREATE_REF, printSUB_CREATE_REF },
- { GSN_SUB_CREATE_CONF, printSUB_CREATE_CONF },
- { GSN_SUB_REMOVE_REQ, printSUB_REMOVE_REQ },
- { GSN_SUB_REMOVE_REF, printSUB_REMOVE_REF },
- { GSN_SUB_REMOVE_CONF, printSUB_REMOVE_CONF },
- { GSN_SUB_START_REQ, printSUB_START_REQ },
- { GSN_SUB_START_REF, printSUB_START_REF },
- { GSN_SUB_START_CONF, printSUB_START_CONF },
- { GSN_SUB_STOP_REQ, printSUB_STOP_REQ },
- { GSN_SUB_STOP_REF, printSUB_STOP_REF },
- { GSN_SUB_STOP_CONF, printSUB_STOP_CONF },
- { GSN_SUB_SYNC_REQ, printSUB_SYNC_REQ },
- { GSN_SUB_SYNC_REF, printSUB_SYNC_REF },
- { GSN_SUB_SYNC_CONF, printSUB_SYNC_CONF },
- { GSN_SUB_TABLE_DATA, printSUB_TABLE_DATA },
- { GSN_SUB_SYNC_CONTINUE_REQ, printSUB_SYNC_CONTINUE_REQ },
- { GSN_SUB_SYNC_CONTINUE_REF, printSUB_SYNC_CONTINUE_REF },
- { GSN_SUB_SYNC_CONTINUE_CONF, printSUB_SYNC_CONTINUE_CONF },
- { GSN_SUB_GCP_COMPLETE_REP, printSUB_GCP_COMPLETE_REP }
-
- ,{ GSN_CREATE_FRAGMENTATION_REQ, printCREATE_FRAGMENTATION_REQ }
- ,{ GSN_CREATE_FRAGMENTATION_REF, printCREATE_FRAGMENTATION_REF }
- ,{ GSN_CREATE_FRAGMENTATION_CONF, printCREATE_FRAGMENTATION_CONF }
-
- ,{ GSN_UTIL_CREATE_LOCK_REQ, printUTIL_CREATE_LOCK_REQ }
- ,{ GSN_UTIL_CREATE_LOCK_REF, printUTIL_CREATE_LOCK_REF }
- ,{ GSN_UTIL_CREATE_LOCK_CONF, printUTIL_CREATE_LOCK_CONF }
- ,{ GSN_UTIL_DESTROY_LOCK_REQ, printUTIL_DESTROY_LOCK_REQ }
- ,{ GSN_UTIL_DESTROY_LOCK_REF, printUTIL_DESTROY_LOCK_REF }
- ,{ GSN_UTIL_DESTROY_LOCK_CONF, printUTIL_DESTROY_LOCK_CONF }
- ,{ GSN_UTIL_LOCK_REQ, printUTIL_LOCK_REQ }
- ,{ GSN_UTIL_LOCK_REF, printUTIL_LOCK_REF }
- ,{ GSN_UTIL_LOCK_CONF, printUTIL_LOCK_CONF }
- ,{ 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_ACC_LOCKREQ, printACC_LOCKREQ }
- ,{ GSN_LQH_TRANSCONF, printLQH_TRANSCONF }
- ,{ GSN_SCAN_FRAGREQ, printSCAN_FRAGREQ }
- ,{ GSN_START_FRAGREQ, printSTART_FRAG_REQ }
- ,{ 0, 0 }
-};
-
-#include <Bitmask.hpp>
-
-template struct BitmaskPOD<1>;
-template struct BitmaskPOD<2>;
-template struct BitmaskPOD<4>;
-template class Bitmask<1>;
-template class Bitmask<2>;
-template class Bitmask<4>;
diff --git a/storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp b/storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp
deleted file mode 100644
index 2ef807fa28b..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <DebuggerNames.hpp>
-#include <signaldata/SignalDroppedRep.hpp>
-
-bool
-printSIGNAL_DROPPED_REP(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
- SignalDroppedRep * sig = (SignalDroppedRep*)theData;
-
- fprintf(output, " originalGsn: %s(%d) Length: %d SectionCount: %d\n",
- getSignalName(sig->originalGsn),
- sig->originalGsn,
- sig->originalLength,
- sig->originalSectionCount);
- return false;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
deleted file mode 100644
index 789a30931c9..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
+++ /dev/null
@@ -1,649 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <GlobalSignalNumbers.h>
-
-const GsnName SignalNames [] = {
- { GSN_API_REGCONF, "API_REGCONF" }
- ,{ GSN_API_REGREF, "API_REGREF" }
- ,{ GSN_API_REGREQ, "API_REGREQ" }
- ,{ GSN_ATTRINFO, "ATTRINFO" }
- ,{ GSN_SCHEMA_INFO, "SCHEMA_INFO" }
- ,{ GSN_SCHEMA_INFOCONF, "SCHEMA_INFOCONF" }
- ,{ GSN_GET_SCHEMA_INFOREQ, "GET_SCHEMA_INFOREQ" }
- ,{ GSN_DIHNDBTAMPER, "DIHNDBTAMPER" }
- ,{ GSN_KEYINFO, "KEYINFO" }
- ,{ GSN_KEYINFO20, "KEYINFO20" }
- ,{ GSN_KEYINFO20_R, "KEYINFO20_R" }
- ,{ GSN_NODE_FAILREP, "NODE_FAILREP" }
- ,{ GSN_READCONF, "READCONF" }
- ,{ GSN_SCAN_NEXTREQ, "SCAN_NEXTREQ" }
- ,{ GSN_SCAN_TABCONF, "SCAN_TABCONF" }
- ,{ GSN_SCAN_TABREF, "SCAN_TABREF" }
- ,{ GSN_SCAN_TABREQ, "SCAN_TABREQ" }
- ,{ GSN_TC_COMMITCONF, "TC_COMMITCONF" }
- ,{ GSN_TC_COMMITREF, "TC_COMMITREF" }
- ,{ GSN_TC_COMMITREQ, "TC_COMMITREQ" }
- ,{ GSN_TCKEY_FAILCONF, "TCKEY_FAILCONF" }
- ,{ GSN_TCKEY_FAILREF, "TCKEY_FAILREF" }
- ,{ GSN_TCKEYCONF, "TCKEYCONF" }
- ,{ GSN_TCKEYREF, "TCKEYREF" }
- ,{ GSN_TCKEYREQ, "TCKEYREQ" }
- ,{ GSN_TCRELEASECONF, "TCRELEASECONF" }
- ,{ GSN_TCRELEASEREF, "TCRELEASEREF" }
- ,{ GSN_TCRELEASEREQ, "TCRELEASEREQ" }
- ,{ GSN_TCROLLBACKCONF, "TCROLLBACKCONF" }
- ,{ GSN_TCROLLBACKREF, "TCROLLBACKREF" }
- ,{ GSN_TCROLLBACKREQ, "TCROLLBACKREQ" }
- ,{ GSN_TCROLLBACKREP, "TCROLLBACKREP" }
- ,{ GSN_TCSEIZECONF, "TCSEIZECONF" }
- ,{ GSN_TCSEIZEREF, "TCSEIZEREF" }
- ,{ GSN_TCSEIZEREQ, "TCSEIZEREQ" }
- ,{ GSN_TRANSID_AI, "TRANSID_AI" }
- ,{ GSN_TRANSID_AI_R, "TRANSID_AI_R" }
- ,{ GSN_ABORT, "ABORT" }
- ,{ GSN_ABORTCONF, "ABORTCONF" }
- ,{ GSN_ABORTED, "ABORTED" }
- ,{ GSN_ABORTREQ, "ABORTREQ" }
- ,{ GSN_ACC_ABORTCONF, "ACC_ABORTCONF" }
- ,{ GSN_ACC_ABORTREQ, "ACC_ABORTREQ" }
- ,{ GSN_ACC_CHECK_SCAN, "ACC_CHECK_SCAN" }
- ,{ GSN_ACC_COMMITCONF, "ACC_COMMITCONF" }
- ,{ GSN_ACC_COMMITREQ, "ACC_COMMITREQ" }
- ,{ GSN_ACC_OVER_REC, "ACC_OVER_REC" }
- ,{ GSN_ACC_SCAN_INFO, "ACC_SCAN_INFO" }
- ,{ GSN_ACC_SCAN_INFO24, "ACC_SCAN_INFO24" }
- ,{ GSN_ACC_SCANCONF, "ACC_SCANCONF" }
- ,{ GSN_ACC_SCANREF, "ACC_SCANREF" }
- ,{ GSN_ACC_SCANREQ, "ACC_SCANREQ" }
- ,{ GSN_ACC_TO_CONF, "ACC_TO_CONF" }
- ,{ GSN_ACC_TO_REF, "ACC_TO_REF" }
- ,{ GSN_ACC_TO_REQ, "ACC_TO_REQ" }
- ,{ GSN_ACCFRAGCONF, "ACCFRAGCONF" }
- ,{ GSN_ACCFRAGREF, "ACCFRAGREF" }
- ,{ GSN_ACCFRAGREQ, "ACCFRAGREQ" }
- ,{ GSN_ACCKEYCONF, "ACCKEYCONF" }
- ,{ GSN_ACCKEYREF, "ACCKEYREF" }
- ,{ GSN_ACCKEYREQ, "ACCKEYREQ" }
- ,{ GSN_ACCMINUPDATE, "ACCMINUPDATE" }
- ,{ GSN_ACCSEIZECONF, "ACCSEIZECONF" }
- ,{ GSN_ACCSEIZEREF, "ACCSEIZEREF" }
- ,{ GSN_ACCSEIZEREQ, "ACCSEIZEREQ" }
- ,{ GSN_ACCUPDATECONF, "ACCUPDATECONF" }
- ,{ GSN_ACCUPDATEKEY, "ACCUPDATEKEY" }
- ,{ GSN_ACCUPDATEREF, "ACCUPDATEREF" }
- ,{ GSN_ADD_FRAGCONF, "ADD_FRAGCONF" }
- ,{ GSN_ADD_FRAGREF, "ADD_FRAGREF" }
- ,{ GSN_ADD_FRAGREQ, "ADD_FRAGREQ" }
- ,{ GSN_API_FAILCONF, "API_FAILCONF" }
- ,{ GSN_API_FAILREQ, "API_FAILREQ" }
- ,{ GSN_CHECK_LCP_STOP, "CHECK_LCP_STOP" }
- ,{ GSN_CLOSE_COMCONF, "CLOSE_COMCONF" }
- ,{ GSN_CLOSE_COMREQ, "CLOSE_COMREQ" }
- ,{ GSN_CM_ACKADD, "CM_ACKADD" }
- ,{ GSN_CM_ADD, "CM_ADD" }
- ,{ GSN_CM_ADD_REP, "CM_ADD_REP" }
- ,{ GSN_CM_HEARTBEAT, "CM_HEARTBEAT" }
- ,{ 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_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" }
- ,{ GSN_COMMIT_FAILREQ, "COMMIT_FAILREQ" }
- ,{ GSN_COMMITCONF, "COMMITCONF" }
- ,{ GSN_COMMITREQ, "COMMITREQ" }
- ,{ GSN_COMMITTED, "COMMITTED" }
- ,{ GSN_LCP_FRAG_ORD, "LCP_FRAG_ORD" }
- ,{ GSN_LCP_FRAG_REP, "LCP_FRAG_REP" }
- ,{ GSN_LCP_COMPLETE_REP, "LCP_COMPLETE_REP" }
- ,{ GSN_START_LCP_REQ, "START_LCP_REQ" }
- ,{ GSN_START_LCP_CONF, "START_LCP_CONF" }
- ,{ GSN_COMPLETE, "COMPLETE" }
- ,{ GSN_COMPLETECONF, "COMPLETECONF" }
- ,{ GSN_COMPLETED, "COMPLETED" }
- ,{ GSN_COMPLETEREQ, "COMPLETEREQ" }
- ,{ GSN_CONNECT_REP, "CONNECT_REP" }
- ,{ GSN_CONTINUEB, "CONTINUEB" }
- ,{ GSN_COPY_ACTIVECONF, "COPY_ACTIVECONF" }
- ,{ GSN_COPY_ACTIVEREF, "COPY_ACTIVEREF" }
- ,{ GSN_COPY_ACTIVEREQ, "COPY_ACTIVEREQ" }
- ,{ GSN_COPY_FRAGCONF, "COPY_FRAGCONF" }
- ,{ GSN_COPY_FRAGREF, "COPY_FRAGREF" }
- ,{ GSN_COPY_FRAGREQ, "COPY_FRAGREQ" }
- ,{ GSN_COPY_GCICONF, "COPY_GCICONF" }
- ,{ GSN_COPY_GCIREQ, "COPY_GCIREQ" }
- ,{ GSN_COPY_STATECONF, "COPY_STATECONF" }
- ,{ GSN_COPY_STATEREQ, "COPY_STATEREQ" }
- ,{ GSN_COPY_TABCONF, "COPY_TABCONF" }
- ,{ GSN_COPY_TABREQ, "COPY_TABREQ" }
- ,{ GSN_CREATE_FRAGCONF, "CREATE_FRAGCONF" }
- ,{ GSN_CREATE_FRAGREF, "CREATE_FRAGREF" }
- ,{ GSN_CREATE_FRAGREQ, "CREATE_FRAGREQ" }
- ,{ GSN_DEBUG_SIG, "DEBUG_SIG" }
- ,{ GSN_DI_FCOUNTCONF, "DI_FCOUNTCONF" }
- ,{ GSN_DI_FCOUNTREF, "DI_FCOUNTREF" }
- ,{ GSN_DI_FCOUNTREQ, "DI_FCOUNTREQ" }
- ,{ GSN_DIADDTABCONF, "DIADDTABCONF" }
- ,{ GSN_DIADDTABREF, "DIADDTABREF" }
- ,{ GSN_DIADDTABREQ, "DIADDTABREQ" }
- ,{ GSN_DICTSTARTCONF, "DICTSTARTCONF" }
- ,{ GSN_DICTSTARTREQ, "DICTSTARTREQ" }
- ,{ GSN_LIST_TABLES_REQ, "LIST_TABLES_REQ" }
- ,{ GSN_LIST_TABLES_CONF, "LIST_TABLES_CONF" }
- ,{ GSN_DIGETNODESCONF, "DIGETNODESCONF" }
- ,{ GSN_DIGETNODESREF, "DIGETNODESREF" }
- ,{ GSN_DIGETNODESREQ, "DIGETNODESREQ" }
- ,{ GSN_DIGETPRIMCONF, "DIGETPRIMCONF" }
- ,{ GSN_DIGETPRIMREF, "DIGETPRIMREF" }
- ,{ GSN_DIGETPRIMREQ, "DIGETPRIMREQ" }
- ,{ GSN_DIH_RESTARTCONF, "DIH_RESTARTCONF" }
- ,{ GSN_DIH_RESTARTREF, "DIH_RESTARTREF" }
- ,{ GSN_DIH_RESTARTREQ, "DIH_RESTARTREQ" }
-
- ,{ GSN_DIRELEASECONF, "DIRELEASECONF" }
- ,{ GSN_DIRELEASEREF, "DIRELEASEREF" }
- ,{ GSN_DIRELEASEREQ, "DIRELEASEREQ" }
- ,{ GSN_DISCONNECT_REP, "DISCONNECT_REP" }
- ,{ GSN_DISEIZECONF, "DISEIZECONF" }
- ,{ GSN_DISEIZEREF, "DISEIZEREF" }
- ,{ GSN_DISEIZEREQ, "DISEIZEREQ" }
- ,{ GSN_DIVERIFYCONF, "DIVERIFYCONF" }
- ,{ GSN_DIVERIFYREF, "DIVERIFYREF" }
- ,{ GSN_DIVERIFYREQ, "DIVERIFYREQ" }
- ,{ GSN_EMPTY_LCP_REQ, "EMPTY_LCP_REQ" }
- ,{ GSN_EMPTY_LCP_CONF, "EMPTY_LCP_CONF" }
- ,{ GSN_ENABLE_COMORD, "ENABLE_COMORD" }
- ,{ GSN_END_LCPCONF, "END_LCPCONF" }
- ,{ GSN_END_LCPREQ, "END_LCPREQ" }
- ,{ GSN_END_TOCONF, "END_TOCONF" }
- ,{ GSN_END_TOREQ, "END_TOREQ" }
- ,{ GSN_EVENT_REP, "EVENT_REP" }
- ,{ GSN_EXEC_FRAGCONF, "EXEC_FRAGCONF" }
- ,{ GSN_EXEC_FRAGREF, "EXEC_FRAGREF" }
- ,{ GSN_EXEC_FRAGREQ, "EXEC_FRAGREQ" }
- ,{ GSN_EXEC_SRCONF, "EXEC_SRCONF" }
- ,{ GSN_EXEC_SRREQ, "EXEC_SRREQ" }
- ,{ GSN_EXPANDCHECK2, "EXPANDCHECK2" }
- ,{ GSN_FAIL_REP, "FAIL_REP" }
- ,{ GSN_FSCLOSECONF, "FSCLOSECONF" }
- ,{ GSN_FSCLOSEREF, "FSCLOSEREF" }
- ,{ GSN_FSCLOSEREQ, "FSCLOSEREQ" }
- ,{ GSN_FSOPENCONF, "FSOPENCONF" }
- ,{ GSN_FSOPENREF, "FSOPENREF" }
- ,{ GSN_FSOPENREQ, "FSOPENREQ" }
- ,{ GSN_FSREADCONF, "FSREADCONF" }
- ,{ GSN_FSREADREF, "FSREADREF" }
- ,{ GSN_FSREADREQ, "FSREADREQ" }
- ,{ GSN_FSSYNCCONF, "FSSYNCCONF" }
- ,{ GSN_FSSYNCREF, "FSSYNCREF" }
- ,{ GSN_FSSYNCREQ, "FSSYNCREQ" }
- ,{ GSN_FSWRITECONF, "FSWRITECONF" }
- ,{ GSN_FSWRITEREF, "FSWRITEREF" }
- ,{ GSN_FSWRITEREQ, "FSWRITEREQ" }
- ,{ GSN_FSAPPENDCONF, "FSAPPENDCONF" }
- ,{ GSN_FSAPPENDREF, "FSAPPENDREF" }
- ,{ GSN_FSAPPENDREQ, "FSAPPENDREQ" }
- ,{ GSN_FSREMOVECONF, "FSREMOVECONF" }
- ,{ GSN_FSREMOVEREF, "FSREMOVEREF" }
- ,{ GSN_FSREMOVEREQ, "FSREMOVEREQ" }
- ,{ GSN_GCP_ABORT, "GCP_ABORT" }
- ,{ GSN_GCP_ABORTED, "GCP_ABORTED" }
- ,{ GSN_GCP_COMMIT, "GCP_COMMIT" }
- ,{ GSN_GCP_NODEFINISH, "GCP_NODEFINISH" }
- ,{ GSN_GCP_NOMORETRANS, "GCP_NOMORETRANS" }
- ,{ GSN_GCP_PREPARE, "GCP_PREPARE" }
- ,{ GSN_GCP_PREPARECONF, "GCP_PREPARECONF" }
- ,{ GSN_GCP_PREPAREREF, "GCP_PREPAREREF" }
- ,{ GSN_GCP_SAVECONF, "GCP_SAVECONF" }
- ,{ GSN_GCP_SAVEREF, "GCP_SAVEREF" }
- ,{ GSN_GCP_SAVEREQ, "GCP_SAVEREQ" }
- ,{ GSN_GCP_TCFINISHED, "GCP_TCFINISHED" }
- ,{ GSN_GET_TABINFOREF, "GET_TABINFOREF" }
- ,{ GSN_GET_TABINFOREQ, "GET_TABINFOREQ" }
- ,{ GSN_GET_TABINFO_CONF, "GET_TABINFO_CONF" }
- ,{ GSN_GETGCICONF, "GETGCICONF" }
- ,{ GSN_GETGCIREQ, "GETGCIREQ" }
- ,{ GSN_HOT_SPAREREP, "HOT_SPAREREP" }
- ,{ GSN_INCL_NODECONF, "INCL_NODECONF" }
- ,{ GSN_INCL_NODEREF, "INCL_NODEREF" }
- ,{ GSN_INCL_NODEREQ, "INCL_NODEREQ" }
- ,{ GSN_LQH_TRANSCONF, "LQH_TRANSCONF" }
- ,{ GSN_LQH_TRANSREQ, "LQH_TRANSREQ" }
- ,{ GSN_LQHADDATTCONF, "LQHADDATTCONF" }
- ,{ GSN_LQHADDATTREF, "LQHADDATTREF" }
- ,{ GSN_LQHADDATTREQ, "LQHADDATTREQ" }
- ,{ GSN_LQHFRAGCONF, "LQHFRAGCONF" }
- ,{ GSN_LQHFRAGREF, "LQHFRAGREF" }
- ,{ GSN_LQHFRAGREQ, "LQHFRAGREQ" }
- ,{ GSN_LQHKEYCONF, "LQHKEYCONF" }
- ,{ GSN_LQHKEYREF, "LQHKEYREF" }
- ,{ GSN_LQHKEYREQ, "LQHKEYREQ" }
- ,{ GSN_MASTER_GCPCONF, "MASTER_GCPCONF" }
- ,{ GSN_MASTER_GCPREF, "MASTER_GCPREF" }
- ,{ GSN_MASTER_GCPREQ, "MASTER_GCPREQ" }
- ,{ GSN_MASTER_LCPCONF, "MASTER_LCPCONF" }
- ,{ GSN_MASTER_LCPREF, "MASTER_LCPREF" }
- ,{ GSN_MASTER_LCPREQ, "MASTER_LCPREQ" }
- ,{ GSN_MEMCHECKCONF, "MEMCHECKCONF" }
- ,{ GSN_MEMCHECKREQ, "MEMCHECKREQ" }
- ,{ GSN_NDB_FAILCONF, "NDB_FAILCONF" }
- ,{ GSN_NDB_STARTCONF, "NDB_STARTCONF" }
- ,{ GSN_NDB_STARTREF, "NDB_STARTREF" }
- ,{ GSN_NDB_STARTREQ, "NDB_STARTREQ" }
- ,{ GSN_NDB_STTOR, "NDB_STTOR" }
- ,{ GSN_NDB_STTORRY, "NDB_STTORRY" }
- ,{ GSN_NDB_TAMPER, "NDB_TAMPER" }
- ,{ GSN_NEXT_SCANCONF, "NEXT_SCANCONF" }
- ,{ GSN_NEXT_SCANREF, "NEXT_SCANREF" }
- ,{ GSN_NEXT_SCANREQ, "NEXT_SCANREQ" }
- ,{ GSN_NEXTOPERATION, "NEXTOPERATION" }
- ,{ GSN_NF_COMPLETEREP, "NF_COMPLETEREP" }
- ,{ GSN_OPEN_COMCONF, "OPEN_COMCONF" }
- ,{ GSN_OPEN_COMREF, "OPEN_COMREF" }
- ,{ GSN_OPEN_COMREQ, "OPEN_COMREQ" }
- ,{ GSN_PACKED_SIGNAL, "PACKED_SIGNAL" }
- ,{ GSN_PREP_FAILCONF, "PREP_FAILCONF" }
- ,{ GSN_PREP_FAILREF, "PREP_FAILREF" }
- ,{ GSN_PREP_FAILREQ, "PREP_FAILREQ" }
- ,{ GSN_PRES_TOCONF, "PRES_TOCONF" }
- ,{ GSN_PRES_TOREQ, "PRES_TOREQ" }
- ,{ GSN_READ_NODESCONF, "READ_NODESCONF" }
- ,{ GSN_READ_NODESREF, "READ_NODESREF" }
- ,{ GSN_READ_NODESREQ, "READ_NODESREQ" }
- ,{ GSN_SCAN_FRAGCONF, "SCAN_FRAGCONF" }
- ,{ GSN_SCAN_FRAGREF, "SCAN_FRAGREF" }
- ,{ GSN_SCAN_FRAGREQ, "SCAN_FRAGREQ" }
- ,{ GSN_SCAN_HBREP, "SCAN_HBREP" }
- ,{ GSN_SCAN_PROCCONF, "SCAN_PROCCONF" }
- ,{ GSN_SCAN_PROCREQ, "SCAN_PROCREQ" }
- ,{ GSN_SEND_PACKED, "SEND_PACKED" }
- ,{ GSN_SET_LOGLEVELORD, "SET_LOGLEVELORD" }
- ,{ GSN_SHRINKCHECK2, "SHRINKCHECK2" }
- ,{ GSN_READ_CONFIG_REQ, "READ_CONFIG_REQ" }
- ,{ GSN_READ_CONFIG_CONF, "READ_CONFIG_CONF" }
- ,{ GSN_START_COPYCONF, "START_COPYCONF" }
- ,{ GSN_START_COPYREF, "START_COPYREF" }
- ,{ GSN_START_COPYREQ, "START_COPYREQ" }
- ,{ GSN_START_EXEC_SR, "START_EXEC_SR" }
- ,{ GSN_START_FRAGCONF, "START_FRAGCONF" }
- ,{ GSN_START_FRAGREF, "START_FRAGREF" }
- ,{ GSN_START_FRAGREQ, "START_FRAGREQ" }
- ,{ GSN_START_LCP_REF, "START_LCP_REF" }
- ,{ GSN_START_LCP_ROUND, "START_LCP_ROUND" }
- ,{ GSN_START_MECONF, "START_MECONF" }
- ,{ GSN_START_MEREF, "START_MEREF" }
- ,{ GSN_START_MEREQ, "START_MEREQ" }
- ,{ GSN_START_PERMCONF, "START_PERMCONF" }
- ,{ GSN_START_PERMREF, "START_PERMREF" }
- ,{ GSN_START_PERMREQ, "START_PERMREQ" }
- ,{ GSN_START_RECCONF, "START_RECCONF" }
- ,{ GSN_START_RECREF, "START_RECREF" }
- ,{ GSN_START_RECREQ, "START_RECREQ" }
- ,{ GSN_START_TOCONF, "START_TOCONF" }
- ,{ GSN_START_TOREQ, "START_TOREQ" }
- ,{ GSN_STORED_PROCCONF, "STORED_PROCCONF" }
- ,{ GSN_STORED_PROCREF, "STORED_PROCREF" }
- ,{ GSN_STORED_PROCREQ, "STORED_PROCREQ" }
- ,{ GSN_STTOR, "STTOR" }
- ,{ GSN_STTORRY, "STTORRY" }
- ,{ GSN_SYSTEM_ERROR, "SYSTEM_ERROR" }
- ,{ GSN_TAB_COMMITCONF, "TAB_COMMITCONF" }
- ,{ GSN_TAB_COMMITREF, "TAB_COMMITREF" }
- ,{ GSN_TAB_COMMITREQ, "TAB_COMMITREQ" }
- ,{ GSN_TAKE_OVERTCCONF, "TAKE_OVERTCCONF" }
- ,{ GSN_TAKE_OVERTCREQ, "TAKE_OVERTCREQ" }
- ,{ GSN_TC_CLOPSIZECONF, "TC_CLOPSIZECONF" }
- ,{ GSN_TC_CLOPSIZEREQ, "TC_CLOPSIZEREQ" }
- ,{ GSN_TC_SCHVERCONF, "TC_SCHVERCONF" }
- ,{ GSN_TC_SCHVERREQ, "TC_SCHVERREQ" }
- ,{ GSN_TCGETOPSIZECONF, "TCGETOPSIZECONF" }
- ,{ GSN_TCGETOPSIZEREQ, "TCGETOPSIZEREQ" }
- ,{ GSN_TEST_ORD, "TEST_ORD" }
- ,{ GSN_TESTSIG, "TESTSIG" }
- ,{ GSN_TIME_SIGNAL, "TIME_SIGNAL" }
- ,{ GSN_TUP_ABORTREQ, "TUP_ABORTREQ" }
- ,{ GSN_TUP_ADD_ATTCONF, "TUP_ADD_ATTCONF" }
- ,{ GSN_TUP_ADD_ATTRREF, "TUP_ADD_ATTRREF" }
- ,{ GSN_TUP_ADD_ATTRREQ, "TUP_ADD_ATTRREQ" }
- ,{ GSN_TUP_ATTRINFO, "TUP_ATTRINFO" }
- ,{ GSN_TUP_COMMITREQ, "TUP_COMMITREQ" }
- ,{ GSN_TUPFRAGCONF, "TUPFRAGCONF" }
- ,{ GSN_TUPFRAGREF, "TUPFRAGREF" }
- ,{ GSN_TUPFRAGREQ, "TUPFRAGREQ" }
- ,{ GSN_TUPKEYCONF, "TUPKEYCONF" }
- ,{ GSN_TUPKEYREF, "TUPKEYREF" }
- ,{ GSN_TUPKEYREQ, "TUPKEYREQ" }
- ,{ GSN_TUPRELEASECONF, "TUPRELEASECONF" }
- ,{ GSN_TUPRELEASEREF, "TUPRELEASEREF" }
- ,{ GSN_TUPRELEASEREQ, "TUPRELEASEREQ" }
- ,{ GSN_TUPSEIZECONF, "TUPSEIZECONF" }
- ,{ GSN_TUPSEIZEREF, "TUPSEIZEREF" }
- ,{ GSN_TUPSEIZEREQ, "TUPSEIZEREQ" }
- ,{ GSN_UNBLO_DICTCONF, "UNBLO_DICTCONF" }
- ,{ GSN_UNBLO_DICTREQ, "UNBLO_DICTREQ" }
- ,{ GSN_UPDATE_TOCONF, "UPDATE_TOCONF" }
- ,{ GSN_UPDATE_TOREF, "UPDATE_TOREF" }
- ,{ GSN_UPDATE_TOREQ, "UPDATE_TOREQ" }
- ,{ GSN_TUP_ALLOCREQ, "TUP_ALLOCREQ" }
- ,{ GSN_LQH_ALLOCREQ, "LQH_ALLOCREQ" }
- ,{ GSN_TUP_DEALLOCREQ, "TUP_DEALLOCREQ" }
- ,{ GSN_TUP_WRITELOG_REQ, "TUP_WRITELOG_REQ" }
- ,{ GSN_LQH_WRITELOG_REQ, "LQH_WRITELOG_REQ" }
-
- ,{ GSN_START_ORD, "START_ORD" }
- ,{ GSN_STOP_ORD, "STOP_ORD" }
- ,{ GSN_TAMPER_ORD, "TAMPER_ORD" }
-
- ,{ GSN_EVENT_SUBSCRIBE_REQ, "EVENT_SUBSCRIBE_REQ" }
- ,{ GSN_EVENT_SUBSCRIBE_CONF, "EVENT_SUBSCRIBE_CONF" }
- ,{ GSN_EVENT_SUBSCRIBE_REF, "EVENT_SUBSCRIBE_REF" }
- ,{ GSN_DUMP_STATE_ORD, "DUMP_STATE_ORD" }
-
- ,{ GSN_NODE_START_REP, "NODE_START_REP" }
-
- ,{ GSN_START_INFOREQ, "START_INFOREQ" }
- ,{ GSN_START_INFOREF, "START_INFOREF" }
- ,{ GSN_START_INFOCONF, "START_INFOCONF" }
-
- ,{ GSN_CHECKNODEGROUPSREQ, "CHECKNODEGROUPSREQ" }
- ,{ GSN_CHECKNODEGROUPSCONF, "CHECKNODEGROUPSCONF" }
-
- ,{ GSN_ARBIT_PREPREQ, "ARBIT_PREPREQ" }
- ,{ GSN_ARBIT_PREPCONF, "ARBIT_PREPCONF" }
- ,{ GSN_ARBIT_PREPREF, "ARBIT_PREPREF" }
- ,{ GSN_ARBIT_STARTREQ, "ARBIT_STARTREQ" }
- ,{ GSN_ARBIT_STARTCONF, "ARBIT_STARTCONF" }
- ,{ GSN_ARBIT_STARTREF, "ARBIT_STARTREF" }
- ,{ GSN_ARBIT_CHOOSEREQ, "ARBIT_CHOOSEREQ" }
- ,{ GSN_ARBIT_CHOOSECONF, "ARBIT_CHOOSECONF" }
- ,{ GSN_ARBIT_CHOOSEREF, "ARBIT_CHOOSEREF" }
- ,{ GSN_ARBIT_STOPORD, "ARBIT_STOPORD" }
- ,{ GSN_ARBIT_STOPREP, "ARBIT_STOPREP" }
-
- ,{ GSN_TC_COMMIT_ACK, "TC_COMMIT_ACK" }
- ,{ GSN_REMOVE_MARKER_ORD, "REMOVE_MARKER_ORD" }
-
- ,{ GSN_NODE_STATE_REP, "NODE_STATE_REP" }
- ,{ GSN_CHANGE_NODE_STATE_REQ, "CHANGE_NODE_STATE_REQ" }
- ,{ GSN_CHANGE_NODE_STATE_CONF, "CHANGE_NODE_STATE_CONF" }
-
- ,{ GSN_BLOCK_COMMIT_ORD, "BLOCK_COMMIT_ORD" }
- ,{ GSN_UNBLOCK_COMMIT_ORD, "UNBLOCK_COMMIT_ORD" }
-
- ,{ GSN_DIH_SWITCH_REPLICA_REQ, "DIH_SWITCH_REPLICA_REQ" }
- ,{ GSN_DIH_SWITCH_REPLICA_REF, "DIH_SWITCH_REPLICA_REF" }
- ,{ GSN_DIH_SWITCH_REPLICA_CONF, "DIH_SWITCH_REPLICA_CONF" }
-
- ,{ GSN_STOP_PERM_REQ, "STOP_PERM_REQ" }
- ,{ GSN_STOP_PERM_REF, "STOP_PERM_REF" }
- ,{ GSN_STOP_PERM_CONF, "STOP_PERM_CONF" }
-
- ,{ GSN_STOP_ME_REQ, "STOP_ME_REQ" }
- ,{ GSN_STOP_ME_REF, "STOP_ME_REF" }
- ,{ GSN_STOP_ME_CONF, "STOP_ME_CONF" }
-
- ,{ GSN_WAIT_GCP_REQ, "WAIT_GCP_REQ" }
- ,{ GSN_WAIT_GCP_REF, "WAIT_GCP_REF" }
- ,{ GSN_WAIT_GCP_CONF, "WAIT_GCP_CONF" }
-
- ,{ GSN_STOP_REQ, "STOP_REQ" }
- ,{ GSN_STOP_REF, "STOP_REF" }
- ,{ GSN_API_VERSION_REQ, "API_VERSION_REQ" }
- ,{ GSN_API_VERSION_CONF, "API_VERSION_CONF" }
-
- ,{ GSN_ABORT_ALL_REQ, "ABORT_ALL_REQ" }
- ,{ GSN_ABORT_ALL_REF, "ABORT_ALL_REF" }
- ,{ GSN_ABORT_ALL_CONF, "ABORT_ALL_CONF" }
-
- ,{ GSN_DROP_TABLE_REQ, "DROP_TABLE_REQ" }
- ,{ GSN_DROP_TABLE_REF, "DROP_TABLE_REF" }
- ,{ GSN_DROP_TABLE_CONF, "DROP_TABLE_CONF" }
-
- ,{ GSN_DROP_TAB_REQ, "DROP_TAB_REQ" }
- ,{ GSN_DROP_TAB_REF, "DROP_TAB_REF" }
- ,{ GSN_DROP_TAB_CONF, "DROP_TAB_CONF" }
-
- ,{ GSN_PREP_DROP_TAB_REQ, "PREP_DROP_TAB_REQ" }
- ,{ GSN_PREP_DROP_TAB_REF, "PREP_DROP_TAB_REF" }
- ,{ GSN_PREP_DROP_TAB_CONF, "PREP_DROP_TAB_CONF" }
-
- ,{ GSN_WAIT_DROP_TAB_REQ, "WAIT_DROP_TAB_REQ" }
- ,{ GSN_WAIT_DROP_TAB_REF, "WAIT_DROP_TAB_REF" }
- ,{ GSN_WAIT_DROP_TAB_CONF, "WAIT_DROP_TAB_CONF" }
-
- ,{ GSN_CREATE_TRIG_REQ, "CREATE_TRIG_REQ" }
- ,{ GSN_CREATE_TRIG_CONF, "CREATE_TRIG_CONF" }
- ,{ GSN_CREATE_TRIG_REF, "CREATE_TRIG_REF" }
- ,{ GSN_ALTER_TRIG_REQ, "ALTER_TRIG_REQ" }
- ,{ GSN_ALTER_TRIG_CONF, "ALTER_TRIG_CONF" }
- ,{ GSN_ALTER_TRIG_REF, "ALTER_TRIG_REF" }
- ,{ GSN_DROP_TRIG_REQ, "DROP_TRIG_REQ" }
- ,{ GSN_DROP_TRIG_CONF, "DROP_TRIG_CONF" }
- ,{ GSN_DROP_TRIG_REF, "DROP_TRIG_REF" }
- ,{ GSN_FIRE_TRIG_ORD, "FIRE_TRIG_ORD" }
- ,{ GSN_TRIG_ATTRINFO, "TRIG_ATTRINFO" }
-
- ,{ GSN_CREATE_INDX_REQ, "CREATE_INDX_REQ" }
- ,{ GSN_CREATE_INDX_CONF, "CREATE_INDX_CONF" }
- ,{ GSN_CREATE_INDX_REF, "CREATE_INDX_REF" }
- ,{ GSN_DROP_INDX_REQ, "DROP_INDX_REQ" }
- ,{ GSN_DROP_INDX_CONF, "DROP_INDX_CONF" }
- ,{ GSN_DROP_INDX_REF, "DROP_INDX_REF" }
- ,{ GSN_ALTER_INDX_REQ, "ALTER_INDX_REQ" }
- ,{ GSN_ALTER_INDX_CONF, "ALTER_INDX_CONF" }
- ,{ GSN_ALTER_INDX_REF, "ALTER_INDX_REF" }
- ,{ GSN_TCINDXREQ, "TCINDXREQ" }
- ,{ GSN_TCINDXCONF, "TCINDXCONF" }
- ,{ GSN_TCINDXREF, "TCINDXREF" }
- ,{ GSN_INDXKEYINFO, "INDXKEYINFO" }
- ,{ GSN_INDXATTRINFO, "INDXATTRINFO" }
- ,{ GSN_BUILDINDXREQ, "BUILDINDXREQ" }
- ,{ GSN_BUILDINDXCONF, "BUILDINDXCONF" }
- ,{ GSN_BUILDINDXREF, "BUILDINDXREF" }
- //,{ GSN_TCINDXNEXTREQ, "TCINDXNEXTREQ" }
- //,{ GSN_TCINDEXNEXTCONF, "TCINDEXNEXTCONF" }
- //,{ GSN_TCINDEXNEXREF, "TCINDEXNEXREF" }
-
- ,{ GSN_CREATE_EVNT_REQ, "CREATE_EVNT_REQ" }
- ,{ GSN_CREATE_EVNT_CONF, "CREATE_EVNT_CONF" }
- ,{ GSN_CREATE_EVNT_REF, "CREATE_EVNT_REF" }
-
- ,{ GSN_SUMA_START_ME_REQ, "SUMA_START_ME_REQ" }
- ,{ GSN_SUMA_START_ME_REF, "SUMA_START_ME_REF" }
- ,{ GSN_SUMA_START_ME_CONF, "SUMA_START_ME_CONF" }
- ,{ GSN_SUMA_HANDOVER_REQ, "SUMA_HANDOVER_REQ"}
- ,{ GSN_SUMA_HANDOVER_REF, "SUMA_HANDOVER_REF"}
- ,{ GSN_SUMA_HANDOVER_CONF, "SUMA_HANDOVER_CONF"}
-
- ,{ GSN_DROP_EVNT_REQ, "DROP_EVNT_REQ" }
- ,{ GSN_DROP_EVNT_CONF, "DROP_EVNT_CONF" }
- ,{ GSN_DROP_EVNT_REF, "DROP_EVNT_REF" }
-
- ,{ GSN_BACKUP_TRIG_REQ, "BACKUP_TRIG_REQ" }
- ,{ GSN_BACKUP_REQ, "BACKUP_REQ" }
- ,{ GSN_BACKUP_DATA, "BACKUP_DATA" }
- ,{ GSN_BACKUP_REF, "BACKUP_REF" }
- ,{ GSN_BACKUP_CONF, "BACKUP_CONF" }
- ,{ GSN_ABORT_BACKUP_ORD, "ABORT_BACKUP_ORD" }
- ,{ GSN_BACKUP_ABORT_REP, "BACKUP_ABORT_REP" }
- ,{ GSN_BACKUP_COMPLETE_REP, "BACKUP_COMPLETE_REP" }
- ,{ GSN_BACKUP_NF_COMPLETE_REP, "BACKUP_NF_COMPLETE_REP" }
- ,{ GSN_DEFINE_BACKUP_REQ, "DEFINE_BACKUP_REQ" }
- ,{ GSN_DEFINE_BACKUP_REF, "DEFINE_BACKUP_REF" }
- ,{ GSN_DEFINE_BACKUP_CONF, "DEFINE_BACKUP_CONF" }
- ,{ GSN_START_BACKUP_REQ, "START_BACKUP_REQ" }
- ,{ GSN_START_BACKUP_REF, "START_BACKUP_REF" }
- ,{ GSN_START_BACKUP_CONF, "START_BACKUP_CONF" }
- ,{ GSN_BACKUP_FRAGMENT_REQ, "BACKUP_FRAGMENT_REQ" }
- ,{ GSN_BACKUP_FRAGMENT_REF, "BACKUP_FRAGMENT_REF" }
- ,{ GSN_BACKUP_FRAGMENT_CONF, "BACKUP_FRAGMENT_CONF" }
- ,{ GSN_STOP_BACKUP_REQ, "STOP_BACKUP_REQ" }
- ,{ GSN_STOP_BACKUP_REF, "STOP_BACKUP_REF" }
- ,{ GSN_STOP_BACKUP_CONF, "STOP_BACKUP_CONF" }
- ,{ GSN_BACKUP_STATUS_REQ, "BACKUP_STATUS_REQ" }
- ,{ GSN_BACKUP_STATUS_REF, "BACKUP_STATUS_REF" }
- ,{ GSN_BACKUP_STATUS_CONF, "BACKUP_STATUS_CONF" }
- ,{ GSN_SIGNAL_DROPPED_REP, "SIGNAL_DROPPED_REP" }
- ,{ GSN_CONTINUE_FRAGMENTED, "CONTINUE_FRAGMENTED" }
-
- /** Util Block Services **/
- ,{ GSN_UTIL_SEQUENCE_REQ, "UTIL_SEQUENCE_REQ" }
- ,{ GSN_UTIL_SEQUENCE_REF, "UTIL_SEQUENCE_REF" }
- ,{ GSN_UTIL_SEQUENCE_CONF, "UTIL_SEQUENCE_CONF" }
- ,{ GSN_UTIL_PREPARE_REQ, "UTIL_PREPARE_REQ" }
- ,{ GSN_UTIL_PREPARE_CONF, "UTIL_PREPARE_CONF" }
- ,{ GSN_UTIL_PREPARE_REF, "UTIL_PREPARE_REF" }
- ,{ GSN_UTIL_EXECUTE_REQ, "UTIL_EXECUTE_REQ" }
- ,{ GSN_UTIL_EXECUTE_CONF, "UTIL_EXECUTE_CONF" }
- ,{ GSN_UTIL_EXECUTE_REF, "UTIL_EXECUTE_REF" }
- ,{ GSN_UTIL_RELEASE_REQ, "UTIL_RELEASE_REQ" }
- ,{ GSN_UTIL_RELEASE_CONF, "UTIL_RELEASE_CONF" }
- ,{ GSN_UTIL_RELEASE_REF, "UTIL_RELASE_REF" }
-
- /* Suma Block Services **/
- ,{ GSN_SUB_CREATE_REQ, "SUB_CREATE_REQ" }
- ,{ GSN_SUB_CREATE_REF, "SUB_CREATE_REF" }
- ,{ GSN_SUB_CREATE_CONF, "SUB_CREATE_CONF" }
- ,{ GSN_SUB_REMOVE_REQ, "SUB_REMOVE_REQ" }
- ,{ GSN_SUB_REMOVE_REF, "SUB_REMOVE_REF" }
- ,{ GSN_SUB_REMOVE_CONF, "SUB_REMOVE_CONF" }
- ,{ GSN_SUB_START_REQ, "SUB_START_REQ" }
- ,{ GSN_SUB_START_REF, "SUB_START_REF" }
- ,{ GSN_SUB_START_CONF, "SUB_START_CONF" }
- ,{ GSN_SUB_STOP_REQ, "SUB_STOP_REQ" }
- ,{ GSN_SUB_STOP_REF, "SUB_STOP_REF" }
- ,{ GSN_SUB_STOP_CONF, "SUB_STOP_CONF" }
- ,{ GSN_SUB_SYNC_REQ, "SUB_SYNC_REQ" }
- ,{ GSN_SUB_SYNC_REF, "SUB_SYNC_REF" }
- ,{ GSN_SUB_SYNC_CONF, "SUB_SYNC_CONF" }
- ,{ GSN_SUB_TABLE_DATA, "SUB_TABLE_DATA" }
- ,{ GSN_SUB_SYNC_CONTINUE_REQ, "SUB_SYNC_CONTINUE_REQ" }
- ,{ GSN_SUB_SYNC_CONTINUE_REF, "SUB_SYNC_CONTINUE_REF" }
- ,{ GSN_SUB_SYNC_CONTINUE_CONF, "SUB_SYNC_CONTINUE_CONF" }
- ,{ GSN_SUB_GCP_COMPLETE_REP, "SUB_GCP_COMPLETE_REP" }
- ,{ GSN_SUB_GCP_COMPLETE_ACK, "SUB_GCP_COMPLETE_ACK" }
-
- ,{ GSN_CREATE_SUBID_REQ, "CREATE_SUBID_REQ" }
- ,{ GSN_CREATE_SUBID_REF, "CREATE_SUBID_REF" }
- ,{ GSN_CREATE_SUBID_CONF, "CREATE_SUBID_CONF" }
-
- ,{ GSN_CREATE_TABLE_REQ, "CREATE_TABLE_REQ" }
- ,{ GSN_CREATE_TABLE_REF, "CREATE_TABLE_REF" }
- ,{ GSN_CREATE_TABLE_CONF, "CREATE_TABLE_CONF" }
-
- ,{ GSN_CREATE_TAB_REQ, "CREATE_TAB_REQ" }
- ,{ GSN_CREATE_TAB_REF, "CREATE_TAB_REF" }
- ,{ GSN_CREATE_TAB_CONF, "CREATE_TAB_CONF" }
-
- ,{ GSN_ALTER_TABLE_REQ, "ALTER_TABLE_REQ" }
- ,{ GSN_ALTER_TABLE_REF, "ALTER_TABLE_REF" }
- ,{ GSN_ALTER_TABLE_CONF, "ALTER_TABLE_CONF" }
-
- ,{ GSN_ALTER_TAB_REQ, "ALTER_TAB_REQ" }
- ,{ GSN_ALTER_TAB_REF, "ALTER_TAB_REF" }
- ,{ GSN_ALTER_TAB_CONF, "ALTER_TAB_CONF" }
-
- ,{ GSN_CREATE_FRAGMENTATION_REQ, "CREATE_FRAGMENTATION_REQ" }
- ,{ GSN_CREATE_FRAGMENTATION_REF, "CREATE_FRAGMENTATION_REF" }
- ,{ GSN_CREATE_FRAGMENTATION_CONF, "CREATE_FRAGMENTATION_CONF" }
-
- ,{ GSN_UTIL_CREATE_LOCK_REQ, "UTIL_CREATE_LOCK_REQ" }
- ,{ GSN_UTIL_CREATE_LOCK_REF, "UTIL_CREATE_LOCK_REF" }
- ,{ GSN_UTIL_CREATE_LOCK_CONF, "UTIL_CREATE_LOCK_CONF" }
- ,{ GSN_UTIL_DESTROY_LOCK_REQ, "UTIL_DESTROY_LOCK_REQ" }
- ,{ GSN_UTIL_DESTROY_LOCK_REF, "UTIL_DESTROY_LOCK_REF" }
- ,{ GSN_UTIL_DESTROY_LOCK_CONF, "UTIL_DESTROY_LOCK_CONF" }
- ,{ GSN_UTIL_LOCK_REQ, "UTIL_LOCK_REQ" }
- ,{ GSN_UTIL_LOCK_REF, "UTIL_LOCK_REF" }
- ,{ GSN_UTIL_LOCK_CONF, "UTIL_LOCK_CONF" }
- ,{ GSN_UTIL_UNLOCK_REQ, "UTIL_UNLOCK_REQ" }
- ,{ GSN_UTIL_UNLOCK_REF, "UTIL_UNLOCK_REF" }
- ,{ GSN_UTIL_UNLOCK_CONF, "UTIL_UNLOCK_CONF" }
-
- /* TUX */
- ,{ GSN_TUXFRAGREQ, "TUXFRAGREQ" }
- ,{ GSN_TUXFRAGCONF, "TUXFRAGCONF" }
- ,{ GSN_TUXFRAGREF, "TUXFRAGREF" }
- ,{ GSN_TUX_ADD_ATTRREQ, "TUX_ADD_ATTRREQ" }
- ,{ GSN_TUX_ADD_ATTRCONF, "TUX_ADD_ATTRCONF" }
- ,{ GSN_TUX_ADD_ATTRREF, "TUX_ADD_ATTRREF" }
- ,{ GSN_TUX_MAINT_REQ, "TUX_MAINT_REQ" }
- ,{ GSN_TUX_MAINT_CONF, "TUX_MAINT_CONF" }
- ,{ GSN_TUX_MAINT_REF, "TUX_MAINT_REF" }
- ,{ GSN_TUX_BOUND_INFO, "TUX_BOUND_INFO" }
- ,{ GSN_ACC_LOCKREQ, "ACC_LOCKREQ" }
-
- ,{ GSN_CREATE_FILEGROUP_REQ, "CREATE_FILEGROUP_REQ" }
- ,{ GSN_CREATE_FILEGROUP_REF, "CREATE_FILEGROUP_REF" }
- ,{ GSN_CREATE_FILEGROUP_CONF, "CREATE_FILEGROUP_CONF" }
-
- ,{ GSN_CREATE_FILE_REQ, "CREATE_FILE_REQ" }
- ,{ GSN_CREATE_FILE_REF, "CREATE_FILE_REF" }
- ,{ GSN_CREATE_FILE_CONF, "CREATE_FILE_CONF" }
-
- ,{ GSN_DROP_FILEGROUP_REQ, "DROP_FILEGROUP_REQ" }
- ,{ GSN_DROP_FILEGROUP_REF, "DROP_FILEGROUP_REF" }
- ,{ GSN_DROP_FILEGROUP_CONF, "DROP_FILEGROUP_CONF" }
-
- ,{ GSN_DROP_FILE_REQ, "DROP_FILE_REQ" }
- ,{ GSN_DROP_FILE_REF, "DROP_FILE_REF" }
- ,{ GSN_DROP_FILE_CONF, "DROP_FILE_CONF" }
-
- ,{ GSN_CREATE_OBJ_REQ, "CREATE_OBJ_REQ" }
- ,{ GSN_CREATE_OBJ_REF, "CREATE_OBJ_REF" }
- ,{ GSN_CREATE_OBJ_CONF, "CREATE_OBJ_CONF" }
-
- ,{ GSN_DROP_OBJ_REQ, "DROP_OBJ_REQ" }
- ,{ GSN_DROP_OBJ_REF, "DROP_OBJ_REF" }
- ,{ GSN_DROP_OBJ_CONF, "DROP_OBJ_CONF" }
-
- ,{ GSN_LCP_PREPARE_REQ, "LCP_PREPARE_REQ" }
- ,{ GSN_LCP_PREPARE_REF, "LCP_PREPARE_REF" }
- ,{ GSN_LCP_PREPARE_CONF, "LCP_PREPARE_CONF" }
-
- ,{ GSN_DICT_ABORT_REQ, "DICT_ABORT_REQ" }
- ,{ GSN_DICT_ABORT_REF, "DICT_ABORT_REF" }
- ,{ GSN_DICT_ABORT_CONF, "DICT_ABORT_CONF" }
-
- ,{ GSN_DICT_COMMIT_REQ, "DICT_COMMIT_REQ" }
- ,{ GSN_DICT_COMMIT_REF, "DICT_COMMIT_REF" }
- ,{ GSN_DICT_COMMIT_CONF, "DICT_COMMIT_CONF" }
-
- /* DICT LOCK */
- ,{ GSN_DICT_LOCK_REQ, "DICT_LOCK_REQ" }
- ,{ GSN_DICT_LOCK_CONF, "DICT_LOCK_CONF" }
- ,{ GSN_DICT_LOCK_REF, "DICT_LOCK_REF" }
- ,{ GSN_DICT_UNLOCK_ORD, "DICT_UNLOCK_ORD" }
-
- ,{ GSN_UPDATE_FRAG_DIST_KEY_ORD, "UPDATE_FRAG_DIST_KEY_ORD" }
- ,{ GSN_DICT_COMMIT_REQ, "DICT_COMMIT_REQ"}
-
- ,{ GSN_ROUTE_ORD, "ROUTE_ORD" }
- ,{ GSN_NODE_VERSION_REP, "NODE_VERSION_REP" }
-
- ,{ GSN_PREPARE_COPY_FRAG_REQ, "PREPARE_COPY_FRAG_REQ" }
- ,{ GSN_PREPARE_COPY_FRAG_REF, "PREPARE_COPY_FRAG_REF" }
- ,{ GSN_PREPARE_COPY_FRAG_CONF, "PREPARE_COPY_FRAG_CONF" }
-};
-const unsigned short NO_OF_SIGNAL_NAMES = sizeof(SignalNames)/sizeof(GsnName);
diff --git a/storage/ndb/src/common/debugger/signaldata/StartRec.cpp b/storage/ndb/src/common/debugger/signaldata/StartRec.cpp
deleted file mode 100644
index 387b4085b12..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/StartRec.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <RefConvert.hpp>
-#include <signaldata/StartRec.hpp>
-#include <signaldata/StartFragReq.hpp>
-
-bool
-printSTART_REC_REQ(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
- StartRecReq * sig = (StartRecReq *) theData;
-
- fprintf(output, " receivingNodeId: %d senderRef: (%d, %d)\n",
- sig->receivingNodeId,
- refToNode(sig->senderRef),
- refToBlock(sig->senderRef));
-
- fprintf(output, " keepGci: %d lastCompletedGci: %d newestGci: %d\n",
- sig->keepGci,
- sig->lastCompletedGci,
- sig->newestGci);
-
- return true;
-}
-
-bool
-printSTART_REC_CONF(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo){
- StartRecConf * sig = (StartRecConf *) theData;
-
- fprintf(output, " startingNodeId: %d\n",
- sig->startingNodeId);
-
- return true;
-}
-
-bool
-printSTART_FRAG_REQ(FILE * output,
- const Uint32 * theData,
- Uint32 len,
- Uint16 recBlockNo)
-{
- StartFragReq* sig = (StartFragReq*)theData;
-
- fprintf(output, " table: %d frag: %d lcpId: %d lcpNo: %d #nodes: %d \n",
- sig->tableId, sig->fragId, sig->lcpId, sig->lcpNo,
- sig->noOfLogNodes);
-
- for(Uint32 i = 0; i<sig->noOfLogNodes; i++)
- {
- fprintf(output, " (node: %d startGci: %d lastGci: %d)",
- sig->lqhLogNode[i],
- sig->startGci[i],
- sig->lastGci[i]);
- }
-
- fprintf(output, "\n");
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp b/storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp
deleted file mode 100644
index 34bd8aa41e6..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/SumaImpl.hpp>
-
-bool
-printSUB_CREATE_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubCreateReq * const sig = (SubCreateReq *)theData;
- fprintf(output, " senderRef: %x\n", sig->senderRef);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " subscriptionType: %x\n", sig->subscriptionType);
- fprintf(output, " tableId: %x\n", sig->tableId);
- return false;
-}
-
-bool
-printSUB_CREATE_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubCreateConf * const sig = (SubCreateConf *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_CREATE_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubCreateRef * const sig = (SubCreateRef *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_REMOVE_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const SubRemoveReq * const sig = (SubRemoveReq *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- return false;
-}
-
-bool
-printSUB_REMOVE_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const SubRemoveConf * const sig = (SubRemoveConf *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_REMOVE_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const SubRemoveRef * const sig = (SubRemoveRef *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " errorCode: %x\n", sig->errorCode);
- return false;
-}
-
-bool
-printSUB_START_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStartReq * const sig = (SubStartReq *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_START_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStartRef * const sig = (SubStartRef *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " startPart: %x\n", sig->part);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " errorCode: %x\n", sig->errorCode);
- return false;
-}
-
-bool
-printSUB_START_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStartConf * const sig = (SubStartConf *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " startPart: %x\n", sig->part);
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_STOP_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStopReq * const sig = (SubStopReq *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_STOP_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStopRef * const sig = (SubStopRef *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " errorCode: %x\n", sig->errorCode);
- return false;
-}
-
-bool
-printSUB_STOP_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubStopConf * const sig = (SubStopConf *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_SYNC_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncReq * const sig = (SubSyncReq *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- fprintf(output, " syncPart: %x\n", sig->part);
- return false;
-}
-
-bool
-printSUB_SYNC_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncRef * const sig = (SubSyncRef *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " errorCode: %x\n", sig->errorCode);
- return false;
-}
-
-bool
-printSUB_SYNC_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncConf * const sig = (SubSyncConf *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- return false;
-}
-
-bool
-printSUB_TABLE_DATA(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubTableData * const sig = (SubTableData *)theData;
- fprintf(output, " senderData: %x\n", sig->senderData);
- fprintf(output, " gci: %x\n", sig->gci);
- fprintf(output, " tableId: %x\n", sig->tableId);
- fprintf(output, " operation: %x\n",
- SubTableData::getOperation(sig->requestInfo));
- return false;
-}
-
-bool
-printSUB_SYNC_CONTINUE_REQ(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncContinueReq * const sig = (SubSyncContinueReq *)theData;
- fprintf(output, " subscriberData: %x\n", sig->subscriberData);
- fprintf(output, " noOfRowsSent: %x\n", sig->noOfRowsSent);
- return false;
-}
-
-bool
-printSUB_SYNC_CONTINUE_REF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncContinueRef * const sig = (SubSyncContinueRef *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- return false;
-}
-
-bool
-printSUB_SYNC_CONTINUE_CONF(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubSyncContinueConf * const sig = (SubSyncContinueConf *)theData;
- fprintf(output, " subscriptionId: %x\n", sig->subscriptionId);
- fprintf(output, " subscriptionKey: %x\n", sig->subscriptionKey);
- return false;
-}
-
-bool
-printSUB_GCP_COMPLETE_REP(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo) {
- const SubGcpCompleteRep * const sig = (SubGcpCompleteRep *)theData;
- fprintf(output, " gci: %x\n", sig->gci);
- return false;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/SystemError.cpp b/storage/ndb/src/common/debugger/signaldata/SystemError.cpp
deleted file mode 100644
index 175ef091aaf..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/SystemError.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <kernel_types.h>
-#include <BlockNumbers.h>
-#include <signaldata/SystemError.hpp>
-
-bool
-printSYSTEM_ERROR(FILE * output, const Uint32 * theData, Uint32 len,
- Uint16 receiverBlockNo){
-
- const SystemError * const sig = (SystemError *) theData;
-
- fprintf(output, "errorRef: H\'%.8x\n",
- sig->errorRef);
- fprintf(output, "errorCode: %d\n",
- sig->errorCode);
- fprintf(output, "data1: H\'%.8x\n",
- sig->data1);
- fprintf(output, "data2: H\'%.8x\n",
- sig->data2);
-
- return true;
-}
-
-
diff --git a/storage/ndb/src/common/debugger/signaldata/TcIndx.cpp b/storage/ndb/src/common/debugger/signaldata/TcIndx.cpp
deleted file mode 100644
index 0927287d95c..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TcIndx.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <BlockNumbers.h>
-
-
-bool
-printTCINDXCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- if (receiverBlockNo == API_PACKED) {
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- }
- else {
- const TcIndxConf * const sig = (TcIndxConf *) theData;
-
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- Uint32 confInfo = sig->confInfo;
- Uint32 noOfOp = TcIndxConf::getNoOfOperations(confInfo);
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
- fprintf(output, "apiConnectPtr: H'%.8x, gci: %u, transId:(H'%.8x, H'%.8x)\n",
- sig->apiConnectPtr, sig->gci, sig->transId1, sig->transId2);
-
- fprintf(output, "noOfOperations: %u, commitFlag: %s, markerFlag: %s\n",
- noOfOp,
- (TcIndxConf::getCommitFlag(confInfo) == 0)?"false":"true",
- (TcIndxConf::getMarkerFlag(confInfo) == 0)?"false":"true");
- fprintf(output, "Operations:\n");
- for(i = 0; i < noOfOp; i++) {
- fprintf(output,
- "apiOperationPtr: H'%.8x, attrInfoLen: %u\n",
- sig->operations[i].apiOperationPtr,
- sig->operations[i].attrInfoLen);
- }
- }
-
- return true;
-}
-
-bool
-printTCINDXREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
-// const TcIndxRef * const sig = (TcIndxRef *) theData;
-
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp b/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp
deleted file mode 100644
index 47695d914cc..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TcKeyConf.hpp>
-#include <BlockNumbers.h>
-
-bool
-printTCKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
-
- if (receiverBlockNo == API_PACKED) {
- return false;
- Uint32 Theader = * theData++;
- Uint32 TpacketLen = (Theader & 0x1F) + 3;
- Uint32 TrecBlockNo = Theader >> 16;
-
- do {
- fprintf(output, "Block: %d %d %d\n", TrecBlockNo, len, TpacketLen);
- printTCKEYCONF(output, theData, TpacketLen, TrecBlockNo);
- assert(len >= (1 + TpacketLen));
- len -= (1 + TpacketLen);
- theData += TpacketLen;
- } while(len);
- return true;
- }
- else {
- const TcKeyConf * const sig = (TcKeyConf *) theData;
-
- Uint32 i = 0;
- Uint32 confInfo = sig->confInfo;
- Uint32 noOfOp = TcKeyConf::getNoOfOperations(confInfo);
- if (noOfOp > 10) noOfOp = 10;
- fprintf(output, " apiConnectPtr: H'%.8x, gci: %u, transId:(H'%.8x, H'%.8x)\n",
- sig->apiConnectPtr, sig->gci, sig->transId1, sig->transId2);
-
- fprintf(output, " noOfOperations: %u, commitFlag: %s, markerFlag: %s\n",
- noOfOp,
- (TcKeyConf::getCommitFlag(confInfo) == 0)?"false":"true",
- (TcKeyConf::getMarkerFlag(confInfo) == 0)?"false":"true");
- fprintf(output, "Operations:\n");
- for(i = 0; i < noOfOp; i++) {
- if(sig->operations[i].attrInfoLen > TcKeyConf::DirtyReadBit)
- fprintf(output,
- " apiOperationPtr: H'%.8x, simplereadnode: %u\n",
- sig->operations[i].apiOperationPtr,
- sig->operations[i].attrInfoLen & (~TcKeyConf::DirtyReadBit));
- else
- fprintf(output,
- " apiOperationPtr: H'%.8x, attrInfoLen: %u\n",
- sig->operations[i].apiOperationPtr,
- sig->operations[i].attrInfoLen);
- }
- }
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp b/storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp
deleted file mode 100644
index fdfe10e4a30..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TcKeyRef.hpp>
-
-bool
-printTCKEYREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp b/storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp
deleted file mode 100644
index 793fa557dd6..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <signaldata/TcKeyReq.hpp>
-
-bool
-printTCKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
-
- const TcKeyReq * const sig = (TcKeyReq *) theData;
-
- UintR requestInfo = sig->requestInfo;
-
- fprintf(output, " apiConnectPtr: H\'%.8x, apiOperationPtr: H\'%.8x\n",
- sig->apiConnectPtr, sig->apiOperationPtr);
- fprintf(output, " Operation: %s, Flags: ",
- sig->getOperationType(requestInfo) == ZREAD ? "Read" :
- sig->getOperationType(requestInfo) == ZREAD_EX ? "Read-Ex" :
- sig->getOperationType(requestInfo) == ZUPDATE ? "Update" :
- sig->getOperationType(requestInfo) == ZINSERT ? "Insert" :
- sig->getOperationType(requestInfo) == ZDELETE ? "Delete" :
- sig->getOperationType(requestInfo) == ZWRITE ? "Write" :
- "Unknown");
- {
- if(sig->getDirtyFlag(requestInfo)){
- fprintf(output, "Dirty ");
- }
- if(sig->getStartFlag(requestInfo)){
- fprintf(output, "Start ");
- }
- if(sig->getExecuteFlag(requestInfo)){
- fprintf(output, "Execute ");
- }
- if(sig->getCommitFlag(requestInfo)){
- fprintf(output, "Commit ");
- }
- if (sig->getExecutingTrigger(requestInfo)) {
- fprintf(output, "Trigger ");
- }
-
- if (sig->getNoDiskFlag(requestInfo)) {
- fprintf(output, "NoDisk ");
- }
-
- UintR TcommitType = sig->getAbortOption(requestInfo);
- if (TcommitType == TcKeyReq::AbortOnError) {
- fprintf(output, "AbortOnError ");
- } else if (TcommitType == TcKeyReq::IgnoreError) {
- fprintf(output, "IgnoreError ");
- }//if
-
- if(sig->getSimpleFlag(requestInfo)){
- fprintf(output, "Simple ");
- }
- if(sig->getScanIndFlag(requestInfo)){
- fprintf(output, "ScanInd ");
- }
- if(sig->getInterpretedFlag(requestInfo)){
- fprintf(output, "Interpreted ");
- }
- if(sig->getDistributionKeyFlag(sig->requestInfo)){
- fprintf(output, " d-key");
- }
- fprintf(output, "\n");
- }
-
- const int keyLen = sig->getKeyLength(requestInfo);
- const int attrInThis = sig->getAIInTcKeyReq(requestInfo);
- const int attrLen = sig->getAttrinfoLen(sig->attrLen);
- const int apiVer = sig->getAPIVersion(sig->attrLen);
- fprintf(output,
- " keyLen: %d, attrLen: %d, AI in this: %d, tableId: %d, "
- "tableSchemaVer: %d, API Ver: %d\n",
- keyLen, attrLen, attrInThis,
- sig->tableId, sig->tableSchemaVersion, apiVer);
-
- fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n -- Variable Data --\n",
- sig->transId1, sig->transId2);
-
- if (len >= TcKeyReq::StaticLength) {
- Uint32 restLen = (len - TcKeyReq::StaticLength);
- const Uint32 * rest = &sig->scanInfo;
- 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");
- }
- } else {
- fprintf(output, "*** invalid len %u ***\n", len);
- }
- return true;
-}
-
diff --git a/storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp b/storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp
deleted file mode 100644
index c96669303db..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TcRollbackRep.hpp>
-
-bool
-printTCROLLBACKREP(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp b/storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp
deleted file mode 100644
index 51abfb5a2f2..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TrigAttrInfo.hpp>
-
-static
-const char *
-tatype(Uint32 i){
- switch(i){
- case TrigAttrInfo::PRIMARY_KEY:
- return "PK";
- break;
- case TrigAttrInfo::BEFORE_VALUES:
- return "BEFORE";
- break;
- case TrigAttrInfo::AFTER_VALUES:
- return "AFTER";
- break;
- }
- return "UNKNOWN";
-}
-
-bool
-printTRIG_ATTRINFO(FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const TrigAttrInfo * const sig = (TrigAttrInfo *) theData;
-
- fprintf(output, " TriggerId: %d Type: %s ConnectPtr: %x\n",
- sig->getTriggerId(),
- tatype(sig->getAttrInfoType()),
- sig->getConnectionPtr());
-
- Uint32 i = 0;
- while (i < len - TrigAttrInfo::StaticLength)
- fprintf(output, " H\'%.8x", sig->getData()[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TupCommit.cpp b/storage/ndb/src/common/debugger/signaldata/TupCommit.cpp
deleted file mode 100644
index e6dcfef5c8f..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TupCommit.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TupCommit.hpp>
-
-bool
-printTUPCOMMITREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TupKey.cpp b/storage/ndb/src/common/debugger/signaldata/TupKey.cpp
deleted file mode 100644
index 9290e942311..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TupKey.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TupKey.hpp>
-
-bool
-printTUPKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
-
-bool
-printTUPKEYCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
-
-bool
-printTUPKEYREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
- fprintf(output, "Signal data: ");
- Uint32 i = 0;
- while (i < len)
- fprintf(output, "H\'%.8x ", theData[i++]);
- fprintf(output,"\n");
-
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp b/storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp
deleted file mode 100644
index 6aa5e2a8d06..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TuxMaint.hpp>
-#include <SignalLoggerManager.hpp>
-#include <AttributeHeader.hpp>
-
-bool
-printTUX_MAINT_REQ(FILE* output, const Uint32* theData, Uint32 len, Uint16 rbn)
-{
- //const bool inOut = rbn & (1 << 15);
- const TuxMaintReq* const sig = (const TuxMaintReq*)theData;
- fprintf(output, " errorCode=%d\n", sig->errorCode);
- fprintf(output, " table: id=%u", sig->tableId);
- fprintf(output, " index: id=%u", sig->indexId);
- fprintf(output, " fragment: id=%u\n", sig->fragId);
- fprintf(output, " tuple: loc=%u.%u version=%u\n", sig->pageId, sig->pageIndex, sig->tupVersion);
- const Uint32 opCode = sig->opInfo & 0xFF;
- const Uint32 opFlag = sig->opInfo >> 8;
- switch (opCode ) {
- case TuxMaintReq::OpAdd:
- fprintf(output, " opCode=Add opFlag=%u\n", opFlag);
- break;
- case TuxMaintReq::OpRemove:
- fprintf(output, " opCode=Remove opFlag=%u\n", opFlag);
- break;
- default:
- fprintf(output, " opInfo=%x ***invalid***\n", sig->opInfo);
- break;
- }
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp b/storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp
deleted file mode 100644
index 8cdb6fb38b8..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/UtilDelete.hpp>
-
-bool
-printUTIL_DELETE_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- (void)l; // Don't want compiler warning
- (void)b; // Don't want compiler warning
-
- UtilDeleteReq* sig = (UtilDeleteReq*)data;
- fprintf(out, " senderData: %d prepareId: %d totalDataLen: %d\n",
- sig->senderData,
- sig->prepareId,
- sig->totalDataLen);
- fprintf(out,
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n"
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n"
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
- sig->attrData[0], sig->attrData[1], sig->attrData[2],
- sig->attrData[3], sig->attrData[4], sig->attrData[5],
- sig->attrData[6], sig->attrData[7], sig->attrData[8],
- sig->attrData[9], sig->attrData[10], sig->attrData[11],
- sig->attrData[12], sig->attrData[13], sig->attrData[14],
- sig->attrData[15], sig->attrData[16], sig->attrData[17],
- sig->attrData[18], sig->attrData[19], sig->attrData[20],
- sig->attrData[21]
- );
-
- return true;
-}
-
-bool
-printUTIL_DELETE_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- (void)l; // Don't want compiler warning
- (void)b; // Don't want compiler warning
-
- UtilDeleteConf* sig = (UtilDeleteConf*)data;
- fprintf(out, " senderData: %d\n", sig->senderData);
- return true;
-}
-
-bool
-printUTIL_DELETE_REF(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- (void)l; // Don't want compiler warning
- (void)b; // Don't want compiler warning
-
- UtilDeleteRef* sig = (UtilDeleteRef*)data;
- fprintf(out, " senderData: %d\n", sig->senderData);
- fprintf(out, " errorCode: %d\n", sig->errorCode);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp b/storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp
deleted file mode 100644
index 1e3cf1f255a..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/UtilExecute.hpp>
-
-bool
-printUTIL_EXECUTE_REQ(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- const UtilExecuteReq* const sig = (UtilExecuteReq*)data;
- fprintf(out, " senderRef: H'%.8x, senderData: H'%.8x prepareId: %d "
- " releaseFlag: %d\n",
- sig->senderRef,
- sig->senderData,
- sig->getPrepareId(),
- sig->getReleaseFlag());
- return true;
-}
-
-bool
-printUTIL_EXECUTE_CONF(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- UtilExecuteConf* sig = (UtilExecuteConf*)data;
- fprintf(out, " senderData: H'%.8x\n",
- sig->senderData);
- return true;
-}
-
-bool
-printUTIL_EXECUTE_REF(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- UtilExecuteRef* sig = (UtilExecuteRef*)data;
- fprintf(out, " senderData: H'%.8x, ", sig->senderData);
- fprintf(out, " errorCode: %s, ",
- sig->errorCode == UtilExecuteRef::IllegalKeyNumber ?
- "IllegalKeyNumber" :
- sig->errorCode == UtilExecuteRef::IllegalAttrNumber ?
- "IllegalAttrNumber" :
- sig->errorCode == UtilExecuteRef::TCError ?
- "TCError" :
- sig->errorCode == UtilExecuteRef::AllocationError ?
- "AllocationError" :
- "Unknown");
- fprintf(out, " TCErrorCode: %d\n",
- sig->TCErrorCode);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/UtilLock.cpp b/storage/ndb/src/common/debugger/signaldata/UtilLock.cpp
deleted file mode 100644
index a10e490fa53..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/UtilLock.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/UtilLock.hpp>
-
-bool
-printUTIL_LOCK_REQ (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilLockReq *const sig = (UtilLockReq *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " requestInfo: %x\n", sig->requestInfo);
- return true;
-}
-
-bool
-printUTIL_LOCK_CONF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilLockConf *const sig = (UtilLockConf *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " lockKey: %x\n", sig->lockKey);
- return true;
-}
-
-bool
-printUTIL_LOCK_REF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilLockRef *const sig = (UtilLockRef *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " errorCode: %x\n", sig->errorCode);
- return true;
-}
-
-bool
-printUTIL_UNLOCK_REQ (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilUnlockReq *const sig = (UtilUnlockReq *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " lockKey: %x\n", sig->lockKey);
- return true;
-}
-
-bool
-printUTIL_UNLOCK_CONF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilUnlockConf *const sig = (UtilUnlockConf *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- return true;
-}
-
-bool
-printUTIL_UNLOCK_REF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilUnlockRef *const sig = (UtilUnlockRef *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " errorCode: %x\n", sig->errorCode);
- return true;
-}
-
-bool
-printUTIL_CREATE_LOCK_REQ (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilCreateLockReq *const sig = (UtilCreateLockReq *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " lockType: %x\n", sig->lockType);
- return true;
-}
-
-bool
-printUTIL_CREATE_LOCK_REF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilCreateLockRef *const sig = (UtilCreateLockRef *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " errorCode: %x\n", sig->errorCode);
- return true;
-}
-
-bool
-printUTIL_CREATE_LOCK_CONF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilCreateLockConf *const sig = (UtilCreateLockConf *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- return true;
-}
-
-bool
-printUTIL_DESTROY_LOCK_REQ (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilDestroyLockReq *const sig = (UtilDestroyLockReq *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " lockKey: %x\n", sig->lockKey);
- return true;
-}
-
-bool
-printUTIL_DESTROY_LOCK_REF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilDestroyLockRef *const sig = (UtilDestroyLockRef *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- fprintf (output, " errorCode: %x\n", sig->errorCode);
- return true;
-}
-
-bool
-printUTIL_DESTROY_LOCK_CONF (FILE * output, const Uint32 * theData,
- Uint32 len, Uint16 receiverBlockNo)
-{
- const UtilDestroyLockConf *const sig = (UtilDestroyLockConf *) theData;
- fprintf (output, " senderData: %x\n", sig->senderData);
- fprintf (output, " senderRef: %x\n", sig->senderRef);
- fprintf (output, " lockId: %x\n", sig->lockId);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp b/storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp
deleted file mode 100644
index ee0234561b6..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/UtilPrepare.hpp>
-
-bool
-printUTIL_PREPARE_REQ(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- UtilPrepareReq* sig = (UtilPrepareReq*)data;
- fprintf(out, " senderRef: H'%.8x senderData: H'%.8x\n",
- sig->senderRef,
- sig->senderData);
-
- return true;
-}
-
-bool
-printUTIL_PREPARE_CONF(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- UtilPrepareConf* sig = (UtilPrepareConf*)data;
- fprintf(out, " senderData: H'%.8x prepareId: %d\n",
- sig->senderData,
- sig->prepareId);
- return true;
-}
-
-bool
-printUTIL_PREPARE_REF(FILE* out, const Uint32 * data, Uint32 len, Uint16 rec)
-{
- UtilPrepareRef* sig = (UtilPrepareRef*)data;
- fprintf(out, " senderData: H'%.8x, ", sig->senderData);
- fprintf(out, " error: %d, ", sig->errorCode);
-
- fprintf(out, " errorMsg: ");
- switch(sig->errorCode) {
- case UtilPrepareRef::NO_ERROR:
- fprintf(out, "No error");
- break;
- case UtilPrepareRef::PREPARE_SEIZE_ERROR:
- fprintf(out, "Failed to seize Prepare record");
- break;
- case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
- fprintf(out, "Failed to seize PreparedOperation record");
- break;
- case UtilPrepareRef::DICT_TAB_INFO_ERROR:
- fprintf(out, "Failed to get table info from DICT");
- break;
- }
- fprintf(out, "\n");
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp b/storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp
deleted file mode 100644
index 2533d1b870e..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/UtilSequence.hpp>
-
-inline
-const char *
-type2string(UtilSequenceReq::RequestType type){
- switch(type){
- case UtilSequenceReq::NextVal:
- return "NextVal";
- case UtilSequenceReq::CurrVal:
- return "CurrVal";
- case UtilSequenceReq::Create:
- return "Create";
- default:
- return "Unknown";
- }
-}
-
-bool
-printUTIL_SEQUENCE_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- UtilSequenceReq* sig = (UtilSequenceReq*)data;
- fprintf(out, " senderData: %d sequenceId: %d RequestType: %s\n",
- sig->senderData,
- sig->sequenceId,
- type2string((UtilSequenceReq::RequestType)sig->requestType));
- return true;
-}
-
-bool
-printUTIL_SEQUENCE_CONF(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- UtilSequenceConf* sig = (UtilSequenceConf*)data;
- fprintf(out, " senderData: %d sequenceId: %d RequestType: %s\n",
- sig->senderData,
- sig->sequenceId,
- type2string((UtilSequenceReq::RequestType)sig->requestType));
- fprintf(out, " val: [ %d %d ]\n",
- sig->sequenceValue[0],
- sig->sequenceValue[1]);
- return true;
-}
-
-bool
-printUTIL_SEQUENCE_REF(FILE * out, const Uint32 * data, Uint32 l, Uint16 b){
- UtilSequenceRef* sig = (UtilSequenceRef*)data;
- fprintf(out, " senderData: %d sequenceId: %d RequestType: %s\n",
- sig->senderData,
- sig->sequenceId,
- type2string((UtilSequenceReq::RequestType)sig->requestType));
- fprintf(out, " errorCode: %d, TCErrorCode: %d\n",
- sig->errorCode, sig->TCErrorCode);
- return true;
-}
diff --git a/storage/ndb/src/common/debugger/signaldata/print.awk b/storage/ndb/src/common/debugger/signaldata/print.awk
deleted file mode 100644
index ac65348170e..00000000000
--- a/storage/ndb/src/common/debugger/signaldata/print.awk
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-BEGIN {
- m_curr="";
- m_count=0;
- m_level=0;
-}
-/^[ ]*class[ ]+.*{/ {
- if(m_curr != ""){
- print;
- print "ERROR: " m_curr;
- exit;
- }
- m_curr = $2;
-}
-/{/ {
- m_level++;
-}
-/bool print/{
- m_print=$3;
- i=index($3, "(");
- if(i > 0){
- m_print=substr($3, 0, i-1);
- }
-}
-
-/[ ]+Uint32[ ]+[^)]*;/ {
- if(m_level >= 0){
- m=$2;
- i=index($2, ";");
- if(i > 0){
- m=substr($2, 0, i-1);
- }
- m_members[m_count]=m;
- m_count++;
- }
-}
-/^[ ]*}[ ]*;/ {
- m_level--;
- if(m_level == 0){
- if(m_count > 0 && m_print != ""){
- print "bool";
- print m_print "(FILE * output, const Uint32 * theData, ";
- print "Uint32 len, Uint16 receiverBlockNo) {";
- print "const " m_curr " * const sig = (" m_curr " *)theData;";
- for(i = 0; i<m_count; i++){
- print "fprintf(output, \" " m_members[i] ": %x\\n\", sig->" m_members[i] ");";
- }
- print "return true;";
- print "}";
- print "";
- }
- m_curr="";
- m_print="";
- m_count=0;
- }
-}
diff --git a/storage/ndb/src/common/logger/ConsoleLogHandler.cpp b/storage/ndb/src/common/logger/ConsoleLogHandler.cpp
deleted file mode 100644
index ddfc9a85a5b..00000000000
--- a/storage/ndb/src/common/logger/ConsoleLogHandler.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "ConsoleLogHandler.hpp"
-
-#include <NdbOut.hpp>
-
-ConsoleLogHandler::ConsoleLogHandler() : LogHandler()
-{
-}
-
-ConsoleLogHandler::~ConsoleLogHandler()
-{
-
-}
-
-bool
-ConsoleLogHandler::open()
-{
- return true;
-}
-
-bool
-ConsoleLogHandler::close()
-{
- return true;
-}
-
-//
-// PROTECTED
-//
-void
-ConsoleLogHandler::writeHeader(const char* pCategory, Logger::LoggerLevel level)
-{
- char str[LogHandler::MAX_HEADER_LENGTH];
- ndbout << getDefaultHeader(str, pCategory, level);
-}
-
-void
-ConsoleLogHandler::writeMessage(const char* pMsg)
-{
- ndbout << pMsg;
-}
-
-void
-ConsoleLogHandler::writeFooter()
-{
- ndbout << getDefaultFooter() << flush;
-}
-
-
-bool
-ConsoleLogHandler::setParam(const BaseString &param, const BaseString &value) {
- return false;
-}
diff --git a/storage/ndb/src/common/logger/FileLogHandler.cpp b/storage/ndb/src/common/logger/FileLogHandler.cpp
deleted file mode 100644
index b2b8b7c7b31..00000000000
--- a/storage/ndb/src/common/logger/FileLogHandler.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <FileLogHandler.hpp>
-#include <File.hpp>
-
-//
-// PUBLIC
-//
-
-FileLogHandler::FileLogHandler() :
- LogHandler(),
- m_maxNoFiles(MAX_NO_FILES),
- m_maxFileSize(MAX_FILE_SIZE),
- m_maxLogEntries(MAX_LOG_ENTRIES)
-
-{
- m_pLogFile = new File_class("logger.log", "a+");
-}
-
-FileLogHandler::FileLogHandler(const char* aFileName,
- int maxNoFiles,
- long maxFileSize,
- unsigned int maxLogEntries) :
- LogHandler(),
- m_maxNoFiles(maxNoFiles),
- m_maxFileSize(maxFileSize),
- m_maxLogEntries(maxLogEntries)
-{
- m_pLogFile = new File_class(aFileName, "a+");
-}
-
-FileLogHandler::~FileLogHandler()
-{
- delete m_pLogFile;
-}
-
-bool
-FileLogHandler::open()
-{
- bool rc = true;
-
- if (m_pLogFile->open())
- {
- if (isTimeForNewFile())
- {
- if (!createNewFile())
- {
- setErrorCode(errno);
- rc = false;
- }
- }
- }
- else
- {
- setErrorCode(errno);
- rc = false;
- }
-
- return rc;
-}
-
-bool
-FileLogHandler::close()
-{
- bool rc = true;
- if (!m_pLogFile->close())
- {
- setErrorCode(errno);
- rc = false;
- }
-
- return rc;
-}
-
-void
-FileLogHandler::writeHeader(const char* pCategory, Logger::LoggerLevel level)
-{
- char str[LogHandler::MAX_HEADER_LENGTH];
- m_pLogFile->writeChar(getDefaultHeader(str, pCategory, level));
-}
-
-void
-FileLogHandler::writeMessage(const char* pMsg)
-{
- m_pLogFile->writeChar(pMsg);
-}
-
-void
-FileLogHandler::writeFooter()
-{
- static int callCount = 0;
- m_pLogFile->writeChar(getDefaultFooter());
- /**
- * The reason I also check the number of log entries instead of
- * only the log size, is that I do not want to check the file size
- * after each log entry which requires system calls and is quite slow.
- * TODO: Any better way?
- */
- if (callCount % m_maxLogEntries != 0) // Check every m_maxLogEntries
- {
- if (isTimeForNewFile())
- {
- if (!createNewFile())
- {
- // Baby one more time...
- createNewFile();
- }
- }
- callCount = 0;
- }
- callCount++;
-
- m_pLogFile->flush();
-}
-
-
-//
-// PRIVATE
-//
-
-bool
-FileLogHandler::isTimeForNewFile()
-{
- return (m_pLogFile->size() >= m_maxFileSize);
-}
-
-bool
-FileLogHandler::createNewFile()
-{
- bool rc = true;
- int fileNo = 1;
- char newName[PATH_MAX];
- time_t newMtime, preMtime = 0;
-
- do
- {
- if (fileNo >= m_maxNoFiles)
- {
- fileNo = 1;
- BaseString::snprintf(newName, sizeof(newName),
- "%s.%d", m_pLogFile->getName(), fileNo);
- break;
- }
- BaseString::snprintf(newName, sizeof(newName),
- "%s.%d", m_pLogFile->getName(), fileNo++);
- newMtime = File_class::mtime(newName);
- if (newMtime < preMtime)
- {
- break;
- }
- else
- {
- preMtime = newMtime;
- }
- } while (File_class::exists(newName));
-
- m_pLogFile->close();
- if (!File_class::rename(m_pLogFile->getName(), newName))
- {
- setErrorCode(errno);
- rc = false;
- }
-
- // Open again
- if (!m_pLogFile->open())
- {
- setErrorCode(errno);
- rc = false;
- }
-
- return rc;
-}
-
-bool
-FileLogHandler::setParam(const BaseString &param, const BaseString &value){
- if(param == "filename")
- return setFilename(value);
- if(param == "maxsize")
- return setMaxSize(value);
- if(param == "maxfiles")
- return setMaxFiles(value);
- setErrorStr("Invalid parameter");
- return false;
-}
-
-bool
-FileLogHandler::setFilename(const BaseString &filename) {
- close();
- if(m_pLogFile)
- delete m_pLogFile;
- m_pLogFile = new File_class(filename.c_str(), "a+");
- return open();
-}
-
-bool
-FileLogHandler::setMaxSize(const BaseString &size) {
- char *end;
- long val = strtol(size.c_str(), &end, 0); /* XXX */
- if(size.c_str() == end || val < 0)
- {
- setErrorStr("Invalid file size");
- return false;
- }
- if(end[0] == 'M')
- val *= 1024*1024;
- if(end[0] == 'k')
- val *= 1024;
-
- m_maxFileSize = val;
-
- return true;
-}
-
-bool
-FileLogHandler::setMaxFiles(const BaseString &files) {
- char *end;
- long val = strtol(files.c_str(), &end, 0);
- if(files.c_str() == end || val < 1)
- {
- setErrorStr("Invalid maximum number of files");
- return false;
- }
- m_maxNoFiles = val;
-
- return true;
-}
-
-bool
-FileLogHandler::checkParams() {
- if(m_pLogFile == NULL)
- {
- setErrorStr("Log file cannot be null.");
- return false;
- }
- return true;
-}
diff --git a/storage/ndb/src/common/logger/LogHandler.cpp b/storage/ndb/src/common/logger/LogHandler.cpp
deleted file mode 100644
index 4e8ad49d56d..00000000000
--- a/storage/ndb/src/common/logger/LogHandler.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "LogHandler.hpp"
-
-#include <NdbTick.h>
-
-//
-// PUBLIC
-//
-LogHandler::LogHandler() :
- m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
- m_errorCode(0),
- m_errorStr(NULL)
-{
- m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
- m_count_repeated_messages= 0;
- m_last_category[0]= 0;
- m_last_message[0]= 0;
- m_last_log_time= 0;
- m_now= 0;
- m_last_level= (Logger::LoggerLevel)-1;
-}
-
-LogHandler::~LogHandler()
-{
-}
-
-void
-LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
- const char* pMsg)
-{
- time_t now;
- now= ::time((time_t*)NULL);
-
- if (level != m_last_level ||
- strcmp(pCategory, m_last_category) ||
- strcmp(pMsg, m_last_message))
- {
- if (m_count_repeated_messages > 0) // print that message
- append_impl(m_last_category, m_last_level, m_last_message);
-
- m_last_level= level;
- strncpy(m_last_category, pCategory, sizeof(m_last_category));
- strncpy(m_last_message, pMsg, sizeof(m_last_message));
- }
- else // repeated message
- {
- if (now < (time_t) (m_last_log_time+m_max_repeat_frequency))
- {
- m_count_repeated_messages++;
- m_now= now;
- return;
- }
- }
-
- m_now= now;
-
- append_impl(pCategory, level, pMsg);
- m_last_log_time= now;
-}
-
-void
-LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level,
- const char* pMsg)
-{
- writeHeader(pCategory, level);
- if (m_count_repeated_messages <= 1)
- writeMessage(pMsg);
- else
- {
- BaseString str(pMsg);
- str.appfmt(" - Repeated %d times", m_count_repeated_messages);
- writeMessage(str.c_str());
- }
- m_count_repeated_messages= 0;
- writeFooter();
-}
-
-const char*
-LogHandler::getDefaultHeader(char* pStr, const char* pCategory,
- Logger::LoggerLevel level) const
-{
- char time[MAX_DATE_TIME_HEADER_LENGTH];
- BaseString::snprintf(pStr, MAX_HEADER_LENGTH, "%s [%s] %s -- ",
- getTimeAsString((char*)time),
- pCategory,
- Logger::LoggerLevelNames[level]);
-
- return pStr;
-}
-
-
-const char*
-LogHandler::getDefaultFooter() const
-{
- return "\n";
-}
-
-const char*
-LogHandler::getDateTimeFormat() const
-{
- return m_pDateTimeFormat;
-}
-
-void
-LogHandler::setDateTimeFormat(const char* pFormat)
-{
- m_pDateTimeFormat = (char*)pFormat;
-}
-
-char*
-LogHandler::getTimeAsString(char* pStr) const
-{
- struct tm* tm_now;
-#ifdef NDB_WIN32
- tm_now = localtime(&m_now);
-#else
- tm_now = ::localtime(&m_now); //uses the "current" timezone
-#endif
-
- BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,
- m_pDateTimeFormat,
- tm_now->tm_year + 1900,
- tm_now->tm_mon + 1, //month is [0,11]. +1 -> [1,12]
- tm_now->tm_mday,
- tm_now->tm_hour,
- tm_now->tm_min,
- tm_now->tm_sec);
-
- return pStr;
-}
-
-int
-LogHandler::getErrorCode() const
-{
- return m_errorCode;
-}
-
-void
-LogHandler::setErrorCode(int code)
-{
- m_errorCode = code;
-}
-
-
-char*
-LogHandler::getErrorStr()
-{
- return m_errorStr;
-}
-
-void
-LogHandler::setErrorStr(const char* str)
-{
- m_errorStr= (char*) str;
-}
-
-bool
-LogHandler::parseParams(const BaseString &_params) {
- Vector<BaseString> v_args;
-
- bool ret = true;
-
- _params.split(v_args, ",");
- for(size_t i=0; i < v_args.size(); i++) {
- Vector<BaseString> v_param_value;
- if(v_args[i].split(v_param_value, "=", 2) != 2)
- {
- ret = false;
- setErrorStr("Can't find key=value pair.");
- }
- else
- {
- v_param_value[0].trim(" \t");
- if (!setParam(v_param_value[0], v_param_value[1]))
- {
- ret = false;
- }
- }
- }
-
- if(!checkParams())
- ret = false;
- return ret;
-}
-
-bool
-LogHandler::checkParams() {
- return true;
-}
-
-//
-// PRIVATE
-//
diff --git a/storage/ndb/src/common/logger/LogHandlerList.cpp b/storage/ndb/src/common/logger/LogHandlerList.cpp
deleted file mode 100644
index c954d20cb96..00000000000
--- a/storage/ndb/src/common/logger/LogHandlerList.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "LogHandlerList.hpp"
-
-#include <LogHandler.hpp>
-
-//
-// PUBLIC
-//
-
-LogHandlerList::LogHandlerList() :
- m_size(0),
- m_pHeadNode(NULL),
- m_pTailNode(NULL),
- m_pCurrNode(NULL)
-{
-}
-
-LogHandlerList::~LogHandlerList()
-{
- removeAll();
-}
-
-void
-LogHandlerList::add(LogHandler* pNewHandler)
-{
- LogHandlerNode* pNode = new LogHandlerNode();
-
- if (m_pHeadNode == NULL)
- {
- m_pHeadNode = pNode;
- pNode->pPrev = NULL;
- }
- else
- {
- m_pTailNode->pNext = pNode;
- pNode->pPrev = m_pTailNode;
- }
- m_pTailNode = pNode;
- pNode->pNext = NULL;
- pNode->pHandler = pNewHandler;
-
- m_size++;
-}
-
-bool
-LogHandlerList::remove(LogHandler* pRemoveHandler)
-{
- LogHandlerNode* pNode = m_pHeadNode;
- bool removed = false;
- do
- {
- if (pNode->pHandler == pRemoveHandler)
- {
- removeNode(pNode);
- removed = true;
- break;
- }
- } while ( (pNode = next(pNode)) != NULL);
-
- return removed;
-}
-
-void
-LogHandlerList::removeAll()
-{
- while (m_pHeadNode != NULL)
- {
- removeNode(m_pHeadNode);
- }
-}
-
-LogHandler*
-LogHandlerList::next()
-{
- LogHandler* pHandler = NULL;
- if (m_pCurrNode == NULL)
- {
- m_pCurrNode = m_pHeadNode;
- if (m_pCurrNode != NULL)
- {
- pHandler = m_pCurrNode->pHandler;
- }
- }
- else
- {
- m_pCurrNode = next(m_pCurrNode); // Next node
- if (m_pCurrNode != NULL)
- {
- pHandler = m_pCurrNode->pHandler;
- }
- }
-
- return pHandler;
-}
-
-int
-LogHandlerList::size() const
-{
- return m_size;
-}
-
-//
-// PRIVATE
-//
-
-LogHandlerList::LogHandlerNode*
-LogHandlerList::next(LogHandlerNode* pNode)
-{
- LogHandlerNode* pCurr = pNode;
- if (pNode->pNext != NULL)
- {
- pCurr = pNode->pNext;
- }
- else
- {
- // Tail
- pCurr = NULL;
- }
- return pCurr;
-}
-
-LogHandlerList::LogHandlerNode*
-LogHandlerList::prev(LogHandlerNode* pNode)
-{
- LogHandlerNode* pCurr = pNode;
- if (pNode->pPrev != NULL) // head
- {
- pCurr = pNode->pPrev;
- }
- else
- {
- // Head
- pCurr = NULL;
- }
-
- return pCurr;
-}
-
-void
-LogHandlerList::removeNode(LogHandlerNode* pNode)
-{
- if (pNode->pPrev == NULL) // If head
- {
- m_pHeadNode = pNode->pNext;
- }
- else
- {
- pNode->pPrev->pNext = pNode->pNext;
- }
-
- if (pNode->pNext == NULL) // if tail
- {
- m_pTailNode = pNode->pPrev;
- }
- else
- {
- pNode->pNext->pPrev = pNode->pPrev;
- }
-
- pNode->pNext = NULL;
- pNode->pPrev = NULL;
- delete pNode->pHandler; // Delete log handler
- delete pNode;
-
- m_size--;
-}
diff --git a/storage/ndb/src/common/logger/LogHandlerList.hpp b/storage/ndb/src/common/logger/LogHandlerList.hpp
deleted file mode 100644
index 0552521d108..00000000000
--- a/storage/ndb/src/common/logger/LogHandlerList.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LOGHANDLERLIST_H
-#define LOGHANDLERLIST_H
-
-class LogHandler;
-#include <ndb_global.h>
-
-/**
- * Provides a simple linked list of log handlers.
- *
- * @see LogHandler
- * @version #@ $Id: LogHandlerList.hpp,v 1.2 2002/03/14 13:07:21 eyualex Exp $
- */
-class LogHandlerList
-{
-public:
- /**
- * Default Constructor.
- */
- LogHandlerList();
-
- /**
- * Destructor.
- */
- ~LogHandlerList();
-
- /**
- * Adds a new log handler.
- *
- * @param pNewHandler log handler.
- */
- void add(LogHandler* pNewHandler);
-
- /**
- * Removes a log handler from the list and call its destructor.
- *
- * @param pRemoveHandler the handler to remove
- */
- bool remove(LogHandler* pRemoveHandler);
-
- /**
- * Removes all log handlers.
- */
- void removeAll();
-
- /**
- * Returns the next log handler in the list.
- * returns a log handler or NULL.
- */
- LogHandler* next();
-
- /**
- * Returns the size of the list.
- */
- int size() const;
-private:
- /** List node */
- struct LogHandlerNode
- {
- LogHandlerNode* pPrev;
- LogHandlerNode* pNext;
- LogHandler* pHandler;
- };
-
- LogHandlerNode* next(LogHandlerNode* pNode);
- LogHandlerNode* prev(LogHandlerNode* pNode);
-
- void removeNode(LogHandlerNode* pNode);
-
- int m_size;
-
- LogHandlerNode* m_pHeadNode;
- LogHandlerNode* m_pTailNode;
- LogHandlerNode* m_pCurrNode;
-};
-
-#endif
-
-
diff --git a/storage/ndb/src/common/logger/Logger.cpp b/storage/ndb/src/common/logger/Logger.cpp
deleted file mode 100644
index 0c8b2aefc7b..00000000000
--- a/storage/ndb/src/common/logger/Logger.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "Logger.hpp"
-
-#include <LogHandler.hpp>
-#include <ConsoleLogHandler.hpp>
-#include <FileLogHandler.hpp>
-#include "LogHandlerList.hpp"
-
-#if !defined NDB_WIN32
-#include <SysLogHandler.hpp>
-#endif
-
-//
-// PUBLIC
-//
-const char* Logger::LoggerLevelNames[] = { "ON ",
- "DEBUG ",
- "INFO ",
- "WARNING ",
- "ERROR ",
- "CRITICAL",
- "ALERT ",
- "ALL "
- };
-Logger::Logger() :
- m_pCategory("Logger"),
- m_pConsoleHandler(NULL),
- m_pFileHandler(NULL),
- m_pSyslogHandler(NULL)
-{
- m_pHandlerList = new LogHandlerList();
- m_mutex= NdbMutex_Create();
- m_handler_mutex= NdbMutex_Create();
- disable(LL_ALL);
- enable(LL_ON);
- enable(LL_INFO);
-}
-
-Logger::~Logger()
-{
- removeAllHandlers();
- delete m_pHandlerList;
- NdbMutex_Destroy(m_handler_mutex);
- NdbMutex_Destroy(m_mutex);
-}
-
-void
-Logger::setCategory(const char* pCategory)
-{
- Guard g(m_mutex);
- m_pCategory = pCategory;
-}
-
-bool
-Logger::createConsoleHandler()
-{
- Guard g(m_handler_mutex);
- bool rc = true;
-
- if (m_pConsoleHandler == NULL)
- {
- m_pConsoleHandler = new ConsoleLogHandler();
- if (!addHandler(m_pConsoleHandler)) // TODO: check error code
- {
- rc = false;
- delete m_pConsoleHandler;
- m_pConsoleHandler = NULL;
- }
- }
-
- return rc;
-}
-
-void
-Logger::removeConsoleHandler()
-{
- Guard g(m_handler_mutex);
- if (removeHandler(m_pConsoleHandler))
- {
- m_pConsoleHandler = NULL;
- }
-}
-
-bool
-Logger::createFileHandler()
-{
- Guard g(m_handler_mutex);
- bool rc = true;
- if (m_pFileHandler == NULL)
- {
- m_pFileHandler = new FileLogHandler();
- if (!addHandler(m_pFileHandler)) // TODO: check error code
- {
- rc = false;
- delete m_pFileHandler;
- m_pFileHandler = NULL;
- }
- }
-
- return rc;
-}
-
-void
-Logger::removeFileHandler()
-{
- Guard g(m_handler_mutex);
- if (removeHandler(m_pFileHandler))
- {
- m_pFileHandler = NULL;
- }
-}
-
-bool
-Logger::createSyslogHandler()
-{
- Guard g(m_handler_mutex);
- bool rc = true;
- if (m_pSyslogHandler == NULL)
- {
-#if defined NDB_WIN32
- m_pSyslogHandler = new ConsoleLogHandler();
-#else
- m_pSyslogHandler = new SysLogHandler();
-#endif
- if (!addHandler(m_pSyslogHandler)) // TODO: check error code
- {
- rc = false;
- delete m_pSyslogHandler;
- m_pSyslogHandler = NULL;
- }
- }
-
- return rc;
-}
-
-void
-Logger::removeSyslogHandler()
-{
- Guard g(m_handler_mutex);
- if (removeHandler(m_pSyslogHandler))
- {
- m_pSyslogHandler = NULL;
- }
-}
-
-bool
-Logger::addHandler(LogHandler* pHandler)
-{
- Guard g(m_mutex);
- assert(pHandler != NULL);
-
- bool rc = pHandler->open();
- if (rc)
- {
- m_pHandlerList->add(pHandler);
- }
- else
- {
- delete pHandler;
- }
-
- return rc;
-}
-
-bool
-Logger::addHandler(const BaseString &logstring, int *err, int len, char* errStr) {
- size_t i;
- Vector<BaseString> logdest;
- Vector<LogHandler *>loghandlers;
- DBUG_ENTER("Logger::addHandler");
-
- logstring.split(logdest, ";");
-
- for(i = 0; i < logdest.size(); i++) {
- DBUG_PRINT("info",("adding: %s",logdest[i].c_str()));
-
- Vector<BaseString> v_type_args;
- logdest[i].split(v_type_args, ":", 2);
-
- BaseString type(v_type_args[0]);
- BaseString params;
- if(v_type_args.size() >= 2)
- params = v_type_args[1];
-
- LogHandler *handler = NULL;
-
-#ifndef NDB_WIN32
- if(type == "SYSLOG")
- {
- handler = new SysLogHandler();
- } else
-#endif
- if(type == "FILE")
- handler = new FileLogHandler();
- else if(type == "CONSOLE")
- handler = new ConsoleLogHandler();
-
- if(handler == NULL)
- {
- snprintf(errStr,len,"Could not create log destination: %s",
- logdest[i].c_str());
- DBUG_RETURN(false);
- }
- if(!handler->parseParams(params))
- {
- *err= handler->getErrorCode();
- if(handler->getErrorStr())
- strncpy(errStr, handler->getErrorStr(), len);
- DBUG_RETURN(false);
- }
- loghandlers.push_back(handler);
- }
-
- for(i = 0; i < loghandlers.size(); i++)
- addHandler(loghandlers[i]);
-
- DBUG_RETURN(true); /* @todo handle errors */
-}
-
-bool
-Logger::removeHandler(LogHandler* pHandler)
-{
- Guard g(m_mutex);
- int rc = false;
- if (pHandler != NULL)
- {
- rc = m_pHandlerList->remove(pHandler);
- }
-
- return rc;
-}
-
-void
-Logger::removeAllHandlers()
-{
- Guard g(m_mutex);
- m_pHandlerList->removeAll();
-}
-
-bool
-Logger::isEnable(LoggerLevel logLevel) const
-{
- Guard g(m_mutex);
- if (logLevel == LL_ALL)
- {
- for (unsigned i = 1; i < MAX_LOG_LEVELS; i++)
- if (!m_logLevels[i])
- return false;
- return true;
- }
- return m_logLevels[logLevel];
-}
-
-void
-Logger::enable(LoggerLevel logLevel)
-{
- Guard g(m_mutex);
- if (logLevel == LL_ALL)
- {
- for (unsigned i = 0; i < MAX_LOG_LEVELS; i++)
- {
- m_logLevels[i] = true;
- }
- }
- else
- {
- m_logLevels[logLevel] = true;
- }
-}
-
-void
-Logger::enable(LoggerLevel fromLogLevel, LoggerLevel toLogLevel)
-{
- Guard g(m_mutex);
- if (fromLogLevel > toLogLevel)
- {
- LoggerLevel tmp = toLogLevel;
- toLogLevel = fromLogLevel;
- fromLogLevel = tmp;
- }
-
- for (int i = fromLogLevel; i <= toLogLevel; i++)
- {
- m_logLevels[i] = true;
- }
-}
-
-void
-Logger::disable(LoggerLevel logLevel)
-{
- Guard g(m_mutex);
- if (logLevel == LL_ALL)
- {
- for (unsigned i = 0; i < MAX_LOG_LEVELS; i++)
- {
- m_logLevels[i] = false;
- }
- }
- else
- {
- m_logLevels[logLevel] = false;
- }
-}
-
-void
-Logger::alert(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_ALERT, pMsg, ap);
- va_end(ap);
-}
-
-void
-Logger::critical(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_CRITICAL, pMsg, ap);
- va_end(ap);
-}
-void
-Logger::error(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_ERROR, pMsg, ap);
- va_end(ap);
-}
-void
-Logger::warning(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_WARNING, pMsg, ap);
- va_end(ap);
-}
-
-void
-Logger::info(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_INFO, pMsg, ap);
- va_end(ap);
-}
-
-void
-Logger::debug(const char* pMsg, ...) const
-{
- va_list ap;
- va_start(ap, pMsg);
- log(LL_DEBUG, pMsg, ap);
- va_end(ap);
-}
-
-//
-// PROTECTED
-//
-
-void
-Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const
-{
- Guard g(m_mutex);
- if (m_logLevels[LL_ON] && m_logLevels[logLevel])
- {
- char buf[MAX_LOG_MESSAGE_SIZE];
- BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
- LogHandler* pHandler = NULL;
- while ( (pHandler = m_pHandlerList->next()) != NULL)
- {
- pHandler->append(m_pCategory, logLevel, buf);
- }
- }
-}
-
-//
-// PRIVATE
-//
-
-template class Vector<LogHandler*>;
diff --git a/storage/ndb/src/common/logger/Makefile.am b/storage/ndb/src/common/logger/Makefile.am
deleted file mode 100644
index 5dd1e14b649..00000000000
--- a/storage/ndb/src/common/logger/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = liblogger.la
-
-SOURCE_WIN = Logger.cpp LogHandlerList.cpp LogHandler.cpp \
- ConsoleLogHandler.cpp FileLogHandler.cpp
-liblogger_la_SOURCES = $(SOURCE_WIN) SysLogHandler.cpp
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-
-windoze-dsp: liblogger.dsp
-
-liblogger.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(SOURCE_WIN)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/logger/SysLogHandler.cpp b/storage/ndb/src/common/logger/SysLogHandler.cpp
deleted file mode 100644
index e4a0de92de5..00000000000
--- a/storage/ndb/src/common/logger/SysLogHandler.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SysLogHandler.hpp"
-
-#include <syslog.h>
-
-//
-// PUBLIC
-//
-
-SysLogHandler::SysLogHandler() :
- m_severity(LOG_INFO),
- m_pIdentity("NDB"),
- m_facility(LOG_USER)
-{
-}
-
-SysLogHandler::SysLogHandler(const char* pIdentity, int facility) :
- m_severity(LOG_INFO),
- m_pIdentity(pIdentity),
- m_facility(facility)
-{
-
-}
-
-SysLogHandler::~SysLogHandler()
-{
-}
-
-bool
-SysLogHandler::open()
-{
- ::setlogmask(LOG_UPTO(LOG_DEBUG)); // Log from EMERGENCY down to DEBUG
- ::openlog(m_pIdentity, LOG_PID|LOG_CONS|LOG_ODELAY, m_facility); // PID, CONSOLE delay openlog
-
- return true;
-}
-
-bool
-SysLogHandler::close()
-{
- ::closelog();
-
- return true;
-}
-
-void
-SysLogHandler::writeHeader(const char* pCategory, Logger::LoggerLevel level)
-{
- // Save category to be used by writeMessage...
- m_pCategory = pCategory;
- // Map LogLevel to syslog severity
- switch (level)
- {
- case Logger::LL_ALERT:
- m_severity = LOG_ALERT;
- break;
- case Logger::LL_CRITICAL:
- m_severity = LOG_CRIT;
- break;
- case Logger::LL_ERROR:
- m_severity = LOG_ERR;
- break;
- case Logger::LL_WARNING:
- m_severity = LOG_WARNING;
- break;
- case Logger::LL_INFO:
- m_severity = LOG_INFO;
- break;
- case Logger::LL_DEBUG:
- m_severity = LOG_DEBUG;
- break;
- default:
- m_severity = LOG_INFO;
- break;
- }
-
-}
-
-void
-SysLogHandler::writeMessage(const char* pMsg)
-{
- ::syslog(m_facility | m_severity, "[%s] %s", m_pCategory, pMsg);
-}
-
-void
-SysLogHandler::writeFooter()
-{
- // Need to close it everytime? Do we run out of file descriptors?
- //::closelog();
-}
-
-bool
-SysLogHandler::setParam(const BaseString &param, const BaseString &value) {
- if(param == "facility") {
- return setFacility(value);
- }
- return false;
-}
-
-static const struct syslog_facility {
- const char *name;
- int value;
-} facilitynames[] = {
- { "auth", LOG_AUTH },
-#ifdef LOG_AUTHPRIV
- { "authpriv", LOG_AUTHPRIV },
-#endif
- { "cron", LOG_CRON },
- { "daemon", LOG_DAEMON },
-#ifdef LOG_FTP
- { "ftp", LOG_FTP },
-#endif
- { "kern", LOG_KERN },
- { "lpr", LOG_LPR },
- { "mail", LOG_MAIL },
- { "news", LOG_NEWS },
- { "syslog", LOG_SYSLOG },
- { "user", LOG_USER },
- { "uucp", LOG_UUCP },
- { "local0", LOG_LOCAL0 },
- { "local1", LOG_LOCAL1 },
- { "local2", LOG_LOCAL2 },
- { "local3", LOG_LOCAL3 },
- { "local4", LOG_LOCAL4 },
- { "local5", LOG_LOCAL5 },
- { "local6", LOG_LOCAL6 },
- { "local7", LOG_LOCAL7 },
- { NULL, -1 }
-};
-
-bool
-SysLogHandler::setFacility(const BaseString &facility) {
- const struct syslog_facility *c;
- for(c = facilitynames; c->name != NULL; c++) {
- if(facility == c->name) {
- m_facility = c->value;
- close();
- open();
- return true;
- }
- }
- setErrorStr("Invalid syslog facility name");
- return false;
-}
diff --git a/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp b/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp
deleted file mode 100644
index 725eca59869..00000000000
--- a/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "LogHandlerListUnitTest.hpp"
-
-#include <ConsoleLogHandler.hpp>
-#include <FileLogHandler.hpp>
-#include <SysLogHandler.hpp>
-
-#include <NdbOut.hpp>
-
-typedef bool (*TESTFUNC)(const char*);
-typedef struct
-{
- const char* name;
- TESTFUNC test;
-}Tests;
-
-static Tests testCases[] = { {"Add", &LogHandlerListUnitTest::testAdd},
- {"Remove", &LogHandlerListUnitTest::testRemove},
- {"Traverse Next", &LogHandlerListUnitTest::testTraverseNext}
- };
-
-
-int testFailed = 0;
-
-int main(int argc, char* argv[])
-{
- char str[256];
- int testCount = (sizeof(testCases) / sizeof(Tests));
- ndbout << "Starting " << testCount << " tests..." << endl;
- for (int i = 0; i < testCount; i++)
- {
- ndbout << "-- " << " Test " << i + 1
- << " [" << testCases[i].name << "] --" << endl;
- BaseString::snprintf(str, 256, "%s %s %s %d", "Logging ",
- testCases[i].name, " message ", i);
- if (testCases[i].test(str))
- {
- ndbout << "-- Passed --" << endl;
- }
- else
- {
- ndbout << "-- Failed -- " << endl;
- }
-
- }
- ndbout << endl << "-- " << testCount - testFailed << " passed, "
- << testFailed << " failed --" << endl;
-
- return 0;
-}
-
-bool
-LogHandlerListUnitTest::testAdd(const char* msg)
-{
- bool rc = true;
- LogHandlerList list;
- int size = 10;
- for (int i = 0; i < size; i++)
- {
- list.add(new ConsoleLogHandler());
- }
- if (list.size() != size)
- {
- rc = false;
- }
- ndbout << "List size: " << list.size() << endl;
-
-
- return rc;
-}
-bool
-LogHandlerListUnitTest::testRemove(const char* msg)
-{
- bool rc = true;
-
- LogHandlerList list;
- int size = 10;
- LogHandler* pHandlers[10];
- for (int i = 0; i < size; i++)
- {
- pHandlers[i] = new ConsoleLogHandler();
- list.add(pHandlers[i]);
- }
-
- // Remove
-
- for (int i = 0; i < size; i++)
- {
- if (!list.remove(pHandlers[i]))
- {
- ndbout << "Could not remove handler!" << endl;
- }
- else
- {
- ndbout << "List size: " << list.size() << endl;
- }
- }
-
- return rc;
-
-}
-bool
-LogHandlerListUnitTest::testTraverseNext(const char* msg)
-{
- bool rc = true;
- LogHandlerList list;
- int size = 10;
- LogHandler* pHandlers[10];
-
- for (int i = 0; i < size; i++)
- {
- char* str = new char[3];
- pHandlers[i] = new ConsoleLogHandler();
- BaseString::snprintf(str, 3, "%d", i);
- pHandlers[i]->setDateTimeFormat(str);
- list.add(pHandlers[i]);
- }
-
- ndbout << "List size: " << list.size() << endl;
-
- LogHandler* pHandler = NULL;
- int i = 0;
- while ((pHandler = list.next()) != NULL)
- {
- ndbout << "Handler[" << i++ << "]:dateformat = "
- << pHandler->getDateTimeFormat() << endl;
- }
-
- list.removeAll();
-
- return rc;
-
-}
-
-void
-LogHandlerListUnitTest::error(const char* msg)
-{
- testFailed++;
- ndbout << "Test failed: " << msg << endl;
-}
-
-LogHandlerListUnitTest::LogHandlerListUnitTest()
-{
-}
-LogHandlerListUnitTest::~LogHandlerListUnitTest()
-{
-}
diff --git a/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp b/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp
deleted file mode 100644
index d2d040c25da..00000000000
--- a/storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LOGHANDLERLISTUNITTEST_H
-#define LOGHANDLERLISTUNITTEST_H
-
-#include "LogHandlerList.hpp"
-
-/**
- * Unit test of LogHandlerList.
- *
- * @version #@ $Id: LogHandlerListUnitTest.hpp,v 1.1 2002/03/13 17:59:15 eyualex Exp $
- */
-class LogHandlerListUnitTest
-{
-public:
-
- static bool testAdd(const char* msg);
- static bool testRemove(const char* msg);
- static bool testTraverseNext(const char* msg);
-
- void error(const char* msg);
-
- LogHandlerListUnitTest();
- ~LogHandlerListUnitTest();
-};
-#endif
diff --git a/storage/ndb/src/common/logger/listtest/Makefile b/storage/ndb/src/common/logger/listtest/Makefile
deleted file mode 100644
index 4688a5e5a2f..00000000000
--- a/storage/ndb/src/common/logger/listtest/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include .defs.mk
-
-TYPE :=
-
-BIN_TARGET := listtest
-BIN_TARGET_ARCHIVES := portlib logger general
-
-SOURCES := LogHandlerListUnitTest.cpp
-
-CCFLAGS_LOC += -I../ -I$(NDB_TOP)/include/logger -I$(NDB_TOP)/include/portlib
-
-include $(NDB_TOP)/Epilogue.mk
-
-
diff --git a/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp b/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp
deleted file mode 100644
index 60ad595c50f..00000000000
--- a/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "LoggerUnitTest.hpp"
-
-#include <Logger.hpp>
-#include <ConsoleLogHandler.hpp>
-#include <FileLogHandler.hpp>
-
-#include <SysLogHandler.hpp>
-
-#include <NdbOut.hpp>
-#include <NdbMain.h>
-
-typedef bool (*TESTFUNC)(const char*);
-typedef struct
-{
- const char* name;
- TESTFUNC test;
-}Tests;
-
-static Tests testCases[] = { {"Alert", &LoggerUnitTest::testAlert},
- {"Critical", &LoggerUnitTest::testCritical},
- {"Error", &LoggerUnitTest::testError},
- {"Warning", &LoggerUnitTest::testWarning},
- {"Info", &LoggerUnitTest::testInfo},
- {"Debug", &LoggerUnitTest::testDebug},
- {"Info to Critical", &LoggerUnitTest::testInfoCritical},
- {"All", &LoggerUnitTest::testAll},
- {"Off", &LoggerUnitTest::testOff}
- };
-
-static Logger logger;
-int testFailed = 0;
-
-NDB_COMMAND(loggertest, "loggertest", "loggertest -console | -file",
- "loggertest", 16384)
-{
- if (argc < 2)
- {
- ndbout << "Usage: loggertest -console | -file | -syslog" << endl;
- return 0;
- }
-
- if (strcmp(argv[1], "-console") == 0)
- {
- logger.createConsoleHandler();
- }
- else if (strcmp(argv[1], "-file") == 0)
- {
- logger.createFileHandler();
- //logger.addHandler(new FileLogHandler(argv[2]));
- }
- else if (strcmp(argv[1], "-syslog") == 0)
- {
- logger.createSyslogHandler();
- }
-
- logger.disable(Logger::LL_ALL);
-
- char str[256];
- int testCount = (sizeof(testCases) / sizeof(Tests));
- ndbout << "Starting " << testCount << " tests..." << endl;
- for (int i = 0; i < testCount; i++)
- {
- ndbout << "-- " << " Test " << i + 1
- << " [" << testCases[i].name << "] --" << endl;
- BaseString::snprintf(str, 256, "%s %s %s %d", "Logging ",
- testCases[i].name, " message ", i);
- if (testCases[i].test(str))
- {
- ndbout << "-- Passed --" << endl;
- }
- else
- {
- ndbout << "-- Failed -- " << endl;
- }
-
- }
- ndbout << endl << "-- " << testCount - testFailed << " passed, "
- << testFailed << " failed --" << endl;
-
- logger.removeAllHandlers();
-
- return 0;
-}
-
-bool
-LoggerUnitTest::logTo(Logger::LoggerLevel from, Logger::LoggerLevel to, const char* msg)
-{
- logger.enable(from, to);
- return logTo(from, msg);
-}
-
-bool
-LoggerUnitTest::logTo(Logger::LoggerLevel level, const char* msg)
-{
- logger.enable(level);
- logger.alert(msg);
- logger.critical(msg);
- logger.error(msg);
- logger.warning(msg);
- logger.info(msg);
- logger.debug(msg);
- logger.disable(level);
- return true;
-}
-
-bool
-LoggerUnitTest::testAll(const char* msg)
-{
- return logTo(Logger::LL_ALL, msg);
-}
-
-bool
-LoggerUnitTest::testOff(const char* msg)
-{
- return logTo(Logger::LL_OFF, msg);
-
-}
-
-bool
-LoggerUnitTest::testAlert(const char* msg)
-{
- return logTo(Logger::LL_ALERT, msg);
-}
-
-bool
-LoggerUnitTest::testCritical(const char* msg)
-{
- return logTo(Logger::LL_CRITICAL, msg);
-}
-
-bool
-LoggerUnitTest::testError(const char* msg)
-{
- return logTo(Logger::LL_ERROR, msg);
-}
-
-bool
-LoggerUnitTest::testWarning(const char* msg)
-{
- return logTo(Logger::LL_WARNING, msg);
-}
-
-bool
-LoggerUnitTest::testInfo(const char* msg)
-{
- return logTo(Logger::LL_INFO, msg);
-}
-
-bool
-LoggerUnitTest::testDebug(const char* msg)
-{
- return logTo(Logger::LL_DEBUG, msg);
-}
-
-bool
-LoggerUnitTest::testInfoCritical(const char* msg)
-{
- return logTo(Logger::LL_CRITICAL, Logger::LL_INFO, msg);
-}
-
-void
-LoggerUnitTest::error(const char* msg)
-{
- testFailed++;
- ndbout << "Test failed: " << msg << endl;
-}
-
-LoggerUnitTest::LoggerUnitTest()
-{
-}
-LoggerUnitTest::~LoggerUnitTest()
-{
-}
diff --git a/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp b/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp
deleted file mode 100644
index 0faab97d2c1..00000000000
--- a/storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LOGGERUNITTEST_H
-#define LOGGERUNITTEST_H
-
-#include "Logger.hpp"
-
-/**
- * Unit test of Logger.
- *
- * @version #@ $Id: LoggerUnitTest.hpp,v 1.1 2002/03/13 17:55:31 eyualex Exp $
- */
-class LoggerUnitTest
-{
-public:
-
- static bool testAll(const char* msg);
- static bool testOff(const char* msg);
- static bool testAlert(const char* msg);
- static bool testCritical(const char* msg);
- static bool testError(const char* msg);
- static bool testWarning(const char* msg);
- static bool testInfo(const char* msg);
- static bool testDebug(const char* msg);
- static bool testInfoCritical(const char* msg);
-
- static bool logTo(Logger::LoggerLevel level, const char* msg);
- static bool logTo(Logger::LoggerLevel from, Logger::LoggerLevel to, const char* msg);
-
- void error(const char* msg);
-
- LoggerUnitTest();
- ~LoggerUnitTest();
-};
-#endif
diff --git a/storage/ndb/src/common/logger/loggertest/Makefile b/storage/ndb/src/common/logger/loggertest/Makefile
deleted file mode 100644
index 0aef0ca2bce..00000000000
--- a/storage/ndb/src/common/logger/loggertest/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-include .defs.mk
-
-TYPE :=
-
-BIN_TARGET := loggertest
-BIN_TARGET_ARCHIVES := logger portlib general
-
-SOURCES := LoggerUnitTest.cpp
-
-CCFLAGS_LOC += -I$(NDB_TOP)/include/logger \
- -I$(NDB_TOP)/include/util \
- -I$(NDB_TOP)/include/portlib
-
-include $(NDB_TOP)/Epilogue.mk
-
-
diff --git a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
deleted file mode 100644
index b4409c4ff8e..00000000000
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_version.h>
-
-#include <ConfigRetriever.hpp>
-#include <SocketServer.hpp>
-
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-
-#include <NdbTCP.h>
-#include <NdbEnv.h>
-#include "MgmtErrorReporter.hpp"
-
-#include <uucode.h>
-#include <Properties.hpp>
-
-#include <socket_io.h>
-#include <NdbConfig.h>
-
-#include <NdbAutoPtr.hpp>
-
-#include <mgmapi.h>
-#include <mgmapi_config_parameters.h>
-#include <mgmapi_configuration.hpp>
-#include <ConfigValues.hpp>
-#include <NdbHost.h>
-
-//****************************************************************************
-//****************************************************************************
-
-ConfigRetriever::ConfigRetriever(const char * _connect_string,
- Uint32 version, Uint32 node_type,
- const char * _bindaddress,
- int timeout_ms)
-{
- DBUG_ENTER("ConfigRetriever::ConfigRetriever");
-
- m_version = version;
- m_node_type = node_type;
- _ownNodeId= 0;
- m_end_session= true;
-
- m_handle= ndb_mgm_create_handle();
-
- if (m_handle == 0) {
- setError(CR_ERROR, "Unable to allocate mgm handle");
- DBUG_VOID_RETURN;
- }
-
- ndb_mgm_set_timeout(m_handle, timeout_ms);
-
- if (ndb_mgm_set_connectstring(m_handle, _connect_string))
- {
- BaseString tmp(ndb_mgm_get_latest_error_msg(m_handle));
- tmp.append(" : ");
- tmp.append(ndb_mgm_get_latest_error_desc(m_handle));
- setError(CR_ERROR, tmp.c_str());
- DBUG_VOID_RETURN;
- }
-
- if (_bindaddress)
- {
- if (ndb_mgm_set_bindaddress(m_handle, _bindaddress))
- {
- setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
- DBUG_VOID_RETURN;
- }
- }
- resetError();
- DBUG_VOID_RETURN;
-}
-
-ConfigRetriever::~ConfigRetriever()
-{
- DBUG_ENTER("ConfigRetriever::~ConfigRetriever");
- if (m_handle) {
- if(m_end_session)
- ndb_mgm_end_session(m_handle);
- ndb_mgm_disconnect(m_handle);
- ndb_mgm_destroy_handle(&m_handle);
- }
- DBUG_VOID_RETURN;
-}
-
-Uint32
-ConfigRetriever::get_configuration_nodeid() const
-{
- return ndb_mgm_get_configuration_nodeid(m_handle);
-}
-
-Uint32 ConfigRetriever::get_mgmd_port() const
-{
- return ndb_mgm_get_connected_port(m_handle);
-}
-
-const char *ConfigRetriever::get_mgmd_host() const
-{
- return ndb_mgm_get_connected_host(m_handle);
-}
-
-const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
-{
- return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
-}
-
-//****************************************************************************
-//****************************************************************************
-
-int
-ConfigRetriever::do_connect(int no_retries,
- int retry_delay_in_seconds, int verbose)
-{
- return
- (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
- 0 : -1;
-}
-
-int
-ConfigRetriever::disconnect()
-{
- return ndb_mgm_disconnect(m_handle);
-}
-
-//****************************************************************************
-//****************************************************************************
-//****************************************************************************
-//****************************************************************************
-struct ndb_mgm_configuration*
-ConfigRetriever::getConfig() {
-
- struct ndb_mgm_configuration * p = 0;
-
- if(m_handle != 0)
- p = getConfig(m_handle);
-
- if(p == 0)
- return 0;
-
- if(!verifyConfig(p, _ownNodeId)){
- free(p);
- p= 0;
- }
-
- return p;
-}
-
-ndb_mgm_configuration *
-ConfigRetriever::getConfig(NdbMgmHandle m_handle_arg)
-{
- ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle_arg,
- m_version);
- if(conf == 0)
- {
- BaseString tmp(ndb_mgm_get_latest_error_msg(m_handle_arg));
- tmp.append(" : ");
- tmp.append(ndb_mgm_get_latest_error_desc(m_handle_arg));
- setError(CR_ERROR, tmp.c_str());
- return 0;
- }
- return conf;
-}
-
-ndb_mgm_configuration *
-ConfigRetriever::getConfig(const char * filename){
-#ifndef NDB_WIN32
-
- struct stat sbuf;
- const int res = stat(filename, &sbuf);
- if(res != 0){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename);
- setError(CR_ERROR, buf);
- return 0;
- }
- const Uint32 bytes = sbuf.st_size;
-
- Uint32 * buf2 = new Uint32[bytes/4+1];
-
- FILE * f = fopen(filename, "rb");
- if(f == 0){
- setError(CR_ERROR, "Failed to open file");
- delete []buf2;
- return 0;
- }
- Uint32 sz = fread(buf2, 1, bytes, f);
- fclose(f);
- if(sz != bytes){
- setError(CR_ERROR, "Failed to read file");
- delete []buf2;
- return 0;
- }
-
- ConfigValuesFactory cvf;
- if(!cvf.unpack(buf2, bytes)){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf), "Error while unpacking");
- setError(CR_ERROR, buf);
- delete []buf2;
- return 0;
- }
- delete [] buf2;
- return (ndb_mgm_configuration*)cvf.m_cfg;
-#else
- return 0;
-#endif
-}
-
-void
-ConfigRetriever::setError(ErrorType et, const char * s){
- errorString.assign(s ? s : "");
- latestErrorType = et;
-}
-
-void
-ConfigRetriever::resetError(){
- setError(CR_NO_ERROR,0);
-}
-
-int
-ConfigRetriever::hasError()
-{
- return latestErrorType != CR_NO_ERROR;
-}
-
-const char *
-ConfigRetriever::getErrorString(){
- return errorString.c_str();
-}
-
-bool
-ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){
-
- 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){
- BaseString::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, nodeid) != 0){
- BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
- setError(CR_ERROR, buf);
- return false;
- }
-
- const char * hostname;
- if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){
- BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST);
- setError(CR_ERROR, buf);
- return false;
- }
-
- const char * datadir;
- if(!ndb_mgm_get_string_parameter(it, CFG_NODE_DATADIR, &datadir)){
- NdbConfig_SetPath(datadir);
- }
-
- if (hostname && hostname[0] != 0 &&
- !SocketServer::tryBind(0,hostname)) {
- BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface,"
- " tried to bind, error = %d - %s",
- hostname, errno, strerror(errno));
- setError(CR_ERROR, buf);
- return false;
- }
-
- unsigned int _type;
- if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){
- BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
- CFG_TYPE_OF_SECTION);
- setError(CR_ERROR, buf);
- return false;
- }
-
- if(_type != m_node_type){
- const char *type_s, *alias_s, *type_s2, *alias_s2;
- alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
- &type_s);
- alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
- &type_s2);
- BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
- "node type %s(%s) don't match for nodeid %d",
- alias_s, type_s, alias_s2, type_s2, nodeid);
- setError(CR_ERROR, buf);
- return false;
- }
-
- /**
- * Check hostnames
- */
- ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
- for(iter.first(); iter.valid(); iter.next()){
-
- Uint32 type = CONNECTION_TYPE_TCP + 1;
- if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
- if(type != CONNECTION_TYPE_TCP) continue;
-
- 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);
-
- const char * name;
- struct in_addr addr;
- BaseString tmp;
- if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
- if(Ndb_getInAddr(&addr, name) != 0){
- tmp.assfmt("Unable to lookup/illegal hostname %s, "
- "connection from node %d to node %d",
- name, nodeid, remoteNodeId);
- setError(CR_ERROR, tmp.c_str());
- return false;
- }
- }
-
- if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
- if(Ndb_getInAddr(&addr, name) != 0){
- tmp.assfmt("Unable to lookup/illegal hostname %s, "
- "connection from node %d to node %d",
- name, nodeid, remoteNodeId);
- setError(CR_ERROR, tmp.c_str());
- return false;
- }
- }
- }
- return true;
-}
-
-int
-ConfigRetriever::setNodeId(Uint32 nodeid)
-{
- return ndb_mgm_set_configuration_nodeid(m_handle, nodeid);
-}
-
-Uint32
-ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
-{
- int res;
- _ownNodeId= 0;
- if(m_handle != 0)
- {
- while (1)
- {
- if(!ndb_mgm_is_connected(m_handle))
- if(!ndb_mgm_connect(m_handle, 0, 0, 0))
- goto next;
-
- res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type,
- no_retries == 0 /* only log last retry */);
- if(res >= 0)
- return _ownNodeId= (Uint32)res;
-
- next:
- int error = ndb_mgm_get_latest_error(m_handle);
- if (no_retries == 0 || error == NDB_MGM_ALLOCID_CONFIG_MISMATCH)
- break;
- no_retries--;
- NdbSleep_SecSleep(retry_delay_in_seconds);
- }
- BaseString tmp(ndb_mgm_get_latest_error_msg(m_handle));
- tmp.append(" : ");
- tmp.append(ndb_mgm_get_latest_error_desc(m_handle));
- setError(CR_ERROR, tmp.c_str());
- } else
- setError(CR_ERROR, "management server handle not initialized");
- return 0;
-}
diff --git a/storage/ndb/src/common/mgmcommon/IPCConfig.cpp b/storage/ndb/src/common/mgmcommon/IPCConfig.cpp
deleted file mode 100644
index 31444953e70..00000000000
--- a/storage/ndb/src/common/mgmcommon/IPCConfig.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_opt_defaults.h>
-#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
-#define DEBUG(t)
-#endif
-
-IPCConfig::IPCConfig(Properties * p)
-{
- theNoOfRemoteNodes = 0;
- the_ownId = 0;
- if(p != 0)
- props = new Properties(* p);
- else
- props = 0;
-}
-
-
-IPCConfig::~IPCConfig()
-{
- if(props != 0){
- delete props;
- }
-}
-
-int
-IPCConfig::init(){
- Uint32 nodeId;
-
- if(props == 0) return -1;
- if(!props->get("LocalNodeId", &nodeId)) {
- DEBUG( "Did not find local node id." );
- return -1;
- }
- the_ownId = nodeId;
-
- Uint32 noOfConnections;
- if(!props->get("NoOfConnections", &noOfConnections)) {
- DEBUG( "Did not find noOfConnections." );
- return -1;
- }
-
- for(Uint32 i = 0; i<noOfConnections; i++){
- const Properties * tmp;
- Uint32 node1, node2;
-
- if(!props->get("Connection", i, &tmp)) {
- DEBUG( "Did not find Connection." );
- return -1;
- }
- if(!tmp->get("NodeId1", &node1)) {
- DEBUG( "Did not find NodeId1." );
- return -1;
- }
- if(!tmp->get("NodeId2", &node2)) {
- DEBUG( "Did not find NodeId2." );
- return -1;
- }
-
- if(node1 == the_ownId && node2 != the_ownId)
- if(!addRemoteNodeId(node2)) {
- DEBUG( "addRemoteNodeId(node2) failed." );
- return -1;
- }
-
- if(node1 != the_ownId && node2 == the_ownId)
- if(!addRemoteNodeId(node1)) {
- DEBUG( "addRemoteNodeId(node2) failed." );
- return -1;
- }
- }
- return 0;
-}
-
-bool
-IPCConfig::addRemoteNodeId(NodeId nodeId){
- for(int i = 0; i<theNoOfRemoteNodes; i++)
- if(theRemoteNodeIds[i] == nodeId)
- return false;
- theRemoteNodeIds[theNoOfRemoteNodes] = nodeId;
- theNoOfRemoteNodes++;
- return true;
-}
-
-/**
- * Supply a nodeId,
- * and get next higher node id
- * Returns false if none found
- */
-bool
-IPCConfig::getNextRemoteNodeId(NodeId & nodeId) const {
- NodeId returnNode = MAX_NODES + 1;
- for(int i = 0; i<theNoOfRemoteNodes; i++)
- if(theRemoteNodeIds[i] > nodeId){
- if(theRemoteNodeIds[i] < returnNode){
- returnNode = theRemoteNodeIds[i];
- }
- }
- if(returnNode == (MAX_NODES + 1))
- return false;
- nodeId = returnNode;
- return true;
-}
-
-
-Uint32
-IPCConfig::getREPHBFrequency(NodeId id) const {
- const Properties * tmp;
- Uint32 out;
-
- /**
- * Todo: Fix correct heartbeat
- */
- if (!props->get("Node", id, &tmp) ||
- !tmp->get("HeartbeatIntervalRepRep", &out)) {
- DEBUG("Illegal Node or HeartbeatIntervalRepRep in config.");
- out = 10000;
- }
-
- return out;
-}
-
-const char*
-IPCConfig::getNodeType(NodeId id) const {
- const char * out;
- const Properties * tmp;
-
- if (!props->get("Node", id, &tmp) || !tmp->get("Type", &out)) {
- DEBUG("Illegal Node or NodeType in config.");
- out = "Unknown";
- }
-
- return out;
-}
-
-#include <mgmapi.h>
-Uint32
-IPCConfig::configureTransporters(Uint32 nodeId,
- const class ndb_mgm_configuration & config,
- class TransporterRegistry & tr){
- TransporterConfiguration conf;
-
- DBUG_ENTER("IPCConfig::configureTransporters");
-
- /**
- * Iterate over all MGM's an construct a connectstring
- * create mgm_handle and give it to the Transporter Registry
- */
- {
- const char *separator= "";
- BaseString connect_string;
- ndb_mgm_configuration_iterator iter(config, CFG_SECTION_NODE);
- for(iter.first(); iter.valid(); iter.next())
- {
- Uint32 type;
- if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
- if(type != NODE_TYPE_MGM) continue;
- const char* hostname;
- Uint32 port;
- if(iter.get(CFG_NODE_HOST, &hostname)) continue;
- if( strlen(hostname) == 0 ) continue;
- if(iter.get(CFG_MGM_PORT, &port)) continue;
- connect_string.appfmt("%s%s:%u",separator,hostname,port);
- separator= ",";
- }
- NdbMgmHandle h= ndb_mgm_create_handle();
- if ( h && connect_string.length() > 0 )
- {
- ndb_mgm_set_connectstring(h,connect_string.c_str());
- tr.set_mgm_handle(h);
- }
- }
-
- Uint32 noOfTransportersCreated= 0;
- ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION);
-
- for(iter.first(); iter.valid(); iter.next()){
-
- Uint32 nodeId1, nodeId2, remoteNodeId;
- const char * remoteHostName= 0, * localHostName= 0;
- 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);
-
- {
- const char * host1= 0, * host2= 0;
- iter.get(CFG_CONNECTION_HOSTNAME_1, &host1);
- iter.get(CFG_CONNECTION_HOSTNAME_2, &host2);
- localHostName = (nodeId == nodeId1 ? host1 : host2);
- remoteHostName = (nodeId == nodeId1 ? host2 : host1);
- }
-
- 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;
-
- Uint32 server_port= 0;
- if(iter.get(CFG_CONNECTION_SERVER_PORT, &server_port)) break;
-
- Uint32 nodeIdServer= 0;
- if(iter.get(CFG_CONNECTION_NODE_ID_SERVER, &nodeIdServer)) break;
-
- /*
- We check the node type.
- */
- Uint32 node1type, node2type;
- ndb_mgm_configuration_iterator node1iter(config, CFG_SECTION_NODE);
- ndb_mgm_configuration_iterator node2iter(config, CFG_SECTION_NODE);
- node1iter.find(CFG_NODE_ID,nodeId1);
- node2iter.find(CFG_NODE_ID,nodeId2);
- node1iter.get(CFG_TYPE_OF_SECTION,&node1type);
- node2iter.get(CFG_TYPE_OF_SECTION,&node2type);
-
- if(node1type==NODE_TYPE_MGM || node2type==NODE_TYPE_MGM)
- conf.isMgmConnection= true;
- else
- conf.isMgmConnection= false;
-
- if (nodeId == nodeIdServer && !conf.isMgmConnection) {
- tr.add_transporter_interface(remoteNodeId, localHostName, server_port);
- }
-
- DBUG_PRINT("info", ("Transporter between this node %d and node %d using port %d, signalId %d, checksum %d",
- nodeId, remoteNodeId, server_port, sendSignalId, checksum));
- /*
- This may be a dynamic port. It depends on when we're getting
- our configuration. If we've been restarted, we'll be getting
- a configuration with our old dynamic port in it, hence the number
- here is negative (and we try the old port number first).
-
- On a first-run, server_port will be zero (with dynamic ports)
-
- If we're not using dynamic ports, we don't do anything.
- */
-
- conf.localNodeId = nodeId;
- conf.remoteNodeId = remoteNodeId;
- conf.checksum = checksum;
- conf.signalId = sendSignalId;
- conf.s_port = server_port;
- conf.localHostName = localHostName;
- conf.remoteHostName = remoteHostName;
- conf.serverNodeId = nodeIdServer;
-
- switch(type){
- case CONNECTION_TYPE_SHM:
- if(iter.get(CFG_SHM_KEY, &conf.shm.shmKey)) break;
- if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shm.shmSize)) break;
-
- Uint32 tmp;
- if(iter.get(CFG_SHM_SIGNUM, &tmp)) break;
- conf.shm.signum= tmp;
-
- if(!tr.createSHMTransporter(&conf)){
- DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d",
- conf.localNodeId, conf.remoteNodeId));
- ndbout << "Failed to create SHM Transporter from: "
- << conf.localNodeId << " to: " << conf.remoteNodeId << endl;
- } else {
- noOfTransportersCreated++;
- }
- DBUG_PRINT("info", ("Created SHM Transporter using shmkey %d, "
- "buf size = %d", conf.shm.shmKey, conf.shm.shmSize));
-
- break;
-
- case CONNECTION_TYPE_SCI:
- if(iter.get(CFG_SCI_SEND_LIMIT, &conf.sci.sendLimit)) break;
- if(iter.get(CFG_SCI_BUFFER_MEM, &conf.sci.bufferSize)) break;
- if (nodeId == nodeId1) {
- if(iter.get(CFG_SCI_HOST2_ID_0, &conf.sci.remoteSciNodeId0)) break;
- if(iter.get(CFG_SCI_HOST2_ID_1, &conf.sci.remoteSciNodeId1)) break;
- } else {
- if(iter.get(CFG_SCI_HOST1_ID_0, &conf.sci.remoteSciNodeId0)) break;
- if(iter.get(CFG_SCI_HOST1_ID_1, &conf.sci.remoteSciNodeId1)) break;
- }
- if (conf.sci.remoteSciNodeId1 == 0) {
- conf.sci.nLocalAdapters = 1;
- } else {
- conf.sci.nLocalAdapters = 2;
- }
- if(!tr.createSCITransporter(&conf)){
- DBUG_PRINT("error", ("Failed to create SCI Transporter from %d to %d",
- conf.localNodeId, conf.remoteNodeId));
- ndbout << "Failed to create SCI Transporter from: "
- << conf.localNodeId << " to: " << conf.remoteNodeId << endl;
- } else {
- DBUG_PRINT("info", ("Created SCI Transporter: Adapters = %d, "
- "remote SCI node id %d",
- conf.sci.nLocalAdapters, conf.sci.remoteSciNodeId0));
- DBUG_PRINT("info", ("Host 1 = %s, Host 2 = %s, sendLimit = %d, "
- "buf size = %d", conf.localHostName,
- conf.remoteHostName, conf.sci.sendLimit,
- conf.sci.bufferSize));
- if (conf.sci.nLocalAdapters > 1) {
- DBUG_PRINT("info", ("Fault-tolerant with 2 Remote Adapters, "
- "second remote SCI node id = %d",
- conf.sci.remoteSciNodeId1));
- }
- noOfTransportersCreated++;
- continue;
- }
- break;
-
- case CONNECTION_TYPE_TCP:
- if(iter.get(CFG_TCP_SEND_BUFFER_SIZE, &conf.tcp.sendBufferSize)) break;
- if(iter.get(CFG_TCP_RECEIVE_BUFFER_SIZE, &conf.tcp.maxReceiveSize)) break;
-
- const char * proxy;
- if (!iter.get(CFG_TCP_PROXY, &proxy)) {
- if (strlen(proxy) > 0 && nodeId2 == nodeId) {
- // TODO handle host:port
- conf.s_port = atoi(proxy);
- }
- }
-
- if(!tr.createTCPTransporter(&conf)){
- ndbout << "Failed to create TCP Transporter from: "
- << nodeId << " to: " << remoteNodeId << endl;
- } else {
- noOfTransportersCreated++;
- }
- DBUG_PRINT("info", ("Created TCP Transporter: sendBufferSize = %d, "
- "maxReceiveSize = %d", conf.tcp.sendBufferSize,
- conf.tcp.maxReceiveSize));
- break;
- default:
- ndbout << "Unknown transporter type from: " << nodeId <<
- " to: " << remoteNodeId << endl;
- break;
- } // switch
- } // for
-
- DBUG_RETURN(noOfTransportersCreated);
-}
-
diff --git a/storage/ndb/src/common/mgmcommon/Makefile.am b/storage/ndb/src/common/mgmcommon/Makefile.am
deleted file mode 100644
index 4dc2d367550..00000000000
--- a/storage/ndb/src/common/mgmcommon/Makefile.am
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libmgmsrvcommon.la
-
-libmgmsrvcommon_la_SOURCES = \
- ConfigRetriever.cpp \
- IPCConfig.cpp
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/storage/ndb/src/mgmsrv
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-include $(top_srcdir)/storage/ndb/config/type_mgmapiclient.mk.am
-
-windoze-dsp: libmgmsrvcommon.dsp
-
-libmgmsrvcommon.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libmgmsrvcommon_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/mgmcommon/printConfig/Makefile b/storage/ndb/src/common/mgmcommon/printConfig/Makefile
deleted file mode 100644
index 77e8943e2c6..00000000000
--- a/storage/ndb/src/common/mgmcommon/printConfig/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi mgmapiclient
-
-BIN_TARGET := printConfig
-BIN_TARGET_ARCHIVES := general portlib
-
-CCFLAGS_LOC += -I..
-
-SOURCES := printConfig.cpp ../ConfigRetriever.cpp
-
-SOURCES.c := ../NdbConfig.c ../LocalConfig.c
-
-CFLAGS_printConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi)
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp b/storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp
deleted file mode 100644
index feabc2168ac..00000000000
--- a/storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbMain.h>
-#include <mgmapi.h>
-#include <ConfigRetriever.hpp>
-#include <Properties.hpp>
-#include <NdbOut.hpp>
-
-void usage(const char * prg){
- ndbout << "Usage " << prg
- << " host <mgm host> <mgm port> <node id> [<ver id>]" << endl;
-
- char buf[255];
- for(unsigned i = 0; i<strlen(prg); i++)
- buf[i] = ' ';
- buf[strlen(prg)] = 0;
- ndbout << " " << buf << " file <filename> <node id> [<ver id>]"
- << endl;
-}
-
-NDB_COMMAND(printConfig,
- "printConfig", "printConfig", "Prints configuration", 16384){
- if(argc < 4){
- usage(argv[0]);
- return 0;
- }
- if(strcmp("file", argv[1]) != 0 && strcmp("host", argv[1]) != 0){
- usage(argv[0]);
- return 0;
- }
-
- if(strcmp("host", argv[1]) == 0 && argc < 5){
- usage(argv[0]);
- return 0;
- }
-
- ConfigRetriever c;
- struct ndb_mgm_configuration * p = 0;
-
- if(strcmp("host", argv[1]) == 0){
- int verId = 0;
- if(argc > 5)
- verId = atoi(argv[5]);
-
- ndbout << "Getting config from: " << argv[2] << ":" << atoi(argv[3])
- << " NodeId =" << atoi(argv[4])
- << " VersionId = " << verId << endl;
-
- p = c.getConfig(argv[2],
- atoi(argv[3]),
- verId);
- } else if (strcmp("file", argv[1]) == 0){
- int verId = 0;
- if(argc > 4)
- verId = atoi(argv[4]);
-
- ndbout << "Getting config from: " << argv[2]
- << " NodeId =" << atoi(argv[3])
- << " VersionId = " << verId << endl;
-
- p = c.getConfig(argv[2], atoi(argv[3]), verId);
- }
-
- if(p != 0){
- //
- free(p);
- } else {
- ndbout << "Configuration not found: " << c.getErrorString() << endl;
- }
-
- return 0;
-}
diff --git a/storage/ndb/src/common/portlib/Makefile.am b/storage/ndb/src/common/portlib/Makefile.am
deleted file mode 100644
index e474764e69f..00000000000
--- a/storage/ndb/src/common/portlib/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2004, 2006 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libportlib.la
-
-libportlib_la_SOURCES = \
- NdbCondition.c NdbMutex.c NdbSleep.c NdbTick.c \
- NdbEnv.c NdbThread.c NdbHost.c NdbTCP.cpp \
- NdbDaemon.c NdbMem.c \
- NdbConfig.c
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_util.mk.am
-
-EXTRA_PROGRAMS = memtest PortLibTest munmaptest
-
-PortLibTest_SOURCES = NdbPortLibTest.cpp
-munmaptest_SOURCES = munmaptest.cpp
-
-WIN_src = win32/NdbCondition.c \
- win32/NdbDaemon.c \
- win32/NdbEnv.c \
- win32/NdbHost.c \
- win32/NdbMem.c \
- win32/NdbMutex.c \
- win32/NdbSleep.c \
- win32/NdbTCP.c \
- win32/NdbThread.c \
- win32/NdbTick.c
-
-windoze-dsp: libportlib.dsp
-
-libportlib.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(WIN_src)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/portlib/NdbCondition.c b/storage/ndb/src/common/portlib/NdbCondition.c
deleted file mode 100644
index 451e5f8ac8c..00000000000
--- a/storage/ndb/src/common/portlib/NdbCondition.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbCondition.h>
-#include <NdbThread.h>
-#include <NdbMutex.h>
-#include <NdbMem.h>
-
-struct NdbCondition
-{
- pthread_cond_t cond;
-};
-
-
-
-struct NdbCondition*
-NdbCondition_Create(void)
-{
- struct NdbCondition* tmpCond;
- int result;
-
- tmpCond = (struct NdbCondition*)NdbMem_Allocate(sizeof(struct NdbCondition));
-
- if (tmpCond == NULL)
- return NULL;
-
- result = pthread_cond_init(&tmpCond->cond, NULL);
-
- assert(result==0);
- return tmpCond;
-}
-
-
-
-int
-NdbCondition_Wait(struct NdbCondition* p_cond,
- NdbMutex* p_mutex)
-{
- int result;
-
- if (p_cond == NULL || p_mutex == NULL)
- return 1;
-
- result = pthread_cond_wait(&p_cond->cond, p_mutex);
-
- return result;
-}
-
-int
-NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
- NdbMutex* p_mutex,
- int msecs){
- int result;
- struct timespec abstime;
- int secs = 0;
-
- if (p_cond == NULL || p_mutex == NULL)
- return 1;
-
-#ifdef HAVE_CLOCK_GETTIME
- clock_gettime(CLOCK_REALTIME, &abstime);
-#else
- {
- struct timeval tick_time;
- gettimeofday(&tick_time, 0);
- abstime.tv_sec = tick_time.tv_sec;
- abstime.tv_nsec = tick_time.tv_usec * 1000;
- }
-#endif
-
- if(msecs >= 1000){
- secs = msecs / 1000;
- msecs = msecs % 1000;
- }
-
- abstime.tv_sec += secs;
- abstime.tv_nsec += msecs * 1000000;
- if (abstime.tv_nsec >= 1000000000) {
- abstime.tv_sec += 1;
- abstime.tv_nsec -= 1000000000;
- }
-
- result = pthread_cond_timedwait(&p_cond->cond, p_mutex, &abstime);
-
- return result;
-}
-
-int
-NdbCondition_Signal(struct NdbCondition* p_cond){
- int result;
-
- if (p_cond == NULL)
- return 1;
-
- result = pthread_cond_signal(&p_cond->cond);
-
- return result;
-}
-
-
-int NdbCondition_Broadcast(struct NdbCondition* p_cond)
-{
- int result;
-
- if (p_cond == NULL)
- return 1;
-
- result = pthread_cond_broadcast(&p_cond->cond);
-
- return result;
-}
-
-
-int NdbCondition_Destroy(struct NdbCondition* p_cond)
-{
- int result;
-
- if (p_cond == NULL)
- return 1;
-
- result = pthread_cond_destroy(&p_cond->cond);
- free(p_cond);
-
- return 0;
-}
-
diff --git a/storage/ndb/src/common/portlib/NdbConfig.c b/storage/ndb/src/common/portlib/NdbConfig.c
deleted file mode 100644
index da4fc997750..00000000000
--- a/storage/ndb/src/common/portlib/NdbConfig.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbConfig.h>
-#include <NdbEnv.h>
-#include <NdbMem.h>
-#include <basestring_vsnprintf.h>
-
-static const char *datadir_path= 0;
-
-const char *
-NdbConfig_get_path(int *_len)
-{
- const char *path= NdbEnv_GetEnv("NDB_HOME", 0, 0);
- int path_len= 0;
- if (path)
- path_len= strlen(path);
- if (path_len == 0 && datadir_path) {
- path= datadir_path;
- path_len= strlen(path);
- }
- if (path_len == 0) {
- path= ".";
- path_len= strlen(path);
- }
- if (_len)
- *_len= path_len;
- return path;
-}
-
-static char*
-NdbConfig_AllocHomePath(int _len)
-{
- int path_len;
- const char *path= NdbConfig_get_path(&path_len);
- int len= _len+path_len;
- char *buf= NdbMem_Allocate(len);
- basestring_snprintf(buf, len, "%s%s", path, DIR_SEPARATOR);
- return buf;
-}
-
-void
-NdbConfig_SetPath(const char* path){
- datadir_path= path;
-}
-
-char*
-NdbConfig_NdbCfgName(int with_ndb_home){
- char *buf;
- int len= 0;
-
- if (with_ndb_home) {
- buf= NdbConfig_AllocHomePath(PATH_MAX);
- len= strlen(buf);
- } else
- buf= NdbMem_Allocate(PATH_MAX);
- basestring_snprintf(buf+len, PATH_MAX, "Ndb.cfg");
- return buf;
-}
-
-static
-char *get_prefix_buf(int len, int node_id)
-{
- char tmp_buf[sizeof("ndb_pid#############")+1];
- char *buf;
- if (node_id > 0)
- basestring_snprintf(tmp_buf, sizeof(tmp_buf), "ndb_%u", node_id);
- else
- basestring_snprintf(tmp_buf, sizeof(tmp_buf), "ndb_pid%u", getpid());
- tmp_buf[sizeof(tmp_buf)-1]= 0;
-
- buf= NdbConfig_AllocHomePath(len+strlen(tmp_buf));
- strcat(buf, tmp_buf);
- return buf;
-}
-
-char*
-NdbConfig_ErrorFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_error.log");
- return buf;
-}
-
-char*
-NdbConfig_ClusterLogFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_cluster.log");
- return buf;
-}
-
-char*
-NdbConfig_SignalLogFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_signal.log");
- return buf;
-}
-
-char*
-NdbConfig_TraceFileName(int node_id, int file_no){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_trace.log.%u", file_no);
- return buf;
-}
-
-char*
-NdbConfig_NextTraceFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_trace.log.next");
- return buf;
-}
-
-char*
-NdbConfig_PidFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, ".pid");
- return buf;
-}
-
-char*
-NdbConfig_StdoutFileName(int node_id){
- char *buf= get_prefix_buf(PATH_MAX, node_id);
- int len= strlen(buf);
- basestring_snprintf(buf+len, PATH_MAX, "_out.log");
- return buf;
-}
diff --git a/storage/ndb/src/common/portlib/NdbDaemon.c b/storage/ndb/src/common/portlib/NdbDaemon.c
deleted file mode 100644
index 22d59925db7..00000000000
--- a/storage/ndb/src/common/portlib/NdbDaemon.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbDaemon.h"
-
-#define NdbDaemon_ErrorSize 500
-long NdbDaemon_DaemonPid = 0;
-int NdbDaemon_ErrorCode = 0;
-char NdbDaemon_ErrorText[NdbDaemon_ErrorSize] = "";
-
-int
-NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
-{
- int lockfd = -1, logfd = -1, n;
- char buf[64];
-
- (void)flags; /* remove warning for unused parameter */
-
- /* Check that we have write access to lock file */
- assert(lockfile != NULL);
- lockfd = open(lockfile, O_CREAT|O_RDWR, 0644);
- if (lockfd == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: open for write failed: %s", lockfile, strerror(errno));
- return -1;
- }
- /* Read any old pid from lock file */
- buf[0] = 0;
- n = read(lockfd, buf, sizeof(buf));
- if (n < 0) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: read failed: %s", lockfile, strerror(errno));
- return -1;
- }
- NdbDaemon_DaemonPid = atol(buf);
- if (lseek(lockfd, 0, SEEK_SET) == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: lseek failed: %s", lockfile, strerror(errno));
- return -1;
- }
-#ifdef F_TLOCK
- /* Test for lock before becoming daemon */
- if (lockf(lockfd, F_TLOCK, 0) == -1)
- {
- if (errno == EACCES || errno == EAGAIN) { /* results may vary */
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid);
- return -1;
- }
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: lock test failed: %s", lockfile, strerror(errno));
- return -1;
- }
-#endif
- /* Test open log file before becoming daemon */
- if (logfile != NULL) {
- logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644);
- if (logfd == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: open for write failed: %s", logfile, strerror(errno));
- return -1;
- }
- }
-#ifdef F_TLOCK
- if (lockf(lockfd, F_ULOCK, 0) == -1)
- {
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: fail to unlock", lockfile);
- return -1;
- }
-#endif
-
- /* Fork */
- n = fork();
- if (n == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "fork failed: %s", strerror(errno));
- return -1;
- }
- /* Exit if we are the parent */
- if (n != 0) {
- exit(0);
- }
- /* Running in child process */
- NdbDaemon_DaemonPid = getpid();
- /* Lock the lock file (likely to succeed due to test above) */
- if (lockf(lockfd, F_LOCK, 0) == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: lock failed: %s", lockfile, strerror(errno));
- return -1;
- }
- /* Become process group leader */
- if (setsid() == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "setsid failed: %s", strerror(errno));
- return -1;
- }
- /* Write pid to lock file */
- if (ftruncate(lockfd, 0) == -1) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: ftruncate failed: %s", lockfile, strerror(errno));
- return -1;
- }
- sprintf(buf, "%ld\n", NdbDaemon_DaemonPid);
- n = strlen(buf);
- if (write(lockfd, buf, n) != n) {
- NdbDaemon_ErrorCode = errno;
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "%s: write failed: %s", lockfile, strerror(errno));
- return -1;
- }
- /* Do input/output redirections (assume fd 0,1,2 not in use) */
- close(0);
- open("/dev/null", O_RDONLY);
- if (logfile != 0) {
- dup2(logfd, 1);
- dup2(logfd, 2);
- close(logfd);
- }
- /* Success */
- return 0;
-}
-
-#if 0
-int
-NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
-{
- /* Fail */
- snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
- "Daemon mode not implemented");
- return -1;
-}
-#endif
-
-#ifdef NDB_DAEMON_TEST
-
-int
-main()
-{
- if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
- fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
- return 1;
- }
- sleep(10);
- return 0;
-}
-
-#endif
diff --git a/storage/ndb/src/common/portlib/NdbEnv.c b/storage/ndb/src/common/portlib/NdbEnv.c
deleted file mode 100644
index 43a06d8352d..00000000000
--- a/storage/ndb/src/common/portlib/NdbEnv.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbEnv.h>
-
-const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
-{
- char* p = NULL;
- p = getenv(name);
-
- if (p != NULL && buf != NULL){
- strncpy(buf, p, buflen);
- buf[buflen-1] = 0;
- }
- return p;
-
-}
-
diff --git a/storage/ndb/src/common/portlib/NdbHost.c b/storage/ndb/src/common/portlib/NdbHost.c
deleted file mode 100644
index 4ac92d121c1..00000000000
--- a/storage/ndb/src/common/portlib/NdbHost.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include "NdbHost.h"
-
-int NdbHost_GetHostName(char* buf)
-{
- if (gethostname(buf, MAXHOSTNAMELEN) != 0)
- {
- return -1;
- }
- return 0;
-}
-
-int NdbHost_GetProcessId(void)
-{
- return getpid();
-}
-
diff --git a/storage/ndb/src/common/portlib/NdbMem.c b/storage/ndb/src/common/portlib/NdbMem.c
deleted file mode 100644
index c89e0747a8c..00000000000
--- a/storage/ndb/src/common/portlib/NdbMem.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbMem.h>
-
-void NdbMem_Create()
-{
- /* Do nothing */
- return;
-}
-
-void NdbMem_Destroy()
-{
- /* Do nothing */
- return;
-}
-
-
-void* NdbMem_Allocate(size_t size)
-{
- void* mem_allocated;
- assert(size > 0);
- mem_allocated= (void*)malloc(size);
- return mem_allocated;
-}
-
-void* NdbMem_AllocateAlign(size_t size, size_t alignment)
-{
- (void)alignment; /* remove warning for unused parameter */
- /*
- return (void*)memalign(alignment, size);
- TEMP fix
- */
- return (void*)malloc(size);
-}
-
-
-void NdbMem_Free(void* ptr)
-{
- free(ptr);
-}
-
-
-int NdbMem_MemLockAll(int i){
- if (i == 1)
- {
-#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined (MCL_FUTURE)
- return mlockall(MCL_CURRENT | MCL_FUTURE);
-#else
- return -1;
-#endif
- }
-#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
- return mlockall(MCL_CURRENT);
-#else
- return -1;
-#endif
-}
-
-int NdbMem_MemUnlockAll(){
-#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
- return munlockall();
-#else
- return -1;
-#endif
-}
-
diff --git a/storage/ndb/src/common/portlib/NdbMutex.c b/storage/ndb/src/common/portlib/NdbMutex.c
deleted file mode 100644
index 77a3e55e0b0..00000000000
--- a/storage/ndb/src/common/portlib/NdbMutex.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbThread.h>
-#include <NdbMutex.h>
-#include <NdbMem.h>
-
-NdbMutex* NdbMutex_Create(void)
-{
- NdbMutex* pNdbMutex;
- int result;
-
- pNdbMutex = (NdbMutex*)NdbMem_Allocate(sizeof(NdbMutex));
-
- if (pNdbMutex == NULL)
- return NULL;
-
- result = pthread_mutex_init(pNdbMutex, NULL);
- assert(result == 0);
-
- return pNdbMutex;
-}
-
-
-int NdbMutex_Destroy(NdbMutex* p_mutex)
-{
- int result;
-
- if (p_mutex == NULL)
- return -1;
-
- result = pthread_mutex_destroy(p_mutex);
-
- NdbMem_Free(p_mutex);
-
- return result;
-}
-
-
-int NdbMutex_Lock(NdbMutex* p_mutex)
-{
- int result;
-
- if (p_mutex == NULL)
- return -1;
-
- result = pthread_mutex_lock(p_mutex);
-
- return result;
-}
-
-
-int NdbMutex_Unlock(NdbMutex* p_mutex)
-{
- int result;
-
- if (p_mutex == NULL)
- return -1;
-
- result = pthread_mutex_unlock(p_mutex);
-
- return result;
-}
-
-
-int NdbMutex_Trylock(NdbMutex* p_mutex)
-{
- int result = -1;
-
- if (p_mutex != NULL) {
- result = pthread_mutex_trylock(p_mutex);
- }
-
- return result;
-}
-
diff --git a/storage/ndb/src/common/portlib/NdbPortLibTest.cpp b/storage/ndb/src/common/portlib/NdbPortLibTest.cpp
deleted file mode 100644
index 87f9246e171..00000000000
--- a/storage/ndb/src/common/portlib/NdbPortLibTest.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/**
- * NdbPortLibTest.cpp
- * Test the functionality of portlib
- * TODO - Add tests for NdbMem
- */
-
-#include <ndb_global.h>
-
-#include "NdbOut.hpp"
-#include "NdbThread.h"
-#include "NdbMutex.h"
-#include "NdbCondition.h"
-#include "NdbSleep.h"
-#include "NdbTick.h"
-#include "NdbEnv.h"
-#include "NdbHost.h"
-#include "NdbMain.h"
-
-int TestHasFailed;
-int verbose = 0;
-
-static void fail(const char* test, const char* cause)
-{
- TestHasFailed = 1;
- ndbout << test << " failed, " << cause << endl;
-}
-
-// test 1 variables and funcs
-
-extern "C" void* thread1func(void* arg)
-{
- int arg1;
- int returnvalue = 8;
- arg1 = *(int*)arg;
- ndbout << "thread1: thread1func called with arg = " << arg1 << endl;
-
- // delay(1000);
- if (arg1 != 7)
- fail("TEST1", "Wrong arg");
-
- return returnvalue;
-}
-
-// test 2 variables and funcs
-
-NdbMutex* test2mutex;
-
-extern "C" void* test2func(void* arg)
-{
-
- int arg1;
- arg1 = *(int*)arg;
- ndbout << "thread" << arg1 << " started in test2func" << endl;
-
- if (NdbMutex_Lock(test2mutex) != 0)
- fail("TEST2", "Failed to lock mutex");
-
- ndbout << "thread" << arg1 << ", test2func " << endl;
-
- if (NdbMutex_Unlock(test2mutex) != 0)
- fail("TEST2", "Failed to unlock mutex");
-
- int returnvalue = arg1;
- return returnvalue;
-}
-
-
-// test 3 and 7 variables and funcs
-
-NdbMutex* testmutex;
-NdbCondition* testcond;
-int testthreadsdone;
-
-extern "C" void* testfunc(void* arg)
-{
- int tmpVar;
- int threadno;
- int result;
-
- threadno = *(int*)arg;
-
- ndbout << "Thread" << threadno << " started in testfunc" << endl;
- do
- {
-
- if ((threadno % 2) == 0)
- result = NdbSleep_SecSleep(1);
- else
- result = NdbSleep_MilliSleep(100);
-
- if (result != 0)
- fail("TEST3", "Wrong result from sleep function");
-
- if (NdbMutex_Lock(testmutex) != 0)
- fail("TEST3", "Wrong result from NdbMutex_Lock function");
-
- ndbout << "thread" << threadno << ", testfunc " << endl;
- testthreadsdone++;
- tmpVar = testthreadsdone;
-
- if (NdbCondition_Signal(testcond) != 0)
- fail("TEST3", "Wrong result from NdbCondition_Signal function");
-
- if (NdbMutex_Unlock(testmutex) != 0)
- fail("TEST3", "Wrong result from NdbMutex_Unlock function");
-
- }
- while(tmpVar<100);
-
- return 0;
-}
-
-extern "C" void* testTryLockfunc(void* arg)
-{
- int tmpVar = 0;
- int threadno;
- int result;
-
- threadno = *(int*)arg;
-
- ndbout << "Thread" << threadno << " started" << endl;
- do
- {
-
- if ((threadno % 2) == 0)
- result = NdbSleep_SecSleep(1);
- else
- result = NdbSleep_MilliSleep(100);
-
- if (result != 0)
- fail("TEST3", "Wrong result from sleep function");
-
- if (NdbMutex_Trylock(testmutex) == 0){
-
- ndbout << "thread" << threadno << ", testTryLockfunc locked" << endl;
- testthreadsdone++;
- tmpVar = testthreadsdone;
-
- if (NdbCondition_Signal(testcond) != 0)
- fail("TEST3", "Wrong result from NdbCondition_Signal function");
-
- if (NdbMutex_Unlock(testmutex) != 0)
- fail("TEST3", "Wrong result from NdbMutex_Unlock function");
- }
-
- }
- while(tmpVar<100);
-
- return 0;
-}
-
-
-
-void testMicros(int count);
-Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2);
-
-NDB_COMMAND(PortLibTest, "portlibtest", "portlibtest", "Test the portable function layer", 4096){
-
- ndbout << "= TESTING ARGUMENT PASSING ============" << endl;
- ndbout << "ARGC: " << argc << endl;
- for(int i = 1; i < argc; i++){
- ndbout << " ARGV"<<i<<": " << (char*)argv[i] << endl;
- }
- ndbout << endl << endl;
-
-
- struct NdbThread* thread1var;
- void *status = 0;
- int arg = 7;
-
- TestHasFailed = 0;
- // create one thread and wait for it to return
- ndbout << "= TEST1 ===============================" << endl;
-
- thread1var = NdbThread_Create(thread1func, // Function
- (void**)&arg,// Arg
- 2048, // Stacksize
- (char*)"thread1", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread priority
-
-
- if(NdbThread_WaitFor(thread1var, &status) != 0)
- fail("TEST1", "NdbThread_WaitFor failed");
- // NOTE! thread return value is not yet used in Ndb and thus not tested(does not work)
- //ndbout << "thread1 returned, status = " << status << endl;
- //if (status != 8)
- // fail("TEST1", "Wrong status");
- ndbout << "TEST1 completed" << endl;
-
-
- NdbThread_Destroy(&thread1var);
-
- // Create 10 threads that will wait for a mutex before printing it's message to screen
- ndbout << "= TEST2 ===============================" << endl;
-#define T2_THREADS 10
- NdbThread* threads[T2_THREADS];
- int args[T2_THREADS];
- void *status2 = 0;
- test2mutex = NdbMutex_Create();
- NdbMutex_Lock(test2mutex);
-
- for (int i = 0; i < T2_THREADS; i++)
- {
- args[i] = i;
- threads[i] = NdbThread_Create(test2func, // Function
- (void**)&args[i],// Arg
- 2048, // Stacksize
- (char*)"test2thread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread priority
- if (threads[i] == NULL)
- fail("TEST2", "NdbThread_Create failed");
- }
-
- ndbout << "All threads created" << endl;
-
- NdbMutex_Unlock(test2mutex);
-
- for (int i = 0; i < T2_THREADS; i++)
- {
- if (NdbThread_WaitFor(threads[i], &status2))
- fail("TEST2", "NdbThread_WaitFor failed");
-
- NdbThread_Destroy(&threads[i]);
- // Don't test return values
- // ndbout << "thread" << i << " returned, status = " << status2 << endl;
- // if (status2 != i)
- // fail("TEST2", "Wrong status");
- }
-
- if (NdbMutex_Lock(test2mutex) != 0)
- fail("TEST2", "NdbMutex_Lock failed");
- if (NdbMutex_Unlock(test2mutex) != 0)
- fail("TEST2", "NdbMutex_Unlock failed");
- if (NdbMutex_Destroy(test2mutex) != 0)
- fail("TEST2", "NdbMutex_Destroy failed");
- ndbout << "TEST2 completed" << endl;
-
- ndbout << "= TEST3 ===============================" << endl;
- // Create 10 threads that will by synchronised by a condition
- // When they are awakened and have the mutex they will increment a global variable
-#define T3_THREADS 10
- NdbThread* t3threads[T3_THREADS];
- int t3args[T3_THREADS];
- void *status3 = 0;
-
- testmutex = NdbMutex_Create();
- testcond = NdbCondition_Create();
- testthreadsdone = 0;
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- t3args[i] = i;
- t3threads[i] = NdbThread_Create(testfunc, // Function
- (void**)&t3args[i],// Arg
- 2048, // Stacksize
- (char*)"test3thread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread priority
- }
-
- ndbout << "All threads created" << endl;
-
- if (NdbMutex_Lock(testmutex) != 0)
- fail("TEST3", "NdbMutex_Lock failed");
-
- while (testthreadsdone < T3_THREADS*10)
- {
- if(NdbCondition_Wait(testcond, testmutex) != 0)
- fail("TEST3", "NdbCondition_Wait failed");
- ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
- }
- if (NdbMutex_Unlock(testmutex) != 0)
- fail("TEST3", "NdbMutex_Unlock failed");
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
- fail("TEST3", "NdbThread_WaitFor failed");
-
- NdbThread_Destroy(&t3threads[i]);
- //ndbout << "thread" << i << " returned, status = " << status3 << endl;
- //if (status3 != i)
- // fail("TEST3", "Wrong status");
- }
-
- NdbMutex_Destroy(testmutex);
- NdbCondition_Destroy(testcond);
- ndbout << "TEST3 completed" << endl;
-
- ndbout << "= TEST4 ===============================" << endl;
- // Check tick functions
-
- //#if 0
-
- int sleeptimes[] = {78, 12, 199, 567, 899};
-
-
- for (int i = 0; i < 5; i++)
- {
- ndbout << "*------------------------------- Measure" << i << endl;
-
- NDB_TICKS millisec_now;
- NDB_TICKS millisec_now2;
-
- millisec_now = NdbTick_CurrentMillisecond();
- NdbSleep_MilliSleep(sleeptimes[i]);
- millisec_now2 = NdbTick_CurrentMillisecond();
-
- ndbout << " Time before sleep = " << millisec_now << endl;
- ndbout << " Time after sleep = " << millisec_now2 << endl;
- ndbout << " Tried to sleep "<<sleeptimes[i]<<" milliseconds." << endl;
- ndbout << " Sleep time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
-
- }
-
- ndbout << "TEST4 completed" << endl;
-
- ndbout << "= TEST5 ===============================" << endl;
- // Check NdbOut
-
- ndbout << "Testing hex and dec functions of NdbOut" << endl;
-
- for (int i = 0; i<= 0xFF; i++)
- {
- ndbout << i << "=" <<hex << i << "="<<dec << i << ", ";
- }
-
- ndbout << endl<< "Testing that hex is reset to dec by endl" << endl;
- ndbout << hex << 67 << endl;
- ndbout << 67 << endl;
-
- ndbout << "TEST5 completed" << endl;
-
-
- ndbout << "= TEST6 ===============================" << endl;
- const char* theEnvHostNamePtr;
- char buf[255];
- char theHostHostName[256];
- theEnvHostNamePtr = NdbEnv_GetEnv("HOSTNAME", buf, 255);
- if(theEnvHostNamePtr == NULL)
- fail("TEST6", "Could not get HOSTNAME from env");
- else{
- ndbout << "HOSTNAME from GetEnv" << theEnvHostNamePtr << endl;
-
- NdbHost_GetHostName(theHostHostName);
-
- ndbout << "HOSTNAME from GetHostName" <<theHostHostName << endl;
-
- if (strcmp(theEnvHostNamePtr, theHostHostName) != 0)
- fail("TEST6", "NdbHost_GetHostName or NdbEnv_GetEnv failed");
- }
-
- ndbout << "= TEST7 ===============================" << endl;
-
- testmutex = NdbMutex_Create();
- testcond = NdbCondition_Create();
- testthreadsdone = 0;
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- t3args[i] = i;
- t3threads[i] = NdbThread_Create(testfunc, // Function
- (void**)&t3args[i],// Arg
- 2048, // Stacksize
- (char*)"test7thread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread priority
- }
-
- ndbout << "All threads created" << endl;
-
- if (NdbMutex_Lock(testmutex) != 0)
- fail("TEST7", "NdbMutex_Lock failed");
-
- while (testthreadsdone < T3_THREADS*10)
- {
- // just testing the functionality without timing out, therefor 20 sec.
- if(NdbCondition_WaitTimeout(testcond, testmutex, 20000) != 0)
- fail("TEST7", "NdbCondition_WaitTimeout failed");
- ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
- }
- if (NdbMutex_Unlock(testmutex) != 0)
- fail("TEST7", "NdbMutex_Unlock failed");
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
- fail("TEST7", "NdbThread_WaitFor failed");
-
- NdbThread_Destroy(&t3threads[i]);
- }
-
- NdbMutex_Destroy(testmutex);
- NdbCondition_Destroy(testcond);
-
- ndbout << "TEST7 completed" << endl;
-
-
- ndbout << "= TEST8 ===============================" << endl;
- ndbout << " NdbCondition_WaitTimeout" << endl;
- testmutex = NdbMutex_Create();
- testcond = NdbCondition_Create();
-
- for (int i = 0; i < 5; i++)
- {
- ndbout << "*------------------------------- Measure" << i << endl;
-
- NDB_TICKS millisec_now;
- NDB_TICKS millisec_now2;
-
- millisec_now = NdbTick_CurrentMillisecond();
- if (NdbCondition_WaitTimeout(testcond, testmutex, sleeptimes[i]) != 0)
- fail("TEST8", "NdbCondition_WaitTimeout failed");
- millisec_now2 = NdbTick_CurrentMillisecond();
-
- ndbout << " Time before WaitTimeout = " << millisec_now << endl;
- ndbout << " Time after WaitTimeout = " << millisec_now2 << endl;
- ndbout << " Tried to wait "<<sleeptimes[i]<<" milliseconds." << endl;
- ndbout << " Wait time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
-
- }
-
- ndbout << "TEST8 completed" << endl;
-
-
- ndbout << "= TEST9 ===============================" << endl;
- ndbout << " NdbTick_CurrentXXXXXsecond compare" << endl;
-
- for (int i = 0; i < 5; i++)
- {
- ndbout << "*------------------------------- Measure" << i << endl;
-
- NDB_TICKS millisec_now;
- NDB_TICKS millisec_now2;
- Uint32 usec_now, usec_now2;
- Uint64 msec_now, msec_now2;
-
-
- millisec_now = NdbTick_CurrentMillisecond();
- NdbTick_CurrentMicrosecond( &msec_now, &usec_now);
-
- NdbSleep_MilliSleep(sleeptimes[i]);
-
- millisec_now2 = NdbTick_CurrentMillisecond();
- NdbTick_CurrentMicrosecond( &msec_now2, &usec_now2);
-
- Uint64 usecdiff = time_diff(msec_now,msec_now2,usec_now,usec_now2);
- NDB_TICKS msecdiff = millisec_now2 -millisec_now;
-
- ndbout << " Slept "<<sleeptimes[i]<<" milliseconds." << endl;
- ndbout << " Measured " << msecdiff <<" milliseconds with milli function ." << endl;
- ndbout << " Measured " << usecdiff/1000 << "," << usecdiff%1000<<" milliseconds with micro function ." << endl;
- }
-
- ndbout << "TEST9 completed" << endl;
-
-
- const int iter = 20;
- ndbout << "Testing microsecond timer - " << iter << " iterations" << endl;
- testMicros(iter);
- ndbout << "Testing microsecond timer - COMPLETED" << endl;
-
- ndbout << "= TEST10 ===============================" << endl;
-
- testmutex = NdbMutex_Create();
- testcond = NdbCondition_Create();
- testthreadsdone = 0;
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- t3args[i] = i;
- t3threads[i] = NdbThread_Create(testTryLockfunc, // Function
- (void**)&t3args[i],// Arg
- 2048, // Stacksize
- (char*)"test10thread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread priority
- }
-
- ndbout << "All threads created" << endl;
-
- if (NdbMutex_Lock(testmutex) != 0)
- fail("TEST10", "NdbMutex_Lock failed");
-
- while (testthreadsdone < T3_THREADS*10)
- {
- if(NdbCondition_Wait(testcond, testmutex) != 0)
- fail("TEST10", "NdbCondition_WaitTimeout failed");
- ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
- }
- if (NdbMutex_Unlock(testmutex) != 0)
- fail("TEST10", "NdbMutex_Unlock failed");
-
- for (int i = 0; i < T3_THREADS; i++)
- {
- if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
- fail("TEST10", "NdbThread_WaitFor failed");
-
- NdbThread_Destroy(&t3threads[i]);
- }
-
- NdbMutex_Destroy(testmutex);
- NdbCondition_Destroy(testcond);
-
- ndbout << "TEST10 completed" << endl;
-
-
- // Check total status of test
-
- if (TestHasFailed == 1)
- ndbout << endl << "TEST FAILED!" << endl;
- else
- ndbout << endl << "TEST PASSED!" << endl;
-
- return TestHasFailed;
-
-};
-
-Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2){
-
- Uint64 diff = 0;
- diff += (s2 - s1) * 1000000;
- if(m2 >= m1)
- diff += (m2 - m1);
- else {
- diff += m2;
- diff -= m1;
- }
-
- // if(0)
- // ndbout("(s1,m1) = (%d, %d) (s2,m2) = (%d, %d) -> diff = %d\n",
- // (Uint32)s1,m1,(Uint32)s2,m2, (Uint32)diff);
-
- return diff;
-};
-
-void
-testMicros(int count){
- Uint32 avg = 0;
- Uint32 sum2 = 0;
-
- for(int i = 0; i<count; i++){
- Uint64 s1, s2;
- Uint32 m1, m2;
- if(NdbTick_CurrentMicrosecond(&s1, &m1) != 0){
- ndbout << "Failed to get current micro" << endl;
- TestHasFailed = 1;
- return;
- }
- Uint32 r = (rand() % 1000) + 1;
- NdbSleep_MilliSleep(r);
- if(NdbTick_CurrentMicrosecond(&s2, &m2) != 0){
- ndbout << "Failed to get current micro" << endl;
- TestHasFailed = 1;
- return;
- }
- Uint64 m = time_diff(s1,s2,m1,m2);
- if(verbose)
- ndbout << "Slept for " << r << " ms"
- << " - Measured " << m << " us" << endl;
-
- if(m > (r*1000)){
- avg += (m - (r*1000));
- sum2 += (m - (r*1000)) * (m - (r*1000));
- } else {
- avg += ((r*1000) - m);
- sum2 += ((r*1000) - m) * ((r*1000) - m);
- }
-#if 0
- m /= 1000;
- if(m > r && ((m - r) > 10)){
- ndbout << "Difference to big: " << (m - r) << " - Test failed" << endl;
- TestHasFailed = 1;
- }
- if(m < r && ((r - m) > 10)){
- ndbout << "Difference to big: " << (r - m) << " - Test failed" << endl;
- TestHasFailed = 1;
- }
-#endif
- }
-
- Uint32 dev = (avg * avg - sum2) / count; dev /= count;
- avg /= count;
-
- Uint32 t = 0;
- while((t*t)<dev) t++;
- ndbout << "NOTE - measure are compared to NdbSleep_MilliSleep(...)" << endl;
- ndbout << "Average error = " << avg << " us" << endl;
- ndbout << "Stddev error = " << t << " us" << endl;
-}
diff --git a/storage/ndb/src/common/portlib/NdbSleep.c b/storage/ndb/src/common/portlib/NdbSleep.c
deleted file mode 100644
index d15cdd058d2..00000000000
--- a/storage/ndb/src/common/portlib/NdbSleep.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <NdbSleep.h>
-
-int
-NdbSleep_MilliSleep(int milliseconds){
- my_sleep(milliseconds*1000);
- return 0;
-#if 0
- int result = 0;
- struct timespec sleeptime;
- sleeptime.tv_sec = milliseconds / 1000;
- sleeptime.tv_nsec = (milliseconds - (sleeptime.tv_sec * 1000)) * 1000000;
- result = nanosleep(&sleeptime, NULL);
- return result;
-#endif
-}
-
-int
-NdbSleep_SecSleep(int seconds){
- int result = 0;
- result = sleep(seconds);
- return result;
-}
-
-
diff --git a/storage/ndb/src/common/portlib/NdbTCP.cpp b/storage/ndb/src/common/portlib/NdbTCP.cpp
deleted file mode 100644
index d2bfa96e009..00000000000
--- a/storage/ndb/src/common/portlib/NdbTCP.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <my_net.h>
-#include <NdbTCP.h>
-
-extern "C"
-int
-Ndb_getInAddr(struct in_addr * dst, const char *address) {
- // DBUG_ENTER("Ndb_getInAddr");
- {
- int tmp_errno;
- struct hostent tmp_hostent, *hp;
- char buff[GETHOSTBYNAME_BUFF_SIZE];
- hp = my_gethostbyname_r(address,&tmp_hostent,buff,sizeof(buff),
- &tmp_errno);
- if (hp)
- {
- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
- my_gethostbyname_r_free();
- return 0; //DBUG_RETURN(0);
- }
- my_gethostbyname_r_free();
- }
- /* Try it as aaa.bbb.ccc.ddd. */
- dst->s_addr = inet_addr(address);
- if (dst->s_addr !=
-#ifdef INADDR_NONE
- INADDR_NONE
-#else
- -1
-#endif
- )
- {
- return 0; //DBUG_RETURN(0);
- }
- // DBUG_PRINT("error",("inet_addr(%s) - %d - %s",
- // address, errno, strerror(errno)));
- return -1; //DBUG_RETURN(-1);
-}
-
-#ifndef DBUG_OFF
-extern "C"
-int NDB_CLOSE_SOCKET(int fd)
-{
- DBUG_PRINT("info", ("NDB_CLOSE_SOCKET(%d)", fd));
- return _NDB_CLOSE_SOCKET(fd);
-}
-#endif
-
-#if 0
-int
-Ndb_getInAddr(struct in_addr * dst, const char *address) {
- struct hostent host, * hostPtr;
- char buf[1024];
- int h_errno;
- hostPtr = gethostbyname_r(address, &host, &buf[0], 1024, &h_errno);
- if (hostPtr != NULL) {
- dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr;
- return 0;
- }
-
- /* Try it as aaa.bbb.ccc.ddd. */
- dst->s_addr = inet_addr(address);
- if (dst->s_addr != -1) {
- return 0;
- }
- return -1;
-}
-#endif
-
-int Ndb_check_socket_hup(NDB_SOCKET_TYPE sock)
-{
-#ifdef HAVE_POLL
- struct pollfd pfd[1];
- int r;
-
- pfd[0].fd= sock;
- pfd[0].events= POLLHUP | POLLIN | POLLOUT | POLLNVAL;
- pfd[0].revents= 0;
- r= poll(pfd,1,0);
- if(pfd[0].revents & (POLLHUP|POLLERR))
- return 1;
-
- return 0;
-#else /* HAVE_POLL */
- fd_set readfds, writefds, errorfds;
- struct timeval tv= {0,0};
- int s_err;
- int s_err_size= sizeof(s_err);
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&errorfds);
-
- FD_SET(sock, &readfds);
- FD_SET(sock, &writefds);
- FD_SET(sock, &errorfds);
-
- if(select(1, &readfds, &writefds, &errorfds, &tv)<0)
- return 1;
-
- if(FD_ISSET(sock,&errorfds))
- return 1;
-
- s_err=0;
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
- return(1);
-
- if (s_err)
- { /* getsockopt could succeed */
- return(1); /* but return an error... */
- }
-
- return 0;
-#endif /* HAVE_POLL */
-}
diff --git a/storage/ndb/src/common/portlib/NdbThread.c b/storage/ndb/src/common/portlib/NdbThread.c
deleted file mode 100644
index 01f08a2505a..00000000000
--- a/storage/ndb/src/common/portlib/NdbThread.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbThread.h>
-#include <my_pthread.h>
-#include <NdbMem.h>
-
-#define MAX_THREAD_NAME 16
-
-/*#define USE_PTHREAD_EXTRAS*/
-
-#ifdef NDB_SHM_TRANSPORTER
-int g_ndb_shm_signum= 0;
-#endif
-
-struct NdbThread
-{
- pthread_t thread;
- char thread_name[MAX_THREAD_NAME];
- NDB_THREAD_FUNC * func;
- void * object;
-};
-
-
-#ifdef NDB_SHM_TRANSPORTER
-void NdbThread_set_shm_sigmask(my_bool block)
-{
- DBUG_ENTER("NdbThread_set_shm_sigmask");
- if (g_ndb_shm_signum)
- {
- sigset_t mask;
- DBUG_PRINT("info",("Block signum %d",g_ndb_shm_signum));
- sigemptyset(&mask);
- sigaddset(&mask, g_ndb_shm_signum);
- if (block)
- pthread_sigmask(SIG_BLOCK, &mask, 0);
- else
- pthread_sigmask(SIG_UNBLOCK, &mask, 0);
- }
- DBUG_VOID_RETURN;
-}
-#endif
-
-
-static
-void*
-ndb_thread_wrapper(void* _ss){
- my_thread_init();
- {
- DBUG_ENTER("ndb_thread_wrapper");
-#ifdef NDB_SHM_TRANSPORTER
- NdbThread_set_shm_sigmask(TRUE);
-#endif
- {
- /**
- * Block all signals to thread by default
- * let them go to main process instead
- */
- sigset_t mask;
- sigfillset(&mask);
- pthread_sigmask(SIG_BLOCK, &mask, 0);
- }
-
- {
- void *ret;
- struct NdbThread * ss = (struct NdbThread *)_ss;
- ret= (* ss->func)(ss->object);
- DBUG_POP();
- NdbThread_Exit(ret);
- }
- /* will never be reached */
- DBUG_RETURN(0);
- }
-}
-
-
-struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
- NDB_THREAD_ARG *p_thread_arg,
- const NDB_THREAD_STACKSIZE _thread_stack_size,
- const char* p_thread_name,
- NDB_THREAD_PRIO thread_prio)
-{
- struct NdbThread* tmpThread;
- int result;
- pthread_attr_t thread_attr;
- NDB_THREAD_STACKSIZE thread_stack_size= _thread_stack_size * SIZEOF_CHARP/4;
-
- DBUG_ENTER("NdbThread_Create");
-
- (void)thread_prio; /* remove warning for unused parameter */
-
- if (p_thread_func == NULL)
- DBUG_RETURN(NULL);
-
- tmpThread = (struct NdbThread*)NdbMem_Allocate(sizeof(struct NdbThread));
- if (tmpThread == NULL)
- DBUG_RETURN(NULL);
-
- DBUG_PRINT("info",("thread_name: %s", p_thread_name));
-
- strnmov(tmpThread->thread_name,p_thread_name,sizeof(tmpThread->thread_name));
-
- pthread_attr_init(&thread_attr);
-#ifdef PTHREAD_STACK_MIN
- if (thread_stack_size < PTHREAD_STACK_MIN)
- thread_stack_size = PTHREAD_STACK_MIN;
-#endif
- pthread_attr_setstacksize(&thread_attr, thread_stack_size);
-#ifdef USE_PTHREAD_EXTRAS
- /* Guard stack overflow with a 2k databuffer */
- pthread_attr_setguardsize(&thread_attr, 2048);
-#endif
-
-#ifdef PTHREAD_CREATE_JOINABLE /* needed on SCO */
- pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
-#endif
- tmpThread->func= p_thread_func;
- tmpThread->object= p_thread_arg;
- result = pthread_create(&tmpThread->thread,
- &thread_attr,
- ndb_thread_wrapper,
- tmpThread);
- if (result != 0)
- {
- NdbMem_Free((char *)tmpThread);
- tmpThread = 0;
- }
-
- pthread_attr_destroy(&thread_attr);
- DBUG_PRINT("exit",("ret: 0x%lx", (long) tmpThread));
- DBUG_RETURN(tmpThread);
-}
-
-
-void NdbThread_Destroy(struct NdbThread** p_thread)
-{
- DBUG_ENTER("NdbThread_Destroy");
- if (*p_thread != NULL){
- DBUG_PRINT("enter",("*p_thread: 0x%lx", (long) *p_thread));
- free(* p_thread);
- * p_thread = 0;
- }
- DBUG_VOID_RETURN;
-}
-
-
-int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
-{
- int result;
-
- if (p_wait_thread == NULL)
- return 0;
-
- if (p_wait_thread->thread == 0)
- return 0;
-
- result = pthread_join(p_wait_thread->thread, status);
-
- return result;
-}
-
-
-void NdbThread_Exit(void *status)
-{
- my_thread_end();
- pthread_exit(status);
-}
-
-
-int NdbThread_SetConcurrencyLevel(int level)
-{
-#ifdef USE_PTHREAD_EXTRAS
- return pthread_setconcurrency(level);
-#else
- (void)level; /* remove warning for unused parameter */
- return 0;
-#endif
-}
diff --git a/storage/ndb/src/common/portlib/NdbTick.c b/storage/ndb/src/common/portlib/NdbTick.c
deleted file mode 100644
index 1e46664b663..00000000000
--- a/storage/ndb/src/common/portlib/NdbTick.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbTick.h>
-
-#define NANOSEC_PER_SEC 1000000000
-#define MICROSEC_PER_SEC 1000000
-#define MILLISEC_PER_SEC 1000
-#define MICROSEC_PER_MILLISEC 1000
-#define MILLISEC_PER_NANOSEC 1000000
-
-
-#ifdef HAVE_CLOCK_GETTIME
-NDB_TICKS NdbTick_CurrentMillisecond(void)
-{
- struct timespec tick_time;
- clock_gettime(CLOCK_REALTIME, &tick_time);
-
- return
- ((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)MILLISEC_PER_SEC) +
- ((NDB_TICKS)tick_time.tv_nsec) / ((NDB_TICKS)MILLISEC_PER_NANOSEC);
-}
-
-int
-NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
- struct timespec t;
- int res = clock_gettime(CLOCK_REALTIME, &t);
- * secs = t.tv_sec;
- * micros = t.tv_nsec / 1000;
- return res;
-}
-#else
-NDB_TICKS NdbTick_CurrentMillisecond(void)
-{
- struct timeval tick_time;
- gettimeofday(&tick_time, 0);
-
- return
- ((NDB_TICKS)tick_time.tv_sec) * ((NDB_TICKS)MILLISEC_PER_SEC) +
- ((NDB_TICKS)tick_time.tv_usec) / ((NDB_TICKS)MICROSEC_PER_MILLISEC);
-}
-
-int
-NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
- struct timeval tick_time;
- int res = gettimeofday(&tick_time, 0);
-
- if(secs==0) {
- NDB_TICKS local_secs = tick_time.tv_sec;
- *micros = tick_time.tv_usec;
- *micros = local_secs*1000000+*micros;
- } else {
- * secs = tick_time.tv_sec;
- * micros = tick_time.tv_usec;
- }
- return res;
-}
-
-#endif
-int
-NdbTick_getMicroTimer(struct MicroSecondTimer* input_timer)
-{
- NDB_TICKS secs;
- Uint32 mics;
- int ret_value;
- ret_value = NdbTick_CurrentMicrosecond(&secs, &mics);
- input_timer->seconds = secs;
- input_timer->micro_seconds = (NDB_TICKS)mics;
- return ret_value;
-}
-
-NDB_TICKS
-NdbTick_getMicrosPassed(struct MicroSecondTimer start,
- struct MicroSecondTimer stop)
-{
- NDB_TICKS ret_value = (NDB_TICKS)0;
- if (start.seconds < stop.seconds) {
- NDB_TICKS sec_passed = stop.seconds - start.seconds;
- ret_value = ((NDB_TICKS)MICROSEC_PER_SEC) * sec_passed;
- } else if (start.seconds > stop.seconds) {
- return ret_value;
- }
- if (start.micro_seconds < stop.micro_seconds) {
- ret_value += (stop.micro_seconds - start.micro_seconds);
- } else if (ret_value != (NDB_TICKS)0) {
- ret_value -= (start.micro_seconds - stop.micro_seconds);
- }
- return ret_value;
-}
diff --git a/storage/ndb/src/common/portlib/memtest.c b/storage/ndb/src/common/portlib/memtest.c
deleted file mode 100644
index 37d87de90e7..00000000000
--- a/storage/ndb/src/common/portlib/memtest.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <ndb_global.h>
-
-long long getMilli();
-long long getMicro();
-void malloctest(int loopcount, int memsize, int touch);
-void freetest(int loopcount, int memsize);
-void mmaptest(int loopcount, int memsize, int touch);
-void unmaptest(int loopcount, int memsize);
-
-
-main(int argc, char ** argv)
-{
-
- int loopcount;
- int memsize;
- if(argc < 4) {
- printf("Usage: memtest X loopcount memsize(MB)\n");
- printf("where X = \n");
- printf("1 : malloc test \n");
- printf("2 : mmap test \n");
- printf("3 : malloc test + touch pages\n");
- printf("4 : mmap test + touch pages\n");
- printf("5 : malloc/free test \n");
- printf("6 : mmap/munmap test \n");
- printf("loopcount - number of loops\n");
- printf("memsize - memory segment size to allocate in MB.\n");
- exit(1);
- }
-
-
- loopcount = atoi(argv[2]);
- memsize = atoi(argv[3]);
- switch(atoi(argv[1])) {
- case 1: malloctest(loopcount, memsize , 0 );
- break;
- case 2: mmaptest(loopcount, memsize,0);
- break;
- case 3: malloctest(loopcount, memsize,1);
- break;
- case 4: mmaptest(loopcount, memsize,1);
- break;
- case 5: freetest(loopcount, memsize);
- break;
- case 6: unmaptest(loopcount, memsize);
- break;
- default:
- break;
- }
-}
-
-long long getMilli() {
- struct timeval tick_time;
- gettimeofday(&tick_time, 0);
-
- return
- ((long long)tick_time.tv_sec) * ((long long)1000) +
- ((long long)tick_time.tv_usec) / ((long long)1000);
-}
-
-long long getMicro(){
- struct timeval tick_time;
- int res = gettimeofday(&tick_time, 0);
-
- long long secs = tick_time.tv_sec;
- long long micros = tick_time.tv_usec;
-
- micros = secs*1000000+micros;
- return micros;
-}
-
-void malloctest(int loopcount, int memsize, int touch) {
- long long start=0;
- int total=0;
- int i=0, j=0;
- int size=memsize*1024*1024; /*bytes*/;
- float mean;
- char * ptr =0;
-
- printf("Staring malloctest ");
- if(touch)
- printf("with touch\n");
- else
- printf("\n");
-
- start=getMicro();
-
- for(i=0; i<loopcount; i++){
- ptr=(char *)malloc((size_t)(size));
- if(ptr==0) {
- printf("failed to malloc!\n");
- return;
- }
- if(touch) {
- for(j=0; j<size; j=j+4096)
- ptr[j]=1;
- }
- }
- total=(int)(getMicro()-start);
-
- mean=(float)((float)total/(float)loopcount);
- printf("Total time malloc %d bytes: %2.3f microsecs loopcount %d touch %d \n",
- size, mean,loopcount, touch);
-}
-
-
-void mmaptest(int loopcount, int memsize, int touch) {
- long long start=0;
- int total=0;
- int i=0, j=0;
- char * ptr;
- int size=memsize*1024*1024; /*bytes*/;
- float mean;
-
- printf("Staring mmaptest ");
- if(touch)
- printf("with touch \n");
- else
- printf("\n");
-
- start=getMicro();
- for(i=0; i<loopcount; i++){
- ptr = mmap(0,
- size,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
- 0,
- 0);
- if(ptr<0) {
- printf("failed to mmap!\n");
- return;
- }
-
- if(touch) {
- for(j=0; j<size; j=j+4096)
- ptr[j]=1;
- }
- }
- total=(int)(getMicro()-start);
- mean=(float)((float)total/(float)loopcount);
- printf("Total time mmap %d bytes: %2.3f microsecs \n",size, mean);
-}
-
-
-void unmaptest(loopcount, memsize)
-{
- long long start=0;
- int total=0;
- int i=0, j=0;
- char * ptr;
- int size=memsize*1024*1024; /*bytes*/;
- float mean;
-
- printf("Staring munmap test (loopcount = 1 no matter what you prev. set)\n");
-
- loopcount = 1;
-
-
- for(i=0; i<loopcount; i++){
- ptr =(char*) mmap(0,
- size,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
- 0,
- 0);
- if(ptr<0) {
- printf("failed to mmap!\n");
- return;
- }
-
-
- for(j=0; j<size; j=j+1)
- ptr[j]='1';
- start=getMicro();
- if(munmap(ptr, size)<0) {
- printf("failed to munmap!\n");
- return;
- }
-
- total=(int)(getMicro()-start);
- /*
- for(j=8192; j<size; j=j+4096) {
-
- *(ptr+j)='1';
- }
-
- for(j=0; j<4096; j=j+4096) {
- *(ptr+j)='1';
- }
-
- */
- }
- mean=(float)((float)total/(float)loopcount);
- printf("Total time unmap %d bytes: %2.3f microsecs \n",size, mean);
-}
-
-void freetest(int loopcount, int memsize) {
- long long start=0;
- int total=0;
- int i=0, j=0;
- int size=memsize*1024*1024; /*bytes*/;
- float mean;
- char * ptr =0;
-
- loopcount = 1;
- printf("Staring free test (loopcount = 1 no matter what you prev. set)\n");
-
-
- for(i=0; i<loopcount; i++){
- ptr=(char*)malloc((size_t)(size));
- if(ptr==0) {
- printf("failed to malloc!\n");
- return;
- }
- for(j=0; j<size; j=j+4096)
- ptr[j]='1';
- start=getMicro();
- free(ptr);
- total=(int)(getMicro()-start);
- }
-
-
- mean=(float)((float)total/(float)loopcount);
- printf("Total time free %d bytes: %2.3f microsecs loopcount %d \n",
- size, mean,loopcount);
-}
diff --git a/storage/ndb/src/common/portlib/mmstest.cpp b/storage/ndb/src/common/portlib/mmstest.cpp
deleted file mode 100644
index adfef7b3ccd..00000000000
--- a/storage/ndb/src/common/portlib/mmstest.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-#include "NdbThread.h"
-#include <NdbMem.h>
-#include <NdbMain.h>
-
-NDB_COMMAND(ndbmem, "ndbmem", "ndbmem", "Test the ndbmem functionality", 4096){
-
- ndbout << "Starting test of NdbMem" << endl;
- ndbout << "=======================" << endl;
-
- ndbout << "Creating NdbMem" << endl;
- NdbMem_Create();
-
-
- ndbout << "NdbMem - test 1" << endl;
- if (argc == 2){
- int size1 = atoi(argv[1]);
- ndbout << "Allocate and test "<<size1<<" bytes of memory" << endl;
- char* mem1 = (char*)NdbMem_Allocate(size1);
- ndbout << "mem1 = " << hex << (int)mem1 << endl;
- if (mem1 != NULL){
- char* p1;
-
- // Write to the memory allocated
- p1 = mem1;
- for(int i = 0; i < size1; i++){
- *p1 = (char)(i%256);
- p1++;
- }
-
- // Read from the memory and check value
- char read1;
- char* pread1;
- pread1 = mem1;
- for(int i = 0; i < size1; i++){
- read1 = *pread1;
- //ndbout << i << "=" << read1 << endl;
- if (read1 != (i%256))
- ndbout << "Byte " << i << " was not correct, read1=" << read1 << endl;
- pread1++;
- }
-
- ndbout << "Freeing NdbMem" << endl;
- NdbMem_Free(mem1);
- }
-
- ndbout << "Destroying NdbMem" << endl;
- NdbMem_Destroy();
- }else{
- ndbout << "Usage: ndbmem <size(bytes)>"<< endl;
- }
-
- return NULL;
-
-}
-
-
-
diff --git a/storage/ndb/src/common/portlib/munmaptest.cpp b/storage/ndb/src/common/portlib/munmaptest.cpp
deleted file mode 100644
index 7977dc88634..00000000000
--- a/storage/ndb/src/common/portlib/munmaptest.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-#include <NdbThread.h>
-#include <NdbMutex.h>
-#include <NdbCondition.h>
-#include <NdbSleep.h>
-#include <NdbTick.h>
-#include <NdbEnv.h>
-#include <NdbHost.h>
-#include <NdbMain.h>
-#include <getarg.h>
-
-struct ThreadData
-{
- char * mapAddr;
- Uint32 mapSize;
- Uint32 chunk;
- Uint32 idx;
-
-};
-
-long long getMilli();
-long long getMicro();
-
-
-void* mapSegment(void * arg);
-void* unmapSegment(void * arg);
-
-
-void* mapSegment(void * arg) {
-
- ThreadData * threadArgs;
- long long start=0;
- int total=0;
- int id = *(int *)arg;
- threadArgs = new ThreadData [1];
- Uint32 size=5*1024*1024;
- struct NdbThread* unmapthread_var;
- void *status = 0;
- int run = 1;
- int max=0, min =100000000, sum=0;
- while(run < 1001) {
- start=getMicro();
- char * ptr =(char*) mmap(0,
- size,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
- 0,
- 0);
-
- total=(int)(getMicro()-start);
-
- ndbout << "T" << id << ": mmap took : " << total << " microsecs. "
- << " Run: " << run ;
- ndbout_c(" mapped @ %p \n", ptr);
-
- if(total>max)
- max = total;
- if(total<min)
- min=total;
-
- sum+=total;
-
- if(ptr<0) {
- ndbout << "failed to mmap!" << endl;
- exit(1);
- }
-
-
- threadArgs[0].mapAddr = (char *)ptr;
- threadArgs[0].mapSize = size;
- threadArgs[0].chunk = 4096;
- threadArgs[0].idx = 0;
-
-
- for(Uint32 j=0; j<size; j=j+4096)
- ptr[j]='1';
-
- unmapthread_var = NdbThread_Create(unmapSegment, // Function
- (void**)&threadArgs[0],// Arg
- 32768, // Stacksize
- (char*)"unmapthread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread prio
-
-
- if(NdbThread_WaitFor(unmapthread_var, &status) != 0) {
- ndbout << "test failed - exitting " << endl;
- exit(1);
- }
- run++;
- }
-
- ndbout << "MAX: " << max << " MIN: " << min;
- float mean = (float) ((float)sum/(float)run);
- ndbout_c(" AVERAGE: %2.5f\n",mean);
-}
-
-
-
-void* unmapSegment(void * arg)
-{
-
- char * freeAddr;
- char * mapAddr;
- ThreadData * threadData = (ThreadData*) arg;
- int start=0;
- int total=0;
- Uint32 mapSize = threadData->mapSize;
- Uint32 chunk = threadData->chunk;
- mapAddr = threadData->mapAddr;
-
-
-
- freeAddr = mapAddr+mapSize-chunk;
- NdbSleep_MilliSleep(100);
- for(Uint32 i=0;i<mapSize; i = i+chunk) {
- start=getMicro();
- if(munmap(freeAddr, chunk) < 0){
- ndbout << "munmap failed" << endl;
- exit(1);
- }
- total=(int)(getMicro()-start);
- freeAddr = freeAddr - chunk;
- NdbSleep_MilliSleep(10);
- ndbout << "unmap 4096 bytes : " << total << "microsecs" << endl;
- }
- return NULL;
-}
-
-
-static int trash;
-static int segmentsize=1;
-
-
-static struct getargs args[] = {
- { "trash", 't', arg_integer, &trash,
- "trash the memory before (1 to trash 0 to not trash)", "trash"},
- { "segment", 's', arg_integer, &segmentsize,
- "segment size (in MB)", "segment"},
-};
-
-
-static const int num_args = sizeof(args) / sizeof(args[0]);
-
-NDB_MAIN(munmaptest) {
-
- const char *progname = "munmaptest";
- int optind = 0;
-
- if(getarg(args, num_args, argc, argv, &optind)) {
- arg_printusage(args, num_args, progname, "");
- exit(1);
- }
-
- int size;
- char * ptr;
- if(trash) {
- for(int i=0; i<100; i++) {
- size=1+(int) (10.0*rand()/(RAND_MAX+1.0));
- NdbSleep_MilliSleep(10);
- ptr =(char*) mmap(0,
- size*1024*1024,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
- 0,
- 0);
- for(int i=0;i<(size*1024*1024); i=i+4096) {
- *(ptr+i)='1';
- }
- NdbSleep_MilliSleep(10);
-
- munmap(ptr,size);
-
- }
-
-
- }
-
- int noThreads = 1;
- struct NdbThread* mapthread_var;
- int id[noThreads];
- void *status=0;
-
- ThreadData * threadArgs = new ThreadData[noThreads];
-
-
-
-
- for(int i=0; i < noThreads; i++) {
- threadArgs[i].mapSize = segmentsize*1024*1024;
- threadArgs[i].idx = i;
- mapthread_var = NdbThread_Create(mapSegment, // Function
- (void**)&threadArgs[i],// Arg
- 32768, // Stacksize
- (char*)"mapthread", // Thread name
- NDB_THREAD_PRIO_MEAN); // Thread prio
-
- }
-
-
- if(NdbThread_WaitFor(mapthread_var, &status) != 0) {
- ndbout << "test failed - exitting " << endl;
- exit(1);
- }
-
-}
-
-long long getMilli() {
- struct timeval tick_time;
- gettimeofday(&tick_time, 0);
-
- return
- ((long long)tick_time.tv_sec) * ((long long)1000) +
- ((long long)tick_time.tv_usec) / ((long long)1000);
-}
-
-long long getMicro(){
- struct timeval tick_time;
- int res = gettimeofday(&tick_time, 0);
-
- long long secs = tick_time.tv_sec;
- long long micros = tick_time.tv_usec;
-
- micros = secs*1000000+micros;
- return micros;
-}
diff --git a/storage/ndb/src/common/portlib/win32/NdbCondition.c b/storage/ndb/src/common/portlib/win32/NdbCondition.c
deleted file mode 100644
index e6ad8d2d257..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbCondition.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include "NdbCondition.h"
-#include <NdbMutex.h>
-
-struct NdbCondition
-{
- long nWaiters;
- NdbMutex* pNdbMutexWaitersLock;
- HANDLE hSemaphore;
- HANDLE hEventWaitersDone;
- int bWasBroadcast;
-};
-
-
-struct NdbCondition*
-NdbCondition_Create(void)
-{
- int result = 0;
- struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
- if(!pNdbCondition)
- return 0;
-
- pNdbCondition->nWaiters = 0;
- pNdbCondition->bWasBroadcast = 0;
- if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
- result = -1;
- else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
- result = -1;
- else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
- result = -1;
-
- assert(!result);
- return pNdbCondition;
-}
-
-
-int
-NdbCondition_Wait(struct NdbCondition* p_cond,
- NdbMutex* p_mutex)
-{
- int result;
- int bLastWaiter;
- if(!p_cond || !p_mutex)
- return 1;
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- p_cond->nWaiters++;
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
-
- if(NdbMutex_Unlock(p_mutex))
- return -1;
- result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- p_cond->nWaiters--;
- bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
-
- if(result==WAIT_OBJECT_0 && bLastWaiter)
- SetEvent(p_cond->hEventWaitersDone);
-
- NdbMutex_Lock(p_mutex);
- return result;
-}
-
-
-int
-NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
- NdbMutex* p_mutex,
- int msecs)
-{
- int result;
- int bLastWaiter;
- if (!p_cond || !p_mutex)
- return 1;
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- p_cond->nWaiters++;
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
- if(msecs<0)
- msecs = 0;
-
- if(NdbMutex_Unlock(p_mutex))
- return -1;
- result = WaitForSingleObject(p_cond->hSemaphore, msecs);
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- p_cond->nWaiters--;
- bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
-
- if(result!=WAIT_OBJECT_0)
- result = -1;
-
- if(bLastWaiter)
- SetEvent(p_cond->hEventWaitersDone);
-
- NdbMutex_Lock(p_mutex);
- return result;
-}
-
-
-int
-NdbCondition_Signal(struct NdbCondition* p_cond)
-{
- int bHaveWaiters;
- if(!p_cond)
- return 1;
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- bHaveWaiters = (p_cond->nWaiters > 0);
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
-
- if(bHaveWaiters)
- return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
- else
- return 0;
-}
-
-
-int NdbCondition_Broadcast(struct NdbCondition* p_cond)
-{
- int bHaveWaiters;
- int result = 0;
- if(!p_cond)
- return 1;
-
- NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
- bHaveWaiters = 0;
- if(p_cond->nWaiters > 0)
- {
- p_cond->bWasBroadcast = !0;
- bHaveWaiters = 1;
- }
- NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
- if(bHaveWaiters)
- {
- if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
- result = -1;
- else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
- result = -1;
- p_cond->bWasBroadcast = 0;
- }
- return result;
-}
-
-
-int NdbCondition_Destroy(struct NdbCondition* p_cond)
-{
- int result;
- if(!p_cond)
- return 1;
-
- CloseHandle(p_cond->hEventWaitersDone);
- NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
- result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1);
-
- free(p_cond);
- return 0;
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbDaemon.c b/storage/ndb/src/common/portlib/win32/NdbDaemon.c
deleted file mode 100644
index 00fa8ea4591..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbDaemon.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "NdbDaemon.h"
-
-#define NdbDaemon_ErrorSize 500
-long NdbDaemon_DaemonPid;
-int NdbDaemon_ErrorCode;
-char NdbDaemon_ErrorText[NdbDaemon_ErrorSize];
-
-int
-NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
-{
- // XXX do something
- return 0;
-}
-
-#ifdef NDB_DAEMON_TEST
-
-int
-main()
-{
- if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
- fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
- return 1;
- }
- sleep(10);
- return 0;
-}
-
-#endif
diff --git a/storage/ndb/src/common/portlib/win32/NdbEnv.c b/storage/ndb/src/common/portlib/win32/NdbEnv.c
deleted file mode 100644
index 7ebee73ae02..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbEnv.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbEnv.h"
-
-const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
-{
- char* p = NULL;
- p = getenv(name);
-
- if (p != NULL && buf != NULL){
- strncpy(buf, p, buflen);
- buf[buflen-1] = 0;
- }
- return p;
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbHost.c b/storage/ndb/src/common/portlib/win32/NdbHost.c
deleted file mode 100644
index 220c080ed4b..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbHost.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include "NdbHost.h"
-
-
-int NdbHost_GetHostName(char* buf)
-{
- /* We must initialize TCP/IP if we want to call gethostname */
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD( 2, 0 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- /**
- * Tell the user that we couldn't find a usable
- * WinSock DLL.
- */
- return -1;
- }
-
- /* Get host name */
- if(gethostname(buf, MAXHOSTNAMELEN))
- {
- return -1;
- }
- return 0;
-}
-
-
-int NdbHost_GetProcessId(void)
-{
- return _getpid();
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbMem.c b/storage/ndb/src/common/portlib/win32/NdbMem.c
deleted file mode 100644
index 0cf1b5f018e..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbMem.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbMem.h"
-
-#if 0
-struct AWEINFO
-{
- SIZE_T dwSizeInBytesRequested;
- ULONG_PTR nNumberOfPagesRequested;
- ULONG_PTR nNumberOfPagesActual;
- ULONG_PTR nNumberOfPagesFreed;
- ULONG_PTR* pnPhysicalMemoryPageArray;
- void* pRegionReserved;
-};
-
-const size_t cNdbMem_nMaxAWEinfo = 256;
-size_t gNdbMem_nAWEinfo = 0;
-
-struct AWEINFO* gNdbMem_pAWEinfo = 0;
-
-
-void ShowLastError(const char* szContext, const char* szFunction)
-{
- DWORD dwError = GetLastError();
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- dwError,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR)&lpMsgBuf,
- 0,
- NULL
- );
- printf("%s : %s failed : %lu : %s\n", szContext, szFunction, dwError, (char*)lpMsgBuf);
- LocalFree(lpMsgBuf);
-}
-
-
-
-void NdbMem_Create()
-{
- // Address Windowing Extensions
- struct PRIVINFO
- {
- DWORD Count;
- LUID_AND_ATTRIBUTES Privilege[1];
- } Info;
-
- HANDLE hProcess = GetCurrentProcess();
- HANDLE hToken;
- if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
- {
- ShowLastError("NdbMem_Create", "OpenProcessToken");
- }
-
- Info.Count = 1;
- Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
- if(!LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &(Info.Privilege[0].Luid)))
- {
- ShowLastError("NdbMem_Create", "LookupPrivilegeValue");
- }
-
- if(!AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&Info, 0, 0, 0))
- {
- ShowLastError("NdbMem_Create", "AdjustTokenPrivileges");
- }
-
- if(!CloseHandle(hToken))
- {
- ShowLastError("NdbMem_Create", "CloseHandle");
- }
-
- return;
-}
-
-void NdbMem_Destroy()
-{
- /* Do nothing */
- return;
-}
-
-void* NdbMem_Allocate(size_t size)
-{
- // Address Windowing Extensions
- struct AWEINFO* pAWEinfo;
- HANDLE hProcess;
- SYSTEM_INFO sysinfo;
-
- if(!gNdbMem_pAWEinfo)
- {
- gNdbMem_pAWEinfo = VirtualAlloc(0,
- sizeof(struct AWEINFO)*cNdbMem_nMaxAWEinfo,
- MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
- }
-
- assert(gNdbMem_nAWEinfo < cNdbMem_nMaxAWEinfo);
- pAWEinfo = gNdbMem_pAWEinfo+gNdbMem_nAWEinfo++;
-
- hProcess = GetCurrentProcess();
- GetSystemInfo(&sysinfo);
- pAWEinfo->nNumberOfPagesRequested = (size+sysinfo.dwPageSize-1)/sysinfo.dwPageSize;
- pAWEinfo->pnPhysicalMemoryPageArray = VirtualAlloc(0,
- sizeof(ULONG_PTR)*pAWEinfo->nNumberOfPagesRequested,
- MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
- pAWEinfo->nNumberOfPagesActual = pAWEinfo->nNumberOfPagesRequested;
- if(!AllocateUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesActual), pAWEinfo->pnPhysicalMemoryPageArray))
- {
- ShowLastError("NdbMem_Allocate", "AllocateUserPhysicalPages");
- return 0;
- }
- if(pAWEinfo->nNumberOfPagesRequested != pAWEinfo->nNumberOfPagesActual)
- {
- ShowLastError("NdbMem_Allocate", "nNumberOfPagesRequested != nNumberOfPagesActual");
- return 0;
- }
-
- pAWEinfo->dwSizeInBytesRequested = size;
- pAWEinfo->pRegionReserved = VirtualAlloc(0, pAWEinfo->dwSizeInBytesRequested, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE);
- if(!pAWEinfo->pRegionReserved)
- {
- ShowLastError("NdbMem_Allocate", "VirtualAlloc");
- return 0;
- }
-
- if(!MapUserPhysicalPages(pAWEinfo->pRegionReserved, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pnPhysicalMemoryPageArray))
- {
- ShowLastError("NdbMem_Allocate", "MapUserPhysicalPages");
- return 0;
- }
-
- /*
- printf("allocate AWE memory: %lu bytes, %lu pages, address %lx\n",
- pAWEinfo->dwSizeInBytesRequested,
- pAWEinfo->nNumberOfPagesActual,
- pAWEinfo->pRegionReserved);
- */
- return pAWEinfo->pRegionReserved;
-}
-
-
-void* NdbMem_AllocateAlign(size_t size, size_t alignment)
-{
- /*
- return (void*)memalign(alignment, size);
- TEMP fix
- */
- return NdbMem_Allocate(size);
-}
-
-
-void NdbMem_Free(void* ptr)
-{
- // VirtualFree(ptr, 0, MEM_DECOMMIT|MEM_RELEASE);
-
- // Address Windowing Extensions
- struct AWEINFO* pAWEinfo = 0;
- size_t i;
- HANDLE hProcess;
-
- for(i=0; i<gNdbMem_nAWEinfo; ++i)
- {
- if(ptr==gNdbMem_pAWEinfo[i].pRegionReserved)
- {
- pAWEinfo = gNdbMem_pAWEinfo+i;
- }
- }
- if(!pAWEinfo)
- {
- ShowLastError("NdbMem_Free", "ptr is not AWE memory");
- }
-
- hProcess = GetCurrentProcess();
- if(!MapUserPhysicalPages(ptr, pAWEinfo->nNumberOfPagesActual, 0))
- {
- ShowLastError("NdbMem_Free", "MapUserPhysicalPages");
- }
-
- if(!VirtualFree(ptr, 0, MEM_RELEASE))
- {
- ShowLastError("NdbMem_Free", "VirtualFree");
- }
-
- pAWEinfo->nNumberOfPagesFreed = pAWEinfo->nNumberOfPagesActual;
- if(!FreeUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesFreed), pAWEinfo->pnPhysicalMemoryPageArray))
- {
- ShowLastError("NdbMem_Free", "FreeUserPhysicalPages");
- }
-
- VirtualFree(pAWEinfo->pnPhysicalMemoryPageArray, 0, MEM_DECOMMIT|MEM_RELEASE);
-}
-
-
-int NdbMem_MemLockAll()
-{
- /*
- HANDLE hProcess = GetCurrentProcess();
- SIZE_T nMinimumWorkingSetSize;
- SIZE_T nMaximumWorkingSetSize;
- GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
- ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
-
- SetProcessWorkingSetSize(hProcess, 50000000, 100000000);
-
- GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
- ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
- */
- return -1;
-}
-
-int NdbMem_MemUnlockAll()
-{
- //VirtualUnlock();
- return -1;
-}
-
-#endif
-
-void NdbMem_Create()
-{
- /* Do nothing */
- return;
-}
-
-void NdbMem_Destroy()
-{
- /* Do nothing */
- return;
-}
-
-
-void* NdbMem_Allocate(size_t size)
-{
- void* mem_allocated;
- assert(size > 0);
- mem_allocated= (void*)malloc(size);
- return mem_allocated;
-}
-
-void* NdbMem_AllocateAlign(size_t size, size_t alignment)
-{
- (void)alignment; /* remove warning for unused parameter */
- /*
- return (void*)memalign(alignment, size);
- TEMP fix
- */
- return (void*)malloc(size);
-}
-
-
-void NdbMem_Free(void* ptr)
-{
- free(ptr);
-}
-
-
-int NdbMem_MemLockAll()
-{
- return 0;
-}
-
-int NdbMem_MemUnlockAll()
-{
- return 0;
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbMutex.c b/storage/ndb/src/common/portlib/win32/NdbMutex.c
deleted file mode 100644
index 8ddfd43a283..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbMutex.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include "NdbMutex.h"
-
-NdbMutex* NdbMutex_Create(void)
-{
- NdbMutex* pNdbMutex = (NdbMutex*)malloc(sizeof(NdbMutex));
- if(!pNdbMutex)
- return 0;
-
- InitializeCriticalSection(pNdbMutex);
- return pNdbMutex;
-}
-
-
-int NdbMutex_Destroy(NdbMutex* p_mutex)
-{
- if(!p_mutex)
- return -1;
-
- DeleteCriticalSection(p_mutex);
- free(p_mutex);
- return 0;
-}
-
-
-int NdbMutex_Lock(NdbMutex* p_mutex)
-{
- if(!p_mutex)
- return -1;
-
- EnterCriticalSection (p_mutex);
- return 0;
-}
-
-
-int NdbMutex_Unlock(NdbMutex* p_mutex)
-{
- if(!p_mutex)
- return -1;
-
- LeaveCriticalSection(p_mutex);
- return 0;
-}
-
-
-int NdbMutex_Trylock(NdbMutex* p_mutex)
-{
- int result = -1;
- if(p_mutex)
- {
- result = NdbMutex_Lock(p_mutex);
- //(TryEnterCriticalSection(p_mutex) ? 0 : -1);
- }
- return result;
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbSleep.c b/storage/ndb/src/common/portlib/win32/NdbSleep.c
deleted file mode 100644
index 2d87cd88234..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbSleep.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbSleep.h"
-
-int
-NdbSleep_MilliSleep(int milliseconds)
-{
- Sleep(milliseconds);
- return 0;
-}
-
-int
-NdbSleep_SecSleep(int seconds)
-{
- return NdbSleep_MilliSleep(seconds*1000);
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbTCP.c b/storage/ndb/src/common/portlib/win32/NdbTCP.c
deleted file mode 100644
index 75e9345a150..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbTCP.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbTCP.h"
-
-int
-Ndb_getInAddr(struct in_addr * dst, const char *address)
-{
- struct hostent * hostPtr;
-
- /* Try it as aaa.bbb.ccc.ddd. */
- dst->s_addr = inet_addr(address);
- if (dst->s_addr != -1) {
- return 0;
- }
-
- hostPtr = gethostbyname(address);
- if (hostPtr != NULL) {
- dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr;
- return 0;
- }
-
- return -1;
-}
-
-int Ndb_check_socket_hup(NDB_SOCKET_TYPE sock)
-{
- fd_set readfds, writefds, errorfds;
- struct timeval tv= {0,0};
- int s_err;
- int s_err_size= sizeof(s_err);
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&errorfds);
-
- FD_SET(sock, &readfds);
- FD_SET(sock, &writefds);
- FD_SET(sock, &errorfds);
-
- if(select(1, &readfds, &writefds, &errorfds, &tv)==SOCKET_ERROR)
- return 1;
-
- if(FD_ISSET(sock,&errorfds))
- return 1;
-
- s_err=0;
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
- return(1);
-
- if (s_err)
- { /* getsockopt could succeed */
- return(1); /* but return an error... */
- }
-
- return 0;
-}
diff --git a/storage/ndb/src/common/portlib/win32/NdbThread.c b/storage/ndb/src/common/portlib/win32/NdbThread.c
deleted file mode 100644
index 98c8e472fcd..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbThread.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbThread.h"
-#include <process.h>
-
-#define MAX_THREAD_NAME 16
-
-typedef unsigned (WINAPI* NDB_WIN32_THREAD_FUNC)(void*);
-
-
-struct NdbThread
-{
- HANDLE hThread;
- unsigned nThreadId;
- char thread_name[MAX_THREAD_NAME];
-};
-
-
-struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
- NDB_THREAD_ARG *p_thread_arg,
- const NDB_THREAD_STACKSIZE thread_stack_size,
- const char* p_thread_name,
- NDB_THREAD_PRIO thread_prio)
-{
- struct NdbThread* tmpThread;
- unsigned initflag;
- int nPriority = 0;
-
- if(!p_thread_func)
- return 0;
-
- tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
- if(!tmpThread)
- return 0;
-
- strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
-
- switch(thread_prio)
- {
- case NDB_THREAD_PRIO_HIGHEST: nPriority=THREAD_PRIORITY_HIGHEST; break;
- case NDB_THREAD_PRIO_HIGH: nPriority=THREAD_PRIORITY_ABOVE_NORMAL; break;
- case NDB_THREAD_PRIO_MEAN: nPriority=THREAD_PRIORITY_NORMAL; break;
- case NDB_THREAD_PRIO_LOW: nPriority=THREAD_PRIORITY_BELOW_NORMAL; break;
- case NDB_THREAD_PRIO_LOWEST: nPriority=THREAD_PRIORITY_LOWEST; break;
- }
- initflag = (nPriority ? CREATE_SUSPENDED : 0);
-
- tmpThread->hThread = (HANDLE)_beginthreadex(0, thread_stack_size,
- (NDB_WIN32_THREAD_FUNC)p_thread_func, p_thread_arg,
- initflag, &tmpThread->nThreadId);
-
- if(nPriority && tmpThread->hThread)
- {
- SetThreadPriority(tmpThread->hThread, nPriority);
- ResumeThread (tmpThread->hThread);
- }
-
- assert(tmpThread->hThread);
- return tmpThread;
-}
-
-
-void NdbThread_Destroy(struct NdbThread** p_thread)
-{
- CloseHandle((*p_thread)->hThread);
- (*p_thread)->hThread = 0;
- free(*p_thread);
- *p_thread = 0;
-}
-
-
-int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
-{
- void *local_status = 0;
- if (status == 0)
- status = &local_status;
-
- if(WaitForSingleObject(p_wait_thread->hThread, INFINITE) == WAIT_OBJECT_0
- && GetExitCodeThread(p_wait_thread->hThread, (LPDWORD)status))
- {
- CloseHandle(p_wait_thread->hThread);
- p_wait_thread->hThread = 0;
- return 0;
- }
- return -1;
-}
-
-
-void NdbThread_Exit(int status)
-{
- _endthreadex((DWORD) status);
-}
-
-
-int NdbThread_SetConcurrencyLevel(int level)
-{
- return 0;
-}
-
diff --git a/storage/ndb/src/common/portlib/win32/NdbTick.c b/storage/ndb/src/common/portlib/win32/NdbTick.c
deleted file mode 100644
index a4157f14fa4..00000000000
--- a/storage/ndb/src/common/portlib/win32/NdbTick.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbTick.h"
-//#include <windows.h>
-
-/*
-#define FILETIME_PER_MICROSEC 10
-#define FILETIME_PER_MILLISEC 10000
-#define FILETIME_PER_SEC 10000000
-
-
-NDB_TICKS NdbTick_CurrentMillisecond(void)
-{
- ULONGLONG ullTime;
- GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
- return (ullTime / FILETIME_PER_MILLISEC);
-}
-
-int
-NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
-{
- ULONGLONG ullTime;
- GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
- *secs = (ullTime / FILETIME_PER_SEC);
- *micros = (Uint32)((ullTime % FILETIME_PER_SEC) / FILETIME_PER_MICROSEC);
- return 0;
-}
-*/
-
-
-NDB_TICKS NdbTick_CurrentMillisecond(void)
-{
- LARGE_INTEGER liCount, liFreq;
- QueryPerformanceCounter(&liCount);
- QueryPerformanceFrequency(&liFreq);
- return (liCount.QuadPart*1000) / liFreq.QuadPart;
-}
-
-int
-NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
-{
- LARGE_INTEGER liCount, liFreq;
- QueryPerformanceCounter(&liCount);
- QueryPerformanceFrequency(&liFreq);
- *secs = liCount.QuadPart / liFreq.QuadPart;
- liCount.QuadPart -= *secs * liFreq.QuadPart;
- *micros = (liCount.QuadPart*1000000) / liFreq.QuadPart;
- return 0;
-}
diff --git a/storage/ndb/src/common/transporter/Makefile.am b/storage/ndb/src/common/transporter/Makefile.am
deleted file mode 100644
index a8374d69662..00000000000
--- a/storage/ndb/src/common/transporter/Makefile.am
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libtransporter.la
-
-libtransporter_la_SOURCES = \
- Transporter.cpp \
- SendBuffer.cpp \
- TCP_Transporter.cpp \
- TransporterRegistry.cpp \
- Packer.cpp
-
-EXTRA_libtransporter_la_SOURCES = SHM_Transporter.cpp SHM_Transporter.unix.cpp SCI_Transporter.cpp
-
-libtransporter_la_LIBADD = @ndb_transporter_opt_objs@
-libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/include/mgmapi -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/storage/ndb/include/debugger -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/include/transporter @NDB_SCI_INCLUDES@
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_util.mk.am
-
-windoze-dsp: libtransporter.dsp
-
-libtransporter.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libtransporter_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/transporter/Packer.cpp b/storage/ndb/src/common/transporter/Packer.cpp
deleted file mode 100644
index 9fb9f77fc7c..00000000000
--- a/storage/ndb/src/common/transporter/Packer.cpp
+++ /dev/null
@@ -1,517 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "Packer.hpp"
-#include <TransporterRegistry.hpp>
-#include <TransporterCallback.hpp>
-#include <RefConvert.hpp>
-
-#ifdef ERROR_INSERT
-Uint32 MAX_RECEIVED_SIGNALS = 1024;
-#else
-#define MAX_RECEIVED_SIGNALS 1024
-#endif
-
-Uint32
-TransporterRegistry::unpack(Uint32 * readPtr,
- Uint32 sizeOfData,
- NodeId remoteNodeId,
- IOState state) {
- SignalHeader signalHeader;
- LinearSectionPtr ptr[3];
-
- Uint32 usedData = 0;
- Uint32 loop_count = 0;
-
- if(state == NoHalt || state == HaltOutput){
- while ((sizeOfData >= 4 + sizeof(Protocol6)) &&
- (loop_count < MAX_RECEIVED_SIGNALS)) {
- Uint32 word1 = readPtr[0];
- Uint32 word2 = readPtr[1];
- Uint32 word3 = readPtr[2];
- loop_count++;
-
-#if 0
- if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
- //Do funky stuff
- }
-#endif
-
- const Uint16 messageLen32 = Protocol6::getMessageLength(word1);
- const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2;
-
- if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){
- DEBUG("Message Size = " << messageLenBytes);
- reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return usedData;
- }//if
-
- if (sizeOfData < messageLenBytes) {
- break;
- }//if
-
- if(Protocol6::getCheckSumIncluded(word1)){
- const Uint32 tmpLen = messageLen32 - 1;
- const Uint32 checkSumSent = readPtr[tmpLen];
- const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen);
-
- if(checkSumComputed != checkSumSent){
- reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM);
- return usedData;
- }//if
- }//if
-
-#if 0
- if(Protocol6::getCompressed(word1)){
- //Do funky stuff
- }//if
-#endif
-
- Protocol6::createSignalHeader(&signalHeader, word1, word2, word3);
-
- Uint32 sBlockNum = signalHeader.theSendersBlockRef;
- sBlockNum = numberToRef(sBlockNum, remoteNodeId);
- signalHeader.theSendersBlockRef = sBlockNum;
-
- Uint8 prio = Protocol6::getPrio(word1);
-
- Uint32 * signalData = &readPtr[3];
-
- if(Protocol6::getSignalIdIncluded(word1) == 0){
- signalHeader.theSendersSignalId = ~0;
- } else {
- signalHeader.theSendersSignalId = * signalData;
- signalData ++;
- }//if
- signalHeader.theSignalId= ~0;
-
- Uint32 * sectionPtr = signalData + signalHeader.theLength;
- Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections;
- for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){
- Uint32 sz = * sectionPtr;
- ptr[i].sz = sz;
- ptr[i].p = sectionData;
-
- sectionPtr ++;
- sectionData += sz;
- }
-
- execute(callbackObj, &signalHeader, prio, signalData, ptr);
-
- readPtr += messageLen32;
- sizeOfData -= messageLenBytes;
- usedData += messageLenBytes;
- }//while
-
- return usedData;
- } else {
- /** state = HaltIO || state == HaltInput */
-
- while ((sizeOfData >= 4 + sizeof(Protocol6)) &&
- (loop_count < MAX_RECEIVED_SIGNALS)) {
- Uint32 word1 = readPtr[0];
- Uint32 word2 = readPtr[1];
- Uint32 word3 = readPtr[2];
- loop_count++;
-
-#if 0
- if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
- //Do funky stuff
- }//if
-#endif
-
- const Uint16 messageLen32 = Protocol6::getMessageLength(word1);
- const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2;
- if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){
- DEBUG("Message Size = " << messageLenBytes);
- reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return usedData;
- }//if
-
- if (sizeOfData < messageLenBytes) {
- break;
- }//if
-
- if(Protocol6::getCheckSumIncluded(word1)){
- const Uint32 tmpLen = messageLen32 - 1;
- const Uint32 checkSumSent = readPtr[tmpLen];
- const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen);
-
- if(checkSumComputed != checkSumSent){
-
- //theTransporters[remoteNodeId]->disconnect();
- reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM);
- return usedData;
- }//if
- }//if
-
-#if 0
- if(Protocol6::getCompressed(word1)){
- //Do funky stuff
- }//if
-#endif
-
- Protocol6::createSignalHeader(&signalHeader, word1, word2, word3);
-
- Uint32 rBlockNum = signalHeader.theReceiversBlockNumber;
-
- if(rBlockNum == 252){
- Uint32 sBlockNum = signalHeader.theSendersBlockRef;
- sBlockNum = numberToRef(sBlockNum, remoteNodeId);
- signalHeader.theSendersBlockRef = sBlockNum;
-
- Uint8 prio = Protocol6::getPrio(word1);
-
- Uint32 * signalData = &readPtr[3];
-
- if(Protocol6::getSignalIdIncluded(word1) == 0){
- signalHeader.theSendersSignalId = ~0;
- } else {
- signalHeader.theSendersSignalId = * signalData;
- signalData ++;
- }//if
-
- Uint32 * sectionPtr = signalData + signalHeader.theLength;
- Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections;
- for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){
- Uint32 sz = * sectionPtr;
- ptr[i].sz = sz;
- ptr[i].p = sectionData;
-
- sectionPtr ++;
- sectionData += sz;
- }
-
- execute(callbackObj, &signalHeader, prio, signalData, ptr);
- } else {
- DEBUG("prepareReceive(...) - Discarding message to block: "
- << rBlockNum << " from Node: " << remoteNodeId);
- }//if
-
- readPtr += messageLen32;
- sizeOfData -= messageLenBytes;
- usedData += messageLenBytes;
- }//while
-
-
- return usedData;
- }//if
-}
-
-Uint32 *
-TransporterRegistry::unpack(Uint32 * readPtr,
- Uint32 * eodPtr,
- NodeId remoteNodeId,
- IOState state) {
- SignalHeader signalHeader;
- LinearSectionPtr ptr[3];
- Uint32 loop_count = 0;
- if(state == NoHalt || state == HaltOutput){
- while ((readPtr < eodPtr) && (loop_count < MAX_RECEIVED_SIGNALS)) {
- Uint32 word1 = readPtr[0];
- Uint32 word2 = readPtr[1];
- Uint32 word3 = readPtr[2];
- loop_count++;
-#if 0
- if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
- //Do funky stuff
- }
-#endif
-
- const Uint16 messageLen32 = Protocol6::getMessageLength(word1);
-
- if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){
- DEBUG("Message Size(words) = " << messageLen32);
- reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return readPtr;
- }//if
-
- if(Protocol6::getCheckSumIncluded(word1)){
- const Uint32 tmpLen = messageLen32 - 1;
- const Uint32 checkSumSent = readPtr[tmpLen];
- const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen);
-
- if(checkSumComputed != checkSumSent){
- reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM);
- return readPtr;
- }//if
- }//if
-
-#if 0
- if(Protocol6::getCompressed(word1)){
- //Do funky stuff
- }//if
-#endif
-
- Protocol6::createSignalHeader(&signalHeader, word1, word2, word3);
-
- Uint32 sBlockNum = signalHeader.theSendersBlockRef;
- sBlockNum = numberToRef(sBlockNum, remoteNodeId);
- signalHeader.theSendersBlockRef = sBlockNum;
-
- Uint8 prio = Protocol6::getPrio(word1);
-
- Uint32 * signalData = &readPtr[3];
-
- if(Protocol6::getSignalIdIncluded(word1) == 0){
- signalHeader.theSendersSignalId = ~0;
- } else {
- signalHeader.theSendersSignalId = * signalData;
- signalData ++;
- }//if
-
- Uint32 * sectionPtr = signalData + signalHeader.theLength;
- Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections;
- for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){
- Uint32 sz = * sectionPtr;
- ptr[i].sz = sz;
- ptr[i].p = sectionData;
-
- sectionPtr ++;
- sectionData += sz;
- }
-
- execute(callbackObj, &signalHeader, prio, signalData, ptr);
-
- readPtr += messageLen32;
- }//while
- } else {
- /** state = HaltIO || state == HaltInput */
-
- while ((readPtr < eodPtr) && (loop_count < MAX_RECEIVED_SIGNALS)) {
- Uint32 word1 = readPtr[0];
- Uint32 word2 = readPtr[1];
- Uint32 word3 = readPtr[2];
- loop_count++;
-#if 0
- if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
- //Do funky stuff
- }//if
-#endif
-
- const Uint16 messageLen32 = Protocol6::getMessageLength(word1);
- if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){
- DEBUG("Message Size(words) = " << messageLen32);
- reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return readPtr;
- }//if
-
- if(Protocol6::getCheckSumIncluded(word1)){
- const Uint32 tmpLen = messageLen32 - 1;
- const Uint32 checkSumSent = readPtr[tmpLen];
- const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen);
-
- if(checkSumComputed != checkSumSent){
-
- //theTransporters[remoteNodeId]->disconnect();
- reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM);
- return readPtr;
- }//if
- }//if
-
-#if 0
- if(Protocol6::getCompressed(word1)){
- //Do funky stuff
- }//if
-#endif
-
- Protocol6::createSignalHeader(&signalHeader, word1, word2, word3);
-
- Uint32 rBlockNum = signalHeader.theReceiversBlockNumber;
-
- if(rBlockNum == 252){
- Uint32 sBlockNum = signalHeader.theSendersBlockRef;
- sBlockNum = numberToRef(sBlockNum, remoteNodeId);
- signalHeader.theSendersBlockRef = sBlockNum;
-
- Uint8 prio = Protocol6::getPrio(word1);
-
- Uint32 * signalData = &readPtr[3];
-
- if(Protocol6::getSignalIdIncluded(word1) == 0){
- signalHeader.theSendersSignalId = ~0;
- } else {
- signalHeader.theSendersSignalId = * signalData;
- signalData ++;
- }//if
-
- Uint32 * sectionPtr = signalData + signalHeader.theLength;
- Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections;
- for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){
- Uint32 sz = * sectionPtr;
- ptr[i].sz = sz;
- ptr[i].p = sectionData;
-
- sectionPtr ++;
- sectionData += sz;
- }
-
- execute(callbackObj, &signalHeader, prio, signalData, ptr);
- } else {
- DEBUG("prepareReceive(...) - Discarding message to block: "
- << rBlockNum << " from Node: " << remoteNodeId);
- }//if
-
- readPtr += messageLen32;
- }//while
- }//if
- return readPtr;
-}
-
-Packer::Packer(bool signalId, bool checksum) {
-
- checksumUsed = (checksum ? 1 : 0);
- signalIdUsed = (signalId ? 1 : 0);
-
- // Set the priority
-
- preComputedWord1 = 0;
- Protocol6::setByteOrder(preComputedWord1, 0);
- Protocol6::setSignalIdIncluded(preComputedWord1, signalIdUsed);
- Protocol6::setCheckSumIncluded(preComputedWord1, checksumUsed);
- Protocol6::setCompressed(preComputedWord1, 0);
-}
-
-inline
-void
-import(Uint32 * & insertPtr, const LinearSectionPtr & ptr){
- const Uint32 sz = ptr.sz;
- memcpy(insertPtr, ptr.p, 4 * sz);
- insertPtr += sz;
-}
-
-void copy(Uint32 * & insertPtr,
- class SectionSegmentPool &, const SegmentedSectionPtr & ptr);
-
-void
-Packer::pack(Uint32 * insertPtr,
- Uint32 prio,
- const SignalHeader * header,
- const Uint32 * theData,
- const LinearSectionPtr ptr[3]) const {
- Uint32 i;
-
- Uint32 dataLen32 = header->theLength;
- Uint32 no_segs = header->m_noOfSections;
-
- Uint32 len32 =
- dataLen32 + no_segs +
- checksumUsed + signalIdUsed + (sizeof(Protocol6)/4);
-
-
- for(i = 0; i<no_segs; i++){
- len32 += ptr[i].sz;
- }
-
- /**
- * Do insert of data
- */
- Uint32 word1 = preComputedWord1;
- Uint32 word2 = 0;
- Uint32 word3 = 0;
-
- Protocol6::setPrio(word1, prio);
- Protocol6::setMessageLength(word1, len32);
- Protocol6::createProtocol6Header(word1, word2, word3, header);
-
- insertPtr[0] = word1;
- insertPtr[1] = word2;
- insertPtr[2] = word3;
-
- Uint32 * tmpInserPtr = &insertPtr[3];
-
- if(signalIdUsed){
- * tmpInserPtr = header->theSignalId;
- tmpInserPtr++;
- }
-
- memcpy(tmpInserPtr, theData, 4 * dataLen32);
-
- tmpInserPtr += dataLen32;
- for(i = 0; i<no_segs; i++){
- tmpInserPtr[i] = ptr[i].sz;
- }
-
- tmpInserPtr += no_segs;
- for(i = 0; i<no_segs; i++){
- import(tmpInserPtr, ptr[i]);
- }
-
- if(checksumUsed){
- * tmpInserPtr = computeChecksum(&insertPtr[0], len32-1);
- }
-}
-
-void
-Packer::pack(Uint32 * insertPtr,
- Uint32 prio,
- const SignalHeader * header,
- const Uint32 * theData,
- class SectionSegmentPool & thePool,
- const SegmentedSectionPtr ptr[3]) const {
- Uint32 i;
-
- Uint32 dataLen32 = header->theLength;
- Uint32 no_segs = header->m_noOfSections;
-
- Uint32 len32 =
- dataLen32 + no_segs +
- checksumUsed + signalIdUsed + (sizeof(Protocol6)/4);
-
- for(i = 0; i<no_segs; i++){
- len32 += ptr[i].sz;
- }
-
- /**
- * Do insert of data
- */
- Uint32 word1 = preComputedWord1;
- Uint32 word2 = 0;
- Uint32 word3 = 0;
-
- Protocol6::setPrio(word1, prio);
- Protocol6::setMessageLength(word1, len32);
- Protocol6::createProtocol6Header(word1, word2, word3, header);
-
- insertPtr[0] = word1;
- insertPtr[1] = word2;
- insertPtr[2] = word3;
-
- Uint32 * tmpInserPtr = &insertPtr[3];
-
- if(signalIdUsed){
- * tmpInserPtr = header->theSignalId;
- tmpInserPtr++;
- }
-
- memcpy(tmpInserPtr, theData, 4 * dataLen32);
-
- tmpInserPtr += dataLen32;
- for(i = 0; i<no_segs; i++){
- tmpInserPtr[i] = ptr[i].sz;
- }
-
- tmpInserPtr += no_segs;
- for(i = 0; i<no_segs; i++){
- copy(tmpInserPtr, thePool, ptr[i]);
- }
-
- if(checksumUsed){
- * tmpInserPtr = computeChecksum(&insertPtr[0], len32-1);
- }
-}
diff --git a/storage/ndb/src/common/transporter/Packer.hpp b/storage/ndb/src/common/transporter/Packer.hpp
deleted file mode 100644
index f3d93a2d87e..00000000000
--- a/storage/ndb/src/common/transporter/Packer.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef PACKER_HPP
-#define PACKER_HPP
-
-#include <TransporterDefinitions.hpp>
-#include "TransporterInternalDefinitions.hpp"
-
-class Packer {
- Uint32 preComputedWord1;
- Uint32 checksumUsed; // Checksum shall be included in the message
- Uint32 signalIdUsed; // Senders signal id shall be included in the message
-public:
- Packer(bool signalId, bool checksum);
-
- Uint32 getMessageLength(const SignalHeader* header,
- const LinearSectionPtr ptr[3]) const ;
-
-
- Uint32 getMessageLength(const SignalHeader* header,
- const SegmentedSectionPtr ptr[3]) const ;
-
- void pack(Uint32 * insertPtr,
- Uint32 prio,
- const SignalHeader* header,
- const Uint32* data,
- const LinearSectionPtr ptr[3]) const ;
-
- void pack(Uint32 * insertPtr,
- Uint32 prio,
- const SignalHeader* header,
- const Uint32* data,
- class SectionSegmentPool & thePool,
- const SegmentedSectionPtr ptr[3]) const ;
-};
-
-inline
-Uint32
-Packer::getMessageLength(const SignalHeader* header,
- const LinearSectionPtr ptr[3]) const {
- Uint32 tLen32 = header->theLength;
- Uint32 no_seg = header->m_noOfSections;
- tLen32 += checksumUsed;
- tLen32 += signalIdUsed;
- tLen32 += no_seg;
-
- for(Uint32 i = 0; i<no_seg; i++){
- tLen32 += ptr[i].sz;
- }
-
- return (tLen32 * 4) + sizeof(Protocol6);
-}
-
-inline
-Uint32
-Packer::getMessageLength(const SignalHeader* header,
- const SegmentedSectionPtr ptr[3]) const {
- Uint32 tLen32 = header->theLength;
- Uint32 no_seg = header->m_noOfSections;
- tLen32 += checksumUsed;
- tLen32 += signalIdUsed;
- tLen32 += no_seg;
-
- for(Uint32 i = 0; i<no_seg; i++){
- tLen32 += ptr[i].sz;
- }
-
- return (tLen32 * 4) + sizeof(Protocol6);
-}
-
-#endif
diff --git a/storage/ndb/src/common/transporter/SCI_Transporter.cpp b/storage/ndb/src/common/transporter/SCI_Transporter.cpp
deleted file mode 100644
index 5e79009c0e7..00000000000
--- a/storage/ndb/src/common/transporter/SCI_Transporter.cpp
+++ /dev/null
@@ -1,910 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "SCI_Transporter.hpp"
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-#include <NdbTick.h>
-#include <NdbTick.h>
-
-#include "TransporterInternalDefinitions.hpp"
-#include <TransporterCallback.hpp>
-
-#include <InputStream.hpp>
-#include <OutputStream.hpp>
-
-#define FLAGS 0
-#define DEBUG_TRANSPORTER
-SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg,
- const char *lHostName,
- const char *rHostName,
- int r_port,
- bool isMgmConnection,
- Uint32 packetSize,
- Uint32 bufferSize,
- Uint32 nAdapters,
- Uint16 remoteSciNodeId0,
- Uint16 remoteSciNodeId1,
- NodeId _localNodeId,
- NodeId _remoteNodeId,
- NodeId serverNodeId,
- bool chksm,
- bool signalId,
- Uint32 reportFreq) :
- Transporter(t_reg, tt_SCI_TRANSPORTER,
- lHostName, rHostName, r_port, isMgmConnection, _localNodeId,
- _remoteNodeId, serverNodeId, 0, false, chksm, signalId)
-{
- DBUG_ENTER("SCI_Transporter::SCI_Transporter");
- m_PacketSize = (packetSize + 3)/4 ;
- m_BufferSize = bufferSize;
- m_sendBuffer.m_buffer = NULL;
-
- m_RemoteSciNodeId = remoteSciNodeId0;
-
- if(remoteSciNodeId0 == 0 || remoteSciNodeId1 == 0)
- m_numberOfRemoteNodes=1;
- else
- m_numberOfRemoteNodes=2;
-
- m_RemoteSciNodeId1 = remoteSciNodeId1;
-
-
- m_initLocal=false;
- m_failCounter=0;
- m_remoteNodes[0]=remoteSciNodeId0;
- m_remoteNodes[1]=remoteSciNodeId1;
- m_adapters = nAdapters;
- m_ActiveAdapterId=0;
- m_StandbyAdapterId=1;
-
- m_mapped = false;
- m_sciinit=false;
-
- sciAdapters= new SciAdapter[nAdapters* (sizeof (SciAdapter))];
- if(sciAdapters==NULL) {
- }
- m_SourceSegm= new sourceSegm[nAdapters* (sizeof (sourceSegm))];
- if(m_SourceSegm==NULL) {
- }
- m_TargetSegm= new targetSegm[nAdapters* (sizeof (targetSegm))];
- if(m_TargetSegm==NULL) {
- }
- m_reportFreq= reportFreq;
-
- //reset all statistic counters.
-#ifdef DEBUG_TRANSPORTER
- i1024=0;
- i2048=0;
- i2049=0;
- i10242048=0;
- i20484096=0;
- i4096=0;
- i4097=0;
-#endif
- DBUG_VOID_RETURN;
-}
-
-void SCI_Transporter::disconnectImpl()
-{
- DBUG_ENTER("SCI_Transporter::disconnectImpl");
- sci_error_t err;
- if(m_mapped){
- setDisconnect();
- DBUG_PRINT("info", ("connect status = %d, remote node = %d",
- (int)getConnectionStatus(), remoteNodeId));
- disconnectRemote();
- disconnectLocal();
- }
-
- // Empty send buffer
-
- m_sendBuffer.m_dataSize = 0;
-
- m_initLocal=false;
- m_mapped = false;
-
- if(m_sciinit) {
- for(Uint32 i=0; i<m_adapters ; i++) {
- SCIClose(sciAdapters[i].scidesc, FLAGS, &err);
-
- if(err != SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_CLOSE_CHANNEL);
- DBUG_PRINT("error",
- ("Cannot close channel to the driver. Error code 0x%x",
- err));
- }
- }
- }
- m_sciinit=false;
-
-#ifdef DEBUG_TRANSPORTER
- ndbout << "total: " << i1024+ i10242048 + i2048+i2049 << endl;
- ndbout << "<1024: " << i1024 << endl;
- ndbout << "1024-2047: " << i10242048 << endl;
- ndbout << "==2048: " << i2048 << endl;
- ndbout << "2049-4096: " << i20484096 << endl;
- ndbout << "==4096: " << i4096 << endl;
- ndbout << ">4096: " << i4097 << endl;
-#endif
- DBUG_VOID_RETURN;
-}
-
-
-bool SCI_Transporter::initTransporter() {
- DBUG_ENTER("SCI_Transporter::initTransporter");
- if(m_BufferSize < (2*MAX_MESSAGE_SIZE + 4096)){
- m_BufferSize = 2 * MAX_MESSAGE_SIZE + 4096;
- }
-
- // Allocate buffers for sending, send buffer size plus 2048 bytes for avoiding
- // the need to send twice when a large message comes around. Send buffer size is
- // measured in words.
- Uint32 sz = 4 * m_PacketSize + MAX_MESSAGE_SIZE;;
-
- m_sendBuffer.m_sendBufferSize = 4 * ((sz + 3) / 4);
- m_sendBuffer.m_buffer = new Uint32[m_sendBuffer.m_sendBufferSize / 4];
- m_sendBuffer.m_dataSize = 0;
-
- DBUG_PRINT("info",
- ("Created SCI Send Buffer with buffer size %d and packet size %d",
- m_sendBuffer.m_sendBufferSize, m_PacketSize * 4));
- if(!getLinkStatus(m_ActiveAdapterId) ||
- (m_adapters > 1 &&
- !getLinkStatus(m_StandbyAdapterId))) {
- DBUG_PRINT("error",
- ("The link is not fully operational. Check the cables and the switches"));
- //NDB should terminate
- report_error(TE_SCI_LINK_ERROR);
- DBUG_RETURN(false);
- }
- DBUG_RETURN(true);
-} // initTransporter()
-
-
-
-Uint32 SCI_Transporter::getLocalNodeId(Uint32 adapterNo)
-{
- sci_query_adapter_t queryAdapter;
- sci_error_t error;
- Uint32 _localNodeId;
-
- queryAdapter.subcommand = SCI_Q_ADAPTER_NODEID;
- queryAdapter.localAdapterNo = adapterNo;
- queryAdapter.data = &_localNodeId;
-
- SCIQuery(SCI_Q_ADAPTER,(void*)(&queryAdapter),(Uint32)NULL,&error);
-
- if(error != SCI_ERR_OK)
- return 0;
- return _localNodeId;
-}
-
-
-bool SCI_Transporter::getLinkStatus(Uint32 adapterNo)
-{
- sci_query_adapter_t queryAdapter;
- sci_error_t error;
- int linkstatus;
- queryAdapter.subcommand = SCI_Q_ADAPTER_LINK_OPERATIONAL;
-
- queryAdapter.localAdapterNo = adapterNo;
- queryAdapter.data = &linkstatus;
-
- SCIQuery(SCI_Q_ADAPTER,(void*)(&queryAdapter),(Uint32)NULL,&error);
-
- if(error != SCI_ERR_OK) {
- DBUG_PRINT("error", ("error %d querying adapter", error));
- return false;
- }
- if(linkstatus<=0)
- return false;
- return true;
-}
-
-
-
-sci_error_t SCI_Transporter::initLocalSegment() {
- DBUG_ENTER("SCI_Transporter::initLocalSegment");
- Uint32 segmentSize = m_BufferSize;
- Uint32 offset = 0;
- sci_error_t err;
- if(!m_sciinit) {
- for(Uint32 i=0; i<m_adapters ; i++) {
- SCIOpen(&(sciAdapters[i].scidesc), FLAGS, &err);
- sciAdapters[i].localSciNodeId=getLocalNodeId(i);
- DBUG_PRINT("info", ("SCInode iD %d adapter %d\n",
- sciAdapters[i].localSciNodeId, i));
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error",
- ("Cannot open an SCI virtual device. Error code 0x%x",
- err));
- DBUG_RETURN(err);
- }
- }
- }
-
- m_sciinit=true;
-
- SCICreateSegment(sciAdapters[0].scidesc,
- &(m_SourceSegm[0].localHandle),
- hostSegmentId(localNodeId, remoteNodeId),
- segmentSize,
- 0,
- 0,
- 0,
- &err);
-
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Error creating segment, err = 0x%x", err));
- DBUG_RETURN(err);
- } else {
- DBUG_PRINT("info", ("created segment id : %d",
- hostSegmentId(localNodeId, remoteNodeId)));
- }
-
- /** Prepare the segment*/
- for(Uint32 i=0; i < m_adapters; i++) {
- SCIPrepareSegment((m_SourceSegm[0].localHandle),
- i,
- FLAGS,
- &err);
-
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error",
- ("Local Segment is not accessible by an SCI adapter. Error code 0x%x\n",
- err));
- DBUG_RETURN(err);
- }
- }
-
-
- m_SourceSegm[0].mappedMemory =
- SCIMapLocalSegment((m_SourceSegm[0].localHandle),
- &(m_SourceSegm[0].lhm[0].map),
- offset,
- segmentSize,
- NULL,
- FLAGS,
- &err);
-
-
-
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Cannot map area of size %d. Error code 0x%x",
- segmentSize,err));
- doDisconnect();
- DBUG_RETURN(err);
- }
-
-
- /** Make the local segment available*/
- for(Uint32 i=0; i < m_adapters; i++) {
- SCISetSegmentAvailable((m_SourceSegm[0].localHandle),
- i,
- FLAGS,
- &err);
-
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error",
- ("Local Segment is not available for remote connections. Error code 0x%x\n",
- err));
- DBUG_RETURN(err);
- }
- }
- setupLocalSegment();
- DBUG_RETURN(err);
-
-} // initLocalSegment()
-
-
-bool SCI_Transporter::doSend() {
-#ifdef DEBUG_TRANSPORTER
- NDB_TICKS startSec=0, stopSec=0;
- Uint32 startMicro=0, stopMicro=0, totalMicro=0;
-#endif
- sci_error_t err;
- Uint32 retry=0;
-
- const char * const sendPtr = (char*)m_sendBuffer.m_buffer;
- const Uint32 sizeToSend = 4 * m_sendBuffer.m_dataSize; //Convert to number of bytes
-
- if (sizeToSend > 0){
-#ifdef DEBUG_TRANSPORTER
- if(sizeToSend < 1024 )
- i1024++;
- if(sizeToSend > 1024 && sizeToSend < 2048 )
- i10242048++;
- if(sizeToSend==2048)
- i2048++;
- if(sizeToSend>2048 && sizeToSend < 4096)
- i20484096++;
- if(sizeToSend==4096)
- i4096++;
- if(sizeToSend==4097)
- i4097++;
-#endif
-
- tryagain:
- retry++;
- if (retry > 3) {
- DBUG_PRINT("error", ("SCI Transfer failed"));
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- return false;
- }
- Uint32 * insertPtr = (Uint32 *)
- (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(sizeToSend);
-
- if(insertPtr != 0) {
-
- const Uint32 remoteOffset=(Uint32)
- ((char*)insertPtr -
- (char*)(m_TargetSegm[m_ActiveAdapterId].mappedMemory));
-
- SCIMemCpy(m_TargetSegm[m_ActiveAdapterId].sequence,
- (void*)sendPtr,
- m_TargetSegm[m_ActiveAdapterId].rhm[m_ActiveAdapterId].map,
- remoteOffset,
- sizeToSend,
- SCI_FLAG_ERROR_CHECK,
- &err);
-
- if (err != SCI_ERR_OK) {
- if (err == SCI_ERR_OUT_OF_RANGE ||
- err == SCI_ERR_SIZE_ALIGNMENT ||
- err == SCI_ERR_OFFSET_ALIGNMENT) {
- DBUG_PRINT("error", ("Data transfer error = %d", err));
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- return false;
- }
- if(err == SCI_ERR_TRANSFER_FAILED) {
- if(getLinkStatus(m_ActiveAdapterId))
- goto tryagain;
- if (m_adapters == 1) {
- DBUG_PRINT("error", ("SCI Transfer failed"));
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- return false;
- }
- m_failCounter++;
- Uint32 temp=m_ActiveAdapterId;
- if (getLinkStatus(m_StandbyAdapterId)) {
- failoverShmWriter();
- SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0);
- m_ActiveAdapterId=m_StandbyAdapterId;
- m_StandbyAdapterId=temp;
- DBUG_PRINT("error", ("Swapping from adapter %u to %u",
- m_StandbyAdapterId, m_ActiveAdapterId));
- } else {
- report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR);
- DBUG_PRINT("error", ("SCI Transfer failed"));
- }
- }
- } else {
- SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer);
- writer->updateWritePtr(sizeToSend);
-
- Uint32 sendLimit = writer->getBufferSize();
- sendLimit -= writer->getWriteIndex();
-
- m_sendBuffer.m_dataSize = 0;
- m_sendBuffer.m_forceSendLimit = sendLimit;
- }
- } else {
- /**
- * If we end up here, the SCI segment is full.
- */
- DBUG_PRINT("error", ("the segment is full for some reason"));
- return false;
- } //if
- }
- return true;
-} // doSend()
-
-
-
-void SCI_Transporter::failoverShmWriter() {
-#if 0
- (m_TargetSegm[m_StandbyAdapterId].writer)
- ->copyIndexes((m_TargetSegm[m_StandbyAdapterId].writer));
-#endif
-} //failoverShm
-
-
-void SCI_Transporter::setupLocalSegment()
-{
- DBUG_ENTER("SCI_Transporter::setupLocalSegment");
- Uint32 sharedSize = 0;
- sharedSize =4096; //start of the buffer is page aligend
-
- Uint32 sizeOfBuffer = m_BufferSize;
-
- sizeOfBuffer -= sharedSize;
-
- Uint32 * localReadIndex =
- (Uint32*)m_SourceSegm[m_ActiveAdapterId].mappedMemory;
- Uint32 * localWriteIndex = (Uint32*)(localReadIndex+ 1);
- m_localStatusFlag = (Uint32*)(localReadIndex + 3);
-
- char * localStartOfBuf = (char*)
- ((char*)m_SourceSegm[m_ActiveAdapterId].mappedMemory+sharedSize);
-
- * localReadIndex = 0;
- * localWriteIndex = 0;
-
- const Uint32 slack = MAX_MESSAGE_SIZE;
-
- reader = new SHM_Reader(localStartOfBuf,
- sizeOfBuffer,
- slack,
- localReadIndex,
- localWriteIndex);
-
- reader->clear();
- DBUG_VOID_RETURN;
-} //setupLocalSegment
-
-void SCI_Transporter::setupRemoteSegment()
-{
- DBUG_ENTER("SCI_Transporter::setupRemoteSegment");
- Uint32 sharedSize = 0;
- sharedSize =4096; //start of the buffer is page aligned
-
- Uint32 sizeOfBuffer = m_BufferSize;
- const Uint32 slack = MAX_MESSAGE_SIZE;
- sizeOfBuffer -= sharedSize;
-
- Uint32 *segPtr = (Uint32*) m_TargetSegm[m_ActiveAdapterId].mappedMemory ;
-
- Uint32 * remoteReadIndex = (Uint32*)segPtr;
- Uint32 * remoteWriteIndex = (Uint32*)(segPtr + 1);
- m_remoteStatusFlag = (Uint32*)(segPtr + 3);
-
- char * remoteStartOfBuf = ( char*)((char*)segPtr+(sharedSize));
-
- writer = new SHM_Writer(remoteStartOfBuf,
- sizeOfBuffer,
- slack,
- remoteReadIndex,
- remoteWriteIndex);
-
- writer->clear();
-
- m_TargetSegm[0].writer=writer;
-
- m_sendBuffer.m_forceSendLimit = writer->getBufferSize();
-
- if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
- DBUG_PRINT("error", ("Unable to create sequence on active"));
- doDisconnect();
- }
- if (m_adapters > 1) {
- segPtr = (Uint32*) m_TargetSegm[m_StandbyAdapterId].mappedMemory ;
-
- Uint32 * remoteReadIndex2 = (Uint32*)segPtr;
- Uint32 * remoteWriteIndex2 = (Uint32*) (segPtr + 1);
- m_remoteStatusFlag2 = (Uint32*)(segPtr + 3);
-
- char * remoteStartOfBuf2 = ( char*)((char *)segPtr+sharedSize);
-
- /**
- * setup a writer. writer2 is used to mirror the changes of
- * writer on the standby
- * segment, so that in the case of a failover, we can switch
- * to the stdby seg. quickly.*
- */
- writer2 = new SHM_Writer(remoteStartOfBuf2,
- sizeOfBuffer,
- slack,
- remoteReadIndex2,
- remoteWriteIndex2);
-
- * remoteReadIndex = 0;
- * remoteWriteIndex = 0;
- writer2->clear();
- m_TargetSegm[1].writer=writer2;
- if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE);
- DBUG_PRINT("error", ("Unable to create sequence on standby"));
- doDisconnect();
- }
- }
- DBUG_VOID_RETURN;
-} //setupRemoteSegment
-
-bool
-SCI_Transporter::init_local()
-{
- DBUG_ENTER("SCI_Transporter::init_local");
- if(!m_initLocal) {
- if(initLocalSegment()!=SCI_ERR_OK){
- NdbSleep_MilliSleep(10);
- //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
- report_error(TE_SCI_CANNOT_INIT_LOCALSEGMENT);
- DBUG_RETURN(false);
- }
- m_initLocal=true;
- }
- DBUG_RETURN(true);
-}
-
-bool
-SCI_Transporter::init_remote()
-{
- DBUG_ENTER("SCI_Transporter::init_remote");
- sci_error_t err;
- Uint32 offset = 0;
- if(!m_mapped ) {
- DBUG_PRINT("info", ("Map remote segments"));
- for(Uint32 i=0; i < m_adapters ; i++) {
- m_TargetSegm[i].rhm[i].remoteHandle=0;
- SCIConnectSegment(sciAdapters[i].scidesc,
- &(m_TargetSegm[i].rhm[i].remoteHandle),
- m_remoteNodes[i],
- remoteSegmentId(localNodeId, remoteNodeId),
- i,
- 0,
- 0,
- 0,
- 0,
- &err);
-
- if(err != SCI_ERR_OK) {
- NdbSleep_MilliSleep(10);
- DBUG_PRINT("error", ("Error connecting segment, err 0x%x", err));
- DBUG_RETURN(false);
- }
- }
- // Map the remote memory segment into program space
- for(Uint32 i=0; i < m_adapters ; i++) {
- m_TargetSegm[i].mappedMemory =
- SCIMapRemoteSegment((m_TargetSegm[i].rhm[i].remoteHandle),
- &(m_TargetSegm[i].rhm[i].map),
- offset,
- m_BufferSize,
- NULL,
- FLAGS,
- &err);
-
- if(err!= SCI_ERR_OK) {
- DBUG_PRINT("error",
- ("Cannot map a segment to the remote node %d. Error code 0x%x",
- m_RemoteSciNodeId, err));
- //NDB SHOULD TERMINATE AND COMPUTER REBOOTED!
- report_error(TE_SCI_CANNOT_MAP_REMOTESEGMENT);
- DBUG_RETURN(false);
- }
- }
- m_mapped=true;
- setupRemoteSegment();
- setConnected();
- DBUG_PRINT("info", ("connected and mapped to segment, remoteNode: %d",
- remoteNodeId));
- DBUG_PRINT("info", ("remoteSegId: %d",
- remoteSegmentId(localNodeId, remoteNodeId)));
- DBUG_RETURN(true);
- } else {
- DBUG_RETURN(getConnectionStatus());
- }
-}
-
-bool
-SCI_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
-{
- SocketInputStream s_input(sockfd);
- SocketOutputStream s_output(sockfd);
- char buf[256];
- DBUG_ENTER("SCI_Transporter::connect_client_impl");
- // Wait for server to create and attach
- if (s_input.gets(buf, 256) == 0) {
- DBUG_PRINT("error", ("No initial response from server in SCI"));
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- if (!init_local()) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- // Send ok to server
- s_output.println("sci client 1 ok");
-
- if (!init_remote()) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- // Wait for ok from server
- if (s_input.gets(buf, 256) == 0) {
- DBUG_PRINT("error", ("No second response from server in SCI"));
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- // Send ok to server
- s_output.println("sci client 2 ok");
-
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("info", ("Successfully connected client to node %d",
- remoteNodeId));
- DBUG_RETURN(true);
-}
-
-bool
-SCI_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd)
-{
- SocketOutputStream s_output(sockfd);
- SocketInputStream s_input(sockfd);
- char buf[256];
- DBUG_ENTER("SCI_Transporter::connect_server_impl");
-
- if (!init_local()) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- // Send ok to client
- s_output.println("sci server 1 ok");
-
- // Wait for ok from client
- if (s_input.gets(buf, 256) == 0) {
- DBUG_PRINT("error", ("No response from client in SCI"));
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- if (!init_remote()) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- // Send ok to client
- s_output.println("sci server 2 ok");
- // Wait for ok from client
- if (s_input.gets(buf, 256) == 0) {
- DBUG_PRINT("error", ("No second response from client in SCI"));
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("info", ("Successfully connected server to node %d",
- remoteNodeId));
- DBUG_RETURN(true);
-}
-
-sci_error_t SCI_Transporter::createSequence(Uint32 adapterid) {
- sci_error_t err;
- SCICreateMapSequence((m_TargetSegm[adapterid].rhm[adapterid].map),
- &(m_TargetSegm[adapterid].sequence),
- SCI_FLAG_FAST_BARRIER,
- &err);
- return err;
-} // createSequence()
-
-bool SCI_Transporter::disconnectLocal()
-{
- DBUG_ENTER("SCI_Transporter::disconnectLocal");
- sci_error_t err;
- m_ActiveAdapterId=0;
-
- /** Free resources used by a local segment
- */
-
- SCIUnmapSegment(m_SourceSegm[0].lhm[0].map,0,&err);
- if(err!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_UNMAP_SEGMENT);
- DBUG_PRINT("error", ("Unable to unmap segment"));
- DBUG_RETURN(false);
- }
-
- SCIRemoveSegment((m_SourceSegm[m_ActiveAdapterId].localHandle),
- FLAGS,
- &err);
-
- if(err!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_REMOVE_SEGMENT);
- DBUG_PRINT("error", ("Unable to remove segment"));
- DBUG_RETURN(false);
- }
- DBUG_PRINT("info", ("Local memory segment is unmapped and removed"));
- DBUG_RETURN(true);
-} // disconnectLocal()
-
-
-bool SCI_Transporter::disconnectRemote() {
- DBUG_ENTER("SCI_Transporter::disconnectRemote");
- sci_error_t err;
- for(Uint32 i=0; i<m_adapters; i++) {
- /**
- * Segment unmapped, disconnect from the remotely connected segment
- */
- SCIUnmapSegment(m_TargetSegm[i].rhm[i].map,0,&err);
- if(err!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_UNMAP_SEGMENT);
- DBUG_PRINT("error", ("Unable to unmap segment"));
- DBUG_RETURN(false);
- }
-
- SCIDisconnectSegment(m_TargetSegm[i].rhm[i].remoteHandle,
- FLAGS,
- &err);
- if(err!=SCI_ERR_OK) {
- report_error(TE_SCI_UNABLE_TO_DISCONNECT_SEGMENT);
- DBUG_PRINT("error", ("Unable to disconnect segment"));
- DBUG_RETURN(false);
- }
- DBUG_PRINT("info", ("Remote memory segment is unmapped and disconnected"));
- }
- DBUG_RETURN(true);
-} // disconnectRemote()
-
-
-SCI_Transporter::~SCI_Transporter() {
- DBUG_ENTER("SCI_Transporter::~SCI_Transporter");
- // Close channel to the driver
- doDisconnect();
- if(m_sendBuffer.m_buffer != NULL)
- delete[] m_sendBuffer.m_buffer;
- DBUG_VOID_RETURN;
-} // ~SCI_Transporter()
-
-void SCI_Transporter::closeSCI() {
- // Termination of SCI
- sci_error_t err;
- DBUG_ENTER("SCI_Transporter::closeSCI");
-
- // Disconnect and remove remote segment
- disconnectRemote();
-
- // Unmap and remove local segment
-
- disconnectLocal();
-
- // Closes an SCI virtual device
- SCIClose(activeSCIDescriptor, FLAGS, &err);
-
- if(err != SCI_ERR_OK) {
- DBUG_PRINT("error",
- ("Cannot close SCI channel to the driver. Error code 0x%x",
- err));
- }
- SCITerminate();
- DBUG_VOID_RETURN;
-} // closeSCI()
-
-Uint32 *
-SCI_Transporter::getWritePtr(Uint32 lenBytes, Uint32 prio)
-{
-
- Uint32 sci_buffer_remaining = m_sendBuffer.m_forceSendLimit;
- Uint32 send_buf_size = m_sendBuffer.m_sendBufferSize;
- Uint32 curr_data_size = m_sendBuffer.m_dataSize << 2;
- Uint32 new_curr_data_size = curr_data_size + lenBytes;
- if ((curr_data_size >= send_buf_size) ||
- (curr_data_size >= sci_buffer_remaining)) {
- /**
- * The new message will not fit in the send buffer. We need to
- * send the send buffer before filling it up with the new
- * signal data. If current data size will spill over buffer edge
- * we will also send to ensure correct operation.
- */
- if (!doSend()) {
- /**
- * We were not successfull sending, report 0 as meaning buffer full and
- * upper levels handle retries and other recovery matters.
- */
- return 0;
- }
- }
- /**
- * New signal fits, simply fill it up with more data.
- */
- Uint32 sz = m_sendBuffer.m_dataSize;
- return &m_sendBuffer.m_buffer[sz];
-}
-
-void
-SCI_Transporter::updateWritePtr(Uint32 lenBytes, Uint32 prio){
-
- Uint32 sz = m_sendBuffer.m_dataSize;
- Uint32 packet_size = m_PacketSize;
- sz += ((lenBytes + 3) >> 2);
- m_sendBuffer.m_dataSize = sz;
-
- if(sz > packet_size) {
- /**-------------------------------------------------
- * Buffer is full and we are ready to send. We will
- * not wait since the signal is already in the buffer.
- * Force flag set has the same indication that we
- * should always send. If it is not possible to send
- * we will not worry since we will soon be back for
- * a renewed trial.
- *-------------------------------------------------
- */
- doSend();
- }
-}
-
-enum SciStatus {
- SCIDISCONNECT = 1,
- SCICONNECTED = 2
-};
-
-bool
-SCI_Transporter::getConnectionStatus() {
- if(*m_localStatusFlag == SCICONNECTED &&
- (*m_remoteStatusFlag == SCICONNECTED ||
- ((m_adapters > 1) &&
- *m_remoteStatusFlag2 == SCICONNECTED)))
- return true;
- else
- return false;
-}
-
-void
-SCI_Transporter::setConnected() {
- *m_remoteStatusFlag = SCICONNECTED;
- if (m_adapters > 1) {
- *m_remoteStatusFlag2 = SCICONNECTED;
- }
- *m_localStatusFlag = SCICONNECTED;
-}
-
-void
-SCI_Transporter::setDisconnect() {
- if(getLinkStatus(m_ActiveAdapterId))
- *m_remoteStatusFlag = SCIDISCONNECT;
- if (m_adapters > 1) {
- if(getLinkStatus(m_StandbyAdapterId))
- *m_remoteStatusFlag2 = SCIDISCONNECT;
- }
-}
-
-bool
-SCI_Transporter::checkConnected() {
- if (*m_localStatusFlag == SCIDISCONNECT) {
- return false;
- }
- else
- return true;
-}
-
-static bool init = false;
-
-bool
-SCI_Transporter::initSCI() {
- DBUG_ENTER("SCI_Transporter::initSCI");
- if(!init){
- sci_error_t error;
- // Initialize SISCI library
- SCIInitialize(0, &error);
- if(error != SCI_ERR_OK) {
- DBUG_PRINT("error", ("Cannot initialize SISCI library."));
- DBUG_PRINT("error",
- ("Inconsistency between SISCI library and SISCI driver. Error code 0x%x",
- error));
- DBUG_RETURN(false);
- }
- init = true;
- }
- DBUG_RETURN(true);
-}
-
-Uint32
-SCI_Transporter::get_free_buffer() const
-{
- return (m_TargetSegm[m_ActiveAdapterId].writer)->get_free_buffer();
-}
-
diff --git a/storage/ndb/src/common/transporter/SCI_Transporter.hpp b/storage/ndb/src/common/transporter/SCI_Transporter.hpp
deleted file mode 100644
index 5135ba7a83b..00000000000
--- a/storage/ndb/src/common/transporter/SCI_Transporter.hpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SCI_Transporter_H
-#define SCI_Transporter_H
-#include "Transporter.hpp"
-#include "SHM_Buffer.hpp"
-
-
-#include <sisci_api.h>
-#include <sisci_error.h>
-#include <sisci_types.h>
-
-#include <ndb_types.h>
-
-/**
- * The SCI Transporter
- *
- * The design goal of the SCI transporter is to deliver high performance
- * data transfers (low latency, high bandwidth) combined with very high
- * availability (failover support).
- * High performance is an inherit feature of SCI and the, whereas failover
- * support is implemented at the application level.
- * In SCI the programming model is similar to the shared memory paradigm.
- * A process on one node (A) allocates a memory segment and import the
- * segment to its virtual address space. Another node (B) can connect to
- * the segment and map this segment into its virtual address space.
- * If A writes data to the segment, then B can read it and vice versa, through
- * ordinary loads and stores. This is also called PIO (programmable IO), and
- * is one thing that distinguish SCI from other interconnects such as,
- * ethernet, Gig-e, Myrinet, and Infiniband. By using PIO, lower network
- * latency is achieved, compared to the interconnects mentioned above.
- * In order for NDB to utilize SCI, the SCI transporter relies on the
- * SISCI api. The SISCI api provides a high level abstraction to the low
- * level SCI driver called PCISCI driver.
- * The SISCI api provides functions to setup, export, and import
- * memory segments in a process virtual address space, and also functions to
- * guarantee the correctness of data transfers between nodes. Basically, the
- *
- * In NDB Cluster, each SCI transporter creates a local segment
- * that is mapped into the virtual address space. After the creation of the
- * local segment, the SCI transporter connects to a segment created by another
- * transporter at a remote node, and the maps the remote segment into its
- * virtual address space. However, since NDB Cluster relies on redundancy
- * at the network level, by using dual SCI adapters communication can be
- * maintained even if one of the adapter cards fails (or anything on the
- * network this adapter card exists in e.g. an SCI switch failure).
- *
- */
-
-/**
- * class SCITransporter
- * @brief - main class for the SCI transporter.
- */
-class SCI_Transporter : public Transporter {
- friend class TransporterRegistry;
-public:
-
- /**
- * Init the transporter. Allocate sendbuffers and open a SCI virtual device
- * for each adapter.
- * @return true if successful, otherwize false
- */
- bool initTransporter();
-
-
- /**
- * Creates a sequence for error checking.
- * @param adapterid the adapter on which to create a new sequence.
- * @return SCI_ERR_OK if ok, otherwize something else.
- */
- sci_error_t createSequence(Uint32 adapterid);
-
-
- /** Initiate Local Segment: create a memory segment,
- * prepare a memory segment, map the local segment
- * into memory space and make segment available.
- * @return SCI_ERR_OK if ok, otherwize something else.
- */
- sci_error_t initLocalSegment();
-
- /**
- * Calculate the segment id for the remote segment
- * @param localNodeId - local id (e.g. 1 = mgm , 2 = ndb.2 etc.)
- * @param remoteNodeId - remote id (e.g. 1 = mgm , 2 = ndb.2 etc.)
- * @return a segment id
- */
- Uint32 remoteSegmentId(Uint16 localNodeId, Uint16 remoteNodeId);
-
- // Get local segment id (inline)
- Uint32 hostSegmentId(Uint16 localNodeId, Uint16 remoteNodeId);
-
- /**
- * closeSCI closes the SCI virtual device
- */
- void closeSCI();
-
-
- /**
- * Check the status of the remote node,
- * if it is connected or has disconnected
- * @return true if connected, otherwize false.
- */
- bool checkConnected();
-
- /**
- * Check if the segment are properly connected to each other (remotely
- * and locally).
- * @return True if the both the local segment is mapped and the
- * remote segment is mapped. Otherwize false.
- */
- bool getConnectionStatus();
-
- virtual Uint32 get_free_buffer() const;
-private:
- SCI_Transporter(TransporterRegistry &t_reg,
- const char *local_host,
- const char *remote_host,
- int port,
- bool isMgmConnection,
- Uint32 packetSize,
- Uint32 bufferSize,
- Uint32 nAdapters,
- Uint16 remoteSciNodeId0,
- Uint16 remoteSciNodeId1,
- NodeId localNodeID,
- NodeId remoteNodeID,
- NodeId serverNodeId,
- bool checksum,
- bool signalId,
- Uint32 reportFreq = 4096);
-
- /**
- * Destructor. Disconnects the transporter.
- */
- ~SCI_Transporter();
- bool m_mapped;
- bool m_initLocal;
- bool m_sciinit;
- Uint32 m_failCounter;
- /**
- * For statistics on transfered packets
- */
-//#ifdef DEBUG_TRANSPORTER
-#if 1
- Uint32 i1024;
- Uint32 i2048;
- Uint32 i2049;
- Uint32 i10242048;
- Uint32 i20484096;
- Uint32 i4096;
- Uint32 i4097;
-#endif
-
- volatile Uint32 * m_localStatusFlag;
- volatile Uint32 * m_remoteStatusFlag;
- volatile Uint32 * m_remoteStatusFlag2;
-
- struct {
- Uint32 * m_buffer; // The buffer
- Uint32 m_dataSize; // No of words in buffer
- Uint32 m_sendBufferSize; // Buffer size
- Uint32 m_forceSendLimit; // Send when buffer is this full
- } m_sendBuffer;
-
- SHM_Reader * reader;
- SHM_Writer * writer;
- SHM_Writer * writer2;
-
- /**
- * Statistics
- */
- Uint32 m_reportFreq;
-
- Uint32 m_adapters;
- Uint32 m_numberOfRemoteNodes;
-
- Uint16 m_remoteNodes[2];
-
- typedef struct SciAdapter {
- sci_desc_t scidesc;
- Uint32 localSciNodeId;
- bool linkStatus;
- } SciAdapter;
-
- SciAdapter* sciAdapters;
- Uint32 m_ActiveAdapterId;
- Uint32 m_StandbyAdapterId;
-
- typedef struct sourceSegm {
- sci_local_segment_t localHandle; // Handle to local segment to be mapped
- struct localHandleMap {
- sci_map_t map; // Handle to the new mapped segment.
- // 2 = max adapters in one node
- } lhm[2];
-
- volatile void *mappedMemory; // Used when reading
- } sourceSegm;
-
- typedef struct targetSegm {
- struct remoteHandleMap {
- sci_remote_segment_t remoteHandle; //Handle to local segment to be mapped
- sci_map_t map; //Handle to the new mapped segment
- } rhm[2];
-
- sci_sequence_status_t m_SequenceStatus; // Used for error checking
- sci_sequence_t sequence;
- volatile void * mappedMemory; // Used when writing
- SHM_Writer * writer;
- } targetSegm;
-
- sci_sequence_status_t m_SequenceStatus; // Used for error checking
-
-
- // Shared between all SCI users active=(either prim or second)
- sci_desc_t activeSCIDescriptor;
-
- sourceSegm* m_SourceSegm; // Local segment reference
- targetSegm* m_TargetSegm; // Remote segment reference
-
- Uint32 m_LocalAdapterId; // Adapter Id
- Uint16 m_LocalSciNodeId; // The SCI-node Id of this machine (adapter 0)
- Uint16 m_LocalSciNodeId1; // The SCI-node Id of this machine (adapter 1)
- Uint16 m_RemoteSciNodeId; // The SCI-node Id of remote machine (adapter 0)
- Uint16 m_RemoteSciNodeId1; // The SCI-node Id of remote machine (adapter 1)
-
- Uint32 m_PacketSize; // The size of each data packet
- Uint32 m_BufferSize; // Mapped SCI buffer size
-
- Uint32 * getWritePtr(Uint32 lenBytes, Uint32 prio);
- void updateWritePtr(Uint32 lenBytes, Uint32 prio);
-
- /**
- * doSend. Copies the data from the source (the send buffer) to the
- * shared mem. segment.
- * Sequences are used for error checking.
- * If an error occurs, the transfer is retried.
- * If the link that we need to swap to is broken, we will disconnect.
- * @return Returns true if datatransfer ok. If not retriable
- * then false is returned.
- */
- bool doSend();
-
- /**
- * @param adapterNo the adapter for which to retrieve the node id.
- * @return Returns the node id for an adapter.
- */
- Uint32 getLocalNodeId(Uint32 adapterNo);
-
- bool hasDataToRead() const {
- return reader->empty() == false;
- }
-
- bool hasDataToSend() const {
- return m_sendBuffer.m_dataSize > 0;
- }
-
- /**
- * Make the local segment unavailable, no new connections will be accepted.
- * @return Returns true if the segment was successfully disconnected.
- */
- bool disconnectLocal();
-
- /**
- * Make the local segment unavailable, no new connections will be accepted.
- * @return Returns true if the segment was successfully disconnected.
- */
- bool disconnectRemote();
-
- void resetToInitialState();
-
- /**
- * It is always possible to send data with SCI!
- * @return True (always)
- */
- bool sendIsPossible(struct timeval * timeout);
-
- void getReceivePtr(Uint32 ** ptr, Uint32 ** eod){
- reader->getReadPtr(* ptr, * eod);
- }
-
- void updateReceivePtr(Uint32 *ptr){
- reader->updateReadPtr(ptr);
- }
-
- /**
- * Corresponds to SHM_Transporter::setupBuffers()
- * Initiates the start pointer of the buffer and read pointers.
- * Initiate the localSegment for the SHM reader.
- */
- void setupLocalSegment();
-
- /**
- * Initiate the remoteSegment for the SHM writer
- */
- void setupRemoteSegment();
-
- /**
- * Set the connect flag in the remote memory segment (write through)
- */
- void setConnected();
-
- /**
- * Set the disconnect flag in the remote memory segment (write through)
- */
- void setDisconnect();
-
- /**
- * Check if there is a link between the adapter and the switch
- * @param adapterNo the adapter for which to retrieve the link status.
- * @return Returns true if there is a link between adapter and switch.
- * Otherwize false is returned and the cables must be checked.
- */
- bool getLinkStatus(Uint32 adapterNo);
-
- /**
- * failoverShmWriter takes the state of the active writer and inserts into
- * the standby writer.
- */
- void failoverShmWriter();
-
- bool init_local();
- bool init_remote();
-
-protected:
-
- /** Perform a connection between segment
- * This is a client node, trying to connect to a remote segment.
- * @param timeout, the time the connect thread sleeps before
- * retrying.
- * @return Returns true on success, otherwize falser
- */
- bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
- bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
-
- /**
- * We will disconnect if:
- * -# the other node has disconnected from us
- * -# unrecoverable error in transmission, on both adapters
- * -# if we are shutdown properly
- */
- void disconnectImpl();
-
- static bool initSCI();
-};
-
-
-/** The theLocalAdapterId combined with the theRemoteNodeId constructs
- * (SCI ids)* a unique identifier for the local segment
- */
-inline
-Uint32
-SCI_Transporter::hostSegmentId(Uint16 SciLocalNodeId,
- Uint16 SciRemoteNodeId) {
-
- return (SciLocalNodeId << 16) | SciRemoteNodeId;
-}
-
-/** The theLocalAdapterId combined with the theRemoteNodeId constructs
- * (SCI ids)* a unique identifier for the remote segment
- */
-inline
-Uint32
-SCI_Transporter::remoteSegmentId(Uint16 SciLocalNodeId,
- Uint16 SciRemoteNodeId) {
-
- return (SciRemoteNodeId << 16) | SciLocalNodeId;
-}
-
-
-#endif
diff --git a/storage/ndb/src/common/transporter/SHM_Buffer.hpp b/storage/ndb/src/common/transporter/SHM_Buffer.hpp
deleted file mode 100644
index 5e900170318..00000000000
--- a/storage/ndb/src/common/transporter/SHM_Buffer.hpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SHM_BUFFER_HPP
-#define SHM_BUFFER_HPP
-
-#include <ndb_global.h>
-
-#include <NdbSleep.h>
-
-/**
- * These classes implement a circular buffer
- *
- * One reader and one writer
- */
-
-/**
- * SHM_Reader
- *
- * Use as follows:
- * getReadPtr(ptr, sz);
- * for(int i = 0; i<sz; i++)
- * printf("%c\n", ptr[i]);
- * updateReadPtr(sz);
- */
-class SHM_Reader {
-public:
- SHM_Reader(char * const _startOfBuffer,
- Uint32 _sizeOfBuffer,
- Uint32 _slack,
- Uint32 * _readIndex,
- Uint32 * _writeIndex) :
- m_startOfBuffer(_startOfBuffer),
- m_totalBufferSize(_sizeOfBuffer),
- m_bufferSize(_sizeOfBuffer - _slack),
- m_sharedReadIndex(_readIndex),
- m_sharedWriteIndex(_writeIndex)
- {
- }
-
- void clear() {
- m_readIndex = 0;
- }
-
- /**
- *
- */
- inline bool empty() const;
-
- /**
- * Get read pointer
- *
- * returns ptr - where to start reading
- * sz - how much can I read
- */
- inline void getReadPtr(Uint32 * & ptr, Uint32 * & eod);
-
- /**
- * Update read ptr
- */
- inline void updateReadPtr(Uint32 *ptr);
-
-private:
- char * const m_startOfBuffer;
- Uint32 m_totalBufferSize;
- Uint32 m_bufferSize;
- Uint32 m_readIndex;
-
- Uint32 * m_sharedReadIndex;
- Uint32 * m_sharedWriteIndex;
-};
-
-inline
-bool
-SHM_Reader::empty() const{
- bool ret = (m_readIndex == * m_sharedWriteIndex);
- return ret;
-}
-
-/**
- * Get read pointer
- *
- * returns ptr - where to start reading
- * sz - how much can I read
- */
-inline
-void
-SHM_Reader::getReadPtr(Uint32 * & ptr, Uint32 * & eod)
-{
- Uint32 tReadIndex = m_readIndex;
- Uint32 tWriteIndex = * m_sharedWriteIndex;
-
- ptr = (Uint32*)&m_startOfBuffer[tReadIndex];
-
- if(tReadIndex <= tWriteIndex){
- eod = (Uint32*)&m_startOfBuffer[tWriteIndex];
- } else {
- eod = (Uint32*)&m_startOfBuffer[m_bufferSize];
- }
-}
-
-/**
- * Update read ptr
- */
-inline
-void
-SHM_Reader::updateReadPtr(Uint32 *ptr)
-{
- Uint32 tReadIndex = ((char*)ptr) - m_startOfBuffer;
-
- assert(tReadIndex < m_totalBufferSize);
-
- if(tReadIndex >= m_bufferSize){
- tReadIndex = 0;
- }
-
- m_readIndex = tReadIndex;
- * m_sharedReadIndex = tReadIndex;
-}
-
-#define WRITER_SLACK 4
-
-class SHM_Writer {
-public:
- SHM_Writer(char * const _startOfBuffer,
- Uint32 _sizeOfBuffer,
- Uint32 _slack,
- Uint32 * _readIndex,
- Uint32 * _writeIndex) :
- m_startOfBuffer(_startOfBuffer),
- m_totalBufferSize(_sizeOfBuffer),
- m_bufferSize(_sizeOfBuffer - _slack),
- m_sharedReadIndex(_readIndex),
- m_sharedWriteIndex(_writeIndex)
- {
- }
-
- void clear() {
- m_writeIndex = 0;
- }
-
- inline char * getWritePtr(Uint32 sz);
- inline void updateWritePtr(Uint32 sz);
-
- inline Uint32 getWriteIndex() const { return m_writeIndex;}
- inline Uint32 getBufferSize() const { return m_bufferSize;}
- inline Uint32 get_free_buffer() const;
-
- inline void copyIndexes(SHM_Writer * standbyWriter);
-
-private:
- char * const m_startOfBuffer;
- Uint32 m_totalBufferSize;
- Uint32 m_bufferSize;
-
- Uint32 m_writeIndex;
-
- Uint32 * m_sharedReadIndex;
- Uint32 * m_sharedWriteIndex;
-};
-
-inline
-char *
-SHM_Writer::getWritePtr(Uint32 sz){
- Uint32 tReadIndex = * m_sharedReadIndex;
- Uint32 tWriteIndex = m_writeIndex;
-
- char * ptr = &m_startOfBuffer[tWriteIndex];
-
- Uint32 free;
- if(tReadIndex <= tWriteIndex){
- free = m_bufferSize + tReadIndex - tWriteIndex;
- } else {
- free = tReadIndex - tWriteIndex;
- }
-
- sz += 4;
- if(sz < free){
- return ptr;
- }
-
- return 0;
-}
-
-inline
-void
-SHM_Writer::updateWritePtr(Uint32 sz){
-
- assert(m_writeIndex == * m_sharedWriteIndex);
-
- Uint32 tWriteIndex = m_writeIndex;
- tWriteIndex += sz;
-
- assert(tWriteIndex < m_totalBufferSize);
-
- if(tWriteIndex >= m_bufferSize){
- tWriteIndex = 0;
- }
-
- m_writeIndex = tWriteIndex;
- * m_sharedWriteIndex = tWriteIndex;
-}
-
-inline
-Uint32
-SHM_Writer::get_free_buffer() const
-{
- Uint32 tReadIndex = * m_sharedReadIndex;
- Uint32 tWriteIndex = m_writeIndex;
-
- Uint32 free;
- if(tReadIndex <= tWriteIndex){
- free = m_bufferSize + tReadIndex - tWriteIndex;
- } else {
- free = tReadIndex - tWriteIndex;
- }
- return free;
-}
-
-#endif
diff --git a/storage/ndb/src/common/transporter/SHM_Transporter.cpp b/storage/ndb/src/common/transporter/SHM_Transporter.cpp
deleted file mode 100644
index 649891a8ad7..00000000000
--- a/storage/ndb/src/common/transporter/SHM_Transporter.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "SHM_Transporter.hpp"
-#include "TransporterInternalDefinitions.hpp"
-#include <TransporterCallback.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-
-#include <InputStream.hpp>
-#include <OutputStream.hpp>
-
-extern int g_ndb_shm_signum;
-
-SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg,
- const char *lHostName,
- const char *rHostName,
- int r_port,
- bool isMgmConnection_arg,
- NodeId lNodeId,
- NodeId rNodeId,
- NodeId serverNodeId,
- bool checksum,
- bool signalId,
- key_t _shmKey,
- Uint32 _shmSize) :
- Transporter(t_reg, tt_SHM_TRANSPORTER,
- lHostName, rHostName, r_port, isMgmConnection_arg,
- lNodeId, rNodeId, serverNodeId,
- 0, false, checksum, signalId),
- shmKey(_shmKey),
- shmSize(_shmSize)
-{
-#ifndef NDB_WIN32
- shmId= 0;
-#endif
- _shmSegCreated = false;
- _attached = false;
-
- shmBuf = 0;
- reader = 0;
- writer = 0;
-
- setupBuffersDone=false;
-#ifdef DEBUG_TRANSPORTER
- printf("shm key (%d - %d) = %d\n", lNodeId, rNodeId, shmKey);
-#endif
- m_signal_threshold = 4096;
-}
-
-SHM_Transporter::~SHM_Transporter(){
- doDisconnect();
-}
-
-bool
-SHM_Transporter::initTransporter(){
- if (g_ndb_shm_signum)
- return true;
- return false;
-}
-
-void
-SHM_Transporter::setupBuffers(){
- Uint32 sharedSize = 0;
- sharedSize += 28; //SHM_Reader::getSharedSize();
- sharedSize += 28; //SHM_Writer::getSharedSize();
-
- const Uint32 slack = MAX_MESSAGE_SIZE;
-
- /**
- * NOTE: There is 7th shared variable in Win2k (sharedCountAttached).
- */
- Uint32 sizeOfBuffer = shmSize;
- sizeOfBuffer -= 2*sharedSize;
- sizeOfBuffer /= 2;
-
- Uint32 * base1 = (Uint32*)shmBuf;
-
- Uint32 * sharedReadIndex1 = base1;
- Uint32 * sharedWriteIndex1 = base1 + 1;
- serverStatusFlag = base1 + 4;
- char * startOfBuf1 = shmBuf+sharedSize;
-
- Uint32 * base2 = (Uint32*)(shmBuf + sizeOfBuffer + sharedSize);
- Uint32 * sharedReadIndex2 = base2;
- Uint32 * sharedWriteIndex2 = base2 + 1;
- clientStatusFlag = base2 + 4;
- char * startOfBuf2 = ((char *)base2)+sharedSize;
-
- if(isServer){
- * serverStatusFlag = 0;
- reader = new SHM_Reader(startOfBuf1,
- sizeOfBuffer,
- slack,
- sharedReadIndex1,
- sharedWriteIndex1);
-
- writer = new SHM_Writer(startOfBuf2,
- sizeOfBuffer,
- slack,
- sharedReadIndex2,
- sharedWriteIndex2);
-
- * sharedReadIndex1 = 0;
- * sharedWriteIndex1 = 0;
-
- * sharedReadIndex2 = 0;
- * sharedWriteIndex2 = 0;
-
- reader->clear();
- writer->clear();
-
- * serverStatusFlag = 1;
-
-#ifdef DEBUG_TRANSPORTER
- printf("-- (%d - %d) - Server -\n", localNodeId, remoteNodeId);
- printf("Reader at: %d (%p)\n", startOfBuf1 - shmBuf, startOfBuf1);
- printf("sharedReadIndex1 at %d (%p) = %d\n",
- (char*)sharedReadIndex1-shmBuf,
- sharedReadIndex1, *sharedReadIndex1);
- printf("sharedWriteIndex1 at %d (%p) = %d\n",
- (char*)sharedWriteIndex1-shmBuf,
- sharedWriteIndex1, *sharedWriteIndex1);
-
- printf("Writer at: %d (%p)\n", startOfBuf2 - shmBuf, startOfBuf2);
- printf("sharedReadIndex2 at %d (%p) = %d\n",
- (char*)sharedReadIndex2-shmBuf,
- sharedReadIndex2, *sharedReadIndex2);
- printf("sharedWriteIndex2 at %d (%p) = %d\n",
- (char*)sharedWriteIndex2-shmBuf,
- sharedWriteIndex2, *sharedWriteIndex2);
-
- printf("sizeOfBuffer = %d\n", sizeOfBuffer);
-#endif
- } else {
- * clientStatusFlag = 0;
- reader = new SHM_Reader(startOfBuf2,
- sizeOfBuffer,
- slack,
- sharedReadIndex2,
- sharedWriteIndex2);
-
- writer = new SHM_Writer(startOfBuf1,
- sizeOfBuffer,
- slack,
- sharedReadIndex1,
- sharedWriteIndex1);
-
- * sharedReadIndex2 = 0;
- * sharedWriteIndex1 = 0;
-
- reader->clear();
- writer->clear();
- * clientStatusFlag = 1;
-#ifdef DEBUG_TRANSPORTER
- printf("-- (%d - %d) - Client -\n", localNodeId, remoteNodeId);
- printf("Reader at: %d (%p)\n", startOfBuf2 - shmBuf, startOfBuf2);
- printf("sharedReadIndex2 at %d (%p) = %d\n",
- (char*)sharedReadIndex2-shmBuf,
- sharedReadIndex2, *sharedReadIndex2);
- printf("sharedWriteIndex2 at %d (%p) = %d\n",
- (char*)sharedWriteIndex2-shmBuf,
- sharedWriteIndex2, *sharedWriteIndex2);
-
- printf("Writer at: %d (%p)\n", startOfBuf1 - shmBuf, startOfBuf1);
- printf("sharedReadIndex1 at %d (%p) = %d\n",
- (char*)sharedReadIndex1-shmBuf,
- sharedReadIndex1, *sharedReadIndex1);
- printf("sharedWriteIndex1 at %d (%p) = %d\n",
- (char*)sharedWriteIndex1-shmBuf,
- sharedWriteIndex1, *sharedWriteIndex1);
-
- printf("sizeOfBuffer = %d\n", sizeOfBuffer);
-#endif
- }
-#ifdef DEBUG_TRANSPORTER
- printf("Mapping from %p to %p\n", shmBuf, shmBuf+shmSize);
-#endif
-}
-
-bool
-SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("SHM_Transporter::connect_server_impl");
- SocketOutputStream s_output(sockfd);
- SocketInputStream s_input(sockfd);
- char buf[256];
-
- // Create
- if(!_shmSegCreated){
- if (!ndb_shm_create()) {
- make_error_info(buf, sizeof(buf));
- report_error(TE_SHM_UNABLE_TO_CREATE_SEGMENT, buf);
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- _shmSegCreated = true;
- }
-
- // Attach
- if(!_attached){
- if (!ndb_shm_attach()) {
- make_error_info(buf, sizeof(buf));
- report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT, buf);
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- _attached = true;
- }
-
- // Send ok to client
- s_output.println("shm server 1 ok: %d",
- m_transporter_registry.m_shm_own_pid);
-
- // Wait for ok from client
- DBUG_PRINT("info", ("Wait for ok from client"));
- if (s_input.gets(buf, sizeof(buf)) == 0)
- {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- if(sscanf(buf, "shm client 1 ok: %d", &m_remote_pid) != 1)
- {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- int r= connect_common(sockfd);
-
- if (r) {
- // Send ok to client
- s_output.println("shm server 2 ok");
- // Wait for ok from client
- if (s_input.gets(buf, 256) == 0) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
- DBUG_PRINT("info", ("Successfully connected server to node %d",
- remoteNodeId));
- }
-
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(r);
-}
-
-bool
-SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("SHM_Transporter::connect_client_impl");
- SocketInputStream s_input(sockfd);
- SocketOutputStream s_output(sockfd);
- char buf[256];
-
- // Wait for server to create and attach
- DBUG_PRINT("info", ("Wait for server to create and attach"));
- if (s_input.gets(buf, 256) == 0) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("error", ("Server id %d did not attach",
- remoteNodeId));
- DBUG_RETURN(false);
- }
-
- if(sscanf(buf, "shm server 1 ok: %d", &m_remote_pid) != 1)
- {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- // Create
- if(!_shmSegCreated){
- if (!ndb_shm_get()) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("error", ("Failed create of shm seg to node %d",
- remoteNodeId));
- DBUG_RETURN(false);
- }
- _shmSegCreated = true;
- }
-
- // Attach
- if(!_attached){
- if (!ndb_shm_attach()) {
- make_error_info(buf, sizeof(buf));
- report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT, buf);
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("error", ("Failed attach of shm seg to node %d",
- remoteNodeId));
- DBUG_RETURN(false);
- }
- _attached = true;
- }
-
- // Send ok to server
- s_output.println("shm client 1 ok: %d",
- m_transporter_registry.m_shm_own_pid);
-
- int r= connect_common(sockfd);
-
- if (r) {
- // Wait for ok from server
- DBUG_PRINT("info", ("Wait for ok from server"));
- if (s_input.gets(buf, 256) == 0) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_PRINT("error", ("No ok from server node %d",
- remoteNodeId));
- DBUG_RETURN(false);
- }
- // Send ok to server
- s_output.println("shm client 2 ok");
- DBUG_PRINT("info", ("Successfully connected client to node %d",
- remoteNodeId));
- }
-
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(r);
-}
-
-bool
-SHM_Transporter::connect_common(NDB_SOCKET_TYPE sockfd)
-{
- if (!checkConnected()) {
- return false;
- }
-
- if(!setupBuffersDone)
- {
- setupBuffers();
- setupBuffersDone=true;
- }
-
- if(setupBuffersDone)
- {
- NdbSleep_MilliSleep(m_timeOutMillis);
- if(*serverStatusFlag == 1 && *clientStatusFlag == 1)
- {
- m_last_signal = 0;
- return true;
- }
- }
-
- DBUG_PRINT("error", ("Failed to set up buffers to node %d",
- remoteNodeId));
- return false;
-}
-
-void
-SHM_Transporter::doSend()
-{
- if(m_last_signal)
- {
- m_last_signal = 0;
- kill(m_remote_pid, g_ndb_shm_signum);
- }
-}
-
-Uint32
-SHM_Transporter::get_free_buffer() const
-{
- return writer->get_free_buffer();
-}
diff --git a/storage/ndb/src/common/transporter/SHM_Transporter.hpp b/storage/ndb/src/common/transporter/SHM_Transporter.hpp
deleted file mode 100644
index d9eef794001..00000000000
--- a/storage/ndb/src/common/transporter/SHM_Transporter.hpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SHM_Transporter_H
-#define SHM_Transporter_H
-
-#include "Transporter.hpp"
-#include "SHM_Buffer.hpp"
-
-#ifdef NDB_WIN32
-typedef Uint32 key_t;
-#endif
-
-/**
- * class SHMTransporter
- * @brief - main class for the SHM transporter.
- */
-
-class SHM_Transporter : public Transporter {
- friend class TransporterRegistry;
-public:
- SHM_Transporter(TransporterRegistry &,
- const char *lHostName,
- const char *rHostName,
- int r_port,
- bool isMgmConnection,
- NodeId lNodeId,
- NodeId rNodeId,
- NodeId serverNodeId,
- bool checksum,
- bool signalId,
- key_t shmKey,
- Uint32 shmSize);
-
- /**
- * SHM destructor
- */
- virtual ~SHM_Transporter();
-
- /**
- * Do initialization
- */
- bool initTransporter();
-
- Uint32 * getWritePtr(Uint32 lenBytes, Uint32 prio)
- {
- return (Uint32 *)writer->getWritePtr(lenBytes);
- }
-
- void updateWritePtr(Uint32 lenBytes, Uint32 prio)
- {
- writer->updateWritePtr(lenBytes);
- m_last_signal += lenBytes;
- if(m_last_signal >= m_signal_threshold)
- {
- doSend();
- }
- }
-
- void getReceivePtr(Uint32 ** ptr, Uint32 ** eod){
- reader->getReadPtr(* ptr, * eod);
- }
-
- void updateReceivePtr(Uint32 * ptr){
- reader->updateReadPtr(ptr);
- }
-
-protected:
- /**
- * disconnect a segmnet
- * -# deletes the shm buffer associated with a segment
- * -# marks the segment for removal
- */
- void disconnectImpl();
-
- /**
- * Blocking
- *
- * -# Create shm segment
- * -# Attach to it
- * -# Wait for someone to attach (max wait = timeout), then rerun again
- * until connection established.
- * @param timeOutMillis - the time to sleep before (ms) trying again.
- * @returns - True if the server managed to hook up with the client,
- * i.e., both agrees that the other one has setup the segment.
- * Otherwise false.
- */
- virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
-
- /**
- * Blocking
- *
- * -# Attach to shm segment
- * -# Check if the segment is setup
- * -# Check if the server set it up
- * -# If all clear, return.
- * @param timeOutMillis - the time to sleep before (ms) trying again.
- * @returns - True if the client managed to hook up with the server,
- * i.e., both agrees that the other one has setup the segment.
- * Otherwise false.
- */
- virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
-
- bool connect_common(NDB_SOCKET_TYPE sockfd);
-
- bool ndb_shm_create();
- bool ndb_shm_get();
- bool ndb_shm_attach();
-
- /**
- * Check if there are two processes attached to the segment (a connection)
- * @return - True if the above holds. Otherwise false.
- */
- bool checkConnected();
-
-
- /**
- * Initialises the SHM_Reader and SHM_Writer on the segment
- */
- void setupBuffers();
-
- /**
- * doSend (i.e signal receiver)
- */
- void doSend();
- int m_remote_pid;
- Uint32 m_last_signal;
- Uint32 m_signal_threshold;
-
- virtual Uint32 get_free_buffer() const;
-
-private:
- bool _shmSegCreated;
- bool _attached;
- bool m_connected;
-
- key_t shmKey;
- volatile Uint32 * serverStatusFlag;
- volatile Uint32 * clientStatusFlag;
- bool setupBuffersDone;
-
-#ifdef NDB_WIN32
- HANDLE hFileMapping;
-#else
- int shmId;
-#endif
-
- int shmSize;
- char * shmBuf;
-
- SHM_Reader * reader;
- SHM_Writer * writer;
-
- /**
- * @return - True if the reader has data to read on its segment.
- */
- bool hasDataToRead() const {
- return reader->empty() == false;
- }
-
- void make_error_info(char info[], int sz);
-};
-
-#endif
diff --git a/storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp b/storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp
deleted file mode 100644
index cc9c5e7cb19..00000000000
--- a/storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "SHM_Transporter.hpp"
-#include "TransporterInternalDefinitions.hpp"
-#include <TransporterCallback.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-void SHM_Transporter::make_error_info(char info[], int sz)
-{
- snprintf(info,sz,"Shm key=%d sz=%d id=%d",
- shmKey, shmSize, shmId);
-}
-
-bool
-SHM_Transporter::ndb_shm_create()
-{
- shmId = shmget(shmKey, shmSize, IPC_CREAT | 960);
- if(shmId == -1) {
- perror("shmget: ");
- return false;
- }
- return true;
-}
-
-bool
-SHM_Transporter::ndb_shm_get()
-{
- shmId = shmget(shmKey, shmSize, 0);
- if(shmId == -1) {
- perror("shmget: ");
- return false;
- }
- return true;
-}
-
-bool
-SHM_Transporter::ndb_shm_attach()
-{
- shmBuf = (char *)shmat(shmId, 0, 0);
- if(shmBuf == 0) {
- perror("shmat: ");
- return false;
- }
- return true;
-}
-
-bool
-SHM_Transporter::checkConnected(){
- struct shmid_ds info;
- const int res = shmctl(shmId, IPC_STAT, &info);
- if(res == -1){
- char buf[128];
- int r= snprintf(buf, sizeof(buf),
- "shmctl(%d, IPC_STAT) errno: %d(%s). ", shmId,
- errno, strerror(errno));
- make_error_info(buf+r, sizeof(buf)-r);
- DBUG_PRINT("error",(buf));
- switch (errno)
- {
- case EACCES:
- report_error(TE_SHM_IPC_PERMANENT, buf);
- break;
- default:
- report_error(TE_SHM_IPC_STAT, buf);
- break;
- }
- return false;
- }
-
- if(info.shm_nattch != 2){
- char buf[128];
- make_error_info(buf, sizeof(buf));
- report_error(TE_SHM_DISCONNECT);
- DBUG_PRINT("error", ("Already connected to node %d",
- remoteNodeId));
- return false;
- }
- return true;
-}
-
-void
-SHM_Transporter::disconnectImpl(){
- if(_attached){
- const int res = shmdt(shmBuf);
- if(res == -1){
- perror("shmdelete: ");
- return;
- }
- _attached = false;
- if(!isServer && _shmSegCreated)
- _shmSegCreated = false;
- }
-
- if(isServer && _shmSegCreated){
- const int res = shmctl(shmId, IPC_RMID, 0);
- if(res == -1){
- char buf[64];
- make_error_info(buf, sizeof(buf));
- report_error(TE_SHM_UNABLE_TO_REMOVE_SEGMENT);
- return;
- }
- _shmSegCreated = false;
- }
- setupBuffersDone=false;
-}
diff --git a/storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp b/storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp
deleted file mode 100644
index 78b1d367ef5..00000000000
--- a/storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "SHM_Transporter.hpp"
-#include "TransporterInternalDefinitions.hpp"
-#include <TransporterCallback.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-
-#include <windows.h>
-
-
-void SHM_Transporter::make_error_info(char info[], int sz)
-{
- snprintf(info,sz,"Shm key=%d sz=%d",
- shmKey, shmSize);
-}
-
-bool
-SHM_Transporter::connectServer(Uint32 timeOutMillis){
- if(!_shmSegCreated)
- {
- char szName[32];
- sprintf(szName, "ndb%lu", shmKey);
- hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
- 0,
- PAGE_READWRITE,
- 0,
- shmSize,
- szName);
-
- if(!hFileMapping)
- {
- reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_CREATE_SEGMENT);
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
- }
- _shmSegCreated = true;
- }
-
- if(!_attached){
- shmBuf = (char*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
- if(shmBuf == 0){
- reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_ATTACH_SEGMENT);
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
- }
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
- ++*sharedCountAttached;
- _attached = true;
- }
-
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
-
- if(*sharedCountAttached == 2 && !setupBuffersDone) {
- setupBuffers();
- setupBuffersDone=true;
- }
- if(*sharedCountAttached > 2) {
- reportThreadError(remoteNodeId, TE_SHM_DISCONNECT);
- return false;
- }
-
- if(setupBuffersDone) {
- NdbSleep_MilliSleep(timeOutMillis);
- if(*serverStatusFlag==1 && *clientStatusFlag==1)
- return true;
- }
-
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
-}
-
-bool
-SHM_Transporter::connectClient(Uint32 timeOutMillis){
- if(!_shmSegCreated)
- {
- char szName[32];
- sprintf(szName, "ndb%lu", shmKey);
- hFileMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
-
- if(!hFileMapping)
- {
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
- }
- _shmSegCreated = true;
- }
-
- if(!_attached){
- shmBuf = (char*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
- if(shmBuf == 0){
- reportThreadError(remoteNodeId, TE_SHM_UNABLE_TO_ATTACH_SEGMENT);
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
- }
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
- ++*sharedCountAttached;
- _attached = true;
- }
-
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
-
- if(*sharedCountAttached == 2 && !setupBuffersDone) {
- setupBuffers();
- setupBuffersDone=true;
- }
-
- if(setupBuffersDone) {
- if(*serverStatusFlag==1 && *clientStatusFlag==1)
- return true;
- }
- NdbSleep_MilliSleep(timeOutMillis);
- return false;
-
-}
-
-
-bool
-SHM_Transporter::checkConnected(){
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
- if(*sharedCountAttached != 2) {
- reportError(callbackObj, remoteNodeId, TE_SHM_DISCONNECT);
- return false;
- }
- return true;
-}
-
-void
-SHM_Transporter::disconnectImpl(){
- if(_attached) {
- volatile Uint32 * sharedCountAttached =
- (volatile Uint32*)(shmBuf + 6*sizeof(Uint32*));
-
- --*sharedCountAttached;
-
- if(!UnmapViewOfFile(shmBuf)) {
- reportError(callbackObj, remoteNodeId, TE_SHM_UNABLE_TO_REMOVE_SEGMENT);
- return;
- }
-
- _attached = false;
- if(!isServer && _shmSegCreated)
- _shmSegCreated = false;
- }
-
- if(_shmSegCreated){
- if(!CloseHandle(hFileMapping)) {
- reportError(callbackObj, remoteNodeId, TE_SHM_UNABLE_TO_REMOVE_SEGMENT);
- return;
- }
- _shmSegCreated = false;
- }
- setupBuffersDone=false;
-
-}
-
diff --git a/storage/ndb/src/common/transporter/SendBuffer.cpp b/storage/ndb/src/common/transporter/SendBuffer.cpp
deleted file mode 100644
index 7e62ebaa91c..00000000000
--- a/storage/ndb/src/common/transporter/SendBuffer.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SendBuffer.hpp"
-#include "TransporterInternalDefinitions.hpp"
-
-SendBuffer::SendBuffer(Uint32 bufSize) {
-
- sizeOfBuffer = bufSize;
- if(sizeOfBuffer < MAX_MESSAGE_SIZE)
- sizeOfBuffer = 2 * MAX_MESSAGE_SIZE;
- startOfBuffer = NULL;
-
- // Initalise pointers
- endOfBuffer = NULL;
- insertPtr = NULL;
- sendPtr = NULL;
- sendDataSize = 0;
- dataSize = 0;
-}
-
-bool
-SendBuffer::initBuffer(Uint32 aRemoteNodeId) {
-
- // Allocate memory for the buffer
-#ifdef DEBUG_TRANSPORTER
- ndbout << "Allocating " << sizeOfBuffer << " bytes for send buffer" << endl;
-#endif
-
- startOfBuffer = new Uint32[(sizeOfBuffer >> 2) + 1];
- endOfBuffer = startOfBuffer + (sizeOfBuffer >> 2);
-
- emptyBuffer();
- theRemoteNodeId = aRemoteNodeId;
- return true;
-}
-
-SendBuffer::~SendBuffer() {
- // Deallocate the buffer memory
- if(startOfBuffer != NULL)
- delete[] startOfBuffer;
-}
-
-int
-SendBuffer::bufferSize() {
- return dataSize;
-}
-
-Uint32
-SendBuffer::bufferSizeRemaining() const {
- return (sizeOfBuffer - dataSize);
-}
-
-void
-SendBuffer::emptyBuffer() {
- insertPtr = startOfBuffer;
- sendPtr = (char*)startOfBuffer;
- dataSize = 0;
- sendDataSize = 0;
-}
-
-#ifdef DEBUG_TRANSPORTER
-void
-SendBuffer::print() {
-
- printf("SendBuffer status printouts\n");
-
- printf( "sizeOfBuffer: %d\n", sizeOfBuffer);
- printf( "startOfBuffer: %.8x\n", startOfBuffer);
- printf( "endOfBuffer: %.8x\n", endOfBuffer);
- printf( "insertPtr: %.8x\n", insertPtr);
- printf( "sendPtr: %.8x\n", sendPtr);
- printf( "sendDataSize: %d\n", sendDataSize);
- printf( "dataSize: %d\n", dataSize);
-}
-#endif
diff --git a/storage/ndb/src/common/transporter/SendBuffer.hpp b/storage/ndb/src/common/transporter/SendBuffer.hpp
deleted file mode 100644
index 8d772aa4dbc..00000000000
--- a/storage/ndb/src/common/transporter/SendBuffer.hpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//****************************************************************************
-//
-// NAME
-// SendBuffer
-//
-// DESCRIPTION
-// The SendBuffer is a circular buffer storing signals waiting to be sent.
-// The signals can be of variable size and are copied into the buffer
-// in Protocol 6 format. There will be two SendBuffer instances
-// (priority level A and B) for each transporter using a buffer for
-// sending. The buffering will in most cases be done to send as big
-// packages as possible over TCP/IP.
-//
-//***************************************************************************/
-#ifndef SendBuffer_H
-#define SendBuffer_H
-
-#include "TransporterDefinitions.hpp"
-#include <TransporterCallback.hpp>
-
-#ifdef DEBUG_TRANSPORTER
-#include <ndb_global.h>
-#endif
-
-class SendBuffer {
- friend class TCP_Transporter;
-public:
- // Set member variables
- SendBuffer(Uint32 bufSize);
-
- // Deallocate the buffer memory
- ~SendBuffer();
-
- // Allocate memory for the buffer and initialize the buffer pointers
- bool initBuffer(Uint32 aRemoteNodeId);
-
- // Number of bytes remaining in the buffer
- Uint32 bufferSizeRemaining() const;
-
- // Number of bytes of data in the buffer
- int bufferSize();
-
- // Empty the buffer
- void emptyBuffer();
-
- /**
- * The transporter calls updateBuffer after a retrieve followed by
- * a successful send, to update the cirkular buffer pointers.
- * updateBuffer is called with the number of bytes really sent,
- * it may be that it is less than what was retrived from the buffer.
- * If that is the case there will be an incomplete message (slack)
- * in the SendBuffer.
- *
- * Returns 0 if buffer empty
- * else ~0
- */
- Uint32 bytesSent(Uint32 len);
-
-#ifdef DEBUG_TRANSPORTER
- // Prints the buffer status on the screen. Can be used for testing purposes.
- void print();
-#endif
-
- Uint32* getInsertPtr(Uint32 bytes);
- void updateInsertPtr(Uint32 bytes);
-
-private:
-
- Uint32 sizeOfBuffer; // Length, in number of bytes, of the buffer memory
- Uint32 dataSize; // Number of bytes in buffer
-
- Uint32 * startOfBuffer; // Pointer to the start of the buffer memory
- Uint32 * endOfBuffer; // Pointer to end of buffer
-
- Uint32 * insertPtr; // Where to insert next
-
- char * sendPtr; // Where data to send starts
- Uint32 sendDataSize; // Num bytes to send
-
- Uint32 theRemoteNodeId;
-};
-
-inline
-Uint32
-SendBuffer::bytesSent(Uint32 bytes) {
-
- if(bytes > dataSize){
-#ifdef DEBUG_TRANSPORTER
- printf("bytes(%d) > dataSize(%d)\n", bytes, dataSize);
-#endif
- abort();
- // reportError(0 ,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return 0;
- }//if
-
- if(bytes > sendDataSize){
-#ifdef DEBUG_TRANSPORTER
- printf("bytes(%d) > sendDataSize(%d)\n", bytes, sendDataSize);
-#endif
- abort();
- //reportError(0,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
- return 0;
- }//if
-
- dataSize -= bytes;
- sendPtr += bytes;
- sendDataSize -= bytes;
-
- if(sendDataSize == 0){
- if(sendPtr > (char*)insertPtr){
- sendPtr = (char *)startOfBuffer;
- sendDataSize = dataSize;
- } else {
- sendPtr = ((char*)insertPtr) - dataSize;
- sendDataSize = dataSize;
- }
- }
-
- if(dataSize == 0)
- return 0;
- return ~0;
-}
-
-inline
-Uint32*
-SendBuffer::getInsertPtr(Uint32 len){
- if (bufferSizeRemaining() < len){
- return 0;
- }
-
- const char * const tmpInsertPtr = (char *) insertPtr;
-
- if(tmpInsertPtr >= sendPtr){
- // Is there enough space at the end of the buffer?
- if ((tmpInsertPtr + len) < (char*)endOfBuffer){
- sendDataSize += len;
- return insertPtr;
- } else {
- // We have passed the end of the cirkular buffer,
- // must start from the beginning
- // Is there enough space in the beginning of the buffer?
- if ((Uint32)(sendPtr - (char *)startOfBuffer) <= len){
- // Not enough space available, insert failed
- return 0;
- } else {
- // There is space available at the beginning of the buffer
- // We start from the beginning, set endOfData and insertPtr
- insertPtr = startOfBuffer;
- if(sendDataSize != 0){
- return insertPtr;
- }
- sendPtr = (char *)startOfBuffer;
- sendDataSize = len;
- return insertPtr;
- }
- }
- } else {
- // sendPtr > insertPtr
- // Is there enought room
- if((tmpInsertPtr + len) < sendPtr){
- return insertPtr;
- }
- return 0;
- }
-}
-
-inline
-void
-SendBuffer::updateInsertPtr(Uint32 lenBytes){
- dataSize += lenBytes;
- insertPtr += (lenBytes / 4);
-}
-
-#endif // Define of SendBuffer_H
diff --git a/storage/ndb/src/common/transporter/TCP_Transporter.cpp b/storage/ndb/src/common/transporter/TCP_Transporter.cpp
deleted file mode 100644
index 768b4f4a052..00000000000
--- a/storage/ndb/src/common/transporter/TCP_Transporter.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbTCP.h>
-#include "TCP_Transporter.hpp"
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-// End of stuff to be moved
-
-#ifdef NDB_WIN32
-class ndbstrerror
-{
-public:
- ndbstrerror(int iError);
- ~ndbstrerror(void);
- operator char*(void) { return m_szError; };
-
-private:
- int m_iError;
- char* m_szError;
-};
-
-ndbstrerror::ndbstrerror(int iError)
-: m_iError(iError)
-{
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- 0,
- iError,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&m_szError,
- 0,
- 0);
-}
-
-ndbstrerror::~ndbstrerror(void)
-{
- LocalFree( m_szError );
- m_szError = 0;
-}
-#else
-#define ndbstrerror strerror
-#endif
-
-TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg,
- int sendBufSize, int maxRecvSize,
- const char *lHostName,
- const char *rHostName,
- int r_port,
- bool isMgmConnection_arg,
- NodeId lNodeId,
- NodeId rNodeId,
- NodeId serverNodeId,
- bool chksm, bool signalId,
- Uint32 _reportFreq) :
- Transporter(t_reg, tt_TCP_TRANSPORTER,
- lHostName, rHostName, r_port, isMgmConnection_arg,
- lNodeId, rNodeId, serverNodeId,
- 0, false, chksm, signalId),
- m_sendBuffer(sendBufSize)
-{
- maxReceiveSize = maxRecvSize;
-
- // Initialize member variables
- theSocket = NDB_INVALID_SOCKET;
-
- sendCount = receiveCount = 0;
- sendSize = receiveSize = 0;
- reportFreq = _reportFreq;
-
- sockOptRcvBufSize = 70080;
- sockOptSndBufSize = 71540;
- sockOptNodelay = 1;
- sockOptTcpMaxSeg = 4096;
-}
-
-TCP_Transporter::~TCP_Transporter() {
-
- // Disconnect
- if (theSocket != NDB_INVALID_SOCKET)
- doDisconnect();
-
- // Delete send buffers
-
- // Delete receive buffer!!
- receiveBuffer.destroy();
-}
-
-bool TCP_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("TCP_Transpporter::connect_server_impl");
- DBUG_RETURN(connect_common(sockfd));
-}
-
-bool TCP_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("TCP_Transpporter::connect_client_impl");
- DBUG_RETURN(connect_common(sockfd));
-}
-
-bool TCP_Transporter::connect_common(NDB_SOCKET_TYPE sockfd)
-{
- theSocket = sockfd;
- setSocketOptions();
- setSocketNonBlocking(theSocket);
- DBUG_PRINT("info", ("Successfully set-up TCP transporter to node %d",
- remoteNodeId));
- return true;
-}
-
-bool
-TCP_Transporter::initTransporter() {
-
- // Allocate buffer for receiving
- // Let it be the maximum size we receive plus 8 kB for any earlier received
- // incomplete messages (slack)
- Uint32 recBufSize = maxReceiveSize;
- if(recBufSize < MAX_MESSAGE_SIZE){
- recBufSize = MAX_MESSAGE_SIZE;
- }
-
- if(!receiveBuffer.init(recBufSize+MAX_MESSAGE_SIZE)){
- return false;
- }
-
- // Allocate buffers for sending
- if (!m_sendBuffer.initBuffer(remoteNodeId)) {
- // XXX What shall be done here?
- // The same is valid for the other init-methods
- return false;
- }
-
- return true;
-}
-
-void
-TCP_Transporter::setSocketOptions(){
- int sockOptKeepAlive = 1;
-
- if (setsockopt(theSocket, SOL_SOCKET, SO_RCVBUF,
- (char*)&sockOptRcvBufSize, sizeof(sockOptRcvBufSize)) < 0) {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("The setsockopt SO_RCVBUF error code = %d", InetErrno);
-#endif
- }//if
-
- if (setsockopt(theSocket, SOL_SOCKET, SO_SNDBUF,
- (char*)&sockOptSndBufSize, sizeof(sockOptSndBufSize)) < 0) {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("The setsockopt SO_SNDBUF error code = %d", InetErrno);
-#endif
- }//if
-
- if (setsockopt(theSocket, SOL_SOCKET, SO_KEEPALIVE,
- (char*)&sockOptKeepAlive, sizeof(sockOptKeepAlive)) < 0) {
- ndbout_c("The setsockopt SO_KEEPALIVE error code = %d", InetErrno);
- }//if
-
- //-----------------------------------------------
- // Set the TCP_NODELAY option so also small packets are sent
- // as soon as possible
- //-----------------------------------------------
- if (setsockopt(theSocket, IPPROTO_TCP, TCP_NODELAY,
- (char*)&sockOptNodelay, sizeof(sockOptNodelay)) < 0) {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("The setsockopt TCP_NODELAY error code = %d", InetErrno);
-#endif
- }//if
-}
-
-
-#ifdef NDB_WIN32
-
-bool
-TCP_Transporter::setSocketNonBlocking(NDB_SOCKET_TYPE socket){
- unsigned long ul = 1;
- if(ioctlsocket(socket, FIONBIO, &ul))
- {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("Set non-blocking server error3: %d", InetErrno);
-#endif
- }//if
- return true;
-}
-
-#else
-
-bool
-TCP_Transporter::setSocketNonBlocking(NDB_SOCKET_TYPE socket){
- int flags;
- flags = fcntl(socket, F_GETFL, 0);
- if (flags < 0) {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("Set non-blocking server error1: %s", strerror(InetErrno));
-#endif
- }//if
- flags |= NDB_NONBLOCK;
- if (fcntl(socket, F_SETFL, flags) == -1) {
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("Set non-blocking server error2: %s", strerror(InetErrno));
-#endif
- }//if
- return true;
-}
-
-#endif
-
-bool
-TCP_Transporter::sendIsPossible(struct timeval * timeout) {
- if(theSocket != NDB_INVALID_SOCKET){
- fd_set writeset;
- FD_ZERO(&writeset);
- FD_SET(theSocket, &writeset);
-
- int selectReply = select(theSocket + 1, NULL, &writeset, NULL, timeout);
-
- if ((selectReply > 0) && FD_ISSET(theSocket, &writeset))
- return true;
- else
- return false;
- }
- return false;
-}
-
-Uint32
-TCP_Transporter::get_free_buffer() const
-{
- return m_sendBuffer.bufferSizeRemaining();
-}
-
-Uint32 *
-TCP_Transporter::getWritePtr(Uint32 lenBytes, Uint32 prio){
-
- Uint32 * insertPtr = m_sendBuffer.getInsertPtr(lenBytes);
-
- struct timeval timeout = {0, 10000};
-
- if (insertPtr == 0) {
- //-------------------------------------------------
- // Buffer was completely full. We have severe problems.
- // We will attempt to wait for a small time
- //-------------------------------------------------
- if(sendIsPossible(&timeout)) {
- //-------------------------------------------------
- // Send is possible after the small timeout.
- //-------------------------------------------------
- if(!doSend()){
- return 0;
- } else {
- //-------------------------------------------------
- // Since send was successful we will make a renewed
- // attempt at inserting the signal into the buffer.
- //-------------------------------------------------
- insertPtr = m_sendBuffer.getInsertPtr(lenBytes);
- }//if
- } else {
- return 0;
- }//if
- }
- return insertPtr;
-}
-
-void
-TCP_Transporter::updateWritePtr(Uint32 lenBytes, Uint32 prio){
- m_sendBuffer.updateInsertPtr(lenBytes);
-
- const int bufsize = m_sendBuffer.bufferSize();
- if(bufsize > TCP_SEND_LIMIT) {
- //-------------------------------------------------
- // Buffer is full and we are ready to send. We will
- // not wait since the signal is already in the buffer.
- // Force flag set has the same indication that we
- // should always send. If it is not possible to send
- // we will not worry since we will soon be back for
- // a renewed trial.
- //-------------------------------------------------
- struct timeval no_timeout = {0,0};
- if(sendIsPossible(&no_timeout)) {
- //-------------------------------------------------
- // Send was possible, attempt at a send.
- //-------------------------------------------------
- doSend();
- }//if
- }
-}
-
-#define DISCONNECT_ERRNO(e, sz) ((sz == 0) || \
- (!((sz == -1) && (e == EAGAIN) || (e == EWOULDBLOCK) || (e == EINTR))))
-
-
-bool
-TCP_Transporter::doSend() {
- // If no sendbuffers are used nothing is done
- // Sends the contents of the SendBuffers until they are empty
- // or until select does not select the socket for write.
- // Before calling send, the socket must be selected for write
- // using "select"
- // It writes on the external TCP/IP interface until the send buffer is empty
- // and as long as write is possible (test it using select)
-
- // Empty the SendBuffers
-
- bool sent_any = true;
- while (m_sendBuffer.dataSize > 0)
- {
- const char * const sendPtr = m_sendBuffer.sendPtr;
- const Uint32 sizeToSend = m_sendBuffer.sendDataSize;
- const int nBytesSent = send(theSocket, sendPtr, sizeToSend, 0);
-
- if (nBytesSent > 0)
- {
- sent_any = true;
- m_sendBuffer.bytesSent(nBytesSent);
-
- sendCount ++;
- sendSize += nBytesSent;
- if(sendCount == reportFreq)
- {
- reportSendLen(get_callback_obj(), remoteNodeId, sendCount, sendSize);
- sendCount = 0;
- sendSize = 0;
- }
- }
- else
- {
- if (nBytesSent < 0 && InetErrno == EAGAIN && sent_any)
- break;
-
- // Send failed
-#if defined DEBUG_TRANSPORTER
- g_eventLogger.error("Send Failure(disconnect==%d) to node = %d nBytesSent = %d "
- "errno = %d strerror = %s",
- DISCONNECT_ERRNO(InetErrno, nBytesSent),
- remoteNodeId, nBytesSent, InetErrno,
- (char*)ndbstrerror(InetErrno));
-#endif
- if(DISCONNECT_ERRNO(InetErrno, nBytesSent)){
- doDisconnect();
- report_disconnect(InetErrno);
- }
-
- return false;
- }
- }
- return true;
-}
-
-int
-TCP_Transporter::doReceive() {
- // Select-function must return the socket for read
- // before this method is called
- // It reads the external TCP/IP interface once
- Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData;
- if(size > 0){
- const int nBytesRead = recv(theSocket,
- receiveBuffer.insertPtr,
- size < maxReceiveSize ? size : maxReceiveSize,
- 0);
-
- if (nBytesRead > 0) {
- receiveBuffer.sizeOfData += nBytesRead;
- receiveBuffer.insertPtr += nBytesRead;
-
- if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){
-#ifdef DEBUG_TRANSPORTER
- g_eventLogger.error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
- receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
- g_eventLogger.error("nBytesRead = %d", nBytesRead);
-#endif
- g_eventLogger.error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)",
- receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer);
- report_error(TE_INVALID_MESSAGE_LENGTH);
- return 0;
- }
-
- receiveCount ++;
- receiveSize += nBytesRead;
-
- if(receiveCount == reportFreq){
- reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize);
- receiveCount = 0;
- receiveSize = 0;
- }
- return nBytesRead;
- } else {
-#if defined DEBUG_TRANSPORTER
- g_eventLogger.error("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d "
- "errno = %d strerror = %s",
- DISCONNECT_ERRNO(InetErrno, nBytesRead),
- remoteNodeId, nBytesRead, InetErrno,
- (char*)ndbstrerror(InetErrno));
-#endif
- if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){
- // The remote node has closed down
- doDisconnect();
- report_disconnect(InetErrno);
- }
- }
- return nBytesRead;
- } else {
- return 0;
- }
-}
-
-void
-TCP_Transporter::disconnectImpl() {
- if(theSocket != NDB_INVALID_SOCKET){
- if(NDB_CLOSE_SOCKET(theSocket) < 0){
- report_error(TE_ERROR_CLOSING_SOCKET);
- }
- }
-
- // Empty send och receive buffers
- receiveBuffer.clear();
- m_sendBuffer.emptyBuffer();
-
- theSocket = NDB_INVALID_SOCKET;
-}
diff --git a/storage/ndb/src/common/transporter/TCP_Transporter.hpp b/storage/ndb/src/common/transporter/TCP_Transporter.hpp
deleted file mode 100644
index 64b48d741a6..00000000000
--- a/storage/ndb/src/common/transporter/TCP_Transporter.hpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TCP_TRANSPORTER_HPP
-#define TCP_TRANSPORTER_HPP
-
-#include "Transporter.hpp"
-#include "SendBuffer.hpp"
-
-#include <NdbTCP.h>
-
-struct ReceiveBuffer {
- Uint32 *startOfBuffer; // Pointer to start of the receive buffer
- Uint32 *readPtr; // Pointer to start reading data
-
- char *insertPtr; // Pointer to first position in the receiveBuffer
- // in which to insert received data. Earlier
- // received incomplete messages (slack) are
- // copied into the first part of the receiveBuffer
-
- Uint32 sizeOfData; // In bytes
- Uint32 sizeOfBuffer;
-
- ReceiveBuffer() {}
- bool init(int bytes);
- void destroy();
-
- void clear();
- void incompleteMessage();
-};
-
-class TCP_Transporter : public Transporter {
- friend class TransporterRegistry;
-private:
- // Initialize member variables
- TCP_Transporter(TransporterRegistry&,
- int sendBufferSize, int maxReceiveSize,
- const char *lHostName,
- const char *rHostName,
- int r_port,
- bool isMgmConnection,
- NodeId lHostId,
- NodeId rHostId,
- NodeId serverNodeId,
- bool checksum, bool signalId,
- Uint32 reportFreq = 4096);
-
- // Disconnect, delete send buffers and receive buffer
- virtual ~TCP_Transporter();
-
- /**
- * Allocate buffers for sending and receiving
- */
- bool initTransporter();
-
- Uint32 * getWritePtr(Uint32 lenBytes, Uint32 prio);
- void updateWritePtr(Uint32 lenBytes, Uint32 prio);
-
- bool hasDataToSend() const ;
-
- /**
- * Retrieves the contents of the send buffers and writes it on
- * the external TCP/IP interface until the send buffers are empty
- * and as long as write is possible.
- */
- bool doSend();
-
- /**
- * It reads the external TCP/IP interface once
- * and puts the data in the receiveBuffer
- */
- int doReceive();
-
- /**
- * Returns socket (used for select)
- */
- NDB_SOCKET_TYPE getSocket() const;
-
- /**
- * Get Receive Data
- *
- * Returns - no of bytes to read
- * and set ptr
- */
- virtual Uint32 getReceiveData(Uint32 ** ptr);
-
- /**
- * Update receive data ptr
- */
- virtual void updateReceiveDataPtr(Uint32 bytesRead);
-
- virtual Uint32 get_free_buffer() const;
-
- inline bool hasReceiveData () const {
- return receiveBuffer.sizeOfData > 0;
- }
-protected:
- /**
- * Setup client/server and perform connect/accept
- * Is used both by clients and servers
- * A client connects to the remote server
- * A server accepts any new connections
- */
- virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
- virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
- bool connect_common(NDB_SOCKET_TYPE sockfd);
-
- /**
- * Disconnects a TCP/IP node. Empty send and receivebuffer.
- */
- virtual void disconnectImpl();
-
-private:
- /**
- * Send buffers
- */
- SendBuffer m_sendBuffer;
-
- // Sending/Receiving socket used by both client and server
- NDB_SOCKET_TYPE theSocket;
-
- Uint32 maxReceiveSize;
-
- /**
- * Socket options
- */
- int sockOptRcvBufSize;
- int sockOptSndBufSize;
- int sockOptNodelay;
- int sockOptTcpMaxSeg;
-
- void setSocketOptions();
-
- static bool setSocketNonBlocking(NDB_SOCKET_TYPE aSocket);
-
- bool sendIsPossible(struct timeval * timeout);
-
- /**
- * Statistics
- */
- Uint32 reportFreq;
- Uint32 receiveCount;
- Uint64 receiveSize;
- Uint32 sendCount;
- Uint64 sendSize;
-
- ReceiveBuffer receiveBuffer;
-};
-
-inline
-NDB_SOCKET_TYPE
-TCP_Transporter::getSocket() const {
- return theSocket;
-}
-
-inline
-Uint32
-TCP_Transporter::getReceiveData(Uint32 ** ptr){
- (* ptr) = receiveBuffer.readPtr;
- return receiveBuffer.sizeOfData;
-}
-
-inline
-void
-TCP_Transporter::updateReceiveDataPtr(Uint32 bytesRead){
- char * ptr = (char *)receiveBuffer.readPtr;
- ptr += bytesRead;
- receiveBuffer.readPtr = (Uint32*)ptr;
- receiveBuffer.sizeOfData -= bytesRead;
- receiveBuffer.incompleteMessage();
-}
-
-inline
-bool
-TCP_Transporter::hasDataToSend() const {
- return m_sendBuffer.dataSize > 0;
-}
-
-inline
-bool
-ReceiveBuffer::init(int bytes){
-#ifdef DEBUG_TRANSPORTER
- ndbout << "Allocating " << bytes << " bytes as receivebuffer" << endl;
-#endif
-
- startOfBuffer = new Uint32[((bytes + 0) >> 2) + 1];
- sizeOfBuffer = bytes + sizeof(Uint32);
- clear();
- return true;
-}
-
-inline
-void
-ReceiveBuffer::destroy(){
- delete[] startOfBuffer;
- sizeOfBuffer = 0;
- startOfBuffer = 0;
- clear();
-}
-
-inline
-void
-ReceiveBuffer::clear(){
- readPtr = startOfBuffer;
- insertPtr = (char *)startOfBuffer;
- sizeOfData = 0;
-}
-
-inline
-void
-ReceiveBuffer::incompleteMessage() {
- if(startOfBuffer != readPtr){
- if(sizeOfData != 0)
- memmove(startOfBuffer, readPtr, sizeOfData);
- readPtr = startOfBuffer;
- insertPtr = ((char *)startOfBuffer) + sizeOfData;
- }
-}
-
-
-#endif // Define of TCP_Transporter_H
diff --git a/storage/ndb/src/common/transporter/Transporter.cpp b/storage/ndb/src/common/transporter/Transporter.cpp
deleted file mode 100644
index fe43124ad86..00000000000
--- a/storage/ndb/src/common/transporter/Transporter.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <TransporterRegistry.hpp>
-#include <TransporterCallback.hpp>
-#include "Transporter.hpp"
-#include "TransporterInternalDefinitions.hpp"
-#include <NdbSleep.h>
-#include <SocketAuthenticator.hpp>
-#include <InputStream.hpp>
-#include <OutputStream.hpp>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-Transporter::Transporter(TransporterRegistry &t_reg,
- TransporterType _type,
- const char *lHostName,
- const char *rHostName,
- int s_port,
- bool _isMgmConnection,
- NodeId lNodeId,
- NodeId rNodeId,
- NodeId serverNodeId,
- int _byteorder,
- bool _compression, bool _checksum, bool _signalId)
- : m_s_port(s_port), remoteNodeId(rNodeId), localNodeId(lNodeId),
- isServer(lNodeId==serverNodeId),
- m_packer(_signalId, _checksum), isMgmConnection(_isMgmConnection),
- m_type(_type),
- m_transporter_registry(t_reg)
-{
- DBUG_ENTER("Transporter::Transporter");
- if (rHostName && strlen(rHostName) > 0){
- strncpy(remoteHostName, rHostName, sizeof(remoteHostName));
- Ndb_getInAddr(&remoteHostAddress, rHostName);
- }
- else
- {
- if (!isServer) {
- ndbout << "Unable to setup transporter. Node " << rNodeId
- << " must have hostname. Update configuration." << endl;
- exit(-1);
- }
- remoteHostName[0]= 0;
- }
- strncpy(localHostName, lHostName, sizeof(localHostName));
-
- DBUG_PRINT("info",("rId=%d lId=%d isServer=%d rHost=%s lHost=%s s_port=%d",
- remoteNodeId, localNodeId, isServer,
- remoteHostName, localHostName,
- s_port));
-
- byteOrder = _byteorder;
- compressionUsed = _compression;
- checksumUsed = _checksum;
- signalIdUsed = _signalId;
-
- m_connected = false;
- m_timeOutMillis = 30000;
-
- m_connect_address.s_addr= 0;
- if(s_port<0)
- s_port= -s_port; // was dynamic
-
- if (isServer)
- m_socket_client= 0;
- else
- {
- m_socket_client= new SocketClient(remoteHostName, s_port,
- new SocketAuthSimple("ndbd",
- "ndbd passwd"));
-
- m_socket_client->set_connect_timeout((m_timeOutMillis+999)/1000);
- }
- DBUG_VOID_RETURN;
-}
-
-Transporter::~Transporter(){
- if (m_socket_client)
- delete m_socket_client;
-}
-
-bool
-Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
- // all initial negotiation is done in TransporterRegistry::connect_server
- DBUG_ENTER("Transporter::connect_server");
-
- if(m_connected)
- {
- DBUG_RETURN(false); // TODO assert(0);
- }
-
- {
- struct sockaddr_in addr;
- SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
- m_connect_address= (&addr)->sin_addr;
- }
-
- bool res = connect_server_impl(sockfd);
- if(res){
- m_connected = true;
- m_errorCount = 0;
- }
-
- DBUG_RETURN(res);
-}
-
-bool
-Transporter::connect_client() {
- NDB_SOCKET_TYPE sockfd;
-
- if(m_connected)
- return true;
-
- if(isMgmConnection)
- {
- sockfd= m_transporter_registry.connect_ndb_mgmd(m_socket_client);
- }
- else
- {
- if (!m_socket_client->init())
- {
- return false;
- }
- if (strlen(localHostName) > 0)
- {
- if (m_socket_client->bind(localHostName, 0) != 0)
- return false;
- }
- sockfd= m_socket_client->connect();
- }
-
- return connect_client(sockfd);
-}
-
-bool
-Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {
-
- if(m_connected)
- return true;
-
- if (sockfd == NDB_INVALID_SOCKET)
- return false;
-
- DBUG_ENTER("Transporter::connect_client");
-
- DBUG_PRINT("info",("port %d isMgmConnection=%d",m_s_port,isMgmConnection));
-
- SocketOutputStream s_output(sockfd);
- SocketInputStream s_input(sockfd);
-
- // send info about own id
- // send info about own transporter type
-
- s_output.println("%d %d", localNodeId, m_type);
- // get remote id
- int nodeId, remote_transporter_type= -1;
-
- char buf[256];
- if (s_input.gets(buf, 256) == 0) {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
- switch (r) {
- case 2:
- break;
- case 1:
- // we're running version prior to 4.1.9
- // ok, but with no checks on transporter configuration compatability
- break;
- default:
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(false);
- }
-
- DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
- nodeId, remote_transporter_type));
-
- if (remote_transporter_type != -1)
- {
- if (remote_transporter_type != m_type)
- {
- DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
- m_type, remote_transporter_type));
- NDB_CLOSE_SOCKET(sockfd);
- g_eventLogger.error("Incompatible configuration: transporter type "
- "mismatch with node %d", nodeId);
- DBUG_RETURN(false);
- }
- }
- else if (m_type == tt_SHM_TRANSPORTER)
- {
- g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
- }
-
- {
- struct sockaddr_in addr;
- SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
- m_connect_address= (&addr)->sin_addr;
- }
-
- bool res = connect_client_impl(sockfd);
- if(res){
- m_connected = true;
- m_errorCount = 0;
- }
- DBUG_RETURN(res);
-}
-
-void
-Transporter::doDisconnect() {
-
- if(!m_connected)
- return; //assert(0); TODO will fail
-
- m_connected= false;
- disconnectImpl();
-}
diff --git a/storage/ndb/src/common/transporter/Transporter.hpp b/storage/ndb/src/common/transporter/Transporter.hpp
deleted file mode 100644
index 28f99e9170d..00000000000
--- a/storage/ndb/src/common/transporter/Transporter.hpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Transporter_H
-#define Transporter_H
-
-#include <ndb_global.h>
-
-#include <SocketClient.hpp>
-
-#include <TransporterRegistry.hpp>
-#include <TransporterCallback.hpp>
-#include "TransporterDefinitions.hpp"
-#include "Packer.hpp"
-
-#include <NdbMutex.h>
-#include <NdbThread.h>
-
-class Transporter {
- friend class TransporterRegistry;
-public:
- virtual bool initTransporter() = 0;
-
- /**
- * Destructor
- */
- virtual ~Transporter();
-
- /**
- * None blocking
- * Use isConnected() to check status
- */
- bool connect_client();
- bool connect_client(NDB_SOCKET_TYPE sockfd);
- bool connect_server(NDB_SOCKET_TYPE socket);
-
- /**
- * Blocking
- */
- virtual void doDisconnect();
-
- virtual Uint32 * getWritePtr(Uint32 lenBytes, Uint32 prio) = 0;
- virtual void updateWritePtr(Uint32 lenBytes, Uint32 prio) = 0;
-
- /**
- * Are we currently connected
- */
- bool isConnected() const;
-
- /**
- * Remote Node Id
- */
- NodeId getRemoteNodeId() const;
-
- /**
- * Local (own) Node Id
- */
- NodeId getLocalNodeId() const;
-
- /**
- * Get port we're connecting to (signed)
- */
- int get_s_port() { return m_s_port; };
-
- /**
- * Set port to connect to (signed)
- */
- void set_s_port(int port) {
- m_s_port = port;
- if(port<0)
- port= -port;
- if(m_socket_client)
- m_socket_client->set_port(port);
- };
-
- virtual Uint32 get_free_buffer() const = 0;
-
-protected:
- Transporter(TransporterRegistry &,
- TransporterType,
- const char *lHostName,
- const char *rHostName,
- int s_port,
- bool isMgmConnection,
- NodeId lNodeId,
- NodeId rNodeId,
- NodeId serverNodeId,
- int byteorder,
- bool compression,
- bool checksum,
- bool signalId);
-
- /**
- * Blocking, for max timeOut milli seconds
- * Returns true if connect succeded
- */
- virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd) = 0;
- virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd) = 0;
-
- /**
- * Blocking
- */
- virtual void disconnectImpl() = 0;
-
- /**
- * Remote host name/and address
- */
- char remoteHostName[256];
- char localHostName[256];
- struct in_addr remoteHostAddress;
- struct in_addr localHostAddress;
-
- int m_s_port;
-
- const NodeId remoteNodeId;
- const NodeId localNodeId;
-
- const bool isServer;
-
- unsigned createIndex;
-
- int byteOrder;
- bool compressionUsed;
- bool checksumUsed;
- bool signalIdUsed;
- Packer m_packer;
-
-private:
-
- /**
- * means that we transform an MGM connection into
- * a transporter connection
- */
- bool isMgmConnection;
-
- SocketClient *m_socket_client;
- struct in_addr m_connect_address;
-
-protected:
- Uint32 getErrorCount();
- Uint32 m_errorCount;
- Uint32 m_timeOutMillis;
-
-protected:
- bool m_connected; // Are we connected
- TransporterType m_type;
-
- TransporterRegistry &m_transporter_registry;
- void *get_callback_obj() { return m_transporter_registry.callbackObj; };
- void report_disconnect(int err){m_transporter_registry.report_disconnect(remoteNodeId,err);};
- void report_error(enum TransporterError err, const char *info = 0)
- { reportError(get_callback_obj(), remoteNodeId, err, info); };
-};
-
-inline
-bool
-Transporter::isConnected() const {
- return m_connected;
-}
-
-inline
-NodeId
-Transporter::getRemoteNodeId() const {
- return remoteNodeId;
-}
-
-inline
-NodeId
-Transporter::getLocalNodeId() const {
- return localNodeId;
-}
-
-inline
-Uint32
-Transporter::getErrorCount()
-{
- return m_errorCount;
-}
-
-#endif // Define of Transporter_H
diff --git a/storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp b/storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp
deleted file mode 100644
index 251e46a6f16..00000000000
--- a/storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TransporterInternalDefinitions_H
-#define TransporterInternalDefinitions_H
-
-#if defined DEBUG_TRANSPORTER || defined VM_TRACE
-#include <NdbOut.hpp>
-#endif
-
-#define NDB_TCP_TRANSPORTER
-
-#ifdef HAVE_NDB_SHM
-#define NDB_SHM_TRANSPORTER
-#endif
-
-#ifdef HAVE_NDB_SCI
-#define NDB_SCI_TRANSPORTER
-#endif
-
-#ifdef DEBUG_TRANSPORTER
-#define DEBUG(x) ndbout << x << endl
-#else
-#define DEBUG(x)
-#endif
-
-#if defined VM_TRACE || defined DEBUG_TRANSPORTER
-#define WARNING(X) ndbout << X << endl;
-#else
-#define WARNING(X)
-#endif
-
-// Calculate a checksum
-inline
-Uint32
-computeChecksum(const Uint32 * const startOfData, int nWords) {
- Uint32 chksum = startOfData[0];
- for (int i=1; i < nWords; i++)
- chksum ^= startOfData[i];
- return chksum;
-}
-
-struct Protocol6 {
- Uint32 word1;
- Uint32 word2;
- Uint32 word3;
-
-/**
- *
- * b = Byte order - 4 Bits (Note 1 significant bit)
- * g = GSN - 16 Bits
- * p = Prio - 2 Bits
- * c = Checksum included - 1 Bit
- * z = Compression - 1 Bit
- * v = Version id - 4 Bits
- * i = Signal id included - 1 Bit
- * m = Message length - 16 Bits (0-65536) (In word -> 0-256k bytes)
- * d = Signal data length - 5 Bits (0-31)
- * t = trace - 6 Bits (0-63)
- * r = Recievers block no - 16 Bits
- * s = Senders block no - 16 Bits
- * u = Unused - 7 Bits
- * f = FragmentInfo1 - 1 Bit
- * h = FragmentInfo2 - 1 bit
- * n = No of segments - 2 Bits
-
- * Word 1
- *
- *
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * bfizcppbmmmmmmmmmmmmmmmmbhdddddb
-
- **
- * Word 2
- *
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * ggggggggggggggggvvvvttttttnn
-
- **
- * Word 3
- *
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * rrrrrrrrrrrrrrrrssssssssssssssss
-
- **
- * Word 4 (Optional Signal Id)
- */
-
- /**
- * 0 = Big endian (Sparc), 1 = Little endian (Intel)
- */
- static Uint32 getByteOrder (const Uint32 & word1);
- static Uint32 getCompressed (const Uint32 & word1);
- static Uint32 getSignalIdIncluded(const Uint32 & word1);
- static Uint32 getCheckSumIncluded(const Uint32 & word1);
- static Uint32 getPrio (const Uint32 & word1);
- static Uint32 getMessageLength (const Uint32 & word1);
-
- static void setByteOrder (Uint32 & word1, Uint32 byteOrder);
- static void setCompressed (Uint32 & word1, Uint32 compressed);
- static void setSignalIdIncluded(Uint32 & word1, Uint32 signalId);
- static void setCheckSumIncluded(Uint32 & word1, Uint32 checkSum);
- static void setPrio (Uint32 & word1, Uint32 prio);
- static void setMessageLength (Uint32 & word1, Uint32 messageLen);
-
- static void createSignalHeader(SignalHeader * const dst,
- const Uint32 & word1,
- const Uint32 & word2,
- const Uint32 & word3);
-
- static void createProtocol6Header(Uint32 & word1,
- Uint32 & word2,
- Uint32 & word3,
- const SignalHeader * const src);
-};
-
-#define WORD1_BYTEORDER_MASK (0x81000081)
-#define WORD1_SIGNALID_MASK (0x00000004)
-#define WORD1_COMPRESSED_MASK (0x00000008)
-#define WORD1_CHECKSUM_MASK (0x00000010)
-#define WORD1_PRIO_MASK (0x00000060)
-#define WORD1_MESSAGELEN_MASK (0x00FFFF00)
-#define WORD1_SIGNAL_LEN_MASK (0x7C000000)
-#define WORD1_FRAG_INF_MASK (0x00000002)
-#define WORD1_FRAG_INF2_MASK (0x02000000)
-
-#define WORD1_FRAG_INF_SHIFT (1)
-#define WORD1_SIGNALID_SHIFT (2)
-#define WORD1_COMPRESSED_SHIFT (3)
-#define WORD1_CHECKSUM_SHIFT (4)
-#define WORD1_PRIO_SHIFT (5)
-#define WORD1_MESSAGELEN_SHIFT (8)
-#define WORD1_FRAG_INF2_SHIFT (25)
-#define WORD1_SIGNAL_LEN_SHIFT (26)
-
-#define WORD2_VERID_GSN_MASK (0x000FFFFF)
-#define WORD2_TRACE_MASK (0x03f00000)
-#define WORD2_SEC_COUNT_MASK (0x0c000000)
-
-#define WORD2_TRACE_SHIFT (20)
-#define WORD2_SEC_COUNT_SHIFT (26)
-
-#define WORD3_SENDER_MASK (0x0000FFFF)
-#define WORD3_RECEIVER_MASK (0xFFFF0000)
-
-#define WORD3_RECEIVER_SHIFT (16)
-
-inline
-Uint32
-Protocol6::getByteOrder(const Uint32 & word1){
- return word1 & 1;
-}
-
-inline
-Uint32
-Protocol6::getCompressed(const Uint32 & word1){
- return (word1 & WORD1_COMPRESSED_MASK) >> WORD1_COMPRESSED_SHIFT;
-}
-
-inline
-Uint32
-Protocol6::getSignalIdIncluded(const Uint32 & word1){
- return (word1 & WORD1_SIGNALID_MASK) >> WORD1_SIGNALID_SHIFT;
-}
-
-inline
-Uint32
-Protocol6::getCheckSumIncluded(const Uint32 & word1){
- return (word1 & WORD1_CHECKSUM_MASK) >> WORD1_CHECKSUM_SHIFT;
-}
-
-inline
-Uint32
-Protocol6::getMessageLength(const Uint32 & word1){
- return (word1 & WORD1_MESSAGELEN_MASK) >> WORD1_MESSAGELEN_SHIFT;
-}
-
-inline
-Uint32
-Protocol6::getPrio(const Uint32 & word1){
- return (word1 & WORD1_PRIO_MASK) >> WORD1_PRIO_SHIFT;
-}
-
-inline
-void
-Protocol6::setByteOrder(Uint32 & word1, Uint32 byteOrder){
- Uint32 tmp = byteOrder;
- tmp |= (tmp << 7);
- tmp |= (tmp << 24);
- word1 |= (tmp & WORD1_BYTEORDER_MASK);
-}
-
-inline
-void
-Protocol6::setCompressed(Uint32 & word1, Uint32 compressed){
- word1 |= ((compressed << WORD1_COMPRESSED_SHIFT) & WORD1_COMPRESSED_MASK);
-}
-
-inline
-void
-Protocol6::setSignalIdIncluded(Uint32 & word1, Uint32 signalId){
- word1 |= ((signalId << WORD1_SIGNALID_SHIFT) & WORD1_SIGNALID_MASK);
-}
-
-inline
-void
-Protocol6::setCheckSumIncluded(Uint32 & word1, Uint32 checkSum){
- word1 |= ((checkSum << WORD1_CHECKSUM_SHIFT) & WORD1_CHECKSUM_MASK);
-}
-
-inline
-void
-Protocol6::setMessageLength(Uint32 & word1, Uint32 messageLen){
- word1 |= ((messageLen << WORD1_MESSAGELEN_SHIFT) & WORD1_MESSAGELEN_MASK);
-}
-
-inline
-void
-Protocol6::setPrio(Uint32 & word1, Uint32 prio){
- word1 |= ((prio << WORD1_PRIO_SHIFT) & WORD1_PRIO_MASK);
-}
-
-inline
-void
-Protocol6::createSignalHeader(SignalHeader * const dst,
- const Uint32 & word1,
- const Uint32 & word2,
- const Uint32 & word3){
-
- Uint32 signal_len = (word1 & WORD1_SIGNAL_LEN_MASK)>> WORD1_SIGNAL_LEN_SHIFT;
- Uint32 fragInfo1 = (word1 & WORD1_FRAG_INF_MASK) >> (WORD1_FRAG_INF_SHIFT-1);
- Uint32 fragInfo2 = (word1 & WORD1_FRAG_INF2_MASK) >> (WORD1_FRAG_INF2_SHIFT);
- Uint32 trace = (word2 & WORD2_TRACE_MASK) >> WORD2_TRACE_SHIFT;
- Uint32 verid_gsn = (word2 & WORD2_VERID_GSN_MASK);
- Uint32 secCount = (word2 & WORD2_SEC_COUNT_MASK) >> WORD2_SEC_COUNT_SHIFT;
-
- dst->theTrace = trace;
- dst->m_noOfSections = secCount;
- dst->m_fragmentInfo = fragInfo1 | fragInfo2;
-
- dst->theLength = signal_len;
- dst->theVerId_signalNumber = verid_gsn;
-
- Uint32 sBlockNum = (word3 & WORD3_SENDER_MASK);
- Uint32 rBlockNum = (word3 & WORD3_RECEIVER_MASK) >> WORD3_RECEIVER_SHIFT;
-
- dst->theSendersBlockRef = sBlockNum;
- dst->theReceiversBlockNumber = rBlockNum;
-}
-
-inline
-void
-Protocol6::createProtocol6Header(Uint32 & word1,
- Uint32 & word2,
- Uint32 & word3,
- const SignalHeader * const src){
- const Uint32 signal_len = src->theLength;
- const Uint32 fragInfo = src->m_fragmentInfo;
- const Uint32 fragInfo1 = (fragInfo & 2);
- const Uint32 fragInfo2 = (fragInfo & 1);
-
- const Uint32 trace = src->theTrace;
- const Uint32 verid_gsn = src->theVerId_signalNumber;
- const Uint32 secCount = src->m_noOfSections;
-
- word1 |= ((signal_len << WORD1_SIGNAL_LEN_SHIFT) & WORD1_SIGNAL_LEN_MASK);
- word1 |= ((fragInfo1 << (WORD1_FRAG_INF_SHIFT-1)) & WORD1_FRAG_INF_MASK);
- word1 |= ((fragInfo2 << WORD1_FRAG_INF2_SHIFT) & WORD1_FRAG_INF2_MASK);
-
- word2 |= ((trace << WORD2_TRACE_SHIFT) & WORD2_TRACE_MASK);
- word2 |= (verid_gsn & WORD2_VERID_GSN_MASK);
- word2 |= ((secCount << WORD2_SEC_COUNT_SHIFT) & WORD2_SEC_COUNT_MASK);
-
- Uint32 sBlockNum = src->theSendersBlockRef ;
- Uint32 rBlockNum = src->theReceiversBlockNumber ;
-
- word3 |= (sBlockNum & WORD3_SENDER_MASK);
- word3 |= ((rBlockNum << WORD3_RECEIVER_SHIFT) & WORD3_RECEIVER_MASK);
-}
-
-// Define of TransporterInternalDefinitions_H
-#endif
diff --git a/storage/ndb/src/common/transporter/TransporterRegistry.cpp b/storage/ndb/src/common/transporter/TransporterRegistry.cpp
deleted file mode 100644
index e820322f96e..00000000000
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp
+++ /dev/null
@@ -1,1448 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-
-#include <TransporterRegistry.hpp>
-#include "TransporterInternalDefinitions.hpp"
-
-#include "Transporter.hpp"
-#include <SocketAuthenticator.hpp>
-
-#ifdef NDB_TCP_TRANSPORTER
-#include "TCP_Transporter.hpp"
-#endif
-
-#ifdef NDB_SCI_TRANSPORTER
-#include "SCI_Transporter.hpp"
-#endif
-
-#ifdef NDB_SHM_TRANSPORTER
-#include "SHM_Transporter.hpp"
-extern int g_ndb_shm_signum;
-#endif
-
-#include "TransporterCallback.hpp"
-#include "NdbOut.hpp"
-#include <NdbSleep.h>
-#include <NdbTick.h>
-#include <InputStream.hpp>
-#include <OutputStream.hpp>
-
-#include <mgmapi/mgmapi.h>
-#include <mgmapi_internal.h>
-#include <mgmapi/mgmapi_debug.h>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-struct in_addr
-TransporterRegistry::get_connect_address(NodeId node_id) const
-{
- return theTransporters[node_id]->m_connect_address;
-}
-
-SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("SocketServer::Session * TransporterService::newSession");
- if (m_auth && !m_auth->server_authenticate(sockfd)){
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(0);
- }
-
- if (!m_transporter_registry->connect_server(sockfd))
- {
- NDB_CLOSE_SOCKET(sockfd);
- DBUG_RETURN(0);
- }
-
- DBUG_RETURN(0);
-}
-
-TransporterRegistry::TransporterRegistry(void * callback,
- unsigned _maxTransporters,
- unsigned sizeOfLongSignalMemory) :
- m_mgm_handle(0),
- m_transp_count(0)
-{
- DBUG_ENTER("TransporterRegistry::TransporterRegistry");
-
- nodeIdSpecified = false;
- maxTransporters = _maxTransporters;
- sendCounter = 1;
-
- callbackObj=callback;
-
- theTCPTransporters = new TCP_Transporter * [maxTransporters];
- theSCITransporters = new SCI_Transporter * [maxTransporters];
- theSHMTransporters = new SHM_Transporter * [maxTransporters];
- theTransporterTypes = new TransporterType [maxTransporters];
- theTransporters = new Transporter * [maxTransporters];
- performStates = new PerformState [maxTransporters];
- ioStates = new IOState [maxTransporters];
-
- // Initialize member variables
- nTransporters = 0;
- nTCPTransporters = 0;
- nSCITransporters = 0;
- nSHMTransporters = 0;
-
- // Initialize the transporter arrays
- for (unsigned i=0; i<maxTransporters; i++) {
- theTCPTransporters[i] = NULL;
- theSCITransporters[i] = NULL;
- theSHMTransporters[i] = NULL;
- theTransporters[i] = NULL;
- performStates[i] = DISCONNECTED;
- ioStates[i] = NoHalt;
- }
-
- DBUG_VOID_RETURN;
-}
-
-void TransporterRegistry::set_mgm_handle(NdbMgmHandle h)
-{
- DBUG_ENTER("TransporterRegistry::set_mgm_handle");
- if (m_mgm_handle)
- ndb_mgm_destroy_handle(&m_mgm_handle);
- m_mgm_handle= h;
- ndb_mgm_set_timeout(m_mgm_handle, 5000);
-#ifndef DBUG_OFF
- if (h)
- {
- char buf[256];
- DBUG_PRINT("info",("handle set with connectstring: %s",
- ndb_mgm_get_connectstring(h,buf, sizeof(buf))));
- }
- else
- {
- DBUG_PRINT("info",("handle set to NULL"));
- }
-#endif
- DBUG_VOID_RETURN;
-}
-
-TransporterRegistry::~TransporterRegistry()
-{
- DBUG_ENTER("TransporterRegistry::~TransporterRegistry");
-
- removeAll();
-
- delete[] theTCPTransporters;
- delete[] theSCITransporters;
- delete[] theSHMTransporters;
- delete[] theTransporterTypes;
- delete[] theTransporters;
- delete[] performStates;
- delete[] ioStates;
-
- if (m_mgm_handle)
- ndb_mgm_destroy_handle(&m_mgm_handle);
-
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterRegistry::removeAll(){
- for(unsigned i = 0; i<maxTransporters; i++){
- if(theTransporters[i] != NULL)
- removeTransporter(theTransporters[i]->getRemoteNodeId());
- }
-}
-
-void
-TransporterRegistry::disconnectAll(){
- for(unsigned i = 0; i<maxTransporters; i++){
- if(theTransporters[i] != NULL)
- theTransporters[i]->doDisconnect();
- }
-}
-
-bool
-TransporterRegistry::init(NodeId nodeId) {
- DBUG_ENTER("TransporterRegistry::init");
- nodeIdSpecified = true;
- localNodeId = nodeId;
-
- DEBUG("TransporterRegistry started node: " << localNodeId);
-
- DBUG_RETURN(true);
-}
-
-bool
-TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd)
-{
- DBUG_ENTER("TransporterRegistry::connect_server");
-
- // read node id from client
- // read transporter type
- int nodeId, remote_transporter_type= -1;
- SocketInputStream s_input(sockfd);
- char buf[256];
- if (s_input.gets(buf, 256) == 0) {
- DBUG_PRINT("error", ("Could not get node id from client"));
- DBUG_RETURN(false);
- }
- int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
- switch (r) {
- case 2:
- break;
- case 1:
- // we're running version prior to 4.1.9
- // ok, but with no checks on transporter configuration compatability
- break;
- default:
- DBUG_PRINT("error", ("Error in node id from client"));
- DBUG_RETURN(false);
- }
-
- DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
- nodeId,remote_transporter_type));
-
- //check that nodeid is valid and that there is an allocated transporter
- if ( nodeId < 0 || nodeId >= (int)maxTransporters) {
- DBUG_PRINT("error", ("Node id out of range from client"));
- DBUG_RETURN(false);
- }
- if (theTransporters[nodeId] == 0) {
- DBUG_PRINT("error", ("No transporter for this node id from client"));
- DBUG_RETURN(false);
- }
-
- //check that the transporter should be connected
- if (performStates[nodeId] != TransporterRegistry::CONNECTING) {
- DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
- DBUG_RETURN(false);
- }
-
- Transporter *t= theTransporters[nodeId];
-
- // send info about own id (just as response to acknowledge connection)
- // send info on own transporter type
- SocketOutputStream s_output(sockfd);
- s_output.println("%d %d", t->getLocalNodeId(), t->m_type);
-
- if (remote_transporter_type != -1)
- {
- if (remote_transporter_type != t->m_type)
- {
- DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
- t->m_type, remote_transporter_type));
- g_eventLogger.error("Incompatible configuration: Transporter type "
- "mismatch with node %d", nodeId);
-
- // wait for socket close for 1 second to let message arrive at client
- {
- fd_set a_set;
- FD_ZERO(&a_set);
- FD_SET(sockfd, &a_set);
- struct timeval timeout;
- timeout.tv_sec = 1; timeout.tv_usec = 0;
- select(sockfd+1, &a_set, 0, 0, &timeout);
- }
- DBUG_RETURN(false);
- }
- }
- else if (t->m_type == tt_SHM_TRANSPORTER)
- {
- g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
- }
-
- // setup transporter (transporter responsible for closing sockfd)
- t->connect_server(sockfd);
-
- DBUG_RETURN(true);
-}
-
-bool
-TransporterRegistry::createTCPTransporter(TransporterConfiguration *config) {
-#ifdef NDB_TCP_TRANSPORTER
-
- if(!nodeIdSpecified){
- init(config->localNodeId);
- }
-
- if(config->localNodeId != localNodeId)
- return false;
-
- if(theTransporters[config->remoteNodeId] != NULL)
- return false;
-
- TCP_Transporter * t = new TCP_Transporter(*this,
- config->tcp.sendBufferSize,
- config->tcp.maxReceiveSize,
- config->localHostName,
- config->remoteHostName,
- config->s_port,
- config->isMgmConnection,
- localNodeId,
- config->remoteNodeId,
- config->serverNodeId,
- config->checksum,
- config->signalId);
- if (t == NULL)
- return false;
- else if (!t->initTransporter()) {
- delete t;
- return false;
- }
-
- // Put the transporter in the transporter arrays
- theTCPTransporters[nTCPTransporters] = t;
- theTransporters[t->getRemoteNodeId()] = t;
- theTransporterTypes[t->getRemoteNodeId()] = tt_TCP_TRANSPORTER;
- performStates[t->getRemoteNodeId()] = DISCONNECTED;
- nTransporters++;
- nTCPTransporters++;
-
- return true;
-#else
- return false;
-#endif
-}
-
-bool
-TransporterRegistry::createSCITransporter(TransporterConfiguration *config) {
-#ifdef NDB_SCI_TRANSPORTER
-
- if(!SCI_Transporter::initSCI())
- abort();
-
- if(!nodeIdSpecified){
- init(config->localNodeId);
- }
-
- if(config->localNodeId != localNodeId)
- return false;
-
- if(theTransporters[config->remoteNodeId] != NULL)
- return false;
-
- SCI_Transporter * t = new SCI_Transporter(*this,
- config->localHostName,
- config->remoteHostName,
- config->s_port,
- config->isMgmConnection,
- config->sci.sendLimit,
- config->sci.bufferSize,
- config->sci.nLocalAdapters,
- config->sci.remoteSciNodeId0,
- config->sci.remoteSciNodeId1,
- localNodeId,
- config->remoteNodeId,
- config->serverNodeId,
- config->checksum,
- config->signalId);
-
- if (t == NULL)
- return false;
- else if (!t->initTransporter()) {
- delete t;
- return false;
- }
- // Put the transporter in the transporter arrays
- theSCITransporters[nSCITransporters] = t;
- theTransporters[t->getRemoteNodeId()] = t;
- theTransporterTypes[t->getRemoteNodeId()] = tt_SCI_TRANSPORTER;
- performStates[t->getRemoteNodeId()] = DISCONNECTED;
- nTransporters++;
- nSCITransporters++;
-
- return true;
-#else
- return false;
-#endif
-}
-
-bool
-TransporterRegistry::createSHMTransporter(TransporterConfiguration *config) {
- DBUG_ENTER("TransporterRegistry::createTransporter SHM");
-#ifdef NDB_SHM_TRANSPORTER
- if(!nodeIdSpecified){
- init(config->localNodeId);
- }
-
- if(config->localNodeId != localNodeId)
- return false;
-
- if (!g_ndb_shm_signum) {
- g_ndb_shm_signum= config->shm.signum;
- DBUG_PRINT("info",("Block signum %d",g_ndb_shm_signum));
- /**
- * Make sure to block g_ndb_shm_signum
- * TransporterRegistry::init is run from "main" thread
- */
- NdbThread_set_shm_sigmask(TRUE);
- }
-
- if(config->shm.signum != g_ndb_shm_signum)
- return false;
-
- if(theTransporters[config->remoteNodeId] != NULL)
- return false;
-
- SHM_Transporter * t = new SHM_Transporter(*this,
- config->localHostName,
- config->remoteHostName,
- config->s_port,
- config->isMgmConnection,
- localNodeId,
- config->remoteNodeId,
- config->serverNodeId,
- config->checksum,
- config->signalId,
- config->shm.shmKey,
- config->shm.shmSize
- );
- if (t == NULL)
- return false;
- else if (!t->initTransporter()) {
- delete t;
- return false;
- }
- // Put the transporter in the transporter arrays
- theSHMTransporters[nSHMTransporters] = t;
- theTransporters[t->getRemoteNodeId()] = t;
- theTransporterTypes[t->getRemoteNodeId()] = tt_SHM_TRANSPORTER;
- performStates[t->getRemoteNodeId()] = DISCONNECTED;
-
- nTransporters++;
- nSHMTransporters++;
-
- DBUG_RETURN(true);
-#else
- DBUG_RETURN(false);
-#endif
-}
-
-
-void
-TransporterRegistry::removeTransporter(NodeId nodeId) {
-
- DEBUG("Removing transporter from " << localNodeId
- << " to " << nodeId);
-
- if(theTransporters[nodeId] == NULL)
- return;
-
- theTransporters[nodeId]->doDisconnect();
-
- const TransporterType type = theTransporterTypes[nodeId];
-
- int ind = 0;
- switch(type){
- case tt_TCP_TRANSPORTER:
-#ifdef NDB_TCP_TRANSPORTER
- for(; ind < nTCPTransporters; ind++)
- if(theTCPTransporters[ind]->getRemoteNodeId() == nodeId)
- break;
- ind++;
- for(; ind<nTCPTransporters; ind++)
- theTCPTransporters[ind-1] = theTCPTransporters[ind];
- nTCPTransporters --;
-#endif
- break;
- case tt_SCI_TRANSPORTER:
-#ifdef NDB_SCI_TRANSPORTER
- for(; ind < nSCITransporters; ind++)
- if(theSCITransporters[ind]->getRemoteNodeId() == nodeId)
- break;
- ind++;
- for(; ind<nSCITransporters; ind++)
- theSCITransporters[ind-1] = theSCITransporters[ind];
- nSCITransporters --;
-#endif
- break;
- case tt_SHM_TRANSPORTER:
-#ifdef NDB_SHM_TRANSPORTER
- for(; ind < nSHMTransporters; ind++)
- if(theSHMTransporters[ind]->getRemoteNodeId() == nodeId)
- break;
- ind++;
- for(; ind<nSHMTransporters; ind++)
- theSHMTransporters[ind-1] = theSHMTransporters[ind];
- nSHMTransporters --;
-#endif
- break;
- }
-
- nTransporters--;
-
- // Delete the transporter and remove it from theTransporters array
- delete theTransporters[nodeId];
- theTransporters[nodeId] = NULL;
-}
-
-Uint32
-TransporterRegistry::get_free_buffer(Uint32 node) const
-{
- Transporter *t;
- if(likely((t = theTransporters[node]) != 0))
- {
- return t->get_free_buffer();
- }
- return 0;
-}
-
-
-SendStatus
-TransporterRegistry::prepareSend(const SignalHeader * const signalHeader,
- Uint8 prio,
- const Uint32 * const signalData,
- NodeId nodeId,
- const LinearSectionPtr ptr[3]){
-
-
- Transporter *t = theTransporters[nodeId];
- if(t != NULL &&
- (((ioStates[nodeId] != HaltOutput) && (ioStates[nodeId] != HaltIO)) ||
- ((signalHeader->theReceiversBlockNumber == 252) ||
- (signalHeader->theReceiversBlockNumber == 4002)))) {
-
- if(t->isConnected()){
- Uint32 lenBytes = t->m_packer.getMessageLength(signalHeader, ptr);
- if(lenBytes <= MAX_MESSAGE_SIZE){
- Uint32 * insertPtr = t->getWritePtr(lenBytes, prio);
- if(insertPtr != 0){
- t->m_packer.pack(insertPtr, prio, signalHeader, signalData, ptr);
- t->updateWritePtr(lenBytes, prio);
- return SEND_OK;
- }
-
- int sleepTime = 2;
-
- /**
- * @note: on linux/i386 the granularity is 10ms
- * so sleepTime = 2 generates a 10 ms sleep.
- */
- for(int i = 0; i<50; i++){
- if((nSHMTransporters+nSCITransporters) == 0)
- NdbSleep_MilliSleep(sleepTime);
- insertPtr = t->getWritePtr(lenBytes, prio);
- if(insertPtr != 0){
- t->m_packer.pack(insertPtr, prio, signalHeader, signalData, ptr);
- t->updateWritePtr(lenBytes, prio);
- break;
- }
- }
-
- if(insertPtr != 0){
- /**
- * Send buffer full, but resend works
- */
- reportError(callbackObj, nodeId, TE_SEND_BUFFER_FULL);
- return SEND_OK;
- }
-
- WARNING("Signal to " << nodeId << " lost(buffer)");
- reportError(callbackObj, nodeId, TE_SIGNAL_LOST_SEND_BUFFER_FULL);
- return SEND_BUFFER_FULL;
- } else {
- return SEND_MESSAGE_TOO_BIG;
- }
- } else {
- DEBUG("Signal to " << nodeId << " lost(disconnect) ");
- return SEND_DISCONNECTED;
- }
- } else {
- DEBUG("Discarding message to block: "
- << signalHeader->theReceiversBlockNumber
- << " node: " << nodeId);
-
- if(t == NULL)
- return SEND_UNKNOWN_NODE;
-
- return SEND_BLOCKED;
- }
-}
-
-SendStatus
-TransporterRegistry::prepareSend(const SignalHeader * const signalHeader,
- Uint8 prio,
- const Uint32 * const signalData,
- NodeId nodeId,
- class SectionSegmentPool & thePool,
- const SegmentedSectionPtr ptr[3]){
-
-
- Transporter *t = theTransporters[nodeId];
- if(t != NULL &&
- (((ioStates[nodeId] != HaltOutput) && (ioStates[nodeId] != HaltIO)) ||
- ((signalHeader->theReceiversBlockNumber == 252)||
- (signalHeader->theReceiversBlockNumber == 4002)))) {
-
- if(t->isConnected()){
- Uint32 lenBytes = t->m_packer.getMessageLength(signalHeader, ptr);
- if(lenBytes <= MAX_MESSAGE_SIZE){
- Uint32 * insertPtr = t->getWritePtr(lenBytes, prio);
- if(insertPtr != 0){
- t->m_packer.pack(insertPtr, prio, signalHeader, signalData, thePool, ptr);
- t->updateWritePtr(lenBytes, prio);
- return SEND_OK;
- }
-
-
- /**
- * @note: on linux/i386 the granularity is 10ms
- * so sleepTime = 2 generates a 10 ms sleep.
- */
- int sleepTime = 2;
- for(int i = 0; i<50; i++){
- if((nSHMTransporters+nSCITransporters) == 0)
- NdbSleep_MilliSleep(sleepTime);
- insertPtr = t->getWritePtr(lenBytes, prio);
- if(insertPtr != 0){
- t->m_packer.pack(insertPtr, prio, signalHeader, signalData, thePool, ptr);
- t->updateWritePtr(lenBytes, prio);
- break;
- }
- }
-
- if(insertPtr != 0){
- /**
- * Send buffer full, but resend works
- */
- reportError(callbackObj, nodeId, TE_SEND_BUFFER_FULL);
- return SEND_OK;
- }
-
- WARNING("Signal to " << nodeId << " lost(buffer)");
- reportError(callbackObj, nodeId, TE_SIGNAL_LOST_SEND_BUFFER_FULL);
- return SEND_BUFFER_FULL;
- } else {
- return SEND_MESSAGE_TOO_BIG;
- }
- } else {
- DEBUG("Signal to " << nodeId << " lost(disconnect) ");
- return SEND_DISCONNECTED;
- }
- } else {
- DEBUG("Discarding message to block: "
- << signalHeader->theReceiversBlockNumber
- << " node: " << nodeId);
-
- if(t == NULL)
- return SEND_UNKNOWN_NODE;
-
- return SEND_BLOCKED;
- }
-}
-
-void
-TransporterRegistry::external_IO(Uint32 timeOutMillis) {
- //-----------------------------------------------------------
- // Most of the time we will send the buffers here and then wait
- // for new signals. Thus we start by sending without timeout
- // followed by the receive part where we expect to sleep for
- // a while.
- //-----------------------------------------------------------
- if(pollReceive(timeOutMillis)){
- performReceive();
- }
- performSend();
-}
-
-Uint32
-TransporterRegistry::pollReceive(Uint32 timeOutMillis){
- Uint32 retVal = 0;
-
- if((nSCITransporters) > 0)
- {
- timeOutMillis=0;
- }
-
-#ifdef NDB_SHM_TRANSPORTER
- if(nSHMTransporters > 0)
- {
- Uint32 res = poll_SHM(0);
- if(res)
- {
- retVal |= res;
- timeOutMillis = 0;
- }
- }
-#endif
-
-#ifdef NDB_TCP_TRANSPORTER
- if(nTCPTransporters > 0 || retVal == 0)
- {
- retVal |= poll_TCP(timeOutMillis);
- }
- else
- tcpReadSelectReply = 0;
-#endif
-#ifdef NDB_SCI_TRANSPORTER
- if(nSCITransporters > 0)
- retVal |= poll_SCI(timeOutMillis);
-#endif
-#ifdef NDB_SHM_TRANSPORTER
- if(nSHMTransporters > 0 && retVal == 0)
- {
- int res = poll_SHM(0);
- retVal |= res;
- }
-#endif
- return retVal;
-}
-
-
-#ifdef NDB_SCI_TRANSPORTER
-Uint32
-TransporterRegistry::poll_SCI(Uint32 timeOutMillis)
-{
- for (int i=0; i<nSCITransporters; i++) {
- SCI_Transporter * t = theSCITransporters[i];
- if (t->isConnected()) {
- if(t->hasDataToRead())
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-
-#ifdef NDB_SHM_TRANSPORTER
-static int g_shm_counter = 0;
-Uint32
-TransporterRegistry::poll_SHM(Uint32 timeOutMillis)
-{
- for(int j=0; j < 100; j++)
- {
- for (int i=0; i<nSHMTransporters; i++) {
- SHM_Transporter * t = theSHMTransporters[i];
- if (t->isConnected()) {
- if(t->hasDataToRead()) {
- return 1;
- }
- }
- }
- }
- return 0;
-}
-#endif
-
-#ifdef NDB_TCP_TRANSPORTER
-Uint32
-TransporterRegistry::poll_TCP(Uint32 timeOutMillis)
-{
- bool hasdata = false;
- if (false && nTCPTransporters == 0)
- {
- tcpReadSelectReply = 0;
- return 0;
- }
-
- NDB_SOCKET_TYPE maxSocketValue = -1;
-
- // Needed for TCP/IP connections
- // The read- and writeset are used by select
-
- FD_ZERO(&tcpReadset);
-
- // Prepare for sending and receiving
- for (int i = 0; i < nTCPTransporters; i++) {
- TCP_Transporter * t = theTCPTransporters[i];
-
- // If the transporter is connected
- NodeId nodeId = t->getRemoteNodeId();
- if (is_connected(nodeId) && t->isConnected()) {
-
- const NDB_SOCKET_TYPE socket = t->getSocket();
- // Find the highest socket value. It will be used by select
- if (socket > maxSocketValue)
- maxSocketValue = socket;
-
- // Put the connected transporters in the socket read-set
- FD_SET(socket, &tcpReadset);
- }
- hasdata |= t->hasReceiveData();
- }
-
- timeOutMillis = hasdata ? 0 : timeOutMillis;
-
- struct timeval timeout;
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
-
- // The highest socket value plus one
- maxSocketValue++;
-
- tcpReadSelectReply = select(maxSocketValue, &tcpReadset, 0, 0, &timeout);
- if(false && tcpReadSelectReply == -1 && errno == EINTR)
- g_eventLogger.info("woke-up by signal");
-
-#ifdef NDB_WIN32
- if(tcpReadSelectReply == SOCKET_ERROR)
- {
- NdbSleep_MilliSleep(timeOutMillis);
- }
-#endif
-
- return tcpReadSelectReply || hasdata;
-}
-#endif
-
-
-void
-TransporterRegistry::performReceive()
-{
-#ifdef NDB_TCP_TRANSPORTER
- for (int i=0; i<nTCPTransporters; i++)
- {
- checkJobBuffer();
- TCP_Transporter *t = theTCPTransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
- const NDB_SOCKET_TYPE socket = t->getSocket();
- if(is_connected(nodeId)){
- if(t->isConnected())
- {
- if (FD_ISSET(socket, &tcpReadset))
- {
- t->doReceive();
- }
-
- if (t->hasReceiveData())
- {
- Uint32 * ptr;
- Uint32 sz = t->getReceiveData(&ptr);
- transporter_recv_from(callbackObj, nodeId);
- Uint32 szUsed = unpack(ptr, sz, nodeId, ioStates[nodeId]);
- t->updateReceiveDataPtr(szUsed);
- }
- }
- }
- }
-#endif
-
-#ifdef NDB_SCI_TRANSPORTER
- //performReceive
- //do prepareReceive on the SCI transporters (prepareReceive(t,,,,))
- for (int i=0; i<nSCITransporters; i++)
- {
- checkJobBuffer();
- SCI_Transporter *t = theSCITransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
- if(is_connected(nodeId))
- {
- if(t->isConnected() && t->checkConnected())
- {
- Uint32 * readPtr, * eodPtr;
- t->getReceivePtr(&readPtr, &eodPtr);
- transporter_recv_from(callbackObj, nodeId);
- Uint32 *newPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]);
- t->updateReceivePtr(newPtr);
- }
- }
- }
-#endif
-#ifdef NDB_SHM_TRANSPORTER
- for (int i=0; i<nSHMTransporters; i++)
- {
- checkJobBuffer();
- SHM_Transporter *t = theSHMTransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
- if(is_connected(nodeId)){
- if(t->isConnected() && t->checkConnected())
- {
- Uint32 * readPtr, * eodPtr;
- t->getReceivePtr(&readPtr, &eodPtr);
- transporter_recv_from(callbackObj, nodeId);
- Uint32 *newPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]);
- t->updateReceivePtr(newPtr);
- }
- }
- }
-#endif
-}
-
-void
-TransporterRegistry::performSend()
-{
- int i;
- sendCounter = 1;
-
-#ifdef NDB_TCP_TRANSPORTER
- for (i = m_transp_count; i < nTCPTransporters; i++)
- {
- TCP_Transporter *t = theTCPTransporters[i];
- if (t && t->hasDataToSend() && t->isConnected() &&
- is_connected(t->getRemoteNodeId()))
- {
- t->doSend();
- }
- }
- for (i = 0; i < m_transp_count && i < nTCPTransporters; i++)
- {
- TCP_Transporter *t = theTCPTransporters[i];
- if (t && t->hasDataToSend() && t->isConnected() &&
- is_connected(t->getRemoteNodeId()))
- {
- t->doSend();
- }
- }
- m_transp_count++;
- if (m_transp_count == nTCPTransporters) m_transp_count = 0;
-#endif
-#ifdef NDB_SCI_TRANSPORTER
- //scroll through the SCI transporters,
- // get each transporter, check if connected, send data
- for (i=0; i<nSCITransporters; i++) {
- SCI_Transporter *t = theSCITransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
-
- if(is_connected(nodeId))
- {
- if(t->isConnected() && t->hasDataToSend()) {
- t->doSend();
- } //if
- } //if
- }
-#endif
-
-#ifdef NDB_SHM_TRANSPORTER
- for (i=0; i<nSHMTransporters; i++)
- {
- SHM_Transporter *t = theSHMTransporters[i];
- const NodeId nodeId = t->getRemoteNodeId();
- if(is_connected(nodeId))
- {
- if(t->isConnected())
- {
- t->doSend();
- }
- }
- }
-#endif
-}
-
-int
-TransporterRegistry::forceSendCheck(int sendLimit){
- int tSendCounter = sendCounter;
- sendCounter = tSendCounter + 1;
- if (tSendCounter >= sendLimit) {
- performSend();
- sendCounter = 1;
- return 1;
- }//if
- return 0;
-}//TransporterRegistry::forceSendCheck()
-
-#ifdef DEBUG_TRANSPORTER
-void
-TransporterRegistry::printState(){
- ndbout << "-- TransporterRegistry -- " << endl << endl
- << "Transporters = " << nTransporters << endl;
- for(int i = 0; i<maxTransporters; i++)
- if(theTransporters[i] != NULL){
- const NodeId remoteNodeId = theTransporters[i]->getRemoteNodeId();
- ndbout << "Transporter: " << remoteNodeId
- << " PerformState: " << performStates[remoteNodeId]
- << " IOState: " << ioStates[remoteNodeId] << endl;
- }
-}
-#endif
-
-IOState
-TransporterRegistry::ioState(NodeId nodeId) {
- return ioStates[nodeId];
-}
-
-void
-TransporterRegistry::setIOState(NodeId nodeId, IOState state) {
- DEBUG("TransporterRegistry::setIOState("
- << nodeId << ", " << state << ")");
- ioStates[nodeId] = state;
-}
-
-static void *
-run_start_clients_C(void * me)
-{
- ((TransporterRegistry*) me)->start_clients_thread();
- return 0;
-}
-
-// Run by kernel thread
-void
-TransporterRegistry::do_connect(NodeId node_id)
-{
- PerformState &curr_state = performStates[node_id];
- switch(curr_state){
- case DISCONNECTED:
- break;
- case CONNECTED:
- return;
- case CONNECTING:
- return;
- case DISCONNECTING:
- break;
- }
- DBUG_ENTER("TransporterRegistry::do_connect");
- DBUG_PRINT("info",("performStates[%d]=CONNECTING",node_id));
- curr_state= CONNECTING;
- DBUG_VOID_RETURN;
-}
-void
-TransporterRegistry::do_disconnect(NodeId node_id)
-{
- PerformState &curr_state = performStates[node_id];
- switch(curr_state){
- case DISCONNECTED:
- return;
- case CONNECTED:
- break;
- case CONNECTING:
- break;
- case DISCONNECTING:
- return;
- }
- DBUG_ENTER("TransporterRegistry::do_disconnect");
- DBUG_PRINT("info",("performStates[%d]=DISCONNECTING",node_id));
- curr_state= DISCONNECTING;
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterRegistry::report_connect(NodeId node_id)
-{
- DBUG_ENTER("TransporterRegistry::report_connect");
- DBUG_PRINT("info",("performStates[%d]=CONNECTED",node_id));
- performStates[node_id] = CONNECTED;
- reportConnect(callbackObj, node_id);
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterRegistry::report_disconnect(NodeId node_id, int errnum)
-{
- DBUG_ENTER("TransporterRegistry::report_disconnect");
- DBUG_PRINT("info",("performStates[%d]=DISCONNECTED",node_id));
- performStates[node_id] = DISCONNECTED;
- reportDisconnect(callbackObj, node_id, errnum);
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterRegistry::update_connections()
-{
- for (int i= 0, n= 0; n < nTransporters; i++){
- Transporter * t = theTransporters[i];
- if (!t)
- continue;
- n++;
-
- const NodeId nodeId = t->getRemoteNodeId();
- switch(performStates[nodeId]){
- case CONNECTED:
- case DISCONNECTED:
- break;
- case CONNECTING:
- if(t->isConnected())
- report_connect(nodeId);
- break;
- case DISCONNECTING:
- if(!t->isConnected())
- report_disconnect(nodeId, 0);
- break;
- }
- }
-}
-
-// run as own thread
-void
-TransporterRegistry::start_clients_thread()
-{
- int persist_mgm_count= 0;
- DBUG_ENTER("TransporterRegistry::start_clients_thread");
- while (m_run_start_clients_thread) {
- NdbSleep_MilliSleep(100);
- persist_mgm_count++;
- if(persist_mgm_count==50)
- {
- ndb_mgm_check_connection(m_mgm_handle);
- persist_mgm_count= 0;
- }
- for (int i= 0, n= 0; n < nTransporters && m_run_start_clients_thread; i++){
- Transporter * t = theTransporters[i];
- if (!t)
- continue;
- n++;
-
- const NodeId nodeId = t->getRemoteNodeId();
- switch(performStates[nodeId]){
- case CONNECTING:
- if(!t->isConnected() && !t->isServer) {
- bool connected= false;
- /**
- * First, we try to connect (if we have a port number).
- */
- if (t->get_s_port())
- connected= t->connect_client();
-
- /**
- * If dynamic, get the port for connecting from the management server
- */
- if( !connected && t->get_s_port() <= 0) { // Port is dynamic
- int server_port= 0;
- struct ndb_mgm_reply mgm_reply;
-
- if(!ndb_mgm_is_connected(m_mgm_handle))
- ndb_mgm_connect(m_mgm_handle, 0, 0, 0);
-
- if(ndb_mgm_is_connected(m_mgm_handle))
- {
- int res=
- ndb_mgm_get_connection_int_parameter(m_mgm_handle,
- t->getRemoteNodeId(),
- t->getLocalNodeId(),
- CFG_CONNECTION_SERVER_PORT,
- &server_port,
- &mgm_reply);
- DBUG_PRINT("info",("Got dynamic port %d for %d -> %d (ret: %d)",
- server_port,t->getRemoteNodeId(),
- t->getLocalNodeId(),res));
- if( res >= 0 )
- {
- /**
- * Server_port == 0 just means that that a mgmt server
- * has not received a new port yet. Keep the old.
- */
- if (server_port)
- t->set_s_port(server_port);
- }
- else if(ndb_mgm_is_connected(m_mgm_handle))
- {
- g_eventLogger.info("Failed to get dynamic port to connect to: %d", res);
- ndb_mgm_disconnect(m_mgm_handle);
- }
- else
- {
- g_eventLogger.info("Management server closed connection early. "
- "It is probably being shut down (or has problems). "
- "We will retry the connection. %d %s %s line: %d",
- ndb_mgm_get_latest_error(m_mgm_handle),
- ndb_mgm_get_latest_error_desc(m_mgm_handle),
- ndb_mgm_get_latest_error_msg(m_mgm_handle),
- ndb_mgm_get_latest_error_line(m_mgm_handle)
- );
- }
- }
- /** else
- * We will not be able to get a new port unless
- * the m_mgm_handle is connected. Note that not
- * being connected is an ok state, just continue
- * until it is able to connect. Continue using the
- * old port until we can connect again and get a
- * new port.
- */
- }
- }
- break;
- case DISCONNECTING:
- if(t->isConnected())
- t->doDisconnect();
- break;
- default:
- break;
- }
- }
- }
- DBUG_VOID_RETURN;
-}
-
-bool
-TransporterRegistry::start_clients()
-{
- m_run_start_clients_thread= true;
- m_start_clients_thread= NdbThread_Create(run_start_clients_C,
- (void**)this,
- 32768,
- "ndb_start_clients",
- NDB_THREAD_PRIO_LOW);
- if (m_start_clients_thread == 0) {
- m_run_start_clients_thread= false;
- return false;
- }
- return true;
-}
-
-bool
-TransporterRegistry::stop_clients()
-{
- if (m_start_clients_thread) {
- m_run_start_clients_thread= false;
- void* status;
- NdbThread_WaitFor(m_start_clients_thread, &status);
- NdbThread_Destroy(&m_start_clients_thread);
- }
- return true;
-}
-
-void
-TransporterRegistry::add_transporter_interface(NodeId remoteNodeId,
- const char *interf,
- int s_port)
-{
- DBUG_ENTER("TransporterRegistry::add_transporter_interface");
- DBUG_PRINT("enter",("interface=%s, s_port= %d", interf, s_port));
- if (interf && strlen(interf) == 0)
- interf= 0;
-
- for (unsigned i= 0; i < m_transporter_interface.size(); i++)
- {
- Transporter_interface &tmp= m_transporter_interface[i];
- if (s_port != tmp.m_s_service_port || tmp.m_s_service_port==0)
- continue;
- if (interf != 0 && tmp.m_interface != 0 &&
- strcmp(interf, tmp.m_interface) == 0)
- {
- DBUG_VOID_RETURN; // found match, no need to insert
- }
- if (interf == 0 && tmp.m_interface == 0)
- {
- DBUG_VOID_RETURN; // found match, no need to insert
- }
- }
- Transporter_interface t;
- t.m_remote_nodeId= remoteNodeId;
- t.m_s_service_port= s_port;
- t.m_interface= interf;
- m_transporter_interface.push_back(t);
- DBUG_PRINT("exit",("interface and port added"));
- DBUG_VOID_RETURN;
-}
-
-bool
-TransporterRegistry::start_service(SocketServer& socket_server)
-{
- DBUG_ENTER("TransporterRegistry::start_service");
- if (m_transporter_interface.size() > 0 && !nodeIdSpecified)
- {
- g_eventLogger.error("TransporterRegistry::startReceiving: localNodeId not specified");
- DBUG_RETURN(false);
- }
-
- for (unsigned i= 0; i < m_transporter_interface.size(); i++)
- {
- Transporter_interface &t= m_transporter_interface[i];
-
- unsigned short port= (unsigned short)t.m_s_service_port;
- if(t.m_s_service_port<0)
- port= -t.m_s_service_port; // is a dynamic port
- TransporterService *transporter_service =
- new TransporterService(new SocketAuthSimple("ndbd", "ndbd passwd"));
- if(!socket_server.setup(transporter_service,
- &port, t.m_interface))
- {
- DBUG_PRINT("info", ("Trying new port"));
- port= 0;
- if(t.m_s_service_port>0
- || !socket_server.setup(transporter_service,
- &port, t.m_interface))
- {
- /*
- * If it wasn't a dynamically allocated port, or
- * our attempts at getting a new dynamic port failed
- */
- g_eventLogger.error("Unable to setup transporter service port: %s:%d!\n"
- "Please check if the port is already used,\n"
- "(perhaps the node is already running)",
- t.m_interface ? t.m_interface : "*", t.m_s_service_port);
- delete transporter_service;
- DBUG_RETURN(false);
- }
- }
- t.m_s_service_port= (t.m_s_service_port<=0)?-port:port; // -`ve if dynamic
- DBUG_PRINT("info", ("t.m_s_service_port = %d",t.m_s_service_port));
- transporter_service->setTransporterRegistry(this);
- }
- DBUG_RETURN(true);
-}
-
-#ifdef NDB_SHM_TRANSPORTER
-static
-RETSIGTYPE
-shm_sig_handler(int signo)
-{
- g_shm_counter++;
-}
-#endif
-
-void
-TransporterRegistry::startReceiving()
-{
- DBUG_ENTER("TransporterRegistry::startReceiving");
-
-#ifdef NDB_SHM_TRANSPORTER
- m_shm_own_pid = getpid();
- if (g_ndb_shm_signum)
- {
- DBUG_PRINT("info",("Install signal handler for signum %d",
- g_ndb_shm_signum));
- struct sigaction sa;
- NdbThread_set_shm_sigmask(FALSE);
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = shm_sig_handler;
- sa.sa_flags = 0;
- int ret;
- while((ret = sigaction(g_ndb_shm_signum, &sa, 0)) == -1 && errno == EINTR);
- if(ret != 0)
- {
- DBUG_PRINT("error",("Install failed"));
- g_eventLogger.error("Failed to install signal handler for"
- " SHM transporter, signum %d, errno: %d (%s)",
- g_ndb_shm_signum, errno, strerror(errno));
- }
- }
-#endif // NDB_SHM_TRANSPORTER
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterRegistry::stopReceiving(){
- /**
- * Disconnect all transporters, this includes detach from remote node
- * and since that must be done from the same process that called attach
- * it's done here in the receive thread
- */
- disconnectAll();
-}
-
-void
-TransporterRegistry::startSending(){
-}
-
-void
-TransporterRegistry::stopSending(){
-}
-
-NdbOut & operator <<(NdbOut & out, SignalHeader & sh){
- out << "-- Signal Header --" << endl;
- out << "theLength: " << sh.theLength << endl;
- out << "gsn: " << sh.theVerId_signalNumber << endl;
- out << "recBlockNo: " << sh.theReceiversBlockNumber << endl;
- out << "sendBlockRef: " << sh.theSendersBlockRef << endl;
- out << "sendersSig: " << sh.theSendersSignalId << endl;
- out << "theSignalId: " << sh.theSignalId << endl;
- out << "trace: " << (int)sh.theTrace << endl;
- return out;
-}
-
-Transporter*
-TransporterRegistry::get_transporter(NodeId nodeId) {
- return theTransporters[nodeId];
-}
-
-bool TransporterRegistry::connect_client(NdbMgmHandle *h)
-{
- DBUG_ENTER("TransporterRegistry::connect_client(NdbMgmHandle)");
-
- Uint32 mgm_nodeid= ndb_mgm_get_mgmd_nodeid(*h);
-
- if(!mgm_nodeid)
- {
- g_eventLogger.error("%s: %d", __FILE__, __LINE__);
- return false;
- }
- Transporter * t = theTransporters[mgm_nodeid];
- if (!t)
- {
- g_eventLogger.error("%s: %d", __FILE__, __LINE__);
- return false;
- }
- DBUG_RETURN(t->connect_client(connect_ndb_mgmd(h)));
-}
-
-/**
- * Given a connected NdbMgmHandle, turns it into a transporter
- * and returns the socket.
- */
-NDB_SOCKET_TYPE TransporterRegistry::connect_ndb_mgmd(NdbMgmHandle *h)
-{
- struct ndb_mgm_reply mgm_reply;
-
- if ( h==NULL || *h == NULL )
- {
- g_eventLogger.error("%s: %d", __FILE__, __LINE__);
- return NDB_INVALID_SOCKET;
- }
-
- for(unsigned int i=0;i < m_transporter_interface.size();i++)
- if (m_transporter_interface[i].m_s_service_port < 0
- && ndb_mgm_set_connection_int_parameter(*h,
- get_localNodeId(),
- m_transporter_interface[i].m_remote_nodeId,
- CFG_CONNECTION_SERVER_PORT,
- m_transporter_interface[i].m_s_service_port,
- &mgm_reply) < 0)
- {
- g_eventLogger.error("Error: %s: %d",
- ndb_mgm_get_latest_error_desc(*h),
- ndb_mgm_get_latest_error(*h));
- g_eventLogger.error("%s: %d", __FILE__, __LINE__);
- ndb_mgm_destroy_handle(h);
- return NDB_INVALID_SOCKET;
- }
-
- /**
- * convert_to_transporter also disposes of the handle (i.e. we don't leak
- * memory here.
- */
- NDB_SOCKET_TYPE sockfd= ndb_mgm_convert_to_transporter(h);
- if ( sockfd == NDB_INVALID_SOCKET)
- {
- g_eventLogger.error("Error: %s: %d",
- ndb_mgm_get_latest_error_desc(*h),
- ndb_mgm_get_latest_error(*h));
- g_eventLogger.error("%s: %d", __FILE__, __LINE__);
- ndb_mgm_destroy_handle(h);
- }
- return sockfd;
-}
-
-/**
- * Given a SocketClient, creates a NdbMgmHandle, turns it into a transporter
- * and returns the socket.
- */
-NDB_SOCKET_TYPE TransporterRegistry::connect_ndb_mgmd(SocketClient *sc)
-{
- NdbMgmHandle h= ndb_mgm_create_handle();
-
- if ( h == NULL )
- {
- return NDB_INVALID_SOCKET;
- }
-
- /**
- * Set connectstring
- */
- {
- BaseString cs;
- cs.assfmt("%s:%u",sc->get_server_name(),sc->get_port());
- ndb_mgm_set_connectstring(h, cs.c_str());
- }
-
- if(ndb_mgm_connect(h, 0, 0, 0)<0)
- {
- ndb_mgm_destroy_handle(&h);
- return NDB_INVALID_SOCKET;
- }
-
- return connect_ndb_mgmd(&h);
-}
-
-template class Vector<TransporterRegistry::Transporter_interface>;
diff --git a/storage/ndb/src/common/transporter/basictest/Makefile b/storage/ndb/src/common/transporter/basictest/Makefile
deleted file mode 100644
index d86af360408..00000000000
--- a/storage/ndb/src/common/transporter/basictest/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := basicTransporterTest
-BIN_TARGET_ARCHIVES := transporter portlib general
-
-SOURCES = basicTransporterTest.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp b/storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp
deleted file mode 100644
index b4b3e638935..00000000000
--- a/storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "TransporterRegistry.hpp"
-#include "TransporterDefinitions.hpp"
-#include "TransporterCallback.hpp"
-#include <RefConvert.hpp>
-
-#include <NdbTick.h>
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-
-int basePortTCP = 17000;
-
-SCI_TransporterConfiguration sciTemplate = {
- 8000,
- // Packet size
- 2500000, // Buffer size
- 2, // number of adapters
- 1, // remote node id SCI
- 2, // Remote node Id SCI
- 0, // local ndb node id (server)
- 0, // remote ndb node id (client)
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-TCP_TransporterConfiguration tcpTemplate = {
- 17000, // port;
- "", // remoteHostName;
- "", // localhostname
- 2, // remoteNodeId;
- 1, // localNodeId;
- 10000, // sendBufferSize - Size of SendBuffer of priority B
- 10000, // maxReceiveSize - Maximum no of bytes to receive
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-SHM_TransporterConfiguration shmTemplate = {
- 0, //remoteNodeId
- 0, //localNodeId;
- false, //compression
- true, //checksum;
- true, //signalId;
- 0, //byteOrder;
- 123, //shmKey;
- 2500000 //shmSize;
-};
-
-TransporterRegistry *tReg = 0;
-
-#include <signal.h>
-
-extern "C"
-void
-signalHandler(int signo){
- ::signal(13, signalHandler);
- char buf[255];
- sprintf(buf,"Signal: %d\n", signo);
- ndbout << buf << endl;
-}
-
-void
-usage(const char * progName){
- ndbout << "Usage: " << progName << " <type> localNodeId localHostName"
- << " remoteHostName1 remoteHostName2" << endl;
- ndbout << " type = shm tcp ose sci" << endl;
- ndbout << " localNodeId - 1 to 3" << endl;
-}
-
-typedef void (* CreateTransporterFunc)(void * conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName);
-
-void createSCITransporter(void *, NodeId, NodeId, const char *, const char *);
-void createTCPTransporter(void *, NodeId, NodeId, const char *, const char *);
-void createSHMTransporter(void *, NodeId, NodeId, const char *, const char *);
-
-int signalReceived[4];
-
-int
-main(int argc, const char **argv){
-
- signalHandler(0);
-
- for(int i = 0; i<4; i++)
- signalReceived[i] = 0;
-
- if(argc < 5){
- usage(argv[0]);
- return 0;
- }
-
- Uint32 noOfConnections = 0;
- const char * progName = argv[0];
- const char * type = argv[1];
- const NodeId localNodeId = atoi(argv[2]);
- const char * localHostName = argv[3];
- const char * remoteHost1 = argv[4];
- const char * remoteHost2 = NULL;
-
- if(argc == 5)
- noOfConnections = 1;
- else {
- noOfConnections = 2;
- remoteHost2 = argv[5];
- }
-
- if(localNodeId < 1 || localNodeId > 3){
- ndbout << "localNodeId = " << localNodeId << endl << endl;
- usage(progName);
- return 0;
- }
-
- ndbout << "-----------------" << endl;
- ndbout << "localNodeId: " << localNodeId << endl;
- ndbout << "localHostName: " << localHostName << endl;
- ndbout << "remoteHost1 (node " << (localNodeId == 1?2:1) << "): "
- << remoteHost1 << endl;
- if(noOfConnections == 2){
- ndbout << "remoteHost2 (node " << (localNodeId == 3?2:3) << "): "
- << remoteHost2 << endl;
- }
- ndbout << "-----------------" << endl;
-
- void * confTemplate = 0;
- CreateTransporterFunc func = 0;
-
- if(strcasecmp(type, "tcp") == 0){
- func = createTCPTransporter;
- confTemplate = &tcpTemplate;
- } else if(strcasecmp(type, "sci") == 0){
- func = createSCITransporter;
- confTemplate = &sciTemplate;
- } else if(strcasecmp(type, "shm") == 0){
- func = createSHMTransporter;
- confTemplate = &shmTemplate;
- } else {
- ndbout << "Unsupported transporter type" << endl;
- return 0;
- }
-
- ndbout << "Creating transporter registry" << endl;
- tReg = new TransporterRegistry;
- tReg->init(localNodeId);
-
- switch(localNodeId){
- case 1:
- (* func)(confTemplate, 1, 2, localHostName, remoteHost1);
- if(noOfConnections == 2)
- (* func)(confTemplate, 1, 3, localHostName, remoteHost2);
- break;
- case 2:
- (* func)(confTemplate, 2, 1, localHostName, remoteHost1);
- if(noOfConnections == 2)
- (* func)(confTemplate, 2, 3, localHostName, remoteHost2);
- break;
- case 3:
- (* func)(confTemplate, 3, 1, localHostName, remoteHost1);
- if(noOfConnections == 2)
- (* func)(confTemplate, 3, 2, localHostName, remoteHost2);
- break;
- }
-
- ndbout << "Doing startSending/startReceiving" << endl;
- tReg->startSending();
- tReg->startReceiving();
-
- ndbout << "Connecting" << endl;
- tReg->setPerformState(PerformConnect);
- tReg->checkConnections();
-
- unsigned sum = 0;
- do {
- sum = 0;
- for(int i = 0; i<4; i++)
- sum += signalReceived[i];
-
- tReg->checkConnections();
-
- tReg->external_IO(500);
- NdbSleep_MilliSleep(500);
-
- ndbout << "In main loop" << endl;
- } while(sum != 2*noOfConnections);
-
- ndbout << "Doing setPerformState(Disconnect)" << endl;
- tReg->setPerformState(PerformDisconnect);
-
- ndbout << "Doing checkConnections()" << endl;
- tReg->checkConnections();
-
- ndbout << "Sleeping 3 secs" << endl;
- NdbSleep_SecSleep(3);
-
- ndbout << "Deleting transporter registry" << endl;
- delete tReg; tReg = 0;
-
- return 0;
-}
-
-void
-checkData(SignalHeader * const header, Uint8 prio, Uint32 * const theData,
- LinearSectionPtr ptr[3]){
- Uint32 expectedLength = 0;
- if(prio == 0)
- expectedLength = 17;
- else
- expectedLength = 19;
-
- if(header->theLength != expectedLength){
- ndbout << "Unexpected signal length: " << header->theLength
- << " expected: " << expectedLength << endl;
- abort();
- }
-
- if(header->theVerId_signalNumber != expectedLength + 1)
- abort();
-
- if(header->theReceiversBlockNumber != expectedLength + 2)
- abort();
-
- if(refToBlock(header->theSendersBlockRef) != expectedLength + 3)
- abort();
-
- if(header->theSendersSignalId != expectedLength + 5)
- abort();
-
- if(header->theTrace != expectedLength + 6)
- abort();
-
- if(header->m_noOfSections != (prio == 0 ? 0 : 1))
- abort();
-
- if(header->m_fragmentInfo != (prio + 1))
- abort();
-
- Uint32 dataWordStart = header->theLength ;
- for(unsigned i = 0; i<header->theLength; i++){
- if(theData[i] != i){ //dataWordStart){
- ndbout << "data corrupt!\n" << endl;
- abort();
- }
- dataWordStart ^= (~i*i);
- }
-
- if(prio != 0){
- ndbout_c("Found section");
- if(ptr[0].sz != header->theLength)
- abort();
-
- if(memcmp(ptr[0].p, theData, (ptr[0].sz * 4)) != 0)
- abort();
- }
-}
-
-void
-sendSignalTo(NodeId nodeId, int prio){
- SignalHeader sh;
- sh.theLength = (prio == 0 ? 17 : 19);
- sh.theVerId_signalNumber = sh.theLength + 1;
- sh.theReceiversBlockNumber = sh.theLength + 2;
- sh.theSendersBlockRef = sh.theLength + 3;
- sh.theSendersSignalId = sh.theLength + 4;
- sh.theSignalId = sh.theLength + 5;
- sh.theTrace = sh.theLength + 6;
- sh.m_noOfSections = (prio == 0 ? 0 : 1);
- sh.m_fragmentInfo = prio + 1;
-
- Uint32 theData[25];
-
- Uint32 dataWordStart = sh.theLength;
- for(unsigned i = 0; i<sh.theLength; i++){
- theData[i] = i;
- dataWordStart ^= (~i*i);
- }
- ndbout << "Sending prio " << (int)prio << " signal to node: "
- << nodeId
- << " gsn = " << sh.theVerId_signalNumber << endl;
-
- LinearSectionPtr ptr[3];
- ptr[0].p = &theData[0];
- ptr[0].sz = sh.theLength;
-
- SendStatus s = tReg->prepareSend(&sh, prio, theData, nodeId, ptr);
- if(s != SEND_OK){
- ndbout << "Send was not ok. Send was: " << s << endl;
- }
-}
-
-void
-execute(void* callbackObj,
- SignalHeader * const header, Uint8 prio, Uint32 * const theData,
- LinearSectionPtr ptr[3]){
- const NodeId nodeId = refToNode(header->theSendersBlockRef);
-
- ndbout << "Recieved prio " << (int)prio << " signal from node: "
- << nodeId
- << " gsn = " << header->theVerId_signalNumber << endl;
- checkData(header, prio, theData, ptr);
- ndbout << " Data is ok!\n" << endl;
-
- signalReceived[nodeId]++;
-
- if(prio == 0)
- sendSignalTo(nodeId, 1);
- else
- tReg->setPerformState(nodeId, PerformDisconnect);
-}
-
-void
-copy(Uint32 * & insertPtr,
- class SectionSegmentPool & thePool, const SegmentedSectionPtr & _ptr){
- abort();
-}
-
-void
-reportError(void* callbackObj, NodeId nodeId, TransporterError errorCode){
- char buf[255];
- sprintf(buf, "reportError (%d, %x)", nodeId, errorCode);
- ndbout << buf << endl;
- if(errorCode & 0x8000){
- tReg->setPerformState(nodeId, PerformDisconnect);
- abort();
- }
-}
-
-/**
- * Report average send theLength in bytes (4096 last sends)
- */
-void
-reportSendLen(void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
- char buf[255];
- sprintf(buf, "reportSendLen(%d, %d)", nodeId, (Uint32)(bytes/count));
- ndbout << buf << endl;
-}
-
-/**
- * Report average receive theLength in bytes (4096 last receives)
- */
-void
-reportReceiveLen(void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
- char buf[255];
- sprintf(buf, "reportReceiveLen(%d, %d)", nodeId, (Uint32)(bytes/count));
- ndbout << buf << endl;
-}
-
-/**
- * Report connection established
- */
-void
-reportConnect(void* callbackObj, NodeId nodeId){
- char buf[255];
- sprintf(buf, "reportConnect(%d)", nodeId);
- ndbout << buf << endl;
- tReg->setPerformState(nodeId, PerformIO);
-
- sendSignalTo(nodeId, 0);
-}
-
-/**
- * Report connection broken
- */
-void
-reportDisconnect(void* callbackObj, NodeId nodeId, Uint32 errNo){
- char buf[255];
- sprintf(buf, "reportDisconnect(%d)", nodeId);
- ndbout << buf << endl;
- if(signalReceived[nodeId] < 2)
- tReg->setPerformState(nodeId, PerformConnect);
-}
-
-int
-checkJobBuffer() {
- /**
- * Check to see if jobbbuffers are starting to get full
- * and if so call doJob
- */
- return 0;
-}
-
-void
-createOSETransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName){
- ndbout << "Creating OSE transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
- OSE_TransporterConfiguration * conf = (OSE_TransporterConfiguration*)_conf;
-
- conf->localNodeId = localNodeId;
- conf->localHostName = localHostName;
- conf->remoteNodeId = remoteNodeId;
- conf->remoteHostName = remoteHostName;
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-void
-createTCPTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName){
- ndbout << "Creating TCP transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
- TCP_TransporterConfiguration * conf = (TCP_TransporterConfiguration*)_conf;
-
- int port;
- if(localNodeId == 1 && remoteNodeId == 2) port = basePortTCP + 0;
- if(localNodeId == 1 && remoteNodeId == 3) port = basePortTCP + 1;
- if(localNodeId == 2 && remoteNodeId == 1) port = basePortTCP + 0;
- if(localNodeId == 2 && remoteNodeId == 3) port = basePortTCP + 2;
- if(localNodeId == 3 && remoteNodeId == 1) port = basePortTCP + 1;
- if(localNodeId == 3 && remoteNodeId == 2) port = basePortTCP + 2;
-
- conf->localNodeId = localNodeId;
- conf->localHostName = localHostName;
- conf->remoteNodeId = remoteNodeId;
- conf->remoteHostName = remoteHostName;
- conf->port = port;
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-void
-createSCITransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName){
-
-
- ndbout << "Creating SCI transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SCI_TransporterConfiguration * conf = (SCI_TransporterConfiguration*)_conf;
-
- conf->remoteSciNodeId0= (Uint16)atoi(localHostName);
- conf->remoteSciNodeId1= (Uint16)atoi(remoteHostName);
-
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-void
-createSHMTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName){
-
-
- ndbout << "Creating SHM transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SHM_TransporterConfiguration * conf = (SHM_TransporterConfiguration*)_conf;
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
diff --git a/storage/ndb/src/common/transporter/buddy.cpp b/storage/ndb/src/common/transporter/buddy.cpp
deleted file mode 100644
index 342ef88a6d2..00000000000
--- a/storage/ndb/src/common/transporter/buddy.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "buddy.hpp"
-
-void Chunk256::setFree(bool free){
- // Bit 0 of allocationTimeStamp represents if the segment is free or not
- Uint32 offMask = 0x0; // A mask to set the 0 bit to 0
- allocationTimeStamp = 0x0;
- if(free)
- // Set this bit to 0, if segment should be free
- allocationTimeStamp = allocationTimeStamp & offMask;
-}
-
-bool Chunk256::getFree(){
- Uint32 offMask = 0x0;
- return ((allocationTimeStamp | offMask) == offMask ? true : false);
-}
-
-void Chunk256::setAllocationTimeStamp(Uint32 cTime){
- // Bits 1-31 of allocationTimeStamp represent the allocation time for segment
-
- // printf("\nSet allocation time. Current time %d", cTime);
- Uint32 onMask = 0x80000000; // A mask to set the 0 bit to 1
- allocationTimeStamp = 0x0;
- allocationTimeStamp = onMask | cTime;
-}
-
-Uint32 Chunk256::getAllocationTimeStamp(){
- Uint32 onMask = 0x80000000;
- allocationTimeStamp = allocationTimeStamp ^ onMask;
- printf("\nGet allocation time. Time is %d", allocationTimeStamp);
- return allocationTimeStamp;
-};
-
-bool BuddyMemory::allocate(int nChunksToAllocate) {
-
- // Allocate the memory block needed. This memory is deallocated in the
- // destructor of TransporterRegistry.
-
- printf("\nAllocating %d chunks...", nChunksToAllocate);
-
- startOfMemoryBlock = (Uint32*) malloc(256 * nChunksToAllocate);
-
- if (startOfMemoryBlock == NULL)
- return false;
-
- // Allocate the array of 256-byte chunks
- chunk = new Chunk256[nChunksToAllocate];
-
- // Initialize the chunk-array. Every 8 kB segment consists of 32 chunks.
- // Set all chunks to free and set the prev and next pointer
- for (int i=0; i < nChunksToAllocate; i++) {
- chunk[i].setFree(true);
- if (i%32 == 0) {
- // The first chunk in every segment will point to the prev and next segment
- chunk[i].prevSegmentOfSameSize = i-32;
- chunk[i].nextSegmentOfSameSize = i + 32;
- chunk[0].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
- chunk[totalNoOfChunks-32].nextSegmentOfSameSize = END_OF_CHUNK_LIST;
- } else {
- // The rest of the chunks in the segments have undefined prev and next pointers
- chunk[i].prevSegmentOfSameSize = UNDEFINED_CHUNK;
- chunk[i].nextSegmentOfSameSize = UNDEFINED_CHUNK;
- }
- }
-
- // Initialize the freeSegment-pointers
- for (int i=0; i<sz_MAX; i++)
- freeSegment[i] = UNDEFINED_CHUNK;
-
- // There are only 8 kB segments at startup
- freeSegment[sz_8192] = 0;
-
- for (int i=0; i<sz_MAX; i++)
- printf("\nPointers: %d", freeSegment[i]);
-
- return true;
-}
-
-
-bool BuddyMemory::getSegment(Uint32 size, Segment * dst) {
-
- // The no of chunks the user asked for
- Uint32 nChunksAskedFor = ceil((double(size)/double(256)));
- int segm;
-
- printf("\n%d chunks asked for", nChunksAskedFor);
-
- // It may be that the closest segment size above
- // nChunksAskedFor*256 is not a size that is available in
- // the freeSegment-list, i.e. it may not be of FreeSegmentSize.
- int nChunksToAllocate = nChunksAskedFor;
-
- // Find the FreeSegmentSize closest above nChunksAskedFor
- if ((nChunksToAllocate != 1) && (nChunksToAllocate % 2 != 0))
- nChunksToAllocate++;
-
- printf("\n%d chunks to allocate", nChunksToAllocate);
- int segmSize = logTwoPlus(nChunksToAllocate) - 1;
- if (size-pow(2,segmSize) > 256)
- segmSize ++;
- printf("\nSegment size: %f", pow(2,int(8+segmSize)));
-
- while ((segmSize <= sz_GET_MAX) && (freeSegment[segmSize] == UNDEFINED_CHUNK))
- segmSize++;
-
- segm = freeSegment[segmSize];
- if (segm != UNDEFINED_CHUNK){
- // Free segment of asked size or larger is found
-
- // Remove the found segment from the freeSegment-list
- removeFromFreeSegmentList(segmSize, segm);
-
- // Set all chunks to allocated (not free) and set the allocation time
- // for the segment we are about to allocate
- for (int i = segm; i <= segm+nChunksToAllocate; i++) {
- chunk[i].setFree(false);
- chunk[i].setAllocationTimeStamp(currentTime);
- }
-
- // Before returning the segment, check if it is larger than the segment asked for
- if (nChunksAskedFor < nChunksToAllocate)
- release(nChunksAskedFor, nChunksToAllocate - nChunksAskedFor - 1);
-
- Segment segment;
- segment.segmentAddress = startOfMemoryBlock+(segm * 256);
- segment.segmentSize = 256 * nChunksAskedFor;
- segment.releaseId = segm;
-
- printf("\nSegment: segment address = %d, segment size = %d, release Id = %d",
- segment.segmentAddress, segment.segmentSize, segment.releaseId);
-
- return true;
- }
- printf("\nNo segments of asked size or larger are found");
- return false;
-}
-
-void BuddyMemory::removeFromFreeSegmentList(int sz, int index) {
- // Remove the segment from the freeSegment list
-
- printf("\nRemoving segment from list...");
- if (index != UNDEFINED_CHUNK) {
- Chunk256 prevChunk;
- Chunk256 nextChunk;
- int prevChunkIndex = chunk[index].prevSegmentOfSameSize;
- int nextChunkIndex = chunk[index].nextSegmentOfSameSize;
-
- if (prevChunkIndex == END_OF_CHUNK_LIST) {
- if (nextChunkIndex == END_OF_CHUNK_LIST)
- // We are about to remove the only element in the list
- freeSegment[sz] = UNDEFINED_CHUNK;
- else {
- // We are about to remove the first element in the list
- nextChunk = chunk[nextChunkIndex];
- nextChunk.prevSegmentOfSameSize = END_OF_CHUNK_LIST;
- freeSegment[sz] = nextChunkIndex;
- }
- } else {
- if (nextChunkIndex == END_OF_CHUNK_LIST) {
- // We are about to remove the last element in the list
- prevChunk = chunk[prevChunkIndex];
- prevChunk.nextSegmentOfSameSize = END_OF_CHUNK_LIST;
- } else {
- // We are about to remove an element in the middle of the list
- prevChunk = chunk[prevChunkIndex];
- nextChunk = chunk[nextChunkIndex];
- prevChunk.nextSegmentOfSameSize = nextChunkIndex;
- nextChunk.prevSegmentOfSameSize = prevChunkIndex;
- }
- }
- }
- for (int i=0; i<sz_MAX; i++)
- printf("\nPointers: %d", freeSegment[i]);
-}
-
-void BuddyMemory::release(int releaseId, int size) {
-
- int nChunksToRelease = (size == 0 ? 1 : ceil(double(size)/double(256)));
- //nChunksToRelease = ceil(double(size)/double(256));
- int startChunk = releaseId;
- int endChunk = releaseId + nChunksToRelease - 1;
-
- printf("\n%d chunks to release (initially)", nChunksToRelease);
-
- // Set the chunks we are about to release to free
- for (int i = startChunk; i <= endChunk; i++){
- chunk[i].setFree(true);
- }
-
- // Look at the chunks before the segment we are about to release
- for (int i = releaseId-1; i >= 0; i--) {
- if (!chunk[i].getFree())
- break;
- else {
- startChunk = i;
- nChunksToRelease++;
- // Look at the next-pointer. If it is valid, we have a
- // chunk that is the start of a free segment. Remove it
- // from the freeSegment-list.
- if (chunk[i].nextSegmentOfSameSize != UNDEFINED_CHUNK)
- removeFromFreeSegmentList(size, i);
- }
- }
-
- // Look at the chunks after the segment we are about to release
- for (int i = endChunk+1; i <= totalNoOfChunks; i++) {
- if (!chunk[i].getFree())
- break;
- else {
- endChunk = i;
- nChunksToRelease++;
- // Look at the next-pointer. If it is valid, we have a
- // chunk that is the start of a free segment. Remove it
- // from the free segment list
- if (chunk[i].nextSegmentOfSameSize != UNDEFINED_CHUNK)
- removeFromFreeSegmentList(size, i);
- }
- }
-
- // We have the start and end indexes and total no of free chunks.
- // Separate the chunks into segments that can be added to the
- // freeSegments-list.
- int restChunk = 0;
- int segmSize;
-
- printf("\n%d chunks to release (finally)", nChunksToRelease);
-
- segmSize = logTwoPlus(nChunksToRelease) - 1;
- if (segmSize > sz_MAX) {
- segmSize = sz_MAX;
- }
-
- nChunksToRelease = pow(2,segmSize);
- addToFreeSegmentList(nChunksToRelease*256, startChunk);
-}
-
-void BuddyMemory::addToFreeSegmentList(int sz, int index) {
- // Add a segment to the freeSegment list
-
- printf("\nAsked to add segment of size %d", sz);
-
- // Get an index in freeSegment list corresponding to sz size
- int segmSize = logTwoPlus(sz) - 1;
- if (sz - pow(2,segmSize) >= 256)
- segmSize ++;
- sz = segmSize - 8;
-
- int nextSegm = freeSegment[sz];
-
- printf("\nAdding a segment of size %f", pow(2,(8 + sz)));
-
- freeSegment[sz] = index;
- if (nextSegm == UNDEFINED_CHUNK) {
- // We are about to add a segment to an empty list
- chunk[index].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
- chunk[index].nextSegmentOfSameSize = END_OF_CHUNK_LIST;
- }
- else {
- // Add the segment first in the list
- chunk[index].prevSegmentOfSameSize = END_OF_CHUNK_LIST;
- chunk[index].nextSegmentOfSameSize = nextSegm;
- chunk[nextSegm].prevSegmentOfSameSize = index;
- }
-
- for (int i=0; i<sz_MAX; i++)
- printf("\nPointers: %d", freeSegment[i]);
-
-}
-
-Uint32 BuddyMemory::logTwoPlus(Uint32 arg) {
- // Calculate log2(arg) + 1
-
- Uint32 resValue;
-
- arg = arg | (arg >> 8);
- arg = arg | (arg >> 4);
- arg = arg | (arg >> 2);
- arg = arg | (arg >> 1);
- resValue = (arg & 0x5555) + ((arg >> 1) & 0x5555);
- resValue = (resValue & 0x3333) + ((resValue >> 2) & 0x3333);
- resValue = resValue + (resValue >> 4);
- resValue = (resValue & 0xf) + ((resValue >> 8) & 0xf);
-
- return resValue;
-}
-
-bool BuddyMemory::memoryAvailable() {
- // Return true if there is at least 8 kB memory available
- for (int i = sz_8192; i < sz_MAX; i++)
- if (freeSegment[i] != UNDEFINED_CHUNK)
- return true;
- return false;
-}
-
-
-void BuddyMemory::refreshTime(Uint32 time) {
- if (time - currentTime > 1000) {
- // Update current time
- currentTime = time;
- // Go through the chunk-list every second and release
- // any chunks that have been allocated for too long
- for (int i=0; i<totalNoOfChunks; i++) {
- if ((!chunk[i].getFree()) &&
- (currentTime-chunk[i].getAllocationTimeStamp() > ALLOCATION_TIMEOUT)) {
- release(i, 256);
- printf("\nChunks hve been allocated for too long");
- }
- }
- }
-}
diff --git a/storage/ndb/src/common/transporter/buddy.hpp b/storage/ndb/src/common/transporter/buddy.hpp
deleted file mode 100644
index 2494a874f92..00000000000
--- a/storage/ndb/src/common/transporter/buddy.hpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef BUDDY_H
-#define BUDDY_H
-
-#include <ndb_global.h>
-
-typedef unsigned int Uint32;
-typedef unsigned short Uint16;
-typedef unsigned long long Uint64;
-
-//
-const int UNDEFINED_CHUNK = -2; // XXX Set to hex
-
-//
-const int END_OF_CHUNK_LIST = -1; // XXX Set to hex
-
-// A timeout (no of seconds) for the memory segments in the TransporterRegistry
-// memory pool. If a segment has been occupied (free=false) for a longer period
-// than this timeout, it will be released.
-const int ALLOCATION_TIMEOUT = 10000;
-
-// Free segments should always be as large as possible
-// and are only allowed to be in any of these sizes
-enum FreeSegmentSize {
- sz_256 = 0,
- sz_512 = 1,
- sz_1024 = 2,
- sz_2048 = 3,
- sz_4096 = 4,
- sz_8192 = 5,
- sz_16384 = 6,
- sz_32768 = 7,
- sz_65536 = 8,
- sz_131072 = 9,
- sz_GET_MAX = 5,
- sz_MAX = 9
-};
-
-struct Segment;
-
-class BuddyMemory {
-public:
-
- // Return true if there is at least 8 kB memory available
- bool memoryAvailable();
-
- //
- bool allocate(int nChunksToAllocate);
-
- // Remove the segment from the freeSegment list
- void removeFromFreeSegmentList(int sz, int index);
-
- // Release the segment of size
- void release(int releaseId, int size);
-
- // Add a segment to the freeSegment list
- void addToFreeSegmentList(int sz, int index);
-
- bool getSegment(Uint32 size, Segment * dst);
-
- void refreshTime(Uint32 time);
-
- //Calculate log2(arg) + 1
- Uint32 logTwoPlus(Uint32 arg);
-
- // The current time
- Uint32 currentTime;
-
- // Pointer to the first free segment of size FreeSegmentSize
- Uint32 freeSegment[sz_MAX];
-
- // Start address of the memory block allocated
- Uint32* startOfMemoryBlock;
-
- // Total number of 256 byte chunks.
- Uint32 totalNoOfChunks;
-
- // Array of 256-byte chunks
- struct Chunk256* chunk;
-};
-
-struct Segment {
- Uint32 segmentSize; // Size of the segment in no of words
- Uint16 index; // Index in the array of SegmentListElements
- Uint16 releaseId; // Unique no used when releasing the segment
- // Undefined if Long_signal.deallocIndicator==0
- union {
- Uint32* segmentAddress; // Address to the memory segment
- Uint64 _padding_NOT_TO_BE_USED_;
- };
-};
-
-struct Chunk256 {
- Uint32 allocationTimeStamp; // Bit 0 represents if the segment is free or not
- // Bit 1-31 is the allocation time for the segment
- // Bit 1-31 are undefined if the segment is free
- Uint32 nextSegmentOfSameSize; // Undefined if allocated.
- // The first chunk in a free segment has a valid
- // next-pointer. In the rest of the chunks
- // belonging to the segment it is UNDEFINED_CHUNK.
- Uint32 prevSegmentOfSameSize; // Undefined if allocated
- // The first chunk in a free segment has a valid
- // prev-pointer. In the rest of the chunks
- // belonging to the segment it is UNDEFINED_CHUNK.
-
- void setFree(bool free);
-
- bool getFree();
-
- void setAllocationTimeStamp(Uint32 cTime);
-
- Uint32 getAllocationTimeStamp();
-};
-
-// inline void Chunk256::setFree(bool free){
-// // Bit 0 of allocationTimeStamp represents if the segment is free or not
-// allocationTimeStamp = 0x0;
-
-// printf("\nSet free segment");
-// Uint32 offMask = 0x0; // A mask to set the 0 bit to 0
-// if(free)
-// // Set this bit to 0, if segment should be free
-// allocationTimeStamp = allocationTimeStamp & offMask;
-// }
-
-// inline bool Chunk256::getFree(){
-// // Get free segment
-
-// allocationTimeStamp = 0x0;
-// Uint32 offMask = 0x0;
-
-// printf("\nGet free segment");
-// return ((allocationTimeStamp | offMask) == offMask ? true : false);
-// }
-
-// inline void Chunk256::setAllocationTimeStamp(Uint32 cTime){
-// // Bits 1-31 of allocationTimeStamp represent the allocation time for segment
-
-// Uint32 onMask = 0x80000000; // A mask to set the 0 bit to 1
-// allocationTimeStamp = 0x0;
-
-// printf("\nSet allocation time");
-
-// allocationTimeStamp = onMask | cTime;
-// }
-
-// inline Uint32 Chunk256::getAllocationTimeStamp(){
-
-// Uint32 onMask = 0x80000000; // A mask to set the 0 bit to 1
-// allocationTimeStamp = 0x0;
-
-// printf("\nGet allocation time");
-// allocationTimeStamp = allocationTimeStamp ^ onMask;
-// return allocationTimeStamp;
-// };
-
-#endif
diff --git a/storage/ndb/src/common/transporter/failoverSCI/Makefile b/storage/ndb/src/common/transporter/failoverSCI/Makefile
deleted file mode 100644
index 1e3d5f4a4b7..00000000000
--- a/storage/ndb/src/common/transporter/failoverSCI/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := failoverSCI
-BIN_TARGET_LIBS := sisci
-BIN_TARGET_ARCHIVES := portlib
-
-CCFLAGS_LOC += -I..
-
-SOURCES = failoverSCI.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp b/storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp
deleted file mode 100644
index b32c839c3b4..00000000000
--- a/storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp
+++ /dev/null
@@ -1,863 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "sisci_types.h"
-#include "sisci_api.h"
-#include "sisci_error.h"
-//#include "sisci_demolib.h"
-#include <NdbTick.h>
-#include <NdbSleep.h>
-#define NO_CALLBACK NULL
-#define NO_FLAGS 0
-#define DATA_TRANSFER_READY 8
-
-sci_error_t error;
-sci_desc_t sdOne;
-sci_desc_t sdTwo;
-sci_local_segment_t localSegmentOne;
-sci_local_segment_t localSegmentTwo;
-sci_remote_segment_t remoteSegmentOne;
-sci_remote_segment_t remoteSegmentTwo;
-sci_map_t localMapOne;
-sci_map_t localMapTwo;
-sci_map_t remoteMapOne;
-sci_map_t remoteMapTwo;
-unsigned int localAdapterNo = 0;
-unsigned int standbyAdapterNo = 1;
-unsigned int localNodeId1;
-unsigned int localNodeId2;
-unsigned int remoteNodeId1 = 0;
-unsigned int remoteNodeId2 = 0;
-unsigned int localSegmentId;
-unsigned int remoteSegmentId1;
-unsigned int remoteSegmentId2;
-unsigned int segmentSize = 8192;
-unsigned int offset = 0;
-unsigned int client = 0;
-unsigned int server = 0;
-unsigned int *localbufferPtr;
-static int data;
-static int interruptConnected=0;
-
-/*********************************************************************************/
-/* U S A G E */
-/* */
-/*********************************************************************************/
-
-void Usage()
-{
- printf("Usage of shmem\n");
- printf("shmem -rn <remote node-id> -client/server [ -adapterno <adapter no> -size <segment size> ] \n\n");
- printf(" -rn : Remote node-id\n");
- printf(" -client : The local node is client\n");
- printf(" -server : The local node is server\n");
- printf(" -adapterno : Local adapter number (default %d)\n", localAdapterNo);
- printf(" -size : Segment block size (default %d)\n", segmentSize);
- printf(" -help : This helpscreen\n");
-
- printf("\n");
-}
-
-
-/*********************************************************************************/
-/* P R I N T P A R A M E T E R S */
-/* */
-/*********************************************************************************/
-void PrintParameters(void)
-{
-
- printf("Test parameters for %s \n",(client) ? "client" : "server" );
- printf("----------------------------\n\n");
- printf("Local node-id1 : %d\n",localNodeId1);
- printf("Local node-id2 : %d\n",localNodeId2);
- // printf("Remote node-id : %d\n",remoteNodeId);
- printf("Local adapter no. : %d\n",localAdapterNo);
- printf("Segment size : %d\n",segmentSize);
- printf("----------------------------\n\n");
-
-}
-
-
-/*********************************************************************************/
-/* F I L L S E G M E N T W I T H D A T A */
-/* */
-/*********************************************************************************/
-
-sci_error_t GetLocalNodeId(Uint32 localAdapterNo, Uint32* localNodeId)
-{
- sci_query_adapter_t queryAdapter;
- sci_error_t error;
- unsigned int _localNodeId;
-
- queryAdapter.subcommand = SCI_Q_ADAPTER_NODEID;
- queryAdapter.localAdapterNo = localAdapterNo;
- queryAdapter.data = &_localNodeId;
-
- SCIQuery(SCI_Q_ADAPTER,&queryAdapter,NO_FLAGS,&error);
-
- *localNodeId=_localNodeId;
-
- return error;
-}
-
-
-
-
-
-
-sci_error_t SendInterrupt(sci_desc_t sd,
- Uint32 localAdapterNo,
- Uint32 localSciNodeId,
- Uint32 remoteSciNodeId,
- Uint32 interruptNo){
-
- sci_error_t error;
- sci_remote_interrupt_t remoteInterrupt;
- Uint32 timeOut = SCI_INFINITE_TIMEOUT;
-
- // Now connect to the other sides interrupt flag
- do {
- SCIConnectInterrupt(sd, &remoteInterrupt, remoteSciNodeId, localAdapterNo,
- interruptNo, timeOut, NO_FLAGS, &error);
- } while (error != SCI_ERR_OK);
-
- if (error != SCI_ERR_OK) {
- fprintf(stderr, "SCIConnectInterrupt failed - Error code 0x%x\n", error);
- return error;
- }
-
- // Trigger interrupt
- printf("\nNode %u sent interrupt (0x%x) to node %d\n",localSciNodeId, interruptNo, remoteSciNodeId);
- SCITriggerInterrupt(remoteInterrupt, NO_FLAGS, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr, "SCITriggerInterrupt failed - Error code 0x%x\n", error);
- return error;
- }
-
-
- // Disconnect and remove interrupts
- SCIDisconnectInterrupt(remoteInterrupt, NO_FLAGS, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr, "SCIDisconnectInterrupt failed - Error code 0x%x\n", error);
- return error;
- }
-
- return error;
-}
-
-
-sci_error_t ReceiveInterrupt(sci_desc_t sd,
- Uint32 localAdapterNo,
- Uint32 localSciNodeId,
- Uint32 interruptNo,
- Uint32 timeout) {
-
- sci_error_t error;
- sci_local_interrupt_t localInterrupt;
- Uint32 timeOut = SCI_INFINITE_TIMEOUT;
-
- // Create an interrupt
- SCICreateInterrupt(sd, &localInterrupt, localAdapterNo,
- &interruptNo, 0, NULL, SCI_FLAG_FIXED_INTNO, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr, "SCICreateInterrupt failed - Error code 0x%x\n", error);
- return error;
- }
-
-
- // Wait for an interrupt
- SCIWaitForInterrupt(localInterrupt, timeOut, NO_FLAGS, &error);
-
- printf("\nNode %u received interrupt (0x%x)\n", localSciNodeId, interruptNo);
-
- // Remove interrupt
-
- SCIRemoveInterrupt(localInterrupt, NO_FLAGS, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr, "SCIRemoveInterrupt failed - Error code 0x%x\n", error);
- return error;
- }
- return error;
-}
-
-
-sci_error_t FillSegmentWithData(unsigned int segmentSize, int reverse)
-{
- unsigned int i;
- unsigned int nostores;
-
-
- nostores = (segmentSize) / sizeof(unsigned int);
-
- /* Allocate buffer */
-
- localbufferPtr = (unsigned int*)malloc( segmentSize );
- if ( localbufferPtr == NULL ) {
- /*
- * Unable to create local buffer - Insufficient memory available
- */
- return SCI_ERR_NOSPC;
- }
- if(reverse) {
- /* Fill in the data into a local buffer */
- printf("Filling forward order \n");
- for (i=0;i<nostores;i++) {
- localbufferPtr[i] = i;
- }
- }
- else {
- int temp=nostores;
- printf("Filling reverse order \n");
- for (i=0;i<nostores;i++) {
- localbufferPtr[i] = temp-- ;
-
- }
-
- }
-
- return SCI_ERR_OK;
-}
-
-
-
-
-/*********************************************************************************/
-/* P R I N T C L I E N T D A T A */
-/* */
-/*********************************************************************************/
-
-void PrintClientData(void)
-{
- unsigned int i;
-
- printf("\nClient data: ");
- /* Print the first 20 entries in the segment */
- for (i=0;i<20;i++) {
- printf("%d ",localbufferPtr[i]);
- }
-
- printf("\n");
-}
-
-
-/*********************************************************************************/
-/* P R I N T S E R V E R D A T A */
-/* */
-/*********************************************************************************/
-
-void PrintServerData(volatile unsigned int *localMapAddr)
-{
-
- unsigned int *buffer;
- int i;
-
- // printf("\nServer data: ");
- buffer = (unsigned int *)localMapAddr;
-
- /* Print the first 20 entries in the segment */
- for (i=0; i< 20; i++) {
-
- printf("%d ",buffer[i]);
- }
- printf("\n");
-
-}
-
-
-
-/*********************************************************************************/
-/* T R A N S F E R D A T A */
-/* */
-/*********************************************************************************/
-
-unsigned int TransferData(sci_map_t remoteMap,
- volatile unsigned int *remoteSegmentAddr1,
- volatile unsigned int *remoteSegmentAddr2,
- unsigned int segmentSize)
-
-{
-
- volatile unsigned int *remoteBuffer1;
- volatile unsigned int *remoteBuffer;
- volatile unsigned int *remoteBuffer2;
- static int times = 0;
- sci_sequence_t sequence;
- sci_error_t error;
- unsigned int nostores;
- unsigned int j;
- sci_sequence_status_t sequenceStatus;
-
-
- remoteBuffer1 = (volatile unsigned int *)remoteSegmentAddr1;
- remoteBuffer2 = (volatile unsigned int *)remoteSegmentAddr2;
- remoteBuffer=remoteBuffer1;
-
- /* 4-byte test only */
- nostores = (segmentSize) / sizeof(unsigned int);
-
- /* Create a sequence for data error checking */
- SCICreateMapSequence(remoteMapOne,&sequence,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCICreateMapSequence failed - Error code 0x%x\n",error);
- return error;
- }
-
-
-
- /* Fill in the data into a local buffer */
- error = SendInterrupt(sdOne,localAdapterNo,localNodeId1,remoteNodeId1, DATA_TRANSFER_READY);
-
- error = FillSegmentWithData(segmentSize, 0);
-
- tryagain:
- PrintServerData(localbufferPtr);
- fprintf(stderr,"After recover \n");
- while(1){
-
-
- //data=0;
-
- if (error != SCI_ERR_OK) {
- /*
- * Unable to create local buffer - Insufficient memory available
- */
- printf( "Unable to create local buffer - Insufficient memory available\n" );
-
- return error;
- }
-
- do {
- /* Start data error checking */
- sequenceStatus = SCIStartSequence(sequence,NO_FLAGS,&error);
- } while (sequenceStatus != SCI_SEQ_OK) ;
-
-
- /* Transfer data to remote node */
- for (j=0;j<nostores;j++) {
- remoteBuffer[j] = localbufferPtr[j];
- }
-
- /* Check for error after data transfer */
- sequenceStatus = SCICheckSequence(sequence,NO_FLAGS,&error);
- if (sequenceStatus != SCI_SEQ_OK) {
- fprintf(stderr,"Data transfer failed\n");
- if(times==0) {
- error = FillSegmentWithData(segmentSize, 1);
-
- SCICreateMapSequence(remoteMapTwo,&sequence,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCICreateMapSequence failed - Error code 0x%x\n",error);
- return error;
- return SCI_ERR_TRANSFER_FAILED;
- }
- }
- else
- {
- error = FillSegmentWithData(segmentSize, 0);
- /* Create a sequence for data error checking */
- SCICreateMapSequence(remoteMapOne,&sequence,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCICreateMapSequence failed - Error code 0x%x\n",error);
- return error;
- return SCI_ERR_TRANSFER_FAILED;
- }
-
- }
- fprintf(stderr,"Recovery \n");
- if(times==0)
- remoteBuffer=remoteBuffer2;
- else
- remoteBuffer=remoteBuffer1;
- times++;
- printf("remotebuffer %p times %d\n", remoteBuffer, times);
- goto tryagain;
-
- }
- int timeout=0;
- // error = SendInterrupt(sdOne,localAdapterNo,localNodeId1,remoteNodeId1, DATA_TRANSFER_READY);
- // NdbSleep_MilliSleep(100);
- //error = ReceiveInterrupt(sdOne,localAdapterNo,localNodeId1,DATA_TRANSFER_READY, timeout);
-
- }
- /* Remove the Sequence */
- SCIRemoveSequence(sequence,NO_FLAGS, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCIRemoveSequence failed - Error code 0x%x\n",error);
- return error;
- }
-
- return SCI_ERR_OK;
-}
-
-
-/*********************************************************************************/
-/* S H M E M C L I E N T N O D E */
-/* */
-/*********************************************************************************/
-
-unsigned int ShmemClientNode(void)
-{
-
- volatile unsigned int *remoteMapAddr1;
- volatile unsigned int *remoteMapAddr2;
- printf("here?\n");
-
-
- /* Create a segmentId */
- remoteSegmentId1 = 1;//(remoteNodeId1 << 16) | localNodeId1;
-
- /* Connect to remote segment */
-
- printf("Connect to remote segment .... \n");
- printf("segid = %d node %d \n",remoteSegmentId1, remoteNodeId1 );
-
- do {
- SCIConnectSegment(sdOne,
- &remoteSegmentOne,
- remoteNodeId1,
- remoteSegmentId1,
- localAdapterNo,
- NO_CALLBACK,
- NULL,
- SCI_INFINITE_TIMEOUT,
- NO_FLAGS,
- &error);
-
- } while (error != SCI_ERR_OK);
-
-
- printf("connected\n");
-
- // remoteSegmentId2 = (remoteNodeId2 << 16) | localNodeId2;
- // printf("segid = %d\n",remoteSegmentId2 );
- printf("segid = %d node %d \n",remoteSegmentId1, remoteNodeId1 );
- do {
- SCIConnectSegment(sdTwo,
- &remoteSegmentTwo,
- remoteNodeId2,
- remoteSegmentId1,
- standbyAdapterNo,
- NO_CALLBACK,
- NULL,
- SCI_INFINITE_TIMEOUT,
- NO_FLAGS,
- &error);
-
- } while (error != SCI_ERR_OK);
-
-
-
- printf("connected 3\n");
- printf("Remote segment (id=0x%x) is connected.\n", remoteSegmentId2);
-
-
- /* Map remote segment to user space */
- remoteMapAddr1 = (unsigned int*)SCIMapRemoteSegment(remoteSegmentOne,&remoteMapOne,offset,segmentSize,NULL,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Remote segment (id=0x%x) is mapped to user space @ 0x%x. \n", remoteSegmentId1, remoteMapAddr1);
- } else {
- fprintf(stderr,"SCIMapRemoteSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- remoteMapAddr2 = (unsigned int *)SCIMapRemoteSegment(remoteSegmentTwo,&remoteMapTwo,offset,segmentSize,NULL,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Remote segment (id=0x%x) is mapped to user space @ 0x%x. \n", remoteSegmentId2, remoteMapAddr2);
- } else {
- fprintf(stderr,"SCIMapRemoteSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- /* Start data transfer and error checking */
- error = (sci_error_t)TransferData(remoteMapOne,remoteMapAddr1, remoteMapAddr2,segmentSize);
- if (error == SCI_ERR_OK) {
- printf("Data transfer done!\n\n");
- } else {
- fprintf(stderr,"Data transfer failed - Error code 0x%x\n\n",error);
- return 0;
- }
-
- /* Send an interrupt to remote node telling that the data transfer is ready */
- error = SendInterrupt(sdOne,localAdapterNo,localNodeId1,remoteNodeId1, DATA_TRANSFER_READY);
- if (error == SCI_ERR_OK) {
- printf("\nInterrupt message sent to remote node\n");
- } else {
- printf("\nInterrupt synchronization failed\n");
- return 0;
- }
-
- PrintClientData();
-
- /* Unmap remote segment */
- SCIUnmapSegment(remoteMapOne,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The remote segment is unmapped\n");
- } else {
- fprintf(stderr,"SCIUnmapSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- SCIUnmapSegment(remoteMapTwo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The remote segment is unmapped\n");
- } else {
- fprintf(stderr,"SCIUnmapSegment failed - Error code 0x%x\n",error);
- return 0;
- }
- /* Disconnect segment */
- SCIDisconnectSegment(remoteSegmentOne,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The segment is disconnected\n");
- } else {
- fprintf(stderr,"SCIDisconnectSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- SCIDisconnectSegment(remoteSegmentTwo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The segment is disconnected\n");
- } else {
- fprintf(stderr,"SCIDisconnectSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- return 1;
-}
-
-
-/*********************************************************************************/
-/* S H M E M S E R V E R N O D E */
-/* */
-/*********************************************************************************/
-
-unsigned int ShmemServerNode(void)
-{
-
- unsigned int *localMapAddr;
-
- /* Create a segmentId */
- localSegmentId =1;// (localNodeId1 << 16) | remoteNodeId1;
-
- /* Create local segment */
- SCICreateSegment(sdOne,&localSegmentOne,localSegmentId, segmentSize, NO_CALLBACK, NULL, NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=%d, size=%d) is created. \n", localSegmentId, segmentSize);
- } else {
- fprintf(stderr,"SCICreateSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- //localSegmentId = (localNodeId2 << 16) | remoteNodeId2;
- /*
- SCICreateSegment(sdTwo,&localSegmentTwo,localSegmentId+1, segmentSize, NO_CALLBACK, NULL, NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=%d, size=%d) is created (2). \n", localSegmentId, segmentSize);
- } else {
- fprintf(stderr,"SCICreateSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- printf("segment one %p segment 2 %p\n", localSegmentOne, localSegmentTwo);
- */
- /* Prepare the segment */
- SCIPrepareSegment(localSegmentOne,localAdapterNo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=%d, size=%d) is prepared. \n", localSegmentId, segmentSize);
- } else {
- fprintf(stderr,"SCIPrepareSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- /* Prepare the segment */
-
- SCIPrepareSegment(localSegmentOne,standbyAdapterNo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=%d, size=%d) is created. \n", localSegmentId, segmentSize);
- } else {
- fprintf(stderr,"SCIPrepareSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- /* Map local segment to user space */
- localMapAddr = (unsigned int *)SCIMapLocalSegment(localSegmentOne,&localMapOne, offset,segmentSize, NULL,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=0x%x) is mapped to user space @ 0x%x.\n", localSegmentId, localMapAddr);
- } else {
- fprintf(stderr,"SCIMapLocalSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- /* Map local segment to user space */
- /*
- localMapAddr = (unsigned int *)SCIMapLocalSegment(localSegmentTwo,&localMapTwo, offset,segmentSize, NULL,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=0x%x) is mapped to user space @ 0x%x.\n", localSegmentId, localMapAddr);
- printf("Local segment (id=%d) is mapped to user space.\n", localSegmentId);
- } else {
- fprintf(stderr,"SCIMapLocalSegment failed - Error code 0x%x\n",error);
- return 0;
- }
- */
-
- /* Set the segment available */
- SCISetSegmentAvailable(localSegmentOne, localAdapterNo, NO_FLAGS, &error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=0x%x) is available for remote connections. \n", localSegmentId);
- } else {
- fprintf(stderr,"SCISetSegmentAvailable failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
- SCISetSegmentAvailable(localSegmentOne, standbyAdapterNo, NO_FLAGS, &error);
- if (error == SCI_ERR_OK) {
- printf("Local segment (id=0x%x) is available for remote connections. \n", localSegmentId);
- } else {
- fprintf(stderr,"SCISetSegmentAvailable failed - Error code 0x%x\n",error);
- return 0;
- }
- int timeout=0;
- error = ReceiveInterrupt(sdOne,localAdapterNo,localNodeId1,DATA_TRANSFER_READY, timeout);
-
- if (error == SCI_ERR_OK) {
- printf("\nThe data transfer is ready\n");
- } else {
- printf("\nInterrupt synchronization failed\n");
- return 0;
- }
-
-
- again:
-
- // printf("Wait for the shared memory data transfer .....");
- /* Wait for interrupt signal telling that block transfer is ready */
-
- //printf("\nData transfer done!\n");
- //PrintClientData()
- PrintServerData(localMapAddr);
- /*Uint32 micros;
- Uint32 micros2;
- NDB_TICKS secs;
- NdbTick_CurrentMicrosecond(&secs, &micros);
- error = SendInterrupt(sdOne,localAdapterNo,localNodeId1,remoteNodeId1, DATA_TRANSFER_READY);
- NdbTick_CurrentMicrosecond(&secs, &micros2);
- printf("TIME ELAPSED %d \n", micros2-micros);
-// NdbSleep_MilliSleep(100);
- */
- goto again;
-
- /* Unmap local segment */
- SCIUnmapSegment(localMapTwo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The local segment is unmapped\n");
- } else {
- fprintf(stderr,"SCIUnmapSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- /* Unmap local segment */
- SCIUnmapSegment(localMapOne,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The local segment is unmapped\n");
- } else {
- fprintf(stderr,"SCIUnmapSegment failed - Error code 0x%x\n",error);
- return 0;
- }
- /* Remove local segment */
- SCIRemoveSegment(localSegmentOne,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The local segment is removed\n");
- } else {
- fprintf(stderr,"SCIRemoveSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
- /* Remove local segment */
- SCIRemoveSegment(localSegmentTwo,NO_FLAGS,&error);
- if (error == SCI_ERR_OK) {
- printf("The local segment is removed\n");
- } else {
- fprintf(stderr,"SCIRemoveSegment failed - Error code 0x%x\n",error);
- return 0;
- }
-
-
-
-
- return 1;
-}
-
-
-
-/*********************************************************************************/
-/* M A I N */
-/* */
-/*********************************************************************************/
-
-int main(int argc,char *argv[])
-{
-
- int counter;
-
- printf("\n %s compiled %s : %s\n\n",argv[0],__DATE__,__TIME__);
-
- if (argc<3) {
- Usage();
- exit(-1);
- }
-
-
- /* Get the parameters */
- for (counter=1; counter<argc; counter++) {
-
- if (!strcmp("-rn",argv[counter])) {
- // remoteNodeId = strtol(argv[counter+1],(char **) NULL,10);
- continue;
- }
-
- if (!strcmp("-size",argv[counter])) {
- segmentSize = strtol(argv[counter+1],(char **) NULL,10);
- continue;
- }
-
- if (!strcmp("-adapterno",argv[counter])) {
- localAdapterNo = strtol(argv[counter+1],(char **) NULL,10);
- continue;
- }
-
- if (!strcmp("-client",argv[counter])) {
- client = 1;
- continue;
- }
-
- if (!strcmp("-server",argv[counter])) {
- server = 1;
- continue;
- }
-
- if (!strcmp("-help",argv[counter])) {
- Usage();
- exit(0);
- }
- }
-
- // if (remoteNodeId == 0) {
- // fprintf(stderr,"Remote node-id is not specified. Use -rn <remote node-id>\n");
- // exit(-1);
- //}
-
- if (server == 0 && client == 0) {
- fprintf(stderr,"You must specify a client node or a server node\n");
- exit(-1);
- }
-
- if (server == 1 && client == 1) {
- fprintf(stderr,"Both server node and client node is selected.\n");
- fprintf(stderr,"You must specify either a client or a server node\n");
- exit(-1);
- }
-
-
- /* Initialize the SISCI library */
- SCIInitialize(NO_FLAGS, &error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCIInitialize failed - Error code: 0x%x\n",error);
- exit(error);
- }
-
-
- /* Open a file descriptor */
- SCIOpen(&sdOne,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- if (error == SCI_ERR_INCONSISTENT_VERSIONS) {
- fprintf(stderr,"Version mismatch between SISCI user library and SISCI driver\n");
- }
- fprintf(stderr,"SCIOpen failed - Error code 0x%x\n",error);
- exit(error);
- }
-
- /* Open a file descriptor */
- SCIOpen(&sdTwo,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- if (error == SCI_ERR_INCONSISTENT_VERSIONS) {
- fprintf(stderr,"Version mismatch between SISCI user library and SISCI driver\n");
- }
- fprintf(stderr,"SCIOpen failed - Error code 0x%x\n",error);
- exit(error);
- }
-
-
- /* Get local node-id */
- error = GetLocalNodeId(localAdapterNo, &localNodeId1);
- error = GetLocalNodeId(standbyAdapterNo, &localNodeId2);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"Could not find the local adapter %d\n", localAdapterNo);
- SCIClose(sdOne,NO_FLAGS,&error);
- SCIClose(sdTwo,NO_FLAGS,&error);
- exit(-1);
- }
-
-
- /* Print parameters */
- PrintParameters();
-
- if (client) {
- remoteNodeId1=324;
- remoteNodeId2=328;
- ShmemClientNode();
- } else {
- remoteNodeId1=452;
- remoteNodeId2=456;
- ShmemServerNode();
- }
-
- /* Close the file descriptor */
- SCIClose(sdOne,NO_FLAGS,&error);
- SCIClose(sdTwo,NO_FLAGS,&error);
- if (error != SCI_ERR_OK) {
- fprintf(stderr,"SCIClose failed - Error code: 0x%x\n",error);
- }
-
-
- /* Free allocated resources */
- SCITerminate();
-
- return SCI_ERR_OK;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/perftest/Makefile b/storage/ndb/src/common/transporter/perftest/Makefile
deleted file mode 100644
index 01869e1acf9..00000000000
--- a/storage/ndb/src/common/transporter/perftest/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := perfTransporterTest
-BIN_TARGET_ARCHIVES := transporter portlib general
-
-SOURCES = perfTransporterTest.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp b/storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp
deleted file mode 100644
index 3aca596ea70..00000000000
--- a/storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp
+++ /dev/null
@@ -1,712 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "TransporterRegistry.hpp"
-#include "TransporterDefinitions.hpp"
-#include "TransporterCallback.hpp"
-#include <RefConvert.hpp>
-
-#include <NdbTick.h>
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-
-int basePortTCP = 17000;
-
-SCI_TransporterConfiguration sciTemplate = {
- 2000,
- // Packet size
- 2000000, // Buffer size
- 2, // number of adapters
- 1, // remote node id SCI
- 2, // Remote node Id SCI
- 0, // local ndb node id (server)
- 0, // remote ndb node id (client)
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-
-SHM_TransporterConfiguration shmTemplate = {
- 0, //remoteNodeId
- 0, //localNodeId;
- false, //compression
- true, //checksum;
- true, //signalId;
- 0, //byteOrder;
- 123, //shmKey;
- 25000000 //shmSize;
-};
-
-
-TCP_TransporterConfiguration tcpTemplate = {
- 17000, // port;
- "", // remoteHostName;
- "", // localhostname
- 2, // remoteNodeId;
- 1, // localNodeId;
- 25000000, // sendBufferSize - Size of SendBuffer of priority B
- 5000000, // maxReceiveSize - Maximum no of bytes to receive
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-TransporterRegistry *tReg = 0;
-
-#include <signal.h>
-
-extern "C"
-void
-signalHandler(int signo){
- ::signal(13, signalHandler);
- char buf[255];
- sprintf(buf,"Signal: %d\n", signo);
- ndbout << buf << endl;
-}
-
-void
-usage(const char * progName){
- ndbout << "Usage: " << progName << " <type> localNodeId localHostName"
- << " remoteHostName"
- << " [<loop count>] [<send buf size>] [<recv buf size>]" << endl;
- ndbout << " type = shm tcp ose sci" << endl;
- ndbout << " localNodeId - {1,2}" << endl;
-}
-
-typedef void (* CreateTransporterFunc)(void * conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendBuf,
- int recvBuf);
-
-void
-createTCPTransporter(void*, NodeId, NodeId, const char*, const char*, int, int);
-void
-createSHMTransporter(void*, NodeId, NodeId, const char*, const char*, int, int);
-void
-createSCITransporter(void*, NodeId, NodeId, const char*, const char*, int, int);
-
-struct TestPhase {
- int signalSize;
- int noOfSignals;
- int noOfSignalSent;
- int noOfSignalReceived;
- NDB_TICKS startTime;
- NDB_TICKS stopTime;
- NDB_TICKS accTime;
- int loopCount;
- Uint64 sendLenBytes, sendCount;
- Uint64 recvLenBytes, recvCount;
-};
-
-TestPhase testSpec[] = {
- { 1, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 1, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 1, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 1, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 8, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 8, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 8, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 8, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 16, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 16, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 16, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 16, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 24, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 24, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 24, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 24, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 0, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of random size
- ,{ 0, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of random size
- ,{ 0, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of random size
- ,{ 0, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of random size
-
- ,{ 100, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals
- ,{ 100, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals
- ,{ 100, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals
- ,{ 100, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals
-
- ,{ 500, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals
- ,{ 500, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals
- ,{ 500, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals
- ,{ 500, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals
-
- ,{ 1000, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals
- ,{ 1000, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals
- ,{ 1000, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals
- ,{ 1000, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals
-};
-
-const int noOfTests = sizeof(testSpec)/sizeof(TestPhase);
-
-Uint32 StaticBuffer[1000];
-
-SendStatus
-sendSignalTo(NodeId nodeId, int signalSize, Uint32 count){
- if(signalSize == 0)
- signalSize = (rand() % 25) + 1;
-
- SignalHeader sh;
- sh.theLength = (signalSize > 25 ? 25 : signalSize);
- sh.theVerId_signalNumber = count;
- sh.theReceiversBlockNumber = rand();
- sh.theSendersBlockRef = rand();
- sh.theSendersSignalId = rand();
- sh.theSignalId = rand();
- sh.theTrace = rand();
-
- Uint32 theData[25];
- for(int i = 0; i<25; i++)
- theData[i] = (i+1) * (Uint32)(&theData[i]);
-
- theData[0] = count;
- LinearSectionPtr ptr[3];
-
- if(signalSize <= 25){
- sh.m_noOfSections = 0;
- } else {
- sh.m_noOfSections = 1;
- ptr[0].sz = signalSize - 25;
- ptr[0].p = &StaticBuffer[0];
- }
-
- return tReg->prepareSend(&sh, 1, theData, nodeId, ptr);
-}
-
-void
-reportHeader(){
- ndbout << "#Sigs\tSz\tTime\tSig/sec\tBps\tBps-tot\t"
- << "s len\tr len" << endl;
-}
-
-void
-print(char * dst, int i){
- if(i > 1000000){
- const int d = i / 1000000;
- const int r = (i - (d * 1000000)) / 100000;
- if(d < 100)
- sprintf(dst, "%d.%dM", d, r);
- else
- sprintf(dst, "%dM", d);
- } else if(i > 1000){
- const int d = i / 1000;
- const int r = (i - (d * 1000)) / 100;
- if(d < 100)
- sprintf(dst, "%d.%dk", d, r);
- else
- sprintf(dst, "%dk", d);
- } else {
- sprintf(dst, "%d", i);
- }
-}
-
-void
-printReport(TestPhase & p){
- if(p.accTime > 0) {
- Uint32 secs = (p.accTime/p.loopCount)/1000;
- Uint32 mill = (p.accTime/p.loopCount)%1000;
- char st[255];
- if(secs > 0){
- sprintf(st, "%d.%.2ds", secs, (mill/10));
- } else {
- sprintf(st, "%dms", mill);
- }
-
- Uint32 sps = (1000*p.noOfSignals*p.loopCount)/p.accTime;
- Uint32 dps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*p.signalSize);
- Uint32 bps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(p.signalSize+3));
- if(p.signalSize == 0){
- dps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(13));
- bps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(13+3));
- }
- char ssps[255];
- char sbps[255];
- char sdps[255];
-
- print(ssps, sps);
- print(sbps, bps);
- print(sdps, dps);
-
-
- char buf[255];
- if(p.signalSize != 0){
- BaseString::snprintf(buf, 255,
- "%d\t%d\t%s\t%s\t%s\t%s\t%d\t%d",
- p.noOfSignals,
- 4*p.signalSize,
- st,
- ssps,
- sdps,
- sbps,
- (int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
- (int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)));
- } else {
- BaseString::snprintf(buf, 255,
- "%d\trand\t%s\t%s\t%s\t%s\t%d\t%d",
- p.noOfSignals,
- st,
- ssps,
- sdps,
- sbps,
- (int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
- (int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)));
-
- }
- ndbout << buf << endl;
- }
-}
-
-int loopCount = 1;
-int sendBufSz = -1;
-int recvBufSz = -1;
-
-bool isClient = false;
-bool isConnected = false;
-bool isStarted = false;
-int currentPhase = 0;
-TestPhase allPhases[noOfTests];
-Uint32 signalToEcho;
-Uint32 signalsEchoed;
-NDB_TICKS startTime, stopTime;
-
-void
-client(NodeId remoteNodeId){
- isClient = true;
-
- currentPhase = 0;
- memcpy(allPhases, testSpec, sizeof(testSpec));
-
- int counter = 0;
- int sigCounter = 0;
-
- while(true){
- TestPhase * current = &allPhases[currentPhase];
- if(current->noOfSignals == current->noOfSignalSent &&
- current->noOfSignals == current->noOfSignalReceived){
-
- /**
- * Test phase done
- */
- current->stopTime = NdbTick_CurrentMillisecond();
- current->accTime += (current->stopTime - current->startTime);
-
- NdbSleep_MilliSleep(500 / loopCount);
-
- current->startTime = NdbTick_CurrentMillisecond();
-
- current->noOfSignalSent = 0;
- current->noOfSignalReceived = 0;
-
- current->loopCount ++;
- if(current->loopCount == loopCount){
-
- printReport(allPhases[currentPhase]);
-
- currentPhase ++;
- if(currentPhase == noOfTests){
- /**
- * Now we are done
- */
- break;
- }
- NdbSleep_MilliSleep(500);
- current = &allPhases[currentPhase];
- current->startTime = NdbTick_CurrentMillisecond();
- }
- }
-
- int signalsLeft = current->noOfSignals - current->noOfSignalSent;
- if(signalsLeft > 0){
- for(; signalsLeft > 0; signalsLeft--){
- if(sendSignalTo(remoteNodeId,current->signalSize,sigCounter)== SEND_OK){
- current->noOfSignalSent++;
- sigCounter++;
- } else {
- ndbout << "Failed to send: " << sigCounter << endl;
- tReg->external_IO(10);
- break;
- }
- }
- }
- if(counter % 10 == 0)
- tReg->checkConnections();
- tReg->external_IO(0);
- counter++;
- }
-}
-
-void
-server(){
- isClient = false;
-
- signalToEcho = 0;
- signalsEchoed = 0;
- for(int i = 0; i<noOfTests; i++)
- signalToEcho += testSpec[i].noOfSignals;
-
- signalToEcho *= loopCount;
-
- while(signalToEcho > signalsEchoed){
- tReg->checkConnections();
- for(int i = 0; i<10; i++)
- tReg->external_IO(10);
- }
-}
-
-int
-main(int argc, const char **argv){
-
- const char * progName = argv[0];
-
- loopCount = 100;
- sendBufSz = -1;
- recvBufSz = -1;
-
- isClient = false;
- isConnected = false;
- isStarted = false;
- currentPhase = 0;
-
- signalHandler(0);
-
- if(argc < 5){
- usage(progName);
- return 0;
- }
-
- const char * type = argv[1];
- const NodeId localNodeId = atoi(argv[2]);
- const char * localHostName = argv[3];
- const char * remoteHost1 = argv[4];
-
- if(argc >= 6)
- loopCount = atoi(argv[5]);
- if(argc >= 7)
- sendBufSz = atoi(argv[6]);
- if(argc >= 8)
- recvBufSz = atoi(argv[7]);
-
- if(localNodeId < 1 || localNodeId > 2){
- ndbout << "localNodeId = " << localNodeId << endl << endl;
- usage(progName);
- return 0;
- }
-
- if(localNodeId == 1)
- ndbout << "-- ECHO CLIENT --" << endl;
- else
- ndbout << "-- ECHO SERVER --" << endl;
-
- ndbout << "localNodeId: " << localNodeId << endl;
- ndbout << "localHostName: " << localHostName << endl;
- ndbout << "remoteHost1 (node " << (localNodeId == 1?2:1) << "): "
- << remoteHost1 << endl;
- ndbout << "Loop count: " << loopCount << endl;
- ndbout << "-----------------" << endl;
-
- void * confTemplate = 0;
- CreateTransporterFunc func = 0;
- if(strcasecmp(type, "tcp") == 0){
- func = createTCPTransporter;
- confTemplate = &tcpTemplate;
- } else if(strcasecmp(type, "sci") == 0){
- func = createSCITransporter;
- confTemplate = &sciTemplate;
- } else if(strcasecmp(type, "shm") == 0){
- func = createSHMTransporter;
- confTemplate = &shmTemplate;
- } else {
- ndbout << "Unsupported transporter type" << endl;
- return 0;
- }
-
- ndbout << "Creating transporter registry" << endl;
- tReg = new TransporterRegistry;
- tReg->init(localNodeId);
-
- switch(localNodeId){
- case 1:
- (* func)(confTemplate, 1, 2, localHostName, remoteHost1,
- sendBufSz, recvBufSz);
- break;
- case 2:
- (* func)(confTemplate, 2, 1, localHostName, remoteHost1,
- sendBufSz, recvBufSz);
- break;
- }
-
- ndbout << "Doing startSending/startReceiving" << endl;
- tReg->startSending();
- tReg->startReceiving();
-
- ndbout << "Connecting" << endl;
- tReg->setPerformState(PerformConnect);
- tReg->checkConnections();
-
- if(localNodeId == 1)
- client(2);
- else
- server();
-
- isStarted = false;
-
- ndbout << "Sleep 3 secs" << endl;
- NdbSleep_SecSleep(3);
-
- ndbout << "Doing setPerformState(Disconnect)" << endl;
- tReg->setPerformState(PerformDisconnect);
-
- ndbout << "Doing checkConnections()" << endl;
- tReg->checkConnections();
-
- ndbout << "Deleting transporter registry" << endl;
- delete tReg; tReg = 0;
-
- return 0;
-}
-
-void
-execute(void* callbackObj, SignalHeader * const header, Uint8 prio,
- Uint32 * const theData,
- LinearSectionPtr ptr[3]){
- const NodeId nodeId = refToNode(header->theSendersBlockRef);
-
- if(isClient){
- allPhases[currentPhase].noOfSignalReceived++;
- } else {
- int sleepTime = 10;
- if(theData[0] != signalsEchoed){
- ndbout << "Missing signal theData[0] = " << theData[0]
- << " signalsEchoed = " << signalsEchoed << endl;
- ndbout << (* header) << endl;
- abort();
- }
- while(tReg->prepareSend(header, prio, theData, nodeId, ptr) != SEND_OK){
- ndbout << "Failed to echo " << theData[0] << endl;
- NdbSleep_MilliSleep(sleepTime);
- // sleepTime += 10;
- }
- signalsEchoed++;
- }
-}
-
-void
-copy(Uint32 * & insertPtr,
- class SectionSegmentPool & thePool, const SegmentedSectionPtr & _ptr){
- abort();
-}
-
-void
-reportError(void* callbackObj, NodeId nodeId, TransporterError errorCode){
- char buf[255];
- sprintf(buf, "reportError (%d, %x) in perfTest", nodeId, errorCode);
- ndbout << buf << endl;
- if(errorCode & 0x8000 && errorCode != 0x8014){
- abort(); //tReg->setPerformState(nodeId, PerformDisconnect);
- }
-}
-
-/**
- * Report average send theLength in bytes (4096 last sends)
- */
-void
-reportSendLen(void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
- allPhases[currentPhase].sendCount += count;
- allPhases[currentPhase].sendLenBytes += bytes;
-
- if(!isClient){
- ndbout << "reportSendLen(" << nodeId << ", "
- << (bytes/count) << ")" << endl;
- }
-}
-
-/**
- * Report average receive theLength in bytes (4096 last receives)
- */
-void
-reportReceiveLen(void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
- allPhases[currentPhase].recvCount += count;
- allPhases[currentPhase].recvLenBytes += bytes;
-
- if(!isClient){
- ndbout << "reportReceiveLen(" << nodeId << ", "
- << (bytes/count) << ")" << endl;
- }
-}
-
-/**
- * Report connection established
- */
-void
-reportConnect(void* callbackObj, NodeId nodeId){
- char buf[255];
- sprintf(buf, "reportConnect(%d)", nodeId);
- ndbout << buf << endl;
- tReg->setPerformState(nodeId, PerformIO);
-
- if(!isStarted){
- isStarted = true;
- startTime = NdbTick_CurrentMillisecond();
- if(isClient){
- reportHeader();
- allPhases[0].startTime = startTime;
- }
- }
- else{
- // Resend signals that were lost when connection failed
- TestPhase * current = &allPhases[currentPhase];
- current->noOfSignalSent = current->noOfSignalReceived;
- }
-}
-
-/**
- * Report connection broken
- */
-void
-reportDisconnect(void* callbackObj, NodeId nodeId, Uint32 errNo){
- char buf[255];
- sprintf(buf, "reportDisconnect(%d)", nodeId);
- ndbout << buf << endl;
-
- if(isStarted)
- tReg->setPerformState(nodeId, PerformConnect);
-}
-
-
-int
-checkJobBuffer() {
- /**
- * Check to see if jobbbuffers are starting to get full
- * and if so call doJob
- */
- return 0;
-}
-
-void
-createSCITransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendbuf,
- int recvbuf) {
-
-
- ndbout << "Creating SCI transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SCI_TransporterConfiguration * conf = (SCI_TransporterConfiguration*)_conf;
-
- conf->remoteSciNodeId0= (Uint16)atoi(localHostName);
- conf->remoteSciNodeId1= (Uint16)atoi(remoteHostName);
-
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-void
-createSHMTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendbuf,
- int recvbuf) {
-
-
- ndbout << "Creating SHM transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SHM_TransporterConfiguration * conf = (SHM_TransporterConfiguration*)_conf;
-
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-
-void
-createTCPTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendBuf,
- int recvBuf){
- ndbout << "Creating TCP transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
- TCP_TransporterConfiguration * conf = (TCP_TransporterConfiguration*)_conf;
-
- int port;
- if(localNodeId == 1 && remoteNodeId == 2) port = basePortTCP + 0;
- if(localNodeId == 1 && remoteNodeId == 3) port = basePortTCP + 1;
- if(localNodeId == 2 && remoteNodeId == 1) port = basePortTCP + 0;
- if(localNodeId == 2 && remoteNodeId == 3) port = basePortTCP + 2;
- if(localNodeId == 3 && remoteNodeId == 1) port = basePortTCP + 1;
- if(localNodeId == 3 && remoteNodeId == 2) port = basePortTCP + 2;
-
- if(sendBuf != -1){
- conf->sendBufferSize = sendBuf;
- }
- if(recvBuf != -1){
- conf->maxReceiveSize = recvBuf;
- }
-
- ndbout << "\tSendBufferSize: " << conf->sendBufferSize << endl;
- ndbout << "\tReceiveBufferSize: " << conf->maxReceiveSize << endl;
-
- conf->localNodeId = localNodeId;
- conf->localHostName = localHostName;
- conf->remoteNodeId = remoteNodeId;
- conf->remoteHostName = remoteHostName;
- conf->port = port;
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
diff --git a/storage/ndb/src/common/transporter/priotest/Makefile b/storage/ndb/src/common/transporter/priotest/Makefile
deleted file mode 100644
index 483fc0f1f07..00000000000
--- a/storage/ndb/src/common/transporter/priotest/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-SOURCES = prioTransporterTest.cpp
-ARCHIVE_TARGET := libpriotransportertest.a
-
-DIRS := prioTCP prioSHM prioSCI
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioSCI/Makefile b/storage/ndb/src/common/transporter/priotest/prioSCI/Makefile
deleted file mode 100644
index 7d403539bf3..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioSCI/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-BIN_TARGET := prioSCI
-BIN_TARGET_LIBS := sisci
-BIN_TARGET_ARCHIVES := priotransportertest transporter portlib general
-
-CCFLAGS_LOC += -I..
-
-SOURCES = prioSCI.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp b/storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp
deleted file mode 100644
index 2d8ee8de979..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <prioTransporterTest.hpp>
-#include <NdbMain.h>
-
-NDB_COMMAND(prioSCI, "prioSCI", "prioSCI", "Test the SCI Transporter", 65535)
-{
- basePortTCP = 17000;
- return prioTransporterTest(TestSCI, "prioSCI", argc, argv);
-}
-
-
-
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioSHM/Makefile b/storage/ndb/src/common/transporter/priotest/prioSHM/Makefile
deleted file mode 100644
index a827c6e3f1e..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioSHM/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := prioSHM
-BIN_TARGET_ARCHIVES := priotransportertest transporter portlib general
-
-CCFLAGS_LOC += -I..
-
-SOURCES = prioSHM.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp b/storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp
deleted file mode 100644
index 4447576987b..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <prioTransporterTest.hpp>
-#include <NdbMain.h>
-
-NDB_COMMAND(prioSHM, "prioSHM", "prioSHM", "Test the SHM Transporter", 65535)
-{
- basePortTCP = 17000;
- return prioTransporterTest(TestSHM, "prioSHM", argc, argv);
-}
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioTCP/Makefile b/storage/ndb/src/common/transporter/priotest/prioTCP/Makefile
deleted file mode 100644
index 92abf3e7424..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioTCP/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := prioTCP
-BIN_TARGET_ARCHIVES := priotransportertest transporter portlib general
-
-CCFLAGS_LOC += -I..
-
-SOURCES = prioTCP.cpp
-
-include $(NDB_TOP)/Epilogue.mk
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp b/storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp
deleted file mode 100644
index ddd549b9818..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <prioTransporterTest.hpp>
-#include <NdbMain.h>
-
-NDB_COMMAND(prioTCP, "prioTCP", "prioTCP", "Test the TCP Transporter", 65535)
-{
- basePortTCP = 17000;
- return prioTransporterTest(TestTCP, "prioTCP", argc, argv);
-}
-
diff --git a/storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp b/storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp
deleted file mode 100644
index 581bc88ac83..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp
+++ /dev/null
@@ -1,708 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "TransporterRegistry.hpp"
-#include "TransporterDefinitions.hpp"
-#include "TransporterCallback.hpp"
-#include <RefConvert.hpp>
-
-#include "prioTransporterTest.hpp"
-
-#include <NdbTick.h>
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-
-int basePortTCP = 17000;
-
-SCI_TransporterConfiguration sciTemplate = {
- 2000,
- // Packet size
- 2000000, // Buffer size
- 2, // number of adapters
- 1, // remote node id SCI
- 2, // Remote node Id SCI
- 0, // local ndb node id (server)
- 0, // remote ndb node id (client)
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-
-SHM_TransporterConfiguration shmTemplate = {
- 100000, // shmSize
- 0, // shmKey
- 1, // local ndb node id (server)
- 2, // remote ndb node id (client)
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-TCP_TransporterConfiguration tcpTemplate = {
- 17000, // port;
- "", // remoteHostName;
- "", // localhostname
- 2, // remoteNodeId;
- 1, // localNodeId;
- 2000000, // sendBufferSize - Size of SendBuffer of priority B
- 2000, // maxReceiveSize - Maximum no of bytes to receive
- 0, // byteOrder;
- false, // compression;
- true, // checksum;
- true // signalId;
-};
-
-TransporterRegistry *tReg = 0;
-
-#include <signal.h>
-
-extern "C"
-void
-signalHandler(int signo){
- ::signal(13, signalHandler);
- char buf[255];
- sprintf(buf,"Signal: %d\n", signo);
- ndbout << buf << endl;
-}
-
-void
-usage(const char * progName){
- ndbout << "Usage: " << progName << " localNodeId localHostName"
- << " remoteHostName"
- << " [<loop count>] [<send buf size>] [<recv buf size>]" << endl;
- ndbout << " localNodeId - {1,2}" << endl;
-}
-
-typedef void (* CreateTransporterFunc)(void * conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendBuf,
- int recvBuf);
-
-void
-createSCITransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendbuf,
- int recvbuf) {
-
-
- ndbout << "Creating SCI transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SCI_TransporterConfiguration * conf = (SCI_TransporterConfiguration*)_conf;
-
- conf->remoteSciNodeId0= (Uint16)atoi(localHostName);
- conf->remoteSciNodeId1= (Uint16)atoi(remoteHostName);
-
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-void
-createSHMTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendbuf,
- int recvbuf) {
-
-
- ndbout << "Creating SHM transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
-
- SHM_TransporterConfiguration * conf = (SHM_TransporterConfiguration*)_conf;
-
-
- conf->localNodeId = localNodeId;
- conf->remoteNodeId = remoteNodeId;
-
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-
-void
-createTCPTransporter(void * _conf,
- NodeId localNodeId,
- NodeId remoteNodeId,
- const char * localHostName,
- const char * remoteHostName,
- int sendBuf,
- int recvBuf){
- ndbout << "Creating TCP transporter from node "
- << localNodeId << "(" << localHostName << ") to "
- << remoteNodeId << "(" << remoteHostName << ")..." << endl;;
-
- TCP_TransporterConfiguration * conf = (TCP_TransporterConfiguration*)_conf;
-
- int port;
- if(localNodeId == 1 && remoteNodeId == 2) port = basePortTCP + 0;
- if(localNodeId == 1 && remoteNodeId == 3) port = basePortTCP + 1;
- if(localNodeId == 2 && remoteNodeId == 1) port = basePortTCP + 0;
- if(localNodeId == 2 && remoteNodeId == 3) port = basePortTCP + 2;
- if(localNodeId == 3 && remoteNodeId == 1) port = basePortTCP + 1;
- if(localNodeId == 3 && remoteNodeId == 2) port = basePortTCP + 2;
-
- if(sendBuf != -1){
- conf->sendBufferSize = sendBuf;
- }
- if(recvBuf != -1){
- conf->maxReceiveSize = recvBuf;
- }
-
- ndbout << "\tSendBufferSize: " << conf->sendBufferSize << endl;
- ndbout << "\tReceiveBufferSize: " << conf->maxReceiveSize << endl;
-
- conf->localNodeId = localNodeId;
- conf->localHostName = localHostName;
- conf->remoteNodeId = remoteNodeId;
- conf->remoteHostName = remoteHostName;
- conf->port = port;
- bool res = tReg->createTransporter(conf);
- if(res)
- ndbout << "... -- Success " << endl;
- else
- ndbout << "... -- Failure " << endl;
-}
-
-struct TestPhase {
- int signalSize;
- int noOfSignals;
- int noOfSignalSent;
- int noOfSignalReceived;
- NDB_TICKS startTime;
- NDB_TICKS stopTime;
-
- NDB_TICKS startTimePrioA;
- NDB_TICKS stopTimePrioA;
- NDB_TICKS totTimePrioA;
- int bytesSentBeforePrioA;
- NDB_TICKS accTime;
- int loopCount;
- Uint64 sendLenBytes, sendCount;
- Uint64 recvLenBytes, recvCount;
-};
-
-TestPhase testSpec[] = {
- { 1, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 1, 10000, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 1, 10000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 1, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 8, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 8, 10000, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 8, 10000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 8, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 16, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 16, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 16, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 16, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 24, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of size 1 word
- ,{ 24, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of size 1 word
- ,{ 24, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of size 1 word
- ,{ 24, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of size 1 word
-
- ,{ 0, 10, 0,0, 0,0,0,0,0,0,0 } // 10 signals of random size
- ,{ 0, 100, 0,0, 0,0,0,0,0,0,0 } // 100 signals of random size
- ,{ 0, 1000, 0,0, 0,0,0,0,0,0,0 } // 1000 signals of random size
- ,{ 0, 10000, 0,0, 0,0,0,0,0,0,0 } // 10000 signals of random size
-};
-
-const int noOfTests = sizeof(testSpec)/sizeof(TestPhase);
-
-SendStatus
-sendSignalTo(NodeId nodeId, int signalSize, int prio){
- if(signalSize == 0)
- signalSize = (rand() % 25) + 1;
-
- SignalHeader sh;
- sh.theLength = signalSize;
- sh.theVerId_signalNumber = rand();
- sh.theReceiversBlockNumber = rand();
- sh.theSendersBlockRef = rand();
- sh.theSendersSignalId = rand();
- sh.theSignalId = rand();
- sh.theTrace = rand();
-
- Uint32 theData[25];
- for(int i = 0; i<signalSize; i++)
- theData[i] = (i+1) * (Uint32)(&theData[i]);
-
- return tReg->prepareSend(&sh, prio, theData, nodeId);
-}
-
-void
-reportHeader(){
- ndbout << "#Sigs\tSz\tPayload\tTime\tSig/sec\tBps\t"
- << "s len\tr len\tprioAtime\tbytesb4pA" << endl;
-}
-
-void
-printReport(TestPhase & p){
- if(p.accTime > 0) {
- Uint32 secs = (p.accTime/p.loopCount)/1000;
- Uint32 mill = (p.accTime/p.loopCount)%1000;
- char st[255];
- if(secs > 0){
- sprintf(st, "%d.%.2ds", secs, (mill/10));
- } else {
- sprintf(st, "%dms", mill);
- }
-
- Uint32 sps = (1000*p.noOfSignals*p.loopCount)/p.accTime;
- Uint32 bps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(p.signalSize+3));
- if(p.signalSize == 0)
- ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(13+3));
-
- char ssps[255];
- if(sps > 1000000){
- sps /= 1000000;
- sprintf(ssps, "%dM", (int)sps);
- } else if(sps > 1000){
- sps /= 1000;
- sprintf(ssps, "%dk", (int)sps);
- } else {
- sprintf(ssps, "%d", (int)sps);
- }
-
- char sbps[255];
- if(bps > 1000000){
- bps /= 1000000;
- sprintf(sbps, "%dM", bps);
- } else if(bps>1000){
- bps /= 1000;
- sprintf(sbps, "%dk", bps);
- } else {
- sprintf(sbps, "%d", bps);
- }
-
- char buf[255];
- if(p.signalSize != 0){
- BaseString::snprintf(buf, 255,
- "%d\t%d\t%d\t%s\t%s\t%s\t%d\t%d\t%d\t%d",
- p.noOfSignals,
- p.signalSize,
- (4*p.signalSize),
- st,
- ssps,
- sbps,
- (int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
- (int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)),
- (int)(p.totTimePrioA / p.loopCount),
- (int)(p.bytesSentBeforePrioA));
- } else {
- BaseString::snprintf(buf, 255,
- "%d\trand\t4*rand\t%s\t%s\t%s\t%d\t%d\t%d\t%d",
- p.noOfSignals,
- st,
- ssps,
- sbps,
- (int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
- (int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)),
- (int)(p.totTimePrioA / p.loopCount),
- (int)(p.bytesSentBeforePrioA));
-
- }
- ndbout << buf << endl;
- }
-}
-
-int loopCount = 1;
-int sendBufSz = -1;
-int recvBufSz = -1;
-
-NDB_TICKS startSec=0;
-NDB_TICKS stopSec=0;
-Uint32 startMicro=0;
-Uint32 stopMicro=0;
-int timerStarted;
-int timerStopped;
-
-bool isClient = false;
-bool isConnected = false;
-bool isStarted = false;
-int currentPhase = 0;
-TestPhase allPhases[noOfTests];
-Uint32 signalToEcho;
-NDB_TICKS startTime, stopTime;
-
-void
-client(NodeId remoteNodeId){
- isClient = true;
-
- currentPhase = 0;
- memcpy(allPhases, testSpec, sizeof(testSpec));
-
- int counter = 0;
-
- while(true){
- TestPhase * current = &allPhases[currentPhase];
- if(current->noOfSignals == current->noOfSignalSent &&
- current->noOfSignals == current->noOfSignalReceived){
-
- /**
- * Test phase done
- */
- current->stopTime = NdbTick_CurrentMillisecond();
- current->accTime += (current->stopTime - current->startTime);
-
- NdbSleep_MilliSleep(500 / loopCount);
-
- current->startTime = NdbTick_CurrentMillisecond();
-
- current->noOfSignalSent = 0;
- current->noOfSignalReceived = 0;
-
- current->loopCount ++;
- if(current->loopCount == loopCount){
-
- printReport(allPhases[currentPhase]);
-
- currentPhase ++;
- if(currentPhase == noOfTests){
- /**
- * Now we are done
- */
- break;
- }
- NdbSleep_MilliSleep(500);
- current = &allPhases[currentPhase];
- current->startTime = NdbTick_CurrentMillisecond();
- }
- }
- int signalsLeft = current->noOfSignals - current->noOfSignalSent;
- if(signalsLeft > 0){
- for(; signalsLeft > 1; signalsLeft--){
- if(sendSignalTo(remoteNodeId, current->signalSize, 1) == SEND_OK) {
- current->noOfSignalSent++;
- // ndbout << "sent prio b" << endl;
- current->bytesSentBeforePrioA += (current->signalSize << 2);
- }
- else {
- tReg->external_IO(10);
- break;
- }
- }
- //prio A
- if(signalsLeft==1) {
- NDB_TICKS sec = 0;
- Uint32 micro=0;
- int ret = NdbTick_CurrentMicrosecond(&sec,&micro);
- if(ret==0)
- current->startTimePrioA = micro + sec*1000000;
- if(sendSignalTo(remoteNodeId, current->signalSize, 0) == SEND_OK) {
- current->noOfSignalSent++;
- signalsLeft--;
- }
- else {
- tReg->external_IO(10);
- break;
- }
- }
- }
-
- if(counter % 10 == 0)
- tReg->checkConnections();
- tReg->external_IO(0);
- counter++;
- }
-}
-
-void
-server(){
- isClient = false;
-
- signalToEcho = 0;
- for(int i = 0; i<noOfTests; i++)
- signalToEcho += testSpec[i].noOfSignals;
-
- signalToEcho *= loopCount;
-
- while(signalToEcho > 0){
- tReg->checkConnections();
- for(int i = 0; i<10; i++)
- tReg->external_IO(10);
- }
-}
-
-int
-prioTransporterTest(TestType tt, const char * progName,
- int argc, const char **argv){
-
- loopCount = 100;
- sendBufSz = -1;
- recvBufSz = -1;
-
- isClient = false;
- isConnected = false;
- isStarted = false;
- currentPhase = 0;
-
- signalHandler(0);
-
- if(argc < 4){
- usage(progName);
- return 0;
- }
-
- const NodeId localNodeId = atoi(argv[1]);
- const char * localHostName = argv[2];
- const char * remoteHost1 = argv[3];
-
- if(argc >= 5)
- loopCount = atoi(argv[4]);
- if(argc >= 6)
- sendBufSz = atoi(argv[5]);
- if(argc >= 7)
- recvBufSz = atoi(argv[6]);
-
- if(localNodeId < 1 || localNodeId > 2){
- ndbout << "localNodeId = " << localNodeId << endl << endl;
- usage(progName);
- return 0;
- }
-
- if(localNodeId == 1)
- ndbout << "-- ECHO CLIENT --" << endl;
- else
- ndbout << "-- ECHO SERVER --" << endl;
-
- ndbout << "localNodeId: " << localNodeId << endl;
- ndbout << "localHostName: " << localHostName << endl;
- ndbout << "remoteHost1 (node " << (localNodeId == 1?2:1) << "): "
- << remoteHost1 << endl;
- ndbout << "Loop count: " << loopCount << endl;
- ndbout << "-----------------" << endl;
-
- void * confTemplate = 0;
- CreateTransporterFunc func = 0;
- switch(tt){
- case TestTCP:
- func = createTCPTransporter;
- confTemplate = &tcpTemplate;
- break;
- case TestSCI:
- func = createSCITransporter;
- confTemplate = &sciTemplate;
- break;
- case TestSHM:
- func = createSHMTransporter;
- confTemplate = &shmTemplate;
- break;
- default:
- ndbout << "Unsupported transporter type" << endl;
- return 0;
- }
-
- ndbout << "Creating transporter registry" << endl;
- tReg = new TransporterRegistry;
- tReg->init(localNodeId);
-
- switch(localNodeId){
- case 1:
- (* func)(confTemplate, 1, 2, localHostName, remoteHost1,
- sendBufSz, recvBufSz);
- break;
- case 2:
- (* func)(confTemplate, 2, 1, localHostName, remoteHost1,
- sendBufSz, recvBufSz);
- break;
- }
-
- ndbout << "Doing startSending/startReceiving" << endl;
- tReg->startSending();
- tReg->startReceiving();
-
- ndbout << "Connecting" << endl;
- tReg->setPerformState(PerformConnect);
- tReg->checkConnections();
-
- if(localNodeId == 1)
- client(2);
- else
- server();
-
- isStarted = false;
-
- ndbout << "Sleep 3 secs" << endl;
- NdbSleep_SecSleep(3);
-
- ndbout << "Doing setPerformState(Disconnect)" << endl;
- tReg->setPerformState(PerformDisconnect);
-
- ndbout << "Doing checkConnections()" << endl;
- tReg->checkConnections();
-
- ndbout << "Deleting transporter registry" << endl;
- delete tReg; tReg = 0;
-
- return 0;
-}
-
-NdbOut & operator <<(NdbOut & out, SignalHeader & sh){
- out << "-- Signal Header --" << endl;
- out << "theLength: " << sh.theLength << endl;
- out << "gsn: " << sh.theVerId_signalNumber << endl;
- out << "recBlockNo: " << sh.theReceiversBlockNumber << endl;
- out << "sendBlockRef: " << sh.theSendersBlockRef << endl;
- out << "sendersSig: " << sh.theSendersSignalId << endl;
- out << "theSignalId: " << sh.theSignalId << endl;
- out << "trace: " << (int)sh.theTrace << endl;
- return out;
-}
-
-void
-execute(SignalHeader * const header, Uint8 prio, Uint32 * const theData){
- const NodeId nodeId = refToNode(header->theSendersBlockRef);
- NDB_TICKS sec = 0;
- Uint32 micro=0;
- int ret = NdbTick_CurrentMicrosecond(&sec,&micro);
- if(prio == 0 && isClient && ret == 0) {
- allPhases[currentPhase].stopTimePrioA = micro + sec*1000000;
- allPhases[currentPhase].totTimePrioA +=
- allPhases[currentPhase].stopTimePrioA -
- allPhases[currentPhase].startTimePrioA;
- }
- if(ret!=0)
- allPhases[currentPhase].totTimePrioA = -1;
-
- if(isClient){
- allPhases[currentPhase].noOfSignalReceived++;
- } else {
- int sleepTime = 10;
- while(tReg->prepareSend(header, prio, theData, nodeId) != SEND_OK){
- ndbout << "Failed to echo" << sleepTime << endl;
- NdbSleep_MilliSleep(sleepTime);
- // sleepTime += 10;
- }
-
- signalToEcho--;
- }
-}
-
-void
-reportError(NodeId nodeId, TransporterError errorCode){
- char buf[255];
- sprintf(buf, "reportError (%d, %x) in perfTest", nodeId, errorCode);
- ndbout << buf << endl;
- if(errorCode & 0x8000){
- tReg->setPerformState(nodeId, PerformDisconnect);
- }
-}
-
-/**
- * Report average send theLength in bytes (4096 last sends)
- */
-void
-reportSendLen(NodeId nodeId, Uint32 count, Uint64 bytes){
- allPhases[currentPhase].sendCount += count;
- allPhases[currentPhase].sendLenBytes += bytes;
-
- if(!isClient){
- ndbout << "reportSendLen(" << nodeId << ", "
- << (bytes/count) << ")" << endl;
- }
-}
-
-/**
- * Report average receive theLength in bytes (4096 last receives)
- */
-void
-reportReceiveLen(NodeId nodeId, Uint32 count, Uint64 bytes){
- allPhases[currentPhase].recvCount += count;
- allPhases[currentPhase].recvLenBytes += bytes;
-
- if(!isClient){
- ndbout << "reportReceiveLen(" << nodeId << ", "
- << (bytes/count) << ")" << endl;
- }
-}
-
-/**
- * Report connection established
- */
-void
-reportConnect(NodeId nodeId){
- char buf[255];
- sprintf(buf, "reportConnect(%d)", nodeId);
- ndbout << buf << endl;
- tReg->setPerformState(nodeId, PerformIO);
-
- if(!isStarted){
- isStarted = true;
- startTime = NdbTick_CurrentMillisecond();
- if(isClient){
- reportHeader();
- allPhases[0].startTime = startTime;
- }
- }
- else{
- // Resend signals that were lost when connection failed
- TestPhase * current = &allPhases[currentPhase];
- current->noOfSignalSent = current->noOfSignalReceived;
- }
-}
-
-/**
- * Report connection broken
- */
-void
-reportDisconnect(NodeId nodeId, Uint32 errNo){
- char buf[255];
- sprintf(buf, "reportDisconnect(%d)", nodeId);
- ndbout << buf << endl;
-
- if(isStarted)
- tReg->setPerformState(nodeId, PerformConnect);
-}
-
-
-int
-checkJobBuffer() {
- /**
- * Check to see if jobbbuffers are starting to get full
- * and if so call doJob
- */
- return 0;
-}
diff --git a/storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp b/storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp
deleted file mode 100644
index 518367b69ef..00000000000
--- a/storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef PRIO_TRANSPORTER_TEST_HPP
-#define PRIO_TRANSPORTER_TEST_HPP
-
-
-enum TestType {
- TestTCP,
- TestSCI,
- TestSHM
-};
-
-extern int basePortTCP;
-
-int prioTransporterTest(TestType tt, const char * pName,
- int argc, const char **argv);
-
-
-
-#endif
diff --git a/storage/ndb/src/common/util/BaseString.cpp b/storage/ndb/src/common/util/BaseString.cpp
deleted file mode 100644
index 019906c9ec6..00000000000
--- a/storage/ndb/src/common/util/BaseString.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/* -*- c-basic-offset: 4; -*- */
-#include <ndb_global.h>
-#include <BaseString.hpp>
-#include "basestring_vsnprintf.h"
-
-BaseString::BaseString()
-{
- m_chr = new char[1];
- if (m_chr == NULL)
- {
- errno = ENOMEM;
- m_len = 0;
- return;
- }
- m_chr[0] = 0;
- m_len = 0;
-}
-
-BaseString::BaseString(const char* s)
-{
- if (s == NULL)
- {
- m_chr = NULL;
- m_len = 0;
- }
- const size_t n = strlen(s);
- m_chr = new char[n + 1];
- if (m_chr == NULL)
- {
- errno = ENOMEM;
- m_len = 0;
- return;
- }
- memcpy(m_chr, s, n + 1);
- m_len = n;
-}
-
-BaseString::BaseString(const BaseString& str)
-{
- const char* const s = str.m_chr;
- const size_t n = str.m_len;
- if (s == NULL)
- {
- m_chr = NULL;
- m_len = 0;
- return;
- }
- char* t = new char[n + 1];
- if (t == NULL)
- {
- errno = ENOMEM;
- m_chr = NULL;
- m_len = 0;
- return;
- }
- memcpy(t, s, n + 1);
- m_chr = t;
- m_len = n;
-}
-
-BaseString::~BaseString()
-{
- delete[] m_chr;
-}
-
-BaseString&
-BaseString::assign(const char* s)
-{
- if (s == NULL)
- {
- m_chr = NULL;
- m_len = 0;
- return *this;
- }
- size_t n = strlen(s);
- char* t = new char[n + 1];
- if (t)
- {
- memcpy(t, s, n + 1);
- }
- else
- {
- errno = ENOMEM;
- n = 0;
- }
- delete[] m_chr;
- m_chr = t;
- m_len = n;
- return *this;
-}
-
-BaseString&
-BaseString::assign(const char* s, size_t n)
-{
- char* t = new char[n + 1];
- if (t)
- {
- memcpy(t, s, n);
- t[n] = 0;
- }
- else
- {
- errno = ENOMEM;
- n = 0;
- }
- delete[] m_chr;
- m_chr = t;
- m_len = n;
- return *this;
-}
-
-BaseString&
-BaseString::assign(const BaseString& str, size_t n)
-{
- if (n > str.m_len)
- n = str.m_len;
- return assign(str.m_chr, n);
-}
-
-BaseString&
-BaseString::append(const char* s)
-{
- size_t n = strlen(s);
- char* t = new char[m_len + n + 1];
- if (t)
- {
- memcpy(t, m_chr, m_len);
- memcpy(t + m_len, s, n + 1);
- }
- else
- {
- errno = ENOMEM;
- m_len = 0;
- n = 0;
- }
- delete[] m_chr;
- m_chr = t;
- m_len += n;
- return *this;
-}
-
-BaseString&
-BaseString::append(char c) {
- return appfmt("%c", c);
-}
-
-BaseString&
-BaseString::append(const BaseString& str)
-{
- return append(str.m_chr);
-}
-
-BaseString&
-BaseString::append(const Vector<BaseString> &vector,
- const BaseString &separator) {
- for(size_t i=0;i<vector.size(); i++) {
- append(vector[i]);
- if(i<vector.size()-1)
- append(separator);
- }
- return *this;
-}
-
-BaseString&
-BaseString::assfmt(const char *fmt, ...)
-{
- char buf[1];
- va_list ap;
- int l;
-
- /* Figure out how long the formatted string will be. A small temporary
- * buffer is used, because I don't trust all implementations to work
- * when called as vsnprintf(NULL, 0, ...).
- */
- va_start(ap, fmt);
- l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
- va_end(ap);
- if(l > (int)m_len) {
- char *t = new char[l];
- if (t == NULL)
- {
- errno = ENOMEM;
- return *this;
- }
- delete[] m_chr;
- m_chr = t;
- }
- va_start(ap, fmt);
- basestring_vsnprintf(m_chr, l, fmt, ap);
- va_end(ap);
- m_len = strlen(m_chr);
- return *this;
-}
-
-BaseString&
-BaseString::appfmt(const char *fmt, ...)
-{
- char buf[1];
- va_list ap;
- int l;
-
- /* Figure out how long the formatted string will be. A small temporary
- * buffer is used, because I don't trust all implementations to work
- * when called as vsnprintf(NULL, 0, ...).
- */
- va_start(ap, fmt);
- l = basestring_vsnprintf(buf, sizeof(buf), fmt, ap) + 1;
- va_end(ap);
- char *tmp = new char[l];
- if (tmp == NULL)
- {
- errno = ENOMEM;
- return *this;
- }
- va_start(ap, fmt);
- basestring_vsnprintf(tmp, l, fmt, ap);
- va_end(ap);
- append(tmp);
- delete[] tmp;
- return *this;
-}
-
-BaseString&
-BaseString::operator=(const BaseString& str)
-{
- if (this != &str) {
- this->assign(str);
- }
- return *this;
-}
-
-int
-BaseString::split(Vector<BaseString> &v,
- const BaseString &separator,
- int maxSize) const {
- char *str = strdup(m_chr);
- int i, start, len, num = 0;
- len = strlen(str);
- for(start = i = 0;
- (i <= len) && ( (maxSize<0) || ((int)v.size()<=maxSize-1) );
- i++) {
- if(strchr(separator.c_str(), str[i]) || i == len) {
- if(maxSize < 0 || (int)v.size() < maxSize-1)
- str[i] = '\0';
- v.push_back(BaseString(str+start));
- num++;
- start = i+1;
- }
- }
- free(str);
-
- return num;
-}
-
-ssize_t
-BaseString::indexOf(char c) {
- char *p;
- p = strchr(m_chr, c);
- if(p == NULL)
- return -1;
- return (ssize_t)(p-m_chr);
-}
-
-ssize_t
-BaseString::lastIndexOf(char c) {
- char *p;
- p = strrchr(m_chr, c);
- if(p == NULL)
- return -1;
- return (ssize_t)(p-m_chr);
-}
-
-BaseString
-BaseString::substr(ssize_t start, ssize_t stop) {
- if(stop < 0)
- stop = length();
- ssize_t len = stop-start;
- if(len <= 0)
- return BaseString("");
- BaseString s;
- s.assign(m_chr+start, len);
- return s;
-}
-
-static bool
-iswhite(char c) {
- switch(c) {
- case ' ':
- case '\t':
- return true;
- default:
- return false;
- }
- /* NOTREACHED */
-}
-
-char **
-BaseString::argify(const char *argv0, const char *src) {
- Vector<char *> vargv;
-
- if(argv0 != NULL)
- {
- char *t = strdup(argv0);
- if (t == NULL)
- {
- errno = ENOMEM;
- return NULL;
- }
- if (vargv.push_back(t))
- {
- free(t);
- return NULL;
- }
- }
-
- char *tmp = new char[strlen(src)+1];
- if (tmp == NULL)
- {
- for(size_t i = 0; i < vargv.size(); i++)
- free(vargv[i]);
- errno = ENOMEM;
- return NULL;
- }
- char *dst = tmp;
- const char *end = src + strlen(src);
- /* Copy characters from src to destination, while compacting them
- * so that all whitespace is compacted and replaced by a NUL-byte.
- * At the same time, add pointers to strings in the vargv vector.
- * When whitespace is detected, the characters '"' and '\' are honored,
- * to make it possible to give arguments containing whitespace.
- * The semantics of '"' and '\' match that of most Unix shells.
- */
- while(src < end && *src) {
- /* Skip initial whitespace */
- while(src < end && *src && iswhite(*src))
- src++;
-
- char *begin = dst;
- while(src < end && *src) {
- /* Handle '"' quotation */
- if(*src == '"') {
- src++;
- while(src < end && *src && *src != '"') {
- if(*src == '\\')
- src++;
- *dst++ = *src++;
- }
- src++;
- if(src >= end)
- goto end;
- }
-
- /* Handle '\' */
- if(*src == '\\')
- src++;
- else if(iswhite(*src))
- break;
-
- /* Actually copy characters */
- *dst++ = *src++;
- }
-
- /* Make sure the string is properly terminated */
- *dst++ = '\0';
- src++;
-
- {
- char *t = strdup(begin);
- if (t == NULL)
- {
- delete[] tmp;
- for(size_t i = 0; i < vargv.size(); i++)
- free(vargv[i]);
- errno = ENOMEM;
- return NULL;
- }
- if (vargv.push_back(t))
- {
- free(t);
- delete[] tmp;
- for(size_t i = 0; i < vargv.size(); i++)
- free(vargv[i]);
- return NULL;
- }
- }
- }
- end:
-
- delete[] tmp;
- if (vargv.push_back(NULL))
- {
- for(size_t i = 0; i < vargv.size(); i++)
- free(vargv[i]);
- return NULL;
- }
-
- /* Convert the C++ Vector into a C-vector of strings, suitable for
- * calling execv().
- */
- char **argv = (char **)malloc(sizeof(*argv) * (vargv.size()));
- if(argv == NULL)
- {
- for(size_t i = 0; i < vargv.size(); i++)
- free(vargv[i]);
- errno = ENOMEM;
- return NULL;
- }
-
- for(size_t i = 0; i < vargv.size(); i++){
- argv[i] = vargv[i];
- }
-
- return argv;
-}
-
-BaseString&
-BaseString::trim(const char * delim){
- trim(m_chr, delim);
- m_len = strlen(m_chr);
- return * this;
-}
-
-char*
-BaseString::trim(char * str, const char * delim){
- int len = strlen(str) - 1;
- for(; len > 0 && strchr(delim, str[len]); len--);
-
- int pos = 0;
- for(; pos <= len && strchr(delim, str[pos]); pos++);
-
- if(pos > len){
- str[0] = 0;
- return 0;
- } else {
- memmove(str, &str[pos], len - pos + 1);
- str[len-pos+1] = 0;
- }
-
- return str;
-}
-
-int
-BaseString::vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
- return(basestring_vsnprintf(str, size, format, ap));
-}
-
-int
-BaseString::snprintf(char *str, size_t size, const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- int ret= basestring_vsnprintf(str, size, format, ap);
- va_end(ap);
- return(ret);
-}
-
-
-#ifdef TEST_BASE_STRING
-
-/*
-g++ -g -Wall -o tbs -DTEST_BASE_STRING -I$NDB_TOP/include/util \
- -I$NDB_TOP/include/portlib BaseString.cpp
-valgrind ./tbs
-*/
-
-int main()
-{
- BaseString s("abc");
- BaseString t(s);
- s.assign("def");
- t.append("123");
- assert(s == "def");
- assert(t == "abc123");
- s.assign("");
- t.assign("");
- for (unsigned i = 0; i < 1000; i++) {
- s.append("xyz");
- t.assign(s);
- assert(strlen(t.c_str()) % 3 == 0);
- }
-
- {
- BaseString s(":123:abc:;:foo:");
- Vector<BaseString> v;
- assert(s.split(v, ":;") == 7);
-
- assert(v[0] == "");
- assert(v[1] == "123");
- assert(v[2] == "abc");
- assert(v[3] == "");
- assert(v[4] == "");
- assert(v[5] == "foo");
- assert(v[6] == "");
- }
-
- {
- BaseString s(":123:abc:foo:bar");
- Vector<BaseString> v;
- assert(s.split(v, ":;", 4) == 4);
-
- assert(v[0] == "");
- assert(v[1] == "123");
- assert(v[2] == "abc");
- assert(v[3] == "foo:bar");
-
- BaseString n;
- n.append(v, "()");
- assert(n == "()123()abc()foo:bar");
- n = "";
- n.append(v);
- assert(n == " 123 abc foo:bar");
- }
-
- {
- assert(BaseString("hamburger").substr(4,2) == "");
- assert(BaseString("hamburger").substr(3) == "burger");
- assert(BaseString("hamburger").substr(4,8) == "urge");
- assert(BaseString("smiles").substr(1,5) == "mile");
- assert(BaseString("012345").indexOf('2') == 2);
- assert(BaseString("hej").indexOf('X') == -1);
- }
-
- {
- assert(BaseString(" 1").trim(" ") == "1");
- assert(BaseString("1 ").trim(" ") == "1");
- assert(BaseString(" 1 ").trim(" ") == "1");
- assert(BaseString("abc\t\n\r kalleabc\t\r\n").trim("abc\t\r\n ") == "kalle");
- assert(BaseString(" ").trim(" ") == "");
- }
- return 0;
-}
-
-#endif
-
-template class Vector<char *>;
-template class Vector<BaseString>;
diff --git a/storage/ndb/src/common/util/Bitmask.cpp b/storage/ndb/src/common/util/Bitmask.cpp
deleted file mode 100644
index 7a73276b0a9..00000000000
--- a/storage/ndb/src/common/util/Bitmask.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (C) 2004-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <Bitmask.hpp>
-#include <NdbOut.hpp>
-
-void
-BitmaskImpl::getFieldImpl(const Uint32 src[],
- unsigned shiftL, unsigned len, Uint32 dst[])
-{
- /* Copy whole words of src to dst, shifting src left
- * by shiftL. Undefined bits of the last written dst word
- * should be zeroed.
- */
- assert(shiftL < 32);
-
- unsigned shiftR = 32 - shiftL;
- unsigned undefined = shiftL ? ~0 : 0;
-
- /* Merge first word with previously set bits if there's a shift */
- * dst = shiftL ? * dst : 0;
-
- /* Treat the zero-shift case separately to avoid
- * trampling or reading past the end of src
- */
- if (shiftL == 0)
- {
- while(len >= 32)
- {
- * dst++ = * src++;
- len -=32;
- }
-
- if (len != 0)
- {
- /* Last word has some bits set */
- Uint32 mask= ((1 << len) -1); // 0000111
- * dst = (* src) & mask;
- }
- }
- else // shiftL !=0, need to build each word from two words shifted
- {
- while(len >= 32)
- {
- * dst++ |= (* src) << shiftL;
- * dst = ((* src++) >> shiftR) & undefined;
- len -= 32;
- }
-
- /* Have space for shiftR more bits in the current dst word
- * is that enough?
- */
- if(len <= shiftR)
- {
- /* Fit the remaining bits in the current dst word */
- * dst |= ((* src) & ((1 << len) - 1)) << shiftL;
- }
- else
- {
- /* Need to write to two dst words */
- * dst++ |= ((* src) << shiftL);
- * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;
- }
- }
-}
-
-void
-BitmaskImpl::setFieldImpl(Uint32 dst[],
- unsigned shiftL, unsigned len, const Uint32 src[])
-{
- /**
- *
- * abcd ef00
- * 00ab cdef
- */
- assert(shiftL < 32);
- unsigned shiftR = 32 - shiftL;
- unsigned undefined = shiftL ? ~0 : 0;
- while(len >= 32)
- {
- * dst = (* src++) >> shiftL;
- * dst++ |= ((* src) << shiftR) & undefined;
- len -= 32;
- }
-
- /* Copy last bits */
- Uint32 mask = ((1 << len) -1);
- * dst = (* dst & ~mask);
- if(len <= shiftR)
- {
- /* Remaining bits fit in current word */
- * dst |= ((* src++) >> shiftL) & mask;
- }
- else
- {
- /* Remaining bits update 2 words */
- * dst |= ((* src++) >> shiftL);
- * dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;
- }
-}
-
-/* Bitmask testcase code moved from here to
- * storage/ndb/test/ndbapi/testBitfield.cpp
- * to get coverage from automated testing
- */
diff --git a/storage/ndb/src/common/util/ConfigValues.cpp b/storage/ndb/src/common/util/ConfigValues.cpp
deleted file mode 100644
index 97ce4cccb5b..00000000000
--- a/storage/ndb/src/common/util/ConfigValues.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/* Copyright (C) 2004, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <ndb_global.h>
-#include <ConfigValues.hpp>
-#include <NdbOut.hpp>
-#include <NdbTCP.h>
-
-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 if(getenv("CV_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 val2 = m_values[pos+1];
-
- switch(::getTypeOf(keypart)){
- case IntType:
- case SectionType:
- result->m_int = val2;
- break;
- case StringType:
- result->m_string = * getString(val2);
- break;
- case Int64Type:
- result->m_int64 = * get64(val2);
- break;
- case InvalidType:
- default:
- return false;
- }
-
- result->m_type = ::getTypeOf(keypart);
-
- return true;
-}
-
-Uint64 *
-ConfigValues::get64(Uint32 index) const {
- assert(index < m_int64Count);
- const Uint32 * data = m_values + (m_size << 1);
- Uint64 * ptr = (Uint64*)data;
- ptr += index;
- return ptr;
-}
-
-char **
-ConfigValues::getString(Uint32 index) const {
- assert(index < m_stringCount);
- const Uint32 * data = m_values + (m_size << 1);
- char * ptr = (char*)data;
- ptr += m_dataSize;
- ptr -= (index * sizeof(char *));
- return (char**)ptr;
-}
-
-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 ? value : "");
- return true;
-}
-
-static
-bool
-findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){
- Uint32 lo = 0;
- Uint32 hi = sz;
- Uint32 pos = (hi + lo) >> 1;
-
- DEBUG printf("findKey(H'%.8x %d)", key, sz);
-
- if (sz == 0)
- {
- DEBUG ndbout_c(" -> false, 0");
- * _pos = 0;
- return false;
- }
-
- Uint32 val = 0;
- Uint32 oldpos = pos + 1;
- while (pos != oldpos)
- {
- DEBUG printf(" [ %d %d %d ] ", lo, pos, hi);
- assert(pos < hi);
- assert(pos >= lo);
- val = values[2*pos] & KP_MASK;
- if (key > val)
- {
- lo = pos;
- }
- else if (key < val)
- {
- hi = pos;
- }
- else
- {
- * _pos = 2*pos;
- DEBUG ndbout_c(" -> true, %d", pos);
- return true;
- }
- oldpos = pos;
- pos = (hi + lo) >> 1;
- }
-
- DEBUG printf(" pos: %d (key %.8x val: %.8x values[pos]: %x) key>val: %d ",
- pos, key, val, values[2*pos] & KP_MASK,
- key > val);
-
- pos += (key > val) ? 1 : 0;
-
- * _pos = 2*pos;
- DEBUG ndbout_c(" -> false, %d", pos);
- return false;
-}
-
-
-ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){
- m_sectionCounter = (1 << KP_SECTION_SHIFT);
- m_freeKeys = keys;
- m_freeData = (data + 7) & ~7;
- m_currentSection = 0;
- m_cfg = create(m_freeKeys, m_freeData);
-}
-
-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);
- }
- }
-}
-
-ConfigValuesFactory::~ConfigValuesFactory()
-{
- if(m_cfg)
- free(m_cfg);
-}
-
-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 ;
- }
-
- DEBUG printf("[ fk fd ] : [ %d %d ]", m_freeKeys, m_freeData);
-
- 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_freeData = (m_freeData + 7) & ~7;
-
- DEBUG ndbout_c(" [ %d %d ]", m_freeKeys, m_freeData);
-
- 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_freeData = (m_freeData + 7) & ~7;
-
- 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 - m_freeKeys;
-
- Uint32 pos;
- if (findKey(m_cfg->m_values, sz, tmp, &pos))
- {
- DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos);
- return false;
- }
-
- DEBUG {
- printf("H'before ");
- Uint32 prev = 0;
- for (Uint32 i = 0; i<sz; i++)
- {
- Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
- ndbout_c("%.8x", val);
- assert(val >= prev);
- prev = val;
- }
- }
-
- if (pos != 2*sz)
- {
- DEBUG ndbout_c("pos: %d sz: %d", pos, sz);
- memmove(m_cfg->m_values + pos + 2, m_cfg->m_values + pos,
- 4 * (2*sz - pos));
- }
-
-
- Uint32 key = tmp;
- key |= (entry.m_type << KP_TYPE_SHIFT);
- m_cfg->m_values[pos] = key;
-
- DEBUG {
- printf("H'after ");
- Uint32 prev = 0;
- for (Uint32 i = 0; i<=sz; i++)
- {
- Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
- ndbout_c("%.8x", val);
- assert(val >= prev);
- prev = val;
- }
- }
-
- 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, 0,
- (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;
- char ** ref = m_cfg->getString(index);
- * ref = strdup(entry.m_string ? 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, 0,
- (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, 0,
- (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->getConfigValues();
- 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 {
- Uint32 i;
- char * dst = (char*)_dst;
- memcpy(dst, Magic, sizeof(Magic)); dst += sizeof(Magic);
-
- for(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(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;
- const char * end = src + len - 4;
- src += sizeof(Magic);
-
- {
- 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 * save = src;
-
- {
- Uint32 keys = 0;
- Uint32 data = 0;
- while(end - src > 4){
- Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
- keys++;
- switch(::getTypeOf(tmp)){
- case ConfigValues::IntType:
- case ConfigValues::SectionType:
- src += 4;
- break;
- case ConfigValues::Int64Type:
- src += 8;
- data += 8;
- break;
- case ConfigValues::StringType:{
- Uint32 s_len = ntohl(* (const Uint32 *)src);
- src += 4 + mod4(s_len);
- data += sizeof(char*);
- break;
- }
- default:
- break;
- }
- }
- expand(keys, data);
- }
-
- src = save;
- 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 = strlen((const char*)src);
- 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/storage/ndb/src/common/util/File.cpp b/storage/ndb/src/common/util/File.cpp
deleted file mode 100644
index 1aa7e7c8543..00000000000
--- a/storage/ndb/src/common/util/File.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <File.hpp>
-
-#include <NdbOut.hpp>
-#include <my_dir.h>
-
-//
-// PUBLIC
-//
-time_t
-File_class::mtime(const char* aFileName)
-{
- MY_STAT stmp;
- time_t rc = 0;
-
- if (my_stat(aFileName, &stmp, MYF(0)) != NULL) {
- rc = stmp.st_mtime;
- }
-
- return rc;
-}
-
-bool
-File_class::exists(const char* aFileName)
-{
- MY_STAT stmp;
-
- return (my_stat(aFileName, &stmp, MYF(0))!=NULL);
-}
-
-off_t
-File_class::size(FILE* f)
-{
- MY_STAT s;
-
- // Note that my_fstat behaves *differently* than my_stat. ARGGGHH!
- if (my_fstat(fileno(f), &s, MYF(0)))
- return 0;
-
- return s.st_size;
-}
-
-bool
-File_class::rename(const char* currFileName, const char* newFileName)
-{
- return ::rename(currFileName, newFileName) == 0 ? true : false;
-}
-bool
-File_class::remove(const char* aFileName)
-{
- return ::remove(aFileName) == 0 ? true : false;
-}
-
-File_class::File_class() :
- m_file(NULL),
- m_fileMode("r")
-{
-}
-
-File_class::File_class(const char* aFileName, const char* mode) :
- m_file(NULL),
- m_fileMode(mode)
-{
- BaseString::snprintf(m_fileName, PATH_MAX, aFileName);
-}
-
-bool
-File_class::open()
-{
- return open(m_fileName, m_fileMode);
-}
-
-bool
-File_class::open(const char* aFileName, const char* mode)
-{
- if(m_fileName != aFileName){
- /**
- * Only copy if it's not the same string
- */
- BaseString::snprintf(m_fileName, PATH_MAX, aFileName);
- }
- m_fileMode = mode;
- bool rc = true;
- if ((m_file = ::fopen(m_fileName, m_fileMode))== NULL)
- {
- rc = false;
- }
-
- return rc;
-}
-File_class::~File_class()
-{
- close();
-}
-
-bool
-File_class::remove()
-{
- // Close the file first!
- close();
- return File_class::remove(m_fileName);
-}
-
-bool
-File_class::close()
-{
- bool rc = true;
- int retval = 0;
-
- if (m_file != NULL)
- {
- ::fflush(m_file);
- retval = ::fclose(m_file);
- while ( (retval != 0) && (errno == EINTR) ){
- retval = ::fclose(m_file);
- }
- if( retval == 0){
- rc = true;
- }
- else {
- rc = false;
- ndbout_c("ERROR: Close file error in File.cpp for %s",strerror(errno));
- }
- }
- m_file = NULL;
-
- return rc;
-}
-
-int
-File_class::read(void* buf, size_t itemSize, size_t nitems) const
-{
- return ::fread(buf, itemSize, nitems, m_file);
-}
-
-int
-File_class::readChar(char* buf, long start, long length) const
-{
- return ::fread((void*)&buf[start], 1, length, m_file);
-}
-
-int
-File_class::readChar(char* buf)
-{
- return readChar(buf, 0, strlen(buf));
-}
-
-int
-File_class::write(const void* buf, size_t size_arg, size_t nitems)
-{
- return ::fwrite(buf, size_arg, nitems, m_file);
-}
-
-int
-File_class::writeChar(const char* buf, long start, long length)
-{
- return ::fwrite((const void*)&buf[start], sizeof(char), length, m_file);
-}
-
-int
-File_class::writeChar(const char* buf)
-{
- return writeChar(buf, 0, ::strlen(buf));
-}
-
-off_t
-File_class::size() const
-{
- return File_class::size(m_file);
-}
-
-const char*
-File_class::getName() const
-{
- return m_fileName;
-}
-
-int
-File_class::flush() const
-{
- return ::fflush(m_file);;
-}
diff --git a/storage/ndb/src/common/util/InputStream.cpp b/storage/ndb/src/common/util/InputStream.cpp
deleted file mode 100644
index 2033cc6fb0c..00000000000
--- a/storage/ndb/src/common/util/InputStream.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "InputStream.hpp"
-#include <socket_io.h>
-
-FileInputStream Stdin(stdin);
-
-FileInputStream::FileInputStream(FILE * file)
- : f(file) {
-}
-
-char*
-FileInputStream::gets(char * buf, int bufLen){
- if(!feof(f)){
- return fgets(buf, bufLen, f);
- }
- return 0;
-}
-
-SocketInputStream::SocketInputStream(NDB_SOCKET_TYPE socket,
- unsigned read_timeout_ms)
- : m_socket(socket) {
- m_startover= true;
- m_timeout_remain= m_timeout_ms = read_timeout_ms;
-
- m_timedout= false;
-}
-
-char*
-SocketInputStream::gets(char * buf, int bufLen) {
- if(timedout())
- return 0;
- assert(bufLen >= 2);
- int offset= 0;
- if(m_startover)
- {
- buf[0]= '\0';
- m_startover= false;
- }
- else
- offset= strlen(buf);
-
- int time= 0;
- int res = readln_socket(m_socket, m_timeout_remain, &time,
- buf+offset, bufLen-offset, m_mutex);
-
- if(res >= 0)
- m_timeout_remain-=time;
- if(res == 0 || m_timeout_remain<=0)
- {
- m_timedout= true;
- buf[0]=0;
- return buf;
- }
-
- m_startover= true;
-
- if(res == -1)
- {
- return 0;
- }
-
- return buf;
-}
diff --git a/storage/ndb/src/common/util/Makefile.am b/storage/ndb/src/common/util/Makefile.am
deleted file mode 100644
index 4c469187645..00000000000
--- a/storage/ndb/src/common/util/Makefile.am
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libgeneral.la
-
-libgeneral_la_SOURCES = \
- File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \
- SimpleProperties.cpp Parser.cpp InputStream.cpp \
- SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
- OutputStream.cpp NdbOut.cpp BaseString.cpp \
- NdbSqlUtil.cpp new.cpp \
- uucode.c random.c version.c \
- strdup.c \
- ConfigValues.cpp ndb_init.c basestring_vsnprintf.c \
- Bitmask.cpp \
- ndb_rand.c
-
-EXTRA_PROGRAMS = testBitmask
-testBitmask_SOURCES = testBitmask.cpp
-testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
-
-testBitmask.cpp : Bitmask.cpp
- rm -f testBitmask.cpp
- @LN_CP_F@ Bitmask.cpp testBitmask.cpp
-
-testBitmask.o: $(testBitmask_SOURCES)
- $(CXXCOMPILE) -c $(INCLUDES) -D__TEST_BITMASK__ $<
-
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_util.mk.am
-
-windoze-dsp: libgeneral.dsp
-
-libgeneral.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libgeneral_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/common/util/NdbOut.cpp b/storage/ndb/src/common/util/NdbOut.cpp
deleted file mode 100644
index 8c6f94cec6c..00000000000
--- a/storage/ndb/src/common/util/NdbOut.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2003-2005, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-#include <OutputStream.hpp>
-
-static FileOutputStream ndbouts_fileoutputstream(stdout);
-NdbOut ndbout(ndbouts_fileoutputstream);
-
-static const char * fms[] = {
- "%d", "0x%02x", // Int8
- "%u", "0x%02x", // Uint8
- "%d", "0x%04x", // Int16
- "%u", "0x%04x", // Uint16
- "%d", "0x%08x", // Int32
- "%u", "0x%08x", // Uint32
- "%lld", "0x%016llx", // Int64
- "%llu", "0x%016llx", // Uint64
- "%llu", "0x%016llx" // UintPtr
-};
-
-NdbOut&
-NdbOut::operator<<(Int8 v) { m_out->print(fms[0+isHex],(int)v); return *this;}
-NdbOut&
-NdbOut::operator<<(Uint8 v) { m_out->print(fms[2+isHex],(int)v); return *this;}
-NdbOut&
-NdbOut::operator<<(Int16 v) { m_out->print(fms[4+isHex],(int)v); return *this;}
-NdbOut&
-NdbOut::operator<<(Uint16 v) { m_out->print(fms[6+isHex],(int)v); return *this;}
-NdbOut&
-NdbOut::operator<<(Int32 v) { m_out->print(fms[8+isHex], v); return *this;}
-NdbOut&
-NdbOut::operator<<(Uint32 v) { m_out->print(fms[10+isHex], v); return *this;}
-NdbOut&
-NdbOut::operator<<(Int64 v) { m_out->print(fms[12+isHex], v); return *this;}
-NdbOut&
-NdbOut::operator<<(Uint64 v) { m_out->print(fms[14+isHex], v); return *this;}
-NdbOut&
-NdbOut::operator<<(unsigned long int v) { return *this << (Uint64) v; }
-
-NdbOut&
-NdbOut::operator<<(const char* val){ m_out->print("%s", val ? val : "(null)"); return * this; }
-NdbOut&
-NdbOut::operator<<(const void* val){ m_out->print("%p", val); return * this; }
-NdbOut&
-NdbOut::operator<<(BaseString &val){ return *this << val.c_str(); }
-
-NdbOut&
-NdbOut::operator<<(float val){ m_out->print("%f", (double)val); return * this;}
-NdbOut&
-NdbOut::operator<<(double val){ m_out->print("%f", val); return * this; }
-
-NdbOut& NdbOut::endline()
-{
- isHex = 0; // Reset hex to normal, if user forgot this
- m_out->println("");
- m_out->flush();
- return *this;
-}
-
-NdbOut& NdbOut::flushline()
-{
- m_out->flush();
- return *this;
-}
-
-NdbOut& NdbOut::setHexFormat(int _format)
-{
- isHex = (_format == 0 ? 0 : 1);
- return *this;
-}
-
-NdbOut::NdbOut(OutputStream & out)
- : m_out(& out)
-{
- isHex = 0;
-}
-
-NdbOut::~NdbOut()
-{
-}
-
-void
-NdbOut::print(const char * fmt, ...){
- va_list ap;
- char buf[1000];
-
- va_start(ap, fmt);
- if (fmt != 0)
- BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << buf;
- va_end(ap);
-}
-
-void
-NdbOut::println(const char * fmt, ...){
- va_list ap;
- char buf[1000];
-
- va_start(ap, fmt);
- if (fmt != 0)
- BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << buf << endl;
- va_end(ap);
-}
-
-extern "C"
-void
-ndbout_c(const char * fmt, ...){
- va_list ap;
- char buf[1000];
-
- va_start(ap, fmt);
- if (fmt != 0)
- BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << buf << endl;
- va_end(ap);
-}
-
-FilteredNdbOut::FilteredNdbOut(OutputStream & out,
- int threshold, int level)
- : NdbOut(out) {
- m_level = level;
- m_threshold = threshold;
- m_org = &out;
- m_null = new NullOutputStream();
- setLevel(level);
-}
-
-FilteredNdbOut::~FilteredNdbOut(){
- delete m_null;
-}
-
-void
-FilteredNdbOut::setLevel(int i){
- m_level = i;
- if(m_level >= m_threshold){
- m_out = m_org;
- } else {
- m_out = m_null;
- }
-}
-
-void
-FilteredNdbOut::setThreshold(int i){
- m_threshold = i;
- setLevel(m_level);
-}
-
-int
-FilteredNdbOut::getLevel() const {
- return m_level;
-}
-int
-FilteredNdbOut::getThreshold() const {
- return m_threshold;
-}
-
diff --git a/storage/ndb/src/common/util/NdbSqlUtil.cpp b/storage/ndb/src/common/util/NdbSqlUtil.cpp
deleted file mode 100644
index c50d3a93e3c..00000000000
--- a/storage/ndb/src/common/util/NdbSqlUtil.cpp
+++ /dev/null
@@ -1,1016 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <NdbSqlUtil.hpp>
-#include <NdbOut.hpp>
-#include <my_sys.h>
-
-/*
- * Data types. The entries must be in the numerical order.
- */
-
-const NdbSqlUtil::Type
-NdbSqlUtil::m_typeList[] = {
- { // 0
- Type::Undefined,
- NULL,
- NULL
- },
- { // 1
- Type::Tinyint,
- cmpTinyint,
- NULL
- },
- { // 2
- Type::Tinyunsigned,
- cmpTinyunsigned,
- NULL
- },
- { // 3
- Type::Smallint,
- cmpSmallint,
- NULL
- },
- { // 4
- Type::Smallunsigned,
- cmpSmallunsigned,
- NULL
- },
- { // 5
- Type::Mediumint,
- cmpMediumint,
- NULL
- },
- { // 6
- Type::Mediumunsigned,
- cmpMediumunsigned,
- NULL
- },
- { // 7
- Type::Int,
- cmpInt,
- NULL
- },
- { // 8
- Type::Unsigned,
- cmpUnsigned,
- NULL
- },
- { // 9
- Type::Bigint,
- cmpBigint,
- NULL
- },
- { // 10
- Type::Bigunsigned,
- cmpBigunsigned,
- NULL
- },
- { // 11
- Type::Float,
- cmpFloat,
- NULL
- },
- { // 12
- Type::Double,
- cmpDouble,
- NULL
- },
- { // 13
- Type::Olddecimal,
- cmpOlddecimal,
- NULL
- },
- { // 14
- Type::Char,
- cmpChar,
- likeChar
- },
- { // 15
- Type::Varchar,
- cmpVarchar,
- likeVarchar
- },
- { // 16
- Type::Binary,
- cmpBinary,
- likeBinary
- },
- { // 17
- Type::Varbinary,
- cmpVarbinary,
- likeVarbinary
- },
- { // 18
- Type::Datetime,
- cmpDatetime,
- NULL
- },
- { // 19
- Type::Date,
- cmpDate,
- NULL
- },
- { // 20
- Type::Blob,
- NULL,
- NULL
- },
- { // 21
- Type::Text,
- NULL,
- NULL
- },
- { // 22
- Type::Bit,
- cmpBit,
- NULL
- },
- { // 23
- Type::Longvarchar,
- cmpLongvarchar,
- likeLongvarchar
- },
- { // 24
- Type::Longvarbinary,
- cmpLongvarbinary,
- likeLongvarbinary
- },
- { // 25
- Type::Time,
- cmpTime,
- NULL
- },
- { // 26
- Type::Year,
- cmpYear,
- NULL
- },
- { // 27
- Type::Timestamp,
- cmpTimestamp,
- NULL
- },
- { // 28
- Type::Olddecimalunsigned,
- cmpOlddecimalunsigned,
- NULL
- },
- { // 29
- Type::Decimal,
- cmpDecimal,
- NULL
- },
- { // 30
- Type::Decimalunsigned,
- cmpDecimalunsigned,
- NULL
- }
-};
-
-const NdbSqlUtil::Type&
-NdbSqlUtil::getType(Uint32 typeId)
-{
- if (typeId < sizeof(m_typeList) / sizeof(m_typeList[0]) &&
- m_typeList[typeId].m_typeId != Type::Undefined) {
- return m_typeList[typeId];
- }
- return m_typeList[Type::Undefined];
-}
-
-const NdbSqlUtil::Type&
-NdbSqlUtil::getTypeBinary(Uint32 typeId)
-{
- switch (typeId) {
- case Type::Char:
- case Type::Varchar:
- case Type::Binary:
- case Type::Varbinary:
- case Type::Longvarchar:
- case Type::Longvarbinary:
- typeId = Type::Binary;
- break;
- case Type::Text:
- typeId = Type::Blob;
- break;
- default:
- break;
- }
- return getType(typeId);
-}
-
-/*
- * Comparison functions.
- */
-
-int
-NdbSqlUtil::cmpTinyint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Int8)) {
- Int8 v1, v2;
- memcpy(&v1, p1, sizeof(Int8));
- memcpy(&v2, p2, sizeof(Int8));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpTinyunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint8)) {
- Uint8 v1, v2;
- memcpy(&v1, p1, sizeof(Uint8));
- memcpy(&v2, p2, sizeof(Uint8));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpSmallint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Int16)) {
- Int16 v1, v2;
- memcpy(&v1, p1, sizeof(Int16));
- memcpy(&v2, p2, sizeof(Int16));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpSmallunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint16)) {
- Uint16 v1, v2;
- memcpy(&v1, p1, sizeof(Uint16));
- memcpy(&v2, p2, sizeof(Uint16));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpMediumint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= 3) {
- Int32 v1, v2;
- v1 = sint3korr((const uchar*)p1);
- v2 = sint3korr((const uchar*)p2);
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpMediumunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= 3) {
- Uint32 v1, v2;
- v1 = uint3korr((const uchar*)p1);
- v2 = uint3korr((const uchar*)p2);
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpInt(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Int32)) {
- Int32 v1, v2;
- memcpy(&v1, p1, sizeof(Int32));
- memcpy(&v2, p2, sizeof(Int32));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpUnsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint32)) {
- Uint32 v1, v2;
- memcpy(&v1, p1, sizeof(Uint32));
- memcpy(&v2, p2, sizeof(Uint32));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpBigint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Int64)) {
- Int64 v1, v2;
- memcpy(&v1, p1, sizeof(Int64));
- memcpy(&v2, p2, sizeof(Int64));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpBigunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint64)) {
- Uint64 v1, v2;
- memcpy(&v1, p1, sizeof(Uint64));
- memcpy(&v2, p2, sizeof(Uint64));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpFloat(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(float)) {
- float v1, v2;
- memcpy(&v1, p1, sizeof(float));
- memcpy(&v2, p2, sizeof(float));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpDouble(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(double)) {
- double v1, v2;
- memcpy(&v1, p1, sizeof(double));
- memcpy(&v2, p2, sizeof(double));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmp_olddecimal(const uchar* s1, const uchar* s2, unsigned n)
-{
- int sgn = +1;
- unsigned i = 0;
- while (i < n) {
- int c1 = s1[i];
- int c2 = s2[i];
- if (c1 == c2) {
- if (c1 == '-')
- sgn = -1;
- } else if (c1 == '-') {
- return -1;
- } else if (c2 == '-') {
- return +1;
- } else if (c1 < c2) {
- return -1 * sgn;
- } else {
- return +1 * sgn;
- }
- i++;
- }
- return 0;
-}
-
-int
-NdbSqlUtil::cmpOlddecimal(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (full) {
- assert(n1 == n2);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- return cmp_olddecimal(v1, v2, n1);
- }
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpOlddecimalunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (full) {
- assert(n1 == n2);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- return cmp_olddecimal(v1, v2, n1);
- }
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpDecimal(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // compare as binary strings
- unsigned n = (n1 <= n2 ? n1 : n2);
- int k = memcmp(v1, v2, n);
- if (k == 0) {
- k = (full ? n1 : n) - n2;
- }
- return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpDecimalunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // compare as binary strings
- unsigned n = (n1 <= n2 ? n1 : n2);
- int k = memcmp(v1, v2, n);
- if (k == 0) {
- k = (full ? n1 : n) - n2;
- }
- return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- // collation does not work on prefix for some charsets
- assert(full);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // not const in MySQL
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- // compare with space padding
- int k = (*cs->coll->strnncollsp)(cs, v1, n1, v2, n2, false);
- return k < 0 ? -1 : k > 0 ? +1 : 0;
-}
-
-int
-NdbSqlUtil::cmpVarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const unsigned lb = 1;
- // collation does not work on prefix for some charsets
- assert(full && n1 >= lb && n2 >= lb);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = *v1;
- unsigned m2 = *v2;
- if (m1 <= n1 - lb && m2 <= n2 - lb) {
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- // compare with space padding
- int k = (*cs->coll->strnncollsp)(cs, v1 + lb, m1, v2 + lb, m2, false);
- return k < 0 ? -1 : k > 0 ? +1 : 0;
- }
- // treat bad data as NULL
- if (m1 > n1 - lb && m2 <= n2 - lb)
- return -1;
- if (m1 <= n1 - lb && m2 > n2 - lb)
- return +1;
- return 0;
-}
-
-int
-NdbSqlUtil::cmpBinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // compare as binary strings
- unsigned n = (n1 <= n2 ? n1 : n2);
- int k = memcmp(v1, v2, n);
- if (k == 0) {
- k = (full ? n1 : n) - n2;
- }
- return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpVarbinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const unsigned lb = 1;
- if (n2 >= lb) {
- assert(n1 >= lb);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = *v1;
- unsigned m2 = *v2;
- if (m1 <= n1 - lb && m2 <= n2 - lb) {
- // compare as binary strings
- unsigned m = (m1 <= m2 ? m1 : m2);
- int k = memcmp(v1 + lb, v2 + lb, m);
- if (k == 0) {
- k = (full ? m1 : m) - m2;
- }
- return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown;
- }
- // treat bad data as NULL
- if (m1 > n1 - lb && m2 <= n2 - lb)
- return -1;
- if (m1 <= n1 - lb && m2 > n2 - lb)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpDatetime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Int64)) {
- Int64 v1, v2;
- memcpy(&v1, p1, sizeof(Int64));
- memcpy(&v2, p2, sizeof(Int64));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpDate(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
-#ifdef ndb_date_is_4_byte_native_int
- if (n2 >= sizeof(Int32)) {
- Int32 v1, v2;
- memcpy(&v1, p1, sizeof(Int32));
- memcpy(&v2, p2, sizeof(Int32));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
-#else
-#ifdef ndb_date_sol9x86_cc_xO3_madness
- if (n2 >= 3) {
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // from Field_newdate::val_int
- Uint64 j1 = uint3korr(v1);
- Uint64 j2 = uint3korr(v2);
- j1 = (j1 % 32L)+(j1 / 32L % 16L)*100L + (j1/(16L*32L))*10000L;
- j2 = (j2 % 32L)+(j2 / 32L % 16L)*100L + (j2/(16L*32L))*10000L;
- if (j1 < j2)
- return -1;
- if (j1 > j2)
- return +1;
- return 0;
- }
-#else
- if (n2 >= 3) {
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- uint j1 = uint3korr(v1);
- uint j2 = uint3korr(v2);
- uint d1 = (j1 & 31);
- uint d2 = (j2 & 31);
- j1 = (j1 >> 5);
- j2 = (j2 >> 5);
- uint m1 = (j1 & 15);
- uint m2 = (j2 & 15);
- j1 = (j1 >> 4);
- j2 = (j2 >> 4);
- uint y1 = j1;
- uint y2 = j2;
- if (y1 < y2)
- return -1;
- if (y1 > y2)
- return +1;
- if (m1 < m2)
- return -1;
- if (m1 > m2)
- return +1;
- if (d1 < d2)
- return -1;
- if (d1 > d2)
- return +1;
- return 0;
- }
-#endif
-#endif
- assert(! full);
- return CmpUnknown;
-}
-
-// not supported
-int
-NdbSqlUtil::cmpBlob(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- assert(false);
- return 0;
-}
-
-// not supported
-int
-NdbSqlUtil::cmpText(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- assert(false);
- return 0;
-}
-
-int
-NdbSqlUtil::cmpBit(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- Uint32 n = (n1 < n2) ? n1 : n2;
- int ret = memcmp(p1, p2, n);
- return ret;
-}
-
-
-int
-NdbSqlUtil::cmpTime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= 3) {
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- // from Field_time::val_int
- Int32 j1 = sint3korr(v1);
- Int32 j2 = sint3korr(v2);
- if (j1 < j2)
- return -1;
- if (j1 > j2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-// not yet
-
-int
-NdbSqlUtil::cmpLongvarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const unsigned lb = 2;
- // collation does not work on prefix for some charsets
- assert(full && n1 >= lb && n2 >= lb);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = uint2korr(v1);
- unsigned m2 = uint2korr(v2);
- if (m1 <= n1 - lb && m2 <= n2 - lb) {
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- // compare with space padding
- int k = (*cs->coll->strnncollsp)(cs, v1 + lb, m1, v2 + lb, m2, false);
- return k < 0 ? -1 : k > 0 ? +1 : 0;
- }
- // treat bad data as NULL
- if (m1 > n1 - lb && m2 <= n2 - lb)
- return -1;
- if (m1 <= n1 - lb && m2 > n2 - lb)
- return +1;
- return 0;
-}
-
-int
-NdbSqlUtil::cmpLongvarbinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- const unsigned lb = 2;
- if (n2 >= lb) {
- assert(n1 >= lb);
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = uint2korr(v1);
- unsigned m2 = uint2korr(v2);
- if (m1 <= n1 - lb && m2 <= n2 - lb) {
- // compare as binary strings
- unsigned m = (m1 <= m2 ? m1 : m2);
- int k = memcmp(v1 + lb, v2 + lb, m);
- if (k == 0) {
- k = (full ? m1 : m) - m2;
- }
- return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown;
- }
- // treat bad data as NULL
- if (m1 > n1 - lb && m2 <= n2 - lb)
- return -1;
- if (m1 <= n1 - lb && m2 > n2 - lb)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpYear(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint8)) {
- Uint8 v1, v2;
- memcpy(&v1, p1, sizeof(Uint8));
- memcpy(&v2, p2, sizeof(Uint8));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-int
-NdbSqlUtil::cmpTimestamp(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full)
-{
- if (n2 >= sizeof(Uint32)) {
- Uint32 v1, v2;
- memcpy(&v1, p1, sizeof(Uint32));
- memcpy(&v2, p2, sizeof(Uint32));
- if (v1 < v2)
- return -1;
- if (v1 > v2)
- return +1;
- return 0;
- }
- assert(! full);
- return CmpUnknown;
-}
-
-// like
-
-static const int ndb_wild_prefix = '\\';
-static const int ndb_wild_one = '_';
-static const int ndb_wild_many = '%';
-
-int
-NdbSqlUtil::likeChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- const char* v1 = (const char*)p1;
- const char* v2 = (const char*)p2;
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- // strip end spaces to match (incorrect) MySQL behaviour
- n1 = (*cs->cset->lengthsp)(cs, v1, n1);
- int k = (*cs->coll->wildcmp)(cs, v1, v1 + n1, v2, v2 + n2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
- return k == 0 ? 0 : +1;
-}
-
-int
-NdbSqlUtil::likeBinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- assert(info == 0);
- return likeChar(&my_charset_bin, p1, n1, p2, n2);
-}
-
-int
-NdbSqlUtil::likeVarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- const unsigned lb = 1;
- if (n1 >= lb) {
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = *v1;
- unsigned m2 = n2;
- if (lb + m1 <= n1) {
- const char* w1 = (const char*)v1 + lb;
- const char* w2 = (const char*)v2;
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- int k = (*cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
- return k == 0 ? 0 : +1;
- }
- }
- return -1;
-}
-
-int
-NdbSqlUtil::likeVarbinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- assert(info == 0);
- return likeVarchar(&my_charset_bin, p1, n1, p2, n2);
-}
-
-int
-NdbSqlUtil::likeLongvarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- const unsigned lb = 2;
- if (n1 >= lb) {
- const uchar* v1 = (const uchar*)p1;
- const uchar* v2 = (const uchar*)p2;
- unsigned m1 = uint2korr(v1);
- unsigned m2 = n2;
- if (lb + m1 <= n1) {
- const char* w1 = (const char*)v1 + lb;
- const char* w2 = (const char*)v2;
- CHARSET_INFO* cs = (CHARSET_INFO*)(info);
- int k = (*cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
- return k == 0 ? 0 : +1;
- }
- }
- return -1;
-}
-
-int
-NdbSqlUtil::likeLongvarbinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
-{
- assert(info == 0);
- return likeLongvarchar(&my_charset_bin, p1, n1, p2, n2);
-}
-
-// check charset
-
-uint
-NdbSqlUtil::check_column_for_pk(Uint32 typeId, const void* info)
-{
- const Type& type = getType(typeId);
- switch (type.m_typeId) {
- case Type::Char:
- case Type::Varchar:
- case Type::Longvarchar:
- {
- const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
- if(cs != 0 &&
- cs->cset != 0 &&
- cs->coll != 0 &&
- cs->coll->strnxfrm != 0 &&
- cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
- return 0;
- else
- return 743;
- }
- break;
- case Type::Undefined:
- case Type::Blob:
- case Type::Text:
- case Type::Bit:
- break;
- default:
- return 0;
- }
- return 906;
-}
-
-uint
-NdbSqlUtil::check_column_for_hash_index(Uint32 typeId, const void* info)
-{
- return check_column_for_pk(typeId, info);
-}
-
-uint
-NdbSqlUtil::check_column_for_ordered_index(Uint32 typeId, const void* info)
-{
- const Type& type = getType(typeId);
- if (type.m_cmp == NULL)
- return false;
- switch (type.m_typeId) {
- case Type::Char:
- case Type::Varchar:
- case Type::Longvarchar:
- {
- const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
- if (cs != 0 &&
- cs->cset != 0 &&
- cs->coll != 0 &&
- cs->coll->strnxfrm != 0 &&
- cs->coll->strnncollsp != 0 &&
- cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
- return 0;
- else
- return 743;
- }
- break;
- case Type::Undefined:
- case Type::Blob:
- case Type::Text:
- case Type::Bit: // can be fixed
- break;
- default:
- return 0;
- }
- return 906;
-}
-
-// utilities
-
-bool
-NdbSqlUtil::get_var_length(Uint32 typeId, const void* p, unsigned attrlen, Uint32& lb, Uint32& len)
-{
- const unsigned char* const src = (const unsigned char*)p;
- switch (typeId) {
- case NdbSqlUtil::Type::Varchar:
- case NdbSqlUtil::Type::Varbinary:
- lb = 1;
- if (attrlen >= lb) {
- len = src[0];
- if (attrlen >= lb + len)
- return true;
- }
- break;
- case NdbSqlUtil::Type::Longvarchar:
- case NdbSqlUtil::Type::Longvarbinary:
- lb = 2;
- if (attrlen >= lb) {
- len = src[0] + (src[1] << 8);
- if (attrlen >= lb + len)
- return true;
- }
- break;
- default:
- lb = 0;
- len = attrlen;
- return true;
- break;
- }
- return false;
-}
-
-// workaround
-
-int
-NdbSqlUtil::strnxfrm_bug7284(CHARSET_INFO* cs, unsigned char* dst, unsigned dstLen, const unsigned char*src, unsigned srcLen)
-{
- unsigned char nsp[20]; // native space char
- unsigned char xsp[20]; // strxfrm-ed space char
-#ifdef VM_TRACE
- memset(nsp, 0x1f, sizeof(nsp));
- memset(xsp, 0x1f, sizeof(xsp));
-#endif
- // convert from unicode codepoint for space
- int n1 = (*cs->cset->wc_mb)(cs, (my_wc_t)0x20, nsp, nsp + sizeof(nsp));
- if (n1 <= 0)
- return -1;
- // strxfrm to binary
- int n2 = (*cs->coll->strnxfrm)(cs, xsp, sizeof(xsp), nsp, n1);
- if (n2 <= 0)
- return -1;
- // XXX bug workaround - strnxfrm may not write full string
- memset(dst, 0x0, dstLen);
- // strxfrm argument string - returns no error indication
- int n3 = (*cs->coll->strnxfrm)(cs, dst, dstLen, src, srcLen);
- // pad with strxfrm-ed space chars
- int n4 = n3;
- while (n4 < (int)dstLen) {
- dst[n4] = xsp[(n4 - n3) % n2];
- n4++;
- }
- // no check for partial last
- return dstLen;
-}
diff --git a/storage/ndb/src/common/util/OutputStream.cpp b/storage/ndb/src/common/util/OutputStream.cpp
deleted file mode 100644
index 37487be29f0..00000000000
--- a/storage/ndb/src/common/util/OutputStream.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <OutputStream.hpp>
-#include <socket_io.h>
-
-FileOutputStream::FileOutputStream(FILE * file){
- f = file;
-}
-
-int
-FileOutputStream::print(const char * fmt, ...){
- va_list ap;
- va_start(ap, fmt);
- const int ret = vfprintf(f, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-int
-FileOutputStream::println(const char * fmt, ...){
- va_list ap;
- va_start(ap, fmt);
- const int ret = vfprintf(f, fmt, ap);
- va_end(ap);
- return ret + fprintf(f, "\n");
-}
-
-SocketOutputStream::SocketOutputStream(NDB_SOCKET_TYPE socket,
- unsigned write_timeout_ms){
- m_socket = socket;
- m_timeout_remain= m_timeout_ms = write_timeout_ms;
- m_timedout= false;
-}
-
-int
-SocketOutputStream::print(const char * fmt, ...){
- va_list ap;
-
- if(timedout())
- return -1;
-
- int time= 0;
- va_start(ap, fmt);
- int ret = vprint_socket(m_socket, m_timeout_ms, &time, fmt, ap);
- va_end(ap);
-
- if(ret >= 0)
- m_timeout_remain-=time;
- if((ret < 0 && errno==ETIMEDOUT) || m_timeout_remain<=0)
- {
- m_timedout= true;
- ret= -1;
- }
-
- return ret;
-}
-int
-SocketOutputStream::println(const char * fmt, ...){
- va_list ap;
-
- if(timedout())
- return -1;
-
- int time= 0;
- va_start(ap, fmt);
- int ret = vprintln_socket(m_socket, m_timeout_ms, &time, fmt, ap);
- va_end(ap);
-
- if(ret >= 0)
- m_timeout_remain-=time;
- if ((ret < 0 && errno==ETIMEDOUT) || m_timeout_remain<=0)
- {
- m_timedout= true;
- ret= -1;
- }
-
- return ret;
-}
diff --git a/storage/ndb/src/common/util/Parser.cpp b/storage/ndb/src/common/util/Parser.cpp
deleted file mode 100644
index b497b320a36..00000000000
--- a/storage/ndb/src/common/util/Parser.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "Parser.hpp"
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-
-#undef DEBUG
-#define DEBUG(x) ndbout << x << endl;
-
-static void trim(char * str);
-
-class ParseInputStream : public InputStream {
-public:
- ParseInputStream(InputStream & in, bool trim = true, char eofComment = '#');
-
- char* gets(char * buf, int bufLen);
- void push_back(const char *);
- void set_mutex(NdbMutex *m) { in.set_mutex(m); };
-private:
- InputStream & in;
- char * buffer;
-};
-
-ParseInputStream::ParseInputStream(InputStream & _in,
- bool /* unused */,
- char /* unused */)
- : in(_in){
- buffer = 0;
-}
-
-char*
-ParseInputStream::gets(char * buf, int bufLen){
- if(buffer != 0){
- strncpy(buf, buffer, bufLen);
- free(buffer);
- buffer = 0;
- return buf;
- }
- char *t = in.gets(buf, bufLen);
- return t;
-}
-
-void
-ParseInputStream::push_back(const char * str){
- if(buffer != 0)
- abort();
- buffer = strdup(str);
-}
-
-ParserImpl::ParserImpl(const DummyRow * rows, InputStream & in,
- bool b_cmd, bool b_empty, bool b_iarg)
- : m_rows(rows), input(* new ParseInputStream(in))
-{
- m_breakOnCmd = b_cmd;
- m_breakOnEmpty = b_empty;
- m_breakOnInvalidArg = b_iarg;
-}
-
-ParserImpl::~ParserImpl(){
- delete & input;
-}
-
-static
-bool
-Empty(const char * str){
- if(str == 0)
- return true;
- const int len = strlen(str);
- if(len == 0)
- return false;
- for(int i = 0; i<len; i++)
- if(str[i] != ' ' && str[i] != '\t' && str[i] != '\n')
- return false;
- return true;
-}
-
-static
-bool
-Eof(const char * str) { return str == 0;}
-
-static
-void
-trim(char * str){
- if(str == NULL)
- return;
- int len = strlen(str);
- for(len--; str[len] == '\n' || str[len] == ' ' || str[len] == '\t'; len--)
- str[len] = 0;
-
- int pos = 0;
- while(str[pos] == ' ' || str[pos] == '\t')
- pos++;
-
- if(str[pos] == '\"' && str[len] == '\"') {
- pos++;
- str[len] = 0;
- len--;
- }
-
- memmove(str, &str[pos], len - pos + 2);
-}
-
-static
-bool
-split(char * buf, char ** name, char ** value){
-
- * value = strchr(buf, ':');
- if(* value == 0)
- * value = strchr(buf, '=');
-
-
- if(* value == 0){
- return false;
- }
- (* value)[0] = 0;
- * value = (* value + 1);
- * name = buf;
-
- trim(* name);
- trim(* value);
-
- return true;
-}
-
-bool
-ParserImpl::run(Context * ctx, const class Properties ** pDst,
- volatile bool * stop) const
-{
- DBUG_ENTER("ParserImpl::run");
-
- input.set_mutex(ctx->m_mutex);
-
- * pDst = 0;
- bool ownStop = false;
- if(stop == 0)
- stop = &ownStop;
-
- ctx->m_aliasUsed.clear();
-
- const unsigned sz = sizeof(ctx->m_tokenBuffer);
- ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
- if(Eof(ctx->m_currentToken)){
- ctx->m_status = Parser<Dummy>::Eof;
- DBUG_RETURN(false);
- }
-
- int last= strlen(ctx->m_currentToken);
- if(last>0)
- last--;
-
- if(ctx->m_currentToken[last] !='\n'){
- ctx->m_status = Parser<Dummy>::NoLine;
- ctx->m_tokenBuffer[0]= '\0';
- DBUG_RETURN(false);
- }
-
- if(Empty(ctx->m_currentToken)){
- ctx->m_status = Parser<Dummy>::EmptyLine;
- DBUG_RETURN(false);
- }
-
- trim(ctx->m_currentToken);
- ctx->m_currentCmd = matchCommand(ctx, ctx->m_currentToken, m_rows);
- if(ctx->m_currentCmd == 0){
- ctx->m_status = Parser<Dummy>::UnknownCommand;
- DBUG_RETURN(false);
- }
-
- Properties * p = new Properties();
-
- bool invalidArgument = false;
- ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
-
- while((! * stop) &&
- !Eof(ctx->m_currentToken) &&
- !Empty(ctx->m_currentToken)){
- if(ctx->m_currentToken[0] != 0){
- trim(ctx->m_currentToken);
- if(!parseArg(ctx, ctx->m_currentToken, ctx->m_currentCmd + 1, p)){
- delete p;
- invalidArgument = true;
- break;
- }
- }
- ctx->m_currentToken = input.gets(ctx->m_tokenBuffer, sz);
- }
-
- if(invalidArgument){
- char buf[sz];
- char * tmp;
- if(!m_breakOnInvalidArg){
- do {
- tmp = input.gets(buf, sz);
- } while((! * stop) && !Eof(tmp) && !Empty(tmp));
- }
- DBUG_RETURN(false);
- }
-
- if(* stop){
- delete p;
- ctx->m_status = Parser<Dummy>::ExternalStop;
- DBUG_RETURN(false);
- }
-
- if(!checkMandatory(ctx, p)){
- ctx->m_status = Parser<Dummy>::MissingMandatoryArgument;
- delete p;
- DBUG_RETURN(false);
- }
-
- /**
- * Add alias to properties
- */
- for(unsigned i = 0; i<ctx->m_aliasUsed.size(); i++){
- const ParserRow<Dummy> * alias = ctx->m_aliasUsed[i];
- Properties tmp;
- tmp.put("name", alias->name);
- tmp.put("realName", alias->realName);
- p->put("$ALIAS", i, &tmp);
- }
- p->put("$ALIAS", ctx->m_aliasUsed.size());
-
- ctx->m_status = Parser<Dummy>::Ok;
- * pDst = p;
- DBUG_RETURN(true);
-}
-
-const ParserImpl::DummyRow*
-ParserImpl::matchCommand(Context* ctx, const char* buf, const DummyRow rows[]){
- const char * name = buf;
- const DummyRow * tmp = &rows[0];
- while(tmp->name != 0 && name != 0){
- if(strcmp(tmp->name, name) == 0){
- if(tmp->type == DummyRow::Cmd)
- return tmp;
- if(tmp->type == DummyRow::CmdAlias){
- if(ctx != 0)
- ctx->m_aliasUsed.push_back(tmp);
- name = tmp->realName;
- tmp = &rows[0];
- continue;
- }
- }
- tmp++;
- }
- return 0;
-}
-
-const ParserImpl::DummyRow*
-ParserImpl::matchArg(Context* ctx, const char * buf, const DummyRow rows[]){
- const char * name = buf;
- const DummyRow * tmp = &rows[0];
- while(tmp->name != 0){
- const DummyRow::Type t = tmp->type;
- if(t != DummyRow::Arg && t != DummyRow::ArgAlias && t !=DummyRow::CmdAlias)
- break;
- if(t !=DummyRow::CmdAlias && strcmp(tmp->name, name) == 0){
- if(tmp->type == DummyRow::Arg){
- return tmp;
- }
- if(tmp->type == DummyRow::ArgAlias){
- if(ctx != 0)
- ctx->m_aliasUsed.push_back(tmp);
- name = tmp->realName;
- tmp = &rows[0];
- continue;
- }
- }
- tmp++;
- }
- return 0;
-}
-
-bool
-ParserImpl::parseArg(Context * ctx,
- char * buf,
- const DummyRow * rows,
- Properties * p){
- char * name;
- char * value;
- if(!split(buf, &name, &value)){
- ctx->m_status = Parser<Dummy>::InvalidArgumentFormat;
- return false;
- }
- const DummyRow * arg = matchArg(ctx, name, rows);
- if(arg == 0){
- ctx->m_status = Parser<Dummy>::UnknownArgument;
- return false;
- }
-
- switch(arg->argType){
- case DummyRow::String:
- if(p->put(arg->name, value))
- return true;
- break;
- case DummyRow::Int:{
- Uint32 i;
- int c = sscanf(value, "%u", &i);
- if(c != 1){
- ctx->m_status = Parser<Dummy>::TypeMismatch;
- return false;
- }
- if(p->put(arg->name, i))
- return true;
- break;
- }
-
- case DummyRow::Properties: {
- abort();
- break;
- }
- default:
- ctx->m_status = Parser<Dummy>::UnknownArgumentType;
- return false;
- }
- if(p->getPropertiesErrno() == E_PROPERTIES_ELEMENT_ALREADY_EXISTS){
- ctx->m_status = Parser<Dummy>::ArgumentGivenTwice;
- return false;
- }
-
- abort();
-}
-
-bool
-ParserImpl::checkMandatory(Context* ctx, const Properties* props){
- const DummyRow * tmp = &ctx->m_currentCmd[1];
- while(tmp->name != 0 && tmp->type == DummyRow::Arg){
- if(tmp->argRequired == ParserRow<Dummy>::Mandatory &&
- !props->contains(tmp->name)){
- ctx->m_status = Parser<Dummy>::MissingMandatoryArgument;
- ctx->m_currentArg = tmp;
- return false;
- }
- tmp++;
- }
- return true;
-}
-
-template class Vector<const ParserRow<ParserImpl::Dummy>*>;
diff --git a/storage/ndb/src/common/util/Properties.cpp b/storage/ndb/src/common/util/Properties.cpp
deleted file mode 100644
index 8e36062dcea..00000000000
--- a/storage/ndb/src/common/util/Properties.cpp
+++ /dev/null
@@ -1,1136 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <Properties.hpp>
-
-#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
- */
-const char Properties::version[] = { 2, 0, 0, 1, 1, 1, 1, 4 };
-const char Properties::delimiter = ':';
-
-/**
- * PropertyImpl
- */
-struct PropertyImpl{
- PropertiesType valueType;
- const char * name;
- void * value;
-
- ~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);
-
- static PropertyImpl * copyPropertyImpl(const PropertyImpl &);
-};
-
-/**
- * PropertiesImpl
- */
-class PropertiesImpl {
- PropertiesImpl(const PropertiesImpl &); // Not implemented
- PropertiesImpl& operator=(const PropertiesImpl&); // Not implemented
-public:
- PropertiesImpl(Properties *, bool case_insensitive);
- PropertiesImpl(Properties *, const PropertiesImpl &);
- ~PropertiesImpl();
-
- Properties * properties;
-
- Uint32 size;
- Uint32 items;
- PropertyImpl **content;
-
- bool m_insensitive;
- int (* compare)(const char *s1, const char *s2);
-
- void setCaseInsensitiveNames(bool value);
- void grow(int sizeToAdd);
-
- PropertyImpl * get(const char * name) const;
- PropertyImpl * put(PropertyImpl *);
- void remove(const char * name);
-
- Uint32 getPackedSize(Uint32 pLen) const;
- bool pack(Uint32 *& buf, const char * prefix, Uint32 prefixLen) const;
- bool unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top, int items);
-
- Uint32 getTotalItems() const;
-
- void setErrno(Uint32 pErr, Uint32 osErr = 0){
- properties->setErrno(pErr, osErr);
- }
-
- const char * getProps(const char * name, const PropertiesImpl ** impl) const;
- const char * getPropsPut(const char * name, PropertiesImpl ** impl);
-};
-
-/**
- * Methods for Property
- */
-Property::Property(const char * name, Uint32 value){
- impl = new PropertyImpl(name, value);
-}
-
-Property::Property(const char * name, const char * value){
- impl = new PropertyImpl(name, value);
-}
-
-Property::Property(const char * name, const class Properties * value){
- impl = new PropertyImpl(name, value);
-
- ((Properties*)impl->value)->setCaseInsensitiveNames(value->getCaseInsensitiveNames());
-}
-
-Property::~Property(){
- delete impl;
-}
-
-/**
- * Methods for Properties
- */
-Properties::Properties(bool case_insensitive){
- parent = 0;
- impl = new PropertiesImpl(this, case_insensitive);
-}
-
-Properties::Properties(const Properties & org){
- parent = 0;
- impl = new PropertiesImpl(this, * org.impl);
-}
-
-Properties::Properties(const Property * anArray, int arrayLen){
- impl = new PropertiesImpl(this, false);
-
- put(anArray, arrayLen);
-}
-
-Properties::~Properties(){
- clear();
- delete impl;
-}
-
-void
-Properties::put(const Property * anArray, int arrayLen){
- if(anArray == 0)
- return;
- for(int i = 0; i<arrayLen; i++)
- impl->put(anArray[i].impl);
-}
-
-template <class T>
-bool
-put(PropertiesImpl * impl, const char * name, T value, bool replace){
- if(name == 0){
- impl->setErrno(E_PROPERTIES_INVALID_NAME);
- return false;
- }
-
- PropertiesImpl * tmp = 0;
- const char * short_name = impl->getPropsPut(name, &tmp);
-
- if(tmp == 0){
- impl->setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
-
- if(tmp->get(short_name) != 0){
- if(replace){
- tmp->remove(short_name);
- } else {
- impl->setErrno(E_PROPERTIES_ELEMENT_ALREADY_EXISTS);
- return false;
- }
- }
- return tmp->put(new PropertyImpl(short_name, value));
-}
-
-
-bool
-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);
-}
-
-bool
-Properties::put(const char * name, const Properties * value, bool replace){
- return ::put(impl, name, value, replace);
-}
-
-bool
-Properties::getTypeOf(const char * name, PropertiesType * type) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
- setErrno(E_PROPERTIES_OK);
- * type = nvp->valueType;
- return true;
-}
-
-bool
-Properties::contains(const char * name) const {
- PropertyImpl * nvp = impl->get(name);
- return nvp != 0;
-}
-
-bool
-Properties::get(const char * name, Uint32 * value) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
-
- if(nvp->valueType == PropertiesType_Uint32){
- * value = * (Uint32 *)nvp->value;
- 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;
-}
-
-bool
-Properties::get(const char * name, const char ** value) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
-
- if(nvp->valueType == PropertiesType_char){
- * value = (const char *)nvp->value;
- setErrno(E_PROPERTIES_OK);
- return true;
- }
- setErrno(E_PROPERTIES_INVALID_TYPE);
- return false;
-}
-
-bool
-Properties::get(const char * name, BaseString& value) const {
- const char *tmp = "";
- bool ret;
- ret = get(name, &tmp);
- value.assign(tmp);
- return ret;
-}
-
-bool
-Properties::get(const char * name, const Properties ** value) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
- if(nvp->valueType == PropertiesType_Properties){
- * value = (const Properties *)nvp->value;
- setErrno(E_PROPERTIES_OK);
- return true;
- }
- setErrno(E_PROPERTIES_INVALID_TYPE);
- return false;
-}
-
-bool
-Properties::getCopy(const char * name, char ** value) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
-
- if(nvp->valueType == PropertiesType_char){
- * value = f_strdup((const char *)nvp->value);
- setErrno(E_PROPERTIES_OK);
- return true;
- }
- setErrno(E_PROPERTIES_INVALID_TYPE);
- return false;
-}
-
-bool
-Properties::getCopy(const char * name, Properties ** value) const {
- PropertyImpl * nvp = impl->get(name);
- if(nvp == 0){
- setErrno(E_PROPERTIES_NO_SUCH_ELEMENT);
- return false;
- }
-
- if(nvp->valueType == PropertiesType_Properties){
- * value = new Properties(* (const Properties *)nvp->value);
- setErrno(E_PROPERTIES_OK);
- return true;
- }
- setErrno(E_PROPERTIES_INVALID_TYPE);
- return false;
-}
-
-void
-Properties::clear(){
- while(impl->items > 0)
- impl->remove(impl->content[0]->name);
-}
-
-void
-Properties::remove(const char * name) {
- impl->remove(name);
-}
-
-void
-Properties::print(FILE * out, const char * prefix) const{
- char buf[1024];
- if(prefix == 0)
- buf[0] = 0;
- else
- strncpy(buf, prefix, 1024);
-
- for(unsigned int i = 0; i<impl->items; i++){
- switch(impl->content[i]->valueType){
- case PropertiesType_Uint32:
- 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);
- break;
- case PropertiesType_Properties:
- char buf2 [1024];
- BaseString::snprintf(buf2, sizeof(buf2), "%s%s%c",buf, impl->content[i]->name,
- Properties::delimiter);
- ((Properties *)impl->content[i]->value)->print(out, buf2);
- break;
- }
- }
-}
-
-Properties::Iterator::Iterator(const Properties* prop) :
- m_prop(prop),
- m_iterator(0) {
-}
-
-const char*
-Properties::Iterator::first() {
- m_iterator = 0;
- return next();
-}
-
-const char*
-Properties::Iterator::next() {
- if (m_iterator < m_prop->impl->items)
- return m_prop->impl->content[m_iterator++]->name;
- else
- return NULL;
-}
-
-Uint32
-Properties::getPackedSize() const {
- Uint32 sz = 0;
-
- sz += sizeof(version); // Version id of properties object
- sz += 4; // No Of Items
- sz += 4; // Checksum
-
- return sz + impl->getPackedSize(0);
-}
-
-static
-Uint32
-computeChecksum(const Uint32 * buf, Uint32 words){
- Uint32 sum = 0;
- for(unsigned int i = 0; i<words; i++)
- sum ^= htonl(buf[i]);
-
- return sum;
-}
-
-bool
-Properties::pack(Uint32 * buf) const {
- Uint32 * bufStart = buf;
-
- memcpy(buf, version, sizeof(version));
-
- // Note that version must be a multiple of 4
- buf += (sizeof(version) / 4);
-
- * buf = htonl(impl->getTotalItems());
- buf++;
- bool res = impl->pack(buf, "", 0);
- if(!res)
- return res;
-
- * buf = htonl(computeChecksum(bufStart, (buf - bufStart)));
-
- return true;
-}
-
-bool
-Properties::unpack(const Uint32 * buf, Uint32 bufLen){
- const Uint32 * bufStart = buf;
- Uint32 bufLenOrg = bufLen;
-
- if(bufLen < sizeof(version)){
- setErrno(E_PROPERTIES_INVALID_BUFFER_TO_SHORT);
- return false;
- }
-
- if(memcmp(buf, version, sizeof(version)) != 0){
- setErrno(E_PROPERTIES_INVALID_VERSION_WHILE_UNPACKING);
- return false;
- }
- bufLen -= sizeof(version);
-
- // Note that version must be a multiple of 4
- buf += (sizeof(version) / 4);
-
- if(bufLen < 4){
- setErrno(E_PROPERTIES_INVALID_BUFFER_TO_SHORT);
- return false;
- }
-
- Uint32 totalItems = ntohl(* buf);
- buf++; bufLen -= 4;
- bool res = impl->unpack(buf, bufLen, this, totalItems);
- if(!res)
- return res;
-
- Uint32 sum = computeChecksum(bufStart, (bufLenOrg-bufLen)/4);
- if(sum != ntohl(bufStart[(bufLenOrg-bufLen)/4])){
- setErrno(E_PROPERTIES_INVALID_CHECKSUM);
- return false;
- }
- return true;
-}
-
-/**
- * Methods for PropertiesImpl
- */
-PropertiesImpl::PropertiesImpl(Properties * p, bool case_insensitive){
- this->properties = p;
- items = 0;
- size = 25;
- content = new PropertyImpl * [size];
- setCaseInsensitiveNames(case_insensitive);
-}
-
-PropertiesImpl::PropertiesImpl(Properties * p, const PropertiesImpl & org){
- this->properties = p;
- this->size = org.size;
- this->items = org.items;
- this->m_insensitive = org.m_insensitive;
- this->compare = org.compare;
- content = new PropertyImpl * [size];
- for(unsigned int i = 0; i<items; i++){
- content[i] = PropertyImpl::copyPropertyImpl(* org.content[i]);
- }
-}
-
-PropertiesImpl::~PropertiesImpl(){
- for(unsigned int i = 0; i<items; i++)
- delete content[i];
- delete [] content;
-}
-
-void
-PropertiesImpl::setCaseInsensitiveNames(bool value){
- m_insensitive = value;
- if(value)
- compare = strcasecmp;
- else
- compare = strcmp;
-}
-
-void
-PropertiesImpl::grow(int sizeToAdd){
- PropertyImpl ** newContent = new PropertyImpl * [size + sizeToAdd];
- memcpy(newContent, content, items * sizeof(PropertyImpl *));
- delete [] content;
- content = newContent;
- size += sizeToAdd;
-}
-
-PropertyImpl *
-PropertiesImpl::get(const char * name) const {
- const PropertiesImpl * tmp = 0;
- const char * short_name = getProps(name, &tmp);
- if(tmp == 0){
- return 0;
- }
-
- for(unsigned int i = 0; i<tmp->items; i++) {
- if((* compare)(tmp->content[i]->name, short_name) == 0)
- return tmp->content[i];
- }
-
- return 0;
-}
-
-PropertyImpl *
-PropertiesImpl::put(PropertyImpl * nvp){
- if(items == size)
- grow(size);
- content[items] = nvp;
-
- items ++;
-
- if(nvp->valueType == PropertiesType_Properties){
- ((Properties*)nvp->value)->parent = properties;
- }
- return nvp;
-}
-
-void
-PropertiesImpl::remove(const char * name){
- for(unsigned int i = 0; i<items; i++){
- if((* compare)(content[i]->name, name) == 0){
- delete content[i];
- memmove(&content[i], &content[i+1], (items-i-1)*sizeof(PropertyImpl *));
- items --;
- return;
- }
- }
-}
-
-Uint32
-PropertiesImpl::getTotalItems() const {
- int ret = 0;
- for(unsigned int i = 0; i<items; i++)
- if(content[i]->valueType == PropertiesType_Properties){
- ret += ((Properties*)content[i]->value)->impl->getTotalItems();
- } else {
- ret ++;
- }
- return ret;
-}
-
-const char *
-PropertiesImpl::getProps(const char * name,
- const PropertiesImpl ** impl) const {
- const char * ret = name;
- const char * tmp = strchr(name, Properties::delimiter);
- if(tmp == 0){
- * impl = this;
- return ret;
- } else {
- Uint32 sz = tmp - name;
- char * tmp2 = (char*)malloc(sz + 1);
- memcpy(tmp2, name, sz);
- tmp2[sz] = 0;
-
- PropertyImpl * nvp = get(tmp2);
-
- free(tmp2);
-
- if(nvp == 0){
- * impl = 0;
- return 0;
- }
- if(nvp->valueType != PropertiesType_Properties){
- * impl = 0;
- return name;
- }
- return ((Properties*)nvp->value)->impl->getProps(tmp+1, impl);
- }
-}
-
-const char *
-PropertiesImpl::getPropsPut(const char * name,
- PropertiesImpl ** impl) {
- const char * ret = name;
- const char * tmp = strchr(name, Properties::delimiter);
- if(tmp == 0){
- * impl = this;
- return ret;
- } else {
- Uint32 sz = tmp - name;
- char * tmp2 = (char*)malloc(sz + 1);
- memcpy(tmp2, name, sz);
- tmp2[sz] = 0;
-
- PropertyImpl * nvp = get(tmp2);
-
- if(nvp == 0){
- Properties * tmpP = new Properties();
- PropertyImpl * tmpPI = new PropertyImpl(tmp2, tmpP);
- PropertyImpl * nvp2 = put(tmpPI);
-
- delete tmpP;
- free(tmp2);
- return ((Properties*)nvp2->value)->impl->getPropsPut(tmp+1, impl);
- }
- free(tmp2);
- if(nvp->valueType != PropertiesType_Properties){
- * impl = 0;
- return name;
- }
- return ((Properties*)nvp->value)->impl->getPropsPut(tmp+1, impl);
- }
-}
-
-int
-mod4(unsigned int i){
- int res = i + (4 - (i % 4));
- return res;
-}
-
-Uint32
-PropertiesImpl::getPackedSize(Uint32 pLen) const {
- Uint32 sz = 0;
- for(unsigned int i = 0; i<items; i++){
- if(content[i]->valueType == PropertiesType_Properties){
- Properties * p = (Properties*)content[i]->value;
- sz += p->impl->getPackedSize(pLen+strlen(content[i]->name)+1);
- } else {
- sz += 4; // Type
- sz += 4; // Name Len
- sz += 4; // Value Len
- sz += mod4(pLen + strlen(content[i]->name)); // Name
- switch(content[i]->valueType){
- case PropertiesType_char:
- sz += mod4(strlen((char *)content[i]->value));
- break;
- case PropertiesType_Uint32:
- sz += mod4(4);
- break;
- case PropertiesType_Uint64:
- sz += mod4(8);
- break;
- case PropertiesType_Properties:
- default:
- assert(0);
- }
- }
- }
- return sz;
-}
-
-struct CharBuf {
- char * buffer;
- Uint32 bufLen;
- Uint32 contentLen;
-
- CharBuf(){
- buffer = 0;
- bufLen = 0;
- contentLen = 0;
- }
-
- ~CharBuf(){
- free(buffer);
- }
-
- void clear() { contentLen = 0;}
- bool add(const char * str, Uint32 strLen){
- if(!expand(contentLen + strLen + 1))
- return false;
- memcpy(&buffer[contentLen], str, strLen);
- contentLen += strLen;
- buffer[contentLen] = 0;
- return true;
- }
-
- bool add(char c){
- return add(&c, 1);
- }
-
- bool expand(Uint32 newSize){
- if(newSize >= bufLen){
-
- char * tmp = (char*)malloc(newSize + 1024);
- memset(tmp, 0, newSize + 1024);
- if(tmp == 0)
- return false;
- if(contentLen > 0)
- memcpy(tmp, buffer, contentLen);
- if(buffer != 0)
- free(buffer);
- buffer = tmp;
- bufLen = newSize + 1024;
- }
- return true;
- }
-};
-
-bool
-PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const {
- CharBuf charBuf;
-
- for(unsigned int i = 0; i<items; i++){
- const int strLenName = strlen(content[i]->name);
-
- if(content[i]->valueType == PropertiesType_Properties){
- charBuf.clear();
- if(!charBuf.add(prefix, pLen)){
- properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING,
- errno);
- return false;
- }
-
- if(!charBuf.add(content[i]->name, strLenName)){
- properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING,
- errno);
- return false;
- }
-
- if(!charBuf.add(Properties::delimiter)){
- properties->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING,
- errno);
- return false;
- }
-
- if(!((Properties*)(content[i]->value))->impl->pack(buf,
- charBuf.buffer,
- charBuf.contentLen)){
-
- return false;
- }
- continue;
- }
-
- Uint32 valLenData = 0;
- Uint32 valLenWrite = 0;
- Uint32 sz = 4 + 4 + 4 + mod4(pLen + strLenName);
- switch(content[i]->valueType){
- case PropertiesType_Uint32:
- valLenData = 4;
- break;
- case PropertiesType_Uint64:
- valLenData = 8;
- break;
- case PropertiesType_char:
- valLenData = strlen((char *)content[i]->value);
- break;
- case PropertiesType_Properties:
- assert(0);
- }
- valLenWrite = mod4(valLenData);
- sz += valLenWrite;
-
- * (buf + 0) = htonl(content[i]->valueType);
- * (buf + 1) = htonl(pLen + strLenName);
- * (buf + 2) = htonl(valLenData);
-
- char * valBuf = (char*)(buf + 3);
- char * nameBuf = (char*)(buf + 3 + (valLenWrite / 4));
-
- memset(valBuf, 0, sz-12);
-
- switch(content[i]->valueType){
- 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;
- case PropertiesType_Properties:
- assert(0);
- }
- if(pLen > 0)
- memcpy(nameBuf, prefix, pLen);
- memcpy(nameBuf + pLen, content[i]->name, strLenName);
-
- buf += (sz / 4);
- }
-
- return true;
-}
-
-bool
-PropertiesImpl::unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top,
- int _items){
- CharBuf charBuf;
- while(_items > 0){
- Uint32 tmp[3];
-
- if(bufLen <= 12){
- top->setErrno(E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING);
- return false;
- }
-
- tmp[0] = ntohl(buf[0]);
- tmp[1] = ntohl(buf[1]);
- tmp[2] = ntohl(buf[2]);
- buf += 3;
- bufLen -= 12;
-
- PropertiesType pt = (PropertiesType)tmp[0];
- Uint32 nameLen = tmp[1];
- Uint32 valueLen = tmp[2];
- Uint32 nameLenRead = mod4(nameLen);
- Uint32 valueLenRead = mod4(valueLen);
-
- Uint32 sz = nameLenRead + valueLenRead;
- if(bufLen < sz){
- top->setErrno(E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING);
- return false;
- }
-
- if(!charBuf.expand(sz)){
- top->setErrno(E_PROPERTIES_ERROR_MALLOC_WHILE_UNPACKING, errno);
- return false;
- }
-
- memcpy(charBuf.buffer, buf, sz);
- buf += (sz / 4);
- bufLen -= sz ;
-
- char * valBuf = charBuf.buffer;
- char * nameBuf = charBuf.buffer + valueLenRead;
-
- nameBuf[nameLen] = 0;
- valBuf[valueLen] = 0;
-
- bool res3 = false;
- switch(pt){
- 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;
- case PropertiesType_Properties:
- assert(0);
- }
- if(!res3){
- return false;
- }
- _items--;
- }
- return true;
-}
-
-PropertyImpl::~PropertyImpl(){
- free((char*)name);
- switch(valueType){
- case PropertiesType_Uint32:
- delete (Uint32 *)value;
- break;
- case PropertiesType_Uint64:
- delete (Uint64 *)value;
- break;
- case PropertiesType_char:
- free((char *)value);
- break;
- case PropertiesType_Properties:
- delete (Properties *)value;
- break;
- }
-}
-
-PropertyImpl *
-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);
- break;
- case PropertiesType_Properties:
- return new PropertyImpl(org.name, (Properties *)org.value);
- break;
- default:
- assert(0);
- }
- return 0;
-}
-
-PropertyImpl::PropertyImpl(const char * _name, Uint32 _value){
- 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 = f_strdup(_name);
- this->value = f_strdup(_value);
- this->valueType = PropertiesType_char;
-
-}
-
-PropertyImpl::PropertyImpl(const char * _name, const Properties * _value){
- this->name = f_strdup(_name);
- this->value = new Properties(* _value);
- this->valueType = PropertiesType_Properties;
-}
-
-const Uint32 E_PROPERTIES_OK = 0;
-const Uint32 E_PROPERTIES_INVALID_NAME = 1;
-const Uint32 E_PROPERTIES_NO_SUCH_ELEMENT = 2;
-const Uint32 E_PROPERTIES_INVALID_TYPE = 3;
-const Uint32 E_PROPERTIES_ELEMENT_ALREADY_EXISTS = 4;
-
-const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING = 5;
-const Uint32 E_PROPERTIES_INVALID_VERSION_WHILE_UNPACKING = 6;
-const Uint32 E_PROPERTIES_INVALID_BUFFER_TO_SHORT = 7;
-const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_UNPACKING = 8;
-const Uint32 E_PROPERTIES_INVALID_CHECKSUM = 9;
-const Uint32 E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING = 10;
-
-/**
- * These are methods that used to be inline
- *
- * But Diab 4.1f could not compile -release with to many inlines
- */
-void
-Properties::setErrno(Uint32 pErr, Uint32 osErr) const {
- if(parent != 0){
- parent->setErrno(pErr, osErr);
- return ;
- }
-
- /**
- * propErrno & osErrno used to be mutable,
- * but diab didn't know what mutable meant.
- */
- *((Uint32*)&propErrno) = pErr;
- *((Uint32*)&osErrno) = osErr;
-}
-
-/**
- * Inlined get/put(name, no, ...) - methods
- */
-
-bool
-Properties::put(const char * name, Uint32 no, Uint32 val, bool replace){
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = put(tmp, val, replace);
- free(tmp);
- 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);
- BaseString::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){
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::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 Properties * val,
- bool replace){
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = put(tmp, val, replace);
- free(tmp);
- return res;
-}
-
-
-bool
-Properties::getTypeOf(const char * name, Uint32 no,
- PropertiesType * type) const {
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = getTypeOf(tmp, type);
- free(tmp);
- return res;
-}
-
-bool
-Properties::contains(const char * name, Uint32 no) const {
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = contains(tmp);
- free(tmp);
- return res;
-}
-
-bool
-Properties::get(const char * name, Uint32 no, Uint32 * value) const{
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::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, Uint64 * value) const{
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::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 {
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::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 Properties ** value) const{
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = get(tmp, value);
- free(tmp);
- return res;
-}
-
-
-bool
-Properties::getCopy(const char * name, Uint32 no, char ** value) const {
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = getCopy(tmp, value);
- free(tmp);
- return res;
-}
-
-
-bool
-Properties::getCopy(const char * name, Uint32 no, Properties ** value) const {
- size_t tmp_len = strlen(name)+20;
- char * tmp = (char*)malloc(tmp_len);
- BaseString::snprintf(tmp, tmp_len, "%s_%d", name, no);
- bool res = getCopy(tmp, value);
- free(tmp);
- return res;
-}
-
-void
-Properties::setCaseInsensitiveNames(bool value){
- impl->setCaseInsensitiveNames(value);
-}
-
-bool
-Properties::getCaseInsensitiveNames() const {
- return impl->m_insensitive;
-}
-
-template bool put(PropertiesImpl *, const char *, Uint32, bool);
-template bool put(PropertiesImpl *, const char *, Uint64, bool);
-template bool put(PropertiesImpl *, const char *, const char *, bool);
-template bool put(PropertiesImpl *, const char *, const Properties*, bool);
diff --git a/storage/ndb/src/common/util/SimpleProperties.cpp b/storage/ndb/src/common/util/SimpleProperties.cpp
deleted file mode 100644
index bb8c5821cd9..00000000000
--- a/storage/ndb/src/common/util/SimpleProperties.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <SimpleProperties.hpp>
-#include <NdbOut.hpp>
-#include <NdbTCP.h>
-#include <UtilBuffer.hpp>
-
-bool
-SimpleProperties::Writer::first(){
- return reset();
-}
-
-bool
-SimpleProperties::Writer::add(Uint16 key, Uint32 value){
- Uint32 head = Uint32Value;
- head <<= 16;
- head += key;
- if(!putWord(htonl(head)))
- return false;
-
- return putWord(htonl(value));
-}
-
-bool
-SimpleProperties::Writer::add(const char * value, int len){
- const Uint32 valLen = (len + 3) / 4;
-
- if ((len % 4) == 0)
- return putWords((Uint32*)value, valLen);
-
- const Uint32 putLen= valLen - 1;
- if (!putWords((Uint32*)value, putLen))
- return false;
-
- // Special handling of last bytes
- union {
- Uint32 lastWord;
- char lastBytes[4];
- } tmp;
- tmp.lastWord =0 ;
- memcpy(tmp.lastBytes,
- value + putLen*4,
- len - putLen*4);
- return putWord(tmp.lastWord);
-}
-
-bool
-SimpleProperties::Writer::add(Uint16 key, const char * value){
- Uint32 head = StringValue;
- head <<= 16;
- head += key;
- if(!putWord(htonl(head)))
- return false;
- Uint32 strLen = strlen(value) + 1; // Including NULL-byte
- if(!putWord(htonl(strLen)))
- return false;
-
- return add(value, (int)strLen);
-
-}
-
-bool
-SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
- Uint32 head = BinaryValue;
- head <<= 16;
- head += key;
- if(!putWord(htonl(head)))
- return false;
- if(!putWord(htonl(len)))
- return false;
-
- return add((const char*)value, len);
-}
-
-SimpleProperties::Reader::Reader(){
- m_itemLen = 0;
-}
-
-bool
-SimpleProperties::Reader::first(){
- reset();
- m_itemLen = 0;
- return readValue();
-}
-
-bool
-SimpleProperties::Reader::next(){
- return readValue();
-}
-
-bool
-SimpleProperties::Reader::valid() const {
- return m_type != InvalidValue;
-}
-
-Uint16
-SimpleProperties::Reader::getKey() const{
- return m_key;
-}
-
-Uint16
-SimpleProperties::Reader::getValueLen() const {
- switch(m_type){
- case Uint32Value:
- return 4;
- case StringValue:
- case BinaryValue:
- return m_strLen;
- case InvalidValue:
- return 0;
- }
- return 0;
-}
-
-SimpleProperties::ValueType
-SimpleProperties::Reader::getValueType() const {
- return m_type;
-}
-
-Uint32
-SimpleProperties::Reader::getUint32() const {
- return m_ui32_value;
-}
-
-char *
-SimpleProperties::Reader::getString(char * dst) const {
- if(peekWords((Uint32*)dst, m_itemLen))
- return dst;
- return 0;
-}
-
-bool
-SimpleProperties::Reader::readValue(){
- if(!step(m_itemLen)){
- m_type = InvalidValue;
- return false;
- }
-
- Uint32 tmp;
- if(!getWord(&tmp)){
- m_type = InvalidValue;
- return false;
- }
-
- tmp = ntohl(tmp);
- m_key = tmp & 0xFFFF;
- m_type = (SimpleProperties::ValueType)(tmp >> 16);
- switch(m_type){
- case Uint32Value:
- m_itemLen = 1;
- if(!peekWord(&m_ui32_value))
- return false;
- m_ui32_value = ntohl(m_ui32_value);
- return true;
- case StringValue:
- case BinaryValue:
- if(!getWord(&tmp))
- return false;
- m_strLen = ntohl(tmp);
- m_itemLen = (m_strLen + 3)/4;
- return true;
- default:
- m_itemLen = 0;
- m_type = InvalidValue;
- return false;
- }
-}
-
-SimpleProperties::UnpackStatus
-SimpleProperties::unpack(Reader & it, void * dst,
- const SP2StructMapping _map[], Uint32 mapSz,
- bool ignoreMinMax,
- bool ignoreUnknownKeys){
- do {
- if(!it.valid())
- break;
-
- bool found = false;
- Uint16 key = it.getKey();
- for(Uint32 i = 0; i<mapSz; i++){
- if(key == _map[i].Key){
- found = true;
- if(_map[i].Type == InvalidValue)
- return Break;
- if(_map[i].Type != it.getValueType())
- return TypeMismatch;
-
- char * _dst = (char *)dst;
- _dst += _map[i].Offset;
-
- switch(it.getValueType()){
- case Uint32Value:{
- const Uint32 val = it.getUint32();
- if(!ignoreMinMax){
- if(val < _map[i].minValue)
- return ValueTooLow;
- if(val > _map[i].maxValue)
- return ValueTooHigh;
- }
- * ((Uint32 *)_dst) = val;
- break;
- }
- case BinaryValue:
- case StringValue:{
- unsigned len = it.getValueLen();
- if(len < _map[i].minValue)
- return ValueTooLow;
- if(len > _map[i].maxValue)
- return ValueTooHigh;
- it.getString(_dst);
- break;
- }
- default:
- abort();
- }
- break;
- }
- }
- if(!found && !ignoreUnknownKeys)
- return UnknownKey;
- } while(it.next());
-
- return Eof;
-}
-
-SimpleProperties::UnpackStatus
-SimpleProperties::pack(Writer & it, const void * __src,
- const SP2StructMapping _map[], Uint32 mapSz,
- bool ignoreMinMax){
-
- const char * _src = (const char *)__src;
-
- for(Uint32 i = 0; i<mapSz; i++){
- bool ok = false;
- const char * src = _src + _map[i].Offset;
- switch(_map[i].Type){
- case SimpleProperties::InvalidValue:
- ok = true;
- break;
- case SimpleProperties::Uint32Value:{
- Uint32 val = * ((Uint32*)src);
- if(!ignoreMinMax){
- if(val < _map[i].minValue)
- return ValueTooLow;
- if(val > _map[i].maxValue)
- return ValueTooHigh;
- }
- ok = it.add(_map[i].Key, val);
- }
- break;
- case SimpleProperties::BinaryValue:{
- const char * src_len = _src + _map[i].Length_Offset;
- Uint32 len = *((Uint32*)src_len);
- if(!ignoreMinMax){
- if(len > _map[i].maxValue)
- return ValueTooHigh;
- }
- ok = it.add(_map[i].Key, src, len);
- break;
- }
- case SimpleProperties::StringValue:
- if(!ignoreMinMax){
- size_t len = strlen(src);
- if(len > _map[i].maxValue)
- return ValueTooHigh;
- }
- ok = it.add(_map[i].Key, src);
- break;
- }
- if(!ok)
- return OutOfMemory;
- }
-
- return Eof;
-}
-
-void
-SimpleProperties::Reader::printAll(NdbOut& ndbout){
- char tmp[1024];
- for(first(); valid(); next()){
- switch(getValueType()){
- case SimpleProperties::Uint32Value:
- ndbout << "Key: " << getKey()
- << " value(" << getValueLen() << ") : "
- << getUint32() << endl;
- break;
- case SimpleProperties::BinaryValue:
- case SimpleProperties::StringValue:
- if(getValueLen() < 1024){
- getString(tmp);
- ndbout << "Key: " << getKey()
- << " value(" << getValueLen() << ") : "
- << "\"" << tmp << "\"" << endl;
- } else {
- ndbout << "Key: " << getKey()
- << " value(" << getValueLen() << ") : "
- << "\"" << "<TOO LONG>" << "\"" << endl;
-
- }
- break;
- default:
- ndbout << "Unknown type for key: " << getKey()
- << " type: " << (Uint32)getValueType() << endl;
- }
- }
-}
-
-SimplePropertiesLinearReader::SimplePropertiesLinearReader
-(const Uint32 * src, Uint32 len){
- m_src = src;
- m_len = len;
- m_pos = 0;
- first();
-}
-
-void
-SimplePropertiesLinearReader::reset() {
- m_pos = 0;
-}
-
-bool
-SimplePropertiesLinearReader::step(Uint32 len){
- m_pos += len;
- return m_pos < m_len;
-}
-
-bool
-SimplePropertiesLinearReader::getWord(Uint32 * dst) {
- if(m_pos<m_len){
- * dst = m_src[m_pos++];
- return true;
- }
- return false;
-}
-
-bool
-SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
- if(m_pos<m_len){
- * dst = m_src[m_pos];
- return true;
- }
- return false;
-}
-
-bool
-SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
- if(m_pos + len <= m_len){
- memcpy(dst, &m_src[m_pos], 4 * len);
- return true;
- }
- return false;
-}
-
-LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
- m_src = src;
- m_len = len;
- reset();
-}
-
-bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}
-
-bool
-LinearWriter::putWord(Uint32 val){
- if(m_pos < m_len){
- m_src[m_pos++] = val;
- return true;
- }
- return false;
-}
-
-bool
-LinearWriter::putWords(const Uint32 * src, Uint32 len){
- if(m_pos + len <= m_len){
- memcpy(&m_src[m_pos], src, 4 * len);
- m_pos += len;
- return true;
- }
- return false;
-}
-
-Uint32
-LinearWriter::getWordsUsed() const { return m_pos;}
-
-UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
- : m_buf(b)
-{
- reset();
-}
-
-bool UtilBufferWriter::reset() { m_buf.clear(); return true;}
-
-bool
-UtilBufferWriter::putWord(Uint32 val){
- return (m_buf.append(&val, 4) == 0);
-}
-
-bool
-UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
- return (m_buf.append(src, 4 * len) == 0);
-}
-
-
-Uint32
-UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
-
-#if 0
-LinearPagesReader::LinearPagesReader(const Uint32 * base,
- Uint32 pageSize,
- Uint32 headerSize,
- Uint32 noOfPages,
- Uint32 len){
- m_base = base;
- m_pageSz = pageSize;
- m_noOfPages = noOfPages;
- m_pageHeaderSz = headerSize;
- m_len = len;
- reset();
-}
-
-void
-LinearPagesReader::reset() { m_pos = 0;}
-
-bool
-LinearPagesReader::step(Uint32 len){
- m_pos += len;
- return m_pos < m_len;
-}
-
-bool
-LinearPagesReader::getWord(Uint32 * dst) {
- if(m_pos<m_len){
- * dst = m_base[getPos(m_pos++)];
- return true;
- }
- return false;
-}
-
-bool
-LinearPagesReader::peekWord(Uint32 * dst) const {
- if(m_pos<m_len){
- * dst = m_base[getPos(m_pos)];
- return true;
- }
- return false;
-}
-
-bool
-LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
- if(m_pos + len <= m_len){
- for(Uint32 i = 0; i<len; i++)
- * (dst + i) = m_base[getPos(m_pos + i)];
- return true;
- }
- return false;
-}
-
-Uint32
-LinearPagesReader::getPos(Uint32 pos) const {
- const Uint32 sz = (m_pageSz - m_pageHeaderSz);
- Uint32 no = pos / sz;
- Uint32 in = pos % sz;
- return no * m_pageSz + m_pageHeaderSz + in;
-}
-
-LinearPagesWriter::LinearPagesWriter(Uint32 * base,
- Uint32 pageSize,
- Uint32 noOfPages,
- Uint32 headerSize){
- m_base = base;
- m_pageSz = pageSize;
- m_noOfPages = noOfPages;
- m_pageHeaderSz = headerSize;
- m_len = noOfPages * (pageSize - headerSize);
- reset();
-}
-
-bool
-LinearPagesWriter::putWord(Uint32 val){
- if(m_pos < m_len){
- m_base[getPos(m_pos++)] = val;
- return true;
- }
- return false;
-}
-
-bool
-LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
- if(m_pos + len <= m_len){
- for(Uint32 i = 0; i<len; i++)
- m_base[getPos(m_pos++)] = src[i];
- return true;
- }
- return false;
-}
-
-#if 0
-Uint32
-LinearPagesWriter::getWordsUsed() const {
- return getPos(m_pos);
-}
-#endif
-
-Uint32
-LinearPagesWriter::getPagesUsed() const {
- return m_pos / (m_pageSz - m_pageHeaderSz);
-}
-
-Uint32
-LinearPagesWriter::getPos(Uint32 pos) const {
- const Uint32 sz = (m_pageSz - m_pageHeaderSz);
- Uint32 no = pos / sz;
- Uint32 in = pos % sz;
- return no * m_pageSz + m_pageHeaderSz + in;
-}
-#endif
diff --git a/storage/ndb/src/common/util/SocketAuthenticator.cpp b/storage/ndb/src/common/util/SocketAuthenticator.cpp
deleted file mode 100644
index 6741ff17d02..00000000000
--- a/storage/ndb/src/common/util/SocketAuthenticator.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <SocketClient.hpp>
-#include <SocketAuthenticator.hpp>
-#include <InputStream.hpp>
-#include <OutputStream.hpp>
-#include <NdbOut.hpp>
-
-SocketAuthSimple::SocketAuthSimple(const char *username, const char *passwd) {
- if (username)
- m_username= strdup(username);
- else
- m_username= 0;
- if (passwd)
- m_passwd= strdup(passwd);
- else
- m_passwd= 0;
-}
-
-SocketAuthSimple::~SocketAuthSimple()
-{
- if (m_passwd)
- free((void*)m_passwd);
- if (m_username)
- free((void*)m_username);
-}
-
-bool SocketAuthSimple::client_authenticate(int sockfd)
-{
- SocketOutputStream s_output(sockfd);
- SocketInputStream s_input(sockfd);
-
- if (m_username)
- s_output.println("%s", m_username);
- else
- s_output.println("");
-
- if (m_passwd)
- s_output.println("%s", m_passwd);
- else
- s_output.println("");
-
- char buf[16];
- if (s_input.gets(buf, 16) == 0) return false;
- if (strncmp("ok", buf, 2) == 0)
- return true;
-
- return false;
-}
-
-bool SocketAuthSimple::server_authenticate(int sockfd)
-{
-
- SocketOutputStream s_output(sockfd);
- SocketInputStream s_input(sockfd);
-
- char buf[256];
-
- if (s_input.gets(buf, 256) == 0) return false;
- buf[255]= 0;
- if (m_username)
- free((void*)m_username);
- m_username= strdup(buf);
-
- if (s_input.gets(buf, 256) == 0) return false;
- buf[255]= 0;
- if (m_passwd)
- free((void*)m_passwd);
- m_passwd= strdup(buf);
-
- s_output.println("ok");
-
- return true;
-}
diff --git a/storage/ndb/src/common/util/SocketClient.cpp b/storage/ndb/src/common/util/SocketClient.cpp
deleted file mode 100644
index 2c2a39a4b01..00000000000
--- a/storage/ndb/src/common/util/SocketClient.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-
-#include <SocketClient.hpp>
-#include <SocketAuthenticator.hpp>
-
-SocketClient::SocketClient(const char *server_name, unsigned short port, SocketAuthenticator *sa)
-{
- m_auth= sa;
- m_port= port;
- m_server_name= server_name ? strdup(server_name) : 0;
- m_sockfd= NDB_INVALID_SOCKET;
- m_connect_timeout_sec= 0;
-}
-
-SocketClient::~SocketClient()
-{
- if (m_server_name)
- free(m_server_name);
- if (m_sockfd != NDB_INVALID_SOCKET)
- NDB_CLOSE_SOCKET(m_sockfd);
- if (m_auth)
- delete m_auth;
-}
-
-bool
-SocketClient::init()
-{
- if (m_sockfd != NDB_INVALID_SOCKET)
- NDB_CLOSE_SOCKET(m_sockfd);
-
- if (m_server_name)
- {
- memset(&m_servaddr, 0, sizeof(m_servaddr));
- m_servaddr.sin_family = AF_INET;
- m_servaddr.sin_port = htons(m_port);
- // Convert ip address presentation format to numeric format
- if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
- return false;
- }
-
- m_sockfd= socket(AF_INET, SOCK_STREAM, 0);
- if (m_sockfd == NDB_INVALID_SOCKET) {
- return false;
- }
-
- DBUG_PRINT("info",("NDB_SOCKET: %d", m_sockfd));
-
- return true;
-}
-
-int
-SocketClient::bind(const char* bindaddress, unsigned short localport)
-{
- if (m_sockfd == NDB_INVALID_SOCKET)
- return -1;
-
- struct sockaddr_in local;
- memset(&local, 0, sizeof(local));
- local.sin_family = AF_INET;
- local.sin_port = htons(localport);
- // Convert ip address presentation format to numeric format
- if (Ndb_getInAddr(&local.sin_addr, bindaddress))
- {
- return errno ? errno : EINVAL;
- }
-
- const int on = 1;
- if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&on, sizeof(on)) == -1) {
-
- int ret = errno;
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return ret;
- }
-
- if (::bind(m_sockfd, (struct sockaddr*)&local, sizeof(local)) == -1)
- {
- int ret = errno;
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return ret;
- }
-
- return 0;
-}
-
-NDB_SOCKET_TYPE
-SocketClient::connect(const char *toaddress, unsigned short toport)
-{
- fd_set rset, wset;
- struct timeval tval;
- int r;
- bool use_timeout;
- SOCKOPT_OPTLEN_TYPE len;
- int flags;
-
- if (m_sockfd == NDB_INVALID_SOCKET)
- {
- if (!init()) {
-#ifdef VM_TRACE
- ndbout << "SocketClient::connect() failed " << m_server_name << " " << m_port << endl;
-#endif
- return NDB_INVALID_SOCKET;
- }
- }
-
- if (toaddress)
- {
- if (m_server_name)
- free(m_server_name);
- m_server_name = strdup(toaddress);
- m_port = toport;
- memset(&m_servaddr, 0, sizeof(m_servaddr));
- m_servaddr.sin_family = AF_INET;
- m_servaddr.sin_port = htons(toport);
- // Convert ip address presentation format to numeric format
- if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
- return NDB_INVALID_SOCKET;
- }
-
- flags= fcntl(m_sockfd, F_GETFL, 0);
- fcntl(m_sockfd, F_SETFL, flags | O_NONBLOCK);
-
- r= ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
-
- if (r == 0)
- goto done; // connected immediately.
-
- if (r < 0 && (errno != EINPROGRESS)) {
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return NDB_INVALID_SOCKET;
- }
-
- FD_ZERO(&rset);
- FD_SET(m_sockfd, &rset);
- wset= rset;
- tval.tv_sec= m_connect_timeout_sec;
- tval.tv_usec= 0;
- use_timeout= m_connect_timeout_sec;
-
- if ((r= select(m_sockfd+1, &rset, &wset, NULL,
- use_timeout? &tval : NULL)) == 0)
- {
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return NDB_INVALID_SOCKET;
- }
-
- if (FD_ISSET(m_sockfd, &rset) || FD_ISSET(m_sockfd, &wset))
- {
- len= sizeof(r);
- if (getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, &r, &len) < 0 || r)
- {
- // Solaris got an error... different than others
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return NDB_INVALID_SOCKET;
- }
- }
- else
- {
- // select error, probably m_sockfd not set.
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return NDB_INVALID_SOCKET;
- }
-
-done:
- fcntl(m_sockfd, F_SETFL, flags);
-
- if (m_auth) {
- if (!m_auth->client_authenticate(m_sockfd))
- {
- NDB_CLOSE_SOCKET(m_sockfd);
- m_sockfd= NDB_INVALID_SOCKET;
- return NDB_INVALID_SOCKET;
- }
- }
- NDB_SOCKET_TYPE sockfd= m_sockfd;
- m_sockfd= NDB_INVALID_SOCKET;
-
- return sockfd;
-}
diff --git a/storage/ndb/src/common/util/SocketServer.cpp b/storage/ndb/src/common/util/SocketServer.cpp
deleted file mode 100644
index 6c634886ad8..00000000000
--- a/storage/ndb/src/common/util/SocketServer.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-
-#include <SocketServer.hpp>
-
-#include <NdbTCP.h>
-#include <NdbOut.hpp>
-#include <NdbThread.h>
-#include <NdbSleep.h>
-
-#define DEBUG(x) ndbout << x << endl;
-
-SocketServer::SocketServer(unsigned maxSessions) :
- m_sessions(10),
- m_services(5)
-{
- m_thread = 0;
- m_stopThread = false;
- m_maxSessions = maxSessions;
-}
-
-SocketServer::~SocketServer() {
- unsigned i;
- for(i = 0; i<m_sessions.size(); i++){
- delete m_sessions[i].m_session;
- }
- for(i = 0; i<m_services.size(); i++){
- if(m_services[i].m_socket)
- NDB_CLOSE_SOCKET(m_services[i].m_socket);
- delete m_services[i].m_service;
- }
-}
-
-bool
-SocketServer::tryBind(unsigned short port, const char * intface) {
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port = htons(port);
-
- if(intface != 0){
- if(Ndb_getInAddr(&servaddr.sin_addr, intface))
- return false;
- }
-
- const NDB_SOCKET_TYPE sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock == NDB_INVALID_SOCKET) {
- return false;
- }
-
- DBUG_PRINT("info",("NDB_SOCKET: %d", sock));
-
- const int on = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&on, sizeof(on)) == -1) {
- NDB_CLOSE_SOCKET(sock);
- return false;
- }
-
- if (bind(sock, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) {
- NDB_CLOSE_SOCKET(sock);
- return false;
- }
-
- NDB_CLOSE_SOCKET(sock);
- return true;
-}
-
-bool
-SocketServer::setup(SocketServer::Service * service,
- unsigned short * port,
- const char * intface){
- DBUG_ENTER("SocketServer::setup");
- DBUG_PRINT("enter",("interface=%s, port=%u", intface, *port));
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port = htons(*port);
-
- if(intface != 0){
- if(Ndb_getInAddr(&servaddr.sin_addr, intface))
- DBUG_RETURN(false);
- }
-
- const NDB_SOCKET_TYPE sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock == NDB_INVALID_SOCKET) {
- DBUG_PRINT("error",("socket() - %d - %s",
- errno, strerror(errno)));
- DBUG_RETURN(false);
- }
-
- DBUG_PRINT("info",("NDB_SOCKET: %d", sock));
-
- const int on = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&on, sizeof(on)) == -1) {
- DBUG_PRINT("error",("setsockopt() - %d - %s",
- errno, strerror(errno)));
- NDB_CLOSE_SOCKET(sock);
- DBUG_RETURN(false);
- }
-
- if (bind(sock, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) {
- DBUG_PRINT("error",("bind() - %d - %s",
- errno, strerror(errno)));
- NDB_CLOSE_SOCKET(sock);
- DBUG_RETURN(false);
- }
-
- /* Get the port we bound to */
- SOCKET_SIZE_TYPE sock_len = sizeof(servaddr);
- if(getsockname(sock,(struct sockaddr*)&servaddr,&sock_len)<0) {
- ndbout_c("An error occurred while trying to find out what"
- " port we bound to. Error: %s",strerror(errno));
- NDB_CLOSE_SOCKET(sock);
- DBUG_RETURN(false);
- }
-
- DBUG_PRINT("info",("bound to %u",ntohs(servaddr.sin_port)));
- if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){
- DBUG_PRINT("error",("listen() - %d - %s",
- errno, strerror(errno)));
- NDB_CLOSE_SOCKET(sock);
- DBUG_RETURN(false);
- }
-
- ServiceInstance i;
- i.m_socket = sock;
- i.m_service = service;
- m_services.push_back(i);
-
- *port = ntohs(servaddr.sin_port);
-
- DBUG_RETURN(true);
-}
-
-void
-SocketServer::doAccept(){
- fd_set readSet, exceptionSet;
- FD_ZERO(&readSet);
- FD_ZERO(&exceptionSet);
-
- m_services.lock();
- int maxSock = 0;
- for (unsigned i = 0; i < m_services.size(); i++){
- const NDB_SOCKET_TYPE s = m_services[i].m_socket;
- FD_SET(s, &readSet);
- FD_SET(s, &exceptionSet);
- maxSock = (maxSock > s ? maxSock : s);
- }
- struct timeval timeout;
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-
- if(select(maxSock + 1, &readSet, 0, &exceptionSet, &timeout) > 0){
- for (unsigned i = 0; i < m_services.size(); i++){
- ServiceInstance & si = m_services[i];
-
- if(FD_ISSET(si.m_socket, &readSet)){
- NDB_SOCKET_TYPE childSock = accept(si.m_socket, 0, 0);
- if(childSock == NDB_INVALID_SOCKET){
- continue;
- }
-
- SessionInstance s;
- s.m_service = si.m_service;
- s.m_session = si.m_service->newSession(childSock);
- if(s.m_session != 0)
- {
- m_session_mutex.lock();
- m_sessions.push_back(s);
- startSession(m_sessions.back());
- m_session_mutex.unlock();
- }
-
- continue;
- }
-
- if(FD_ISSET(si.m_socket, &exceptionSet)){
- DEBUG("socket in the exceptionSet");
- continue;
- }
- }
- }
- m_services.unlock();
-}
-
-extern "C"
-void*
-socketServerThread_C(void* _ss){
- SocketServer * ss = (SocketServer *)_ss;
- ss->doRun();
- return 0;
-}
-
-void
-SocketServer::startServer(){
- m_threadLock.lock();
- if(m_thread == 0 && m_stopThread == false){
- m_thread = NdbThread_Create(socketServerThread_C,
- (void**)this,
- 32768,
- "NdbSockServ",
- NDB_THREAD_PRIO_LOW);
- }
- m_threadLock.unlock();
-}
-
-void
-SocketServer::stopServer(){
- m_threadLock.lock();
- if(m_thread != 0){
- m_stopThread = true;
-
- void * res;
- NdbThread_WaitFor(m_thread, &res);
- NdbThread_Destroy(&m_thread);
- m_thread = 0;
- }
- m_threadLock.unlock();
-}
-
-void
-SocketServer::doRun(){
-
- while(!m_stopThread){
- m_session_mutex.lock();
- checkSessionsImpl();
- if(m_sessions.size() < m_maxSessions){
- m_session_mutex.unlock();
- doAccept();
- } else {
- m_session_mutex.unlock();
- NdbSleep_MilliSleep(200);
- }
- }
-}
-
-void
-SocketServer::startSession(SessionInstance & si){
- si.m_thread = NdbThread_Create(sessionThread_C,
- (void**)si.m_session,
- 32768,
- "NdbSock_Session",
- NDB_THREAD_PRIO_LOW);
-}
-
-void
-SocketServer::foreachSession(void (*func)(SocketServer::Session*, void *), void *data)
-{
- m_session_mutex.lock();
- for(int i = m_sessions.size() - 1; i >= 0; i--){
- (*func)(m_sessions[i].m_session, data);
- }
- m_session_mutex.unlock();
-}
-
-void
-SocketServer::checkSessions()
-{
- m_session_mutex.lock();
- checkSessionsImpl();
- m_session_mutex.unlock();
-}
-
-void
-SocketServer::checkSessionsImpl()
-{
- for(int i = m_sessions.size() - 1; i >= 0; i--)
- {
- if(m_sessions[i].m_session->m_stopped)
- {
- if(m_sessions[i].m_thread != 0)
- {
- void* ret;
- NdbThread_WaitFor(m_sessions[i].m_thread, &ret);
- NdbThread_Destroy(&m_sessions[i].m_thread);
- }
- m_sessions[i].m_session->stopSession();
- delete m_sessions[i].m_session;
- m_sessions.erase(i);
- }
- }
-}
-
-void
-SocketServer::stopSessions(bool wait){
- int i;
- m_session_mutex.lock();
- for(i = m_sessions.size() - 1; i>=0; i--)
- {
- m_sessions[i].m_session->stopSession();
- m_sessions[i].m_session->m_stop = true; // to make sure
- }
- m_session_mutex.unlock();
-
- for(i = m_services.size() - 1; i>=0; i--)
- m_services[i].m_service->stopSessions();
-
- if(wait){
- m_session_mutex.lock();
- while(m_sessions.size() > 0){
- checkSessionsImpl();
- m_session_mutex.unlock();
- NdbSleep_MilliSleep(100);
- m_session_mutex.lock();
- }
- m_session_mutex.unlock();
- }
-}
-
-/***** Session code ******/
-
-extern "C"
-void*
-sessionThread_C(void* _sc){
- SocketServer::Session * si = (SocketServer::Session *)_sc;
-
- /**
- * may have m_stopped set if we're transforming a mgm
- * connection into a transporter connection.
- */
- if(!si->m_stopped)
- {
- if(!si->m_stop){
- si->m_stopped = false;
- si->runSession();
- } else {
- NDB_CLOSE_SOCKET(si->m_socket);
- }
- }
-
- si->m_stopped = true;
- return 0;
-}
-
-template class MutexVector<SocketServer::ServiceInstance>;
-template class Vector<SocketServer::SessionInstance>;
diff --git a/storage/ndb/src/common/util/basestring_vsnprintf.c b/storage/ndb/src/common/util/basestring_vsnprintf.c
deleted file mode 100644
index bfe7d7ca7a2..00000000000
--- a/storage/ndb/src/common/util/basestring_vsnprintf.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifdef __sgi
-/* define on IRIX to get posix compliant vsnprintf */
-#define _XOPEN_SOURCE 500
-#endif
-#include <stdio.h>
-#include <basestring_vsnprintf.h>
-#include <my_config.h>
-
-#ifdef _WINDOWS
-#define SNPRINTF_RETURN_TRUNC
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-int
-basestring_snprintf(char *str, size_t size, const char *format, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, format);
- ret= basestring_vsnprintf(str, size, format, ap);
- va_end(ap);
- return(ret);
-}
-
-#ifdef SNPRINTF_RETURN_TRUNC
-static char basestring_vsnprintf_buf[16*1024];
-#endif
-int
-basestring_vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
- if (size == 0)
- {
-#ifdef SNPRINTF_RETURN_TRUNC
- return vsnprintf(basestring_vsnprintf_buf,
- sizeof(basestring_vsnprintf_buf),
- format, ap);
-#else
- char buf[1];
- return vsnprintf(buf, 1, format, ap);
-#endif
- }
- {
- int ret= vsnprintf(str, size, format, ap);
-#ifdef SNPRINTF_RETURN_TRUNC
- if (ret == size-1 || ret == -1)
- {
- ret= vsnprintf(basestring_vsnprintf_buf,
- sizeof(basestring_vsnprintf_buf),
- format, ap);
- }
-#endif
- return ret;
- }
-}
diff --git a/storage/ndb/src/common/util/filetest/FileUnitTest.cpp b/storage/ndb/src/common/util/filetest/FileUnitTest.cpp
deleted file mode 100644
index 8549fa26c7c..00000000000
--- a/storage/ndb/src/common/util/filetest/FileUnitTest.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "FileUnitTest.hpp"
-#include <File.hpp>
-
-#include <NdbOut.hpp>
-
-typedef bool (*TESTFUNC)(const char*);
-
-typedef const char TESTNAME;
-typedef struct
-{
- const char* name;
- TESTFUNC test;
-}Tests;
-
-static Tests testCases[] = { {"Create/Write", &FileUnitTest::testWrite},
- {"Read", &FileUnitTest::testRead},
- {"Exists", &FileUnitTest::testExists},
- {"File Size", &FileUnitTest::testSize},
- {"Rename", &FileUnitTest::testRename},
- {"Remove", &FileUnitTest::testRemove} };
-
-static int testFailed = 0;
-
-int main(int argc, char* argv[])
-{
- if (argc < 2)
- {
- ndbout << "Usage: filetest <filename>" << endl;
- return 0;
- }
- const char* fileName = argv[1];
-
- int testCount = (sizeof(testCases) / sizeof(Tests));
- ndbout << "Starting " << testCount << " tests..." << endl;
- for (int i = 0; i < testCount; i++)
- {
- ndbout << "-- " << " Test " << i + 1
- << " [" << testCases[i].name << "] --" << endl;
- if (testCases[i].test(fileName))
- {
- ndbout << "-- Passed --" << endl;
- }
- else
- {
- ndbout << "-- Failed -- " << endl;
- }
-
- }
- ndbout << endl << "-- " << testCount - testFailed << " passed, "
- << testFailed << " failed --" << endl;
- return 0;
-}
-
-
-bool
-FileUnitTest::testWrite(const char* aFileName)
-{
- bool rc = true;
- File f;
- if (f.open(aFileName, "w"))
- {
- f.writeChar("ABABABABABAB ABBABAB ABBABA ABAB JKH KJHA JHHAHAH...");
- f.writeChar("12129791242 1298371923 912738912 378129837128371128132...\n");
- f.close();
- }
- else
- {
- error("testWrite failed: ");
- rc = false;
- }
- return rc;
-}
-
-bool
-FileUnitTest::testRead(const char* aFileName)
-{
- bool rc = true;
- // Read file
- File f;
- if (f.open(aFileName, "r"))
- {
- long size = f.size();
- ndbout << "File size = " << size << endl;
- ndbout << "Allocating buf of " << size << " bytes" << endl;
- char* buf = new char[size];
- buf[size - 1] = '\0';
- int r = 0;
- while ((r = f.readChar(buf, r, size)) > 0)
- {
- ndbout << "Read(" << r << "):" << buf << endl;
- }
- f.close();
- delete buf;
- }
- else
- {
- error("readTest failed: ");
- rc = false;
- }
- return rc;
-}
-
-bool
-FileUnitTest::testExists(const char* aFileName)
-{
- bool rc = true;
- if (File::exists(aFileName))
- {
- if (File::exists("ThisFileShouldnotbe.txt"))
- {
- rc = false;
- error("testExists failed, the file should NOT be found.");
- }
- }
- else
- {
- rc = false;
- error("testExists failed, the file should exist.");
- }
-
- return rc;
-}
-
-
-bool
-FileUnitTest::testSize(const char* aFileName)
-{
- bool rc = true;
- File f;
- if (f.open(aFileName, "r"))
- {
- long size = f.size();
- if (size <= 0)
- {
- rc = false;
- error("testSize failed, size is <= 0");
- }
- ndbout << "File size = " << size << endl;
- }
- else
- {
- rc = false;
- error("testSize failed, could no open file.");
- }
- f.close();
- return rc;
-}
-
-bool
-FileUnitTest::testRename(const char* aFileName)
-{
- bool rc = true;
- if (File::rename(aFileName, "filetest_new.txt"))
- {
- if (!File::exists("filetest_new.txt"))
- {
- rc = false;
- error("testRename failed, new file does not exists.");
- }
- else
- {
- ndbout << "Renamed " << aFileName << " to filetest_new.txt" << endl;
- }
- }
- else
- {
- rc = false;
- error("testRename failed, unable to rename file.");
- }
-
- return rc;
-}
-
-bool
-FileUnitTest::testRemove(const char* aFileName)
-{
- bool rc = true;
- File f;
- if (f.open("filetest_new.txt", "r"))
- {
- if (!f.remove())
- {
- rc = false;
- error("testRemove failed, could not remove file.");
- }
- else
- {
- if (File::exists("filetest_new"))
- {
- rc = false;
- error("testRemove failed, file was not removed, it still exists.");
- }
- }
- } // (f.open("filetest_new", "r"))
- else
- {
- rc = false;
- error("testRemove failed, could not read the file.");
- }
-
- return rc;
-}
-
-void
-FileUnitTest::error(const char* msg)
-{
- testFailed++;
- ndbout << "Test failed: " << msg << endl;
- perror("Errno msg");
-}
-
-
-FileUnitTest::FileUnitTest()
-{
-
-}
-
-FileUnitTest::~FileUnitTest()
-{
-
-}
diff --git a/storage/ndb/src/common/util/filetest/FileUnitTest.hpp b/storage/ndb/src/common/util/filetest/FileUnitTest.hpp
deleted file mode 100644
index dc88c8984af..00000000000
--- a/storage/ndb/src/common/util/filetest/FileUnitTest.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef FILEUNITTEST_H
-#define FILEUNITTEST_H
-
-/**
- * Unit test of File.
- *
- * @version #@ $Id: FileUnitTest.hpp,v 1.1 2002/03/13 18:09:03 eyualex Exp $
- */
-class FileUnitTest
-{
-public:
- static bool testWrite(const char* aFileName);
- static bool testRead(const char* aFileName);
- static bool testExists(const char* aFileName);
- static bool testSize(const char* aFileName);
- static bool testRename(const char* aFileName);
- static bool testRemove(const char* aFileName);
-
- static void error(const char* msg);
-private:
- FileUnitTest();
- ~FileUnitTest();
-
-};
-#endif
diff --git a/storage/ndb/src/common/util/filetest/Makefile b/storage/ndb/src/common/util/filetest/Makefile
deleted file mode 100644
index fe1842921f9..00000000000
--- a/storage/ndb/src/common/util/filetest/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include .defs.mk
-
-TYPE :=
-
-BIN_TARGET := filetest
-BIN_TARGET_ARCHIVES := portlib general
-
-SOURCES := FileUnitTest.cpp
-
-CCFLAGS_LOC += -I$(NDB_TOP)/include/logger -I$(NDB_TOP)/include/portlib
-
-include $(NDB_TOP)/Epilogue.mk
-
-
diff --git a/storage/ndb/src/common/util/getarg.cat3 b/storage/ndb/src/common/util/getarg.cat3
deleted file mode 100644
index 31685510537..00000000000
--- a/storage/ndb/src/common/util/getarg.cat3
+++ /dev/null
@@ -1,237 +0,0 @@
-GETARG(3) OpenBSD Programmer's Manual GETARG(3)
-
-NNAAMMEE
- ggeettaarrgg, aarrgg__pprriinnttuussaaggee - collect command line options
-
-SSYYNNOOPPSSIISS
- ##iinncclluuddee <<ggeettaarrgg..hh>>
-
-
- _i_n_t
- ggeettaarrgg(_s_t_r_u_c_t _g_e_t_a_r_g_s _*_a_r_g_s, _s_i_z_e___t _n_u_m___a_r_g_s, _i_n_t _a_r_g_c, _c_h_a_r _*_*_a_r_g_v,
- _i_n_t _*_o_p_t_i_n_d);
-
-
- _v_o_i_d
- aarrgg__pprriinnttuussaaggee(_s_t_r_u_c_t _g_e_t_a_r_g_s _*_a_r_g_s, _s_i_z_e___t _n_u_m___a_r_g_s,
- _c_o_n_s_t _c_h_a_r _*_p_r_o_g_n_a_m_e, _c_o_n_s_t _c_h_a_r _*_e_x_t_r_a___s_t_r_i_n_g);
-
-
-DDEESSCCRRIIPPTTIIOONN
- ggeettaarrgg() collects any command line options given to a program in an easi­
- ly used way. aarrgg__pprriinnttuussaaggee() pretty-prints the available options, with
- a short help text.
-
- _a_r_g_s is the option specification to use, and it's an array of _s_t_r_u_c_t
- _g_e_t_a_r_g_s elements. _n_u_m___a_r_g_s is the size of _a_r_g_s (in elements). _a_r_g_c and
- _a_r_g_v are the argument count and argument vector to extract option from.
- _o_p_t_i_n_d is a pointer to an integer where the index to the last processed
- argument is stored, it must be initialised to the first index (minus one)
- to process (normally 0) before the first call.
-
- _a_r_g___p_r_i_n_t_u_s_a_g_e take the same _a_r_g_s and _n_u_m___a_r_g_s as getarg; _p_r_o_g_n_a_m_e _i_s _t_h_e
- _n_a_m_e _o_f _t_h_e _p_r_o_g_r_a_m _(_t_o _b_e progname0 _0progname1 _1progname2 _2progname3
- _3progname4 _4progname5 _e_x_t_r_a___s_t_r_i_n_g is a string to print after the actual
- options to indicate more arguments. The usefulness of this function is
- realised only be people who has used programs that has help strings that
- doesn't match what the code does.
-
- The _g_e_t_a_r_g_s struct has the following elements.
-
-
- struct getargs{
- const char *long_name;
- char short_name;
- enum { arg_integer,
- arg_string,
- arg_flag,
- arg_negative_flag,
- arg_strings,
- arg_double,
- arg_collect
- } type;
- void *value;
- const char *help;
- const char *arg_help;
- };
-
- _l_o_n_g___n_a_m_e is the long name of the option, it can be NULL, if you don't
- want a long name. _s_h_o_r_t___n_a_m_e is the characted to use as short option, it
- can be zero. If the option has a value the _v_a_l_u_e field gets filled in
- with that value interpreted as specified by the _t_y_p_e field. _h_e_l_p is a
- longer help string for the option as a whole, if it's NULL the help text
- for the option is omitted (but it's still displayed in the synopsis).
- _a_r_g___h_e_l_p is a description of the argument, if NULL a default value will
- be used, depending on the type of the option:
-
-
- arg_integer the argument is a signed integer, and _v_a_l_u_e should
- point to an _i_n_t.
-
- _a_r_g___s_t_r_i_n_g the argument is a string, and _v_a_l_u_e should point to a
- _c_h_a_r_*.
-
- _a_r_g___f_l_a_g the argument is a flag, and _v_a_l_u_e should point to a
- _i_n_t. It gets filled in with either zero or one, de­
- pending on how the option is given, the normal case
- beeing one. Note that if the option isn't given, the
- value isn't altered, so it should be initialised to
- some useful default.
-
- _a_r_g___n_e_g_a_t_i_v_e___f_l_a_g this is the same as _a_r_g___f_l_a_g but it reverses the mean­
- ing of the flag (a given short option clears the
- flag), and the synopsis of a long option is negated.
-
- _a_r_g___s_t_r_i_n_g_s the argument can be given multiple times, and the val­
- ues are collected in an array; _v_a_l_u_e should be a
- pointer to a _s_t_r_u_c_t _g_e_t_a_r_g___s_t_r_i_n_g_s structure, which
- holds a length and a string pointer.
-
- _a_r_g___d_o_u_b_l_e argument is a double precision floating point value,
- and _v_a_l_u_e should point to a _d_o_u_b_l_e.
-
- _a_r_g___c_o_l_l_e_c_t allows more fine-grained control of the option parsing
- process. _v_a_l_u_e should be a pointer to a
- _g_e_t_a_r_g___c_o_l_l_e_c_t___i_n_f_o structure:
-
- typedef int (*getarg_collect_func)(int short_opt,
- int argc,
- char **argv,
- int *optind,
- int *optarg,
- void *data);
-
- typedef struct getarg_collect_info {
- getarg_collect_func func;
- void *data;
- } getarg_collect_info;
-
- With the _f_u_n_c member set to a function to call, and
- _d_a_t_a to some application specific data. The parameters
- to the collect function are:
-
- _s_h_o_r_t___f_l_a_g non-zero if this call is via a short option
- flag, zero otherwise
-
- _a_r_g_c, _a_r_g_v the whole argument list
-
- _o_p_t_i_n_d pointer to the index in argv where the flag is
-
- _o_p_t_a_r_g pointer to the index in argv[*optind] where the
- flag name starts
-
- _d_a_t_a application specific data
-
- You can modify _*_o_p_t_i_n_d, and _*_o_p_t_a_r_g, but to do this
- correct you (more or less) have to know about the in­
- ner workings of getarg.
-
- You can skip parts of arguments by increasing _*_o_p_t_a_r_g
- (you could implement the --zz_3 set of flags from ggzziipp
- with this), or whole argument strings by increasing
- _*_o_p_t_i_n_d (let's say you want a flag --cc _x _y _z to specify
- a coordinate); if you also have to set _*_o_p_t_a_r_g to a
- sane value.
-
- The collect function should return one of
- ARG_ERR_NO_MATCH, ARG_ERR_BAD_ARG, ARG_ERR_NO_ARG on
- error, zero otherwise.
-
- For your convenience there is a function,
- ggeettaarrgg__ooppttaarrgg(), that returns the traditional argument
- string, and you pass it all arguments, sans data, that
- where given to the collection function.
-
- Don't use this more this unless you absolutely have
- to.
-
- Option parsing is similar to what getopt uses. Short options without ar­
- guments can be compressed (--xxyyzz is the same as --xx --yy --zz), and short op­
- tions with arguments take these as either the rest of the argv-string or
- as the next option (--oo_f_o_o, or --oo _f_o_o).
-
- Long option names are prefixed with -- (double dash), and the value with
- a = (equal), ----ffoooo==_b_a_r. Long option flags can either be specified as they
- are (----hheellpp), or with an (boolean parsable) option (----hheellpp==_y_e_s,
- ----hheellpp==_t_r_u_e, or similar), or they can also be negated (----nnoo--hheellpp is the
- same as ----hheellpp==no), and if you're really confused you can do it multiple
- times (----nnoo--nnoo--hheellpp==_f_a_l_s_e, or even ----nnoo--nnoo--hheellpp==_m_a_y_b_e).
-
-EEXXAAMMPPLLEE
- #include <stdio.h>
- #include <string.h>
- #include <getarg.h>
-
- char *source = "Ouagadougou";
- char *destination;
- int weight;
- int include_catalog = 1;
- int help_flag;
-
- struct getargs args[] = {
- { "source", 's', arg_string, &source,
- "source of shippment", "city" },
- { "destination", 'd', arg_string, &destination,
- "destination of shippment", "city" },
- { "weight", 'w', arg_integer, &weight,
- "weight of shippment", "tons" },
- { "catalog", 'c', arg_negative_flag, &include_catalog,
- "include product catalog" },
- { "help", 'h', arg_flag, &help_flag }
- };
-
- int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
-
- const char *progname = "ship++";
-
- int
- main(int argc, char **argv)
- {
- int optind = 0;
- if (getarg(args, num_args, argc, argv, &optind)) {
- arg_printusage(args, num_args, progname, "stuff...");
- exit (1);
- }
- if (help_flag) {
- arg_printusage(args, num_args, progname, "stuff...");
- exit (0);
- }
- if (destination == NULL) {
- fprintf(stderr, "%s: must specify destination0, progname);
- exit(1);
- }
- if (strcmp(source, destination) == 0) {
- fprintf(stderr, "%s: destination must be different from source0);
- exit(1);
- }
- /* include more stuff here ... */
- exit(2);
- }
-
- The output help output from this program looks like this:
-
- $ ship++ --help
- Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
- [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
- -s city, --source=city source of shippment
- -d city, --destination=city destination of shippment
- -w tons, --weight=tons weight of shippment
- -c, --no-catalog include product catalog
-
-
-BBUUGGSS
- It should be more flexible, so it would be possible to use other more
- complicated option syntaxes, such as what ps(1), and tar(1), uses, or the
- AFS model where you can skip the flag names as long as the options come
- in the correct order.
-
- Options with multiple arguments should be handled better.
-
- Should be integreated with SL.
-
- It's very confusing that the struct you pass in is called getargS.
-
-SSEEEE AALLSSOO
- getopt(3)
-
- ROKEN September 24, 1999 4
diff --git a/storage/ndb/src/common/util/md5_hash.cpp b/storage/ndb/src/common/util/md5_hash.cpp
deleted file mode 100644
index cf8c1bb86f0..00000000000
--- a/storage/ndb/src/common/util/md5_hash.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include "md5_hash.hpp"
-
-#ifdef WORDS_BIGENDIAN
-#define HIGHFIRST 1
-#endif
-
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * The code has been modified by Mikael Ronstroem to handle
- * calculating a hash value of a key that is always a multiple
- * of 4 bytes long. Word 0 of the calculated 4-word hash value
- * is returned as the hash value.
- */
-
-#ifndef HIGHFIRST
-#define byteReverse(buf, len) /* Nothing */
-#else
-void byteReverse(unsigned char *buf, unsigned longs);
-/*
- * Note: this code is harmless on little-endian machines.
- */
-void byteReverse(unsigned char *buf, unsigned longs)
-{
- Uint32 t;
- do {
- t = (Uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(Uint32 *) buf = t;
- buf += 4;
- } while (--longs);
-}
-#endif
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void MD5Transform(Uint32 buf[4], Uint32 const in[16])
-{
- register Uint32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void md5_hash(Uint32 result[4], const Uint64* keybuf, Uint32 no_of_32_words)
-{
- /**
- * This is the external interface of the module
- * It is assumed that keybuf is placed on 8 byte
- * alignment.
- */
- Uint32 i;
- Uint32 buf[4];
- Uint64 transform64_buf[8];
- Uint32* transform32_buf;
- Uint32 len = no_of_32_words << 2;
- const Uint64* key64buf = (const Uint64*)keybuf;
- const Uint32* key32buf = (const Uint32*)keybuf;
-
- transform32_buf = (Uint32*)&transform64_buf[0];
- buf[0] = 0x67452301;
- buf[1] = 0xefcdab89;
- buf[2] = 0x98badcfe;
- buf[3] = 0x10325476;
-
- while (no_of_32_words >= 16) {
- transform64_buf[0] = key64buf[0];
- transform64_buf[1] = key64buf[1];
- transform64_buf[2] = key64buf[2];
- transform64_buf[3] = key64buf[3];
- transform64_buf[4] = key64buf[4];
- transform64_buf[5] = key64buf[5];
- transform64_buf[6] = key64buf[6];
- transform64_buf[7] = key64buf[7];
- no_of_32_words -= 16;
- key64buf += 8;
- byteReverse((unsigned char *)transform32_buf, 16);
- MD5Transform(buf, transform32_buf);
- }
-
- key32buf = (const Uint32*)key64buf;
- transform64_buf[0] = 0;
- transform64_buf[1] = 0;
- transform64_buf[2] = 0;
- transform64_buf[3] = 0;
- transform64_buf[4] = 0;
- transform64_buf[5] = 0;
- transform64_buf[6] = 0;
- transform64_buf[7] = (Uint64)len;
-
- for (i = 0; i < no_of_32_words; i++)
- transform32_buf[i] = key32buf[i];
- transform32_buf[no_of_32_words] = 0x80000000;
-
- if (no_of_32_words < 14) {
- byteReverse((unsigned char *)transform32_buf, 16);
- MD5Transform(buf, transform32_buf);
- } else {
- if (no_of_32_words == 14)
- transform32_buf[15] = 0;
- MD5Transform(buf, transform32_buf);
- transform64_buf[0] = 0;
- transform64_buf[1] = 0;
- transform64_buf[2] = 0;
- transform64_buf[3] = 0;
- transform64_buf[4] = 0;
- transform64_buf[5] = 0;
- transform64_buf[6] = 0;
- transform64_buf[7] = (Uint64)len;
- byteReverse((unsigned char *)transform32_buf, 16);
- MD5Transform(buf, transform32_buf);
- }
-
- result[0] = buf[0];
- result[1] = buf[1];
- result[2] = buf[2];
- result[3] = buf[3];
-}
-
diff --git a/storage/ndb/src/common/util/ndb_init.c b/storage/ndb/src/common/util/ndb_init.c
deleted file mode 100644
index 4cf924840ff..00000000000
--- a/storage/ndb/src/common/util/ndb_init.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <NdbMutex.h>
-
-NdbMutex *g_ndb_connection_mutex = NULL;
-
-void
-ndb_init_internal()
-{
- if (!g_ndb_connection_mutex)
- g_ndb_connection_mutex = NdbMutex_Create();
-}
-
-int
-ndb_init()
-{
- if (my_init()) {
- const char* err = "my_init() failed - exit\n";
- write(2, err, strlen(err));
- exit(1);
- }
- ndb_init_internal();
- return 0;
-}
-
-void
-ndb_end_internal()
-{
- if (g_ndb_connection_mutex)
- NdbMutex_Destroy(g_ndb_connection_mutex);
-}
-
-void
-ndb_end(int flags)
-{
- my_end(flags);
- ndb_end_internal();
-}
diff --git a/storage/ndb/src/common/util/ndb_rand.c b/storage/ndb/src/common/util/ndb_rand.c
deleted file mode 100644
index a8e922e8bc7..00000000000
--- a/storage/ndb/src/common/util/ndb_rand.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (c) 2003, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_rand.h>
-
-static unsigned long next= 1;
-
-/**
- * ndb_rand
- *
- * constant time, cheap, pseudo-random number generator.
- *
- * NDB_RAND_MAX assumed to be 32767
- *
- * This is the POSIX example for "generating the same sequence on
- * different machines". Although that is not one of our requirements.
- */
-int ndb_rand(void)
-{
- next= next * 1103515245 + 12345;
- return((unsigned)(next/65536) % 32768);
-}
-
-void ndb_srand(unsigned seed)
-{
- next= seed;
-}
-
diff --git a/storage/ndb/src/common/util/new.cpp b/storage/ndb/src/common/util/new.cpp
deleted file mode 100644
index e307e00d510..00000000000
--- a/storage/ndb/src/common/util/new.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (C) 2004-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <ndb_global.h>
-#include <NdbMem.h>
-
-extern "C" {
- void (* ndb_new_handler)() = 0;
-}
-
-#if 0
-
-void *operator new (size_t sz)
-{
- void * p = NdbMem_Allocate(sz ? sz : 1);
- if(p)
- return p;
- if(ndb_new_handler)
- (* ndb_new_handler)();
- abort();
-}
-
-void *operator new[] (size_t sz)
-{
- void * p = (void *) NdbMem_Allocate(sz ? sz : 1);
- if(p)
- return p;
- if(ndb_new_handler)
- (* ndb_new_handler)();
- abort();
-}
-
-void operator delete (void *ptr)
-{
- if (ptr)
- NdbMem_Free(ptr);
-}
-
-void operator delete[] (void *ptr) throw ()
-{
- if (ptr)
- NdbMem_Free(ptr);
-}
-
-#endif // USE_MYSYS_NEW
diff --git a/storage/ndb/src/common/util/random.c b/storage/ndb/src/common/util/random.c
deleted file mode 100644
index e53501507c6..00000000000
--- a/storage/ndb/src/common/util/random.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/***************************************************************
-* I N C L U D E D F I L E S *
-***************************************************************/
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-
-#include <random.h>
-
-/***************************************************************
-* L O C A L C O N S T A N T S *
-***************************************************************/
-
-/***************************************************************
-* L O C A L D A T A S T R U C T U R E S *
-***************************************************************/
-
-typedef struct {
- unsigned short int x[3]; /* Current state. */
- unsigned short int a[3]; /* Factor in congruential formula. */
- unsigned short int c; /* Additive const. in congruential formula. */
- int init; /* Flag for initializing. */
-}DRand48Data;
-
-/***************************************************************
-* L O C A L F U N C T I O N S *
-***************************************************************/
-
-static void shuffleSequence(RandomSequence *seq);
-
-/***************************************************************
-* L O C A L D A T A *
-***************************************************************/
-
-static DRand48Data dRand48Data;
-
-/***************************************************************
-* P U B L I C D A T A *
-***************************************************************/
-
-
-/***************************************************************
-****************************************************************
-* L O C A L F U N C T I O N S C O D E S E C T I O N *
-****************************************************************
-***************************************************************/
-
-static void localRandom48Init(long int seedval, DRand48Data *buffer)
-{
- /* The standards say we only have 32 bits. */
- if (sizeof (long int) > 4)
- seedval &= 0xffffffffl;
-
-#if USHRT_MAX == 0xffffU
- buffer->x[2] = seedval >> 16;
- buffer->x[1] = seedval & 0xffffl;
- buffer->x[0] = 0x330e;
-
- buffer->a[2] = 0x5;
- buffer->a[1] = 0xdeec;
- buffer->a[0] = 0xe66d;
-#else
- buffer->x[2] = seedval;
- buffer->x[1] = 0x330e0000UL;
- buffer->x[0] = 0;
-
- buffer->a[2] = 0x5deecUL;
- buffer->a[1] = 0xe66d0000UL;
- buffer->a[0] = 0;
-#endif
-
- buffer->c = 0xb;
- buffer->init = 1;
-}
-
-static void localRandom48(DRand48Data *buffer, long int *result)
-{
- Uint64 X;
- Uint64 a;
- Uint64 loc_result;
-
- /*--------------------------------------*/
- /* Initialize buffer, if not yet done. */
- /*--------------------------------------*/
- if (!buffer->init) {
-#if (USHRT_MAX == 0xffffU)
- buffer->a[2] = 0x5;
- buffer->a[1] = 0xdeec;
- buffer->a[0] = 0xe66d;
-#else
- buffer->a[2] = 0x5deecUL;
- buffer->a[1] = 0xe66d0000UL;
- buffer->a[0] = 0;
-#endif
- buffer->c = 0xb;
- buffer->init = 1;
- }
-
- /* Do the real work. We choose a data type which contains at least
- 48 bits. Because we compute the modulus it does not care how
- many bits really are computed. */
-
- if (sizeof (unsigned short int) == 2) {
- X = (Uint64)buffer->x[2] << 32 |
- (Uint64)buffer->x[1] << 16 |
- buffer->x[0];
- a = ((Uint64)buffer->a[2] << 32 |
- (Uint64)buffer->a[1] << 16 |
- buffer->a[0]);
-
- loc_result = X * a + buffer->c;
-
- buffer->x[0] = loc_result & 0xffff;
- buffer->x[1] = (loc_result >> 16) & 0xffff;
- buffer->x[2] = (loc_result >> 32) & 0xffff;
- }
- else {
- X = (Uint64)buffer->x[2] << 16 |
- buffer->x[1] >> 16;
- a = (Uint64)buffer->a[2] << 16 |
- buffer->a[1] >> 16;
-
- loc_result = X * a + buffer->c;
-
- buffer->x[0] = loc_result >> 16 & 0xffffffffl;
- buffer->x[1] = loc_result << 16 & 0xffff0000l;
- }
-
- /*--------------------*/
- /* Store the result. */
- /*--------------------*/
- if (sizeof (unsigned short int) == 2)
- *result = buffer->x[2] << 15 | buffer->x[1] >> 1;
- else
- *result = buffer->x[2] >> 1;
-}
-
-static void shuffleSequence(RandomSequence *seq)
-{
- unsigned int i;
- unsigned int j;
- unsigned int tmp;
-
- if( !seq ) return;
-
- for(i = 0; i < seq->length; i++ ) {
- j = myRandom48(seq->length);
- if( i != j ) {
- tmp = seq->values[i];
- seq->values[i] = seq->values[j];
- seq->values[j] = tmp;
- }
- }
-}
-
-
-/***************************************************************
-****************************************************************
-* P U B L I C F U N C T I O N S C O D E S E C T I O N *
-****************************************************************
-***************************************************************/
-
-
-double getTps(unsigned int count, double timeValue)
-{
- double f;
-
- if( timeValue != 0.0 )
- f = count / timeValue;
- else
- f = 0.0;
-
- return(f);
-}
-
-/*----------------------------*/
-/* Random Sequences Functions */
-/*----------------------------*/
-int initSequence(RandomSequence *seq, SequenceValues *inputValues)
-{
- unsigned int i;
- unsigned int j;
- unsigned int totalLength;
- unsigned int idx;
-
- if( !seq || !inputValues ) return(-1);
-
- /*------------------------------------*/
- /* Find the total length of the array */
- /*------------------------------------*/
- totalLength = 0;
-
- for(i = 0; inputValues[i].length != 0; i++)
- totalLength += inputValues[i].length;
-
- if( totalLength == 0 ) return(-1);
-
- seq->length = totalLength;
- seq->values = calloc(totalLength, sizeof(unsigned int));
-
- if( seq->values == 0 ) return(-1);
-
- /*----------------------*/
- /* set the array values */
- /*----------------------*/
- idx = 0;
-
- for(i = 0; inputValues[i].length != 0; i++) {
- for(j = 0; j < inputValues[i].length; j++ ) {
- seq->values[idx] = inputValues[i].value;
- idx++;
- }
- }
-
- shuffleSequence(seq);
-
- seq->currentIndex = 0;
-
- return(0);
-}
-
-unsigned int getNextRandom(RandomSequence *seq)
-{
- unsigned int nextValue;
-
- nextValue = seq->values[seq->currentIndex];
-
- seq->currentIndex++;
-
- if(seq->currentIndex == seq->length){
- seq->currentIndex = 0;
- shuffleSequence(seq);
- }
-
- return nextValue;
-}
-
-void printSequence(RandomSequence *seq, unsigned int numPerRow)
-{
- unsigned int i;
-
- if( !seq ) return;
-
- for(i = 0; i<seq->length; i++) {
- ndbout_c("%d ", seq->values[i]);
-
- if((i+1) % numPerRow == 0)
- ndbout_c("");
- }
-
- if(i % numPerRow != 0)
- ndbout_c("");
-}
-
-void myRandom48Init(long int seedval)
-{
- localRandom48Init(seedval, &dRand48Data);
-}
-
-long int myRandom48(unsigned int maxValue)
-{
- long int result;
-
- localRandom48(&dRand48Data, &result);
-
- return(result % maxValue);
-}
diff --git a/storage/ndb/src/common/util/socket_io.cpp b/storage/ndb/src/common/util/socket_io.cpp
deleted file mode 100644
index 2e0d9828fa0..00000000000
--- a/storage/ndb/src/common/util/socket_io.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbTCP.h>
-#include <socket_io.h>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-extern "C"
-int
-read_socket(NDB_SOCKET_TYPE socket, int timeout_millis,
- char * buf, int buflen){
- if(buflen < 1)
- return 0;
-
- fd_set readset;
- FD_ZERO(&readset);
- FD_SET(socket, &readset);
-
- struct timeval timeout;
- timeout.tv_sec = (timeout_millis / 1000);
- timeout.tv_usec = (timeout_millis % 1000) * 1000;
-
- const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
- if(selectRes == 0)
- return 0;
-
- if(selectRes == -1){
- return -1;
- }
-
- return recv(socket, &buf[0], buflen, 0);
-}
-
-extern "C"
-int
-readln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- char * buf, int buflen, NdbMutex *mutex){
- if(buflen <= 1)
- return 0;
-
- fd_set readset;
- FD_ZERO(&readset);
- FD_SET(socket, &readset);
-
- struct timeval timeout;
- timeout.tv_sec = (timeout_millis / 1000);
- timeout.tv_usec = (timeout_millis % 1000) * 1000;
-
- if(mutex)
- NdbMutex_Unlock(mutex);
- Uint64 tick= NdbTick_CurrentMillisecond();
- const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
-
- *time= NdbTick_CurrentMillisecond() - tick;
- if(mutex)
- NdbMutex_Lock(mutex);
-
- if(selectRes == 0){
- return 0;
- }
-
- if(selectRes == -1){
- return -1;
- }
-
- char* ptr = buf;
- int len = buflen;
- do
- {
- int t;
- while((t = recv(socket, ptr, len, MSG_PEEK)) == -1 && errno == EINTR);
-
- if(t < 1)
- {
- return -1;
- }
-
-
- for(int i = 0; i<t; i++)
- {
- if(ptr[i] == '\n')
- {
- /**
- * Now consume
- */
- for (len = 1 + i; len; )
- {
- while ((t = recv(socket, ptr, len, 0)) == -1 && errno == EINTR);
- if (t < 1)
- return -1;
- ptr += t;
- len -= t;
- }
- if (i > 0 && buf[i-1] == '\r')
- {
- buf[i-1] = '\n';
- ptr--;
- }
- ptr[0]= 0;
- return ptr - buf;
- }
- }
-
- for (int tmp = t; tmp; )
- {
- while ((t = recv(socket, ptr, tmp, 0)) == -1 && errno == EINTR);
- if (t < 1)
- {
- return -1;
- }
- ptr += t;
- len -= t;
- tmp -= t;
- }
-
- FD_ZERO(&readset);
- FD_SET(socket, &readset);
- timeout.tv_sec = ((timeout_millis - *time) / 1000);
- timeout.tv_usec = ((timeout_millis - *time) % 1000) * 1000;
-
- tick= NdbTick_CurrentMillisecond();
- const int selectRes = select(socket + 1, &readset, 0, 0, &timeout);
- *time= NdbTick_CurrentMillisecond() - tick;
-
- if(selectRes != 1){
- return -1;
- }
- } while (len > 0);
-
- return -1;
-}
-
-extern "C"
-int
-write_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- const char buf[], int len){
- fd_set writeset;
- FD_ZERO(&writeset);
- FD_SET(socket, &writeset);
- struct timeval timeout;
- timeout.tv_sec = (timeout_millis / 1000);
- timeout.tv_usec = (timeout_millis % 1000) * 1000;
-
-
- Uint64 tick= NdbTick_CurrentMillisecond();
- const int selectRes = select(socket + 1, 0, &writeset, 0, &timeout);
- *time= NdbTick_CurrentMillisecond() - tick;
-
- if(selectRes != 1){
- return -1;
- }
-
- const char * tmp = &buf[0];
- while(len > 0){
- const int w = send(socket, tmp, len, 0);
- if(w == -1){
- return -1;
- }
- len -= w;
- tmp += w;
-
- if(len == 0)
- break;
-
- FD_ZERO(&writeset);
- FD_SET(socket, &writeset);
- timeout.tv_sec = ((timeout_millis - *time) / 1000);
- timeout.tv_usec = ((timeout_millis - *time) % 1000) * 1000;
-
- Uint64 tick= NdbTick_CurrentMillisecond();
- const int selectRes2 = select(socket + 1, 0, &writeset, 0, &timeout);
- *time= NdbTick_CurrentMillisecond() - tick;
-
- if(selectRes2 != 1){
- return -1;
- }
- }
-
- return 0;
-}
-
-extern "C"
-int
-print_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- const char * fmt, ...){
- va_list ap;
- va_start(ap, fmt);
- int ret = vprint_socket(socket, timeout_millis, time, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-extern "C"
-int
-println_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- const char * fmt, ...){
- va_list ap;
- va_start(ap, fmt);
- int ret = vprintln_socket(socket, timeout_millis, time, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-extern "C"
-int
-vprint_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- const char * fmt, va_list ap){
- char buf[1000];
- char *buf2 = buf;
- size_t size;
-
- if (fmt != 0 && fmt[0] != 0) {
- size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
- /* Check if the output was truncated */
- if(size > sizeof(buf)) {
- buf2 = (char *)malloc(size);
- if(buf2 == NULL)
- return -1;
- BaseString::vsnprintf(buf2, size, fmt, ap);
- }
- } else
- return 0;
-
- int ret = write_socket(socket, timeout_millis, time, buf2, size);
- if(buf2 != buf)
- free(buf2);
- return ret;
-}
-
-extern "C"
-int
-vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, int *time,
- const char * fmt, va_list ap){
- char buf[1000];
- char *buf2 = buf;
- size_t size;
-
- if (fmt != 0 && fmt[0] != 0) {
- size = BaseString::vsnprintf(buf, sizeof(buf), fmt, ap)+1;// extra byte for '/n'
- /* Check if the output was truncated */
- if(size > sizeof(buf)) {
- buf2 = (char *)malloc(size);
- if(buf2 == NULL)
- return -1;
- BaseString::vsnprintf(buf2, size, fmt, ap);
- }
- } else {
- size = 1;
- }
- buf2[size-1]='\n';
-
- int ret = write_socket(socket, timeout_millis, time, buf2, size);
- if(buf2 != buf)
- free(buf2);
- return ret;
-}
-
-#ifdef NDB_WIN32
-
-class INIT_WINSOCK2
-{
-public:
- INIT_WINSOCK2(void);
- ~INIT_WINSOCK2(void);
-
-private:
- bool m_bAcceptable;
-};
-
-INIT_WINSOCK2 g_init_winsock2;
-
-INIT_WINSOCK2::INIT_WINSOCK2(void)
-: m_bAcceptable(false)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD( 2, 2 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- /* Tell the user that we could not find a usable */
- /* WinSock DLL. */
- m_bAcceptable = false;
- }
-
- /* Confirm that the WinSock DLL supports 2.2.*/
- /* Note that if the DLL supports versions greater */
- /* than 2.2 in addition to 2.2, it will still return */
- /* 2.2 in wVersion since that is the version we */
- /* requested. */
-
- if ( LOBYTE( wsaData.wVersion ) != 2 ||
- HIBYTE( wsaData.wVersion ) != 2 ) {
- /* Tell the user that we could not find a usable */
- /* WinSock DLL. */
- WSACleanup( );
- m_bAcceptable = false;
- }
-
- /* The WinSock DLL is acceptable. Proceed. */
- m_bAcceptable = true;
-}
-
-INIT_WINSOCK2::~INIT_WINSOCK2(void)
-{
- if(m_bAcceptable)
- {
- m_bAcceptable = false;
- WSACleanup();
- }
-}
-
-#endif
-
diff --git a/storage/ndb/src/common/util/strdup.c b/storage/ndb/src/common/util/strdup.c
deleted file mode 100644
index 96b6df37712..00000000000
--- a/storage/ndb/src/common/util/strdup.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#ifndef HAVE_STRDUP
-char *
-strdup(const char *s){
- void *p2;
- if ((p2 = malloc(strlen(s)+1)))
- strcpy(p2, s);
- return p2;
-}
-#endif
diff --git a/storage/ndb/src/common/util/testConfigValues/Makefile b/storage/ndb/src/common/util/testConfigValues/Makefile
deleted file mode 100644
index 5b7400f5ee3..00000000000
--- a/storage/ndb/src/common/util/testConfigValues/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-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/storage/ndb/src/common/util/testConfigValues/testConfigValues.cpp b/storage/ndb/src/common/util/testConfigValues/testConfigValues.cpp
deleted file mode 100644
index b21133a438a..00000000000
--- a/storage/ndb/src/common/util/testConfigValues/testConfigValues.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Copyright (C) 2004 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#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/storage/ndb/src/common/util/testProperties/Makefile b/storage/ndb/src/common/util/testProperties/Makefile
deleted file mode 100644
index 343c07a49e7..00000000000
--- a/storage/ndb/src/common/util/testProperties/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include .defs.mk
-
-TYPE := util
-
-BIN_TARGET := keso
-
-SOURCES := testProperties.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/common/util/testProperties/testProperties.cpp b/storage/ndb/src/common/util/testProperties/testProperties.cpp
deleted file mode 100644
index b6f7fcb84d5..00000000000
--- a/storage/ndb/src/common/util/testProperties/testProperties.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "Properties.hpp"
-#include <NdbOut.hpp>
-
-#include "uucode.h"
-
-bool
-writeToFile(const Properties & p, const char * fname, bool uu = true){
- Uint32 sz = p.getPackedSize();
- char * buffer = (char*)malloc(sz);
-
- FILE * f = fopen(fname, "wb");
- bool res = p.pack((Uint32*)buffer);
- if(res != true){
- ndbout << "Error packing" << endl;
- ndbout << "p.getPropertiesErrno() = " << p.getPropertiesErrno() << endl;
- ndbout << "p.getOSErrno() = " << p.getOSErrno() << endl;
- }
- if(uu)
- uuencode(buffer, sz, f);
- else {
- fwrite(buffer, 1, sz, f);
- }
-
- fclose(f);
- free(buffer);
- return res;
-}
-
-bool
-readFromFile(Properties & p, const char *fname, bool uu = true){
- Uint32 sz = 30000;
- char * buffer = (char*)malloc(sz);
- FILE * f = fopen(fname, "rb");
- if(uu)
- uudecode(f, buffer, sz);
- else
- fread(buffer, 1, sz, f);
- fclose(f);
- bool res = p.unpack((Uint32*)buffer, sz);
- if(res != true){
- ndbout << "Error unpacking" << endl;
- ndbout << "p.getPropertiesErrno() = " << p.getPropertiesErrno() << endl;
- ndbout << "p.getOSErrno() = " << p.getOSErrno() << endl;
- }
- free(buffer);
- return res;
-}
-
-void putALot(Properties & tmp){
- int i = 123;
- tmp.put("LockPagesInMainMemory", i++);
- tmp.put("SleepWhenIdle", i++);
- tmp.put("NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", i++);
- tmp.put("TimeBetweenWatchDogCheck", i++);
- tmp.put("StopOnError", i++);
-
- tmp.put("MaxNoOfConcurrentOperations", i++);
- tmp.put("MaxNoOfConcurrentTransactions", i++);
- tmp.put("MemorySpaceIndexes", i++);
- tmp.put("MemorySpaceTuples", i++);
- tmp.put("MemoryDiskPages", i++);
- tmp.put("NoOfFreeDiskClusters", i++);
- tmp.put("NoOfDiskClusters", i++);
-
- tmp.put("TimeToWaitAlive", i++);
- tmp.put("HeartbeatIntervalDbDb", i++);
- tmp.put("HeartbeatIntervalDbApi", i++);
- tmp.put("TimeBetweenInactiveTransactionAbortCheck", i++);
-
- tmp.put("TimeBetweenLocalCheckpoints", i++);
- tmp.put("TimeBetweenGlobalCheckpoints", i++);
- tmp.put("NoOfFragmentLogFiles", i++);
- tmp.put("NoOfConcurrentCheckpointsDuringRestart", i++);
- tmp.put("TransactionInactiveTimeBeforeAbort", i++);
- tmp.put("NoOfConcurrentProcessesHandleTakeover", i++);
-
- tmp.put("NoOfConcurrentCheckpointsAfterRestart", i++);
-
- tmp.put("NoOfDiskPagesToDiskDuringRestartTUP", i++);
- tmp.put("NoOfDiskPagesToDiskAfterRestartTUP", i++);
- tmp.put("NoOfDiskPagesToDiskDuringRestartACC", i++);
- tmp.put("NoOfDiskPagesToDiskAfterRestartACC", i++);
-
- tmp.put("NoOfDiskClustersPerDiskFile", i++);
- tmp.put("NoOfDiskFiles", i++);
-
- // Always found
- tmp.put("NoOfReplicas", 33);
- tmp.put("MaxNoOfAttributes", 34);
- tmp.put("MaxNoOfTables", 35);
-}
-
-int
-main(void){
- Properties p;
-
- p.put("Kalle", 1);
- p.put("Ank1", "anka");
- p.put("Ank2", "anka");
- p.put("Ank3", "anka");
- p.put("Ank4", "anka");
- putALot(p);
-
- Properties tmp;
- tmp.put("Type", "TCP");
- tmp.put("OwnNodeId", 1);
- tmp.put("RemoteNodeId", 2);
- tmp.put("OwnHostName", "local");
- tmp.put("RemoteHostName", "remote");
-
- tmp.put("SendSignalId", 1);
- tmp.put("Compression", (Uint32)false);
- tmp.put("Checksum", 1);
-
- tmp.put64("SendBufferSize", 2000);
- tmp.put64("MaxReceiveSize", 1000);
-
- tmp.put("PortNumber", 1233);
- putALot(tmp);
-
- p.put("Connection", 1, &tmp);
-
- p.put("NoOfConnections", 2);
- p.put("NoOfConnection2", 2);
-
- p.put("kalle", 3);
- p.put("anka", "kalle");
-
- Properties p2;
- p2.put("kalle", "anka");
-
- p.put("prop", &p2);
-
- p.put("Connection", 2, &tmp);
-
- p.put("Connection", 3, &tmp);
-
- p.put("Connection", 4, &tmp);
- /*
- */
-
- Uint32 a = 99;
- const char * b;
- const Properties * p3;
- Properties * p4;
-
- bool bb = p.get("kalle", &a);
- bool cc = p.get("anka", &b);
- bool dd = p.get("prop", &p3);
- if(p.getCopy("prop", &p4))
- delete p4;
-
- p2.put("p2", &p2);
-
- p.put("prop2", &p2);
- /* */
-
- p.print(stdout, "testing 1: ");
-
- writeToFile(p, "A_1");
- writeToFile(p, "B_1", false);
-
- Properties r1;
- readFromFile(r1, "A_1");
- writeToFile(r1, "A_3");
-
- //r1.print(stdout, "testing 2: ");
- Properties r2;
- readFromFile(r2, "A_1");
- writeToFile(r2, "A_4");
-
- Properties r3;
- readFromFile(r3, "B_1", false);
- writeToFile(r3, "A_5");
- r3.print(stdout, "testing 3: ");
-
- return 0;
-}
diff --git a/storage/ndb/src/common/util/testSimpleProperties/Makefile b/storage/ndb/src/common/util/testSimpleProperties/Makefile
deleted file mode 100644
index 89d33fa8dd8..00000000000
--- a/storage/ndb/src/common/util/testSimpleProperties/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-include .defs.mk
-
-TYPE := util
-
-BIN_TARGET := sp_test
-BIN_TARGET_ARCHIVES := portlib general
-
-SOURCES := sp_test.cpp
-
-CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/util)
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp b/storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp
deleted file mode 100644
index d3278c63b9d..00000000000
--- a/storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "SimpleProperties.hpp"
-#include <NdbOut.hpp>
-
-Uint32 page[8192];
-
-int writer();
-int reader(Uint32 *, Uint32 len);
-int unpack(Uint32 *, Uint32 len);
-
-int main(){
- int len = writer();
- reader(page, len);
- unpack(page, len);
-
- return 0;
-}
-
-int
-writer(){
- LinearWriter w(&page[0], 8192);
-
- w.first();
- w.add(1, 2);
- w.add(7, 3);
- w.add(3, "jonas");
- w.add(5, "0123456789");
- w.add(7, 4);
- w.add(3, "e cool");
- w.add(5, "9876543210");
-
- ndbout_c("WordsUsed = %d", w.getWordsUsed());
-
- return w.getWordsUsed();
-}
-
-int
-reader(Uint32 * pages, Uint32 len){
- SimplePropertiesLinearReader it(pages, len);
-
- it.printAll(ndbout);
- return 0;
-}
-
-struct Test {
- Uint32 val1;
- Uint32 val7;
- char val3[100];
- Test() : val1(0xFFFFFFFF), val7(0xFFFFFFFF) { sprintf(val3, "bad");}
-};
-
-static const
-SimpleProperties::SP2StructMapping
-test_map [] = {
- { 1, offsetof(Test, val1), SimpleProperties::Uint32Value, 0, ~0 },
- { 7, offsetof(Test, val7), SimpleProperties::Uint32Value, 0, ~0 },
- { 3, offsetof(Test, val3), SimpleProperties::StringValue, 0, sizeof(100) },
- { 5, 0, SimpleProperties::InvalidValue, 0, 0 }
-};
-
-static unsigned
-test_map_sz = sizeof(test_map)/sizeof(test_map[0]);
-
-int
-unpack(Uint32 * pages, Uint32 len){
- Test test;
- SimplePropertiesLinearReader it(pages, len);
- SimpleProperties::UnpackStatus status;
- while((status = SimpleProperties::unpack(it, &test, test_map, test_map_sz,
- true, false)) == SimpleProperties::Break){
- ndbout << "test.val1 = " << test.val1 << endl;
- ndbout << "test.val7 = " << test.val7 << endl;
- ndbout << "test.val3 = " << test.val3 << endl;
- it.next();
- }
- assert(status == SimpleProperties::Eof);
- return 0;
-}
diff --git a/storage/ndb/src/common/util/uucode.c b/storage/ndb/src/common/util/uucode.c
deleted file mode 100644
index b861e040a5e..00000000000
--- a/storage/ndb/src/common/util/uucode.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-/* ENC is the basic 1 character encoding function to make a char printing */
-/* DEC is single character decode */
-#define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
-#define DEC(c) (((c) - ' ') & 077)
-
-/*
- * copy from in to out, encoding as you go along.
- */
-void
-uuencode(const char * data, int dataLen, FILE * out)
-{
- int ch, n;
- const char *p = data;
-
- fprintf(out, "begin\n");
-
- while (dataLen > 0){
- n = dataLen > 45 ? 45 : dataLen;
- dataLen -= n;
- ch = ENC(n);
- if (putc(ch, out) == EOF)
- break;
- for (; n > 0; n -= 3, p += 3) {
- char p_0 = * p;
- char p_1 = 0;
- char p_2 = 0;
-
- if(n >= 2){
- p_1 = p[1];
- }
- if(n >= 3){
- p_2 = p[2];
- }
-
- ch = p_0 >> 2;
- ch = ENC(ch);
- if (putc(ch, out) == EOF)
- break;
- ch = ((p_0 << 4) & 060) | ((p_1 >> 4) & 017);
- ch = ENC(ch);
- if (putc(ch, out) == EOF)
- break;
- ch = ((p_1 << 2) & 074) | ((p_2 >> 6) & 03);
- ch = ENC(ch);
- if (putc(ch, out) == EOF)
- break;
- ch = p_2 & 077;
- ch = ENC(ch);
- if (putc(ch, out) == EOF)
- break;
- }
- if (putc('\n', out) == EOF)
- break;
- }
- ch = ENC('\0');
- putc(ch, out);
- putc('\n', out);
- fprintf(out, "end\n");
-}
-
-int
-uudecode(FILE * input, char * outBuf, int bufLen){
- int n;
- char ch, *p, returnCode;
- char buf[255];
-
- returnCode = 0;
- /* search for header line */
- do {
- if (!fgets(buf, sizeof(buf), input)) {
- return 1;
- }
- } while (strncmp(buf, "begin", 5));
-
- /* for each input line */
- for (;;) {
- if (!fgets(p = buf, sizeof(buf), input)) {
- return 1;
- }
- /*
- * `n' is used to avoid writing out all the characters
- * at the end of the file.
- */
- if ((n = DEC(*p)) <= 0)
- break;
- if(n >= bufLen){
- returnCode = 1;
- break;
- }
- for (++p; n > 0; p += 4, n -= 3)
- if (n >= 3) {
- ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
- * outBuf = ch; outBuf++; bufLen--;
- ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
- * outBuf = ch; outBuf++; bufLen--;
- ch = DEC(p[2]) << 6 | DEC(p[3]);
- * outBuf = ch; outBuf++; bufLen--;
- } else {
- if (n >= 1) {
- ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
- * outBuf = ch; outBuf++; bufLen--;
- }
- if (n >= 2) {
- ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
- * outBuf = ch; outBuf++; bufLen--;
- }
- if (n >= 3) {
- ch = DEC(p[2]) << 6 | DEC(p[3]);
- * outBuf = ch; outBuf++; bufLen--;
- }
- }
- }
- if (!fgets(buf, sizeof(buf), input) || strcmp(buf, "end\n")) {
- return 1;
- }
- return returnCode;
-}
-
-int
-uuencode_mem(char * dst, const char * data, int dataLen)
-{
- int sz = 0;
-
- int ch, n;
- const char *p = data;
-
- while (dataLen > 0){
- n = dataLen > 45 ? 45 : dataLen;
- dataLen -= n;
- ch = ENC(n);
- * dst = ch; dst++; sz++;
- for (; n > 0; n -= 3, p += 3) {
- char p_0 = * p;
- char p_1 = 0;
- char p_2 = 0;
-
- if(n >= 2){
- p_1 = p[1];
- }
- if(n >= 3){
- p_2 = p[2];
- }
-
- ch = p_0 >> 2;
- ch = ENC(ch);
- * dst = ch; dst++; sz++;
-
- ch = ((p_0 << 4) & 060) | ((p_1 >> 4) & 017);
- ch = ENC(ch);
- * dst = ch; dst++; sz++;
-
- ch = ((p_1 << 2) & 074) | ((p_2 >> 6) & 03);
- ch = ENC(ch);
- * dst = ch; dst++; sz++;
-
- ch = p_2 & 077;
- ch = ENC(ch);
- * dst = ch; dst++; sz++;
- }
-
- * dst = '\n'; dst++; sz++;
- }
- ch = ENC('\0');
- * dst = ch; dst++; sz++;
-
- * dst = '\n'; dst++; sz++;
- * dst = 0; dst++; sz++;
-
- return sz;
-}
-
-int
-uudecode_mem(char * outBuf, int bufLen, const char * src){
- int n;
- char ch;
- int sz = 0;
- const char * p = src;
-
- /*
- * `n' is used to avoid writing out all the characters
- * at the end of the file.
- */
- if ((n = DEC(*p)) <= 0)
- return 0;
- if(n >= bufLen){
- return -1;
- }
- for (++p; n > 0; p += 4, n -= 3){
- if (n >= 3) {
- ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
- * outBuf = ch; outBuf++; bufLen--; sz++;
- ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
- * outBuf = ch; outBuf++; bufLen--; sz++;
- ch = DEC(p[2]) << 6 | DEC(p[3]);
- * outBuf = ch; outBuf++; bufLen--; sz++;
- } else {
- if (n >= 1) {
- ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
- * outBuf = ch; outBuf++; bufLen--; sz++;
- }
- if (n >= 2) {
- ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
- * outBuf = ch; outBuf++; bufLen--; sz++;
- }
- if (n >= 3) {
- ch = DEC(p[2]) << 6 | DEC(p[3]);
- * outBuf = ch; outBuf++; bufLen--; sz++;
- }
- }
- }
- return sz;
-}
-
-
-
diff --git a/storage/ndb/src/common/util/version.c b/storage/ndb/src/common/util/version.c
deleted file mode 100644
index 241d071b603..00000000000
--- a/storage/ndb/src/common/util/version.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_version.h>
-#include <version.h>
-#include <basestring_vsnprintf.h>
-#include <NdbEnv.h>
-#include <NdbOut.hpp>
-
-Uint32 ndbGetMajor(Uint32 version) {
- return (version >> 16) & 0xFF;
-}
-
-Uint32 ndbGetMinor(Uint32 version) {
- return (version >> 8) & 0xFF;
-}
-
-Uint32 ndbGetBuild(Uint32 version) {
- return (version >> 0) & 0xFF;
-}
-
-Uint32 ndbMakeVersion(Uint32 major, Uint32 minor, Uint32 build) {
- return NDB_MAKE_VERSION(major, minor, build);
-
-}
-
-const char * ndbGetOwnVersionString()
-{
- static char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ];
- return ndbGetVersionString(NDB_VERSION, NDB_VERSION_STATUS,
- ndb_version_string_buf,
- sizeof(ndb_version_string_buf));
-}
-
-const char * ndbGetVersionString(Uint32 version, const char * status,
- char *buf, unsigned sz)
-{
- if (status && status[0] != 0)
- basestring_snprintf(buf, sz,
- "Version %d.%d.%d (%s)",
- getMajor(version),
- getMinor(version),
- getBuild(version),
- status);
- else
- basestring_snprintf(buf, sz,
- "Version %d.%d.%d",
- getMajor(version),
- getMinor(version),
- getBuild(version));
- return buf;
-}
-
-typedef enum {
- UG_Null,
- UG_Range,
- UG_Exact
-} UG_MatchType;
-
-struct NdbUpGradeCompatible {
- Uint32 ownVersion;
- Uint32 otherVersion;
- UG_MatchType matchType;
-};
-
-/*#define TEST_VERSION*/
-
-#define HAVE_NDB_SETVERSION
-#ifdef HAVE_NDB_SETVERSION
-Uint32 ndbOwnVersionTesting = 0;
-void
-ndbSetOwnVersion() {
- char buf[256];
- if (NdbEnv_GetEnv("NDB_SETVERSION", buf, sizeof(buf))) {
- Uint32 _v1,_v2,_v3;
- if (sscanf(buf, "%u.%u.%u", &_v1, &_v2, &_v3) == 3) {
- ndbOwnVersionTesting = MAKE_VERSION(_v1,_v2,_v3);
- ndbout_c("Testing: Version set to 0x%x", ndbOwnVersionTesting);
- }
- }
-}
-#else
-void ndbSetOwnVersion() {}
-#endif
-
-#ifndef TEST_VERSION
-struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
- { MAKE_VERSION(5,4,NDB_VERSION_BUILD), MAKE_VERSION(5,1,18), UG_Range},
- { MAKE_VERSION(5,1,17), MAKE_VERSION(5,1,0), UG_Range},
- { MAKE_VERSION(5,0,NDB_VERSION_BUILD), MAKE_VERSION(5,0,12), UG_Range},
- { MAKE_VERSION(5,0,11), MAKE_VERSION(5,0,2), UG_Range},
- { MAKE_VERSION(4,1,NDB_VERSION_BUILD), MAKE_VERSION(4,1,15), UG_Range },
- { MAKE_VERSION(4,1,14), MAKE_VERSION(4,1,10), UG_Range },
- { MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact },
- { MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact },
- { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact },
- { 0, 0, UG_Null }
-};
-
-struct NdbUpGradeCompatible ndbCompatibleTable_upgrade[] = {
- { MAKE_VERSION(5,0,12), MAKE_VERSION(5,0,11), UG_Exact },
- { MAKE_VERSION(5,0,2), MAKE_VERSION(4,1,8), UG_Exact },
- { MAKE_VERSION(4,1,15), MAKE_VERSION(4,1,14), UG_Exact },
- { MAKE_VERSION(3,5,4), MAKE_VERSION(3,5,3), UG_Exact },
- { 0, 0, UG_Null }
-};
-
-#else /* testing purposes */
-
-struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
- { MAKE_VERSION(4,1,5), MAKE_VERSION(4,1,0), UG_Range },
- { MAKE_VERSION(3,6,9), MAKE_VERSION(3,6,1), UG_Range },
- { MAKE_VERSION(3,6,2), MAKE_VERSION(3,6,1), UG_Range },
- { MAKE_VERSION(3,5,7), MAKE_VERSION(3,5,0), UG_Range },
- { MAKE_VERSION(3,5,1), MAKE_VERSION(3,5,0), UG_Range },
- { NDB_VERSION_D , MAKE_VERSION(NDB_VERSION_MAJOR,NDB_VERSION_MINOR,2), UG_Range },
- { 0, 0, UG_Null }
-};
-
-struct NdbUpGradeCompatible ndbCompatibleTable_upgrade[] = {
- { MAKE_VERSION(4,1,5), MAKE_VERSION(3,6,9), UG_Exact },
- { MAKE_VERSION(3,6,2), MAKE_VERSION(3,5,7), UG_Exact },
- { MAKE_VERSION(3,5,1), NDB_VERSION_D , UG_Exact },
- { 0, 0, UG_Null }
-};
-
-
-#endif
-
-void ndbPrintVersion()
-{
- printf("Version: %u.%u.%u\n",
- getMajor(ndbGetOwnVersion()),
- getMinor(ndbGetOwnVersion()),
- getBuild(ndbGetOwnVersion()));
-}
-
-Uint32
-ndbGetOwnVersion()
-{
-#ifdef HAVE_NDB_SETVERSION
- if (ndbOwnVersionTesting == 0)
- return NDB_VERSION_D;
- else
- return ndbOwnVersionTesting;
-#else
- return NDB_VERSION_D;
-#endif
-}
-
-int
-ndbSearchUpgradeCompatibleTable(Uint32 ownVersion, Uint32 otherVersion,
- struct NdbUpGradeCompatible table[])
-{
- int i;
- for (i = 0; table[i].ownVersion != 0 && table[i].otherVersion != 0; i++) {
- if (table[i].ownVersion == ownVersion ||
- table[i].ownVersion == (Uint32) ~0) {
- switch (table[i].matchType) {
- case UG_Range:
- if (otherVersion >= table[i].otherVersion){
- return 1;
- }
- break;
- case UG_Exact:
- if (otherVersion == table[i].otherVersion){
- return 1;
- }
- break;
- default:
- break;
- }
- }
- }
- return 0;
-}
-
-int
-ndbCompatible(Uint32 ownVersion, Uint32 otherVersion, struct NdbUpGradeCompatible table[])
-{
- if (otherVersion >= ownVersion) {
- return 1;
- }
- return ndbSearchUpgradeCompatibleTable(ownVersion, otherVersion, table);
-}
-
-int
-ndbCompatible_full(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible(ownVersion, otherVersion, ndbCompatibleTable_full);
-}
-
-int
-ndbCompatible_upgrade(Uint32 ownVersion, Uint32 otherVersion)
-{
- if (ndbCompatible_full(ownVersion, otherVersion))
- return 1;
- return ndbCompatible(ownVersion, otherVersion, ndbCompatibleTable_upgrade);
-}
-
-int
-ndbCompatible_mgmt_ndb(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_upgrade(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_mgmt_api(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_upgrade(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_ndb_mgmt(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_full(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_api_mgmt(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_full(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_api_ndb(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_full(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_ndb_api(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_upgrade(ownVersion, otherVersion);
-}
-
-int
-ndbCompatible_ndb_ndb(Uint32 ownVersion, Uint32 otherVersion)
-{
- return ndbCompatible_upgrade(ownVersion, otherVersion);
-}
diff --git a/storage/ndb/src/cw/Makefile.am b/storage/ndb/src/cw/Makefile.am
deleted file mode 100644
index f354846a5b6..00000000000
--- a/storage/ndb/src/cw/Makefile.am
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = cpcd
-
-windoze-dsp:
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp
deleted file mode 100644
index 068416b2f15..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "stdafx.h"
-
-HINSTANCE hInst ;
-TCHAR szTitle[MAX_LOADSTRING] ;
-TCHAR szWindowClass[MAX_LOADSTRING] ;
-
-static CNdbControls controls ;
-
-int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow){
- MSG msg;
- HACCEL hAccelTable;
-
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING) ;
- LoadString(hInstance, IDC_CPC_GUI, szWindowClass, MAX_LOADSTRING) ;
- NdbRegisterClass(hInstance);
-
- if (!InitInstance (hInstance, nCmdShow)) {
- return FALSE;
- }
-
- hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CPC_GUI);
-
- while (GetMessage(&msg, NULL, 0, 0)){
-
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){
-
- TranslateMessage(&msg);
- DispatchMessage(&msg);
-
- }
-
- }
-
- return msg.wParam;
-}
-
-
-ATOM NdbRegisterClass(HINSTANCE hInstance){
- WNDCLASSEX wcex;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
-
- wcex.style = CS_HREDRAW | CS_VREDRAW ;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CPC_GUI);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
- wcex.lpszMenuName = (LPCSTR)IDC_CPC_GUI;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
-
- return RegisterClassEx(&wcex);
-}
-
-
-BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
-
- HWND hWnd;
-
- hInst = hInstance;
-
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
-
- InitCommonControls();
-
- if (!hWnd) return FALSE ;
-
- ShowWindow(hWnd, nCmdShow) ;
- UpdateWindow(hWnd) ;
-
- return TRUE;
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
-
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- int c = 0 ;
-
- switch (message)
- {
-
- case WM_CREATE:
- _assert(controls.Create(hInst, hWnd)) ;
- return 0 ;
-
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
-
- switch (wmId){
- case IDM_ABOUT:
- DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR) lParam)->code) {
- case TTN_GETDISPINFO: {
-
- LPTOOLTIPTEXT lpttt;
- lpttt = (LPTOOLTIPTEXT) lParam;
- lpttt->hinst = hInst;
-
- int idButton = lpttt->hdr.idFrom;
-
- switch (idButton){
- case IDM_NEW:
- lpttt->lpszText = MAKEINTRESOURCE(IDS_TIP_NEW);
- break;
- case IDM_DELETE:
- lpttt->lpszText = MAKEINTRESOURCE(IDS_TIP_DELETE);
- break;
- case IDM_PROPS:
- lpttt->lpszText = MAKEINTRESOURCE(IDS_TIP_PROPS);
- break;
- }
- break;
- }
- case TVN_SELCHANGED: {
- LPNMTREEVIEW pnmtv ;
-
- pnmtv = (LPNMTREEVIEW) lParam ;
- controls.ToggleListViews(pnmtv) ;
-
- break ;
- }
-
- case NM_RCLICK: {
- LPNMHDR lpnmh ;
- lpnmh = (LPNMHDR) lParam ;
- switch(lpnmh->idFrom){
- case ID_TREEVIEW:
- break;
- default:
- break ;
- }
- }
-
- default:
- break;
- }
-
-
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps) ;
- EndPaint(hWnd, &ps);
- break;
-
- case WM_SIZE:
- controls.Resize() ;
- return 0 ;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
-}
-
-
-LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){
-
- switch (message){
-
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){
- EndDialog(hDlg, LOWORD(wParam));
- return TRUE;
- }
- break;
- }
- return FALSE;
-}
-
-
-
-
-
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsp b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsp
deleted file mode 100644
index 91007b0a47e..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsp
+++ /dev/null
@@ -1,216 +0,0 @@
-# Microsoft Developer Studio Project File - Name="CPC_GUI" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Application" 0x0101
-
-CFG=CPC_GUI - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "CPC_GUI.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "CPC_GUI.mak" CFG="CPC_GUI - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "CPC_GUI - Win32 Release" (based on "Win32 (x86) Application")
-!MESSAGE "CPC_GUI - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "CPC_GUI - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc42.lib /nologo /subsystem:windows /machine:I386
-
-!ELSEIF "$(CFG)" == "CPC_GUI - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /Yu"stdafx.h" /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib comctl32.lib mfc42d.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "CPC_GUI - Win32 Release"
-# Name "CPC_GUI - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\CPC_GUI.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\CPC_GUI.rc
-# End Source File
-# Begin Source File
-
-SOURCE=.\NdbControls.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\StdAfx.cpp
-# ADD CPP /Yc"stdafx.h"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\CPC_GUI.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\NdbControls.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\resource.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\StdAfx.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=.\bitmap1.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\bmp00001.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\C.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Closed.BMP
-# End Source File
-# Begin Source File
-
-SOURCE=.\Closed.ICO
-# End Source File
-# Begin Source File
-
-SOURCE=.\Closed24.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Computer24.BMP
-# End Source File
-# Begin Source File
-
-SOURCE=.\CPC_GUI.ico
-# End Source File
-# Begin Source File
-
-SOURCE=.\Db.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\icon1.ico
-# End Source File
-# Begin Source File
-
-SOURCE=.\O.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Open.BMP
-# End Source File
-# Begin Source File
-
-SOURCE=.\Open.ICO
-# End Source File
-# Begin Source File
-
-SOURCE=.\Open24.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\small.ico
-# End Source File
-# Begin Source File
-
-SOURCE=.\toolbar.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\toolbar1.bmp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Tower2.ICO
-# End Source File
-# Begin Source File
-
-SOURCE=.\TowerIC1.BMP
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\ReadMe.txt
-# End Source File
-# End Target
-# End Project
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsw b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsw
deleted file mode 100644
index 1f163a31662..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "CPC_GUI"=.\CPC_GUI.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h
deleted file mode 100644
index bbf5115510a..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#if !defined(AFX_CPC_GUI_H__EA01C861_C56D_48F1_856F_4935E20620B1__INCLUDED_)
-#define AFX_CPC_GUI_H__EA01C861_C56D_48F1_856F_4935E20620B1__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-
-#define MAX_LOADSTRING 100
-
-
-
-#define TV_ROOT_ITEMS 2
-
-
-// Global Variables
-
-ATOM NdbRegisterClass(HINSTANCE) ;
-BOOL InitInstance(HINSTANCE, int) ;
-LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;
-LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
-
-#endif // !defined(AFX_CPC_GUI_H__EA01C861_C56D_48F1_856F_4935E20620B1__INCLUDED_)
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.ico b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.ico
deleted file mode 100644
index 386883523bc..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.ico
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.rc b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.rc
deleted file mode 100644
index 41d75b2b282..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.rc
+++ /dev/null
@@ -1,193 +0,0 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#define APSTUDIO_HIDDEN_SYMBOLS
-#include "windows.h"
-#undef APSTUDIO_HIDDEN_SYMBOLS
-#include "resource.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_CPC_GUI ICON DISCARDABLE "CPC_GUI.ICO"
-IDI_SMALL ICON DISCARDABLE "SMALL.ICO"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Menu
-//
-
-IDM_CPC_GUI MENU DISCARDABLE
-BEGIN
- POPUP "&File"
- BEGIN
- MENUITEM "E&xit", IDM_EXIT
- END
- POPUP "&Actions"
- BEGIN
- MENUITEM "&Insert...", ID_ACTIONS_INSERT
- MENUITEM "&Delete", ID_ACTIONS_DELETE
- MENUITEM "&Properties", ID_ACTIONS_PROPERTIES
- END
- POPUP "&Help"
- BEGIN
- MENUITEM "&About ...", IDM_ABOUT
- END
-END
-
-IDM_TREEVIEW MENU DISCARDABLE
-BEGIN
- MENUITEM "&Insert", ID_TREEVIEW1
- MENUITEM "&Delete", ID_DELETE
- MENUITEM "&Properties", ID_PROPERTIES
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Accelerator
-//
-
-IDC_CPC_GUI ACCELERATORS MOVEABLE PURE
-BEGIN
- "?", IDM_ABOUT, ASCII, ALT
- "/", IDM_ABOUT, ASCII, ALT
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75
-STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
-CAPTION "About"
-FONT 8, "MS Sans Serif"
-BEGIN
- LTEXT "NDB Cluster Process Control Applet v1.0",IDC_STATIC,7,8,
- 213,8,SS_NOPREFIX
- LTEXT "Copyright (C) 2003 MySQL AB",
- IDC_STATIC,7,20,213,20
- DEFPUSHBUTTON "OK",IDOK,185,55,41,16,WS_GROUP
-END
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-2 TEXTINCLUDE MOVEABLE PURE
-BEGIN
- "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
- "#include ""windows.h""\r\n"
- "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
- "#include ""resource.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE MOVEABLE PURE
-BEGIN
- "\r\n"
- "\0"
-END
-
-1 TEXTINCLUDE MOVEABLE PURE
-BEGIN
- "resource.h\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Bitmap
-//
-
-IDR_TOOLBAR BITMAP MOVEABLE PURE "toolbar.bmp"
-IDB_TOOLBAR BITMAP MOVEABLE PURE "bitmap1.bmp"
-IDB_COMPUTER BITMAP MOVEABLE PURE "TowerIC1.BMP"
-IDB_OPEN BITMAP MOVEABLE PURE "Open.BMP"
-IDB_CLOSED BITMAP MOVEABLE PURE "Closed.BMP"
-IDB_DATABASE BITMAP MOVEABLE PURE "DB.bmp"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Toolbar
-//
-
-IDR_TOOLBAR TOOLBAR MOVEABLE PURE 18, 18
-BEGIN
- BUTTON ID_BUTTON32773
- BUTTON ID_BUTTON32783
- BUTTON ID_BUTTON32784
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// String Table
-//
-
-STRINGTABLE DISCARDABLE
-BEGIN
- IDS_APP_TITLE "NDB Cluster Process Control Applet"
- IDS_TV_ROOT_COMPUTERS "Computers"
- IDS_TV_ROOT_DATABASES "Databases"
- IDS_LV_COMPUTER_HEADER_1 "Computer"
- IDS_LV_COMPUTER_HEADER_2 "Hostname"
- IDS_LV_PROCESS_HEADER_1 "Process"
- IDC_CPC_GUI "CPC_GUI"
- IDS_TIP_NEW "Add new computer or database"
- IDS_TIP_DELETE "Delete selected computer or database"
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- IDS_TIP_PROPS "Display properties for selected computer or database"
- IDS_LV_PROCESS_HEADER_2 "Name"
- IDS_LV_PROCESS_HEADER_3 "Owner"
- IDS_LV_PROCESS_HEADER_4 "Status"
- IDS_LV_COMPUTER_HEADER_3 "Status"
-END
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.sln b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.sln
deleted file mode 100644
index 86b574d851d..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPC_GUI", "CPC_GUI.vcproj", "{F5FADD9D-4353-4A73-88DC-474A4D17B485}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {F5FADD9D-4353-4A73-88DC-474A4D17B485}.Debug.ActiveCfg = Debug|Win32
- {F5FADD9D-4353-4A73-88DC-474A4D17B485}.Debug.Build.0 = Debug|Win32
- {F5FADD9D-4353-4A73-88DC-474A4D17B485}.Release.ActiveCfg = Release|Win32
- {F5FADD9D-4353-4A73-88DC-474A4D17B485}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.suo b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.suo
deleted file mode 100644
index e7d178f04c3..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.suo
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.vcproj b/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.vcproj
deleted file mode 100644
index fb1e2fd601c..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.vcproj
+++ /dev/null
@@ -1,240 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="CPC_GUI"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\release_obj"
- IntermediateDirectory=".\release_obj"
- ConfigurationType="1"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="3"
- PrecompiledHeaderThrough="stdafx.h"
- PrecompiledHeaderFile=".\release_obj/CPC_GUI.pch"
- AssemblerListingLocation=".\release_obj/"
- ObjectFile=".\release_obj/"
- ProgramDataBaseFileName=".\release_obj/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="mfc42.lib"
- OutputFile=".\release_obj/CPC_GUI.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- ProgramDatabaseFile=".\release_obj/CPC_GUI.pdb"
- SubSystem="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\release_obj/CPC_GUI.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\debug_obj"
- IntermediateDirectory=".\debug_obj"
- ConfigurationType="1"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="3"
- PrecompiledHeaderThrough="stdafx.h"
- PrecompiledHeaderFile=".\debug_obj/CPC_GUI.pch"
- AssemblerListingLocation=".\debug_obj/"
- ObjectFile=".\debug_obj/"
- ProgramDataBaseFileName=".\debug_obj/"
- BrowseInformation="1"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="comctl32.lib mfc70d.lib"
- OutputFile=".\debug_obj/CPC_GUI.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\debug_obj/CPC_GUI.pdb"
- SubSystem="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\debug_obj/CPC_GUI.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath=".\CPC_GUI.cpp">
- </File>
- <File
- RelativePath=".\CPC_GUI.rc">
- </File>
- <File
- RelativePath=".\NdbControls.cpp">
- </File>
- <File
- RelativePath=".\StdAfx.cpp">
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"/>
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath=".\CPC_GUI.h">
- </File>
- <File
- RelativePath=".\NdbControls.h">
- </File>
- <File
- RelativePath=".\StdAfx.h">
- </File>
- <File
- RelativePath=".\resource.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- <File
- RelativePath=".\C.bmp">
- </File>
- <File
- RelativePath=".\CPC_GUI.ico">
- </File>
- <File
- RelativePath=".\Closed.BMP">
- </File>
- <File
- RelativePath=".\Closed.ICO">
- </File>
- <File
- RelativePath=".\Closed24.bmp">
- </File>
- <File
- RelativePath=".\Computer24.BMP">
- </File>
- <File
- RelativePath=".\Db.bmp">
- </File>
- <File
- RelativePath=".\O.bmp">
- </File>
- <File
- RelativePath=".\Open.BMP">
- </File>
- <File
- RelativePath=".\Open.ICO">
- </File>
- <File
- RelativePath=".\Open24.bmp">
- </File>
- <File
- RelativePath=".\Tower2.ICO">
- </File>
- <File
- RelativePath=".\TowerIC1.BMP">
- </File>
- <File
- RelativePath=".\bitmap1.bmp">
- </File>
- <File
- RelativePath=".\bmp00001.bmp">
- </File>
- <File
- RelativePath=".\icon1.ico">
- </File>
- <File
- RelativePath=".\small.ico">
- </File>
- <File
- RelativePath=".\toolbar.bmp">
- </File>
- <File
- RelativePath=".\toolbar1.bmp">
- </File>
- </Filter>
- <File
- RelativePath=".\ReadMe.txt">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/Closed.ICO b/storage/ndb/src/cw/cpcc-win32/C++/Closed.ICO
deleted file mode 100644
index 044042b42fb..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/Closed.ICO
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp b/storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp
deleted file mode 100644
index 63383ad0990..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "stdafx.h"
-#include "NdbControls.h"
-
-
-/**
-* CNdbControl implementation
-*/
-
-BOOL CNdbControl::GetRect(LPRECT lprc) const {
-
- _ASSERT(this) ;
-
- return GetClientRect(m_hControl, lprc) ;
-
-}
-
-BOOL CNdbControl::Resize(LONG x, LONG y, LONG w, LONG h) const {
-
- _ASSERT(this) ;
-
- if(!MoveWindow(m_hControl, x, y, w, h, TRUE))
- return FALSE ;
- if(m_bVisible){
- ShowWindow(m_hControl, SW_SHOW) ;
- UpdateWindow(m_hControl) ;
- }
- return TRUE ;
-
-}
-
-BOOL CNdbControl::Show(BOOL bShow) {
-
- _ASSERT(this) ;
-
- if(bShow){
- ShowWindow(m_hControl, SW_SHOW);
- m_bVisible = TRUE ;
- }else{
- ShowWindow(m_hControl, SW_HIDE);
- m_bVisible = FALSE ;
- }
- EnableWindow(m_hControl, bShow) ;
- UpdateWindow(m_hControl) ;
-
- return TRUE ;
-}
-
-
-
-CNdbControl::~CNdbControl(){
-
- DestroyWindow(m_hControl) ;
- if(m_hMenu)
- DestroyMenu(m_hMenu) ;
-
-}
-
-
-/**
-* CNdbListView implementation
-*/
-
-BOOL CNdbListView::Create(HINSTANCE hInst, HWND hParent, DWORD dwId, NDB_ITEM_TYPE enType, PNDB_LV pstH, DWORD dwWidth) {
-
- if(!pstH)
- return FALSE ;
-
- LV_COLUMN lvC ;
- m_hInstance = hInst ;
- m_hParent = hParent ;
- m_dwId = dwId ;
- m_dwWidth = dwWidth ;
- m_dwWidth = 100 ;
- m_enType = enType;
- char* szLabels[MAX_LV_HEADERS] ;
- int count = 0 ;
-
- m_hControl = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, WC_LISTVIEW, TEXT(""),
- WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT,
- 0, 0, 0, 0, m_hParent, (HMENU)m_dwId, hInst, NULL );
-
- if(!m_hControl)
- return FALSE ;
-
- lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
- lvC.fmt = LVCFMT_LEFT;
-
- switch(enType){
- case ITEM_COMPR_ROOT:
- szLabels[0] = pstH->szComputer ;
- szLabels[1] = pstH->szHostname ;
- szLabels[2] = pstH->szStatus ;
- count = 3 ;
- break ;
- case ITEM_DB_ROOT:
- szLabels[0] = pstH->szDatabase ;
- szLabels[1] = pstH->szStatus ;
- count = 2 ;
- break ;
- case ITEM_COMPR:
- szLabels[0] = pstH->szProcess ;
- szLabels[1] = pstH->szDatabase;
- szLabels[2] = pstH->szOwner ;
- szLabels[3] = pstH->szStatus ;
- count = 4 ;
- case ITEM_DB:
- szLabels[0] = pstH->szProcess ;
- szLabels[1] = pstH->szComputer;
- szLabels[2] = pstH->szOwner ;
- szLabels[3] = pstH->szStatus ;
- count = 4 ;
- break ;
- NDB_DEFAULT_UNREACHABLE ;
- }
-
- for(int j = 0 ; j < count ; ++j){
- lvC.iSubItem = j ;
- lvC.cx = m_dwWidth ;
- lvC.pszText = szLabels[j] ;
- if(0xFFFFFFFF == ListView_InsertColumn(m_hControl, j, &lvC))
- return FALSE ;
- }
-
- SendMessage(m_hControl, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT,
- LVS_EX_FULLROWSELECT );
-
- ShowWindow(m_hControl, SW_SHOW) ;
-
- return TRUE ;
-
-}
-
-
-
-/**
-* CNdbToolBar implementation
-*/
-
-
-
-/**
-* CNdbTreeView implementation
-*/
-
-BOOL CNdbTreeView::Create(HINSTANCE hInst, HWND hParent, DWORD dwMenuId, DWORD dwId){
-
- if(!CreateTreeView(hInst, hParent, dwId))
- return FALSE ;
-
- m_hMenu = LoadMenu(m_hInstance,MAKEINTRESOURCE(dwMenuId)) ;
- if(!m_hMenu)
- return FALSE ;
-
- return TRUE ;
-}
-
-
-BOOL CNdbTreeView::CreateTreeView(HINSTANCE hInst, HWND hParent, DWORD dwId){
-
-
- m_hInstance = hInst ;
- m_hParent = hParent ;
- m_dwId = dwId ;
- HIMAGELIST himl ;
- HBITMAP hbmp ;
- DWORD dwCount = 0 ;
-
- m_hControl = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, WC_TREEVIEW, "Tree View",
- WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES |
- TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SINGLEEXPAND,
- 0, 0, 0, 0, m_hParent, (HMENU)m_dwId, m_hInstance, NULL) ;
-
- if(!m_hControl)
- return FALSE ;
-
- if((himl = ImageList_Create(nX, nY, ILC_MASK | ILC_COLOR8, 4, 0)) == NULL)
- return FALSE ;
-
- hbmp = LoadBitmap(m_hInstance, MAKEINTRESOURCE(IDI_OPEN));
- hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_OPEN), IMAGE_BITMAP, nX, 0, LR_DEFAULTSIZE);
- m_nOpen = ImageList_AddMasked(himl, hbmp, clr);
- DeleteObject(hbmp);
- hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_CLOSED), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
- m_nClosed = ImageList_AddMasked(himl, hbmp, clr);
- DeleteObject(hbmp);
- hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_COMPUTER),IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
- m_nComputer = ImageList_AddMasked(himl, hbmp, clr);
- DeleteObject(hbmp);
- hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_DATABASE), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
- m_nDatabase = ImageList_AddMasked(himl, hbmp, clr);
- DeleteObject(hbmp);
-
- if(ImageList_GetImageCount(himl) < 4)
- return FALSE ;
-
- TreeView_SetImageList(m_hControl, himl, TVSIL_NORMAL);
-
- ShowWindow(m_hControl, SW_SHOW) ;
-
- return TRUE ;
-
-}
-
-
-
-HTREEITEM CNdbTreeView::AddItem(LPSTR szText, NDB_ITEM_TYPE enType, DWORD dwLVId){
-
- TVITEM tvi ;
- TVINSERTSTRUCT tvins ;
- HTREEITEM hti ;
- HTREEITEM hTemp ;
- int nImage = m_nClosed ;
-
- tvi.mask = TVIF_TEXT | TVIF_IMAGE
- | TVIF_SELECTEDIMAGE | TVIF_PARAM;
-
- tvi.pszText = szText;
- tvi.cchTextMax = lstrlen(szText);
-
- switch(enType){
-
- case ITEM_COMPR_ROOT:
- nImage = m_nClosed ;
- if(!m_hPrevRoot)
- tvins.hParent = TVI_ROOT;
- else
- tvins.hInsertAfter = m_hPrevRoot ;
- break ;
-
- case ITEM_DB_ROOT:
- if(!m_hPrevRoot)
- tvins.hParent = TVI_ROOT;
- else
- tvins.hInsertAfter = m_hPrevRoot ;
- break ;
-
- case ITEM_COMPR:
- nImage = m_nComputer ;
- if(!m_hPrevComputersChild || !m_hComputersRoot)
- return 0 ;
- else
- tvins.hInsertAfter = m_hPrevComputersChild ;
- tvins.hParent = m_hComputersRoot ;
- break ;
-
- case ITEM_DB:
- nImage = m_nDatabase ;
- if(!m_hPrevComputersChild || !m_hComputersRoot)
- return 0 ;
- else
- tvins.hInsertAfter = m_hPrevDatabasesChild ;
- tvins.hParent = m_hDatabasesRoot ;
- break ;
-
- NDB_DEFAULT_UNREACHABLE ;
-
- }
-
- tvi.iImage = nImage ;
- tvi.iSelectedImage = nImage ;
- tvi.lParam = (LPARAM) dwLVId ;
- tvins.item = tvi ;
-
- hTemp = TreeView_InsertItem(m_hControl, &tvins);
- if(!hTemp)
- return NULL ;
-
- switch(enType){
-
- case ITEM_COMPR_ROOT:
- m_hComputersRoot = hTemp ;
- break ;
-
- case ITEM_DB_ROOT:
- m_hDatabasesRoot = hTemp ;
- break ;
-
- case ITEM_COMPR:
- m_hPrevComputersChild = hTemp ;
- break ;
-
- case ITEM_DB:
- m_hPrevComputersChild = hTemp ;
- break ;
-
- NDB_DEFAULT_UNREACHABLE ;
-
- }
-
- if (ITEM_COMPR_ROOT != enType && ITEM_DB_ROOT != enType) {
-
- hti = TreeView_GetParent(m_hControl, hTemp);
- tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- tvi.hItem = hti;
- tvi.iImage = m_nClosed;
- tvi.iSelectedImage = m_nClosed;
- TreeView_SetItem(m_hControl, &tvi);
-
- }
-
- return hTemp ;
-}
-
-
-BOOL CNdbControls::Create(HINSTANCE hInst, HWND hParent){
-
- m_hInstance = hInst ;
- m_hParent = hParent ;
- m_tb.Create(m_hInstance, m_hParent, ID_TOOLBAR, IDB_TOOLBAR) ;
- m_sb.Create(m_hInstance, m_hParent, ID_STATUSBAR) ;
- m_tv.Create(m_hInstance, m_hParent, IDM_TREEVIEW, ID_TREEVIEW) ;
- _assert(AddView("Computers", ITEM_COMPR_ROOT)) ;
- _assert(AddView("Databases", ITEM_DB_ROOT)) ;
-
- return TRUE ;
-}
-
-BOOL CNdbControls::AddListView(NDB_ITEM_TYPE enType, DWORD dwId){
-
- int count ;
- CNdbListView* plv ;
- PNDB_LV pst ;
-
- plv = new CNdbListView ;
-
- if(!plv)
- return FALSE ;
-
- count = m_map_lvc.GetCount() + m_dwFirstId_lv ;
-
- switch(enType){
- case ITEM_COMPR_ROOT:
- pst = &m_stlvcRoot ;
- break ;
- case ITEM_DB_ROOT:
- pst = &m_stlvdRoot ;
- break ;
- case ITEM_COMPR:
- pst = &m_stlvc ;
- break ;
- case ITEM_DB:
- pst = &m_stlvd ;
- break ;
- NDB_DEFAULT_UNREACHABLE ;
- }
-
- plv->Create(m_hInstance, m_hParent, dwId, enType, pst, LV_HEADER_WIDTH) ;
-
- m_map_lvc[count] = plv ;
-
- return TRUE ;
-}
-
-BOOL CNdbControls::AddView(LPSTR szText, NDB_ITEM_TYPE enType){
-
- DWORD dwId_lv = m_dwNextId_lv ;
-
- if(AddListView(enType, dwId_lv) && m_tv.AddItem(szText, enType, dwId_lv))
- m_dwNextId_lv++ ;
- else
- return FALSE ;
-
- return TRUE ;
-};
-
-
-VOID CNdbControls::ToggleListViews(LPNMTREEVIEW pnmtv){
-
- CNdbListView* plv ;
- int count = m_map_lvc.GetCount() + m_dwFirstId_lv ;
-
- for(int c = FIRST_ID_LV ; c < count; ++c){
- _assert(m_map_lvc.Lookup(c, plv)) ;
- if(pnmtv->itemNew.lParam == (c))
- plv->Show(TRUE) ;
- else
- plv->Show(FALSE) ;
- }
-}
-
-
-
-VOID CNdbControls::Resize(){
-
- RECT rc, rcTB, rcSB ;
- LONG tw, sw, lx, ly, lw, lh, tvw, tvh ;
- CNdbListView* plv ;
- int count ; //, id ;
-
- GetClientRect(m_hParent, &rc) ;
- m_tb.GetRect(&rcTB) ;
- m_sb.GetRect(&rcSB) ;
-
- sw = rcSB.bottom ;
- tw = rcTB.bottom ;
-
- m_tb.Resize(0, 0, rc.right, tw) ;
-
- tvw = rc.right / 4 ;
- tvh = rc.bottom - sw - tw - BORDER ;
-
- m_tv.Resize(0, tw + BORDER, tvw, tvh) ;
-
- m_sb.Resize(0, tvh, rc.left, sw) ;
-
- lx = tvw + BORDER - 2 ;
- ly = tw + BORDER ;
- lw = rc.right - tvw - BORDER + 1 ;
- lh = tvh ;
-
- count = m_map_lvc.GetCount() + FIRST_ID_LV ;
-
- for(int c = FIRST_ID_LV ; c < count; ++c){
- _assert(m_map_lvc.Lookup(c, plv)) ;
- plv->Resize(lx, ly, lw, lh) ;
- }
-
- return ;
-
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/Open.ICO b/storage/ndb/src/cw/cpcc-win32/C++/Open.ICO
deleted file mode 100644
index ab7b05d9df7..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/Open.ICO
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp b/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp
deleted file mode 100644
index d2b002c3d90..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-// stdafx.cpp : source file that includes just the standard includes
-// CPC_GUI.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h b/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h
deleted file mode 100644
index aedd535b205..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
-#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-
-#ifdef _DEBUG
-#define NDB_DEFAULT_UNREACHABLE default: _ASSERT(0); break
-#elif _MSC_VER >= 1200
-#define NDB_DEFAULT_UNREACHABLE default: __assume(0); break
-#else
-#define NDB_DEFAULT_UNREACHABLE default: break
-#endif;
-
-
-#ifdef _DEBUG
-#define _assert _ASSERT
-#else
-#define _assert(expr) expr
-#endif
-
-
-#include <afx.h>
-#include <afxtempl.h>
-
-// C RunTime Header Files
-#include <ndb_global.h>
-#include <memory.h>
-#include <tchar.h>
-#include <commctrl.h>
-#include <shlwapi.h>
-#include <crtdbg.h>
-
-// Local Header Files
-#include "resource.h"
-#include "NdbControls.h"
-#include "CPC_GUI.h"
-
-
-// TODO: reference additional headers your program requires here
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp b/storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp
deleted file mode 100644
index bcc7e67d06f..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "StdAfx.h"
-#include "resource.h"
-#include "CPC_GUI.h"
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/TreeView.h b/storage/ndb/src/cw/cpcc-win32/C++/TreeView.h
deleted file mode 100644
index 68859693228..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/TreeView.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/bmp00001.bmp b/storage/ndb/src/cw/cpcc-win32/C++/bmp00001.bmp
deleted file mode 100644
index e50af403eda..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/bmp00001.bmp
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/resource.h b/storage/ndb/src/cw/cpcc-win32/C++/resource.h
deleted file mode 100644
index 8270a3e9962..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/resource.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by CPC_GUI.rc
-//
-#define IDC_MYICON 2
-#define IDD_CPC_GUI_DIALOG 102
-#define IDD_ABOUTBOX 103
-#define IDS_APP_TITLE 103
-#define IDM_ABOUT 104
-#define IDS_LV_ROOT_COMPUTERS 104
-#define IDS_TV_ROOT_COMPUTERS 104
-#define IDM_EXIT 105
-#define IDS_LV_ROOT_DATABASES 105
-#define IDS_TV_ROOT_DATABASES 105
-#define IDS_HELLO 106
-#define IDS_LV_COMPUTER_HEADER_1 106
-#define IDI_CPC_GUI 107
-#define IDS_LV_COMPUTER_HEADER_2 107
-#define IDI_SMALL 108
-#define IDS_LV_PROCESS_HEADER_1 108
-#define IDC_CPC_GUI 109
-#define IDM_CPC_GUI 109
-#define IDS_TIP_NEW 110
-#define IDS_TIP_DELETE 111
-#define IDS_TIP_PROPS 112
-#define IDS_LV_PROCESS_HEADER_2 113
-#define IDS_LV_PROCESS_HEADER_3 114
-#define IDS_LV_PROCESS_HEADER_4 115
-#define IDS_LV_COMPUTER_HEADER_3 116
-#define IDR_MAINFRAME 128
-#define ID_TREEVIEW 130
-#define IDM_TREEVIEW 130
-#define IDB_TOOLBAR 137
-#define ID_TOOLBAR 158
-#define IDB_COMPUTER 168
-#define IDB_CLOSED 169
-#define IDB_OPEN 170
-#define IDI_DATABASE 172
-#define IDI_CLOSED 175
-#define IDI_OPEN 176
-#define IDI_COMPUTER 177
-#define IDB_MASK 178
-#define IDB_DATABASE 182
-#define IDM_TV 183
-#define ID_TREEVIEW1 32771
-#define ID_BUTTON32773 32773
-#define IDM_NEW 32774
-#define IDM_DELETE 32775
-#define IDM_PROPS 32776
-#define ID_LIST_C 32777
-#define ID_ACTIONS_INSERT 32778
-#define ID_ACTIONS_DELETE 32779
-#define ID_DELETE 32780
-#define ID_PROPERTIES 32781
-#define ID_ACTIONS_PROPERTIES 32782
-#define ID_BUTTON32783 32783
-#define ID_BUTTON32784 32784
-#define ID_LIST_P 32785
-#define ID_STATUSBAR 32786
-#define ID_LIST_C_ROOT 32787
-#define ID_LIST_D_ROOT 32788
-#define IDM_ADDNEW 32793
-#define IDC_STATIC -1
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 184
-#define _APS_NEXT_COMMAND_VALUE 32796
-#define _APS_NEXT_CONTROL_VALUE 1000
-#define _APS_NEXT_SYMED_VALUE 110
-#endif
-#endif
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/small.ico b/storage/ndb/src/cw/cpcc-win32/C++/small.ico
deleted file mode 100644
index 8f94d9aa828..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/small.ico
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/C++/toolbar.bmp b/storage/ndb/src/cw/cpcc-win32/C++/toolbar.bmp
deleted file mode 100644
index a1059352c66..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/C++/toolbar.bmp
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/App.ico b/storage/ndb/src/cw/cpcc-win32/csharp/App.ico
deleted file mode 100644
index 3a5525fd794..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/App.ico
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs b/storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs
deleted file mode 100644
index c29998ff178..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs
+++ /dev/null
@@ -1,1416 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-using System.Threading;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for Form1.
- /// </summary>
- public class CPC : System.Windows.Forms.Form
- {
- private System.Windows.Forms.TreeView tvComputerCluster;
- private System.Windows.Forms.ContextMenu ctxTreeViewMenu;
- private System.Windows.Forms.ColumnHeader chComputer;
- private System.Windows.Forms.ColumnHeader chProcessName;
- private System.Windows.Forms.ContextMenu ctxListViewMenu;
- private System.Windows.Forms.MenuItem mainMenuItem;
- private System.Windows.Forms.ColumnHeader chProcesses;
- private System.Windows.Forms.MainMenu mainMenu;
- private System.Windows.Forms.Panel panel1;
- private System.Windows.Forms.MenuItem menuItem7;
- private System.Windows.Forms.MenuItem menuItem10;
- private System.Windows.Forms.MenuItem mainMenuFile;
- private System.Windows.Forms.MenuItem mainMenuComputer;
- private System.Windows.Forms.MenuItem subMenuComputerAdd;
- private System.Windows.Forms.MenuItem subMenuComputerRemove;
- private System.Windows.Forms.MenuItem subMenuComputerDisconnect;
- private System.Windows.Forms.MenuItem subMenuComputerProperties;
- private System.ComponentModel.IContainer components;
-
- private System.Windows.Forms.MenuItem menuItem3;
- private System.Windows.Forms.MenuItem computerMenuAdd;
- private System.Windows.Forms.MenuItem computerMenuRemove;
- private System.Windows.Forms.MenuItem menuItem5;
- private System.Windows.Forms.MenuItem computerMenuDisconnect;
- private System.Windows.Forms.MenuItem computerMenuConnect;
- private System.Windows.Forms.MenuItem computerMenuProperties;
- private System.Windows.Forms.MenuItem menuItem11;
- private System.Windows.Forms.MenuItem tvCtxMenuComputerAdd;
- private System.Windows.Forms.MenuItem tvCtxMenuComputerRemove;
- private System.Windows.Forms.MenuItem tvCtxMenuComputerConnect;
- private System.Windows.Forms.MenuItem tvCtxMenuComputerDisconnect;
- private System.Windows.Forms.MenuItem tvCtxMenuComputerDefine;
- private System.Windows.Forms.MenuItem tvCtxMenuDatabaseNew;
- private System.Windows.Forms.MenuItem menuItem1;
- private System.Windows.Forms.MenuItem menuItem2;
- private System.Windows.Forms.MenuItem mainMenuDatabase;
- private System.Windows.Forms.MenuItem subMenuDatabaseCreate;
- private System.Windows.Forms.MenuItem menuItem8;
- private System.Windows.Forms.MenuItem tvCtxMenuProperties;
- private System.Windows.Forms.ImageList imageTV;
-
- private ComputerMgmt computerMgmt;
- private System.Windows.Forms.MenuItem computerMenuRefresh;
- private System.Windows.Forms.ListView listView;
- private System.Windows.Forms.ColumnHeader chComputerIP;
- private System.Windows.Forms.ColumnHeader chDatabase;
- private System.Windows.Forms.ColumnHeader chName;
- private System.Windows.Forms.ColumnHeader chOwner;
- private System.Windows.Forms.ColumnHeader chStatus;
- private System.Windows.Forms.Splitter splitter2;
- private System.Windows.Forms.Splitter splitterVertical;
- private System.Windows.Forms.Splitter splitterHorizont;
- private Thread guiThread;
- private float resizeWidthRatio;
- private System.Windows.Forms.MenuItem menuItem6;
- private System.Windows.Forms.MenuItem menuGetStatus;
- private System.Windows.Forms.MenuItem menuStartProcess;
- private System.Windows.Forms.MenuItem menuRestartProcess;
- private System.Windows.Forms.MenuItem menuStopProcess;
- private System.Windows.Forms.MenuItem menuRemoveProcess;
- private System.Windows.Forms.MenuItem menuRefresh;
- private System.Windows.Forms.OpenFileDialog openHostFileDialog;
- private System.Windows.Forms.SaveFileDialog saveHostFileDialog;
- private float resizeHeightRatio;
- private System.Windows.Forms.TextBox mgmConsole;
- int i;
- public CPC()
- {
- //
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- // TODO: Add any constructor code after InitializeComponent call
- //
- computerMgmt = new ComputerMgmt();
- guiThread = new Thread(new ThreadStart(updateGuiThread));
-
- // guiThread.Start();
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if (components != null)
- {
- components.Dispose();
- }
- }
- //guiThread.Abort();
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(CPC));
- this.tvComputerCluster = new System.Windows.Forms.TreeView();
- this.ctxTreeViewMenu = new System.Windows.Forms.ContextMenu();
- this.tvCtxMenuComputerAdd = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuComputerRemove = new System.Windows.Forms.MenuItem();
- this.menuGetStatus = new System.Windows.Forms.MenuItem();
- this.menuItem6 = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuComputerConnect = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuComputerDisconnect = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuDatabaseNew = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuComputerDefine = new System.Windows.Forms.MenuItem();
- this.menuItem8 = new System.Windows.Forms.MenuItem();
- this.tvCtxMenuProperties = new System.Windows.Forms.MenuItem();
- this.imageTV = new System.Windows.Forms.ImageList(this.components);
- this.ctxListViewMenu = new System.Windows.Forms.ContextMenu();
- this.menuStartProcess = new System.Windows.Forms.MenuItem();
- this.menuRestartProcess = new System.Windows.Forms.MenuItem();
- this.menuStopProcess = new System.Windows.Forms.MenuItem();
- this.menuRemoveProcess = new System.Windows.Forms.MenuItem();
- this.menuRefresh = new System.Windows.Forms.MenuItem();
- this.computerMenuAdd = new System.Windows.Forms.MenuItem();
- this.menuItem3 = new System.Windows.Forms.MenuItem();
- this.computerMenuRemove = new System.Windows.Forms.MenuItem();
- this.menuItem5 = new System.Windows.Forms.MenuItem();
- this.computerMenuDisconnect = new System.Windows.Forms.MenuItem();
- this.computerMenuConnect = new System.Windows.Forms.MenuItem();
- this.menuItem11 = new System.Windows.Forms.MenuItem();
- this.computerMenuProperties = new System.Windows.Forms.MenuItem();
- this.computerMenuRefresh = new System.Windows.Forms.MenuItem();
- this.chComputer = new System.Windows.Forms.ColumnHeader();
- this.chProcessName = new System.Windows.Forms.ColumnHeader();
- this.mainMenuItem = new System.Windows.Forms.MenuItem();
- this.chProcesses = new System.Windows.Forms.ColumnHeader();
- this.mainMenu = new System.Windows.Forms.MainMenu();
- this.mainMenuFile = new System.Windows.Forms.MenuItem();
- this.menuItem2 = new System.Windows.Forms.MenuItem();
- this.menuItem1 = new System.Windows.Forms.MenuItem();
- this.mainMenuComputer = new System.Windows.Forms.MenuItem();
- this.subMenuComputerAdd = new System.Windows.Forms.MenuItem();
- this.menuItem7 = new System.Windows.Forms.MenuItem();
- this.subMenuComputerDisconnect = new System.Windows.Forms.MenuItem();
- this.subMenuComputerRemove = new System.Windows.Forms.MenuItem();
- this.menuItem10 = new System.Windows.Forms.MenuItem();
- this.subMenuComputerProperties = new System.Windows.Forms.MenuItem();
- this.mainMenuDatabase = new System.Windows.Forms.MenuItem();
- this.subMenuDatabaseCreate = new System.Windows.Forms.MenuItem();
- this.panel1 = new System.Windows.Forms.Panel();
- this.mgmConsole = new System.Windows.Forms.TextBox();
- this.splitterHorizont = new System.Windows.Forms.Splitter();
- this.splitter2 = new System.Windows.Forms.Splitter();
- this.listView = new System.Windows.Forms.ListView();
- this.chComputerIP = new System.Windows.Forms.ColumnHeader();
- this.chStatus = new System.Windows.Forms.ColumnHeader();
- this.chDatabase = new System.Windows.Forms.ColumnHeader();
- this.chName = new System.Windows.Forms.ColumnHeader();
- this.chOwner = new System.Windows.Forms.ColumnHeader();
- this.splitterVertical = new System.Windows.Forms.Splitter();
- this.openHostFileDialog = new System.Windows.Forms.OpenFileDialog();
- this.saveHostFileDialog = new System.Windows.Forms.SaveFileDialog();
- this.panel1.SuspendLayout();
- this.SuspendLayout();
- //
- // tvComputerCluster
- //
- this.tvComputerCluster.CausesValidation = false;
- this.tvComputerCluster.ContextMenu = this.ctxTreeViewMenu;
- this.tvComputerCluster.Dock = System.Windows.Forms.DockStyle.Left;
- this.tvComputerCluster.ImageList = this.imageTV;
- this.tvComputerCluster.Name = "tvComputerCluster";
- this.tvComputerCluster.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
- new System.Windows.Forms.TreeNode("Computer", 0, 0),
- new System.Windows.Forms.TreeNode("Database", 5, 5)});
- this.tvComputerCluster.Size = new System.Drawing.Size(104, 333);
- this.tvComputerCluster.TabIndex = 5;
- this.tvComputerCluster.MouseDown += new System.Windows.Forms.MouseEventHandler(this.tvComputerCluster_MouseDown);
- this.tvComputerCluster.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvComputerCluster_AfterSelect);
- this.tvComputerCluster.BeforeCollapse += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvComputerCluster_BeforeCollapse);
- this.tvComputerCluster.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvComputerCluster_BeforeExpand);
- //
- // ctxTreeViewMenu
- //
- this.ctxTreeViewMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.tvCtxMenuComputerAdd,
- this.tvCtxMenuComputerRemove,
- this.menuGetStatus,
- this.menuItem6,
- this.tvCtxMenuComputerConnect,
- this.tvCtxMenuComputerDisconnect,
- this.tvCtxMenuDatabaseNew,
- this.tvCtxMenuComputerDefine,
- this.menuItem8,
- this.tvCtxMenuProperties});
- this.ctxTreeViewMenu.Popup += new System.EventHandler(this.ctxTreeViewMenu_Popup);
- //
- // tvCtxMenuComputerAdd
- //
- this.tvCtxMenuComputerAdd.Index = 0;
- this.tvCtxMenuComputerAdd.Text = "Add computer";
- this.tvCtxMenuComputerAdd.Click += new System.EventHandler(this.computerMenuAdd_Click);
- //
- // tvCtxMenuComputerRemove
- //
- this.tvCtxMenuComputerRemove.Index = 1;
- this.tvCtxMenuComputerRemove.Text = "Remove computer";
- this.tvCtxMenuComputerRemove.Click += new System.EventHandler(this.computerMenuRemove_Click);
- //
- // menuGetStatus
- //
- this.menuGetStatus.Index = 2;
- this.menuGetStatus.Text = "Get Status";
- this.menuGetStatus.Click += new System.EventHandler(this.menuGetStatus_Click);
- //
- // menuItem6
- //
- this.menuItem6.Index = 3;
- this.menuItem6.Text = "-";
- //
- // tvCtxMenuComputerConnect
- //
- this.tvCtxMenuComputerConnect.Index = 4;
- this.tvCtxMenuComputerConnect.Text = "Connect";
- //
- // tvCtxMenuComputerDisconnect
- //
- this.tvCtxMenuComputerDisconnect.Index = 5;
- this.tvCtxMenuComputerDisconnect.Text = "Disconnect";
- //
- // tvCtxMenuDatabaseNew
- //
- this.tvCtxMenuDatabaseNew.Index = 6;
- this.tvCtxMenuDatabaseNew.Text = "Create database...";
- this.tvCtxMenuDatabaseNew.Click += new System.EventHandler(this.subMenuDatabaseCreate_Click);
- //
- // tvCtxMenuComputerDefine
- //
- this.tvCtxMenuComputerDefine.Index = 7;
- this.tvCtxMenuComputerDefine.Text = "Define process...";
- this.tvCtxMenuComputerDefine.Click += new System.EventHandler(this.tvCtxMenuComputerDefine_Click);
- //
- // menuItem8
- //
- this.menuItem8.Index = 8;
- this.menuItem8.Text = "-";
- //
- // tvCtxMenuProperties
- //
- this.tvCtxMenuProperties.Index = 9;
- this.tvCtxMenuProperties.Text = "Properties";
- //
- // imageTV
- //
- this.imageTV.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
- this.imageTV.ImageSize = new System.Drawing.Size(16, 16);
- this.imageTV.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageTV.ImageStream")));
- this.imageTV.TransparentColor = System.Drawing.Color.Transparent;
- //
- // ctxListViewMenu
- //
- this.ctxListViewMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.menuStartProcess,
- this.menuRestartProcess,
- this.menuStopProcess,
- this.menuRemoveProcess,
- this.menuRefresh});
- this.ctxListViewMenu.Popup += new System.EventHandler(this.ctxListViewMenu_Popup);
- //
- // menuStartProcess
- //
- this.menuStartProcess.Index = 0;
- this.menuStartProcess.Text = "Start process";
- this.menuStartProcess.Click += new System.EventHandler(this.startProcess);
- //
- // menuRestartProcess
- //
- this.menuRestartProcess.Index = 1;
- this.menuRestartProcess.Text = "Restart process";
- this.menuRestartProcess.Click += new System.EventHandler(this.restartProcess);
- //
- // menuStopProcess
- //
- this.menuStopProcess.Index = 2;
- this.menuStopProcess.Text = "Stop process";
- this.menuStopProcess.Click += new System.EventHandler(this.stopProcess);
- //
- // menuRemoveProcess
- //
- this.menuRemoveProcess.Index = 3;
- this.menuRemoveProcess.Text = "Remove process";
- this.menuRemoveProcess.Click += new System.EventHandler(this.removeProcess);
- //
- // menuRefresh
- //
- this.menuRefresh.Index = 4;
- this.menuRefresh.Text = "Refresh";
- this.menuRefresh.Click += new System.EventHandler(this.menuRefresh_Click);
- //
- // computerMenuAdd
- //
- this.computerMenuAdd.Index = -1;
- this.computerMenuAdd.Text = "Add";
- this.computerMenuAdd.Click += new System.EventHandler(this.computerMenuAdd_Click);
- //
- // menuItem3
- //
- this.menuItem3.Index = -1;
- this.menuItem3.Text = "-";
- //
- // computerMenuRemove
- //
- this.computerMenuRemove.Index = -1;
- this.computerMenuRemove.Text = "Remove";
- this.computerMenuRemove.Click += new System.EventHandler(this.computerMenuRemove_Click);
- //
- // menuItem5
- //
- this.menuItem5.Index = -1;
- this.menuItem5.Text = "-";
- //
- // computerMenuDisconnect
- //
- this.computerMenuDisconnect.Index = -1;
- this.computerMenuDisconnect.Text = "Disconnect";
- //
- // computerMenuConnect
- //
- this.computerMenuConnect.Index = -1;
- this.computerMenuConnect.Text = "Connect";
- //
- // menuItem11
- //
- this.menuItem11.Index = -1;
- this.menuItem11.Text = "-";
- //
- // computerMenuProperties
- //
- this.computerMenuProperties.Index = -1;
- this.computerMenuProperties.Text = "Properties";
- //
- // computerMenuRefresh
- //
- this.computerMenuRefresh.Index = -1;
- this.computerMenuRefresh.Text = "Refresh";
- this.computerMenuRefresh.Click += new System.EventHandler(this.computerMenuRefresh_Click);
- //
- // chComputer
- //
- this.chComputer.Text = "Computer";
- //
- // chProcessName
- //
- this.chProcessName.Text = "Name";
- //
- // mainMenuItem
- //
- this.mainMenuItem.Index = -1;
- this.mainMenuItem.Text = "File";
- //
- // chProcesses
- //
- this.chProcesses.Text = "Id";
- //
- // mainMenu
- //
- this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.mainMenuFile,
- this.mainMenuComputer,
- this.mainMenuDatabase});
- //
- // mainMenuFile
- //
- this.mainMenuFile.Index = 0;
- this.mainMenuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.menuItem2,
- this.menuItem1});
- this.mainMenuFile.Text = "&File";
- //
- // menuItem2
- //
- this.menuItem2.Index = 0;
- this.menuItem2.Text = "&Import...";
- this.menuItem2.Click += new System.EventHandler(this.importHostFile);
- //
- // menuItem1
- //
- this.menuItem1.Index = 1;
- this.menuItem1.Text = "&Export...";
- this.menuItem1.Click += new System.EventHandler(this.exportHostFile);
- //
- // mainMenuComputer
- //
- this.mainMenuComputer.Index = 1;
- this.mainMenuComputer.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.subMenuComputerAdd,
- this.menuItem7,
- this.subMenuComputerDisconnect,
- this.subMenuComputerRemove,
- this.menuItem10,
- this.subMenuComputerProperties});
- this.mainMenuComputer.Text = "&Computer";
- //
- // subMenuComputerAdd
- //
- this.subMenuComputerAdd.Index = 0;
- this.subMenuComputerAdd.Text = "&Add Computer";
- this.subMenuComputerAdd.Click += new System.EventHandler(this.computerMenuAdd_Click);
- //
- // menuItem7
- //
- this.menuItem7.Index = 1;
- this.menuItem7.Text = "-";
- //
- // subMenuComputerDisconnect
- //
- this.subMenuComputerDisconnect.Index = 2;
- this.subMenuComputerDisconnect.Text = "&Disconnect";
- //
- // subMenuComputerRemove
- //
- this.subMenuComputerRemove.Index = 3;
- this.subMenuComputerRemove.Text = "&Remove Computer";
- this.subMenuComputerRemove.Click += new System.EventHandler(this.computerMenuRemove_Click);
- //
- // menuItem10
- //
- this.menuItem10.Index = 4;
- this.menuItem10.Text = "-";
- //
- // subMenuComputerProperties
- //
- this.subMenuComputerProperties.Index = 5;
- this.subMenuComputerProperties.Text = "&Properties";
- //
- // mainMenuDatabase
- //
- this.mainMenuDatabase.Index = 2;
- this.mainMenuDatabase.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.subMenuDatabaseCreate});
- this.mainMenuDatabase.Text = "&Database";
- this.mainMenuDatabase.Click += new System.EventHandler(this.subMenuDatabaseCreate_Click);
- //
- // subMenuDatabaseCreate
- //
- this.subMenuDatabaseCreate.Index = 0;
- this.subMenuDatabaseCreate.Text = "&Create database...";
- this.subMenuDatabaseCreate.Click += new System.EventHandler(this.subMenuDatabaseCreate_Click);
- //
- // panel1
- //
- this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.mgmConsole,
- this.splitterHorizont,
- this.splitter2,
- this.listView});
- this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.panel1.Location = new System.Drawing.Point(104, 0);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(384, 333);
- this.panel1.TabIndex = 6;
- //
- // mgmConsole
- //
- this.mgmConsole.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText;
- this.mgmConsole.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.mgmConsole.Location = new System.Drawing.Point(0, 231);
- this.mgmConsole.Multiline = true;
- this.mgmConsole.Name = "mgmConsole";
- this.mgmConsole.Size = new System.Drawing.Size(384, 96);
- this.mgmConsole.TabIndex = 5;
- this.mgmConsole.Text = "textBox1";
- this.mgmConsole.TextChanged += new System.EventHandler(this.mgmConsole_TextChanged);
- this.mgmConsole.Enter += new System.EventHandler(this.mgmConsole_Enter);
- //
- // splitterHorizont
- //
- this.splitterHorizont.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.splitterHorizont.Location = new System.Drawing.Point(0, 327);
- this.splitterHorizont.MinExtra = 100;
- this.splitterHorizont.MinSize = 100;
- this.splitterHorizont.Name = "splitterHorizont";
- this.splitterHorizont.Size = new System.Drawing.Size(384, 3);
- this.splitterHorizont.TabIndex = 4;
- this.splitterHorizont.TabStop = false;
- //
- // splitter2
- //
- this.splitter2.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.splitter2.Location = new System.Drawing.Point(0, 330);
- this.splitter2.Name = "splitter2";
- this.splitter2.Size = new System.Drawing.Size(384, 3);
- this.splitter2.TabIndex = 2;
- this.splitter2.TabStop = false;
- //
- // listView
- //
- this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
- this.chComputerIP,
- this.chStatus,
- this.chDatabase,
- this.chName,
- this.chOwner});
- this.listView.ContextMenu = this.ctxListViewMenu;
- this.listView.Dock = System.Windows.Forms.DockStyle.Fill;
- this.listView.FullRowSelect = true;
- this.listView.Name = "listView";
- this.listView.Size = new System.Drawing.Size(384, 333);
- this.listView.TabIndex = 0;
- this.listView.View = System.Windows.Forms.View.Details;
- this.listView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listView_ColumnClick_1);
- this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
- //
- // chComputerIP
- //
- this.chComputerIP.Text = "IP Adress";
- //
- // chStatus
- //
- this.chStatus.Text = "Status";
- //
- // chDatabase
- //
- this.chDatabase.Text = "Database";
- //
- // chName
- //
- this.chName.Text = "Name";
- //
- // chOwner
- //
- this.chOwner.Text = "Owner";
- //
- // splitterVertical
- //
- this.splitterVertical.Location = new System.Drawing.Point(104, 0);
- this.splitterVertical.MinSize = 100;
- this.splitterVertical.Name = "splitterVertical";
- this.splitterVertical.Size = new System.Drawing.Size(3, 333);
- this.splitterVertical.TabIndex = 7;
- this.splitterVertical.TabStop = false;
- this.splitterVertical.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitterVertical_SplitterMoved);
- //
- // openHostFileDialog
- //
- this.openHostFileDialog.DefaultExt = "cpc";
- this.openHostFileDialog.Filter = "CPCd configuration files (*.cpc)|*.cpc| All Files (*.*)|*.*";
- this.openHostFileDialog.Title = "Import a CPCd configuration file";
- this.openHostFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.openHostFileDialog_FileOk);
- //
- // saveHostFileDialog
- //
- this.saveHostFileDialog.Filter = "CPCd configuration files (*.cpc)|*.cpc| All Files (*.*)|*.*";
- this.saveHostFileDialog.Title = "Export a CPCd configuration file";
- this.saveHostFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.saveHostFileDialog_FileOk);
- //
- // CPC
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(488, 333);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.splitterVertical,
- this.panel1,
- this.tvComputerCluster});
- this.Menu = this.mainMenu;
- this.Name = "CPC";
- this.Text = "CPC";
- this.Resize += new System.EventHandler(this.CPC_Resize);
- this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CPC_MouseDown);
- this.Closing += new System.ComponentModel.CancelEventHandler(this.CPC_Closing);
- this.Load += new System.EventHandler(this.CPC_Load);
- this.Activated += new System.EventHandler(this.CPC_Activated);
- this.Paint += new System.Windows.Forms.PaintEventHandler(this.CPC_Paint);
- this.panel1.ResumeLayout(false);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static void Main()
- {
- Application.Run(new CPC());
-
- }
-
- private void tvComputerCluster_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
- {
- if(e.Node.Text.ToString().Equals("Database"))
- {
- updateListViews("Database");
-
- return;
- }
- if(e.Node.Text.ToString().Equals("Computer"))
- {
- //updateListViews();
-
- updateListViews("Computer");
- return;
- }
- if(e.Node.Parent.Text.ToString().Equals("Database"))
- {
- //updateListViews();
- listView.Columns.Clear();
- listView.Columns.Add(this.chName);
- listView.Columns.Add(this.chDatabase);
- listView.Columns.Add(this.chStatus);
- listView.Columns.Add(this.chOwner);
- updateDatabaseView(e.Node.Text.ToString());
- }
-
- if(e.Node.Parent.Text=="Computer")
- {
- //updateListViews();
-
- Computer c=computerMgmt.getComputer(e.Node.Text.ToString());
- string [] processcols= new string[5];
- ArrayList processes;
- processes = c.getProcesses();
- listView.Items.Clear();
- listView.Columns.Clear();
- listView.Columns.Add(this.chComputer);
- listView.Columns.Add(this.chDatabase);
- listView.Columns.Add(this.chName);
- listView.Columns.Add(this.chStatus);
- listView.Columns.Add(this.chOwner);
- if(processes != null )
- {
-
- listView.BeginUpdate();
- foreach(Process p in processes)
- {
- processcols[0]=p.getComputer().getName();
- processcols[1]=p.getDatabase();
- processcols[2]=p.getName();
- processcols[3]=p.getStatusString();
- processcols[4]=p.getOwner();
- ListViewItem lvp= new ListViewItem(processcols);
- listView.Items.Add(lvp);
- }
-
- listView.EndUpdate();
- }
-
-
- listView.Show();
- }
-
- }
-
-
-
- private void ctxTreeViewMenu_Popup(object sender, System.EventArgs e)
- {
- tvCtxMenuComputerAdd.Enabled=true;
- tvCtxMenuComputerRemove.Enabled=true;
- tvCtxMenuComputerConnect.Enabled=true;
- tvCtxMenuComputerDisconnect.Enabled=true;
- tvCtxMenuComputerDefine.Enabled=true;
- menuGetStatus.Enabled=true;
- tvCtxMenuDatabaseNew.Enabled=true;
- tvCtxMenuComputerAdd.Visible=true;
- tvCtxMenuComputerRemove.Visible=true;
- tvCtxMenuComputerConnect.Visible=true;
- tvCtxMenuComputerDisconnect.Visible=true;
- tvCtxMenuComputerDefine.Visible=true;
- tvCtxMenuDatabaseNew.Visible=true;
- tvCtxMenuProperties.Visible=true;
- menuGetStatus.Visible=true;
-
- if(tvComputerCluster.SelectedNode.Text.Equals("Computer"))
- {
- tvCtxMenuComputerAdd.Enabled=true;
- tvCtxMenuComputerRemove.Enabled=false;
- tvCtxMenuComputerConnect.Enabled=false;
- tvCtxMenuComputerDisconnect.Enabled=false;
- tvCtxMenuComputerDefine.Enabled=false;
- tvCtxMenuDatabaseNew.Visible=false;
- menuGetStatus.Visible=false;
- return;
- }
-
- if(tvComputerCluster.SelectedNode.Text.Equals("Database"))
- {
- // ctxTreeViewMenu.MenuItems.Add(menuDatabaseItem1);
- tvCtxMenuComputerAdd.Visible=false;
- tvCtxMenuComputerRemove.Visible=false;
- tvCtxMenuComputerConnect.Visible=false;
- tvCtxMenuComputerDisconnect.Visible=false;
- tvCtxMenuComputerDefine.Visible=false;
- tvCtxMenuDatabaseNew.Visible=true;
- tvCtxMenuDatabaseNew.Enabled=true;
- menuGetStatus.Visible=false;
- menuItem6.Visible=false;
- return;
- }
- if(tvComputerCluster.SelectedNode.Parent.Text.Equals("Computer"))
- {
-
- Computer c= computerMgmt.getComputer(tvComputerCluster.SelectedNode.Text.ToString());
- if(c.getStatus().Equals(Computer.Status.Disconnected))
- {
- tvCtxMenuComputerConnect.Enabled=true;
- tvCtxMenuComputerDisconnect.Enabled=false;
- }
- else
- {
- tvCtxMenuComputerDisconnect.Enabled=true;
- tvCtxMenuComputerConnect.Enabled=false;
- }
-
- tvCtxMenuComputerAdd.Enabled=false;
- tvCtxMenuComputerRemove.Enabled=true;
- menuGetStatus.Visible=false;
-
- tvCtxMenuComputerDefine.Enabled=true;
- tvCtxMenuDatabaseNew.Visible=false;
- return;
- }
-
- if(tvComputerCluster.SelectedNode.Parent.Text.Equals("Database"))
- {
- tvCtxMenuComputerAdd.Enabled=true;
- tvCtxMenuComputerRemove.Enabled=false;
- tvCtxMenuComputerConnect.Enabled=false;
- tvCtxMenuComputerDisconnect.Enabled=false;
- tvCtxMenuComputerDefine.Enabled=false;
- tvCtxMenuDatabaseNew.Visible=true;
- menuGetStatus.Visible=true;
- return;
- }
-
-
- }
-
-
- private void listView_SelectedIndexChanged(object sender, System.EventArgs e)
- {
- //MessageBox.Show(listView.SelectedItems[0].Text);
- }
-
-
- private void tvComputerCluster_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
- { /*
- TreeNode node = tvComputerCluster.GetNodeAt(e.X,e.Y);
- if(node==null)
- {
- return;
- }
- tvComputerCluster.SelectedNode=node;
-// updateListViews();
- tvComputerCluster.SelectedNode.Expand();
- */
- }
-
-
- private void subMenuComputerRemove_Click(object sender, System.EventArgs e)
- {
- //ComputerRemoveDialog crd=new ComputerRemoveDialog(computerMgmt);
- //crd.Show();
- //updateListViews();
-/* string computer = tvComputerCluster.SelectedNode.Text.ToString();
- if(MessageBox.Show(this,"Are you sure you want to remove: " +computer+ "?","Remove computer",MessageBoxButtons.YesNo)==DialogResult.Yes)
- {
- computerMgmt.RemoveComputer(computer);
- }
-*/
- }
-
- private void subMenuComputerAdd_Click(object sender, System.EventArgs e)
- {
- ComputerAddDialog cad=new ComputerAddDialog(computerMgmt);
- cad.ShowDialog();
- cad.Dispose();
-/// updateListViews(tvComputerCluster.SelectedNode.Text.ToString());
- }
-
-
-
- private void updateListViews(string node)
- {
- if(node.Equals("Computer"))
- {
- listView.Columns.Clear();
- listView.Items.Clear();
- ArrayList list= computerMgmt.getComputerCollection();
- string [] computercols= new string[2];
-
-
- listView.BeginUpdate();
- listView.Columns.Add(this.chComputer);
- listView.Columns.Add(this.chStatus);
- foreach (Computer computer in list)
- {
- computercols[0]=computer.getName();
- computercols[1]=computer.getStatusString();
-
- ListViewItem lvc= new ListViewItem(computercols);
-
- listView.Items.Add(lvc);
-
- }
- listView.EndUpdate();
- listView.Show();
- }
-
- if(node.Equals("Database"))
- {
-
- ArrayList databases= computerMgmt.getDatabaseCollection();
- string [] dbcols= new string[3];
-
-
- listView.BeginUpdate();
- listView.Items.Clear();
- listView.Columns.Clear();
- listView.Columns.Add(this.chDatabase);
- listView.Columns.Add(this.chStatus);
- listView.Columns.Add(this.chOwner);
- foreach (Database db in databases)
- {
- dbcols[0]=db.getName();
- dbcols[1]=db.getStatusString();
- dbcols[2]=db.getOwner();
-
- ListViewItem lvc= new ListViewItem(dbcols);
-
- listView.Items.Add(lvc);
-
- }
- listView.EndUpdate();
-
- listView.Show();
- }
-
- }
-
- public void updateDatabaseView(string database)
- {
- Database d=computerMgmt.getDatabase(database);
- string [] processcols= new string[5];
- ArrayList processes = d.getProcesses();
- listView.Items.Clear();
- if(processes != null )
- {
-
- listView.BeginUpdate();
- listView.Columns.Clear();
- listView.Columns.Add(this.chComputer);
- listView.Columns.Add(this.chDatabase);
- listView.Columns.Add(this.chName);
- listView.Columns.Add(this.chStatus);
- listView.Columns.Add(this.chOwner);
-
- foreach(Process p in processes)
- {
- processcols[0]=p.getComputer().getName();
- processcols[1]=p.getDatabase();
- processcols[2]=p.getName();
- processcols[3]=p.getStatusString();
- processcols[4]=p.getOwner();
- ListViewItem lvp= new ListViewItem(processcols);
- listView.Items.Add(lvp);
- }
-
- listView.EndUpdate();
- }
-
- listView.Show();
- }
-
- private void updateTreeViews()
- {
- //tvComputerCluster.Nodes.Clear();
- ArrayList computers= computerMgmt.getComputerCollection();
-
- ArrayList databases= computerMgmt.getDatabaseCollection();
-
- tvComputerCluster.BeginUpdate();
- tvComputerCluster.Nodes[0].Nodes.Clear();
- tvComputerCluster.Nodes[1].Nodes.Clear();
- if(computers != null)
- {
- foreach (Computer computer in computers)
- {
- tvComputerCluster.Nodes[0].Nodes.Add(new TreeNode(computer.getName().ToString()));
- }
- }
- if(databases != null)
- {
- foreach (Database db in databases)
- {
- tvComputerCluster.Nodes[1].Nodes.Add(new TreeNode(db.getName().ToString()));
- }
- }
-
- tvComputerCluster.EndUpdate();
- }
-
-
- private void CPC_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- //updateListViews();
- //updateTreeViews();
-
- }
-
- private void CPC_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
- if(tvComputerCluster.SelectedNode!=null)
- {
- if(tvComputerCluster.SelectedNode.Text.ToString().Equals("Computer"))
- updateListViews("Computer");
- }
-
- //updateListViews();
- //updateTreeViews();
- }
-
- private void CPC_Activated(object sender, System.EventArgs e)
- {
- updateListViews(tvComputerCluster.SelectedNode.Text.ToString());
- //updateListViews();
- updateTreeViews();
- }
-
-
- private void computerMenuAdd_Click(object sender, System.EventArgs e)
- {
- ComputerAddDialog cad=new ComputerAddDialog(computerMgmt);
- cad.ShowDialog();
- cad.Dispose();
-
- }
-
- private void computerMenuRemove_Click(object sender, System.EventArgs e)
- {
-
- string computer = tvComputerCluster.SelectedNode.Text.ToString();
- if(MessageBox.Show("Are you sure you want to remove: " + computer +"?\n" + "This will remove all processes on the computer!" ,"Remove selected computer",MessageBoxButtons.YesNo, MessageBoxIcon.Question)== DialogResult.Yes)
- {
- removeComputer(computer);
- }
- }
-
- private void removeComputer(string computer)
- {
- ArrayList processes;
- Computer c=computerMgmt.getComputer(computer);
- processes = c.getProcesses();
-
- /*foreach(Process p in processes)
- {
- removeProcess(computer,p.getName());
- processes=c.getProcesses();
- }
-*/
- if(computerMgmt.RemoveComputer(computer))
- {
- tvComputerCluster.SelectedNode=tvComputerCluster.SelectedNode.PrevVisibleNode;
- this.updateTreeViews();
- this.updateListViews("Computer");
-
- if(tvComputerCluster.SelectedNode!=null)
- this.updateListViews(tvComputerCluster.SelectedNode.Text.ToString());
- //updateListViews();
- }
- }
-
- private void listView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
- {
-
- if(listView.Sorting.Equals(SortOrder.Ascending))
- listView.Sorting=SortOrder.Descending;
- else
- listView.Sorting=SortOrder.Ascending;
-
- }
-
-
- private void subMenuDatabaseCreate_Click(object sender, System.EventArgs e)
- {
- PanelWizard p = new PanelWizard(this.computerMgmt);
- p.ShowDialog();
- }
-
- private void tvCtxMenuComputerDefine_Click(object sender, System.EventArgs e)
- {
- ProcessDefineDialog pdd = new ProcessDefineDialog(this.computerMgmt,
- tvComputerCluster.SelectedNode.Text.ToString());
- pdd.Show();
- }
-
- private void listView_ItemActivate(object sender, System.EventArgs e)
- {
- updateDatabaseView(listView.SelectedItems[0].Text.ToString());
- for(int i=0;i<tvComputerCluster.Nodes[1].Nodes.Count;i++)
- {
- if(tvComputerCluster.Nodes[1].Nodes[i].Text.ToString().Equals(listView.SelectedItems[0].Text.ToString()))
- {
- tvComputerCluster.SelectedNode=tvComputerCluster.Nodes[1].Nodes[i];
- break;
- }
- }
-
-
- }
-
- private void CPC_Resize(object sender, System.EventArgs e)
- {
- if(this.Width < 200) this.Width=200;
- if(this.Height <200) this.Height=200;
- this.tvComputerCluster.Width=(int)(this.Width*this.resizeWidthRatio);
- this.listView.Height=(int)(this.Height*this.resizeHeightRatio);
-
- //this.Size=new System.Drawing.Size((int)(this.Size.Width*this.tvComputerCluster.Width
-
- }
-
-
-
- private void updateGuiThread()
- {
- while(true) {
- if(tvComputerCluster.SelectedNode!=null)
- {
- if(tvComputerCluster.SelectedNode.Text.ToString().Equals("Computer"))
- updateListViews("Computer");
- }
- Thread.Sleep(1000);
- }
- }
-
- private void computerMenuRefresh_Click(object sender, System.EventArgs e)
- {
- updateListViews("Computer");
- }
-
- private void CPC_Closing(object sender, System.ComponentModel.CancelEventArgs e)
- {
- /*clean up*/
- ArrayList comp = this.computerMgmt.getComputerCollection();
- foreach(Computer c in comp)
- {
- c.disconnect();
- }
- }
-
- private void CPC_Load(object sender, System.EventArgs e)
- {
- this.tvComputerCluster.Width=104;
- resizeWidthRatio =(float) ((float)(this.tvComputerCluster.Width)/(float)(this.Width));
- resizeHeightRatio = (float) ((float)(this.listView.Height)/(float)(this.Height));
- listView.Columns.Clear();
- listView.Columns.Add(this.chComputer);
- listView.Columns.Add(this.chStatus);
-
- }
-
- private void splitterVertical_SplitterMoved(object sender, System.Windows.Forms.SplitterEventArgs e)
- {
- if(this.Width < 500)
- this.Width=500;
- }
-
- private void menuGetStatus_Click(object sender, System.EventArgs e)
- {
-
- }
-
- private void tvComputerCluster_BeforeExpand(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
- {
- if (e.Node.Parent!=null && e.Node.Nodes.Count !=0)
- e.Cancel=true;
- if(e.Node.IsExpanded)
- e.Cancel=true;
- }
-
- private void tvComputerCluster_BeforeCollapse(object sender, System.Windows.Forms.TreeViewCancelEventArgs e)
- {
- e.Cancel=true;
- if (e.Node.Parent!=null && e.Node.Nodes.Count !=0)
- e.Cancel=true;
- if(e.Node.IsExpanded)
- e.Cancel=false;
- }
-
-
-
- private void ctxListViewMenu_Popup(object sender, System.EventArgs e)
- {
-
- menuStartProcess.Visible=false;
- menuStopProcess.Visible=false;
- menuRestartProcess.Visible=false;
- menuRemoveProcess.Visible=false;
- menuRefresh.Visible=false;
-
-
- if(this.tvComputerCluster.SelectedNode.Text.Equals("Computer"))
- {
- return;
- }
-
- if(this.tvComputerCluster.SelectedNode.Text.Equals("Database"))
- {
- return;
- }
-
- if(this.tvComputerCluster.SelectedNode.Parent.Text.Equals("Computer"))
- {
- if(listView.SelectedItems==null)
- return;
- menuRefresh.Visible=true;
- }
- if(this.tvComputerCluster.SelectedNode.Parent.Text.Equals("Database"))
- {
- if(listView.SelectedItems==null)
- return;
- menuStartProcess.Visible=true;
- menuStopProcess.Visible=true;
- menuRestartProcess.Visible=true;
- menuRemoveProcess.Visible=true;
- menuRefresh.Visible=true;
- menuStopProcess.Enabled=true;
- menuStartProcess.Enabled=true;
- menuRestartProcess.Enabled=true;
- menuRemoveProcess.Enabled=true;
- menuRefresh.Enabled=true;
- }
-
-
- computerMenuRemove.Enabled=true;
- computerMenuConnect.Enabled=true;
- computerMenuDisconnect.Enabled=true;
- computerMenuRefresh.Enabled=true;
- string selectedItem="";
- if(listView.SelectedItems.Count>0)
- selectedItem=listView.FocusedItem.Text.ToString();
-
-
- if(selectedItem.Equals(""))
- {
- computerMenuAdd.Enabled=true;
- computerMenuRemove.Enabled=false;
- computerMenuConnect.Enabled=false;
- computerMenuDisconnect.Enabled=false;
- return;
- }
- else
- {
- computerMenuAdd.Enabled=false;
- if(computerMgmt.getStatus(selectedItem).Equals(Computer.Status.Connected))
- {
- computerMenuConnect.Enabled=false;
- computerMenuRemove.Enabled=true;
- }
- if(computerMgmt.getStatus(selectedItem).Equals(Computer.Status.Disconnected))
- computerMenuDisconnect.Enabled=false;
- }
-
-
- }
-
- private void startProcess(object sender, System.EventArgs e)
- {
- if(listView.SelectedItems.Count==0)
- return;
-
- string computer = listView.SelectedItems[0].SubItems[0].Text.ToString();
- string process = listView.SelectedItems[0].SubItems[2].Text.ToString();
-
- if(computerMgmt.getComputer(computer).getProcessByName(process).getStatus()==Process.Status.Running)
- {
- MessageBox.Show(this,"The process is already started!" ,"Process failed to start",MessageBoxButtons.OK);
- return;
- }
-
- int status = startProcess(listView.SelectedItems[0].SubItems[0].Text.ToString(),listView.SelectedItems[0].SubItems[2].Text.ToString());
-
-
- if(status < 0)
- MessageBox.Show(this,"Either the link is not OK, or the process is misconfigured! Status : " + status,"Process failed to start",MessageBoxButtons.OK);
- else
- MessageBox.Show(this,"The process was sucessfully started!","Process started",MessageBoxButtons.OK);
-
- }
-
- private int startProcess(string computer, string process)
- {
- Computer c=computerMgmt.getComputer(computer);
- int status = c.startProcess(c.getProcessByName(process));
- return status;
- }
-
- private void listView_ColumnClick_1(object sender, System.Windows.Forms.ColumnClickEventArgs e)
- {
- // if(listView.Columns[e.Column].Text.Equals("Computer"))
- // {
- if(listView.Sorting.Equals(SortOrder.Ascending))
- {
- listView.Sorting=SortOrder.Descending;
- }
- else
- {
- listView.Sorting=SortOrder.Ascending;
- }
- // }
- }
-
- private void removeProcess(object sender, System.EventArgs e)
- {
- if(listView.SelectedItems.Count==0)
- return;
- string process = listView.SelectedItems[0].SubItems[2].Text.ToString();
- string computer = listView.SelectedItems[0].SubItems[0].Text.ToString();
-
- if(MessageBox.Show("Are you sure that you want to remove " + process + " permanently?","Remove process",MessageBoxButtons.YesNo) == DialogResult.No)
- return;
- removeProcess(computer,process);
- MessageBox.Show(this,"The process was sucessfully removed!","Remove process",MessageBoxButtons.OK);
- }
-
- private void removeProcess(string computer, string process)
- {
-
- Computer c=computerMgmt.getComputer(computer);
- stopProcess(computer,process);
- int status = c.undefineProcess(c.getProcessByName(process));
- //if(status < 0)
- // MessageBox.Show(this,"The process could not be removed!","Failed to remove process",MessageBoxButtons.OK);
- // else
- // {
- Database db = computerMgmt.getDatabase((c.getProcessByName(process).getDatabase()));
- db.removeProcess(process);
- c.removeProcess(process,db.getName());
- updateListViews("Database");
- // }
- }
-
- private void stopProcess(object sender, System.EventArgs e)
- {
- if(listView.SelectedItems.Count==0)
- return;
- string computer = listView.SelectedItems[0].SubItems[0].Text.ToString();
- string process = listView.SelectedItems[0].SubItems[2].Text.ToString();
- if(computerMgmt.getComputer(computer).getProcessByName(process).getStatus()==Process.Status.Stopped)
- {
- MessageBox.Show(this,"The process is already stopped!" ,"Process failed to stop",MessageBoxButtons.OK);
- return;
- }
-
- if(DialogResult.No==MessageBox.Show(this,"Are you sure you want to stop the " + process + " process?","Stop process!", MessageBoxButtons.YesNo))
- return;
-
- int status = stopProcess(computer, process);
- if(status < 0)
- MessageBox.Show(this,"The process could not be stopped. Status: " + status ,"Process failed to stop",MessageBoxButtons.OK);
- else
- MessageBox.Show(this,"The process was sucessfully stopped!","Process stopped",MessageBoxButtons.OK);
- }
-
- private int stopProcess(string computer, string process)
- {
- Computer c=computerMgmt.getComputer(computer);
- int status = c.stopProcess(c.getProcessByName(process));
- return status;
- }
-
- private void restartProcess(object sender, System.EventArgs e)
- {
- if(listView.SelectedItems.Count==0)
- return;
- string computer = listView.SelectedItems[0].SubItems[0].Text.ToString();
- string process = listView.SelectedItems[0].SubItems[2].Text.ToString();
- if(stopProcess(computer, process)<0)
- {
- MessageBox.Show("Restart process failed!!!", "Restart process");
- return;
- }
- if(startProcess(computer, process)<0)
- {
- MessageBox.Show("Restart process failed!!!", "Restart process");
- return;
- }
- MessageBox.Show("Succesfully restarted the process!","Restart process");
- }
-
- private void menuRefresh_Click(object sender, System.EventArgs e)
- {
- //string computer = tvComputerCluster.SelectedNode.Text;
-
- this.listProcesses();
- }
-
- private void importHostFile(object sender, System.EventArgs e)
- {
- openHostFileDialog.ShowDialog();
- }
-
- private void exportHostFile(object sender, System.EventArgs e)
- {
- saveHostFileDialog.ShowDialog();
- }
-
- private void listProcesses()
- {
- /* add process in computer list*/
- ArrayList computers = computerMgmt.getComputerCollection();
- foreach(Computer c in computers)
- {
- c.listProcesses();
- ArrayList processes = c.getProcesses();
- if(processes!=null)
- {
- foreach(Process p in processes)
- {
- Database db = computerMgmt.getDatabase(p.getDatabase());
- if(db!=null)
- {
- p.setDefined(true);
- db.addProcessCheck(p);
- }
- }
- }
- }
- updateListViews("Computer");
- updateListViews("Database");
- }
-
- private void openHostFileDialog_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
- {
- computerMgmt.importHostFile(openHostFileDialog.FileName);
- this.updateTreeViews();
- openHostFileDialog.Dispose();
- listProcesses();
- }
-
- private void saveHostFileDialog_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
- {
- computerMgmt.exportHostFile(saveHostFileDialog.FileName);
- saveHostFileDialog.Dispose();
- }
-
- private void mgmConsole_Enter(object sender, System.EventArgs e)
- {/*
- //telnetclient.telnetClient tc= new telnetclient.telnetClient("10.0.13.1",10000,mgmConsole);
- socketcomm.SocketComm sc = new socketcomm.SocketComm("10.0.13.1",10000);
- sc.doConnect();
- while(!sc.isConnected())
- {
- Thread.Sleep(100);
- }
- sc.writeMessage("get status\r");
- string line = sc.readLine();
- while(!line.Equals(""))
- {
- MessageBox.Show(line);
- line=sc.readLine();
- }
-*/
- }
-
- private void mgmConsole_TextChanged(object sender, System.EventArgs e)
- {
-
- }
-
-
-
-
-
-
-
-
-
- }
-
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs b/storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs
deleted file mode 100644
index 879605dbd23..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs
+++ /dev/null
@@ -1,272 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-using System.IO;
-using NDB_CPC.socketcomm;
-using NDB_CPC.simpleparser;
-
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for Computer.
- /// </summary>
- public class Computer
- {
- public enum Status {Disconnected=1,Connected=2, Unknown=3}
- private string m_ip;
- private int m_cpcdPort;
- private string m_name;
- private Status m_status;
- private ArrayList m_processes;
- private SocketComm m_socket;
- public Computer(string name, int port)
- {
- m_name = name;
- m_status = Status.Disconnected;
- m_processes = new ArrayList();
- m_cpcdPort=port;
- m_socket = new SocketComm(m_name,m_cpcdPort);
- }
-
- public Computer(string name, string ip)
- {
- m_ip = ip;
- m_name = name;
- m_status = Status.Disconnected;
- m_processes = new ArrayList();
- m_cpcdPort=1234; //default port
- m_socket = new SocketComm(m_ip,m_cpcdPort);
- }
-
- public void connectToCpcd()
- {
- m_socket.doConnect();
- }
-
- private bool sendMessage(string str)
- {
- return m_socket.writeMessage(str);
-
- }
-
- public string getName() {return m_name;}
- public string getIp() {return m_ip;}
- public ArrayList getProcesses()
- {
- if(m_processes.Count>0)
- return m_processes;
- else
- return null;
- }
- public string getStatusString()
- {
- try
- {
- if(m_socket.isConnected())
- return "Connected";
- else
- return "Disconnected";
- }
- catch(Exception e)
- {
- return "Unknown";
- }
- }
-
-
- public bool isConnected()
- {
- if(m_socket.isConnected())
- return true;
- return false;
- }
-
- public Status getStatus()
- {
- try
- {
- if(m_socket.isConnected())
- return Status.Connected;
- else
- return Status.Disconnected;
- }
- catch(Exception e)
- {
- return Status.Unknown;
- }
- }
-
- public void setStatus(Status status)
- {
- m_status=status;
- }
-
- public void addProcess(Process process)
- {
- m_processes.Add(process);
- }
-
- public Process getProcessByName(string name)
- {
- foreach(Process process in m_processes)
- {
- if(process.getName().Equals(name))
- return process;
- }
- return null;
- }
-
-
- public bool removeProcess(string name, string database)
- {
- foreach(Process p in m_processes)
- {
- if(p.getName().Equals(name) && p.getDatabase().Equals(database))
- {
- m_processes.Remove(p);
- return true;
- }
- }
- return false;
- }
-
- public void disconnect()
- {
- m_socket.disconnect();
- }
- public Process getProcess(string id)
- {
- foreach(Process process in m_processes)
- {
- if(process.getId().Equals(id))
- return process;
- }
- return null;
- }
-
- public int listProcesses()
- {
- string list = "list processes\n\n";
-
- if(!sendMessage(list))
- return -2;
-
- SimpleCPCParser.parse(m_processes, this, m_socket);
- return 1;
- }
-
- public int defineProcess(Process p)
- {
- string define = "define process \n";
- define = define + "name:" + p.getName() + "\n";
- define = define + "group:" + p.getDatabase() + "\n";
- define = define + "env:" + "NDB_CONNECTSTRING="+p.getConnectString() ;
- if(p.getEnv().Equals(""))
- define = define + "\n";
- else
- define = define + " " + p.getEnv() + "\n";
-
- //if(p.getPath().EndsWith("\\"))
- // define = define + "path:" + p.getPath()+ "ndb" + "\n";
- //else
- define = define + "path:" + p.getPath() + "\n";
- define = define + "args:" + p.getArgs() + "\n";
- define = define + "type:" + "permanent" + "\n";
- define = define + "cwd:" + p.getCwd() + "\n";
- define = define + "owner:" + "ejohson" + "\n\n";
-
- if(!sendMessage(define))
- return -2;
-
- SimpleCPCParser.parse(p, m_socket);
- if(p.isDefined())
- return 1;
- else
- return -1;
-
- }
-
- public int startProcess(Process p)
- {
- if(!p.isDefined())
- {
- this.defineProcess(p);
- if(!p.isDefined())
- return -4; //process misconfigured
-
- }
- string start= "start process \n";
- start = start + "id:" + p.getId() + "\n\n";
- if(!sendMessage(start))
- return -2;
- SimpleCPCParser.parse(p, m_socket);
- if(p.getStatus().Equals(Process.Status.Running))
- return 1;
- else
- return -1;
- }
-
- public int stopProcess(Process p)
- {
- if(!p.isDefined())
- {
- return -4; //process not defined
- }
- string stop= "stop process \n";
- stop = stop + "id:" + p.getId() + "\n\n";
- if(!sendMessage(stop))
- return -2;
- SimpleCPCParser.parse(p, m_socket);
-
- if(p.getStatus().Equals(Process.Status.Stopped))
- return 1;
- else
- return -1;
- }
-
- public int undefineProcess(Process p)
- {
- if(!p.isDefined())
- {
- return -4; //process not defined
- }
- string undefine= "undefine process \n";
- undefine = undefine + "id:" + p.getId() + "\n\n";
- if(!sendMessage(undefine))
- return -2;
- SimpleCPCParser.parse(p, m_socket);
- if(!p.isDefined())
- {
- return 1;
-
- }
- return -1;
- }
-
- public int getCpcdPort()
- {
- return this.m_cpcdPort;
- }
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs b/storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs
deleted file mode 100644
index bdd8b04c0ae..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs
+++ /dev/null
@@ -1,258 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for ComputerAddDialog.
- /// </summary>
- public class ComputerAddDialog : System.Windows.Forms.Form
- {
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.TextBox textboxComputerName;
- private System.Windows.Forms.Button btnAdd;
- private System.Windows.Forms.Button btnCancel;
- private System.Windows.Forms.Label label2;
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- private System.Windows.Forms.Label label6;
- private System.Windows.Forms.CheckBox checkBoxDefault;
- private System.Windows.Forms.TextBox textBoxPort;
-
- private ComputerMgmt mgmt;
- public ComputerAddDialog(ComputerMgmt mgmt)
- {
- //
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- this.mgmt=mgmt;
- }
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if(components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.textboxComputerName = new System.Windows.Forms.TextBox();
- this.label1 = new System.Windows.Forms.Label();
- this.btnAdd = new System.Windows.Forms.Button();
- this.btnCancel = new System.Windows.Forms.Button();
- this.label2 = new System.Windows.Forms.Label();
- this.label6 = new System.Windows.Forms.Label();
- this.textBoxPort = new System.Windows.Forms.TextBox();
- this.checkBoxDefault = new System.Windows.Forms.CheckBox();
- this.SuspendLayout();
- //
- // textboxComputerName
- //
- this.textboxComputerName.Location = new System.Drawing.Point(128, 16);
- this.textboxComputerName.Name = "textboxComputerName";
- this.textboxComputerName.Size = new System.Drawing.Size(136, 20);
- this.textboxComputerName.TabIndex = 0;
- this.textboxComputerName.Text = "";
- //
- // label1
- //
- this.label1.Location = new System.Drawing.Point(40, 16);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(88, 23);
- this.label1.TabIndex = 1;
- this.label1.Text = "Computer name:";
- this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- //
- // btnAdd
- //
- this.btnAdd.Location = new System.Drawing.Point(112, 128);
- this.btnAdd.Name = "btnAdd";
- this.btnAdd.Size = new System.Drawing.Size(80, 24);
- this.btnAdd.TabIndex = 4;
- this.btnAdd.Text = "Add";
- this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
- //
- // btnCancel
- //
- this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.btnCancel.Location = new System.Drawing.Point(200, 128);
- this.btnCancel.Name = "btnCancel";
- this.btnCancel.Size = new System.Drawing.Size(80, 24);
- this.btnCancel.TabIndex = 5;
- this.btnCancel.Text = "Cancel";
- this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
- //
- // label2
- //
- this.label2.Location = new System.Drawing.Point(128, 40);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(136, 16);
- this.label2.TabIndex = 4;
- this.label2.Text = "(e.g. Ndb01 or 10.0.1.1)";
- //
- // label6
- //
- this.label6.Location = new System.Drawing.Point(48, 64);
- this.label6.Name = "label6";
- this.label6.Size = new System.Drawing.Size(80, 24);
- this.label6.TabIndex = 9;
- this.label6.Text = "CPCd port:";
- this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- //
- // textBoxPort
- //
- this.textBoxPort.Enabled = false;
- this.textBoxPort.Location = new System.Drawing.Point(128, 64);
- this.textBoxPort.Name = "textBoxPort";
- this.textBoxPort.Size = new System.Drawing.Size(136, 20);
- this.textBoxPort.TabIndex = 2;
- this.textBoxPort.TabStop = false;
- this.textBoxPort.Text = "";
- //
- // checkBoxDefault
- //
- this.checkBoxDefault.Checked = true;
- this.checkBoxDefault.CheckState = System.Windows.Forms.CheckState.Checked;
- this.checkBoxDefault.Location = new System.Drawing.Point(96, 96);
- this.checkBoxDefault.Name = "checkBoxDefault";
- this.checkBoxDefault.Size = new System.Drawing.Size(168, 16);
- this.checkBoxDefault.TabIndex = 3;
- this.checkBoxDefault.Text = "Use default port (1234)?";
- this.checkBoxDefault.CheckedChanged += new System.EventHandler(this.checkBoxDefault_CheckedChanged);
- //
- // ComputerAddDialog
- //
- this.AcceptButton = this.btnAdd;
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.CancelButton = this.btnCancel;
- this.ClientSize = new System.Drawing.Size(298, 159);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.checkBoxDefault,
- this.label6,
- this.textBoxPort,
- this.label2,
- this.btnCancel,
- this.btnAdd,
- this.label1,
- this.textboxComputerName});
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "ComputerAddDialog";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- this.Text = "Add a computer";
- this.Load += new System.EventHandler(this.ComputerAddDialog_Load);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- private void btnCancel_Click(object sender, System.EventArgs e)
- {
- this.Close();
- this.Dispose();
- }
-
- private void btnAdd_Click(object sender, System.EventArgs e)
- {
- int port;
- if(this.textboxComputerName.Text.Equals(""))
- {
- MessageBox.Show(this,"A computer must have an IP address or a host name","Warning!",MessageBoxButtons.OK);
- return;
- }
- if(this.checkBoxDefault.Checked)
- {
- port=1234;
- }
- else
- {
- if(this.textBoxPort.Text.Equals(""))
- {
- MessageBox.Show(this,"You must specify a port number!!!","Warning!",MessageBoxButtons.OK);
- return;
- }
- else
- {
- try
- {
- port=Convert.ToInt32(this.textBoxPort.Text.ToString());
-
- }
- catch (Exception exception)
- {
- MessageBox.Show(this,"Port number must be numeric!!!","Warning!",MessageBoxButtons.OK);
- return;
- }
- }
- }
-
- if(mgmt.getComputer(this.textboxComputerName.Text)==null)
- {
- mgmt.AddComputer(this.textboxComputerName.Text.ToString(),port);}
- else
- {
- MessageBox.Show("This computer does already exist!", "Add computer");
- return;
- }
-
- this.Dispose();
- }
-
- private void ComputerAddDialog_Load(object sender, System.EventArgs e)
- {
-
- }
-
- private void checkBoxDefault_CheckedChanged(object sender, System.EventArgs e)
- {
- if(checkBoxDefault.Checked)
- textBoxPort.Enabled=false;
- else
- textBoxPort.Enabled=true;
- }
-
-
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs b/storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs
deleted file mode 100644
index e2f32637a8c..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for ComputerRemoveDialog.
- /// </summary>
- public class ComputerRemoveDialog : System.Windows.Forms.Form
- {
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.ComboBox comboComputer;
- private System.Windows.Forms.Button btnCancel;
- private System.Windows.Forms.Button btnRemove;
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- private ComputerMgmt mgmt;
-
- public ComputerRemoveDialog(ComputerMgmt mgmt)
- {
- //
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- this.mgmt=mgmt;
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if(components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(ComputerRemoveDialog));
- this.label1 = new System.Windows.Forms.Label();
- this.comboComputer = new System.Windows.Forms.ComboBox();
- this.btnCancel = new System.Windows.Forms.Button();
- this.btnRemove = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // label1
- //
- this.label1.AccessibleDescription = ((string)(resources.GetObject("label1.AccessibleDescription")));
- this.label1.AccessibleName = ((string)(resources.GetObject("label1.AccessibleName")));
- this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("label1.Anchor")));
- this.label1.AutoSize = ((bool)(resources.GetObject("label1.AutoSize")));
- this.label1.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("label1.Dock")));
- this.label1.Enabled = ((bool)(resources.GetObject("label1.Enabled")));
- this.label1.Font = ((System.Drawing.Font)(resources.GetObject("label1.Font")));
- this.label1.Image = ((System.Drawing.Image)(resources.GetObject("label1.Image")));
- this.label1.ImageAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("label1.ImageAlign")));
- this.label1.ImageIndex = ((int)(resources.GetObject("label1.ImageIndex")));
- this.label1.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("label1.ImeMode")));
- this.label1.Location = ((System.Drawing.Point)(resources.GetObject("label1.Location")));
- this.label1.Name = "label1";
- this.label1.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("label1.RightToLeft")));
- this.label1.Size = ((System.Drawing.Size)(resources.GetObject("label1.Size")));
- this.label1.TabIndex = ((int)(resources.GetObject("label1.TabIndex")));
- this.label1.Text = resources.GetString("label1.Text");
- this.label1.TextAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("label1.TextAlign")));
- this.label1.Visible = ((bool)(resources.GetObject("label1.Visible")));
- //
- // comboComputer
- //
- this.comboComputer.AccessibleDescription = ((string)(resources.GetObject("comboComputer.AccessibleDescription")));
- this.comboComputer.AccessibleName = ((string)(resources.GetObject("comboComputer.AccessibleName")));
- this.comboComputer.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("comboComputer.Anchor")));
- this.comboComputer.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("comboComputer.BackgroundImage")));
- this.comboComputer.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("comboComputer.Dock")));
- this.comboComputer.Enabled = ((bool)(resources.GetObject("comboComputer.Enabled")));
- this.comboComputer.Font = ((System.Drawing.Font)(resources.GetObject("comboComputer.Font")));
- this.comboComputer.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("comboComputer.ImeMode")));
- this.comboComputer.IntegralHeight = ((bool)(resources.GetObject("comboComputer.IntegralHeight")));
- this.comboComputer.ItemHeight = ((int)(resources.GetObject("comboComputer.ItemHeight")));
- this.comboComputer.Location = ((System.Drawing.Point)(resources.GetObject("comboComputer.Location")));
- this.comboComputer.MaxDropDownItems = ((int)(resources.GetObject("comboComputer.MaxDropDownItems")));
- this.comboComputer.MaxLength = ((int)(resources.GetObject("comboComputer.MaxLength")));
- this.comboComputer.Name = "comboComputer";
- this.comboComputer.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("comboComputer.RightToLeft")));
- this.comboComputer.Size = ((System.Drawing.Size)(resources.GetObject("comboComputer.Size")));
- this.comboComputer.Sorted = true;
- this.comboComputer.TabIndex = ((int)(resources.GetObject("comboComputer.TabIndex")));
- this.comboComputer.Text = resources.GetString("comboComputer.Text");
- this.comboComputer.Visible = ((bool)(resources.GetObject("comboComputer.Visible")));
- this.comboComputer.SelectedIndexChanged += new System.EventHandler(this.comboComputer_SelectedIndexChanged);
- //
- // btnCancel
- //
- this.btnCancel.AccessibleDescription = ((string)(resources.GetObject("btnCancel.AccessibleDescription")));
- this.btnCancel.AccessibleName = ((string)(resources.GetObject("btnCancel.AccessibleName")));
- this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("btnCancel.Anchor")));
- this.btnCancel.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnCancel.BackgroundImage")));
- this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.btnCancel.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("btnCancel.Dock")));
- this.btnCancel.Enabled = ((bool)(resources.GetObject("btnCancel.Enabled")));
- this.btnCancel.FlatStyle = ((System.Windows.Forms.FlatStyle)(resources.GetObject("btnCancel.FlatStyle")));
- this.btnCancel.Font = ((System.Drawing.Font)(resources.GetObject("btnCancel.Font")));
- this.btnCancel.Image = ((System.Drawing.Image)(resources.GetObject("btnCancel.Image")));
- this.btnCancel.ImageAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("btnCancel.ImageAlign")));
- this.btnCancel.ImageIndex = ((int)(resources.GetObject("btnCancel.ImageIndex")));
- this.btnCancel.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("btnCancel.ImeMode")));
- this.btnCancel.Location = ((System.Drawing.Point)(resources.GetObject("btnCancel.Location")));
- this.btnCancel.Name = "btnCancel";
- this.btnCancel.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("btnCancel.RightToLeft")));
- this.btnCancel.Size = ((System.Drawing.Size)(resources.GetObject("btnCancel.Size")));
- this.btnCancel.TabIndex = ((int)(resources.GetObject("btnCancel.TabIndex")));
- this.btnCancel.Text = resources.GetString("btnCancel.Text");
- this.btnCancel.TextAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("btnCancel.TextAlign")));
- this.btnCancel.Visible = ((bool)(resources.GetObject("btnCancel.Visible")));
- this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
- //
- // btnRemove
- //
- this.btnRemove.AccessibleDescription = ((string)(resources.GetObject("btnRemove.AccessibleDescription")));
- this.btnRemove.AccessibleName = ((string)(resources.GetObject("btnRemove.AccessibleName")));
- this.btnRemove.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("btnRemove.Anchor")));
- this.btnRemove.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnRemove.BackgroundImage")));
- this.btnRemove.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("btnRemove.Dock")));
- this.btnRemove.Enabled = ((bool)(resources.GetObject("btnRemove.Enabled")));
- this.btnRemove.FlatStyle = ((System.Windows.Forms.FlatStyle)(resources.GetObject("btnRemove.FlatStyle")));
- this.btnRemove.Font = ((System.Drawing.Font)(resources.GetObject("btnRemove.Font")));
- this.btnRemove.Image = ((System.Drawing.Image)(resources.GetObject("btnRemove.Image")));
- this.btnRemove.ImageAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("btnRemove.ImageAlign")));
- this.btnRemove.ImageIndex = ((int)(resources.GetObject("btnRemove.ImageIndex")));
- this.btnRemove.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("btnRemove.ImeMode")));
- this.btnRemove.Location = ((System.Drawing.Point)(resources.GetObject("btnRemove.Location")));
- this.btnRemove.Name = "btnRemove";
- this.btnRemove.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("btnRemove.RightToLeft")));
- this.btnRemove.Size = ((System.Drawing.Size)(resources.GetObject("btnRemove.Size")));
- this.btnRemove.TabIndex = ((int)(resources.GetObject("btnRemove.TabIndex")));
- this.btnRemove.Text = resources.GetString("btnRemove.Text");
- this.btnRemove.TextAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("btnRemove.TextAlign")));
- this.btnRemove.Visible = ((bool)(resources.GetObject("btnRemove.Visible")));
- this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
- //
- // ComputerRemoveDialog
- //
- this.AcceptButton = this.btnRemove;
- this.AccessibleDescription = ((string)(resources.GetObject("$this.AccessibleDescription")));
- this.AccessibleName = ((string)(resources.GetObject("$this.AccessibleName")));
- this.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("$this.Anchor")));
- this.AutoScaleBaseSize = ((System.Drawing.Size)(resources.GetObject("$this.AutoScaleBaseSize")));
- this.AutoScroll = ((bool)(resources.GetObject("$this.AutoScroll")));
- this.AutoScrollMargin = ((System.Drawing.Size)(resources.GetObject("$this.AutoScrollMargin")));
- this.AutoScrollMinSize = ((System.Drawing.Size)(resources.GetObject("$this.AutoScrollMinSize")));
- this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
- this.CancelButton = this.btnCancel;
- this.ClientSize = ((System.Drawing.Size)(resources.GetObject("$this.ClientSize")));
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.btnRemove,
- this.btnCancel,
- this.comboComputer,
- this.label1});
- this.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("$this.Dock")));
- this.Enabled = ((bool)(resources.GetObject("$this.Enabled")));
- this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
- this.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("$this.ImeMode")));
- this.Location = ((System.Drawing.Point)(resources.GetObject("$this.Location")));
- this.MaximizeBox = false;
- this.MaximumSize = ((System.Drawing.Size)(resources.GetObject("$this.MaximumSize")));
- this.MinimizeBox = false;
- this.MinimumSize = ((System.Drawing.Size)(resources.GetObject("$this.MinimumSize")));
- this.Name = "ComputerRemoveDialog";
- this.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("$this.RightToLeft")));
- this.StartPosition = ((System.Windows.Forms.FormStartPosition)(resources.GetObject("$this.StartPosition")));
- this.Text = resources.GetString("$this.Text");
- this.Visible = ((bool)(resources.GetObject("$this.Visible")));
- this.Load += new System.EventHandler(this.ComputerRemoveDialog_Load);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- private void btnRemove_Click(object sender, System.EventArgs e)
- {
- mgmt.RemoveComputer(comboComputer.SelectedItem.ToString());
- this.Dispose();
- }
-
- private void ComputerRemoveDialog_Load(object sender, System.EventArgs e)
- {
- ArrayList list = mgmt.getComputerCollection();
- foreach (Computer computer in list)
- {
- comboComputer.Items.Add(computer.getName());
- }
- }
-
- private void btnCancel_Click(object sender, System.EventArgs e)
- {
- this.Close();
- this.Dispose();
- }
-
- private void comboComputer_SelectedIndexChanged(object sender, System.EventArgs e)
- {
- }
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/DATABASE.ICO b/storage/ndb/src/cw/cpcc-win32/csharp/DATABASE.ICO
deleted file mode 100644
index 9689aa88361..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/DATABASE.ICO
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/Database.cs b/storage/ndb/src/cw/cpcc-win32/csharp/Database.cs
deleted file mode 100644
index d08d3464b18..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/Database.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for Database.
- /// </summary>
- public class Database
- {
- public enum Status {Disconnected=1,Connected=2, Unknown=3}
- private string m_name;
- private string m_owner;
- private int m_mgmtPort;
- private Status m_status;
- private ArrayList m_processes;
- public Database(string name)
- {
- m_name=name;
- m_processes = new ArrayList();
- }
- public Database(string name, string owner)
- {
- m_name=name;
- m_owner=owner;
- m_processes = new ArrayList();
- }
- public Database()
- {
- m_processes = new ArrayList();
- }
-
- public string getName()
- {
- return m_name;
- }
-
- public void setName(string name)
- {
- m_name=name;
- }
-
- public void setMgmtPort(int port)
- {
- m_mgmtPort=port;
- }
-
- public string getOwner()
- {
- return m_owner;
- }
-
- public void setOwner(string name)
- {
- m_owner=name;
- }
-
-
- public Status getStatus()
- {
- return m_status;
- }
-
- public string getStatusString()
- {
- if(m_status.Equals(Status.Connected))
- return "Connected";
- if(m_status.Equals(Status.Disconnected))
- return "Disconnected";
- if(m_status.Equals(Status.Unknown))
- return "Unknown";
- return "Unknown";
- }
- public void setStatus(Status status)
- {
- m_status=status;
- }
-
- public void addProcess(Process process)
- {
- /*if(check)
- {
- if(m_processes==null)
- return;
- if(m_processes.Count>0)
- {
- foreach (Process p in m_processes)
- {
- if(process.getId().Equals(p.getId()))
- return;
- }
- }
- }
- */
- m_processes.Add(process);
- }
- public void addProcessCheck(Process process)
- {
-
- if(m_processes==null)
- return;
- if(m_processes.Count>0)
- {
- foreach (Process p in m_processes)
- {
- if(process.getId().Equals(p.getId()))
- return;
- }
- }
- m_processes.Add(process);
- }
-
- public Process getProcess(string id)
- {
- foreach(Process process in m_processes)
- {
- if(process.getId().Equals(id))
- return process;
- }
- return null;
- }
-
- public Process getProcessByName(string name)
- {
- foreach(Process process in m_processes)
- {
- if(process.getName().Equals(name))
- return process;
- }
- return null;
- }
-
- public void removeProcess( string processName)
- {
- Process p = this.getProcessByName(processName);
- m_processes.Remove(p);
- }
-
- public void removeAllProcesses()
- {
- Computer c;
- foreach(Process p in m_processes)
- {
- c=p.getComputer();
- if(c.removeProcess(p.getName(),m_name).Equals(false))
- {
-
- }
- }
- m_processes.Clear();
- }
-
- public ArrayList getProcesses()
- {
- return m_processes;
- }
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj b/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj
deleted file mode 100644
index 6384eff8329..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj
+++ /dev/null
@@ -1,240 +0,0 @@
-<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.0.9466"
- SchemaVersion = "1.0"
- ProjectGuid = "{B78F6720-D36C-43DD-B442-F583718D0286}"
- >
- <Build>
- <Settings
- ApplicationIcon = "App.ico"
- AssemblyKeyContainerName = ""
- AssemblyName = "NDB_CPC"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "WinExe"
- RootNamespace = "NDB_CPC"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE"
- DocumentationFile = ""
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "true"
- Optimize = "false"
- OutputPath = "bin\Debug\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE"
- DocumentationFile = ""
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- Optimize = "true"
- OutputPath = "bin\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
- />
- <Reference
- Name = "System.Drawing"
- AssemblyName = "System.Drawing"
- HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
- />
- <Reference
- Name = "System.Windows.Forms"
- AssemblyName = "System.Windows.Forms"
- HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
- />
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.0.3705\System.dll"
- />
- <Reference
- Name = "VBIDE"
- Guid = "{0002E157-0000-0000-C000-000000000046}"
- VersionMajor = "5"
- VersionMinor = "3"
- Lcid = "0"
- WrapperTool = "tlbimp"
- />
- <Reference
- Name = "stdole"
- Guid = "{00020430-0000-0000-C000-000000000046}"
- VersionMajor = "2"
- VersionMinor = "0"
- Lcid = "0"
- WrapperTool = "primary"
- />
- <Reference
- Name = "Microsoft.Office.Core"
- Guid = "{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}"
- VersionMajor = "2"
- VersionMinor = "2"
- Lcid = "0"
- WrapperTool = "tlbimp"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "app.config"
- BuildAction = "None"
- />
- <File
- RelPath = "App.ico"
- BuildAction = "Content"
- />
- <File
- RelPath = "AssemblyInfo.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "Computer.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ComputerAddDialog.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ComputerAddDialog.resx"
- DependentUpon = "ComputerAddDialog.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "ComputerMgmt.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ComputerRemoveDialog.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ComputerRemoveDialog.af.resx"
- DependentUpon = "ComputerRemoveDialog.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "ComputerRemoveDialog.resx"
- DependentUpon = "ComputerRemoveDialog.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "CPC_Form.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "CPC_Form.resx"
- DependentUpon = "CPC_Form.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "Database.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PanelWizard.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "PanelWizard.resx"
- DependentUpon = "PanelWizard.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "Process.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ProcessDefineDialog.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "ProcessDefineDialog.resx"
- DependentUpon = "ProcessDefineDialog.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "startDatabaseDlg.cs"
- SubType = "Form"
- BuildAction = "Compile"
- />
- <File
- RelPath = "startDatabaseDlg.resx"
- DependentUpon = "startDatabaseDlg.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "fileaccess\FileMgmt.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "simpleparser\SimpleCPCParser.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "socketcomm\myTcpClient.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "socketcomm\SocketComm.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "telnetclient\telnetClient.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj.user b/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj.user
deleted file mode 100644
index 68937906d93..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.csproj.user
+++ /dev/null
@@ -1,48 +0,0 @@
-<VisualStudioProject>
- <CSHARP>
- <Build>
- <Settings ReferencePath = "" >
- <Config
- Name = "Debug"
- EnableASPDebugging = "false"
- EnableASPXDebugging = "false"
- EnableUnmanagedDebugging = "false"
- EnableSQLServerDebugging = "false"
- RemoteDebugEnabled = "false"
- RemoteDebugMachine = ""
- StartAction = "Project"
- StartArguments = ""
- StartPage = ""
- StartProgram = ""
- StartURL = ""
- StartWorkingDirectory = ""
- StartWithIE = "false"
- />
- <Config
- Name = "Release"
- EnableASPDebugging = "false"
- EnableASPXDebugging = "false"
- EnableUnmanagedDebugging = "false"
- EnableSQLServerDebugging = "false"
- RemoteDebugEnabled = "false"
- RemoteDebugMachine = ""
- StartAction = "Project"
- StartArguments = ""
- StartPage = ""
- StartProgram = ""
- StartURL = ""
- StartWorkingDirectory = ""
- StartWithIE = "true"
- />
- </Settings>
- </Build>
- <OtherProjectSettings
- CopyProjectDestinationFolder = ""
- CopyProjectUncPath = ""
- CopyProjectOption = "0"
- ProjectView = "ProjectFiles"
- ProjectTrust = "0"
- />
- </CSHARP>
-</VisualStudioProject>
-
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.ncb b/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.ncb
deleted file mode 100644
index ed3460476b0..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.ncb
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.sln b/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.sln
deleted file mode 100644
index ef18b5e94ce..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/NDB_CPC.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NDB_CPC", "NDB_CPC.csproj", "{B78F6720-D36C-43DD-B442-F583718D0286}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {B78F6720-D36C-43DD-B442-F583718D0286}.Debug.ActiveCfg = Debug|.NET
- {B78F6720-D36C-43DD-B442-F583718D0286}.Debug.Build.0 = Debug|.NET
- {B78F6720-D36C-43DD-B442-F583718D0286}.Release.ActiveCfg = Release|.NET
- {B78F6720-D36C-43DD-B442-F583718D0286}.Release.Build.0 = Release|.NET
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs b/storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs
deleted file mode 100644
index e4cfc37e850..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs
+++ /dev/null
@@ -1,1899 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//author:Arun
-//date:Nov 13,2002
-//Wizard using panel
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for MDXQueryBuilderWizard.
- /// </summary>
- public class PanelWizard : System.Windows.Forms.Form
- {
- private System.Windows.Forms.Button btnCancel;
- private System.Windows.Forms.Button btnback;
- private System.Windows.Forms.Button btnNext;
- private System.Windows.Forms.Button btnFinish;
-
- //---enabling and disabling the buttons
- private bool cancelEnabled;
- private bool backEnabled;
- private bool nextEnabled;
- private bool finishEnabled;
- //--------
- //--set the next and back panel
- private Panel nextPanel;
- private Panel backPanel;
- private Panel presentPanel;
- //
- private Panel[] arrayPanel;
- private System.Windows.Forms.Panel panel1;
- private System.Windows.Forms.Panel panel2;
- private System.Windows.Forms.Panel panel3;
- private System.Windows.Forms.RadioButton radioBtnYes;
- private System.Windows.Forms.RadioButton radioBtnNo;
- private System.Windows.Forms.ListBox listBoxComputers;
- private System.Windows.Forms.Label label5;
- private System.Windows.Forms.Label label1;
- private System.ComponentModel.IContainer components;
- private System.Windows.Forms.Button buttonComputerAdd;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Label label6;
- private System.Windows.Forms.Label label7;
- private System.Windows.Forms.ComboBox comboNDB;
- private System.Windows.Forms.ComboBox comboAPI;
- private System.Windows.Forms.Label label8;
- private System.Windows.Forms.ComboBox comboMGM;
- private System.Windows.Forms.Button btnTransferNodeToComp;
- private System.Windows.Forms.TreeView tvComputer;
- private System.Windows.Forms.ListView lvNode;
- private System.Windows.Forms.Button btnTransferCompToNode;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.Label label9;
- private System.Windows.Forms.Label label10;
- private int m_nMGM;
- private ComputerMgmt mgmt;
- private int m_nNDB;
- private int m_nAPI;
- private Database m_db;
- private System.Windows.Forms.Label label11;
- private System.Windows.Forms.TextBox textDbName;
- private System.Windows.Forms.Label label31;
- private System.Windows.Forms.Label label32;
- private System.Windows.Forms.Label label33;
- private System.Windows.Forms.Label label18;
- private System.Windows.Forms.Label labelTitle;
- private System.Windows.Forms.Label labelCwd;
- private System.Windows.Forms.Label labelArgs;
- private System.Windows.Forms.Label labelOther;
- private System.Windows.Forms.Label labelPath;
- private int m_noOfConfiguredNodes;
- private int m_noOfConfiguredMgmt;
- private int m_noOfConfiguredNdb;
- private string m_mgmHost;
- private string m_mgmPort;
- private System.Windows.Forms.TextBox textCwd;
- private System.Windows.Forms.TextBox textArgs;
- private System.Windows.Forms.TextBox textOther;
- private System.Windows.Forms.TextBox textPath;
- private System.Windows.Forms.TextBox textComputer;
- private System.Windows.Forms.TextBox textDatabase;
- private System.Windows.Forms.TextBox textName;
- private int m_noOfConfiguredApi;
- private bool m_bMgmt;
- private System.Windows.Forms.Button buttonSave;
- private System.Windows.Forms.CheckBox checkBoxReuse;
- private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Panel panel4;
- private System.Windows.Forms.CheckBox checkBoxLater;
- private System.Windows.Forms.RadioButton radioYes;
- private System.Windows.Forms.RadioButton radioNo;
- private System.Windows.Forms.Panel panel6;
- private System.Windows.Forms.Panel panel5;
- private System.Windows.Forms.RadioButton radioStartNo;
- private System.Windows.Forms.RadioButton radioStartYes;
- private System.Windows.Forms.ImageList imageListComp;
- private System.Windows.Forms.Label label12;
- private System.Windows.Forms.TextBox textOwner;
- private System.Windows.Forms.Label label13;
- private System.Windows.Forms.TextBox textEnv;
- private bool m_bNdb;
- public PanelWizard(ComputerMgmt comp)
- {
- mgmt=comp;
- m_noOfConfiguredNodes=0;
- m_noOfConfiguredMgmt=0;
- m_noOfConfiguredNdb=0;
- m_noOfConfiguredApi=0;
- Size panelSize= new Size(350,300);
- Size s= new Size(355,360);
- Point cancel= new Point(8,310);
- Point back= new Point(96,310);
- Point next = new Point(184,310);
- Point finish= new Point(272,310);
- InitializeComponent();
- this.Size=s;
- this.btnCancel.Location=cancel;
-
- this.btnback.Location=back;
- this.btnNext.Location=next;
- this.btnFinish.Location=finish;
-
- arrayPanel=new Panel[]{panel1,panel2,panel3,panel4,panel5,panel6};//,panel5, panel6};
- panel1.Size=panelSize;
-
- comboNDB.SelectedIndex=0;
- comboAPI.SelectedIndex=0;
- comboMGM.SelectedIndex=0;
- m_bMgmt=false;
- m_bNdb=false;
-
- m_db = new Database();
- if(listBoxComputers.Items.Count.Equals(0))
- btnNext.Enabled=false;
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if(components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PanelWizard));
- this.panel1 = new System.Windows.Forms.Panel();
- this.buttonComputerAdd = new System.Windows.Forms.Button();
- this.label1 = new System.Windows.Forms.Label();
- this.label5 = new System.Windows.Forms.Label();
- this.listBoxComputers = new System.Windows.Forms.ListBox();
- this.radioBtnNo = new System.Windows.Forms.RadioButton();
- this.radioBtnYes = new System.Windows.Forms.RadioButton();
- this.panel2 = new System.Windows.Forms.Panel();
- this.label12 = new System.Windows.Forms.Label();
- this.textOwner = new System.Windows.Forms.TextBox();
- this.label11 = new System.Windows.Forms.Label();
- this.textDbName = new System.Windows.Forms.TextBox();
- this.label8 = new System.Windows.Forms.Label();
- this.label7 = new System.Windows.Forms.Label();
- this.label6 = new System.Windows.Forms.Label();
- this.comboMGM = new System.Windows.Forms.ComboBox();
- this.comboAPI = new System.Windows.Forms.ComboBox();
- this.comboNDB = new System.Windows.Forms.ComboBox();
- this.label2 = new System.Windows.Forms.Label();
- this.panel3 = new System.Windows.Forms.Panel();
- this.checkBoxLater = new System.Windows.Forms.CheckBox();
- this.label10 = new System.Windows.Forms.Label();
- this.label9 = new System.Windows.Forms.Label();
- this.label3 = new System.Windows.Forms.Label();
- this.btnTransferCompToNode = new System.Windows.Forms.Button();
- this.btnTransferNodeToComp = new System.Windows.Forms.Button();
- this.lvNode = new System.Windows.Forms.ListView();
- this.tvComputer = new System.Windows.Forms.TreeView();
- this.imageListComp = new System.Windows.Forms.ImageList(this.components);
- this.panel6 = new System.Windows.Forms.Panel();
- this.radioStartNo = new System.Windows.Forms.RadioButton();
- this.radioStartYes = new System.Windows.Forms.RadioButton();
- this.label18 = new System.Windows.Forms.Label();
- this.btnCancel = new System.Windows.Forms.Button();
- this.btnback = new System.Windows.Forms.Button();
- this.btnNext = new System.Windows.Forms.Button();
- this.btnFinish = new System.Windows.Forms.Button();
- this.panel4 = new System.Windows.Forms.Panel();
- this.textEnv = new System.Windows.Forms.TextBox();
- this.label13 = new System.Windows.Forms.Label();
- this.checkBoxReuse = new System.Windows.Forms.CheckBox();
- this.buttonSave = new System.Windows.Forms.Button();
- this.labelTitle = new System.Windows.Forms.Label();
- this.textComputer = new System.Windows.Forms.TextBox();
- this.textCwd = new System.Windows.Forms.TextBox();
- this.textArgs = new System.Windows.Forms.TextBox();
- this.textOther = new System.Windows.Forms.TextBox();
- this.textPath = new System.Windows.Forms.TextBox();
- this.textDatabase = new System.Windows.Forms.TextBox();
- this.textName = new System.Windows.Forms.TextBox();
- this.labelCwd = new System.Windows.Forms.Label();
- this.labelArgs = new System.Windows.Forms.Label();
- this.labelOther = new System.Windows.Forms.Label();
- this.labelPath = new System.Windows.Forms.Label();
- this.label31 = new System.Windows.Forms.Label();
- this.label32 = new System.Windows.Forms.Label();
- this.label33 = new System.Windows.Forms.Label();
- this.panel5 = new System.Windows.Forms.Panel();
- this.radioNo = new System.Windows.Forms.RadioButton();
- this.radioYes = new System.Windows.Forms.RadioButton();
- this.label4 = new System.Windows.Forms.Label();
- this.panel1.SuspendLayout();
- this.panel2.SuspendLayout();
- this.panel3.SuspendLayout();
- this.panel6.SuspendLayout();
- this.panel4.SuspendLayout();
- this.panel5.SuspendLayout();
- this.SuspendLayout();
- //
- // panel1
- //
- this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.buttonComputerAdd,
- this.label1,
- this.label5,
- this.listBoxComputers,
- this.radioBtnNo,
- this.radioBtnYes});
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(344, 312);
- this.panel1.TabIndex = 0;
- this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
- //
- // buttonComputerAdd
- //
- this.buttonComputerAdd.Enabled = false;
- this.buttonComputerAdd.Location = new System.Drawing.Point(192, 232);
- this.buttonComputerAdd.Name = "buttonComputerAdd";
- this.buttonComputerAdd.Size = new System.Drawing.Size(96, 24);
- this.buttonComputerAdd.TabIndex = 3;
- this.buttonComputerAdd.Text = "Add computer...";
- this.buttonComputerAdd.Click += new System.EventHandler(this.buttonComputerAdd_Click);
- //
- // label1
- //
- this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label1.Location = new System.Drawing.Point(80, 8);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(200, 23);
- this.label1.TabIndex = 5;
- this.label1.Text = "Configure computers";
- this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // label5
- //
- this.label5.Location = new System.Drawing.Point(24, 40);
- this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(128, 23);
- this.label5.TabIndex = 4;
- this.label5.Text = "Available computers:";
- this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // listBoxComputers
- //
- this.listBoxComputers.Location = new System.Drawing.Point(24, 64);
- this.listBoxComputers.Name = "listBoxComputers";
- this.listBoxComputers.Size = new System.Drawing.Size(128, 212);
- this.listBoxComputers.TabIndex = 3;
- this.listBoxComputers.SelectedIndexChanged += new System.EventHandler(this.listBoxComputers_SelectedIndexChanged);
- //
- // radioBtnNo
- //
- this.radioBtnNo.AutoCheck = false;
- this.radioBtnNo.Location = new System.Drawing.Point(168, 168);
- this.radioBtnNo.Name = "radioBtnNo";
- this.radioBtnNo.Size = new System.Drawing.Size(152, 64);
- this.radioBtnNo.TabIndex = 2;
- this.radioBtnNo.Text = "No, I have to add more computers in order to deploy NDB Cluster. ";
- this.radioBtnNo.Click += new System.EventHandler(this.radioBtnNo_Click);
- //
- // radioBtnYes
- //
- this.radioBtnYes.AutoCheck = false;
- this.radioBtnYes.Location = new System.Drawing.Point(168, 72);
- this.radioBtnYes.Name = "radioBtnYes";
- this.radioBtnYes.Size = new System.Drawing.Size(152, 80);
- this.radioBtnYes.TabIndex = 1;
- this.radioBtnYes.Text = "Yes, all the computers that I need to deploy NDB Cluster exists in the list \"Avai" +
- "lable computers\"";
- this.radioBtnYes.Click += new System.EventHandler(this.radioBtnYes_Click);
- //
- // panel2
- //
- this.panel2.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.label12,
- this.textOwner,
- this.label11,
- this.textDbName,
- this.label8,
- this.label7,
- this.label6,
- this.comboMGM,
- this.comboAPI,
- this.comboNDB,
- this.label2});
- this.panel2.Location = new System.Drawing.Point(0, 320);
- this.panel2.Name = "panel2";
- this.panel2.Size = new System.Drawing.Size(344, 312);
- this.panel2.TabIndex = 1;
- this.panel2.Validating += new System.ComponentModel.CancelEventHandler(this.panel2_Validating);
- this.panel2.Paint += new System.Windows.Forms.PaintEventHandler(this.panel2_Paint);
- //
- // label12
- //
- this.label12.Location = new System.Drawing.Point(72, 216);
- this.label12.Name = "label12";
- this.label12.Size = new System.Drawing.Size(112, 24);
- this.label12.TabIndex = 16;
- this.label12.Text = "Database owner:";
- this.label12.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- //
- // textOwner
- //
- this.textOwner.Location = new System.Drawing.Point(192, 216);
- this.textOwner.Name = "textOwner";
- this.textOwner.TabIndex = 5;
- this.textOwner.Text = "";
- this.textOwner.TextChanged += new System.EventHandler(this.textOwner_TextChanged);
- //
- // label11
- //
- this.label11.Location = new System.Drawing.Point(72, 184);
- this.label11.Name = "label11";
- this.label11.Size = new System.Drawing.Size(112, 24);
- this.label11.TabIndex = 14;
- this.label11.Text = "Database name:";
- this.label11.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.label11.Click += new System.EventHandler(this.label11_Click);
- //
- // textDbName
- //
- this.textDbName.Location = new System.Drawing.Point(192, 184);
- this.textDbName.Name = "textDbName";
- this.textDbName.TabIndex = 4;
- this.textDbName.Text = "";
-
- this.textDbName.TextChanged += new System.EventHandler(this.textDbName_TextChanged);
- //
- // label8
- //
- this.label8.Location = new System.Drawing.Point(16, 120);
- this.label8.Name = "label8";
- this.label8.Size = new System.Drawing.Size(176, 24);
- this.label8.TabIndex = 12;
- this.label8.Text = "Number of management servers:";
- this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
- //
- // label7
- //
- this.label7.Location = new System.Drawing.Point(16, 88);
- this.label7.Name = "label7";
- this.label7.Size = new System.Drawing.Size(120, 24);
- this.label7.TabIndex = 11;
- this.label7.Text = "Number of API nodes:";
- this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
- //
- // label6
- //
- this.label6.Location = new System.Drawing.Point(16, 56);
- this.label6.Name = "label6";
- this.label6.Size = new System.Drawing.Size(144, 24);
- this.label6.TabIndex = 10;
- this.label6.Text = "Number of database nodes:";
- this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
- //
- // comboMGM
- //
- this.comboMGM.DisplayMember = "0";
- this.comboMGM.Items.AddRange(new object[] {
- "1"});
- this.comboMGM.Location = new System.Drawing.Point(192, 120);
- this.comboMGM.Name = "comboMGM";
- this.comboMGM.Size = new System.Drawing.Size(104, 21);
- this.comboMGM.TabIndex = 3;
- this.comboMGM.Text = "comboBox3";
- //
- // comboAPI
- //
- this.comboAPI.DisplayMember = "0";
- this.comboAPI.Items.AddRange(new object[] {
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- "8",
- "9",
- "10"});
- this.comboAPI.Location = new System.Drawing.Point(192, 88);
- this.comboAPI.Name = "comboAPI";
- this.comboAPI.Size = new System.Drawing.Size(104, 21);
- this.comboAPI.TabIndex = 2;
- this.comboAPI.Text = "comboBox2";
- //
- // comboNDB
- //
- this.comboNDB.DisplayMember = "0";
- this.comboNDB.Items.AddRange(new object[] {
- "1",
- "2",
- "4",
- "8"});
- this.comboNDB.Location = new System.Drawing.Point(192, 56);
- this.comboNDB.Name = "comboNDB";
- this.comboNDB.Size = new System.Drawing.Size(104, 21);
- this.comboNDB.TabIndex = 1;
- this.comboNDB.Text = "comboBox1";
- //
- // label2
- //
- this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label2.Location = new System.Drawing.Point(80, 8);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(208, 23);
- this.label2.TabIndex = 6;
- this.label2.Text = "Setup NDB Cluster nodes";
- this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // panel3
- //
- this.panel3.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.checkBoxLater,
- this.label10,
- this.label9,
- this.label3,
- this.btnTransferCompToNode,
- this.btnTransferNodeToComp,
- this.lvNode,
- this.tvComputer});
- this.panel3.Location = new System.Drawing.Point(360, 8);
- this.panel3.Name = "panel3";
- this.panel3.Size = new System.Drawing.Size(320, 312);
- this.panel3.TabIndex = 2;
- //
- // checkBoxLater
- //
- this.checkBoxLater.Location = new System.Drawing.Point(40, 256);
- this.checkBoxLater.Name = "checkBoxLater";
- this.checkBoxLater.Size = new System.Drawing.Size(240, 16);
- this.checkBoxLater.TabIndex = 9;
- this.checkBoxLater.Text = "I will configure these nodes manually, later.";
- //
- // label10
- //
- this.label10.Location = new System.Drawing.Point(16, 40);
- this.label10.Name = "label10";
- this.label10.Size = new System.Drawing.Size(104, 16);
- this.label10.TabIndex = 8;
- this.label10.Text = "NDB Cluster nodes:";
- this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
- //
- // label9
- //
- this.label9.Location = new System.Drawing.Point(192, 40);
- this.label9.Name = "label9";
- this.label9.Size = new System.Drawing.Size(100, 16);
- this.label9.TabIndex = 7;
- this.label9.Text = "Computers:";
- this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
- //
- // label3
- //
- this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label3.Location = new System.Drawing.Point(40, 8);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(280, 23);
- this.label3.TabIndex = 6;
- this.label3.Text = "Assign NDB nodes to computers";
- this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // btnTransferCompToNode
- //
- this.btnTransferCompToNode.Location = new System.Drawing.Point(144, 160);
- this.btnTransferCompToNode.Name = "btnTransferCompToNode";
- this.btnTransferCompToNode.Size = new System.Drawing.Size(40, 24);
- this.btnTransferCompToNode.TabIndex = 4;
- this.btnTransferCompToNode.Text = "<---";
- //
- // btnTransferNodeToComp
- //
- this.btnTransferNodeToComp.Location = new System.Drawing.Point(144, 128);
- this.btnTransferNodeToComp.Name = "btnTransferNodeToComp";
- this.btnTransferNodeToComp.Size = new System.Drawing.Size(40, 24);
- this.btnTransferNodeToComp.TabIndex = 3;
- this.btnTransferNodeToComp.Text = "--->";
- this.btnTransferNodeToComp.Click += new System.EventHandler(this.btnTransferNodeToComp_Click);
- //
- // lvNode
- //
- this.lvNode.HideSelection = false;
- this.lvNode.Location = new System.Drawing.Point(16, 56);
- this.lvNode.Name = "lvNode";
- this.lvNode.Size = new System.Drawing.Size(112, 192);
- this.lvNode.TabIndex = 2;
- this.lvNode.View = System.Windows.Forms.View.List;
- this.lvNode.SelectedIndexChanged += new System.EventHandler(this.lvNode_SelectedIndexChanged);
- //
- // tvComputer
- //
- this.tvComputer.HideSelection = false;
- this.tvComputer.ImageList = this.imageListComp;
- this.tvComputer.Location = new System.Drawing.Point(192, 56);
- this.tvComputer.Name = "tvComputer";
- this.tvComputer.Size = new System.Drawing.Size(120, 192);
- this.tvComputer.TabIndex = 1;
- this.tvComputer.MouseDown += new System.Windows.Forms.MouseEventHandler(this.tvComputer_MouseDown);
- this.tvComputer.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvComputer_AfterSelect);
- this.tvComputer.MouseLeave += new System.EventHandler(this.tvComputer_MouseLeave);
- this.tvComputer.DragDrop += new System.Windows.Forms.DragEventHandler(this.tvComputer_DragDrop);
- //
- // imageListComp
- //
- this.imageListComp.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
- this.imageListComp.ImageSize = new System.Drawing.Size(16, 16);
- this.imageListComp.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListComp.ImageStream")));
- this.imageListComp.TransparentColor = System.Drawing.Color.Transparent;
- //
- // panel6
- //
- this.panel6.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.radioStartNo,
- this.radioStartYes,
- this.label18});
- this.panel6.Location = new System.Drawing.Point(344, 336);
- this.panel6.Name = "panel6";
- this.panel6.Size = new System.Drawing.Size(344, 312);
- this.panel6.TabIndex = 3;
- this.panel6.Paint += new System.Windows.Forms.PaintEventHandler(this.panel4_Paint);
- //
- // radioStartNo
- //
- this.radioStartNo.Location = new System.Drawing.Point(40, 144);
- this.radioStartNo.Name = "radioStartNo";
- this.radioStartNo.Size = new System.Drawing.Size(272, 48);
- this.radioStartNo.TabIndex = 81;
- this.radioStartNo.Text = "Manually start NDB Cluster. The Magician will exit and you must start NDB Cluster" +
- " manually.";
- this.radioStartNo.CheckedChanged += new System.EventHandler(this.radioStartNo_CheckedChanged);
- //
- // radioStartYes
- //
- this.radioStartYes.Location = new System.Drawing.Point(40, 40);
- this.radioStartYes.Name = "radioStartYes";
- this.radioStartYes.Size = new System.Drawing.Size(272, 88);
- this.radioStartYes.TabIndex = 80;
- this.radioStartYes.Text = "Start NDB Cluster now. The Magician will start NDB Cluster and exit. MAKE SURE YO" +
- "U HAVE STARTED THE MGMTSRVR WITH THE CORRECT CONFIGURATION FILE!!!";
- this.radioStartYes.CheckedChanged += new System.EventHandler(this.radioStartYes_CheckedChanged);
- //
- // label18
- //
- this.label18.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label18.Location = new System.Drawing.Point(56, 8);
- this.label18.Name = "label18";
- this.label18.Size = new System.Drawing.Size(224, 24);
- this.label18.TabIndex = 79;
- this.label18.Text = "Start NDB Cluster and finish";
- //
- // btnCancel
- //
- this.btnCancel.Location = new System.Drawing.Point(8, 656);
- this.btnCancel.Name = "btnCancel";
- this.btnCancel.Size = new System.Drawing.Size(70, 23);
- this.btnCancel.TabIndex = 10;
- this.btnCancel.Text = "Cancel";
- this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
- //
- // btnback
- //
- this.btnback.Location = new System.Drawing.Point(96, 656);
- this.btnback.Name = "btnback";
- this.btnback.Size = new System.Drawing.Size(70, 23);
- this.btnback.TabIndex = 11;
- this.btnback.Text = "< Back";
- this.btnback.Click += new System.EventHandler(this.btnback_Click);
- //
- // btnNext
- //
- this.btnNext.Location = new System.Drawing.Point(184, 656);
- this.btnNext.Name = "btnNext";
- this.btnNext.Size = new System.Drawing.Size(70, 23);
- this.btnNext.TabIndex = 12;
- this.btnNext.Text = "Next >";
- this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
- //
- // btnFinish
- //
- this.btnFinish.Location = new System.Drawing.Point(272, 656);
- this.btnFinish.Name = "btnFinish";
- this.btnFinish.Size = new System.Drawing.Size(70, 23);
- this.btnFinish.TabIndex = 13;
- this.btnFinish.Text = "Finish";
- this.btnFinish.Click += new System.EventHandler(this.btnFinish_Click);
- //
- // panel4
- //
- this.panel4.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.textEnv,
- this.label13,
- this.checkBoxReuse,
- this.buttonSave,
- this.labelTitle,
- this.textComputer,
- this.textCwd,
- this.textArgs,
- this.textOther,
- this.textPath,
- this.textDatabase,
- this.textName,
- this.labelCwd,
- this.labelArgs,
- this.labelOther,
- this.labelPath,
- this.label31,
- this.label32,
- this.label33});
- this.panel4.Location = new System.Drawing.Point(672, 8);
- this.panel4.Name = "panel4";
- this.panel4.Size = new System.Drawing.Size(344, 312);
- this.panel4.TabIndex = 62;
- this.panel4.Paint += new System.Windows.Forms.PaintEventHandler(this.panel5_Paint);
- //
- // textEnv
- //
- this.textEnv.Location = new System.Drawing.Point(136, 136);
- this.textEnv.Name = "textEnv";
- this.textEnv.Size = new System.Drawing.Size(184, 20);
- this.textEnv.TabIndex = 2;
- this.textEnv.TabStop = false;
- this.textEnv.Text = "";
- //
- // label13
- //
- this.label13.Location = new System.Drawing.Point(8, 136);
- this.label13.Name = "label13";
- this.label13.Size = new System.Drawing.Size(136, 24);
- this.label13.TabIndex = 81;
- this.label13.Text = "Environment variables:";
- //
- // checkBoxReuse
- //
- this.checkBoxReuse.Location = new System.Drawing.Point(88, 232);
- this.checkBoxReuse.Name = "checkBoxReuse";
- this.checkBoxReuse.Size = new System.Drawing.Size(240, 32);
- this.checkBoxReuse.TabIndex = 5;
- this.checkBoxReuse.TabStop = false;
- this.checkBoxReuse.Text = "Use the same configuration for ALL NDB nodes?";
- //
- // buttonSave
- //
- this.buttonSave.Location = new System.Drawing.Point(184, 264);
- this.buttonSave.Name = "buttonSave";
- this.buttonSave.Size = new System.Drawing.Size(88, 24);
- this.buttonSave.TabIndex = 6;
- this.buttonSave.Text = "Save";
- this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
- //
- // labelTitle
- //
- this.labelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.labelTitle.Location = new System.Drawing.Point(80, 16);
- this.labelTitle.Name = "labelTitle";
- this.labelTitle.Size = new System.Drawing.Size(192, 23);
- this.labelTitle.TabIndex = 79;
- this.labelTitle.Text = "Mgmtsrvr configuration";
- //
- // textComputer
- //
- this.textComputer.Location = new System.Drawing.Point(136, 40);
- this.textComputer.Name = "textComputer";
- this.textComputer.ReadOnly = true;
- this.textComputer.Size = new System.Drawing.Size(184, 20);
- this.textComputer.TabIndex = 77;
- this.textComputer.TabStop = false;
- this.textComputer.Text = "";
- //
- // textCwd
- //
- this.textCwd.Location = new System.Drawing.Point(136, 208);
- this.textCwd.Name = "textCwd";
- this.textCwd.Size = new System.Drawing.Size(184, 20);
- this.textCwd.TabIndex = 5;
- this.textCwd.TabStop = false;
- this.textCwd.Text = "";
- //
- // textArgs
- //
- this.textArgs.Location = new System.Drawing.Point(136, 184);
- this.textArgs.Name = "textArgs";
- this.textArgs.Size = new System.Drawing.Size(184, 20);
- this.textArgs.TabIndex = 4;
- this.textArgs.TabStop = false;
- this.textArgs.Text = "";
- //
- // textOther
- //
- this.textOther.Location = new System.Drawing.Point(136, 160);
- this.textOther.Name = "textOther";
- this.textOther.Size = new System.Drawing.Size(184, 20);
- this.textOther.TabIndex = 3;
- this.textOther.TabStop = false;
- this.textOther.Text = "";
- //
- // textPath
- //
- this.textPath.Location = new System.Drawing.Point(136, 112);
- this.textPath.Name = "textPath";
- this.textPath.Size = new System.Drawing.Size(184, 20);
- this.textPath.TabIndex = 1;
- this.textPath.TabStop = false;
- this.textPath.Text = "";
- this.textPath.TextChanged += new System.EventHandler(this.textPath_TextChanged);
- //
- // textDatabase
- //
- this.textDatabase.Location = new System.Drawing.Point(136, 88);
- this.textDatabase.Name = "textDatabase";
- this.textDatabase.ReadOnly = true;
- this.textDatabase.Size = new System.Drawing.Size(184, 20);
- this.textDatabase.TabIndex = 62;
- this.textDatabase.TabStop = false;
- this.textDatabase.Text = "";
- //
- // textName
- //
- this.textName.Location = new System.Drawing.Point(136, 64);
- this.textName.Name = "textName";
- this.textName.ReadOnly = true;
- this.textName.Size = new System.Drawing.Size(184, 20);
- this.textName.TabIndex = 60;
- this.textName.TabStop = false;
- this.textName.Text = "";
- //
- // labelCwd
- //
- this.labelCwd.Location = new System.Drawing.Point(8, 208);
- this.labelCwd.Name = "labelCwd";
- this.labelCwd.Size = new System.Drawing.Size(112, 24);
- this.labelCwd.TabIndex = 72;
- this.labelCwd.Text = "Current working dir.:";
- //
- // labelArgs
- //
- this.labelArgs.Location = new System.Drawing.Point(8, 184);
- this.labelArgs.Name = "labelArgs";
- this.labelArgs.Size = new System.Drawing.Size(128, 24);
- this.labelArgs.TabIndex = 70;
- this.labelArgs.Text = "Arguments to mgmtsrvr:";
- //
- // labelOther
- //
- this.labelOther.Location = new System.Drawing.Point(8, 160);
- this.labelOther.Name = "labelOther";
- this.labelOther.Size = new System.Drawing.Size(136, 24);
- this.labelOther.TabIndex = 69;
- this.labelOther.Text = "Mgmtsrvr port:";
- //
- // labelPath
- //
- this.labelPath.Location = new System.Drawing.Point(8, 112);
- this.labelPath.Name = "labelPath";
- this.labelPath.Size = new System.Drawing.Size(128, 24);
- this.labelPath.TabIndex = 67;
- this.labelPath.Text = "Path to mgmtsrvr binary:";
- //
- // label31
- //
- this.label31.Location = new System.Drawing.Point(8, 88);
- this.label31.Name = "label31";
- this.label31.Size = new System.Drawing.Size(88, 24);
- this.label31.TabIndex = 65;
- this.label31.Text = "Database:";
- //
- // label32
- //
- this.label32.Location = new System.Drawing.Point(8, 64);
- this.label32.Name = "label32";
- this.label32.Size = new System.Drawing.Size(88, 24);
- this.label32.TabIndex = 63;
- this.label32.Text = "Process name:";
- //
- // label33
- //
- this.label33.Location = new System.Drawing.Point(8, 40);
- this.label33.Name = "label33";
- this.label33.Size = new System.Drawing.Size(64, 24);
- this.label33.TabIndex = 61;
- this.label33.Text = "Computer:";
- //
- // panel5
- //
- this.panel5.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.radioNo,
- this.radioYes,
- this.label4});
- this.panel5.Location = new System.Drawing.Point(672, 328);
- this.panel5.Name = "panel5";
- this.panel5.Size = new System.Drawing.Size(344, 312);
- this.panel5.TabIndex = 63;
- //
- // radioNo
- //
- this.radioNo.Location = new System.Drawing.Point(72, 160);
- this.radioNo.Name = "radioNo";
- this.radioNo.Size = new System.Drawing.Size(240, 48);
- this.radioNo.TabIndex = 1;
- this.radioNo.Text = "I already have a configuration file that I want to use for this configuration.";
- this.radioNo.CheckedChanged += new System.EventHandler(this.radioNo_CheckedChanged);
- //
- // radioYes
- //
- this.radioYes.Checked = true;
- this.radioYes.Location = new System.Drawing.Point(72, 56);
- this.radioYes.Name = "radioYes";
- this.radioYes.Size = new System.Drawing.Size(240, 88);
- this.radioYes.TabIndex = 0;
- this.radioYes.TabStop = true;
- this.radioYes.Text = "Generate a configuration file template (initconfig.txt) for the mgmtsrvr based on" +
- " the specified configuration? Notepad will be started with a template that you m" +
- "ust complete and save in the cwd of the mgmtsrvr.";
- this.radioYes.CheckedChanged += new System.EventHandler(this.radioYes_CheckedChanged);
- //
- // label4
- //
- this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
- this.label4.Location = new System.Drawing.Point(88, 8);
- this.label4.Name = "label4";
- this.label4.Size = new System.Drawing.Size(192, 40);
- this.label4.TabIndex = 79;
- this.label4.Text = "Tying up the configuration";
- this.label4.TextAlign = System.Drawing.ContentAlignment.TopCenter;
- //
- // PanelWizard
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(1030, 755);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.panel5,
- this.panel4,
- this.panel1,
- this.btnFinish,
- this.btnNext,
- this.btnback,
- this.btnCancel,
- this.panel6,
- this.panel3,
- this.panel2});
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "PanelWizard";
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
- this.Text = "Create Database Magician";
- this.Load += new System.EventHandler(this.MDXQueryBuilderWizard_Load);
- this.Activated += new System.EventHandler(this.PanelWizard_Activated);
- this.panel1.ResumeLayout(false);
- this.panel2.ResumeLayout(false);
- this.panel3.ResumeLayout(false);
- this.panel6.ResumeLayout(false);
- this.panel4.ResumeLayout(false);
- this.panel5.ResumeLayout(false);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- private void MDXQueryBuilderWizard_Load(object sender, System.EventArgs e)
- {
-
- foreach(Control ct in this.Controls)
- {
- if(ct.GetType().Name=="Panel")
- {
- ct.Left=0;
- ct.Top=0;
- ct.Visible=false;
- }
-
- }
- presentPanel=arrayPanel[0];
- //--set the properties
- setBtnPanProperty(getPosition(presentPanel));
- //------
- refreshLook();
- }
-
- //-set the buttons and panel
- private void refreshLook()
- {
- if(cancelEnabled)
- btnCancel.Enabled=true;
- else
- btnCancel.Enabled=false;
-
- if(backEnabled)
- btnback.Enabled=true;
- else
- btnback.Enabled=false;
-
- if(nextEnabled)
- btnNext.Enabled=true;
- else
- btnNext.Enabled=false;
-
- if(finishEnabled)
- btnFinish.Enabled=true;
- else
- btnFinish.Enabled=false;
-
- if(presentPanel!=null)
- {
- presentPanel.Show();
- presentPanel.BringToFront();
- }
- }
- //--------
- private int getPosition(Panel p)
- {
- int result=-1;
- for(int i=0;i<arrayPanel.Length;i++)
- {
- if(arrayPanel[i]==p)
- {
- result=i;
- break;
- }
- }
- return result ;
- }
- //----
-
- private void setBtnPanProperty(int presentPanelPosition )
- {
- int panelLength=arrayPanel.Length-1;
- if(presentPanelPosition==0)
- {
- //first panel...no back ,no finish
- cancelEnabled=true;
- backEnabled=false;
- nextEnabled=false;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=arrayPanel[presentPanelPosition+1];
- backPanel=null;
-
- }
- else if(presentPanelPosition==1)
- {
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=false;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=arrayPanel[presentPanelPosition+1];
- backPanel=arrayPanel[presentPanelPosition-1];
- }
-
- else if(presentPanelPosition==2)
- {
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=false;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=arrayPanel[presentPanelPosition+1];
- backPanel=arrayPanel[presentPanelPosition-1];
- }
-
- else if(presentPanelPosition==3)
- {
- //last panel...no next,finish
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=true;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=arrayPanel[presentPanelPosition+1];
- backPanel=arrayPanel[presentPanelPosition-1];
- }
- else if(presentPanelPosition==4)
- {
- //last panel...no next,finish
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=true;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=presentPanel;
- backPanel=arrayPanel[presentPanelPosition-1];
- }
-
- else if(presentPanelPosition==5)
- {
- //last panel...no next,finish yes
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=false;
- finishEnabled=false;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=null;
- backPanel=arrayPanel[presentPanelPosition-1];
- }
-
- else
- {
- //no finish,next and back
- cancelEnabled=true;
- backEnabled=true;
- nextEnabled=false;
- finishEnabled=true;
- presentPanel=arrayPanel[presentPanelPosition];
- nextPanel=null;
- backPanel=arrayPanel[presentPanelPosition-1];
- }
- }
-
- private void btnNext_Click(object sender, System.EventArgs e)
- {
-
- if(arrayPanel[getPosition(presentPanel)].Equals(panel1))
- {
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- refreshLook();
- return;
- }
- if(arrayPanel[getPosition(presentPanel)].Equals(panel2))
- {
- m_db.setName(textDbName.Text.ToString());
- m_db.setOwner(textOwner.Text.ToString());
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- //presentPanel
- setBtnPanProperty(getPosition(presentPanel));
- prepareNodeAssignmentPanel();
- refreshLook();
-
- return;
- }
- if(arrayPanel[getPosition(presentPanel)].Equals(panel3))
- {
- prepareNodeConfigurationPanel();
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- refreshLook();
- return;
- }
- if(arrayPanel[getPosition(presentPanel)].Equals(panel4))
- {
- nextEnabled=true;
- finishEnabled=true;
- backEnabled=true;
- cancelEnabled=true;
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- refreshLook();
- return;
- }
- if(arrayPanel[getPosition(presentPanel)].Equals(panel5))
- {
- generateInitConfig();
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- refreshLook();
- return;
- }
-
- if(arrayPanel[getPosition(presentPanel)].Equals(panel6))
- {
- // presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- refreshLook();
- return;
- }
- /*else
- {
- presentPanel=arrayPanel[getPosition(presentPanel)+1];
- setBtnPanProperty(getPosition(presentPanel));
- updateListViews();
- refreshLook();
- }*/
- }
-
-
- private void btnback_Click(object sender, System.EventArgs e)
- {
- presentPanel=arrayPanel[getPosition(presentPanel)-1];
- setBtnPanProperty(getPosition(presentPanel));
- m_noOfConfiguredNodes=0;
- m_noOfConfiguredNodes=0;
- m_noOfConfiguredMgmt=0;
- m_noOfConfiguredNdb=0;
- m_noOfConfiguredApi=0;
- m_bNdb=false;
- m_bMgmt=false;
- refreshLook();
- }
-
-
- private void btnCancel_Click(object sender, System.EventArgs e)
- {
- m_db.removeAllProcesses();
- this.Dispose(true);
- }
-
-
-
-
- private void radioBtnYes_Click(object sender, System.EventArgs e)
- {
- if(radioBtnNo.Checked.Equals(false))
- {
- if(radioBtnYes.Checked.Equals(true))
- radioBtnYes.Checked=false;
- else
- {
- radioBtnYes.Checked=true;
- this.btnNext.Enabled=true;
- }
-
- }
- if(radioBtnNo.Checked.Equals(true))
- {
- radioBtnNo.Checked=false;
- radioBtnYes.Checked=true;
- buttonComputerAdd.Enabled=false;
- this.btnNext.Enabled=true;
- }
-
- }
-
- private void radioBtnNo_Click(object sender, System.EventArgs e)
- {
- if(radioBtnYes.Checked.Equals(false))
- {
- if(radioBtnNo.Checked.Equals(true))
- {
- radioBtnNo.Checked=false;
- buttonComputerAdd.Enabled=false;
- }
- else
- {
- radioBtnNo.Checked=true;
- buttonComputerAdd.Enabled=true;
- this.btnNext.Enabled=false;
- }
-
- }
- if(radioBtnYes.Checked.Equals(true))
- {
- radioBtnYes.Checked=false;
- radioBtnNo.Checked=true;
- buttonComputerAdd.Enabled=true;
- this.btnNext.Enabled=false;
- }
- }
-
- private void buttonComputerAdd_Click(object sender, System.EventArgs e)
- {
- if(getPosition(presentPanel)==0)
- {
- if(radioBtnNo.Checked.Equals(true))
- {
- ComputerAddDialog cad = new ComputerAddDialog(mgmt);
- cad.ShowDialog();
- }
- }
- }
-
- private void PanelWizard_Activated(object sender, System.EventArgs e)
- {
- updateComputers();
- }
-
- private void updateComputers()
- {
- ArrayList list = mgmt.getComputerCollection();
- this.listBoxComputers.BeginUpdate();
- this.listBoxComputers.Items.Clear();
- foreach(Computer c in list)
- {
- this.listBoxComputers.Items.Add(c.getName());
- }
- if(listBoxComputers.Items.Count > 0)
- {
- btnNext.Enabled=true;
- }
- this.listBoxComputers.EndUpdate();
- this.listBoxComputers.Refresh();
- }
-
-
- private void tvComputer_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
- {
- tvComputer.SelectedNode.Expand();
-
- }
-
- private void tvComputer_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
- {
-
- }
-
- private void tvComputer_MouseLeave(object sender, System.EventArgs e)
- {
-
- }
-
- private void tvComputer_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- TreeNode prevNode = tvComputer.SelectedNode;
- if(prevNode!=null)
- {
- prevNode.BackColor=Color.White;
- }
- TreeNode node = tvComputer.GetNodeAt(e.X,e.Y);
- if(node==null)
- {
- return;
- }
-
- tvComputer.SelectedNode=node;
- tvComputer.SelectedNode.BackColor=Color.LightGray;
-
- }
-
- private void btnTransferNodeToComp_Click(object sender, System.EventArgs e)
- {
-
- if(tvComputer.SelectedNode==null)
- return;
- if(lvNode.SelectedItems.Equals(null))
- return;
- int itemCount=lvNode.SelectedItems.Count;
- lvNode.BeginUpdate();
- tvComputer.BeginUpdate();
- for(int i=0;i < itemCount;i++)
- {
- tvComputer.SelectedNode.Nodes.Add(lvNode.SelectedItems[i].Text.ToString());
- }
-
- for(int i=0;i < itemCount;i++)
- {
- lvNode.Items.RemoveAt(lvNode.SelectedIndices[0]);
-
- }
- if(lvNode.Items.Count.Equals(0))
- btnNext.Enabled=true;
- else
- btnNext.Enabled=false;
- tvComputer.SelectedNode.Expand();
- lvNode.EndUpdate();
- tvComputer.EndUpdate();
- }
-
- private void lvNode_SelectedIndexChanged(object sender, System.EventArgs e)
- {
- }
-
- private void prepareNodeAssignmentPanel()
- {
- ArrayList computers = mgmt.getComputerCollection();
- m_nNDB=Convert.ToInt32(comboNDB.SelectedItem.ToString());
- m_nAPI=Convert.ToInt32(comboAPI.SelectedItem.ToString());
- m_nMGM=Convert.ToInt32(comboMGM.SelectedItem.ToString());
-
- lvNode.Items.Clear();
- tvComputer.Nodes.Clear();
- for (int i=1;i<=m_nMGM;i++)
- lvNode.Items.Add("mgm."+i);
-
- for (int i=m_nMGM+1;i<=(m_nNDB+m_nMGM);i++)
- lvNode.Items.Add("ndb."+i);
-
- for (int i=m_nMGM+m_nNDB+1;i<=(m_nNDB+m_nMGM+m_nAPI);i++)
- lvNode.Items.Add("api."+i);
-
- foreach(Computer c in computers)
- {
- if(c.getStatus() == Computer.Status.Connected)
- tvComputer.Nodes.Add(c.getName());
- }
-
- }
- private void prepareNodeConfigurationPanel()
- {
- Computer c;
- for(int i=0;i<tvComputer.Nodes.Count;i++)
- {
- c=mgmt.getComputer(tvComputer.Nodes[i].Text.ToString());
- for(int j=0; j < tvComputer.Nodes[i].Nodes.Count;j++)
- {
- m_db.addProcess(new Process(tvComputer.Nodes[i].Nodes[j].Text.ToString(),m_db.getOwner(),m_db.getName(),c));
- c.addProcess(m_db.getProcessByName(tvComputer.Nodes[i].Nodes[j].Text.ToString()));
- }
- }
- }
-
- private void updateListViews()
- {/*
- lvConfig.Items.Clear();
- ArrayList processes = m_db.getProcesses();
- string [] processcols= new string[5];
- foreach (Process process in processes)
- {
- processcols[0]=process.getName();
- processcols[1]=process.getComputer().getName();
- processcols[2]=process.getPath();
- processcols[3]="";
- processcols[4]="";
-
- ListViewItem lvc= new ListViewItem(processcols);
-
-
- lvConfig.Items.Add(lvc);
- }
- lvConfig.EndUpdate();
- */
- }
-
- private void btnConfigure_Click(object sender, System.EventArgs e)
- {
-
- }
-
- private void textDbName_TextChanged(object sender, System.EventArgs e)
- {
- if(textOwner.TextLength>0 && textDbName.TextLength > 0)
- nextEnabled=true;
- else
- nextEnabled=false;
-
- refreshLook();
-
- }
-
- private void checkBoxLater_CheckedChanged(object sender, System.EventArgs e)
- {
- if(checkBoxLater.Checked.Equals(true))
- {
- this.finishEnabled=true;
- this.nextEnabled=false;
- }
- else
- {
- this.finishEnabled=false;
- this.nextEnabled=true;
- }
- this.refreshLook();
- }
-
- private void btnFinish_Click(object sender, System.EventArgs e)
- {
- mgmt.AddDatabase(this.m_db);
-
- if(radioStartYes.Checked==true)
- startDatabase();
- this.Dispose();
- }
-
- private void panel4_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
-
- // Point location= new Point(8,40);
- // Size s= new Size(panel4.Size.Width-8,panel4.Size.Height-120);
- // lvConfig.Location=location;
- // lvConfig.Size=s;
-
-
- }
-
- private void configureMgmt()
- {
- //clear old
- textOther.Text="";
- textArgs.Text="";
- textCwd.Text="";
- textPath.Text="";
-
- textPath.Clear();
- textEnv.Clear();
- textOther.Clear();
- textCwd.Clear();
- textArgs.Clear();
-
- textPath.ClearUndo();
- textEnv.ClearUndo();
- textOther.ClearUndo();
- textCwd.ClearUndo();
- textArgs.ClearUndo();
-
-
- textOther.Enabled=true;
- textArgs.Enabled=true;
- textCwd.Enabled=true;
- textPath.Enabled=true;
-
- textPath.TabStop=true;
- textOther.TabStop=true;
- textArgs.TabStop=true;
- textCwd.TabStop=true;
- textEnv.TabStop=true;
-
- labelTitle.Text="Mgmtsrvr configuration";
- labelPath.Text="Path to mgmtsrvr binary:";
- labelArgs.Text="Arguments to mgmtsrvr:";
- labelOther.Text="Mgmtsrvr port (-p X):";
-
- //get new
- String process="mgm." + Convert.ToString(m_noOfConfiguredMgmt+1);
- Process mgmt=m_db.getProcessByName(process);
- textComputer.Text=mgmt.getComputer().getName();
- textName.Text=mgmt.getName().ToString();
- textDatabase.Text=mgmt.getDatabase().ToString();
- m_mgmHost=mgmt.getComputer().getName();
- textPath.Focus();
- }
- private void configureApi()
- {
- checkBoxReuse.Text="Use the same configuration for ALL API nodes?";
- if(m_nAPI > 1)
- {
- checkBoxReuse.Visible=true;
- checkBoxReuse.Enabled=true;
-
- }
- else
- {
- checkBoxReuse.Enabled=false;
- checkBoxReuse.Visible=true;
- }
-
- // clear previous and get a new api
-
- textOther.Text="";
- textArgs.Text="";
- //textCwd.Text="";
- //textPath.Text="";
- //get new api
- textOther.Enabled=false;
- textArgs.Enabled=true;
- labelTitle.Text="API node configuration";
- labelPath.Text="Path to api binary:";
- labelArgs.Text="Arguments to api:";
- labelOther.Text="NDB_CONNECTSTRING";
- String process="api." + Convert.ToString(m_noOfConfiguredApi+m_nMGM+m_nNDB+1);
- Process api=m_db.getProcessByName(process);
- textComputer.Text=api.getComputer().getName();
- textName.Text=api.getName().ToString();
- textOther.Text="nodeid=" + Convert.ToString(m_noOfConfiguredApi+m_nMGM+m_nNDB+1) + ";host="+this.m_mgmHost + ":" + this.m_mgmPort;
- textDatabase.Text=api.getDatabase().ToString();
- textPath.Focus();
- }
-
- private void configureNdb()
- {
-
-
- checkBoxReuse.Text="Use the same configuration for ALL NDB nodes?";
-
-
- if(this.m_nNDB > 1)
- {
- checkBoxReuse.Visible=true;
- checkBoxReuse.Enabled=true;
-
- }
- else
- {
- checkBoxReuse.Enabled=false;
- checkBoxReuse.Visible=true;
- }
-
-
-
- labelPath.Text="Path to ndb binary:";
- labelArgs.Text="Arguments to ndb:";
-
- // clear previous and get a new ndb
-
- labelOther.Text="NDB_CONNECTSTRING";
- textArgs.Text="-i";
- textOther.Enabled=false;
- textArgs.Enabled=false;
-
- textPath.TabStop=true;
- textEnv.TabStop=true;
- textOther.TabStop=false;
- textArgs.TabStop=false;
- textCwd.TabStop=true;
-
- //textCwd.Text="";
- //textPath.Text="";
- //get new
-
- String process="ndb." + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1);
- textOther.Text="nodeid=" + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1) + ";host="+this.m_mgmHost + ":" + this.m_mgmPort;
- Process ndb=m_db.getProcessByName(process);
- textComputer.Text=ndb.getComputer().getName();
- textName.Text=ndb.getName().ToString();
- textDatabase.Text=ndb.getDatabase().ToString();
- textPath.Focus();
- }
-
-
- public void saveMgm()
- {
- String process="mgm." + Convert.ToString(m_noOfConfiguredMgmt+1);
- Process mgmt=m_db.getProcessByName(process);
- mgmt.setOther(textOther.Text.ToString());
- mgmt.setEnv(textEnv.Text.ToString());
- m_mgmPort = textOther.Text.ToString();
- try
- {
- m_db.setMgmtPort(Convert.ToInt32(m_mgmPort));
- }
- catch(Exception e)
- {
- MessageBox.Show("Port number must be numeric!!!", "Error",MessageBoxButtons.OK);
- this.configureMgmt();
- return;
- }
- mgmt.setPath(textPath.Text.ToString());
- mgmt.setCwd(textCwd.Text.ToString());
- mgmt.setProcessType("permanent");
- mgmt.setArgs("-i initconfig.txt");
- mgmt.setConnectString("nodeid=" + Convert.ToString(m_noOfConfiguredMgmt+1)+";host="+m_mgmHost+":" + m_mgmPort);
- this.m_noOfConfiguredMgmt++;
- }
-
- public void saveApi()
- {
- if(checkBoxReuse.Checked)
- {
- for(;m_noOfConfiguredApi<m_nAPI;m_noOfConfiguredApi++)
- {
- String process="api." + Convert.ToString(m_noOfConfiguredApi+m_nMGM+m_nNDB+1);
- Process api=m_db.getProcessByName(process);
- textName.Text=process;
- api.setPath(textPath.Text.ToString());
- api.setArgs(textArgs.Text.ToString());
- api.setCwd(textCwd.Text.ToString());
- api.setEnv(textEnv.Text.ToString());
- api.setConnectString("nodeid=" + Convert.ToString(m_noOfConfiguredApi+m_nNDB+m_nMGM+1)+";host="+m_mgmHost+":" + m_mgmPort);
- api.setProcessType("permanent");
- }
-
- }
- else
- {
- String process="api." + Convert.ToString(m_noOfConfiguredApi+m_nMGM+m_nNDB+1);
- Process api=m_db.getProcessByName(process);
- api.setPath(textPath.Text.ToString());
- api.setCwd(textCwd.Text.ToString());
- api.setEnv(textEnv.Text.ToString());
- api.setConnectString("nodeid=" + Convert.ToString(m_noOfConfiguredApi+m_nNDB+m_nMGM+1)+";host="+m_mgmHost+":" + m_mgmPort);
- api.setArgs(textArgs.Text.ToString());
- api.setProcessType("permanent");
- this.m_noOfConfiguredApi++;
- }
- }
-
- public void saveNdb()
- {
-
- if(checkBoxReuse.Checked)
- {
- for(;m_noOfConfiguredNdb<m_nNDB;m_noOfConfiguredNdb++)
- {
- String process="ndb." + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1);
- Process ndb=m_db.getProcessByName(process);
- ndb.setConnectString("nodeid=" + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1)+";host="+m_mgmHost+":" + m_mgmPort);
- ndb.setPath(textPath.Text.ToString());
- ndb.setArgs(textArgs.Text.ToString());
- ndb.setEnv(textEnv.Text.ToString());
- ndb.setCwd(textCwd.Text.ToString());
- ndb.setProcessType("permanent");
- }
- checkBoxReuse.Checked=false;
- return;
- }
- else
- {
- String process="ndb." + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1);
- Process ndb=m_db.getProcessByName(process);
- ndb.setConnectString("nodeid=" + Convert.ToString(m_noOfConfiguredNdb+m_nMGM+1)+";host="+m_mgmHost+":" + m_mgmPort);
- ndb.setPath(textPath.Text.ToString());
- ndb.setCwd(textCwd.Text.ToString());
- ndb.setArgs(textArgs.Text.ToString());
- ndb.setEnv(textEnv.Text.ToString());
- ndb.setProcessType("permanent");
- m_noOfConfiguredNdb++;
- }
-
- }
-
-
- private void panel5_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
- nextEnabled=false;
- buttonSave.Enabled=true;
- checkBoxReuse.Visible=false;
- refreshLook();
- configureMgmt();
- }
-
- private void buttonSave_Click(object sender, System.EventArgs e)
- {
- Process p = m_db.getProcessByName(textName.Text.ToString());
-
- if(textOther.Text.ToString().Equals(""))
- {
- if(textName.Text.StartsWith("mgm"))
- {
- MessageBox.Show("You have to specify a port.","Warning",MessageBoxButtons.OK);
- return;
- }
- if(textName.Text.StartsWith("ndb"))
- {
- MessageBox.Show("You have to specify a filesystem path.","Warning",MessageBoxButtons.OK);
- return;
- }
-
- }
-
- if(textPath.Text.ToString().Equals(""))
- {
- if(textName.Text.StartsWith("mgm"))
- {
- MessageBox.Show("You have to specify the path to the mgmtsrvr.","Warning",MessageBoxButtons.OK);
- return;
- }
- if(textName.Text.StartsWith("ndb"))
- {
- MessageBox.Show("You have to specify the path to ndb.","Warning",MessageBoxButtons.OK);
- return;
- }
- }
-
- if(textArgs.Text.ToString().Equals(""))
- {
- if(textName.Text.StartsWith("mgm"))
- {
- MessageBox.Show("You have to specify the arguments to the mgmtsrvr.","Warning",MessageBoxButtons.OK);
- return;
- }
- }
-
- if(textCwd.Text.ToString().Equals(""))
- {
- if(textCwd.Text.StartsWith("mgm"))
- {
- MessageBox.Show("You have to specify the current working directory for the mgmtsrvr.","Warning",MessageBoxButtons.OK);
- return;
- }
- }
-
-
- /*
- * INPUT IS FINE AT THIS POINT
- * Everything needed for respective process is ok
- * */
-
- if(textName.Text.StartsWith("mgm"))
- {
- //MessageBox.Show(textOther.Text.ToString());
- saveMgm();
-
- }
-
- if(textName.Text.StartsWith("ndb"))
- {
- saveNdb();
-
- }
-
- if(textName.Text.StartsWith("api"))
- {
- saveApi();
-
- }
-
- if(m_noOfConfiguredMgmt < m_nMGM)
- {
- //load another Mgmt
- labelTitle.Text="Mgmtsrvr configuration";
- configureMgmt();
- }
- else
- {
- m_bMgmt=true;
- }
-
- if(m_bMgmt)
- {
- labelTitle.Text="NDB node configuration";
- if(m_noOfConfiguredNdb < m_nNDB)
- {
- configureNdb();
- }
- else
- m_bNdb=true;
- }
-
- if(m_bNdb && m_bMgmt)
- {
- labelTitle.Text="API node configuration";
- if(m_noOfConfiguredApi < m_nAPI)
- configureApi();
- else
- {
- nextEnabled=true;
- buttonSave.Enabled=false;
- refreshLook();
- }
- }
-
- }
-
- private void listBoxComputers_SelectedIndexChanged(object sender, System.EventArgs e)
- {
-
- }
-
- private void panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
- updateComputers();
- }
-
- private void radioYes_CheckedChanged(object sender, System.EventArgs e)
- {
- if(radioYes.Checked==true)
- {
- radioNo.Checked=false;
- }
- if(radioYes.Checked==false)
- {
- radioNo.Checked=true;
- }
-
- }
-
- private void radioNo_CheckedChanged(object sender, System.EventArgs e)
- {
- if(radioNo.Checked==true)
- {
- radioYes.Checked=false;
- }
- if(radioNo.Checked==false)
- {
- radioYes.Checked=true;
- }
- }
-
- private void radioStartYes_CheckedChanged(object sender, System.EventArgs e)
- {
-
- if(radioStartYes.Checked==true)
- {
- radioStartNo.Checked=false;
- }
- if(radioStartYes.Checked==false)
- {
- radioStartNo.Checked=true;
- }
- finishEnabled=true;
- refreshLook();
- }
-
- private void radioStartNo_CheckedChanged(object sender, System.EventArgs e)
- {
- if(radioStartNo.Checked==true)
- {
- radioStartYes.Checked=false;
- }
- if(radioStartNo.Checked==false)
- {
- radioStartYes.Checked=true;
- }
- finishEnabled=true;
- refreshLook();
- }
-
-
-
-
- public void startDatabase()
- {
- startDatabaseDlg x = new startDatabaseDlg(this.m_db);
-
-
- x.ShowDialog();
-
-
- }
-
-
- public void generateInitConfig()
- {
- MessageBox.Show("Generate initconfig.txt");
- }
-
- private void label11_Click(object sender, System.EventArgs e)
- {
-
- }
-
- private void textOwner_TextChanged(object sender, System.EventArgs e)
- {
- if(textDbName.TextLength > 0 && textOwner.TextLength > 0)
- nextEnabled=true;
- else
- nextEnabled=false;
-
- refreshLook();
- }
-
- private void panel2_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
- textOwner.Text=System.Environment.UserName;
- this.Validate();
- if(textDbName.TextLength > 0 && textOwner.TextLength>0)
- {
- nextEnabled=true;
- }
- else
- {
- nextEnabled=false;
- }
- refreshLook();
- }
-
- private void textPath_TextChanged(object sender, System.EventArgs e)
- {
- try
- {
-
- }
- catch (Exception exc)
- {
- MessageBox.Show(exc.ToString());
- }
- }
-
- private void panel2_Validating(object sender, System.ComponentModel.CancelEventArgs e)
- {
- if(textOwner.TextLength>0 && textDbName.TextLength > 0)
- nextEnabled=true;
- else
- nextEnabled=false;
- }
-
-
-
-
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/Process.cs b/storage/ndb/src/cw/cpcc-win32/csharp/Process.cs
deleted file mode 100644
index d861781c737..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/Process.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for Process.
- /// </summary>
- public class Process
- {
- public enum Status {Running, Stopped, Unknown}
- private string m_id;
- protected string m_name;
- private Status m_status;
- private Computer m_computer;
- private string m_owner;
- private string m_cwd;
- private string m_type;
- private string m_path;
- private string m_other;
- private string m_args;
- private string m_env;
- private string m_database;
- private string m_connectString;
- private bool m_defined;
- public Process( string name,
- string owner, string database,
- Computer computer)
- {
- m_name=name;
- m_owner=owner;
- m_computer=computer;
- m_status=Status.Unknown;
- m_database=database;
- m_defined=false;
- m_path="";
- m_cwd="";
- m_args="";
- m_other="";
- }
- public Process()
- {
-
- }
- public Process(string id)
- {
- m_id=id;
- }
-
- public Process( string name,
- string database,
- Computer computer)
- {
- m_name=name;
- m_computer=computer;
- m_status=Status.Unknown;
- m_database=database;
- m_defined=false;
- }
-
- public Process( string name,
- Computer computer)
- {
- m_name=name;
- m_computer=computer;
- m_status=Status.Unknown;
- m_defined=false;
- }
-
-
- public string getStatusString()
- {
- if(m_status.Equals(Status.Running))
- return "Running";
- if(m_status.Equals(Status.Stopped))
- return "Stopped";
- return "Unknown";
- }
-
- public Computer getComputer() {return m_computer;}
- public string getName() {return m_name;}
- public string getDatabase() {return m_database;}
- public string getOwner() {return m_owner;}
- public string getId() {return m_id;}
- public void setId(string id) {m_id=id;}
-
- public void setCwd(string cwd) {m_cwd=cwd;}
- public void setPath(string path) {m_path=path;}
- public void setArgs(string args) {m_args=args;}
- public void setOther(string other) {m_other=other;}
- public void setEnv(string env) {m_env=env;}
- public void setName(string name) {m_name=name;}
- public void setOwner(string owner) {m_owner=owner;}
- public void setDatabase(string db) {m_database=db;}
- public void setComputer(Computer c) {m_computer=c;}
-
-
- public string getCwd() {return m_cwd;}
- public string getPath() {return m_path;}
- public string getArgs() {return m_args;}
- public string getOther() {return m_other;}
- public string getEnv() {return m_env;}
-
- public bool isDefined() {return m_defined;}
- public void setDefined(bool defined)
- {
- m_defined=defined;
- }
-
- public Status getStatus()
- {
- return m_status;
- }
-
- public void setConnectString(string cs)
- {
- m_connectString=cs;
- }
-
- public string getConnectString()
- {
- return m_connectString;
- }
- public void setStatus(Status status)
- {
- m_status=status;
- }
-
-
- public void setProcessType(string type)
- {
- m_type=type;
- }
- public string getProcessType()
- {
- return m_type;
- }
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs b/storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs
deleted file mode 100644
index 814b820c53d..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs
+++ /dev/null
@@ -1,451 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for ProcessDefineDialog.
- /// </summary>
- public class ProcessDefineDialog : System.Windows.Forms.Form
- {
- private System.Windows.Forms.ComboBox comboComputer;
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Label label3;
- private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Label label5;
- private System.Windows.Forms.Label label6;
- private System.Windows.Forms.Label label7;
- private System.Windows.Forms.Label label8;
- private System.Windows.Forms.Label label9;
- private System.Windows.Forms.TextBox textProcessName;
- private System.Windows.Forms.TextBox textProcessGroup;
- private System.Windows.Forms.TextBox textProcessEnv;
- private System.Windows.Forms.TextBox textProcessPath;
- private System.Windows.Forms.TextBox textProcessArgs;
- private System.Windows.Forms.TextBox textProcessCWD;
- private System.Windows.Forms.TextBox textProcessOwner;
- private System.Windows.Forms.ComboBox comboType;
- private System.Windows.Forms.Label label10;
- private System.Windows.Forms.Label label11;
- private System.Windows.Forms.Label label12;
- private System.Windows.Forms.Label label13;
- private System.Windows.Forms.Label label15;
- private System.Windows.Forms.Label label16;
- private System.Windows.Forms.Label label14;
- private System.Windows.Forms.Label label17;
- private System.Windows.Forms.Label label18;
- private System.Windows.Forms.Button btnAdd;
- private System.Windows.Forms.Button btnCancel;
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- private ComputerMgmt c_mgmt;
- private string m_selComputer;
- public ProcessDefineDialog(ComputerMgmt mgmt, string computer)
- {
-
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- m_selComputer =computer; //the selected computer in the TreeView
- c_mgmt=mgmt;
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if(components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.comboComputer = new System.Windows.Forms.ComboBox();
- this.label1 = new System.Windows.Forms.Label();
- this.label2 = new System.Windows.Forms.Label();
- this.label3 = new System.Windows.Forms.Label();
- this.label4 = new System.Windows.Forms.Label();
- this.label5 = new System.Windows.Forms.Label();
- this.label6 = new System.Windows.Forms.Label();
- this.label7 = new System.Windows.Forms.Label();
- this.label8 = new System.Windows.Forms.Label();
- this.label9 = new System.Windows.Forms.Label();
- this.textProcessName = new System.Windows.Forms.TextBox();
- this.textProcessGroup = new System.Windows.Forms.TextBox();
- this.textProcessEnv = new System.Windows.Forms.TextBox();
- this.textProcessPath = new System.Windows.Forms.TextBox();
- this.textProcessArgs = new System.Windows.Forms.TextBox();
- this.textProcessCWD = new System.Windows.Forms.TextBox();
- this.textProcessOwner = new System.Windows.Forms.TextBox();
- this.comboType = new System.Windows.Forms.ComboBox();
- this.label10 = new System.Windows.Forms.Label();
- this.label11 = new System.Windows.Forms.Label();
- this.label12 = new System.Windows.Forms.Label();
- this.label13 = new System.Windows.Forms.Label();
- this.label15 = new System.Windows.Forms.Label();
- this.label16 = new System.Windows.Forms.Label();
- this.label14 = new System.Windows.Forms.Label();
- this.label17 = new System.Windows.Forms.Label();
- this.label18 = new System.Windows.Forms.Label();
- this.btnAdd = new System.Windows.Forms.Button();
- this.btnCancel = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // comboComputer
- //
- this.comboComputer.ItemHeight = 13;
- this.comboComputer.Location = new System.Drawing.Point(152, 24);
- this.comboComputer.Name = "comboComputer";
- this.comboComputer.Size = new System.Drawing.Size(112, 21);
- this.comboComputer.TabIndex = 0;
- //
- // label1
- //
- this.label1.Location = new System.Drawing.Point(24, 24);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(64, 24);
- this.label1.TabIndex = 1;
- this.label1.Text = "Computer:";
- //
- // label2
- //
- this.label2.Location = new System.Drawing.Point(24, 48);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(88, 24);
- this.label2.TabIndex = 2;
- this.label2.Text = "Process name:";
- //
- // label3
- //
- this.label3.Location = new System.Drawing.Point(24, 72);
- this.label3.Name = "label3";
- this.label3.Size = new System.Drawing.Size(88, 24);
- this.label3.TabIndex = 3;
- this.label3.Text = "Group:";
- //
- // label4
- //
- this.label4.Location = new System.Drawing.Point(24, 96);
- this.label4.Name = "label4";
- this.label4.Size = new System.Drawing.Size(88, 24);
- this.label4.TabIndex = 4;
- this.label4.Text = "Env. variables:";
- //
- // label5
- //
- this.label5.Location = new System.Drawing.Point(24, 120);
- this.label5.Name = "label5";
- this.label5.Size = new System.Drawing.Size(88, 24);
- this.label5.TabIndex = 5;
- this.label5.Text = "Path to binary:";
- //
- // label6
- //
- this.label6.Location = new System.Drawing.Point(24, 144);
- this.label6.Name = "label6";
- this.label6.Size = new System.Drawing.Size(112, 24);
- this.label6.TabIndex = 6;
- this.label6.Text = "Arguments to binary:";
- //
- // label7
- //
- this.label7.Location = new System.Drawing.Point(24, 168);
- this.label7.Name = "label7";
- this.label7.Size = new System.Drawing.Size(112, 24);
- this.label7.TabIndex = 7;
- this.label7.Text = "Type of process:";
- //
- // label8
- //
- this.label8.Location = new System.Drawing.Point(24, 192);
- this.label8.Name = "label8";
- this.label8.Size = new System.Drawing.Size(112, 24);
- this.label8.TabIndex = 8;
- this.label8.Text = "Current working dir.:";
- //
- // label9
- //
- this.label9.Location = new System.Drawing.Point(24, 216);
- this.label9.Name = "label9";
- this.label9.Size = new System.Drawing.Size(112, 24);
- this.label9.TabIndex = 9;
- this.label9.Text = "Owner:";
- //
- // textProcessName
- //
- this.textProcessName.Location = new System.Drawing.Point(152, 48);
- this.textProcessName.Name = "textProcessName";
- this.textProcessName.Size = new System.Drawing.Size(112, 20);
- this.textProcessName.TabIndex = 1;
- this.textProcessName.Text = "";
- //
- // textProcessGroup
- //
- this.textProcessGroup.Location = new System.Drawing.Point(152, 72);
- this.textProcessGroup.Name = "textProcessGroup";
- this.textProcessGroup.Size = new System.Drawing.Size(112, 20);
- this.textProcessGroup.TabIndex = 2;
- this.textProcessGroup.Text = "";
- //
- // textProcessEnv
- //
- this.textProcessEnv.Location = new System.Drawing.Point(152, 96);
- this.textProcessEnv.Name = "textProcessEnv";
- this.textProcessEnv.Size = new System.Drawing.Size(112, 20);
- this.textProcessEnv.TabIndex = 3;
- this.textProcessEnv.Text = "";
- //
- // textProcessPath
- //
- this.textProcessPath.Location = new System.Drawing.Point(152, 120);
- this.textProcessPath.Name = "textProcessPath";
- this.textProcessPath.Size = new System.Drawing.Size(112, 20);
- this.textProcessPath.TabIndex = 4;
- this.textProcessPath.Text = "";
- //
- // textProcessArgs
- //
- this.textProcessArgs.Location = new System.Drawing.Point(152, 144);
- this.textProcessArgs.Name = "textProcessArgs";
- this.textProcessArgs.Size = new System.Drawing.Size(112, 20);
- this.textProcessArgs.TabIndex = 5;
- this.textProcessArgs.Text = "";
- //
- // textProcessCWD
- //
- this.textProcessCWD.Location = new System.Drawing.Point(152, 192);
- this.textProcessCWD.Name = "textProcessCWD";
- this.textProcessCWD.Size = new System.Drawing.Size(112, 20);
- this.textProcessCWD.TabIndex = 7;
- this.textProcessCWD.Text = "";
- //
- // textProcessOwner
- //
- this.textProcessOwner.Location = new System.Drawing.Point(152, 216);
- this.textProcessOwner.Name = "textProcessOwner";
- this.textProcessOwner.Size = new System.Drawing.Size(112, 20);
- this.textProcessOwner.TabIndex = 8;
- this.textProcessOwner.Text = "";
- //
- // comboType
- //
- this.comboType.ItemHeight = 13;
- this.comboType.Items.AddRange(new object[] {
- "Permanent",
- "Interactive"});
- this.comboType.Location = new System.Drawing.Point(152, 168);
- this.comboType.Name = "comboType";
- this.comboType.Size = new System.Drawing.Size(112, 21);
- this.comboType.TabIndex = 6;
- //
- // label10
- //
- this.label10.Location = new System.Drawing.Point(272, 32);
- this.label10.Name = "label10";
- this.label10.Size = new System.Drawing.Size(88, 16);
- this.label10.TabIndex = 19;
- this.label10.Text = "(Mandatory)";
- //
- // label11
- //
- this.label11.Location = new System.Drawing.Point(272, 56);
- this.label11.Name = "label11";
- this.label11.Size = new System.Drawing.Size(88, 16);
- this.label11.TabIndex = 20;
- this.label11.Text = "(Mandatory)";
- //
- // label12
- //
- this.label12.Location = new System.Drawing.Point(272, 80);
- this.label12.Name = "label12";
- this.label12.Size = new System.Drawing.Size(88, 16);
- this.label12.TabIndex = 21;
- this.label12.Text = "(Mandatory)";
- //
- // label13
- //
- this.label13.Location = new System.Drawing.Point(272, 127);
- this.label13.Name = "label13";
- this.label13.Size = new System.Drawing.Size(88, 16);
- this.label13.TabIndex = 22;
- this.label13.Text = "(Mandatory)";
- //
- // label15
- //
- this.label15.Location = new System.Drawing.Point(272, 176);
- this.label15.Name = "label15";
- this.label15.Size = new System.Drawing.Size(88, 16);
- this.label15.TabIndex = 24;
- this.label15.Text = "(Mandatory)";
- //
- // label16
- //
- this.label16.Location = new System.Drawing.Point(272, 200);
- this.label16.Name = "label16";
- this.label16.Size = new System.Drawing.Size(88, 16);
- this.label16.TabIndex = 25;
- this.label16.Text = "(Mandatory)";
- //
- // label14
- //
- this.label14.Location = new System.Drawing.Point(272, 224);
- this.label14.Name = "label14";
- this.label14.Size = new System.Drawing.Size(88, 16);
- this.label14.TabIndex = 26;
- this.label14.Text = "(Mandatory)";
- //
- // label17
- //
- this.label17.Location = new System.Drawing.Point(272, 104);
- this.label17.Name = "label17";
- this.label17.Size = new System.Drawing.Size(88, 16);
- this.label17.TabIndex = 27;
- this.label17.Text = "(Optional)";
- //
- // label18
- //
- this.label18.Location = new System.Drawing.Point(272, 152);
- this.label18.Name = "label18";
- this.label18.Size = new System.Drawing.Size(88, 16);
- this.label18.TabIndex = 28;
- this.label18.Text = "(Optional)";
- //
- // btnAdd
- //
- this.btnAdd.Location = new System.Drawing.Point(288, 248);
- this.btnAdd.Name = "btnAdd";
- this.btnAdd.TabIndex = 9;
- this.btnAdd.Text = "Define...";
- this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
- //
- // btnCancel
- //
- this.btnCancel.Location = new System.Drawing.Point(152, 248);
- this.btnCancel.Name = "btnCancel";
- this.btnCancel.TabIndex = 10;
- this.btnCancel.Text = "Cancel";
- this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
- //
- // ProcessDefineDialog
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(370, 279);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.btnCancel,
- this.btnAdd,
- this.label18,
- this.label17,
- this.label14,
- this.label16,
- this.label15,
- this.label13,
- this.label12,
- this.label11,
- this.label10,
- this.comboType,
- this.textProcessOwner,
- this.textProcessCWD,
- this.textProcessArgs,
- this.textProcessPath,
- this.textProcessEnv,
- this.textProcessGroup,
- this.textProcessName,
- this.label9,
- this.label8,
- this.label7,
- this.label6,
- this.label5,
- this.label4,
- this.label3,
- this.label2,
- this.label1,
- this.comboComputer});
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "ProcessDefineDialog";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- this.Text = "Define Process";
- this.Load += new System.EventHandler(this.ProcessDefineDialog_Load);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- private void btnCancel_Click(object sender, System.EventArgs e)
- {
- this.Dispose();
- this.Close();
- }
-
- private void btnAdd_Click(object sender, System.EventArgs e)
- {
- //TODO: ERROR CHECK
-
- Computer c;
- c=c_mgmt.getComputer(this.m_selComputer);
-
- c.addProcess(new Process(this.textProcessName.Text.ToString(),
- this.textProcessOwner.Text.ToString(),
- this.textProcessGroup.Text.ToString(),
- c));
- this.Close();
- this.Dispose();
- }
-
- private void ProcessDefineDialog_Load(object sender, System.EventArgs e)
- {
- comboType.SelectedIndex=0;
- ArrayList list = c_mgmt.getComputerCollection();
- int i=0, selIndex=0;
- foreach(Computer computer in list)
- {
- this.comboComputer.Items.Add(computer.getName());
- if(computer.getName().Equals(m_selComputer))
- selIndex=i;
- i++;
- }
- comboComputer.SelectedIndex=selIndex;
- }
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs b/storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs
deleted file mode 100644
index 246c108c661..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Text;
-using System.Collections.Specialized;
-using System.IO;
-using System.Windows.Forms;
-namespace NDB_CPC.fileaccess
-{
- /// <summary>
- /// Summary description for FileMgmt.
- /// </summary>
- public class FileMgmt
- {
- public FileMgmt()
- {
- }
-
- public StringCollection importHostFile(string filename)
- {
- StringCollection sc = new StringCollection();
- StreamReader SR = new StreamReader(filename);
- string line ="";
- line = SR.ReadLine();
- while(!line.Equals(""))
- {
- sc.Add(line);
- line = SR.ReadLine();
- }
- return sc;
- }
-
- public void exportHostFile(string filename, string content)
- {
- StreamWriter SW = new StreamWriter(filename,false);
- SW.Write(content);
- SW.WriteLine("");
- SW.WriteLine("");
- SW.Close();
- }
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs b/storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs
deleted file mode 100644
index 1b55d2c2ab8..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Collections;
-using System.IO;
-using System.Windows.Forms;
-using NDB_CPC;
-using NDB_CPC.socketcomm;
-
-namespace NDB_CPC.simpleparser
-{
- /// <summary>
- /// Summary description for SimpleCPCParser.
- /// </summary>
- public class SimpleCPCParser
- {
- public SimpleCPCParser()
- {
- //
- // TODO: Add constructor logic here
- //
- }
-
- public static void parse(Process p, SocketComm comm)
- {
-
- string line=comm.readLine();//reader.ReadLine();
- while(line.Equals(""))
- {
- line=comm.readLine();
- }
- if(line.Equals("define process"))
- {
- defineProcess(p, comm);
- line="";
- return;
- }
- if(line.Equals("start process"))
- {
- startProcess(p,comm);
- line="";
- return;
- }
- if(line.Equals("stop process"))
- {
- stopProcess(p,comm);
- line="";
- return;
- }
- if(line.Equals("undefine process"))
- {
- undefineProcess(p,comm);
- line="";
- return;
- }
-
- }
-
- public static void parse(ArrayList processes, Computer c, SocketComm comm)
- {
-
- string line=comm.readLine();//reader.ReadLine();
- while(line.Equals(""))
- {
- line=comm.readLine();
- }
-
- if(line.Equals("start processes"))
- {
- listProcesses(processes, c, comm);
- line="";
- return;
- }
-
- }
-
- private static void defineProcess(Process p, SocketComm comm)
- {
- string line=comm.readLine();//reader.ReadLine();
- while(!line.Equals(""))
- {
- if(line.StartsWith("status:"))
- {
- line=line.Remove(0,7);
- line=line.Trim();
- if(line.Equals("1"))
- {
- p.setDefined(true);
- p.setStatus(Process.Status.Stopped);
- }
- else
- p.setDefined(false);
- }
- if(line.StartsWith("id:"))
- {
- line=line.Remove(0,3);
- line=line.Trim();
- p.setId(line);
- }
- line=comm.readLine();
- }
- }
-
-
- private static void startProcess(Process p, SocketComm comm)
- {
- string line=comm.readLine();//reader.ReadLine();
- while(!line.Equals(""))
- {
- if(line.StartsWith("status:"))
- {
- line=line.Remove(0,7);
- line=line.Trim();
- if(line.Equals("1"))
- p.setStatus(NDB_CPC.Process.Status.Running);
- else
- p.setStatus(NDB_CPC.Process.Status.Unknown);
-
- }
- if(line.StartsWith("id:"))
- {
- line=line.Remove(0,3);
- line=line.Trim();
- if(p.getId().Equals(line))
- {
- ;
- }
- else
- {
- //damn something is wrong
- p.setStatus(NDB_CPC.Process.Status.Unknown);
- }
-
- }
- line=comm.readLine();
- }
- }
- private static void undefineProcess(Process p, SocketComm comm)
- {
- string line=comm.readLine();//reader.ReadLine();
- while(!line.Equals(""))
- {
- if(line.StartsWith("status:"))
- {
-
- line=line.Remove(0,7);
- line=line.Trim();
- if(line.Equals("1"))
- p.setDefined(false);
- else
- p.setDefined(true);
-
- }
- if(line.StartsWith("id:"))
- {
- line=line.Remove(0,3);
- line=line.Trim();
- }
- line=comm.readLine();
- }
- }
-
- private static void stopProcess(Process p, SocketComm comm)
- {
- string line=comm.readLine();//reader.ReadLine();
- while(!line.Equals(""))
- {
- if(line.StartsWith("status:"))
- {
- line=line.Remove(0,7);
- line=line.Trim();
- if(line.Equals("1"))
- p.setStatus(NDB_CPC.Process.Status.Stopped);
- else
- p.setStatus(NDB_CPC.Process.Status.Unknown);
-
- }
- if(line.StartsWith("id:"))
- {
- line=line.Remove(0,3);
- line=line.Trim();
- if(p.getId().Equals(line))
- {
- ;
- }
- else
- {
- //damn something is wrong
- p.setStatus(NDB_CPC.Process.Status.Unknown);
- }
-
- }
- line=comm.readLine();
- }
- }
- private static void listProcesses(ArrayList processes, Computer c, SocketComm comm)
- {
- bool processExist = false;
-
- string line=comm.readLine();//reader.ReadLine();
- while(!line.Equals("end processes"))
- {
- if(line.Equals("process"))
- {
- line=comm.readLine();
- Process p = new Process();
-
- while(!line.Equals(""))
- {
- if(line.StartsWith("id:"))
- {
- string pid;
- line=line.Remove(0,3);
- pid=line.Trim();
- /*check if process already exist*/
- processExist=findProcess(processes,pid);
- if(!processExist)
- {
- p.setId(pid);
- }
- }
-
- if(line.StartsWith("name:"))
- {
-
- line=line.Remove(0,5);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setName(line);
- }
- }
-
- if(line.StartsWith("path:"))
- {
-
- line=line.Remove(0,5);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setPath(line);
- }
- }
-
- if(line.StartsWith("args:"))
- {
-
- line=line.Remove(0,5);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setArgs(line);
- }
- }
-
- if(line.StartsWith("type:"))
- {
-
- line=line.Remove(0,5);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
-
- }
- }
-
- if(line.StartsWith("cwd:"))
- {
-
- line=line.Remove(0,4);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setCwd(line);
- }
- }
-
- if(line.StartsWith("env:"))
- {
-
- line=line.Remove(0,4);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setEnv(line);
- }
- }
-
- if(line.StartsWith("owner:"))
- {
-
- line=line.Remove(0,6);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setOwner(line);
- }
- }
- if(line.StartsWith("group:"))
- {
-
- line=line.Remove(0,6);
- line=line.Trim();
- /*check if process already exist*/
- if(!processExist)
- {
- p.setDatabase(line);
- }
- }
-
- if(line.StartsWith("status:"))
- {
-
- line=line.Remove(0,7);
- line=line.Trim();
- /*check if process already exist*/
- //if(!processExist)
- //{
- if(line.Equals("0"))
- p.setStatus(Process.Status.Stopped);
- if(line.Equals("1"))
- p.setStatus(Process.Status.Running);
- if(line.Equals("2"))
- p.setStatus(Process.Status.Unknown);
- //}
- }
-
-
- line=comm.readLine();
- }
- if(!processExist)
- {
- p.setComputer(c);
- p.setDefined(true);
- processes.Add(p);
- }
- processExist=false;
- }
- line=comm.readLine();
-
- }
- }
-
- private static bool findProcess(ArrayList processes, string pid)
- {
- foreach (Process p in processes)
- {
- if(p.getId().Equals(pid))
- return true;
- }
- return false;
-
- }
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs b/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs
deleted file mode 100644
index 34678086057..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Windows.Forms;
-using System.Threading;
-using System.IO;
-
-namespace NDB_CPC.socketcomm
-{
- /// <summary>
- /// Summary description for SocketComm.
- /// </summary>
- public class SocketComm
- {
- private myTcpClient sender;
- private StreamWriter writer;
- private StreamReader reader;
- private string m_host;
- private int m_port;
- private bool m_connected;
- private bool m_connecting;
- private Thread connectThread;
- public SocketComm(string host, int port)
- {
-
- m_host=host;
- m_port=port;
- m_connected=false;
- m_connecting=false;
- }
-
-
-
- public bool isConnected()
- {
- return m_connected;
- }
-
- public void doConnect()
- {
- if(!m_connecting && !m_connected)
- {
- connectThread= new Thread(new ThreadStart(connect));
- connectThread.Start();
- }
-
- }
-
- private void connect()
- {
- m_connecting=true;
- while(true)
- {
- if(!m_connected)
- {
- try
- {
- // Establish the remote endpoint for the socket.
- // The name of the
- // remote device is "host.contoso.com".
-
- // Create a TCP/IP socket.
- sender = new myTcpClient();
- // Connect the socket to the remote endpoint. Catch any errors.
- try
- {
- /*
- IPAddress ipAddress = Dns.Resolve(host).AddressList[0];
- IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);
-*/
-
-
- sender.Connect(m_host,m_port);;
-
- writer = new StreamWriter(sender.GetStream(), Encoding.ASCII);
- reader = new StreamReader(sender.GetStream(), Encoding.ASCII);
- m_connected=true;
- m_connecting=false;
- // break;
- Console.WriteLine("Socket connected to {0}",
- sender.ToString());
-
- }
- catch (ArgumentNullException ane)
- {
- Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
- m_connected=false;
- }
- catch (SocketException se)
- {
- Console.WriteLine("SocketException : {0}",se.ToString());
- m_connected=false;
- }
- }
- catch (Exception e)
- {
- Console.WriteLine("Unexpected exception : {0}", e.ToString());
- m_connected=false;
- }
-
- }
-
- Thread.Sleep(200);
- }
- }
-
- public bool disconnect()
- {
- try
- {
- this.m_connected=false;
- this.m_connecting=false;
- sender.GetUnderlyingSocket().Shutdown(SocketShutdown.Both);
- sender.GetUnderlyingSocket().Close();
- writer.Close();
- reader.Close();
- sender.Close();
-
- }
- catch (ArgumentNullException ane)
- {
- Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
- connectThread.Abort();
- return false;
- }
- catch (SocketException se)
- {
- Console.WriteLine("SocketException : {0}",se.ToString());
- connectThread.Abort();
- return false;
- }
- catch (Exception e)
- {
- Console.WriteLine("Unexpected exception : {0}", e.ToString());
- connectThread.Abort();
- return false;
- }
- connectThread.Abort();
- return true;
- }
-
- public bool writeMessage(string message)
- {
- int attempts=0;
- while (attempts < 10)
- {
- try
- {
- writer.WriteLine(message);
- writer.Flush();
- message="";
- return true;
- }
- catch(IOException e)
- {
- this.disconnect();
- this.doConnect();
- Thread.Sleep(200);
- attempts++;
- }
- catch(System.NullReferenceException)
- {
- this.disconnect();
- this.doConnect();
-
- Thread.Sleep(200);
- attempts++;
- }
- }
- return false;
- }
-
- public string readLine()
- {
- int attempts=0;
- string line="";
- while (attempts < 10){
- try
- {
- line = reader.ReadLine();
- if(line==null)
- line="";
- return line;
- }
- catch(IOException e)
- {
- this.disconnect();
- this.doConnect();
- Thread.Sleep(400);
- attempts++;
- }
- catch(System.NullReferenceException)
- {
- this.disconnect();
- this.doConnect();
- Thread.Sleep(400);
- attempts++;
- }
- }
- return "";
-
- }
-
- }
-}
-
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs b/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs
deleted file mode 100644
index 20d86477b3a..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.IO;
-
-
-namespace NDB_CPC.socketcomm
-{
- public class myTcpClient : TcpClient
- {
- private Socket s;
- public myTcpClient(): base()
- {
- if(this.Active)
- {
- s = this.Client;
- }
- }
- public Socket GetUnderlyingSocket()
- {
- return s;
- }
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs b/storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs
deleted file mode 100644
index 9a702b9fc9e..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs
+++ /dev/null
@@ -1,267 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using NDB_CPC.simpleparser;
-
-namespace NDB_CPC
-{
- /// <summary>
- /// Summary description for startDatabase.
- /// </summary>
- public class startDatabaseDlg : System.Windows.Forms.Form
- {
- private System.Windows.Forms.TextBox textAction;
- private System.Windows.Forms.Label label1;
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- private System.Windows.Forms.ProgressBar progressBar;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.Button buttonGo;
- private Database m_db;
- public startDatabaseDlg(Database db)
- {
-
- //
- // Required for Windows Form Designer support
- //
- InitializeComponent();
-
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- m_db=db;
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose( bool disposing )
- {
- if( disposing )
- {
- if(components != null)
- {
- components.Dispose();
- }
- }
- base.Dispose( disposing );
- }
-
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.textAction = new System.Windows.Forms.TextBox();
- this.label1 = new System.Windows.Forms.Label();
- this.progressBar = new System.Windows.Forms.ProgressBar();
- this.label2 = new System.Windows.Forms.Label();
- this.buttonGo = new System.Windows.Forms.Button();
- this.SuspendLayout();
- //
- // textAction
- //
- this.textAction.Location = new System.Drawing.Point(104, 40);
- this.textAction.Name = "textAction";
- this.textAction.ReadOnly = true;
- this.textAction.Size = new System.Drawing.Size(256, 20);
- this.textAction.TabIndex = 0;
- this.textAction.Text = "";
- //
- // label1
- //
- this.label1.Location = new System.Drawing.Point(8, 40);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(96, 16);
- this.label1.TabIndex = 1;
- this.label1.Text = "Current activity:";
- this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- //
- // progressBar
- //
- this.progressBar.Location = new System.Drawing.Point(104, 88);
- this.progressBar.Name = "progressBar";
- this.progressBar.Size = new System.Drawing.Size(152, 16);
- this.progressBar.TabIndex = 2;
- //
- // label2
- //
- this.label2.Location = new System.Drawing.Point(8, 88);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(96, 16);
- this.label2.TabIndex = 3;
- this.label2.Text = "Activity progress:";
- this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- //
- // buttonGo
- //
- this.buttonGo.Location = new System.Drawing.Point(152, 136);
- this.buttonGo.Name = "buttonGo";
- this.buttonGo.Size = new System.Drawing.Size(96, 24);
- this.buttonGo.TabIndex = 4;
- this.buttonGo.Text = "Go!";
- this.buttonGo.Click += new System.EventHandler(this.buttonGo_Click);
- //
- // startDatabaseDlg
- //
- this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
- this.ClientSize = new System.Drawing.Size(378, 167);
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.buttonGo,
- this.label2,
- this.progressBar,
- this.label1,
- this.textAction});
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "startDatabaseDlg";
- this.Text = "Starting database";
- this.Load += new System.EventHandler(this.startDatabase_Load);
- this.Paint += new System.Windows.Forms.PaintEventHandler(this.startDatabase_Paint);
- this.ResumeLayout(false);
-
- }
- #endregion
-
- private void startDatabase_Load(object sender, System.EventArgs e)
- {
-
- }
-
- private void startDatabase_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
- {
-
-
-
- }
- private void defineProcesses()
- {
- ArrayList processes = m_db.getProcesses();
- progressBar.Maximum = processes.Count;
- progressBar.Minimum = 0;
-
- int retry=0;
- //sc.connect("130.100.232.7");
- foreach (Process p in processes)
- {
- Computer comp;
- retry=0;
- //if(p.getName().StartsWith("ndb") || p.getName().StartsWith("mgm"))
- //{
- textAction.Text="Defining process " + p.getName();
- textAction.Refresh();
- comp=p.getComputer();
- while(retry<10)
- {
- if(!comp.isConnected())
- {
- comp.connectToCpcd();
-
- }
- else
- {
- if(comp.defineProcess(p)<0)
- {
- ;
- }
- else
- break;
- }
- if(retry==9)
- {
- if(MessageBox.Show(this,"Failed to define process. Try again?","Warning!!!",MessageBoxButtons.YesNo)==DialogResult.Yes)
- retry=0;
- }
- retry++;
- //comp.undefineProcess(p);
- }
- //}
- progressBar.PerformStep();
- }
- }
-
- private void startProcesses()
- {
-
- ArrayList processes = m_db.getProcesses();
- progressBar.Maximum = processes.Count;
- progressBar.Minimum = 0;
- string start = "start process \n";
-
- int retry=0;
- //sc.connect("130.100.232.7");
- foreach (Process p in processes)
- {
- Computer comp;
- if((p.getName().StartsWith("ndb")) || (p.getName().StartsWith("mgm")))
- {
- textAction.Text="Starting process " + p.getName();
- textAction.Refresh();
- start = start + "id:" + p.getId() + "\n\n";
- comp=p.getComputer();
- while(retry<10)
- {
- if(!comp.isConnected())
- {
- comp.connectToCpcd();
- }
- else
- {
- if(comp.startProcess(p)<0)
- {
- ;
- }
- else
- break;
- }
- if(retry==9)
- {
- if(MessageBox.Show(this,"Failed to start process. Retry again?","Warning!!!",MessageBoxButtons.YesNo)==DialogResult.Yes)
- retry=0;
- }
-
- retry++;
- }
- }
- progressBar.PerformStep();
-
- }
-
- }
-
- private void buttonGo_Click(object sender, System.EventArgs e)
- {
- buttonGo.Enabled=false;
- progressBar.Step=1;
- defineProcesses();
- progressBar.Value=0;
- startProcesses();
-
- }
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs b/storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs
deleted file mode 100644
index fda0fc937e1..00000000000
--- a/storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs
+++ /dev/null
@@ -1,424 +0,0 @@
-/* Copyright (c) 2004, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-using System;
-using System.Drawing;
-using System.Collections;
-using System.ComponentModel;
-using System.Windows.Forms;
-using System.Data;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.IO;
-using System.Threading ;
-
-namespace NDB_CPC.telnetclient
-{
- /// <summary>
- /// Summary description for telnetClient.
- /// </summary>
- public class telnetClient
- {
- Char IAC = Convert.ToChar(255);
- Char DO = Convert.ToChar(253);
- Char DONT = Convert.ToChar(254);
- Char WILL = Convert.ToChar(251);
- Char WONT = Convert.ToChar(252);
- Char SB = Convert.ToChar(250);
- Char SE = Convert.ToChar(240);
- const Char IS = '0';
- const Char SEND = '1';
- const Char INFO = '2';
- const Char VAR = '0';
- const Char VALUE = '1';
- const Char ESC = '2';
- const Char USERVAR = '3';
- string m_strResp;
-
- private ArrayList m_ListOptions = new ArrayList();
- private IPEndPoint iep ;
- private AsyncCallback callbackProc ;
- private string address ;
- private int port ;
- private Socket s ;
- private TextBox textBox1;
- Byte[] m_byBuff = new Byte[32767];
-
-
- public telnetClient(string ip, int p, TextBox tb)
- {
-
- address = ip;
- port = p;
- textBox1=tb;
- IPHostEntry IPHost = Dns.Resolve(address);
- string []aliases = IPHost.Aliases;
- IPAddress[] addr = IPHost.AddressList;
-
- try
- {
- // Create New Socket
- s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- // Create New EndPoint
- iep = new IPEndPoint(addr[0],port);
- // This is a non blocking IO
- s.Blocking = false ;
- // Assign Callback function to read from Asyncronous Socket
- callbackProc = new AsyncCallback(ConnectCallback);
- // Begin Asyncronous Connection
- s.BeginConnect(iep , callbackProc, s ) ;
-
- }
- catch(Exception eeeee )
- {
- MessageBox.Show(eeeee.Message , "Application Error!!!" , MessageBoxButtons.OK , MessageBoxIcon.Stop );
- Application.Exit();
- }
- }
-
- public void ConnectCallback( IAsyncResult ar )
- {
- try
- {
- // Get The connection socket from the callback
- Socket sock1 = (Socket)ar.AsyncState;
- if ( sock1.Connected )
- {
- // Define a new Callback to read the data
- AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
- // Begin reading data asyncronously
- sock1.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData , sock1 );
- }
- }
- catch( Exception ex )
- {
- MessageBox.Show(ex.Message, "Setup Recieve callbackProc failed!" );
- }
- }
-
-
- public void OnRecievedData( IAsyncResult ar )
- {
- // Get The connection socket from the callback
- Socket sock = (Socket)ar.AsyncState;
- // Get The data , if any
- int nBytesRec = sock.EndReceive( ar );
- if( nBytesRec > 0 )
- {
- string sRecieved = Encoding.ASCII.GetString( m_byBuff, 0, nBytesRec );
- string m_strLine="";
- for ( int i=0; i < nBytesRec;i++)
- {
- Char ch = Convert.ToChar(m_byBuff[i]);
- switch( ch )
- {
- case '\r':
- m_strLine += Convert.ToString("\r\n");
- break;
- case '\n':
- break;
- default:
- m_strLine += Convert.ToString(ch);
- break;
- }
- }
- try
- {
- int strLinelen = m_strLine.Length ;
- if ( strLinelen == 0 )
- {
- m_strLine = Convert.ToString("\r\n");
- }
-
- Byte[] mToProcess = new Byte[strLinelen];
- for ( int i=0; i < strLinelen ; i++)
- mToProcess[i] = Convert.ToByte(m_strLine[i]);
- // Process the incoming data
- string mOutText = ProcessOptions(mToProcess);
- if ( mOutText != "" )
- textBox1.AppendText(mOutText);
-
- // Respond to any incoming commands
- RespondToOptions();
- }
- catch( Exception ex )
- {
- Object x = this ;
- MessageBox.Show(ex.Message , "Information!" );
- }
- }
- else
- {
- // If no data was recieved then the connection is probably dead
- Console.WriteLine( "Disconnected", sock.RemoteEndPoint );
- sock.Shutdown( SocketShutdown.Both );
- sock.Close();
- Application.Exit();
- }
- }
-
- private string ProcessOptions(byte[] m_strLineToProcess)
- {
- string m_DISPLAYTEXT ="";
- string m_strTemp ="" ;
- string m_strOption ="";
- string m_strNormalText ="";
- bool bScanDone =false;
- int ndx =0;
- int ldx =0;
- char ch ;
- try
- {
- for ( int i=0; i < m_strLineToProcess.Length ; i++)
- {
- Char ss = Convert.ToChar(m_strLineToProcess[i]);
- m_strTemp = m_strTemp + Convert.ToString(ss);
- }
-
- while(bScanDone != true )
- {
- int lensmk = m_strTemp.Length;
- ndx = m_strTemp.IndexOf(Convert.ToString(IAC));
- if ( ndx > lensmk )
- ndx = m_strTemp.Length;
-
- if(ndx != -1)
- {
- m_DISPLAYTEXT+= m_strTemp.Substring(0,ndx);
- ch = m_strTemp[ndx + 1];
- if ( ch == DO || ch == DONT || ch == WILL || ch == WONT )
- {
- m_strOption = m_strTemp.Substring(ndx, 3);
- string txt = m_strTemp.Substring(ndx + 3);
- m_DISPLAYTEXT+= m_strTemp.Substring(0,ndx);
- m_ListOptions.Add(m_strOption);
- m_strTemp = txt ;
- }
- else
- if ( ch == IAC)
- {
- m_DISPLAYTEXT= m_strTemp.Substring(0,ndx);
- m_strTemp = m_strTemp.Substring(ndx + 1);
- }
- else
- if ( ch == SB )
- {
- m_DISPLAYTEXT= m_strTemp.Substring(0,ndx);
- ldx = m_strTemp.IndexOf(Convert.ToString(SE));
- m_strOption = m_strTemp.Substring(ndx, ldx);
- m_ListOptions.Add(m_strOption);
- m_strTemp = m_strTemp.Substring(ldx);
- }
- }
- else
- {
- m_DISPLAYTEXT = m_DISPLAYTEXT + m_strTemp;
- bScanDone = true ;
- }
- }
- m_strNormalText = m_DISPLAYTEXT;
- }
- catch(Exception eP)
- {
- MessageBox.Show(eP.Message , "Application Error!!!" , MessageBoxButtons.OK , MessageBoxIcon.Stop );
- Application.Exit();
- }
- return m_strNormalText ;
- }
-
- void DispatchMessage(string strText)
- {
- try
- {
- Byte[] smk = new Byte[strText.Length];
- for ( int i=0; i < strText.Length ; i++)
- {
- Byte ss = Convert.ToByte(strText[i]);
- smk[i] = ss ;
- }
-
- IAsyncResult ar2 = s.BeginSend(smk , 0 , smk.Length , SocketFlags.None , callbackProc , s );
- s.EndSend(ar2);
- }
- catch(Exception ers)
- {
- MessageBox.Show("ERROR IN RESPOND OPTIONS");
- }
- }
-
- void RespondToOptions()
- {
- try
- {
- string strOption;
- for ( int i=0; i < m_ListOptions.Count; i++)
- {
- strOption = (string)m_ListOptions[i];
- ArrangeReply(strOption);
- }
- DispatchMessage(m_strResp);
- m_strResp ="";
- m_ListOptions.Clear();
- }
- catch(Exception ers)
- {
- MessageBox.Show("ERROR IN RESPOND OPTIONS");
- }
- }
- void ArrangeReply(string strOption)
- {
- try
- {
-
- Char Verb;
- Char Option;
- Char Modifier;
- Char ch;
- bool bDefined = false;
-
- if(strOption.Length < 3) return;
-
- Verb = strOption[1];
- Option = strOption[2];
-
- if ( Option == 1 || Option == 3 )
- {
- // case 1: // Echo
- // case 3: // Suppress Go-Ahead
- bDefined = true;
- // break;
- }
-
- m_strResp += IAC;
-
- if(bDefined == true )
- {
- if ( Verb == DO )
- {
- // case DO:
- ch = WILL;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == DONT )
- {
- ch = WONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == WILL )
- {
- ch = DO;
- m_strResp += ch;
- m_strResp += Option;
- //break;
- }
- if ( Verb == WONT)
- {
- ch = DONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == SB)
- {
- Modifier = strOption[3];
- if(Modifier == SEND)
- {
- ch = SB;
- m_strResp += ch;
- m_strResp += Option;
- m_strResp += IS;
- m_strResp += IAC;
- m_strResp += SE;
- }
- // break;
- }
- }
- else
- {
- // switch(Verb)
- // {
- if ( Verb == DO )
- {
- ch = WONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == DONT)
- {
- ch = WONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == WILL)
- {
- ch = DONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- if ( Verb == WONT)
- {
- ch = DONT;
- m_strResp += ch;
- m_strResp += Option;
- // break;
- }
- }
- }
- catch(Exception eeeee )
- {
- MessageBox.Show(eeeee.Message , "Application Error!!!" , MessageBoxButtons.OK , MessageBoxIcon.Stop );
- Application.Exit();
- }
-
- }
-
- private void textBox1_KeyPress_1(object sender, System.Windows.Forms.KeyPressEventArgs e)
- {
- if ( e.KeyChar == 13 )
- {
- DispatchMessage("\r\n");
- }
- else
- if ( e.KeyChar == 8 )
- {
- try
- {
-// string mtmp = textBox1.Text.Substring(0,textBox1.Text.Length-1);
-// textBox1.Text = "" ;
- }
- catch(Exception ebs)
- {
- MessageBox.Show("ERROR IN BACKSPACE");
- }
- }
- else
- {
- string str = e.KeyChar.ToString();
- DispatchMessage(str);
- }
- }
-
-
- }
-}
diff --git a/storage/ndb/src/cw/cpcd/APIService.cpp b/storage/ndb/src/cw/cpcd/APIService.cpp
deleted file mode 100644
index b8f2b7d5f05..00000000000
--- a/storage/ndb/src/cw/cpcd/APIService.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <Parser.hpp>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include <socket_io.h>
-
-#include "APIService.hpp"
-#include "CPCD.hpp"
-#include <NdbMutex.h>
-#include <OutputStream.hpp>
-
-/**
- const char * name;
- const char * realName;
- const Type type;
- const ArgType argType;
- const ArgRequired argRequired;
- const ArgMinMax argMinMax;
- const int minVal;
- const int maxVal;
- void (T::* function)(const class Properties & args);
- const char * description;
-*/
-
-#define CPCD_CMD(name, fun, desc) \
- { name, \
- 0, \
- ParserRow<CPCDAPISession>::Cmd, \
- ParserRow<CPCDAPISession>::String, \
- ParserRow<CPCDAPISession>::Optional, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- 0, 0, \
- fun, \
- desc, 0 }
-
-#define CPCD_ARG(name, type, opt, desc) \
- { name, \
- 0, \
- ParserRow<CPCDAPISession>::Arg, \
- ParserRow<CPCDAPISession>::type, \
- ParserRow<CPCDAPISession>::opt, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- desc, 0 }
-
-#define CPCD_ARG2(name, type, opt, min, max, desc) \
- { name, \
- 0, \
- ParserRow<CPCDAPISession>::Arg, \
- ParserRow<CPCDAPISession>::type, \
- ParserRow<CPCDAPISession>::opt, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- min, max, \
- 0, \
- desc, 0 }
-
-#define CPCD_END() \
- { 0, \
- 0, \
- ParserRow<CPCDAPISession>::Arg, \
- ParserRow<CPCDAPISession>::Int, \
- ParserRow<CPCDAPISession>::Optional, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-#define CPCD_CMD_ALIAS(name, realName, fun) \
- { name, \
- realName, \
- ParserRow<CPCDAPISession>::CmdAlias, \
- ParserRow<CPCDAPISession>::Int, \
- ParserRow<CPCDAPISession>::Optional, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-#define CPCD_ARG_ALIAS(name, realName, fun) \
- { name, \
- realName, \
- ParserRow<CPCDAPISession>::ArgAlias, \
- ParserRow<CPCDAPISession>::Int, \
- ParserRow<CPCDAPISession>::Optional, \
- ParserRow<CPCDAPISession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-const
-ParserRow<CPCDAPISession> commands[] =
-{
- CPCD_CMD("define process" , &CPCDAPISession::defineProcess, ""),
- CPCD_ARG("id", Int, Optional, "Id of process."),
- CPCD_ARG("name", String, Mandatory, "Name of process"),
- CPCD_ARG("group", String, Mandatory, "Group of process"),
- CPCD_ARG("env", String, Optional, "Environment variables for process"),
- CPCD_ARG("path", String, Mandatory, "Path to binary"),
- CPCD_ARG("args", String, Optional, "Arguments to process"),
- CPCD_ARG("type", String, Mandatory, "Type of process"),
- CPCD_ARG("cwd", String, Mandatory, "Working directory of process"),
- CPCD_ARG("owner", String, Mandatory, "Owner of process"),
- CPCD_ARG("runas", String, Optional, "Run as user"),
- CPCD_ARG("stdout", String, Optional, "Redirection of stdout"),
- CPCD_ARG("stderr", String, Optional, "Redirection of stderr"),
- CPCD_ARG("stdin", String, Optional, "Redirection of stderr"),
- CPCD_ARG("ulimit", String, Optional, "ulimit"),
- CPCD_ARG("shutdown", String, Optional, "shutdown options"),
-
- CPCD_CMD("undefine process", &CPCDAPISession::undefineProcess, ""),
- CPCD_CMD_ALIAS("undef", "undefine process", 0),
- CPCD_ARG("id", Int, Mandatory, "Id of process"),
- CPCD_ARG_ALIAS("i", "id", 0),
-
- CPCD_CMD("start process", &CPCDAPISession::startProcess, ""),
- CPCD_ARG("id", Int, Mandatory, "Id of process"),
-
- CPCD_CMD("stop process", &CPCDAPISession::stopProcess, ""),
- CPCD_ARG("id", Int, Mandatory, "Id of process"),
-
- CPCD_CMD("list processes", &CPCDAPISession::listProcesses, ""),
-
- CPCD_CMD("show version", &CPCDAPISession::showVersion, ""),
-
- CPCD_END()
-};
-CPCDAPISession::CPCDAPISession(NDB_SOCKET_TYPE sock,
- CPCD & cpcd)
- : SocketServer::Session(sock)
- , m_cpcd(cpcd)
-{
- m_input = new SocketInputStream(sock, 7*24*60*60000);
- m_output = new SocketOutputStream(sock);
- m_parser = new Parser<CPCDAPISession>(commands, *m_input, true, true, true);
-}
-
-CPCDAPISession::CPCDAPISession(FILE * f, CPCD & cpcd)
- : SocketServer::Session(1)
- , m_cpcd(cpcd)
-{
- m_input = new FileInputStream(f);
- m_parser = new Parser<CPCDAPISession>(commands, *m_input, true, true, true);
-}
-
-CPCDAPISession::~CPCDAPISession() {
- delete m_input;
- delete m_parser;
-}
-
-void
-CPCDAPISession::runSession(){
- Parser_t::Context ctx;
- while(!m_stop){
- m_parser->run(ctx, * this);
- if(ctx.m_currentToken == 0)
- break;
-
- switch(ctx.m_status){
- case Parser_t::Ok:
- for(size_t i = 0; i<ctx.m_aliasUsed.size(); i++)
- ndbout_c("Used alias: %s -> %s",
- ctx.m_aliasUsed[i]->name, ctx.m_aliasUsed[i]->realName);
- break;
- case Parser_t::NoLine:
- case Parser_t::EmptyLine:
- break;
- default:
- break;
- }
- }
- NDB_CLOSE_SOCKET(m_socket);
-}
-
-void
-CPCDAPISession::stopSession(){
- CPCD::RequestStatus rs;
- for(size_t i = 0; i<m_temporaryProcesses.size(); i++){
- Uint32 id = m_temporaryProcesses[i];
- m_cpcd.undefineProcess(&rs, id);
- }
-}
-
-void
-CPCDAPISession::loadFile(){
- Parser_t::Context ctx;
- while(!m_stop){
- m_parser->run(ctx, * this);
- if(ctx.m_currentToken == 0)
- break;
-
- switch(ctx.m_status){
- case Parser_t::Ok:
- for(size_t i = 0; i<ctx.m_aliasUsed.size(); i++)
- ndbout_c("Used alias: %s -> %s",
- ctx.m_aliasUsed[i]->name, ctx.m_aliasUsed[i]->realName);
- break;
- case Parser_t::NoLine:
- case Parser_t::EmptyLine:
- break;
- default:
- break;
- }
- }
-}
-
-static const int g_TimeOut = 1000;
-
-void
-CPCDAPISession::defineProcess(Parser_t::Context & /* unused */,
- const class Properties & args){
-
- CPCD::Process * p = new CPCD::Process(args, &m_cpcd);
-
- CPCD::RequestStatus rs;
-
- bool ret = m_cpcd.defineProcess(&rs, p);
- if(!m_cpcd.loadingProcessList) {
- m_output->println("define process");
- m_output->println("status: %d", rs.getStatus());
- if(ret == true){
- m_output->println("id: %d", p->m_id);
- if(p->m_processType == TEMPORARY){
- m_temporaryProcesses.push_back(p->m_id);
- }
- } else {
- m_output->println("errormessage: %s", rs.getErrMsg());
- }
- m_output->println("");
- }
-}
-
-void
-CPCDAPISession::undefineProcess(Parser_t::Context & /* unused */,
- const class Properties & args){
- Uint32 id;
- CPCD::RequestStatus rs;
-
- args.get("id", &id);
- bool ret = m_cpcd.undefineProcess(&rs, id);
-
- m_output->println("undefine process");
- m_output->println("id: %d", id);
- m_output->println("status: %d", rs.getStatus());
- if(!ret)
- m_output->println("errormessage: %s", rs.getErrMsg());
-
- m_output->println("");
-}
-
-void
-CPCDAPISession::startProcess(Parser_t::Context & /* unused */,
- const class Properties & args){
- Uint32 id;
- CPCD::RequestStatus rs;
-
- args.get("id", &id);
- const int ret = m_cpcd.startProcess(&rs, id);
-
- if(!m_cpcd.loadingProcessList) {
- m_output->println("start process");
- m_output->println("id: %d", id);
- m_output->println("status: %d", rs.getStatus());
- if(!ret)
- m_output->println("errormessage: %s", rs.getErrMsg());
- m_output->println("");
- }
-}
-
-void
-CPCDAPISession::stopProcess(Parser_t::Context & /* unused */,
- const class Properties & args){
- Uint32 id;
- CPCD::RequestStatus rs;
-
- args.get("id", &id);
- int ret = m_cpcd.stopProcess(&rs, id);
-
- m_output->println("stop process");
- m_output->println("id: %d", id);
- m_output->println("status: %d", rs.getStatus());
- if(!ret)
- m_output->println("errormessage: %s", rs.getErrMsg());
-
- m_output->println("");
-}
-
-static const char *
-propToString(Properties *prop, const char *key) {
- static char buf[32];
- const char *retval = NULL;
- PropertiesType pt;
-
- prop->getTypeOf(key, &pt);
- switch(pt) {
- case PropertiesType_Uint32:
- Uint32 val;
- prop->get(key, &val);
- BaseString::snprintf(buf, sizeof buf, "%d", val);
- retval = buf;
- break;
- case PropertiesType_char:
- const char *str;
- prop->get(key, &str);
- retval = str;
- break;
- default:
- BaseString::snprintf(buf, sizeof buf, "(unknown)");
- retval = buf;
- }
- return retval;
-}
-
-void
-CPCDAPISession::printProperty(Properties *prop, const char *key) {
- m_output->println("%s: %s", key, propToString(prop, key));
-}
-
-void
-CPCDAPISession::listProcesses(Parser_t::Context & /* unused */,
- const class Properties & /* unused */){
- m_cpcd.m_processes.lock();
- MutexVector<CPCD::Process *> *proclist = m_cpcd.getProcessList();
-
- m_output->println("start processes");
- m_output->println("");
-
-
- for(size_t i = 0; i < proclist->size(); i++) {
- CPCD::Process *p = (*proclist)[i];
-
- m_output->println("process");
-
- m_output->println("id: %d", p->m_id);
- m_output->println("name: %s", p->m_name.c_str());
- m_output->println("path: %s", p->m_path.c_str());
- m_output->println("args: %s", p->m_args.c_str());
- m_output->println("type: %s", p->m_type.c_str());
- m_output->println("cwd: %s", p->m_cwd.c_str());
- m_output->println("env: %s", p->m_env.c_str());
- m_output->println("owner: %s", p->m_owner.c_str());
- m_output->println("group: %s", p->m_group.c_str());
- m_output->println("runas: %s", p->m_runas.c_str());
- m_output->println("stdin: %s", p->m_stdin.c_str());
- m_output->println("stdout: %s", p->m_stdout.c_str());
- m_output->println("stderr: %s", p->m_stderr.c_str());
- m_output->println("ulimit: %s", p->m_ulimit.c_str());
- m_output->println("shutdown: %s", p->m_shutdown_options.c_str());
- switch(p->m_status){
- case STOPPED:
- m_output->println("status: stopped");
- break;
- case STARTING:
- m_output->println("status: starting");
- break;
- case RUNNING:
- m_output->println("status: running");
- break;
- case STOPPING:
- m_output->println("status: stopping");
- break;
- }
-
- m_output->println("");
-
- }
-
- m_output->println("end processes");
- m_output->println("");
-
- m_cpcd.m_processes.unlock();
-}
-
-void
-CPCDAPISession::showVersion(Parser_t::Context & /* unused */,
- const class Properties & args){
- CPCD::RequestStatus rs;
-
- m_output->println("show version");
- m_output->println("compile time: %s %s", __DATE__, __TIME__);
-
- m_output->println("");
-}
-
-template class Vector<ParserRow<CPCDAPISession> const*>;
diff --git a/storage/ndb/src/cw/cpcd/APIService.hpp b/storage/ndb/src/cw/cpcd/APIService.hpp
deleted file mode 100644
index d6a45dc26a4..00000000000
--- a/storage/ndb/src/cw/cpcd/APIService.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef CPCD_API_HPP
-#define CPCD_API_HPP
-
-#include <Parser.hpp>
-#include <InputStream.hpp>
-#include <SocketServer.hpp>
-
-class CPCD;
-
-class CPCDAPISession : public SocketServer::Session {
- typedef Parser<CPCDAPISession> Parser_t;
-
- class CPCD & m_cpcd;
- InputStream *m_input;
- OutputStream *m_output;
- Parser_t *m_parser;
-
- Vector<int> m_temporaryProcesses;
-
- void printProperty(Properties *prop, const char *key);
-public:
- CPCDAPISession(NDB_SOCKET_TYPE, class CPCD &);
- CPCDAPISession(FILE * f, CPCD & cpcd);
- ~CPCDAPISession();
-
- virtual void runSession();
- virtual void stopSession();
- void loadFile();
-
- void defineProcess(Parser_t::Context & ctx, const class Properties & args);
- void undefineProcess(Parser_t::Context & ctx, const class Properties & args);
- void startProcess(Parser_t::Context & ctx, const class Properties & args);
- void stopProcess(Parser_t::Context & ctx, const class Properties & args);
- void showProcess(Parser_t::Context & ctx, const class Properties & args);
- void listProcesses(Parser_t::Context & ctx, const class Properties & args);
- void showVersion(Parser_t::Context & ctx, const class Properties & args);
-};
-
-class CPCDAPIService : public SocketServer::Service {
- class CPCD & m_cpcd;
-public:
- CPCDAPIService(class CPCD & cpcd) : m_cpcd(cpcd) {}
-
- CPCDAPISession * newSession(NDB_SOCKET_TYPE theSock){
- return new CPCDAPISession(theSock, m_cpcd);
- }
-};
-
-#endif
diff --git a/storage/ndb/src/cw/cpcd/CPCD.cpp b/storage/ndb/src/cw/cpcd/CPCD.cpp
deleted file mode 100644
index 48e946f58b8..00000000000
--- a/storage/ndb/src/cw/cpcd/CPCD.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-
-#include "APIService.hpp"
-#include "CPCD.hpp"
-#include <NdbMutex.h>
-
-#include "common.hpp"
-
-extern const ParserRow<CPCDAPISession> commands[];
-
-
-CPCD::CPCD() {
- loadingProcessList = false;
- m_processes.clear();
- m_monitor = NULL;
- m_monitor = new Monitor(this);
- m_procfile = "ndb_cpcd.db";
-}
-
-CPCD::~CPCD() {
- if(m_monitor != NULL) {
- delete m_monitor;
- m_monitor = NULL;
- }
-}
-
-int
-CPCD::findUniqueId() {
- int id;
- bool ok = false;
- m_processes.lock();
-
- while(!ok) {
- ok = true;
- id = random() % 8192; /* Don't want so big numbers */
-
- if(id == 0)
- ok = false;
-
- for(size_t i = 0; i<m_processes.size(); i++) {
- if(m_processes[i]->m_id == id)
- ok = false;
- }
- }
- m_processes.unlock();
- return id;
-}
-
-bool
-CPCD::defineProcess(RequestStatus * rs, Process * arg){
- if(arg->m_id == -1)
- arg->m_id = findUniqueId();
-
- Guard tmp(m_processes);
-
- for(size_t i = 0; i<m_processes.size(); i++) {
- Process * proc = m_processes[i];
-
- if((strcmp(arg->m_name.c_str(), proc->m_name.c_str()) == 0) &&
- (strcmp(arg->m_group.c_str(), proc->m_group.c_str()) == 0)) {
- /* Identical names in the same group */
- rs->err(AlreadyExists, "Name already exists");
- return false;
- }
-
- if(arg->m_id == proc->m_id) {
- /* Identical ID numbers */
- rs->err(AlreadyExists, "Id already exists");
- return false;
- }
- }
-
- m_processes.push_back(arg, false);
-
- notifyChanges();
- report(arg->m_id, CPCEvent::ET_PROC_USER_DEFINE);
-
- return true;
-}
-
-bool
-CPCD::undefineProcess(CPCD::RequestStatus *rs, int id) {
-
- Guard tmp(m_processes);
-
- Process * proc = 0;
- size_t i;
- for(i = 0; i < m_processes.size(); i++) {
- if(m_processes[i]->m_id == id) {
- proc = m_processes[i];
- break;
- }
- }
-
- if(proc == 0){
- rs->err(NotExists, "No such process");
- return false;
- }
-
- switch(proc->m_status){
- case RUNNING:
- case STOPPED:
- case STOPPING:
- case STARTING:
- proc->stop();
- m_processes.erase(i, false /* Already locked */);
- }
-
-
- notifyChanges();
-
- report(id, CPCEvent::ET_PROC_USER_UNDEFINE);
-
- return true;
-}
-
-bool
-CPCD::startProcess(CPCD::RequestStatus *rs, int id) {
-
- Process * proc = 0;
- {
-
- Guard tmp(m_processes);
-
- for(size_t i = 0; i < m_processes.size(); i++) {
- if(m_processes[i]->m_id == id) {
- proc = m_processes[i];
- break;
- }
- }
-
- if(proc == 0){
- rs->err(NotExists, "No such process");
- return false;
- }
-
- switch(proc->m_status){
- case STOPPED:
- proc->m_status = STARTING;
- if(proc->start() != 0){
- rs->err(Error, "Failed to start");
- return false;
- }
- break;
- case STARTING:
- rs->err(Error, "Already starting");
- return false;
- case RUNNING:
- rs->err(Error, "Already started");
- return false;
- case STOPPING:
- rs->err(Error, "Currently stopping");
- return false;
- }
-
- notifyChanges();
- }
- report(id, CPCEvent::ET_PROC_USER_START);
-
- return true;
-}
-
-bool
-CPCD::stopProcess(CPCD::RequestStatus *rs, int id) {
-
- Guard tmp(m_processes);
-
- Process * proc = 0;
- for(size_t i = 0; i < m_processes.size(); i++) {
- if(m_processes[i]->m_id == id) {
- proc = m_processes[i];
- break;
- }
- }
-
- if(proc == 0){
- rs->err(NotExists, "No such process");
- return false;
- }
-
- switch(proc->m_status){
- case STARTING:
- case RUNNING:
- proc->stop();
- break;
- case STOPPED:
- rs->err(AlreadyStopped, "Already stopped");
- return false;
- break;
- case STOPPING:
- rs->err(Error, "Already stopping");
- return false;
- }
-
- notifyChanges();
-
- report(id, CPCEvent::ET_PROC_USER_START);
-
- return true;
-}
-
-bool
-CPCD::notifyChanges() {
- bool ret = true;
- if(!loadingProcessList)
- ret = saveProcessList();
-
- m_monitor->signal();
-
- return ret;
-}
-
-/* Must be called with m_processlist locked */
-bool
-CPCD::saveProcessList(){
- char newfile[PATH_MAX+4];
- char oldfile[PATH_MAX+4];
- char curfile[PATH_MAX];
- FILE *f;
-
- /* Create the filenames that we will use later */
- BaseString::snprintf(newfile, sizeof(newfile), "%s.new", m_procfile.c_str());
- BaseString::snprintf(oldfile, sizeof(oldfile), "%s.old", m_procfile.c_str());
- BaseString::snprintf(curfile, sizeof(curfile), "%s", m_procfile.c_str());
-
- f = fopen(newfile, "w");
-
- if(f == NULL) {
- /* XXX What should be done here? */
- logger.critical("Cannot open `%s': %s\n", newfile, strerror(errno));
- return false;
- }
-
- for(size_t i = 0; i<m_processes.size(); i++){
- m_processes[i]->print(f);
- fprintf(f, "\n");
-
- if(m_processes[i]->m_processType == TEMPORARY){
- /**
- * Interactive process should never be "restarted" on cpcd restart
- */
- continue;
- }
-
- if(m_processes[i]->m_status == RUNNING ||
- m_processes[i]->m_status == STARTING){
- fprintf(f, "start process\nid: %d\n\n", m_processes[i]->m_id);
- }
- }
-
- fclose(f);
- f = NULL;
-
- /* This will probably only work on reasonably Unix-like systems. You have
- * been warned...
- *
- * The motivation behind all this link()ing is that the daemon might
- * crash right in the middle of updating the configuration file, and in
- * that case we want to be sure that the old file is around until we are
- * guaranteed that there is always at least one copy of either the old or
- * the new configuration file left.
- */
-
- /* Remove an old config file if it exists */
- unlink(oldfile);
-
- if(link(curfile, oldfile) != 0) /* make a backup of the running config */
- logger.error("Cannot rename '%s' -> '%s'", curfile, oldfile);
- else {
- if(unlink(curfile) != 0) { /* remove the running config file */
- logger.critical("Cannot remove file '%s'", curfile);
- return false;
- }
- }
-
- if(link(newfile, curfile) != 0) { /* put the new config file in place */
- printf("-->%d\n", __LINE__);
-
- logger.critical("Cannot rename '%s' -> '%s': %s",
- curfile, newfile, strerror(errno));
- return false;
- }
-
- /* XXX Ideally we would fsync() the directory here, but I'm not sure if
- * that actually works.
- */
-
- unlink(newfile); /* remove the temporary file */
- unlink(oldfile); /* remove the old file */
-
- logger.info("Process list saved as '%s'", curfile);
-
- return true;
-}
-
-bool
-CPCD::loadProcessList(){
- BaseString secondfile;
- FILE *f;
-
- loadingProcessList = true;
-
- secondfile.assfmt("%s.new", m_procfile.c_str());
-
- /* Try to open the config file */
- f = fopen(m_procfile.c_str(), "r");
-
- /* If it did not exist, try to open the backup. See the saveProcessList()
- * method for an explanation why it is done this way.
- */
- if(f == NULL) {
- f = fopen(secondfile.c_str(), "r");
-
- if(f == NULL) {
- /* XXX What to do here? */
- logger.info("Configuration file `%s' not found",
- m_procfile.c_str());
- logger.info("Starting with empty configuration");
- loadingProcessList = false;
- return false;
- } else {
- logger.info("Configuration file `%s' missing",
- m_procfile.c_str());
- logger.info("Backup configuration file `%s' is used",
- secondfile.c_str());
- /* XXX Maybe we should just rename the backup file to the official
- * name, and be done with it?
- */
- }
- }
-
- CPCDAPISession sess(f, *this);
- sess.loadFile();
- loadingProcessList = false;
-
- size_t i;
- Vector<int> temporary;
- for(i = 0; i<m_processes.size(); i++){
- Process * proc = m_processes[i];
- proc->readPid();
- if(proc->m_processType == TEMPORARY){
- temporary.push_back(proc->m_id);
- }
- }
-
- for(i = 0; i<temporary.size(); i++){
- RequestStatus rs;
- undefineProcess(&rs, temporary[i]);
- }
-
- /* Don't call notifyChanges here, as that would save the file we just
- loaded */
- m_monitor->signal();
- return true;
-}
-
-MutexVector<CPCD::Process *> *
-CPCD::getProcessList() {
- return &m_processes;
-}
-
-void
-CPCD::RequestStatus::err(enum RequestStatusCode status, const char *msg) {
- m_status = status;
- BaseString::snprintf(m_errorstring, sizeof(m_errorstring), "%s", msg);
-}
-
-#if 0
-void
-CPCD::sigchild(int pid){
- m_processes.lock();
- for(size_t i = 0; i<m_processes.size(); i++){
- if(m_processes[i].m_pid == pid){
- }
- }
- wait(pid, 0, 0);
-}
-#endif
-
- /** Register event subscriber */
-void
-CPCD::do_register(EventSubscriber * sub){
- m_subscribers.lock();
- m_subscribers.push_back(sub, false);
- m_subscribers.unlock();
-}
-
-EventSubscriber*
-CPCD::do_unregister(EventSubscriber * sub){
- m_subscribers.lock();
-
- for(size_t i = 0; i<m_subscribers.size(); i++){
- if(m_subscribers[i] == sub){
- m_subscribers.erase(i);
- m_subscribers.unlock();
- return sub;
- }
- }
-
- m_subscribers.unlock();
- return 0;
-}
-
-void
-CPCD::report(int id, CPCEvent::EventType t){
- CPCEvent e;
- e.m_time = time(0);
- e.m_proc = id;
- e.m_type = t;
- m_subscribers.lock();
- for(size_t i = 0; i<m_subscribers.size(); i++){
- (* m_subscribers[i]).report(e);
- }
- m_subscribers.unlock();
-}
-
-template class MutexVector<EventSubscriber*>;
diff --git a/storage/ndb/src/cw/cpcd/CPCD.hpp b/storage/ndb/src/cw/cpcd/CPCD.hpp
deleted file mode 100644
index 3c2934c0f49..00000000000
--- a/storage/ndb/src/cw/cpcd/CPCD.hpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef CPCD_HPP
-#define CPCD_HPP
-
-#include <Vector.hpp>
-#include <Properties.hpp>
-#include <NdbOut.hpp>
-#include <NdbThread.h>
-#include <NdbCondition.h>
-#include <BaseString.hpp>
-
-/* XXX Need to figure out how to do this for non-Unix systems */
-#define CPCD_DEFAULT_WORK_DIR "/var/run/ndb_cpcd"
-#define CPCD_DEFAULT_PROC_FILE "ndb_cpcd.conf"
-#define CPCD_DEFAULT_TCP_PORT 1234
-#define CPCD_DEFAULT_POLLING_INTERVAL 5 /* seconds */
-#define CPCD_DEFAULT_CONFIG_FILE "/etc/ndb_cpcd.conf"
-
-enum ProcessStatus {
- STOPPED = 0,
- STARTING = 1,
- RUNNING = 2,
- STOPPING = 3
-};
-
-enum ProcessType {
- PERMANENT = 0,
- TEMPORARY = 1
-};
-
-struct CPCEvent {
- enum EventType {
- ET_USER_CONNECT,
- ET_USER_DISCONNECT,
-
- ET_PROC_USER_DEFINE, // Defined proc
- ET_PROC_USER_UNDEFINE, // Undefined proc
- ET_PROC_USER_START, // Proc ordered to start
- ET_PROC_USER_STOP, // Proc ordered to stop
- ET_PROC_STATE_RUNNING, // exec returned(?) ok
- ET_PROC_STATE_STOPPED // detected that proc is ! running
- };
-
- int m_proc;
- time_t m_time;
- EventType m_type;
-};
-
-struct EventSubscriber {
- virtual void report(const CPCEvent &) = 0;
- EventSubscriber() {}
- virtual ~EventSubscriber() {}
-};
-
-/**
- * @brief Error codes for CPCD requests
- */
-enum RequestStatusCode {
- OK = 0, ///< Everything OK
- Error = 1, ///< Generic error
- AlreadyExists = 2, ///< Entry already exists in list
- NotExists = 3, ///< Entry does not exist in list
- AlreadyStopped = 4
-};
-
-/**
- * @class CPCD
- * @brief Manages processes, letting them be controlled with a TCP connection.
- *
- * The class implementing the Cluster Process Control Daemon
- */
-class CPCD {
-public:
- /** @brief Describes the status of a client request */
- class RequestStatus {
- public:
- /** @brief Constructs an empty RequestStatus */
- RequestStatus() { m_status = OK; m_errorstring[0] = '\0'; };
-
- /** @brief Sets an errorcode and a printable message */
- void err(enum RequestStatusCode, const char *);
-
- /** @brief Returns the error message */
- char *getErrMsg() { return m_errorstring; };
-
- /** @brief Returns the error code */
- enum RequestStatusCode getStatus() { return m_status; };
- private:
- enum RequestStatusCode m_status;
- char m_errorstring[256];
- };
- /**
- * @brief Manages a process
- */
- class Process {
- int m_pid;
- public:
- /**
- * @brief Constructs and empty Process
- */
- Process(const Properties & props, class CPCD *cpcd);
- /**
- * @brief Monitors the process
- *
- * The process is started or stopped as needed.
- */
- void monitor();
-
- /**
- * @brief Checks if the process is running or not
- *
- * @return
- * - true if the process is running,
- * - false if the process is not running
- */
- bool isRunning();
-
- /** @brief Starts the process */
- int start();
-
- /** @brief Stops the process */
- void stop();
-
- /**
- * @brief Reads the pid from stable storage
- *
- * @return The pid number
- */
- int readPid();
-
- /**
- * @brief Writes the pid from stable storage
- *
- * @return
- * - 0 if successful
- - -1 and sets errno if an error occured
- */
- int writePid(int pid);
-
- /**
- * @brief Prints a textual description of the process on a file
- */
- void print(FILE *);
-
- /** Id number of the Process.
- *
- * @note This is not the same as a pid. This number is used in the
- * protocol, and will not be changed if a processes is restarted.
- */
- int m_id;
-
- /** @brief The name shown to the user */
- BaseString m_name;
-
- /** @brief Used to group a number of processes */
- BaseString m_group;
-
- /** @brief Environment variables
- *
- * Environmentvariables to add for the process.
- *
- * @note
- * - The environment cpcd started with is preserved
- * - There is no way to delete variables
- */
- BaseString m_env;
-
- /** @brief Path to the binary to run */
- BaseString m_path;
-
- /** @brief Arguments to the process.
- *
- * @note
- * - This includes argv[0].
- * - If no argv[0] is given, argv[0] will be set to m_path.
- */
- BaseString m_args;
-
- /**
- * @brief Type of process
- *
- * Either set to "interactive" or "permanent".
- */
- BaseString m_type;
- ProcessType m_processType;
-
- /**
- * @brief Working directory
- *
- * Working directory the process will start in.
- */
- BaseString m_cwd;
-
- /**
- * @brief Owner of the process.
- *
- * @note This will not affect the process' uid or gid;
- * it is only used for managemental purposes.
- * @see m_runas
- */
- BaseString m_owner;
-
- /**
- * @bried Run as
- * @note This affects uid
- * @see m_owner
- */
- BaseString m_runas;
-
- /**
- * @brief redirection for stdin
- */
- BaseString m_stdin;
-
- /**
- * @brief redirection for stdout
- */
- BaseString m_stdout;
-
- /**
- * @brief redirection for stderr
- */
- BaseString m_stderr;
-
- /** @brief Status of the process */
- enum ProcessStatus m_status;
-
- /**
- * @brief ulimits for process
- * @desc Format c:unlimited d:0 ...
- */
- BaseString m_ulimit;
-
- /**
- * @brief shutdown options
- */
- BaseString m_shutdown_options;
-
- private:
- class CPCD *m_cpcd;
- void do_exec();
- };
-
- /**
- * @brief Starts and stops processes as needed
- *
- * At a specified interval (default 5 seconds) calls the monitor function
- * of all the processes in the CPCDs list, causing the to start or
- * stop, depending on the configuration.
- */
- class Monitor {
- public:
- /** Creates a new CPCD::Monitor object, connected to the specified
- * CPCD.
- * A new thread will be created, which will poll the processes of
- * the CPCD at the specifed interval.
- */
- Monitor(CPCD *cpcd, int poll = CPCD_DEFAULT_POLLING_INTERVAL);
-
- /** Stops the monitor, but does not stop the processes */
- ~Monitor();
-
- /** Runs the monitor thread. */
- void run();
-
- /** Signals configuration changes to the monitor thread, causing it to
- * do the check without waiting for the timeout */
- void signal();
- private:
- class CPCD *m_cpcd;
- struct NdbThread *m_monitorThread;
- bool m_monitorThreadQuitFlag;
- struct NdbCondition *m_changeCondition;
- NdbMutex *m_changeMutex;
- int m_pollingInterval; /* seconds */
- };
-
- /** @brief Constructs a CPCD object */
- CPCD();
-
- /**
- * @brief Destroys a CPCD object,
- * but does not stop the processes it manages
- */
- ~CPCD();
-
- /** Adds a Process to the CPCDs list of managed Processes.
- *
- * @note The process will not be started until it is explicitly
- * marked as running with CPCD::startProcess().
- *
- * @return
- * - true if the addition was successful,
- * - false if not
- * - RequestStatus will be filled in with a suitable error
- * if an error occured.
- */
- bool defineProcess(RequestStatus *rs, Process * arg);
-
- /** Removes a Process from the CPCD.
- *
- * @note A Process that is running cannot be removed.
- *
- * @return
- * - true if the removal was successful,
- * - false if not
- * - The RequestStatus will be filled in with a suitable error
- * if an error occured.
- */
- bool undefineProcess(RequestStatus *rs, int id);
-
- /** Marks a Process for starting.
- *
- * @note The fact that a process has started does not mean it will actually
- * start properly. This command only makes sure the CPCD will
- * try to start it.
- *
- * @return
- * - true if the marking was successful
- * - false if not
- * - RequestStatus will be filled in with a suitable error
- * if an error occured.
- */
- bool startProcess(RequestStatus *rs, int id);
-
- /** Marks a Process for stopping.
- *
- * @return
- * - true if the marking was successful
- * - false if not
- * - The RequestStatus will be filled in with a suitable error
- * if an error occured.
- */
- bool stopProcess(RequestStatus *rs, int id);
-
- /** Generates a list of processes, and sends them to the CPCD client */
- bool listProcesses(RequestStatus *rs, MutexVector<const char *> &);
-
- /** Set to true while the CPCD is reading the configuration file */
- bool loadingProcessList;
-
- /** Saves the list of Processes and their status to the configuration file.
- * Called whenever the configuration is changed.
- */
- bool saveProcessList();
-
- /** Loads the list of Processes and their status from the configuration
- * file.
- * @note This function should only be called when the CPCD is starting,
- * calling it at other times will cause unspecified behaviour.
- */
- bool loadProcessList();
-
- /** Returns the list of processes */
- MutexVector<Process *> *getProcessList();
-
- /** The list of processes. Should not be used directly */
- MutexVector<Process *> m_processes;
-
- /** Register event subscriber */
- void do_register(EventSubscriber * sub);
- EventSubscriber* do_unregister(EventSubscriber * sub);
-
-private:
- friend class Process;
- bool notifyChanges();
- int findUniqueId();
- BaseString m_procfile;
- Monitor *m_monitor;
-
- void report(int id, CPCEvent::EventType);
- MutexVector<EventSubscriber *> m_subscribers;
-};
-
-#endif
diff --git a/storage/ndb/src/cw/cpcd/Makefile.am b/storage/ndb/src/cw/cpcd/Makefile.am
deleted file mode 100644
index 58092dd6025..00000000000
--- a/storage/ndb/src/cw/cpcd/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-ndbbin_PROGRAMS = ndb_cpcd
-
-ndb_cpcd_SOURCES = main.cpp CPCD.cpp Process.cpp APIService.cpp Monitor.cpp common.cpp
-
-LDADD_LOC = \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_util.mk.am
-
-ndb_cpcd_LDFLAGS = -static @ndb_bin_am_ldflags@
-
-windoze-dsp:
diff --git a/storage/ndb/src/cw/cpcd/Monitor.cpp b/storage/ndb/src/cw/cpcd/Monitor.cpp
deleted file mode 100644
index c096bb85029..00000000000
--- a/storage/ndb/src/cw/cpcd/Monitor.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbThread.h>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-
-#include "CPCD.hpp"
-#include "common.hpp"
-
-static void *
-monitor_thread_create_wrapper(void * arg) {
- CPCD::Monitor *mon = (CPCD::Monitor *)arg;
- mon->run();
- return NULL;
-}
-
-CPCD::Monitor::Monitor(CPCD *cpcd, int poll) {
- m_cpcd = cpcd;
- m_pollingInterval = poll;
- m_changeCondition = NdbCondition_Create();
- m_changeMutex = NdbMutex_Create();
- m_monitorThread = NdbThread_Create(monitor_thread_create_wrapper,
- (NDB_THREAD_ARG*) this,
- 32768,
- "ndb_cpcd_monitor",
- NDB_THREAD_PRIO_MEAN);
- m_monitorThreadQuitFlag = false;
-}
-
-CPCD::Monitor::~Monitor() {
- NdbThread_Destroy(&m_monitorThread);
- NdbCondition_Destroy(m_changeCondition);
- NdbMutex_Destroy(m_changeMutex);
-}
-
-void
-CPCD::Monitor::run() {
- while(1) {
- NdbMutex_Lock(m_changeMutex);
- NdbCondition_WaitTimeout(m_changeCondition,
- m_changeMutex,
- m_pollingInterval * 1000);
-
- MutexVector<CPCD::Process *> &proc = *m_cpcd->getProcessList();
-
- proc.lock();
-
- for(size_t i = 0; i < proc.size(); i++) {
- proc[i]->monitor();
- }
-
- proc.unlock();
-
- NdbMutex_Unlock(m_changeMutex);
- }
-}
-
-void
-CPCD::Monitor::signal() {
- NdbCondition_Signal(m_changeCondition);
-}
-
-template class MutexVector<CPCD::Process*>;
diff --git a/storage/ndb/src/cw/cpcd/Process.cpp b/storage/ndb/src/cw/cpcd/Process.cpp
deleted file mode 100644
index c2e24cecd77..00000000000
--- a/storage/ndb/src/cw/cpcd/Process.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <BaseString.hpp>
-#include <InputStream.hpp>
-
-#include "common.hpp"
-#include "CPCD.hpp"
-
-#include <pwd.h>
-#ifdef HAVE_GETRLIMIT
-#include <sys/resource.h>
-#endif
-
-void
-CPCD::Process::print(FILE * f){
- fprintf(f, "define process\n");
- fprintf(f, "id: %d\n", m_id);
- fprintf(f, "name: %s\n", m_name.c_str() ? m_name.c_str() : "");
- fprintf(f, "group: %s\n", m_group.c_str() ? m_group.c_str() : "");
- fprintf(f, "env: %s\n", m_env.c_str() ? m_env.c_str() : "");
- fprintf(f, "path: %s\n", m_path.c_str() ? m_path.c_str() : "");
- fprintf(f, "args: %s\n", m_args.c_str() ? m_args.c_str() : "");
- fprintf(f, "type: %s\n", m_type.c_str() ? m_type.c_str() : "");
- fprintf(f, "cwd: %s\n", m_cwd.c_str() ? m_cwd.c_str() : "");
- fprintf(f, "owner: %s\n", m_owner.c_str() ? m_owner.c_str() : "");
- fprintf(f, "runas: %s\n", m_runas.c_str() ? m_runas.c_str() : "");
- fprintf(f, "stdin: %s\n", m_stdin.c_str() ? m_stdin.c_str() : "");
- fprintf(f, "stdout: %s\n", m_stdout.c_str() ? m_stdout.c_str() : "");
- fprintf(f, "stderr: %s\n", m_stderr.c_str() ? m_stderr.c_str() : "");
- fprintf(f, "ulimit: %s\n", m_ulimit.c_str() ? m_ulimit.c_str() : "");
- fprintf(f, "shutdown: %s\n", m_shutdown_options.c_str() ?
- m_shutdown_options.c_str() : "");
-}
-
-CPCD::Process::Process(const Properties & props, class CPCD *cpcd) {
- m_id = -1;
- m_pid = -1;
- props.get("id", (Uint32 *) &m_id);
- props.get("name", m_name);
- props.get("group", m_group);
- props.get("env", m_env);
- props.get("path", m_path);
- props.get("args", m_args);
- props.get("cwd", m_cwd);
- props.get("owner", m_owner);
- props.get("type", m_type);
- props.get("runas", m_runas);
-
- props.get("stdin", m_stdin);
- props.get("stdout", m_stdout);
- props.get("stderr", m_stderr);
- props.get("ulimit", m_ulimit);
- props.get("shutdown", m_shutdown_options);
- m_status = STOPPED;
-
- if(strcasecmp(m_type.c_str(), "temporary") == 0){
- m_processType = TEMPORARY;
- } else {
- m_processType = PERMANENT;
- }
-
- m_cpcd = cpcd;
-}
-
-void
-CPCD::Process::monitor() {
- switch(m_status) {
- case STARTING:
- break;
- case RUNNING:
- if(!isRunning()){
- m_cpcd->report(m_id, CPCEvent::ET_PROC_STATE_STOPPED);
- if(m_processType == TEMPORARY){
- m_status = STOPPED;
- } else {
- start();
- }
- }
- break;
- case STOPPED:
- assert(!isRunning());
- break;
- case STOPPING:
- break;
- }
-}
-
-bool
-CPCD::Process::isRunning() {
-
- if(m_pid <= 1){
- //logger.critical("isRunning(%d) invalid pid: %d", m_id, m_pid);
- return false;
- }
- /* Check if there actually exists a process with such a pid */
- errno = 0;
- int s = kill((pid_t)-m_pid, 0); /* Sending "signal" 0 to a process only
- * checkes if the process actually exists */
- if(s != 0) {
- switch(errno) {
- case EPERM:
- logger.critical("Not enough privileges to control pid %d\n", m_pid);
- break;
- case ESRCH:
- /* The pid in the file does not exist, which probably means that it
- has died, or the file contains garbage for some other reason */
- break;
- default:
- logger.critical("Cannot not control pid %d: %s\n", m_pid, strerror(errno));
- break;
- }
- return false;
- }
- return true;
-}
-
-int
-CPCD::Process::readPid() {
- if(m_pid != -1){
- logger.critical("Reading pid while != -1(%d)", m_pid);
- return m_pid;
- }
-
- char filename[PATH_MAX*2+1];
- char buf[1024];
- FILE *f;
-
- memset(buf, 0, sizeof(buf));
-
- BaseString::snprintf(filename, sizeof(filename), "%d", m_id);
-
- f = fopen(filename, "r");
-
- if(f == NULL){
- return -1; /* File didn't exist */
- }
-
- errno = 0;
- size_t r = fread(buf, 1, sizeof(buf), f);
- fclose(f);
- if(r > 0)
- m_pid = strtol(buf, (char **)NULL, 0);
-
- if(errno == 0){
- return m_pid;
- }
-
- return -1;
-}
-
-int
-CPCD::Process::writePid(int pid) {
- char tmpfilename[PATH_MAX+1+4+8];
- char filename[PATH_MAX*2+1];
- FILE *f;
-
- BaseString::snprintf(tmpfilename, sizeof(tmpfilename), "tmp.XXXXXX");
- BaseString::snprintf(filename, sizeof(filename), "%d", m_id);
-
- int fd = mkstemp(tmpfilename);
- if(fd < 0) {
- logger.error("Cannot open `%s': %s\n", tmpfilename, strerror(errno));
- return -1; /* Couldn't open file */
- }
-
- f = fdopen(fd, "w");
-
- if(f == NULL) {
- logger.error("Cannot open `%s': %s\n", tmpfilename, strerror(errno));
- return -1; /* Couldn't open file */
- }
-
- fprintf(f, "%d", pid);
- fclose(f);
-
- if(rename(tmpfilename, filename) == -1){
- logger.error("Unable to rename from %s to %s", tmpfilename, filename);
- return -1;
- }
- return 0;
-}
-
-static void
-setup_environment(const char *env) {
- char **p;
- p = BaseString::argify("", env);
- for(int i = 0; p[i] != NULL; i++){
- /*int res = */ putenv(p[i]);
- }
-}
-
-static
-int
-set_ulimit(const BaseString & pair){
-#ifdef HAVE_GETRLIMIT
- errno = 0;
- Vector<BaseString> list;
- pair.split(list, ":");
- if(list.size() != 2){
- logger.error("Unable to process ulimit: split >%s< list.size()=%d",
- pair.c_str(), list.size());
- return -1;
- }
-
- int res;
- rlim_t value = RLIM_INFINITY;
- if(!(list[1].trim() == "unlimited")){
- value = atoi(list[1].c_str());
- }
-
- struct rlimit rlp;
-#define _RLIMIT_FIX(x) { res = getrlimit(x,&rlp); if(!res){ rlp.rlim_cur = value; res = setrlimit(x, &rlp); }}
-
- if(list[0].trim() == "c"){
- _RLIMIT_FIX(RLIMIT_CORE);
- } else if(list[0] == "d"){
- _RLIMIT_FIX(RLIMIT_DATA);
- } else if(list[0] == "f"){
- _RLIMIT_FIX(RLIMIT_FSIZE);
- } else if(list[0] == "n"){
- _RLIMIT_FIX(RLIMIT_NOFILE);
- } else if(list[0] == "s"){
- _RLIMIT_FIX(RLIMIT_STACK);
- } else if(list[0] == "t"){
- _RLIMIT_FIX(RLIMIT_CPU);
- } else {
- res= -11;
- errno = EINVAL;
- }
- if(res){
- logger.error("Unable to process ulimit: %s res=%d error=%d(%s)",
- pair.c_str(), res, errno, strerror(errno));
- return -1;
- }
-#endif
- return 0;
-}
-
-void
-CPCD::Process::do_exec() {
- size_t i;
- setup_environment(m_env.c_str());
-
- char **argv = BaseString::argify(m_path.c_str(), m_args.c_str());
-
- if(strlen(m_cwd.c_str()) > 0) {
- int err = chdir(m_cwd.c_str());
- if(err == -1) {
- BaseString err;
- logger.error("%s: %s\n", m_cwd.c_str(), strerror(errno));
- _exit(1);
- }
- }
-
- Vector<BaseString> ulimit;
- m_ulimit.split(ulimit);
- for(i = 0; i<ulimit.size(); i++){
- if(ulimit[i].trim().length() > 0 && set_ulimit(ulimit[i]) != 0){
- _exit(1);
- }
- }
-
- int fd = open("/dev/null", O_RDWR, 0);
- if(fd == -1) {
- logger.error("Cannot open `/dev/null': %s\n", strerror(errno));
- _exit(1);
- }
-
- BaseString * redirects[] = { &m_stdin, &m_stdout, &m_stderr };
- int fds[3];
- for(i = 0; i<3; i++){
- if(redirects[i]->empty()){
-#ifndef DEBUG
- dup2(fd, i);
-#endif
- continue;
- }
-
- if((* redirects[i]) == "2>&1" && i == 2){
- dup2(fds[1], 2);
- continue;
- }
-
- /**
- * Make file
- */
- int flags = 0;
- int mode = S_IRUSR | S_IWUSR ;
- if(i == 0){
- flags |= O_RDONLY;
- } else {
- flags |= O_WRONLY | O_CREAT | O_APPEND;
- }
- int f = fds[i]= open(redirects[i]->c_str(), flags, mode);
- if(f == -1){
- logger.error("Cannot redirect %d to/from '%s' : %s\n", i,
- redirects[i]->c_str(), strerror(errno));
- _exit(1);
- }
- dup2(f, i);
- }
-
- /* Close all filedescriptors */
- for(i = STDERR_FILENO+1; (int)i < getdtablesize(); i++)
- close(i);
-
- execv(m_path.c_str(), argv);
- /* XXX If we reach this point, an error has occurred, but it's kind of hard
- * to report it, because we've closed all files... So we should probably
- * create a new logger here */
- logger.error("Exec failed: %s\n", strerror(errno));
- /* NOTREACHED */
-}
-
-int
-CPCD::Process::start() {
- /* We need to fork() twice, so that the second child (grandchild?) can
- * become a daemon. The original child then writes the pid file,
- * so that the monitor knows the pid of the new process, and then
- * exit()s. That way, the monitor process can pickup the pid, and
- * the running process is a daemon.
- *
- * This is a bit tricky but has the following advantages:
- * - the cpcd can die, and "reconnect" to the monitored clients
- * without restarting them.
- * - the cpcd does not have to wait() for the childs. init(1) will
- * take care of that.
- */
- logger.info("Starting %d: %s", m_id, m_name.c_str());
- m_status = STARTING;
-
- int pid = -1;
- switch(m_processType){
- case TEMPORARY:{
- /**
- * Simple fork
- * don't ignore child
- */
- switch(pid = fork()) {
- case 0: /* Child */
- setsid();
- writePid(getpgrp());
- if(runas(m_runas.c_str()) == 0){
- signal(SIGCHLD, SIG_DFL);
- do_exec();
- }
- _exit(1);
- break;
- case -1: /* Error */
- logger.error("Cannot fork: %s\n", strerror(errno));
- m_status = STOPPED;
- return -1;
- break;
- default: /* Parent */
- logger.debug("Started temporary %d : pid=%d", m_id, pid);
- m_cpcd->report(m_id, CPCEvent::ET_PROC_STATE_RUNNING);
- break;
- }
- break;
- }
- case PERMANENT:{
- /**
- * PERMANENT
- */
- switch(fork()) {
- case 0: /* Child */
- signal(SIGCHLD, SIG_IGN);
- switch(pid = fork()) {
- case 0: /* Child */
- setsid();
- writePid(getpgrp());
- if(runas(m_runas.c_str()) != 0){
- _exit(1);
- }
- signal(SIGCHLD, SIG_DFL);
- do_exec();
- _exit(1);
- /* NOTREACHED */
- break;
- case -1: /* Error */
- logger.error("Cannot fork: %s\n", strerror(errno));
- writePid(-1);
- _exit(1);
- break;
- default: /* Parent */
- logger.debug("Started permanent %d : pid=%d", m_id, pid);
- _exit(0);
- break;
- }
- break;
- case -1: /* Error */
- logger.error("Cannot fork: %s\n", strerror(errno));
- m_status = STOPPED;
- return -1;
- break;
- default: /* Parent */
- m_cpcd->report(m_id, CPCEvent::ET_PROC_STATE_RUNNING);
- break;
- }
- break;
- }
- default:
- logger.critical("Unknown process type");
- return -1;
- }
-
- while(readPid() < 0){
- sched_yield();
- }
-
- errno = 0;
- pid_t pgid = getpgid(pid);
-
- if(pgid != -1 && pgid != m_pid){
- logger.error("pgid and m_pid don't match: %d %d (%d)", pgid, m_pid, pid);
- }
-
- if(isRunning()){
- m_status = RUNNING;
- return 0;
- }
- m_status = STOPPED;
- return -1;
-}
-
-void
-CPCD::Process::stop() {
-
- char filename[PATH_MAX*2+1];
- BaseString::snprintf(filename, sizeof(filename), "%d", m_id);
- unlink(filename);
-
- if(m_pid <= 1){
- logger.critical("Stopping process with bogus pid: %d id: %d",
- m_pid, m_id);
- return;
- }
- m_status = STOPPING;
-
- errno = 0;
- int signo= SIGTERM;
- if(m_shutdown_options == "SIGKILL")
- signo= SIGKILL;
-
- int ret = kill(-m_pid, signo);
- switch(ret) {
- case 0:
- logger.debug("Sent SIGTERM to pid %d", (int)-m_pid);
- break;
- default:
- logger.debug("kill pid: %d : %s", (int)-m_pid, strerror(errno));
- break;
- }
-
- if(isRunning()){
- errno = 0;
- ret = kill(-m_pid, SIGKILL);
- switch(ret) {
- case 0:
- logger.debug("Sent SIGKILL to pid %d", (int)-m_pid);
- break;
- default:
- logger.debug("kill pid: %d : %s\n", (int)-m_pid, strerror(errno));
- break;
- }
- }
-
- m_pid = -1;
- m_status = STOPPED;
-}
diff --git a/storage/ndb/src/cw/cpcd/common.cpp b/storage/ndb/src/cw/cpcd/common.cpp
deleted file mode 100644
index 1a799bc2bd5..00000000000
--- a/storage/ndb/src/cw/cpcd/common.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "common.hpp"
-#include <logger/Logger.hpp>
-#include <pwd.h>
-
-#include <Properties.hpp>
-#include <BaseString.hpp>
-
-int debug = 0;
-
-Logger logger;
-
-int
-runas(const char * user){
- if(user == 0 || strlen(user) == 0){
- return 0;
- }
- struct passwd * pw = getpwnam(user);
- if(pw == 0){
- logger.error("Can't find user to %s", user);
- return -1;
- }
- uid_t uid = pw->pw_uid;
- gid_t gid = pw->pw_gid;
- int res = setgid(gid);
- if(res != 0){
- logger.error("Can't change group to %s(%d)", user, gid);
- return res;
- }
-
- res = setuid(uid);
- if(res != 0){
- logger.error("Can't change user to %s(%d)", user, uid);
- }
- return res;
-}
-
-int
-insert(const char * pair, Properties & p){
- BaseString tmp(pair);
-
- tmp.trim(" \t\n\r");
-
- Vector<BaseString> split;
- tmp.split(split, ":=", 2);
-
- if(split.size() != 2)
- return -1;
-
- p.put(split[0].trim().c_str(), split[1].trim().c_str());
-
- return 0;
-}
-
-int
-insert_file(FILE * f, class Properties& p, bool break_on_empty){
- if(f == 0)
- return -1;
-
- while(!feof(f)){
- char buf[1024];
- fgets(buf, 1024, f);
- BaseString tmp = buf;
-
- if(tmp.length() > 0 && tmp.c_str()[0] == '#')
- continue;
-
- if(insert(tmp.c_str(), p) != 0 && break_on_empty)
- break;
- }
-
- return 0;
-}
-
-int
-insert_file(const char * filename, class Properties& p){
- FILE * f = fopen(filename, "r");
- int res = insert_file(f, p);
- if(f) fclose(f);
- return res;
-}
diff --git a/storage/ndb/src/cw/cpcd/common.hpp b/storage/ndb/src/cw/cpcd/common.hpp
deleted file mode 100644
index eb984696f00..00000000000
--- a/storage/ndb/src/cw/cpcd/common.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __CPCD_COMMON_HPP_INCLUDED__
-#define __CPCD_COMMON_HPP_INCLUDED__
-
-#include <ndb_global.h>
-#include <logger/Logger.hpp>
-#if 0
-#include <getarg.h>
-#endif
-
-extern int debug;
-
-extern Logger logger;
-
-int runas(const char * user);
-int insert(const char * pair, class Properties & p);
-
-int insert_file(const char * filename, class Properties&);
-int insert_file(FILE *, class Properties&, bool break_on_empty = false);
-
-#endif /* ! __CPCD_COMMON_HPP_INCLUDED__ */
diff --git a/storage/ndb/src/cw/cpcd/main.cpp b/storage/ndb/src/cw/cpcd/main.cpp
deleted file mode 100644
index c90d0f43f1b..00000000000
--- a/storage/ndb/src/cw/cpcd/main.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h> /* Needed for mkdir(2) */
-#include <my_sys.h>
-#include <my_getopt.h>
-#include <mysql_version.h>
-#include <ndb_version.h>
-
-#include "CPCD.hpp"
-#include "APIService.hpp"
-#include <NdbMain.h>
-#include <NdbSleep.h>
-#include <BaseString.hpp>
-#include <logger/Logger.hpp>
-#include <logger/FileLogHandler.hpp>
-#include <logger/SysLogHandler.hpp>
-
-#include "common.hpp"
-
-static const char *work_dir = CPCD_DEFAULT_WORK_DIR;
-static int unsigned port;
-static int use_syslog;
-static const char *logfile = NULL;
-static const char *user = 0;
-
-static struct my_option my_long_options[] =
-{
- { "work-dir", 'w', "Work directory",
- &work_dir, &work_dir, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "port", 'p', "TCP port to listen on",
- &port, &port, 0,
- GET_INT, REQUIRED_ARG, CPCD_DEFAULT_TCP_PORT, 0, 0, 0, 0, 0 },
- { "syslog", 'S', "Log events to syslog",
- &use_syslog, &use_syslog, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "logfile", 'L', "File to log events to",
- &logfile, &logfile, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "debug", 'D', "Enable debug mode",
- &debug, &debug, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "user", 'u', "Run as user",
- &user, &user, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-static my_bool
-get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
- char *argument)
-{
- return 0;
-}
-
-static CPCD * g_cpcd = 0;
-#if 0
-extern "C" static void sig_child(int signo, siginfo_t*, void*);
-#endif
-
-const char *progname = "ndb_cpcd";
-
-int main(int argc, char** argv){
- const char *load_default_groups[]= { "ndb_cpcd",0 };
- MY_INIT(argv[0]);
-
- load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
- if (handle_options(&argc, &argv, my_long_options, get_one_option)) {
- print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
- puts("");
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
- exit(1);
- }
-
- logger.setCategory(progname);
- logger.enable(Logger::LL_ALL);
-
- if(debug)
- logger.createConsoleHandler();
-
- if(user && runas(user) != 0){
- logger.critical("Unable to change user: %s", user);
- _exit(1);
- }
-
- if(logfile != NULL){
- BaseString tmp;
- if(logfile[0] != '/')
- tmp.append(work_dir);
- tmp.append(logfile);
- logger.addHandler(new FileLogHandler(tmp.c_str()));
- }
-
- if(use_syslog)
- logger.addHandler(new SysLogHandler());
-
- logger.info("Starting");
-
- CPCD cpcd;
- g_cpcd = &cpcd;
-
- /* XXX This will probably not work on !unix */
- int err = mkdir(work_dir, S_IRWXU | S_IRGRP | S_IROTH);
- if(err != 0) {
- switch(errno) {
- case EEXIST:
- break;
- default:
- fprintf(stderr, "Cannot mkdir %s: %s\n", work_dir, strerror(errno));
- exit(1);
- }
- }
-
- if(strlen(work_dir) > 0){
- logger.debug("Changing dir to '%s'", work_dir);
- if((err = chdir(work_dir)) != 0){
- fprintf(stderr, "Cannot chdir %s: %s\n", work_dir, strerror(errno));
- exit(1);
- }
- }
-
- cpcd.loadProcessList();
-
- SocketServer * ss = new SocketServer();
- CPCDAPIService * serv = new CPCDAPIService(cpcd);
- unsigned short real_port= port; // correct type
- if(!ss->setup(serv, &real_port)){
- logger.critical("Cannot setup server: %s", strerror(errno));
- sleep(1);
- delete ss;
- delete serv;
- return 1;
- }
-
- ss->startServer();
-
- {
- signal(SIGPIPE, SIG_IGN);
- signal(SIGCHLD, SIG_IGN);
-#if 0
- struct sigaction act;
- act.sa_handler = 0;
- act.sa_sigaction = sig_child;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- sigaction(SIGCHLD, &act, 0);
-#endif
- }
-
- logger.debug("Start completed");
- while(true) NdbSleep_MilliSleep(1000);
-
- delete ss;
- return 0;
-}
-
-#if 0
-extern "C"
-void
-sig_child(int signo, siginfo_t* info, void*){
- printf("signo: %d si_signo: %d si_errno: %d si_code: %d si_pid: %d\n",
- signo,
- info->si_signo,
- info->si_errno,
- info->si_code,
- info->si_pid);
-
-}
-#endif
diff --git a/storage/ndb/src/cw/test/socketclient/Makefile b/storage/ndb/src/cw/test/socketclient/Makefile
deleted file mode 100644
index 04f11f031e5..00000000000
--- a/storage/ndb/src/cw/test/socketclient/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-include .defs.mk
-
-TYPE :=
-
-BIN_TARGET := socketclient
-
-
-
-CCFLAGS_LOC += -I../../util/ -I../../cpcd/
-
-LIBS_LOC += -L$(NDB_TOP)/lib/ -L$(EXTERNAL_LIB_DIR)/sci
-
-LIBS_SPEC += -lsocketclient
-
-
-SOURCES = socketClientTest.cpp
-
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-
-
-
diff --git a/storage/ndb/src/cw/test/socketclient/socketClientTest.cpp b/storage/ndb/src/cw/test/socketclient/socketClientTest.cpp
deleted file mode 100644
index 6b17d072f64..00000000000
--- a/storage/ndb/src/cw/test/socketclient/socketClientTest.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include <socket_io.h>
-#include <NdbTick.h>
-#include <NdbMain.h>
-#include <NdbSleep.h>
-#include "SocketService.hpp"
-#include "SocketRegistry.hpp"
-#include "SocketClient.hpp"
-#include "ClientInterface.hpp"
-
-#include <InputStream.hpp>
-
-#include <Parser.hpp>
-
-NDB_MAIN(socketclient) {
-
-
- if(argc<3) {
- printf("wrong args: socketclient <hostname> <port>\n");
- return 0;
- }
- const char * remotehost = argv[1];
- const int port = atoi(argv[2]);
-
-
- ClientInterface * ci = new ClientInterface(2);
- ci->connectCPCDdaemon(remotehost,port);
-
- /*ci->listProcesses(remotehost);
-
- ci->startProcess(remotehost, "1247");
-
- ci->stopProcess(remotehost, "1247");*/
-
- ci->defineProcess(remotehost, "ndb", "ndb-cluster1", "envirnm", "/ndb/bin",
- "-i", "permanent", "/ndb/ndb.2", "team");
-
- ci->startProcess(remotehost, "1247");
-
- ci->listProcesses(remotehost);
-
- //ci->undefineProcess(remotehost, "1247");
-
- ci->disconnectCPCDdaemon(remotehost);
-}
diff --git a/storage/ndb/src/cw/util/ClientInterface.cpp b/storage/ndb/src/cw/util/ClientInterface.cpp
deleted file mode 100644
index 725a9d47d43..00000000000
--- a/storage/ndb/src/cw/util/ClientInterface.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "ClientInterface.hpp"
-
-
-
-ClientInterface::ClientInterface(Uint32 maxNoOfCPCD) {
- sr = new SocketRegistry<SocketService>(maxNoOfCPCD);
- ss = new SocketService();
-}
-
-
-ClientInterface::~ClientInterface() {
- delete sr;
- delete ss;
-
-}
-
-
-void ClientInterface::connectCPCDdaemon(const char * remotehost, Uint16 port)
-{
- sr->createSocketClient(remotehost, port);
-}
-
-void ClientInterface::disconnectCPCDdaemon(const char * remotehost)
-{
- sr->removeSocketClient(remotehost);
-}
-
-void ClientInterface::removeCPCDdaemon(const char * remotehost)
-{
- sr->removeSocketClient(remotehost);
-}
-
-void ClientInterface::startProcess(const char * remotehost, char * id) {
- char buf[255] = "start process ";
- char str[80];
- char line[10];
-
- strcpy(line, id);
- strcpy(str, "id:");
- strcat(str, line);
- strcat(str, "\n\n");
- strcat(buf, str);
- printf("Request: %s\n", buf);
-
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
-
-void ClientInterface::stopProcess(const char * remotehost, char * id) {
- char buf[255] = "stop process ";
- char str[80];
- char line[10];
-
- strcpy(line, id);
- strcpy(str, "id:");
- strcat(str, line);
- strcat(str, "\n\n");
- strcat(buf, str);
- printf("Request: %s\n", buf);
-
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
-
-void ClientInterface::defineProcess(const char * remotehost, char * name,
- char * group, char * env, char * path,
- char * args, char * type, char * cwd, char * owner){
- char buf[255] = "define process ";
- char str[80];
- char line[10];
-
- strcpy(line, name);
- strcpy(str, "name:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, group);
- strcpy(str, "group:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, env);
- strcpy(str, "env:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, path);
- strcpy(str, "path:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, args);
- strcpy(str, "args:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, type);
- strcpy(str, "type:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, cwd);
- strcpy(str, "cwd:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, " \n");
-
- strcpy(line, owner);
- strcpy(str, "owner:");
- strcat(str, line);
- strcat(buf, str);
- strcat(buf, "\n\n");
-
- printf("Request: %s\n", buf);
-
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
-
-void ClientInterface::undefineProcess(const char * remotehost, char * id){
- char buf[255] = "undefine process ";
- char str[80];
- char line[10];
-
- strcpy(line, id);
- strcpy(str, "id:");
- strcat(str, line);
- strcat(str, "\n\n");
- strcat(buf, str);
- printf("Request: %s\n", buf);
-
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
-
-void ClientInterface::listProcesses(const char * remotehost) {
- char buf[255]="list processes\n\n";
- printf("Request: %s\n", buf);
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
-
-void ClientInterface::showProcess(const char * remotehost, char * id) {
- char buf[255] = "show process ";
- char str[80];
- char line[10];
-
- strcpy(line, id);
- strcpy(str, "id:");
- strcat(str, line);
- strcat(str, "\n\n");
- strcat(buf, str);
- printf("Request: %s\n", buf);
-
- sr->performSend(buf,255,remotehost);
- sr->syncPerformReceive(remotehost, *ss, 0);
- ss->getPropertyObject();
-}
diff --git a/storage/ndb/src/cw/util/ClientInterface.hpp b/storage/ndb/src/cw/util/ClientInterface.hpp
deleted file mode 100644
index 798f9c80a3a..00000000000
--- a/storage/ndb/src/cw/util/ClientInterface.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef CLIENT_IF_HPP
-#define CLIENT_IF_HPP
-#include <ndb_global.h>
-#include <Parser.hpp>
-#include <InputStream.hpp>
-#include <Parser.hpp>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include "SocketRegistry.hpp"
-#include "SocketService.hpp"
-
-class ClientInterface {
-private:
- SocketService * ss;
- SocketRegistry<SocketService> * sr;
-
-public:
- ClientInterface(Uint32 maxNoOfCPC);
- ~ClientInterface();
- void startProcess(const char * remotehost, char * id);
- void stopProcess(const char * remotehost, char * id);
- void defineProcess(const char * remotehost, char * name, char * group,
- char * env, char * path, char * args, char * type,
- char * cwd, char * owner);
- void undefineProcess(const char * remotehost, char * id);
- void listProcesses(const char * remotehost);
- void showProcess(const char * remotehost, char * id);
- void connectCPCDdaemon(const char * remotehost, Uint16 port);
- void disconnectCPCDdaemon(const char * remotehost);
- void removeCPCDdaemon(const char * remotehost);
-
-};
-#endif
diff --git a/storage/ndb/src/cw/util/Makefile b/storage/ndb/src/cw/util/Makefile
deleted file mode 100644
index f5ab16721be..00000000000
--- a/storage/ndb/src/cw/util/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include .defs.mk
-TYPE := ndbapi
-
-PIC_ARCHIVE := Y
-ARCHIVE_TARGET := socketclient
-
-# Source files of non-templated classes (.cpp files)
-SOURCES = ClientInterface.cpp SocketService.cpp SocketClient.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/cw/util/SocketRegistry.cpp b/storage/ndb/src/cw/util/SocketRegistry.cpp
deleted file mode 100644
index 0bda227be6e..00000000000
--- a/storage/ndb/src/cw/util/SocketRegistry.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SocketRegistry.hpp"
-#include <Parser.hpp>
-
-template<class T>
-SocketRegistry<T>::SocketRegistry(Uint32 maxSocketClients) {
-
-}
-
-
-template<class T>
-SocketRegistry<T>::~SocketRegistry() {
- delete [] m_socketClients;
-}
-
-template<class T>
-bool
-SocketRegistry<T>::createSocketClient(const char * host, Uint16 port) {
-
- if(port == 0)
- return false;
- if(host==NULL)
- return false;
-
- SocketClient * socketClient = new SocketClient(host, port);
-
- if(socketClient->openSocket() < 0 || socketClient == NULL) {
- ndbout << "could not connect" << endl;
- delete socketClient;
- return false;
- }
- else {
- m_socketClients[m_nSocketClients] = socketClient;
- m_nSocketClients++;
- }
- return true;
-}
-
-template<class T>
-int
-SocketRegistry<T>::pollSocketClients(Uint32 timeOutMillis) {
-
-
-
- // Return directly if there are no TCP transporters configured
- if (m_nSocketClients == 0){
- tcpReadSelectReply = 0;
- return 0;
- }
- struct timeval timeout;
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
-
-
- NDB_SOCKET_TYPE maxSocketValue = 0;
-
- // Needed for TCP/IP connections
- // The read- and writeset are used by select
-
- FD_ZERO(&tcpReadset);
-
- // Prepare for sending and receiving
- for (Uint32 i = 0; i < m_nSocketClients; i++) {
- SocketClient * t = m_socketClients[i];
-
- // If the socketclient is connected
- if (t->isConnected()) {
-
- const NDB_SOCKET_TYPE socket = t->getSocket();
- // Find the highest socket value. It will be used by select
- if (socket > maxSocketValue)
- maxSocketValue = socket;
-
- // Put the connected transporters in the socket read-set
- FD_SET(socket, &tcpReadset);
- }
- }
-
- // The highest socket value plus one
- maxSocketValue++;
-
- tcpReadSelectReply = select(maxSocketValue, &tcpReadset, 0, 0, &timeout);
-#ifdef NDB_WIN32
- if(tcpReadSelectReply == SOCKET_ERROR)
- {
- NdbSleep_MilliSleep(timeOutMillis);
- }
-#endif
-
- return tcpReadSelectReply;
-
-}
-
-template<class T>
-bool
-SocketRegistry<T>::performSend(const char * buf,
- Uint32 len,
- const char * remotehost)
-{
- SocketClient * socketClient;
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), remotehost)==0) {
- if(socketClient->isConnected()) {
- if(socketClient->writeSocket(buf, len)>0)
- return true;
- else
- return false;
- }
- }
- }
- return false;
-}
-
-template<class T>
-int
-SocketRegistry<T>::performReceive(T & t) {
- char buf[255] ; //temp. just for testing. must fix better
-
- if(tcpReadSelectReply > 0){
- for (Uint32 i=0; i<m_nSocketClients; i++) {
- SocketClient *sc = m_socketClients[i];
- const NDB_SOCKET_TYPE socket = sc->getSocket();
- if(sc->isConnected() && FD_ISSET(socket, &tcpReadset)) {
- t->runSession(socket,t);
- }
- }
- return 1;
- }
- return 0;
-
-}
-
-
-
-template<class T>
-inline
-int
-SocketRegistry<T>::syncPerformReceive(char * host,
- T & t,
- Uint32 timeOutMillis) {
- char buf[255] ; //temp. just for testing. must fix better
- struct timeval timeout;
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
- int reply;
- SocketClient * sc;
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- sc = m_socketClients[i];
- if(strcmp(sc->gethostname(), remotehost)==0) {
- if(sc->isConnected()) {
- FD_ZERO(&tcpReadset);
- reply = select(sc->getSocket(), &tcpReadset, 0, 0, &timeout);
- if(reply > 0) {
- return t->runSession(sc->getSocket(), t);
- }
- }
-
- }
- }
- return 0;
-}
-
-
-
-template<class T>
-bool
-SocketRegistry<T>::reconnect(const char * host){
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- SocketClient * socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), host)==0) {
- if(!socketClient->isConnected()) {
- if(socketClient->openSocket() > 0)
- return true;
- else return false;
- }
- }
- }
- return false;
-}
-
-template<class T>
-bool
-SocketRegistry<T>::removeSocketClient(const char * host){
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- SocketClient * socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), host)==0) {
- if(!socketClient->isConnected()) {
- if(socketClient->closeSocket() > 0) {
- delete socketClient;
- return true;
- }
- else return false;
- }
- }
- }
- return false;
-}
diff --git a/storage/ndb/src/cw/util/SocketRegistry.hpp b/storage/ndb/src/cw/util/SocketRegistry.hpp
deleted file mode 100644
index 9e1b737f224..00000000000
--- a/storage/ndb/src/cw/util/SocketRegistry.hpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SocketClientRegistry_H
-#define SocketClientRegistry_H
-
-#include <NdbTCP.h>
-#include <NdbOut.hpp>
-
-#include "SocketClient.hpp"
-
-template<class T>
-class SocketRegistry {
-
-public:
- SocketRegistry(Uint32 maxSocketClients);
- ~SocketRegistry();
- /**
- * creates and adds a SocketClient to m_socketClients[]
- * @param host - host name
- * @param port - port to connect to
- */
- bool createSocketClient(const char * host, const Uint16 port);
-
- /**
- * performReceive reads from sockets should do more stuff
- */
- int performReceive(T &);
-
-
- /**
- * performReceive reads from sockets should do more stuff
- */
- int syncPerformReceive(const char* ,T &, Uint32);
-
-
- /**
- * performSend sends a command to a host
- */
- bool performSend(const char * buf, Uint32 len, const char * remotehost);
-
- /**
- * pollSocketClients performs a select (for a max. of timeoutmillis) or
- * until there is data to be read from any SocketClient
- * @param timeOutMillis - select timeout
- */
- int pollSocketClients(Uint32 timeOutMillis);
-
- /**
- * reconnect tries to reconnect to a cpcd given its hostname
- * @param host - name of host to reconnect to.
- */
- bool reconnect(const char * host);
-
-
- /**
- * removeSocketClient
- * @param host - name of host for which to remove the SocketConnection
- */
- bool removeSocketClient(const char * host);
-
-private:
- SocketClient** m_socketClients;
- Uint32 m_maxSocketClients;
- Uint32 m_nSocketClients;
- int tcpReadSelectReply;
- fd_set tcpReadset;
-
-
-};
-
-
-template<class T>
-inline
-SocketRegistry<T>::SocketRegistry(Uint32 maxSocketClients) {
- m_maxSocketClients = maxSocketClients;
- m_socketClients = new SocketClient * [m_maxSocketClients];
- m_nSocketClients = 0;
-}
-
-
-template<class T>
-inline
-SocketRegistry<T>::~SocketRegistry() {
- delete [] m_socketClients;
-}
-
-template<class T>
-inline
-bool
-SocketRegistry<T>::createSocketClient(const char * host, Uint16 port) {
-
- if(port == 0)
- return false;
- if(host==NULL)
- return false;
-
- SocketClient * socketClient = new SocketClient(host, port);
-
- if(socketClient->openSocket() < 0 || socketClient == NULL) {
- ndbout << "could not connect" << endl;
- delete socketClient;
- return false;
- }
- else {
- m_socketClients[m_nSocketClients] = socketClient;
- m_nSocketClients++;
- }
- return true;
-}
-
-template<class T>
-inline
-int
-SocketRegistry<T>::pollSocketClients(Uint32 timeOutMillis) {
-
-
-
- // Return directly if there are no TCP transporters configured
- if (m_nSocketClients == 0){
- tcpReadSelectReply = 0;
- return 0;
- }
- struct timeval timeout;
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
-
-
- NDB_SOCKET_TYPE maxSocketValue = 0;
-
- // Needed for TCP/IP connections
- // The read- and writeset are used by select
-
- FD_ZERO(&tcpReadset);
-
- // Prepare for sending and receiving
- for (Uint32 i = 0; i < m_nSocketClients; i++) {
- SocketClient * t = m_socketClients[i];
-
- // If the socketclient is connected
- if (t->isConnected()) {
-
- const NDB_SOCKET_TYPE socket = t->getSocket();
- // Find the highest socket value. It will be used by select
- if (socket > maxSocketValue)
- maxSocketValue = socket;
-
- // Put the connected transporters in the socket read-set
- FD_SET(socket, &tcpReadset);
- }
- }
-
- // The highest socket value plus one
- maxSocketValue++;
-
- tcpReadSelectReply = select(maxSocketValue, &tcpReadset, 0, 0, &timeout);
-#ifdef NDB_WIN32
- if(tcpReadSelectReply == SOCKET_ERROR)
- {
- NdbSleep_MilliSleep(timeOutMillis);
- }
-#endif
-
- return tcpReadSelectReply;
-
-}
-
-template<class T>
-inline
-bool
-SocketRegistry<T>::performSend(const char * buf, Uint32 len, const char * remotehost)
-{
- SocketClient * socketClient;
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), remotehost)==0) {
- if(socketClient->isConnected()) {
- if(socketClient->writeSocket(buf, len)>0)
- return true;
- else
- return false;
- }
- }
- }
- return false;
-}
-
-template<class T>
-inline
-int
-SocketRegistry<T>::performReceive(T & t) {
- char buf[255] ; //temp. just for testing. must fix better
-
- if(tcpReadSelectReply > 0){
- for (Uint32 i=0; i<m_nSocketClients; i++) {
- SocketClient *sc = m_socketClients[i];
- const NDB_SOCKET_TYPE socket = sc->getSocket();
- if(sc->isConnected() && FD_ISSET(socket, &tcpReadset)) {
- t->runSession(socket,t);
- }
- }
- return 1;
- }
- return 0;
-
-}
-
-
-
-template<class T>
-inline
-int
-SocketRegistry<T>::syncPerformReceive(const char * remotehost,
- T & t,
- Uint32 timeOutMillis) {
- char buf[255] ; //temp. just for testing. must fix better
- struct timeval timeout;
- timeout.tv_sec = timeOutMillis / 1000;
- timeout.tv_usec = (timeOutMillis % 1000) * 1000;
- int reply;
- SocketClient * sc;
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- sc = m_socketClients[i];
- if(strcmp(sc->gethostname(), remotehost)==0) {
- if(sc->isConnected()) {
- /*FD_ZERO(&tcpReadset);
- reply = select(sc->getSocket()+1, 0, 0, 0, &timeout);
- reply=1;
- if(reply > 0) {*/
- t.runSession(sc->getSocket(), t);
- //}
- }
-
- }
- }
-}
-
-
-
-template<class T>
-inline
-bool
-SocketRegistry<T>::reconnect(const char * host){
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- SocketClient * socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), host)==0) {
- if(!socketClient->isConnected()) {
- if(socketClient->openSocket() > 0)
- return true;
- else return false;
- }
- }
- }
- return false;
-}
-
-template<class T>
-inline
-bool
-SocketRegistry<T>::removeSocketClient(const char * host){
- for(Uint32 i=0; i < m_nSocketClients; i++) {
- SocketClient * socketClient = m_socketClients[i];
- if(strcmp(socketClient->gethostname(), host)==0) {
- if(!socketClient->isConnected()) {
- if(socketClient->closeSocket() > 0) {
- delete socketClient;
- return true;
- }
- else return false;
- }
- }
- }
- return false;
-}
-
-
-#endif // Define of SocketRegistry
diff --git a/storage/ndb/src/cw/util/SocketService.cpp b/storage/ndb/src/cw/util/SocketService.cpp
deleted file mode 100644
index ee64f3bc4f1..00000000000
--- a/storage/ndb/src/cw/util/SocketService.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <Parser.hpp>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include "SocketService.hpp"
-
-SocketService::SocketService() {
-
-}
-
-SocketService::~SocketService() {
-
-}
-
-int
-SocketService::runSession(NDB_SOCKET_TYPE socket, SocketService & ss){
- InputStream *m_input = new SocketInputStream(socket);
- char buf[255];
-
- m_input->gets(buf,255);
- ndbout_c("SocketService:received: %s\n", buf);
- ndbout_c("This should now be parsed\n");
- ndbout_c("and put in a property object.\n");
- ndbout_c("The propery is then accessible from the ClientInterface.\n");
- ndbout_c("by getPropertyObject.\n");
- ndbout_c("At least this is the idea.");
- /*Parser_t *m_parser =
- new Parser<SocketService>(commands, *m_input, true, true, true);
- */
- /** to do
- * add a proprty object to which the parser will put its result.
- */
-
- return 1 ; //succesful
- //return 0; //unsuccesful
-
-}
-
-void
-SocketService::getPropertyObject() {
- ndbout << "get property object. return to front end or something" << endl;
-}
-
-
diff --git a/storage/ndb/src/cw/util/SocketService.hpp b/storage/ndb/src/cw/util/SocketService.hpp
deleted file mode 100644
index 5a860f3aee1..00000000000
--- a/storage/ndb/src/cw/util/SocketService.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SOCKET_SERVICE_HPP
-#define SOCKET_SERVICE_HPP
-#include <Parser.hpp>
-#include <InputStream.hpp>
-#include <Parser.hpp>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include "SocketRegistry.hpp"
-
-
-
-
-class SocketService {
- friend class SocketRegistry<SocketService>;
-private:
- typedef Parser<SocketService> Parser_t;
- int runSession(NDB_SOCKET_TYPE socket, SocketService &);
-public:
- void getPropertyObject();
- SocketService();
- ~SocketService();
-
-};
-
-
-
-
-
-
-#endif
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/SISCI_LIBRARY_WIN32.TXT b/storage/ndb/src/external/WIN32.x86/sci/lib/SISCI_LIBRARY_WIN32.TXT
deleted file mode 100644
index 97fe959bb2c..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/SISCI_LIBRARY_WIN32.TXT
+++ /dev/null
@@ -1,77 +0,0 @@
-SISCI_API LIBRARIES AND LINKING
-===============================
-
-
-/MD, /ML, /MT (Use Run-Time Library)
-
-
-
-sisci_api.lib - Single threaded
-
-sisci_api_md.lib - Multithreaded DLL
-
-sisci_api_mt.lib - Multithreaded
-
-
-
-
-With these libraries, you can select either single-threaded or multithreaded run-time routines,
-indicate that a multithreaded module is a dynamic-link library (DLL), and select the retail
-or debug version of the library.
-
-Note Having more than one copy of the run-time libraries in a process can cause problems,
-because static data in one copy is not shared with the other copy. To ensure that your process
-contains only one copy, avoid mixing static and dynamic versions of the run-time libraries.
-The linker will prevent you from linking with both static and dynamic versions within one .EXE file,
-but you can still end up with two (or more) copies of the run-time libraries.
-For example, a dynamic-link library linked with the static (non-DLL) versions of the run-time
-libraries can cause problems when used with an .EXE file that was linked with the dynamic (DLL)
-version of the run-time libraries. (You should also avoid mixing the debug and non-debug versions
-of the libraries in one process.)
-
-
-MD Multithreaded
-----------------
-
-/MD Multithreaded DLL Defines _MT and _DLL so that both multithread- and DLL-specific versions
-of the run-time routines are selected from the standard .H files. This option also causes the
-compiler to place the library name MSVCRT.LIB into the .OBJ file.
-Applications compiled with this option are statically linked to MSVCRT.LIB. This library provides
-a layer of code that allows the linker to resolve external references. The actual working code is
-contained in MSVCRT.DLL, which must be available at run time to applications linked with MSVCRT.LIB.
-
-
-/MDd Debug Multithreaded DLL Defines _DEBUG, _MT, and _DLL so that debug multithread- and DLL-specific
-versions of the run-time routines are selected from the standard .H files. It also causes the compiler
-to place the library name MSVCRTD.LIB into the .OBJ file.
-
-
-ML Single-Threaded
-------------------
-
-
-/ML Single-Threaded Causes the compiler to place the library name LIBC.LIB into the .OBJ file so
-that the linker will use LIBC.LIB to resolve external symbols. This is the compiler’s default action.
-LIBC.LIB does not provide multithread support.
-
-
-/MLd Debug Single-Threaded Defines _DEBUG and causes the compiler to place the library name LIBCD.LIB
-into the .OBJ file so that the linker will use LIBCD.LIB to resolve external symbols. LIBCD.LIB does
-not provide multithread support.
-
-
-MT Multithreaded
-----------------
-
-
-/MT Multithreaded Defines _MT so that multithread-specific versions of the run-time routines are
-selected from the standard header (.H) files. This option also causes the compiler to place the library
-name LIBCMT.LIB into the .OBJ file so that the linker will use LIBCMT.LIB to resolve external symbols.
-
-Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
-/MTd Debug Multithreaded Defines _DEBUG and _MT. Defining _MT causes multithread-specific versions of
-the run-time routines to be selected from the standard .H files. This option also causes the compiler
-to place the library name LIBCMTD.LIB into the .OBJ file so that the linker will use LIBCMTD.LIB to
-resolve external symbols. Either /MTd or /MDd (or their non-debug equivalents /MT or MD) is required to
-create multithreaded programs.
-
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/scilib.lib
deleted file mode 100644
index 572169a2016..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_md.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_md.lib
deleted file mode 100644
index f18cba61336..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_md.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_mt.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_mt.lib
deleted file mode 100644
index 3e9982468ea..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/scilib_mt.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api.lib
deleted file mode 100644
index 3fbff6ec809..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_md.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_md.lib
deleted file mode 100644
index 1d8d42d1d35..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_md.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_mt.lib b/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_mt.lib
deleted file mode 100644
index 017fad7ba31..00000000000
--- a/storage/ndb/src/external/WIN32.x86/sci/lib/sisci_api_mt.lib
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/kernel/Makefile.am b/storage/ndb/src/kernel/Makefile.am
deleted file mode 100644
index 7652c5f3ade..00000000000
--- a/storage/ndb/src/kernel/Makefile.am
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2004-2006 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = vm error blocks
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-
-ndbbin_PROGRAMS = ndbd
-
-ndbd_SOURCES = main.cpp SimBlockList.cpp
-
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-INCLUDES += \
- -I$(srcdir)/blocks/cmvmi \
- -I$(srcdir)/blocks/dbacc \
- -I$(srcdir)/blocks/dbdict \
- -I$(srcdir)/blocks/dbdih \
- -I$(srcdir)/blocks/dblqh \
- -I$(srcdir)/blocks/dbtc \
- -I$(srcdir)/blocks/dbtup \
- -I$(srcdir)/blocks/ndbfs \
- -I$(srcdir)/blocks/ndbcntr \
- -I$(srcdir)/blocks/qmgr \
- -I$(srcdir)/blocks/trix \
- -I$(srcdir)/blocks/backup \
- -I$(srcdir)/blocks/dbutil \
- -I$(srcdir)/blocks/suma \
- -I$(srcdir)/blocks/dbtux \
- -I$(srcdir)/blocks
-
-LDADD += \
- blocks/libblocks.a \
- vm/libkernel.a \
- error/liberror.a \
- $(top_builddir)/storage/ndb/src/common/transporter/libtransporter.la \
- $(top_builddir)/storage/ndb/src/common/debugger/libtrace.la \
- $(top_builddir)/storage/ndb/src/common/debugger/signaldata/libsignaldataprint.la \
- $(top_builddir)/storage/ndb/src/common/logger/liblogger.la \
- $(top_builddir)/storage/ndb/src/common/mgmcommon/libmgmsrvcommon.la \
- $(top_builddir)/storage/ndb/src/mgmapi/libmgmapi.la \
- $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
- $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
-
-windoze-dsp: ndbd.dsp
-
-storage/ndbd.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-prg.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndbd_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
diff --git a/storage/ndb/src/kernel/SimBlockList.cpp b/storage/ndb/src/kernel/SimBlockList.cpp
deleted file mode 100644
index 68c0b4a4642..00000000000
--- a/storage/ndb/src/kernel/SimBlockList.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SimBlockList.hpp"
-#include <Emulator.hpp>
-#include <SimulatedBlock.hpp>
-#include <Cmvmi.hpp>
-#include <Ndbfs.hpp>
-#include <Dbacc.hpp>
-#include <Dbdict.hpp>
-#include <Dbdih.hpp>
-#include <Dblqh.hpp>
-#include <Dbtc.hpp>
-#include <Dbtup.hpp>
-#include <Ndbcntr.hpp>
-#include <Qmgr.hpp>
-#include <Trix.hpp>
-#include <Backup.hpp>
-#include <DbUtil.hpp>
-#include <Suma.hpp>
-#include <Dbtux.hpp>
-#include <tsman.hpp>
-#include <lgman.hpp>
-#include <pgman.hpp>
-#include <restore.hpp>
-#include <NdbEnv.h>
-
-#ifndef VM_TRACE
-#define NEW_BLOCK(B) new B
-#else
-enum SIMBLOCKLIST_DUMMY { A_VALUE = 0 };
-
-void * operator new (size_t sz, SIMBLOCKLIST_DUMMY dummy){
- char * tmp = (char *)malloc(sz);
-
-#ifndef NDB_PURIFY
-#ifdef VM_TRACE
- const int initValue = 0xf3;
-#else
- const int initValue = 0x0;
-#endif
-
- const int p = (sz / 4096);
- const int r = (sz % 4096);
-
- for(int i = 0; i<p; i++)
- memset(tmp+(i*4096), initValue, 4096);
-
- if(r > 0)
- memset(tmp+p*4096, initValue, r);
-
-#endif
-
- return tmp;
-}
-#define NEW_BLOCK(B) new(A_VALUE) B
-#endif
-
-void
-SimBlockList::load(EmulatorData& data){
- noOfBlocks = NO_OF_BLOCKS;
- theList = new SimulatedBlock * [noOfBlocks];
- Dbdict* dbdict = 0;
- Dbdih* dbdih = 0;
- Pgman* pg = 0;
- Lgman* lg = 0;
- Tsman* ts = 0;
-
- Block_context ctx(*data.theConfiguration, *data.m_mem_manager);
-
- SimulatedBlock * fs = 0;
- {
- Uint32 dl;
- const ndb_mgm_configuration_iterator * p =
- ctx.m_config.getOwnConfigIterator();
- if(p && !ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl){
- fs = NEW_BLOCK(VoidFs)(ctx);
- } else {
- fs = NEW_BLOCK(Ndbfs)(ctx);
- }
- }
-
- theList[0] = pg = NEW_BLOCK(Pgman)(ctx);
- theList[1] = lg = NEW_BLOCK(Lgman)(ctx);
- theList[2] = ts = NEW_BLOCK(Tsman)(ctx, pg, lg);
- theList[3] = NEW_BLOCK(Dbacc)(ctx);
- theList[4] = NEW_BLOCK(Cmvmi)(ctx);
- theList[5] = fs;
- theList[6] = dbdict = NEW_BLOCK(Dbdict)(ctx);
- theList[7] = dbdih = NEW_BLOCK(Dbdih)(ctx);
- theList[8] = NEW_BLOCK(Dblqh)(ctx);
- theList[9] = NEW_BLOCK(Dbtc)(ctx);
- theList[10] = NEW_BLOCK(Dbtup)(ctx, pg);
- theList[11] = NEW_BLOCK(Ndbcntr)(ctx);
- theList[12] = NEW_BLOCK(Qmgr)(ctx);
- theList[13] = NEW_BLOCK(Trix)(ctx);
- theList[14] = NEW_BLOCK(Backup)(ctx);
- theList[15] = NEW_BLOCK(DbUtil)(ctx);
- theList[16] = NEW_BLOCK(Suma)(ctx);
- theList[17] = NEW_BLOCK(Dbtux)(ctx);
- theList[18] = NEW_BLOCK(Restore)(ctx);
- assert(NO_OF_BLOCKS == 19);
-}
-
-void
-SimBlockList::unload(){
- if(theList != 0){
- for(int i = 0; i<noOfBlocks; i++){
- if(theList[i] != 0){
-#ifdef VM_TRACE
- theList[i]->~SimulatedBlock();
- free(theList[i]);
-#else
- delete(theList[i]);
-#endif
- theList[i] = 0;
- }
- }
- delete [] theList;
- theList = 0;
- noOfBlocks = 0;
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/ERROR_codes.txt b/storage/ndb/src/kernel/blocks/ERROR_codes.txt
deleted file mode 100644
index 150400b9deb..00000000000
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt
+++ /dev/null
@@ -1,565 +0,0 @@
-Next QMGR 1
-Next NDBCNTR 1002
-Next NDBFS 2000
-Next DBACC 3002
-Next DBTUP 4029
-Next DBLQH 5050
-Next DBDICT 6008
-Next DBDIH 7195
-Next DBTC 8058
-Next CMVMI 9000
-Next BACKUP 10038
-Next DBUTIL 11002
-Next DBTUX 12008
-Next SUMA 13034
-Next SUMA 13036
-Next LGMAN 15001
-Next TSMAN 16001
-
-TESTING NODE FAILURE, ARBITRATION
----------------------------------
-
-911 - 919:
-Crash president when he starts to run in ArbitState 1-9.
-
-910: Crash new president after node crash
-
-934 : Crash president in ALLOC_NODE_ID_REQ
-
-935 : Crash master on node failure (delayed)
- and skip sending GSN_COMMIT_FAILREQ to specified node
-
-ERROR CODES FOR TESTING NODE FAILURE, GLOBAL CHECKPOINT HANDLING:
------------------------------------------------------------------
-
-7000:
-Insert system error in master when global checkpoint is idle.
-
-7001:
-Insert system error in master after receiving GCP_PREPARE from
-all nodes in the cluster.
-
-7002:
-Insert system error in master after receiving GCP_NODEFINISH from
-all nodes in the cluster.
-
-7003:
-Insert system error in master after receiving GCP_SAVECONF from
-all nodes in the cluster.
-
-7004:
-Insert system error in master after completing global checkpoint with
-all nodes in the cluster.
-
-7005:
-Insert system error in GCP participant when receiving GCP_PREPARE.
-
-7006:
-Insert system error in GCP participant when receiving GCP_COMMIT.
-
-7007:
-Insert system error in GCP participant when receiving GCP_TCFINISHED.
-
-7008:
-Insert system error in GCP participant when receiving COPY_GCICONF.
-
-5000:
-Insert system error in GCP participant when receiving GCP_SAVEREQ.
-
-5007:
-Delay GCP_SAVEREQ by 10 secs
-
-7165: Delay INCL_NODE_REQ in starting node yeilding error in GCP_PREPARE
-
-7030: Delay in GCP_PREPARE until node has completed a node failure
-7031: Delay in GCP_PREPARE and die 3s later
-
-7177: Delay copying of sysfileData in execCOPY_GCIREQ
-
-7180: Crash master during master-take-over in execMASTER_LCPCONF
-
-7183: Crash when receiving COPY_GCIREQ
-
-7184: Crash before starting next GCP after a node failure
-
-7185: Dont reply to COPY_GCI_REQ where reason == GCP
-
-7193: Dont send LCP_FRAG_ORD to self, and crash when sending first
- LCP_FRAG_ORD(last)
-
-7194: Force removeNodeFromStored to complete in the middle of MASTER_LCPCONF
-
-ERROR CODES FOR TESTING NODE FAILURE, LOCAL CHECKPOINT HANDLING:
------------------------------------------------------------------
-
-7009:
-Insert system error in master when local checkpoint is idle.
-
-7010:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = CALCULATE_KEEP_GCI.
-
-7011:
-Stop local checkpoint in the state CALCULATE_KEEP_GCI.
-
-7012:
-Restart local checkpoint after stopping in CALCULATE_KEEP_GCI.
-
-Method:
-1) Error 7011 in master, wait until report of stopped.
-2) Error xxxx in participant to crash it.
-3) Error 7012 in master to start again.
-
-7013:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = COPY_GCI before sending COPY_GCIREQ.
-
-7014:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = TC_CLOPSIZE before sending TC_CLOPSIZEREQ.
-
-7015:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = START_LCP_ROUND before sending START_LCP_ROUND.
-
-7016:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = START_LCP_ROUND after receiving LCP_REPORT.
-
-7017:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = TAB_COMPLETED.
-
-7018:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = TAB_SAVED before sending DIH_LCPCOMPLETE.
-
-7019:
-Insert system error in master when local checkpoint is in the
-state clcpStatus = IDLE before sending CONTINUEB(ZCHECK_TC_COUNTER).
-
-7020:
-Insert system error in local checkpoint participant at reception of
-COPY_GCIREQ.
-
-7075: Master
-Don't send any LCP_FRAG_ORD(last=true)
-And crash when all have "not" been sent
-
-8000: Crash particpant when receiving TCGETOPSIZEREQ
-8001: Crash particpant when receiving TC_CLOPSIZEREQ
-5010: Crash any when receiving LCP_FRAGORD
-
-7021: Crash in master when receiving START_LCP_REQ
-7022: Crash in !master when receiving START_LCP_REQ
-
-7023: Crash in master when sending START_LCP_CONF
-7024: Crash in !master when sending START_LCP_CONF
-
-7025: Crash in master when receiving LCP_FRAG_REP
-7016: Crash in !master when receiving LCP_FRAG_REP
-
-7026: Crash in master when changing state to LCP_TAB_COMPLETED
-7017: Crash in !master when changing state to LCP_TAB_COMPLETED
-
-7027: Crash in master when changing state to LCP_TAB_SAVED
-7018: Crash in master when changing state to LCP_TAB_SAVED
-
-7191: Crash when receiving LCP_COMPLETE_REP
-7192: Crash in setLcpActiveStatusStart - when dead node missed to LCP's
-
-ERROR CODES FOR TESTING NODE FAILURE, FAILURE IN COPY FRAGMENT PROCESS:
------------------------------------------------------------------------
-
-5002:
-Insert node failure in starting node when receiving a tuple copied from the copy node
-as part of copy fragment process.
-5003:
-Insert node failure when receiving ABORT signal.
-
-5004:
-Insert node failure handling when receiving COMMITREQ.
-
-5005:
-Insert node failure handling when receiving COMPLETEREQ.
-
-5006:
-Insert node failure handling when receiving ABORTREQ.
-
-5042:
-As 5002, but with specified table (see DumpStateOrd)
-
-These error code can be combined with error codes for testing time-out
-handling in DBTC to ensure that node failures are also well handled in
-time-out handling. They can also be used to test multiple node failure
-handling.
-
-5045: Crash in PREPARE_COPY_FRAG_REQ
-5046: Crash if LQHKEYREQ (NrCopy) comes when frag-state is incorrect
-
-ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBLQH
--------------------------------------------------
-5011:
-Delay execution of COMMIT signal 2 seconds to generate time-out.
-
-5012 (use 5017):
-First delay execution of COMMIT signal 2 seconds to generate COMMITREQ.
-Delay execution of COMMITREQ signal 2 seconds to generate time-out.
-
-5013:
-Delay execution of COMPLETE signal 2 seconds to generate time-out.
-
-5014 (use 5018):
-First delay execution of COMPLETE signal 2 seconds to generate COMPLETEREQ.
-Delay execution of COMPLETEREQ signal 2 seconds to generate time-out.
-
-5015:
-Delay execution of ABORT signal 2 seconds to generate time-out.
-
-5016: (ABORTREQ only as part of take-over)
-Delay execution of ABORTREQ signal 2 seconds to generate time-out.
-
-5031: lqhKeyRef, ZNO_TC_CONNECT_ERROR
-5032: lqhKeyRef, ZTEMPORARY_REDO_LOG_FAILURE
-5033: lqhKeyRef, ZTAIL_PROBLEM_IN_LOG_ERROR
-
-5034: Don't pop scan queue
-
-5035: Delay ACC_CONTOPCONT
-
-5038: Drop LQHKEYREQ + set 5039
-5039: Drop ABORT + set 5003
-
-8048: Make TC not choose own node for simple/dirty read
-5041: Crash is receiving simple read from other TC on different node
-
-8050: Send TCKEYREF is operation is non local
-
-5100,5101: Drop ABORT req in primary replica
- Crash on "next" ABORT
-
-ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC
--------------------------------------------------
-8040:
-Delay execution of ABORTED signal 2 seconds to generate time-out.
-
-8041:
-Delay execution of COMMITTED signal 2 seconds to generate time-out.
-8042 (use 8046):
-Delay execution of COMMITTED signal 2 seconds to generate COMMITCONF.
-Delay execution of COMMITCONF signal 2 seconds to generate time-out.
-
-8043:
-Delay execution of COMPLETED signal 2 seconds to generate time-out.
-
-8044 (use 8047):
-Delay execution of COMPLETED signal 2 seconds to generate COMPLETECONF.
-Delay execution of COMPLETECONF signal 2 seconds to generate time-out.
-
-8045: (ABORTCONF only as part of take-over)
-Delay execution of ABORTCONF signal 2 seconds to generate time-out.
-
-8050: Send ZABORT_TIMEOUT_BREAK delayed
-
-8053: Crash in timeOutFoundLab, state CS_WAIT_COMMIT_CONF
-
-5048: Crash in execCOMMIT
-5049: SET_ERROR_INSERT_VALUE(5048)
-
-ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC
--------------------------------------------------
-
-8003: Throw away a LQHKEYCONF in state STARTED
-8004: Throw away a LQHKEYCONF in state RECEIVING
-8005: Throw away a LQHKEYCONF in state REC_COMMITTING
-8006: Throw away a LQHKEYCONF in state START_COMMITTING
-
-8007: Ignore send of LQHKEYREQ in state STARTED
-8008: Ignore send of LQHKEYREQ in state START_COMMITTING
-
-8009: Ignore send of LQHKEYREQ+ATTRINFO in state STARTED
-8010: Ignore send of LQHKEYREQ+ATTRINFO in state START_COMMITTING
-
-8011: Abort at send of CONTINUEB(ZSEND_ATTRINFO) in state STARTED
-8012: Abort at send of CONTINUEB(ZSEND_ATTRINFO) in state START_COMMITTING
-
-8013: Ignore send of CONTINUEB(ZSEND_COMPLETE_LOOP) (should crash eventually)
-8014: Ignore send of CONTINUEB(ZSEND_COMMIT_LOOP) (should crash eventually)
-
-8015: Ignore ATTRINFO signal in DBTC in state REC_COMMITTING
-8016: Ignore ATTRINFO signal in DBTC in state RECEIVING
-
-8017: Return immediately from DIVERIFYCONF (should crash eventually)
-8018: Throw away a COMMITTED signal
-8019: Throw away a COMPLETED signal
-
-TESTING TAKE-OVER FUNCTIONALITY IN DBTC
----------------------------------------
-
-8002: Crash when sending LQHKEYREQ
-8029: Crash when receiving LQHKEYCONF
-8030: Crash when receiving COMMITTED
-8031: Crash when receiving COMPLETED
-8020: Crash when all COMMITTED has arrived
-8021: Crash when all COMPLETED has arrived
-8022: Crash when all LQHKEYCONF has arrived
-
-COMBINATION OF TIME-OUT + CRASH
--------------------------------
-
-8023 (use 8024): Ignore LQHKEYCONF and crash when ABORTED signal arrives by setting 8024
-8025 (use 8026): Ignore COMMITTED and crash when COMMITCONF signal arrives by setting 8026
-8027 (use 8028): Ignore COMPLETED and crash when COMPLETECONF signal arrives by setting 8028
-
-ABORT OF TCKEYREQ
------------------
-
-8032: No free TC records any more
-
-8037 : Invalid schema version in TCINDXREQ
-
-------
-
-8038 : Simulate API disconnect just after SCAN_TAB_REQ
-
-8057 : Send only 1 COMMIT per timeslice
-
-8052 : Simulate failure of TransactionBufferMemory allocation for OI lookup
-
-8051 : Simulate failure of allocation for saveINDXKEYINFO
-
-
-CMVMI
------
-9000 Set RestartOnErrorInsert to restart -n
-9998 Enter endless loop (trigger watchdog)
-9999 Crash system immediatly
-
-Test Crashes in handling node restarts
---------------------------------------
-
-7121: Crash after receiving permission to start (START_PERMCONF) in starting
- node.
-7122: Crash master when receiving request for permission to start (START_PERMREQ).
-7123: Crash any non-starting node when receiving information about a starting node
- (START_INFOREQ)
-7124: Respond negatively on an info request (START_INFOREQ)
-7125: Stop an invalidate Node LCP process in the middle to test if START_INFOREQ
- stopped by long-running processes are handled in a correct manner.
-7126: Allow node restarts for all nodes (used in conjunction with 7025)
-7127: Crash when receiving a INCL_NODEREQ message.
-7128: Crash master after receiving all INCL_NODECONF from all nodes
-7129: Crash master after receiving all INCL_NODECONF from all nodes and releasing
- the lock on the dictionary
-7130: Crash starting node after receiving START_MECONF
-7131: Crash when receiving START_COPYREQ in master node
-7132: Crash when receiving START_COPYCONF in starting node
-
-7170: Crash when receiving START_PERMREF (InitialStartRequired)
-
-8039: DBTC delay INCL_NODECONF and kill starting node
-
-7174: Crash starting node before sending DICT_LOCK_REQ
-7175: Master sends one fake START_PERMREF (ZNODE_ALREADY_STARTING_ERROR)
-7176: Slave NR pretends master does not support DICT lock (rolling upgrade)
-
-DICT:
-6000 Crash during NR when receiving DICTSTARTREQ
-6001 Crash during NR when receiving SCHEMA_INFO
-6002 Crash during NR soon after sending GET_TABINFO_REQ
-
-LQH:
-5026 Crash when receiving COPY_ACTIVEREQ
-5027 Crash when receiving STAT_RECREQ
-
-5043 Crash starting node, when scan is finished on primary replica
-
-Test Crashes in handling take over
-----------------------------------
-
-7133: Crash when receiving START_TOREQ
-7134: Crash master after receiving all START_TOCONF
-7135: Crash master after copying table 0 to starting node
-7136: Crash master after completing copy of tables
-7137: Crash master after adding a fragment before copying it
-7138: Crash when receiving CREATE_FRAGREQ in prepare phase
-7139: Crash when receiving CREATE_FRAGREQ in commit phase
-7140: Crash master when receiving all CREATE_FRAGCONF in prepare phase
-7141: Crash master when receiving all CREATE_FRAGCONF in commit phase
-7142: Crash master when receiving COPY_FRAGCONF
-7143: Crash master when receiving COPY_ACTIVECONF
-7144: Crash when receiving END_TOREQ
-7145: Crash master after receiving first END_TOCONF
-7146: Crash master after receiving all END_TOCONF
-7147: Crash master after receiving first START_TOCONF
-7148: Crash master after receiving first CREATE_FRAGCONF
-7152: Crash master after receiving first UPDATE_TOCONF
-7153: Crash master after receiving all UPDATE_TOCONF
-7154: Crash when receiving UPDATE_TOREQ
-7155: Crash master when completing writing start take over info
-7156: Crash master when completing writing end take over info
-
-Test failures in various states in take over functionality
-----------------------------------------------------------
-7157: Block take over at start take over
-7158: Block take over at sending of START_TOREQ
-7159: Block take over at selecting next fragment
-7160: Block take over at creating new fragment
-7161: Block take over at sending of CREATE_FRAGREQ in prepare phase
-7162: Block take over at sending of CREATE_FRAGREQ in commit phase
-7163: Block take over at sending of UPDATE_TOREQ at end of copy frag
-7164: Block take over at sending of END_TOREQ
-7169: Block take over at sending of UPDATE_TOREQ at end of copy
-
-5008: Crash at reception of EMPTY_LCPREQ (at master take over after NF)
-5009: Crash at sending of EMPTY_LCPCONF (at master take over after NF)
-
-Test Crashes in Handling Graceful Shutdown
-------------------------------------------
-7065: Crash when receiving STOP_PERMREQ in master
-7066: Crash when receiving STOP_PERMREQ in slave
-7067: Crash when receiving DIH_SWITCH_REPLICA_REQ
-7068: Crash when receiving DIH_SWITCH_REPLICA_CONF
-
-
-Backup Stuff:
-------------------------------------------
-10001: Crash on NODE_FAILREP in Backup coordinator
-10002: Crash on NODE_FAILREP when coordinatorTakeOver
-10003: Crash on PREP_CREATE_TRIG_{CONF/REF} (only coordinator)
-10004: Crash on START_BACKUP_{CONF/REF} (only coordinator)
-10005: Crash on CREATE_TRIG_{CONF/REF} (only coordinator)
-10006: Crash on WAIT_GCP_REF (only coordinator)
-10007: Crash on WAIT_GCP_CONF (only coordinator)
-10008: Crash on WAIT_GCP_CONF during start of backup (only coordinator)
-10009: Crash on WAIT_GCP_CONF during stop of backup (only coordinator)
-10010: Crash on BACKUP_FRAGMENT_CONF (only coordinator)
-10011: Crash on BACKUP_FRAGMENT_REF (only coordinator)
-10012: Crash on DROP_TRIG_{CONF/REF} (only coordinator)
-10013: Crash on STOP_BACKUP_{CONF/REF} (only coordinator)
-10014: Crash on DEFINE_BACKUP_REQ (participant)
-10015: Crash on START_BACKUP_REQ (participant)
-10016: Crash on BACKUP_FRAGMENT_REQ (participant)
-10017: Crash on SCAN_FRAGCONF (participant)
-10018: Crash on FSAPPENDCONF (participant)
-10019: Crash on TRIG_ATTRINFO (participant)
-10020: Crash on STOP_BACKUP_REQ (participant)
-10021: Crash on NODE_FAILREP in participant not becoming coordinator
-
-10022: Fake no backup records at DEFINE_BACKUP_REQ (participant)
-10023: Abort backup by error at reception of UTIL_SEQUENCE_CONF (code 300)
-10024: Abort backup by error at reception of DEFINE_BACKUP_CONF (code 301)
-10025: Abort backup by error at reception of CREATE_TRIG_CONF last (code 302)
-10026: Abort backup by error at reception of START_BACKUP_CONF (code 303)
-10027: Abort backup by error at reception of DEFINE_BACKUP_REQ at master (code 304)
-10028: Abort backup by error at reception of BACKUP_FRAGMENT_CONF at master (code 305)
-10029: Abort backup by error at reception of FSAPPENDCONF in slave (FileOrScanError = 5)
-10030: Simulate buffer full from trigger execution => abort backup
-10031: Error 331 for dictCommitTableMutex_locked
-10032: backup checkscan
-10033: backup checkscan
-10034: define backup reply error
-10035: Fail to allocate buffers
-
-10036: Halt backup for table >= 2
-10037: Resume backup (from 10036)
-
-11001: Send UTIL_SEQUENCE_REF (in master)
-
-5028: Crash when receiving LQHKEYREQ (in non-master)
-
-Failed Create Table:
---------------------
-7173: Create table failed due to not sufficient number of fragment or
- replica records.
-3001: Fail create 1st fragment
-4007 12001: Fail create 1st fragment
-4008 12002: Fail create 2nd fragment
-4009 12003: Fail create 1st attribute in 1st fragment
-4010 12004: Fail create last attribute in 1st fragment
-4011 12005: Fail create 1st attribute in 2nd fragment
-4012 12006: Fail create last attribute in 2nd fragment
-
-Drop Table/Index:
------------------
-4001: Crash on REL_TABMEMREQ in TUP
-4002: Crash on DROP_TABFILEREQ in TUP
-4003: Fail next trigger create in TUP
-4004: Fail next trigger drop in TUP
-8033: Fail next trigger create in TC
-8034: Fail next index create in TC
-8035: Fail next trigger drop in TC
-8036: Fail next index drop in TC
-6006: Crash participant in create index
-
-4013: verify TUP tab descr before and after next DROP TABLE
-
-System Restart:
----------------
-
-5020: Force system to read pages form file when executing prepare operation record
-3000: Delay writing of datapages in ACC when LCP is started
-4000: Delay writing of datapages in TUP when LCP is started
-7070: Set TimeBetweenLcp to min value
-7071: Set TimeBetweenLcp to max value
-7072: Split START_FRAGREQ into several log nodes
-7073: Don't include own node in START_FRAGREQ
-7074: 7072 + 7073
-
-Scan:
-------
-
-5021: Crash when receiving SCAN_NEXTREQ if sender is own node
-5022: Crash when receiving SCAN_NEXTREQ if sender is NOT own node
-5023: Drop SCAN_NEXTREQ if sender is own node
-5024: Drop SCAN_NEXTREQ if sender is NOT own node
-5025: Delay SCAN_NEXTREQ 1 second if sender is NOT own node
-5030: Drop all SCAN_NEXTREQ until node is shutdown with SYSTEM_ERROR
- because of scan fragment timeout
-
-Test routing of signals:
------------------------
-4006: Turn on routing of TRANSID_AI signals from TUP
-5029: Turn on routing of KEYINFO20 signals from LQH
-
-Ordered index:
---------------
-12007: Make next alloc node fail with no memory error
-
-Dbdict:
--------
-6003 Crash in participant @ CreateTabReq::Prepare
-6004 Crash in participant @ CreateTabReq::Commit
-6005 Crash in participant @ CreateTabReq::CreateDrop
-6007 Fail on readTableFile for READ_TAB_FILE1 (28770)
-
-Dbtup:
-4014 - handleInsert - Out of undo buffer
-4015 - handleInsert - Out of log space
-4016 - handleInsert - AI Inconsistency
-4017 - handleInsert - Out of memory
-4018 - handleInsert - Null check error
-4019 - handleInsert - Alloc rowid error
-4020 - handleInsert - Size change error
-4021 - handleInsert - Out of disk space
-
-4022 - addTuxEntries - fail before add of first entry
-4023 - addTuxEntries - fail add of last entry (the entry for last index)
-
-4025: Fail all inserts with out of memory
-4026: Fail one insert with oom
-4027: Fail inserts randomly with oom
-4028: Fail one random insert with oom
-
-NDBCNTR:
-
-1000: Crash insertion on SystemError::CopyFragRef
-1001: Delay sending NODE_FAILREP (to own node), until error is cleared
-
-LGMAN:
------
-15000: Fail to create log file
-
-TSMAN:
------
-16000: Fail to create data file
diff --git a/storage/ndb/src/kernel/blocks/Makefile.am b/storage/ndb/src/kernel/blocks/Makefile.am
deleted file mode 100644
index 9b806638837..00000000000
--- a/storage/ndb/src/kernel/blocks/Makefile.am
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2004-2006 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = \
- dbdict \
- dbdih \
- dblqh \
- dbtup \
- backup
-
-noinst_LIBRARIES = libblocks.a
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/kernel/blocks/dblqh
-libblocks_a_SOURCES = tsman.cpp lgman.cpp pgman.cpp diskpage.cpp restore.cpp\
- cmvmi/Cmvmi.cpp \
- dbacc/DbaccInit.cpp dbacc/DbaccMain.cpp \
- dbdict/Dbdict.cpp \
- dbdih/DbdihInit.cpp dbdih/DbdihMain.cpp \
- dblqh/DblqhInit.cpp dblqh/DblqhMain.cpp \
- dbtc/DbtcInit.cpp dbtc/DbtcMain.cpp \
- dbtup/DbtupExecQuery.cpp dbtup/DbtupBuffer.cpp \
- dbtup/DbtupRoutines.cpp dbtup/DbtupCommit.cpp \
- dbtup/DbtupFixAlloc.cpp dbtup/DbtupTrigger.cpp \
- dbtup/DbtupAbort.cpp dbtup/DbtupPageMap.cpp \
- dbtup/DbtupPagMan.cpp dbtup/DbtupStoredProcDef.cpp \
- dbtup/DbtupMeta.cpp dbtup/DbtupTabDesMan.cpp \
- dbtup/DbtupGen.cpp dbtup/DbtupIndex.cpp \
- dbtup/DbtupDebug.cpp dbtup/DbtupScan.cpp \
- dbtup/DbtupDiskAlloc.cpp dbtup/DbtupVarAlloc.cpp \
- dbtup/tuppage.cpp dbtup/Undo_buffer.cpp \
- ndbfs/AsyncFile.cpp ndbfs/Ndbfs.cpp ndbfs/VoidFs.cpp \
- ndbfs/Filename.cpp ndbfs/CircularIndex.cpp \
- ndbcntr/NdbcntrInit.cpp ndbcntr/NdbcntrSysTable.cpp ndbcntr/NdbcntrMain.cpp \
- qmgr/QmgrInit.cpp qmgr/QmgrMain.cpp \
- trix/Trix.cpp \
- backup/Backup.cpp backup/BackupInit.cpp \
- dbutil/DbUtil.cpp \
- suma/Suma.cpp suma/SumaInit.cpp \
- dbtux/DbtuxGen.cpp dbtux/DbtuxMeta.cpp dbtux/DbtuxMaint.cpp \
- dbtux/DbtuxNode.cpp dbtux/DbtuxTree.cpp dbtux/DbtuxScan.cpp \
- dbtux/DbtuxSearch.cpp dbtux/DbtuxCmp.cpp dbtux/DbtuxStat.cpp \
- dbtux/DbtuxDebug.cpp
-
-EXTRA_PROGRAMS = ndb_print_file
-ndb_print_file_SOURCES = print_file.cpp diskpage.cpp dbtup/tuppage.cpp
-ndb_print_file_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-windoze-dsp:
diff --git a/storage/ndb/src/kernel/blocks/NodeRestart.new.txt b/storage/ndb/src/kernel/blocks/NodeRestart.new.txt
deleted file mode 100644
index 00ab8f0c208..00000000000
--- a/storage/ndb/src/kernel/blocks/NodeRestart.new.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-Master DIH Starting DIH Starting DICT
----------------------- ---------------------- ---------------------
-
- Check for sysfile
- DIH_RESTARTCONF ->
-
-******************************************************************************
-* NDB_STTOR interal startphase = 1
-******************************************************************************
-
- Read schema file
-
-******************************************************************************
-* NDB_STTOR interal startphase = 2
-******************************************************************************
-
- <- START_PERMREQ
-
-XXX
-
-START_PERMCONF ->
-
-******************************************************************************
-* NDB_STTOR interal startphase = 3
-******************************************************************************
-
- <- START_MEREQ
-
-START_RECREQ -> starting LQH
- <- START_RECCONF
-
-For each table
- COPY_TABREQ -> starting DIH
-
-DICTSTARTREQ -> starting DICT
- GET_SCHEMA_INFOREQ
- (to master DICT)
-
- ->SCHEMA_INFO
- (schema file)
-
- 1) For each table
- If TableStatus OK
- ReadTableFile
- else
- GET_TABINFOREQ
- 2) DIADDTABREQ->DIH
-
- For each local frag
- ADD_FRAG_REQ -> local DICT
- DI_ADD_TAB_CONF
- <- DICTSTARTCONF
-
-INCL_NODEREQ -> all DIH
-
-START_MECONF -> starting DIH
- (including sysfile)
-
-******************************************************************************
-* NDB_STTOR interal startphase = 5
-******************************************************************************
-
- <- START_COPYREQ
-
-START_TOREQ -> all DIH
-
-For each fragment
- CREATE_FRAGREQ -> all DIH
-
- COPY-DATA (LQHKEYREQ++)
-
- UPDATE_TOREQ -> all DIH
-
- COPY_ACTIVEREQ -> starting LQH
-
- CREATE_FRAGREQ -> all DIH
-
-START_COPYCONF ->
-
-LOCAL CHECKPOINT
-
diff --git a/storage/ndb/src/kernel/blocks/NodeRestart.txt b/storage/ndb/src/kernel/blocks/NodeRestart.txt
deleted file mode 100644
index e9f277bb39e..00000000000
--- a/storage/ndb/src/kernel/blocks/NodeRestart.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-
-Master DIH Starting DIH Starting DICT
----------------------- ---------------------- ---------------------
-
- Check for sysfile
- DIH_RESTARTCONF ->
-
-******************************************************************************
-* NDB_STTOR interal startphase = 1
-******************************************************************************
-
- Read schema file
-
-******************************************************************************
-* NDB_STTOR interal startphase = 2
-******************************************************************************
-
- <- START_PERMREQ
-
-XXX
-
-START_PERMCONF ->
-
-******************************************************************************
-* NDB_STTOR interal startphase = 3
-******************************************************************************
-
- <- START_MEREQ
-
-START_RECREQ -> starting LQH
- <- START_RECCONF
-
-DICTSTARTREQ -> starting DICT
- GET_SCHEMA_INFOREQ
- (to master DICT)
-
- ->SCHEMA_INFO
- (schema file)
-
- 1) For each table
- 1) If TableStatus match
- ReadTableFile
- else
- GET_TABINFOREQ
-
- <- DICTSTARTCONF
-
-For each table
- COPY_TABREQ -> starting DIH
-
-INCL_NODEREQ -> all DIH
-
-START_MECONF -> starting DIH
- (including sysfile)
-
-******************************************************************************
-* NDB_STTOR interal startphase = 5
-******************************************************************************
-
- <- START_COPYREQ
-
-START_TOREQ -> all DIH
-
-For each fragment
- ADD_FRAG_REQ -> local DICT -> LQHFRAGREQ -> starting LQH
-
- CREATE_FRAGREQ -> all DIH
-
- COPY-DATA (LQHKEYREQ++)
-
- UPDATE_TOREQ -> all DIH
-
- COPY_ACTIVEREQ -> starting LQH
-
- CREATE_FRAGREQ -> all DIH
-
-START_COPYCONF ->
-
-LOCAL CHECKPOINT
-
diff --git a/storage/ndb/src/kernel/blocks/OptNR.txt b/storage/ndb/src/kernel/blocks/OptNR.txt
deleted file mode 100644
index 17e9a62bb0e..00000000000
--- a/storage/ndb/src/kernel/blocks/OptNR.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-*** Copy thread
-
- Scan rowids with GCP > starting nodes GCP
- Cases for different ROWID combinations
-
-RI Primary Starting Result
-1 A A Update A
-2 B B* Delete B* + Insert B
-3 C C* Delete C* + Delete C + Insert C
- C
-4 Deleted D Delete D
-5 E Deleted Insert E
-6 F Deleted Delete F + Insert F
- F
-7 Deleted Deleted Update GCP
-
-*** Ordinary operations
-Op Starting Result
-Insert A@1 A@1 Update A
-Insert A@1 A@2 Delete A@2, Insert A@1
-Insert A@1 1 busy, A@2 Delete 1, Delete A@2, Insert A@1
-Insert A@1 1 busy Delete 1, Insert A@1
-
-Delete A@1 A@1 Delete A@1
-Delete A@1 else noop
-
-Update A@1 A@1 Update A
-Update A@1 else noop
-
-***
-
-Rationale:
-
-If copy has passed rowid,
- then no ordinary operation should be a noop
-
-If copy has not passed,
- then it's ok to do a noop as copy will get there sooner or later
-
-Copy may not end up in lock queue, as no lock is held on primary.
- therefore ordinary ops must be noops when rowid missmatch
-
-When not scanning in rowid order (e.g. disk order) one must
-1 make a second pass in rowid order
- - finding deletes and inserts (as 2)
-2 mark all inserts "earlier" than current scan pos
- so they will be found during second pass
-
-Note: Dealloc is performed first on backup then on primary
diff --git a/storage/ndb/src/kernel/blocks/Start.txt b/storage/ndb/src/kernel/blocks/Start.txt
deleted file mode 100644
index 3e805ebab55..00000000000
--- a/storage/ndb/src/kernel/blocks/Start.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-
---- Start phase 1 - Qmgr -------------------------------------------
-
-1) Set timer 1 - TimeToWaitAlive
-
-2) Send CM_REGREQ to all connected(and connecting) nodes
-
-3) Wait until -
-a) The precident answers CM_REGCONF
-b) All nodes has answered and I'm the candidate -> election won
-c) 30s has passed and I'm the candidate -> election won
-d) TimeToWaitAlive has passed -> Failure to start
-
-When receiving CM_REGCONF
-4) Send CM_NODEINFOREQ to all connected(and connecting) nodes
- reported in CM_REGCONF
-
-5) Wait until -
-a) All CM_NODEINFO_CONF has arrived
-b) TimeToWaitAlive has passed -> Failure to start
-
-6) Send CM_ACKADD to president
-
-7) Wait until -
-a) Receive CM_ADD(CommitNew) from president -> I'm in the qmgr cluster
-b) TimeToWaitAlive has passed -> Failure to start
-
-NOTE:
-30s is hardcoded in 3c.
-TimeToWaitAlive should be atleast X sec greater than 30s. i.e. 30+X sec
-to support "partial starts"
-
-NOTE:
-In 3b, a more correct number (instead of all) would be
-N-NG+1 where N is #nodes and NG is #node groups = (N/R where R is # replicas)
-But Qmgr has no notion about node groups or replicas
-
---- Start phase X - Qmgr -------------------------------------------
-
-President - When accepting a CM_REGREQ
-1) Send CM_REGCONF to starting node
-2) Send CM_ADD(Prepare) to all started nodes + starting node
-3) Send CM_ADD(AddCommit) to all started nodes
-4) Send CM_ADD(CommitNew) to starting node
-
-Cluster participant -
-1) Wait for both CM_NODEINFOREQ from starting and CM_ADD(Prepare) from pres.
-2) Send CM_ACKADD(Prepare)
-3) Wait for CM_ADD(AddCommit) from president
-4) Send CM_ACKADD(AddCommit)
-
---- Start phase 2 - NdbCntr ----------------------------------------
-
-- Use same TimeToWaitAliveTimer
-
-1) Check sysfile (DIH_RESTART_REQ)
-2) Read nodes (from Qmgr) P = qmgr president
-
-3) Send CNTR_MASTER_REQ to cntr(P)
- including info in DIH_RESTART_REF/CONF
-
-4) Wait until -
-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
-
---
-Initial start/System restart NdbCntr (on qmgr president node)
-
-1) Wait until -
-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) Send CNTR_START_CONF to all nodes "with filesystem"
-
-3) Wait until -
- Receiving CNTR_START_REP for all starting nodes
-
-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
-
-When receiving CNTR_MASTER_REQ
-1) If I'm not master send CNTR_MASTER_REF (including master node id)
-2) If I'm master
- Coordinate parallell node restarts
- send CNTR_MASTER_CONF (node restart)
diff --git a/storage/ndb/src/kernel/blocks/SystemRestart.new.txt b/storage/ndb/src/kernel/blocks/SystemRestart.new.txt
deleted file mode 100644
index 3738de28df8..00000000000
--- a/storage/ndb/src/kernel/blocks/SystemRestart.new.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-DIH DICT CNTR
----------------------- ---------------------- ---------------------
- <- DIHRESTARTREQ
-Check for sysfile
-DIH_RESTARTCONF ->
-
-NDB_STTORY -> DICT (sp=1)
- Read schema file
-
-******************************************************************************
-* Elect master
-******************************************************************************
-
--- Master DIH --
-
-Read sysfile
-
-COPY_GCIREQ -> all DIHs
-
-DICTSTARTREQ -> local DICT (master)
-
- master
- ======
- For each table (that should be started)
- 1) ReadTableFile
- 2) DI_ADD_TAB_REQ -> local DIH
-
-1) ReadTableFile (DIH)
-2) COPY_TABREQ -> all DIH (but self)
-3) For each local frag
- ADD_FRAG_REQ -> local DICT
-4) DI_ADD_TAB_CONF
-
- SCHEMA_INFO -> all DICTs
- Info = schema file
-
- Participant
- ===========
- 1) For each table
- 1) If TableStatus match
- ReadTableFile
- else
- GET_TABINFOREQ
- 2) WriteTableFile
- 3) Parse Table Data
- 4) DI_ADD_TAB_REQ -> local DIH
-
- <- SCHEMA_INFOCONF
-
-
- <- DICTSTARTCONF
-
-For each fragment
- IF Fragment is logged
- START_FRAGREQ -> LQH x
-
- START_RECREQ -> all LQH
- Note does not wait for START_FRAGCONF
-
-NDB_STARTCONF ->
diff --git a/storage/ndb/src/kernel/blocks/SystemRestart.txt b/storage/ndb/src/kernel/blocks/SystemRestart.txt
deleted file mode 100644
index 235dfb968fa..00000000000
--- a/storage/ndb/src/kernel/blocks/SystemRestart.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-NDBCNTR DIH DICT
----------------------- ---------------------- ---------------
-DIH_RESTARTREQ -> DIH
- Check for sysfile
- <- DIH_RESTARTCONF
-
-NDB_STTORY -> DICT
-sp = 1
- Read schema file
-
----- Master
-
-NDB_STARTREQ -> DIH
- Read sysfile
-
- COPY_GCIREQ -> all DIHs
-
- DICTSTARTREQ -> local DICT
- local
- ======
- SCHEMA_INFO -> all DICTs
- Info = schema file
-
- Participant
- ===========
- 1) For each table
- If TableStatus match
- ReadTableFile
- else
- GET_TABINFOREQ
-
- <- SCHEMA_INFOCONF
-
- local
- ======
- For each table
- DIHSTARTTABREQ -> DIH
-
- <- DICTSTARTCONF
-
- For each table (STARTED)
- Read table description
- from disk
-
- For each fragment
- IF Fragment dont have LCP
- ADD_FRAGREQ -> local DICT
- 1) LQHFRAGREQ -> LQH x
- 2) For each attribute
- LQHADDATTREQ
- IF Fragment is logged
- START_FRAGREQ -> LQH x
-
- START_RECREQ -> all LQH
- Note does not wait for START_FRAGCONF
-
- For each table
- COPY_TABREQ -> all DIH (but self)
-
- <- NDB_STARTCONF
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
deleted file mode 100644
index 3aa19644491..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
+++ /dev/null
@@ -1,5144 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <my_config.h>
-#include "Backup.hpp"
-
-#include <ndb_version.h>
-
-#include <NdbTCP.h>
-#include <Bitmask.hpp>
-
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-
-#include <signaldata/DihFragCount.hpp>
-#include <signaldata/ScanFrag.hpp>
-
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/ListTables.hpp>
-
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsAppendReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-
-#include <signaldata/BackupImpl.hpp>
-#include <signaldata/BackupSignalData.hpp>
-#include <signaldata/BackupContinueB.hpp>
-#include <signaldata/EventReport.hpp>
-
-#include <signaldata/UtilSequence.hpp>
-
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/AlterTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/FireTrigOrd.hpp>
-#include <signaldata/TrigAttrInfo.hpp>
-#include <AttributeHeader.hpp>
-
-#include <signaldata/WaitGCP.hpp>
-#include <signaldata/LCP.hpp>
-
-#include <NdbTick.h>
-
-static NDB_TICKS startTime;
-
-static const Uint32 BACKUP_SEQUENCE = 0x1F000000;
-
-#ifdef VM_TRACE
-#define DEBUG_OUT(x) ndbout << x << endl
-#else
-#define DEBUG_OUT(x)
-#endif
-
-//#define DEBUG_ABORT
-//#define dbg globalSignalLoggers.log
-
-static Uint32 g_TypeOfStart = NodeState::ST_ILLEGAL_TYPE;
-
-#define SEND_BACKUP_STARTED_FLAG(A) (((A) & 0x3) > 0)
-#define SEND_BACKUP_COMPLETED_FLAG(A) (((A) & 0x3) > 1)
-
-void
-Backup::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- const Uint32 startphase = signal->theData[1];
- const Uint32 typeOfStart = signal->theData[7];
-
- if (startphase == 1)
- {
- m_curr_disk_write_speed = c_defaults.m_disk_write_speed_sr;
- m_overflow_disk_write = 0;
- m_reset_disk_speed_time = NdbTick_CurrentMillisecond();
- m_reset_delay_used = Backup::DISK_SPEED_CHECK_DELAY;
- signal->theData[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal,
- Backup::DISK_SPEED_CHECK_DELAY, 1);
- }
- if (startphase == 3) {
- jam();
- g_TypeOfStart = typeOfStart;
- signal->theData[0] = reference();
- sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
- return;
- }//if
-
- if (startphase == 7)
- {
- m_curr_disk_write_speed = c_defaults.m_disk_write_speed;
- }
-
- if(startphase == 7 && g_TypeOfStart == NodeState::ST_INITIAL_START &&
- c_masterNodeId == getOwnNodeId()){
- jam();
- createSequence(signal);
- return;
- }//if
-
- sendSTTORRY(signal);
- return;
-}//Dbdict::execSTTOR()
-
-void
-Backup::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
- ReadNodesConf * conf = (ReadNodesConf *)signal->getDataPtr();
-
- c_aliveNodes.clear();
-
- Uint32 count = 0;
- for (Uint32 i = 0; i<MAX_NDB_NODES; i++) {
- jam();
- if(NodeBitmask::get(conf->allNodes, i)){
- jam();
- count++;
-
- NodePtr node;
- ndbrequire(c_nodes.seize(node));
-
- node.p->nodeId = i;
- if(NodeBitmask::get(conf->inactiveNodes, i)) {
- jam();
- node.p->alive = 0;
- } else {
- jam();
- node.p->alive = 1;
- c_aliveNodes.set(i);
- }//if
- }//if
- }//for
- c_masterNodeId = conf->masterNodeId;
- ndbrequire(count == conf->noOfNodes);
- sendSTTORRY(signal);
-}
-
-void
-Backup::sendSTTORRY(Signal* signal)
-{
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 3;
- signal->theData[5] = 7;
- signal->theData[6] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
-}
-
-void
-Backup::createSequence(Signal* signal)
-{
- UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
-
- req->senderData = RNIL;
- req->sequenceId = BACKUP_SEQUENCE;
- req->requestType = UtilSequenceReq::Create;
-
- sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
- signal, UtilSequenceReq::SignalLength, JBB);
-}
-
-void
-Backup::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- const Uint32 Tdata0 = signal->theData[0];
- const Uint32 Tdata1 = signal->theData[1];
- const Uint32 Tdata2 = signal->theData[2];
-
- switch(Tdata0) {
- case BackupContinueB::RESET_DISK_SPEED_COUNTER:
- {
- /*
- Adjust for upto 10 millisecond delay of this signal. Longer
- delays will not be handled, in this case the system is most
- likely under too high load and it won't matter very much that
- we decrease the speed of checkpoints.
-
- We use a technique where we allow an overflow write in one
- period. This overflow will be removed from the next period
- such that the load will at average be as specified.
- */
- int delay_time = m_reset_delay_used;
- NDB_TICKS curr_time = NdbTick_CurrentMillisecond();
- int sig_delay = curr_time - m_reset_disk_speed_time;
-
- m_words_written_this_period = m_overflow_disk_write;
- m_overflow_disk_write = 0;
- m_reset_disk_speed_time = curr_time;
-
- if (sig_delay > delay_time + 10)
- delay_time = Backup::DISK_SPEED_CHECK_DELAY - 10;
- else if (sig_delay < delay_time - 10)
- delay_time = Backup::DISK_SPEED_CHECK_DELAY + 10;
- else
- delay_time = Backup::DISK_SPEED_CHECK_DELAY - (sig_delay - delay_time);
- m_reset_delay_used= delay_time;
- signal->theData[0] = BackupContinueB::RESET_DISK_SPEED_COUNTER;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, delay_time, 1);
-#if 0
- ndbout << "Signal delay was = " << sig_delay;
- ndbout << " Current time = " << curr_time << endl;
- ndbout << " Delay time will be = " << delay_time << endl << endl;
-#endif
- break;
- }
- case BackupContinueB::BACKUP_FRAGMENT_INFO:
- {
- jam();
- const Uint32 ptr_I = Tdata1;
- Uint32 tabPtr_I = Tdata2;
- Uint32 fragPtr_I = signal->theData[3];
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptr_I);
- TablePtr tabPtr;
- ptr.p->tables.getPtr(tabPtr, tabPtr_I);
-
- if (fragPtr_I != tabPtr.p->fragments.getSize())
- {
- jam();
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I);
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
-
- const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2;
- Uint32 * dst;
- if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz))
- {
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 4);
- return;
- }
-
- BackupFormat::CtlFile::FragmentInfo * fragInfo =
- (BackupFormat::CtlFile::FragmentInfo*)dst;
- fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO);
- fragInfo->SectionLength = htonl(sz);
- fragInfo->TableId = htonl(fragPtr.p->tableId);
- fragInfo->FragmentNo = htonl(fragPtr_I);
- fragInfo->NoOfRecordsLow = htonl(fragPtr.p->noOfRecords & 0xFFFFFFFF);
- fragInfo->NoOfRecordsHigh = htonl(fragPtr.p->noOfRecords >> 32);
- fragInfo->FilePosLow = htonl(0);
- fragInfo->FilePosHigh = htonl(0);
-
- filePtr.p->operation.dataBuffer.updateWritePtr(sz);
-
- fragPtr_I++;
- }
-
- if (fragPtr_I == tabPtr.p->fragments.getSize())
- {
- signal->theData[0] = tabPtr.p->tableId;
- signal->theData[1] = 0; // unlock
- EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
-
- fragPtr_I = 0;
- ptr.p->tables.next(tabPtr);
- if ((tabPtr_I = tabPtr.i) == RNIL)
- {
- jam();
- closeFiles(signal, ptr);
- return;
- }
- }
-
- signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
- signal->theData[1] = ptr_I;
- signal->theData[2] = tabPtr_I;
- signal->theData[3] = fragPtr_I;
- sendSignal(BACKUP_REF, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }
- case BackupContinueB::START_FILE_THREAD:
- case BackupContinueB::BUFFER_UNDERFLOW:
- {
- jam();
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, Tdata1);
- checkFile(signal, filePtr);
- return;
- }
- break;
- case BackupContinueB::BUFFER_FULL_SCAN:
- {
- jam();
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, Tdata1);
- checkScan(signal, filePtr);
- return;
- }
- break;
- case BackupContinueB::BUFFER_FULL_FRAG_COMPLETE:
- {
- jam();
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, Tdata1);
- fragmentCompleted(signal, filePtr);
- return;
- }
- break;
- case BackupContinueB::BUFFER_FULL_META:
- {
- jam();
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, Tdata1);
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- FsBuffer & buf = filePtr.p->operation.dataBuffer;
-
- if(buf.getFreeSize() < buf.getMaxWrite()) {
- jam();
- TablePtr tabPtr LINT_SET_PTR;
- c_tablePool.getPtr(tabPtr, Tdata2);
-
- DEBUG_OUT("Backup - Buffer full - "
- << buf.getFreeSize()
- << " < " << buf.getMaxWrite()
- << " (sz: " << buf.getUsableSize()
- << " getMinRead: " << buf.getMinRead()
- << ") - tableId = " << tabPtr.p->tableId);
-
- signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
- signal->theData[1] = Tdata1;
- signal->theData[2] = Tdata2;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
- return;
- }//if
-
- TablePtr tabPtr LINT_SET_PTR;
- c_tablePool.getPtr(tabPtr, Tdata2);
- GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = ptr.i;
- req->requestType = GetTabInfoReq::RequestById |
- GetTabInfoReq::LongSignalConf;
- req->tableId = tabPtr.p->tableId;
- sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- return;
- }
- case BackupContinueB::ZDELAY_SCAN_NEXT:
- if (ERROR_INSERTED(10036))
- {
- jam();
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 300,
- signal->getLength());
- return;
- }
- else
- {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- ndbout_c("Resuming backup");
- memmove(signal->theData, signal->theData + 1,
- 4*ScanFragNextReq::SignalLength);
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- return ;
- }
- default:
- ndbrequire(0);
- }//switch
-}
-
-void
-Backup::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
-
- if(signal->theData[0] == 20){
- if(signal->length() > 1){
- c_defaults.m_dataBufferSize = (signal->theData[1] * 1024 * 1024);
- }
- if(signal->length() > 2){
- c_defaults.m_logBufferSize = (signal->theData[2] * 1024 * 1024);
- }
- if(signal->length() > 3){
- c_defaults.m_minWriteSize = signal->theData[3] * 1024;
- }
- if(signal->length() > 4){
- c_defaults.m_maxWriteSize = signal->theData[4] * 1024;
- }
-
- infoEvent("Backup: data: %d log: %d min: %d max: %d",
- c_defaults.m_dataBufferSize,
- c_defaults.m_logBufferSize,
- c_defaults.m_minWriteSize,
- c_defaults.m_maxWriteSize);
- return;
- }
- if(signal->theData[0] == 21){
- BackupReq * req = (BackupReq*)signal->getDataPtrSend();
- req->senderData = 23;
- req->backupDataLen = 0;
- sendSignal(BACKUP_REF, GSN_BACKUP_REQ,signal,BackupReq::SignalLength, JBB);
- startTime = NdbTick_CurrentMillisecond();
- return;
- }
-
- if(signal->theData[0] == 22){
- const Uint32 seq = signal->theData[1];
- FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = 23;
- req->directory = 1;
- req->ownDirectory = 1;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
- FsOpenReq::v2_setSequence(req->fileNumber, seq);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
- FsRemoveReq::SignalLength, JBA);
- return;
- }
-
- if(signal->theData[0] == 23){
- /**
- * Print records
- */
- BackupRecordPtr ptr LINT_SET_PTR;
- for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)){
- infoEvent("BackupRecord %d: BackupId: %d MasterRef: %x ClientRef: %x",
- ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
- infoEvent(" State: %d", ptr.p->slaveState.getState());
- BackupFilePtr filePtr;
- for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
- ptr.p->files.next(filePtr)){
- jam();
- infoEvent(" file %d: type: %d flags: H'%x",
- filePtr.i, filePtr.p->fileType,
- filePtr.p->m_flags);
- }
- }
-
- ndbout_c("m_curr_disk_write_speed: %u m_words_written_this_period: %u m_overflow_disk_write: %u",
- m_curr_disk_write_speed, m_words_written_this_period, m_overflow_disk_write);
- ndbout_c("m_reset_delay_used: %u m_reset_disk_speed_time: %llu",
- m_reset_delay_used, (Uint64)m_reset_disk_speed_time);
- for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr))
- {
- ndbout_c("BackupRecord %u: BackupId: %u MasterRef: %x ClientRef: %x",
- ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
- ndbout_c(" State: %u", ptr.p->slaveState.getState());
- ndbout_c(" noOfByte: %llu noOfRecords: %llu",
- ptr.p->noOfBytes, ptr.p->noOfRecords);
- ndbout_c(" noOfLogBytes: %llu noOfLogRecords: %llu",
- ptr.p->noOfLogBytes, ptr.p->noOfLogRecords);
- ndbout_c(" errorCode: %u", ptr.p->errorCode);
- BackupFilePtr filePtr;
- for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
- ptr.p->files.next(filePtr))
- {
- ndbout_c(" file %u: type: %u flags: H'%x tableId: %u fragmentId: %u",
- filePtr.i, filePtr.p->fileType, filePtr.p->m_flags,
- filePtr.p->tableId, filePtr.p->fragmentNo);
- }
- if (ptr.p->slaveState.getState() == SCANNING && ptr.p->dataFilePtr != RNIL)
- {
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
- OperationRecord & op = filePtr.p->operation;
- Uint32 *tmp = NULL;
- Uint32 sz = 0;
- bool eof = FALSE;
- bool ready = op.dataBuffer.getReadPtr(&tmp, &sz, &eof);
- ndbout_c("ready: %s eof: %s", ready ? "TRUE" : "FALSE", eof ? "TRUE" : "FALSE");
- }
- }
- return;
- }
- if(signal->theData[0] == 24){
- /**
- * Print size of records etc.
- */
- infoEvent("Backup - dump pool sizes");
- infoEvent("BackupPool: %d BackupFilePool: %d TablePool: %d",
- c_backupPool.getSize(), c_backupFilePool.getSize(),
- c_tablePool.getSize());
- infoEvent("AttrPool: %d TriggerPool: %d FragmentPool: %d",
- c_backupPool.getSize(), c_backupFilePool.getSize(),
- c_tablePool.getSize());
- infoEvent("PagePool: %d",
- c_pagePool.getSize());
-
-
- if(signal->getLength() == 2 && signal->theData[1] == 2424)
- {
- /**
- * Handle LCP
- */
- BackupRecordPtr lcp;
- ndbrequire(c_backups.first(lcp));
-
- ndbrequire(c_backupPool.getSize() == c_backupPool.getNoOfFree() + 1);
- if(lcp.p->tables.isEmpty())
- {
- ndbrequire(c_tablePool.getSize() == c_tablePool.getNoOfFree());
- ndbrequire(c_attributePool.getSize() == c_attributePool.getNoOfFree());
- ndbrequire(c_fragmentPool.getSize() == c_fragmentPool.getNoOfFree());
- ndbrequire(c_triggerPool.getSize() == c_triggerPool.getNoOfFree());
- }
- ndbrequire(c_backupFilePool.getSize() == c_backupFilePool.getNoOfFree() + 1);
- BackupFilePtr lcp_file;
- c_backupFilePool.getPtr(lcp_file, lcp.p->dataFilePtr);
- ndbrequire(c_pagePool.getSize() ==
- c_pagePool.getNoOfFree() +
- lcp_file.p->pages.getSize());
- }
- }
-}
-
-bool
-Backup::findTable(const BackupRecordPtr & ptr,
- TablePtr & tabPtr, Uint32 tableId) const
-{
- for(ptr.p->tables.first(tabPtr);
- tabPtr.i != RNIL;
- ptr.p->tables.next(tabPtr)) {
- jam();
- if(tabPtr.p->tableId == tableId){
- jam();
- return true;
- }//if
- }//for
- tabPtr.i = RNIL;
- tabPtr.p = 0;
- return false;
-}
-
-static Uint32 xps(Uint64 x, Uint64 ms)
-{
- float fx = x;
- float fs = ms;
-
- if(ms == 0 || x == 0) {
- jam();
- return 0;
- }//if
- jam();
- return ((Uint32)(1000.0f * (fx + fs/2.1f))) / ((Uint32)fs);
-}
-
-struct Number {
- Number(Uint64 r) { val = r;}
- Number & operator=(Uint64 r) { val = r; return * this; }
- Uint64 val;
-};
-
-NdbOut &
-operator<< (NdbOut & out, const Number & val){
- char p = 0;
- Uint32 loop = 1;
- while(val.val > loop){
- loop *= 1000;
- p += 3;
- }
- if(loop != 1){
- p -= 3;
- loop /= 1000;
- }
-
- switch(p){
- case 0:
- break;
- case 3:
- p = 'k';
- break;
- case 6:
- p = 'M';
- break;
- case 9:
- p = 'G';
- break;
- default:
- p = 0;
- }
- char str[2];
- str[0] = p;
- str[1] = 0;
- Uint32 tmp = (val.val + (loop >> 1)) / loop;
-#if 1
- if(p > 0)
- out << tmp << str;
- else
- out << tmp;
-#else
- out << val.val;
-#endif
-
- return out;
-}
-
-void
-Backup::execBACKUP_CONF(Signal* signal)
-{
- jamEntry();
- BackupConf * conf = (BackupConf*)signal->getDataPtr();
-
- ndbout_c("Backup %d has started", conf->backupId);
-}
-
-void
-Backup::execBACKUP_REF(Signal* signal)
-{
- jamEntry();
- BackupRef * ref = (BackupRef*)signal->getDataPtr();
-
- ndbout_c("Backup (%d) has NOT started %d", ref->senderData, ref->errorCode);
-}
-
-void
-Backup::execBACKUP_COMPLETE_REP(Signal* signal)
-{
- jamEntry();
- BackupCompleteRep* rep = (BackupCompleteRep*)signal->getDataPtr();
-
- startTime = NdbTick_CurrentMillisecond() - startTime;
-
- ndbout_c("Backup %d has completed", rep->backupId);
- const Uint64 bytes =
- rep->noOfBytesLow + (((Uint64)rep->noOfBytesHigh) << 32);
- const Uint64 records =
- rep->noOfRecordsLow + (((Uint64)rep->noOfRecordsHigh) << 32);
-
- Number rps = xps(records, startTime);
- Number bps = xps(bytes, startTime);
-
- ndbout << " Data [ "
- << Number(records) << " rows "
- << Number(bytes) << " bytes " << startTime << " ms ] "
- << " => "
- << rps << " row/s & " << bps << "b/s" << endl;
-
- bps = xps(rep->noOfLogBytes, startTime);
- rps = xps(rep->noOfLogRecords, startTime);
-
- ndbout << " Log [ "
- << Number(rep->noOfLogRecords) << " log records "
- << Number(rep->noOfLogBytes) << " bytes " << startTime << " ms ] "
- << " => "
- << rps << " records/s & " << bps << "b/s" << endl;
-
-}
-
-void
-Backup::execBACKUP_ABORT_REP(Signal* signal)
-{
- jamEntry();
- BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtr();
-
- ndbout_c("Backup %d has been aborted %d", rep->backupId, rep->reason);
-}
-
-const TriggerEvent::Value triggerEventValues[] = {
- TriggerEvent::TE_INSERT,
- TriggerEvent::TE_UPDATE,
- TriggerEvent::TE_DELETE
-};
-
-const Backup::State
-Backup::validSlaveTransitions[] = {
- INITIAL, DEFINING,
- DEFINING, DEFINED,
- DEFINED, STARTED,
- STARTED, STARTED, // Several START_BACKUP_REQ is sent
- STARTED, SCANNING,
- SCANNING, STARTED,
- STARTED, STOPPING,
- STOPPING, CLEANING,
- CLEANING, INITIAL,
-
- INITIAL, ABORTING, // Node fail
- DEFINING, ABORTING,
- DEFINED, ABORTING,
- STARTED, ABORTING,
- SCANNING, ABORTING,
- STOPPING, ABORTING,
- CLEANING, ABORTING, // Node fail w/ master takeover
- ABORTING, ABORTING, // Slave who initiates ABORT should have this transition
-
- ABORTING, INITIAL,
- INITIAL, INITIAL
-};
-
-const Uint32
-Backup::validSlaveTransitionsCount =
-sizeof(Backup::validSlaveTransitions) / sizeof(Backup::State);
-
-void
-Backup::CompoundState::setState(State newState){
- bool found = false;
- const State currState = state;
- for(unsigned i = 0; i<noOfValidTransitions; i+= 2) {
- jam();
- if(validTransitions[i] == currState &&
- validTransitions[i+1] == newState){
- jam();
- found = true;
- break;
- }
- }
-
- //ndbrequire(found);
-
- if (newState == INITIAL)
- abortState = INITIAL;
- if(newState == ABORTING && currState != ABORTING) {
- jam();
- abortState = currState;
- }
- state = newState;
-#ifdef DEBUG_ABORT
- if (newState != currState) {
- ndbout_c("%u: Old state = %u, new state = %u, abort state = %u",
- id, currState, newState, abortState);
- }
-#endif
-}
-
-void
-Backup::CompoundState::forceState(State newState)
-{
- const State currState = state;
- if (newState == INITIAL)
- abortState = INITIAL;
- if(newState == ABORTING && currState != ABORTING) {
- jam();
- abortState = currState;
- }
- state = newState;
-#ifdef DEBUG_ABORT
- if (newState != currState) {
- ndbout_c("%u: FORCE: Old state = %u, new state = %u, abort state = %u",
- id, currState, newState, abortState);
- }
-#endif
-}
-
-Backup::Table::Table(ArrayPool<Attribute> & ah,
- ArrayPool<Fragment> & fh)
- : attributes(ah), fragments(fh)
-{
- triggerIds[0] = ILLEGAL_TRIGGER_ID;
- triggerIds[1] = ILLEGAL_TRIGGER_ID;
- triggerIds[2] = ILLEGAL_TRIGGER_ID;
- triggerAllocated[0] = false;
- triggerAllocated[1] = false;
- triggerAllocated[2] = false;
-}
-
-/*****************************************************************************
- *
- * Node state handling
- *
- *****************************************************************************/
-void
-Backup::execNODE_FAILREP(Signal* signal)
-{
- jamEntry();
-
- NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
-
- bool doStuff = false;
- /*
- Start by saving important signal data which will be destroyed before the
- process is completed.
- */
- NodeId new_master_node_id = rep->masterNodeId;
- Uint32 theFailedNodes[NodeBitmask::Size];
- for (Uint32 i = 0; i < NodeBitmask::Size; i++)
- theFailedNodes[i] = rep->theNodes[i];
-
- c_masterNodeId = new_master_node_id;
-
- NodePtr nodePtr;
- for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
- jam();
- if(NodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)){
- if(nodePtr.p->alive){
- jam();
- ndbrequire(c_aliveNodes.get(nodePtr.p->nodeId));
- doStuff = true;
- } else {
- jam();
- ndbrequire(!c_aliveNodes.get(nodePtr.p->nodeId));
- }//if
- nodePtr.p->alive = 0;
- c_aliveNodes.clear(nodePtr.p->nodeId);
- }//if
- }//for
-
- if(!doStuff){
- jam();
- return;
- }//if
-
-#ifdef DEBUG_ABORT
- ndbout_c("****************** Node fail rep ******************");
-#endif
-
- NodeId newCoordinator = c_masterNodeId;
- BackupRecordPtr ptr;
- for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
- jam();
- checkNodeFail(signal, ptr, newCoordinator, theFailedNodes);
- }
-}
-
-bool
-Backup::verifyNodesAlive(BackupRecordPtr ptr,
- const NdbNodeBitmask& aNodeBitMask)
-{
- Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
- for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
- jam();
- if(aNodeBitMask.get(i)) {
- if(!c_aliveNodes.get(i)){
- jam();
- ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
- return false;
- }//if
- if(getNodeInfo(i).m_version != version)
- {
- jam();
- ptr.p->setErrorCode(AbortBackupOrd::IncompatibleVersions);
- return false;
- }
- }//if
- }//for
- return true;
-}
-
-void
-Backup::checkNodeFail(Signal* signal,
- BackupRecordPtr ptr,
- NodeId newCoord,
- Uint32 theFailedNodes[NodeBitmask::Size])
-{
- NdbNodeBitmask mask;
- mask.assign(2, theFailedNodes);
-
- /* Update ptr.p->nodes to be up to date with current alive nodes
- */
- NodePtr nodePtr;
- bool found = false;
- for(c_nodes.first(nodePtr); nodePtr.i != RNIL; c_nodes.next(nodePtr)) {
- jam();
- if(NodeBitmask::get(theFailedNodes, nodePtr.p->nodeId)) {
- jam();
- if (ptr.p->nodes.get(nodePtr.p->nodeId)) {
- jam();
- ptr.p->nodes.clear(nodePtr.p->nodeId);
- found = true;
- }
- }//if
- }//for
-
- if(!found) {
- jam();
- return; // failed node is not part of backup process, safe to continue
- }
-
- if(mask.get(refToNode(ptr.p->masterRef)))
- {
- /**
- * Master died...abort
- */
- ptr.p->masterRef = reference();
- ptr.p->nodes.clear();
- ptr.p->nodes.set(getOwnNodeId());
- ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
- switch(ptr.p->m_gsn){
- case GSN_DEFINE_BACKUP_REQ:
- case GSN_START_BACKUP_REQ:
- case GSN_BACKUP_FRAGMENT_REQ:
- case GSN_STOP_BACKUP_REQ:
- // I'm currently processing...reply to self and abort...
- ptr.p->masterData.gsn = ptr.p->m_gsn;
- ptr.p->masterData.sendCounter = ptr.p->nodes;
- return;
- case GSN_DEFINE_BACKUP_REF:
- case GSN_DEFINE_BACKUP_CONF:
- case GSN_START_BACKUP_REF:
- case GSN_START_BACKUP_CONF:
- case GSN_BACKUP_FRAGMENT_REF:
- case GSN_BACKUP_FRAGMENT_CONF:
- case GSN_STOP_BACKUP_REF:
- case GSN_STOP_BACKUP_CONF:
- ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
- masterAbort(signal, ptr);
- return;
- case GSN_ABORT_BACKUP_ORD:
- // Already aborting
- return;
- }
- }
- else if (newCoord == getOwnNodeId())
- {
- /**
- * I'm master for this backup
- */
- jam();
- CRASH_INSERTION((10001));
-#ifdef DEBUG_ABORT
- ndbout_c("**** Master: Node failed: Master id = %u",
- refToNode(ptr.p->masterRef));
-#endif
-
- Uint32 gsn, len, pos;
- LINT_INIT(gsn);
- LINT_INIT(len);
- LINT_INIT(pos);
- ptr.p->nodes.bitANDC(mask);
- switch(ptr.p->masterData.gsn){
- case GSN_DEFINE_BACKUP_REQ:
- {
- DefineBackupRef * ref = (DefineBackupRef*)signal->getDataPtr();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
- gsn= GSN_DEFINE_BACKUP_REF;
- len= DefineBackupRef::SignalLength;
- pos= &ref->nodeId - signal->getDataPtr();
- break;
- }
- case GSN_START_BACKUP_REQ:
- {
- StartBackupRef * ref = (StartBackupRef*)signal->getDataPtr();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
- gsn= GSN_START_BACKUP_REF;
- len= StartBackupRef::SignalLength;
- pos= &ref->nodeId - signal->getDataPtr();
- break;
- }
- case GSN_BACKUP_FRAGMENT_REQ:
- {
- BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
- gsn= GSN_BACKUP_FRAGMENT_REF;
- len= BackupFragmentRef::SignalLength;
- pos= &ref->nodeId - signal->getDataPtr();
- break;
- }
- case GSN_STOP_BACKUP_REQ:
- {
- StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
- ref->nodeId = getOwnNodeId();
- gsn= GSN_STOP_BACKUP_REF;
- len= StopBackupRef::SignalLength;
- pos= &ref->nodeId - signal->getDataPtr();
- break;
- }
- case GSN_WAIT_GCP_REQ:
- case GSN_DROP_TRIG_REQ:
- case GSN_CREATE_TRIG_REQ:
- case GSN_ALTER_TRIG_REQ:
- ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
- return;
- case GSN_UTIL_SEQUENCE_REQ:
- case GSN_UTIL_LOCK_REQ:
- return;
- default:
- ndbrequire(false);
- }
-
- for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; )
- {
- signal->theData[pos] = i;
- sendSignal(reference(), gsn, signal, len, JBB);
-#ifdef DEBUG_ABORT
- ndbout_c("sending %d to self from %d", gsn, i);
-#endif
- }
- return;
- }//if
-
- /**
- * I abort myself as slave if not master
- */
- CRASH_INSERTION((10021));
-}
-
-void
-Backup::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
-
- const Uint32 senderRef = signal->theData[0];
- const Uint32 inclNode = signal->theData[1];
-
- NodePtr node;
- for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
- jam();
- const Uint32 nodeId = node.p->nodeId;
- if(inclNode == nodeId){
- jam();
-
- ndbrequire(node.p->alive == 0);
- ndbrequire(!c_aliveNodes.get(nodeId));
-
- node.p->alive = 1;
- c_aliveNodes.set(nodeId);
-
- break;
- }//if
- }//for
- signal->theData[0] = inclNode;
- signal->theData[1] = reference();
- sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB);
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Define backup
- *
- *****************************************************************************/
-
-void
-Backup::execBACKUP_REQ(Signal* signal)
-{
- jamEntry();
- BackupReq * req = (BackupReq*)signal->getDataPtr();
-
- const Uint32 senderData = req->senderData;
- const BlockReference senderRef = signal->senderBlockRef();
- const Uint32 dataLen32 = req->backupDataLen; // In 32 bit words
- const Uint32 flags = signal->getLength() > 2 ? req->flags : 2;
-
- if(getOwnNodeId() != getMasterNodeId()) {
- jam();
- sendBackupRef(senderRef, flags, signal, senderData, BackupRef::IAmNotMaster);
- return;
- }//if
-
- if (c_defaults.m_diskless)
- {
- sendBackupRef(senderRef, flags, signal, senderData,
- BackupRef::CannotBackupDiskless);
- return;
- }
-
- if(dataLen32 != 0) {
- jam();
- sendBackupRef(senderRef, flags, signal, senderData,
- BackupRef::BackupDefinitionNotImplemented);
- return;
- }//if
-
-#ifdef DEBUG_ABORT
- dumpUsedResources();
-#endif
- /**
- * Seize a backup record
- */
- BackupRecordPtr ptr;
- c_backups.seize(ptr);
- if(ptr.i == RNIL) {
- jam();
- sendBackupRef(senderRef, flags, signal, senderData, BackupRef::OutOfBackupRecord);
- return;
- }//if
-
- ndbrequire(ptr.p->tables.isEmpty());
-
- ptr.p->m_gsn = 0;
- ptr.p->errorCode = 0;
- ptr.p->clientRef = senderRef;
- ptr.p->clientData = senderData;
- ptr.p->flags = flags;
- ptr.p->masterRef = reference();
- ptr.p->nodes = c_aliveNodes;
- ptr.p->backupId = 0;
- ptr.p->backupKey[0] = 0;
- ptr.p->backupKey[1] = 0;
- ptr.p->backupDataLen = 0;
- ptr.p->masterData.errorCode = 0;
-
- UtilSequenceReq * utilReq = (UtilSequenceReq*)signal->getDataPtrSend();
-
- ptr.p->masterData.gsn = GSN_UTIL_SEQUENCE_REQ;
- utilReq->senderData = ptr.i;
- utilReq->sequenceId = BACKUP_SEQUENCE;
- utilReq->requestType = UtilSequenceReq::NextVal;
- sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
- signal, UtilSequenceReq::SignalLength, JBB);
-}
-
-void
-Backup::execUTIL_SEQUENCE_REF(Signal* signal)
-{
- BackupRecordPtr ptr LINT_SET_PTR;
- jamEntry();
- UtilSequenceRef * utilRef = (UtilSequenceRef*)signal->getDataPtr();
- ptr.i = utilRef->senderData;
- c_backupPool.getPtr(ptr);
- ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
- sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
-}//execUTIL_SEQUENCE_REF()
-
-
-void
-Backup::sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode)
-{
- jam();
- sendBackupRef(ptr.p->clientRef, ptr.p->flags, signal, ptr.p->clientData, errorCode);
- cleanup(signal, ptr);
-}
-
-void
-Backup::sendBackupRef(BlockReference senderRef, Uint32 flags, Signal *signal,
- Uint32 senderData, Uint32 errorCode)
-{
- jam();
- if (SEND_BACKUP_STARTED_FLAG(flags))
- {
- BackupRef* ref = (BackupRef*)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->errorCode = errorCode;
- ref->masterRef = numberToRef(BACKUP, getMasterNodeId());
- sendSignal(senderRef, GSN_BACKUP_REF, signal, BackupRef::SignalLength, JBB);
- }
-
- if(errorCode != BackupRef::IAmNotMaster){
- signal->theData[0] = NDB_LE_BackupFailedToStart;
- signal->theData[1] = senderRef;
- signal->theData[2] = errorCode;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }
-}
-
-void
-Backup::execUTIL_SEQUENCE_CONF(Signal* signal)
-{
- jamEntry();
-
- UtilSequenceConf * conf = (UtilSequenceConf*)signal->getDataPtr();
-
- if(conf->requestType == UtilSequenceReq::Create)
- {
- jam();
- sendSTTORRY(signal); // At startup in NDB
- return;
- }
-
- BackupRecordPtr ptr LINT_SET_PTR;
- ptr.i = conf->senderData;
- c_backupPool.getPtr(ptr);
-
- ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
-
- if (ptr.p->checkError())
- {
- jam();
- sendBackupRef(signal, ptr, ptr.p->errorCode);
- return;
- }//if
-
- if (ERROR_INSERTED(10023))
- {
- sendBackupRef(signal, ptr, 323);
- return;
- }//if
-
-
- {
- Uint64 backupId;
- memcpy(&backupId,conf->sequenceValue,8);
- ptr.p->backupId= (Uint32)backupId;
- }
- ptr.p->backupKey[0] = (getOwnNodeId() << 16) | (ptr.p->backupId & 0xFFFF);
- ptr.p->backupKey[1] = NdbTick_CurrentMillisecond();
-
- ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
- Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
- Callback c = { safe_cast(&Backup::defineBackupMutex_locked), ptr.i };
- ndbrequire(mutex.lock(c));
-
- return;
-}
-
-void
-Backup::defineBackupMutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
- jamEntry();
- ndbrequire(retVal == 0);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- ptr.i = ptrI;
- c_backupPool.getPtr(ptr);
-
- ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
-
- ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
- Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
- Callback c = { safe_cast(&Backup::dictCommitTableMutex_locked), ptr.i };
- ndbrequire(mutex.lock(c));
-}
-
-void
-Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
-{
- jamEntry();
- ndbrequire(retVal == 0);
-
- /**
- * We now have both the mutexes
- */
- BackupRecordPtr ptr LINT_SET_PTR;
- ptr.i = ptrI;
- c_backupPool.getPtr(ptr);
-
- ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
-
- if (ERROR_INSERTED(10031)) {
- ptr.p->setErrorCode(331);
- }//if
-
- if (ptr.p->checkError())
- {
- jam();
-
- /**
- * Unlock mutexes
- */
- jam();
- Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
- jam();
- mutex1.unlock(); // ignore response
-
- jam();
- Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
- jam();
- mutex2.unlock(); // ignore response
-
- sendBackupRef(signal, ptr, ptr.p->errorCode);
- return;
- }//if
-
- sendDefineBackupReq(signal, ptr);
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Define backup cont'd (from now on all slaves are in)
- *
- *****************************************************************************/
-
-bool
-Backup::haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId)
-{
- ndbrequire(ptr.p->masterRef == reference());
- ndbrequire(ptr.p->masterData.gsn == gsn);
- ndbrequire(!ptr.p->masterData.sendCounter.done());
- ndbrequire(ptr.p->masterData.sendCounter.isWaitingFor(nodeId));
-
- ptr.p->masterData.sendCounter.clearWaitingFor(nodeId);
- return ptr.p->masterData.sendCounter.done();
-}
-
-void
-Backup::sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr)
-{
- /**
- * Sending define backup to all participants
- */
- DefineBackupReq * req = (DefineBackupReq*)signal->getDataPtrSend();
- req->backupId = ptr.p->backupId;
- req->clientRef = ptr.p->clientRef;
- req->clientData = ptr.p->clientData;
- req->senderRef = reference();
- req->backupPtr = ptr.i;
- req->backupKey[0] = ptr.p->backupKey[0];
- req->backupKey[1] = ptr.p->backupKey[1];
- req->nodes = ptr.p->nodes;
- req->backupDataLen = ptr.p->backupDataLen;
- req->flags = ptr.p->flags;
-
- ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
- ptr.p->masterData.sendCounter = ptr.p->nodes;
- NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
- sendSignal(rg, GSN_DEFINE_BACKUP_REQ, signal,
- DefineBackupReq::SignalLength, JBB);
-
- /**
- * Now send backup data
- */
- const Uint32 len = ptr.p->backupDataLen;
- if(len == 0){
- /**
- * No data to send
- */
- jam();
- return;
- }//if
-
- /**
- * Not implemented
- */
- ndbrequire(0);
-}
-
-void
-Backup::execDEFINE_BACKUP_REF(Signal* signal)
-{
- jamEntry();
-
- DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtr();
-
- const Uint32 ptrI = ref->backupPtr;
- //const Uint32 backupId = ref->backupId;
- const Uint32 nodeId = ref->nodeId;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->setErrorCode(ref->errorCode);
- defineBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::execDEFINE_BACKUP_CONF(Signal* signal)
-{
- jamEntry();
-
- DefineBackupConf* conf = (DefineBackupConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->backupPtr;
- //const Uint32 backupId = conf->backupId;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- if (ERROR_INSERTED(10024))
- {
- ptr.p->setErrorCode(324);
- }
-
- defineBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
-{
- if (!haveAllSignals(ptr, GSN_DEFINE_BACKUP_REQ, nodeId)) {
- jam();
- return;
- }
-
- /**
- * Unlock mutexes
- */
- jam();
- Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
- jam();
- mutex1.unlock(); // ignore response
-
- jam();
- Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
- jam();
- mutex2.unlock(); // ignore response
-
- if(ptr.p->checkError())
- {
- jam();
- masterAbort(signal, ptr);
- return;
- }
-
- /**
- * Reply to client
- */
- CRASH_INSERTION((10034));
-
- if (SEND_BACKUP_STARTED_FLAG(ptr.p->flags))
- {
- BackupConf * conf = (BackupConf*)signal->getDataPtrSend();
- conf->backupId = ptr.p->backupId;
- conf->senderData = ptr.p->clientData;
- conf->nodes = ptr.p->nodes;
- sendSignal(ptr.p->clientRef, GSN_BACKUP_CONF, signal,
- BackupConf::SignalLength, JBB);
- }
-
- signal->theData[0] = NDB_LE_BackupStarted;
- signal->theData[1] = ptr.p->clientRef;
- signal->theData[2] = ptr.p->backupId;
- ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+3);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3+NdbNodeBitmask::Size, JBB);
-
- /**
- * We've received GSN_DEFINE_BACKUP_CONF from all participants.
- *
- * Our next step is to send START_BACKUP_REQ to all participants,
- * who will then send CREATE_TRIG_REQ for all tables to their local
- * DBTUP.
- */
- TablePtr tabPtr;
- ptr.p->tables.first(tabPtr);
-
- sendStartBackup(signal, ptr, tabPtr);
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Prepare triggers
- *
- *****************************************************************************/
-void
-Backup::createAttributeMask(TablePtr tabPtr,
- Bitmask<MAXNROFATTRIBUTESINWORDS> & mask)
-{
- mask.clear();
- Table & table = * tabPtr.p;
- Ptr<Attribute> attrPtr;
- table.attributes.first(attrPtr);
- for(; !attrPtr.isNull(); table.attributes.next(attrPtr))
- {
- jam();
- mask.set(attrPtr.p->data.attrId);
- }
-}
-
-void
-Backup::sendCreateTrig(Signal* signal,
- BackupRecordPtr ptr, TablePtr tabPtr)
-{
- CreateTrigReq * req =(CreateTrigReq *)signal->getDataPtrSend();
-
- /*
- * First, setup the structures
- */
- for(Uint32 j=0; j<3; j++) {
- jam();
-
- TriggerPtr trigPtr;
- if(!ptr.p->triggers.seize(trigPtr)) {
- jam();
- ptr.p->m_gsn = GSN_START_BACKUP_REF;
- StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = StartBackupRef::FailedToAllocateTriggerRecord;
- ref->nodeId = getOwnNodeId();
- sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
- StartBackupRef::SignalLength, JBB);
- return;
- } // if
-
- const Uint32 triggerId= trigPtr.i;
- tabPtr.p->triggerIds[j] = triggerId;
- tabPtr.p->triggerAllocated[j] = true;
- trigPtr.p->backupPtr = ptr.i;
- trigPtr.p->tableId = tabPtr.p->tableId;
- trigPtr.p->tab_ptr_i = tabPtr.i;
- trigPtr.p->logEntry = 0;
- trigPtr.p->event = j;
- trigPtr.p->maxRecordSize = 4096;
- trigPtr.p->operation =
- &ptr.p->files.getPtr(ptr.p->logFilePtr)->operation;
- trigPtr.p->operation->noOfBytes = 0;
- trigPtr.p->operation->noOfRecords = 0;
- trigPtr.p->errorCode = 0;
- } // for
-
- /*
- * now ask DBTUP to create
- */
- ptr.p->slaveData.gsn = GSN_CREATE_TRIG_REQ;
- ptr.p->slaveData.trigSendCounter = 3;
- ptr.p->slaveData.createTrig.tableId = tabPtr.p->tableId;
-
- req->setUserRef(reference());
- req->setReceiverRef(reference());
- req->setConnectionPtr(ptr.i);
- req->setRequestType(CreateTrigReq::RT_USER);
-
- Bitmask<MAXNROFATTRIBUTESINWORDS> attrMask;
- createAttributeMask(tabPtr, attrMask);
- req->setAttributeMask(attrMask);
- req->setTableId(tabPtr.p->tableId);
- req->setIndexId(RNIL); // not used
- req->setTriggerType(TriggerType::SUBSCRIPTION);
- req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
- req->setMonitorReplicas(true);
- req->setMonitorAllAttributes(false);
- req->setOnline(true);
-
- for (int i=0; i < 3; i++) {
- req->setTriggerId(tabPtr.p->triggerIds[i]);
- req->setTriggerEvent(triggerEventValues[i]);
-
- sendSignal(DBTUP_REF, GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB);
- }
-}
-
-void
-Backup::execCREATE_TRIG_CONF(Signal* signal)
-{
- jamEntry();
- CreateTrigConf * conf = (CreateTrigConf*)signal->getDataPtr();
-
- const Uint32 ptrI = conf->getConnectionPtr();
- const Uint32 tableId = conf->getTableId();
- const TriggerEvent::Value type = conf->getTriggerEvent();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- /**
- * Verify that I'm waiting for this conf
- *
- * ptr.p->masterRef != reference()
- * as slaves and masters have triggers now.
- */
- ndbrequire(ptr.p->slaveData.gsn == GSN_CREATE_TRIG_REQ);
- ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
- ndbrequire(ptr.p->slaveData.createTrig.tableId == tableId);
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, tableId));
- ndbrequire(type < 3); // if some decides to change the enums
-
- createTrigReply(signal, ptr);
-}
-
-void
-Backup::execCREATE_TRIG_REF(Signal* signal)
-{
- jamEntry();
- CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtr();
-
- const Uint32 ptrI = ref->getConnectionPtr();
- const Uint32 tableId = ref->getTableId();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- /**
- * Verify that I'm waiting for this ref
- *
- * ptr.p->masterRef != reference()
- * as slaves and masters have triggers now
- */
- ndbrequire(ptr.p->slaveData.gsn == GSN_CREATE_TRIG_REQ);
- ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
- ndbrequire(ptr.p->slaveData.createTrig.tableId == tableId);
-
- ptr.p->setErrorCode(ref->getErrorCode());
-
- createTrigReply(signal, ptr);
-}
-
-void
-Backup::createTrigReply(Signal* signal, BackupRecordPtr ptr)
-{
- CRASH_INSERTION(10003);
-
- /**
- * Check finished with table
- */
- ptr.p->slaveData.trigSendCounter--;
- if(ptr.p->slaveData.trigSendCounter.done() == false){
- jam();
- return;
- }//if
-
- if (ERROR_INSERTED(10025))
- {
- ptr.p->errorCode = 325;
- }
-
- if(ptr.p->checkError()) {
- jam();
- ptr.p->m_gsn = GSN_START_BACKUP_REF;
- StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = ptr.p->errorCode;
- ref->nodeId = getOwnNodeId();
- sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
- StartBackupRef::SignalLength, JBB);
- return;
- }//if
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, ptr.p->slaveData.createTrig.tableId));
-
- /**
- * Next table
- */
- ptr.p->tables.next(tabPtr);
- if(tabPtr.i != RNIL){
- jam();
- sendCreateTrig(signal, ptr, tabPtr);
- return;
- }//if
-
- /**
- * We've finished creating triggers.
- *
- * send conf and wait
- */
- ptr.p->m_gsn = GSN_START_BACKUP_CONF;
- StartBackupConf* conf = (StartBackupConf*)signal->getDataPtrSend();
- conf->backupPtr = ptr.i;
- conf->backupId = ptr.p->backupId;
- sendSignal(ptr.p->masterRef, GSN_START_BACKUP_CONF, signal,
- StartBackupConf::SignalLength, JBB);
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Start backup
- *
- *****************************************************************************/
-void
-Backup::sendStartBackup(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
-{
-
- ptr.p->masterData.startBackup.tablePtr = tabPtr.i;
-
- StartBackupReq* req = (StartBackupReq*)signal->getDataPtrSend();
- req->backupId = ptr.p->backupId;
- req->backupPtr = ptr.i;
-
- /**
- * We use trigger Ids that are unique to BACKUP.
- * These don't interfere with other triggers (e.g. from DBDICT)
- * as there is a special case in DBTUP.
- *
- * Consequently, backups during online upgrade won't work
- */
- ptr.p->masterData.gsn = GSN_START_BACKUP_REQ;
- ptr.p->masterData.sendCounter = ptr.p->nodes;
- NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
- sendSignal(rg, GSN_START_BACKUP_REQ, signal,
- StartBackupReq::SignalLength, JBB);
-}
-
-void
-Backup::execSTART_BACKUP_REF(Signal* signal)
-{
- jamEntry();
-
- StartBackupRef* ref = (StartBackupRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->backupPtr;
- //const Uint32 backupId = ref->backupId;
- const Uint32 nodeId = ref->nodeId;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->setErrorCode(ref->errorCode);
- startBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::execSTART_BACKUP_CONF(Signal* signal)
-{
- jamEntry();
-
- StartBackupConf* conf = (StartBackupConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->backupPtr;
- //const Uint32 backupId = conf->backupId;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- startBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::startBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
-{
-
- CRASH_INSERTION((10004));
-
- if (!haveAllSignals(ptr, GSN_START_BACKUP_REQ, nodeId)) {
- jam();
- return;
- }
-
- if (ERROR_INSERTED(10026))
- {
- ptr.p->errorCode = 326;
- }
-
- if(ptr.p->checkError()){
- jam();
- masterAbort(signal, ptr);
- return;
- }
-
- /**
- * Wait for GCP
- */
- ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
- ptr.p->masterData.waitGCP.startBackup = true;
-
- WaitGCPReq * waitGCPReq = (WaitGCPReq*)signal->getDataPtrSend();
- waitGCPReq->senderRef = reference();
- waitGCPReq->senderData = ptr.i;
- waitGCPReq->requestType = WaitGCPReq::CompleteForceStart;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength,JBB);
-}
-
-void
-Backup::execWAIT_GCP_REF(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10006));
-
- WaitGCPRef * ref = (WaitGCPRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->senderData;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ndbrequire(ptr.p->masterRef == reference());
- ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
-
- WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = ptr.i;
- req->requestType = WaitGCPReq::CompleteForceStart;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength,JBB);
-}
-
-void
-Backup::execWAIT_GCP_CONF(Signal* signal){
- jamEntry();
-
- CRASH_INSERTION((10007));
-
- WaitGCPConf * conf = (WaitGCPConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->senderData;
- const Uint32 gcp = conf->gcp;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ndbrequire(ptr.p->masterRef == reference());
- ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
-
- if(ptr.p->checkError()) {
- jam();
- masterAbort(signal, ptr);
- return;
- }//if
-
- if(ptr.p->masterData.waitGCP.startBackup) {
- jam();
- CRASH_INSERTION((10008));
- ptr.p->startGCP = gcp;
- ptr.p->masterData.sendCounter= 0;
- ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ;
- nextFragment(signal, ptr);
- return;
- } else {
- jam();
- if(gcp >= ptr.p->startGCP + 3)
- {
- CRASH_INSERTION((10009));
- ptr.p->stopGCP = gcp;
- /**
- * Backup is complete - begin cleanup
- * STOP_BACKUP_REQ is sent to participants.
- * They then drop the local triggers
- */
- sendStopBackup(signal, ptr);
- return;
- }//if
-
- /**
- * Make sure that we got entire stopGCP
- */
- WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = ptr.i;
- req->requestType = WaitGCPReq::CompleteForceStart;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength,JBB);
- return;
- }
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Backup fragment
- *
- *****************************************************************************/
-void
-Backup::nextFragment(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtrSend();
- req->backupPtr = ptr.i;
- req->backupId = ptr.p->backupId;
-
- NodeBitmask nodes = ptr.p->nodes;
- Uint32 idleNodes = nodes.count();
- Uint32 saveIdleNodes = idleNodes;
- ndbrequire(idleNodes > 0);
-
- TablePtr tabPtr;
- ptr.p->tables.first(tabPtr);
- for(; tabPtr.i != RNIL && idleNodes > 0; ptr.p->tables.next(tabPtr)) {
- jam();
- FragmentPtr fragPtr;
- Array<Fragment> & frags = tabPtr.p->fragments;
- const Uint32 fragCount = frags.getSize();
-
- for(Uint32 i = 0; i<fragCount && idleNodes > 0; i++) {
- jam();
- tabPtr.p->fragments.getPtr(fragPtr, i);
- const Uint32 nodeId = fragPtr.p->node;
- if(fragPtr.p->scanning != 0) {
- jam();
- ndbrequire(nodes.get(nodeId));
- nodes.clear(nodeId);
- idleNodes--;
- } else if(fragPtr.p->scanned == 0 && nodes.get(nodeId)){
- jam();
- fragPtr.p->scanning = 1;
- nodes.clear(nodeId);
- idleNodes--;
-
- req->tableId = tabPtr.p->tableId;
- req->fragmentNo = i;
- req->count = 0;
-
- ptr.p->masterData.sendCounter++;
- const BlockReference ref = numberToRef(BACKUP, nodeId);
- sendSignal(ref, GSN_BACKUP_FRAGMENT_REQ, signal,
- BackupFragmentReq::SignalLength, JBB);
- }//if
- }//for
- }//for
-
- if(idleNodes != saveIdleNodes){
- jam();
- return;
- }//if
-
- /**
- * Finished with all tables
- */
- {
- ptr.p->masterData.gsn = GSN_WAIT_GCP_REQ;
- ptr.p->masterData.waitGCP.startBackup = false;
-
- WaitGCPReq * req = (WaitGCPReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = ptr.i;
- req->requestType = WaitGCPReq::CompleteForceStart;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
- }
-}
-
-void
-Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10010));
-
- BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->backupPtr;
- //const Uint32 backupId = conf->backupId;
- const Uint32 tableId = conf->tableId;
- const Uint32 fragmentNo = conf->fragmentNo;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
- const Uint64 noOfBytes =
- conf->noOfBytesLow + (((Uint64)conf->noOfBytesHigh) << 32);
- const Uint64 noOfRecords =
- conf->noOfRecordsLow + (((Uint64)conf->noOfRecordsHigh) << 32);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->noOfBytes += noOfBytes;
- ptr.p->noOfRecords += noOfRecords;
- ptr.p->masterData.sendCounter--;
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, tableId));
-
- tabPtr.p->noOfRecords += noOfRecords;
-
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragmentNo);
-
- fragPtr.p->noOfRecords = noOfRecords;
-
- ndbrequire(fragPtr.p->scanned == 0);
- ndbrequire(fragPtr.p->scanning == 1);
- ndbrequire(fragPtr.p->node == nodeId);
-
- fragPtr.p->scanned = 1;
- fragPtr.p->scanning = 0;
-
- if (ERROR_INSERTED(10028))
- {
- ptr.p->errorCode = 328;
- }
-
- if(ptr.p->checkError())
- {
- if(ptr.p->masterData.sendCounter.done())
- {
- jam();
- masterAbort(signal, ptr);
- return;
- }//if
- }
- else
- {
- NodeBitmask nodes = ptr.p->nodes;
- nodes.clear(getOwnNodeId());
- if (!nodes.isclear())
- {
- BackupFragmentCompleteRep *rep =
- (BackupFragmentCompleteRep*)signal->getDataPtrSend();
- rep->backupId = ptr.p->backupId;
- rep->backupPtr = ptr.i;
- rep->tableId = tableId;
- rep->fragmentNo = fragmentNo;
- rep->noOfTableRowsLow = (Uint32)(tabPtr.p->noOfRecords & 0xFFFFFFFF);
- rep->noOfTableRowsHigh = (Uint32)(tabPtr.p->noOfRecords >> 32);
- rep->noOfFragmentRowsLow = (Uint32)(noOfRecords & 0xFFFFFFFF);
- rep->noOfFragmentRowsHigh = (Uint32)(noOfRecords >> 32);
- NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
- sendSignal(rg, GSN_BACKUP_FRAGMENT_COMPLETE_REP, signal,
- BackupFragmentCompleteRep::SignalLength, JBB);
- }
- nextFragment(signal, ptr);
- }
-}
-
-void
-Backup::execBACKUP_FRAGMENT_REF(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10011));
-
- BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->backupPtr;
- //const Uint32 backupId = ref->backupId;
- const Uint32 nodeId = ref->nodeId;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- TablePtr tabPtr;
- ptr.p->tables.first(tabPtr);
- for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
- jam();
- FragmentPtr fragPtr;
- Array<Fragment> & frags = tabPtr.p->fragments;
- const Uint32 fragCount = frags.getSize();
-
- for(Uint32 i = 0; i<fragCount; i++) {
- jam();
- tabPtr.p->fragments.getPtr(fragPtr, i);
- if(fragPtr.p->scanning != 0 && nodeId == fragPtr.p->node)
- {
- jam();
- ndbrequire(fragPtr.p->scanned == 0);
- fragPtr.p->scanned = 1;
- fragPtr.p->scanning = 0;
- goto done;
- }
- }
- }
- goto err;
-
-done:
- ptr.p->masterData.sendCounter--;
- ptr.p->setErrorCode(ref->errorCode);
-
- if(ptr.p->masterData.sendCounter.done())
- {
- jam();
- masterAbort(signal, ptr);
- return;
- }//if
-
-err:
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->requestType = AbortBackupOrd::LogBufferFull;
- ord->senderData= ptr.i;
- execABORT_BACKUP_ORD(signal);
-}
-
-void
-Backup::execBACKUP_FRAGMENT_COMPLETE_REP(Signal* signal)
-{
- jamEntry();
- BackupFragmentCompleteRep * rep =
- (BackupFragmentCompleteRep*)signal->getDataPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, rep->backupPtr);
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, rep->tableId));
-
- tabPtr.p->noOfRecords =
- rep->noOfTableRowsLow + (((Uint64)rep->noOfTableRowsHigh) << 32);
-
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, rep->fragmentNo);
-
- fragPtr.p->noOfRecords =
- rep->noOfFragmentRowsLow + (((Uint64)rep->noOfFragmentRowsHigh) << 32);
-}
-
-/*****************************************************************************
- *
- * Slave functionallity - Drop triggers
- *
- *****************************************************************************/
-
-void
-Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr)
-{
- TablePtr tabPtr;
- ptr.p->slaveData.gsn = GSN_DROP_TRIG_REQ;
-
- if (ptr.p->slaveData.dropTrig.tableId == RNIL) {
- jam();
- if(ptr.p->tables.count())
- ptr.p->tables.first(tabPtr);
- else
- {
- // Early abort, go to close files
- jam();
- closeFiles(signal, ptr);
- return;
- }
- } else {
- jam();
- ndbrequire(findTable(ptr, tabPtr, ptr.p->slaveData.dropTrig.tableId));
- ptr.p->tables.next(tabPtr);
- }//if
- if (tabPtr.i != RNIL) {
- jam();
- sendDropTrig(signal, ptr, tabPtr);
- } else {
- /**
- * Insert footers
- */
- //if backup error, we needn't insert footers
- if(ptr.p->checkError())
- {
- jam();
- closeFiles(signal, ptr);
- ptr.p->errorCode = 0;
- return;
- }
-
- {
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
- Uint32 * dst;
- LINT_INIT(dst);
- ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, 1));
- * dst = 0;
- filePtr.p->operation.dataBuffer.updateWritePtr(1);
- }
-
- {
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
-
- const Uint32 gcpSz = sizeof(BackupFormat::CtlFile::GCPEntry) >> 2;
-
- Uint32 * dst;
- LINT_INIT(dst);
- ndbrequire(filePtr.p->operation.dataBuffer.getWritePtr(&dst, gcpSz));
-
- BackupFormat::CtlFile::GCPEntry * gcp =
- (BackupFormat::CtlFile::GCPEntry*)dst;
-
- gcp->SectionType = htonl(BackupFormat::GCP_ENTRY);
- gcp->SectionLength = htonl(gcpSz);
- gcp->StartGCP = htonl(ptr.p->startGCP);
- gcp->StopGCP = htonl(ptr.p->stopGCP - 1);
- filePtr.p->operation.dataBuffer.updateWritePtr(gcpSz);
-
- {
- TablePtr tabPtr;
- if (ptr.p->tables.first(tabPtr))
- {
- jam();
- signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
- signal->theData[1] = ptr.i;
- signal->theData[2] = tabPtr.i;
- signal->theData[3] = 0;
- sendSignal(BACKUP_REF, GSN_CONTINUEB, signal, 4, JBB);
- }
- else
- {
- jam();
- closeFiles(signal, ptr);
- }
- }
- }
- }
-}
-
-void
-Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
-{
- jam();
- DropTrigReq * req = (DropTrigReq *)signal->getDataPtrSend();
-
- ptr.p->slaveData.gsn = GSN_DROP_TRIG_REQ;
- ptr.p->slaveData.trigSendCounter = 0;
- req->setConnectionPtr(ptr.i);
- req->setUserRef(reference()); // Sending to myself
- req->setRequestType(DropTrigReq::RT_USER);
- req->setIndexId(RNIL);
- req->setTriggerInfo(0); // not used on DROP
- req->setTriggerType(TriggerType::SUBSCRIPTION);
- req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
-
- ptr.p->slaveData.dropTrig.tableId = tabPtr.p->tableId;
- req->setTableId(tabPtr.p->tableId);
-
- for (int i = 0; i < 3; i++) {
- Uint32 id = tabPtr.p->triggerIds[i];
- req->setTriggerId(id);
- req->setTriggerEvent(triggerEventValues[i]);
- sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- ptr.p->slaveData.trigSendCounter ++;
- }
-}
-
-void
-Backup::execDROP_TRIG_REF(Signal* signal)
-{
- jamEntry();
-
- DropTrigRef* ref = (DropTrigRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->getConnectionPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- if(ref->getConf()->getTriggerId() != ~(Uint32) 0)
- {
- ndbout << "ERROR DROPPING TRIGGER: " << ref->getConf()->getTriggerId();
- ndbout << " Err: " << (Uint32)ref->getErrorCode() << endl << endl;
- }
-
- dropTrigReply(signal, ptr);
-}
-
-void
-Backup::execDROP_TRIG_CONF(Signal* signal)
-{
- jamEntry();
-
- DropTrigConf* conf = (DropTrigConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->getConnectionPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- dropTrigReply(signal, ptr);
-}
-
-void
-Backup::dropTrigReply(Signal* signal, BackupRecordPtr ptr)
-{
- CRASH_INSERTION((10012));
-
- ndbrequire(ptr.p->slaveData.gsn == GSN_DROP_TRIG_REQ);
- ndbrequire(ptr.p->slaveData.trigSendCounter.done() == false);
-
- // move from .masterData to .slaveData
- ptr.p->slaveData.trigSendCounter--;
- if(ptr.p->slaveData.trigSendCounter.done() == false){
- jam();
- return;
- }//if
-
- sendDropTrig(signal, ptr); // recursive next
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Stop backup
- *
- *****************************************************************************/
-void
-Backup::execSTOP_BACKUP_REF(Signal* signal)
-{
- jamEntry();
-
- StopBackupRef* ref = (StopBackupRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->backupPtr;
- //const Uint32 backupId = ref->backupId;
- const Uint32 nodeId = ref->nodeId;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->setErrorCode(ref->errorCode);
- stopBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::sendStopBackup(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- StopBackupReq* stop = (StopBackupReq*)signal->getDataPtrSend();
- stop->backupPtr = ptr.i;
- stop->backupId = ptr.p->backupId;
- stop->startGCP = ptr.p->startGCP;
- stop->stopGCP = ptr.p->stopGCP;
-
- ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
- ptr.p->masterData.sendCounter = ptr.p->nodes;
- NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
- sendSignal(rg, GSN_STOP_BACKUP_REQ, signal,
- StopBackupReq::SignalLength, JBB);
-}
-
-void
-Backup::execSTOP_BACKUP_CONF(Signal* signal)
-{
- jamEntry();
-
- StopBackupConf* conf = (StopBackupConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->backupPtr;
- //const Uint32 backupId = conf->backupId;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->noOfLogBytes += conf->noOfLogBytes;
- ptr.p->noOfLogRecords += conf->noOfLogRecords;
-
- stopBackupReply(signal, ptr, nodeId);
-}
-
-void
-Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
-{
- CRASH_INSERTION((10013));
-
- if (!haveAllSignals(ptr, GSN_STOP_BACKUP_REQ, nodeId)) {
- jam();
- return;
- }
-
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupComplete);
-
- if(!ptr.p->checkError())
- {
- if (SEND_BACKUP_COMPLETED_FLAG(ptr.p->flags))
- {
- BackupCompleteRep * rep = (BackupCompleteRep*)signal->getDataPtrSend();
- rep->backupId = ptr.p->backupId;
- rep->senderData = ptr.p->clientData;
- rep->startGCP = ptr.p->startGCP;
- rep->stopGCP = ptr.p->stopGCP;
- rep->noOfBytesLow = (Uint32)(ptr.p->noOfBytes & 0xFFFFFFFF);
- rep->noOfRecordsLow = (Uint32)(ptr.p->noOfRecords & 0xFFFFFFFF);
- rep->noOfBytesHigh = (Uint32)(ptr.p->noOfBytes >> 32);
- rep->noOfRecordsHigh = (Uint32)(ptr.p->noOfRecords >> 32);
- rep->noOfLogBytes = ptr.p->noOfLogBytes;
- rep->noOfLogRecords = ptr.p->noOfLogRecords;
- rep->nodes = ptr.p->nodes;
- sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal,
- BackupCompleteRep::SignalLength, JBB);
- }
-
- signal->theData[0] = NDB_LE_BackupCompleted;
- signal->theData[1] = ptr.p->clientRef;
- signal->theData[2] = ptr.p->backupId;
- signal->theData[3] = ptr.p->startGCP;
- signal->theData[4] = ptr.p->stopGCP;
- signal->theData[5] = (Uint32)(ptr.p->noOfBytes & 0xFFFFFFFF);
- signal->theData[6] = (Uint32)(ptr.p->noOfRecords & 0xFFFFFFFF);
- signal->theData[7] = ptr.p->noOfLogBytes;
- signal->theData[8] = ptr.p->noOfLogRecords;
- ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9);
- signal->theData[9+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfBytes >> 32);
- signal->theData[10+NdbNodeBitmask::Size] = (Uint32)(ptr.p->noOfRecords >> 32);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 11+NdbNodeBitmask::Size, JBB);
- }
- else
- {
- masterAbort(signal, ptr);
- }
-}
-
-/*****************************************************************************
- *
- * Master functionallity - Abort backup
- *
- *****************************************************************************/
-void
-Backup::masterAbort(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-#ifdef DEBUG_ABORT
- ndbout_c("************ masterAbort");
-#endif
-
- ndbassert(ptr.p->masterRef == reference());
-
- if(ptr.p->masterData.errorCode != 0)
- {
- jam();
- return;
- }
-
- if (SEND_BACKUP_COMPLETED_FLAG(ptr.p->flags))
- {
- BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtrSend();
- rep->backupId = ptr.p->backupId;
- rep->senderData = ptr.p->clientData;
- rep->reason = ptr.p->errorCode;
- sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal,
- BackupAbortRep::SignalLength, JBB);
- }
- signal->theData[0] = NDB_LE_BackupAborted;
- signal->theData[1] = ptr.p->clientRef;
- signal->theData[2] = ptr.p->backupId;
- signal->theData[3] = ptr.p->errorCode;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- ndbrequire(ptr.p->errorCode);
- ptr.p->masterData.errorCode = ptr.p->errorCode;
-
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->senderData= ptr.i;
- NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
-
- switch(ptr.p->masterData.gsn){
- case GSN_DEFINE_BACKUP_REQ:
- ord->requestType = AbortBackupOrd::BackupFailure;
- sendSignal(rg, GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
- return;
- case GSN_CREATE_TRIG_REQ:
- case GSN_START_BACKUP_REQ:
- case GSN_ALTER_TRIG_REQ:
- case GSN_WAIT_GCP_REQ:
- case GSN_BACKUP_FRAGMENT_REQ:
- jam();
- ptr.p->stopGCP= ptr.p->startGCP + 1;
- sendStopBackup(signal, ptr); // dropping due to error
- return;
- case GSN_UTIL_SEQUENCE_REQ:
- case GSN_UTIL_LOCK_REQ:
- ndbrequire(false);
- return;
- case GSN_DROP_TRIG_REQ:
- case GSN_STOP_BACKUP_REQ:
- return;
- }
-}
-
-void
-Backup::abort_scan(Signal * signal, BackupRecordPtr ptr)
-{
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->senderData= ptr.i;
- ord->requestType = AbortBackupOrd::AbortScan;
-
- TablePtr tabPtr;
- ptr.p->tables.first(tabPtr);
- for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
- jam();
- FragmentPtr fragPtr;
- Array<Fragment> & frags = tabPtr.p->fragments;
- const Uint32 fragCount = frags.getSize();
-
- for(Uint32 i = 0; i<fragCount; i++) {
- jam();
- tabPtr.p->fragments.getPtr(fragPtr, i);
- const Uint32 nodeId = fragPtr.p->node;
- if(fragPtr.p->scanning != 0 && ptr.p->nodes.get(nodeId)) {
- jam();
-
- const BlockReference ref = numberToRef(BACKUP, nodeId);
- sendSignal(ref, GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
-
- }
- }
- }
-}
-
-/*****************************************************************************
- *
- * Slave functionallity: Define Backup
- *
- *****************************************************************************/
-void
-Backup::defineBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errCode)
-{
- jam();
- ptr.p->setErrorCode(errCode);
- if(ptr.p->is_lcp())
- {
- jam();
- if (ptr.p->ctlFilePtr == RNIL) {
- ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
- ndbrequire(ptr.p->errorCode != 0);
- DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
- ref->backupId = ptr.p->backupId;
- ref->backupPtr = ptr.i;
- ref->errorCode = ptr.p->errorCode;
- ref->nodeId = getOwnNodeId();
- sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
- DefineBackupRef::SignalLength, JBB);
- return;
- }
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- if (filePtr.p->m_flags & BackupFile::BF_LCP_META)
- {
- jam();
- ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_FILE_THREAD));
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_LCP_META;
- if (filePtr.p->m_flags & BackupFile::BF_OPEN)
- {
- closeFile(signal, ptr, filePtr);
- return;
- }
- }
-
- ndbrequire(filePtr.p->m_flags == 0);
-
- TablePtr tabPtr;
- FragmentPtr fragPtr;
-
- ndbrequire(ptr.p->tables.first(tabPtr));
- tabPtr.p->fragments.getPtr(fragPtr, 0);
-
- LcpPrepareRef* ref= (LcpPrepareRef*)signal->getDataPtrSend();
- ref->senderData = ptr.p->clientData;
- ref->senderRef = reference();
- ref->tableId = tabPtr.p->tableId;
- ref->fragmentId = fragPtr.p->fragmentId;
- ref->errorCode = errCode;
- sendSignal(ptr.p->masterRef, GSN_LCP_PREPARE_REF,
- signal, LcpPrepareRef::SignalLength, JBB);
- return;
- }
-
- ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
- ndbrequire(ptr.p->errorCode != 0);
-
- DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
- ref->backupId = ptr.p->backupId;
- ref->backupPtr = ptr.i;
- ref->errorCode = ptr.p->errorCode;
- ref->nodeId = getOwnNodeId();
- sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
- DefineBackupRef::SignalLength, JBB);
-}
-
-void
-Backup::execDEFINE_BACKUP_REQ(Signal* signal)
-{
- jamEntry();
-
- DefineBackupReq* req = (DefineBackupReq*)signal->getDataPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- const Uint32 ptrI = req->backupPtr;
- const Uint32 backupId = req->backupId;
- const BlockReference senderRef = req->senderRef;
-
- if(senderRef == reference()){
- /**
- * Signal sent from myself -> record already seized
- */
- jam();
- c_backupPool.getPtr(ptr, ptrI);
- } else { // from other node
- jam();
-#ifdef DEBUG_ABORT
- dumpUsedResources();
-#endif
- if(!c_backups.seizeId(ptr, ptrI)) {
- jam();
- ndbrequire(false); // If master has succeeded slave should succed
- }//if
- }//if
-
- CRASH_INSERTION((10014));
-
- ptr.p->m_gsn = GSN_DEFINE_BACKUP_REQ;
- ptr.p->slaveState.forceState(INITIAL);
- ptr.p->slaveState.setState(DEFINING);
- ptr.p->slaveData.dropTrig.tableId = RNIL;
- ptr.p->errorCode = 0;
- ptr.p->clientRef = req->clientRef;
- ptr.p->clientData = req->clientData;
- if(senderRef == reference())
- ptr.p->flags = req->flags;
- else
- ptr.p->flags = req->flags & ~((Uint32)0x3); /* remove waitCompleted flags
- * as non master should never
- * reply
- */
- ptr.p->masterRef = senderRef;
- ptr.p->nodes = req->nodes;
- ptr.p->backupId = backupId;
- ptr.p->backupKey[0] = req->backupKey[0];
- ptr.p->backupKey[1] = req->backupKey[1];
- ptr.p->backupDataLen = req->backupDataLen;
- ptr.p->masterData.errorCode = 0;
- ptr.p->noOfBytes = 0;
- ptr.p->noOfRecords = 0;
- ptr.p->noOfLogBytes = 0;
- ptr.p->noOfLogRecords = 0;
- ptr.p->currGCP = 0;
- ptr.p->startGCP = 0;
- ptr.p->stopGCP = 0;
-
- /**
- * Allocate files
- */
- BackupFilePtr files[3];
- Uint32 noOfPages[] = {
- NO_OF_PAGES_META_FILE,
- 2, // 32k
- 0 // 3M
- };
- const Uint32 maxInsert[] = {
- MAX_WORDS_META_FILE,
- 4096, // 16k
- 16*3000, // Max 16 tuples
- };
- Uint32 minWrite[] = {
- 8192,
- 8192,
- 32768
- };
- Uint32 maxWrite[] = {
- 8192,
- 8192,
- 32768
- };
-
- minWrite[1] = c_defaults.m_minWriteSize;
- maxWrite[1] = c_defaults.m_maxWriteSize;
- noOfPages[1] = (c_defaults.m_logBufferSize + sizeof(Page32) - 1) /
- sizeof(Page32);
- minWrite[2] = c_defaults.m_minWriteSize;
- maxWrite[2] = c_defaults.m_maxWriteSize;
- noOfPages[2] = (c_defaults.m_dataBufferSize + sizeof(Page32) - 1) /
- sizeof(Page32);
-
- if (ptr.p->is_lcp())
- {
- noOfPages[2] = (c_defaults.m_lcp_buffer_size + sizeof(Page32) - 1) /
- sizeof(Page32);
- }
-
- ptr.p->ctlFilePtr = ptr.p->logFilePtr = ptr.p->dataFilePtr = RNIL;
-
- for(Uint32 i = 0; i<3; i++) {
- jam();
- if(ptr.p->is_lcp() && i != 2)
- {
- files[i].i = RNIL;
- continue;
- }
- if(!ptr.p->files.seize(files[i])) {
- jam();
- defineBackupRef(signal, ptr,
- DefineBackupRef::FailedToAllocateFileRecord);
- return;
- }//if
-
- files[i].p->tableId = RNIL;
- files[i].p->backupPtr = ptr.i;
- files[i].p->filePointer = RNIL;
- files[i].p->m_flags = 0;
- files[i].p->errorCode = 0;
-
- if(ERROR_INSERTED(10035) || files[i].p->pages.seize(noOfPages[i]) == false)
- {
- jam();
- DEBUG_OUT("Failed to seize " << noOfPages[i] << " pages");
- defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateBuffers);
- return;
- }//if
- Page32Ptr pagePtr;
- files[i].p->pages.getPtr(pagePtr, 0);
-
- const char * msg = files[i].p->
- operation.dataBuffer.setup((Uint32*)pagePtr.p,
- noOfPages[i] * (sizeof(Page32) >> 2),
- 128,
- minWrite[i] >> 2,
- maxWrite[i] >> 2,
- maxInsert[i]);
- if(msg != 0) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedToSetupFsBuffers);
- return;
- }//if
-
- switch(i){
- case 0:
- files[i].p->fileType = BackupFormat::CTL_FILE;
- ptr.p->ctlFilePtr = files[i].i;
- break;
- case 1:
- files[i].p->fileType = BackupFormat::LOG_FILE;
- ptr.p->logFilePtr = files[i].i;
- break;
- case 2:
- files[i].p->fileType = BackupFormat::DATA_FILE;
- ptr.p->dataFilePtr = files[i].i;
- }
- }//for
-
- if (!verifyNodesAlive(ptr, ptr.p->nodes)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::Undefined);
- return;
- }//if
- if (ERROR_INSERTED(10027)) {
- jam();
- defineBackupRef(signal, ptr, 327);
- return;
- }//if
-
- if(ptr.p->backupDataLen == 0) {
- jam();
- backupAllData(signal, ptr);
- return;
- }//if
-
- if(ptr.p->is_lcp())
- {
- jam();
- getFragmentInfoDone(signal, ptr);
- return;
- }
-
- /**
- * Not implemented
- */
- ndbrequire(0);
-}
-
-void
-Backup::backupAllData(Signal* signal, BackupRecordPtr ptr)
-{
- /**
- * Get all tables from dict
- */
- ListTablesReq * req = (ListTablesReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = ptr.i;
- req->requestData = 0;
- sendSignal(DBDICT_REF, GSN_LIST_TABLES_REQ, signal,
- ListTablesReq::SignalLength, JBB);
-}
-
-void
-Backup::execLIST_TABLES_CONF(Signal* signal)
-{
- jamEntry();
-
- ListTablesConf* conf = (ListTablesConf*)signal->getDataPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, conf->senderData);
-
- const Uint32 len = signal->length() - ListTablesConf::HeaderLength;
- for(unsigned int i = 0; i<len; i++) {
- jam();
- Uint32 tableId = ListTablesConf::getTableId(conf->tableData[i]);
- Uint32 tableType = ListTablesConf::getTableType(conf->tableData[i]);
- Uint32 state= ListTablesConf::getTableState(conf->tableData[i]);
-
- if (! (DictTabInfo::isTable(tableType) ||
- DictTabInfo::isIndex(tableType) ||
- DictTabInfo::isFilegroup(tableType) ||
- DictTabInfo::isFile(tableType)))
- {
- jam();
- continue;
- }
-
- if (state != DictTabInfo::StateOnline)
- {
- jam();
- continue;
- }
-
- TablePtr tabPtr;
- ptr.p->tables.seize(tabPtr);
- if(tabPtr.i == RNIL) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedToAllocateTables);
- return;
- }//if
- tabPtr.p->tableId = tableId;
- tabPtr.p->tableType = tableType;
- }//for
-
- if(len == ListTablesConf::DataLength) {
- jam();
- /**
- * Not finished...
- */
- return;
- }//if
-
- /**
- * All tables fetched
- */
- openFiles(signal, ptr);
-}
-
-void
-Backup::openFiles(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- BackupFilePtr filePtr LINT_SET_PTR;
-
- FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->fileFlags =
- FsOpenReq::OM_WRITEONLY |
- FsOpenReq::OM_TRUNCATE |
- FsOpenReq::OM_CREATE |
- FsOpenReq::OM_APPEND |
- FsOpenReq::OM_AUTOSYNC;
- FsOpenReq::v2_setCount(req->fileNumber, 0xFFFFFFFF);
- req->auto_sync_size = c_defaults.m_disk_synch_size;
- /**
- * Ctl file
- */
- c_backupFilePool.getPtr(filePtr, ptr.p->ctlFilePtr);
- filePtr.p->m_flags |= BackupFile::BF_OPENING;
-
- req->userPointer = filePtr.i;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
- FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-
- /**
- * Log file
- */
- c_backupFilePool.getPtr(filePtr, ptr.p->logFilePtr);
- filePtr.p->m_flags |= BackupFile::BF_OPENING;
-
- req->userPointer = filePtr.i;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_LOG);
- FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-
- /**
- * Data file
- */
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
- filePtr.p->m_flags |= BackupFile::BF_OPENING;
-
- if (c_defaults.m_o_direct)
- req->fileFlags |= FsOpenReq::OM_DIRECT;
- req->userPointer = filePtr.i;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
- FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- FsOpenReq::v2_setCount(req->fileNumber, 0);
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}
-
-void
-Backup::execFSOPENREF(Signal* signal)
-{
- jamEntry();
-
- FsRef * ref = (FsRef *)signal->getDataPtr();
-
- const Uint32 userPtr = ref->userPointer;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, userPtr);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
- ptr.p->setErrorCode(ref->errorCode);
- openFilesReply(signal, ptr, filePtr);
-}
-
-void
-Backup::execFSOPENCONF(Signal* signal)
-{
- jamEntry();
-
- FsConf * conf = (FsConf *)signal->getDataPtr();
-
- const Uint32 userPtr = conf->userPointer;
- const Uint32 filePointer = conf->filePointer;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, userPtr);
- filePtr.p->filePointer = filePointer;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_OPEN));
- filePtr.p->m_flags |= BackupFile::BF_OPEN;
- openFilesReply(signal, ptr, filePtr);
-}
-
-void
-Backup::openFilesReply(Signal* signal,
- BackupRecordPtr ptr, BackupFilePtr filePtr)
-{
- jam();
-
- /**
- * Mark files as "opened"
- */
- ndbrequire(filePtr.p->m_flags & BackupFile::BF_OPENING);
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_OPENING;
- filePtr.p->m_flags |= BackupFile::BF_OPEN;
- /**
- * Check if all files have recived open_reply
- */
- for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
- {
- jam();
- if(filePtr.p->m_flags & BackupFile::BF_OPENING) {
- jam();
- return;
- }//if
- }//for
-
- /**
- * Did open succeed for all files
- */
- if(ptr.p->checkError()) {
- jam();
- defineBackupRef(signal, ptr);
- return;
- }//if
-
- if(!ptr.p->is_lcp())
- {
- /**
- * Insert file headers
- */
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- if(!insertFileHeader(BackupFormat::CTL_FILE, ptr.p, filePtr.p)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
- return;
- }//if
-
- ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
- if(!insertFileHeader(BackupFormat::LOG_FILE, ptr.p, filePtr.p)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
- return;
- }//if
-
- ptr.p->files.getPtr(filePtr, ptr.p->dataFilePtr);
- if(!insertFileHeader(BackupFormat::DATA_FILE, ptr.p, filePtr.p)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
- return;
- }//if
- }
- else
- {
- ptr.p->files.getPtr(filePtr, ptr.p->dataFilePtr);
- if(!insertFileHeader(BackupFormat::LCP_FILE, ptr.p, filePtr.p)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertFileHeader);
- return;
- }//if
-
- ptr.p->ctlFilePtr = ptr.p->dataFilePtr;
- }
-
- /**
- * Start CTL file thread
- */
- if (!ptr.p->is_lcp())
- {
- jam();
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
-
- signal->theData[0] = BackupContinueB::START_FILE_THREAD;
- signal->theData[1] = filePtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 2);
- }
- else
- {
- jam();
- filePtr.p->m_flags |= BackupFile::BF_LCP_META;
- }
-
- /**
- * Insert table list in ctl file
- */
- FsBuffer & buf = filePtr.p->operation.dataBuffer;
-
- const Uint32 sz =
- (sizeof(BackupFormat::CtlFile::TableList) >> 2) +
- ptr.p->tables.count() - 1;
-
- Uint32 * dst;
- ndbrequire(sz < buf.getMaxWrite());
- if(!buf.getWritePtr(&dst, sz)) {
- jam();
- defineBackupRef(signal, ptr, DefineBackupRef::FailedInsertTableList);
- return;
- }//if
-
- BackupFormat::CtlFile::TableList* tl =
- (BackupFormat::CtlFile::TableList*)dst;
- tl->SectionType = htonl(BackupFormat::TABLE_LIST);
- tl->SectionLength = htonl(sz);
-
- TablePtr tabPtr;
- Uint32 count = 0;
- for(ptr.p->tables.first(tabPtr);
- tabPtr.i != RNIL;
- ptr.p->tables.next(tabPtr)){
- jam();
- tl->TableIds[count] = htonl(tabPtr.p->tableId);
- count++;
- }//for
-
- buf.updateWritePtr(sz);
-
- /**
- * Start getting table definition data
- */
- ndbrequire(ptr.p->tables.first(tabPtr));
-
- signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
- signal->theData[1] = ptr.i;
- signal->theData[2] = tabPtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
- return;
-}
-
-bool
-Backup::insertFileHeader(BackupFormat::FileType ft,
- BackupRecord * ptrP,
- BackupFile * filePtrP){
- FsBuffer & buf = filePtrP->operation.dataBuffer;
-
- const Uint32 sz = sizeof(BackupFormat::FileHeader) >> 2;
-
- Uint32 * dst;
- ndbrequire(sz < buf.getMaxWrite());
- if(!buf.getWritePtr(&dst, sz)) {
- jam();
- return false;
- }//if
-
- BackupFormat::FileHeader* header = (BackupFormat::FileHeader*)dst;
- ndbrequire(sizeof(header->Magic) == sizeof(BACKUP_MAGIC));
- memcpy(header->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC));
- header->NdbVersion = htonl(NDB_VERSION);
- header->SectionType = htonl(BackupFormat::FILE_HEADER);
- header->SectionLength = htonl(sz - 3);
- header->FileType = htonl(ft);
- header->BackupId = htonl(ptrP->backupId);
- header->BackupKey_0 = htonl(ptrP->backupKey[0]);
- header->BackupKey_1 = htonl(ptrP->backupKey[1]);
- header->ByteOrder = 0x12345678;
-
- buf.updateWritePtr(sz);
- return true;
-}
-
-void
-Backup::execGET_TABINFOREF(Signal* signal)
-{
- GetTabInfoRef * ref = (GetTabInfoRef*)signal->getDataPtr();
-
- const Uint32 senderData = ref->senderData;
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, senderData);
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
-
- defineBackupRef(signal, ptr, ref->errorCode);
-}
-
-void
-Backup::execGET_TABINFO_CONF(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)) {
- jam();
- return;
- }//if
-
- GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
- //const Uint32 senderRef = info->senderRef;
- const Uint32 len = conf->totalLen;
- const Uint32 senderData = conf->senderData;
- const Uint32 tableType = conf->tableType;
- const Uint32 tableId = conf->tableId;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, senderData);
-
- SegmentedSectionPtr dictTabInfoPtr;
- signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
- ndbrequire(dictTabInfoPtr.sz == len);
-
- TablePtr tabPtr ;
- ndbrequire(findTable(ptr, tabPtr, tableId));
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- FsBuffer & buf = filePtr.p->operation.dataBuffer;
- Uint32* dst = 0;
- { // Write into ctl file
- Uint32 dstLen = len + 3;
- if(!buf.getWritePtr(&dst, dstLen)) {
- jam();
- ndbrequire(false);
- ptr.p->setErrorCode(DefineBackupRef::FailedAllocateTableMem);
- releaseSections(signal);
- defineBackupRef(signal, ptr);
- return;
- }//if
- if(dst != 0) {
- jam();
-
- BackupFormat::CtlFile::TableDescription * desc =
- (BackupFormat::CtlFile::TableDescription*)dst;
- desc->SectionType = htonl(BackupFormat::TABLE_DESCRIPTION);
- desc->SectionLength = htonl(len + 3);
- desc->TableType = htonl(tableType);
- dst += 3;
-
- copy(dst, dictTabInfoPtr);
- buf.updateWritePtr(dstLen);
- }//if
- }
-
- releaseSections(signal);
-
- if(ptr.p->checkError()) {
- jam();
- defineBackupRef(signal, ptr);
- return;
- }//if
-
- if (!DictTabInfo::isTable(tabPtr.p->tableType))
- {
- jam();
-
- TablePtr tmp = tabPtr;
- ptr.p->tables.next(tabPtr);
- ptr.p->tables.release(tmp);
- goto next;
- }
-
- if (!parseTableDescription(signal, ptr, tabPtr, dst, len))
- {
- jam();
- defineBackupRef(signal, ptr);
- return;
- }
-
- if(!ptr.p->is_lcp())
- {
- jam();
- signal->theData[0] = tabPtr.p->tableId;
- signal->theData[1] = 1; // lock
- EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
- }
-
- ptr.p->tables.next(tabPtr);
-
-next:
- if(tabPtr.i == RNIL)
- {
- /**
- * Done with all tables...
- */
- jam();
-
- if(ptr.p->is_lcp())
- {
- lcp_open_file_done(signal, ptr);
- return;
- }
-
- ndbrequire(ptr.p->tables.first(tabPtr));
- DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtrSend();
- req->m_connectionData = RNIL;
- req->m_tableRef = tabPtr.p->tableId;
- req->m_senderData = ptr.i;
- sendSignal(DBDIH_REF, GSN_DI_FCOUNTREQ, signal,
- DihFragCountReq::SignalLength, JBB);
- return;
- }//if
-
- /**
- * Fetch next table...
- */
- signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
- signal->theData[1] = ptr.i;
- signal->theData[2] = tabPtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
- return;
-}
-
-bool
-Backup::parseTableDescription(Signal* signal,
- BackupRecordPtr ptr,
- TablePtr tabPtr,
- const Uint32 * tabdescptr,
- Uint32 len)
-{
- SimplePropertiesLinearReader it(tabdescptr, len);
-
- it.first();
-
- DictTabInfo::Table tmpTab; tmpTab.init();
- SimpleProperties::UnpackStatus stat;
- stat = SimpleProperties::unpack(it, &tmpTab,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
- ndbrequire(stat == SimpleProperties::Break);
-
- bool lcp = ptr.p->is_lcp();
-
- ndbrequire(tabPtr.p->tableId == tmpTab.TableId);
- ndbrequire(lcp || (tabPtr.p->tableType == tmpTab.TableType));
-
- /**
- * LCP should not save disk attributes but only mem attributes
- */
-
- /**
- * Initialize table object
- */
- tabPtr.p->noOfRecords = 0;
- tabPtr.p->schemaVersion = tmpTab.TableVersion;
- tabPtr.p->noOfAttributes = tmpTab.NoOfAttributes;
- tabPtr.p->noOfNull = 0;
- tabPtr.p->noOfVariable = 0; // Computed while iterating over attribs
- tabPtr.p->sz_FixedAttributes = 0; // Computed while iterating over attribs
- tabPtr.p->triggerIds[0] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->triggerIds[1] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->triggerIds[2] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->triggerAllocated[0] = false;
- tabPtr.p->triggerAllocated[1] = false;
- tabPtr.p->triggerAllocated[2] = false;
-
- Uint32 disk = 0;
- const Uint32 count = tabPtr.p->noOfAttributes;
- for(Uint32 i = 0; i<count; i++) {
- jam();
- DictTabInfo::Attribute tmp; tmp.init();
- stat = SimpleProperties::unpack(it, &tmp,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
-
- ndbrequire(stat == SimpleProperties::Break);
- it.next(); // Move Past EndOfAttribute
-
- const Uint32 arr = tmp.AttributeArraySize;
- const Uint32 sz = 1 << tmp.AttributeSize;
- const Uint32 sz32 = (sz * arr + 31) >> 5;
-
- if(lcp && tmp.AttributeStorageType == NDB_STORAGETYPE_DISK)
- {
- disk++;
- continue;
- }
-
- AttributePtr attrPtr;
- if(!tabPtr.p->attributes.seize(attrPtr))
- {
- jam();
- ptr.p->setErrorCode(DefineBackupRef::FailedToAllocateAttributeRecord);
- return false;
- }
-
- attrPtr.p->data.m_flags = 0;
- attrPtr.p->data.attrId = tmp.AttributeId;
-
- attrPtr.p->data.m_flags |=
- (tmp.AttributeNullableFlag ? Attribute::COL_NULLABLE : 0);
- attrPtr.p->data.m_flags |= (tmp.AttributeArrayType == NDB_ARRAYTYPE_FIXED)?
- Attribute::COL_FIXED : 0;
- attrPtr.p->data.sz32 = sz32;
-
- /**
- * 1) Fixed non-nullable
- * 2) Other
- */
- if(attrPtr.p->data.m_flags & Attribute::COL_FIXED &&
- !(attrPtr.p->data.m_flags & Attribute::COL_NULLABLE)) {
- jam();
- attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
- tabPtr.p->sz_FixedAttributes += sz32;
- } else {
- attrPtr.p->data.offset = ~0;
- tabPtr.p->noOfVariable++;
- }
- }//for
-
-
- if(lcp)
- {
- if (disk)
- {
- /**
- * Remove all disk attributes
- */
- tabPtr.p->noOfAttributes -= disk;
-
- {
- AttributePtr attrPtr;
- ndbrequire(tabPtr.p->attributes.seize(attrPtr));
-
- Uint32 sz32 = 2;
- attrPtr.p->data.attrId = AttributeHeader::DISK_REF;
- attrPtr.p->data.m_flags = Attribute::COL_FIXED;
- attrPtr.p->data.sz32 = 2;
-
- attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
- tabPtr.p->sz_FixedAttributes += sz32;
- tabPtr.p->noOfAttributes ++;
- }
- }
-
- {
- AttributePtr attrPtr;
- ndbrequire(tabPtr.p->attributes.seize(attrPtr));
-
- Uint32 sz32 = 2;
- attrPtr.p->data.attrId = AttributeHeader::ROWID;
- attrPtr.p->data.m_flags = Attribute::COL_FIXED;
- attrPtr.p->data.sz32 = 2;
-
- attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
- tabPtr.p->sz_FixedAttributes += sz32;
- tabPtr.p->noOfAttributes ++;
- }
-
- if (tmpTab.RowGCIFlag)
- {
- AttributePtr attrPtr;
- ndbrequire(tabPtr.p->attributes.seize(attrPtr));
-
- Uint32 sz32 = 2;
- attrPtr.p->data.attrId = AttributeHeader::ROW_GCI;
- attrPtr.p->data.m_flags = Attribute::COL_FIXED;
- attrPtr.p->data.sz32 = 2;
-
- attrPtr.p->data.offset = tabPtr.p->sz_FixedAttributes;
- tabPtr.p->sz_FixedAttributes += sz32;
- tabPtr.p->noOfAttributes ++;
- }
- }
- return true;
-}
-
-void
-Backup::execDI_FCOUNTCONF(Signal* signal)
-{
- jamEntry();
- DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
- const Uint32 userPtr = conf->m_connectionData;
- const Uint32 fragCount = conf->m_fragmentCount;
- const Uint32 tableId = conf->m_tableRef;
- const Uint32 senderData = conf->m_senderData;
-
- ndbrequire(userPtr == RNIL && signal->length() == 5);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, senderData);
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, tableId));
-
- ndbrequire(tabPtr.p->fragments.seize(fragCount) != false);
- for(Uint32 i = 0; i<fragCount; i++) {
- jam();
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, i);
- fragPtr.p->scanned = 0;
- fragPtr.p->scanning = 0;
- fragPtr.p->tableId = tableId;
- fragPtr.p->fragmentId = i;
- fragPtr.p->node = 0;
- }//for
-
- /**
- * Next table
- */
- if(ptr.p->tables.next(tabPtr)) {
- jam();
- DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtrSend();
- req->m_connectionData = RNIL;
- req->m_tableRef = tabPtr.p->tableId;
- req->m_senderData = ptr.i;
- sendSignal(DBDIH_REF, GSN_DI_FCOUNTREQ, signal,
- DihFragCountReq::SignalLength, JBB);
- return;
- }//if
-
- ptr.p->tables.first(tabPtr);
- getFragmentInfo(signal, ptr, tabPtr, 0);
-}
-
-void
-Backup::getFragmentInfo(Signal* signal,
- BackupRecordPtr ptr, TablePtr tabPtr, Uint32 fragNo)
-{
- jam();
-
- for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
- jam();
- const Uint32 fragCount = tabPtr.p->fragments.getSize();
- for(; fragNo < fragCount; fragNo ++) {
- jam();
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragNo);
-
- if(fragPtr.p->scanned == 0 && fragPtr.p->scanning == 0) {
- jam();
- signal->theData[0] = RNIL;
- signal->theData[1] = ptr.i;
- signal->theData[2] = tabPtr.p->tableId;
- signal->theData[3] = fragNo;
- sendSignal(DBDIH_REF, GSN_DIGETPRIMREQ, signal, 4, JBB);
- return;
- }//if
- }//for
- fragNo = 0;
- }//for
-
- getFragmentInfoDone(signal, ptr);
-}
-
-void
-Backup::execDIGETPRIMCONF(Signal* signal)
-{
- jamEntry();
-
- const Uint32 userPtr = signal->theData[0];
- const Uint32 senderData = signal->theData[1];
- const Uint32 nodeCount = signal->theData[6];
- const Uint32 tableId = signal->theData[7];
- const Uint32 fragNo = signal->theData[8];
-
- ndbrequire(userPtr == RNIL && signal->length() == 9);
- ndbrequire(nodeCount > 0 && nodeCount <= MAX_REPLICAS);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, senderData);
-
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, tableId));
-
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragNo);
-
- fragPtr.p->node = signal->theData[2];
-
- getFragmentInfo(signal, ptr, tabPtr, fragNo + 1);
-}
-
-void
-Backup::getFragmentInfoDone(Signal* signal, BackupRecordPtr ptr)
-{
- ptr.p->m_gsn = GSN_DEFINE_BACKUP_CONF;
- ptr.p->slaveState.setState(DEFINED);
- DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtr();
- conf->backupPtr = ptr.i;
- conf->backupId = ptr.p->backupId;
- sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_CONF, signal,
- DefineBackupConf::SignalLength, JBB);
-}
-
-
-/*****************************************************************************
- *
- * Slave functionallity: Start backup
- *
- *****************************************************************************/
-void
-Backup::execSTART_BACKUP_REQ(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10015));
-
- StartBackupReq* req = (StartBackupReq*)signal->getDataPtr();
- const Uint32 ptrI = req->backupPtr;
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->slaveState.setState(STARTED);
- ptr.p->m_gsn = GSN_START_BACKUP_REQ;
-
- /**
- * Start file threads...
- */
- BackupFilePtr filePtr;
- for(ptr.p->files.first(filePtr); filePtr.i!=RNIL;ptr.p->files.next(filePtr))
- {
- jam();
- if(! (filePtr.p->m_flags & BackupFile::BF_FILE_THREAD))
- {
- jam();
- filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
- signal->theData[0] = BackupContinueB::START_FILE_THREAD;
- signal->theData[1] = filePtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 2);
- }//if
- }//for
-
- /**
- * Tell DBTUP to create triggers
- */
- TablePtr tabPtr;
- ndbrequire(ptr.p->tables.first(tabPtr));
- sendCreateTrig(signal, ptr, tabPtr);
-}
-
-/*****************************************************************************
- *
- * Slave functionallity: Backup fragment
- *
- *****************************************************************************/
-void
-Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
-{
- jamEntry();
- BackupFragmentReq* req = (BackupFragmentReq*)signal->getDataPtr();
-
- CRASH_INSERTION((10016));
-
- const Uint32 ptrI = req->backupPtr;
- //const Uint32 backupId = req->backupId;
- const Uint32 tableId = req->tableId;
- const Uint32 fragNo = req->fragmentNo;
- const Uint32 count = req->count;
-
- /**
- * Get backup record
- */
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->slaveState.setState(SCANNING);
- ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REQ;
-
- /**
- * Get file
- */
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
-
- ndbrequire(filePtr.p->backupPtr == ptrI);
- ndbrequire(filePtr.p->m_flags ==
- (BackupFile::BF_OPEN | BackupFile::BF_FILE_THREAD));
-
- /**
- * Get table
- */
- TablePtr tabPtr;
- ndbrequire(findTable(ptr, tabPtr, tableId));
-
- /**
- * Get fragment
- */
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragNo);
-
- ndbrequire(fragPtr.p->scanned == 0);
- ndbrequire(fragPtr.p->scanning == 0 ||
- refToNode(ptr.p->masterRef) == getOwnNodeId());
-
- /**
- * Init operation
- */
- if(filePtr.p->tableId != tableId) {
- jam();
- filePtr.p->operation.init(tabPtr);
- filePtr.p->tableId = tableId;
- }//if
-
- /**
- * Check for space in buffer
- */
- if(!filePtr.p->operation.newFragment(tableId, fragPtr.p->fragmentId)) {
- jam();
- req->count = count + 1;
- sendSignalWithDelay(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal, 50,
- signal->length());
- ptr.p->slaveState.setState(STARTED);
- return;
- }//if
-
- /**
- * Mark things as "in use"
- */
- fragPtr.p->scanning = 1;
- filePtr.p->fragmentNo = fragPtr.p->fragmentId;
-
- /**
- * Start scan
- */
- {
- filePtr.p->m_flags |= BackupFile::BF_SCAN_THREAD;
-
- Table & table = * tabPtr.p;
- ScanFragReq * req = (ScanFragReq *)signal->getDataPtrSend();
- const Uint32 parallelism = 16;
- const Uint32 attrLen = 5 + table.noOfAttributes;
-
- req->senderData = filePtr.i;
- req->resultRef = reference();
- req->schemaVersion = table.schemaVersion;
- req->fragmentNoKeyLen = fragPtr.p->fragmentId;
- req->requestInfo = 0;
- req->savePointId = 0;
- req->tableId = table.tableId;
- ScanFragReq::setReadCommittedFlag(req->requestInfo, 1);
- ScanFragReq::setLockMode(req->requestInfo, 0);
- ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
- ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
- ScanFragReq::setAttrLen(req->requestInfo,attrLen);
- ScanFragReq::setTupScanFlag(req->requestInfo, 1);
- if (ptr.p->is_lcp())
- {
- ScanFragReq::setScanPrio(req->requestInfo, 1);
- ScanFragReq::setNoDiskFlag(req->requestInfo, 1);
- ScanFragReq::setLcpScanFlag(req->requestInfo, 1);
- }
- req->transId1 = 0;
- req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
- req->clientOpPtr= filePtr.i;
- req->batch_size_rows= parallelism;
- req->batch_size_bytes= 0;
- sendSignal(DBLQH_REF, GSN_SCAN_FRAGREQ, signal,
- ScanFragReq::SignalLength, JBB);
-
- signal->theData[0] = filePtr.i;
- signal->theData[1] = 0;
- signal->theData[2] = (BACKUP << 20) + (getOwnNodeId() << 8);
-
- // Return all
- signal->theData[3] = table.noOfAttributes;
- signal->theData[4] = 0;
- signal->theData[5] = 0;
- signal->theData[6] = 0;
- signal->theData[7] = 0;
-
- Uint32 dataPos = 8;
- Ptr<Attribute> attrPtr;
- table.attributes.first(attrPtr);
- for(; !attrPtr.isNull(); table.attributes.next(attrPtr))
- {
- jam();
-
- /**
- * LCP should not save disk attributes
- */
- ndbrequire(! (ptr.p->is_lcp() &&
- attrPtr.p->data.m_flags & Attribute::COL_DISK));
-
- AttributeHeader::init(&signal->theData[dataPos],
- attrPtr.p->data.attrId, 0);
- dataPos++;
- if(dataPos == 25) {
- jam();
- sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, 25, JBB);
- dataPos = 3;
- }//if
- }//for
- if(dataPos != 3) {
- jam();
- sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, dataPos, JBB);
- }//if
- }
-}
-
-void
-Backup::execSCAN_HBREP(Signal* signal)
-{
- jamEntry();
-}
-
-void
-Backup::execTRANSID_AI(Signal* signal)
-{
- jamEntry();
-
- const Uint32 filePtrI = signal->theData[0];
- //const Uint32 transId1 = signal->theData[1];
- //const Uint32 transId2 = signal->theData[2];
- const Uint32 dataLen = signal->length() - 3;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- OperationRecord & op = filePtr.p->operation;
-
- TablePtr tabPtr LINT_SET_PTR;
- c_tablePool.getPtr(tabPtr, op.tablePtr);
-
- Table & table = * tabPtr.p;
-
- /**
- * Unpack data
- */
- op.attrSzTotal += dataLen;
-
- Uint32 srcSz = dataLen;
- Uint32 usedSz = 0;
- const Uint32 * src = &signal->theData[3];
-
- Ptr<Attribute> attrPtr;
- table.attributes.first(attrPtr);
- Uint32 columnNo = 0;
-
- while (usedSz < srcSz)
- {
- jam();
-
- /**
- * Finished with one attribute now find next
- */
- const AttributeHeader attrHead(* src);
- const Uint32 attrId = attrHead.getAttributeId();
- const bool null = attrHead.isNULL();
- const Attribute::Data attr = attrPtr.p->data;
- ndbrequire(attrId == attr.attrId);
-
- usedSz += attrHead.getHeaderSize();
- src += attrHead.getHeaderSize();
-
- if (null) {
- jam();
- ndbrequire(attr.m_flags & Attribute::COL_NULLABLE);
- op.nullVariable();
- } else {
- Uint32* dst;
- Uint32 dstSz = attrHead.getDataSize();
- if (attr.m_flags & Attribute::COL_FIXED &&
- ! (attr.m_flags & Attribute::COL_NULLABLE)) {
- jam();
- dst = op.newAttrib(attr.offset, dstSz);
- ndbrequire(dstSz == attr.sz32);
- } else {
- dst = op.newVariable(columnNo, attrHead.getByteSize());
- ndbrequire(dstSz <= attr.sz32);
- }
-
- memcpy(dst, src, (dstSz << 2));
- src += dstSz;
- usedSz += dstSz;
- }
- table.attributes.next(attrPtr);
- columnNo++;
- }
-
- ndbrequire(usedSz == srcSz);
- ndbrequire(op.finished());
- op.newRecord(op.dst);
-}
-
-void
-Backup::OperationRecord::init(const TablePtr & ptr)
-{
-
- tablePtr = ptr.i;
- noOfAttributes = ptr.p->noOfAttributes;
-
- sz_Bitmask = (ptr.p->noOfNull + 31) >> 5;
- sz_FixedAttribs = ptr.p->sz_FixedAttributes;
-
- if(ptr.p->noOfVariable == 0) {
- jam();
- maxRecordSize = 1 + sz_Bitmask + sz_FixedAttribs;
- } else {
- jam();
- maxRecordSize =
- 1 + sz_Bitmask + 2048 /* Max tuple size */ + 2 * ptr.p->noOfVariable;
- }//if
-}
-
-bool
-Backup::OperationRecord::newFragment(Uint32 tableId, Uint32 fragNo)
-{
- Uint32 * tmp;
- const Uint32 headSz = (sizeof(BackupFormat::DataFile::FragmentHeader) >> 2);
- const Uint32 sz = headSz + 16 * maxRecordSize;
-
- ndbrequire(sz < dataBuffer.getMaxWrite());
- if(dataBuffer.getWritePtr(&tmp, sz)) {
- jam();
- BackupFormat::DataFile::FragmentHeader * head =
- (BackupFormat::DataFile::FragmentHeader*)tmp;
-
- head->SectionType = htonl(BackupFormat::FRAGMENT_HEADER);
- head->SectionLength = htonl(headSz);
- head->TableId = htonl(tableId);
- head->FragmentNo = htonl(fragNo);
- head->ChecksumType = htonl(0);
-
- opNoDone = opNoConf = opLen = 0;
- newRecord(tmp + headSz);
- scanStart = tmp;
- scanStop = (tmp + headSz);
-
- noOfRecords = 0;
- noOfBytes = 0;
- return true;
- }//if
- return false;
-}
-
-bool
-Backup::OperationRecord::fragComplete(Uint32 tableId, Uint32 fragNo, bool fill_record)
-{
- Uint32 * tmp;
- const Uint32 footSz = sizeof(BackupFormat::DataFile::FragmentFooter) >> 2;
- Uint32 sz = footSz + 1;
-
- if (fill_record)
- {
- Uint32 * new_tmp;
- if (!dataBuffer.getWritePtr(&tmp, sz))
- return false;
- new_tmp = tmp + sz;
-
- if ((UintPtr)new_tmp & (sizeof(Page32)-1))
- {
- /* padding is needed to get full write */
- new_tmp += 2 /* to fit empty header minimum 2 words*/;
- new_tmp = (Uint32 *)(((UintPtr)new_tmp + sizeof(Page32)-1) &
- ~(UintPtr)(sizeof(Page32)-1));
- /* new write sz */
- sz = new_tmp - tmp;
- }
- }
-
- if(dataBuffer.getWritePtr(&tmp, sz)) {
- jam();
- * tmp = 0; // Finish record stream
- tmp++;
- BackupFormat::DataFile::FragmentFooter * foot =
- (BackupFormat::DataFile::FragmentFooter*)tmp;
- foot->SectionType = htonl(BackupFormat::FRAGMENT_FOOTER);
- foot->SectionLength = htonl(footSz);
- foot->TableId = htonl(tableId);
- foot->FragmentNo = htonl(fragNo);
- foot->NoOfRecords = htonl(noOfRecords);
- foot->Checksum = htonl(0);
-
- if (sz != footSz + 1)
- {
- tmp += footSz;
- memset(tmp, 0, (sz - footSz - 1) * 4);
- *tmp = htonl(BackupFormat::EMPTY_ENTRY);
- tmp++;
- *tmp = htonl(sz - footSz - 1);
- }
-
- dataBuffer.updateWritePtr(sz);
- return true;
- }//if
- return false;
-}
-
-bool
-Backup::OperationRecord::newScan()
-{
- Uint32 * tmp;
- ndbrequire(16 * maxRecordSize < dataBuffer.getMaxWrite());
- if(dataBuffer.getWritePtr(&tmp, 16 * maxRecordSize)) {
- jam();
- opNoDone = opNoConf = opLen = 0;
- newRecord(tmp);
- scanStart = tmp;
- scanStop = tmp;
- return true;
- }//if
- return false;
-}
-
-bool
-Backup::OperationRecord::closeScan()
-{
- opNoDone = opNoConf = opLen = 0;
- return true;
-}
-
-bool
-Backup::OperationRecord::scanConf(Uint32 noOfOps, Uint32 total_len)
-{
- const Uint32 done = opNoDone-opNoConf;
-
- ndbrequire(noOfOps == done);
- ndbrequire(opLen == total_len);
- opNoConf = opNoDone;
-
- const Uint32 len = (scanStop - scanStart);
- ndbrequire(len < dataBuffer.getMaxWrite());
- dataBuffer.updateWritePtr(len);
- noOfBytes += (len << 2);
- return true;
-}
-
-void
-Backup::execSCAN_FRAGREF(Signal* signal)
-{
- jamEntry();
-
- ScanFragRef * ref = (ScanFragRef*)signal->getDataPtr();
-
- const Uint32 filePtrI = ref->senderData;
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- filePtr.p->errorCode = ref->errorCode;
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
-
- backupFragmentRef(signal, filePtr);
-}
-
-void
-Backup::execSCAN_FRAGCONF(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10017));
-
- ScanFragConf * conf = (ScanFragConf*)signal->getDataPtr();
-
- const Uint32 filePtrI = conf->senderData;
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- OperationRecord & op = filePtr.p->operation;
-
- op.scanConf(conf->completedOps, conf->total_len);
- const Uint32 completed = conf->fragmentCompleted;
- if(completed != 2) {
- jam();
-
- checkScan(signal, filePtr);
- return;
- }//if
-
- fragmentCompleted(signal, filePtr);
-}
-
-void
-Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
-{
- jam();
-
- if(filePtr.p->errorCode != 0)
- {
- jam();
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
- backupFragmentRef(signal, filePtr); // Scan completed
- return;
- }//if
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- OperationRecord & op = filePtr.p->operation;
- if(!op.fragComplete(filePtr.p->tableId, filePtr.p->fragmentNo,
- c_defaults.m_o_direct))
- {
- jam();
- signal->theData[0] = BackupContinueB::BUFFER_FULL_FRAG_COMPLETE;
- signal->theData[1] = filePtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 50, 2);
- return;
- }//if
-
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_SCAN_THREAD;
-
- if (ptr.p->is_lcp())
- {
- ptr.p->slaveState.setState(STOPPING);
- filePtr.p->operation.dataBuffer.eof();
- }
- else
- {
- BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
- conf->backupId = ptr.p->backupId;
- conf->backupPtr = ptr.i;
- conf->tableId = filePtr.p->tableId;
- conf->fragmentNo = filePtr.p->fragmentNo;
- conf->noOfRecordsLow = (Uint32)(op.noOfRecords & 0xFFFFFFFF);
- conf->noOfRecordsHigh = (Uint32)(op.noOfRecords >> 32);
- conf->noOfBytesLow = (Uint32)(op.noOfBytes & 0xFFFFFFFF);
- conf->noOfBytesHigh = (Uint32)(op.noOfBytes >> 32);
- sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
- BackupFragmentConf::SignalLength, JBB);
-
- ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF;
- ptr.p->slaveState.setState(STARTED);
- }
- return;
-}
-
-void
-Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr)
-{
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REF;
-
- BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtrSend();
- ref->backupId = ptr.p->backupId;
- ref->backupPtr = ptr.i;
- ref->nodeId = getOwnNodeId();
- ref->errorCode = filePtr.p->errorCode;
- sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
- BackupFragmentRef::SignalLength, JBB);
-}
-
-void
-Backup::checkScan(Signal* signal, BackupFilePtr filePtr)
-{
- OperationRecord & op = filePtr.p->operation;
-
- if(filePtr.p->errorCode != 0)
- {
- jam();
-
- /**
- * Close scan
- */
- op.closeScan();
- ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
- req->senderData = filePtr.i;
- req->closeFlag = 1;
- req->transId1 = 0;
- req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- return;
- }//if
-
- if(op.newScan()) {
- jam();
-
- ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
- req->senderData = filePtr.i;
- req->closeFlag = 0;
- req->transId1 = 0;
- req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
- req->batch_size_rows= 16;
- req->batch_size_bytes= 0;
-
- if (ERROR_INSERTED(10036) &&
- filePtr.p->tableId >= 2 &&
- filePtr.p->operation.noOfRecords > 0)
- {
- ndbout_c("halting backup for table %d fragment: %d after %llu records",
- filePtr.p->tableId,
- filePtr.p->fragmentNo,
- filePtr.p->operation.noOfRecords);
- memmove(signal->theData+1, signal->theData,
- 4*ScanFragNextReq::SignalLength);
- signal->theData[0] = BackupContinueB::ZDELAY_SCAN_NEXT;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal,
- 300, 1+ScanFragNextReq::SignalLength);
- return;
- }
- if(ERROR_INSERTED(10032))
- sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- 100, ScanFragNextReq::SignalLength);
- else if(ERROR_INSERTED(10033))
- {
- SET_ERROR_INSERT_VALUE(10032);
- sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- 10000, ScanFragNextReq::SignalLength);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->requestType = AbortBackupOrd::FileOrScanError;
- ord->senderData= ptr.i;
- sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
- }
- else
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- return;
- }//if
-
- signal->theData[0] = BackupContinueB::BUFFER_FULL_SCAN;
- signal->theData[1] = filePtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 50, 2);
-}
-
-void
-Backup::execFSAPPENDREF(Signal* signal)
-{
- jamEntry();
-
- FsRef * ref = (FsRef *)signal->getDataPtr();
-
- const Uint32 filePtrI = ref->userPointer;
- const Uint32 errCode = ref->errorCode;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
- filePtr.p->errorCode = errCode;
-
- checkFile(signal, filePtr);
-}
-
-void
-Backup::execFSAPPENDCONF(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION((10018));
-
- //FsConf * conf = (FsConf*)signal->getDataPtr();
- const Uint32 filePtrI = signal->theData[0]; //conf->userPointer;
- const Uint32 bytes = signal->theData[1]; //conf->bytes;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- OperationRecord & op = filePtr.p->operation;
-
- op.dataBuffer.updateReadPtr(bytes >> 2);
-
- checkFile(signal, filePtr);
-}
-
-/*
- This routine handles two problems with writing to disk during local
- checkpoints and backups. The first problem is that we need to limit
- the writing to ensure that we don't use too much CPU and disk resources
- for backups and checkpoints. The perfect solution to this is to use
- a dynamic algorithm that adapts to the environment. Until we have
- implemented this we can satisfy ourselves with an algorithm that
- uses a configurable limit.
-
- The second problem is that in Linux we can get severe problems if we
- write very much to the disk without synching. In the worst case we
- can have Gigabytes of data in the Linux page cache before we reach
- the limit of how much we can write. If this happens the performance
- will drop significantly when we reach this limit since the Linux flush
- daemon will spend a few minutes on writing out the page cache to disk.
- To avoid this we ensure that a file never have more than a certain
- amount of data outstanding before synch. This variable is also
- configurable.
-*/
-bool
-Backup::ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP)
-{
-#if 0
- ndbout << "ready_to_write: ready = " << ready << " eof = " << eof;
- ndbout << " sz = " << sz << endl;
- ndbout << "words this period = " << m_words_written_this_period;
- ndbout << endl << "overflow disk write = " << m_overflow_disk_write;
- ndbout << endl << "Current Millisecond is = ";
- ndbout << NdbTick_CurrentMillisecond() << endl;
-#endif
- if ((ready || eof) &&
- m_words_written_this_period <= m_curr_disk_write_speed)
- {
- /*
- We have a buffer ready to write or we have reached end of
- file and thus we must write the last before closing the
- file.
- We have already check that we are allowed to write at this
- moment. We only worry about history of last 100 milliseconds.
- What happened before that is of no interest since a disk
- write that was issued more than 100 milliseconds should be
- completed by now.
- */
- int overflow;
- m_words_written_this_period += sz;
- overflow = m_words_written_this_period - m_curr_disk_write_speed;
- if (overflow > 0)
- m_overflow_disk_write = overflow;
-#if 0
- ndbout << "Will write with " << endl;
- ndbout << endl;
-#endif
- return true;
- }
- else
- {
-#if 0
- ndbout << "Will not write now" << endl << endl;
-#endif
- return false;
- }
-}
-
-void
-Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
-{
-
-#ifdef DEBUG_ABORT
- // ndbout_c("---- check file filePtr.i = %u", filePtr.i);
-#endif
-
- OperationRecord & op = filePtr.p->operation;
- Uint32 *tmp = NULL;
- Uint32 sz = 0;
- bool eof = FALSE;
- bool ready = op.dataBuffer.getReadPtr(&tmp, &sz, &eof);
-#if 0
- ndbout << "Ptr to data = " << hex << tmp << endl;
-#endif
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- if (ERROR_INSERTED(10036))
- {
- jam();
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
- filePtr.p->errorCode = 2810;
- ptr.p->setErrorCode(2810);
-
- if(ptr.p->m_gsn == GSN_STOP_BACKUP_REQ)
- {
- jam();
- closeFile(signal, ptr, filePtr);
- }
- return;
- }
-
- if(filePtr.p->errorCode != 0)
- {
- jam();
- ptr.p->setErrorCode(filePtr.p->errorCode);
-
- if(ptr.p->m_gsn == GSN_STOP_BACKUP_REQ)
- {
- jam();
- closeFile(signal, ptr, filePtr);
- }
- return;
- }
-
- if (!ready_to_write(ready, sz, eof, filePtr.p))
- {
- jam();
- signal->theData[0] = BackupContinueB::BUFFER_UNDERFLOW;
- signal->theData[1] = filePtr.i;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 20, 2);
- return;
- }
- else if (sz > 0)
- {
- jam();
- FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
- req->filePointer = filePtr.p->filePointer;
- req->userPointer = filePtr.i;
- req->userReference = reference();
- req->varIndex = 0;
- req->offset = tmp - c_startOfPages;
- req->size = sz;
- req->synch_flag = 0;
-
- sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
- FsAppendReq::SignalLength, JBA);
- return;
- }
-
- Uint32 flags = filePtr.p->m_flags;
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_FILE_THREAD;
-
- ndbrequire(flags & BackupFile::BF_OPEN);
- ndbrequire(flags & BackupFile::BF_FILE_THREAD);
-
- closeFile(signal, ptr, filePtr);
-}
-
-
-/****************************************************************************
- *
- * Slave functionallity: Perform logging
- *
- ****************************************************************************/
-void
-Backup::execBACKUP_TRIG_REQ(Signal* signal)
-{
- /*
- TUP asks if this trigger is to be fired on this node.
- */
- TriggerPtr trigPtr LINT_SET_PTR;
- TablePtr tabPtr LINT_SET_PTR;
- FragmentPtr fragPtr;
- Uint32 trigger_id = signal->theData[0];
- Uint32 frag_id = signal->theData[1];
- Uint32 result;
-
- jamEntry();
-
- c_triggerPool.getPtr(trigPtr, trigger_id);
-
- c_tablePool.getPtr(tabPtr, trigPtr.p->tab_ptr_i);
- tabPtr.p->fragments.getPtr(fragPtr, frag_id);
- if (fragPtr.p->node != getOwnNodeId()) {
-
- jam();
- result = ZFALSE;
- } else {
- jam();
- result = ZTRUE;
- }//if
- signal->theData[0] = result;
-}
-
-void
-Backup::execTRIG_ATTRINFO(Signal* signal) {
- jamEntry();
-
- CRASH_INSERTION((10019));
-
- TrigAttrInfo * trg = (TrigAttrInfo*)signal->getDataPtr();
-
- TriggerPtr trigPtr LINT_SET_PTR;
- c_triggerPool.getPtr(trigPtr, trg->getTriggerId());
- ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID); // Online...
-
- if(trigPtr.p->errorCode != 0) {
- jam();
- return;
- }//if
-
- if(trg->getAttrInfoType() == TrigAttrInfo::BEFORE_VALUES) {
- jam();
- /**
- * Backup is doing REDO logging and don't need before values
- */
- return;
- }//if
-
- BackupFormat::LogFile::LogEntry * logEntry = trigPtr.p->logEntry;
- if(logEntry == 0)
- {
- jam();
- Uint32 * dst;
- FsBuffer & buf = trigPtr.p->operation->dataBuffer;
- ndbrequire(trigPtr.p->maxRecordSize <= buf.getMaxWrite());
-
- if(ERROR_INSERTED(10030) ||
- !buf.getWritePtr(&dst, trigPtr.p->maxRecordSize))
- {
- jam();
- Uint32 save[TrigAttrInfo::StaticLength];
- memcpy(save, signal->getDataPtr(), 4*TrigAttrInfo::StaticLength);
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
- trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->requestType = AbortBackupOrd::LogBufferFull;
- ord->senderData= ptr.i;
- sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
-
- memcpy(signal->getDataPtrSend(), save, 4*TrigAttrInfo::StaticLength);
- return;
- }//if
-
- logEntry = (BackupFormat::LogFile::LogEntry *)dst;
- trigPtr.p->logEntry = logEntry;
- logEntry->Length = 0;
- logEntry->TableId = htonl(trigPtr.p->tableId);
-
-
- if(trigPtr.p->event==0)
- logEntry->TriggerEvent= htonl(TriggerEvent::TE_INSERT);
- else if(trigPtr.p->event==1)
- logEntry->TriggerEvent= htonl(TriggerEvent::TE_UPDATE);
- else if(trigPtr.p->event==2)
- logEntry->TriggerEvent= htonl(TriggerEvent::TE_DELETE);
- else {
- ndbout << "Bad Event: " << trigPtr.p->event << endl;
- ndbrequire(false);
- }
- } else {
- ndbrequire(logEntry->TableId == htonl(trigPtr.p->tableId));
-// ndbrequire(logEntry->TriggerEvent == htonl(trigPtr.p->event));
- }//if
-
- const Uint32 pos = logEntry->Length;
- const Uint32 dataLen = signal->length() - TrigAttrInfo::StaticLength;
- memcpy(&logEntry->Data[pos], trg->getData(), dataLen << 2);
-
- logEntry->Length = pos + dataLen;
-}
-
-void
-Backup::execFIRE_TRIG_ORD(Signal* signal)
-{
- jamEntry();
- FireTrigOrd* trg = (FireTrigOrd*)signal->getDataPtr();
-
- const Uint32 gci = trg->getGCI();
- const Uint32 trI = trg->getTriggerId();
- const Uint32 fragId = trg->fragId;
-
- TriggerPtr trigPtr LINT_SET_PTR;
- c_triggerPool.getPtr(trigPtr, trI);
-
- ndbrequire(trigPtr.p->event != ILLEGAL_TRIGGER_ID);
-
- if(trigPtr.p->errorCode != 0) {
- jam();
- return;
- }//if
-
- ndbrequire(trigPtr.p->logEntry != 0);
- Uint32 len = trigPtr.p->logEntry->Length;
- trigPtr.p->logEntry->FragId = htonl(fragId);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
- if(gci != ptr.p->currGCP)
- {
- jam();
- trigPtr.p->logEntry->TriggerEvent|= htonl(0x10000);
- trigPtr.p->logEntry->Data[len] = htonl(gci);
- len++;
- ptr.p->currGCP = gci;
- }
-
- len += (sizeof(BackupFormat::LogFile::LogEntry) >> 2) - 2;
- trigPtr.p->logEntry->Length = htonl(len);
-
- ndbrequire(len + 1 <= trigPtr.p->operation->dataBuffer.getMaxWrite());
- trigPtr.p->operation->dataBuffer.updateWritePtr(len + 1);
- trigPtr.p->logEntry = 0;
-
- trigPtr.p->operation->noOfBytes += (len + 1) << 2;
- trigPtr.p->operation->noOfRecords += 1;
-}
-
-void
-Backup::sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr,
- Uint32 requestType)
-{
- jam();
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->requestType = requestType;
- ord->senderData= ptr.i;
- NodePtr node;
- for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)) {
- jam();
- const Uint32 nodeId = node.p->nodeId;
- if(node.p->alive && ptr.p->nodes.get(nodeId)) {
- jam();
- sendSignal(numberToRef(BACKUP, nodeId), GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
- }//if
- }//for
-}
-
-/*****************************************************************************
- *
- * Slave functionallity: Stop backup
- *
- *****************************************************************************/
-void
-Backup::execSTOP_BACKUP_REQ(Signal* signal)
-{
- jamEntry();
- StopBackupReq * req = (StopBackupReq*)signal->getDataPtr();
-
- CRASH_INSERTION((10020));
-
- const Uint32 ptrI = req->backupPtr;
- //const Uint32 backupId = req->backupId;
- const Uint32 startGCP = req->startGCP;
- const Uint32 stopGCP = req->stopGCP;
-
- /**
- * At least one GCP must have passed
- */
- ndbrequire(stopGCP > startGCP);
-
- /**
- * Get backup record
- */
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
-
- ptr.p->slaveState.setState(STOPPING);
- ptr.p->m_gsn = GSN_STOP_BACKUP_REQ;
- ptr.p->startGCP= startGCP;
- ptr.p->stopGCP= stopGCP;
-
- /**
- * Destroy the triggers in local DBTUP we created
- */
- sendDropTrig(signal, ptr);
-}
-
-void
-Backup::closeFiles(Signal* sig, BackupRecordPtr ptr)
-{
- /**
- * Close all files
- */
- BackupFilePtr filePtr;
- int openCount = 0;
- for(ptr.p->files.first(filePtr); filePtr.i!=RNIL; ptr.p->files.next(filePtr))
- {
- if(! (filePtr.p->m_flags & BackupFile::BF_OPEN))
- {
- jam();
- continue;
- }
-
- jam();
- openCount++;
-
- if(filePtr.p->m_flags & BackupFile::BF_CLOSING)
- {
- jam();
- continue;
- }//if
-
- filePtr.p->operation.dataBuffer.eof();
- if(filePtr.p->m_flags & BackupFile::BF_FILE_THREAD)
- {
- jam();
-#ifdef DEBUG_ABORT
- ndbout_c("Close files fileRunning == 1, filePtr.i=%u", filePtr.i);
-#endif
- }
- else
- {
- jam();
- closeFile(sig, ptr, filePtr);
- }
- }
-
- if(openCount == 0){
- jam();
- closeFilesDone(sig, ptr);
- }//if
-}
-
-void
-Backup::closeFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr)
-{
- ndbrequire(filePtr.p->m_flags & BackupFile::BF_OPEN);
- ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_OPENING));
- ndbrequire(! (filePtr.p->m_flags & BackupFile::BF_CLOSING));
- filePtr.p->m_flags |= BackupFile::BF_CLOSING;
-
- FsCloseReq * req = (FsCloseReq *)signal->getDataPtrSend();
- req->filePointer = filePtr.p->filePointer;
- req->userPointer = filePtr.i;
- req->userReference = reference();
- req->fileFlag = 0;
-
- if (ptr.p->errorCode)
- {
- FsCloseReq::setRemoveFileFlag(req->fileFlag, 1);
- }
-
-#ifdef DEBUG_ABORT
- ndbout_c("***** a FSCLOSEREQ filePtr.i = %u flags: %x",
- filePtr.i, filePtr.p->m_flags);
-#endif
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
-
-}
-
-void
-Backup::execFSCLOSEREF(Signal* signal)
-{
- jamEntry();
-
- FsRef * ref = (FsRef*)signal->getDataPtr();
- const Uint32 filePtrI = ref->userPointer;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- FsConf * conf = (FsConf*)signal->getDataPtr();
- conf->userPointer = filePtrI;
-
- execFSCLOSECONF(signal);
-}
-
-void
-Backup::execFSCLOSECONF(Signal* signal)
-{
- jamEntry();
-
- FsConf * conf = (FsConf*)signal->getDataPtr();
- const Uint32 filePtrI = conf->userPointer;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, filePtrI);
-
-#ifdef DEBUG_ABORT
- ndbout_c("***** FSCLOSECONF filePtrI = %u", filePtrI);
-#endif
-
- ndbrequire(filePtr.p->m_flags == (BackupFile::BF_OPEN |
- BackupFile::BF_CLOSING));
-
-
- filePtr.p->m_flags &= ~(Uint32)(BackupFile::BF_OPEN |BackupFile::BF_CLOSING);
- filePtr.p->operation.dataBuffer.reset();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
- closeFiles(signal, ptr);
-}
-
-void
-Backup::closeFilesDone(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- if(ptr.p->is_lcp())
- {
- lcp_close_file_conf(signal, ptr);
- return;
- }
-
- jam();
-
- //error when do insert footer or close file
- if(ptr.p->checkError())
- {
- StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
- ref->backupPtr = ptr.i;
- ref->backupId = ptr.p->backupId;
- ref->errorCode = ptr.p->errorCode;
- ref->nodeId = getOwnNodeId();
- sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_REF, signal,
- StopBackupConf::SignalLength, JBB);
-
- ptr.p->m_gsn = GSN_STOP_BACKUP_REF;
- ptr.p->slaveState.setState(CLEANING);
- return;
- }
-
- StopBackupConf* conf = (StopBackupConf*)signal->getDataPtrSend();
- conf->backupId = ptr.p->backupId;
- conf->backupPtr = ptr.i;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- if(ptr.p->logFilePtr != RNIL)
- {
- ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
- conf->noOfLogBytes= filePtr.p->operation.noOfBytes;
- conf->noOfLogRecords= filePtr.p->operation.noOfRecords;
- }
- else
- {
- conf->noOfLogBytes= 0;
- conf->noOfLogRecords= 0;
- }
-
- sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_CONF, signal,
- StopBackupConf::SignalLength, JBB);
-
- ptr.p->m_gsn = GSN_STOP_BACKUP_CONF;
- ptr.p->slaveState.setState(CLEANING);
-}
-
-/*****************************************************************************
- *
- * Slave functionallity: Abort backup
- *
- *****************************************************************************/
-/*****************************************************************************
- *
- * Slave functionallity: Abort backup
- *
- *****************************************************************************/
-void
-Backup::execABORT_BACKUP_ORD(Signal* signal)
-{
- jamEntry();
- AbortBackupOrd* ord = (AbortBackupOrd*)signal->getDataPtr();
-
- const Uint32 backupId = ord->backupId;
- const AbortBackupOrd::RequestType requestType =
- (AbortBackupOrd::RequestType)ord->requestType;
- const Uint32 senderData = ord->senderData;
-
-#ifdef DEBUG_ABORT
- ndbout_c("******** ABORT_BACKUP_ORD ********* nodeId = %u",
- refToNode(signal->getSendersBlockRef()));
- ndbout_c("backupId = %u, requestType = %u, senderData = %u, ",
- backupId, requestType, senderData);
- dumpUsedResources();
-#endif
-
- BackupRecordPtr ptr LINT_SET_PTR;
- if(requestType == AbortBackupOrd::ClientAbort) {
- if (getOwnNodeId() != getMasterNodeId()) {
- jam();
- // forward to master
-#ifdef DEBUG_ABORT
- ndbout_c("---- Forward to master nodeId = %u", getMasterNodeId());
-#endif
- sendSignal(calcBackupBlockRef(getMasterNodeId()), GSN_ABORT_BACKUP_ORD,
- signal, AbortBackupOrd::SignalLength, JBB);
- return;
- }
- jam();
- for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
- jam();
- if(ptr.p->backupId == backupId && ptr.p->clientData == senderData) {
- jam();
- break;
- }//if
- }//for
- if(ptr.i == RNIL) {
- jam();
- return;
- }//if
- } else {
- if (c_backupPool.findId(senderData)) {
- jam();
- c_backupPool.getPtr(ptr, senderData);
- } else {
- jam();
-#ifdef DEBUG_ABORT
- ndbout_c("Backup: abort request type=%u on id=%u,%u not found",
- requestType, backupId, senderData);
-#endif
- return;
- }
- }//if
-
- ptr.p->m_gsn = GSN_ABORT_BACKUP_ORD;
- const bool isCoordinator = (ptr.p->masterRef == reference());
-
- bool ok = false;
- switch(requestType){
-
- /**
- * Requests sent to master
- */
- case AbortBackupOrd::ClientAbort:
- jam();
- // fall through
- case AbortBackupOrd::LogBufferFull:
- jam();
- // fall through
- case AbortBackupOrd::FileOrScanError:
- jam();
- ndbrequire(isCoordinator);
- ptr.p->setErrorCode(requestType);
- if(ptr.p->masterData.gsn == GSN_BACKUP_FRAGMENT_REQ)
- {
- /**
- * Only scans are actively aborted
- */
- abort_scan(signal, ptr);
- }
- return;
-
- /**
- * Requests sent to slave
- */
- case AbortBackupOrd::AbortScan:
- jam();
- ptr.p->setErrorCode(requestType);
- return;
-
- case AbortBackupOrd::BackupComplete:
- jam();
- cleanup(signal, ptr);
- return;
- case AbortBackupOrd::BackupFailure:
- case AbortBackupOrd::BackupFailureDueToNodeFail:
- case AbortBackupOrd::OkToClean:
- case AbortBackupOrd::IncompatibleVersions:
-#ifndef VM_TRACE
- default:
-#endif
- ptr.p->setErrorCode(requestType);
- ok= true;
- }
- ndbrequire(ok);
-
- ptr.p->masterRef = reference();
- ptr.p->nodes.clear();
- ptr.p->nodes.set(getOwnNodeId());
-
-
- ptr.p->stopGCP= ptr.p->startGCP + 1;
- sendStopBackup(signal, ptr);
-}
-
-
-void
-Backup::dumpUsedResources()
-{
- jam();
- BackupRecordPtr ptr;
-
- for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)) {
- ndbout_c("Backup id=%u, slaveState.getState = %u, errorCode=%u",
- ptr.p->backupId,
- ptr.p->slaveState.getState(),
- ptr.p->errorCode);
-
- TablePtr tabPtr;
- for(ptr.p->tables.first(tabPtr);
- tabPtr.i != RNIL;
- ptr.p->tables.next(tabPtr)) {
- jam();
- for(Uint32 j = 0; j<3; j++) {
- jam();
- TriggerPtr trigPtr LINT_SET_PTR;
- if(tabPtr.p->triggerAllocated[j]) {
- jam();
- c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
- ndbout_c("Allocated[%u] Triggerid = %u, event = %u",
- j,
- tabPtr.p->triggerIds[j],
- trigPtr.p->event);
- }//if
- }//for
- }//for
-
- BackupFilePtr filePtr;
- for(ptr.p->files.first(filePtr);
- filePtr.i != RNIL;
- ptr.p->files.next(filePtr)) {
- jam();
- ndbout_c("filePtr.i = %u, flags: H'%x ",
- filePtr.i, filePtr.p->m_flags);
- }//for
- }
-}
-
-void
-Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
-{
-
- TablePtr tabPtr;
- for(ptr.p->tables.first(tabPtr); tabPtr.i != RNIL;ptr.p->tables.next(tabPtr))
- {
- jam();
- tabPtr.p->attributes.release();
- tabPtr.p->fragments.release();
- for(Uint32 j = 0; j<3; j++) {
- jam();
- TriggerPtr trigPtr LINT_SET_PTR;
- if(tabPtr.p->triggerAllocated[j]) {
- jam();
- c_triggerPool.getPtr(trigPtr, tabPtr.p->triggerIds[j]);
- trigPtr.p->event = ILLEGAL_TRIGGER_ID;
- tabPtr.p->triggerAllocated[j] = false;
- }//if
- tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
- }//for
- {
- signal->theData[0] = tabPtr.p->tableId;
- signal->theData[1] = 0; // unlock
- EXECUTE_DIRECT(DBDICT, GSN_BACKUP_FRAGMENT_REQ, signal, 2);
- }
- }//for
-
- BackupFilePtr filePtr;
- for(ptr.p->files.first(filePtr);filePtr.i != RNIL;ptr.p->files.next(filePtr))
- {
- jam();
- ndbrequire(filePtr.p->m_flags == 0);
- filePtr.p->pages.release();
- }//for
-
- ptr.p->files.release();
- ptr.p->tables.release();
- ptr.p->triggers.release();
- ptr.p->backupId = ~0;
-
- if(ptr.p->checkError())
- removeBackup(signal, ptr);
- else
- c_backups.release(ptr);
-}
-
-
-void
-Backup::removeBackup(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->directory = 1;
- req->ownDirectory = 1;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
- FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
- FsRemoveReq::SignalLength, JBA);
-}
-
-void
-Backup::execFSREMOVEREF(Signal* signal)
-{
- jamEntry();
- FsRef * ref = (FsRef*)signal->getDataPtr();
- const Uint32 ptrI = ref->userPointer;
-
- FsConf * conf = (FsConf*)signal->getDataPtr();
- conf->userPointer = ptrI;
- execFSREMOVECONF(signal);
-}
-
-void
-Backup::execFSREMOVECONF(Signal* signal){
- jamEntry();
-
- FsConf * conf = (FsConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->userPointer;
-
- /**
- * Get backup record
- */
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, ptrI);
- c_backups.release(ptr);
-}
-
-/**
- * LCP
- */
-void
-Backup::execLCP_PREPARE_REQ(Signal* signal)
-{
- jamEntry();
- LcpPrepareReq req = *(LcpPrepareReq*)signal->getDataPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, req.backupPtr);
-
- ptr.p->m_gsn = GSN_LCP_PREPARE_REQ;
-
- TablePtr tabPtr;
- FragmentPtr fragPtr;
- if (!ptr.p->tables.isEmpty())
- {
- jam();
- ndbrequire(ptr.p->errorCode);
- ptr.p->tables.first(tabPtr);
- if (tabPtr.p->tableId == req.tableId)
- {
- jam();
- ndbrequire(!tabPtr.p->fragments.empty());
- tabPtr.p->fragments.getPtr(fragPtr, 0);
- fragPtr.p->fragmentId = req.fragmentId;
- defineBackupRef(signal, ptr, ptr.p->errorCode);
- return;
- }
- else
- {
- jam();
- tabPtr.p->attributes.release();
- tabPtr.p->fragments.release();
- ptr.p->tables.release();
- ptr.p->errorCode = 0;
- // fall-through
- }
- }
-
- if(!ptr.p->tables.seize(tabPtr) || !tabPtr.p->fragments.seize(1))
- {
- if(!tabPtr.isNull())
- ptr.p->tables.release();
- ndbrequire(false); // TODO
- }
- tabPtr.p->tableId = req.tableId;
- tabPtr.p->fragments.getPtr(fragPtr, 0);
- tabPtr.p->tableType = DictTabInfo::UserTable;
- fragPtr.p->fragmentId = req.fragmentId;
- fragPtr.p->lcp_no = req.lcpNo;
- fragPtr.p->scanned = 0;
- fragPtr.p->scanning = 0;
- fragPtr.p->tableId = req.tableId;
-
- ptr.p->backupId= req.backupId;
- lcp_open_file(signal, ptr);
-}
-
-void
-Backup::lcp_close_file_conf(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- TablePtr tabPtr;
- ndbrequire(ptr.p->tables.first(tabPtr));
- Uint32 tableId = tabPtr.p->tableId;
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
- ndbrequire(filePtr.p->m_flags == 0);
-
- if (ptr.p->m_gsn == GSN_LCP_PREPARE_REQ)
- {
- jam();
- defineBackupRef(signal, ptr, ptr.p->errorCode);
- return;
- }
-
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, 0);
- Uint32 fragmentId = fragPtr.p->fragmentId;
-
- tabPtr.p->attributes.release();
- tabPtr.p->fragments.release();
- ptr.p->tables.release();
- ptr.p->errorCode = 0;
-
- BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtrSend();
- conf->backupId = ptr.p->backupId;
- conf->backupPtr = ptr.i;
- conf->tableId = tableId;
- conf->fragmentNo = fragmentId;
- conf->noOfRecordsLow = 0;
- conf->noOfRecordsHigh = 0;
- conf->noOfBytesLow = 0;
- conf->noOfBytesHigh = 0;
- sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
- BackupFragmentConf::SignalLength, JBB);
-}
-
-void
-Backup::lcp_open_file(Signal* signal, BackupRecordPtr ptr)
-{
- FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->fileFlags =
- FsOpenReq::OM_WRITEONLY |
- FsOpenReq::OM_TRUNCATE |
- FsOpenReq::OM_CREATE |
- FsOpenReq::OM_APPEND |
- FsOpenReq::OM_AUTOSYNC;
- if (c_defaults.m_o_direct)
- req->fileFlags |= FsOpenReq::OM_DIRECT;
- FsOpenReq::v2_setCount(req->fileNumber, 0xFFFFFFFF);
- req->auto_sync_size = c_defaults.m_disk_synch_size;
-
- TablePtr tabPtr;
- FragmentPtr fragPtr;
-
- ndbrequire(ptr.p->tables.first(tabPtr));
- tabPtr.p->fragments.getPtr(fragPtr, 0);
-
- /**
- * Lcp file
- */
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
- ndbrequire(filePtr.p->m_flags == 0);
- filePtr.p->m_flags |= BackupFile::BF_OPENING;
- filePtr.p->tableId = RNIL; // Will force init
- req->userPointer = filePtr.i;
- FsOpenReq::setVersion(req->fileNumber, 5);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
- FsOpenReq::v5_setLcpNo(req->fileNumber, fragPtr.p->lcp_no);
- FsOpenReq::v5_setTableId(req->fileNumber, tabPtr.p->tableId);
- FsOpenReq::v5_setFragmentId(req->fileNumber, fragPtr.p->fragmentId);
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}
-
-void
-Backup::lcp_open_file_done(Signal* signal, BackupRecordPtr ptr)
-{
- TablePtr tabPtr;
- FragmentPtr fragPtr;
-
- ndbrequire(ptr.p->tables.first(tabPtr));
- tabPtr.p->fragments.getPtr(fragPtr, 0);
-
- BackupFilePtr filePtr LINT_SET_PTR;
- c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr);
- ndbrequire(filePtr.p->m_flags ==
- (BackupFile::BF_OPEN | BackupFile::BF_LCP_META));
- filePtr.p->m_flags &= ~(Uint32)BackupFile::BF_LCP_META;
-
- ptr.p->slaveState.setState(STARTED);
-
- LcpPrepareConf* conf= (LcpPrepareConf*)signal->getDataPtrSend();
- conf->senderData = ptr.p->clientData;
- conf->senderRef = reference();
- conf->tableId = tabPtr.p->tableId;
- conf->fragmentId = fragPtr.p->fragmentId;
- sendSignal(ptr.p->masterRef, GSN_LCP_PREPARE_CONF,
- signal, LcpPrepareConf::SignalLength, JBB);
-
- /**
- * Start file thread
- */
- filePtr.p->m_flags |= BackupFile::BF_FILE_THREAD;
-
- signal->theData[0] = BackupContinueB::START_FILE_THREAD;
- signal->theData[1] = filePtr.i;
- signal->theData[2] = __LINE__;
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 3);
-}
-
-void
-Backup::execEND_LCPREQ(Signal* signal)
-{
- EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
-
- BackupRecordPtr ptr LINT_SET_PTR;
- c_backupPool.getPtr(ptr, req->backupPtr);
- ndbrequire(ptr.p->backupId == req->backupId);
-
- BackupFilePtr filePtr LINT_SET_PTR;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- ndbrequire(filePtr.p->m_flags == 0);
-
- if (!ptr.p->tables.isEmpty())
- {
- jam();
- ndbrequire(ptr.p->errorCode);
- TablePtr tabPtr;
- ptr.p->tables.first(tabPtr);
- tabPtr.p->attributes.release();
- tabPtr.p->fragments.release();
- ptr.p->tables.release();
- ptr.p->errorCode = 0;
- }
-
- ptr.p->errorCode = 0;
- ptr.p->slaveState.setState(CLEANING);
- ptr.p->slaveState.setState(INITIAL);
- ptr.p->slaveState.setState(DEFINING);
- ptr.p->slaveState.setState(DEFINED);
-
- EndLcpConf* conf= (EndLcpConf*)signal->getDataPtr();
- conf->senderData = ptr.p->clientData;
- conf->senderRef = reference();
- sendSignal(ptr.p->masterRef, GSN_END_LCPCONF,
- signal, EndLcpConf::SignalLength, JBB);
-}
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.hpp b/storage/ndb/src/kernel/blocks/backup/Backup.hpp
deleted file mode 100644
index 7a3280f2ba6..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/Backup.hpp
+++ /dev/null
@@ -1,752 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef BACKUP_H
-#define BACKUP_H
-
-#include <ndb_limits.h>
-#include <SimulatedBlock.hpp>
-
-#include "FsBuffer.hpp"
-#include "BackupFormat.hpp"
-
-#include <NodeBitmask.hpp>
-#include <SimpleProperties.hpp>
-
-#include <SLList.hpp>
-#include <DLFifoList.hpp>
-#include <DLCFifoList.hpp>
-#include <SignalCounter.hpp>
-#include <blocks/mutexes.hpp>
-
-#include <NdbTCP.h>
-#include <NdbTick.h>
-#include <Array.hpp>
-
-/**
- * Backup - This block manages database backup and restore
- */
-class Backup : public SimulatedBlock
-{
-public:
- Backup(Block_context& ctx);
- virtual ~Backup();
- BLOCK_DEFINES(Backup);
-
-protected:
-
- void execSTTOR(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- /**
- * Testing
- */
- void execBACKUP_REF(Signal* signal);
- void execBACKUP_CONF(Signal* signal);
- void execBACKUP_ABORT_REP(Signal* signal);
- void execBACKUP_COMPLETE_REP(Signal* signal);
-
- /**
- * Signals sent from master
- */
- void execDEFINE_BACKUP_REQ(Signal* signal);
- void execBACKUP_DATA(Signal* signal);
- void execSTART_BACKUP_REQ(Signal* signal);
- void execBACKUP_FRAGMENT_REQ(Signal* signal);
- void execBACKUP_FRAGMENT_COMPLETE_REP(Signal* signal);
- void execSTOP_BACKUP_REQ(Signal* signal);
- void execBACKUP_STATUS_REQ(Signal* signal);
- void execABORT_BACKUP_ORD(Signal* signal);
-
- /**
- * The actual scan
- */
- void execSCAN_HBREP(Signal* signal);
- void execTRANSID_AI(Signal* signal);
- void execSCAN_FRAGREF(Signal* signal);
- void execSCAN_FRAGCONF(Signal* signal);
-
- /**
- * Trigger logging
- */
- void execBACKUP_TRIG_REQ(Signal* signal);
- void execTRIG_ATTRINFO(Signal* signal);
- void execFIRE_TRIG_ORD(Signal* signal);
-
- /**
- * DICT signals
- */
- void execLIST_TABLES_CONF(Signal* signal);
- void execGET_TABINFOREF(Signal* signal);
- void execGET_TABINFO_CONF(Signal* signal);
- void execCREATE_TRIG_REF(Signal* signal);
- void execCREATE_TRIG_CONF(Signal* signal);
- void execDROP_TRIG_REF(Signal* signal);
- void execDROP_TRIG_CONF(Signal* signal);
-
- /**
- * DIH signals
- */
- void execDI_FCOUNTCONF(Signal* signal);
- void execDIGETPRIMCONF(Signal* signal);
-
- /**
- * FS signals
- */
- void execFSOPENREF(Signal* signal);
- void execFSOPENCONF(Signal* signal);
-
- void execFSCLOSEREF(Signal* signal);
- void execFSCLOSECONF(Signal* signal);
-
- void execFSAPPENDREF(Signal* signal);
- void execFSAPPENDCONF(Signal* signal);
-
- void execFSREMOVEREF(Signal* signal);
- void execFSREMOVECONF(Signal* signal);
-
- /**
- * Master functinallity
- */
- void execBACKUP_REQ(Signal* signal);
- void execABORT_BACKUP_REQ(Signal* signal);
-
- void execDEFINE_BACKUP_REF(Signal* signal);
- void execDEFINE_BACKUP_CONF(Signal* signal);
-
- void execSTART_BACKUP_REF(Signal* signal);
- void execSTART_BACKUP_CONF(Signal* signal);
-
- void execBACKUP_FRAGMENT_REF(Signal* signal);
- void execBACKUP_FRAGMENT_CONF(Signal* signal);
-
- void execSTOP_BACKUP_REF(Signal* signal);
- void execSTOP_BACKUP_CONF(Signal* signal);
-
- void execBACKUP_STATUS_CONF(Signal* signal);
-
- void execUTIL_SEQUENCE_REF(Signal* signal);
- void execUTIL_SEQUENCE_CONF(Signal* signal);
-
- void execWAIT_GCP_REF(Signal* signal);
- void execWAIT_GCP_CONF(Signal* signal);
-
- void execLCP_PREPARE_REQ(Signal* signal);
- void execLCP_FRAGMENT_REQ(Signal*);
- void execEND_LCPREQ(Signal* signal);
-private:
- void defineBackupMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
- void dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal);
-
-public:
- struct Node {
- Uint32 nodeId;
- Uint32 alive;
- Uint32 nextList;
- union { Uint32 prevList; Uint32 nextPool; };
- };
- typedef Ptr<Node> NodePtr;
-
-#define BACKUP_WORDS_PER_PAGE 8191
- struct Page32 {
- Uint32 data[BACKUP_WORDS_PER_PAGE];
- Uint32 nextPool;
- };
- typedef Ptr<Page32> Page32Ptr;
-
- struct Attribute {
- enum Flags {
- COL_NULLABLE = 0x1,
- COL_FIXED = 0x2,
- COL_DISK = 0x4
- };
- struct Data {
- Uint16 m_flags;
- Uint16 attrId;
- Uint32 sz32; // No of 32 bit words
- Uint32 offset; // Relative DataFixedAttributes/DataFixedKeys
- Uint32 offsetNull; // In NullBitmask
- } data;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<Attribute> AttributePtr;
-
- struct Fragment {
- Uint64 noOfRecords;
- Uint32 tableId;
- Uint16 node;
- Uint16 fragmentId;
- Uint8 scanned; // 0 = not scanned x = scanned by node x
- Uint8 scanning; // 0 = not scanning x = scanning on node x
- Uint8 lcp_no;
- Uint32 nextPool;
- };
- typedef Ptr<Fragment> FragmentPtr;
-
- struct Table {
- Table(ArrayPool<Attribute> &, ArrayPool<Fragment> &);
-
- Uint64 noOfRecords;
-
- Uint32 tableId;
- Uint32 schemaVersion;
- Uint32 tableType;
- Uint32 noOfNull;
- Uint32 noOfAttributes;
- Uint32 noOfVariable;
- Uint32 sz_FixedAttributes;
- Uint32 triggerIds[3];
- bool triggerAllocated[3];
-
- DLFifoList<Attribute> attributes;
- Array<Fragment> fragments;
-
- Uint32 nextList;
- union { Uint32 nextPool; Uint32 prevList; };
- };
- typedef Ptr<Table> TablePtr;
-
- struct OperationRecord {
- public:
- OperationRecord(Backup & b) : backup(b) {}
-
- /**
- * Once per table
- */
- void init(const TablePtr & ptr);
-
- /**
- * Once per fragment
- */
- bool newFragment(Uint32 tableId, Uint32 fragNo);
- bool fragComplete(Uint32 tableId, Uint32 fragNo, bool fill_record);
-
- /**
- * Once per scan frag (next) req/conf
- */
- bool newScan();
- bool scanConf(Uint32 noOfOps, Uint32 opLen);
- bool closeScan();
-
- /**
- * Per record
- */
- void newRecord(Uint32 * base);
- bool finished();
-
- /**
- * Per attribute
- */
- void nullVariable();
- void nullAttribute(Uint32 nullOffset);
- Uint32 * newNullable(Uint32 attrId, Uint32 sz);
- Uint32 * newAttrib(Uint32 offset, Uint32 sz);
- Uint32 * newVariable(Uint32 id, Uint32 sz);
-
- private:
- Uint32* base;
- Uint32* dst_Length;
- Uint32* dst_Bitmask;
- Uint32* dst_FixedAttribs;
- BackupFormat::DataFile::VariableData* dst_VariableData;
-
- Uint32 noOfAttributes; // No of Attributes
- Uint32 attrLeft; // No of attributes left
-
- Uint32 opNoDone;
- Uint32 opNoConf;
- Uint32 opLen;
-
- public:
- Uint32* dst;
- Uint32 attrSzTotal; // No of AI words received
- Uint32 tablePtr; // Ptr.i to current table
-
- FsBuffer dataBuffer;
- Uint64 noOfRecords;
- Uint64 noOfBytes;
- Uint32 maxRecordSize;
-
- private:
- Uint32* scanStart;
- Uint32* scanStop;
-
- /**
- * sizes of part
- */
- Uint32 sz_Bitmask;
- Uint32 sz_FixedAttribs;
-
- public:
- union { Uint32 nextPool; Uint32 nextList; };
- Uint32 prevList;
- private:
-
- Backup & backup;
- BlockNumber number() const { return backup.number(); }
- void progError(int line, int cause, const char * extra) {
- backup.progError(line, cause, extra);
- }
- };
- friend struct OperationRecord;
-
- struct TriggerRecord {
- TriggerRecord() { event = ~0;}
- OperationRecord * operation;
- BackupFormat::LogFile::LogEntry * logEntry;
- Uint32 maxRecordSize;
- Uint32 tableId;
- Uint32 tab_ptr_i;
- Uint32 event;
- Uint32 backupPtr;
- Uint32 errorCode;
- union { Uint32 nextPool; Uint32 nextList; };
- };
- typedef Ptr<TriggerRecord> TriggerPtr;
-
- /**
- * BackupFile - At least 3 per backup
- */
- struct BackupFile {
- BackupFile(Backup & backup, ArrayPool<Page32> & pp)
- : operation(backup), pages(pp) {}
-
- Uint32 backupPtr; // Pointer to backup record
- Uint32 tableId;
- Uint32 fragmentNo;
- Uint32 filePointer;
- Uint32 errorCode;
- BackupFormat::FileType fileType;
- OperationRecord operation;
-
- Array<Page32> pages;
- Uint32 nextList;
- union { Uint32 prevList; Uint32 nextPool; };
-
- enum {
- BF_OPEN = 0x1
- ,BF_OPENING = 0x2
- ,BF_CLOSING = 0x4
- ,BF_FILE_THREAD = 0x8
- ,BF_SCAN_THREAD = 0x10
- ,BF_LCP_META = 0x20
- };
- Uint32 m_flags;
- Uint32 m_pos;
- };
- typedef Ptr<BackupFile> BackupFilePtr;
-
-
- /**
- * State for BackupRecord
- */
- enum State {
- INITIAL = 0,
- DEFINING = 1, // Defining backup content and parameters
- DEFINED = 2, // DEFINE_BACKUP_CONF sent in slave, received all in master
- STARTED = 3, // Creating triggers
- SCANNING = 4, // Scanning fragments
- STOPPING = 5, // Closing files
- CLEANING = 6, // Cleaning resources
- ABORTING = 7 // Aborting backup
- };
-
- static const Uint32 validSlaveTransitionsCount;
- static const Uint32 validMasterTransitionsCount;
- static const State validSlaveTransitions[];
- static const State validMasterTransitions[];
-
- class CompoundState {
- public:
- CompoundState(Backup & b,
- const State valid[],
- Uint32 count, Uint32 _id)
- : backup(b)
- , validTransitions(valid),
- noOfValidTransitions(count), id(_id)
- {
- state = INITIAL;
- abortState = state;
- }
-
- void setState(State s);
- State getState() const { return state;}
- State getAbortState() const { return abortState;}
-
- void forceState(State s);
-
- BlockNumber number() const { return backup.number(); }
- void progError(int line, int cause, const char * extra) {
- backup.progError(line, cause, extra);
- }
- private:
- Backup & backup;
- State state;
- State abortState; /**
- When state == ABORTING, this contains the state
- when the abort started
- */
- const State * validTransitions;
- const Uint32 noOfValidTransitions;
- const Uint32 id;
- };
- friend class CompoundState;
-
- /**
- * Backup record
- *
- * One record per backup
- */
- struct BackupRecord {
- BackupRecord(Backup& b,
- ArrayPool<Table> & tp,
- ArrayPool<BackupFile> & bp,
- ArrayPool<TriggerRecord> & trp)
- : slaveState(b, validSlaveTransitions, validSlaveTransitionsCount,1)
- , tables(tp), triggers(trp), files(bp)
- , ctlFilePtr(RNIL), logFilePtr(RNIL), dataFilePtr(RNIL)
- , masterData(b), backup(b)
-
- {
- }
-
- Uint32 m_gsn;
- CompoundState slaveState;
-
- Uint32 clientRef;
- Uint32 clientData;
- Uint32 flags;
- Uint32 signalNo;
- Uint32 backupId;
- Uint32 backupKey[2];
- Uint32 masterRef;
- Uint32 errorCode;
- NdbNodeBitmask nodes;
-
- Uint64 noOfBytes;
- Uint64 noOfRecords;
- Uint64 noOfLogBytes;
- Uint64 noOfLogRecords;
-
- Uint32 startGCP;
- Uint32 currGCP;
- Uint32 stopGCP;
- DLCFifoList<Table> tables;
- SLList<TriggerRecord> triggers;
-
- SLList<BackupFile> files;
- Uint32 ctlFilePtr; // Ptr.i to ctl-file
- Uint32 logFilePtr; // Ptr.i to log-file
- Uint32 dataFilePtr; // Ptr.i to first data-file
-
- Uint32 backupDataLen; // Used for (un)packing backup request
- SimpleProperties props;// Used for (un)packing backup request
-
- struct SlaveData {
- SignalCounter trigSendCounter;
- Uint32 gsn;
- struct {
- Uint32 tableId;
- } createTrig;
- struct {
- Uint32 tableId;
- } dropTrig;
- } slaveData;
-
- struct MasterData {
- MasterData(Backup & b)
- {
- }
- MutexHandle2<BACKUP_DEFINE_MUTEX> m_defineBackupMutex;
- MutexHandle2<DICT_COMMIT_TABLE_MUTEX> m_dictCommitTableMutex;
-
- Uint32 gsn;
- SignalCounter sendCounter;
- Uint32 errorCode;
- union {
- struct {
- Uint32 startBackup;
- } waitGCP;
- struct {
- Uint32 signalNo;
- Uint32 noOfSignals;
- Uint32 tablePtr;
- } startBackup;
- struct {
- Uint32 dummy;
- } stopBackup;
- };
- } masterData;
-
- Uint32 nextList;
- union { Uint32 prevList; Uint32 nextPool; };
-
- void setErrorCode(Uint32 errCode){
- if(errorCode == 0)
- errorCode = errCode;
- }
-
- bool checkError() const {
- return errorCode != 0;
- }
-
- bool is_lcp() const {
- return backupDataLen == ~(Uint32)0;
- }
-
- Backup & backup;
- BlockNumber number() const { return backup.number(); }
- void progError(int line, int cause, const char * extra) {
- backup.progError(line, cause, extra);
- }
- };
- friend struct BackupRecord;
- typedef Ptr<BackupRecord> BackupRecordPtr;
-
- struct Config {
- Uint32 m_dataBufferSize;
- Uint32 m_logBufferSize;
- Uint32 m_minWriteSize;
- Uint32 m_maxWriteSize;
- Uint32 m_lcp_buffer_size;
-
- Uint32 m_disk_write_speed_sr;
- Uint32 m_disk_write_speed;
- Uint32 m_disk_synch_size;
- Uint32 m_diskless;
- Uint32 m_o_direct;
- };
-
- /**
- * Variables
- */
- Uint32 * c_startOfPages;
- NodeId c_masterNodeId;
- SLList<Node> c_nodes;
- NdbNodeBitmask c_aliveNodes;
- DLList<BackupRecord> c_backups;
- Config c_defaults;
-
- /*
- Variables that control checkpoint to disk speed
- */
- Uint32 m_curr_disk_write_speed;
- Uint32 m_words_written_this_period;
- Uint32 m_overflow_disk_write;
- Uint32 m_reset_delay_used;
- NDB_TICKS m_reset_disk_speed_time;
- static const int DISK_SPEED_CHECK_DELAY = 100;
-
- STATIC_CONST(NO_OF_PAGES_META_FILE =
- (2*MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
- BACKUP_WORDS_PER_PAGE);
-
- /**
- * Pools
- */
- ArrayPool<Table> c_tablePool;
- ArrayPool<Attribute> c_attributePool;
- ArrayPool<BackupRecord> c_backupPool;
- ArrayPool<BackupFile> c_backupFilePool;
- ArrayPool<Page32> c_pagePool;
- ArrayPool<Fragment> c_fragmentPool;
- ArrayPool<Node> c_nodePool;
- ArrayPool<TriggerRecord> c_triggerPool;
-
- void checkFile(Signal*, BackupFilePtr);
- void checkScan(Signal*, BackupFilePtr);
- void fragmentCompleted(Signal*, BackupFilePtr);
-
- void backupAllData(Signal* signal, BackupRecordPtr);
-
- void getFragmentInfo(Signal*, BackupRecordPtr, TablePtr, Uint32 fragNo);
- void getFragmentInfoDone(Signal*, BackupRecordPtr);
-
- void openFiles(Signal* signal, BackupRecordPtr ptr);
- void openFilesReply(Signal*, BackupRecordPtr ptr, BackupFilePtr);
- void closeFiles(Signal*, BackupRecordPtr ptr);
- void closeFile(Signal*, BackupRecordPtr, BackupFilePtr);
- void closeFilesDone(Signal*, BackupRecordPtr ptr);
-
- void sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr);
-
- void defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
- void createTrigReply(Signal* signal, BackupRecordPtr ptr);
- void alterTrigReply(Signal* signal, BackupRecordPtr ptr);
- void startBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32);
- void stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
-
- void defineBackupRef(Signal*, BackupRecordPtr, Uint32 errCode = 0);
- void backupFragmentRef(Signal * signal, BackupFilePtr filePtr);
-
- void nextFragment(Signal*, BackupRecordPtr);
-
- void sendCreateTrig(Signal*, BackupRecordPtr ptr, TablePtr tabPtr);
- void createAttributeMask(TablePtr tab, Bitmask<MAXNROFATTRIBUTESINWORDS>&);
- void sendStartBackup(Signal*, BackupRecordPtr, TablePtr);
- void sendAlterTrig(Signal*, BackupRecordPtr ptr);
-
- void sendDropTrig(Signal*, BackupRecordPtr ptr);
- void sendDropTrig(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr);
- void dropTrigReply(Signal*, BackupRecordPtr ptr);
-
- void sendSignalAllWait(BackupRecordPtr ptr, Uint32 gsn, Signal *signal,
- Uint32 signalLength,
- bool executeDirect = false);
- bool haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId);
-
- void sendStopBackup(Signal*, BackupRecordPtr ptr);
- void sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr, Uint32 errCode);
- void sendAbortBackupOrdSlave(Signal* signal, BackupRecordPtr ptr,
- Uint32 errCode);
- void masterAbort(Signal*, BackupRecordPtr ptr);
- void masterSendAbortBackup(Signal*, BackupRecordPtr ptr);
- void slaveAbort(Signal*, BackupRecordPtr ptr);
-
- void abortFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr);
- void abortFileHook(Signal* signal, BackupFilePtr filePtr, bool scanDone);
-
- bool verifyNodesAlive(BackupRecordPtr, const NdbNodeBitmask& aNodeBitMask);
- bool checkAbort(BackupRecordPtr ptr);
- void checkNodeFail(Signal* signal,
- BackupRecordPtr ptr,
- NodeId newCoord,
- Uint32 theFailedNodes[NodeBitmask::Size]);
- void masterTakeOver(Signal* signal, BackupRecordPtr ptr);
-
-
- NodeId getMasterNodeId() const { return c_masterNodeId; }
- bool findTable(const BackupRecordPtr &, TablePtr &, Uint32 tableId) const;
- bool parseTableDescription(Signal*, BackupRecordPtr ptr, TablePtr, const Uint32*, Uint32);
-
- bool insertFileHeader(BackupFormat::FileType, BackupRecord*, BackupFile*);
- void sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode);
- void sendBackupRef(BlockReference ref, Uint32 flags, Signal *signal,
- Uint32 senderData, Uint32 errorCode);
- void dumpUsedResources();
- void cleanup(Signal*, BackupRecordPtr ptr);
- void abort_scan(Signal*, BackupRecordPtr ptr);
- void removeBackup(Signal*, BackupRecordPtr ptr);
-
- void sendSTTORRY(Signal*);
- void createSequence(Signal* signal);
- void createSequenceReply(Signal*, class UtilSequenceConf *);
-
- void lcp_open_file(Signal* signal, BackupRecordPtr ptr);
- void lcp_open_file_done(Signal*, BackupRecordPtr);
- void lcp_close_file_conf(Signal* signal, BackupRecordPtr);
-
- bool ready_to_write(bool ready, Uint32 sz, bool eof, BackupFile *fileP);
-};
-
-inline
-void
-Backup::OperationRecord::newRecord(Uint32 * p){
- base = p;
- dst_Length = p; p += 1;
- dst_Bitmask = p; p += sz_Bitmask;
- dst_FixedAttribs = p; p += sz_FixedAttribs;
- dst_VariableData = (BackupFormat::DataFile::VariableData*)p;
- BitmaskImpl::clear(sz_Bitmask, dst_Bitmask);
- attrLeft = noOfAttributes;
- attrSzTotal = 0;
-}
-
-inline
-Uint32 *
-Backup::OperationRecord::newAttrib(Uint32 offset, Uint32 sz){
- attrLeft--;
- dst = dst_FixedAttribs + offset;
- return dst;
-}
-
-inline
-void
-Backup::OperationRecord::nullAttribute(Uint32 offsetNull){
- attrLeft --;
- BitmaskImpl::set(sz_Bitmask, dst_Bitmask, offsetNull);
-}
-
-inline
-void
-Backup::OperationRecord::nullVariable()
-{
- attrLeft --;
-}
-
-inline
-Uint32 *
-Backup::OperationRecord::newNullable(Uint32 id, Uint32 sz){
- Uint32 sz32 = (sz + 3) >> 2;
-
- attrLeft--;
-
- dst = &dst_VariableData->Data[0];
- dst_VariableData->Sz = htonl(sz);
- dst_VariableData->Id = htonl(id);
-
- dst_VariableData = (BackupFormat::DataFile::VariableData *)(dst + sz32);
-
- // Clear all bits on newRecord -> dont need to clear this
- // BitmaskImpl::clear(sz_Bitmask, dst_Bitmask, offsetNull);
- return dst;
-}
-
-inline
-Uint32 *
-Backup::OperationRecord::newVariable(Uint32 id, Uint32 sz){
- Uint32 sz32 = (sz + 3) >> 2;
-
- attrLeft--;
-
- dst = &dst_VariableData->Data[0];
- dst_VariableData->Sz = htonl(sz);
- dst_VariableData->Id = htonl(id);
-
- dst_VariableData = (BackupFormat::DataFile::VariableData *)(dst + sz32);
- return dst;
-}
-
-inline
-bool
-Backup::OperationRecord::finished(){
- if(attrLeft != 0){
- return false;
- }
-
- opLen += attrSzTotal;
- opNoDone++;
-
- scanStop = dst = (Uint32 *)dst_VariableData;
-
- const Uint32 len = (dst - base - 1);
- * dst_Length = htonl(len);
-
- noOfRecords++;
-
- return true;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.txt b/storage/ndb/src/kernel/blocks/backup/Backup.txt
deleted file mode 100644
index 38b93f2d3c4..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/Backup.txt
+++ /dev/null
@@ -1,427 +0,0 @@
--- BACKUP SIGNAL DIAGRAM COMPLEMENT TO BACKUP AMENDMENTS 2003-07-11 --
-
-USER MASTER MASTER SLAVE SLAVE
----------------------------------------------------------------------
-BACKUP_REQ
----------------->
- UTIL_SEQUENCE
- --------------->
- <---------------
- DEFINE_BACKUP
- ------------------------------> (Local signals)
- LIST_TABLES
- --------------->
- <---------------
- FSOPEN
- --------------->
- GET_TABINFO
- <---------------
- DI_FCOUNT
- --------------->
- <---------------
- DI_GETPRIM
- --------------->
- <---------------
- <-------------------------------
-BACKUP_CONF
-<----------------
- START_BACKUP
- ------------------------------>
- CREATE_TRIG
- -------------->
- <--------------
- <------------------------------
- WAIT_GCP
- -------------->
- <--------------
- BACKUP_FRAGMENT
- ------------------------------>
- SCAN_FRAG
- --------------->
- <---------------
- <------------------------------
- WAIT_GCP
- -------------->
- <--------------
- STOP_BACKUP
- ------------------------------>
- DROP_TRIG
- -------------->
- <--------------
- <------------------------------
-BACKUP_COMPLETE_REP
-<----------------
- ABORT_BACKUP
- ------------------------------>
-
-----------------------------------------------------------------------------
-
-USER BACKUP-MASTER
-
-1) BACKUP_REQ -->
-
-2) To all slaves DEFINE_BACKUP_REQ
- This signals contains info so that all
- slaves can take over as master
- Tomas: Except triggerId info...
-
-3) Wait for conf
-
-4) <-- BACKUP_CONF
-
-5) For Each Table
- PREP_CREATE_TRIG_REQ
- Wait for Conf
-
-6) To all slaves START_BACKUP_REQ
- Include trigger ids
- Wait for conf
-
-7) For Each Table
- CREATE_TRIG_REQ
- Wait for conf
-
-8) Wait for GCP
-
-9) For each table
- For each fragment
- BACKUP_FRAGMENT_REQ -->
- <-- BACKUP_FRAGMENT_CONF
-
-10) Wait for GCP
-
-11) To all slaves STOP_BACKUP_REQ
- This signal turns off logging
-
-12) Wait for conf
-
-13) <-- BACKUP_COMPLETE_REP
-
-----
-
-Slave: Master Died
-Wait for master take-over, max 30 sec then abort everything
-
-Slave: Master TakeOver
-
-BACKUP_STATUS_REQ --> To all nodes
-<-- BACKUP_STATUS_CONF
-
-BACKUP_STATUS_CONF
- BACKUP_DEFINED
- BACKUP_STARTED
- BACKUP_FRAGMENT
-
-Master: Slave died
-
--- Define Backup Req --
-
-1) Get backup definition
- Which tables (all)
-
-2) Open files
- Write table list to CTL - file
-
-3) Get definitions for all tables in backup
-
-4) Get Fragment info
-
-5) Define Backup Conf
-
--- Define Backup Req --
-
--- Abort Backup Req --
-
-1) Report to others
-
-2) Stop logging
-3) Stop file(s)
-4) Stop scan
-
-5) If failure/abort
- Remove files
-
-6) If XXX
- Report to user
-7) Clean up records/stuff
-
--- Abort Backup --
-
-Reasons for aborting:
-
-1a) client abort
-
-1b) slave failure
-
-1c) node failure
-
-Resources to be cleaned up:
-
-Slave responsability:
-
-2a) Close and remove files
-
-2b) Free allocated resources
-
-Master responsability:
-
-2c) Drop triggers
-
-USER MASTER MASTER SLAVE SLAVE
----------------------------------------------------------------------
- BACKUP_ABORT_ORD:
- -------------------------(ALL)-->
- Set Master State ABORTING Set Slave State ABORTING
- Drop Triggers Close and Remove files
- CleanupSlaveResources()
-
- BACKUP_ABORT_ORD:OkToClean
- -------------------------(ALL)-->
-
-
- CleanupMasterResources()
-
-BACKUP_ABORT_REP
-<---------------
-
-
-
-State descriptions:
-
-Master - INITIAL
-BACKUP_REQ ->
-Master - DEFINING
-DEFINE_BACKUP_CONF ->
-Master - DEFINED
-CREATE_TRIG_CONF ->
-Master - STARTED
-<--->
-Master - SCANNING
-WAIT_GCP_CONF ->
-Master - STOPPING
-(Master - CLEANING)
---------
-Master - ABORTING
-
-
-Slave - INITIAL
-DEFINE_BACKUP_REQ ->
-Slave - DEFINING
- - backupId
- - tables
-DIGETPRIMCONF ->
-Slave - DEFINED
-START_BACKUP_REQ ->
-Slave - STARTED
-Slave - SCANNING
-STOP_BACKUP_REQ ->
-Slave - STOPPING
-FSCLOSECONF ->
-Slave - CLEANING
------
-Slave - ABORTING
-
-
-
-Testcases:
-
-2. Master failure at first START_BACKUP_CONF
-
-<masterId> error 10004
-start backup
-
-- Ok
-
-2. Master failure at first CREATE_TRIG_CONF
-
-<masterId> error 10003
-start backup
-
-- Ok
-
-2. Master failure at first ALTER_TRIG_CONF
-
-<masterId> error 10005
-start backup
-
-- Ok
-
-2. Master failure at WAIT_GCP_CONF
-
-<masterId> error 10007
-start backup
-
-- Ok
-
-2. Master failure at WAIT_GCP_CONF, nextFragment
-
-<masterId> error 10008
-start backup
-
-- Ok
-
-2. Master failure at WAIT_GCP_CONF, stopping
-
-<masterId> error 10009
-start backup
-
-- Ok
-
-2. Master failure at BACKUP_FRAGMENT_CONF
-
-<masterId> error 10010
-start backup
-
-- Ok
-
-2. Master failure at first DROP_TRIG_CONF
-
-<masterId> error 10012
-start backup
-
-- Ok
-
-1. Master failure at first STOP_BACKUP_CONF
-
-<masterId> error 10013
-start backup
-
-- Ok
-
-3. Multiple node failiure:
-
-<masterId> error 10001
-<otheId> error 10014
-start backup
-
-- Ok (note, mgmtsrvr does gets BACKUP_ABORT_REP but expects BACKUP_REF, hangs...)
-
-4. Multiple node failiure:
-
-<masterId> error 10007
-<takeover id> error 10002
-start backup
-
-- Ok
-
-
-
- ndbrequire(!ERROR_INSERTED(10001));
- ndbrequire(!ERROR_INSERTED(10002));
- ndbrequire(!ERROR_INSERTED(10021));
- ndbrequire(!ERROR_INSERTED(10003));
- ndbrequire(!ERROR_INSERTED(10004));
- ndbrequire(!ERROR_INSERTED(10005));
- ndbrequire(!ERROR_INSERTED(10006));
- ndbrequire(!ERROR_INSERTED(10007));
- ndbrequire(!ERROR_INSERTED(10008));
- ndbrequire(!ERROR_INSERTED(10009));
- ndbrequire(!ERROR_INSERTED(10010));
- ndbrequire(!ERROR_INSERTED(10011));
- ndbrequire(!ERROR_INSERTED(10012));
- ndbrequire(!ERROR_INSERTED(10013));
- ndbrequire(!ERROR_INSERTED(10014));
- ndbrequire(!ERROR_INSERTED(10015));
- ndbrequire(!ERROR_INSERTED(10016));
- ndbrequire(!ERROR_INSERTED(10017));
- ndbrequire(!ERROR_INSERTED(10018));
- ndbrequire(!ERROR_INSERTED(10019));
- ndbrequire(!ERROR_INSERTED(10020));
-
- if (ERROR_INSERTED(10023)) {
- if (ERROR_INSERTED(10023)) {
- if (ERROR_INSERTED(10024)) {
- if (ERROR_INSERTED(10025)) {
- if (ERROR_INSERTED(10026)) {
- if (ERROR_INSERTED(10028)) {
- if (ERROR_INSERTED(10027)) {
- (ERROR_INSERTED(10022))) {
- if (ERROR_INSERTED(10029)) {
- if(trigPtr.p->operation->noOfBytes > 123 && ERROR_INSERTED(10030)) {
-
------ XXX ---
-
-DEFINE_BACKUP_REF ->
- ABORT_BACKUP_ORD(no reply) when all DEFINE_BACKUP replies has arrived
-
-START_BACKUP_REF
- ABORT_BACKUP_ORD(no reply) when all START_BACKUP_ replies has arrived
-
-BACKUP_FRAGMENT_REF
- ABORT_BACKUP_ORD(reply) directly to all nodes running BACKUP_FRAGMENT
-
- When all nodes has replied BACKUP_FRAGMENT
- ABORT_BACKUP_ORD(no reply)
-
-STOP_BACKUP_REF
- ABORT_BACKUP_ORD(no reply) when all STOP_BACKUP_ replies has arrived
-
-NF_COMPLETE_REP
- slave dies
- master sends OUTSTANDING_REF to self
- slave does nothing
-
- master dies
- slave elects self as master and sets only itself as participant
-
-
-DATA FORMATS
-------------
-
-Note: api-restore must be able to read all old formats.
-
-Todo: header formats
-
-4.1.x
------
-
-Todo
-
-5.0.x
------
-
-Producers: backup, Consumers: api-restore
-
-In 5.0
- 1) attrs have fixed size
- 2) external attr id (column_no) is same as internal attr id (attr_id).
- 3) no disk attributes
-
-Format:
- Part 0: null-bit mask for all nullable rounded to word
- Part 1: fixed + non-nullable in column_no order
- Part 2: fixed + nullable in column_no order
-
-Part 1:
- plain value rounded to words [value]
-
-Part 2:
- not-null => clear null bit, data words [len_in_words attr_id value]
- null => set only null bit in null-bit mask
-
-Note: redundancy in null-bit mask vs 2 word header
-
-5.1.x
------
-
-Producers: backup, Consumers: api-restore lcp-restore
-
-In 5.1
- 1) attrs can have var size, length encoded in value
- 2) column_no need not equal attr_id
- 3) disk attributes
-
-Null-bit mask (5.0) is dropped.
-Length encoded in value is not used.
-In "lcp backup" disk attributes are replaced by 64-bit DISK_REF.
-
-Format:
- Part 1: fixed + non-nullable in column_no order
- Part 2: other attributes
-
-Part 1:
- plain value rounded to words [value]
-
-Part 2:
- not-null => data words [len_in_bytes attr_id value]
- null => not present
diff --git a/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp b/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp
deleted file mode 100644
index f48d0ed09d3..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef BACKUP_FORMAT_HPP
-#define BACKUP_FORMAT_HPP
-
-#include <ndb_types.h>
-
-static const char BACKUP_MAGIC[] = { 'N', 'D', 'B', 'B', 'C', 'K', 'U', 'P' };
-
-struct BackupFormat {
-
- /**
- * Section types in file
- */
- enum SectionType {
- FILE_HEADER = 1,
- FRAGMENT_HEADER = 2,
- FRAGMENT_FOOTER = 3,
- TABLE_LIST = 4,
- TABLE_DESCRIPTION = 5,
- GCP_ENTRY = 6,
- FRAGMENT_INFO = 7,
- EMPTY_ENTRY = 8
- };
-
- struct FileHeader {
- char Magic[8];
- Uint32 NdbVersion;
-
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 FileType;
- Uint32 BackupId;
- Uint32 BackupKey_0;
- Uint32 BackupKey_1;
- Uint32 ByteOrder;
- };
-
- /**
- * File types
- */
- enum FileType {
- CTL_FILE = 1,
- LOG_FILE = 2,
- DATA_FILE = 3,
- LCP_FILE = 4
- };
-
- /**
- * Data file formats
- */
- struct DataFile {
-
- struct FragmentHeader {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 TableId;
- Uint32 FragmentNo;
- Uint32 ChecksumType;
- };
-
- struct VariableData {
- Uint32 Sz;
- Uint32 Id;
- Uint32 Data[1];
- };
-
- struct Record {
- Uint32 Length;
- Uint32 NullBitmask[1];
- Uint32 DataFixedKeys[1];
- Uint32 DataFixedAttributes[1];
- VariableData DataVariableAttributes[1];
- };
-
- struct FragmentFooter {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 TableId;
- Uint32 FragmentNo;
- Uint32 NoOfRecords;
- Uint32 Checksum;
- };
-
- /* optional padding for O_DIRECT */
- struct EmptyEntry {
- Uint32 SectionType;
- Uint32 SectionLength;
- /* not used data */
- };
- };
-
- /**
- * CTL file formats
- */
- struct CtlFile {
-
- /**
- * Table list
- */
- struct TableList {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 TableIds[1]; // Length = SectionLength - 2
- };
-
- /**
- * Table description(s)
- */
- struct TableDescription {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 TableType;
- Uint32 DictTabInfo[1]; // Length = SectionLength - 3
- };
-
- /**
- * GCP Entry
- */
- struct GCPEntry {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 StartGCP;
- Uint32 StopGCP;
- };
-
- /**
- * Fragment Info
- */
- struct FragmentInfo {
- Uint32 SectionType;
- Uint32 SectionLength;
- Uint32 TableId;
- Uint32 FragmentNo;
- Uint32 NoOfRecordsLow;
- Uint32 NoOfRecordsHigh;
- Uint32 FilePosLow;
- Uint32 FilePosHigh;
- };
- };
-
- /**
- * LOG file format
- */
- struct LogFile {
-
- /**
- * Log Entry
- */
- struct LogEntry {
- Uint32 Length;
- Uint32 TableId;
- // If TriggerEvent & 0x10000 == true then GCI is right after data
- Uint32 TriggerEvent;
- Uint32 FragId;
- Uint32 Data[1]; // Len = Length - 3
- };
-
- /**
- * Log Entry pre NDBD_FRAGID_VERSION
- */
- struct LogEntry_no_fragid {
- Uint32 Length;
- Uint32 TableId;
- // If TriggerEvent & 0x10000 == true then GCI is right after data
- Uint32 TriggerEvent;
- Uint32 Data[1]; // Len = Length - 2
- };
- };
-
- /**
- * LCP file format
- */
- struct LcpFile {
- CtlFile::TableList TableList;
- CtlFile::TableDescription TableDescription;
- DataFile::FragmentHeader FragmentHeader;
- DataFile::Record Record;
- DataFile::FragmentFooter FragmentFooter;
- };
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp b/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp
deleted file mode 100644
index 00a2a258085..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//****************************************************************************
-//
-// NAME
-// Backup - Database backup / restore
-//
-//===========================================================================
-#include "Backup.hpp"
-
-#include <Properties.hpp>
-#include <Configuration.hpp>
-
-//extern const unsigned Ndbcntr::g_sysTableCount;
-
-Backup::Backup(Block_context& ctx) :
- SimulatedBlock(BACKUP, ctx),
- c_nodes(c_nodePool),
- c_backups(c_backupPool)
-{
- BLOCK_CONSTRUCTOR(Backup);
-
- c_masterNodeId = getOwnNodeId();
-
- // Add received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &Backup::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &Backup::execSTTOR);
- addRecSignal(GSN_DUMP_STATE_ORD, &Backup::execDUMP_STATE_ORD);
- addRecSignal(GSN_READ_NODESCONF, &Backup::execREAD_NODESCONF);
- addRecSignal(GSN_NODE_FAILREP, &Backup::execNODE_FAILREP);
- addRecSignal(GSN_INCL_NODEREQ, &Backup::execINCL_NODEREQ);
- addRecSignal(GSN_CONTINUEB, &Backup::execCONTINUEB);
- addRecSignal(GSN_READ_CONFIG_REQ, &Backup::execREAD_CONFIG_REQ, true);
-
- addRecSignal(GSN_SCAN_HBREP, &Backup::execSCAN_HBREP);
- addRecSignal(GSN_TRANSID_AI, &Backup::execTRANSID_AI);
- addRecSignal(GSN_SCAN_FRAGREF, &Backup::execSCAN_FRAGREF);
- addRecSignal(GSN_SCAN_FRAGCONF, &Backup::execSCAN_FRAGCONF);
-
- addRecSignal(GSN_BACKUP_TRIG_REQ, &Backup::execBACKUP_TRIG_REQ);
- addRecSignal(GSN_TRIG_ATTRINFO, &Backup::execTRIG_ATTRINFO);
- addRecSignal(GSN_FIRE_TRIG_ORD, &Backup::execFIRE_TRIG_ORD);
-
- addRecSignal(GSN_LIST_TABLES_CONF, &Backup::execLIST_TABLES_CONF);
- addRecSignal(GSN_GET_TABINFOREF, &Backup::execGET_TABINFOREF);
- addRecSignal(GSN_GET_TABINFO_CONF, &Backup::execGET_TABINFO_CONF);
-
- addRecSignal(GSN_CREATE_TRIG_REF, &Backup::execCREATE_TRIG_REF);
- addRecSignal(GSN_CREATE_TRIG_CONF, &Backup::execCREATE_TRIG_CONF);
-
- addRecSignal(GSN_DROP_TRIG_REF, &Backup::execDROP_TRIG_REF);
- addRecSignal(GSN_DROP_TRIG_CONF, &Backup::execDROP_TRIG_CONF);
-
- addRecSignal(GSN_DI_FCOUNTCONF, &Backup::execDI_FCOUNTCONF);
- addRecSignal(GSN_DIGETPRIMCONF, &Backup::execDIGETPRIMCONF);
-
- addRecSignal(GSN_FSOPENREF, &Backup::execFSOPENREF, true);
- addRecSignal(GSN_FSOPENCONF, &Backup::execFSOPENCONF);
-
- addRecSignal(GSN_FSCLOSEREF, &Backup::execFSCLOSEREF, true);
- addRecSignal(GSN_FSCLOSECONF, &Backup::execFSCLOSECONF);
-
- addRecSignal(GSN_FSAPPENDREF, &Backup::execFSAPPENDREF, true);
- addRecSignal(GSN_FSAPPENDCONF, &Backup::execFSAPPENDCONF);
-
- addRecSignal(GSN_FSREMOVEREF, &Backup::execFSREMOVEREF, true);
- addRecSignal(GSN_FSREMOVECONF, &Backup::execFSREMOVECONF);
-
- /*****/
- addRecSignal(GSN_BACKUP_REQ, &Backup::execBACKUP_REQ);
- addRecSignal(GSN_ABORT_BACKUP_ORD, &Backup::execABORT_BACKUP_ORD);
-
- addRecSignal(GSN_DEFINE_BACKUP_REQ, &Backup::execDEFINE_BACKUP_REQ);
- addRecSignal(GSN_DEFINE_BACKUP_REF, &Backup::execDEFINE_BACKUP_REF);
- addRecSignal(GSN_DEFINE_BACKUP_CONF, &Backup::execDEFINE_BACKUP_CONF);
-
- addRecSignal(GSN_START_BACKUP_REQ, &Backup::execSTART_BACKUP_REQ);
- addRecSignal(GSN_START_BACKUP_REF, &Backup::execSTART_BACKUP_REF);
- addRecSignal(GSN_START_BACKUP_CONF, &Backup::execSTART_BACKUP_CONF);
-
- addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Backup::execBACKUP_FRAGMENT_REQ);
- addRecSignal(GSN_BACKUP_FRAGMENT_REF, &Backup::execBACKUP_FRAGMENT_REF);
- addRecSignal(GSN_BACKUP_FRAGMENT_CONF, &Backup::execBACKUP_FRAGMENT_CONF);
-
- addRecSignal(GSN_BACKUP_FRAGMENT_COMPLETE_REP,
- &Backup::execBACKUP_FRAGMENT_COMPLETE_REP);
-
- addRecSignal(GSN_STOP_BACKUP_REQ, &Backup::execSTOP_BACKUP_REQ);
- addRecSignal(GSN_STOP_BACKUP_REF, &Backup::execSTOP_BACKUP_REF);
- addRecSignal(GSN_STOP_BACKUP_CONF, &Backup::execSTOP_BACKUP_CONF);
-
- //addRecSignal(GSN_BACKUP_STATUS_REQ, &Backup::execBACKUP_STATUS_REQ);
- //addRecSignal(GSN_BACKUP_STATUS_CONF, &Backup::execBACKUP_STATUS_CONF);
-
- addRecSignal(GSN_UTIL_SEQUENCE_REF, &Backup::execUTIL_SEQUENCE_REF);
- addRecSignal(GSN_UTIL_SEQUENCE_CONF, &Backup::execUTIL_SEQUENCE_CONF);
-
- addRecSignal(GSN_WAIT_GCP_REF, &Backup::execWAIT_GCP_REF);
- addRecSignal(GSN_WAIT_GCP_CONF, &Backup::execWAIT_GCP_CONF);
-
- /**
- * Testing
- */
- addRecSignal(GSN_BACKUP_REF, &Backup::execBACKUP_REF);
- addRecSignal(GSN_BACKUP_CONF, &Backup::execBACKUP_CONF);
- addRecSignal(GSN_BACKUP_ABORT_REP, &Backup::execBACKUP_ABORT_REP);
- addRecSignal(GSN_BACKUP_COMPLETE_REP, &Backup::execBACKUP_COMPLETE_REP);
-
- addRecSignal(GSN_LCP_PREPARE_REQ, &Backup::execLCP_PREPARE_REQ);
- addRecSignal(GSN_END_LCPREQ, &Backup::execEND_LCPREQ);
-}
-
-Backup::~Backup()
-{
-}
-
-BLOCK_FUNCTIONS(Backup)
-
-template class ArrayPool<Backup::Page32>;
-template class ArrayPool<Backup::Attribute>;
-template class ArrayPool<Backup::Fragment>;
-
-void
-Backup::execREAD_CONFIG_REQ(Signal* signal)
-{
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
- ndbrequire(req->noOfParameters == 0);
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- c_defaults.m_disk_write_speed = 10 * (1024 * 1024);
- c_defaults.m_disk_write_speed_sr = 100 * (1024 * 1024);
- c_defaults.m_disk_synch_size = 4 * (1024 * 1024);
- c_defaults.m_o_direct = true;
-
- Uint32 noBackups = 0, noTables = 0, noAttribs = 0, noFrags = 0;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS,
- &c_defaults.m_diskless));
- ndb_mgm_get_int_parameter(p, CFG_DB_O_DIRECT,
- &c_defaults.m_o_direct);
- ndb_mgm_get_int_parameter(p, CFG_DB_CHECKPOINT_SPEED_SR,
- &c_defaults.m_disk_write_speed_sr);
- ndb_mgm_get_int_parameter(p, CFG_DB_CHECKPOINT_SPEED,
- &c_defaults.m_disk_write_speed);
- ndb_mgm_get_int_parameter(p, CFG_DB_DISK_SYNCH_SIZE,
- &c_defaults.m_disk_synch_size);
-
- /*
- We adjust the disk speed parameters from bytes per second to rather be
- words per 100 milliseconds. We convert disk synch size from bytes per
- second to words per second.
- */
- c_defaults.m_disk_write_speed /= (4 * 10);
- c_defaults.m_disk_write_speed_sr /= (4 * 10);
-
- 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_DICT_TABLE, &noTables));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, &noFrags));
-
- noAttribs++; //RT 527 bug fix
-
- c_nodePool.setSize(MAX_NDB_NODES);
- c_backupPool.setSize(noBackups + 1);
- c_backupFilePool.setSize(3 * noBackups + 1);
- c_tablePool.setSize(noBackups * noTables + 1);
- c_attributePool.setSize(noBackups * noAttribs + MAX_ATTRIBUTES_IN_TABLE);
- c_triggerPool.setSize(noBackups * 3 * noTables);
- c_fragmentPool.setSize(noBackups * noFrags + 1);
-
- Uint32 szDataBuf = (2 * 1024 * 1024);
- Uint32 szLogBuf = (2 * 1024 * 1024);
- Uint32 szWrite = 32768, maxWriteSize = (256 * 1024);
- 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);
- ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MAX_WRITE_SIZE, &maxWriteSize);
-
- c_defaults.m_logBufferSize = szLogBuf;
- c_defaults.m_dataBufferSize = szDataBuf;
- c_defaults.m_minWriteSize = szWrite;
- c_defaults.m_maxWriteSize = maxWriteSize;
- c_defaults.m_lcp_buffer_size = szDataBuf;
-
-
- Uint32 szMem = 0;
- ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MEM, &szMem);
- Uint32 noPages = (szMem + c_defaults.m_lcp_buffer_size + 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.
- c_pagePool.setSize(noPages + NO_OF_PAGES_META_FILE + 2, true);
-
- { // Init all tables
- SLList<Table> tables(c_tablePool);
- TablePtr ptr;
- while(tables.seize(ptr)){
- new (ptr.p) Table(c_attributePool, c_fragmentPool);
- }
- tables.release();
- }
-
- {
- SLList<BackupFile> ops(c_backupFilePool);
- BackupFilePtr ptr;
- while(ops.seize(ptr)){
- new (ptr.p) BackupFile(* this, c_pagePool);
- }
- ops.release();
- }
-
- {
- SLList<BackupRecord> recs(c_backupPool);
- BackupRecordPtr ptr;
- while(recs.seize(ptr)){
- new (ptr.p) BackupRecord(* this, c_tablePool,
- c_backupFilePool, c_triggerPool);
- }
- recs.release();
- }
-
- // Initialize BAT for interface to file system
- {
- Page32Ptr p;
- ndbrequire(c_pagePool.seizeId(p, 0));
- c_startOfPages = (Uint32 *)p.p;
- c_pagePool.release(p);
-
- NewVARIABLE* bat = allocateBat(1);
- bat[0].WA = c_startOfPages;
- bat[0].nrr = c_pagePool.getSize()*sizeof(Page32)/sizeof(Uint32);
- }
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
diff --git a/storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp b/storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp
deleted file mode 100644
index 1349ddf6282..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef FS_BUFFER_HPP
-#define FS_BUFFER_HPP
-
-#include <ndb_global.h>
-
-#define DEBUG(x)
-
-/**
- * A circular data buffer to be used together with the FS
- *
- * One writer - Typically your block
- * getWritePtr()
- * updateWritePtr()
- *
- * One reader - Typically "thread" in your block sending stuff to NDBFS
- * getReadPtr()
- * updateReadPtr()
- */
-class FsBuffer {
-public:
- /**
- * Default constructor
- */
- FsBuffer();
-
- /**
- * setup FsBuffer
- *
- * @param Buffer - Ptr to continuous memory
- * @param Size - Buffer size in 32-bit words
- * @param BlockSize - Size of block in 32-bit words
- * @param MinRead - Min read size in 32-bit words
- * Get rounded(down) to nearest multiple of block size.
- * @param MaxRead - Max read size in 32-bit words
- * Get rounded(down) to nearest multiple of block size.
- * @param MaxWrite - Maximum write (into buffer) in 32-bit words
- *
- * @return NULL if everything is OK
- * else A string describing problem
- */
- const char * setup(Uint32 * Buffer,
- Uint32 Size,
- Uint32 BlockSize = 128, // 512 bytes
- Uint32 MinRead = 1024, // 4k
- Uint32 MaxRead = 1024, // 4k
- Uint32 MaxWrite = 1024); // 4k
- /*
- * @return NULL if everything is OK
- * else A string describing problem
- */
- const char * valid() const;
-
- Uint32 getBufferSize() const;
- Uint32 getUsableSize() const;
- Uint32 * getStart() const;
-
- /**
- * getReadPtr - Get pointer and size of data to send to FS
- *
- * @param ptr - Where to fetch data
- * @param sz - How much data in 32-bit words
- * @param eof - Is this the last fetch (only if return false)
- *
- * @return true - If there is data of size >= minread
- * false - If there is can be data be if it is is < minread
- * - else eof = true
- */
- bool getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * eof);
-
- /**
- * @note: sz must be equal to sz returned by getReadPtr
- */
- void updateReadPtr(Uint32 sz);
-
- /**
- *
- * @note Must be followed by a updateWritePtr(no of words used)
- */
- bool getWritePtr(Uint32 ** ptr, Uint32 sz);
-
- void updateWritePtr(Uint32 sz);
-
- /**
- * There will be no more writing to this buffer
- */
- void eof();
-
- /**
- * Getters for varibles
- */
- Uint32 getMaxWrite() const { return m_maxWrite;}
- Uint32 getMinRead() const { return m_minRead;}
-
- Uint32 getFreeSize() const { return m_free; }
-
- /**
- * reset
- */
- void reset();
-
-private:
-
- Uint32 m_free;
- Uint32 m_readIndex;
- Uint32 m_writeIndex;
- Uint32 m_eof;
- Uint32 * m_start;
- Uint32 m_minRead;
- Uint32 m_maxRead;
- Uint32 m_maxWrite;
- Uint32 m_size;
-
- Uint32 * m_buffer;
- Uint32 m_bufSize;
- Uint32 m_blockSize;
-
- void clear();
-};
-
-inline
-FsBuffer::FsBuffer()
-{
- clear();
-}
-
-inline
-void
-FsBuffer::clear(){
- m_minRead = m_maxRead = m_maxWrite = m_size = m_bufSize = m_free = 0;
- m_buffer = m_start = 0;
-}
-
-static
-Uint32 *
-align(Uint32 * ptr, Uint32 alignment, bool downwards){
-
- const UintPtr a = (UintPtr)ptr;
- const UintPtr b = a % alignment;
-
- if(downwards){
- return (Uint32 *)(a - b);
- } else {
- return (Uint32 *)(a + (b == 0 ? 0 : (alignment - b)));
- }
-}
-
-inline
-const char *
-FsBuffer::setup(Uint32 * Buffer,
- Uint32 Size,
- Uint32 Block,
- Uint32 MinRead,
- Uint32 MaxRead,
- Uint32 MaxWrite)
-{
- clear();
- m_buffer = Buffer;
- m_bufSize = Size;
- m_blockSize = Block;
- if(Block == 0){
- return valid();
- }
-
- m_minRead = (MinRead / Block) * Block;
- m_maxRead = (MaxRead / Block) * Block;
- m_maxWrite = MaxWrite;
-
- m_start = align(Buffer, Block*4, false);
- Uint32 * stop = align(Buffer + Size - MaxWrite, Block*4, true);
- if(stop > m_start){
- m_size = stop - m_start;
- } else {
- m_size = 0;
- }
-
- if(m_minRead == 0)
- m_size = 0;
- else
- m_size = (m_size / m_minRead) * m_minRead;
-
-#if 0
- ndbout_c("Block = %d MinRead = %d -> %d", Block*4, MinRead*4, m_minRead*4);
- ndbout_c("Block = %d MaxRead = %d -> %d", Block*4, MaxRead*4, m_maxRead*4);
-
- ndbout_c("Buffer = %d -> %d", Buffer, m_start);
- ndbout_c("Buffer = %d Size = %d MaxWrite = %d -> %d",
- Buffer, Size*4, MaxWrite*4, m_size*4);
-#endif
-
- m_readIndex = m_writeIndex = m_eof = 0;
- m_free = m_size;
- return valid();
-}
-
-inline
-void
-FsBuffer::reset()
-{
- m_readIndex = m_writeIndex = 0;
- m_free = m_size;
- m_eof = 0;
-}
-
-inline
-const char *
-FsBuffer::valid() const {
- if(m_buffer == 0) return "Null pointer buffer";
- if(m_bufSize == 0) return "Zero size buffer";
- if(m_blockSize == 0) return "Zero block size";
- if(m_minRead < m_blockSize) return "Min read less than block size";
- if(m_maxRead < m_blockSize) return "Max read less than block size";
- if(m_maxRead < m_minRead) return "Max read less than min read";
- if(m_size == 0) return "Zero usable space";
- return 0;
-}
-
-inline
-Uint32
-FsBuffer::getBufferSize() const {
- return m_bufSize;
-}
-
-inline
-Uint32
-FsBuffer::getUsableSize() const {
- return m_size;
-}
-
-inline
-Uint32 *
-FsBuffer::getStart() const {
- return m_start;
-}
-
-inline
-bool
-FsBuffer::getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * _eof){
-
- Uint32 * Tp = m_start;
- const Uint32 Tr = m_readIndex;
- const Uint32 Tm = m_minRead;
- const Uint32 Ts = m_size;
- const Uint32 Tmw = m_maxRead;
-
- Uint32 sz1 = m_size - m_free; // Used
-
- if(sz1 >= Tm){
- if(Tr + sz1 > Ts)
- sz1 = (Ts - Tr);
-
- if(sz1 > Tmw)
- * sz = Tmw;
- else
- * sz = sz1 - (sz1 % Tm);
-
- * ptr = &Tp[Tr];
-
- DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d",
- Tr, Tmw, Ts, Tm, sz1, * sz));
-
- return true;
- }
-
- if(!m_eof){
- * _eof = false;
-
- DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> false",
- Tr, Tmw, Ts, Tm, sz1));
-
- return false;
- }
-
- * sz = sz1;
- * _eof = true;
- * ptr = &Tp[Tr];
-
- DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d eof",
- Tr, Tmw, Ts, Tm, sz1, * sz));
-
- return false;
-}
-
-inline
-void
-FsBuffer::updateReadPtr(Uint32 sz){
- const Uint32 Tr = m_readIndex;
- const Uint32 Ts = m_size;
-
- m_free += sz;
- m_readIndex = (Tr + sz) % Ts;
-}
-
-inline
-bool
-FsBuffer::getWritePtr(Uint32 ** ptr, Uint32 sz){
- assert(sz <= m_maxWrite);
- Uint32 * Tp = m_start;
- const Uint32 Tw = m_writeIndex;
- const Uint32 sz1 = m_free;
-
- if(sz1 > sz){ // Note at least 1 word of slack
- * ptr = &Tp[Tw];
-
- DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> true",
- sz, Tw, sz1));
- return true;
- }
-
- DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> false",
- sz, Tw, sz1));
-
- return false;
-}
-
-inline
-void
-FsBuffer::updateWritePtr(Uint32 sz){
- assert(sz <= m_maxWrite);
- Uint32 * Tp = m_start;
- const Uint32 Tw = m_writeIndex;
- const Uint32 Ts = m_size;
-
- const Uint32 Tnew = (Tw + sz);
- m_free -= sz;
- if(Tnew < Ts){
- m_writeIndex = Tnew;
- DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",
- sz, m_writeIndex));
- return;
- }
-
- memcpy(Tp, &Tp[Ts], (Tnew - Ts) << 2);
- m_writeIndex = Tnew - Ts;
- DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",
- sz, m_writeIndex));
-}
-
-inline
-void
-FsBuffer::eof(){
- m_eof = 1;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/backup/Makefile.am b/storage/ndb/src/kernel/blocks/backup/Makefile.am
deleted file mode 100644
index d8a82014445..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-ndbtools_PROGRAMS = ndb_print_backup_file
-ndb_print_backup_file_SOURCES = read.cpp
-ndb_print_backup_file_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/strings/libmystrings.a
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
diff --git a/storage/ndb/src/kernel/blocks/backup/read.cpp b/storage/ndb/src/kernel/blocks/backup/read.cpp
deleted file mode 100644
index 3d4780f5eb4..00000000000
--- a/storage/ndb/src/kernel/blocks/backup/read.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbTCP.h>
-#include <NdbOut.hpp>
-#include "BackupFormat.hpp"
-#include <AttributeHeader.hpp>
-#include <SimpleProperties.hpp>
-#include <ndb_version.h>
-
-bool readHeader(FILE*, BackupFormat::FileHeader *);
-bool readFragHeader(FILE*, BackupFormat::DataFile::FragmentHeader *);
-bool readFragFooter(FILE*, BackupFormat::DataFile::FragmentFooter *);
-Int32 readRecord(FILE*, Uint32 **);
-
-NdbOut & operator<<(NdbOut&, const BackupFormat::FileHeader &);
-NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentHeader &);
-NdbOut & operator<<(NdbOut&, const BackupFormat::DataFile::FragmentFooter &);
-
-bool readTableList(FILE*, BackupFormat::CtlFile::TableList **);
-bool readTableDesc(FILE*, BackupFormat::CtlFile::TableDescription **);
-bool readGCPEntry(FILE*, BackupFormat::CtlFile::GCPEntry **);
-
-NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableList &);
-NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::TableDescription &);
-NdbOut & operator<<(NdbOut&, const BackupFormat::CtlFile::GCPEntry &);
-
-Int32 readLogEntry(FILE*, Uint32**);
-
-static Uint32 recNo;
-static Uint32 logEntryNo;
-
-int
-main(int argc, const char * argv[]){
-
- ndb_init();
- if(argc <= 1){
- printf("Usage: %s <filename>\n", argv[0]);
- exit(1);
- }
- FILE * f = fopen(argv[1], "rb");
- if(!f){
- ndbout << "No such file!" << endl;
- exit(1);
- }
-
- BackupFormat::FileHeader fileHeader;
- if(!readHeader(f, &fileHeader)){
- ndbout << "Invalid file!" << endl;
- exit(1);
- }
- ndbout << fileHeader << endl;
-
- switch(fileHeader.FileType){
- case BackupFormat::DATA_FILE:
- while(!feof(f)){
- BackupFormat::DataFile::FragmentHeader fragHeader;
- if(!readFragHeader(f, &fragHeader))
- break;
- ndbout << fragHeader << endl;
-
- Uint32 len, * data;
- while((len = readRecord(f, &data)) > 0){
-#if 0
- ndbout << "-> " << hex;
- for(Uint32 i = 0; i<len; i++){
- ndbout << data[i] << " ";
- }
- ndbout << endl;
-#endif
- }
-
- BackupFormat::DataFile::FragmentFooter fragFooter;
- if(!readFragFooter(f, &fragFooter))
- break;
- ndbout << fragFooter << endl;
- }
- break;
- case BackupFormat::CTL_FILE:{
- BackupFormat::CtlFile::TableList * tabList;
- if(!readTableList(f, &tabList)){
- ndbout << "Invalid file! No table list" << endl;
- break;
- }
- ndbout << (* tabList) << endl;
-
- const Uint32 noOfTables = tabList->SectionLength - 2;
- for(Uint32 i = 0; i<noOfTables; i++){
- BackupFormat::CtlFile::TableDescription * tabDesc;
- if(!readTableDesc(f, &tabDesc)){
- ndbout << "Invalid file missing table description" << endl;
- break;
- }
- ndbout << (* tabDesc) << endl;
- }
-
- BackupFormat::CtlFile::GCPEntry * gcpE;
- if(!readGCPEntry(f, &gcpE)){
- ndbout << "Invalid file! GCP ENtry" << endl;
- break;
- }
- ndbout << (* gcpE) << endl;
-
- break;
- }
- case BackupFormat::LOG_FILE:{
- logEntryNo = 0;
-
- typedef BackupFormat::LogFile::LogEntry LogEntry;
-
- Uint32 len, * data;
- while((len = readLogEntry(f, &data)) > 0){
- LogEntry * logEntry = (LogEntry *) data;
- /**
- * Log Entry
- */
- Uint32 event = ntohl(logEntry->TriggerEvent);
- bool gcp = (event & 0x10000) != 0;
- event &= 0xFFFF;
- if(gcp)
- len --;
-
- ndbout << "LogEntry Table: " << (Uint32)ntohl(logEntry->TableId)
- << " Event: " << event
- << " Length: " << (len - 2);
-
- const Uint32 dataLen = len - 2;
-#if 0
- Uint32 pos = 0;
- while(pos < dataLen){
- AttributeHeader * ah = (AttributeHeader*)&logEntry->Data[pos];
- ndbout_c(" Attribut: %d Size: %d",
- ah->getAttributeId(),
- ah->getDataSize());
- pos += ah->getDataSize() + 1;
- }
-#endif
- if(gcp)
- ndbout << " GCP: " << (Uint32)ntohl(logEntry->Data[dataLen]);
- ndbout << endl;
- }
- break;
- }
- case BackupFormat::LCP_FILE:
- {
- BackupFormat::CtlFile::TableList * tabList;
- if(!readTableList(f, &tabList)){
- ndbout << "Invalid file! No table list" << endl;
- break;
- }
- ndbout << (* tabList) << endl;
-
- const Uint32 noOfTables = tabList->SectionLength - 2;
- for(Uint32 i = 0; i<noOfTables; i++){
- BackupFormat::CtlFile::TableDescription * tabDesc;
- if(!readTableDesc(f, &tabDesc)){
- ndbout << "Invalid file missing table description" << endl;
- break;
- }
- ndbout << (* tabDesc) << endl;
- }
-
- while(!feof(f)){
- BackupFormat::DataFile::FragmentHeader fragHeader;
- if(!readFragHeader(f, &fragHeader))
- break;
- ndbout << fragHeader << endl;
-
- Uint32 len, * data;
- while((len = readRecord(f, &data)) > 0){
-#if 0
- ndbout << "-> " << hex;
- for(Uint32 i = 0; i<len; i++){
- ndbout << data[i] << " ";
- }
- ndbout << endl;
-#endif
- }
-
- BackupFormat::DataFile::FragmentFooter fragFooter;
- if(!readFragFooter(f, &fragFooter))
- break;
- ndbout << fragFooter << endl;
- }
- break;
- }
- default:
- ndbout << "Unsupported file type for printer: "
- << fileHeader.FileType << endl;
- break;
- }
- fclose(f);
- return 0;
-}
-
-#define RETURN_FALSE() { ndbout_c("false: %d", __LINE__); abort(); return false; }
-
-static bool endian = false;
-
-bool
-readHeader(FILE* f, BackupFormat::FileHeader * dst){
- if(fread(dst, 4, 3, f) != 3)
- RETURN_FALSE();
-
- if(memcmp(dst->Magic, BACKUP_MAGIC, sizeof(BACKUP_MAGIC)) != 0)
- RETURN_FALSE();
-
- dst->NdbVersion = ntohl(dst->NdbVersion);
- if(dst->NdbVersion != NDB_VERSION)
- RETURN_FALSE();
-
- if(fread(&dst->SectionType, 4, 2, f) != 2)
- RETURN_FALSE();
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
-
- if(dst->SectionType != BackupFormat::FILE_HEADER)
- RETURN_FALSE();
-
- if(dst->SectionLength != ((sizeof(BackupFormat::FileHeader) - 12) >> 2))
- RETURN_FALSE();
-
- if(fread(&dst->FileType, 4, dst->SectionLength - 2, f) !=
- (dst->SectionLength - 2))
- RETURN_FALSE();
-
- dst->FileType = ntohl(dst->FileType);
- dst->BackupId = ntohl(dst->BackupId);
- dst->BackupKey_0 = ntohl(dst->BackupKey_0);
- dst->BackupKey_1 = ntohl(dst->BackupKey_1);
-
- if(dst->ByteOrder != 0x12345678)
- endian = true;
-
- return true;
-}
-
-bool
-readFragHeader(FILE* f, BackupFormat::DataFile::FragmentHeader * dst){
- if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
- return false;
-
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
- dst->TableId = ntohl(dst->TableId);
- dst->FragmentNo = ntohl(dst->FragmentNo);
- dst->ChecksumType = ntohl(dst->ChecksumType);
-
- if(dst->SectionLength != (sizeof(* dst) >> 2))
- RETURN_FALSE();
-
- if(dst->SectionType != BackupFormat::FRAGMENT_HEADER)
- RETURN_FALSE();
-
- recNo = 0;
-
- return true;
-}
-
-bool
-readFragFooter(FILE* f, BackupFormat::DataFile::FragmentFooter * dst){
- if(fread(dst, 1, sizeof(* dst), f) != sizeof(* dst))
- RETURN_FALSE();
-
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
- dst->TableId = ntohl(dst->TableId);
- dst->FragmentNo = ntohl(dst->FragmentNo);
- dst->NoOfRecords = ntohl(dst->NoOfRecords);
- dst->Checksum = ntohl(dst->Checksum);
-
- if(dst->SectionLength != (sizeof(* dst) >> 2))
- RETURN_FALSE();
-
- if(dst->SectionType != BackupFormat::FRAGMENT_FOOTER)
- RETURN_FALSE();
- return true;
-}
-
-static Uint32 buf[8192];
-
-Int32
-readRecord(FILE* f, Uint32 **dst){
- Uint32 len;
- if(fread(&len, 1, 4, f) != 4)
- RETURN_FALSE();
-
- len = ntohl(len);
-
- if(fread(buf, 4, len, f) != len)
- {
- return -1;
- }
-
- if(len > 0)
- recNo++;
- else
- ndbout_c("Found %d records", recNo);
-
- * dst = &buf[0];
-
-
- return len;
-}
-
-Int32
-readLogEntry(FILE* f, Uint32 **dst){
- Uint32 len;
- if(fread(&len, 1, 4, f) != 4)
- RETURN_FALSE();
-
- len = ntohl(len);
-
- if(fread(&buf[1], 4, len, f) != len)
- return -1;
-
- buf[0] = len;
-
- if(len > 0)
- logEntryNo++;
-
- * dst = &buf[0];
-
- return len;
-}
-
-
-NdbOut &
-operator<<(NdbOut& ndbout, const BackupFormat::FileHeader & hf){
-
- char buf[9];
- memcpy(buf, hf.Magic, sizeof(hf.Magic));
- buf[8] = 0;
-
- ndbout << "-- FileHeader:" << endl;
- ndbout << "Magic: " << buf << endl;
- ndbout << "NdbVersion: " << hf.NdbVersion << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
- ndbout << "FileType: " << hf.FileType << endl;
- ndbout << "BackupId: " << hf.BackupId << endl;
- ndbout << "BackupKey: [ " << hex << hf.BackupKey_0
- << " "<< hf.BackupKey_1 << " ]" << endl;
- ndbout << "ByteOrder: " << hex << hf.ByteOrder << endl;
- return ndbout;
-}
-
-NdbOut & operator<<(NdbOut& ndbout,
- const BackupFormat::DataFile::FragmentHeader & hf){
-
- ndbout << "-- Fragment header:" << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
- ndbout << "TableId: " << hf.TableId << endl;
- ndbout << "FragmentNo: " << hf.FragmentNo << endl;
- ndbout << "ChecksumType: " << hf.ChecksumType << endl;
-
- return ndbout;
-}
-NdbOut & operator<<(NdbOut& ndbout,
- const BackupFormat::DataFile::FragmentFooter & hf){
-
- ndbout << "-- Fragment footer:" << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
- ndbout << "TableId: " << hf.TableId << endl;
- ndbout << "FragmentNo: " << hf.FragmentNo << endl;
- ndbout << "NoOfRecords: " << hf.NoOfRecords << endl;
- ndbout << "Checksum: " << hf.Checksum << endl;
-
- return ndbout;
-}
-
-bool
-readTableList(FILE* f, BackupFormat::CtlFile::TableList **ret){
- BackupFormat::CtlFile::TableList * dst =
- (BackupFormat::CtlFile::TableList *)&buf[0];
-
- if(fread(dst, 4, 2, f) != 2)
- RETURN_FALSE();
-
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
-
- if(dst->SectionType != BackupFormat::TABLE_LIST)
- RETURN_FALSE();
-
- const Uint32 len = dst->SectionLength - 2;
- if(fread(&dst->TableIds[0], 4, len, f) != len)
- RETURN_FALSE();
-
- for(Uint32 i = 0; i<len; i++){
- dst->TableIds[i] = ntohl(dst->TableIds[i]);
- }
-
- * ret = dst;
-
- return true;
-}
-
-bool
-readTableDesc(FILE* f, BackupFormat::CtlFile::TableDescription **ret){
- BackupFormat::CtlFile::TableDescription * dst =
- (BackupFormat::CtlFile::TableDescription *)&buf[0];
-
- if(fread(dst, 4, 2, f) != 2)
- RETURN_FALSE();
-
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
-
- if(dst->SectionType != BackupFormat::TABLE_DESCRIPTION)
- RETURN_FALSE();
-
- const Uint32 len = dst->SectionLength - 2;
- if(fread(&dst->DictTabInfo[0], 4, len, f) != len)
- RETURN_FALSE();
-
- * ret = dst;
-
- return true;
-}
-
-bool
-readGCPEntry(FILE* f, BackupFormat::CtlFile::GCPEntry **ret){
- BackupFormat::CtlFile::GCPEntry * dst =
- (BackupFormat::CtlFile::GCPEntry *)&buf[0];
-
- if(fread(dst, 4, 4, f) != 4)
- RETURN_FALSE();
-
- dst->SectionType = ntohl(dst->SectionType);
- dst->SectionLength = ntohl(dst->SectionLength);
-
- if(dst->SectionType != BackupFormat::GCP_ENTRY)
- RETURN_FALSE();
-
- dst->StartGCP = ntohl(dst->StartGCP);
- dst->StopGCP = ntohl(dst->StopGCP);
-
- * ret = dst;
-
- return true;
-}
-
-
-NdbOut &
-operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableList & hf) {
- ndbout << "-- Table List:" << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
- for(Uint32 i = 0; i < hf.SectionLength - 2; i++){
- ndbout << hf.TableIds[i] << " ";
- if((i + 1) % 16 == 0)
- ndbout << endl;
- }
- return ndbout;
-}
-
-NdbOut &
-operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::TableDescription & hf){
- ndbout << "-- Table Description:" << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
-
- SimplePropertiesLinearReader it(&hf.DictTabInfo[0], hf.SectionLength - 2);
- char buf[1024];
- for(it.first(); it.valid(); it.next()){
- switch(it.getValueType()){
- case SimpleProperties::Uint32Value:
- ndbout << "Key: " << it.getKey()
- << " value(" << it.getValueLen() << ") : "
- << it.getUint32() << endl;
- break;
- case SimpleProperties::StringValue:
- if(it.getValueLen() < sizeof(buf)){
- it.getString(buf);
- ndbout << "Key: " << it.getKey()
- << " value(" << it.getValueLen() << ") : "
- << "\"" << buf << "\"" << endl;
- } else {
- ndbout << "Key: " << it.getKey()
- << " value(" << it.getValueLen() << ") : "
- << "\"" << "<TOO LONG>" << "\"" << endl;
-
- }
- break;
- default:
- ndbout << "Unknown type for key: " << it.getKey()
- << " type: " << it.getValueType() << endl;
- }
- }
-
- return ndbout;
-}
-
-NdbOut &
-operator<<(NdbOut& ndbout, const BackupFormat::CtlFile::GCPEntry & hf) {
- ndbout << "-- GCP Entry:" << endl;
- ndbout << "SectionType: " << hf.SectionType << endl;
- ndbout << "SectionLength: " << hf.SectionLength << endl;
- ndbout << "Start GCP: " << hf.StartGCP << endl;
- ndbout << "Stop GCP: " << hf.StopGCP << endl;
-
- return ndbout;
-}
-
diff --git a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
deleted file mode 100644
index a99ae597f00..00000000000
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
+++ /dev/null
@@ -1,1453 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Cmvmi.hpp"
-
-#include <Configuration.hpp>
-#include <kernel_types.h>
-#include <TransporterRegistry.hpp>
-#include <NdbOut.hpp>
-#include <NdbMem.h>
-
-#include <SignalLoggerManager.hpp>
-#include <FastScheduler.hpp>
-
-#define DEBUG(x) { ndbout << "CMVMI::" << x << endl; }
-
-#include <signaldata/TestOrd.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/TamperOrd.hpp>
-#include <signaldata/StartOrd.hpp>
-#include <signaldata/CloseComReqConf.hpp>
-#include <signaldata/SetLogLevelOrd.hpp>
-#include <signaldata/EventSubscribeReq.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/DisconnectRep.hpp>
-
-#include <EventLogger.hpp>
-#include <TimeQueue.hpp>
-
-#include <NdbSleep.h>
-#include <SafeCounter.hpp>
-
-// Used here only to print event reports on stdout/console.
-EventLogger g_eventLogger;
-extern int simulate_error_during_shutdown;
-
-Cmvmi::Cmvmi(Block_context& ctx) :
- SimulatedBlock(CMVMI, ctx)
- ,subscribers(subscriberPool)
-{
- BLOCK_CONSTRUCTOR(Cmvmi);
-
- Uint32 long_sig_buffer_size;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- ndb_mgm_get_int_parameter(p, CFG_DB_LONG_SIGNAL_BUFFER,
- &long_sig_buffer_size);
-
- long_sig_buffer_size= long_sig_buffer_size / 256;
- g_sectionSegmentPool.setSize(long_sig_buffer_size,
- false,true,true,CFG_DB_LONG_SIGNAL_BUFFER);
-
- // Add received signals
- addRecSignal(GSN_CONNECT_REP, &Cmvmi::execCONNECT_REP);
- addRecSignal(GSN_DISCONNECT_REP, &Cmvmi::execDISCONNECT_REP);
-
- 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);
- addRecSignal(GSN_READ_CONFIG_REQ, &Cmvmi::execREAD_CONFIG_REQ);
- addRecSignal(GSN_CLOSE_COMREQ, &Cmvmi::execCLOSE_COMREQ);
- addRecSignal(GSN_ENABLE_COMORD, &Cmvmi::execENABLE_COMORD);
- addRecSignal(GSN_OPEN_COMREQ, &Cmvmi::execOPEN_COMREQ);
- addRecSignal(GSN_TEST_ORD, &Cmvmi::execTEST_ORD);
-
- addRecSignal(GSN_TAMPER_ORD, &Cmvmi::execTAMPER_ORD);
- addRecSignal(GSN_STOP_ORD, &Cmvmi::execSTOP_ORD);
- addRecSignal(GSN_START_ORD, &Cmvmi::execSTART_ORD);
- addRecSignal(GSN_EVENT_SUBSCRIBE_REQ,
- &Cmvmi::execEVENT_SUBSCRIBE_REQ);
-
- addRecSignal(GSN_DUMP_STATE_ORD, &Cmvmi::execDUMP_STATE_ORD);
-
- addRecSignal(GSN_TESTSIG, &Cmvmi::execTESTSIG);
- addRecSignal(GSN_NODE_START_REP, &Cmvmi::execNODE_START_REP, true);
-
- subscriberPool.setSize(5);
-
- const ndb_mgm_configuration_iterator * db = m_ctx.m_config.getOwnConfigIterator();
- for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
- Uint32 logLevel;
- if(!ndb_mgm_get_int_parameter(db, CFG_MIN_LOGLEVEL+j, &logLevel)){
- clogLevel.setLogLevel((LogLevel::EventCategory)j,
- logLevel);
- }
- }
-
- ndb_mgm_configuration_iterator * iter = m_ctx.m_config.getClusterConfigIterator();
- for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){
- jam();
- 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:
- break;
- default:
- ndbrequire(false);
- }
- setNodeInfo(nodeId).m_type = nodeType;
- }
-
- setNodeInfo(getOwnNodeId()).m_connected = true;
- setNodeInfo(getOwnNodeId()).m_version = ndbGetOwnVersion();
-}
-
-Cmvmi::~Cmvmi()
-{
- m_shared_page_pool.clear();
-}
-
-#ifdef ERROR_INSERT
-NodeBitmask c_error_9000_nodes_mask;
-extern Uint32 MAX_RECEIVED_SIGNALS;
-#endif
-
-void Cmvmi::execNDB_TAMPER(Signal* signal)
-{
- jamEntry();
- SET_ERROR_INSERT_VALUE(signal->theData[0]);
- if(ERROR_INSERTED(9999)){
- CRASH_INSERTION(9999);
- }
-
- if(ERROR_INSERTED(9998)){
- while(true) NdbSleep_SecSleep(1);
- }
-
- if(ERROR_INSERTED(9997)){
- ndbrequire(false);
- }
-
-#ifndef NDB_WIN32
- if(ERROR_INSERTED(9996)){
- simulate_error_during_shutdown= SIGSEGV;
- ndbrequire(false);
- }
-
- if(ERROR_INSERTED(9995)){
- simulate_error_during_shutdown= SIGSEGV;
- kill(getpid(), SIGABRT);
- }
-#endif
-
-#ifdef ERROR_INSERT
- if (signal->theData[0] == 9003)
- {
- if (MAX_RECEIVED_SIGNALS < 1024)
- {
- MAX_RECEIVED_SIGNALS = 1024;
- }
- else
- {
- MAX_RECEIVED_SIGNALS = 1 + (rand() % 128);
- }
- ndbout_c("MAX_RECEIVED_SIGNALS: %d", MAX_RECEIVED_SIGNALS);
- CLEAR_ERROR_INSERT_VALUE;
- }
-#endif
-}//execNDB_TAMPER()
-
-void Cmvmi::execSET_LOGLEVELORD(Signal* signal)
-{
- SetLogLevelOrd * const llOrd = (SetLogLevelOrd *)&signal->theData[0];
- LogLevel::EventCategory category;
- Uint32 level;
- jamEntry();
-
- for(unsigned int i = 0; i<llOrd->noOfEntries; i++){
- category = (LogLevel::EventCategory)(llOrd->theData[i] >> 16);
- level = llOrd->theData[i] & 0xFFFF;
-
- clogLevel.setLogLevel(category, level);
- }
-}//execSET_LOGLEVELORD()
-
-void Cmvmi::execEVENT_REP(Signal* signal)
-{
- //-----------------------------------------------------------------------
- // This message is sent to report any types of events in NDB.
- // Based on the log level they will be either ignored or
- // reported. Currently they are printed, but they will be
- // transferred to the management server for further distribution
- // to the graphical management interface.
- //-----------------------------------------------------------------------
- EventReport * const eventReport = (EventReport *)&signal->theData[0];
- Ndb_logevent_type eventType = eventReport->getEventType();
- Uint32 nodeId= eventReport->getNodeId();
- if (nodeId == 0)
- {
- nodeId= refToNode(signal->getSendersBlockRef());
- eventReport->setNodeId(nodeId);
- }
-
- jamEntry();
-
- /**
- * If entry is not found
- */
- Uint32 threshold;
- LogLevel::EventCategory eventCategory;
- Logger::LoggerLevel severity;
- EventLoggerBase::EventTextFunction textF;
- if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF))
- return;
-
- SubscriberPtr ptr;
- for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){
- if(ptr.p->logLevel.getLogLevel(eventCategory) < threshold){
- continue;
- }
-
- sendSignal(ptr.p->blockRef, GSN_EVENT_REP, signal, signal->length(), JBB);
- }
-
- if(clogLevel.getLogLevel(eventCategory) < threshold){
- return;
- }
-
- // Print the event info
- g_eventLogger.log(eventReport->getEventType(), signal->theData);
-
- return;
-}//execEVENT_REP()
-
-void
-Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
- EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0];
- Uint32 senderRef = signal->getSendersBlockRef();
- SubscriberPtr ptr;
- jamEntry();
- DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ");
-
- /**
- * Search for subcription
- */
- for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){
- if(ptr.p->blockRef == subReq->blockRef)
- break;
- }
-
- if(ptr.i == RNIL){
- /**
- * Create a new one
- */
- if(subscribers.seize(ptr) == false){
- sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB);
- return;
- }
- ptr.p->logLevel.clear();
- ptr.p->blockRef = subReq->blockRef;
- }
-
- if(subReq->noOfEntries == 0){
- /**
- * Cancel subscription
- */
- subscribers.release(ptr.i);
- } else {
- /**
- * Update subscription
- */
- LogLevel::EventCategory category;
- Uint32 level = 0;
- for(Uint32 i = 0; i<subReq->noOfEntries; i++){
- category = (LogLevel::EventCategory)(subReq->theData[i] >> 16);
- level = subReq->theData[i] & 0xFFFF;
- ptr.p->logLevel.setLogLevel(category, level);
- DBUG_PRINT("info",("entry %d: level=%d, category= %d", i, level, category));
- }
- }
-
- signal->theData[0] = ptr.i;
- sendSignal(senderRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB);
- DBUG_VOID_RETURN;
-}
-
-void
-Cmvmi::cancelSubscription(NodeId nodeId){
-
- SubscriberPtr ptr;
- subscribers.first(ptr);
-
- while(ptr.i != RNIL){
- Uint32 i = ptr.i;
- BlockReference blockRef = ptr.p->blockRef;
-
- subscribers.next(ptr);
-
- if(refToNode(blockRef) == nodeId){
- subscribers.release(i);
- }
- }
-}
-
-void Cmvmi::sendSTTORRY(Signal* signal)
-{
- 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
-
-
-void
-Cmvmi::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint64 page_buffer = 64*1024*1024;
- ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
-
- Uint32 pages = 0;
- pages += page_buffer / GLOBAL_PAGE_SIZE; // in pages
- pages += LCP_RESTORE_BUFFER;
- m_global_page_pool.setSize(pages + 64, true);
-
- Uint64 shared_mem = 8*1024*1024;
- ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
- shared_mem /= GLOBAL_PAGE_SIZE;
- if (shared_mem)
- {
- Resource_limit rl;
- rl.m_min = 0;
- rl.m_max = shared_mem;
- rl.m_resource_id = 0;
- m_ctx.m_mm.set_resource_limit(rl);
- }
-
- ndbrequire(m_ctx.m_mm.init());
- {
- void* ptr = m_ctx.m_mm.get_memroot();
- m_shared_page_pool.set((GlobalPage*)ptr, ~0);
- }
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void Cmvmi::execSTTOR(Signal* signal)
-{
- Uint32 theStartPhase = signal->theData[1];
-
- jamEntry();
- if (theStartPhase == 1){
- jam();
-
- if(m_ctx.m_config.lockPagesInMainMemory() == 1)
- {
- int res = NdbMem_MemLockAll(0);
- if(res != 0){
- g_eventLogger.warning("Failed to memlock pages");
- warningEvent("Failed to memlock pages");
- }
- }
-
- sendSTTORRY(signal);
- return;
- } else if (theStartPhase == 3) {
- jam();
- globalData.activateSendPacked = 1;
- sendSTTORRY(signal);
- } 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);
- globalData.theStartLevel = NodeState::SL_STARTED;
- sendSTTORRY(signal);
- }
-}
-
-void Cmvmi::execCLOSE_COMREQ(Signal* signal)
-{
- // Close communication with the node and halt input/output from
- // other blocks than QMGR
-
- CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
-
- const BlockReference userRef = closeCom->xxxBlockRef;
- Uint32 failNo = closeCom->failNo;
-// Uint32 noOfNodes = closeCom->noOfNodes;
-
- jamEntry();
- for (unsigned i = 0; i < MAX_NODES; i++)
- {
- if(NodeBitmask::get(closeCom->theNodes, i))
- {
- jam();
-
- //-----------------------------------------------------
- // Report that the connection to the node is closed
- //-----------------------------------------------------
- signal->theData[0] = NDB_LE_CommunicationClosed;
- signal->theData[1] = i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- globalTransporterRegistry.setIOState(i, HaltIO);
- globalTransporterRegistry.do_disconnect(i);
- }
- }
-
- if (failNo != 0)
- {
- jam();
- signal->theData[0] = userRef;
- signal->theData[1] = failNo;
- sendSignal(QMGR_REF, GSN_CLOSE_COMCONF, signal, 19, JBA);
- }
-}
-
-void Cmvmi::execOPEN_COMREQ(Signal* signal)
-{
- // Connect to the specifed NDB node, only QMGR allowed communication
- // so far with the node
-
- 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)
- {
-#ifdef ERROR_INSERT
- if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
- && c_error_9000_nodes_mask.get(tStartingNode)))
-#endif
- {
- if (globalData.theStartLevel != NodeState::SL_STARTED &&
- (getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
- getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
- {
- jam();
- goto done;
- }
-
- globalTransporterRegistry.do_connect(tStartingNode);
- globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
-
- //-----------------------------------------------------
- // Report that the connection to the node is opened
- //-----------------------------------------------------
- signal->theData[0] = NDB_LE_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();
-
-#ifdef ERROR_INSERT
- if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
- && c_error_9000_nodes_mask.get(i))
- continue;
-#endif
-
- globalTransporterRegistry.do_connect(i);
- globalTransporterRegistry.setIOState(i, HaltIO);
-
- signal->theData[0] = NDB_LE_CommunicationOpened;
- signal->theData[1] = i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- }
- }
- }
-
-done:
- if (userRef != 0) {
- jam();
- signal->theData[0] = tStartingNode;
- signal->theData[1] = tData2;
- sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA);
- }
-}
-
-void Cmvmi::execENABLE_COMORD(Signal* signal)
-{
- // Enable communication with all our NDB blocks to this node
-
- Uint32 tStartingNode = signal->theData[0];
- globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
- setNodeInfo(tStartingNode).m_connected = true;
- //-----------------------------------------------------
- // Report that the version of the node
- //-----------------------------------------------------
- signal->theData[0] = NDB_LE_ConnectedApiVersion;
- signal->theData[1] = tStartingNode;
- signal->theData[2] = getNodeInfo(tStartingNode).m_version;
-
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- //-----------------------------------------------------
-
- jamEntry();
-}
-
-void Cmvmi::execDISCONNECT_REP(Signal *signal)
-{
- const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
- const Uint32 hostId = rep->nodeId;
- const Uint32 errNo = rep->err;
-
- jamEntry();
-
- setNodeInfo(hostId).m_connected = false;
- setNodeInfo(hostId).m_connectCount++;
- const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
- ndbrequire(type != NodeInfo::INVALID);
-
- sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
- DisconnectRep::SignalLength, JBA);
-
- cancelSubscription(hostId);
-
- signal->theData[0] = NDB_LE_Disconnected;
- signal->theData[1] = hostId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-}
-
-void Cmvmi::execCONNECT_REP(Signal *signal){
- const Uint32 hostId = signal->theData[0];
- jamEntry();
-
- const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
- ndbrequire(type != NodeInfo::INVALID);
- globalData.m_nodeInfo[hostId].m_version = 0;
- globalData.m_nodeInfo[hostId].m_signalVersion = 0;
-
- if(type == NodeInfo::DB || globalData.theStartLevel >= NodeState::SL_STARTED){
- jam();
-
- /**
- * Inform QMGR that client has connected
- */
-
- signal->theData[0] = hostId;
- sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
- } else if(globalData.theStartLevel == NodeState::SL_CMVMI ||
- globalData.theStartLevel == NodeState::SL_STARTING) {
- jam();
- /**
- * Someone connected before start was finished
- */
- if(type == NodeInfo::MGM){
- jam();
- signal->theData[0] = hostId;
- sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
- } else {
- /**
- * Dont allow api nodes to connect
- */
- ndbout_c("%d %d %d", hostId, type, globalData.theStartLevel);
- abort();
- globalTransporterRegistry.do_disconnect(hostId);
- }
- }
-
- /* Automatically subscribe events for MGM nodes.
- */
- if(type == NodeInfo::MGM){
- jam();
- globalTransporterRegistry.setIOState(hostId, NoHalt);
- }
-
- //------------------------------------------
- // Also report this event to the Event handler
- //------------------------------------------
- signal->theData[0] = NDB_LE_Connected;
- signal->theData[1] = hostId;
- signal->header.theLength = 2;
-
- execEVENT_REP(signal);
-}
-
-#ifdef VM_TRACE
-void
-modifySignalLogger(bool allBlocks, BlockNumber bno,
- TestOrd::Command cmd,
- TestOrd::SignalLoggerSpecification spec){
- SignalLoggerManager::LogMode logMode;
-
- /**
- * Mapping between SignalLoggerManager::LogMode and
- * TestOrd::SignalLoggerSpecification
- */
- switch(spec){
- case TestOrd::InputSignals:
- logMode = SignalLoggerManager::LogIn;
- break;
- case TestOrd::OutputSignals:
- logMode = SignalLoggerManager::LogOut;
- break;
- case TestOrd::InputOutputSignals:
- logMode = SignalLoggerManager::LogInOut;
- break;
- default:
- return;
- break;
- }
-
- switch(cmd){
- case TestOrd::On:
- globalSignalLoggers.logOn(allBlocks, bno, logMode);
- break;
- case TestOrd::Off:
- globalSignalLoggers.logOff(allBlocks, bno, logMode);
- break;
- case TestOrd::Toggle:
- globalSignalLoggers.logToggle(allBlocks, bno, logMode);
- break;
- case TestOrd::KeepUnchanged:
- // Do nothing
- break;
- }
- globalSignalLoggers.flushSignalLog();
-}
-#endif
-
-void
-Cmvmi::execTEST_ORD(Signal * signal){
- jamEntry();
-
-#ifdef VM_TRACE
- TestOrd * const testOrd = (TestOrd *)&signal->theData[0];
-
- TestOrd::Command cmd;
-
- {
- /**
- * Process Trace command
- */
- TestOrd::TraceSpecification traceSpec;
-
- testOrd->getTraceCommand(cmd, traceSpec);
- unsigned long traceVal = traceSpec;
- unsigned long currentTraceVal = globalSignalLoggers.getTrace();
- switch(cmd){
- case TestOrd::On:
- currentTraceVal |= traceVal;
- break;
- case TestOrd::Off:
- currentTraceVal &= (~traceVal);
- break;
- case TestOrd::Toggle:
- currentTraceVal ^= traceVal;
- break;
- case TestOrd::KeepUnchanged:
- // Do nothing
- break;
- }
- globalSignalLoggers.setTrace(currentTraceVal);
- }
-
- {
- /**
- * Process Log command
- */
- TestOrd::SignalLoggerSpecification logSpec;
- BlockNumber bno;
- unsigned int loggers = testOrd->getNoOfSignalLoggerCommands();
-
- if(loggers == (unsigned)~0){ // Apply command to all blocks
- testOrd->getSignalLoggerCommand(0, bno, cmd, logSpec);
- modifySignalLogger(true, bno, cmd, logSpec);
- } else {
- for(unsigned int i = 0; i<loggers; i++){
- testOrd->getSignalLoggerCommand(i, bno, cmd, logSpec);
- modifySignalLogger(false, bno, cmd, logSpec);
- }
- }
- }
-
- {
- /**
- * Process test command
- */
- testOrd->getTestCommand(cmd);
- switch(cmd){
- case TestOrd::On:{
- SET_GLOBAL_TEST_ON;
- }
- break;
- case TestOrd::Off:{
- SET_GLOBAL_TEST_OFF;
- }
- break;
- case TestOrd::Toggle:{
- TOGGLE_GLOBAL_TEST_FLAG;
- }
- break;
- case TestOrd::KeepUnchanged:
- // Do nothing
- break;
- }
- globalSignalLoggers.flushSignalLog();
- }
-
-#endif
-}
-
-void Cmvmi::execSTOP_ORD(Signal* signal)
-{
- jamEntry();
- globalData.theRestartFlag = perform_stop;
-}//execSTOP_ORD()
-
-void
-Cmvmi::execSTART_ORD(Signal* signal) {
-
- StartOrd * const startOrd = (StartOrd *)&signal->theData[0];
- jamEntry();
-
- Uint32 tmp = startOrd->restartInfo;
- if(StopReq::getPerformRestart(tmp)){
- jam();
- /**
- *
- */
- NdbRestartType type = NRT_Default;
- if(StopReq::getNoStart(tmp) && StopReq::getInitialStart(tmp))
- type = NRT_NoStart_InitialStart;
- if(StopReq::getNoStart(tmp) && !StopReq::getInitialStart(tmp))
- type = NRT_NoStart_Restart;
- if(!StopReq::getNoStart(tmp) && StopReq::getInitialStart(tmp))
- type = NRT_DoStart_InitialStart;
- if(!StopReq::getNoStart(tmp)&&!StopReq::getInitialStart(tmp))
- type = NRT_DoStart_Restart;
- NdbShutdown(NST_Restart, type);
- }
-
- if(globalData.theRestartFlag == system_started){
- jam()
- /**
- * START_ORD received when already started(ignored)
- */
- //ndbout << "START_ORD received when already started(ignored)" << endl;
- return;
- }
-
- if(globalData.theRestartFlag == perform_stop){
- jam()
- /**
- * START_ORD received when stopping(ignored)
- */
- //ndbout << "START_ORD received when stopping(ignored)" << endl;
- return;
- }
-
- if(globalData.theStartLevel == NodeState::SL_NOTHING){
- jam();
- globalData.theStartLevel = NodeState::SL_CMVMI;
- /**
- * Open connections to management servers
- */
- for(unsigned int i = 1; i < MAX_NODES; i++ ){
- if (getNodeInfo(i).m_type == NodeInfo::MGM){
- if(!globalTransporterRegistry.is_connected(i)){
- globalTransporterRegistry.do_connect(i);
- globalTransporterRegistry.setIOState(i, NoHalt);
- }
- }
- }
-
- EXECUTE_DIRECT(QMGR, GSN_START_ORD, signal, 1);
- return ;
- }
-
- if(globalData.theStartLevel == NodeState::SL_CMVMI){
- jam();
-
- if(m_ctx.m_config.lockPagesInMainMemory() == 2)
- {
- int res = NdbMem_MemLockAll(1);
- if(res != 0)
- {
- g_eventLogger.warning("Failed to memlock pages");
- warningEvent("Failed to memlock pages");
- }
- else
- {
- g_eventLogger.info("Locked future allocations");
- }
- }
-
- globalData.theStartLevel = NodeState::SL_STARTING;
- globalData.theRestartFlag = system_started;
- /**
- * StartLevel 1
- *
- * Do Restart
- */
-
- // Disconnect all nodes as part of the system restart.
- // We need to ensure that we are starting up
- // without any connected nodes.
- for(unsigned int i = 1; i < MAX_NODES; i++ ){
- if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){
- globalTransporterRegistry.do_disconnect(i);
- globalTransporterRegistry.setIOState(i, HaltIO);
- }
- }
-
- /**
- * Start running startphases
- */
- sendSignal(NDBCNTR_REF, GSN_START_ORD, signal, 1, JBA);
- return;
- }
-}//execSTART_ORD()
-
-void Cmvmi::execTAMPER_ORD(Signal* signal)
-{
- jamEntry();
- // TODO We should maybe introduce a CONF and REF signal
- // to be able to indicate if we really introduced an error.
-#ifdef ERROR_INSERT
- TamperOrd* const tamperOrd = (TamperOrd*)&signal->theData[0];
- signal->theData[2] = 0;
- signal->theData[1] = tamperOrd->errorNo;
- signal->theData[0] = 5;
- sendSignal(DBDIH_REF, GSN_DIHNDBTAMPER, signal, 3,JBB);
-#endif
-
-}//execTAMPER_ORD()
-
-#ifdef VM_TRACE
-class RefSignalTest {
-public:
- enum ErrorCode {
- OK = 0,
- NF_FakeErrorREF = 7
- };
- Uint32 senderRef;
- Uint32 senderData;
- Uint32 errorCode;
-};
-#endif
-
-
-static int iii;
-
-static
-int
-recurse(char * buf, int loops, int arg){
- char * tmp = (char*)alloca(arg);
- printf("tmp = %p\n", tmp);
- for(iii = 0; iii<arg; iii += 1024){
- tmp[iii] = (iii % 23 + (arg & iii));
- }
-
- if(loops == 0)
- return tmp[345];
- else
- return tmp[arg/loops] + recurse(tmp, loops - 1, arg);
-}
-
-void
-Cmvmi::execDUMP_STATE_ORD(Signal* signal)
-{
-
- sendSignal(QMGR_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(NDBCNTR_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBTC_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBDIH_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBDICT_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBLQH_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBTUP_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBACC_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(NDBFS_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(BACKUP_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBUTIL_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(SUMA_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(TRIX_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(DBTUX_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(LGMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(TSMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
- sendSignal(PGMAN_REF, GSN_DUMP_STATE_ORD, signal, signal->length(), JBB);
-
- /**
- *
- * Here I can dump CMVMI state if needed
- */
- if(signal->theData[0] == 13){
-#if 0
- int loop = 100;
- int len = (10*1024*1024);
- if(signal->getLength() > 1)
- loop = signal->theData[1];
- if(signal->getLength() > 2)
- len = signal->theData[2];
-
- ndbout_c("recurse(%d loop, %dkb per recurse)", loop, len/1024);
- int a = recurse(0, loop, len);
- ndbout_c("after...%d", a);
-#endif
- }
-
- DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
- Uint32 arg = dumpState->args[0];
- if (arg == DumpStateOrd::CmvmiDumpConnections){
- for(unsigned int i = 1; i < MAX_NODES; i++ ){
- const char* nodeTypeStr = "";
- switch(getNodeInfo(i).m_type){
- case NodeInfo::DB:
- nodeTypeStr = "DB";
- break;
- case NodeInfo::API:
- nodeTypeStr = "API";
- break;
- case NodeInfo::MGM:
- nodeTypeStr = "MGM";
- break;
- case NodeInfo::INVALID:
- nodeTypeStr = 0;
- break;
- default:
- nodeTypeStr = "<UNKNOWN>";
- }
-
- if(nodeTypeStr == 0)
- continue;
-
- infoEvent("Connection to %d (%s) %s",
- i,
- nodeTypeStr,
- globalTransporterRegistry.getPerformStateString(i));
- }
- }
-
- if (arg == DumpStateOrd::CmvmiDumpSubscriptions)
- {
- SubscriberPtr ptr;
- subscribers.first(ptr);
- g_eventLogger.info("List subscriptions:");
- while(ptr.i != RNIL)
- {
- g_eventLogger.info("Subscription: %u, nodeId: %u, ref: 0x%x",
- ptr.i, refToNode(ptr.p->blockRef), ptr.p->blockRef);
- for(Uint32 i = 0; i < LogLevel::LOGLEVEL_CATEGORIES; i++)
- {
- Uint32 level = ptr.p->logLevel.getLogLevel((LogLevel::EventCategory)i);
- g_eventLogger.info("Category %u Level %u", i, level);
- }
- subscribers.next(ptr);
- }
- }
-
- if (arg == DumpStateOrd::CmvmiDumpLongSignalMemory){
- infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d",
- g_sectionSegmentPool.getSize(),
- g_sectionSegmentPool.getNoOfFree());
- }
-
- if (dumpState->args[0] == 1000)
- {
- Uint32 len = signal->getLength();
- if (signal->getLength() == 1)
- {
- signal->theData[1] = 0;
- signal->theData[2] = ~0;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
- return;
- }
- Uint32 id = signal->theData[1];
- Resource_limit rl;
- if (!m_ctx.m_mm.get_resource_limit(id, rl))
- len = 2;
- else
- {
- if (rl.m_min || rl.m_curr || rl.m_max)
- infoEvent("Resource %d min: %d max: %d curr: %d",
- id, rl.m_min, rl.m_max, rl.m_curr);
- }
-
- if (len == 3)
- {
- signal->theData[0] = 1000;
- signal->theData[1] = id+1;
- signal->theData[2] = ~0;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
- }
- return;
- }
-
- if (arg == DumpStateOrd::CmvmiSetRestartOnErrorInsert)
- {
- if(signal->getLength() == 1)
- {
- Uint32 val = (Uint32)NRT_NoStart_Restart;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- if(!ndb_mgm_get_int_parameter(p, CFG_DB_STOP_ON_ERROR_INSERT, &val))
- {
- m_ctx.m_config.setRestartOnErrorInsert(val);
- }
- }
- else
- {
- m_ctx.m_config.setRestartOnErrorInsert(signal->theData[1]);
- }
- }
-
- if (arg == DumpStateOrd::CmvmiTestLongSigWithDelay) {
- unsigned i;
- Uint32 loopCount = dumpState->args[1];
- const unsigned len0 = 11;
- const unsigned len1 = 123;
- Uint32 sec0[len0];
- Uint32 sec1[len1];
- for (i = 0; i < len0; i++)
- sec0[i] = i;
- for (i = 0; i < len1; i++)
- sec1[i] = 16 * i;
- Uint32* sig = signal->getDataPtrSend();
- sig[0] = reference();
- sig[1] = 20; // test type
- sig[2] = 0;
- sig[3] = 0;
- sig[4] = loopCount;
- sig[5] = len0;
- sig[6] = len1;
- sig[7] = 0;
- LinearSectionPtr ptr[3];
- ptr[0].p = sec0;
- ptr[0].sz = len0;
- ptr[1].p = sec1;
- ptr[1].sz = len1;
- sendSignal(reference(), GSN_TESTSIG, signal, 8, JBB, ptr, 2);
- }
-
-#ifdef ERROR_INSERT
- if (arg == 9000 || arg == 9002)
- {
- SET_ERROR_INSERT_VALUE(arg);
- for (Uint32 i = 1; i<signal->getLength(); i++)
- c_error_9000_nodes_mask.set(signal->theData[i]);
- }
-
- if (arg == 9001)
- {
- CLEAR_ERROR_INSERT_VALUE;
- if (signal->getLength() == 1 || signal->theData[1])
- {
- for (Uint32 i = 0; i<MAX_NODES; i++)
- {
- if (c_error_9000_nodes_mask.get(i))
- {
- signal->theData[0] = 0;
- signal->theData[1] = i;
- EXECUTE_DIRECT(CMVMI, GSN_OPEN_COMREQ, signal, 2);
- }
- }
- }
- c_error_9000_nodes_mask.clear();
- }
-#endif
-
-#ifdef VM_TRACE
-#if 0
- {
- SafeCounterManager mgr(* this); mgr.setSize(1);
- SafeCounterHandle handle;
-
- {
- SafeCounter tmp(mgr, handle);
- tmp.init<RefSignalTest>(CMVMI, GSN_TESTSIG, /* senderData */ 13);
- tmp.setWaitingFor(3);
- ndbrequire(!tmp.done());
- ndbout_c("Allocted");
- }
- ndbrequire(!handle.done());
- {
- SafeCounter tmp(mgr, handle);
- tmp.clearWaitingFor(3);
- ndbrequire(tmp.done());
- ndbout_c("Deallocted");
- }
- ndbrequire(handle.done());
- }
-#endif
-#endif
-
- if (arg == 9999)
- {
- Uint32 delay = 1000;
- switch(signal->getLength()){
- case 1:
- break;
- case 2:
- delay = signal->theData[1];
- break;
- default:{
- Uint32 dmin = signal->theData[1];
- Uint32 dmax = signal->theData[2];
- delay = dmin + (rand() % (dmax - dmin));
- break;
- }
- }
-
- signal->theData[0] = 9999;
- if (delay == 0)
- {
- execNDB_TAMPER(signal);
- }
- else if (delay < 10)
- {
- sendSignal(reference(), GSN_NDB_TAMPER, signal, 1, JBB);
- }
- else
- {
- sendSignalWithDelay(reference(), GSN_NDB_TAMPER, signal, delay, 1);
- }
- }
-}//Cmvmi::execDUMP_STATE_ORD()
-
-void
-Cmvmi::execNODE_START_REP(Signal* signal)
-{
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(9002) && signal->theData[0] == getOwnNodeId())
- {
- signal->theData[0] = 9001;
- execDUMP_STATE_ORD(signal);
- }
-#endif
-}
-
-BLOCK_FUNCTIONS(Cmvmi)
-
-static Uint32 g_print;
-static LinearSectionPtr g_test[3];
-
-void
-Cmvmi::execTESTSIG(Signal* signal){
- Uint32 i;
- /**
- * Test of SafeCounter
- */
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- Uint32 ref = signal->theData[0];
- Uint32 testType = signal->theData[1];
- Uint32 fragmentLength = signal->theData[2];
- g_print = signal->theData[3];
-// Uint32 returnCount = signal->theData[4];
- Uint32 * secSizes = &signal->theData[5];
-
- if(g_print){
- SignalLoggerManager::printSignalHeader(stdout,
- signal->header,
- 0,
- getOwnNodeId(),
- true);
- ndbout_c("-- Fixed section --");
- for(i = 0; i<signal->length(); i++){
- fprintf(stdout, "H'0x%.8x ", signal->theData[i]);
- if(((i + 1) % 6) == 0)
- fprintf(stdout, "\n");
- }
- fprintf(stdout, "\n");
-
- for(i = 0; i<signal->header.m_noOfSections; i++){
- SegmentedSectionPtr ptr(0,0,0);
- ndbout_c("-- Section %d --", i);
- signal->getSection(ptr, i);
- ndbrequire(ptr.p != 0);
- print(ptr, stdout);
- ndbrequire(ptr.sz == secSizes[i]);
- }
- }
-
- /**
- * Validate length:s
- */
- for(i = 0; i<signal->header.m_noOfSections; i++){
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, i);
- ndbrequire(ptr.p != 0);
- ndbrequire(ptr.sz == secSizes[i]);
- }
-
- /**
- * Testing send with delay.
- */
- if (testType == 20) {
- if (signal->theData[4] == 0) {
- releaseSections(signal);
- return;
- }
- signal->theData[4]--;
- sendSignalWithDelay(reference(), GSN_TESTSIG, signal, 100, 8);
- return;
- }
-
- NodeReceiverGroup rg(CMVMI, c_dbNodes);
-
- if(signal->getSendersBlockRef() == ref){
- /**
- * Signal from API (not via NodeReceiverGroup)
- */
- if((testType % 2) == 1){
- signal->theData[4] = 1;
- } else {
- signal->theData[1] --;
- signal->theData[4] = rg.m_nodes.count();
- }
- }
-
- switch(testType){
- case 1:
- sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB);
- break;
- case 2:
- sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB);
- break;
- case 3:
- case 4:{
- LinearSectionPtr ptr[3];
- const Uint32 secs = signal->getNoOfSections();
- for(i = 0; i<secs; i++){
- SegmentedSectionPtr sptr(0,0,0);
- signal->getSection(sptr, i);
- ptr[i].sz = sptr.sz;
- ptr[i].p = new Uint32[sptr.sz];
- copy(ptr[i].p, sptr);
- }
-
- if(testType == 3){
- sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
- } else {
- sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB, ptr, secs);
- }
- for(Uint32 i = 0; i<secs; i++){
- delete[] ptr[i].p;
- }
- break;
- }
- case 5:
- case 6:{
-
- NodeReceiverGroup tmp;
- if(testType == 5){
- tmp = ref;
- } else {
- tmp = rg;
- }
-
- FragmentSendInfo fragSend;
- sendFirstFragment(fragSend,
- tmp,
- GSN_TESTSIG,
- signal,
- signal->length(),
- JBB,
- fragmentLength);
- int count = 1;
- while(fragSend.m_status != FragmentSendInfo::SendComplete){
- count++;
- if(g_print)
- ndbout_c("Sending fragment %d", count);
- sendNextSegmentedFragment(signal, fragSend);
- }
- break;
- }
- case 7:
- case 8:{
- LinearSectionPtr ptr[3];
- const Uint32 secs = signal->getNoOfSections();
- for(i = 0; i<secs; i++){
- SegmentedSectionPtr sptr(0,0,0);
- signal->getSection(sptr, i);
- ptr[i].sz = sptr.sz;
- ptr[i].p = new Uint32[sptr.sz];
- copy(ptr[i].p, sptr);
- }
-
- NodeReceiverGroup tmp;
- if(testType == 7){
- tmp = ref;
- } else {
- tmp = rg;
- }
-
- FragmentSendInfo fragSend;
- sendFirstFragment(fragSend,
- tmp,
- GSN_TESTSIG,
- signal,
- signal->length(),
- JBB,
- ptr,
- secs,
- fragmentLength);
-
- int count = 1;
- while(fragSend.m_status != FragmentSendInfo::SendComplete){
- count++;
- if(g_print)
- ndbout_c("Sending fragment %d", count);
- sendNextLinearFragment(signal, fragSend);
- }
-
- for(i = 0; i<secs; i++){
- delete[] ptr[i].p;
- }
- break;
- }
- case 9:
- case 10:{
-
- Callback m_callBack;
- m_callBack.m_callbackFunction =
- safe_cast(&Cmvmi::sendFragmentedComplete);
-
- if(testType == 9){
- m_callBack.m_callbackData = 9;
- sendFragmentedSignal(ref,
- GSN_TESTSIG, signal, signal->length(), JBB,
- m_callBack,
- fragmentLength);
- } else {
- m_callBack.m_callbackData = 10;
- sendFragmentedSignal(rg,
- GSN_TESTSIG, signal, signal->length(), JBB,
- m_callBack,
- fragmentLength);
- }
- break;
- }
- case 11:
- case 12:{
-
- const Uint32 secs = signal->getNoOfSections();
- memset(g_test, 0, sizeof(g_test));
- for(i = 0; i<secs; i++){
- SegmentedSectionPtr sptr(0,0,0);
- signal->getSection(sptr, i);
- g_test[i].sz = sptr.sz;
- g_test[i].p = new Uint32[sptr.sz];
- copy(g_test[i].p, sptr);
- }
-
-
- Callback m_callBack;
- m_callBack.m_callbackFunction =
- safe_cast(&Cmvmi::sendFragmentedComplete);
-
- if(testType == 11){
- m_callBack.m_callbackData = 11;
- sendFragmentedSignal(ref,
- GSN_TESTSIG, signal, signal->length(), JBB,
- g_test, secs,
- m_callBack,
- fragmentLength);
- } else {
- m_callBack.m_callbackData = 12;
- sendFragmentedSignal(rg,
- GSN_TESTSIG, signal, signal->length(), JBB,
- g_test, secs,
- m_callBack,
- fragmentLength);
- }
- 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(i = 0; i<count; i++){
- sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB);
- }
- return;
- }
-
- default:
- ndbrequire(false);
- }
- return;
-}
-
-void
-Cmvmi::sendFragmentedComplete(Signal* signal, Uint32 data, Uint32 returnCode){
- if(g_print)
- ndbout_c("sendFragmentedComplete: %d", data);
- if(data == 11 || data == 12){
- for(Uint32 i = 0; i<3; i++){
- if(g_test[i].p != 0)
- delete[] g_test[i].p;
- }
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp
deleted file mode 100644
index 8e4f140ea4d..00000000000
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Cmvmi_H_
-#define Cmvmi_H_
-
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include <LogLevel.hpp>
-
-#include <DLList.hpp>
-
-/**
- * Cmvmi class
- */
-class Cmvmi : public SimulatedBlock {
-public:
- Cmvmi(Block_context&);
- virtual ~Cmvmi();
-
-private:
- /**
- * These methods used to be reportXXX
- *
- * But they in a nasty way intefere with the execution model
- * they been turned in to exec-Method used via prio A signals
- */
- void execDISCONNECT_REP(Signal*);
- void execCONNECT_REP(Signal*);
-
-private:
- BLOCK_DEFINES(Cmvmi);
-
- // The signal processing functions
- void execNDB_TAMPER(Signal* signal);
- void execSET_LOGLEVELORD(Signal* signal);
- void execEVENT_REP(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execCLOSE_COMREQ(Signal* signal);
- void execENABLE_COMORD(Signal* signal);
- void execOPEN_COMREQ(Signal* signal);
- void execSIZEALT_ACK(Signal* signal);
- void execTEST_ORD(Signal* signal);
-
- void execSTOP_ORD(Signal* signal);
- void execSTART_ORD(Signal* signal);
- void execTAMPER_ORD(Signal* signal);
-
- void execDUMP_STATE_ORD(Signal* signal);
-
- void execEVENT_SUBSCRIBE_REQ(Signal *);
- void cancelSubscription(NodeId nodeId);
-
- void execTESTSIG(Signal* signal);
- void execNODE_START_REP(Signal* signal);
-
- char theErrorMessage[256];
- void sendSTTORRY(Signal* signal);
-
- LogLevel clogLevel;
- NdbNodeBitmask c_dbNodes;
-
- /**
- * This struct defines the data needed for a EVENT_REP subscriber
- */
- struct EventRepSubscriber {
- /**
- * What log level is the subscriber using
- */
- LogLevel logLevel;
-
- /**
- * What block reference does he use
- * (Where should the EVENT_REP's be forwarded)
- */
- BlockReference blockRef;
-
- /**
- * Next ptr (used in pool/list)
- */
- union { Uint32 nextPool; Uint32 nextList; };
- Uint32 prevList;
- };
- typedef Ptr<EventRepSubscriber> SubscriberPtr;
-
- /**
- * Pool of EventRepSubscriber record
- */
- ArrayPool<EventRepSubscriber> subscriberPool;
-
- /**
- * List of current subscribers
- */
- DLList<EventRepSubscriber> subscribers;
-
-private:
- // Declared but not defined
- Cmvmi(const Cmvmi &obj);
- void operator = (const Cmvmi &);
-
- void sendFragmentedComplete(Signal* signal, Uint32 data, Uint32 returnCode);
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
deleted file mode 100644
index 267fc2ec8ef..00000000000
--- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
+++ /dev/null
@@ -1,1106 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBACC_H
-#define DBACC_H
-
-#ifdef VM_TRACE
-#define ACC_SAFE_QUEUE
-#endif
-
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-
-#ifdef DBACC_C
-// Debug Macros
-#define dbgWord32(ptr, ind, val)
-
-/*
-#define dbgWord32(ptr, ind, val) \
-if(debug_jan){ \
-tmp_val = val; \
-switch(ind){ \
-case 1: strcpy(tmp_string, "ZPOS_PAGE_TYPE "); \
-break; \
-case 2: strcpy(tmp_string, "ZPOS_NO_ELEM_IN_PAGE"); \
-break; \
-case 3: strcpy(tmp_string, "ZPOS_CHECKSUM "); \
-break; \
-case 4: strcpy(tmp_string, "ZPOS_OVERFLOWREC "); \
-break; \
-case 5: strcpy(tmp_string, "ZPOS_FREE_AREA_IN_PAGE"); \
-break; \
-case 6: strcpy(tmp_string, "ZPOS_LAST_INDEX "); \
-break; \
-case 7: strcpy(tmp_string, "ZPOS_INSERT_INDEX "); \
-break; \
-case 8: strcpy(tmp_string, "ZPOS_ARRAY_POS "); \
-break; \
-case 9: strcpy(tmp_string, "ZPOS_NEXT_FREE_INDEX"); \
-break; \
-case 10: strcpy(tmp_string, "ZPOS_NEXT_PAGE "); \
-break; \
-case 11: strcpy(tmp_string, "ZPOS_PREV_PAGE "); \
-break; \
-default: sprintf(tmp_string, "%-20d", ind);\
-} \
-ndbout << "Ptr: " << ptr.p->word32 << " \tIndex: " << tmp_string << " \tValue: " << tmp_val << " \tLINE: " << __LINE__ << endl; \
-}\
-*/
-
-// Constants
-/** ------------------------------------------------------------------------
- * THESE ARE CONSTANTS THAT ARE USED FOR DEFINING THE SIZE OF BUFFERS, THE
- * SIZE OF PAGE HEADERS, THE NUMBER OF BUFFERS IN A PAGE AND A NUMBER OF
- * OTHER CONSTANTS WHICH ARE CHANGED WHEN THE BUFFER SIZE IS CHANGED.
- * ----------------------------------------------------------------------- */
-#define ZHEAD_SIZE 32
-#define ZCON_HEAD_SIZE 2
-#define ZBUF_SIZE 28
-#define ZEMPTYLIST 72
-#define ZUP_LIMIT 14
-#define ZDOWN_LIMIT 12
-#define ZSHIFT_PLUS 5
-#define ZSHIFT_MINUS 2
-#define ZFREE_LIMIT 65
-#define ZNO_CONTAINERS 64
-#define ZELEM_HEAD_SIZE 1
-/* ------------------------------------------------------------------------- */
-/* THESE CONSTANTS DEFINE THE USE OF THE PAGE HEADER IN THE INDEX PAGES. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_PAGE_ID 0
-#define ZPOS_PAGE_TYPE 1
-#define ZPOS_PAGE_TYPE_BIT 14
-#define ZPOS_EMPTY_LIST 1
-#define ZPOS_ALLOC_CONTAINERS 2
-#define ZPOS_CHECKSUM 3
-#define ZPOS_OVERFLOWREC 4
-#define ZPOS_NO_ELEM_IN_PAGE 2
-#define ZPOS_FREE_AREA_IN_PAGE 5
-#define ZPOS_LAST_INDEX 6
-#define ZPOS_INSERT_INDEX 7
-#define ZPOS_ARRAY_POS 8
-#define ZPOS_NEXT_FREE_INDEX 9
-#define ZPOS_NEXT_PAGE 10
-#define ZPOS_PREV_PAGE 11
-#define ZNORMAL_PAGE_TYPE 0
-#define ZOVERFLOW_PAGE_TYPE 1
-#define ZDEFAULT_LIST 3
-#define ZWORDS_IN_PAGE 2048
-#define ZADDFRAG 0
-#define ZDIRARRAY 68
-#define ZDIRRANGESIZE 65
-//#define ZEMPTY_FRAGMENT 0
-#define ZFRAGMENTSIZE 64
-#define ZFIRSTTIME 1
-#define ZFS_CONNECTSIZE 300
-#define ZFS_OPSIZE 100
-#define ZKEYINKEYREQ 4
-#define ZLEFT 1
-#define ZLOCALLOGFILE 2
-#define ZLOCKED 0
-#define ZMAXSCANSIGNALLEN 20
-#define ZMAINKEYLEN 8
-#define ZNO_OF_DISK_VERSION 3
-#define ZNO_OF_OP_PER_SIGNAL 20
-//#define ZNOT_EMPTY_FRAGMENT 1
-#define ZOP_HEAD_INFO_LN 3
-#define ZOPRECSIZE 740
-#define ZOVERFLOWRECSIZE 5
-#define ZPAGE8_BASE_ADD 1
-#define ZPAGESIZE 128
-#define ZPARALLEL_QUEUE 1
-#define ZPDIRECTORY 1
-#define ZSCAN_MAX_LOCK 4
-#define ZSERIAL_QUEUE 2
-#define ZSPH1 1
-#define ZSPH2 2
-#define ZSPH3 3
-#define ZSPH6 6
-#define ZREADLOCK 0
-#define ZRIGHT 2
-#define ZROOTFRAGMENTSIZE 32
-#define ZSCAN_LOCK_ALL 3
-/**
- * Check kernel_types for other operation types
- */
-#define ZSCAN_OP 6
-#define ZSCAN_REC_SIZE 256
-#define ZSTAND_BY 2
-#define ZTABLESIZE 16
-#define ZTABMAXINDEX 3
-#define ZUNDEFINED_OP 6
-#define ZUNLOCKED 1
-
-/* --------------------------------------------------------------------------------- */
-/* CONTINUEB CODES */
-/* --------------------------------------------------------------------------------- */
-#define ZINITIALISE_RECORDS 1
-#define ZSEND_SCAN_HBREP 4
-#define ZREL_ROOT_FRAG 5
-#define ZREL_FRAG 6
-#define ZREL_DIR 7
-#define ZREPORT_MEMORY_USAGE 8
-
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES */
-/* ------------------------------------------------------------------------- */
-#define ZLIMIT_OF_ERROR 600 // Limit check for error codes
-#define ZCHECKROOT_ERROR 601 // Delete fragment error code
-#define ZCONNECT_SIZE_ERROR 602 // ACC_SEIZEREF
-#define ZDIR_RANGE_ERROR 603 // Add fragment error code
-#define ZFULL_FRAGRECORD_ERROR 604 // Add fragment error code
-#define ZFULL_ROOTFRAGRECORD_ERROR 605 // Add fragment error code
-#define ZROOTFRAG_STATE_ERROR 606 // Add fragment
-#define ZOVERTAB_REC_ERROR 607 // Add fragment
-
-#define ZSCAN_REFACC_CONNECT_ERROR 608 // ACC_SCANREF
-#define ZFOUR_ACTIVE_SCAN_ERROR 609 // ACC_SCANREF
-#define ZNULL_SCAN_REC_ERROR 610 // ACC_SCANREF
-
-#define ZDIRSIZE_ERROR 623
-#define ZOVER_REC_ERROR 624 // Insufficient Space
-#define ZPAGESIZE_ERROR 625
-#define ZTUPLE_DELETED_ERROR 626
-#define ZREAD_ERROR 626
-#define ZWRITE_ERROR 630
-#define ZTO_OP_STATE_ERROR 631
-#define ZTOO_EARLY_ACCESS_ERROR 632
-#endif
-
-class ElementHeader {
- /**
- *
- * l = Locked -- If true contains operation else scan bits + hash value
- * s = Scan bits
- * h = Hash value
- * o = Operation ptr I
- *
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * lssssssssssss hhhhhhhhhhhhhhhh
- * ooooooooooooooooooooooooooooooo
- */
-public:
- STATIC_CONST( HASH_VALUE_PART_MASK = 0xFFFF );
-
- static bool getLocked(Uint32 data);
- static bool getUnlocked(Uint32 data);
- static Uint32 getScanBits(Uint32 data);
- static Uint32 getHashValuePart(Uint32 data);
- static Uint32 getOpPtrI(Uint32 data);
-
- static Uint32 setLocked(Uint32 opPtrI);
- static Uint32 setUnlocked(Uint32 hashValuePart, Uint32 scanBits);
- static Uint32 setScanBit(Uint32 header, Uint32 scanBit);
- static Uint32 clearScanBit(Uint32 header, Uint32 scanBit);
-};
-
-inline
-bool
-ElementHeader::getLocked(Uint32 data){
- return (data & 1) == 0;
-}
-
-inline
-bool
-ElementHeader::getUnlocked(Uint32 data){
- return (data & 1) == 1;
-}
-
-inline
-Uint32
-ElementHeader::getScanBits(Uint32 data){
- assert(getUnlocked(data));
- return (data >> 1) & ((1 << MAX_PARALLEL_SCANS_PER_FRAG) - 1);
-}
-
-inline
-Uint32
-ElementHeader::getHashValuePart(Uint32 data){
- assert(getUnlocked(data));
- return data >> 16;
-}
-
-inline
-Uint32
-ElementHeader::getOpPtrI(Uint32 data){
- assert(getLocked(data));
- return data >> 1;
-}
-
-inline
-Uint32
-ElementHeader::setLocked(Uint32 opPtrI){
- return (opPtrI << 1) + 0;
-}
-inline
-Uint32
-ElementHeader::setUnlocked(Uint32 hashValue, Uint32 scanBits){
- return (hashValue << 16) + (scanBits << 1) + 1;
-}
-
-inline
-Uint32
-ElementHeader::setScanBit(Uint32 header, Uint32 scanBit){
- assert(getUnlocked(header));
- return header | (scanBit << 1);
-}
-
-inline
-Uint32
-ElementHeader::clearScanBit(Uint32 header, Uint32 scanBit){
- assert(getUnlocked(header));
- return header & (~(scanBit << 1));
-}
-
-
-class Dbacc: public SimulatedBlock {
-public:
-// State values
-enum State {
- FREEFRAG = 0,
- ACTIVEFRAG = 1,
- //SEND_QUE_OP = 2,
- WAIT_NOTHING = 10,
- WAIT_ONE_CONF = 26,
- FREE_OP = 30,
- WAIT_EXE_OP = 32,
- WAIT_IN_QUEUE = 34,
- EXE_OP = 35,
- SCAN_ACTIVE = 36,
- SCAN_WAIT_IN_QUEUE = 37,
- IDLE = 39,
- ACTIVE = 40,
- WAIT_COMMIT_ABORT = 41,
- ABORT = 42,
- ABORTADDFRAG = 43,
- REFUSEADDFRAG = 44,
- DELETEFRAG = 45,
- DELETETABLE = 46,
- UNDEFINEDROOT = 47,
- ADDFIRSTFRAG = 48,
- ADDSECONDFRAG = 49,
- DELETEFIRSTFRAG = 50,
- DELETESECONDFRAG = 51,
- ACTIVEROOT = 52
-};
-
-// Records
-
-/* --------------------------------------------------------------------------------- */
-/* DIRECTORY RANGE */
-/* --------------------------------------------------------------------------------- */
- struct DirRange {
- Uint32 dirArray[256];
- }; /* p2c: size = 1024 bytes */
-
- typedef Ptr<DirRange> DirRangePtr;
-
-/* --------------------------------------------------------------------------------- */
-/* DIRECTORYARRAY */
-/* --------------------------------------------------------------------------------- */
-struct Directoryarray {
- Uint32 pagep[256];
-}; /* p2c: size = 1024 bytes */
-
- typedef Ptr<Directoryarray> DirectoryarrayPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* FRAGMENTREC. ALL INFORMATION ABOUT FRAMENT AND HASH TABLE IS SAVED IN FRAGMENT */
-/* REC A POINTER TO FRAGMENT RECORD IS SAVED IN ROOTFRAGMENTREC FRAGMENT */
-/* --------------------------------------------------------------------------------- */
-struct Fragmentrec {
- Uint32 scan[MAX_PARALLEL_SCANS_PER_FRAG];
- union {
- Uint32 mytabptr;
- Uint32 myTableId;
- };
- union {
- Uint32 fragmentid;
- Uint32 myfid;
- };
- Uint32 roothashcheck;
- Uint32 noOfElements;
- Uint32 m_commit_count;
- State rootState;
-
-//-----------------------------------------------------------------------------
-// These variables keep track of allocated pages, the number of them and the
-// start file page of them. Used during local checkpoints.
-//-----------------------------------------------------------------------------
- Uint32 datapages[8];
- Uint32 activeDataPage;
-
-//-----------------------------------------------------------------------------
-// Temporary variables used during shrink and expand process.
-//-----------------------------------------------------------------------------
- Uint32 expReceivePageptr;
- Uint32 expReceiveIndex;
- Uint32 expReceiveForward;
- Uint32 expSenderDirIndex;
- Uint32 expSenderDirptr;
- Uint32 expSenderIndex;
- Uint32 expSenderPageptr;
-
-//-----------------------------------------------------------------------------
-// List of lock owners and list of lock waiters to support LCP handling
-//-----------------------------------------------------------------------------
- Uint32 lockOwnersList;
-
-//-----------------------------------------------------------------------------
-// References to Directory Ranges (which in turn references directories, which
-// in its turn references the pages) for the bucket pages and the overflow
-// bucket pages.
-//-----------------------------------------------------------------------------
- Uint32 directory;
- Uint32 dirsize;
- Uint32 overflowdir;
- Uint32 lastOverIndex;
-
-//-----------------------------------------------------------------------------
-// We have a list of overflow pages with free areas. We have a special record,
-// the overflow record representing these pages. The reason is that the
-// same record is also used to represent pages in the directory array that have
-// been released since they were empty (there were however higher indexes with
-// data in them). These are put in the firstFreeDirIndexRec-list.
-// An overflow record representing a page can only be in one of these lists.
-//-----------------------------------------------------------------------------
- Uint32 firstOverflowRec;
- Uint32 lastOverflowRec;
- Uint32 firstFreeDirindexRec;
-
-//-----------------------------------------------------------------------------
-// Counter keeping track of how many times we have expanded. We need to ensure
-// that we do not shrink so many times that this variable becomes negative.
-//-----------------------------------------------------------------------------
- Uint32 expandCounter;
-
-//-----------------------------------------------------------------------------
-// These variables are important for the linear hashing algorithm.
-// localkeylen is the size of the local key (1 and 2 is currently supported)
-// maxloadfactor is the factor specifying when to expand
-// minloadfactor is the factor specifying when to shrink (hysteresis model)
-// maxp and p
-// maxp and p is the variables most central to linear hashing. p + maxp + 1 is the
-// current number of buckets. maxp is the largest value of the type 2**n - 1
-// which is smaller than the number of buckets. These values are used to find
-// correct bucket with the aid of the hash value.
-//
-// slack is the variable keeping track of whether we have inserted more than
-// the current size is suitable for or less. Slack together with the boundaries
-// set by maxloadfactor and minloadfactor decides when to expand/shrink
-// slackCheck When slack goes over this value it is time to expand.
-// slackCheck = (maxp + p + 1)*(maxloadfactor - minloadfactor) or
-// bucketSize * hysteresis
-//-----------------------------------------------------------------------------
- Uint32 localkeylen;
- Uint32 maxp;
- Uint32 maxloadfactor;
- Uint32 minloadfactor;
- Uint32 p;
- Uint32 slack;
- Uint32 slackCheck;
-
-//-----------------------------------------------------------------------------
-// nextfreefrag is the next free fragment if linked into a free list
-//-----------------------------------------------------------------------------
- Uint32 nextfreefrag;
-
-//-----------------------------------------------------------------------------
-// This variable is used during restore to keep track of page id of read pages.
-// During read of bucket pages this is used to calculate the page id and also
-// to verify that the page id of the read page is correct. During read of over-
-// flow pages it is only used to keep track of the number of pages read.
-//-----------------------------------------------------------------------------
- Uint32 nextAllocPage;
-
-//-----------------------------------------------------------------------------
-// Number of pages read from file during restore
-//-----------------------------------------------------------------------------
- Uint32 noOfExpectedPages;
-
-//-----------------------------------------------------------------------------
-// Fragment State, mostly applicable during LCP and restore
-//-----------------------------------------------------------------------------
- State fragState;
-
-//-----------------------------------------------------------------------------
-// elementLength: Length of element in bucket and overflow pages
-// keyLength: Length of key
-//-----------------------------------------------------------------------------
- Uint8 elementLength;
- Uint16 keyLength;
-
-//-----------------------------------------------------------------------------
-// This flag is used to avoid sending a big number of expand or shrink signals
-// when simultaneously committing many inserts or deletes.
-//-----------------------------------------------------------------------------
- Uint8 expandFlag;
-
-//-----------------------------------------------------------------------------
-// hashcheckbit is the bit to check whether to send element to split bucket or not
-// k (== 6) is the number of buckets per page
-// lhfragbits is the number of bits used to calculate the fragment id
-// lhdirbits is the number of bits used to calculate the page id
-//-----------------------------------------------------------------------------
- Uint8 hashcheckbit;
- Uint8 k;
- Uint8 lhfragbits;
- Uint8 lhdirbits;
-
-//-----------------------------------------------------------------------------
-// nodetype can only be STORED in this release. Is currently only set, never read
-//-----------------------------------------------------------------------------
- Uint8 nodetype;
-
-//-----------------------------------------------------------------------------
-// flag to avoid accessing table record if no char attributes
-//-----------------------------------------------------------------------------
- Uint8 hasCharAttr;
-};
-
- typedef Ptr<Fragmentrec> FragmentrecPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* OPERATIONREC */
-/* --------------------------------------------------------------------------------- */
-struct Operationrec {
- Uint32 m_op_bits;
- Uint32 localdata[2];
- Uint32 elementIsforward;
- Uint32 elementPage;
- Uint32 elementPointer;
- Uint32 fid;
- Uint32 fragptr;
- Uint32 hashvaluePart;
- Uint32 hashValue;
- Uint32 nextLockOwnerOp;
- Uint32 nextOp;
- Uint32 nextParallelQue;
- union {
- Uint32 nextSerialQue;
- Uint32 m_lock_owner_ptr_i; // if nextParallelQue = RNIL, else undefined
- };
- Uint32 prevOp;
- Uint32 prevLockOwnerOp;
- union {
- Uint32 prevParallelQue;
- Uint32 m_lo_last_parallel_op_ptr_i;
- };
- union {
- Uint32 prevSerialQue;
- Uint32 m_lo_last_serial_op_ptr_i;
- };
- Uint32 scanRecPtr;
- Uint32 transId1;
- Uint32 transId2;
- Uint32 userptr;
- Uint16 elementContainer;
- Uint16 tupkeylen;
- Uint32 xfrmtupkeylen;
- Uint32 userblockref;
- Uint32 scanBits;
-
- enum OpBits {
- OP_MASK = 0x0000F // 4 bits for operation type
- ,OP_LOCK_MODE = 0x00010 // 0 - shared lock, 1 = exclusive lock
- ,OP_ACC_LOCK_MODE = 0x00020 // Or:de lock mode of all operation
- // before me
- ,OP_LOCK_OWNER = 0x00040
- ,OP_RUN_QUEUE = 0x00080 // In parallell queue of lock owner
- ,OP_DIRTY_READ = 0x00100
- ,OP_LOCK_REQ = 0x00200 // isAccLockReq
- ,OP_COMMIT_DELETE_CHECK = 0x00400
- ,OP_INSERT_IS_DONE = 0x00800
- ,OP_ELEMENT_DISAPPEARED = 0x01000
-
- ,OP_STATE_MASK = 0xF0000
- ,OP_STATE_IDLE = 0xF0000
- ,OP_STATE_WAITING = 0x00000
- ,OP_STATE_RUNNING = 0x10000
- ,OP_STATE_EXECUTED = 0x30000
-
- ,OP_EXECUTED_DIRTY_READ = 0x3050F
- ,OP_INITIAL = ~(Uint32)0
- };
-
- Operationrec() {}
- bool is_same_trans(const Operationrec* op) const {
- return
- transId1 == op->transId1 && transId2 == op->transId2;
- }
-
-}; /* p2c: size = 168 bytes */
-
- typedef Ptr<Operationrec> OperationrecPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* OVERFLOW_RECORD */
-/* --------------------------------------------------------------------------------- */
-struct OverflowRecord {
- Uint32 dirindex;
- Uint32 nextOverRec;
- Uint32 nextOverList;
- Uint32 prevOverRec;
- Uint32 prevOverList;
- Uint32 overpage;
- Uint32 nextfreeoverrec;
-};
-
- typedef Ptr<OverflowRecord> OverflowRecordPtr;
-
-/* --------------------------------------------------------------------------------- */
-/* PAGE8 */
-/* --------------------------------------------------------------------------------- */
-struct Page8 {
- Uint32 word32[2048];
-}; /* p2c: size = 8192 bytes */
-
- typedef Ptr<Page8> Page8Ptr;
-
-/* --------------------------------------------------------------------------------- */
-/* SCAN_REC */
-/* --------------------------------------------------------------------------------- */
-struct ScanRec {
- enum ScanState {
- WAIT_NEXT,
- SCAN_DISCONNECT
- };
- enum ScanBucketState {
- FIRST_LAP,
- SECOND_LAP,
- SCAN_COMPLETED
- };
- Uint32 activeLocalFrag;
- Uint32 nextBucketIndex;
- Uint32 scanNextfreerec;
- Uint32 scanFirstActiveOp;
- Uint32 scanFirstLockedOp;
- Uint32 scanLastLockedOp;
- Uint32 scanFirstQueuedOp;
- Uint32 scanLastQueuedOp;
- Uint32 scanUserptr;
- Uint32 scanTrid1;
- Uint32 scanTrid2;
- Uint32 startNoOfBuckets;
- Uint32 minBucketIndexToRescan;
- Uint32 maxBucketIndexToRescan;
- Uint32 scanOpsAllocated;
- ScanBucketState scanBucketState;
- ScanState scanState;
- Uint16 scanLockHeld;
- Uint32 scanUserblockref;
- Uint32 scanMask;
- Uint8 scanLockMode;
- Uint8 scanTimer;
- Uint8 scanContinuebCounter;
- Uint8 scanReadCommittedFlag;
-};
-
- typedef Ptr<ScanRec> ScanRecPtr;
-
-
-/* --------------------------------------------------------------------------------- */
-/* TABREC */
-/* --------------------------------------------------------------------------------- */
-struct Tabrec {
- Uint32 fragholder[MAX_FRAG_PER_NODE];
- Uint32 fragptrholder[MAX_FRAG_PER_NODE];
- Uint32 tabUserPtr;
- BlockReference tabUserRef;
-};
- typedef Ptr<Tabrec> TabrecPtr;
-
-public:
- Dbacc(Block_context&);
- virtual ~Dbacc();
-
- // pointer to TUP instance in this thread
- class Dbtup* c_tup;
- class Dblqh* c_lqh;
-
- void execACCMINUPDATE(Signal* signal);
-
-private:
- BLOCK_DEFINES(Dbacc);
-
- // Transit signals
- void execDEBUG_SIG(Signal* signal);
- void execCONTINUEB(Signal* signal);
- void execACC_CHECK_SCAN(Signal* signal);
- void execEXPANDCHECK2(Signal* signal);
- void execSHRINKCHECK2(Signal* signal);
- void execACC_OVER_REC(Signal* signal);
- void execNEXTOPERATION(Signal* signal);
- void execREAD_PSEUDO_REQ(Signal* signal);
-
- // Received signals
- void execSTTOR(Signal* signal);
- void execACCKEYREQ(Signal* signal);
- void execACCSEIZEREQ(Signal* signal);
- void execACCFRAGREQ(Signal* signal);
- void execNEXT_SCANREQ(Signal* signal);
- void execACC_ABORTREQ(Signal* signal);
- void execACC_SCANREQ(Signal* signal);
- void execACC_COMMITREQ(Signal* signal);
- void execACC_TO_REQ(Signal* signal);
- void execACC_LOCKREQ(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execDROP_TAB_REQ(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
-
- // Statement blocks
- void ACCKEY_error(Uint32 fromWhere);
-
- void commitDeleteCheck();
- void report_dealloc(Signal* signal, const Operationrec* opPtrP);
-
- typedef void * RootfragmentrecPtr;
- void initRootFragPageZero(FragmentrecPtr, Page8Ptr);
- void initFragAdd(Signal*, FragmentrecPtr);
- void initFragPageZero(FragmentrecPtr, Page8Ptr);
- void initFragGeneral(FragmentrecPtr);
- void verifyFragCorrect(FragmentrecPtr regFragPtr);
- void releaseFragResources(Signal* signal, Uint32 fragIndex);
- void releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr);
- void releaseRootFragResources(Signal* signal, Uint32 tableId);
- void releaseDirResources(Signal* signal,
- Uint32 fragIndex,
- Uint32 dirIndex,
- Uint32 startIndex);
- void releaseDirectoryResources(Signal* signal,
- Uint32 fragIndex,
- Uint32 dirIndex,
- Uint32 startIndex,
- Uint32 directoryIndex);
- void releaseOverflowResources(Signal* signal, FragmentrecPtr regFragPtr);
- void releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr);
- void releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr);
- void initScanFragmentPart(Signal* signal);
- Uint32 checkScanExpand(Signal* signal);
- Uint32 checkScanShrink(Signal* signal);
- void initialiseDirRec(Signal* signal);
- void initialiseDirRangeRec(Signal* signal);
- void initialiseFragRec(Signal* signal);
- void initialiseFsConnectionRec(Signal* signal);
- void initialiseFsOpRec(Signal* signal);
- void initialiseOperationRec(Signal* signal);
- void initialiseOverflowRec(Signal* signal);
- void initialisePageRec(Signal* signal);
- void initialiseRootfragRec(Signal* signal);
- void initialiseScanRec(Signal* signal);
- void initialiseTableRec(Signal* signal);
- bool addfragtotab(Signal* signal, Uint32 rootIndex, Uint32 fragId);
- void initOpRec(Signal* signal);
- void sendAcckeyconf(Signal* signal);
- Uint32 getNoParallelTransaction(const Operationrec*);
-
-#ifdef VM_TRACE
- Uint32 getNoParallelTransactionFull(const Operationrec*);
-#endif
-#ifdef ACC_SAFE_QUEUE
- bool validate_lock_queue(OperationrecPtr opPtr);
- Uint32 get_parallel_head(OperationrecPtr opPtr);
- void dump_lock_queue(OperationrecPtr loPtr);
-#else
- bool validate_lock_queue(OperationrecPtr) { return true;}
-#endif
-
-public:
- void execACCKEY_ORD(Signal* signal, Uint32 opPtrI);
- void startNext(Signal* signal, OperationrecPtr lastOp);
-
-private:
- Uint32 placeReadInLockQueue(OperationrecPtr lockOwnerPtr);
- Uint32 placeWriteInLockQueue(OperationrecPtr lockOwnerPtr);
- void placeSerialQueue(OperationrecPtr lockOwner, OperationrecPtr op);
- void abortSerieQueueOperation(Signal* signal, OperationrecPtr op);
- void abortParallelQueueOperation(Signal* signal, OperationrecPtr op);
-
- void expandcontainer(Signal* signal);
- void shrinkcontainer(Signal* signal);
- void nextcontainerinfoExp(Signal* signal);
- void releaseAndCommitActiveOps(Signal* signal);
- void releaseAndCommitQueuedOps(Signal* signal);
- void releaseAndAbortLockedOps(Signal* signal);
- void containerinfo(Signal* signal);
- bool getScanElement(Signal* signal);
- void initScanOpRec(Signal* signal);
- void nextcontainerinfo(Signal* signal);
- void putActiveScanOp(Signal* signal);
- void putOpScanLockQue();
- void putReadyScanQueue(Signal* signal, Uint32 scanRecIndex);
- void releaseScanBucket(Signal* signal);
- void releaseScanContainer(Signal* signal);
- void releaseScanRec(Signal* signal);
- bool searchScanContainer(Signal* signal);
- void sendNextScanConf(Signal* signal);
- void setlock(Signal* signal);
- void takeOutActiveScanOp(Signal* signal);
- void takeOutScanLockQueue(Uint32 scanRecIndex);
- void takeOutReadyScanQueue(Signal* signal);
- void insertElement(Signal* signal);
- void insertContainer(Signal* signal);
- void addnewcontainer(Signal* signal);
- void getfreelist(Signal* signal);
- void increaselistcont(Signal* signal);
- void seizeLeftlist(Signal* signal);
- void seizeRightlist(Signal* signal);
- Uint32 readTablePk(Uint32 localkey1, Uint32 eh, OperationrecPtr);
- Uint32 getElement(Signal* signal, OperationrecPtr& lockOwner);
- void getdirindex(Signal* signal);
- void commitdelete(Signal* signal);
- void deleteElement(Signal* signal);
- void getLastAndRemove(Signal* signal);
- void releaseLeftlist(Signal* signal);
- void releaseRightlist(Signal* signal);
- void checkoverfreelist(Signal* signal);
- void abortOperation(Signal* signal);
- void commitOperation(Signal* signal);
- void copyOpInfo(OperationrecPtr dst, OperationrecPtr src);
- Uint32 executeNextOperation(Signal* signal);
- void releaselock(Signal* signal);
- void release_lockowner(Signal* signal, OperationrecPtr, bool commit);
- void startNew(Signal* signal, OperationrecPtr newOwner);
- void abortWaitingOperation(Signal*, OperationrecPtr);
- void abortExecutedOperation(Signal*, OperationrecPtr);
-
- void takeOutFragWaitQue(Signal* signal);
- void check_lock_upgrade(Signal* signal, OperationrecPtr release_op, bool lo);
- void check_lock_upgrade(Signal* signal, OperationrecPtr lock_owner,
- OperationrecPtr release_op);
- void allocOverflowPage(Signal* signal);
- bool getfragmentrec(Signal* signal, FragmentrecPtr&, Uint32 fragId);
- void insertLockOwnersList(Signal* signal, const OperationrecPtr&);
- void takeOutLockOwnersList(Signal* signal, const OperationrecPtr&);
-
- void initFsOpRec(Signal* signal);
- void initOverpage(Signal* signal);
- void initPage(Signal* signal);
- void initRootfragrec(Signal* signal);
- void putOpInFragWaitQue(Signal* signal);
- void putOverflowRecInFrag(Signal* signal);
- void putRecInFreeOverdir(Signal* signal);
- void releaseDirectory(Signal* signal);
- void releaseDirrange(Signal* signal);
- void releaseFsConnRec(Signal* signal);
- void releaseFsOpRec(Signal* signal);
- void releaseOpRec(Signal* signal);
- void releaseOverflowRec(Signal* signal);
- void releaseOverpage(Signal* signal);
- void releasePage(Signal* signal);
- void releaseLogicalPage(Fragmentrec * fragP, Uint32 logicalPageId);
- void seizeDirectory(Signal* signal);
- void seizeDirrange(Signal* signal);
- void seizeFragrec(Signal* signal);
- void seizeFsConnectRec(Signal* signal);
- void seizeFsOpRec(Signal* signal);
- void seizeOpRec(Signal* signal);
- void seizeOverRec(Signal* signal);
- void seizePage(Signal* signal);
- void seizeRootfragrec(Signal* signal);
- void seizeScanRec(Signal* signal);
- void sendSystemerror(Signal* signal, int line);
- void takeRecOutOfFreeOverdir(Signal* signal);
- void takeRecOutOfFreeOverpage(Signal* signal);
- void sendScanHbRep(Signal* signal, Uint32);
-
- void addFragRefuse(Signal* signal, Uint32 errorCode);
- void ndbsttorryLab(Signal* signal);
- void acckeyref1Lab(Signal* signal, Uint32 result_code);
- void insertelementLab(Signal* signal);
- void checkNextFragmentLab(Signal* signal);
- void endofexpLab(Signal* signal);
- void endofshrinkbucketLab(Signal* signal);
- void senddatapagesLab(Signal* signal);
- void sttorrysignalLab(Signal* signal);
- void sendholdconfsignalLab(Signal* signal);
- void accIsLockedLab(Signal* signal, OperationrecPtr lockOwnerPtr);
- void insertExistElemLab(Signal* signal, OperationrecPtr lockOwnerPtr);
- void refaccConnectLab(Signal* signal);
- void releaseScanLab(Signal* signal);
- void ndbrestart1Lab(Signal* signal);
- void initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data);
- void checkNextBucketLab(Signal* signal);
- void storeDataPageInDirectoryLab(Signal* signal);
-
- void zpagesize_error(const char* where);
-
- void reportMemoryUsage(Signal* signal, int gth);
- void reenable_expand_after_redo_log_exection_complete(Signal*);
-
- // charsets
- void xfrmKeyData(Signal* signal);
-
- // Initialisation
- void initData();
- void initRecords();
-
- // Variables
-/* --------------------------------------------------------------------------------- */
-/* DIRECTORY RANGE */
-/* --------------------------------------------------------------------------------- */
- DirRange *dirRange;
- DirRangePtr expDirRangePtr;
- DirRangePtr gnsDirRangePtr;
- DirRangePtr newDirRangePtr;
- DirRangePtr rdDirRangePtr;
- DirRangePtr nciOverflowrangeptr;
- Uint32 cdirrangesize;
- Uint32 cfirstfreeDirrange;
-/* --------------------------------------------------------------------------------- */
-/* DIRECTORYARRAY */
-/* --------------------------------------------------------------------------------- */
- Directoryarray *directoryarray;
- DirectoryarrayPtr expDirptr;
- DirectoryarrayPtr rdDirptr;
- DirectoryarrayPtr sdDirptr;
- DirectoryarrayPtr nciOverflowDirptr;
- Uint32 cdirarraysize;
- Uint32 cdirmemory;
- Uint32 cfirstfreedir;
-/* --------------------------------------------------------------------------------- */
-/* FRAGMENTREC. ALL INFORMATION ABOUT FRAMENT AND HASH TABLE IS SAVED IN FRAGMENT */
-/* REC A POINTER TO FRAGMENT RECORD IS SAVED IN ROOTFRAGMENTREC FRAGMENT */
-/* --------------------------------------------------------------------------------- */
- Fragmentrec *fragmentrec;
- FragmentrecPtr fragrecptr;
- Uint32 cfirstfreefrag;
- Uint32 cfragmentsize;
-/* --------------------------------------------------------------------------------- */
-/* FS_CONNECTREC */
-/* --------------------------------------------------------------------------------- */
-/* OPERATIONREC */
-/* --------------------------------------------------------------------------------- */
- Operationrec *operationrec;
- OperationrecPtr operationRecPtr;
- OperationrecPtr idrOperationRecPtr;
- OperationrecPtr mlpqOperPtr;
- OperationrecPtr queOperPtr;
- OperationrecPtr readWriteOpPtr;
- Uint32 cfreeopRec;
- Uint32 coprecsize;
-/* --------------------------------------------------------------------------------- */
-/* OVERFLOW_RECORD */
-/* --------------------------------------------------------------------------------- */
- OverflowRecord *overflowRecord;
- OverflowRecordPtr iopOverflowRecPtr;
- OverflowRecordPtr tfoOverflowRecPtr;
- OverflowRecordPtr porOverflowRecPtr;
- OverflowRecordPtr priOverflowRecPtr;
- OverflowRecordPtr rorOverflowRecPtr;
- OverflowRecordPtr sorOverflowRecPtr;
- OverflowRecordPtr troOverflowRecPtr;
- Uint32 cfirstfreeoverrec;
- Uint32 coverflowrecsize;
-
-/* --------------------------------------------------------------------------------- */
-/* PAGE8 */
-/* --------------------------------------------------------------------------------- */
- Page8 *page8;
- /* 8 KB PAGE */
- Page8Ptr ancPageptr;
- Page8Ptr colPageptr;
- Page8Ptr ccoPageptr;
- Page8Ptr datapageptr;
- Page8Ptr delPageptr;
- Page8Ptr excPageptr;
- Page8Ptr expPageptr;
- Page8Ptr gdiPageptr;
- Page8Ptr gePageptr;
- Page8Ptr gflPageptr;
- Page8Ptr idrPageptr;
- Page8Ptr ilcPageptr;
- Page8Ptr inpPageptr;
- Page8Ptr iopPageptr;
- Page8Ptr lastPageptr;
- Page8Ptr lastPrevpageptr;
- Page8Ptr lcnPageptr;
- Page8Ptr lcnCopyPageptr;
- Page8Ptr lupPageptr;
- Page8Ptr ciPageidptr;
- Page8Ptr gsePageidptr;
- Page8Ptr isoPageptr;
- Page8Ptr nciPageidptr;
- Page8Ptr rsbPageidptr;
- Page8Ptr rscPageidptr;
- Page8Ptr slPageidptr;
- Page8Ptr sscPageidptr;
- Page8Ptr rlPageptr;
- Page8Ptr rlpPageptr;
- Page8Ptr ropPageptr;
- Page8Ptr rpPageptr;
- Page8Ptr slPageptr;
- Page8Ptr spPageptr;
- Uint32 cfirstfreepage;
- Uint32 cfreepage;
- Uint32 cpagesize;
- Uint32 cnoOfAllocatedPages;
-/* --------------------------------------------------------------------------------- */
-/* ROOTFRAGMENTREC */
-/* DURING EXPAND FRAGMENT PROCESS, EACH FRAGMEND WILL BE EXPAND INTO TWO */
-/* NEW FRAGMENTS.TO MAKE THIS PROCESS EASIER, DURING ADD FRAGMENT PROCESS */
-/* NEXT FRAGMENT IDENTIIES WILL BE CALCULATED, AND TWO FRAGMENTS WILL BE */
-/* ADDED IN (NDBACC). THEREBY EXPAND OF FRAGMENT CAN BE PERFORMED QUICK AND */
-/* EASY.THE NEW FRAGMENT ID SENDS TO TUP MANAGER FOR ALL OPERATION PROCESS. */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* SCAN_REC */
-/* --------------------------------------------------------------------------------- */
- ScanRec *scanRec;
- ScanRecPtr scanPtr;
- Uint32 cscanRecSize;
- Uint32 cfirstFreeScanRec;
-/* --------------------------------------------------------------------------------- */
-/* TABREC */
-/* --------------------------------------------------------------------------------- */
- Tabrec *tabrec;
- TabrecPtr tabptr;
- Uint32 ctablesize;
- Uint32 tgseElementptr;
- Uint32 tgseContainerptr;
- Uint32 trlHead;
- Uint32 trlRelCon;
- Uint32 trlNextused;
- Uint32 trlPrevused;
- Uint32 tlcnChecksum;
- Uint32 tlupElemIndex;
- Uint32 tlupIndex;
- Uint32 tlupForward;
- Uint32 tancNext;
- Uint32 tancBufType;
- Uint32 tancContainerptr;
- Uint32 tancPageindex;
- Uint32 tancPageid;
- Uint32 tidrResult;
- Uint32 tidrElemhead;
- Uint32 tidrForward;
- Uint32 tidrPageindex;
- Uint32 tidrContainerptr;
- Uint32 tidrContainerhead;
- Uint32 tlastForward;
- Uint32 tlastPageindex;
- Uint32 tlastContainerlen;
- Uint32 tlastElementptr;
- Uint32 tlastContainerptr;
- Uint32 tlastContainerhead;
- Uint32 trlPageindex;
- Uint32 tdelContainerptr;
- Uint32 tdelElementptr;
- Uint32 tdelForward;
- Uint32 tiopPageId;
- Uint32 tipPageId;
- Uint32 tgeContainerptr;
- Uint32 tgeElementptr;
- Uint32 tgeForward;
- Uint32 texpReceivedBucket;
- Uint32 texpDirInd;
- Uint32 texpDirRangeIndex;
- Uint32 texpDirPageIndex;
- Uint32 tdata0;
- Uint32 tcheckpointid;
- Uint32 tciContainerptr;
- Uint32 tnciContainerptr;
- Uint32 tisoContainerptr;
- Uint32 trscContainerptr;
- Uint32 tsscContainerptr;
- Uint32 tciContainerlen;
- Uint32 trscContainerlen;
- Uint32 tsscContainerlen;
- Uint32 tciContainerhead;
- Uint32 tnciContainerhead;
- Uint32 tslElementptr;
- Uint32 tisoElementptr;
- Uint32 tsscElementptr;
- Uint32 tfid;
- Uint32 tscanFlag;
- Uint32 tgflBufType;
- Uint32 tgseIsforward;
- Uint32 tsscIsforward;
- Uint32 trscIsforward;
- Uint32 tciIsforward;
- Uint32 tnciIsforward;
- Uint32 tisoIsforward;
- Uint32 tgseIsLocked;
- Uint32 tsscIsLocked;
- Uint32 tkeylen;
- Uint32 tmp;
- Uint32 tmpP;
- Uint32 tmpP2;
- Uint32 tmp1;
- Uint32 tmp2;
- Uint32 tgflPageindex;
- Uint32 tmpindex;
- Uint32 tslNextfree;
- Uint32 tslPageindex;
- Uint32 tgsePageindex;
- Uint32 tnciNextSamePage;
- Uint32 tslPrevfree;
- Uint32 tciPageindex;
- Uint32 trsbPageindex;
- Uint32 tnciPageindex;
- Uint32 tlastPrevconptr;
- Uint32 tresult;
- Uint32 tslUpdateHeader;
- Uint32 tuserptr;
- BlockReference tuserblockref;
- Uint32 tlqhPointer;
- Uint32 tholdSentOp;
- Uint32 tholdMore;
- Uint32 tgdiPageindex;
- Uint32 tiopIndex;
- Uint32 tnciTmp;
- Uint32 tullIndex;
- Uint32 turlIndex;
- Uint32 tlfrTmp1;
- Uint32 tlfrTmp2;
- Uint32 tscanTrid1;
- Uint32 tscanTrid2;
-
- Uint32 ctest;
- Uint32 clqhPtr;
- BlockReference clqhBlockRef;
- Uint32 cminusOne;
- NodeId cmynodeid;
- BlockReference cownBlockref;
- BlockReference cndbcntrRef;
- Uint16 csignalkey;
- Uint32 czero;
- Uint32 csystemRestart;
- Uint32 cexcForward;
- Uint32 cexcPageindex;
- Uint32 cexcContainerptr;
- Uint32 cexcContainerhead;
- Uint32 cexcContainerlen;
- Uint32 cexcElementptr;
- Uint32 cexcPrevconptr;
- Uint32 cexcMovedLen;
- Uint32 cexcPrevpageptr;
- Uint32 cexcPrevpageindex;
- Uint32 cexcPrevforward;
- Uint32 clocalkey[32];
- union {
- Uint32 ckeys[2048 * MAX_XFRM_MULTIPLY];
- Uint64 ckeys_align;
- };
-
- Uint32 c_errorInsert3000_TableId;
- Uint32 c_memusage_report_frequency;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp
deleted file mode 100644
index 29ea4801b7b..00000000000
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#define DBACC_C
-#include "Dbacc.hpp"
-
-#define DEBUG(x) { ndbout << "ACC::" << x << endl; }
-
-void Dbacc::initData()
-{
- cdirarraysize = ZDIRARRAY;
- coprecsize = ZOPRECSIZE;
- cpagesize = ZPAGESIZE;
- ctablesize = ZTABLESIZE;
- cfragmentsize = ZFRAGMENTSIZE;
- cdirrangesize = ZDIRRANGESIZE;
- coverflowrecsize = ZOVERFLOWRECSIZE;
- cscanRecSize = ZSCAN_REC_SIZE;
-
-
- dirRange = 0;
- directoryarray = 0;
- fragmentrec = 0;
- operationrec = 0;
- overflowRecord = 0;
- page8 = 0;
- scanRec = 0;
- tabrec = 0;
-
- cnoOfAllocatedPages = cpagesize = 0;
- // Records with constant sizes
-}//Dbacc::initData()
-
-void Dbacc::initRecords()
-{
- // Records with dynamic sizes
- page8 = (Page8*)allocRecord("Page8",
- sizeof(Page8),
- cpagesize,
- false,
- CFG_DB_INDEX_MEM);
-
- operationrec = (Operationrec*)allocRecord("Operationrec",
- sizeof(Operationrec),
- coprecsize);
-
- dirRange = (DirRange*)allocRecord("DirRange",
- sizeof(DirRange),
- cdirrangesize);
-
- directoryarray = (Directoryarray*)allocRecord("Directoryarray",
- sizeof(Directoryarray),
- cdirarraysize);
-
- fragmentrec = (Fragmentrec*)allocRecord("Fragmentrec",
- sizeof(Fragmentrec),
- cfragmentsize);
-
- overflowRecord = (OverflowRecord*)allocRecord("OverflowRecord",
- sizeof(OverflowRecord),
- coverflowrecsize);
-
- scanRec = (ScanRec*)allocRecord("ScanRec",
- sizeof(ScanRec),
- cscanRecSize);
-
- tabrec = (Tabrec*)allocRecord("Tabrec",
- sizeof(Tabrec),
- ctablesize);
-}//Dbacc::initRecords()
-
-Dbacc::Dbacc(Block_context& ctx):
- SimulatedBlock(DBACC, ctx),
- c_tup(0)
-{
- BLOCK_CONSTRUCTOR(Dbacc);
-
- // Transit signals
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbacc::execDUMP_STATE_ORD);
- addRecSignal(GSN_DEBUG_SIG, &Dbacc::execDEBUG_SIG);
- addRecSignal(GSN_CONTINUEB, &Dbacc::execCONTINUEB);
- addRecSignal(GSN_ACC_CHECK_SCAN, &Dbacc::execACC_CHECK_SCAN);
- addRecSignal(GSN_EXPANDCHECK2, &Dbacc::execEXPANDCHECK2);
- addRecSignal(GSN_SHRINKCHECK2, &Dbacc::execSHRINKCHECK2);
- addRecSignal(GSN_READ_PSEUDO_REQ, &Dbacc::execREAD_PSEUDO_REQ);
-
- // Received signals
- addRecSignal(GSN_STTOR, &Dbacc::execSTTOR);
- addRecSignal(GSN_ACCKEYREQ, &Dbacc::execACCKEYREQ);
- addRecSignal(GSN_ACCSEIZEREQ, &Dbacc::execACCSEIZEREQ);
- addRecSignal(GSN_ACCFRAGREQ, &Dbacc::execACCFRAGREQ);
- addRecSignal(GSN_NEXT_SCANREQ, &Dbacc::execNEXT_SCANREQ);
- addRecSignal(GSN_ACC_ABORTREQ, &Dbacc::execACC_ABORTREQ);
- addRecSignal(GSN_ACC_SCANREQ, &Dbacc::execACC_SCANREQ);
- addRecSignal(GSN_ACCMINUPDATE, &Dbacc::execACCMINUPDATE);
- addRecSignal(GSN_ACC_COMMITREQ, &Dbacc::execACC_COMMITREQ);
- addRecSignal(GSN_ACC_TO_REQ, &Dbacc::execACC_TO_REQ);
- addRecSignal(GSN_ACC_LOCKREQ, &Dbacc::execACC_LOCKREQ);
- addRecSignal(GSN_NDB_STTOR, &Dbacc::execNDB_STTOR);
- addRecSignal(GSN_DROP_TAB_REQ, &Dbacc::execDROP_TAB_REQ);
- addRecSignal(GSN_READ_CONFIG_REQ, &Dbacc::execREAD_CONFIG_REQ, true);
-
- initData();
-
-#ifdef VM_TRACE
- {
- void* tmp[] = { &expDirRangePtr,
- &gnsDirRangePtr,
- &newDirRangePtr,
- &rdDirRangePtr,
- &nciOverflowrangeptr,
- &expDirptr,
- &rdDirptr,
- &sdDirptr,
- &nciOverflowDirptr,
- &fragrecptr,
- &operationRecPtr,
- &idrOperationRecPtr,
- &mlpqOperPtr,
- &queOperPtr,
- &readWriteOpPtr,
- &iopOverflowRecPtr,
- &tfoOverflowRecPtr,
- &porOverflowRecPtr,
- &priOverflowRecPtr,
- &rorOverflowRecPtr,
- &sorOverflowRecPtr,
- &troOverflowRecPtr,
- &ancPageptr,
- &colPageptr,
- &ccoPageptr,
- &datapageptr,
- &delPageptr,
- &excPageptr,
- &expPageptr,
- &gdiPageptr,
- &gePageptr,
- &gflPageptr,
- &idrPageptr,
- &ilcPageptr,
- &inpPageptr,
- &iopPageptr,
- &lastPageptr,
- &lastPrevpageptr,
- &lcnPageptr,
- &lcnCopyPageptr,
- &lupPageptr,
- &ciPageidptr,
- &gsePageidptr,
- &isoPageptr,
- &nciPageidptr,
- &rsbPageidptr,
- &rscPageidptr,
- &slPageidptr,
- &sscPageidptr,
- &rlPageptr,
- &rlpPageptr,
- &ropPageptr,
- &rpPageptr,
- &slPageptr,
- &spPageptr,
- &scanPtr,
- &tabptr
- };
- init_globals_list(tmp, sizeof(tmp)/sizeof(tmp[0]));
- }
-#endif
-}//Dbacc::Dbacc()
-
-Dbacc::~Dbacc()
-{
- deallocRecord((void **)&dirRange, "DirRange",
- sizeof(DirRange),
- cdirrangesize);
-
- deallocRecord((void **)&directoryarray, "Directoryarray",
- sizeof(Directoryarray),
- cdirarraysize);
-
- deallocRecord((void **)&fragmentrec, "Fragmentrec",
- sizeof(Fragmentrec),
- cfragmentsize);
-
- deallocRecord((void **)&operationrec, "Operationrec",
- sizeof(Operationrec),
- coprecsize);
-
- deallocRecord((void **)&overflowRecord, "OverflowRecord",
- sizeof(OverflowRecord),
- coverflowrecsize);
-
- deallocRecord((void **)&page8, "Page8",
- sizeof(Page8),
- cpagesize);
-
- deallocRecord((void **)&scanRec, "ScanRec",
- sizeof(ScanRec),
- cscanRecSize);
-
- deallocRecord((void **)&tabrec, "Tabrec",
- sizeof(Tabrec),
- ctablesize);
- }//Dbacc::~Dbacc()
-
-BLOCK_FUNCTIONS(Dbacc)
diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
deleted file mode 100644
index da614b0276c..00000000000
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ /dev/null
@@ -1,8549 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBACC_C
-#include "Dbacc.hpp"
-#include <my_sys.h>
-
-#include <AttributeHeader.hpp>
-#include <signaldata/AccFrag.hpp>
-#include <signaldata/AccScan.hpp>
-#include <signaldata/NextScan.hpp>
-#include <signaldata/AccLock.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/TuxMaint.hpp>
-#include <KeyDescriptor.hpp>
-
-// TO_DO_RONM is a label for comments on what needs to be improved in future versions
-// when more time is given.
-
-#ifdef VM_TRACE
-#define DEBUG(x) ndbout << "DBACC: "<< x << endl;
-#else
-#define DEBUG(x)
-#endif
-
-#ifdef ACC_SAFE_QUEUE
-#define vlqrequire(x) do { if (unlikely(!(x))) {\
- dump_lock_queue(loPtr); \
- ndbrequire(false); } } while(0)
-#else
-#define vlqrequire(x) ndbrequire(x)
-#define dump_lock_queue(x)
-#endif
-
-
-// primary key is stored in TUP
-#include "../dbtup/Dbtup.hpp"
-#include "../dblqh/Dblqh.hpp"
-
-
-// Signal entries and statement blocks
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* COMMON SIGNAL RECEPTION MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-
-/* --------------------------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* CONTINUEB CONTINUE SIGNAL */
-/* ******************------------------------------+ */
-/* SENDER: ACC, LEVEL B */
-void Dbacc::execCONTINUEB(Signal* signal)
-{
- Uint32 tcase;
-
- jamEntry();
- tcase = signal->theData[0];
- tdata0 = signal->theData[1];
- tresult = 0;
- switch (tcase) {
- case ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal, signal->theData[3], signal->theData[4]);
- return;
- break;
- case ZSEND_SCAN_HBREP:
- jam();
- sendScanHbRep(signal, tdata0);
- break;
- case ZREL_ROOT_FRAG:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- releaseRootFragResources(signal, tableId);
- break;
- }
- case ZREL_FRAG:
- {
- jam();
- Uint32 fragIndex = signal->theData[1];
- releaseFragResources(signal, fragIndex);
- break;
- }
- case ZREL_DIR:
- {
- jam();
- Uint32 fragIndex = signal->theData[1];
- Uint32 dirIndex = signal->theData[2];
- Uint32 startIndex = signal->theData[3];
- releaseDirResources(signal, fragIndex, dirIndex, startIndex);
- break;
- }
- case ZREPORT_MEMORY_USAGE:{
- jam();
- Uint32 cnt = signal->theData[1];
- static int c_currentMemUsed = 0;
- int now = cpagesize ? (cnoOfAllocatedPages * 100)/cpagesize : 0;
- const int thresholds[] = { 99, 90, 80, 0};
-
- Uint32 i = 0;
- const Uint32 sz = sizeof(thresholds)/sizeof(thresholds[0]);
- for(i = 0; i<sz; i++){
- if(now >= thresholds[i]){
- now = thresholds[i];
- break;
- }
- }
-
- if(now != c_currentMemUsed ||
- (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency))
- {
- reportMemoryUsage(signal,
- now > c_currentMemUsed ? 1 :
- now < c_currentMemUsed ? -1 : 0);
- cnt = 0;
- c_currentMemUsed = now;
- }
- else
- {
- cnt ++;
- }
- signal->theData[0] = ZREPORT_MEMORY_USAGE;
- signal->theData[1] = cnt;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
- return;
- }
-
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbacc::execCONTINUEB()
-
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* END OF COMMON SIGNAL RECEPTION MODULE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* SYSTEM RESTART MODULE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-void Dbacc::execNDB_STTOR(Signal* signal)
-{
- Uint32 tstartphase;
- Uint32 tStartType;
-
- jamEntry();
- cndbcntrRef = signal->theData[0];
- cmynodeid = signal->theData[1];
- tstartphase = signal->theData[2];
- tStartType = signal->theData[3];
- switch (tstartphase) {
- case ZSPH1:
- jam();
- ndbsttorryLab(signal);
- return;
- break;
- case ZSPH2:
- ndbsttorryLab(signal);
- return;
- break;
- case ZSPH3:
- if ((tStartType == NodeState::ST_NODE_RESTART) ||
- (tStartType == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- //---------------------------------------------
- // csystemRestart is used to check what is needed
- // during log execution. When starting a node it
- // is not a log execution and rather a normal
- // execution. Thus we reset the variable here to
- // avoid unnecessary system crashes.
- //---------------------------------------------
- csystemRestart = ZFALSE;
- }//if
- break;
- case ZSPH6:
- jam();
- csystemRestart = ZFALSE;
-
- signal->theData[0] = ZREPORT_MEMORY_USAGE;
- signal->theData[1] = 0;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
- break;
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- ndbsttorryLab(signal);
- return;
-}//Dbacc::execNDB_STTOR()
-
-/* ******************--------------------------------------------------------------- */
-/* STTOR START / RESTART */
-/* ******************------------------------------+ */
-/* SENDER: ANY, LEVEL B */
-void Dbacc::execSTTOR(Signal* signal)
-{
- jamEntry();
- Uint32 tstartphase = signal->theData[1];
- switch (tstartphase) {
- case 1:
- jam();
- ndbrequire((c_tup = (Dbtup*)globalData.getBlock(DBTUP)) != 0);
- ndbrequire((c_lqh = (Dblqh*)globalData.getBlock(DBLQH)) != 0);
- break;
- }
- tuserblockref = signal->theData[3];
- csignalkey = signal->theData[6];
- sttorrysignalLab(signal);
- return;
-}//Dbacc::execSTTOR()
-
-/* --------------------------------------------------------------------------------- */
-/* ZSPH1 */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::ndbrestart1Lab(Signal* signal)
-{
- cmynodeid = globalData.ownId;
- cownBlockref = numberToRef(DBACC, cmynodeid);
- czero = 0;
- cminusOne = czero - 1;
- ctest = 0;
- csystemRestart = ZTRUE;
- return;
-}//Dbacc::ndbrestart1Lab()
-
-void Dbacc::initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data)
-{
- switch (tdata0) {
- case 0:
- jam();
- initialiseTableRec(signal);
- break;
- case 1:
- case 2:
- break;
- case 3:
- jam();
- break;
- case 4:
- jam();
- initialiseDirRec(signal);
- break;
- case 5:
- jam();
- initialiseDirRangeRec(signal);
- break;
- case 6:
- jam();
- initialiseFragRec(signal);
- break;
- case 7:
- jam();
- initialiseOverflowRec(signal);
- break;
- case 8:
- jam();
- initialiseOperationRec(signal);
- break;
- case 9:
- jam();
- initialisePageRec(signal);
- break;
- case 10:
- jam();
- break;
- case 11:
- jam();
- initialiseScanRec(signal);
- break;
- case 12:
- jam();
-
- {
- 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
-
- signal->theData[0] = ZINITIALISE_RECORDS;
- signal->theData[1] = tdata0 + 1;
- signal->theData[2] = 0;
- signal->theData[3] = ref;
- signal->theData[4] = data;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
- return;
-}//Dbacc::initialiseRecordsLab()
-
-/* *********************************<< */
-/* NDB_STTORRY */
-/* *********************************<< */
-void Dbacc::ndbsttorryLab(Signal* signal)
-{
- signal->theData[0] = cownBlockref;
- sendSignal(cndbcntrRef, GSN_NDB_STTORRY, signal, 1, JBB);
- return;
-}//Dbacc::ndbsttorryLab()
-
-/* *********************************<< */
-/* SIZEALT_REP SIZE ALTERATION */
-/* *********************************<< */
-void Dbacc::execREAD_CONFIG_REQ(Signal* signal)
-{
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
- ndbrequire(req->noOfParameters == 0);
-
- jamEntry();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.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_TABLE, &ctablesize));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_SCAN, &cscanRecSize));
- initRecords();
- ndbrestart1Lab(signal);
-
- c_memusage_report_frequency = 0;
- ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY,
- &c_memusage_report_frequency);
-
- tdata0 = 0;
- initialiseRecordsLab(signal, ref, senderData);
- return;
-}//Dbacc::execSIZEALT_REP()
-
-/* *********************************<< */
-/* STTORRY */
-/* *********************************<< */
-void Dbacc::sttorrysignalLab(Signal* signal)
-{
- signal->theData[0] = csignalkey;
- signal->theData[1] = 3;
- /* BLOCK CATEGORY */
- signal->theData[2] = 2;
- /* SIGNAL VERSION NUMBER */
- signal->theData[3] = ZSPH1;
- signal->theData[4] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- /* END OF START PHASES */
- return;
-}//Dbacc::sttorrysignalLab()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_DIR_REC */
-/* INITIALATES THE DIRECTORY RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseDirRec(Signal* signal)
-{
- DirectoryarrayPtr idrDirptr;
- ndbrequire(cdirarraysize > 0);
- for (idrDirptr.i = 0; idrDirptr.i < cdirarraysize; idrDirptr.i++) {
- refresh_watch_dog();
- ptrAss(idrDirptr, directoryarray);
- for (Uint32 i = 0; i <= 255; i++) {
- idrDirptr.p->pagep[i] = RNIL;
- }//for
- }//for
- cdirmemory = 0;
- cfirstfreedir = RNIL;
-}//Dbacc::initialiseDirRec()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_DIR_RANGE_REC */
-/* INITIALATES THE DIR_RANGE RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseDirRangeRec(Signal* signal)
-{
- DirRangePtr idrDirRangePtr;
-
- ndbrequire(cdirrangesize > 0);
- for (idrDirRangePtr.i = 0; idrDirRangePtr.i < cdirrangesize; idrDirRangePtr.i++) {
- refresh_watch_dog();
- ptrAss(idrDirRangePtr, dirRange);
- idrDirRangePtr.p->dirArray[0] = idrDirRangePtr.i + 1;
- for (Uint32 i = 1; i < 256; i++) {
- idrDirRangePtr.p->dirArray[i] = RNIL;
- }//for
- }//for
- idrDirRangePtr.i = cdirrangesize - 1;
- ptrAss(idrDirRangePtr, dirRange);
- idrDirRangePtr.p->dirArray[0] = RNIL;
- cfirstfreeDirrange = 0;
-}//Dbacc::initialiseDirRangeRec()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_FRAG_REC */
-/* INITIALATES THE FRAGMENT RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseFragRec(Signal* signal)
-{
- FragmentrecPtr regFragPtr;
- ndbrequire(cfragmentsize > 0);
- for (regFragPtr.i = 0; regFragPtr.i < cfragmentsize; regFragPtr.i++) {
- jam();
- refresh_watch_dog();
- ptrAss(regFragPtr, fragmentrec);
- initFragGeneral(regFragPtr);
- regFragPtr.p->nextfreefrag = regFragPtr.i + 1;
- }//for
- regFragPtr.i = cfragmentsize - 1;
- ptrAss(regFragPtr, fragmentrec);
- regFragPtr.p->nextfreefrag = RNIL;
- cfirstfreefrag = 0;
-}//Dbacc::initialiseFragRec()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_OPERATION_REC */
-/* INITIALATES THE OPERATION RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseOperationRec(Signal* signal)
-{
- ndbrequire(coprecsize > 0);
- for (operationRecPtr.i = 0; operationRecPtr.i < coprecsize; operationRecPtr.i++) {
- refresh_watch_dog();
- ptrAss(operationRecPtr, operationrec);
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- operationRecPtr.p->nextOp = operationRecPtr.i + 1;
- }//for
- operationRecPtr.i = coprecsize - 1;
- ptrAss(operationRecPtr, operationrec);
- operationRecPtr.p->nextOp = RNIL;
- cfreeopRec = 0;
-}//Dbacc::initialiseOperationRec()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_OVERFLOW_REC */
-/* INITIALATES THE OVERFLOW RECORDS */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseOverflowRec(Signal* signal)
-{
- OverflowRecordPtr iorOverflowRecPtr;
-
- ndbrequire(coverflowrecsize > 0);
- for (iorOverflowRecPtr.i = 0; iorOverflowRecPtr.i < coverflowrecsize; iorOverflowRecPtr.i++) {
- refresh_watch_dog();
- ptrAss(iorOverflowRecPtr, overflowRecord);
- iorOverflowRecPtr.p->nextfreeoverrec = iorOverflowRecPtr.i + 1;
- }//for
- iorOverflowRecPtr.i = coverflowrecsize - 1;
- ptrAss(iorOverflowRecPtr, overflowRecord);
- iorOverflowRecPtr.p->nextfreeoverrec = RNIL;
- cfirstfreeoverrec = 0;
-}//Dbacc::initialiseOverflowRec()
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_PAGE_REC */
-/* INITIALATES THE PAGE RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialisePageRec(Signal* signal)
-{
- ndbrequire(cpagesize > 0);
- cfreepage = 0;
- cfirstfreepage = RNIL;
- cnoOfAllocatedPages = 0;
-}//Dbacc::initialisePageRec()
-
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_ROOTFRAG_REC */
-/* INITIALATES THE ROOTFRAG RECORDS. */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_SCAN_REC */
-/* INITIALATES THE QUE_SCAN RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseScanRec(Signal* signal)
-{
- ndbrequire(cscanRecSize > 0);
- for (scanPtr.i = 0; scanPtr.i < cscanRecSize; scanPtr.i++) {
- ptrAss(scanPtr, scanRec);
- scanPtr.p->scanNextfreerec = scanPtr.i + 1;
- scanPtr.p->scanState = ScanRec::SCAN_DISCONNECT;
- scanPtr.p->scanTimer = 0;
- scanPtr.p->scanContinuebCounter = 0;
- }//for
- scanPtr.i = cscanRecSize - 1;
- ptrAss(scanPtr, scanRec);
- scanPtr.p->scanNextfreerec = RNIL;
- cfirstFreeScanRec = 0;
-}//Dbacc::initialiseScanRec()
-
-
-/* --------------------------------------------------------------------------------- */
-/* INITIALISE_TABLE_REC */
-/* INITIALATES THE TABLE RECORDS. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initialiseTableRec(Signal* signal)
-{
- ndbrequire(ctablesize > 0);
- for (tabptr.i = 0; tabptr.i < ctablesize; tabptr.i++) {
- refresh_watch_dog();
- ptrAss(tabptr, tabrec);
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- tabptr.p->fragholder[i] = RNIL;
- tabptr.p->fragptrholder[i] = RNIL;
- }//for
- }//for
-}//Dbacc::initialiseTableRec()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF SYSTEM RESTART MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* ADD/DELETE FRAGMENT MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-
-// JONAS This methods "aer ett saall"
-void Dbacc::execACCFRAGREQ(Signal* signal)
-{
- const AccFragReq * const req = (AccFragReq*)&signal->theData[0];
- jamEntry();
- if (ERROR_INSERTED(3001)) {
- jam();
- addFragRefuse(signal, 1);
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
- tabptr.i = req->tableId;
-#ifndef VM_TRACE
- // config mismatch - do not crash if release compiled
- if (tabptr.i >= ctablesize) {
- jam();
- addFragRefuse(signal, 640);
- return;
- }
-#endif
- ptrCheckGuard(tabptr, ctablesize, tabrec);
- ndbrequire((req->reqInfo & 0xF) == ZADDFRAG);
- ndbrequire(!getfragmentrec(signal, fragrecptr, req->fragId));
- if (cfirstfreefrag == RNIL) {
- jam();
- addFragRefuse(signal, ZFULL_FRAGRECORD_ERROR);
- return;
- }//if
-
- seizeFragrec(signal);
- initFragGeneral(fragrecptr);
- initFragAdd(signal, fragrecptr);
-
- if (!addfragtotab(signal, fragrecptr.i, req->fragId)) {
- jam();
- releaseFragRecord(signal, fragrecptr);
- addFragRefuse(signal, ZFULL_FRAGRECORD_ERROR);
- return;
- }//if
- if (cfirstfreeDirrange == RNIL) {
- jam();
- releaseFragRecord(signal, fragrecptr);
- addFragRefuse(signal, ZDIR_RANGE_ERROR);
- return;
- } else {
- jam();
- seizeDirrange(signal);
- }//if
-
- fragrecptr.p->directory = newDirRangePtr.i;
- seizeDirectory(signal);
- if (tresult < ZLIMIT_OF_ERROR) {
- jam();
- newDirRangePtr.p->dirArray[0] = sdDirptr.i;
- } else {
- jam();
- addFragRefuse(signal, tresult);
- return;
- }//if
-
- seizePage(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- addFragRefuse(signal, tresult);
- return;
- }//if
- sdDirptr.p->pagep[0] = spPageptr.i;
- tipPageId = 0;
- inpPageptr = spPageptr;
- initPage(signal);
- if (cfirstfreeDirrange == RNIL) {
- jam();
- addFragRefuse(signal, ZDIR_RANGE_ERROR);
- return;
- } else {
- jam();
- seizeDirrange(signal);
- }//if
- fragrecptr.p->overflowdir = newDirRangePtr.i;
- seizeDirectory(signal);
- if (tresult < ZLIMIT_OF_ERROR) {
- jam();
- newDirRangePtr.p->dirArray[0] = sdDirptr.i;
- } else {
- jam();
- addFragRefuse(signal, tresult);
- return;
- }//if
-
- Uint32 userPtr = req->userPtr;
- BlockReference retRef = req->userRef;
- fragrecptr.p->rootState = ACTIVEROOT;
-
- AccFragConf * const conf = (AccFragConf*)&signal->theData[0];
- conf->userPtr = userPtr;
- conf->rootFragPtr = RNIL;
- conf->fragId[0] = fragrecptr.p->fragmentid;
- conf->fragId[1] = RNIL;
- conf->fragPtr[0] = fragrecptr.i;
- conf->fragPtr[1] = RNIL;
- conf->rootHashCheck = fragrecptr.p->roothashcheck;
- sendSignal(retRef, GSN_ACCFRAGCONF, signal, AccFragConf::SignalLength, JBB);
-}//Dbacc::execACCFRAGREQ()
-
-void Dbacc::addFragRefuse(Signal* signal, Uint32 errorCode)
-{
- const AccFragReq * const req = (AccFragReq*)&signal->theData[0];
- AccFragRef * const ref = (AccFragRef*)&signal->theData[0];
- Uint32 userPtr = req->userPtr;
- BlockReference retRef = req->userRef;
-
- ref->userPtr = userPtr;
- ref->errorCode = errorCode;
- sendSignal(retRef, GSN_ACCFRAGREF, signal, AccFragRef::SignalLength, JBB);
- return;
-}//Dbacc::addFragRefuseEarly()
-
-void
-Dbacc::execDROP_TAB_REQ(Signal* signal){
- jamEntry();
- DropTabReq* req = (DropTabReq*)signal->getDataPtr();
-
- TabrecPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctablesize, tabrec);
-
- tabPtr.p->tabUserRef = req->senderRef;
- tabPtr.p->tabUserPtr = req->senderData;
-
- signal->theData[0] = ZREL_ROOT_FRAG;
- signal->theData[1] = tabPtr.i;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void Dbacc::releaseRootFragResources(Signal* signal, Uint32 tableId)
-{
- TabrecPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctablesize, tabrec);
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabPtr.p->fragholder[i] != RNIL) {
- jam();
- tabPtr.p->fragholder[i] = RNIL;
- releaseFragResources(signal, tabPtr.p->fragptrholder[i]);
- return;
- }//if
- }//for
-
- /**
- * Finished...
- */
-
- DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
- dropConf->senderRef = reference();
- dropConf->senderData = tabPtr.p->tabUserPtr;
- dropConf->tableId = tabPtr.i;
- sendSignal(tabPtr.p->tabUserRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
-
- tabPtr.p->tabUserPtr = RNIL;
- tabPtr.p->tabUserRef = 0;
-}//Dbacc::releaseRootFragResources()
-
-void Dbacc::releaseFragResources(Signal* signal, Uint32 fragIndex)
-{
- FragmentrecPtr regFragPtr;
- regFragPtr.i = fragIndex;
- ptrCheckGuard(regFragPtr, cfragmentsize, fragmentrec);
- verifyFragCorrect(regFragPtr);
- if (regFragPtr.p->directory != RNIL) {
- jam();
- releaseDirResources(signal, regFragPtr.i, regFragPtr.p->directory, 0);
- regFragPtr.p->directory = RNIL;
- } else if (regFragPtr.p->overflowdir != RNIL) {
- jam();
- releaseDirResources(signal, regFragPtr.i, regFragPtr.p->overflowdir, 0);
- regFragPtr.p->overflowdir = RNIL;
- } else if (regFragPtr.p->firstOverflowRec != RNIL) {
- jam();
- releaseOverflowResources(signal, regFragPtr);
- } else if (regFragPtr.p->firstFreeDirindexRec != RNIL) {
- jam();
- releaseDirIndexResources(signal, regFragPtr);
- } else {
- jam();
- Uint32 tab = regFragPtr.p->mytabptr;
- releaseFragRecord(signal, regFragPtr);
- signal->theData[0] = ZREL_ROOT_FRAG;
- signal->theData[1] = tab;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
-}//Dbacc::releaseFragResources()
-
-void Dbacc::verifyFragCorrect(FragmentrecPtr regFragPtr)
-{
- ndbrequire(regFragPtr.p->lockOwnersList == RNIL);
-}//Dbacc::verifyFragCorrect()
-
-void Dbacc::releaseDirResources(Signal* signal,
- Uint32 fragIndex,
- Uint32 dirIndex,
- Uint32 startIndex)
-{
- DirRangePtr regDirRangePtr;
- regDirRangePtr.i = dirIndex;
- ptrCheckGuard(regDirRangePtr, cdirrangesize, dirRange);
- for (Uint32 i = startIndex; i < 256; i++) {
- jam();
- if (regDirRangePtr.p->dirArray[i] != RNIL) {
- jam();
- Uint32 directoryIndex = regDirRangePtr.p->dirArray[i];
- regDirRangePtr.p->dirArray[i] = RNIL;
- releaseDirectoryResources(signal, fragIndex, dirIndex, (i + 1), directoryIndex);
- return;
- }//if
- }//for
- rdDirRangePtr = regDirRangePtr;
- releaseDirrange(signal);
- signal->theData[0] = ZREL_FRAG;
- signal->theData[1] = fragIndex;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
-}//Dbacc::releaseDirResources()
-
-void Dbacc::releaseDirectoryResources(Signal* signal,
- Uint32 fragIndex,
- Uint32 dirIndex,
- Uint32 startIndex,
- Uint32 directoryIndex)
-{
- DirectoryarrayPtr regDirPtr;
- regDirPtr.i = directoryIndex;
- ptrCheckGuard(regDirPtr, cdirarraysize, directoryarray);
- for (Uint32 i = 0; i < 256; i++) {
- jam();
- if (regDirPtr.p->pagep[i] != RNIL) {
- jam();
- rpPageptr.i = regDirPtr.p->pagep[i];
- ptrCheckGuard(rpPageptr, cpagesize, page8);
- releasePage(signal);
- regDirPtr.p->pagep[i] = RNIL;
- }//if
- }//for
- rdDirptr = regDirPtr;
- releaseDirectory(signal);
- signal->theData[0] = ZREL_DIR;
- signal->theData[1] = fragIndex;
- signal->theData[2] = dirIndex;
- signal->theData[3] = startIndex;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 4, JBB);
-}//Dbacc::releaseDirectoryResources()
-
-void Dbacc::releaseOverflowResources(Signal* signal, FragmentrecPtr regFragPtr)
-{
- Uint32 loopCount = 0;
- OverflowRecordPtr regOverflowRecPtr;
- while ((regFragPtr.p->firstOverflowRec != RNIL) &&
- (loopCount < 1)) {
- jam();
- regOverflowRecPtr.i = regFragPtr.p->firstOverflowRec;
- ptrCheckGuard(regOverflowRecPtr, coverflowrecsize, overflowRecord);
- regFragPtr.p->firstOverflowRec = regOverflowRecPtr.p->nextOverRec;
- rorOverflowRecPtr = regOverflowRecPtr;
- releaseOverflowRec(signal);
- loopCount++;
- }//while
- signal->theData[0] = ZREL_FRAG;
- signal->theData[1] = regFragPtr.i;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
-}//Dbacc::releaseOverflowResources()
-
-void Dbacc::releaseDirIndexResources(Signal* signal, FragmentrecPtr regFragPtr)
-{
- Uint32 loopCount = 0;
- OverflowRecordPtr regOverflowRecPtr;
- while ((regFragPtr.p->firstFreeDirindexRec != RNIL) &&
- (loopCount < 1)) {
- jam();
- regOverflowRecPtr.i = regFragPtr.p->firstFreeDirindexRec;
- ptrCheckGuard(regOverflowRecPtr, coverflowrecsize, overflowRecord);
- regFragPtr.p->firstFreeDirindexRec = regOverflowRecPtr.p->nextOverList;
- rorOverflowRecPtr = regOverflowRecPtr;
- releaseOverflowRec(signal);
- loopCount++;
- }//while
- signal->theData[0] = ZREL_FRAG;
- signal->theData[1] = regFragPtr.i;
- sendSignal(cownBlockref, GSN_CONTINUEB, signal, 2, JBB);
-}//Dbacc::releaseDirIndexResources()
-
-void Dbacc::releaseFragRecord(Signal* signal, FragmentrecPtr regFragPtr)
-{
- regFragPtr.p->nextfreefrag = cfirstfreefrag;
- cfirstfreefrag = regFragPtr.i;
- initFragGeneral(regFragPtr);
-}//Dbacc::releaseFragRecord()
-
-/* -------------------------------------------------------------------------- */
-/* ADDFRAGTOTAB */
-/* DESCRIPTION: PUTS A FRAGMENT ID AND A POINTER TO ITS RECORD INTO */
-/* TABLE ARRRAY OF THE TABLE RECORD. */
-/* -------------------------------------------------------------------------- */
-bool Dbacc::addfragtotab(Signal* signal, Uint32 rootIndex, Uint32 fid)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragholder[i] == RNIL) {
- jam();
- tabptr.p->fragholder[i] = fid;
- tabptr.p->fragptrholder[i] = rootIndex;
- return true;
- }//if
- }//for
- return false;
-}//Dbacc::addfragtotab()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF ADD/DELETE FRAGMENT MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* CONNECTION MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* ACCSEIZEREQ SEIZE REQ */
-/* SENDER: LQH, LEVEL B */
-/* ENTER ACCSEIZEREQ WITH */
-/* TUSERPTR , CONECTION PTR OF LQH */
-/* TUSERBLOCKREF BLOCK REFERENCE OF LQH */
-/* ******************--------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* ACCSEIZEREQ SEIZE REQ */
-/* ******************------------------------------+ */
-/* SENDER: LQH, LEVEL B */
-void Dbacc::execACCSEIZEREQ(Signal* signal)
-{
- jamEntry();
- tuserptr = signal->theData[0];
- /* CONECTION PTR OF LQH */
- tuserblockref = signal->theData[1];
- /* BLOCK REFERENCE OF LQH */
- tresult = 0;
- if (cfreeopRec == RNIL) {
- jam();
- refaccConnectLab(signal);
- return;
- }//if
- seizeOpRec(signal);
- ptrGuard(operationRecPtr);
- operationRecPtr.p->userptr = tuserptr;
- operationRecPtr.p->userblockref = tuserblockref;
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- /* ******************************< */
- /* ACCSEIZECONF */
- /* ******************************< */
- signal->theData[0] = tuserptr;
- signal->theData[1] = operationRecPtr.i;
- sendSignal(tuserblockref, GSN_ACCSEIZECONF, signal, 2, JBB);
- return;
-}//Dbacc::execACCSEIZEREQ()
-
-void Dbacc::refaccConnectLab(Signal* signal)
-{
- tresult = ZCONNECT_SIZE_ERROR;
- /* ******************************< */
- /* ACCSEIZEREF */
- /* ******************************< */
- signal->theData[0] = tuserptr;
- signal->theData[1] = tresult;
- sendSignal(tuserblockref, GSN_ACCSEIZEREF, signal, 2, JBB);
- return;
-}//Dbacc::refaccConnectLab()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF CONNECTION MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* EXECUTE OPERATION MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* INIT_OP_REC */
-/* INFORMATION WHICH IS RECIEVED BY ACCKEYREQ WILL BE SAVED */
-/* IN THE OPERATION RECORD. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initOpRec(Signal* signal)
-{
- register Uint32 Treqinfo;
-
- Treqinfo = signal->theData[2];
-
- operationRecPtr.p->hashValue = signal->theData[3];
- operationRecPtr.p->tupkeylen = signal->theData[4];
- operationRecPtr.p->xfrmtupkeylen = signal->theData[4];
- operationRecPtr.p->transId1 = signal->theData[5];
- operationRecPtr.p->transId2 = signal->theData[6];
-
- Uint32 readFlag = (((Treqinfo >> 4) & 0x3) == 0); // Only 1 if Read
- Uint32 dirtyFlag = (((Treqinfo >> 6) & 0x1) == 1); // Only 1 if Dirty
- Uint32 dirtyReadFlag = readFlag & dirtyFlag;
-
- Uint32 opbits = 0;
- opbits |= Treqinfo & 0x7;
- opbits |= ((Treqinfo >> 4) & 0x3) ? (Uint32) Operationrec::OP_LOCK_MODE : 0;
- opbits |= ((Treqinfo >> 4) & 0x3) ? (Uint32) Operationrec::OP_ACC_LOCK_MODE : 0;
- opbits |= (dirtyReadFlag) ? (Uint32) Operationrec::OP_DIRTY_READ : 0;
- opbits |= ((Treqinfo >> 31) & 0x1) ? (Uint32) Operationrec::OP_LOCK_REQ : 0;
-
- //operationRecPtr.p->nodeType = (Treqinfo >> 7) & 0x3;
- operationRecPtr.p->fid = fragrecptr.p->myfid;
- operationRecPtr.p->fragptr = fragrecptr.i;
- operationRecPtr.p->nextParallelQue = RNIL;
- operationRecPtr.p->prevParallelQue = RNIL;
- operationRecPtr.p->nextSerialQue = RNIL;
- operationRecPtr.p->prevSerialQue = RNIL;
- operationRecPtr.p->elementPage = RNIL;
- operationRecPtr.p->scanRecPtr = RNIL;
- operationRecPtr.p->m_op_bits = opbits;
-
- // bit to mark lock operation
- // undo log is not run via ACCKEYREQ
-
-}//Dbacc::initOpRec()
-
-/* --------------------------------------------------------------------------------- */
-/* SEND_ACCKEYCONF */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::sendAcckeyconf(Signal* signal)
-{
- signal->theData[0] = operationRecPtr.p->userptr;
- signal->theData[1] = operationRecPtr.p->m_op_bits & Operationrec::OP_MASK;
- signal->theData[2] = operationRecPtr.p->fid;
- signal->theData[3] = operationRecPtr.p->localdata[0];
- signal->theData[4] = operationRecPtr.p->localdata[1];
- signal->theData[5] = fragrecptr.p->localkeylen;
-}//Dbacc::sendAcckeyconf()
-
-
-void
-Dbacc::ACCKEY_error(Uint32 fromWhere)
-{
- switch(fromWhere) {
- case 0:
- ndbrequire(false);
- case 1:
- ndbrequire(false);
- case 2:
- ndbrequire(false);
- case 3:
- ndbrequire(false);
- case 4:
- ndbrequire(false);
- case 5:
- ndbrequire(false);
- case 6:
- ndbrequire(false);
- case 7:
- ndbrequire(false);
- case 8:
- ndbrequire(false);
- case 9:
- ndbrequire(false);
- default:
- ndbrequire(false);
- }//switch
-}//Dbacc::ACCKEY_error()
-
-/* ******************--------------------------------------------------------------- */
-/* ACCKEYREQ REQUEST FOR INSERT, DELETE, */
-/* RERAD AND UPDATE, A TUPLE. */
-/* SENDER: LQH, LEVEL B */
-/* SIGNAL DATA: OPERATION_REC_PTR, CONNECTION PTR */
-/* TABPTR, TABLE ID = TABLE RECORD POINTER */
-/* TREQINFO, */
-/* THASHVALUE, HASH VALUE OF THE TUP */
-/* TKEYLEN, LENGTH OF THE PRIMARY KEYS */
-/* TKEY1, PRIMARY KEY 1 */
-/* TKEY2, PRIMARY KEY 2 */
-/* TKEY3, PRIMARY KEY 3 */
-/* TKEY4, PRIMARY KEY 4 */
-/* ******************--------------------------------------------------------------- */
-void Dbacc::execACCKEYREQ(Signal* signal)
-{
- jamEntry();
- operationRecPtr.i = signal->theData[0]; /* CONNECTION PTR */
- fragrecptr.i = signal->theData[1]; /* FRAGMENT RECORD POINTER */
- if (!((operationRecPtr.i < coprecsize) ||
- (fragrecptr.i < cfragmentsize))) {
- ACCKEY_error(0);
- return;
- }//if
- ptrAss(operationRecPtr, operationrec);
- ptrAss(fragrecptr, fragmentrec);
-
- ndbrequire(operationRecPtr.p->m_op_bits == Operationrec::OP_INITIAL);
-
- initOpRec(signal);
- // normalize key if any char attr
- if (operationRecPtr.p->tupkeylen && fragrecptr.p->hasCharAttr)
- xfrmKeyData(signal);
-
- /*---------------------------------------------------------------*/
- /* */
- /* WE WILL USE THE HASH VALUE TO LOOK UP THE PROPER MEMORY */
- /* PAGE AND MEMORY PAGE INDEX TO START THE SEARCH WITHIN. */
- /* WE REMEMBER THESE ADDRESS IF WE LATER NEED TO INSERT */
- /* THE ITEM AFTER NOT FINDING THE ITEM. */
- /*---------------------------------------------------------------*/
- OperationrecPtr lockOwnerPtr;
- const Uint32 found = getElement(signal, lockOwnerPtr);
-
- Uint32 opbits = operationRecPtr.p->m_op_bits;
- Uint32 op = opbits & Operationrec::OP_MASK;
- if (found == ZTRUE)
- {
- switch (op) {
- case ZREAD:
- case ZUPDATE:
- case ZDELETE:
- case ZWRITE:
- case ZSCAN_OP:
- if (!lockOwnerPtr.p)
- {
- if(op == ZWRITE)
- {
- jam();
- opbits &= ~(Uint32)Operationrec::OP_MASK;
- opbits |= (op = ZUPDATE);
- operationRecPtr.p->m_op_bits = opbits; // store to get correct ACCKEYCONF
- }
- opbits |= Operationrec::OP_STATE_RUNNING;
- opbits |= Operationrec::OP_RUN_QUEUE;
- sendAcckeyconf(signal);
- if (! (opbits & Operationrec::OP_DIRTY_READ)) {
- /*---------------------------------------------------------------*/
- // It is not a dirty read. We proceed by locking and continue with
- // the operation.
- /*---------------------------------------------------------------*/
- Uint32 eh = gePageptr.p->word32[tgeElementptr];
- operationRecPtr.p->scanBits = ElementHeader::getScanBits(eh);
- operationRecPtr.p->hashvaluePart = ElementHeader::getHashValuePart(eh);
- operationRecPtr.p->elementPage = gePageptr.i;
- operationRecPtr.p->elementContainer = tgeContainerptr;
- operationRecPtr.p->elementPointer = tgeElementptr;
- operationRecPtr.p->elementIsforward = tgeForward;
-
- eh = ElementHeader::setLocked(operationRecPtr.i);
- dbgWord32(gePageptr, tgeElementptr, eh);
- gePageptr.p->word32[tgeElementptr] = eh;
-
- opbits |= Operationrec::OP_LOCK_OWNER;
- insertLockOwnersList(signal, operationRecPtr);
- } else {
- jam();
- /*---------------------------------------------------------------*/
- // It is a dirty read. We do not lock anything. Set state to
- // IDLE since no COMMIT call will come.
- /*---------------------------------------------------------------*/
- opbits = Operationrec::OP_EXECUTED_DIRTY_READ;
- }//if
- operationRecPtr.p->m_op_bits = opbits;
- return;
- } else {
- jam();
- accIsLockedLab(signal, lockOwnerPtr);
- return;
- }//if
- break;
- case ZINSERT:
- jam();
- insertExistElemLab(signal, lockOwnerPtr);
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- } else if (found == ZFALSE) {
- switch (op){
- case ZWRITE:
- opbits &= ~(Uint32)Operationrec::OP_MASK;
- opbits |= (op = ZINSERT);
- case ZINSERT:
- jam();
- opbits |= Operationrec::OP_INSERT_IS_DONE;
- opbits |= Operationrec::OP_STATE_RUNNING;
- opbits |= Operationrec::OP_RUN_QUEUE;
- operationRecPtr.p->m_op_bits = opbits;
- insertelementLab(signal);
- return;
- break;
- case ZREAD:
- case ZUPDATE:
- case ZDELETE:
- case ZSCAN_OP:
- jam();
- acckeyref1Lab(signal, ZREAD_ERROR);
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- } else {
- jam();
- acckeyref1Lab(signal, found);
- return;
- }//if
- return;
-}//Dbacc::execACCKEYREQ()
-
-void
-Dbacc::execACCKEY_ORD(Signal* signal, Uint32 opPtrI)
-{
- jamEntry();
- OperationrecPtr lastOp;
- lastOp.i = opPtrI;
- ptrCheckGuard(lastOp, coprecsize, operationrec);
- Uint32 opbits = lastOp.p->m_op_bits;
- Uint32 opstate = opbits & Operationrec::OP_STATE_MASK;
-
- if (likely(opbits == Operationrec::OP_EXECUTED_DIRTY_READ))
- {
- jam();
- lastOp.p->m_op_bits = Operationrec::OP_INITIAL;
- return;
- }
- else if (likely(opstate == Operationrec::OP_STATE_RUNNING))
- {
- opbits |= Operationrec::OP_STATE_EXECUTED;
- lastOp.p->m_op_bits = opbits;
- startNext(signal, lastOp);
- return;
- }
- else
- {
- }
-
- ndbout_c("bits: %.8x state: %.8x", opbits, opstate);
- ndbrequire(false);
-}
-
-void
-Dbacc::startNext(Signal* signal, OperationrecPtr lastOp)
-{
- jam();
- OperationrecPtr nextOp;
- OperationrecPtr loPtr;
- nextOp.i = lastOp.p->nextParallelQue;
- loPtr.i = lastOp.p->m_lock_owner_ptr_i;
- Uint32 opbits = lastOp.p->m_op_bits;
-
- if ((opbits & Operationrec::OP_STATE_MASK)!= Operationrec::OP_STATE_EXECUTED)
- {
- jam();
- return;
- }
-
- Uint32 nextbits;
- if (nextOp.i != RNIL)
- {
- jam();
- ptrCheckGuard(nextOp, coprecsize, operationrec);
- nextbits = nextOp.p->m_op_bits;
- goto checkop;
- }
-
- if ((opbits & Operationrec::OP_LOCK_OWNER) == 0)
- {
- jam();
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
- else
- {
- jam();
- loPtr = lastOp;
- }
-
- nextOp.i = loPtr.p->nextSerialQue;
- ndbassert(loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
-
- if (nextOp.i == RNIL)
- {
- jam();
- return;
- }
-
- /**
- * There is an op in serie queue...
- * Check if it can run
- */
- ptrCheckGuard(nextOp, coprecsize, operationrec);
- nextbits = nextOp.p->m_op_bits;
-
- {
- const bool same = nextOp.p->is_same_trans(lastOp.p);
-
- if (!same && ((opbits & Operationrec::OP_ACC_LOCK_MODE) ||
- (nextbits & Operationrec::OP_LOCK_MODE)))
- {
- jam();
- /**
- * Not same transaction
- * and either last had exclusive lock
- * or next had exclusive lock
- */
- return;
- }
-
- /**
- * same trans and X-lock
- */
- if (same && (opbits & Operationrec::OP_ACC_LOCK_MODE))
- {
- jam();
- goto upgrade;
- }
- }
-
- /**
- * all shared lock...
- */
- if ((opbits & Operationrec::OP_ACC_LOCK_MODE) == 0 &&
- (nextbits & Operationrec::OP_LOCK_MODE) == 0)
- {
- jam();
- goto upgrade;
- }
-
- /**
- * There is a shared parallell queue & and exclusive op is first in queue
- */
- ndbassert((opbits & Operationrec::OP_ACC_LOCK_MODE) == 0 &&
- (nextbits & Operationrec::OP_LOCK_MODE));
-
- /**
- * We must check if there are many transactions in parallel queue...
- */
- OperationrecPtr tmp;
- tmp= loPtr;
- while (tmp.i != RNIL)
- {
- ptrCheckGuard(tmp, coprecsize, operationrec);
- if (!nextOp.p->is_same_trans(tmp.p))
- {
- jam();
- /**
- * parallel queue contained another transaction, dont let it run
- */
- return;
- }
- tmp.i = tmp.p->nextParallelQue;
- }
-
-upgrade:
- /**
- * Move first op in serie queue to end of parallell queue
- */
-
- tmp.i = loPtr.p->nextSerialQue = nextOp.p->nextSerialQue;
- loPtr.p->m_lo_last_parallel_op_ptr_i = nextOp.i;
- nextOp.p->nextSerialQue = RNIL;
- nextOp.p->prevSerialQue = RNIL;
- nextOp.p->m_lock_owner_ptr_i = loPtr.i;
- nextOp.p->prevParallelQue = lastOp.i;
- lastOp.p->nextParallelQue = nextOp.i;
-
- if (tmp.i != RNIL)
- {
- jam();
- ptrCheckGuard(tmp, coprecsize, operationrec);
- tmp.p->prevSerialQue = loPtr.i;
- }
- else
- {
- jam();
- loPtr.p->m_lo_last_serial_op_ptr_i = RNIL;
- }
-
- nextbits |= Operationrec::OP_RUN_QUEUE;
-
- /**
- * Currently no grouping of ops in serie queue
- */
- ndbrequire(nextOp.p->nextParallelQue == RNIL);
-
-checkop:
- Uint32 errCode = 0;
- OperationrecPtr save = operationRecPtr;
- operationRecPtr = nextOp;
-
- Uint32 lastop = opbits & Operationrec::OP_MASK;
- Uint32 nextop = nextbits & Operationrec::OP_MASK;
-
- nextbits &= nextbits & ~(Uint32)Operationrec::OP_STATE_MASK;
- nextbits |= Operationrec::OP_STATE_RUNNING;
-
- if (lastop == ZDELETE)
- {
- jam();
- if (nextop != ZINSERT && nextop != ZWRITE)
- {
- errCode = ZREAD_ERROR;
- goto ref;
- }
-
- nextbits &= ~(Uint32)Operationrec::OP_MASK;
- nextbits &= ~(Uint32)Operationrec::OP_ELEMENT_DISAPPEARED;
- nextbits |= (nextop = ZINSERT);
- nextbits |= Operationrec::OP_INSERT_IS_DONE;
- goto conf;
- }
- else if (nextop == ZINSERT)
- {
- jam();
- errCode = ZWRITE_ERROR;
- goto ref;
- }
- else if (nextop == ZWRITE)
- {
- jam();
- nextbits &= ~(Uint32)Operationrec::OP_MASK;
- nextbits |= (nextop = ZUPDATE);
- goto conf;
- }
- else
- {
- jam();
- }
-
-conf:
- nextOp.p->m_op_bits = nextbits;
- nextOp.p->localdata[0] = lastOp.p->localdata[0];
- nextOp.p->localdata[1] = lastOp.p->localdata[1];
-
- if (nextop == ZSCAN_OP && (nextbits & Operationrec::OP_LOCK_REQ) == 0)
- {
- jam();
- takeOutScanLockQueue(nextOp.p->scanRecPtr);
- putReadyScanQueue(signal, nextOp.p->scanRecPtr);
- }
- else
- {
- jam();
- fragrecptr.i = nextOp.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
-
- sendAcckeyconf(signal);
- sendSignal(nextOp.p->userblockref, GSN_ACCKEYCONF,
- signal, 6, JBB);
- }
-
- operationRecPtr = save;
- return;
-
-ref:
- nextOp.p->m_op_bits = nextbits;
-
- if (nextop == ZSCAN_OP && (nextbits & Operationrec::OP_LOCK_REQ) == 0)
- {
- jam();
- nextOp.p->m_op_bits |= Operationrec::OP_ELEMENT_DISAPPEARED;
- takeOutScanLockQueue(nextOp.p->scanRecPtr);
- putReadyScanQueue(signal, nextOp.p->scanRecPtr);
- }
- else
- {
- jam();
- signal->theData[0] = nextOp.p->userptr;
- signal->theData[1] = errCode;
- sendSignal(nextOp.p->userblockref, GSN_ACCKEYREF, signal,
- 2, JBB);
- }
-
- operationRecPtr = save;
- return;
-}
-
-
-#if 0
-void
-Dbacc::execACCKEY_REP_REF(Signal* signal, Uint32 opPtrI)
-{
-}
-#endif
-
-void
-Dbacc::xfrmKeyData(Signal* signal)
-{
- Uint32 table = fragrecptr.p->myTableId;
- Uint32 dst[MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
- Uint32* src = &signal->theData[7];
- Uint32 len = xfrm_key(table, src, dst, sizeof(dst) >> 2, keyPartLen);
- ndbrequire(len); // 0 means error
- memcpy(src, dst, len << 2);
- operationRecPtr.p->xfrmtupkeylen = len;
-}
-
-void
-Dbacc::accIsLockedLab(Signal* signal, OperationrecPtr lockOwnerPtr)
-{
- ndbrequire(csystemRestart == ZFALSE);
-
- Uint32 bits = operationRecPtr.p->m_op_bits;
- validate_lock_queue(lockOwnerPtr);
-
- if ((bits & Operationrec::OP_DIRTY_READ) == 0){
- Uint32 return_result;
- if ((bits & Operationrec::OP_LOCK_MODE) == ZREADLOCK) {
- jam();
- return_result = placeReadInLockQueue(lockOwnerPtr);
- } else {
- jam();
- return_result = placeWriteInLockQueue(lockOwnerPtr);
- }//if
- if (return_result == ZPARALLEL_QUEUE) {
- jam();
- sendAcckeyconf(signal);
- return;
- } else if (return_result == ZSERIAL_QUEUE) {
- jam();
- signal->theData[0] = RNIL;
- return;
- } else {
- jam();
- acckeyref1Lab(signal, return_result);
- return;
- }//if
- ndbrequire(false);
- }
- else
- {
- if (!(lockOwnerPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED) &&
- lockOwnerPtr.p->localdata[0] != ~(Uint32)0)
- {
- jam();
- /* ---------------------------------------------------------------
- * It is a dirty read. We do not lock anything. Set state to
- *IDLE since no COMMIT call will arrive.
- * ---------------------------------------------------------------*/
- sendAcckeyconf(signal);
- operationRecPtr.p->m_op_bits = Operationrec::OP_EXECUTED_DIRTY_READ;
- return;
- }
- else
- {
- jam();
- /*---------------------------------------------------------------*/
- // The tuple does not exist in the committed world currently.
- // Report read error.
- /*---------------------------------------------------------------*/
- acckeyref1Lab(signal, ZREAD_ERROR);
- return;
- }//if
- }//if
-}//Dbacc::accIsLockedLab()
-
-/* ------------------------------------------------------------------------ */
-/* I N S E R T E X I S T E L E M E N T */
-/* ------------------------------------------------------------------------ */
-void Dbacc::insertExistElemLab(Signal* signal, OperationrecPtr lockOwnerPtr)
-{
- if (!lockOwnerPtr.p)
- {
- jam();
- acckeyref1Lab(signal, ZWRITE_ERROR);/* THE ELEMENT ALREADY EXIST */
- return;
- }//if
- accIsLockedLab(signal, lockOwnerPtr);
-}//Dbacc::insertExistElemLab()
-
-/* --------------------------------------------------------------------------------- */
-/* INSERTELEMENT */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::insertelementLab(Signal* signal)
-{
- if (fragrecptr.p->firstOverflowRec == RNIL) {
- jam();
- allocOverflowPage(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- acckeyref1Lab(signal, tresult);
- return;
- }//if
- }//if
- ndbrequire(operationRecPtr.p->tupkeylen <= fragrecptr.p->keyLength);
- ndbassert(!(operationRecPtr.p->m_op_bits & Operationrec::OP_LOCK_REQ));
- Uint32 localKey = ~(Uint32)0;
-
- insertLockOwnersList(signal, operationRecPtr);
-
- const Uint32 tmp = fragrecptr.p->k + fragrecptr.p->lhfragbits;
- operationRecPtr.p->hashvaluePart =
- (operationRecPtr.p->hashValue >> tmp) & 0xFFFF;
- operationRecPtr.p->scanBits = 0; /* NOT ANY ACTIVE SCAN */
- tidrElemhead = ElementHeader::setLocked(operationRecPtr.i);
- idrPageptr = gdiPageptr;
- tidrPageindex = tgdiPageindex;
- tidrForward = ZTRUE;
- idrOperationRecPtr = operationRecPtr;
- clocalkey[0] = localKey;
- operationRecPtr.p->localdata[0] = localKey;
- /* ----------------------------------------------------------------------- */
- /* WE SET THE LOCAL KEY TO MINUS ONE TO INDICATE IT IS NOT YET VALID. */
- /* ----------------------------------------------------------------------- */
- insertElement(signal);
- sendAcckeyconf(signal);
- return;
-}//Dbacc::insertelementLab()
-
-
-/* ------------------------------------------------------------------------ */
-/* GET_NO_PARALLEL_TRANSACTION */
-/* ------------------------------------------------------------------------ */
-Uint32
-Dbacc::getNoParallelTransaction(const Operationrec * op)
-{
- OperationrecPtr tmp;
-
- tmp.i= op->nextParallelQue;
- Uint32 transId[2] = { op->transId1, op->transId2 };
- while (tmp.i != RNIL)
- {
- jam();
- ptrCheckGuard(tmp, coprecsize, operationrec);
- if (tmp.p->transId1 == transId[0] && tmp.p->transId2 == transId[1])
- tmp.i = tmp.p->nextParallelQue;
- else
- return 2;
- }
- return 1;
-}//Dbacc::getNoParallelTransaction()
-
-#ifdef VM_TRACE
-Uint32
-Dbacc::getNoParallelTransactionFull(const Operationrec * op)
-{
- ConstPtr<Operationrec> tmp;
-
- tmp.p = op;
- while ((tmp.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0)
- {
- tmp.i = tmp.p->prevParallelQue;
- if (tmp.i != RNIL)
- {
- ptrCheckGuard(tmp, coprecsize, operationrec);
- }
- else
- {
- break;
- }
- }
-
- return getNoParallelTransaction(tmp.p);
-}
-#endif
-
-#ifdef ACC_SAFE_QUEUE
-
-Uint32
-Dbacc::get_parallel_head(OperationrecPtr opPtr)
-{
- while ((opPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0 &&
- opPtr.p->prevParallelQue != RNIL)
- {
- opPtr.i = opPtr.p->prevParallelQue;
- ptrCheckGuard(opPtr, coprecsize, operationrec);
- }
-
- return opPtr.i;
-}
-
-bool
-Dbacc::validate_lock_queue(OperationrecPtr opPtr)
-{
- OperationrecPtr loPtr;
- loPtr.i = get_parallel_head(opPtr);
- ptrCheckGuard(loPtr, coprecsize, operationrec);
-
- while((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0 &&
- loPtr.p->prevSerialQue != RNIL)
- {
- loPtr.i = loPtr.p->prevSerialQue;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
-
- // Now we have lock owner...
- vlqrequire(loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- vlqrequire(loPtr.p->m_op_bits & Operationrec::OP_RUN_QUEUE);
-
- // 1 Validate page pointer
- {
- Page8Ptr pagePtr;
- pagePtr.i = loPtr.p->elementPage;
- ptrCheckGuard(pagePtr, cpagesize, page8);
- arrGuard(loPtr.p->elementPointer, 2048);
- Uint32 eh = pagePtr.p->word32[loPtr.p->elementPointer];
- vlqrequire(ElementHeader::getLocked(eh));
- vlqrequire(ElementHeader::getOpPtrI(eh) == loPtr.i);
- }
-
- // 2 Lock owner should always have same LOCK_MODE and ACC_LOCK_MODE
- if (loPtr.p->m_op_bits & Operationrec::OP_LOCK_MODE)
- {
- vlqrequire(loPtr.p->m_op_bits & Operationrec::OP_ACC_LOCK_MODE);
- }
- else
- {
- vlqrequire((loPtr.p->m_op_bits & Operationrec::OP_ACC_LOCK_MODE) == 0);
- }
-
- // 3 Lock owner should never be waiting...
- bool running = false;
- {
- Uint32 opstate = loPtr.p->m_op_bits & Operationrec::OP_STATE_MASK;
- if (opstate == Operationrec::OP_STATE_RUNNING)
- running = true;
- else
- {
- vlqrequire(opstate == Operationrec::OP_STATE_EXECUTED);
- }
- }
-
- // Validate parallel queue
- {
- bool many = false;
- bool orlockmode = loPtr.p->m_op_bits & Operationrec::OP_LOCK_MODE;
- OperationrecPtr lastP = loPtr;
-
- while (lastP.p->nextParallelQue != RNIL)
- {
- Uint32 prev = lastP.i;
- lastP.i = lastP.p->nextParallelQue;
- ptrCheckGuard(lastP, coprecsize, operationrec);
-
- vlqrequire(lastP.p->prevParallelQue == prev);
-
- Uint32 opbits = lastP.p->m_op_bits;
- many |= loPtr.p->is_same_trans(lastP.p) ? 0 : 1;
- orlockmode |= !!(opbits & Operationrec::OP_LOCK_MODE);
-
- vlqrequire(opbits & Operationrec::OP_RUN_QUEUE);
- vlqrequire((opbits & Operationrec::OP_LOCK_OWNER) == 0);
-
- Uint32 opstate = opbits & Operationrec::OP_STATE_MASK;
- if (running)
- {
- // If I found a running operation,
- // all following should be waiting
- vlqrequire(opstate == Operationrec::OP_STATE_WAITING);
- }
- else
- {
- if (opstate == Operationrec::OP_STATE_RUNNING)
- running = true;
- else
- vlqrequire(opstate == Operationrec::OP_STATE_EXECUTED);
- }
-
- if (lastP.p->m_op_bits & Operationrec::OP_LOCK_MODE)
- {
- vlqrequire(lastP.p->m_op_bits & Operationrec::OP_ACC_LOCK_MODE);
- }
- else
- {
- vlqrequire((lastP.p->m_op_bits && orlockmode) == orlockmode);
- vlqrequire((lastP.p->m_op_bits & Operationrec::OP_MASK) == ZREAD ||
- (lastP.p->m_op_bits & Operationrec::OP_MASK) == ZSCAN_OP);
- }
-
- if (many)
- {
- vlqrequire(orlockmode == 0);
- }
- }
-
- if (lastP.i != loPtr.i)
- {
- vlqrequire(loPtr.p->m_lo_last_parallel_op_ptr_i == lastP.i);
- vlqrequire(lastP.p->m_lock_owner_ptr_i == loPtr.i);
- }
- else
- {
- vlqrequire(loPtr.p->m_lo_last_parallel_op_ptr_i == RNIL);
- }
- }
-
- // Validate serie queue
- if (loPtr.p->nextSerialQue != RNIL)
- {
- Uint32 prev = loPtr.i;
- OperationrecPtr lastS;
- lastS.i = loPtr.p->nextSerialQue;
- while (true)
- {
- ptrCheckGuard(lastS, coprecsize, operationrec);
- vlqrequire(lastS.p->prevSerialQue == prev);
- vlqrequire(getNoParallelTransaction(lastS.p) == 1);
- vlqrequire((lastS.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0);
- vlqrequire((lastS.p->m_op_bits & Operationrec::OP_RUN_QUEUE) == 0);
- vlqrequire((lastS.p->m_op_bits & Operationrec::OP_STATE_MASK) == Operationrec::OP_STATE_WAITING);
- if (lastS.p->nextSerialQue == RNIL)
- break;
- prev = lastS.i;
- lastS.i = lastS.p->nextSerialQue;
- }
-
- vlqrequire(loPtr.p->m_lo_last_serial_op_ptr_i == lastS.i);
- }
- else
- {
- vlqrequire(loPtr.p->m_lo_last_serial_op_ptr_i == RNIL);
- }
- return true;
-}
-
-NdbOut&
-operator<<(NdbOut & out, Dbacc::OperationrecPtr ptr)
-{
- Uint32 opbits = ptr.p->m_op_bits;
- out << "[ " << dec << ptr.i
- << " [ " << hex << ptr.p->transId1
- << " " << hex << ptr.p->transId2 << "] "
- << " bits: H'" << hex << opbits << " ";
-
- bool read = false;
- switch(opbits & Dbacc::Operationrec::OP_MASK){
- case ZREAD: out << "READ "; read = true; break;
- case ZINSERT: out << "INSERT "; break;
- case ZUPDATE: out << "UPDATE "; break;
- case ZDELETE: out << "DELETE "; break;
- case ZWRITE: out << "WRITE "; break;
- case ZSCAN_OP: out << "SCAN "; read = true; break;
- default:
- out << "<Unknown: H'"
- << hex << (opbits & Dbacc::Operationrec::OP_MASK)
- << "> ";
- }
-
- if (read)
- {
- if (opbits & Dbacc::Operationrec::OP_LOCK_MODE)
- out << "(X)";
- else
- out << "(S)";
- if (opbits & Dbacc::Operationrec::OP_ACC_LOCK_MODE)
- out << "(X)";
- else
- out << "(S)";
- }
-
- if (opbits)
- {
- out << "(RQ)";
- }
-
- switch(opbits & Dbacc::Operationrec::OP_STATE_MASK){
- case Dbacc::Operationrec::OP_STATE_WAITING:
- out << " WAITING "; break;
- case Dbacc::Operationrec::OP_STATE_RUNNING:
- out << " RUNNING "; break;
- case Dbacc::Operationrec::OP_STATE_EXECUTED:
- out << " EXECUTED "; break;
- case Dbacc::Operationrec::OP_STATE_IDLE:
- out << " IDLE "; break;
- default:
- out << " <Unknown: H'"
- << hex << (opbits & Dbacc::Operationrec::OP_STATE_MASK)
- << "> ";
- }
-
-/*
- OP_MASK = 0x000F // 4 bits for operation type
- ,OP_LOCK_MODE = 0x0010 // 0 - shared lock, 1 = exclusive lock
- ,OP_ACC_LOCK_MODE = 0x0020 // Or:de lock mode of all operation
- // before me
- ,OP_LOCK_OWNER = 0x0040
- ,OP_DIRTY_READ = 0x0080
- ,OP_LOCK_REQ = 0x0100 // isAccLockReq
- ,OP_COMMIT_DELETE_CHECK = 0x0200
- ,OP_INSERT_IS_DONE = 0x0400
- ,OP_ELEMENT_DISAPPEARED = 0x0800
-
- ,OP_STATE_MASK = 0xF000
- ,OP_STATE_IDLE = 0xF000
- ,OP_STATE_WAITING = 0x0000
- ,OP_STATE_RUNNING = 0x1000
- ,OP_STATE_EXECUTED = 0x3000
- };
-*/
- if (opbits & Dbacc::Operationrec::OP_LOCK_OWNER)
- out << "LO ";
-
- if (opbits & Dbacc::Operationrec::OP_DIRTY_READ)
- out << "DR ";
-
- if (opbits & Dbacc::Operationrec::OP_LOCK_REQ)
- out << "LOCK_REQ ";
-
- if (opbits & Dbacc::Operationrec::OP_COMMIT_DELETE_CHECK)
- out << "COMMIT_DELETE_CHECK ";
-
- if (opbits & Dbacc::Operationrec::OP_INSERT_IS_DONE)
- out << "INSERT_IS_DONE ";
-
- if (opbits & Dbacc::Operationrec::OP_ELEMENT_DISAPPEARED)
- out << "ELEMENT_DISAPPEARED ";
-
- if (opbits & Dbacc::Operationrec::OP_LOCK_OWNER)
- {
- out << "last_parallel: " << dec << ptr.p->m_lo_last_parallel_op_ptr_i << " ";
- out << "last_serial: " << dec << ptr.p->m_lo_last_serial_op_ptr_i << " ";
- }
-
- out << "]";
- return out;
-}
-
-void
-Dbacc::dump_lock_queue(OperationrecPtr loPtr)
-{
- if ((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0)
- {
- while ((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0 &&
- loPtr.p->prevParallelQue != RNIL)
- {
- loPtr.i = loPtr.p->prevParallelQue;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
-
- while ((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0 &&
- loPtr.p->prevSerialQue != RNIL)
- {
- loPtr.i = loPtr.p->prevSerialQue;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
-
- ndbassert(loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- }
-
- ndbout << "-- HEAD --" << endl;
- OperationrecPtr tmp = loPtr;
- while (tmp.i != RNIL)
- {
- ptrCheckGuard(tmp, coprecsize, operationrec);
- ndbout << tmp << " ";
- tmp.i = tmp.p->nextParallelQue;
-
- if (tmp.i == loPtr.i)
- {
- ndbout << " <LOOP>";
- break;
- }
- }
- ndbout << endl;
-
- tmp.i = loPtr.p->nextSerialQue;
- while (tmp.i != RNIL)
- {
- ptrCheckGuard(tmp, coprecsize, operationrec);
- OperationrecPtr tmp2 = tmp;
-
- if (tmp.i == loPtr.i)
- {
- ndbout << "<LOOP S>" << endl;
- break;
- }
-
- while (tmp2.i != RNIL)
- {
- ptrCheckGuard(tmp2, coprecsize, operationrec);
- ndbout << tmp2 << " ";
- tmp2.i = tmp2.p->nextParallelQue;
-
- if (tmp2.i == tmp.i)
- {
- ndbout << "<LOOP 3>";
- break;
- }
- }
- ndbout << endl;
- tmp.i = tmp.p->nextSerialQue;
- }
-}
-#endif
-
-/* -------------------------------------------------------------------------
- * PLACE_WRITE_IN_LOCK_QUEUE
- * INPUT: OPERATION_REC_PTR OUR OPERATION POINTER
- * QUE_OPER_PTR LOCK QUEUE OWNER OPERATION POINTER
- * PWI_PAGEPTR PAGE POINTER OF ELEMENT
- * TPWI_ELEMENTPTR ELEMENT POINTER OF ELEMENT
- * OUTPUT TRESULT =
- * ZPARALLEL_QUEUE OPERATION PLACED IN PARALLEL QUEUE
- * OPERATION CAN PROCEED NOW.
- * ZSERIAL_QUEUE OPERATION PLACED IN SERIAL QUEUE
- * ERROR CODE OPERATION NEEDS ABORTING
- * ------------------------------------------------------------------------- */
-Uint32
-Dbacc::placeWriteInLockQueue(OperationrecPtr lockOwnerPtr)
-{
- OperationrecPtr lastOpPtr;
- lastOpPtr.i = lockOwnerPtr.p->m_lo_last_parallel_op_ptr_i;
- Uint32 opbits = operationRecPtr.p->m_op_bits;
-
- if (lastOpPtr.i == RNIL)
- {
- lastOpPtr = lockOwnerPtr;
- }
- else
- {
- ptrCheckGuard(lastOpPtr, coprecsize, operationrec);
- }
-
- ndbassert(get_parallel_head(lastOpPtr) == lockOwnerPtr.i);
-
- Uint32 lastbits = lastOpPtr.p->m_op_bits;
- if (lastbits & Operationrec::OP_ACC_LOCK_MODE)
- {
- if(operationRecPtr.p->is_same_trans(lastOpPtr.p))
- {
- goto checkop;
- }
- }
- else
- {
- /**
- * We dont have an exclusive lock on operation and
- *
- */
- jam();
-
- /**
- * Scan parallell queue to see if we are the only one
- */
- OperationrecPtr loopPtr = lockOwnerPtr;
- do
- {
- ptrCheckGuard(loopPtr, coprecsize, operationrec);
- if (!loopPtr.p->is_same_trans(operationRecPtr.p))
- {
- goto serial;
- }
- loopPtr.i = loopPtr.p->nextParallelQue;
- } while (loopPtr.i != RNIL);
-
- goto checkop;
- }
-
-serial:
- jam();
- placeSerialQueue(lockOwnerPtr, operationRecPtr);
-
- validate_lock_queue(lockOwnerPtr);
-
- return ZSERIAL_QUEUE;
-
-checkop:
- /*
- WE ARE PERFORMING AN READ EXCLUSIVE, INSERT, UPDATE OR DELETE IN THE SAME
- TRANSACTION WHERE WE PREVIOUSLY HAVE EXECUTED AN OPERATION.
- Read-All, Update-All, Insert-All and Delete-Insert are allowed
- combinations.
- Delete-Read, Delete-Update and Delete-Delete are not an allowed
- combination and will result in tuple not found error.
- */
- Uint32 lstate = lastbits & Operationrec::OP_STATE_MASK;
-
- Uint32 retValue = ZSERIAL_QUEUE; // So that it gets blocked...
- if (lstate == Operationrec::OP_STATE_EXECUTED)
- {
- jam();
-
- /**
- * Since last operation has executed...we can now check operation types
- * if not, we have to wait until it has executed
- */
- Uint32 op = opbits & Operationrec::OP_MASK;
- Uint32 lop = lastbits & Operationrec::OP_MASK;
- if (op == ZINSERT && lop != ZDELETE)
- {
- jam();
- return ZWRITE_ERROR;
- }//if
-
- /**
- * NOTE. No checking op operation types, as one can read different save
- * points...
- */
-#if 0
- if (lop == ZDELETE && (op != ZINSERT && op != ZWRITE))
- {
- jam();
- return ZREAD_ERROR;
- }
-#else
- if (lop == ZDELETE && (op == ZUPDATE && op == ZDELETE))
- {
- jam();
- return ZREAD_ERROR;
- }
-#endif
-
- if(op == ZWRITE)
- {
- opbits &= ~(Uint32)Operationrec::OP_MASK;
- opbits |= (lop == ZDELETE) ? ZINSERT : ZUPDATE;
- }
-
- opbits |= Operationrec::OP_STATE_RUNNING;
- operationRecPtr.p->localdata[0] = lastOpPtr.p->localdata[0];
- operationRecPtr.p->localdata[1] = lastOpPtr.p->localdata[1];
- retValue = ZPARALLEL_QUEUE;
- }
-
- opbits |= Operationrec::OP_RUN_QUEUE;
- operationRecPtr.p->m_op_bits = opbits;
- operationRecPtr.p->prevParallelQue = lastOpPtr.i;
- operationRecPtr.p->m_lock_owner_ptr_i = lockOwnerPtr.i;
- lastOpPtr.p->nextParallelQue = operationRecPtr.i;
- lockOwnerPtr.p->m_lo_last_parallel_op_ptr_i = operationRecPtr.i;
-
- validate_lock_queue(lockOwnerPtr);
-
- return retValue;
-}//Dbacc::placeWriteInLockQueue()
-
-Uint32
-Dbacc::placeReadInLockQueue(OperationrecPtr lockOwnerPtr)
-{
- OperationrecPtr lastOpPtr;
- OperationrecPtr loopPtr = lockOwnerPtr;
- lastOpPtr.i = lockOwnerPtr.p->m_lo_last_parallel_op_ptr_i;
- Uint32 opbits = operationRecPtr.p->m_op_bits;
-
- if (lastOpPtr.i == RNIL)
- {
- lastOpPtr = lockOwnerPtr;
- }
- else
- {
- ptrCheckGuard(lastOpPtr, coprecsize, operationrec);
- }
-
- ndbassert(get_parallel_head(lastOpPtr) == lockOwnerPtr.i);
-
- /**
- * Last operation in parallell queue of lock owner is same trans
- * and ACC_LOCK_MODE is exlusive, then we can proceed
- */
- Uint32 lastbits = lastOpPtr.p->m_op_bits;
- bool same = operationRecPtr.p->is_same_trans(lastOpPtr.p);
- if (same && (lastbits & Operationrec::OP_ACC_LOCK_MODE))
- {
- jam();
- opbits |= Operationrec::OP_LOCK_MODE; // Upgrade to X-lock
- goto checkop;
- }
-
- if ((lastbits & Operationrec::OP_ACC_LOCK_MODE) && !same)
- {
- jam();
- /**
- * Last op in serial queue had X-lock and was not our transaction...
- */
- goto serial;
- }
-
- if (lockOwnerPtr.p->nextSerialQue == RNIL)
- {
- jam();
- goto checkop;
- }
-
- /**
- * Scan parallell queue to see if we are already there...
- */
- do
- {
- ptrCheckGuard(loopPtr, coprecsize, operationrec);
- if (loopPtr.p->is_same_trans(operationRecPtr.p))
- goto checkop;
- loopPtr.i = loopPtr.p->nextParallelQue;
- } while (loopPtr.i != RNIL);
-
-serial:
- placeSerialQueue(lockOwnerPtr, operationRecPtr);
-
- validate_lock_queue(lockOwnerPtr);
-
- return ZSERIAL_QUEUE;
-
-checkop:
- Uint32 lstate = lastbits & Operationrec::OP_STATE_MASK;
-
- Uint32 retValue = ZSERIAL_QUEUE; // So that it gets blocked...
- if (lstate == Operationrec::OP_STATE_EXECUTED)
- {
- jam();
-
- /**
- * NOTE. No checking op operation types, as one can read different save
- * points...
- */
-
-#if 0
- /**
- * Since last operation has executed...we can now check operation types
- * if not, we have to wait until it has executed
- */
- if (lop == ZDELETE)
- {
- jam();
- return ZREAD_ERROR;
- }
-#endif
-
- opbits |= Operationrec::OP_STATE_RUNNING;
- operationRecPtr.p->localdata[0] = lastOpPtr.p->localdata[0];
- operationRecPtr.p->localdata[1] = lastOpPtr.p->localdata[1];
- retValue = ZPARALLEL_QUEUE;
- }
- opbits |= (lastbits & Operationrec::OP_ACC_LOCK_MODE);
- opbits |= Operationrec::OP_RUN_QUEUE;
- operationRecPtr.p->m_op_bits = opbits;
-
- operationRecPtr.p->prevParallelQue = lastOpPtr.i;
- operationRecPtr.p->m_lock_owner_ptr_i = lockOwnerPtr.i;
- lastOpPtr.p->nextParallelQue = operationRecPtr.i;
- lockOwnerPtr.p->m_lo_last_parallel_op_ptr_i = operationRecPtr.i;
-
- validate_lock_queue(lockOwnerPtr);
-
- return retValue;
-}//Dbacc::placeReadInLockQueue
-
-void Dbacc::placeSerialQueue(OperationrecPtr lockOwnerPtr,
- OperationrecPtr opPtr)
-{
- OperationrecPtr lastOpPtr;
- lastOpPtr.i = lockOwnerPtr.p->m_lo_last_serial_op_ptr_i;
-
- if (lastOpPtr.i == RNIL)
- {
- // Lock owner is last...
- ndbrequire(lockOwnerPtr.p->nextSerialQue == RNIL);
- lastOpPtr = lockOwnerPtr;
- }
- else
- {
- ptrCheckGuard(lastOpPtr, coprecsize, operationrec);
- }
-
- operationRecPtr.p->prevSerialQue = lastOpPtr.i;
- lastOpPtr.p->nextSerialQue = opPtr.i;
- lockOwnerPtr.p->m_lo_last_serial_op_ptr_i = opPtr.i;
-}
-
-/* ------------------------------------------------------------------------- */
-/* ACC KEYREQ END */
-/* ------------------------------------------------------------------------- */
-void Dbacc::acckeyref1Lab(Signal* signal, Uint32 result_code)
-{
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- /* ************************<< */
- /* ACCKEYREF */
- /* ************************<< */
- signal->theData[0] = cminusOne;
- signal->theData[1] = result_code;
- return;
-}//Dbacc::acckeyref1Lab()
-
-/* ******************----------------------------------------------------- */
-/* ACCMINUPDATE UPDATE LOCAL KEY REQ */
-/* DESCRIPTION: UPDATES LOCAL KEY OF AN ELEMENTS IN THE HASH TABLE */
-/* THIS SIGNAL IS WAITED AFTER ANY INSERT REQ */
-/* ENTER ACCMINUPDATE WITH SENDER: LQH, LEVEL B */
-/* OPERATION_REC_PTR, OPERATION RECORD PTR */
-/* CLOCALKEY(0), LOCAL KEY 1 */
-/* CLOCALKEY(1) LOCAL KEY 2 */
-/* ******************----------------------------------------------------- */
-void Dbacc::execACCMINUPDATE(Signal* signal)
-{
- Page8Ptr ulkPageidptr;
- Uint32 tulkLocalPtr;
- Uint32 tlocalkey1, tlocalkey2;
-
- jamEntry();
- operationRecPtr.i = signal->theData[0];
- tlocalkey1 = signal->theData[1];
- tlocalkey2 = signal->theData[2];
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- Uint32 opbits = operationRecPtr.p->m_op_bits;
- fragrecptr.i = operationRecPtr.p->fragptr;
- ulkPageidptr.i = operationRecPtr.p->elementPage;
- tulkLocalPtr = operationRecPtr.p->elementPointer +
- operationRecPtr.p->elementIsforward;
-
- if ((opbits & Operationrec::OP_STATE_MASK) == Operationrec::OP_STATE_RUNNING)
- {
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- ptrCheckGuard(ulkPageidptr, cpagesize, page8);
- dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey1);
- arrGuard(tulkLocalPtr, 2048);
- ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey1;
- operationRecPtr.p->localdata[0] = tlocalkey1;
- if (likely(fragrecptr.p->localkeylen == 1))
- {
- return;
- }
- else if (fragrecptr.p->localkeylen == 2)
- {
- jam();
- tulkLocalPtr = tulkLocalPtr + operationRecPtr.p->elementIsforward;
- operationRecPtr.p->localdata[1] = tlocalkey2;
- dbgWord32(ulkPageidptr, tulkLocalPtr, tlocalkey2);
- arrGuard(tulkLocalPtr, 2048);
- ulkPageidptr.p->word32[tulkLocalPtr] = tlocalkey2;
- return;
- } else {
- jam();
- }//if
- }//if
- ndbrequire(false);
-}//Dbacc::execACCMINUPDATE()
-
-/* ******************--------------------------------------------------------------- */
-/* ACC_COMMITREQ COMMIT TRANSACTION */
-/* SENDER: LQH, LEVEL B */
-/* INPUT: OPERATION_REC_PTR , */
-/* ******************--------------------------------------------------------------- */
-void Dbacc::execACC_COMMITREQ(Signal* signal)
-{
- Uint8 Toperation;
- jamEntry();
- Uint32 tmp = operationRecPtr.i = signal->theData[0];
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- void* ptr = operationRecPtr.p;
- Uint32 opbits = operationRecPtr.p->m_op_bits;
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- Toperation = opbits & Operationrec::OP_MASK;
- commitOperation(signal);
- ndbassert(operationRecPtr.i == tmp);
- ndbassert(operationRecPtr.p == ptr);
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- if(Toperation != ZREAD){
- fragrecptr.p->m_commit_count++;
- if (Toperation != ZINSERT) {
- if (Toperation != ZDELETE) {
- return;
- } else {
- jam();
- fragrecptr.p->noOfElements--;
- fragrecptr.p->slack += fragrecptr.p->elementLength;
- if (fragrecptr.p->slack > fragrecptr.p->slackCheck) {
- /* TIME FOR JOIN BUCKETS PROCESS */
- if (fragrecptr.p->expandCounter > 0) {
- if (fragrecptr.p->expandFlag < 2) {
- jam();
- signal->theData[0] = fragrecptr.i;
- signal->theData[1] = fragrecptr.p->p;
- signal->theData[2] = fragrecptr.p->maxp;
- signal->theData[3] = fragrecptr.p->expandFlag;
- fragrecptr.p->expandFlag = 2;
- sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 4, JBB);
- }//if
- }//if
- }//if
- }//if
- } else {
- jam(); /* EXPAND PROCESS HANDLING */
- fragrecptr.p->noOfElements++;
- fragrecptr.p->slack -= fragrecptr.p->elementLength;
- if (fragrecptr.p->slack >= (1u << 31)) {
- /* IT MEANS THAT IF SLACK < ZERO */
- if (fragrecptr.p->expandFlag == 0) {
- jam();
- fragrecptr.p->expandFlag = 2;
- signal->theData[0] = fragrecptr.i;
- signal->theData[1] = fragrecptr.p->p;
- signal->theData[2] = fragrecptr.p->maxp;
- sendSignal(cownBlockref, GSN_EXPANDCHECK2, signal, 3, JBB);
- }//if
- }//if
- }
- }
- return;
-}//Dbacc::execACC_COMMITREQ()
-
-/* ******************------------------------------------------------------- */
-/* ACC ABORT REQ ABORT ALL OPERATION OF THE TRANSACTION */
-/* ******************------------------------------+ */
-/* SENDER: LQH, LEVEL B */
-/* ******************------------------------------------------------------- */
-/* ACC ABORT REQ ABORT TRANSACTION */
-/* ******************------------------------------+ */
-/* SENDER: LQH, LEVEL B */
-void Dbacc::execACC_ABORTREQ(Signal* signal)
-{
- jamEntry();
- operationRecPtr.i = signal->theData[0];
- Uint32 sendConf = signal->theData[1];
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- fragrecptr.i = operationRecPtr.p->fragptr;
- Uint32 opbits = operationRecPtr.p->m_op_bits;
- Uint32 opstate = opbits & Operationrec::OP_STATE_MASK;
- tresult = 0; /* ZFALSE */
-
- if (opbits == Operationrec::OP_EXECUTED_DIRTY_READ)
- {
- jam();
- }
- else if (opstate == Operationrec::OP_STATE_EXECUTED ||
- opstate == Operationrec::OP_STATE_WAITING ||
- opstate == Operationrec::OP_STATE_RUNNING)
- {
- jam();
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- abortOperation(signal);
- }
-
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
-
- signal->theData[0] = operationRecPtr.p->userptr;
- signal->theData[1] = 0;
- switch(sendConf){
- case 0:
- return;
- case 2:
- if (opstate != Operationrec::OP_STATE_RUNNING)
- {
- return;
- }
- case 1:
- sendSignal(operationRecPtr.p->userblockref, GSN_ACC_ABORTCONF,
- signal, 1, JBB);
- }
-
- signal->theData[1] = RNIL;
-}
-
-/*
- * Lock or unlock tuple.
- */
-void Dbacc::execACC_LOCKREQ(Signal* signal)
-{
- jamEntry();
- AccLockReq* sig = (AccLockReq*)signal->getDataPtrSend();
- AccLockReq reqCopy = *sig;
- AccLockReq* const req = &reqCopy;
- Uint32 lockOp = (req->requestInfo & 0xFF);
- if (lockOp == AccLockReq::LockShared ||
- lockOp == AccLockReq::LockExclusive) {
- jam();
- // find table
- tabptr.i = req->tableId;
- ptrCheckGuard(tabptr, ctablesize, tabrec);
- // find fragment (TUX will know it)
- if (req->fragPtrI == RNIL) {
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragholder[i] == req->fragId){
- jam();
- req->fragPtrI = tabptr.p->fragptrholder[i];
- break;
- }
- }
- }
- fragrecptr.i = req->fragPtrI;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- ndbrequire(req->fragId == fragrecptr.p->myfid);
- // caller must be explicit here
- ndbrequire(req->accOpPtr == RNIL);
- // seize operation to hold the lock
- if (cfreeopRec != RNIL) {
- jam();
- seizeOpRec(signal);
- // init as in ACCSEIZEREQ
- operationRecPtr.p->userptr = req->userPtr;
- operationRecPtr.p->userblockref = req->userRef;
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- operationRecPtr.p->scanRecPtr = RNIL;
- // do read with lock via ACCKEYREQ
- Uint32 lockMode = (lockOp == AccLockReq::LockShared) ? 0 : 1;
- Uint32 opCode = ZSCAN_OP;
- signal->theData[0] = operationRecPtr.i;
- signal->theData[1] = fragrecptr.i;
- signal->theData[2] = opCode | (lockMode << 4) | (1u << 31);
- signal->theData[3] = req->hashValue;
- signal->theData[4] = 0; // search local key
- signal->theData[5] = req->transId1;
- signal->theData[6] = req->transId2;
- // enter local key in place of PK
- signal->theData[7] = req->tupAddr;
- EXECUTE_DIRECT(DBACC, GSN_ACCKEYREQ, signal, 8);
- // translate the result
- if (signal->theData[0] < RNIL) {
- jam();
- req->returnCode = AccLockReq::Success;
- req->accOpPtr = operationRecPtr.i;
- } else if (signal->theData[0] == RNIL) {
- jam();
- req->returnCode = AccLockReq::IsBlocked;
- req->accOpPtr = operationRecPtr.i;
- } else {
- ndbrequire(signal->theData[0] == (UintR)-1);
- releaseOpRec(signal);
- req->returnCode = AccLockReq::Refused;
- req->accOpPtr = RNIL;
- }
- } else {
- jam();
- req->returnCode = AccLockReq::NoFreeOp;
- }
- *sig = *req;
- return;
- }
- if (lockOp == AccLockReq::Unlock) {
- jam();
- // do unlock via ACC_COMMITREQ (immediate)
- signal->theData[0] = req->accOpPtr;
- EXECUTE_DIRECT(DBACC, GSN_ACC_COMMITREQ, signal, 1);
- releaseOpRec(signal);
- req->returnCode = AccLockReq::Success;
- *sig = *req;
- return;
- }
- if (lockOp == AccLockReq::Abort) {
- jam();
- // do abort via ACC_ABORTREQ (immediate)
- signal->theData[0] = req->accOpPtr;
- signal->theData[1] = 0; // Dont send abort
- execACC_ABORTREQ(signal);
- releaseOpRec(signal);
- req->returnCode = AccLockReq::Success;
- *sig = *req;
- return;
- }
- if (lockOp == AccLockReq::AbortWithConf) {
- jam();
- // do abort via ACC_ABORTREQ (with conf signal)
- signal->theData[0] = req->accOpPtr;
- signal->theData[1] = 1; // send abort
- execACC_ABORTREQ(signal);
- releaseOpRec(signal);
- req->returnCode = AccLockReq::Success;
- *sig = *req;
- return;
- }
- ndbrequire(false);
-}
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF EXECUTE OPERATION MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* MODULE: INSERT */
-/* THE FOLLOWING SUBROUTINES ARE ONLY USED BY INSERT_ELEMENT. THIS */
-/* ROUTINE IS THE SOLE INTERFACE TO INSERT ELEMENTS INTO THE INDEX. */
-/* CURRENT USERS ARE INSERT REQUESTS, EXPAND CONTAINER AND SHRINK */
-/* CONTAINER. */
-/* */
-/* THE FOLLOWING SUBROUTINES ARE INCLUDED IN THIS MODULE: */
-/* INSERT_ELEMENT */
-/* INSERT_CONTAINER */
-/* ADDNEWCONTAINER */
-/* GETFREELIST */
-/* INCREASELISTCONT */
-/* SEIZE_LEFTLIST */
-/* SEIZE_RIGHTLIST */
-/* */
-/* THESE ROUTINES ARE ONLY USED BY THIS MODULE AND BY NO ONE ELSE. */
-/* ALSO THE ROUTINES MAKE NO USE OF ROUTINES IN OTHER MODULES. */
-/* TAKE_REC_OUT_OF_FREE_OVERPAGE AND RELEASE_OVERFLOW_REC ARE */
-/* EXCEPTIONS TO THIS RULE. */
-/* */
-/* THE ONLY SHORT-LIVED VARIABLES USED IN OTHER PARTS OF THE BLOCK ARE */
-/* THOSE DEFINED AS INPUT AND OUTPUT IN INSERT_ELEMENT */
-/* SHORT-LIVED VARIABLES INCLUDE TEMPORARY VARIABLES, COMMON VARIABLES */
-/* AND POINTER VARIABLES. */
-/* THE ONLY EXCEPTION TO THIS RULE IS FRAGRECPTR WHICH POINTS TO THE */
-/* FRAGMENT RECORD. THIS IS MORE LESS STATIC ALWAYS DURING A SIGNAL */
-/* EXECUTION. */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* INSERT_ELEMENT */
-/* INPUT: */
-/* IDR_PAGEPTR (POINTER TO THE ACTIVE PAGE REC) */
-/* TIDR_PAGEINDEX (INDEX OF THE CONTAINER) */
-/* TIDR_FORWARD (DIRECTION FORWARD OR BACKWARD) */
-/* TIDR_ELEMHEAD (HEADER OF ELEMENT TO BE INSERTED */
-/* CIDR_KEYS(ARRAY OF TUPLE KEYS) */
-/* CLOCALKEY(ARRAY OF LOCAL KEYS). */
-/* FRAGRECPTR */
-/* IDR_OPERATION_REC_PTR */
-/* TIDR_KEY_LEN */
-/* */
-/* OUTPUT: */
-/* TIDR_PAGEINDEX (PAGE INDEX OF INSERTED ELEMENT) */
-/* IDR_PAGEPTR (PAGE POINTER OF INSERTED ELEMENT) */
-/* TIDR_FORWARD (CONTAINER DIRECTION OF INSERTED ELEMENT) */
-/* NONE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::insertElement(Signal* signal)
-{
- DirRangePtr inrOverflowrangeptr;
- DirectoryarrayPtr inrOverflowDirptr;
- OverflowRecordPtr inrOverflowRecPtr;
- Page8Ptr inrNewPageptr;
- Uint32 tinrNextSamePage;
- Uint32 tinrTmp;
-
- do {
- insertContainer(signal);
- if (tidrResult != ZFALSE) {
- jam();
- return;
- /* INSERTION IS DONE, OR */
- /* AN ERROR IS DETECTED */
- }//if
- if (((tidrContainerhead >> 7) & 0x3) != 0) {
- tinrNextSamePage = (tidrContainerhead >> 9) & 0x1; /* CHECK BIT FOR CHECKING WHERE */
- /* THE NEXT CONTAINER IS IN THE SAME PAGE */
- tidrPageindex = tidrContainerhead & 0x7f; /* NEXT CONTAINER PAGE INDEX 7 BITS */
- if (((tidrContainerhead >> 7) & 3) == ZLEFT) {
- jam();
- tidrForward = ZTRUE;
- } else if (((tidrContainerhead >> 7) & 3) == ZRIGHT) {
- jam();
- tidrForward = cminusOne;
- } else {
- ndbrequire(false);
- return;
- }//if
- if (tinrNextSamePage == ZFALSE) {
- jam(); /* NEXT CONTAINER IS IN AN OVERFLOW PAGE */
- tinrTmp = idrPageptr.p->word32[tidrContainerptr + 1];
- inrOverflowrangeptr.i = fragrecptr.p->overflowdir;
- ptrCheckGuard(inrOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard((tinrTmp >> 8), 256);
- inrOverflowDirptr.i = inrOverflowrangeptr.p->dirArray[tinrTmp >> 8];
- ptrCheckGuard(inrOverflowDirptr, cdirarraysize, directoryarray);
- idrPageptr.i = inrOverflowDirptr.p->pagep[tinrTmp & 0xff];
- ptrCheckGuard(idrPageptr, cpagesize, page8);
- }//if
- ndbrequire(tidrPageindex < ZEMPTYLIST);
- } else {
- break;
- }//if
- } while (1);
- gflPageptr.p = idrPageptr.p;
- getfreelist(signal);
- if (tgflPageindex == ZEMPTYLIST) {
- jam();
- /* NO FREE BUFFER IS FOUND */
- if (fragrecptr.p->firstOverflowRec == RNIL) {
- jam();
- allocOverflowPage(signal);
- ndbrequire(tresult <= ZLIMIT_OF_ERROR);
- }//if
- inrOverflowRecPtr.i = fragrecptr.p->firstOverflowRec;
- ptrCheckGuard(inrOverflowRecPtr, coverflowrecsize, overflowRecord);
- inrNewPageptr.i = inrOverflowRecPtr.p->overpage;
- ptrCheckGuard(inrNewPageptr, cpagesize, page8);
- gflPageptr.p = inrNewPageptr.p;
- getfreelist(signal);
- ndbrequire(tgflPageindex != ZEMPTYLIST);
- tancNext = 0;
- } else {
- jam();
- inrNewPageptr = idrPageptr;
- tancNext = 1;
- }//if
- tslUpdateHeader = ZTRUE;
- tslPageindex = tgflPageindex;
- slPageptr.p = inrNewPageptr.p;
- if (tgflBufType == ZLEFT) {
- seizeLeftlist(signal);
- tidrForward = ZTRUE;
- } else {
- seizeRightlist(signal);
- tidrForward = cminusOne;
- }//if
- tancPageindex = tgflPageindex;
- tancPageid = inrNewPageptr.p->word32[ZPOS_PAGE_ID];
- tancBufType = tgflBufType;
- tancContainerptr = tidrContainerptr;
- ancPageptr.p = idrPageptr.p;
- addnewcontainer(signal);
-
- idrPageptr = inrNewPageptr;
- tidrPageindex = tgflPageindex;
- insertContainer(signal);
- ndbrequire(tidrResult == ZTRUE);
-}//Dbacc::insertElement()
-
-/* --------------------------------------------------------------------------------- */
-/* INSERT_CONTAINER */
-/* INPUT: */
-/* IDR_PAGEPTR (POINTER TO THE ACTIVE PAGE REC) */
-/* TIDR_PAGEINDEX (INDEX OF THE CONTAINER) */
-/* TIDR_FORWARD (DIRECTION FORWARD OR BACKWARD) */
-/* TIDR_ELEMHEAD (HEADER OF ELEMENT TO BE INSERTED */
-/* CKEYS(ARRAY OF TUPLE KEYS) */
-/* CLOCALKEY(ARRAY 0F LOCAL KEYS). */
-/* TIDR_KEY_LEN */
-/* FRAGRECPTR */
-/* IDR_OPERATION_REC_PTR */
-/* OUTPUT: */
-/* TIDR_RESULT (ZTRUE FOR SUCCESS AND ZFALSE OTHERWISE) */
-/* TIDR_CONTAINERHEAD (HEADER OF CONTAINER) */
-/* TIDR_CONTAINERPTR (POINTER TO CONTAINER HEADER) */
-/* */
-/* DESCRIPTION: */
-/* THE FREE AREA OF THE CONTAINER WILL BE CALCULATED. IF IT IS */
-/* LARGER THAN OR EQUAL THE ELEMENT LENGTH. THE ELEMENT WILL BE */
-/* INSERT IN THE CONTAINER AND CONTAINER HEAD WILL BE UPDATED. */
-/* THIS ROUTINE ALWAYS DEALS WITH ONLY ONE CONTAINER AND DO NEVER */
-/* START ANYTHING OUTSIDE OF THIS CONTAINER. */
-/* */
-/* SHORT FORM: IDR */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::insertContainer(Signal* signal)
-{
- Uint32 tidrContainerlen;
- Uint32 tidrConfreelen;
- Uint32 tidrNextSide;
- Uint32 tidrNextConLen;
- Uint32 tidrIndex;
- Uint32 tidrInputIndex;
- Uint32 tidrContLen;
- Uint32 guard26;
-
- tidrResult = ZFALSE;
- tidrContainerptr = (tidrPageindex << ZSHIFT_PLUS) - (tidrPageindex << ZSHIFT_MINUS);
- tidrContainerptr = tidrContainerptr + ZHEAD_SIZE;
- /* --------------------------------------------------------------------------------- */
- /* CALCULATE THE POINTER TO THE ELEMENT TO BE INSERTED AND THE POINTER TO THE */
- /* CONTAINER HEADER OF THE OTHER SIDE OF THE BUFFER. */
- /* --------------------------------------------------------------------------------- */
- if (tidrForward == ZTRUE) {
- jam();
- tidrNextSide = tidrContainerptr + (ZBUF_SIZE - ZCON_HEAD_SIZE);
- arrGuard(tidrNextSide + 1, 2048);
- tidrContainerhead = idrPageptr.p->word32[tidrContainerptr];
- tidrContainerlen = tidrContainerhead >> 26;
- tidrIndex = tidrContainerptr + tidrContainerlen;
- } else {
- jam();
- tidrNextSide = tidrContainerptr;
- tidrContainerptr = tidrContainerptr + (ZBUF_SIZE - ZCON_HEAD_SIZE);
- arrGuard(tidrContainerptr + 1, 2048);
- tidrContainerhead = idrPageptr.p->word32[tidrContainerptr];
- tidrContainerlen = tidrContainerhead >> 26;
- tidrIndex = (tidrContainerptr - tidrContainerlen) + (ZCON_HEAD_SIZE - 1);
- }//if
- if (tidrContainerlen > (ZBUF_SIZE - 3)) {
- return;
- }//if
- tidrConfreelen = ZBUF_SIZE - tidrContainerlen;
- /* --------------------------------------------------------------------------------- */
- /* WE CALCULATE THE TOTAL LENGTH THE CONTAINER CAN EXPAND TO */
- /* THIS INCLUDES THE OTHER SIDE OF THE BUFFER IF POSSIBLE TO EXPAND THERE. */
- /* --------------------------------------------------------------------------------- */
- if (((tidrContainerhead >> 10) & 1) == 0) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* WE HAVE NOT EXPANDED TO THE ENTIRE BUFFER YET. WE CAN THUS READ THE OTHER */
- /* SIDE'S CONTAINER HEADER TO READ HIS LENGTH. */
- /* --------------------------------------------------------------------------------- */
- tidrNextConLen = idrPageptr.p->word32[tidrNextSide] >> 26;
- tidrConfreelen = tidrConfreelen - tidrNextConLen;
- if (tidrConfreelen > ZBUF_SIZE) {
- ndbrequire(false);
- /* --------------------------------------------------------------------------------- */
- /* THE BUFFERS ARE PLACED ON TOP OF EACH OTHER. THIS SHOULD NEVER OCCUR. */
- /* --------------------------------------------------------------------------------- */
- return;
- }//if
- } else {
- jam();
- tidrNextConLen = 1; /* INDICATE OTHER SIDE IS NOT PART OF FREE LIST */
- }//if
- if (tidrConfreelen < fragrecptr.p->elementLength) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE CONTAINER COULD NOT BE EXPANDED TO FIT THE NEW ELEMENT. WE HAVE TO */
- /* RETURN AND FIND A NEW CONTAINER TO INSERT IT INTO. */
- /* --------------------------------------------------------------------------------- */
- return;
- }//if
- tidrContainerlen = tidrContainerlen + fragrecptr.p->elementLength;
- if (tidrNextConLen == 0) {
- /* EACH SIDE OF THE BUFFER WHICH BELONG TO A FREE */
- /* LIST, HAS ZERO AS LENGTH. */
- if (tidrContainerlen > ZUP_LIMIT) {
- dbgWord32(idrPageptr, tidrContainerptr, idrPageptr.p->word32[tidrContainerptr] | (1 << 10));
- idrPageptr.p->word32[tidrContainerptr] = idrPageptr.p->word32[tidrContainerptr] | (1 << 10);
- tslUpdateHeader = ZFALSE;
- tslPageindex = tidrPageindex;
- slPageptr.p = idrPageptr.p;
- if (tidrForward == ZTRUE) {
- jam();
- seizeRightlist(signal); /* REMOVE THE RIGHT SIDE OF THE BUFFER FROM THE LIST */
- } else {
- jam();
- /* OF THE FREE CONTAINERS */
- seizeLeftlist(signal); /* REMOVE THE LEFT SIDE OF THE BUFFER FROM THE LIST */
- }//if
- }//if
- }//if
- /* OF THE FREE CONTAINERS */
- /* --------------------------------------------------------------------------------- */
- /* WE HAVE NOW FOUND A FREE SPOT IN THE CURRENT CONTAINER. WE INSERT THE */
- /* ELEMENT HERE. THE ELEMENT CONTAINS A HEADER, A LOCAL KEY AND A TUPLE KEY. */
- /* BEFORE INSERTING THE ELEMENT WE WILL UPDATE THE OPERATION RECORD WITH THE */
- /* DATA CONCERNING WHERE WE INSERTED THE ELEMENT. THIS MAKES IT EASY TO FIND */
- /* THIS INFORMATION WHEN WE RETURN TO UPDATE THE LOCAL KEY OR RETURN TO COMMIT */
- /* OR ABORT THE INSERT. IF NO OPERATION RECORD EXIST IT MEANS THAT WE ARE */
- /* PERFORMING THIS AS A PART OF THE EXPAND OR SHRINK PROCESS. */
- /* --------------------------------------------------------------------------------- */
- if (idrOperationRecPtr.i != RNIL) {
- jam();
- idrOperationRecPtr.p->elementIsforward = tidrForward;
- idrOperationRecPtr.p->elementPage = idrPageptr.i;
- idrOperationRecPtr.p->elementContainer = tidrContainerptr;
- idrOperationRecPtr.p->elementPointer = tidrIndex;
- }//if
- /* --------------------------------------------------------------------------------- */
- /* WE CHOOSE TO UNDO LOG INSERTS BY WRITING THE BEFORE VALUE TO THE UNDO LOG. */
- /* WE COULD ALSO HAVE DONE THIS BY WRITING THIS BEFORE VALUE WHEN DELETING */
- /* ELEMENTS. WE CHOOSE TO PUT IT HERE SINCE WE THEREBY ENSURE THAT WE ALWAYS */
- /* UNDO LOG ALL WRITES TO PAGE MEMORY. IT SHOULD BE EASIER TO MAINTAIN SUCH A */
- /* STRUCTURE. IT IS RATHER DIFFICULT TO MAINTAIN A LOGICAL STRUCTURE WHERE */
- /* DELETES ARE INSERTS AND INSERTS ARE PURELY DELETES. */
- /* --------------------------------------------------------------------------------- */
- dbgWord32(idrPageptr, tidrIndex, tidrElemhead);
- idrPageptr.p->word32[tidrIndex] = tidrElemhead; /* INSERTS THE HEAD OF THE ELEMENT */
- tidrIndex += tidrForward;
- guard26 = fragrecptr.p->localkeylen - 1;
- arrGuard(guard26, 2);
- for (tidrInputIndex = 0; tidrInputIndex <= guard26; tidrInputIndex++) {
- dbgWord32(idrPageptr, tidrIndex, clocalkey[tidrInputIndex]);
- arrGuard(tidrIndex, 2048);
- idrPageptr.p->word32[tidrIndex] = clocalkey[tidrInputIndex]; /* INSERTS LOCALKEY */
- tidrIndex += tidrForward;
- }//for
- tidrContLen = idrPageptr.p->word32[tidrContainerptr] << 6;
- tidrContLen = tidrContLen >> 6;
- dbgWord32(idrPageptr, tidrContainerptr, (tidrContainerlen << 26) | tidrContLen);
- idrPageptr.p->word32[tidrContainerptr] = (tidrContainerlen << 26) | tidrContLen;
- tidrResult = ZTRUE;
-}//Dbacc::insertContainer()
-
-/* --------------------------------------------------------------------------------- */
-/* ADDNEWCONTAINER */
-/* INPUT: */
-/* TANC_CONTAINERPTR */
-/* ANC_PAGEPTR */
-/* TANC_NEXT */
-/* TANC_PAGEINDEX */
-/* TANC_BUF_TYPE */
-/* TANC_PAGEID */
-/* OUTPUT: */
-/* NONE */
-/* */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::addnewcontainer(Signal* signal)
-{
- Uint32 tancTmp1;
-
- /* THE OLD DATA IS STORED ON AN UNDO PAGE */
- /* --------------------------------------------------------------------------------- */
- /* KEEP LENGTH INFORMATION IN BIT 26-31. */
- /* SET BIT 9 INDICATING IF NEXT BUFFER IN THE SAME PAGE USING TANC_NEXT. */
- /* SET TYPE OF NEXT CONTAINER IN BIT 7-8. */
- /* SET PAGE INDEX OF NEXT CONTAINER IN BIT 0-6. */
- /* KEEP INDICATOR OF OWNING OTHER SIDE OF BUFFER IN BIT 10. */
- /* --------------------------------------------------------------------------------- */
- tancTmp1 = ancPageptr.p->word32[tancContainerptr] >> 10;
- tancTmp1 = tancTmp1 << 1;
- tancTmp1 = tancTmp1 | tancNext;
- tancTmp1 = tancTmp1 << 2;
- tancTmp1 = tancTmp1 | tancBufType; /* TYPE OF THE NEXT CONTAINER */
- tancTmp1 = tancTmp1 << 7;
- tancTmp1 = tancTmp1 | tancPageindex;
- dbgWord32(ancPageptr, tancContainerptr, tancTmp1);
- ancPageptr.p->word32[tancContainerptr] = tancTmp1; /* HEAD OF THE CONTAINER IS UPDATED */
- dbgWord32(ancPageptr, tancContainerptr + 1, tancPageid);
- ancPageptr.p->word32[tancContainerptr + 1] = tancPageid;
-}//Dbacc::addnewcontainer()
-
-/* --------------------------------------------------------------------------------- */
-/* GETFREELIST */
-/* INPUT: */
-/* GFL_PAGEPTR (POINTER TO A PAGE RECORD). */
-/* OUTPUT: */
-/* TGFL_PAGEINDEX(POINTER TO A FREE BUFFER IN THE FREEPAGE), AND */
-/* TGFL_BUF_TYPE( TYPE OF THE FREE BUFFER). */
-/* DESCRIPTION: SEARCHS IN THE FREE LIST OF THE FREE BUFFER IN THE PAGE HEAD */
-/* (WORD32(1)),AND RETURN ADDRESS OF A FREE BUFFER OR NIL. */
-/* THE FREE BUFFER CAN BE A RIGHT CONTAINER OR A LEFT ONE */
-/* THE KIND OF THE CONTAINER IS NOTED BY TGFL_BUF_TYPE. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::getfreelist(Signal* signal)
-{
- Uint32 tgflTmp;
-
- tgflTmp = gflPageptr.p->word32[ZPOS_EMPTY_LIST];
- tgflPageindex = (tgflTmp >> 7) & 0x7f; /* LEFT FREE LIST */
- tgflBufType = ZLEFT;
- if (tgflPageindex == ZEMPTYLIST) {
- jam();
- tgflPageindex = tgflTmp & 0x7f; /* RIGHT FREE LIST */
- tgflBufType = ZRIGHT;
- }//if
- ndbrequire(tgflPageindex <= ZEMPTYLIST);
-}//Dbacc::getfreelist()
-
-/* --------------------------------------------------------------------------------- */
-/* INCREASELISTCONT */
-/* INPUT: */
-/* ILC_PAGEPTR PAGE POINTER TO INCREASE NUMBER OF CONTAINERS IN */
-/* A CONTAINER OF AN OVERFLOW PAGE (FREEPAGEPTR) IS ALLOCATED, NR OF */
-/* ALLOCATED CONTAINER HAVE TO BE INCRESE BY ONE . */
-/* IF THE NUMBER OF ALLOCATED CONTAINERS IS ABOVE THE FREE LIMIT WE WILL */
-/* REMOVE THE PAGE FROM THE FREE LIST. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::increaselistcont(Signal* signal)
-{
- OverflowRecordPtr ilcOverflowRecPtr;
-
- dbgWord32(ilcPageptr, ZPOS_ALLOC_CONTAINERS, ilcPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] + 1);
- ilcPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] = ilcPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] + 1;
- if (ilcPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] > ZFREE_LIMIT) {
- if (ilcPageptr.p->word32[ZPOS_OVERFLOWREC] != RNIL) {
- jam();
- ilcOverflowRecPtr.i = ilcPageptr.p->word32[ZPOS_OVERFLOWREC];
- dbgWord32(ilcPageptr, ZPOS_OVERFLOWREC, RNIL);
- ilcPageptr.p->word32[ZPOS_OVERFLOWREC] = RNIL;
- ptrCheckGuard(ilcOverflowRecPtr, coverflowrecsize, overflowRecord);
- tfoOverflowRecPtr = ilcOverflowRecPtr;
- takeRecOutOfFreeOverpage(signal);
- rorOverflowRecPtr = ilcOverflowRecPtr;
- releaseOverflowRec(signal);
- }//if
- }//if
-}//Dbacc::increaselistcont()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_LEFTLIST */
-/* INPUT: */
-/* TSL_PAGEINDEX PAGE INDEX OF CONTAINER TO SEIZE */
-/* SL_PAGEPTR PAGE POINTER OF CONTAINER TO SEIZE */
-/* TSL_UPDATE_HEADER SHOULD WE UPDATE THE CONTAINER HEADER */
-/* */
-/* OUTPUT: */
-/* NONE */
-/* DESCRIPTION: THE BUFFER NOTED BY TSL_PAGEINDEX WILL BE REMOVED FROM THE */
-/* LIST OF LEFT FREE CONTAINER, IN THE HEADER OF THE PAGE */
-/* (FREEPAGEPTR). PREVIOUS AND NEXT BUFFER OF REMOVED BUFFER */
-/* WILL BE UPDATED. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeLeftlist(Signal* signal)
-{
- Uint32 tsllTmp1;
- Uint32 tsllNewHead;
- Uint32 tsllHeadIndex;
- Uint32 tsllTmp;
-
- tsllHeadIndex = ((tslPageindex << ZSHIFT_PLUS) - (tslPageindex << ZSHIFT_MINUS)) + ZHEAD_SIZE;
- arrGuard(tsllHeadIndex + 1, 2048);
- tslNextfree = slPageptr.p->word32[tsllHeadIndex];
- tslPrevfree = slPageptr.p->word32[tsllHeadIndex + 1];
- if (tslPrevfree == ZEMPTYLIST) {
- jam();
- /* UPDATE FREE LIST OF LEFT CONTAINER IN PAGE HEAD */
- tsllTmp1 = slPageptr.p->word32[ZPOS_EMPTY_LIST];
- tsllTmp = tsllTmp1 & 0x7f;
- tsllTmp1 = (tsllTmp1 >> 14) << 14;
- tsllTmp1 = (tsllTmp1 | (tslNextfree << 7)) | tsllTmp;
- dbgWord32(slPageptr, ZPOS_EMPTY_LIST, tsllTmp1);
- slPageptr.p->word32[ZPOS_EMPTY_LIST] = tsllTmp1;
- } else {
- ndbrequire(tslPrevfree < ZEMPTYLIST);
- jam();
- tsllTmp = ((tslPrevfree << ZSHIFT_PLUS) - (tslPrevfree << ZSHIFT_MINUS)) + ZHEAD_SIZE;
- dbgWord32(slPageptr, tsllTmp, tslNextfree);
- slPageptr.p->word32[tsllTmp] = tslNextfree;
- }//if
- if (tslNextfree < ZEMPTYLIST) {
- jam();
- tsllTmp = (((tslNextfree << ZSHIFT_PLUS) - (tslNextfree << ZSHIFT_MINUS)) + ZHEAD_SIZE) + 1;
- dbgWord32(slPageptr, tsllTmp, tslPrevfree);
- slPageptr.p->word32[tsllTmp] = tslPrevfree;
- } else {
- ndbrequire(tslNextfree == ZEMPTYLIST);
- jam();
- }//if
- /* --------------------------------------------------------------------------------- */
- /* IF WE ARE UPDATING THE HEADER WE ARE CREATING A NEW CONTAINER IN THE PAGE. */
- /* TO BE ABLE TO FIND ALL LOCKED ELEMENTS WE KEEP ALL CONTAINERS IN LINKED */
- /* LISTS IN THE PAGE. */
- /* */
- /* ZPOS_EMPTY_LIST CONTAINS A NEXT POINTER IN BIT 16-22 THAT REFERS TO THE */
- /* FIRST CONTAINER IN A LIST OF USED RIGHT CONTAINERS IN THE PAGE. */
- /* ZPOS_EMPTY_LIST CONTAINS A NEXT POINTER IN BIT 23-29 THAT REFERS TO THE */
- /* FIRST CONTAINER IN A LIST OF USED LEFT CONTAINERS IN THE PAGE. */
- /* EACH CONTAINER IN THE LIST CONTAINS A NEXT POINTER IN BIT 11-17 AND IT */
- /* CONTAINS A PREVIOUS POINTER IN BIT 18-24. */
- /* WE ALSO SET BIT 25 TO INDICATE THAT IT IS A CONTAINER HEADER. */
- /* --------------------------------------------------------------------------------- */
- if (tslUpdateHeader == ZTRUE) {
- jam();
- tslNextfree = (slPageptr.p->word32[ZPOS_EMPTY_LIST] >> 23) & 0x7f;
- tsllNewHead = ZCON_HEAD_SIZE;
- tsllNewHead = ((tsllNewHead << 8) + ZEMPTYLIST) + (1 << 7);
- tsllNewHead = (tsllNewHead << 7) + tslNextfree;
- tsllNewHead = tsllNewHead << 11;
- dbgWord32(slPageptr, tsllHeadIndex, tsllNewHead);
- slPageptr.p->word32[tsllHeadIndex] = tsllNewHead;
- tsllTmp = slPageptr.p->word32[ZPOS_EMPTY_LIST] & 0xc07fffff;
- tsllTmp = tsllTmp | (tslPageindex << 23);
- dbgWord32(slPageptr, ZPOS_EMPTY_LIST, tsllTmp);
- slPageptr.p->word32[ZPOS_EMPTY_LIST] = tsllTmp;
- if (tslNextfree < ZEMPTYLIST) {
- jam();
- tsllTmp = ((tslNextfree << ZSHIFT_PLUS) - (tslNextfree << ZSHIFT_MINUS)) + ZHEAD_SIZE;
- tsllTmp1 = slPageptr.p->word32[tsllTmp] & 0xfe03ffff;
- tsllTmp1 = tsllTmp1 | (tslPageindex << 18);
- dbgWord32(slPageptr, tsllTmp, tsllTmp1);
- slPageptr.p->word32[tsllTmp] = tsllTmp1;
- } else {
- ndbrequire(tslNextfree == ZEMPTYLIST);
- jam();
- }//if
- }//if
- ilcPageptr.p = slPageptr.p;
- increaselistcont(signal);
-}//Dbacc::seizeLeftlist()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_RIGHTLIST */
-/* DESCRIPTION: THE BUFFER NOTED BY TSL_PAGEINDEX WILL BE REMOVED FROM THE */
-/* LIST OF RIGHT FREE CONTAINER, IN THE HEADER OF THE PAGE */
-/* (SL_PAGEPTR). PREVIOUS AND NEXT BUFFER OF REMOVED BUFFER */
-/* WILL BE UPDATED. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeRightlist(Signal* signal)
-{
- Uint32 tsrlTmp1;
- Uint32 tsrlNewHead;
- Uint32 tsrlHeadIndex;
- Uint32 tsrlTmp;
-
- tsrlHeadIndex = ((tslPageindex << ZSHIFT_PLUS) - (tslPageindex << ZSHIFT_MINUS)) + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- arrGuard(tsrlHeadIndex + 1, 2048);
- tslNextfree = slPageptr.p->word32[tsrlHeadIndex];
- tslPrevfree = slPageptr.p->word32[tsrlHeadIndex + 1];
- if (tslPrevfree == ZEMPTYLIST) {
- jam();
- tsrlTmp = slPageptr.p->word32[ZPOS_EMPTY_LIST];
- dbgWord32(slPageptr, ZPOS_EMPTY_LIST, ((tsrlTmp >> 7) << 7) | tslNextfree);
- slPageptr.p->word32[ZPOS_EMPTY_LIST] = ((tsrlTmp >> 7) << 7) | tslNextfree;
- } else {
- ndbrequire(tslPrevfree < ZEMPTYLIST);
- jam();
- tsrlTmp = ((tslPrevfree << ZSHIFT_PLUS) - (tslPrevfree << ZSHIFT_MINUS)) + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- dbgWord32(slPageptr, tsrlTmp, tslNextfree);
- slPageptr.p->word32[tsrlTmp] = tslNextfree;
- }//if
- if (tslNextfree < ZEMPTYLIST) {
- jam();
- tsrlTmp = ((tslNextfree << ZSHIFT_PLUS) - (tslNextfree << ZSHIFT_MINUS)) + ((ZHEAD_SIZE + ZBUF_SIZE) - (ZCON_HEAD_SIZE - 1));
- dbgWord32(slPageptr, tsrlTmp, tslPrevfree);
- slPageptr.p->word32[tsrlTmp] = tslPrevfree;
- } else {
- ndbrequire(tslNextfree == ZEMPTYLIST);
- jam();
- }//if
- /* --------------------------------------------------------------------------------- */
- /* IF WE ARE UPDATING THE HEADER WE ARE CREATING A NEW CONTAINER IN THE PAGE. */
- /* TO BE ABLE TO FIND ALL LOCKED ELEMENTS WE KEEP ALL CONTAINERS IN LINKED */
- /* LISTS IN THE PAGE. */
- /* */
- /* ZPOS_EMPTY_LIST CONTAINS A NEXT POINTER IN BIT 16-22 THAT REFERS TO THE */
- /* FIRST CONTAINER IN A LIST OF USED RIGHT CONTAINERS IN THE PAGE. */
- /* ZPOS_EMPTY_LIST CONTAINS A NEXT POINTER IN BIT 23-29 THAT REFERS TO THE */
- /* FIRST CONTAINER IN A LIST OF USED LEFT CONTAINERS IN THE PAGE. */
- /* EACH CONTAINER IN THE LIST CONTAINS A NEXT POINTER IN BIT 11-17 AND IT */
- /* CONTAINS A PREVIOUS POINTER IN BIT 18-24. */
- /* --------------------------------------------------------------------------------- */
- if (tslUpdateHeader == ZTRUE) {
- jam();
- tslNextfree = (slPageptr.p->word32[ZPOS_EMPTY_LIST] >> 16) & 0x7f;
- tsrlNewHead = ZCON_HEAD_SIZE;
- tsrlNewHead = ((tsrlNewHead << 8) + ZEMPTYLIST) + (1 << 7);
- tsrlNewHead = (tsrlNewHead << 7) + tslNextfree;
- tsrlNewHead = tsrlNewHead << 11;
- dbgWord32(slPageptr, tsrlHeadIndex, tsrlNewHead);
- slPageptr.p->word32[tsrlHeadIndex] = tsrlNewHead;
- tsrlTmp = slPageptr.p->word32[ZPOS_EMPTY_LIST] & 0xff80ffff;
- dbgWord32(slPageptr, ZPOS_EMPTY_LIST, tsrlTmp | (tslPageindex << 16));
- slPageptr.p->word32[ZPOS_EMPTY_LIST] = tsrlTmp | (tslPageindex << 16);
- if (tslNextfree < ZEMPTYLIST) {
- jam();
- tsrlTmp = ((tslNextfree << ZSHIFT_PLUS) - (tslNextfree << ZSHIFT_MINUS)) + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- tsrlTmp1 = slPageptr.p->word32[tsrlTmp] & 0xfe03ffff;
- dbgWord32(slPageptr, tsrlTmp, tsrlTmp1 | (tslPageindex << 18));
- slPageptr.p->word32[tsrlTmp] = tsrlTmp1 | (tslPageindex << 18);
- } else {
- ndbrequire(tslNextfree == ZEMPTYLIST);
- jam();
- }//if
- }//if
- ilcPageptr.p = slPageptr.p;
- increaselistcont(signal);
-}//Dbacc::seizeRightlist()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF INSERT_ELEMENT MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* MODULE: GET_ELEMENT */
-/* THE FOLLOWING SUBROUTINES ARE ONLY USED BY GET_ELEMENT AND */
-/* GETDIRINDEX. THIS ROUTINE IS THE SOLE INTERFACE TO GET ELEMENTS */
-/* FROM THE INDEX. CURRENT USERS ARE ALL REQUESTS AND EXECUTE UNDO LOG */
-/* */
-/* THE FOLLOWING SUBROUTINES ARE INCLUDED IN THIS MODULE: */
-/* GET_ELEMENT */
-/* GET_DIRINDEX */
-/* SEARCH_LONG_KEY */
-/* */
-/* THESE ROUTINES ARE ONLY USED BY THIS MODULE AND BY NO ONE ELSE. */
-/* ALSO THE ROUTINES MAKE NO USE OF ROUTINES IN OTHER MODULES. */
-/* THE ONLY SHORT-LIVED VARIABLES USED IN OTHER PARTS OF THE BLOCK ARE */
-/* THOSE DEFINED AS INPUT AND OUTPUT IN GET_ELEMENT AND GETDIRINDEX */
-/* SHORT-LIVED VARIABLES INCLUDE TEMPORARY VARIABLES, COMMON VARIABLES */
-/* AND POINTER VARIABLES. */
-/* THE ONLY EXCEPTION TO THIS RULE IS FRAGRECPTR WHICH POINTS TO THE */
-/* FRAGMENT RECORD. THIS IS MORE LESS STATIC ALWAYS DURING A SIGNAL */
-/* EXECUTION. */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* GETDIRINDEX */
-/* SUPPORT ROUTINE FOR INSERT ELEMENT, GET ELEMENT AND COMMITDELETE */
-/* INPUT:FRAGRECPTR ( POINTER TO THE ACTIVE FRAGMENT REC) */
-/* OPERATION_REC_PTR (POINTER TO THE OPERATION REC). */
-/* */
-/* OUTPUT:GDI_PAGEPTR ( POINTER TO THE PAGE OF THE ELEMENT) */
-/* TGDI_PAGEINDEX ( INDEX OF THE ELEMENT IN THE PAGE). */
-/* */
-/* DESCRIPTION: CHECK THE HASH VALUE OF THE OPERATION REC AND CALCULATE THE */
-/* THE ADDRESS OF THE ELEMENT IN THE HASH TABLE,(GDI_PAGEPTR, */
-/* TGDI_PAGEINDEX) ACCORDING TO LH3. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::getdirindex(Signal* signal)
-{
- DirRangePtr gdiDirRangePtr;
- DirectoryarrayPtr gdiDirptr;
- Uint32 tgdiTmp;
- Uint32 tgdiAddress;
-
- tgdiTmp = fragrecptr.p->k + fragrecptr.p->lhfragbits; /* OBS K = 6 */
- tgdiPageindex = operationRecPtr.p->hashValue & ((1 << fragrecptr.p->k) - 1);
- tgdiTmp = operationRecPtr.p->hashValue >> tgdiTmp;
- tgdiTmp = (tgdiTmp << fragrecptr.p->k) | tgdiPageindex;
- tgdiAddress = tgdiTmp & fragrecptr.p->maxp;
- gdiDirRangePtr.i = fragrecptr.p->directory;
- ptrCheckGuard(gdiDirRangePtr, cdirrangesize, dirRange);
- if (tgdiAddress < fragrecptr.p->p) {
- jam();
- tgdiAddress = tgdiTmp & ((fragrecptr.p->maxp << 1) | 1);
- }//if
- tgdiTmp = tgdiAddress >> fragrecptr.p->k;
- arrGuard((tgdiTmp >> 8), 256);
- gdiDirptr.i = gdiDirRangePtr.p->dirArray[tgdiTmp >> 8];
- ptrCheckGuard(gdiDirptr, cdirarraysize, directoryarray);
- gdiPageptr.i = gdiDirptr.p->pagep[tgdiTmp & 0xff]; /* DIRECTORY INDEX OF SEND BUCKET PAGE */
- ptrCheckGuard(gdiPageptr, cpagesize, page8);
-}//Dbacc::getdirindex()
-
-Uint32
-Dbacc::readTablePk(Uint32 localkey1, Uint32 eh, Ptr<Operationrec> opPtr)
-{
- int ret;
- Uint32 tableId = fragrecptr.p->myTableId;
- Uint32 fragId = fragrecptr.p->myfid;
- bool xfrm = fragrecptr.p->hasCharAttr;
-
-#ifdef VM_TRACE
- memset(ckeys, 0x1f, (fragrecptr.p->keyLength * MAX_XFRM_MULTIPLY) << 2);
-#endif
-
- if (likely(localkey1 != ~(Uint32)0))
- {
- Uint32 fragPageId = localkey1 >> MAX_TUPLES_BITS;
- Uint32 pageIndex = localkey1 & ((1 << MAX_TUPLES_BITS ) - 1);
- ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex,
- ckeys, true);
- }
- else
- {
- ndbrequire(ElementHeader::getLocked(eh));
- if (unlikely((opPtr.p->m_op_bits & Operationrec::OP_MASK) == ZSCAN_OP))
- {
- dump_lock_queue(opPtr);
- ndbrequire(opPtr.p->nextParallelQue == RNIL);
- ndbrequire(opPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED);
- ndbrequire(opPtr.p->m_op_bits & Operationrec::OP_COMMIT_DELETE_CHECK);
- ndbrequire((opPtr.p->m_op_bits & Operationrec::OP_STATE_MASK) == Operationrec::OP_STATE_RUNNING);
- return 0;
- }
- ret = c_lqh->readPrimaryKeys(opPtr.p->userptr, ckeys, xfrm);
- }
- jamEntry();
- ndbrequire(ret >= 0);
- return ret;
-}
-
-/* --------------------------------------------------------------------------------- */
-/* GET_ELEMENT */
-/* INPUT: */
-/* OPERATION_REC_PTR */
-/* FRAGRECPTR */
-/* OUTPUT: */
-/* TGE_RESULT RESULT SUCCESS = ZTRUE OTHERWISE ZFALSE */
-/* TGE_LOCKED LOCK INFORMATION IF SUCCESSFUL RESULT */
-/* GE_PAGEPTR PAGE POINTER OF FOUND ELEMENT */
-/* TGE_CONTAINERPTR CONTAINER INDEX OF FOUND ELEMENT */
-/* TGE_ELEMENTPTR ELEMENT INDEX OF FOUND ELEMENT */
-/* TGE_FORWARD DIRECTION OF CONTAINER WHERE ELEMENT FOUND */
-/* */
-/* DESCRIPTION: THE SUBROUTIN GOES THROUGH ALL CONTAINERS OF THE ACTIVE */
-/* BUCKET, AND SERCH FOR ELEMENT.THE PRIMARY KEYS WHICH IS SAVED */
-/* IN THE OPERATION REC ARE THE CHECK ITEMS IN THE SEARCHING. */
-/* --------------------------------------------------------------------------------- */
-
-#if __ia64 == 1
-#if __INTEL_COMPILER == 810
-int ndb_acc_ia64_icc810_dummy_var = 0;
-void ndb_acc_ia64_icc810_dummy_func()
-{
- ndb_acc_ia64_icc810_dummy_var++;
-}
-#endif
-#endif
-
-Uint32
-Dbacc::getElement(Signal* signal, OperationrecPtr& lockOwnerPtr)
-{
- Uint32 errcode;
- DirRangePtr geOverflowrangeptr;
- DirectoryarrayPtr geOverflowDirptr;
- Uint32 tgeElementHeader;
- Uint32 tgeElemStep;
- Uint32 tgeContainerhead;
- Uint32 tgePageindex;
- Uint32 tgeActivePageDir;
- Uint32 tgeNextptrtype;
- register Uint32 tgeKeyptr;
- register Uint32 tgeRemLen;
- register Uint32 TelemLen = fragrecptr.p->elementLength;
- register Uint32* Tkeydata = (Uint32*)&signal->theData[7];
-
- getdirindex(signal);
- tgePageindex = tgdiPageindex;
- gePageptr = gdiPageptr;
- /*
- * The value seached is
- * - table key for ACCKEYREQ, stored in TUP
- * - local key (1 word) for ACC_LOCKREQ and UNDO, stored in ACC
- */
- const bool searchLocalKey = operationRecPtr.p->tupkeylen == 0;
-
- ndbrequire(TelemLen == ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
- tgeNextptrtype = ZLEFT;
-
- const Uint32 tmp = fragrecptr.p->k + fragrecptr.p->lhfragbits;
- const Uint32 opHashValuePart = (operationRecPtr.p->hashValue >> tmp) &0xFFFF;
- do {
- tgeContainerptr = (tgePageindex << ZSHIFT_PLUS) - (tgePageindex << ZSHIFT_MINUS);
- if (tgeNextptrtype == ZLEFT) {
- jam();
- tgeContainerptr = tgeContainerptr + ZHEAD_SIZE;
- tgeElementptr = tgeContainerptr + ZCON_HEAD_SIZE;
- tgeKeyptr = (tgeElementptr + ZELEM_HEAD_SIZE) + fragrecptr.p->localkeylen;
- tgeElemStep = TelemLen;
- tgeForward = 1;
- if (unlikely(tgeContainerptr >= 2048))
- {
- errcode = 4;
- goto error;
- }
- tgeRemLen = gePageptr.p->word32[tgeContainerptr] >> 26;
- if (unlikely(((tgeContainerptr + tgeRemLen - 1) >= 2048)))
- {
- errcode = 5;
- goto error;
- }
- } else if (tgeNextptrtype == ZRIGHT) {
- jam();
- tgeContainerptr = tgeContainerptr + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- tgeElementptr = tgeContainerptr - 1;
- tgeKeyptr = (tgeElementptr - ZELEM_HEAD_SIZE) - fragrecptr.p->localkeylen;
- tgeElemStep = 0 - TelemLen;
- tgeForward = (Uint32)-1;
- if (unlikely(tgeContainerptr >= 2048))
- {
- errcode = 4;
- goto error;
- }
- tgeRemLen = gePageptr.p->word32[tgeContainerptr] >> 26;
- if (unlikely((tgeContainerptr - tgeRemLen) >= 2048))
- {
- errcode = 5;
- goto error;
- }
- } else {
- errcode = 6;
- goto error;
- }//if
- if (tgeRemLen >= ZCON_HEAD_SIZE + TelemLen) {
- if (unlikely(tgeRemLen > ZBUF_SIZE))
- {
- errcode = 7;
- goto error;
- }//if
- /* ------------------------------------------------------------------- */
- // There is at least one element in this container.
- // Check if it is the element searched for.
- /* ------------------------------------------------------------------- */
- do {
- tgeElementHeader = gePageptr.p->word32[tgeElementptr];
- tgeRemLen = tgeRemLen - TelemLen;
- Uint32 hashValuePart;
- Uint32 localkey1, localkey2;
- lockOwnerPtr.i = RNIL;
- lockOwnerPtr.p = NULL;
- if (ElementHeader::getLocked(tgeElementHeader)) {
- jam();
- lockOwnerPtr.i = ElementHeader::getOpPtrI(tgeElementHeader);
- ptrCheckGuard(lockOwnerPtr, coprecsize, operationrec);
- hashValuePart = lockOwnerPtr.p->hashvaluePart;
- localkey1 = lockOwnerPtr.p->localdata[0];
- localkey2 = lockOwnerPtr.p->localdata[1];
- } else {
- jam();
- hashValuePart = ElementHeader::getHashValuePart(tgeElementHeader);
- localkey1 = gePageptr.p->word32[tgeElementptr + tgeForward];
- localkey2 = 0;
- }
- if (hashValuePart == opHashValuePart) {
- jam();
- bool found;
- if (! searchLocalKey)
- {
- Uint32 len = readTablePk(localkey1, tgeElementHeader,
- lockOwnerPtr);
- found = (len == operationRecPtr.p->xfrmtupkeylen) &&
- (memcmp(Tkeydata, ckeys, len << 2) == 0);
- } else {
- jam();
- found = (localkey1 == Tkeydata[0]);
- }
- if (found)
- {
- jam();
- operationRecPtr.p->localdata[0] = localkey1;
- operationRecPtr.p->localdata[1] = localkey2;
- return ZTRUE;
- }
- }
- if (tgeRemLen <= ZCON_HEAD_SIZE) {
- break;
- }
- tgeElementptr = tgeElementptr + tgeElemStep;
- } while (true);
- }//if
- if (unlikely(tgeRemLen != ZCON_HEAD_SIZE))
- {
- errcode = 8;
- goto error;
- }//if
- tgeContainerhead = gePageptr.p->word32[tgeContainerptr];
- tgeNextptrtype = (tgeContainerhead >> 7) & 0x3;
- if (tgeNextptrtype == 0) {
- jam();
- return ZFALSE; /* NO MORE CONTAINER */
- }//if
- tgePageindex = tgeContainerhead & 0x7f; /* NEXT CONTAINER PAGE INDEX 7 BITS */
- if (unlikely(tgePageindex > ZEMPTYLIST))
- {
- errcode = 9;
- goto error;
- }//if
- if (((tgeContainerhead >> 9) & 1) == ZFALSE) {
- jam();
- tgeActivePageDir = gePageptr.p->word32[tgeContainerptr + 1]; /* NEXT PAGE ID */
- geOverflowrangeptr.i = fragrecptr.p->overflowdir;
- ptrCheckGuard(geOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard((tgeActivePageDir >> 8), 256);
- geOverflowDirptr.i = geOverflowrangeptr.p->dirArray[tgeActivePageDir >> 8];
- ptrCheckGuard(geOverflowDirptr, cdirarraysize, directoryarray);
- gePageptr.i = geOverflowDirptr.p->pagep[tgeActivePageDir & 0xff];
- ptrCheckGuard(gePageptr, cpagesize, page8);
- }//if
- } while (1);
-
- return ZFALSE;
-
-error:
- ACCKEY_error(errcode);
- return ~0;
-}//Dbacc::getElement()
-
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* END OF GET_ELEMENT MODULE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* MODULE: DELETE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* COMMITDELETE */
-/* INPUT: OPERATION_REC_PTR, PTR TO AN OPERATION RECORD. */
-/* FRAGRECPTR, PTR TO A FRAGMENT RECORD */
-/* */
-/* OUTPUT: */
-/* NONE */
-/* DESCRIPTION: DELETE OPERATIONS WILL BE COMPLETED AT THE
- * COMMIT OF TRANSACTION. THIS SUBROUTINE SEARCHS FOR ELEMENT AND
- * DELETES IT. IT DOES SO BY REPLACING IT WITH THE LAST
- * ELEMENT IN THE BUCKET. IF THE DELETED ELEMENT IS ALSO THE LAST
- * ELEMENT THEN IT IS ONLY NECESSARY TO REMOVE THE ELEMENT
- * ------------------------------------------------------------------------- */
-void
-Dbacc::report_dealloc(Signal* signal, const Operationrec* opPtrP)
-{
- Uint32 localKey = opPtrP->localdata[0];
- Uint32 opbits = opPtrP->m_op_bits;
- Uint32 userptr= opPtrP->userptr;
- Uint32 scanInd =
- ((opbits & Operationrec::OP_MASK) == ZSCAN_OP) ||
- (opbits & Operationrec::OP_LOCK_REQ);
-
- if (localKey != ~(Uint32)0)
- {
- signal->theData[0] = fragrecptr.p->myfid;
- signal->theData[1] = fragrecptr.p->myTableId;
- Uint32 pageId = localKey >> MAX_TUPLES_BITS;
- Uint32 pageIndex = localKey & ((1 << MAX_TUPLES_BITS) - 1);
- signal->theData[2] = pageId;
- signal->theData[3] = pageIndex;
- signal->theData[4] = userptr;
- signal->theData[5] = scanInd;
- EXECUTE_DIRECT(DBLQH, GSN_TUP_DEALLOCREQ, signal, 6);
- jamEntry();
- }
-}
-
-void Dbacc::commitdelete(Signal* signal)
-{
- jam();
- report_dealloc(signal, operationRecPtr.p);
-
- getdirindex(signal);
- tlastPageindex = tgdiPageindex;
- lastPageptr.i = gdiPageptr.i;
- lastPageptr.p = gdiPageptr.p;
- tlastForward = ZTRUE;
- tlastContainerptr = (tlastPageindex << ZSHIFT_PLUS) - (tlastPageindex << ZSHIFT_MINUS);
- tlastContainerptr = tlastContainerptr + ZHEAD_SIZE;
- arrGuard(tlastContainerptr, 2048);
- tlastContainerhead = lastPageptr.p->word32[tlastContainerptr];
- tlastContainerlen = tlastContainerhead >> 26;
- lastPrevpageptr.i = RNIL;
- ptrNull(lastPrevpageptr);
- tlastPrevconptr = 0;
- getLastAndRemove(signal);
-
- delPageptr.i = operationRecPtr.p->elementPage;
- ptrCheckGuard(delPageptr, cpagesize, page8);
- tdelElementptr = operationRecPtr.p->elementPointer;
- /* --------------------------------------------------------------------------------- */
- // Here we have to take extreme care since we do not want locks to end up after the
- // log execution. Thus it is necessary to put back the element in unlocked shape.
- // We thus update the element header to ensure we log an unlocked element. We do not
- // need to restore it later since it is deleted immediately anyway.
- /* --------------------------------------------------------------------------------- */
- const Uint32 hv = operationRecPtr.p->hashvaluePart;
- const Uint32 eh = ElementHeader::setUnlocked(hv, 0);
- delPageptr.p->word32[tdelElementptr] = eh;
- if (operationRecPtr.p->elementPage == lastPageptr.i) {
- if (operationRecPtr.p->elementPointer == tlastElementptr) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE LAST ELEMENT WAS THE ELEMENT TO BE DELETED. WE NEED NOT COPY IT. */
- /* --------------------------------------------------------------------------------- */
- return;
- }//if
- }//if
- /* --------------------------------------------------------------------------------- */
- /* THE DELETED ELEMENT IS NOT THE LAST. WE READ THE LAST ELEMENT AND OVERWRITE THE */
- /* DELETED ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- tdelContainerptr = operationRecPtr.p->elementContainer;
- tdelForward = operationRecPtr.p->elementIsforward;
- deleteElement(signal);
-}//Dbacc::commitdelete()
-
-/* --------------------------------------------------------------------------------- */
-/* DELETE_ELEMENT */
-/* INPUT: FRAGRECPTR, POINTER TO A FRAGMENT RECORD */
-/* LAST_PAGEPTR, POINTER TO THE PAGE OF THE LAST ELEMENT */
-/* DEL_PAGEPTR, POINTER TO THE PAGE OF THE DELETED ELEMENT */
-/* TLAST_ELEMENTPTR, ELEMENT POINTER OF THE LAST ELEMENT */
-/* TDEL_ELEMENTPTR, ELEMENT POINTER OF THE DELETED ELEMENT */
-/* TLAST_FORWARD, DIRECTION OF LAST ELEMENT */
-/* TDEL_FORWARD, DIRECTION OF DELETED ELEMENT */
-/* TDEL_CONTAINERPTR, CONTAINER POINTER OF DELETED ELEMENT */
-/* DESCRIPTION: COPY LAST ELEMENT TO DELETED ELEMENT AND UPDATE UNDO LOG AND */
-/* UPDATE ANY ACTIVE OPERATION ON THE MOVED ELEMENT. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::deleteElement(Signal* signal)
-{
- OperationrecPtr deOperationRecPtr;
- Uint32 tdeIndex;
- Uint32 tlastMoveElemptr;
- Uint32 tdelMoveElemptr;
- Uint32 guard31;
-
- if (tlastElementptr >= 2048)
- goto deleteElement_index_error1;
- {
- const Uint32 tdeElemhead = lastPageptr.p->word32[tlastElementptr];
- tlastMoveElemptr = tlastElementptr;
- tdelMoveElemptr = tdelElementptr;
- guard31 = fragrecptr.p->elementLength - 1;
- for (tdeIndex = 0; tdeIndex <= guard31; tdeIndex++) {
- dbgWord32(delPageptr, tdelMoveElemptr, lastPageptr.p->word32[tlastMoveElemptr]);
- if ((tlastMoveElemptr >= 2048) ||
- (tdelMoveElemptr >= 2048))
- goto deleteElement_index_error2;
- delPageptr.p->word32[tdelMoveElemptr] = lastPageptr.p->word32[tlastMoveElemptr];
- tdelMoveElemptr = tdelMoveElemptr + tdelForward;
- tlastMoveElemptr = tlastMoveElemptr + tlastForward;
- }//for
- if (ElementHeader::getLocked(tdeElemhead)) {
- /* --------------------------------------------------------------------------------- */
- /* THE LAST ELEMENT IS LOCKED AND IS THUS REFERENCED BY AN OPERATION RECORD. WE NEED */
- /* TO UPDATE THE OPERATION RECORD WITH THE NEW REFERENCE TO THE ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- deOperationRecPtr.i = ElementHeader::getOpPtrI(tdeElemhead);
- ptrCheckGuard(deOperationRecPtr, coprecsize, operationrec);
- deOperationRecPtr.p->elementPage = delPageptr.i;
- deOperationRecPtr.p->elementContainer = tdelContainerptr;
- deOperationRecPtr.p->elementPointer = tdelElementptr;
- deOperationRecPtr.p->elementIsforward = tdelForward;
- /* --------------------------------------------------------------------------------- */
- // We need to take extreme care to not install locked records after system restart.
- // An undo of the delete will reinstall the moved record. We have to ensure that the
- // lock is removed to ensure that no such thing happen.
- /* --------------------------------------------------------------------------------- */
- Uint32 eh = ElementHeader::setUnlocked(deOperationRecPtr.p->hashvaluePart,
- 0);
- lastPageptr.p->word32[tlastElementptr] = eh;
- }//if
- return;
- }
-
- deleteElement_index_error1:
- arrGuard(tlastElementptr, 2048);
- return;
-
- deleteElement_index_error2:
- arrGuard(tdelMoveElemptr + guard31, 2048);
- arrGuard(tlastMoveElemptr, 2048);
- return;
-
-}//Dbacc::deleteElement()
-
-/* --------------------------------------------------------------------------------- */
-/* GET_LAST_AND_REMOVE */
-/* INPUT: */
-/* LAST_PAGEPTR PAGE POINTER OF FIRST CONTAINER IN SEARCH OF LAST*/
-/* TLAST_CONTAINERPTR CONTAINER INDEX OF THE SAME */
-/* TLAST_CONTAINERHEAD CONTAINER HEADER OF THE SAME */
-/* TLAST_PAGEINDEX PAGE INDEX OF THE SAME */
-/* TLAST_FORWARD CONTAINER DIRECTION OF THE SAME */
-/* TLAST_CONTAINERLEN CONTAINER LENGTH OF THE SAME */
-/* LAST_PREVPAGEPTR PAGE POINTER OF PREVIOUS CONTAINER OF THE SAME */
-/* TLAST_PREVCONPTR CONTAINER INDEX OF PREVIOUS CONTAINER OF THE SAME*/
-/* */
-/* OUTPUT: */
-/* ALL VARIABLES FROM INPUT BUT NOW CONTAINING INFO ABOUT LAST */
-/* CONTAINER. */
-/* TLAST_ELEMENTPTR LAST ELEMENT POINTER IN LAST CONTAINER */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::getLastAndRemove(Signal* signal)
-{
- DirRangePtr glrOverflowrangeptr;
- DirectoryarrayPtr glrOverflowDirptr;
- Uint32 tglrHead;
- Uint32 tglrTmp;
-
- GLR_LOOP_10:
- if (((tlastContainerhead >> 7) & 0x3) != 0) {
- jam();
- lastPrevpageptr.i = lastPageptr.i;
- lastPrevpageptr.p = lastPageptr.p;
- tlastPrevconptr = tlastContainerptr;
- tlastPageindex = tlastContainerhead & 0x7f;
- if (((tlastContainerhead >> 9) & 0x1) == ZFALSE) {
- jam();
- arrGuard(tlastContainerptr + 1, 2048);
- tglrTmp = lastPageptr.p->word32[tlastContainerptr + 1];
- glrOverflowrangeptr.i = fragrecptr.p->overflowdir;
- ptrCheckGuard(glrOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard((tglrTmp >> 8), 256);
- glrOverflowDirptr.i = glrOverflowrangeptr.p->dirArray[tglrTmp >> 8];
- ptrCheckGuard(glrOverflowDirptr, cdirarraysize, directoryarray);
- lastPageptr.i = glrOverflowDirptr.p->pagep[tglrTmp & 0xff];
- ptrCheckGuard(lastPageptr, cpagesize, page8);
- }//if
- tlastContainerptr = (tlastPageindex << ZSHIFT_PLUS) - (tlastPageindex << ZSHIFT_MINUS);
- if (((tlastContainerhead >> 7) & 3) == ZLEFT) {
- jam();
- tlastForward = ZTRUE;
- tlastContainerptr = tlastContainerptr + ZHEAD_SIZE;
- } else if (((tlastContainerhead >> 7) & 3) == ZRIGHT) {
- jam();
- tlastForward = cminusOne;
- tlastContainerptr = ((tlastContainerptr + ZHEAD_SIZE) + ZBUF_SIZE) - ZCON_HEAD_SIZE;
- } else {
- ndbrequire(false);
- return;
- }//if
- arrGuard(tlastContainerptr, 2048);
- tlastContainerhead = lastPageptr.p->word32[tlastContainerptr];
- tlastContainerlen = tlastContainerhead >> 26;
- ndbrequire(tlastContainerlen >= ((Uint32)ZCON_HEAD_SIZE + fragrecptr.p->elementLength));
- goto GLR_LOOP_10;
- }//if
- tlastContainerlen = tlastContainerlen - fragrecptr.p->elementLength;
- if (tlastForward == ZTRUE) {
- jam();
- tlastElementptr = tlastContainerptr + tlastContainerlen;
- } else {
- jam();
- tlastElementptr = (tlastContainerptr + (ZCON_HEAD_SIZE - 1)) - tlastContainerlen;
- }//if
- rlPageptr.i = lastPageptr.i;
- rlPageptr.p = lastPageptr.p;
- trlPageindex = tlastPageindex;
- if (((tlastContainerhead >> 10) & 1) == 1) {
- /* --------------------------------------------------------------------------------- */
- /* WE HAVE OWNERSHIP OF BOTH PARTS OF THE CONTAINER ENDS. */
- /* --------------------------------------------------------------------------------- */
- if (tlastContainerlen < ZDOWN_LIMIT) {
- /* --------------------------------------------------------------------------------- */
- /* WE HAVE DECREASED THE SIZE BELOW THE DOWN LIMIT, WE MUST GIVE UP THE OTHER */
- /* SIDE OF THE BUFFER. */
- /* --------------------------------------------------------------------------------- */
- tlastContainerhead = tlastContainerhead ^ (1 << 10);
- trlRelCon = ZFALSE;
- if (tlastForward == ZTRUE) {
- jam();
- turlIndex = tlastContainerptr + (ZBUF_SIZE - ZCON_HEAD_SIZE);
- releaseRightlist(signal);
- } else {
- jam();
- tullIndex = tlastContainerptr - (ZBUF_SIZE - ZCON_HEAD_SIZE);
- releaseLeftlist(signal);
- }//if
- }//if
- }//if
- if (tlastContainerlen <= 2) {
- ndbrequire(tlastContainerlen == 2);
- if (lastPrevpageptr.i != RNIL) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE LAST CONTAINER IS EMPTY AND IS NOT THE FIRST CONTAINER WHICH IS NOT REMOVED. */
- /* DELETE THE LAST CONTAINER AND UPDATE THE PREVIOUS CONTAINER. ALSO PUT THIS */
- /* CONTAINER IN FREE CONTAINER LIST OF THE PAGE. */
- /* --------------------------------------------------------------------------------- */
- ndbrequire(tlastPrevconptr < 2048);
- tglrTmp = lastPrevpageptr.p->word32[tlastPrevconptr] >> 9;
- dbgWord32(lastPrevpageptr, tlastPrevconptr, tglrTmp << 9);
- lastPrevpageptr.p->word32[tlastPrevconptr] = tglrTmp << 9;
- trlRelCon = ZTRUE;
- if (tlastForward == ZTRUE) {
- jam();
- tullIndex = tlastContainerptr;
- releaseLeftlist(signal);
- } else {
- jam();
- turlIndex = tlastContainerptr;
- releaseRightlist(signal);
- }//if
- return;
- }//if
- }//if
- tglrHead = tlastContainerhead << 6;
- tglrHead = tglrHead >> 6;
- tglrHead = tglrHead | (tlastContainerlen << 26);
- dbgWord32(lastPageptr, tlastContainerptr, tglrHead);
- arrGuard(tlastContainerptr, 2048);
- lastPageptr.p->word32[tlastContainerptr] = tglrHead;
-}//Dbacc::getLastAndRemove()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_LEFTLIST */
-/* INPUT: */
-/* RL_PAGEPTR PAGE POINTER OF CONTAINER TO BE RELEASED */
-/* TRL_PAGEINDEX PAGE INDEX OF CONTAINER TO BE RELEASED */
-/* TURL_INDEX INDEX OF CONTAINER TO BE RELEASED */
-/* TRL_REL_CON TRUE IF CONTAINER RELEASED OTHERWISE ONLY */
-/* A PART IS RELEASED. */
-/* */
-/* OUTPUT: */
-/* NONE */
-/* */
-/* THE FREE LIST OF LEFT FREE BUFFER IN THE PAGE WILL BE UPDATE */
-/* TULL_INDEX IS INDEX TO THE FIRST WORD IN THE LEFT SIDE OF THE BUFFER */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseLeftlist(Signal* signal)
-{
- Uint32 tullTmp;
- Uint32 tullTmp1;
-
- /* --------------------------------------------------------------------------------- */
- /* IF A CONTAINER IS RELEASED AND NOT ONLY A PART THEN WE HAVE TO REMOVE IT */
- /* FROM THE LIST OF USED CONTAINERS IN THE PAGE. THIS IN ORDER TO ENSURE THAT */
- /* WE CAN FIND ALL LOCKED ELEMENTS DURING LOCAL CHECKPOINT. */
- /* --------------------------------------------------------------------------------- */
- if (trlRelCon == ZTRUE) {
- arrGuard(tullIndex, 2048);
- trlHead = rlPageptr.p->word32[tullIndex];
- trlNextused = (trlHead >> 11) & 0x7f;
- trlPrevused = (trlHead >> 18) & 0x7f;
- if (trlNextused < ZEMPTYLIST) {
- jam();
- tullTmp1 = (trlNextused << ZSHIFT_PLUS) - (trlNextused << ZSHIFT_MINUS);
- tullTmp1 = tullTmp1 + ZHEAD_SIZE;
- tullTmp = rlPageptr.p->word32[tullTmp1] & 0xfe03ffff;
- dbgWord32(rlPageptr, tullTmp1, tullTmp | (trlPrevused << 18));
- rlPageptr.p->word32[tullTmp1] = tullTmp | (trlPrevused << 18);
- } else {
- ndbrequire(trlNextused == ZEMPTYLIST);
- jam();
- }//if
- if (trlPrevused < ZEMPTYLIST) {
- jam();
- tullTmp1 = (trlPrevused << ZSHIFT_PLUS) - (trlPrevused << ZSHIFT_MINUS);
- tullTmp1 = tullTmp1 + ZHEAD_SIZE;
- tullTmp = rlPageptr.p->word32[tullTmp1] & 0xfffc07ff;
- dbgWord32(rlPageptr, tullTmp1, tullTmp | (trlNextused << 11));
- rlPageptr.p->word32[tullTmp1] = tullTmp | (trlNextused << 11);
- } else {
- ndbrequire(trlPrevused == ZEMPTYLIST);
- jam();
- /* --------------------------------------------------------------------------------- */
- /* WE ARE FIRST IN THE LIST AND THUS WE NEED TO UPDATE THE FIRST POINTER. */
- /* --------------------------------------------------------------------------------- */
- tullTmp = rlPageptr.p->word32[ZPOS_EMPTY_LIST] & 0xc07fffff;
- dbgWord32(rlPageptr, ZPOS_EMPTY_LIST, tullTmp | (trlNextused << 23));
- rlPageptr.p->word32[ZPOS_EMPTY_LIST] = tullTmp | (trlNextused << 23);
- }//if
- }//if
- dbgWord32(rlPageptr, tullIndex + 1, ZEMPTYLIST);
- arrGuard(tullIndex + 1, 2048);
- rlPageptr.p->word32[tullIndex + 1] = ZEMPTYLIST;
- tullTmp1 = (rlPageptr.p->word32[ZPOS_EMPTY_LIST] >> 7) & 0x7f;
- dbgWord32(rlPageptr, tullIndex, tullTmp1);
- arrGuard(tullIndex, 2048);
- rlPageptr.p->word32[tullIndex] = tullTmp1;
- if (tullTmp1 < ZEMPTYLIST) {
- jam();
- tullTmp1 = (tullTmp1 << ZSHIFT_PLUS) - (tullTmp1 << ZSHIFT_MINUS);
- tullTmp1 = (tullTmp1 + ZHEAD_SIZE) + 1;
- dbgWord32(rlPageptr, tullTmp1, trlPageindex);
- rlPageptr.p->word32[tullTmp1] = trlPageindex; /* UPDATES PREV POINTER IN THE NEXT FREE */
- } else {
- ndbrequire(tullTmp1 == ZEMPTYLIST);
- }//if
- tullTmp = rlPageptr.p->word32[ZPOS_EMPTY_LIST];
- tullTmp = (((tullTmp >> 14) << 14) | (trlPageindex << 7)) | (tullTmp & 0x7f);
- dbgWord32(rlPageptr, ZPOS_EMPTY_LIST, tullTmp);
- rlPageptr.p->word32[ZPOS_EMPTY_LIST] = tullTmp;
- dbgWord32(rlPageptr, ZPOS_ALLOC_CONTAINERS, rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] - 1);
- rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] = rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] - 1;
- ndbrequire(rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] <= ZNIL);
- if (((rlPageptr.p->word32[ZPOS_EMPTY_LIST] >> ZPOS_PAGE_TYPE_BIT) & 3) == 1) {
- jam();
- colPageptr.i = rlPageptr.i;
- colPageptr.p = rlPageptr.p;
- ptrCheck(colPageptr, cpagesize, page8);
- checkoverfreelist(signal);
- }//if
-}//Dbacc::releaseLeftlist()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_RIGHTLIST */
-/* INPUT: */
-/* RL_PAGEPTR PAGE POINTER OF CONTAINER TO BE RELEASED */
-/* TRL_PAGEINDEX PAGE INDEX OF CONTAINER TO BE RELEASED */
-/* TURL_INDEX INDEX OF CONTAINER TO BE RELEASED */
-/* TRL_REL_CON TRUE IF CONTAINER RELEASED OTHERWISE ONLY */
-/* A PART IS RELEASED. */
-/* */
-/* OUTPUT: */
-/* NONE */
-/* */
-/* THE FREE LIST OF RIGHT FREE BUFFER IN THE PAGE WILL BE UPDATE. */
-/* TURL_INDEX IS INDEX TO THE FIRST WORD IN THE RIGHT SIDE OF */
-/* THE BUFFER, WHICH IS THE LAST WORD IN THE BUFFER. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseRightlist(Signal* signal)
-{
- Uint32 turlTmp1;
- Uint32 turlTmp;
-
- /* --------------------------------------------------------------------------------- */
- /* IF A CONTAINER IS RELEASED AND NOT ONLY A PART THEN WE HAVE TO REMOVE IT */
- /* FROM THE LIST OF USED CONTAINERS IN THE PAGE. THIS IN ORDER TO ENSURE THAT */
- /* WE CAN FIND ALL LOCKED ELEMENTS DURING LOCAL CHECKPOINT. */
- /* --------------------------------------------------------------------------------- */
- if (trlRelCon == ZTRUE) {
- jam();
- arrGuard(turlIndex, 2048);
- trlHead = rlPageptr.p->word32[turlIndex];
- trlNextused = (trlHead >> 11) & 0x7f;
- trlPrevused = (trlHead >> 18) & 0x7f;
- if (trlNextused < ZEMPTYLIST) {
- jam();
- turlTmp1 = (trlNextused << ZSHIFT_PLUS) - (trlNextused << ZSHIFT_MINUS);
- turlTmp1 = turlTmp1 + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- turlTmp = rlPageptr.p->word32[turlTmp1] & 0xfe03ffff;
- dbgWord32(rlPageptr, turlTmp1, turlTmp | (trlPrevused << 18));
- rlPageptr.p->word32[turlTmp1] = turlTmp | (trlPrevused << 18);
- } else {
- ndbrequire(trlNextused == ZEMPTYLIST);
- jam();
- }//if
- if (trlPrevused < ZEMPTYLIST) {
- jam();
- turlTmp1 = (trlPrevused << ZSHIFT_PLUS) - (trlPrevused << ZSHIFT_MINUS);
- turlTmp1 = turlTmp1 + ((ZHEAD_SIZE + ZBUF_SIZE) - ZCON_HEAD_SIZE);
- turlTmp = rlPageptr.p->word32[turlTmp1] & 0xfffc07ff;
- dbgWord32(rlPageptr, turlTmp1, turlTmp | (trlNextused << 11));
- rlPageptr.p->word32[turlTmp1] = turlTmp | (trlNextused << 11);
- } else {
- ndbrequire(trlPrevused == ZEMPTYLIST);
- jam();
- /* --------------------------------------------------------------------------------- */
- /* WE ARE FIRST IN THE LIST AND THUS WE NEED TO UPDATE THE FIRST POINTER */
- /* OF THE RIGHT CONTAINER LIST. */
- /* --------------------------------------------------------------------------------- */
- turlTmp = rlPageptr.p->word32[ZPOS_EMPTY_LIST] & 0xff80ffff;
- dbgWord32(rlPageptr, ZPOS_EMPTY_LIST, turlTmp | (trlNextused << 16));
- rlPageptr.p->word32[ZPOS_EMPTY_LIST] = turlTmp | (trlNextused << 16);
- }//if
- }//if
- dbgWord32(rlPageptr, turlIndex + 1, ZEMPTYLIST);
- arrGuard(turlIndex + 1, 2048);
- rlPageptr.p->word32[turlIndex + 1] = ZEMPTYLIST;
- turlTmp1 = rlPageptr.p->word32[ZPOS_EMPTY_LIST] & 0x7f;
- dbgWord32(rlPageptr, turlIndex, turlTmp1);
- arrGuard(turlIndex, 2048);
- rlPageptr.p->word32[turlIndex] = turlTmp1;
- if (turlTmp1 < ZEMPTYLIST) {
- jam();
- turlTmp = (turlTmp1 << ZSHIFT_PLUS) - (turlTmp1 << ZSHIFT_MINUS);
- turlTmp = turlTmp + ((ZHEAD_SIZE + ZBUF_SIZE) - (ZCON_HEAD_SIZE - 1));
- dbgWord32(rlPageptr, turlTmp, trlPageindex);
- rlPageptr.p->word32[turlTmp] = trlPageindex; /* UPDATES PREV POINTER IN THE NEXT FREE */
- } else {
- ndbrequire(turlTmp1 == ZEMPTYLIST);
- }//if
- turlTmp = rlPageptr.p->word32[ZPOS_EMPTY_LIST];
- dbgWord32(rlPageptr, ZPOS_EMPTY_LIST, ((turlTmp >> 7) << 7) | trlPageindex);
- rlPageptr.p->word32[ZPOS_EMPTY_LIST] = ((turlTmp >> 7) << 7) | trlPageindex;
- dbgWord32(rlPageptr, ZPOS_ALLOC_CONTAINERS, rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] - 1);
- rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] = rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] - 1;
- ndbrequire(rlPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] <= ZNIL);
- if (((rlPageptr.p->word32[ZPOS_EMPTY_LIST] >> ZPOS_PAGE_TYPE_BIT) & 3) == 1) {
- jam();
- colPageptr.i = rlPageptr.i;
- colPageptr.p = rlPageptr.p;
- checkoverfreelist(signal);
- }//if
-}//Dbacc::releaseRightlist()
-
-/* --------------------------------------------------------------------------------- */
-/* CHECKOVERFREELIST */
-/* INPUT: COL_PAGEPTR, POINTER OF AN OVERFLOW PAGE RECORD. */
-/* DESCRIPTION: CHECKS IF THE PAGE HAVE TO PUT IN FREE LIST OF OVER FLOW */
-/* PAGES. WHEN IT HAVE TO, AN OVERFLOW REC PTR WILL BE ALLOCATED */
-/* TO KEEP NFORMATION ABOUT THE PAGE. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::checkoverfreelist(Signal* signal)
-{
- Uint32 tcolTmp;
-
- tcolTmp = colPageptr.p->word32[ZPOS_ALLOC_CONTAINERS];
- if (tcolTmp <= ZFREE_LIMIT) {
- if (tcolTmp == 0) {
- jam();
- ropPageptr = colPageptr;
- releaseOverpage(signal);
- } else {
- jam();
- if (colPageptr.p->word32[ZPOS_OVERFLOWREC] == RNIL) {
- ndbrequire(cfirstfreeoverrec != RNIL);
- jam();
- seizeOverRec(signal);
- sorOverflowRecPtr.p->dirindex = colPageptr.p->word32[ZPOS_PAGE_ID];
- sorOverflowRecPtr.p->overpage = colPageptr.i;
- dbgWord32(colPageptr, ZPOS_OVERFLOWREC, sorOverflowRecPtr.i);
- colPageptr.p->word32[ZPOS_OVERFLOWREC] = sorOverflowRecPtr.i;
- porOverflowRecPtr = sorOverflowRecPtr;
- putOverflowRecInFrag(signal);
- }//if
- }//if
- }//if
-}//Dbacc::checkoverfreelist()
-
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* END OF DELETE MODULE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* */
-/* COMMIT AND ABORT MODULE */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ABORT_OPERATION */
-/*DESCRIPTION: AN OPERATION RECORD CAN BE IN A LOCK QUEUE OF AN ELEMENT OR */
-/*OWNS THE LOCK. BY THIS SUBROUTINE THE LOCK STATE OF THE OPERATION WILL */
-/*BE CHECKED. THE OPERATION RECORD WILL BE REMOVED FROM THE QUEUE IF IT */
-/*BELONGED TO ANY ONE, OTHERWISE THE ELEMENT HEAD WILL BE UPDATED. */
-/* ------------------------------------------------------------------------- */
-
-/**
- *
- * P0 - P1 - P2 - P3
- * S0
- * S1
- * S2
- */
-void
-Dbacc::abortParallelQueueOperation(Signal* signal, OperationrecPtr opPtr)
-{
- jam();
- OperationrecPtr nextP;
- OperationrecPtr prevP;
- OperationrecPtr loPtr;
-
- Uint32 opbits = opPtr.p->m_op_bits;
- Uint32 opstate = opbits & Operationrec::OP_STATE_MASK;
- nextP.i = opPtr.p->nextParallelQue;
- prevP.i = opPtr.p->prevParallelQue;
- loPtr.i = opPtr.p->m_lock_owner_ptr_i;
-
- ndbassert(! (opbits & Operationrec::OP_LOCK_OWNER));
- ndbassert(opbits & Operationrec::OP_RUN_QUEUE);
-
- ptrCheckGuard(prevP, coprecsize, operationrec);
- ndbassert(prevP.p->nextParallelQue == opPtr.i);
- prevP.p->nextParallelQue = nextP.i;
-
- if (nextP.i != RNIL)
- {
- ptrCheckGuard(nextP, coprecsize, operationrec);
- ndbassert(nextP.p->prevParallelQue == opPtr.i);
- nextP.p->prevParallelQue = prevP.i;
- }
- else if (prevP.i != loPtr.i)
- {
- jam();
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- ndbassert(loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- ndbassert(loPtr.p->m_lo_last_parallel_op_ptr_i == opPtr.i);
- loPtr.p->m_lo_last_parallel_op_ptr_i = prevP.i;
- prevP.p->m_lock_owner_ptr_i = loPtr.i;
-
- /**
- * Abort P3...check start next
- */
- startNext(signal, prevP);
- validate_lock_queue(prevP);
- return;
- }
- else
- {
- jam();
- /**
- * P0 - P1
- *
- * Abort P1, check start next
- */
- ndbassert(prevP.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- prevP.p->m_lo_last_parallel_op_ptr_i = RNIL;
- startNext(signal, prevP);
- validate_lock_queue(prevP);
- return;
- }
-
- /**
- * Abort P1/P2
- */
- if (opbits & Operationrec::OP_LOCK_MODE)
- {
- Uint32 nextbits = nextP.p->m_op_bits;
- while ((nextbits & Operationrec::OP_LOCK_MODE) == 0)
- {
- ndbassert(nextbits & Operationrec::OP_ACC_LOCK_MODE);
- nextbits &= ~(Uint32)Operationrec::OP_ACC_LOCK_MODE;
- nextP.p->m_op_bits = nextbits;
-
- if (nextP.p->nextParallelQue != RNIL)
- {
- nextP.i = nextP.p->nextParallelQue;
- ptrCheckGuard(nextP, coprecsize, operationrec);
- nextbits = nextP.p->m_op_bits;
- }
- else
- {
- break;
- }
- }
- }
-
- /**
- * Abort P1, P2
- */
- if (opstate == Operationrec::OP_STATE_RUNNING)
- {
- jam();
- startNext(signal, prevP);
- validate_lock_queue(prevP);
- return;
- }
-
- ndbassert(opstate == Operationrec::OP_STATE_EXECUTED ||
- opstate == Operationrec::OP_STATE_WAITING);
-
- /**
- * Scan to last of run queue
- */
- while (nextP.p->nextParallelQue != RNIL)
- {
- jam();
- nextP.i = nextP.p->nextParallelQue;
- ptrCheckGuard(nextP, coprecsize, operationrec);
- }
-
-#ifdef VM_TRACE
- loPtr.i = nextP.p->m_lock_owner_ptr_i;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- ndbassert(loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- ndbassert(loPtr.p->m_lo_last_parallel_op_ptr_i == nextP.i);
-#endif
- startNext(signal, nextP);
- validate_lock_queue(nextP);
-
- return;
-}
-
-void
-Dbacc::abortSerieQueueOperation(Signal* signal, OperationrecPtr opPtr)
-{
- jam();
- OperationrecPtr prevS, nextS;
- OperationrecPtr prevP, nextP;
- OperationrecPtr loPtr;
-
- Uint32 opbits = opPtr.p->m_op_bits;
-
- prevS.i = opPtr.p->prevSerialQue;
- nextS.i = opPtr.p->nextSerialQue;
-
- prevP.i = opPtr.p->prevParallelQue;
- nextP.i = opPtr.p->nextParallelQue;
-
- ndbassert((opbits & Operationrec::OP_LOCK_OWNER) == 0);
- ndbassert((opbits & Operationrec::OP_RUN_QUEUE) == 0);
-
- if (prevP.i != RNIL)
- {
- /**
- * We're not list head...
- */
- ptrCheckGuard(prevP, coprecsize, operationrec);
- ndbassert(prevP.p->nextParallelQue == opPtr.i);
- prevP.p->nextParallelQue = nextP.i;
-
- if (nextP.i != RNIL)
- {
- ptrCheckGuard(nextP, coprecsize, operationrec);
- ndbassert(nextP.p->prevParallelQue == opPtr.i);
- ndbassert((nextP.p->m_op_bits & Operationrec::OP_STATE_MASK) ==
- Operationrec::OP_STATE_WAITING);
- nextP.p->prevParallelQue = prevP.i;
-
- if ((prevP.p->m_op_bits & Operationrec::OP_ACC_LOCK_MODE) == 0 &&
- opbits & Operationrec::OP_LOCK_MODE)
- {
- /**
- * Scan right in parallel queue to fix OP_ACC_LOCK_MODE
- */
- while ((nextP.p->m_op_bits & Operationrec::OP_LOCK_MODE) == 0)
- {
- ndbassert(nextP.p->m_op_bits & Operationrec::OP_ACC_LOCK_MODE);
- nextP.p->m_op_bits &= ~(Uint32)Operationrec::OP_ACC_LOCK_MODE;
- nextP.i = nextP.p->nextParallelQue;
- if (nextP.i == RNIL)
- break;
- ptrCheckGuard(nextP, coprecsize, operationrec);
- }
- }
- }
- validate_lock_queue(prevP);
- return;
- }
- else
- {
- /**
- * We're a list head
- */
- ptrCheckGuard(prevS, coprecsize, operationrec);
- ndbassert(prevS.p->nextSerialQue == opPtr.i);
-
- if (nextP.i != RNIL)
- {
- /**
- * Promote nextP to list head
- */
- ptrCheckGuard(nextP, coprecsize, operationrec);
- ndbassert(nextP.p->prevParallelQue == opPtr.i);
- prevS.p->nextSerialQue = nextP.i;
- nextP.p->prevParallelQue = RNIL;
- nextP.p->nextSerialQue = nextS.i;
- if (nextS.i != RNIL)
- {
- jam();
- ptrCheckGuard(nextS, coprecsize, operationrec);
- ndbassert(nextS.p->prevSerialQue == opPtr.i);
- nextS.p->prevSerialQue = nextP.i;
- validate_lock_queue(prevS);
- return;
- }
- else
- {
- // nextS is RNIL, i.e we're last in serie queue...
- // we must update lockOwner.m_lo_last_serial_op_ptr_i
- loPtr = prevS;
- while ((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0)
- {
- loPtr.i = loPtr.p->prevSerialQue;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
- ndbassert(loPtr.p->m_lo_last_serial_op_ptr_i == opPtr.i);
- loPtr.p->m_lo_last_serial_op_ptr_i = nextP.i;
- validate_lock_queue(loPtr);
- return;
- }
- }
-
- if (nextS.i == RNIL)
- {
- /**
- * Abort S2
- */
-
- // nextS is RNIL, i.e we're last in serie queue...
- // and we have no parallel queue,
- // we must update lockOwner.m_lo_last_serial_op_ptr_i
- prevS.p->nextSerialQue = RNIL;
-
- loPtr = prevS;
- while ((loPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) == 0)
- {
- loPtr.i = loPtr.p->prevSerialQue;
- ptrCheckGuard(loPtr, coprecsize, operationrec);
- }
- ndbassert(loPtr.p->m_lo_last_serial_op_ptr_i == opPtr.i);
- if (prevS.i != loPtr.i)
- {
- jam();
- loPtr.p->m_lo_last_serial_op_ptr_i = prevS.i;
- }
- else
- {
- loPtr.p->m_lo_last_serial_op_ptr_i = RNIL;
- }
- validate_lock_queue(loPtr);
- }
- else if (nextP.i == RNIL)
- {
- ptrCheckGuard(nextS, coprecsize, operationrec);
- ndbassert(nextS.p->prevSerialQue == opPtr.i);
- prevS.p->nextSerialQue = nextS.i;
- nextS.p->prevSerialQue = prevS.i;
-
- if (prevS.p->m_op_bits & Operationrec::OP_LOCK_OWNER)
- {
- /**
- * Abort S0
- */
- OperationrecPtr lastOp;
- lastOp.i = prevS.p->m_lo_last_parallel_op_ptr_i;
- if (lastOp.i != RNIL)
- {
- jam();
- ptrCheckGuard(lastOp, coprecsize, operationrec);
- ndbassert(lastOp.p->m_lock_owner_ptr_i == prevS.i);
- }
- else
- {
- jam();
- lastOp = prevS;
- }
- startNext(signal, lastOp);
- validate_lock_queue(lastOp);
- }
- else
- {
- validate_lock_queue(prevS);
- }
- }
- }
-}
-
-
-void Dbacc::abortOperation(Signal* signal)
-{
- Uint32 opbits = operationRecPtr.p->m_op_bits;
-
- validate_lock_queue(operationRecPtr);
-
- if (opbits & Operationrec::OP_LOCK_OWNER)
- {
- takeOutLockOwnersList(signal, operationRecPtr);
- opbits &= ~(Uint32)Operationrec::OP_LOCK_OWNER;
- if (opbits & Operationrec::OP_INSERT_IS_DONE)
- {
- jam();
- opbits |= Operationrec::OP_ELEMENT_DISAPPEARED;
- }//if
- operationRecPtr.p->m_op_bits = opbits;
- const bool queue = (operationRecPtr.p->nextParallelQue != RNIL ||
- operationRecPtr.p->nextSerialQue != RNIL);
-
- if (queue)
- {
- jam();
- release_lockowner(signal, operationRecPtr, false);
- }
- else
- {
- /* -------------------------------------------------------------------
- * WE ARE OWNER OF THE LOCK AND NO OTHER OPERATIONS ARE QUEUED.
- * IF INSERT OR STANDBY WE DELETE THE ELEMENT OTHERWISE WE REMOVE
- * THE LOCK FROM THE ELEMENT.
- * ------------------------------------------------------------------ */
- if ((opbits & Operationrec::OP_ELEMENT_DISAPPEARED) == 0)
- {
- jam();
- Page8Ptr aboPageidptr;
- Uint32 taboElementptr;
- Uint32 tmp2Olq;
-
- taboElementptr = operationRecPtr.p->elementPointer;
- aboPageidptr.i = operationRecPtr.p->elementPage;
- tmp2Olq = ElementHeader::setUnlocked(operationRecPtr.p->hashvaluePart,
- operationRecPtr.p->scanBits);
- ptrCheckGuard(aboPageidptr, cpagesize, page8);
- dbgWord32(aboPageidptr, taboElementptr, tmp2Olq);
- arrGuard(taboElementptr, 2048);
- aboPageidptr.p->word32[taboElementptr] = tmp2Olq;
- return;
- }
- else
- {
- jam();
- commitdelete(signal);
- }//if
- }//if
- }
- else if (opbits & Operationrec::OP_RUN_QUEUE)
- {
- abortParallelQueueOperation(signal, operationRecPtr);
- }
- else
- {
- abortSerieQueueOperation(signal, operationRecPtr);
- }
-}
-
-void
-Dbacc::commitDeleteCheck()
-{
- OperationrecPtr opPtr;
- OperationrecPtr lastOpPtr;
- OperationrecPtr deleteOpPtr;
- Uint32 elementDeleted = 0;
- bool deleteCheckOngoing = true;
- Uint32 hashValue = 0;
- lastOpPtr = operationRecPtr;
- opPtr.i = operationRecPtr.p->nextParallelQue;
- while (opPtr.i != RNIL) {
- jam();
- ptrCheckGuard(opPtr, coprecsize, operationrec);
- lastOpPtr = opPtr;
- opPtr.i = opPtr.p->nextParallelQue;
- }//while
- deleteOpPtr = lastOpPtr;
- do {
- Uint32 opbits = deleteOpPtr.p->m_op_bits;
- Uint32 op = opbits & Operationrec::OP_MASK;
- if (op == ZDELETE) {
- jam();
- /* -------------------------------------------------------------------
- * IF THE CURRENT OPERATION TO BE COMMITTED IS A DELETE OPERATION DUE TO
- * A SCAN-TAKEOVER THE ACTUAL DELETE WILL BE PERFORMED BY THE PREVIOUS
- * OPERATION (SCAN) IN THE PARALLEL QUEUE WHICH OWNS THE LOCK.
- * THE PROBLEM IS THAT THE SCAN OPERATION DOES NOT HAVE A HASH VALUE
- * ASSIGNED TO IT SO WE COPY IT FROM THIS OPERATION.
- *
- * WE ASSUME THAT THIS SOLUTION WILL WORK BECAUSE THE ONLY WAY A
- * SCAN CAN PERFORM A DELETE IS BY BEING FOLLOWED BY A NORMAL
- * DELETE-OPERATION THAT HAS A HASH VALUE.
- * ----------------------------------------------------------------- */
- hashValue = deleteOpPtr.p->hashValue;
- elementDeleted = Operationrec::OP_ELEMENT_DISAPPEARED;
- deleteCheckOngoing = false;
- } else if (op == ZREAD || op == ZSCAN_OP) {
- /* -------------------------------------------------------------------
- * We are trying to find out whether the commit will in the end delete
- * the tuple. Normally the delete will be the last operation in the
- * list of operations on this. It is however possible to issue reads
- * and scans in the same savepoint as the delete operation was issued
- * and these can end up after the delete in the list of operations
- * in the parallel queue. Thus if we discover a read or a scan
- * we have to continue scanning the list looking for a delete operation.
- */
- deleteOpPtr.i = deleteOpPtr.p->prevParallelQue;
- if (opbits & Operationrec::OP_LOCK_OWNER) {
- jam();
- deleteCheckOngoing = false;
- } else {
- jam();
- ptrCheckGuard(deleteOpPtr, coprecsize, operationrec);
- }//if
- } else {
- jam();
- /* ------------------------------------------------------------------ */
- /* Finding an UPDATE or INSERT before finding a DELETE
- * means we cannot be deleting as the end result of this transaction.
- */
- deleteCheckOngoing = false;
- }//if
- } while (deleteCheckOngoing);
- opPtr = lastOpPtr;
- do {
- jam();
- opPtr.p->m_op_bits |= Operationrec::OP_COMMIT_DELETE_CHECK;
- if (elementDeleted) {
- jam();
- opPtr.p->m_op_bits |= elementDeleted;
- opPtr.p->hashValue = hashValue;
- }//if
- opPtr.i = opPtr.p->prevParallelQue;
- if (opPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER) {
- jam();
- break;
- }//if
- ptrCheckGuard(opPtr, coprecsize, operationrec);
- } while (true);
-}//Dbacc::commitDeleteCheck()
-
-/* ------------------------------------------------------------------------- */
-/* COMMIT_OPERATION */
-/* INPUT: OPERATION_REC_PTR, POINTER TO AN OPERATION RECORD */
-/* DESCRIPTION: THE OPERATION RECORD WILL BE TAKE OUT OF ANY LOCK QUEUE. */
-/* IF IT OWNS THE ELEMENT LOCK. HEAD OF THE ELEMENT WILL BE UPDATED. */
-/* ------------------------------------------------------------------------- */
-void Dbacc::commitOperation(Signal* signal)
-{
- validate_lock_queue(operationRecPtr);
-
- Uint32 opbits = operationRecPtr.p->m_op_bits;
- Uint32 op = opbits & Operationrec::OP_MASK;
- ndbrequire((opbits & Operationrec::OP_STATE_MASK) == Operationrec::OP_STATE_EXECUTED);
- if ((opbits & Operationrec::OP_COMMIT_DELETE_CHECK) == 0 &&
- (op != ZREAD && op != ZSCAN_OP))
- {
- jam();
- /* This method is used to check whether the end result of the transaction
- will be to delete the tuple. In this case all operation will be marked
- with elementIsDisappeared = true to ensure that the last operation
- committed will remove the tuple. We only run this once per transaction
- (commitDeleteCheckFlag = true if performed earlier) and we don't
- execute this code when committing a scan operation since committing
- a scan operation only means that the scan is continuing and the scan
- lock is released.
- */
- commitDeleteCheck();
- opbits = operationRecPtr.p->m_op_bits;
- }//if
-
- ndbassert(opbits & Operationrec::OP_RUN_QUEUE);
-
- if (opbits & Operationrec::OP_LOCK_OWNER)
- {
- takeOutLockOwnersList(signal, operationRecPtr);
- opbits &= ~(Uint32)Operationrec::OP_LOCK_OWNER;
- operationRecPtr.p->m_op_bits = opbits;
-
- const bool queue = (operationRecPtr.p->nextParallelQue != RNIL ||
- operationRecPtr.p->nextSerialQue != RNIL);
-
- if (!queue && (opbits & Operationrec::OP_ELEMENT_DISAPPEARED) == 0)
- {
- /*
- * This is the normal path through the commit for operations owning the
- * lock without any queues and not a delete operation.
- */
- Page8Ptr coPageidptr;
- Uint32 tcoElementptr;
- Uint32 tmp2Olq;
-
- coPageidptr.i = operationRecPtr.p->elementPage;
- tcoElementptr = operationRecPtr.p->elementPointer;
- tmp2Olq = ElementHeader::setUnlocked(operationRecPtr.p->hashvaluePart,
- operationRecPtr.p->scanBits);
- ptrCheckGuard(coPageidptr, cpagesize, page8);
- dbgWord32(coPageidptr, tcoElementptr, tmp2Olq);
- arrGuard(tcoElementptr, 2048);
- coPageidptr.p->word32[tcoElementptr] = tmp2Olq;
- return;
- }
- else if (queue)
- {
- jam();
- /*
- * The case when there is a queue lined up.
- * Release the lock and pass it to the next operation lined up.
- */
- release_lockowner(signal, operationRecPtr, true);
- return;
- }
- else
- {
- jam();
- /*
- * No queue and elementIsDisappeared is true.
- * We perform the actual delete operation.
- */
- commitdelete(signal);
- return;
- }//if
- }
- else
- {
- /**
- * THE OPERATION DOES NOT OWN THE LOCK. IT MUST BE IN A LOCK QUEUE OF THE
- * ELEMENT.
- */
- jam();
- OperationrecPtr prev, next, lockOwner;
- prev.i = operationRecPtr.p->prevParallelQue;
- next.i = operationRecPtr.p->nextParallelQue;
- lockOwner.i = operationRecPtr.p->m_lock_owner_ptr_i;
- ptrCheckGuard(prev, coprecsize, operationrec);
-
- prev.p->nextParallelQue = next.i;
- if (next.i != RNIL)
- {
- jam();
- ptrCheckGuard(next, coprecsize, operationrec);
- next.p->prevParallelQue = prev.i;
- }
- else if (prev.p->m_op_bits & Operationrec::OP_LOCK_OWNER)
- {
- jam();
- ndbassert(lockOwner.i == prev.i);
- prev.p->m_lo_last_parallel_op_ptr_i = RNIL;
- next = prev;
- }
- else
- {
- jam();
- /**
- * Last operation in parallell queue
- */
- ndbassert(prev.i != lockOwner.i);
- ptrCheckGuard(lockOwner, coprecsize, operationrec);
- ndbassert(lockOwner.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
- lockOwner.p->m_lo_last_parallel_op_ptr_i = prev.i;
- prev.p->m_lock_owner_ptr_i = lockOwner.i;
- next = prev;
- }
-
- /**
- * Check possible lock upgrade
- */
- if(opbits & Operationrec::OP_ACC_LOCK_MODE)
- {
- jam();
-
- /**
- * Not lock owner...committing a exclusive operation...
- *
- * e.g
- * T1(R) T1(X)
- * T2(R/X)
- *
- * If T1(X) commits T2(R/X) is not supposed to run
- * as T1(R) should also commit
- *
- * e.g
- * T1(R) T1(X) T1*(R)
- * T2(R/X)
- *
- * If T1*(R) commits T2(R/X) is not supposed to run
- * as T1(R),T2(x) should also commit
- */
- validate_lock_queue(prev);
- return;
- }
-
- /**
- * We committed a shared lock
- * Check if we can start next...
- */
- while(next.p->nextParallelQue != RNIL)
- {
- jam();
- next.i = next.p->nextParallelQue;
- ptrCheckGuard(next, coprecsize, operationrec);
-
- if ((next.p->m_op_bits & Operationrec::OP_STATE_MASK) !=
- Operationrec::OP_STATE_EXECUTED)
- {
- jam();
- return;
- }
- }
-
- startNext(signal, next);
-
- validate_lock_queue(prev);
- }
-}//Dbacc::commitOperation()
-
-void
-Dbacc::release_lockowner(Signal* signal, OperationrecPtr opPtr, bool commit)
-{
- OperationrecPtr nextP;
- OperationrecPtr nextS;
- OperationrecPtr newOwner;
- OperationrecPtr lastP;
-
- Uint32 opbits = opPtr.p->m_op_bits;
- nextP.i = opPtr.p->nextParallelQue;
- nextS.i = opPtr.p->nextSerialQue;
- lastP.i = opPtr.p->m_lo_last_parallel_op_ptr_i;
- Uint32 lastS = opPtr.p->m_lo_last_serial_op_ptr_i;
-
- ndbassert(lastP.i != RNIL || lastS != RNIL);
- ndbassert(nextP.i != RNIL || nextS.i != RNIL);
-
- enum {
- NOTHING,
- CHECK_LOCK_UPGRADE,
- START_NEW
- } action = NOTHING;
-
- if (nextP.i != RNIL)
- {
- jam();
- ptrCheckGuard(nextP, coprecsize, operationrec);
- newOwner = nextP;
-
- if (lastP.i == newOwner.i)
- {
- newOwner.p->m_lo_last_parallel_op_ptr_i = RNIL;
- lastP = nextP;
- }
- else
- {
- ptrCheckGuard(lastP, coprecsize, operationrec);
- newOwner.p->m_lo_last_parallel_op_ptr_i = lastP.i;
- lastP.p->m_lock_owner_ptr_i = newOwner.i;
- }
-
- newOwner.p->m_lo_last_serial_op_ptr_i = lastS;
- newOwner.p->nextSerialQue = nextS.i;
-
- if (nextS.i != RNIL)
- {
- jam();
- ptrCheckGuard(nextS, coprecsize, operationrec);
- ndbassert(nextS.p->prevSerialQue == opPtr.i);
- nextS.p->prevSerialQue = newOwner.i;
- }
-
- if (commit)
- {
- if ((opbits & Operationrec::OP_ACC_LOCK_MODE) == ZREADLOCK)
- {
- jam();
- /**
- * Lock owner...committing a shared operation...
- * this can be a lock upgrade
- *
- * e.g
- * T1(R) T2(R)
- * T2(X)
- *
- * If T1(R) commits T2(X) is supposed to run
- *
- * e.g
- * T1(X) T1(R)
- * T2(R)
- *
- * If T1(X) commits, then T1(R) _should_ commit before T2(R) is
- * allowed to proceed
- */
- action = CHECK_LOCK_UPGRADE;
- }
- else
- {
- jam();
- newOwner.p->m_op_bits |= Operationrec::OP_LOCK_MODE;
- }
- }
- else
- {
- /**
- * Aborting an operation can *always* lead to lock upgrade
- */
- action = CHECK_LOCK_UPGRADE;
- Uint32 opstate = opbits & Operationrec::OP_STATE_MASK;
- if (opstate != Operationrec::OP_STATE_EXECUTED)
- {
- ndbassert(opstate == Operationrec::OP_STATE_RUNNING);
- if (opbits & Operationrec::OP_ELEMENT_DISAPPEARED)
- {
- jam();
- report_dealloc(signal, opPtr.p);
- newOwner.p->localdata[0] = ~(Uint32)0;
- }
- else
- {
- jam();
- newOwner.p->localdata[0] = opPtr.p->localdata[0];
- newOwner.p->localdata[1] = opPtr.p->localdata[1];
- }
- action = START_NEW;
- }
-
- /**
- * Update ACC_LOCK_MODE
- */
- if (opbits & Operationrec::OP_LOCK_MODE)
- {
- Uint32 nextbits = nextP.p->m_op_bits;
- while ((nextbits & Operationrec::OP_LOCK_MODE) == 0)
- {
- ndbassert(nextbits & Operationrec::OP_ACC_LOCK_MODE);
- nextbits &= ~(Uint32)Operationrec::OP_ACC_LOCK_MODE;
- nextP.p->m_op_bits = nextbits;
-
- if (nextP.p->nextParallelQue != RNIL)
- {
- nextP.i = nextP.p->nextParallelQue;
- ptrCheckGuard(nextP, coprecsize, operationrec);
- nextbits = nextP.p->m_op_bits;
- }
- else
- {
- break;
- }
- }
- }
- }
- }
- else
- {
- jam();
- ptrCheckGuard(nextS, coprecsize, operationrec);
- newOwner = nextS;
-
- newOwner.p->m_op_bits |= Operationrec::OP_RUN_QUEUE;
-
- if (opbits & Operationrec::OP_ELEMENT_DISAPPEARED)
- {
- report_dealloc(signal, opPtr.p);
- newOwner.p->localdata[0] = ~(Uint32)0;
- }
- else
- {
- jam();
- newOwner.p->localdata[0] = opPtr.p->localdata[0];
- newOwner.p->localdata[1] = opPtr.p->localdata[1];
- }
-
- lastP = newOwner;
- while (lastP.p->nextParallelQue != RNIL)
- {
- lastP.i = lastP.p->nextParallelQue;
- ptrCheckGuard(lastP, coprecsize, operationrec);
- lastP.p->m_op_bits |= Operationrec::OP_RUN_QUEUE;
- }
-
- if (newOwner.i != lastP.i)
- {
- jam();
- newOwner.p->m_lo_last_parallel_op_ptr_i = lastP.i;
- }
- else
- {
- jam();
- newOwner.p->m_lo_last_parallel_op_ptr_i = RNIL;
- }
-
- if (newOwner.i != lastS)
- {
- jam();
- newOwner.p->m_lo_last_serial_op_ptr_i = lastS;
- }
- else
- {
- jam();
- newOwner.p->m_lo_last_serial_op_ptr_i = RNIL;
- }
-
- action = START_NEW;
- }
-
- insertLockOwnersList(signal, newOwner);
-
- /**
- * Copy op info, and store op in element
- *
- */
- {
- newOwner.p->elementPage = opPtr.p->elementPage;
- newOwner.p->elementIsforward = opPtr.p->elementIsforward;
- newOwner.p->elementPointer = opPtr.p->elementPointer;
- newOwner.p->elementContainer = opPtr.p->elementContainer;
- newOwner.p->scanBits = opPtr.p->scanBits;
- newOwner.p->hashvaluePart = opPtr.p->hashvaluePart;
- newOwner.p->m_op_bits |= (opbits & Operationrec::OP_ELEMENT_DISAPPEARED);
- if (opbits & Operationrec::OP_ELEMENT_DISAPPEARED)
- {
- /* ------------------------------------------------------------------- */
- // If the elementIsDisappeared is set then we know that the
- // hashValue is also set since it always originates from a
- // committing abort or a aborting insert.
- // Scans do not initialise the hashValue and must have this
- // value initialised if they are
- // to successfully commit the delete.
- /* ------------------------------------------------------------------- */
- jam();
- newOwner.p->hashValue = opPtr.p->hashValue;
- }//if
-
- Page8Ptr pagePtr;
- pagePtr.i = newOwner.p->elementPage;
- ptrCheckGuard(pagePtr, cpagesize, page8);
- const Uint32 tmp = ElementHeader::setLocked(newOwner.i);
- arrGuard(newOwner.p->elementPointer, 2048);
- pagePtr.p->word32[newOwner.p->elementPointer] = tmp;
- }
-
- switch(action){
- case NOTHING:
- validate_lock_queue(newOwner);
- return;
- case START_NEW:
- startNew(signal, newOwner);
- validate_lock_queue(newOwner);
- return;
- case CHECK_LOCK_UPGRADE:
- startNext(signal, lastP);
- validate_lock_queue(lastP);
- break;
- }
-
-}
-
-void
-Dbacc::startNew(Signal* signal, OperationrecPtr newOwner)
-{
- OperationrecPtr save = operationRecPtr;
- operationRecPtr = newOwner;
-
- Uint32 opbits = newOwner.p->m_op_bits;
- Uint32 op = opbits & Operationrec::OP_MASK;
- Uint32 opstate = (opbits & Operationrec::OP_STATE_MASK);
- ndbassert(opstate == Operationrec::OP_STATE_WAITING);
- ndbassert(opbits & Operationrec::OP_LOCK_OWNER);
- const bool deleted = opbits & Operationrec::OP_ELEMENT_DISAPPEARED;
- Uint32 errCode = 0;
-
- opbits &= opbits & ~(Uint32)Operationrec::OP_STATE_MASK;
- opbits |= Operationrec::OP_STATE_RUNNING;
-
- if (op == ZSCAN_OP && (opbits & Operationrec::OP_LOCK_REQ) == 0)
- goto scan;
-
- if (deleted)
- {
- jam();
- if (op != ZINSERT && op != ZWRITE)
- {
- errCode = ZREAD_ERROR;
- goto ref;
- }
-
- opbits &= ~(Uint32)Operationrec::OP_MASK;
- opbits &= ~(Uint32)Operationrec::OP_ELEMENT_DISAPPEARED;
- opbits |= (op = ZINSERT);
- opbits |= Operationrec::OP_INSERT_IS_DONE;
- goto conf;
- }
- else if (op == ZINSERT)
- {
- jam();
- errCode = ZWRITE_ERROR;
- goto ref;
- }
- else if (op == ZWRITE)
- {
- jam();
- opbits &= ~(Uint32)Operationrec::OP_MASK;
- opbits |= (op = ZUPDATE);
- goto conf;
- }
-
-conf:
- newOwner.p->m_op_bits = opbits;
-
- sendAcckeyconf(signal);
- sendSignal(newOwner.p->userblockref, GSN_ACCKEYCONF,
- signal, 6, JBB);
-
- operationRecPtr = save;
- return;
-
-scan:
- jam();
- newOwner.p->m_op_bits = opbits;
-
- takeOutScanLockQueue(newOwner.p->scanRecPtr);
- putReadyScanQueue(signal, newOwner.p->scanRecPtr);
-
- operationRecPtr = save;
- return;
-
-ref:
- newOwner.p->m_op_bits = opbits;
-
- signal->theData[0] = newOwner.p->userptr;
- signal->theData[1] = errCode;
- sendSignal(newOwner.p->userblockref, GSN_ACCKEYREF, signal,
- 2, JBB);
-
- operationRecPtr = save;
- return;
-}
-
-/**
- * takeOutLockOwnersList
- *
- * Description: Take out an operation from the doubly linked
- * lock owners list on the fragment.
- *
- */
-void Dbacc::takeOutLockOwnersList(Signal* signal,
- const OperationrecPtr& outOperPtr)
-{
- const Uint32 Tprev = outOperPtr.p->prevLockOwnerOp;
- const Uint32 Tnext = outOperPtr.p->nextLockOwnerOp;
-#ifdef VM_TRACE
- // Check that operation is already in the list
- OperationrecPtr tmpOperPtr;
- bool inList = false;
- tmpOperPtr.i = fragrecptr.p->lockOwnersList;
- while (tmpOperPtr.i != RNIL){
- ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
- if (tmpOperPtr.i == outOperPtr.i)
- inList = true;
- tmpOperPtr.i = tmpOperPtr.p->nextLockOwnerOp;
- }
- ndbrequire(inList == true);
-#endif
-
- ndbassert(outOperPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER);
-
- // Fast path through the code for the common case.
- if ((Tprev == RNIL) && (Tnext == RNIL)) {
- ndbrequire(fragrecptr.p->lockOwnersList == outOperPtr.i);
- fragrecptr.p->lockOwnersList = RNIL;
- return;
- }
-
- // Check previous operation
- if (Tprev != RNIL) {
- jam();
- arrGuard(Tprev, coprecsize);
- operationrec[Tprev].nextLockOwnerOp = Tnext;
- } else {
- fragrecptr.p->lockOwnersList = Tnext;
- }//if
-
- // Check next operation
- if (Tnext == RNIL) {
- return;
- } else {
- jam();
- arrGuard(Tnext, coprecsize);
- operationrec[Tnext].prevLockOwnerOp = Tprev;
- }//if
-
- return;
-}//Dbacc::takeOutLockOwnersList()
-
-/**
- * insertLockOwnersList
- *
- * Description: Insert an operation first in the dubly linked lock owners
- * list on the fragment.
- *
- */
-void Dbacc::insertLockOwnersList(Signal* signal,
- const OperationrecPtr& insOperPtr)
-{
- OperationrecPtr tmpOperPtr;
-#ifdef VM_TRACE
- // Check that operation is not already in list
- tmpOperPtr.i = fragrecptr.p->lockOwnersList;
- while(tmpOperPtr.i != RNIL){
- ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
- ndbrequire(tmpOperPtr.i != insOperPtr.i);
- tmpOperPtr.i = tmpOperPtr.p->nextLockOwnerOp;
- }
-#endif
- tmpOperPtr.i = fragrecptr.p->lockOwnersList;
-
- ndbrequire(! (insOperPtr.p->m_op_bits & Operationrec::OP_LOCK_OWNER));
-
- insOperPtr.p->m_op_bits |= Operationrec::OP_LOCK_OWNER;
- insOperPtr.p->prevLockOwnerOp = RNIL;
- insOperPtr.p->nextLockOwnerOp = tmpOperPtr.i;
-
- fragrecptr.p->lockOwnersList = insOperPtr.i;
- if (tmpOperPtr.i == RNIL) {
- return;
- } else {
- jam();
- ptrCheckGuard(tmpOperPtr, coprecsize, operationrec);
- tmpOperPtr.p->prevLockOwnerOp = insOperPtr.i;
- }//if
-}//Dbacc::insertLockOwnersList()
-
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF COMMIT AND ABORT MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* ALLOC_OVERFLOW_PAGE */
-/* DESCRIPTION: */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::allocOverflowPage(Signal* signal)
-{
- DirRangePtr aopDirRangePtr;
- DirectoryarrayPtr aopOverflowDirptr;
- OverflowRecordPtr aopOverflowRecPtr;
- Uint32 taopTmp1;
- Uint32 taopTmp2;
- Uint32 taopTmp3;
-
- tresult = 0;
- if ((cfirstfreepage == RNIL) &&
- (cfreepage >= cpagesize)) {
- jam();
- zpagesize_error("Dbacc::allocOverflowPage");
- tresult = ZPAGESIZE_ERROR;
- return;
- }//if
- if (fragrecptr.p->firstFreeDirindexRec != RNIL) {
- jam();
- /* FRAGRECPTR:FIRST_FREE_DIRINDEX_REC POINTS */
- /* TO THE FIRST ELEMENT IN A FREE LIST OF THE */
- /* DIRECTORY INDEX WICH HAVE NULL AS PAGE */
- aopOverflowRecPtr.i = fragrecptr.p->firstFreeDirindexRec;
- ptrCheckGuard(aopOverflowRecPtr, coverflowrecsize, overflowRecord);
- troOverflowRecPtr.p = aopOverflowRecPtr.p;
- takeRecOutOfFreeOverdir(signal);
- } else if (cfirstfreeoverrec == RNIL) {
- jam();
- tresult = ZOVER_REC_ERROR;
- return;
- } else if ((cfirstfreedir == RNIL) &&
- (cdirarraysize <= cdirmemory)) {
- jam();
- tresult = ZDIRSIZE_ERROR;
- return;
- } else {
- jam();
- seizeOverRec(signal);
- aopOverflowRecPtr = sorOverflowRecPtr;
- aopOverflowRecPtr.p->dirindex = fragrecptr.p->lastOverIndex;
- }//if
- aopOverflowRecPtr.p->nextOverRec = RNIL;
- aopOverflowRecPtr.p->prevOverRec = RNIL;
- fragrecptr.p->firstOverflowRec = aopOverflowRecPtr.i;
- fragrecptr.p->lastOverflowRec = aopOverflowRecPtr.i;
- taopTmp1 = aopOverflowRecPtr.p->dirindex;
- aopDirRangePtr.i = fragrecptr.p->overflowdir;
- taopTmp2 = taopTmp1 >> 8;
- taopTmp3 = taopTmp1 & 0xff;
- ptrCheckGuard(aopDirRangePtr, cdirrangesize, dirRange);
- arrGuard(taopTmp2, 256);
- if (aopDirRangePtr.p->dirArray[taopTmp2] == RNIL) {
- jam();
- seizeDirectory(signal);
- ndbrequire(tresult <= ZLIMIT_OF_ERROR);
- aopDirRangePtr.p->dirArray[taopTmp2] = sdDirptr.i;
- }//if
- aopOverflowDirptr.i = aopDirRangePtr.p->dirArray[taopTmp2];
- seizePage(signal);
- ndbrequire(tresult <= ZLIMIT_OF_ERROR);
- ptrCheckGuard(aopOverflowDirptr, cdirarraysize, directoryarray);
- aopOverflowDirptr.p->pagep[taopTmp3] = spPageptr.i;
- tiopPageId = aopOverflowRecPtr.p->dirindex;
- iopOverflowRecPtr = aopOverflowRecPtr;
- iopPageptr = spPageptr;
- initOverpage(signal);
- aopOverflowRecPtr.p->overpage = spPageptr.i;
- if (fragrecptr.p->lastOverIndex <= aopOverflowRecPtr.p->dirindex) {
- jam();
- ndbrequire(fragrecptr.p->lastOverIndex == aopOverflowRecPtr.p->dirindex);
- fragrecptr.p->lastOverIndex++;
- }//if
-}//Dbacc::allocOverflowPage()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* EXPAND/SHRINK MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/*EXPANDCHECK EXPAND BUCKET ORD */
-/* SENDER: ACC, LEVEL B */
-/* INPUT: FRAGRECPTR, POINTS TO A FRAGMENT RECORD. */
-/* DESCRIPTION: A BUCKET OF A FRAGMENT PAGE WILL BE EXPAND INTO TWO BUCKETS */
-/* ACCORDING TO LH3. */
-/* ******************--------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* EXPANDCHECK EXPAND BUCKET ORD */
-/* ******************------------------------------+ */
-/* SENDER: ACC, LEVEL B */
-/* A BUCKET OF THE FRAGMENT WILL */
-/* BE EXPANDED ACORDING TO LH3, */
-/* AND COMMIT TRANSACTION PROCESS */
-/* WILL BE CONTINUED */
-Uint32 Dbacc::checkScanExpand(Signal* signal)
-{
- Uint32 Ti;
- Uint32 TreturnCode = 0;
- Uint32 TPageIndex;
- Uint32 TDirInd;
- Uint32 TSplit;
- Uint32 TreleaseInd = 0;
- Uint32 TreleaseScanBucket;
- Uint32 TreleaseScanIndicator[4];
- DirectoryarrayPtr TDirptr;
- DirRangePtr TDirRangePtr;
- Page8Ptr TPageptr;
- ScanRecPtr TscanPtr;
-
- TSplit = fragrecptr.p->p;
- for (Ti = 0; Ti < 4; Ti++) {
- TreleaseScanIndicator[Ti] = 0;
- if (fragrecptr.p->scan[Ti] != RNIL) {
- //-------------------------------------------------------------
- // A scan is ongoing on this particular local fragment. We have
- // to check its current state.
- //-------------------------------------------------------------
- TscanPtr.i = fragrecptr.p->scan[Ti];
- ptrCheckGuard(TscanPtr, cscanRecSize, scanRec);
- if (TscanPtr.p->activeLocalFrag == fragrecptr.i) {
- if (TscanPtr.p->scanBucketState == ScanRec::FIRST_LAP) {
- if (TSplit == TscanPtr.p->nextBucketIndex) {
- jam();
- //-------------------------------------------------------------
- // We are currently scanning this bucket. We cannot split it
- // simultaneously with the scan. We have to pass this offer for
- // splitting the bucket.
- //-------------------------------------------------------------
- TreturnCode = 1;
- return TreturnCode;
- } else if (TSplit > TscanPtr.p->nextBucketIndex) {
- jam();
- //-------------------------------------------------------------
- // This bucket has not yet been scanned. We must reset the scanned
- // bit indicator for this scan on this bucket.
- //-------------------------------------------------------------
- TreleaseScanIndicator[Ti] = 1;
- TreleaseInd = 1;
- } else {
- jam();
- }//if
- } else if (TscanPtr.p->scanBucketState == ScanRec::SECOND_LAP) {
- jam();
- //-------------------------------------------------------------
- // We are performing a second lap to handle buckets that was
- // merged during the first lap of scanning. During this second
- // lap we do not allow any splits or merges.
- //-------------------------------------------------------------
- TreturnCode = 1;
- return TreturnCode;
- } else {
- ndbrequire(TscanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED);
- jam();
- //-------------------------------------------------------------
- // The scan is completed and we can thus go ahead and perform
- // the split.
- //-------------------------------------------------------------
- }//if
- }//if
- }//if
- }//for
- if (TreleaseInd == 1) {
- TreleaseScanBucket = TSplit;
- TDirRangePtr.i = fragrecptr.p->directory;
- TPageIndex = TreleaseScanBucket & ((1 << fragrecptr.p->k) - 1); /* PAGE INDEX OBS K = 6 */
- TDirInd = TreleaseScanBucket >> fragrecptr.p->k; /* DIRECTORY INDEX OBS K = 6 */
- ptrCheckGuard(TDirRangePtr, cdirrangesize, dirRange);
- arrGuard((TDirInd >> 8), 256);
- TDirptr.i = TDirRangePtr.p->dirArray[TDirInd >> 8];
- ptrCheckGuard(TDirptr, cdirarraysize, directoryarray);
- TPageptr.i = TDirptr.p->pagep[TDirInd & 0xff];
- ptrCheckGuard(TPageptr, cpagesize, page8);
- for (Ti = 0; Ti < 4; Ti++) {
- if (TreleaseScanIndicator[Ti] == 1) {
- jam();
- scanPtr.i = fragrecptr.p->scan[Ti];
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
- rsbPageidptr = TPageptr;
- trsbPageindex = TPageIndex;
- releaseScanBucket(signal);
- }//if
- }//for
- }//if
- return TreturnCode;
-}//Dbacc::checkScanExpand()
-
-void Dbacc::execEXPANDCHECK2(Signal* signal)
-{
- jamEntry();
-
- if(refToBlock(signal->getSendersBlockRef()) == DBLQH)
- {
- jam();
- return;
- }
-
- DirectoryarrayPtr newDirptr;
-
- fragrecptr.i = signal->theData[0];
- tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
- Uint32 tmp = 1;
- tmp = tmp << 31;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- fragrecptr.p->expandFlag = 0;
- if (fragrecptr.p->slack < tmp) {
- jam();
- /* IT MEANS THAT IF SLACK > ZERO */
- /*--------------------------------------------------------------*/
- /* THE SLACK HAS IMPROVED AND IS NOW ACCEPTABLE AND WE */
- /* CAN FORGET ABOUT THE EXPAND PROCESS. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- if (fragrecptr.p->firstOverflowRec == RNIL) {
- jam();
- allocOverflowPage(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- /*--------------------------------------------------------------*/
- /* WE COULD NOT ALLOCATE ANY OVERFLOW PAGE. THUS WE HAVE TO STOP*/
- /* THE EXPAND SINCE WE CANNOT GUARANTEE ITS COMPLETION. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- }//if
- if (cfirstfreepage == RNIL) {
- if (cfreepage >= cpagesize) {
- jam();
- /*--------------------------------------------------------------*/
- /* WE HAVE TO STOP THE EXPAND PROCESS SINCE THERE ARE NO FREE */
- /* PAGES. THIS MEANS THAT WE COULD BE FORCED TO CRASH SINCE WE */
- /* CANNOT COMPLETE THE EXPAND. TO AVOID THE CRASH WE EXIT HERE. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- }//if
- if (checkScanExpand(signal) == 1) {
- jam();
- /*--------------------------------------------------------------*/
- // A scan state was inconsistent with performing an expand
- // operation.
- /*--------------------------------------------------------------*/
- return;
- }//if
-
- /*--------------------------------------------------------------------------*/
- /* WE START BY FINDING THE PAGE, THE PAGE INDEX AND THE PAGE DIRECTORY*/
- /* OF THE NEW BUCKET WHICH SHALL RECEIVE THE ELEMENT WHICH HAVE A 1 IN*/
- /* THE NEXT HASH BIT. THIS BIT IS USED IN THE SPLIT MECHANISM TO */
- /* DECIDE WHICH ELEMENT GOES WHERE. */
- /*--------------------------------------------------------------------------*/
- expDirRangePtr.i = fragrecptr.p->directory;
- texpReceivedBucket = (fragrecptr.p->maxp + fragrecptr.p->p) + 1; /* RECEIVED BUCKET */
- texpDirInd = texpReceivedBucket >> fragrecptr.p->k;
- newDirptr.i = RNIL;
- ptrNull(newDirptr);
- texpDirRangeIndex = texpDirInd >> 8;
- ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange);
- arrGuard(texpDirRangeIndex, 256);
- expDirptr.i = expDirRangePtr.p->dirArray[texpDirRangeIndex];
- if (expDirptr.i == RNIL) {
- jam();
- seizeDirectory(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- return;
- } else {
- jam();
- newDirptr = sdDirptr;
- expDirptr = sdDirptr;
- expDirRangePtr.p->dirArray[texpDirRangeIndex] = sdDirptr.i;
- }//if
- } else {
- ptrCheckGuard(expDirptr, cdirarraysize, directoryarray);
- }//if
- texpDirPageIndex = texpDirInd & 0xff;
- expPageptr.i = expDirptr.p->pagep[texpDirPageIndex];
- if (expPageptr.i == RNIL) {
- jam();
- seizePage(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- if (newDirptr.i != RNIL) {
- jam();
- rdDirptr.i = newDirptr.i;
- releaseDirectory(signal);
- }//if
- return;
- }//if
- expDirptr.p->pagep[texpDirPageIndex] = spPageptr.i;
- tipPageId = texpDirInd;
- inpPageptr = spPageptr;
- initPage(signal);
- fragrecptr.p->dirsize++;
- expPageptr = spPageptr;
- } else {
- ptrCheckGuard(expPageptr, cpagesize, page8);
- }//if
-
- fragrecptr.p->expReceivePageptr = expPageptr.i;
- fragrecptr.p->expReceiveIndex = texpReceivedBucket & ((1 << fragrecptr.p->k) - 1);
- /*--------------------------------------------------------------------------*/
- /* THE NEXT ACTION IS TO FIND THE PAGE, THE PAGE INDEX AND THE PAGE */
- /* DIRECTORY OF THE BUCKET TO BE SPLIT. */
- /*--------------------------------------------------------------------------*/
- expDirRangePtr.i = fragrecptr.p->directory;
- cexcPageindex = fragrecptr.p->p & ((1 << fragrecptr.p->k) - 1); /* PAGE INDEX OBS K = 6 */
- texpDirInd = fragrecptr.p->p >> fragrecptr.p->k; /* DIRECTORY INDEX OBS K = 6 */
- ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange);
- arrGuard((texpDirInd >> 8), 256);
- expDirptr.i = expDirRangePtr.p->dirArray[texpDirInd >> 8];
- ptrCheckGuard(expDirptr, cdirarraysize, directoryarray);
- excPageptr.i = expDirptr.p->pagep[texpDirInd & 0xff];
- fragrecptr.p->expSenderIndex = cexcPageindex;
- fragrecptr.p->expSenderPageptr = excPageptr.i;
- if (excPageptr.i == RNIL) {
- jam();
- endofexpLab(signal); /* EMPTY BUCKET */
- return;
- }//if
- fragrecptr.p->expReceiveForward = ZTRUE;
- ptrCheckGuard(excPageptr, cpagesize, page8);
- expandcontainer(signal);
- endofexpLab(signal);
- return;
-}//Dbacc::execEXPANDCHECK2()
-
-void Dbacc::endofexpLab(Signal* signal)
-{
- fragrecptr.p->p++;
- fragrecptr.p->slack += fragrecptr.p->maxloadfactor;
- fragrecptr.p->expandCounter++;
- if (fragrecptr.p->p > fragrecptr.p->maxp) {
- jam();
- fragrecptr.p->maxp = (fragrecptr.p->maxp << 1) | 1;
- fragrecptr.p->lhdirbits++;
- fragrecptr.p->hashcheckbit++;
- fragrecptr.p->p = 0;
- }//if
- Uint32 noOfBuckets = (fragrecptr.p->maxp + 1) + fragrecptr.p->p;
- Uint32 Thysteres = fragrecptr.p->maxloadfactor - fragrecptr.p->minloadfactor;
- fragrecptr.p->slackCheck = noOfBuckets * Thysteres;
- if (fragrecptr.p->slack > (1u << 31)) {
- jam();
- /* IT MEANS THAT IF SLACK < ZERO */
- /* --------------------------------------------------------------------------------- */
- /* IT IS STILL NECESSARY TO EXPAND THE FRAGMENT EVEN MORE. START IT FROM HERE */
- /* WITHOUT WAITING FOR NEXT COMMIT ON THE FRAGMENT. */
- /* --------------------------------------------------------------------------------- */
- fragrecptr.p->expandFlag = 2;
- signal->theData[0] = fragrecptr.i;
- signal->theData[1] = fragrecptr.p->p;
- signal->theData[2] = fragrecptr.p->maxp;
- sendSignal(cownBlockref, GSN_EXPANDCHECK2, signal, 3, JBB);
- }//if
- return;
-}//Dbacc::endofexpLab()
-
-void Dbacc::reenable_expand_after_redo_log_exection_complete(Signal* signal){
-
- tabptr.i = signal->theData[0];
- Uint32 fragId = signal->theData[1];
-
- ptrCheckGuard(tabptr, ctablesize, tabrec);
- ndbrequire(getfragmentrec(signal, fragrecptr, fragId));
-#if 0
- ndbout_c("reenable expand check for table %d fragment: %d",
- tabptr.i, fragId);
-#endif
-
- switch(fragrecptr.p->expandFlag){
- case 0:
- /**
- * Hmm... this means that it's alreay has been reenabled...
- */
- fragrecptr.p->expandFlag = 1;
- break;
- case 1:
- /**
- * Nothing is going on start expand check
- */
- case 2:
- /**
- * A shrink is running, do expand check anyway
- * (to reset expandFlag)
- */
- fragrecptr.p->expandFlag = 2;
- signal->theData[0] = fragrecptr.i;
- signal->theData[1] = fragrecptr.p->p;
- signal->theData[2] = fragrecptr.p->maxp;
- sendSignal(cownBlockref, GSN_EXPANDCHECK2, signal, 3, JBB);
- break;
- }
-}
-
-void Dbacc::execDEBUG_SIG(Signal* signal)
-{
- jamEntry();
- expPageptr.i = signal->theData[0];
-
- progError(__LINE__, NDBD_EXIT_SR_UNDOLOG);
- return;
-}//Dbacc::execDEBUG_SIG()
-
-/* --------------------------------------------------------------------------------- */
-/* EXPANDCONTAINER */
-/* INPUT: EXC_PAGEPTR (POINTER TO THE ACTIVE PAGE RECORD) */
-/* CEXC_PAGEINDEX (INDEX OF THE BUCKET). */
-/* */
-/* DESCRIPTION: THE HASH VALUE OF ALL ELEMENTS IN THE CONTAINER WILL BE */
-/* CHECKED. SOME OF THIS ELEMENTS HAVE TO MOVE TO THE NEW CONTAINER */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::expandcontainer(Signal* signal)
-{
- Uint32 texcHashvalue;
- Uint32 texcTmp;
- Uint32 texcIndex;
- Uint32 guard20;
-
- cexcPrevpageptr = RNIL;
- cexcPrevconptr = 0;
- cexcForward = ZTRUE;
- EXP_CONTAINER_LOOP:
- cexcContainerptr = (cexcPageindex << ZSHIFT_PLUS) - (cexcPageindex << ZSHIFT_MINUS);
- if (cexcForward == ZTRUE) {
- jam();
- cexcContainerptr = cexcContainerptr + ZHEAD_SIZE;
- cexcElementptr = cexcContainerptr + ZCON_HEAD_SIZE;
- } else {
- jam();
- cexcContainerptr = ((cexcContainerptr + ZHEAD_SIZE) + ZBUF_SIZE) - ZCON_HEAD_SIZE;
- cexcElementptr = cexcContainerptr - 1;
- }//if
- arrGuard(cexcContainerptr, 2048);
- cexcContainerhead = excPageptr.p->word32[cexcContainerptr];
- cexcContainerlen = cexcContainerhead >> 26;
- cexcMovedLen = ZCON_HEAD_SIZE;
- if (cexcContainerlen <= ZCON_HEAD_SIZE) {
- ndbrequire(cexcContainerlen >= ZCON_HEAD_SIZE);
- jam();
- goto NEXT_ELEMENT;
- }//if
- NEXT_ELEMENT_LOOP:
- idrOperationRecPtr.i = RNIL;
- ptrNull(idrOperationRecPtr);
- /* --------------------------------------------------------------------------------- */
- /* CEXC_PAGEINDEX PAGE INDEX OF CURRENT CONTAINER BEING EXAMINED. */
- /* CEXC_CONTAINERPTR INDEX OF CURRENT CONTAINER BEING EXAMINED. */
- /* CEXC_ELEMENTPTR INDEX OF CURRENT ELEMENT BEING EXAMINED. */
- /* EXC_PAGEPTR PAGE WHERE CURRENT ELEMENT RESIDES. */
- /* CEXC_PREVPAGEPTR PAGE OF PREVIOUS CONTAINER. */
- /* CEXC_PREVCONPTR INDEX OF PREVIOUS CONTAINER */
- /* CEXC_FORWARD DIRECTION OF CURRENT CONTAINER */
- /* --------------------------------------------------------------------------------- */
- arrGuard(cexcElementptr, 2048);
- tidrElemhead = excPageptr.p->word32[cexcElementptr];
- if (ElementHeader::getUnlocked(tidrElemhead)){
- jam();
- texcHashvalue = ElementHeader::getHashValuePart(tidrElemhead);
- } else {
- jam();
- idrOperationRecPtr.i = ElementHeader::getOpPtrI(tidrElemhead);
- ptrCheckGuard(idrOperationRecPtr, coprecsize, operationrec);
- texcHashvalue = idrOperationRecPtr.p->hashvaluePart;
- }//if
- if (((texcHashvalue >> fragrecptr.p->hashcheckbit) & 1) == 0) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THIS ELEMENT IS NOT TO BE MOVED. WE CALCULATE THE WHEREABOUTS OF THE NEXT */
- /* ELEMENT AND PROCEED WITH THAT OR END THE SEARCH IF THERE ARE NO MORE */
- /* ELEMENTS IN THIS CONTAINER. */
- /* --------------------------------------------------------------------------------- */
- goto NEXT_ELEMENT;
- }//if
- /* --------------------------------------------------------------------------------- */
- /* THE HASH BIT WAS SET AND WE SHALL MOVE THIS ELEMENT TO THE NEW BUCKET. */
- /* WE START BY READING THE ELEMENT TO BE ABLE TO INSERT IT INTO THE NEW BUCKET.*/
- /* THEN WE INSERT THE ELEMENT INTO THE NEW BUCKET. THE NEXT STEP IS TO DELETE */
- /* THE ELEMENT FROM THIS BUCKET. THIS IS PERFORMED BY REPLACING IT WITH THE */
- /* LAST ELEMENT IN THE BUCKET. IF THIS ELEMENT IS TO BE MOVED WE MOVE IT AND */
- /* GET THE LAST ELEMENT AGAIN UNTIL WE EITHER FIND ONE THAT STAYS OR THIS */
- /* ELEMENT IS THE LAST ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- texcTmp = cexcElementptr + cexcForward;
- guard20 = fragrecptr.p->localkeylen - 1;
- for (texcIndex = 0; texcIndex <= guard20; texcIndex++) {
- arrGuard(texcIndex, 2);
- arrGuard(texcTmp, 2048);
- clocalkey[texcIndex] = excPageptr.p->word32[texcTmp];
- texcTmp = texcTmp + cexcForward;
- }//for
- tidrPageindex = fragrecptr.p->expReceiveIndex;
- idrPageptr.i = fragrecptr.p->expReceivePageptr;
- ptrCheckGuard(idrPageptr, cpagesize, page8);
- tidrForward = fragrecptr.p->expReceiveForward;
- insertElement(signal);
- fragrecptr.p->expReceiveIndex = tidrPageindex;
- fragrecptr.p->expReceivePageptr = idrPageptr.i;
- fragrecptr.p->expReceiveForward = tidrForward;
- REMOVE_LAST_LOOP:
- jam();
- lastPageptr.i = excPageptr.i;
- lastPageptr.p = excPageptr.p;
- tlastContainerptr = cexcContainerptr;
- lastPrevpageptr.i = cexcPrevpageptr;
- ptrCheck(lastPrevpageptr, cpagesize, page8);
- tlastPrevconptr = cexcPrevconptr;
- arrGuard(tlastContainerptr, 2048);
- tlastContainerhead = lastPageptr.p->word32[tlastContainerptr];
- tlastContainerlen = tlastContainerhead >> 26;
- tlastForward = cexcForward;
- tlastPageindex = cexcPageindex;
- getLastAndRemove(signal);
- if (excPageptr.i == lastPageptr.i) {
- if (cexcElementptr == tlastElementptr) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE CURRENT ELEMENT WAS ALSO THE LAST ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- return;
- }//if
- }//if
- /* --------------------------------------------------------------------------------- */
- /* THE CURRENT ELEMENT WAS NOT THE LAST ELEMENT. IF THE LAST ELEMENT SHOULD */
- /* STAY WE COPY IT TO THE POSITION OF THE CURRENT ELEMENT, OTHERWISE WE INSERT */
- /* INTO THE NEW BUCKET, REMOVE IT AND TRY WITH THE NEW LAST ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- idrOperationRecPtr.i = RNIL;
- ptrNull(idrOperationRecPtr);
- arrGuard(tlastElementptr, 2048);
- tidrElemhead = lastPageptr.p->word32[tlastElementptr];
- if (ElementHeader::getUnlocked(tidrElemhead)) {
- jam();
- texcHashvalue = ElementHeader::getHashValuePart(tidrElemhead);
- } else {
- jam();
- idrOperationRecPtr.i = ElementHeader::getOpPtrI(tidrElemhead);
- ptrCheckGuard(idrOperationRecPtr, coprecsize, operationrec);
- texcHashvalue = idrOperationRecPtr.p->hashvaluePart;
- }//if
- if (((texcHashvalue >> fragrecptr.p->hashcheckbit) & 1) == 0) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE LAST ELEMENT IS NOT TO BE MOVED. WE COPY IT TO THE CURRENT ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- delPageptr = excPageptr;
- tdelContainerptr = cexcContainerptr;
- tdelForward = cexcForward;
- tdelElementptr = cexcElementptr;
- deleteElement(signal);
- } else {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* THE LAST ELEMENT IS ALSO TO BE MOVED. */
- /* --------------------------------------------------------------------------------- */
- texcTmp = tlastElementptr + tlastForward;
- for (texcIndex = 0; texcIndex < fragrecptr.p->localkeylen; texcIndex++) {
- arrGuard(texcIndex, 2);
- arrGuard(texcTmp, 2048);
- clocalkey[texcIndex] = lastPageptr.p->word32[texcTmp];
- texcTmp = texcTmp + tlastForward;
- }//for
- tidrPageindex = fragrecptr.p->expReceiveIndex;
- idrPageptr.i = fragrecptr.p->expReceivePageptr;
- ptrCheckGuard(idrPageptr, cpagesize, page8);
- tidrForward = fragrecptr.p->expReceiveForward;
- insertElement(signal);
- fragrecptr.p->expReceiveIndex = tidrPageindex;
- fragrecptr.p->expReceivePageptr = idrPageptr.i;
- fragrecptr.p->expReceiveForward = tidrForward;
- goto REMOVE_LAST_LOOP;
- }//if
- NEXT_ELEMENT:
- arrGuard(cexcContainerptr, 2048);
- cexcContainerhead = excPageptr.p->word32[cexcContainerptr];
- cexcMovedLen = cexcMovedLen + fragrecptr.p->elementLength;
- if ((cexcContainerhead >> 26) > cexcMovedLen) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* WE HAVE NOT YET MOVED THE COMPLETE CONTAINER. WE PROCEED WITH THE NEXT */
- /* ELEMENT IN THE CONTAINER. IT IS IMPORTANT TO READ THE CONTAINER LENGTH */
- /* FROM THE CONTAINER HEADER SINCE IT MIGHT CHANGE BY REMOVING THE LAST */
- /* ELEMENT IN THE BUCKET. */
- /* --------------------------------------------------------------------------------- */
- cexcElementptr = cexcElementptr + (cexcForward * fragrecptr.p->elementLength);
- goto NEXT_ELEMENT_LOOP;
- }//if
- if (((cexcContainerhead >> 7) & 3) != 0) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* WE PROCEED TO THE NEXT CONTAINER IN THE BUCKET. */
- /* --------------------------------------------------------------------------------- */
- cexcPrevpageptr = excPageptr.i;
- cexcPrevconptr = cexcContainerptr;
- nextcontainerinfoExp(signal);
- goto EXP_CONTAINER_LOOP;
- }//if
-}//Dbacc::expandcontainer()
-
-/* ******************--------------------------------------------------------------- */
-/* SHRINKCHECK JOIN BUCKET ORD */
-/* SENDER: ACC, LEVEL B */
-/* INPUT: FRAGRECPTR, POINTS TO A FRAGMENT RECORD. */
-/* DESCRIPTION: TWO BUCKET OF A FRAGMENT PAGE WILL BE JOINED TOGETHER */
-/* ACCORDING TO LH3. */
-/* ******************--------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* SHRINKCHECK JOIN BUCKET ORD */
-/* ******************------------------------------+ */
-/* SENDER: ACC, LEVEL B */
-/* TWO BUCKETS OF THE FRAGMENT */
-/* WILL BE JOINED ACORDING TO LH3 */
-/* AND COMMIT TRANSACTION PROCESS */
-/* WILL BE CONTINUED */
-Uint32 Dbacc::checkScanShrink(Signal* signal)
-{
- Uint32 Ti;
- Uint32 TreturnCode = 0;
- Uint32 TPageIndex;
- Uint32 TDirInd;
- Uint32 TmergeDest;
- Uint32 TmergeSource;
- Uint32 TreleaseScanBucket;
- Uint32 TreleaseInd = 0;
- Uint32 TreleaseScanIndicator[4];
- DirectoryarrayPtr TDirptr;
- DirRangePtr TDirRangePtr;
- Page8Ptr TPageptr;
- ScanRecPtr TscanPtr;
-
- if (fragrecptr.p->p == 0) {
- jam();
- TmergeDest = fragrecptr.p->maxp >> 1;
- } else {
- jam();
- TmergeDest = fragrecptr.p->p - 1;
- }//if
- TmergeSource = fragrecptr.p->maxp + fragrecptr.p->p;
- for (Ti = 0; Ti < 4; Ti++) {
- TreleaseScanIndicator[Ti] = 0;
- if (fragrecptr.p->scan[Ti] != RNIL) {
- TscanPtr.i = fragrecptr.p->scan[Ti];
- ptrCheckGuard(TscanPtr, cscanRecSize, scanRec);
- if (TscanPtr.p->activeLocalFrag == fragrecptr.i) {
- //-------------------------------------------------------------
- // A scan is ongoing on this particular local fragment. We have
- // to check its current state.
- //-------------------------------------------------------------
- if (TscanPtr.p->scanBucketState == ScanRec::FIRST_LAP) {
- jam();
- if ((TmergeDest == TscanPtr.p->nextBucketIndex) ||
- (TmergeSource == TscanPtr.p->nextBucketIndex)) {
- jam();
- //-------------------------------------------------------------
- // We are currently scanning one of the buckets involved in the
- // merge. We cannot merge while simultaneously performing a scan.
- // We have to pass this offer for merging the buckets.
- //-------------------------------------------------------------
- TreturnCode = 1;
- return TreturnCode;
- } else if (TmergeDest < TscanPtr.p->nextBucketIndex) {
- jam();
- TreleaseScanIndicator[Ti] = 1;
- TreleaseInd = 1;
- }//if
- } else if (TscanPtr.p->scanBucketState == ScanRec::SECOND_LAP) {
- jam();
- //-------------------------------------------------------------
- // We are performing a second lap to handle buckets that was
- // merged during the first lap of scanning. During this second
- // lap we do not allow any splits or merges.
- //-------------------------------------------------------------
- TreturnCode = 1;
- return TreturnCode;
- } else if (TscanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED) {
- jam();
- //-------------------------------------------------------------
- // The scan is completed and we can thus go ahead and perform
- // the split.
- //-------------------------------------------------------------
- } else {
- jam();
- sendSystemerror(signal, __LINE__);
- return TreturnCode;
- }//if
- }//if
- }//if
- }//for
- if (TreleaseInd == 1) {
- jam();
- TreleaseScanBucket = TmergeSource;
- TDirRangePtr.i = fragrecptr.p->directory;
- TPageIndex = TreleaseScanBucket & ((1 << fragrecptr.p->k) - 1); /* PAGE INDEX OBS K = 6 */
- TDirInd = TreleaseScanBucket >> fragrecptr.p->k; /* DIRECTORY INDEX OBS K = 6 */
- ptrCheckGuard(TDirRangePtr, cdirrangesize, dirRange);
- arrGuard((TDirInd >> 8), 256);
- TDirptr.i = TDirRangePtr.p->dirArray[TDirInd >> 8];
- ptrCheckGuard(TDirptr, cdirarraysize, directoryarray);
- TPageptr.i = TDirptr.p->pagep[TDirInd & 0xff];
- ptrCheckGuard(TPageptr, cpagesize, page8);
- for (Ti = 0; Ti < 4; Ti++) {
- if (TreleaseScanIndicator[Ti] == 1) {
- jam();
- scanPtr.i = fragrecptr.p->scan[Ti];
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
- rsbPageidptr.i = TPageptr.i;
- rsbPageidptr.p = TPageptr.p;
- trsbPageindex = TPageIndex;
- releaseScanBucket(signal);
- if (TmergeDest < scanPtr.p->minBucketIndexToRescan) {
- jam();
- //-------------------------------------------------------------
- // We have to keep track of the starting bucket to Rescan in the
- // second lap.
- //-------------------------------------------------------------
- scanPtr.p->minBucketIndexToRescan = TmergeDest;
- }//if
- if (TmergeDest > scanPtr.p->maxBucketIndexToRescan) {
- jam();
- //-------------------------------------------------------------
- // We have to keep track of the ending bucket to Rescan in the
- // second lap.
- //-------------------------------------------------------------
- scanPtr.p->maxBucketIndexToRescan = TmergeDest;
- }//if
- }//if
- }//for
- }//if
- return TreturnCode;
-}//Dbacc::checkScanShrink()
-
-void Dbacc::execSHRINKCHECK2(Signal* signal)
-{
- Uint32 tshrTmp1;
-
- jamEntry();
- fragrecptr.i = signal->theData[0];
- Uint32 oldFlag = signal->theData[3];
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- fragrecptr.p->expandFlag = oldFlag;
- tresult = 0; /* 0= FALSE,1= TRUE,> ZLIMIT_OF_ERROR =ERRORCODE */
- if (fragrecptr.p->slack <= fragrecptr.p->slackCheck) {
- jam();
- /* TIME FOR JOIN BUCKETS PROCESS */
- /*--------------------------------------------------------------*/
- /* NO LONGER NECESSARY TO SHRINK THE FRAGMENT. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- if (fragrecptr.p->slack > (1u << 31)) {
- jam();
- /*--------------------------------------------------------------*/
- /* THE SLACK IS NEGATIVE, IN THIS CASE WE WILL NOT NEED ANY */
- /* SHRINK. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- texpDirInd = (fragrecptr.p->maxp + fragrecptr.p->p) >> fragrecptr.p->k;
- if (fragrecptr.p->firstOverflowRec == RNIL) {
- jam();
- allocOverflowPage(signal);
- if (tresult > ZLIMIT_OF_ERROR) {
- jam();
- return;
- }//if
- }//if
- if (cfirstfreepage == RNIL) {
- if (cfreepage >= cpagesize) {
- jam();
- /*--------------------------------------------------------------*/
- /* WE HAVE TO STOP THE SHRINK PROCESS SINCE THERE ARE NO FREE */
- /* PAGES. THIS MEANS THAT WE COULD BE FORCED TO CRASH SINCE WE */
- /* CANNOT COMPLETE THE SHRINK. TO AVOID THE CRASH WE EXIT HERE. */
- /*--------------------------------------------------------------*/
- return;
- }//if
- }//if
- if (checkScanShrink(signal) == 1) {
- jam();
- /*--------------------------------------------------------------*/
- // A scan state was inconsistent with performing a shrink
- // operation.
- /*--------------------------------------------------------------*/
- return;
- }//if
- if (fragrecptr.p->p == 0) {
- jam();
- fragrecptr.p->maxp = fragrecptr.p->maxp >> 1;
- fragrecptr.p->p = fragrecptr.p->maxp;
- fragrecptr.p->lhdirbits--;
- fragrecptr.p->hashcheckbit--;
- } else {
- jam();
- fragrecptr.p->p--;
- }//if
-
- /*--------------------------------------------------------------------------*/
- /* WE START BY FINDING THE NECESSARY INFORMATION OF THE BUCKET TO BE */
- /* REMOVED WHICH WILL SEND ITS ELEMENTS TO THE RECEIVING BUCKET. */
- /*--------------------------------------------------------------------------*/
- expDirRangePtr.i = fragrecptr.p->directory;
- cexcPageindex = ((fragrecptr.p->maxp + fragrecptr.p->p) + 1) & ((1 << fragrecptr.p->k) - 1);
- texpDirInd = ((fragrecptr.p->maxp + fragrecptr.p->p) + 1) >> fragrecptr.p->k;
- texpDirRangeIndex = texpDirInd >> 8;
- texpDirPageIndex = texpDirInd & 0xff;
- ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange);
- arrGuard(texpDirRangeIndex, 256);
- expDirptr.i = expDirRangePtr.p->dirArray[texpDirRangeIndex];
- ptrCheckGuard(expDirptr, cdirarraysize, directoryarray);
- excPageptr.i = expDirptr.p->pagep[texpDirPageIndex];
- fragrecptr.p->expSenderDirptr = expDirptr.i;
- fragrecptr.p->expSenderIndex = cexcPageindex;
- fragrecptr.p->expSenderPageptr = excPageptr.i;
- fragrecptr.p->expSenderDirIndex = texpDirInd;
- /*--------------------------------------------------------------------------*/
- /* WE NOW PROCEED BY FINDING THE NECESSARY INFORMATION ABOUT THE */
- /* RECEIVING BUCKET. */
- /*--------------------------------------------------------------------------*/
- expDirRangePtr.i = fragrecptr.p->directory;
- texpReceivedBucket = fragrecptr.p->p >> fragrecptr.p->k;
- ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange);
- arrGuard((texpReceivedBucket >> 8), 256);
- expDirptr.i = expDirRangePtr.p->dirArray[texpReceivedBucket >> 8];
- ptrCheckGuard(expDirptr, cdirarraysize, directoryarray);
- fragrecptr.p->expReceivePageptr = expDirptr.p->pagep[texpReceivedBucket & 0xff];
- fragrecptr.p->expReceiveIndex = fragrecptr.p->p & ((1 << fragrecptr.p->k) - 1);
- fragrecptr.p->expReceiveForward = ZTRUE;
- if (excPageptr.i == RNIL) {
- jam();
- endofshrinkbucketLab(signal); /* EMPTY BUCKET */
- return;
- }//if
- /*--------------------------------------------------------------------------*/
- /* INITIALISE THE VARIABLES FOR THE SHRINK PROCESS. */
- /*--------------------------------------------------------------------------*/
- ptrCheckGuard(excPageptr, cpagesize, page8);
- cexcForward = ZTRUE;
- cexcContainerptr = (cexcPageindex << ZSHIFT_PLUS) - (cexcPageindex << ZSHIFT_MINUS);
- cexcContainerptr = cexcContainerptr + ZHEAD_SIZE;
- arrGuard(cexcContainerptr, 2048);
- cexcContainerhead = excPageptr.p->word32[cexcContainerptr];
- cexcContainerlen = cexcContainerhead >> 26;
- if (cexcContainerlen <= ZCON_HEAD_SIZE) {
- ndbrequire(cexcContainerlen == ZCON_HEAD_SIZE);
- } else {
- jam();
- shrinkcontainer(signal);
- }//if
- /*--------------------------------------------------------------------------*/
- /* THIS CONTAINER IS NOT YET EMPTY AND WE REMOVE ALL THE ELEMENTS. */
- /*--------------------------------------------------------------------------*/
- if (((cexcContainerhead >> 10) & 1) == 1) {
- jam();
- rlPageptr = excPageptr;
- trlPageindex = cexcPageindex;
- trlRelCon = ZFALSE;
- turlIndex = cexcContainerptr + (ZBUF_SIZE - ZCON_HEAD_SIZE);
- releaseRightlist(signal);
- }//if
- tshrTmp1 = ZCON_HEAD_SIZE;
- tshrTmp1 = tshrTmp1 << 26;
- dbgWord32(excPageptr, cexcContainerptr, tshrTmp1);
- arrGuard(cexcContainerptr, 2048);
- excPageptr.p->word32[cexcContainerptr] = tshrTmp1;
- if (((cexcContainerhead >> 7) & 0x3) == 0) {
- jam();
- endofshrinkbucketLab(signal);
- return;
- }//if
- nextcontainerinfoExp(signal);
- do {
- cexcContainerptr = (cexcPageindex << ZSHIFT_PLUS) - (cexcPageindex << ZSHIFT_MINUS);
- if (cexcForward == ZTRUE) {
- jam();
- cexcContainerptr = cexcContainerptr + ZHEAD_SIZE;
- } else {
- jam();
- cexcContainerptr = ((cexcContainerptr + ZHEAD_SIZE) + ZBUF_SIZE) - ZCON_HEAD_SIZE;
- }//if
- arrGuard(cexcContainerptr, 2048);
- cexcContainerhead = excPageptr.p->word32[cexcContainerptr];
- cexcContainerlen = cexcContainerhead >> 26;
- ndbrequire(cexcContainerlen > ZCON_HEAD_SIZE);
- /*--------------------------------------------------------------------------*/
- /* THIS CONTAINER IS NOT YET EMPTY AND WE REMOVE ALL THE ELEMENTS. */
- /*--------------------------------------------------------------------------*/
- shrinkcontainer(signal);
- cexcPrevpageptr = excPageptr.i;
- cexcPrevpageindex = cexcPageindex;
- cexcPrevforward = cexcForward;
- if (((cexcContainerhead >> 7) & 0x3) != 0) {
- jam();
- /*--------------------------------------------------------------------------*/
- /* WE MUST CALL THE NEXT CONTAINER INFO ROUTINE BEFORE WE RELEASE THE */
- /* CONTAINER SINCE THE RELEASE WILL OVERWRITE THE NEXT POINTER. */
- /*--------------------------------------------------------------------------*/
- nextcontainerinfoExp(signal);
- }//if
- rlPageptr.i = cexcPrevpageptr;
- ptrCheckGuard(rlPageptr, cpagesize, page8);
- trlPageindex = cexcPrevpageindex;
- if (cexcPrevforward == ZTRUE) {
- jam();
- if (((cexcContainerhead >> 10) & 1) == 1) {
- jam();
- trlRelCon = ZFALSE;
- turlIndex = cexcContainerptr + (ZBUF_SIZE - ZCON_HEAD_SIZE);
- releaseRightlist(signal);
- }//if
- trlRelCon = ZTRUE;
- tullIndex = cexcContainerptr;
- releaseLeftlist(signal);
- } else {
- jam();
- if (((cexcContainerhead >> 10) & 1) == 1) {
- jam();
- trlRelCon = ZFALSE;
- tullIndex = cexcContainerptr - (ZBUF_SIZE - ZCON_HEAD_SIZE);
- releaseLeftlist(signal);
- }//if
- trlRelCon = ZTRUE;
- turlIndex = cexcContainerptr;
- releaseRightlist(signal);
- }//if
- } while (((cexcContainerhead >> 7) & 0x3) != 0);
- endofshrinkbucketLab(signal);
- return;
-}//Dbacc::execSHRINKCHECK2()
-
-void Dbacc::endofshrinkbucketLab(Signal* signal)
-{
- fragrecptr.p->expandCounter--;
- fragrecptr.p->slack -= fragrecptr.p->maxloadfactor;
- if (fragrecptr.p->expSenderIndex == 0) {
- jam();
- fragrecptr.p->dirsize--;
- if (fragrecptr.p->expSenderPageptr != RNIL) {
- jam();
- rpPageptr.i = fragrecptr.p->expSenderPageptr;
- ptrCheckGuard(rpPageptr, cpagesize, page8);
- releasePage(signal);
- expDirptr.i = fragrecptr.p->expSenderDirptr;
- ptrCheckGuard(expDirptr, cdirarraysize, directoryarray);
- expDirptr.p->pagep[fragrecptr.p->expSenderDirIndex & 0xff] = RNIL;
- }//if
- if (((((fragrecptr.p->p + fragrecptr.p->maxp) + 1) >> fragrecptr.p->k) & 0xff) == 0) {
- jam();
- rdDirptr.i = fragrecptr.p->expSenderDirptr;
- releaseDirectory(signal);
- expDirRangePtr.i = fragrecptr.p->directory;
- ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange);
- arrGuard((fragrecptr.p->expSenderDirIndex >> 8), 256);
- expDirRangePtr.p->dirArray[fragrecptr.p->expSenderDirIndex >> 8] = RNIL;
- }//if
- }//if
- if (fragrecptr.p->slack < (1u << 31)) {
- jam();
- /*--------------------------------------------------------------*/
- /* THE SLACK IS POSITIVE, IN THIS CASE WE WILL CHECK WHETHER */
- /* WE WILL CONTINUE PERFORM ANOTHER SHRINK. */
- /*--------------------------------------------------------------*/
- Uint32 noOfBuckets = (fragrecptr.p->maxp + 1) + fragrecptr.p->p;
- Uint32 Thysteresis = fragrecptr.p->maxloadfactor - fragrecptr.p->minloadfactor;
- fragrecptr.p->slackCheck = noOfBuckets * Thysteresis;
- if (fragrecptr.p->slack > Thysteresis) {
- /*--------------------------------------------------------------*/
- /* IT IS STILL NECESSARY TO SHRINK THE FRAGMENT MORE. THIS*/
- /* CAN HAPPEN WHEN A NUMBER OF SHRINKS GET REJECTED */
- /* DURING A LOCAL CHECKPOINT. WE START A NEW SHRINK */
- /* IMMEDIATELY FROM HERE WITHOUT WAITING FOR A COMMIT TO */
- /* START IT. */
- /*--------------------------------------------------------------*/
- if (fragrecptr.p->expandCounter > 0) {
- jam();
- /*--------------------------------------------------------------*/
- /* IT IS VERY IMPORTANT TO NOT TRY TO SHRINK MORE THAN */
- /* WAS EXPANDED. IF MAXP IS SET TO A VALUE BELOW 63 THEN */
- /* WE WILL LOSE RECORDS SINCE GETDIRINDEX CANNOT HANDLE */
- /* SHRINKING BELOW 2^K - 1 (NOW 63). THIS WAS A BUG THAT */
- /* WAS REMOVED 2000-05-12. */
- /*--------------------------------------------------------------*/
- signal->theData[0] = fragrecptr.i;
- signal->theData[1] = fragrecptr.p->p;
- signal->theData[2] = fragrecptr.p->maxp;
- signal->theData[3] = fragrecptr.p->expandFlag;
- ndbrequire(fragrecptr.p->expandFlag < 2);
- fragrecptr.p->expandFlag = 2;
- sendSignal(cownBlockref, GSN_SHRINKCHECK2, signal, 4, JBB);
- }//if
- }//if
- }//if
- ndbrequire(fragrecptr.p->maxp >= (Uint32)((1 << fragrecptr.p->k) - 1));
- return;
-}//Dbacc::endofshrinkbucketLab()
-
-/* --------------------------------------------------------------------------------- */
-/* SHRINKCONTAINER */
-/* INPUT: EXC_PAGEPTR (POINTER TO THE ACTIVE PAGE RECORD) */
-/* CEXC_CONTAINERLEN (LENGTH OF THE CONTAINER). */
-/* CEXC_CONTAINERPTR (ARRAY INDEX OF THE CONTAINER). */
-/* CEXC_FORWARD (CONTAINER FORWARD (+1) OR BACKWARD (-1)) */
-/* */
-/* DESCRIPTION: ALL ELEMENTS OF THE ACTIVE CONTAINER HAVE TO MOVE TO THE NEW */
-/* CONTAINER. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::shrinkcontainer(Signal* signal)
-{
- Uint32 tshrElementptr;
- Uint32 tshrRemLen;
- Uint32 tshrInc;
- Uint32 tshrTmp;
- Uint32 tshrIndex;
- Uint32 guard21;
-
- tshrRemLen = cexcContainerlen - ZCON_HEAD_SIZE;
- tshrInc = fragrecptr.p->elementLength;
- if (cexcForward == ZTRUE) {
- jam();
- tshrElementptr = cexcContainerptr + ZCON_HEAD_SIZE;
- } else {
- jam();
- tshrElementptr = cexcContainerptr - 1;
- }//if
- SHR_LOOP:
- idrOperationRecPtr.i = RNIL;
- ptrNull(idrOperationRecPtr);
- /* --------------------------------------------------------------------------------- */
- /* THE CODE BELOW IS ALL USED TO PREPARE FOR THE CALL TO INSERT_ELEMENT AND */
- /* HANDLE THE RESULT FROM INSERT_ELEMENT. INSERT_ELEMENT INSERTS THE ELEMENT */
- /* INTO ANOTHER BUCKET. */
- /* --------------------------------------------------------------------------------- */
- arrGuard(tshrElementptr, 2048);
- tidrElemhead = excPageptr.p->word32[tshrElementptr];
- if (ElementHeader::getLocked(tidrElemhead)) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* IF THE ELEMENT IS LOCKED WE MUST UPDATE THE ELEMENT INFO IN THE OPERATION */
- /* RECORD OWNING THE LOCK. WE DO THIS BY READING THE OPERATION RECORD POINTER */
- /* FROM THE ELEMENT HEADER. */
- /* --------------------------------------------------------------------------------- */
- idrOperationRecPtr.i = ElementHeader::getOpPtrI(tidrElemhead);
- ptrCheckGuard(idrOperationRecPtr, coprecsize, operationrec);
- }//if
- tshrTmp = tshrElementptr + cexcForward;
- guard21 = fragrecptr.p->localkeylen - 1;
- for (tshrIndex = 0; tshrIndex <= guard21; tshrIndex++) {
- arrGuard(tshrIndex, 2);
- arrGuard(tshrTmp, 2048);
- clocalkey[tshrIndex] = excPageptr.p->word32[tshrTmp];
- tshrTmp = tshrTmp + cexcForward;
- }//for
- tidrPageindex = fragrecptr.p->expReceiveIndex;
- idrPageptr.i = fragrecptr.p->expReceivePageptr;
- ptrCheckGuard(idrPageptr, cpagesize, page8);
- tidrForward = fragrecptr.p->expReceiveForward;
- insertElement(signal);
- /* --------------------------------------------------------------------------------- */
- /* TAKE CARE OF RESULT FROM INSERT_ELEMENT. */
- /* --------------------------------------------------------------------------------- */
- fragrecptr.p->expReceiveIndex = tidrPageindex;
- fragrecptr.p->expReceivePageptr = idrPageptr.i;
- fragrecptr.p->expReceiveForward = tidrForward;
- if (tshrRemLen < tshrInc) {
- jam();
- sendSystemerror(signal, __LINE__);
- }//if
- tshrRemLen = tshrRemLen - tshrInc;
- if (tshrRemLen != 0) {
- jam();
- tshrElementptr = tshrTmp;
- goto SHR_LOOP;
- }//if
-}//Dbacc::shrinkcontainer()
-
-/* --------------------------------------------------------------------------------- */
-/* NEXTCONTAINERINFO_EXP */
-/* DESCRIPTION:THE CONTAINER HEAD WILL BE CHECKED TO CALCULATE INFORMATION */
-/* ABOUT NEXT CONTAINER IN THE BUCKET. */
-/* INPUT: CEXC_CONTAINERHEAD */
-/* CEXC_CONTAINERPTR */
-/* EXC_PAGEPTR */
-/* OUTPUT: */
-/* CEXC_PAGEINDEX (INDEX FROM WHICH PAGE INDEX CAN BE CALCULATED. */
-/* EXC_PAGEPTR (PAGE REFERENCE OF NEXT CONTAINER) */
-/* CEXC_FORWARD */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::nextcontainerinfoExp(Signal* signal)
-{
- tnciNextSamePage = (cexcContainerhead >> 9) & 0x1; /* CHECK BIT FOR CHECKING WHERE */
- /* THE NEXT CONTAINER IS IN THE SAME PAGE */
- cexcPageindex = cexcContainerhead & 0x7f; /* NEXT CONTAINER PAGE INDEX 7 BITS */
- if (((cexcContainerhead >> 7) & 3) == ZLEFT) {
- jam();
- cexcForward = ZTRUE;
- } else if (((cexcContainerhead >> 7) & 3) == ZRIGHT) {
- jam();
- cexcForward = cminusOne;
- } else {
- jam();
- sendSystemerror(signal, __LINE__);
- cexcForward = 0; /* DUMMY FOR COMPILER */
- }//if
- if (tnciNextSamePage == ZFALSE) {
- jam();
- /* NEXT CONTAINER IS IN AN OVERFLOW PAGE */
- arrGuard(cexcContainerptr + 1, 2048);
- tnciTmp = excPageptr.p->word32[cexcContainerptr + 1];
- nciOverflowrangeptr.i = fragrecptr.p->overflowdir;
- ptrCheckGuard(nciOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard((tnciTmp >> 8), 256);
- nciOverflowDirptr.i = nciOverflowrangeptr.p->dirArray[tnciTmp >> 8];
- ptrCheckGuard(nciOverflowDirptr, cdirarraysize, directoryarray);
- excPageptr.i = nciOverflowDirptr.p->pagep[tnciTmp & 0xff];
- ptrCheckGuard(excPageptr, cpagesize, page8);
- }//if
-}//Dbacc::nextcontainerinfoExp()
-
-void Dbacc::initFragAdd(Signal* signal,
- FragmentrecPtr regFragPtr)
-{
- const AccFragReq * const req = (AccFragReq*)&signal->theData[0];
- Uint32 lhFragBits = req->lhFragBits + 1;
- Uint32 minLoadFactor = (req->minLoadFactor * ZBUF_SIZE) / 100;
- Uint32 maxLoadFactor = (req->maxLoadFactor * ZBUF_SIZE) / 100;
- if (minLoadFactor >= maxLoadFactor) {
- jam();
- minLoadFactor = maxLoadFactor - 1;
- }//if
- regFragPtr.p->fragState = ACTIVEFRAG;
- // NOTE: next line must match calculation in Dblqh::execLQHFRAGREQ
- regFragPtr.p->myfid = req->fragId;
- regFragPtr.p->myTableId = req->tableId;
- ndbrequire(req->kValue == 6);
- regFragPtr.p->k = req->kValue; /* TK_SIZE = 6 IN THIS VERSION */
- regFragPtr.p->expandCounter = 0;
-
- /**
- * Only allow shrink during SR
- * - to make sure we don't run out of pages during REDO log execution
- *
- * Is later restored to 0 by LQH at end of REDO log execution
- */
- regFragPtr.p->expandFlag = 0;
- regFragPtr.p->p = 0;
- regFragPtr.p->maxp = (1 << req->kValue) - 1;
- regFragPtr.p->minloadfactor = minLoadFactor;
- regFragPtr.p->maxloadfactor = maxLoadFactor;
- regFragPtr.p->slack = (regFragPtr.p->maxp + 1) * maxLoadFactor;
- regFragPtr.p->lhfragbits = lhFragBits;
- regFragPtr.p->lhdirbits = 0;
- regFragPtr.p->hashcheckbit = 0; //lhFragBits;
- regFragPtr.p->localkeylen = req->localKeyLen;
- regFragPtr.p->nodetype = (req->reqInfo >> 4) & 0x3;
- regFragPtr.p->lastOverIndex = 0;
- regFragPtr.p->dirsize = 1;
- regFragPtr.p->keyLength = req->keyLength;
- ndbrequire(req->keyLength != 0);
- regFragPtr.p->elementLength = ZELEM_HEAD_SIZE + regFragPtr.p->localkeylen;
- Uint32 Tmp1 = (regFragPtr.p->maxp + 1) + regFragPtr.p->p;
- Uint32 Tmp2 = regFragPtr.p->maxloadfactor - regFragPtr.p->minloadfactor;
- Tmp2 = Tmp1 * Tmp2;
- regFragPtr.p->slackCheck = Tmp2;
- regFragPtr.p->mytabptr = req->tableId;
- regFragPtr.p->roothashcheck = req->kValue + req->lhFragBits;
- regFragPtr.p->noOfElements = 0;
- for (Uint32 i = 0; i < MAX_PARALLEL_SCANS_PER_FRAG; i++) {
- regFragPtr.p->scan[i] = RNIL;
- }//for
-
- Uint32 hasCharAttr = g_key_descriptor_pool.getPtr(req->tableId)->hasCharAttr;
- regFragPtr.p->hasCharAttr = hasCharAttr;
-}//Dbacc::initFragAdd()
-
-void Dbacc::initFragGeneral(FragmentrecPtr regFragPtr)
-{
- regFragPtr.p->directory = RNIL;
- regFragPtr.p->overflowdir = RNIL;
- regFragPtr.p->firstOverflowRec = RNIL;
- regFragPtr.p->lastOverflowRec = RNIL;
- regFragPtr.p->lockOwnersList = RNIL;
- regFragPtr.p->firstFreeDirindexRec = RNIL;
-
- regFragPtr.p->activeDataPage = 0;
- regFragPtr.p->hasCharAttr = ZFALSE;
- regFragPtr.p->nextAllocPage = 0;
- regFragPtr.p->fragState = FREEFRAG;
-}//Dbacc::initFragGeneral()
-
-
-void
-Dbacc::releaseLogicalPage(Fragmentrec * fragP, Uint32 logicalPageId){
- Ptr<struct DirRange> dirRangePtr;
- dirRangePtr.i = fragP->directory;
- ptrCheckGuard(dirRangePtr, cdirrangesize, dirRange);
-
- const Uint32 lp1 = logicalPageId >> 8;
- const Uint32 lp2 = logicalPageId & 0xFF;
- ndbrequire(lp1 < 256);
-
- Ptr<struct Directoryarray> dirArrPtr;
- dirArrPtr.i = dirRangePtr.p->dirArray[lp1];
- ptrCheckGuard(dirArrPtr, cdirarraysize, directoryarray);
-
- const Uint32 physicalPageId = dirArrPtr.p->pagep[lp2];
-
- rpPageptr.i = physicalPageId;
- ptrCheckGuard(rpPageptr, cpagesize, page8);
- releasePage(0);
-
- dirArrPtr.p->pagep[lp2] = RNIL;
-}
-
-void Dbacc::execACC_SCANREQ(Signal* signal)
-{
- jamEntry();
- AccScanReq * req = (AccScanReq*)&signal->theData[0];
- tuserptr = req->senderData;
- tuserblockref = req->senderRef;
- tabptr.i = req->tableId;
- tfid = req->fragmentNo;
- tscanFlag = req->requestInfo;
- tscanTrid1 = req->transId1;
- tscanTrid2 = req->transId2;
-
- tresult = 0;
- ptrCheckGuard(tabptr, ctablesize, tabrec);
- ndbrequire(getfragmentrec(signal, fragrecptr, tfid));
-
- Uint32 i;
- for (i = 0; i < MAX_PARALLEL_SCANS_PER_FRAG; i++) {
- jam();
- if (fragrecptr.p->scan[i] == RNIL) {
- jam();
- break;
- }
- }
- ndbrequire(i != MAX_PARALLEL_SCANS_PER_FRAG);
- ndbrequire(cfirstFreeScanRec != RNIL);
- seizeScanRec(signal);
-
- fragrecptr.p->scan[i] = scanPtr.i;
- scanPtr.p->scanBucketState = ScanRec::FIRST_LAP;
- scanPtr.p->scanLockMode = AccScanReq::getLockMode(tscanFlag);
- scanPtr.p->scanReadCommittedFlag = AccScanReq::getReadCommittedFlag(tscanFlag);
-
- /* TWELVE BITS OF THE ELEMENT HEAD ARE SCAN */
- /* CHECK BITS. THE MASK NOTES WHICH BIT IS */
- /* ALLOCATED FOR THE ACTIVE SCAN */
- scanPtr.p->scanMask = 1 << i;
- scanPtr.p->scanUserptr = tuserptr;
- scanPtr.p->scanUserblockref = tuserblockref;
- scanPtr.p->scanTrid1 = tscanTrid1;
- scanPtr.p->scanTrid2 = tscanTrid2;
- scanPtr.p->scanLockHeld = 0;
- scanPtr.p->scanOpsAllocated = 0;
- scanPtr.p->scanFirstActiveOp = RNIL;
- scanPtr.p->scanFirstQueuedOp = RNIL;
- scanPtr.p->scanLastQueuedOp = RNIL;
- scanPtr.p->scanFirstLockedOp = RNIL;
- scanPtr.p->scanLastLockedOp = RNIL;
- scanPtr.p->scanState = ScanRec::WAIT_NEXT;
- initScanFragmentPart(signal);
-
- /*------------------------------------------------------*/
- /* We start the timeout loop for the scan process here. */
- /*------------------------------------------------------*/
- ndbrequire(scanPtr.p->scanTimer == 0);
- if (scanPtr.p->scanContinuebCounter == 0) {
- jam();
- scanPtr.p->scanContinuebCounter = 1;
- signal->theData[0] = ZSEND_SCAN_HBREP;
- signal->theData[1] = scanPtr.i;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 2);
- }//if
- scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
- /* ************************ */
- /* ACC_SCANCONF */
- /* ************************ */
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = scanPtr.i;
- signal->theData[2] = 1; /* NR OF LOCAL FRAGMENT */
- signal->theData[3] = fragrecptr.p->fragmentid;
- signal->theData[4] = RNIL;
- signal->theData[7] = AccScanConf::ZNOT_EMPTY_FRAGMENT;
- sendSignal(scanPtr.p->scanUserblockref, GSN_ACC_SCANCONF, signal, 8, JBB);
- /* NOT EMPTY FRAGMENT */
- return;
-}//Dbacc::execACC_SCANREQ()
-
-/* ******************--------------------------------------------------------------- */
-/* NEXT_SCANREQ REQUEST FOR NEXT ELEMENT OF */
-/* ******************------------------------------+ A FRAGMENT. */
-/* SENDER: LQH, LEVEL B */
-void Dbacc::execNEXT_SCANREQ(Signal* signal)
-{
- Uint32 tscanNextFlag;
- jamEntry();
- scanPtr.i = signal->theData[0];
- operationRecPtr.i = signal->theData[1];
- tscanNextFlag = signal->theData[2];
- /* ------------------------------------------ */
- /* 1 = ZCOPY_NEXT GET NEXT ELEMENT */
- /* 2 = ZCOPY_NEXT_COMMIT COMMIT THE */
- /* ACTIVE ELEMENT AND GET THE NEXT ONE */
- /* 3 = ZCOPY_COMMIT COMMIT THE ACTIVE ELEMENT */
- /* 4 = ZCOPY_REPEAT GET THE ACTIVE ELEMENT */
- /* 5 = ZCOPY_ABORT RELOCK THE ACTIVE ELEMENT */
- /* 6 = ZCOPY_CLOSE THE SCAN PROCESS IS READY */
- /* ------------------------------------------ */
- tresult = 0;
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
- ndbrequire(scanPtr.p->scanState == ScanRec::WAIT_NEXT);
-
- scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
- switch (tscanNextFlag) {
- case NextScanReq::ZSCAN_NEXT:
- jam();
- /*empty*/;
- break;
- case NextScanReq::ZSCAN_NEXT_COMMIT:
- case NextScanReq::ZSCAN_COMMIT:
- jam();
- /* --------------------------------------------------------------------- */
- /* COMMIT ACTIVE OPERATION.
- * SEND NEXT SCAN ELEMENT IF IT IS ZCOPY_NEXT_COMMIT.
- * --------------------------------------------------------------------- */
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- if (!scanPtr.p->scanReadCommittedFlag) {
- commitOperation(signal);
- }//if
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- takeOutActiveScanOp(signal);
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- if (tscanNextFlag == NextScanReq::ZSCAN_COMMIT) {
- jam();
- signal->theData[0] = scanPtr.p->scanUserptr;
- Uint32 blockNo = refToBlock(scanPtr.p->scanUserblockref);
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 1);
- return;
- }//if
- break;
- case NextScanReq::ZSCAN_CLOSE:
- jam();
- fragrecptr.i = scanPtr.p->activeLocalFrag;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- /* ---------------------------------------------------------------------
- * THE SCAN PROCESS IS FINISHED. RELOCK ALL LOCKED EL.
- * RELESE ALL INVOLVED REC.
- * ------------------------------------------------------------------- */
- releaseScanLab(signal);
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZNOT_CHECK_LCP_STOP;
- execACC_CHECK_SCAN(signal);
- return;
-}//Dbacc::execNEXT_SCANREQ()
-
-void Dbacc::checkNextBucketLab(Signal* signal)
-{
- DirRangePtr cscDirRangePtr;
- DirectoryarrayPtr cscDirptr;
- DirectoryarrayPtr tnsDirptr;
- Page8Ptr nsPageptr;
- Page8Ptr cscPageidptr;
- Page8Ptr gnsPageidptr;
- Page8Ptr tnsPageidptr;
- Uint32 tnsElementptr;
- Uint32 tnsContainerptr;
- Uint32 tnsIsLocked;
- Uint32 tnsTmp1;
- Uint32 tnsTmp2;
- Uint32 tnsCopyIndex1;
- Uint32 tnsCopyIndex2;
- Uint32 tnsCopyDir;
-
- tnsCopyDir = scanPtr.p->nextBucketIndex >> fragrecptr.p->k;
- tnsCopyIndex1 = tnsCopyDir >> 8;
- tnsCopyIndex2 = tnsCopyDir & 0xff;
- arrGuard(tnsCopyIndex1, 256);
- tnsDirptr.i = gnsDirRangePtr.p->dirArray[tnsCopyIndex1];
- ptrCheckGuard(tnsDirptr, cdirarraysize, directoryarray);
- tnsPageidptr.i = tnsDirptr.p->pagep[tnsCopyIndex2];
- ptrCheckGuard(tnsPageidptr, cpagesize, page8);
- gnsPageidptr.i = tnsPageidptr.i;
- gnsPageidptr.p = tnsPageidptr.p;
- tnsTmp1 = (1 << fragrecptr.p->k) - 1;
- tgsePageindex = scanPtr.p->nextBucketIndex & tnsTmp1;
- gsePageidptr.i = gnsPageidptr.i;
- gsePageidptr.p = gnsPageidptr.p;
- if (!getScanElement(signal)) {
- scanPtr.p->nextBucketIndex++;
- if (scanPtr.p->scanBucketState == ScanRec::SECOND_LAP) {
- if (scanPtr.p->nextBucketIndex > scanPtr.p->maxBucketIndexToRescan) {
- /* ---------------------------------------------------------------- */
- // We have finished the rescan phase.
- // We are ready to proceed with the next fragment part.
- /* ---------------------------------------------------------------- */
- jam();
- checkNextFragmentLab(signal);
- return;
- }//if
- } else if (scanPtr.p->scanBucketState == ScanRec::FIRST_LAP) {
- if ((fragrecptr.p->p + fragrecptr.p->maxp) < scanPtr.p->nextBucketIndex) {
- /* ---------------------------------------------------------------- */
- // All buckets have been scanned a first time.
- /* ---------------------------------------------------------------- */
- if (scanPtr.p->minBucketIndexToRescan == 0xFFFFFFFF) {
- jam();
- /* -------------------------------------------------------------- */
- // We have not had any merges behind the scan.
- // Thus it is not necessary to perform any rescan any buckets
- // and we can proceed immediately with the next fragment part.
- /* --------------------------------------------------------------- */
- checkNextFragmentLab(signal);
- return;
- } else {
- jam();
- /* --------------------------------------------------------------------------------- */
- // Some buckets are in the need of rescanning due to merges that have moved records
- // from in front of the scan to behind the scan. During the merges we kept track of
- // which buckets that need a rescan. We start with the minimum and end with maximum.
- /* --------------------------------------------------------------------------------- */
- scanPtr.p->nextBucketIndex = scanPtr.p->minBucketIndexToRescan;
- scanPtr.p->scanBucketState = ScanRec::SECOND_LAP;
- if (scanPtr.p->maxBucketIndexToRescan > (fragrecptr.p->p + fragrecptr.p->maxp)) {
- jam();
- /* --------------------------------------------------------------------------------- */
- // If we have had so many merges that the maximum is bigger than the number of buckets
- // then we will simply satisfy ourselves with scanning to the end. This can only happen
- // after bringing down the total of buckets to less than half and the minimum should
- // be 0 otherwise there is some problem.
- /* --------------------------------------------------------------------------------- */
- if (scanPtr.p->minBucketIndexToRescan != 0) {
- jam();
- sendSystemerror(signal, __LINE__);
- return;
- }//if
- scanPtr.p->maxBucketIndexToRescan = fragrecptr.p->p + fragrecptr.p->maxp;
- }//if
- }//if
- }//if
- }//if
- if ((scanPtr.p->scanBucketState == ScanRec::FIRST_LAP) &&
- (scanPtr.p->nextBucketIndex <= scanPtr.p->startNoOfBuckets)) {
- /* --------------------------------------------------------------------------------- */
- // We will only reset the scan indicator on the buckets that existed at the start of the
- // scan. The others will be handled by the split and merge code.
- /* --------------------------------------------------------------------------------- */
- tnsTmp2 = (1 << fragrecptr.p->k) - 1;
- trsbPageindex = scanPtr.p->nextBucketIndex & tnsTmp2;
- if (trsbPageindex != 0) {
- jam();
- rsbPageidptr.i = gnsPageidptr.i;
- rsbPageidptr.p = gnsPageidptr.p;
- } else {
- jam();
- cscDirRangePtr.i = fragrecptr.p->directory;
- tmpP = scanPtr.p->nextBucketIndex >> fragrecptr.p->k;
- tmpP2 = tmpP >> 8;
- tmpP = tmpP & 0xff;
- ptrCheckGuard(cscDirRangePtr, cdirrangesize, dirRange);
- arrGuard(tmpP2, 256);
- cscDirptr.i = cscDirRangePtr.p->dirArray[tmpP2];
- ptrCheckGuard(cscDirptr, cdirarraysize, directoryarray);
- cscPageidptr.i = cscDirptr.p->pagep[tmpP];
- ptrCheckGuard(cscPageidptr, cpagesize, page8);
- tmp1 = (1 << fragrecptr.p->k) - 1;
- trsbPageindex = scanPtr.p->nextBucketIndex & tmp1;
- rsbPageidptr.i = cscPageidptr.i;
- rsbPageidptr.p = cscPageidptr.p;
- }//if
- releaseScanBucket(signal);
- }//if
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(cownBlockref, GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- }//if
- /* ----------------------------------------------------------------------- */
- /* AN ELEMENT WHICH HAVE NOT BEEN SCANNED WAS FOUND. WE WILL PREPARE IT */
- /* TO BE SENT TO THE LQH BLOCK FOR FURTHER PROCESSING. */
- /* WE ASSUME THERE ARE OPERATION RECORDS AVAILABLE SINCE LQH SHOULD HAVE*/
- /* GUARANTEED THAT THROUGH EARLY BOOKING. */
- /* ----------------------------------------------------------------------- */
- tnsIsLocked = tgseIsLocked;
- tnsElementptr = tgseElementptr;
- tnsContainerptr = tgseContainerptr;
- nsPageptr.i = gsePageidptr.i;
- nsPageptr.p = gsePageidptr.p;
- seizeOpRec(signal);
- tisoIsforward = tgseIsforward;
- tisoContainerptr = tnsContainerptr;
- tisoElementptr = tnsElementptr;
- isoPageptr.i = nsPageptr.i;
- isoPageptr.p = nsPageptr.p;
- initScanOpRec(signal);
-
- if (!tnsIsLocked){
- if (!scanPtr.p->scanReadCommittedFlag) {
- jam();
- slPageidptr = nsPageptr;
- tslElementptr = tnsElementptr;
- setlock(signal);
- insertLockOwnersList(signal, operationRecPtr);
- operationRecPtr.p->m_op_bits |=
- Operationrec::OP_STATE_RUNNING | Operationrec::OP_RUN_QUEUE;
- }//if
- } else {
- arrGuard(tnsElementptr, 2048);
- queOperPtr.i =
- ElementHeader::getOpPtrI(nsPageptr.p->word32[tnsElementptr]);
- ptrCheckGuard(queOperPtr, coprecsize, operationrec);
- if (queOperPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED ||
- queOperPtr.p->localdata[0] == ~(Uint32)0)
- {
- jam();
- /* ------------------------------------------------------------------ */
- // If the lock owner indicates the element is disappeared then
- // we will not report this tuple. We will continue with the next tuple.
- /* ------------------------------------------------------------------ */
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(cownBlockref, GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- }//if
- if (!scanPtr.p->scanReadCommittedFlag) {
- Uint32 return_result;
- if (scanPtr.p->scanLockMode == ZREADLOCK) {
- jam();
- return_result = placeReadInLockQueue(queOperPtr);
- } else {
- jam();
- return_result = placeWriteInLockQueue(queOperPtr);
- }//if
- if (return_result == ZSERIAL_QUEUE) {
- /* -----------------------------------------------------------------
- * WE PLACED THE OPERATION INTO A SERIAL QUEUE AND THUS WE HAVE TO
- * WAIT FOR THE LOCK TO BE RELEASED. WE CONTINUE WITH THE NEXT ELEMENT
- * ----------------------------------------------------------------- */
- putOpScanLockQue(); /* PUT THE OP IN A QUE IN THE SCAN REC */
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(cownBlockref, GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- } else if (return_result != ZPARALLEL_QUEUE) {
- jam();
- /* ----------------------------------------------------------------- */
- // The tuple is either not committed yet or a delete in
- // the same transaction (not possible here since we are a scan).
- // Thus we simply continue with the next tuple.
- /* ----------------------------------------------------------------- */
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(cownBlockref, GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- }//if
- ndbassert(return_result == ZPARALLEL_QUEUE);
- }//if
- }//if
- /* ----------------------------------------------------------------------- */
- // Committed read proceed without caring for locks immediately
- // down here except when the tuple was deleted permanently
- // and no new operation has inserted it again.
- /* ----------------------------------------------------------------------- */
- putActiveScanOp(signal);
- sendNextScanConf(signal);
- return;
-}//Dbacc::checkNextBucketLab()
-
-
-void Dbacc::checkNextFragmentLab(Signal* signal)
-{
- scanPtr.p->scanBucketState = ScanRec::SCAN_COMPLETED;
- // The scan is completed. ACC_CHECK_SCAN will perform all the necessary
- // checks to see
- // what the next step is.
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- execACC_CHECK_SCAN(signal);
- return;
-}//Dbacc::checkNextFragmentLab()
-
-void Dbacc::initScanFragmentPart(Signal* signal)
-{
- DirRangePtr cnfDirRangePtr;
- DirectoryarrayPtr cnfDirptr;
- Page8Ptr cnfPageidptr;
- /* ----------------------------------------------------------------------- */
- // Set the active fragment part.
- // Set the current bucket scanned to the first.
- // Start with the first lap.
- // Remember the number of buckets at start of the scan.
- // Set the minimum and maximum to values that will always be smaller and
- // larger than.
- // Reset the scan indicator on the first bucket.
- /* ----------------------------------------------------------------------- */
- scanPtr.p->activeLocalFrag = fragrecptr.i;
- scanPtr.p->nextBucketIndex = 0; /* INDEX OF SCAN BUCKET */
- scanPtr.p->scanBucketState = ScanRec::FIRST_LAP;
- scanPtr.p->startNoOfBuckets = fragrecptr.p->p + fragrecptr.p->maxp;
- scanPtr.p->minBucketIndexToRescan = 0xFFFFFFFF;
- scanPtr.p->maxBucketIndexToRescan = 0;
- cnfDirRangePtr.i = fragrecptr.p->directory;
- ptrCheckGuard(cnfDirRangePtr, cdirrangesize, dirRange);
- cnfDirptr.i = cnfDirRangePtr.p->dirArray[0];
- ptrCheckGuard(cnfDirptr, cdirarraysize, directoryarray);
- cnfPageidptr.i = cnfDirptr.p->pagep[0];
- ptrCheckGuard(cnfPageidptr, cpagesize, page8);
- trsbPageindex = scanPtr.p->nextBucketIndex & ((1 << fragrecptr.p->k) - 1);
- rsbPageidptr.i = cnfPageidptr.i;
- rsbPageidptr.p = cnfPageidptr.p;
- releaseScanBucket(signal);
-}//Dbacc::initScanFragmentPart()
-
-/* -------------------------------------------------------------------------
- * FLAG = 6 = ZCOPY_CLOSE THE SCAN PROCESS IS READY OR ABORTED.
- * ALL OPERATION IN THE ACTIVE OR WAIT QUEUE ARE RELEASED,
- * SCAN FLAG OF ROOT FRAG IS RESET AND THE SCAN RECORD IS RELEASED.
- * ------------------------------------------------------------------------ */
-void Dbacc::releaseScanLab(Signal* signal)
-{
- releaseAndCommitActiveOps(signal);
- releaseAndCommitQueuedOps(signal);
- releaseAndAbortLockedOps(signal);
-
- fragrecptr.i = scanPtr.p->activeLocalFrag;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- for (tmp = 0; tmp < MAX_PARALLEL_SCANS_PER_FRAG; tmp++) {
- jam();
- if (fragrecptr.p->scan[tmp] == scanPtr.i) {
- jam();
- fragrecptr.p->scan[tmp] = RNIL;
- }//if
- }//for
- // Stops the heartbeat.
- scanPtr.p->scanTimer = 0;
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = RNIL;
- signal->theData[2] = RNIL;
- sendSignal(scanPtr.p->scanUserblockref, GSN_NEXT_SCANCONF, signal, 3, JBB);
- releaseScanRec(signal);
- return;
-}//Dbacc::releaseScanLab()
-
-
-void Dbacc::releaseAndCommitActiveOps(Signal* signal)
-{
- OperationrecPtr trsoOperPtr;
- operationRecPtr.i = scanPtr.p->scanFirstActiveOp;
- while (operationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- trsoOperPtr.i = operationRecPtr.p->nextOp;
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- if (!scanPtr.p->scanReadCommittedFlag) {
- jam();
- if ((operationRecPtr.p->m_op_bits & Operationrec::OP_STATE_MASK) ==
- Operationrec::OP_STATE_EXECUTED)
- {
- commitOperation(signal);
- }
- else
- {
- abortOperation(signal);
- }
- }//if
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- takeOutActiveScanOp(signal);
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- operationRecPtr.i = trsoOperPtr.i;
- }//if
-}//Dbacc::releaseAndCommitActiveOps()
-
-
-void Dbacc::releaseAndCommitQueuedOps(Signal* signal)
-{
- OperationrecPtr trsoOperPtr;
- operationRecPtr.i = scanPtr.p->scanFirstQueuedOp;
- while (operationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- trsoOperPtr.i = operationRecPtr.p->nextOp;
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- if (!scanPtr.p->scanReadCommittedFlag) {
- jam();
- if ((operationRecPtr.p->m_op_bits & Operationrec::OP_STATE_MASK) ==
- Operationrec::OP_STATE_EXECUTED)
- {
- commitOperation(signal);
- }
- else
- {
- abortOperation(signal);
- }
- }//if
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- takeOutReadyScanQueue(signal);
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- operationRecPtr.i = trsoOperPtr.i;
- }//if
-}//Dbacc::releaseAndCommitQueuedOps()
-
-void Dbacc::releaseAndAbortLockedOps(Signal* signal) {
-
- OperationrecPtr trsoOperPtr;
- operationRecPtr.i = scanPtr.p->scanFirstLockedOp;
- while (operationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- trsoOperPtr.i = operationRecPtr.p->nextOp;
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- if (!scanPtr.p->scanReadCommittedFlag) {
- jam();
- abortOperation(signal);
- }//if
- takeOutScanLockQueue(scanPtr.i);
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- operationRecPtr.i = trsoOperPtr.i;
- }//if
-}//Dbacc::releaseAndAbortLockedOps()
-
-/* 3.18.3 ACC_CHECK_SCAN */
-/* ******************--------------------------------------------------------------- */
-/* ACC_CHECK_SCAN */
-/* ENTER ACC_CHECK_SCAN WITH */
-/* SCAN_PTR */
-/* ******************--------------------------------------------------------------- */
-/* ******************--------------------------------------------------------------- */
-/* ACC_CHECK_SCAN */
-/* ******************------------------------------+ */
-void Dbacc::execACC_CHECK_SCAN(Signal* signal)
-{
- Uint32 TcheckLcpStop;
- jamEntry();
- scanPtr.i = signal->theData[0];
- TcheckLcpStop = signal->theData[1];
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
- while (scanPtr.p->scanFirstQueuedOp != RNIL) {
- jam();
- //---------------------------------------------------------------------
- // An operation has been released from the lock queue.
- // We are in the parallel queue of this tuple. We are
- // ready to report the tuple now.
- //------------------------------------------------------------------------
- operationRecPtr.i = scanPtr.p->scanFirstQueuedOp;
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- takeOutReadyScanQueue(signal);
- fragrecptr.i = operationRecPtr.p->fragptr;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- if (operationRecPtr.p->m_op_bits & Operationrec::OP_ELEMENT_DISAPPEARED)
- {
- jam();
- abortOperation(signal);
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
- releaseOpRec(signal);
- scanPtr.p->scanOpsAllocated--;
- continue;
- }//if
- putActiveScanOp(signal);
- sendNextScanConf(signal);
- return;
- }//while
-
-
- if ((scanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED) &&
- (scanPtr.p->scanLockHeld == 0)) {
- jam();
- //----------------------------------------------------------------------------
- // The scan is now completed and there are no more locks outstanding. Thus we
- // we will report the scan as completed to LQH.
- //----------------------------------------------------------------------------
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = RNIL;
- signal->theData[2] = RNIL;
- sendSignal(scanPtr.p->scanUserblockref, GSN_NEXT_SCANCONF, signal, 3, JBB);
- return;
- }//if
- if (TcheckLcpStop == AccCheckScan::ZCHECK_LCP_STOP) {
- //---------------------------------------------------------------------------
- // To ensure that the block of the fragment occurring at the start of a local
- // checkpoint is not held for too long we insert a release and reacquiring of
- // that lock here. This is performed in LQH. If we are blocked or if we have
- // requested a sleep then we will receive RNIL in the returning signal word.
- //---------------------------------------------------------------------------
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] =
- ((scanPtr.p->scanLockHeld >= ZSCAN_MAX_LOCK) ||
- (scanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED));
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- if (signal->theData[0] == RNIL) {
- jam();
- return;
- }//if
- }//if
- /**
- * If we have more than max locks held OR
- * scan is completed AND at least one lock held
- * - Inform LQH about this condition
- */
- if ((scanPtr.p->scanLockHeld >= ZSCAN_MAX_LOCK) ||
- (cfreeopRec == RNIL) ||
- ((scanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED) &&
- (scanPtr.p->scanLockHeld > 0))) {
- jam();
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = RNIL; // No operation is returned
- signal->theData[2] = 512; // MASV
- sendSignal(scanPtr.p->scanUserblockref, GSN_NEXT_SCANCONF, signal, 3, JBB);
- return;
- }
- if (scanPtr.p->scanBucketState == ScanRec::SCAN_COMPLETED) {
- jam();
- signal->theData[0] = scanPtr.i;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- execACC_CHECK_SCAN(signal);
- return;
- }//if
-
- scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
-
- fragrecptr.i = scanPtr.p->activeLocalFrag;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- gnsDirRangePtr.i = fragrecptr.p->directory;
- ptrCheckGuard(gnsDirRangePtr, cdirrangesize, dirRange);
- checkNextBucketLab(signal);
- return;
-}//Dbacc::execACC_CHECK_SCAN()
-
-/* ******************---------------------------------------------------- */
-/* ACC_TO_REQ PERFORM A TAKE OVER */
-/* ******************-------------------+ */
-/* SENDER: LQH, LEVEL B */
-void Dbacc::execACC_TO_REQ(Signal* signal)
-{
- OperationrecPtr tatrOpPtr;
-
- jamEntry();
- tatrOpPtr.i = signal->theData[1]; /* OPER PTR OF ACC */
- ptrCheckGuard(tatrOpPtr, coprecsize, operationrec);
- if ((tatrOpPtr.p->m_op_bits & Operationrec::OP_MASK) == ZSCAN_OP)
- {
- tatrOpPtr.p->transId1 = signal->theData[2];
- tatrOpPtr.p->transId2 = signal->theData[3];
- validate_lock_queue(tatrOpPtr);
- } else {
- jam();
- signal->theData[0] = cminusOne;
- signal->theData[1] = ZTO_OP_STATE_ERROR;
- }//if
- return;
-}//Dbacc::execACC_TO_REQ()
-
-/* --------------------------------------------------------------------------------- */
-/* CONTAINERINFO */
-/* INPUT: */
-/* CI_PAGEIDPTR (PAGE POINTER WHERE CONTAINER RESIDES) */
-/* TCI_PAGEINDEX (INDEX OF CONTAINER, USED TO CALCULATE PAGE INDEX) */
-/* TCI_ISFORWARD (DIRECTION OF CONTAINER FORWARD OR BACKWARD) */
-/* */
-/* OUTPUT: */
-/* TCI_CONTAINERPTR (A POINTER TO THE HEAD OF THE CONTAINER) */
-/* TCI_CONTAINERLEN (LENGTH OF THE CONTAINER */
-/* TCI_CONTAINERHEAD (THE HEADER OF THE CONTAINER) */
-/* */
-/* DESCRIPTION: THE ADDRESS OF THE CONTAINER WILL BE CALCULATED AND */
-/* ALL INFORMATION ABOUT THE CONTAINER WILL BE READ */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::containerinfo(Signal* signal)
-{
- tciContainerptr = (tciPageindex << ZSHIFT_PLUS) - (tciPageindex << ZSHIFT_MINUS);
- if (tciIsforward == ZTRUE) {
- jam();
- tciContainerptr = tciContainerptr + ZHEAD_SIZE;
- } else {
- jam();
- tciContainerptr = ((tciContainerptr + ZHEAD_SIZE) + ZBUF_SIZE) - ZCON_HEAD_SIZE;
- }//if
- arrGuard(tciContainerptr, 2048);
- tciContainerhead = ciPageidptr.p->word32[tciContainerptr];
- tciContainerlen = tciContainerhead >> 26;
-}//Dbacc::containerinfo()
-
-/* --------------------------------------------------------------------------------- */
-/* GET_SCAN_ELEMENT */
-/* INPUT: GSE_PAGEIDPTR */
-/* TGSE_PAGEINDEX */
-/* OUTPUT: TGSE_IS_LOCKED (IF TRESULT /= ZFALSE) */
-/* GSE_PAGEIDPTR */
-/* TGSE_PAGEINDEX */
-/* --------------------------------------------------------------------------------- */
-bool Dbacc::getScanElement(Signal* signal)
-{
- tgseIsforward = ZTRUE;
- NEXTSEARCH_SCAN_LOOP:
- ciPageidptr.i = gsePageidptr.i;
- ciPageidptr.p = gsePageidptr.p;
- tciPageindex = tgsePageindex;
- tciIsforward = tgseIsforward;
- containerinfo(signal);
- sscPageidptr.i = gsePageidptr.i;
- sscPageidptr.p = gsePageidptr.p;
- tsscContainerlen = tciContainerlen;
- tsscContainerptr = tciContainerptr;
- tsscIsforward = tciIsforward;
- if (searchScanContainer(signal)) {
- jam();
- tgseIsLocked = tsscIsLocked;
- tgseElementptr = tsscElementptr;
- tgseContainerptr = tsscContainerptr;
- return true;
- }//if
- if (((tciContainerhead >> 7) & 0x3) != 0) {
- jam();
- nciPageidptr.i = gsePageidptr.i;
- nciPageidptr.p = gsePageidptr.p;
- tnciContainerhead = tciContainerhead;
- tnciContainerptr = tciContainerptr;
- nextcontainerinfo(signal);
- tgsePageindex = tnciPageindex;
- gsePageidptr.i = nciPageidptr.i;
- gsePageidptr.p = nciPageidptr.p;
- tgseIsforward = tnciIsforward;
- goto NEXTSEARCH_SCAN_LOOP;
- }//if
- return false;
-}//Dbacc::getScanElement()
-
-/* --------------------------------------------------------------------------------- */
-/* INIT_SCAN_OP_REC */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initScanOpRec(Signal* signal)
-{
- Uint32 tisoTmp;
- Uint32 tisoLocalPtr;
- Uint32 guard24;
-
- scanPtr.p->scanOpsAllocated++;
-
- Uint32 opbits = 0;
- opbits |= ZSCAN_OP;
- opbits |= scanPtr.p->scanLockMode ? (Uint32) Operationrec::OP_LOCK_MODE : 0;
- opbits |= scanPtr.p->scanLockMode ? (Uint32) Operationrec::OP_ACC_LOCK_MODE : 0;
- opbits |= (scanPtr.p->scanReadCommittedFlag ?
- (Uint32) Operationrec::OP_EXECUTED_DIRTY_READ : 0);
- opbits |= Operationrec::OP_COMMIT_DELETE_CHECK;
- operationRecPtr.p->userptr = RNIL;
- operationRecPtr.p->scanRecPtr = scanPtr.i;
- operationRecPtr.p->fid = fragrecptr.p->myfid;
- operationRecPtr.p->fragptr = fragrecptr.i;
- operationRecPtr.p->nextParallelQue = RNIL;
- operationRecPtr.p->prevParallelQue = RNIL;
- operationRecPtr.p->nextSerialQue = RNIL;
- operationRecPtr.p->prevSerialQue = RNIL;
- operationRecPtr.p->transId1 = scanPtr.p->scanTrid1;
- operationRecPtr.p->transId2 = scanPtr.p->scanTrid2;
- operationRecPtr.p->elementIsforward = tisoIsforward;
- operationRecPtr.p->elementContainer = tisoContainerptr;
- operationRecPtr.p->elementPointer = tisoElementptr;
- operationRecPtr.p->elementPage = isoPageptr.i;
- operationRecPtr.p->m_op_bits = opbits;
- tisoLocalPtr = tisoElementptr + tisoIsforward;
- guard24 = fragrecptr.p->localkeylen - 1;
- for (tisoTmp = 0; tisoTmp <= guard24; tisoTmp++) {
- arrGuard(tisoTmp, 2);
- arrGuard(tisoLocalPtr, 2048);
- operationRecPtr.p->localdata[tisoTmp] = isoPageptr.p->word32[tisoLocalPtr];
- tisoLocalPtr = tisoLocalPtr + tisoIsforward;
- }//for
- arrGuard(tisoLocalPtr, 2048);
- operationRecPtr.p->tupkeylen = fragrecptr.p->keyLength;
- operationRecPtr.p->xfrmtupkeylen = 0; // not used
-}//Dbacc::initScanOpRec()
-
-/* --------------------------------------------------------------------------------- */
-/* NEXTCONTAINERINFO */
-/* DESCRIPTION:THE CONTAINER HEAD WILL BE CHECKED TO CALCULATE INFORMATION */
-/* ABOUT NEXT CONTAINER IN THE BUCKET. */
-/* INPUT: TNCI_CONTAINERHEAD */
-/* NCI_PAGEIDPTR */
-/* TNCI_CONTAINERPTR */
-/* OUTPUT: */
-/* TNCI_PAGEINDEX (INDEX FROM WHICH PAGE INDEX CAN BE CALCULATED). */
-/* TNCI_ISFORWARD (IS THE NEXT CONTAINER FORWARD (+1) OR BACKWARD (-1) */
-/* NCI_PAGEIDPTR (PAGE REFERENCE OF NEXT CONTAINER) */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::nextcontainerinfo(Signal* signal)
-{
- tnciNextSamePage = (tnciContainerhead >> 9) & 0x1; /* CHECK BIT FOR CHECKING WHERE */
- /* THE NEXT CONTAINER IS IN THE SAME PAGE */
- tnciPageindex = tnciContainerhead & 0x7f; /* NEXT CONTAINER PAGE INDEX 7 BITS */
- if (((tnciContainerhead >> 7) & 3) == ZLEFT) {
- jam();
- tnciIsforward = ZTRUE;
- } else {
- jam();
- tnciIsforward = cminusOne;
- }//if
- if (tnciNextSamePage == ZFALSE) {
- jam();
- /* NEXT CONTAINER IS IN AN OVERFLOW PAGE */
- arrGuard(tnciContainerptr + 1, 2048);
- tnciTmp = nciPageidptr.p->word32[tnciContainerptr + 1];
- nciOverflowrangeptr.i = fragrecptr.p->overflowdir;
- ptrCheckGuard(nciOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard((tnciTmp >> 8), 256);
- nciOverflowDirptr.i = nciOverflowrangeptr.p->dirArray[tnciTmp >> 8];
- ptrCheckGuard(nciOverflowDirptr, cdirarraysize, directoryarray);
- nciPageidptr.i = nciOverflowDirptr.p->pagep[tnciTmp & 0xff];
- ptrCheckGuard(nciPageidptr, cpagesize, page8);
- }//if
-}//Dbacc::nextcontainerinfo()
-
-/* --------------------------------------------------------------------------------- */
-/* PUT_ACTIVE_SCAN_OP */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::putActiveScanOp(Signal* signal)
-{
- OperationrecPtr pasOperationRecPtr;
- pasOperationRecPtr.i = scanPtr.p->scanFirstActiveOp;
- if (pasOperationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(pasOperationRecPtr, coprecsize, operationrec);
- pasOperationRecPtr.p->prevOp = operationRecPtr.i;
- }//if
- operationRecPtr.p->nextOp = pasOperationRecPtr.i;
- operationRecPtr.p->prevOp = RNIL;
- scanPtr.p->scanFirstActiveOp = operationRecPtr.i;
-}//Dbacc::putActiveScanOp()
-
-/**
- * putOpScanLockQueue
- *
- * Description: Put an operation in the doubly linked
- * lock list on a scan record. The list is used to
- * keep track of which operations belonging
- * to the scan are put in serial lock list of another
- * operation
- *
- * @note Use takeOutScanLockQueue to remove an operation
- * from the list
- *
- */
-void Dbacc::putOpScanLockQue()
-{
-
-#ifdef VM_TRACE
- // DEBUG CODE
- // Check that there are as many operations in the lockqueue as
- // scanLockHeld indicates
- OperationrecPtr tmpOp;
- int numLockedOpsBefore = 0;
- tmpOp.i = scanPtr.p->scanFirstLockedOp;
- while(tmpOp.i != RNIL){
- numLockedOpsBefore++;
- ptrCheckGuard(tmpOp, coprecsize, operationrec);
- if (tmpOp.p->nextOp == RNIL)
- ndbrequire(tmpOp.i == scanPtr.p->scanLastLockedOp);
- tmpOp.i = tmpOp.p->nextOp;
- }
- ndbrequire(numLockedOpsBefore==scanPtr.p->scanLockHeld);
-#endif
-
- OperationrecPtr pslOperationRecPtr;
- ScanRec theScanRec;
- theScanRec = *scanPtr.p;
-
- pslOperationRecPtr.i = scanPtr.p->scanLastLockedOp;
- operationRecPtr.p->prevOp = pslOperationRecPtr.i;
- operationRecPtr.p->nextOp = RNIL;
- if (pslOperationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(pslOperationRecPtr, coprecsize, operationrec);
- pslOperationRecPtr.p->nextOp = operationRecPtr.i;
- } else {
- jam();
- scanPtr.p->scanFirstLockedOp = operationRecPtr.i;
- }//if
- scanPtr.p->scanLastLockedOp = operationRecPtr.i;
- scanPtr.p->scanLockHeld++;
-
-}//Dbacc::putOpScanLockQue()
-
-/* --------------------------------------------------------------------------------- */
-/* PUT_READY_SCAN_QUEUE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::putReadyScanQueue(Signal* signal, Uint32 scanRecIndex)
-{
- OperationrecPtr prsOperationRecPtr;
- ScanRecPtr TscanPtr;
-
- TscanPtr.i = scanRecIndex;
- ptrCheckGuard(TscanPtr, cscanRecSize, scanRec);
-
- prsOperationRecPtr.i = TscanPtr.p->scanLastQueuedOp;
- operationRecPtr.p->prevOp = prsOperationRecPtr.i;
- operationRecPtr.p->nextOp = RNIL;
- TscanPtr.p->scanLastQueuedOp = operationRecPtr.i;
- if (prsOperationRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(prsOperationRecPtr, coprecsize, operationrec);
- prsOperationRecPtr.p->nextOp = operationRecPtr.i;
- } else {
- jam();
- TscanPtr.p->scanFirstQueuedOp = operationRecPtr.i;
- }//if
-}//Dbacc::putReadyScanQueue()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_SCAN_BUCKET */
-// Input:
-// rsbPageidptr.i Index to page where buckets starts
-// rsbPageidptr.p Pointer to page where bucket starts
-// trsbPageindex Page index of starting container in bucket
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseScanBucket(Signal* signal)
-{
- Uint32 trsbIsforward;
-
- trsbIsforward = ZTRUE;
- NEXTRELEASESCANLOOP:
- ciPageidptr.i = rsbPageidptr.i;
- ciPageidptr.p = rsbPageidptr.p;
- tciPageindex = trsbPageindex;
- tciIsforward = trsbIsforward;
- containerinfo(signal);
- rscPageidptr.i = rsbPageidptr.i;
- rscPageidptr.p = rsbPageidptr.p;
- trscContainerlen = tciContainerlen;
- trscContainerptr = tciContainerptr;
- trscIsforward = trsbIsforward;
- releaseScanContainer(signal);
- if (((tciContainerhead >> 7) & 0x3) != 0) {
- jam();
- nciPageidptr.i = rsbPageidptr.i;
- nciPageidptr.p = rsbPageidptr.p;
- tnciContainerhead = tciContainerhead;
- tnciContainerptr = tciContainerptr;
- nextcontainerinfo(signal);
- rsbPageidptr.i = nciPageidptr.i;
- rsbPageidptr.p = nciPageidptr.p;
- trsbPageindex = tnciPageindex;
- trsbIsforward = tnciIsforward;
- goto NEXTRELEASESCANLOOP;
- }//if
-}//Dbacc::releaseScanBucket()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_SCAN_CONTAINER */
-/* INPUT: TRSC_CONTAINERLEN */
-/* RSC_PAGEIDPTR */
-/* TRSC_CONTAINERPTR */
-/* TRSC_ISFORWARD */
-/* SCAN_PTR */
-/* */
-/* DESCRIPTION: SEARCHS IN A CONTAINER, AND THE SCAN BIT OF THE ELEMENTS */
-/* OF THE CONTAINER IS RESET */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseScanContainer(Signal* signal)
-{
- OperationrecPtr rscOperPtr;
- Uint32 trscElemStep;
- Uint32 trscElementptr;
- Uint32 trscElemlens;
- Uint32 trscElemlen;
-
- if (trscContainerlen < 4) {
- if (trscContainerlen != ZCON_HEAD_SIZE) {
- jam();
- sendSystemerror(signal, __LINE__);
- }//if
- return; /* 2 IS THE MINIMUM SIZE OF THE ELEMENT */
- }//if
- trscElemlens = trscContainerlen - ZCON_HEAD_SIZE;
- trscElemlen = fragrecptr.p->elementLength;
- if (trscIsforward == 1) {
- jam();
- trscElementptr = trscContainerptr + ZCON_HEAD_SIZE;
- trscElemStep = trscElemlen;
- } else {
- jam();
- trscElementptr = trscContainerptr - 1;
- trscElemStep = 0 - trscElemlen;
- }//if
- do {
- arrGuard(trscElementptr, 2048);
- const Uint32 eh = rscPageidptr.p->word32[trscElementptr];
- const Uint32 scanMask = scanPtr.p->scanMask;
- if (ElementHeader::getUnlocked(eh)) {
- jam();
- const Uint32 tmp = ElementHeader::clearScanBit(eh, scanMask);
- dbgWord32(rscPageidptr, trscElementptr, tmp);
- rscPageidptr.p->word32[trscElementptr] = tmp;
- } else {
- jam();
- rscOperPtr.i = ElementHeader::getOpPtrI(eh);
- ptrCheckGuard(rscOperPtr, coprecsize, operationrec);
- rscOperPtr.p->scanBits &= ~scanMask;
- }//if
- trscElemlens = trscElemlens - trscElemlen;
- trscElementptr = trscElementptr + trscElemStep;
- } while (trscElemlens > 1);
- if (trscElemlens != 0) {
- jam();
- sendSystemerror(signal, __LINE__);
- }//if
-}//Dbacc::releaseScanContainer()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_SCAN_REC */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseScanRec(Signal* signal)
-{
- // Check that all ops this scan has allocated have been
- // released
- ndbrequire(scanPtr.p->scanOpsAllocated==0);
-
- // Check that all locks this scan might have aquired
- // have been properly released
- ndbrequire(scanPtr.p->scanLockHeld == 0);
- ndbrequire(scanPtr.p->scanFirstLockedOp == RNIL);
- ndbrequire(scanPtr.p->scanLastLockedOp == RNIL);
-
- // Check that all active operations have been
- // properly released
- ndbrequire(scanPtr.p->scanFirstActiveOp == RNIL);
-
- // Check that all queued operations have been
- // properly released
- ndbrequire(scanPtr.p->scanFirstQueuedOp == RNIL);
- ndbrequire(scanPtr.p->scanLastQueuedOp == RNIL);
-
- // Put scan record in free list
- scanPtr.p->scanNextfreerec = cfirstFreeScanRec;
- scanPtr.p->scanState = ScanRec::SCAN_DISCONNECT;
- cfirstFreeScanRec = scanPtr.i;
-
-}//Dbacc::releaseScanRec()
-
-/* --------------------------------------------------------------------------------- */
-/* SEARCH_SCAN_CONTAINER */
-/* INPUT: TSSC_CONTAINERLEN */
-/* TSSC_CONTAINERPTR */
-/* TSSC_ISFORWARD */
-/* SSC_PAGEIDPTR */
-/* SCAN_PTR */
-/* OUTPUT: TSSC_IS_LOCKED */
-/* */
-/* DESCRIPTION: SEARCH IN A CONTAINER TO FIND THE NEXT SCAN ELEMENT. */
-/* TO DO THIS THE SCAN BIT OF THE ELEMENT HEADER IS CHECKED. IF */
-/* THIS BIT IS ZERO, IT IS SET TO ONE AND THE ELEMENT IS RETURNED.*/
-/* --------------------------------------------------------------------------------- */
-bool Dbacc::searchScanContainer(Signal* signal)
-{
- OperationrecPtr sscOperPtr;
- Uint32 tsscScanBits;
- Uint32 tsscElemlens;
- Uint32 tsscElemlen;
- Uint32 tsscElemStep;
-
- if (tsscContainerlen < 4) {
- jam();
- return false; /* 2 IS THE MINIMUM SIZE OF THE ELEMENT */
- }//if
- tsscElemlens = tsscContainerlen - ZCON_HEAD_SIZE;
- tsscElemlen = fragrecptr.p->elementLength;
- /* LENGTH OF THE ELEMENT */
- if (tsscIsforward == 1) {
- jam();
- tsscElementptr = tsscContainerptr + ZCON_HEAD_SIZE;
- tsscElemStep = tsscElemlen;
- } else {
- jam();
- tsscElementptr = tsscContainerptr - 1;
- tsscElemStep = 0 - tsscElemlen;
- }//if
- SCANELEMENTLOOP001:
- arrGuard(tsscElementptr, 2048);
- const Uint32 eh = sscPageidptr.p->word32[tsscElementptr];
- tsscIsLocked = ElementHeader::getLocked(eh);
- if (!tsscIsLocked){
- jam();
- tsscScanBits = ElementHeader::getScanBits(eh);
- if ((scanPtr.p->scanMask & tsscScanBits) == 0) {
- jam();
- const Uint32 tmp = ElementHeader::setScanBit(eh, scanPtr.p->scanMask);
- dbgWord32(sscPageidptr, tsscElementptr, tmp);
- sscPageidptr.p->word32[tsscElementptr] = tmp;
- return true;
- }//if
- } else {
- jam();
- sscOperPtr.i = ElementHeader::getOpPtrI(eh);
- ptrCheckGuard(sscOperPtr, coprecsize, operationrec);
- if ((sscOperPtr.p->scanBits & scanPtr.p->scanMask) == 0) {
- jam();
- sscOperPtr.p->scanBits |= scanPtr.p->scanMask;
- return true;
- }//if
- }//if
- /* THE ELEMENT IS ALREADY SENT. */
- /* SEARCH FOR NEXT ONE */
- tsscElemlens = tsscElemlens - tsscElemlen;
- if (tsscElemlens > 1) {
- jam();
- tsscElementptr = tsscElementptr + tsscElemStep;
- goto SCANELEMENTLOOP001;
- }//if
- return false;
-}//Dbacc::searchScanContainer()
-
-/* --------------------------------------------------------------------------------- */
-/* SEND THE RESPONSE NEXT_SCANCONF AND POSSIBLE KEYINFO SIGNALS AS WELL. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::sendNextScanConf(Signal* signal)
-{
- scanPtr.p->scanTimer = scanPtr.p->scanContinuebCounter;
- Uint32 blockNo = refToBlock(scanPtr.p->scanUserblockref);
- jam();
- /** ---------------------------------------------------------------------
- * LQH WILL NOT HAVE ANY USE OF THE TUPLE KEY LENGTH IN THIS CASE AND
- * SO WE DO NOT PROVIDE IT. IN THIS CASE THESE VALUES ARE UNDEFINED.
- * ---------------------------------------------------------------------- */
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = operationRecPtr.i;
- signal->theData[2] = operationRecPtr.p->fid;
- signal->theData[3] = operationRecPtr.p->localdata[0];
- signal->theData[4] = operationRecPtr.p->localdata[1];
- signal->theData[5] = fragrecptr.p->localkeylen;
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 6);
- return;
-}//Dbacc::sendNextScanConf()
-
-/*---------------------------------------------------------------------------
- * sendScanHbRep
- * Description: Using Dispatcher::execute() to send a heartbeat to DBTC
- * from DBLQH telling the scan is alive. We use the sendScanHbRep()
- * in DBLQH, this needs to be done here in DBACC since it can take
- * a while before LQH receives an answer the normal way from ACC.
- *--------------------------------------------------------------------------*/
-void Dbacc::sendScanHbRep(Signal* signal, Uint32 scanPtrIndex)
-{
- scanPtr.i = scanPtrIndex;
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
-
- // If the timer status is on we continue with a new heartbeat in one second,
- // else the loop stops and we will not send a new CONTINUEB
- if (scanPtr.p->scanTimer != 0){
- if (scanPtr.p->scanTimer == scanPtr.p->scanContinuebCounter){
- jam();
- ndbrequire(scanPtr.p->scanState != ScanRec::SCAN_DISCONNECT);
-
- signal->theData[0] = scanPtr.p->scanUserptr;
- signal->theData[1] = scanPtr.p->scanTrid1;
- signal->theData[2] = scanPtr.p->scanTrid2;
- EXECUTE_DIRECT(DBLQH, GSN_SCAN_HBREP, signal, 3);
- jamEntry();
- }//if
- scanPtr.p->scanContinuebCounter++;
- signal->theData[0] = ZSEND_SCAN_HBREP;
- signal->theData[1] = scanPtr.i;
- sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 2);
- } else {
- jam();
- scanPtr.p->scanContinuebCounter = 0;
- }//if
-}//Dbacc::sendScanHbRep()
-
-/* --------------------------------------------------------------------------------- */
-/* SETLOCK */
-/* DESCRIPTION:SETS LOCK ON AN ELEMENT. INFORMATION ABOUT THE ELEMENT IS */
-/* SAVED IN THE ELEMENT HEAD.A COPY OF THIS INFORMATION WILL */
-/* BE PUT IN THE OPERATION RECORD. A FIELD IN THE HEADER OF */
-/* THE ELEMENT POINTS TO THE OPERATION RECORD. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::setlock(Signal* signal)
-{
- Uint32 tselTmp1;
-
- arrGuard(tslElementptr, 2048);
- tselTmp1 = slPageidptr.p->word32[tslElementptr];
- operationRecPtr.p->scanBits = ElementHeader::getScanBits(tselTmp1);
- operationRecPtr.p->hashvaluePart = ElementHeader::getHashValuePart(tselTmp1);
-
- tselTmp1 = ElementHeader::setLocked(operationRecPtr.i);
- dbgWord32(slPageidptr, tslElementptr, tselTmp1);
- slPageidptr.p->word32[tslElementptr] = tselTmp1;
-}//Dbacc::setlock()
-
-/* --------------------------------------------------------------------------------- */
-/* TAKE_OUT_ACTIVE_SCAN_OP */
-/* DESCRIPTION: AN ACTIVE SCAN OPERATION IS BELOGED TO AN ACTIVE LIST OF THE */
-/* SCAN RECORD. BY THIS SUBRUTIN THE LIST IS UPDATED. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::takeOutActiveScanOp(Signal* signal)
-{
- OperationrecPtr tasOperationRecPtr;
-
- if (operationRecPtr.p->prevOp != RNIL) {
- jam();
- tasOperationRecPtr.i = operationRecPtr.p->prevOp;
- ptrCheckGuard(tasOperationRecPtr, coprecsize, operationrec);
- tasOperationRecPtr.p->nextOp = operationRecPtr.p->nextOp;
- } else {
- jam();
- scanPtr.p->scanFirstActiveOp = operationRecPtr.p->nextOp;
- }//if
- if (operationRecPtr.p->nextOp != RNIL) {
- jam();
- tasOperationRecPtr.i = operationRecPtr.p->nextOp;
- ptrCheckGuard(tasOperationRecPtr, coprecsize, operationrec);
- tasOperationRecPtr.p->prevOp = operationRecPtr.p->prevOp;
- }//if
-}//Dbacc::takeOutActiveScanOp()
-
-/**
- * takeOutScanLockQueue
- *
- * Description: Take out an operation from the doubly linked
- * lock list on a scan record.
- *
- * @note Use putOpScanLockQue to insert a operation in
- * the list
- *
- */
-void Dbacc::takeOutScanLockQueue(Uint32 scanRecIndex)
-{
- OperationrecPtr tslOperationRecPtr;
- ScanRecPtr TscanPtr;
-
- TscanPtr.i = scanRecIndex;
- ptrCheckGuard(TscanPtr, cscanRecSize, scanRec);
-
- if (operationRecPtr.p->prevOp != RNIL) {
- jam();
- tslOperationRecPtr.i = operationRecPtr.p->prevOp;
- ptrCheckGuard(tslOperationRecPtr, coprecsize, operationrec);
- tslOperationRecPtr.p->nextOp = operationRecPtr.p->nextOp;
- } else {
- jam();
- // Check that first are pointing at operation to take out
- ndbrequire(TscanPtr.p->scanFirstLockedOp==operationRecPtr.i);
- TscanPtr.p->scanFirstLockedOp = operationRecPtr.p->nextOp;
- }//if
- if (operationRecPtr.p->nextOp != RNIL) {
- jam();
- tslOperationRecPtr.i = operationRecPtr.p->nextOp;
- ptrCheckGuard(tslOperationRecPtr, coprecsize, operationrec);
- tslOperationRecPtr.p->prevOp = operationRecPtr.p->prevOp;
- } else {
- jam();
- // Check that last are pointing at operation to take out
- ndbrequire(TscanPtr.p->scanLastLockedOp==operationRecPtr.i);
- TscanPtr.p->scanLastLockedOp = operationRecPtr.p->prevOp;
- }//if
- TscanPtr.p->scanLockHeld--;
-
-#ifdef VM_TRACE
- // DEBUG CODE
- // Check that there are as many operations in the lockqueue as
- // scanLockHeld indicates
- OperationrecPtr tmpOp;
- int numLockedOps = 0;
- tmpOp.i = TscanPtr.p->scanFirstLockedOp;
- while(tmpOp.i != RNIL){
- numLockedOps++;
- ptrCheckGuard(tmpOp, coprecsize, operationrec);
- if (tmpOp.p->nextOp == RNIL)
- ndbrequire(tmpOp.i == TscanPtr.p->scanLastLockedOp);
- tmpOp.i = tmpOp.p->nextOp;
- }
- ndbrequire(numLockedOps==TscanPtr.p->scanLockHeld);
-#endif
-}//Dbacc::takeOutScanLockQueue()
-
-/* --------------------------------------------------------------------------------- */
-/* TAKE_OUT_READY_SCAN_QUEUE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::takeOutReadyScanQueue(Signal* signal)
-{
- OperationrecPtr trsOperationRecPtr;
-
- if (operationRecPtr.p->prevOp != RNIL) {
- jam();
- trsOperationRecPtr.i = operationRecPtr.p->prevOp;
- ptrCheckGuard(trsOperationRecPtr, coprecsize, operationrec);
- trsOperationRecPtr.p->nextOp = operationRecPtr.p->nextOp;
- } else {
- jam();
- scanPtr.p->scanFirstQueuedOp = operationRecPtr.p->nextOp;
- }//if
- if (operationRecPtr.p->nextOp != RNIL) {
- jam();
- trsOperationRecPtr.i = operationRecPtr.p->nextOp;
- ptrCheckGuard(trsOperationRecPtr, coprecsize, operationrec);
- trsOperationRecPtr.p->prevOp = operationRecPtr.p->prevOp;
- } else {
- jam();
- scanPtr.p->scanLastQueuedOp = operationRecPtr.p->nextOp;
- }//if
-}//Dbacc::takeOutReadyScanQueue()
-
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* */
-/* END OF SCAN MODULE */
-/* */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-
-bool Dbacc::getfragmentrec(Signal* signal, FragmentrecPtr& rootPtr, Uint32 fid)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragholder[i] == fid) {
- jam();
- fragrecptr.i = tabptr.p->fragptrholder[i];
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- return true;
- }//if
- }//for
- return false;
-}//Dbacc::getrootfragmentrec()
-
-/* --------------------------------------------------------------------------------- */
-/* INIT_OVERPAGE */
-/* INPUT. IOP_PAGEPTR, POINTER TO AN OVERFLOW PAGE RECORD */
-/* DESCRIPTION: CONTAINERS AND FREE LISTS OF THE PAGE, GET INITIALE VALUE */
-/* ACCORDING TO LH3 AND PAGE STRUCTOR DESCRIPTION OF NDBACC BLOCK */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initOverpage(Signal* signal)
-{
- Uint32 tiopTmp;
- Uint32 tiopPrevFree;
- Uint32 tiopNextFree;
-
- for (tiopIndex = 0; tiopIndex <= 2047; tiopIndex++) {
- iopPageptr.p->word32[tiopIndex] = 0;
- }//for
- iopPageptr.p->word32[ZPOS_OVERFLOWREC] = iopOverflowRecPtr.i;
- iopPageptr.p->word32[ZPOS_CHECKSUM] = 0;
- iopPageptr.p->word32[ZPOS_PAGE_ID] = tiopPageId;
- iopPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] = 0;
- tiopTmp = ZEMPTYLIST;
- tiopTmp = (tiopTmp << 16) + (tiopTmp << 23);
- iopPageptr.p->word32[ZPOS_EMPTY_LIST] = tiopTmp + (1 << ZPOS_PAGE_TYPE_BIT);
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE PREVIOUS PART OF DOUBLY LINKED LIST FOR LEFT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tiopIndex = ZHEAD_SIZE + 1;
- iopPageptr.p->word32[tiopIndex] = ZEMPTYLIST;
- for (tiopPrevFree = 0; tiopPrevFree <= ZEMPTYLIST - 2; tiopPrevFree++) {
- tiopIndex = tiopIndex + ZBUF_SIZE;
- iopPageptr.p->word32[tiopIndex] = tiopPrevFree;
- }//for
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE NEXT PART OF DOUBLY LINKED LIST FOR LEFT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tiopIndex = ZHEAD_SIZE;
- for (tiopNextFree = 1; tiopNextFree <= ZEMPTYLIST - 1; tiopNextFree++) {
- iopPageptr.p->word32[tiopIndex] = tiopNextFree;
- tiopIndex = tiopIndex + ZBUF_SIZE;
- }//for
- iopPageptr.p->word32[tiopIndex] = ZEMPTYLIST; /* LEFT_LIST IS UPDATED */
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE PREVIOUS PART OF DOUBLY LINKED LIST FOR RIGHT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tiopIndex = (ZBUF_SIZE + ZHEAD_SIZE) - 1;
- iopPageptr.p->word32[tiopIndex] = ZEMPTYLIST;
- for (tiopPrevFree = 0; tiopPrevFree <= ZEMPTYLIST - 2; tiopPrevFree++) {
- tiopIndex = tiopIndex + ZBUF_SIZE;
- iopPageptr.p->word32[tiopIndex] = tiopPrevFree;
- }//for
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE NEXT PART OF DOUBLY LINKED LIST FOR RIGHT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tiopIndex = (ZBUF_SIZE + ZHEAD_SIZE) - 2;
- for (tiopNextFree = 1; tiopNextFree <= ZEMPTYLIST - 1; tiopNextFree++) {
- iopPageptr.p->word32[tiopIndex] = tiopNextFree;
- tiopIndex = tiopIndex + ZBUF_SIZE;
- }//for
- iopPageptr.p->word32[tiopIndex] = ZEMPTYLIST; /* RIGHT_LIST IS UPDATED */
-}//Dbacc::initOverpage()
-
-/* --------------------------------------------------------------------------------- */
-/* INIT_PAGE */
-/* INPUT. INP_PAGEPTR, POINTER TO A PAGE RECORD */
-/* DESCRIPTION: CONTAINERS AND FREE LISTS OF THE PAGE, GET INITIALE VALUE */
-/* ACCORDING TO LH3 AND PAGE STRUCTOR DISACRIPTION OF NDBACC BLOCK */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::initPage(Signal* signal)
-{
- Uint32 tinpTmp1;
- Uint32 tinpIndex;
- Uint32 tinpTmp;
- Uint32 tinpPrevFree;
- Uint32 tinpNextFree;
-
- for (tiopIndex = 0; tiopIndex <= 2047; tiopIndex++) {
- inpPageptr.p->word32[tiopIndex] = 0;
- }//for
- /* --------------------------------------------------------------------------------- */
- /* SET PAGE ID FOR USE OF CHECKPOINTER. */
- /* PREPARE CONTAINER HEADERS INDICATING EMPTY CONTAINERS WITHOUT NEXT. */
- /* --------------------------------------------------------------------------------- */
- inpPageptr.p->word32[ZPOS_PAGE_ID] = tipPageId;
- tinpTmp1 = ZCON_HEAD_SIZE;
- tinpTmp1 = tinpTmp1 << 26;
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE ZNO_CONTAINERS PREDEFINED HEADERS ON LEFT SIZE. */
- /* --------------------------------------------------------------------------------- */
- tinpIndex = ZHEAD_SIZE;
- for (tinpTmp = 0; tinpTmp <= ZNO_CONTAINERS - 1; tinpTmp++) {
- inpPageptr.p->word32[tinpIndex] = tinpTmp1;
- tinpIndex = tinpIndex + ZBUF_SIZE;
- }//for
- /* WORD32(ZPOS_EMPTY_LIST) DATA STRUCTURE:*/
- /*--------------------------------------- */
- /*| PAGE TYPE|LEFT FREE|RIGHT FREE */
- /*| 1 | LIST | LIST */
- /*| BIT | 7 BITS | 7 BITS */
- /*--------------------------------------- */
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE FIRST POINTER TO DOUBLY LINKED LIST OF FREE CONTAINERS. */
- /* INITIALISE EMPTY LISTS OF USED CONTAINERS. */
- /* INITIALISE LEFT FREE LIST TO 64 AND RIGHT FREE LIST TO ZERO. */
- /* ALSO INITIALISE PAGE TYPE TO NOT OVERFLOW PAGE. */
- /* --------------------------------------------------------------------------------- */
- tinpTmp = ZEMPTYLIST;
- tinpTmp = (tinpTmp << 16) + (tinpTmp << 23);
- tinpTmp = tinpTmp + (ZNO_CONTAINERS << 7);
- inpPageptr.p->word32[ZPOS_EMPTY_LIST] = tinpTmp;
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE PREVIOUS PART OF DOUBLY LINKED LIST FOR RIGHT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tinpIndex = (ZHEAD_SIZE + ZBUF_SIZE) - 1;
- inpPageptr.p->word32[tinpIndex] = ZEMPTYLIST;
- for (tinpPrevFree = 0; tinpPrevFree <= ZEMPTYLIST - 2; tinpPrevFree++) {
- tinpIndex = tinpIndex + ZBUF_SIZE;
- inpPageptr.p->word32[tinpIndex] = tinpPrevFree;
- }//for
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE NEXT PART OF DOUBLY LINKED LIST FOR RIGHT CONTAINERS. */
- /* --------------------------------------------------------------------------------- */
- tinpIndex = (ZHEAD_SIZE + ZBUF_SIZE) - 2;
- for (tinpNextFree = 1; tinpNextFree <= ZEMPTYLIST - 1; tinpNextFree++) {
- inpPageptr.p->word32[tinpIndex] = tinpNextFree;
- tinpIndex = tinpIndex + ZBUF_SIZE;
- }//for
- inpPageptr.p->word32[tinpIndex] = ZEMPTYLIST;
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE PREVIOUS PART OF DOUBLY LINKED LIST FOR LEFT CONTAINERS. */
- /* THE FIRST ZNO_CONTAINERS ARE NOT PUT INTO FREE LIST SINCE THEY ARE */
- /* PREDEFINED AS OCCUPIED. */
- /* --------------------------------------------------------------------------------- */
- tinpIndex = (ZNO_CONTAINERS * ZBUF_SIZE) + ZHEAD_SIZE;
- for (tinpNextFree = ZNO_CONTAINERS + 1; tinpNextFree <= ZEMPTYLIST - 1; tinpNextFree++) {
- inpPageptr.p->word32[tinpIndex] = tinpNextFree;
- tinpIndex = tinpIndex + ZBUF_SIZE;
- }//for
- inpPageptr.p->word32[tinpIndex] = ZEMPTYLIST;
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE NEXT PART OF DOUBLY LINKED LIST FOR LEFT CONTAINERS. */
- /* THE FIRST ZNO_CONTAINERS ARE NOT PUT INTO FREE LIST SINCE THEY ARE */
- /* PREDEFINED AS OCCUPIED. */
- /* --------------------------------------------------------------------------------- */
- tinpIndex = ((ZNO_CONTAINERS * ZBUF_SIZE) + ZHEAD_SIZE) + 1;
- inpPageptr.p->word32[tinpIndex] = ZEMPTYLIST;
- for (tinpPrevFree = ZNO_CONTAINERS; tinpPrevFree <= ZEMPTYLIST - 2; tinpPrevFree++) {
- tinpIndex = tinpIndex + ZBUF_SIZE;
- inpPageptr.p->word32[tinpIndex] = tinpPrevFree;
- }//for
- /* --------------------------------------------------------------------------------- */
- /* INITIALISE HEADER POSITIONS NOT CURRENTLY USED AND ENSURE USE OF OVERFLOW */
- /* RECORD POINTER ON THIS PAGE LEADS TO ERROR. */
- /* --------------------------------------------------------------------------------- */
- inpPageptr.p->word32[ZPOS_CHECKSUM] = 0;
- inpPageptr.p->word32[ZPOS_ALLOC_CONTAINERS] = 0;
- inpPageptr.p->word32[ZPOS_OVERFLOWREC] = RNIL;
-}//Dbacc::initPage()
-
-/* --------------------------------------------------------------------------------- */
-/* PUT_OVERFLOW_REC_IN_FRAG */
-/* DESCRIPTION: AN OVERFLOW RECORD WITCH IS USED TO KEEP INFORMATION ABOUT */
-/* OVERFLOW PAGE WILL BE PUT IN A LIST OF OVERFLOW RECORDS IN */
-/* THE FRAGMENT RECORD. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::putOverflowRecInFrag(Signal* signal)
-{
- OverflowRecordPtr tpifNextOverrecPtr;
- OverflowRecordPtr tpifPrevOverrecPtr;
-
- tpifNextOverrecPtr.i = fragrecptr.p->firstOverflowRec;
- LINT_INIT(tpifPrevOverrecPtr.p);
- tpifPrevOverrecPtr.i = RNIL;
- while (tpifNextOverrecPtr.i != RNIL) {
- ptrCheckGuard(tpifNextOverrecPtr, coverflowrecsize, overflowRecord);
- if (tpifNextOverrecPtr.p->dirindex < porOverflowRecPtr.p->dirindex) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* PROCEED IN LIST TO THE NEXT IN THE LIST SINCE THE ENTRY HAD A LOWER PAGE ID.*/
- /* WE WANT TO ENSURE THAT LOWER PAGE ID'S ARE KEPT FULL RATHER THAN THE */
- /* OPPOSITE TO ENSURE THAT HIGH PAGE ID'S CAN BE REMOVED WHEN SHRINKS ARE */
- /* PERFORMED. */
- /* --------------------------------------------------------------------------------- */
- tpifPrevOverrecPtr = tpifNextOverrecPtr;
- tpifNextOverrecPtr.i = tpifNextOverrecPtr.p->nextOverRec;
- } else {
- jam();
- ndbrequire(tpifNextOverrecPtr.p->dirindex != porOverflowRecPtr.p->dirindex);
- /* --------------------------------------------------------------------------------- */
- /* TRYING TO INSERT THE SAME PAGE TWICE. SYSTEM ERROR. */
- /* --------------------------------------------------------------------------------- */
- break;
- }//if
- }//while
- if (tpifNextOverrecPtr.i == RNIL) {
- jam();
- fragrecptr.p->lastOverflowRec = porOverflowRecPtr.i;
- } else {
- jam();
- tpifNextOverrecPtr.p->prevOverRec = porOverflowRecPtr.i;
- }//if
- if (tpifPrevOverrecPtr.i == RNIL) {
- jam();
- fragrecptr.p->firstOverflowRec = porOverflowRecPtr.i;
- } else {
- jam();
- tpifPrevOverrecPtr.p->nextOverRec = porOverflowRecPtr.i;
- }//if
- porOverflowRecPtr.p->prevOverRec = tpifPrevOverrecPtr.i;
- porOverflowRecPtr.p->nextOverRec = tpifNextOverrecPtr.i;
-}//Dbacc::putOverflowRecInFrag()
-
-/* --------------------------------------------------------------------------------- */
-/* PUT_REC_IN_FREE_OVERDIR */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::putRecInFreeOverdir(Signal* signal)
-{
- OverflowRecordPtr tpfoNextOverrecPtr;
- OverflowRecordPtr tpfoPrevOverrecPtr;
-
- tpfoNextOverrecPtr.i = fragrecptr.p->firstFreeDirindexRec;
- LINT_INIT(tpfoPrevOverrecPtr.p);
- tpfoPrevOverrecPtr.i = RNIL;
- while (tpfoNextOverrecPtr.i != RNIL) {
- ptrCheckGuard(tpfoNextOverrecPtr, coverflowrecsize, overflowRecord);
- if (tpfoNextOverrecPtr.p->dirindex < priOverflowRecPtr.p->dirindex) {
- jam();
- /* --------------------------------------------------------------------------------- */
- /* PROCEED IN LIST TO THE NEXT IN THE LIST SINCE THE ENTRY HAD A LOWER PAGE ID.*/
- /* WE WANT TO ENSURE THAT LOWER PAGE ID'S ARE KEPT FULL RATHER THAN THE */
- /* OPPOSITE TO ENSURE THAT HIGH PAGE ID'S CAN BE REMOVED WHEN SHRINKS ARE */
- /* PERFORMED. */
- /* --------------------------------------------------------------------------------- */
- tpfoPrevOverrecPtr = tpfoNextOverrecPtr;
- tpfoNextOverrecPtr.i = tpfoNextOverrecPtr.p->nextOverList;
- } else {
- jam();
- ndbrequire(tpfoNextOverrecPtr.p->dirindex != priOverflowRecPtr.p->dirindex);
- /* --------------------------------------------------------------------------------- */
- /* ENSURE WE ARE NOT TRYING TO INSERT THE SAME PAGE TWICE. */
- /* --------------------------------------------------------------------------------- */
- break;
- }//if
- }//while
- if (tpfoNextOverrecPtr.i != RNIL) {
- jam();
- tpfoNextOverrecPtr.p->prevOverList = priOverflowRecPtr.i;
- }//if
- if (tpfoPrevOverrecPtr.i == RNIL) {
- jam();
- fragrecptr.p->firstFreeDirindexRec = priOverflowRecPtr.i;
- } else {
- jam();
- tpfoPrevOverrecPtr.p->nextOverList = priOverflowRecPtr.i;
- }//if
- priOverflowRecPtr.p->prevOverList = tpfoPrevOverrecPtr.i;
- priOverflowRecPtr.p->nextOverList = tpfoNextOverrecPtr.i;
-}//Dbacc::putRecInFreeOverdir()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_DIRECTORY */
-/* --------------------------------------- ----------------------------------------- */
-void Dbacc::releaseDirectory(Signal* signal)
-{
- ptrCheckGuard(rdDirptr, cdirarraysize, directoryarray);
- rdDirptr.p->pagep[0] = cfirstfreedir;
- cfirstfreedir = rdDirptr.i;
-}//Dbacc::releaseDirectory()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_DIRRANGE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseDirrange(Signal* signal)
-{
- ptrCheckGuard(rdDirRangePtr, cdirrangesize, dirRange);
- rdDirRangePtr.p->dirArray[0] = cfirstfreeDirrange;
- cfirstfreeDirrange = rdDirRangePtr.i;
-}//Dbacc::releaseDirrange()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE OP RECORD */
-/* PUT A FREE OPERATION IN A FREE LIST OF THE OPERATIONS */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseOpRec(Signal* signal)
-{
-#if 0
- // DEBUG CODE
- // Check that the operation to be released isn't
- // already in the list of free operations
- // Since this code loops through the entire list of free operations
- // it's only enabled in VM_TRACE mode
- OperationrecPtr opRecPtr;
- bool opInList = false;
- opRecPtr.i = cfreeopRec;
- while (opRecPtr.i != RNIL){
- if (opRecPtr.i == operationRecPtr.i){
- opInList = true;
- break;
- }
- ptrCheckGuard(opRecPtr, coprecsize, operationrec);
- opRecPtr.i = opRecPtr.p->nextOp;
- }
- ndbrequire(opInList == false);
-#endif
- ndbrequire(operationRecPtr.p->m_op_bits == Operationrec::OP_INITIAL);
-
- operationRecPtr.p->nextOp = cfreeopRec;
- cfreeopRec = operationRecPtr.i; /* UPDATE FREE LIST OF OP RECORDS */
- operationRecPtr.p->prevOp = RNIL;
- operationRecPtr.p->m_op_bits = Operationrec::OP_INITIAL;
-}//Dbacc::releaseOpRec()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_OVERFLOW_REC */
-/* PUT A FREE OVERFLOW REC IN A FREE LIST OF THE OVERFLOW RECORDS */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseOverflowRec(Signal* signal)
-{
- rorOverflowRecPtr.p->nextfreeoverrec = cfirstfreeoverrec;
- cfirstfreeoverrec = rorOverflowRecPtr.i;
-}//Dbacc::releaseOverflowRec()
-
-/* --------------------------------------------------------------------------------- */
-/* RELEASE_OVERPAGE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::releaseOverpage(Signal* signal)
-{
- DirRangePtr ropOverflowrangeptr;
- DirectoryarrayPtr ropOverflowDirptr;
- OverflowRecordPtr ropOverflowRecPtr;
- OverflowRecordPtr tuodOverflowRecPtr;
- Uint32 tropTmp;
- Uint32 tropTmp1;
- Uint32 tropTmp2;
-
- ropOverflowRecPtr.i = ropPageptr.p->word32[ZPOS_OVERFLOWREC];
- ndbrequire(ropOverflowRecPtr.i != RNIL);
- /* THE OVERFLOW REC WILL BE TAKEN OUT OF THE */
- /* FREELIST OF OVERFLOW PAGE WITH FREE */
- /* CONTAINER AND WILL BE PUT IN THE FREE LIST */
- /* OF THE FREE DIRECTORY INDEXES. */
- if ((fragrecptr.p->lastOverflowRec == ropOverflowRecPtr.i) &&
- (fragrecptr.p->firstOverflowRec == ropOverflowRecPtr.i)) {
- jam();
- return; /* THERE IS ONLY ONE OVERFLOW PAGE */
- }//if
-#if kalle
- logicalPage = 0;
-
- i = fragrecptr.p->directory;
- p = dirRange.getPtr(i);
-
- i1 = logicalPage >> 8;
- i2 = logicalPage & 0xFF;
-
- ndbrequire(i1 < 256);
-
- i = p->dirArray[i1];
- p = directoryarray.getPtr(i);
-
- physicPageId = p->pagep[i2];
- physicPageP = page8.getPtr(physicPageId);
-
- p->pagep[i2] = RNIL;
- rpPageptr = { physicPageId, physicPageP };
- releasePage(signal);
-
-#endif
-
- /* ----------------------------------------------------------------------- */
- /* IT WAS OK TO RELEASE THE PAGE. */
- /* ----------------------------------------------------------------------- */
- ptrCheckGuard(ropOverflowRecPtr, coverflowrecsize, overflowRecord);
- tfoOverflowRecPtr = ropOverflowRecPtr;
- takeRecOutOfFreeOverpage(signal);
- ropOverflowRecPtr.p->overpage = RNIL;
- priOverflowRecPtr = ropOverflowRecPtr;
- putRecInFreeOverdir(signal);
- tropTmp = ropPageptr.p->word32[ZPOS_PAGE_ID];
- ropOverflowrangeptr.i = fragrecptr.p->overflowdir;
- tropTmp1 = tropTmp >> 8;
- tropTmp2 = tropTmp & 0xff;
- ptrCheckGuard(ropOverflowrangeptr, cdirrangesize, dirRange);
- arrGuard(tropTmp1, 256);
- ropOverflowDirptr.i = ropOverflowrangeptr.p->dirArray[tropTmp1];
- ptrCheckGuard(ropOverflowDirptr, cdirarraysize, directoryarray);
- ropOverflowDirptr.p->pagep[tropTmp2] = RNIL;
- rpPageptr = ropPageptr;
- releasePage(signal);
- if (ropOverflowRecPtr.p->dirindex != (fragrecptr.p->lastOverIndex - 1)) {
- jam();
- return;
- }//if
- /* ----------------------------------------------------------------------- */
- /* THE LAST PAGE IN THE DIRECTORY WAS RELEASED IT IS NOW NECESSARY
- * TO REMOVE ALL RELEASED OVERFLOW DIRECTORIES AT THE END OF THE LIST.
- * ---------------------------------------------------------------------- */
- do {
- fragrecptr.p->lastOverIndex--;
- if (tropTmp2 == 0) {
- jam();
- ndbrequire(tropTmp1 != 0);
- ropOverflowrangeptr.p->dirArray[tropTmp1] = RNIL;
- rdDirptr.i = ropOverflowDirptr.i;
- releaseDirectory(signal);
- tropTmp1--;
- tropTmp2 = 255;
- } else {
- jam();
- tropTmp2--;
- }//if
- ropOverflowDirptr.i = ropOverflowrangeptr.p->dirArray[tropTmp1];
- ptrCheckGuard(ropOverflowDirptr, cdirarraysize, directoryarray);
- } while (ropOverflowDirptr.p->pagep[tropTmp2] == RNIL);
- /* ----------------------------------------------------------------------- */
- /* RELEASE ANY OVERFLOW RECORDS THAT ARE PART OF THE FREE INDEX LIST WHICH */
- /* DIRECTORY INDEX NOW HAS BEEN RELEASED. */
- /* ----------------------------------------------------------------------- */
- tuodOverflowRecPtr.i = fragrecptr.p->firstFreeDirindexRec;
- jam();
- while (tuodOverflowRecPtr.i != RNIL) {
- jam();
- ptrCheckGuard(tuodOverflowRecPtr, coverflowrecsize, overflowRecord);
- if (tuodOverflowRecPtr.p->dirindex >= fragrecptr.p->lastOverIndex) {
- jam();
- rorOverflowRecPtr = tuodOverflowRecPtr;
- troOverflowRecPtr.p = tuodOverflowRecPtr.p;
- tuodOverflowRecPtr.i = troOverflowRecPtr.p->nextOverList;
- takeRecOutOfFreeOverdir(signal);
- releaseOverflowRec(signal);
- } else {
- jam();
- tuodOverflowRecPtr.i = tuodOverflowRecPtr.p->nextOverList;
- }//if
- }//while
-}//Dbacc::releaseOverpage()
-
-/* ------------------------------------------------------------------------- */
-/* RELEASE_PAGE */
-/* ------------------------------------------------------------------------- */
-void Dbacc::releasePage(Signal* signal)
-{
-#ifdef VM_TRACE
- bool inList = false;
- Uint32 numInList = 0;
- Page8Ptr tmpPagePtr;
- tmpPagePtr.i = cfirstfreepage;
- while (tmpPagePtr.i != RNIL){
- ptrCheckGuard(tmpPagePtr, cpagesize, page8);
- if (tmpPagePtr.i == rpPageptr.i){
- jam(); inList = true;
- break;
- }
- numInList++;
- tmpPagePtr.i = tmpPagePtr.p->word32[0];
- }
- ndbrequire(inList == false);
- // ndbrequire(numInList == cnoOfAllocatedPages);
-#endif
- rpPageptr.p->word32[0] = cfirstfreepage;
- cfirstfreepage = rpPageptr.i;
- cnoOfAllocatedPages--;
-}//Dbacc::releasePage()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_DIRECTORY */
-/* DESCRIPTION: A DIRECTORY BLOCK (ZDIRBLOCKSIZE NUMBERS OF DIRECTORY */
-/* RECORDS WILL BE ALLOCATED AND RETURNED. */
-/* SIZE OF DIRECTORY ERROR_CODE, WILL BE RETURNED IF THERE IS NO ANY */
-/* FREE BLOCK */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeDirectory(Signal* signal)
-{
- Uint32 tsdyIndex;
-
- if (cfirstfreedir == RNIL) {
- jam();
- if (cdirarraysize <= cdirmemory) {
- jam();
- tresult = ZDIRSIZE_ERROR;
- return;
- } else {
- jam();
- sdDirptr.i = cdirmemory;
- ptrCheckGuard(sdDirptr, cdirarraysize, directoryarray);
- cdirmemory = cdirmemory + 1;
- }//if
- } else {
- jam();
- sdDirptr.i = cfirstfreedir;
- ptrCheckGuard(sdDirptr, cdirarraysize, directoryarray);
- cfirstfreedir = sdDirptr.p->pagep[0];
- sdDirptr.p->pagep[0] = RNIL;
- }//if
- for (tsdyIndex = 0; tsdyIndex <= 255; tsdyIndex++) {
- sdDirptr.p->pagep[tsdyIndex] = RNIL;
- }//for
-}//Dbacc::seizeDirectory()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_DIRRANGE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeDirrange(Signal* signal)
-{
- Uint32 tsdeIndex;
-
- newDirRangePtr.i = cfirstfreeDirrange;
- ptrCheckGuard(newDirRangePtr, cdirrangesize, dirRange);
- cfirstfreeDirrange = newDirRangePtr.p->dirArray[0];
- for (tsdeIndex = 0; tsdeIndex <= 255; tsdeIndex++) {
- newDirRangePtr.p->dirArray[tsdeIndex] = RNIL;
- }//for
-}//Dbacc::seizeDirrange()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE FRAGREC */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeFragrec(Signal* signal)
-{
- fragrecptr.i = cfirstfreefrag;
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- cfirstfreefrag = fragrecptr.p->nextfreefrag;
- fragrecptr.p->nextfreefrag = RNIL;
-}//Dbacc::seizeFragrec()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_OP_REC */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeOpRec(Signal* signal)
-{
- operationRecPtr.i = cfreeopRec;
- ptrCheckGuard(operationRecPtr, coprecsize, operationrec);
- cfreeopRec = operationRecPtr.p->nextOp; /* UPDATE FREE LIST OF OP RECORDS */
- /* PUTS OPERTION RECORD PTR IN THE LIST */
- /* OF OPERATION IN CONNECTION RECORD */
- operationRecPtr.p->nextOp = RNIL;
-}//Dbacc::seizeOpRec()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE OVERFLOW RECORD */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeOverRec(Signal* signal) {
- sorOverflowRecPtr.i = cfirstfreeoverrec;
- ptrCheckGuard(sorOverflowRecPtr, coverflowrecsize, overflowRecord);
- cfirstfreeoverrec = sorOverflowRecPtr.p->nextfreeoverrec;
- sorOverflowRecPtr.p->nextfreeoverrec = RNIL;
- sorOverflowRecPtr.p->prevOverRec = RNIL;
- sorOverflowRecPtr.p->nextOverRec = RNIL;
-}//Dbacc::seizeOverRec()
-
-
-/**
- * A ZPAGESIZE_ERROR has occured, out of index pages
- * Print some debug info if debug compiled
- */
-void Dbacc::zpagesize_error(const char* where){
- DEBUG(where << endl
- << " ZPAGESIZE_ERROR" << endl
- << " cfirstfreepage=" << cfirstfreepage << endl
- << " cfreepage=" <<cfreepage<<endl
- << " cpagesize=" <<cpagesize<<endl
- << " cnoOfAllocatedPages="<<cnoOfAllocatedPages);
-}
-
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_PAGE */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizePage(Signal* signal)
-{
- tresult = 0;
- if (cfirstfreepage == RNIL) {
- if (cfreepage < cpagesize) {
- jam();
- spPageptr.i = cfreepage;
- ptrCheckGuard(spPageptr, cpagesize, page8);
- cfreepage++;
- cnoOfAllocatedPages++;
- } else {
- jam();
- zpagesize_error("Dbacc::seizePage");
- tresult = ZPAGESIZE_ERROR;
- }//if
- } else {
- jam();
- spPageptr.i = cfirstfreepage;
- ptrCheckGuard(spPageptr, cpagesize, page8);
- cfirstfreepage = spPageptr.p->word32[0];
- cnoOfAllocatedPages++;
- }//if
-}//Dbacc::seizePage()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_ROOTFRAGREC */
-/* --------------------------------------------------------------------------------- */
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_SCAN_REC */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::seizeScanRec(Signal* signal)
-{
- scanPtr.i = cfirstFreeScanRec;
- ptrCheckGuard(scanPtr, cscanRecSize, scanRec);
- ndbrequire(scanPtr.p->scanState == ScanRec::SCAN_DISCONNECT);
- cfirstFreeScanRec = scanPtr.p->scanNextfreerec;
-}//Dbacc::seizeScanRec()
-
-/* --------------------------------------------------------------------------------- */
-/* SEIZE_SR_VERSION_REC */
-/* --------------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------------- */
-/* SEND_SYSTEMERROR */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::sendSystemerror(Signal* signal, int line)
-{
- progError(line, NDBD_EXIT_PRGERR);
-}//Dbacc::sendSystemerror()
-
-/* --------------------------------------------------------------------------------- */
-/* TAKE_REC_OUT_OF_FREE_OVERDIR */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::takeRecOutOfFreeOverdir(Signal* signal)
-{
- OverflowRecordPtr tofoOverrecPtr;
- if (troOverflowRecPtr.p->nextOverList != RNIL) {
- jam();
- tofoOverrecPtr.i = troOverflowRecPtr.p->nextOverList;
- ptrCheckGuard(tofoOverrecPtr, coverflowrecsize, overflowRecord);
- tofoOverrecPtr.p->prevOverList = troOverflowRecPtr.p->prevOverList;
- }//if
- if (troOverflowRecPtr.p->prevOverList != RNIL) {
- jam();
- tofoOverrecPtr.i = troOverflowRecPtr.p->prevOverList;
- ptrCheckGuard(tofoOverrecPtr, coverflowrecsize, overflowRecord);
- tofoOverrecPtr.p->nextOverList = troOverflowRecPtr.p->nextOverList;
- } else {
- jam();
- fragrecptr.p->firstFreeDirindexRec = troOverflowRecPtr.p->nextOverList;
- }//if
-}//Dbacc::takeRecOutOfFreeOverdir()
-
-/* --------------------------------------------------------------------------------- */
-/* TAKE_REC_OUT_OF_FREE_OVERPAGE */
-/* DESCRIPTION: AN OVERFLOW PAGE WHICH IS EMPTY HAVE TO BE TAKE OUT OF THE */
-/* FREE LIST OF OVERFLOW PAGE. BY THIS SUBROUTINE THIS LIST */
-/* WILL BE UPDATED. */
-/* --------------------------------------------------------------------------------- */
-void Dbacc::takeRecOutOfFreeOverpage(Signal* signal)
-{
- OverflowRecordPtr tfoNextOverflowRecPtr;
- OverflowRecordPtr tfoPrevOverflowRecPtr;
-
- if (tfoOverflowRecPtr.p->nextOverRec != RNIL) {
- jam();
- tfoNextOverflowRecPtr.i = tfoOverflowRecPtr.p->nextOverRec;
- ptrCheckGuard(tfoNextOverflowRecPtr, coverflowrecsize, overflowRecord);
- tfoNextOverflowRecPtr.p->prevOverRec = tfoOverflowRecPtr.p->prevOverRec;
- } else {
- ndbrequire(fragrecptr.p->lastOverflowRec == tfoOverflowRecPtr.i);
- jam();
- fragrecptr.p->lastOverflowRec = tfoOverflowRecPtr.p->prevOverRec;
- }//if
- if (tfoOverflowRecPtr.p->prevOverRec != RNIL) {
- jam();
- tfoPrevOverflowRecPtr.i = tfoOverflowRecPtr.p->prevOverRec;
- ptrCheckGuard(tfoPrevOverflowRecPtr, coverflowrecsize, overflowRecord);
- tfoPrevOverflowRecPtr.p->nextOverRec = tfoOverflowRecPtr.p->nextOverRec;
- } else {
- ndbrequire(fragrecptr.p->firstOverflowRec == tfoOverflowRecPtr.i);
- jam();
- fragrecptr.p->firstOverflowRec = tfoOverflowRecPtr.p->nextOverRec;
- }//if
-}//Dbacc::takeRecOutOfFreeOverpage()
-
-void
-Dbacc::reportMemoryUsage(Signal* signal, int gth){
- signal->theData[0] = NDB_LE_MemoryUsage;
- signal->theData[1] = gth;
- signal->theData[2] = sizeof(* rpPageptr.p);
- signal->theData[3] = cnoOfAllocatedPages;
- signal->theData[4] = cpagesize;
- signal->theData[5] = DBACC;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
-}
-
-void
-Dbacc::execDUMP_STATE_ORD(Signal* signal)
-{
- DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
- if (dumpState->args[0] == DumpStateOrd::AccDumpOneScanRec){
- Uint32 recordNo = RNIL;
- if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= cscanRecSize)
- return;
-
- scanPtr.i = recordNo;
- ptrAss(scanPtr, scanRec);
- infoEvent("Dbacc::ScanRec[%d]: state=%d, transid(0x%x, 0x%x)",
- scanPtr.i, scanPtr.p->scanState,scanPtr.p->scanTrid1,
- scanPtr.p->scanTrid2);
- infoEvent(" timer=%d, continueBCount=%d, "
- "activeLocalFrag=%d, nextBucketIndex=%d",
- scanPtr.p->scanTimer,
- scanPtr.p->scanContinuebCounter,
- scanPtr.p->activeLocalFrag,
- scanPtr.p->nextBucketIndex);
- infoEvent(" scanNextfreerec=%d firstActOp=%d firstLockedOp=%d, "
- "scanLastLockedOp=%d firstQOp=%d lastQOp=%d",
- scanPtr.p->scanNextfreerec,
- scanPtr.p->scanFirstActiveOp,
- scanPtr.p->scanFirstLockedOp,
- scanPtr.p->scanLastLockedOp,
- scanPtr.p->scanFirstQueuedOp,
- scanPtr.p->scanLastQueuedOp);
- infoEvent(" scanUserP=%d, startNoBuck=%d, minBucketIndexToRescan=%d, "
- "maxBucketIndexToRescan=%d",
- scanPtr.p->scanUserptr,
- scanPtr.p->startNoOfBuckets,
- scanPtr.p->minBucketIndexToRescan,
- scanPtr.p->maxBucketIndexToRescan);
- infoEvent(" scanBucketState=%d, scanLockHeld=%d, userBlockRef=%d, "
- "scanMask=%d scanLockMode=%d",
- scanPtr.p->scanBucketState,
- scanPtr.p->scanLockHeld,
- scanPtr.p->scanUserblockref,
- scanPtr.p->scanMask,
- scanPtr.p->scanLockMode);
- return;
- }
-
- // Dump all ScanRec(ords)
- if (dumpState->args[0] == DumpStateOrd::AccDumpAllScanRec){
- Uint32 recordNo = 0;
- if (signal->length() == 1)
- infoEvent("ACC: Dump all ScanRec - size: %d",
- cscanRecSize);
- else if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- dumpState->args[0] = DumpStateOrd::AccDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
-
- if (recordNo < cscanRecSize-1){
- dumpState->args[0] = DumpStateOrd::AccDumpAllScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- return;
- }
-
- // Dump all active ScanRec(ords)
- if (dumpState->args[0] == DumpStateOrd::AccDumpAllActiveScanRec){
- Uint32 recordNo = 0;
- if (signal->length() == 1)
- infoEvent("ACC: Dump active ScanRec - size: %d",
- cscanRecSize);
- else if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- ScanRecPtr sp;
- sp.i = recordNo;
- ptrAss(sp, scanRec);
- if (sp.p->scanState != ScanRec::SCAN_DISCONNECT){
- dumpState->args[0] = DumpStateOrd::AccDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
- }
-
- if (recordNo < cscanRecSize-1){
- dumpState->args[0] = DumpStateOrd::AccDumpAllActiveScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::DumpPageMemory &&
- signal->getLength() == 1){
- reportMemoryUsage(signal, 0);
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::EnableUndoDelayDataWrite){
- ndbout << "Dbacc:: delay write of datapages for table = "
- << dumpState->args[1]<< endl;
- c_errorInsert3000_TableId = dumpState->args[1];
- SET_ERROR_INSERT_VALUE(3000);
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::AccDumpOneOperationRec){
- Uint32 recordNo = RNIL;
- if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= coprecsize)
- return;
-
- OperationrecPtr tmpOpPtr;
- tmpOpPtr.i = recordNo;
- ptrAss(tmpOpPtr, operationrec);
- infoEvent("Dbacc::operationrec[%d]: transid(0x%x, 0x%x)",
- tmpOpPtr.i, tmpOpPtr.p->transId1,
- tmpOpPtr.p->transId2);
- infoEvent("elementIsforward=%d, elementPage=%d, elementPointer=%d ",
- tmpOpPtr.p->elementIsforward, tmpOpPtr.p->elementPage,
- tmpOpPtr.p->elementPointer);
- infoEvent("fid=%d, fragptr=%d, hashvaluePart=%d ",
- tmpOpPtr.p->fid, tmpOpPtr.p->fragptr,
- tmpOpPtr.p->hashvaluePart);
- infoEvent("hashValue=%d", tmpOpPtr.p->hashValue);
- infoEvent("nextLockOwnerOp=%d, nextOp=%d, nextParallelQue=%d ",
- tmpOpPtr.p->nextLockOwnerOp, tmpOpPtr.p->nextOp,
- tmpOpPtr.p->nextParallelQue);
- infoEvent("nextSerialQue=%d, prevOp=%d ",
- tmpOpPtr.p->nextSerialQue,
- tmpOpPtr.p->prevOp);
- infoEvent("prevLockOwnerOp=%d, prevParallelQue=%d",
- tmpOpPtr.p->prevLockOwnerOp, tmpOpPtr.p->nextParallelQue);
- infoEvent("prevSerialQue=%d, scanRecPtr=%d",
- tmpOpPtr.p->prevSerialQue, tmpOpPtr.p->scanRecPtr);
- infoEvent("m_op_bits=0x%x, scanBits=%d ",
- tmpOpPtr.p->m_op_bits, tmpOpPtr.p->scanBits);
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::AccDumpNumOpRecs){
-
- Uint32 freeOpRecs = 0;
- OperationrecPtr opRecPtr;
- opRecPtr.i = cfreeopRec;
- while (opRecPtr.i != RNIL){
- freeOpRecs++;
- ptrCheckGuard(opRecPtr, coprecsize, operationrec);
- opRecPtr.i = opRecPtr.p->nextOp;
- }
-
- infoEvent("Dbacc::OperationRecords: num=%d, free=%d",
- coprecsize, freeOpRecs);
-
- return;
- }
- if(dumpState->args[0] == DumpStateOrd::AccDumpFreeOpRecs){
-
- OperationrecPtr opRecPtr;
- opRecPtr.i = cfreeopRec;
- while (opRecPtr.i != RNIL){
-
- dumpState->args[0] = DumpStateOrd::AccDumpOneOperationRec;
- dumpState->args[1] = opRecPtr.i;
- execDUMP_STATE_ORD(signal);
-
- ptrCheckGuard(opRecPtr, coprecsize, operationrec);
- opRecPtr.i = opRecPtr.p->nextOp;
- }
-
-
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::AccDumpNotFreeOpRecs){
- Uint32 recordStart = RNIL;
- if (signal->length() == 2)
- recordStart = dumpState->args[1];
- else
- return;
-
- if (recordStart >= coprecsize)
- return;
-
- for (Uint32 i = recordStart; i < coprecsize; i++){
-
- bool inFreeList = false;
- OperationrecPtr opRecPtr;
- opRecPtr.i = cfreeopRec;
- while (opRecPtr.i != RNIL){
- if (opRecPtr.i == i){
- inFreeList = true;
- break;
- }
- ptrCheckGuard(opRecPtr, coprecsize, operationrec);
- opRecPtr.i = opRecPtr.p->nextOp;
- }
- if (inFreeList == false){
- dumpState->args[0] = DumpStateOrd::AccDumpOneOperationRec;
- dumpState->args[1] = i;
- execDUMP_STATE_ORD(signal);
- }
- }
- return;
- }
-
-#if 0
- if (type == 100) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 2;
- req->secondaryTableId = RNIL;
- req->userPtr = 2;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 101) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 4;
- req->secondaryTableId = 5;
- req->userPtr = 4;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 102) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 6;
- req->secondaryTableId = 8;
- req->userPtr = 6;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 103) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 2;
- req->secondaryTableId = RNIL;
- req->userPtr = 2;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
- if (type == 104) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 4;
- req->secondaryTableId = 5;
- req->userPtr = 4;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
- if (type == 105) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 6;
- req->secondaryTableId = 8;
- req->userPtr = 6;
- req->userRef = DBDICT_REF;
- sendSignal(cownBlockref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
-#endif
-}//Dbacc::execDUMP_STATE_ORD()
-
-void
-Dbacc::execREAD_PSEUDO_REQ(Signal* signal){
- jamEntry();
- fragrecptr.i = signal->theData[0];
- Uint32 attrId = signal->theData[1];
- ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
- Uint64 tmp;
- switch(attrId){
- case AttributeHeader::ROW_COUNT:
- tmp = fragrecptr.p->noOfElements;
- break;
- case AttributeHeader::COMMIT_COUNT:
- tmp = fragrecptr.p->m_commit_count;
- break;
- default:
- tmp = 0;
- }
- memcpy(signal->theData, &tmp, 8); /* must be memcpy, gives strange results on
- * ithanium gcc (GCC) 3.4.1 smp linux 2.4
- * otherwise
- */
- // Uint32 * src = (Uint32*)&tmp;
- // signal->theData[0] = src[0];
- // signal->theData[1] = src[1];
-}
diff --git a/storage/ndb/src/kernel/blocks/dbdict/CreateIndex.txt b/storage/ndb/src/kernel/blocks/dbdict/CreateIndex.txt
deleted file mode 100644
index 3d11e501c07..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/CreateIndex.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-Unique Hash Index
-=================
-
-unique hash index X on T(A1,...,An) becomes:
-table X with primary key A1,...,An and extra attribute NDB$PK
-
-NDB$PK is primary key of T concatenated at 4-byte boundaries
-
-Protocols:
-
-U - user, initiator of protocol
-C - coordinator
-P - participants, including coordinator node
-
-RT_ - request type, current state
-
-P always replies to C with current RT_ (initially RT_DICT_PREPARE)
-C replies to U at the end
-
-CREATE INDEX
-------------
-
-U: RT_USER
-
-C: forward request to P's
-P: check and reply
-
-C: invoke CREATE TABLE for index table
-
-C: invoke ALTER INDEX online
-
-C: send RT_DICT_COMMIT to P's
-P: reply
-
-C: reply to U
-
-DROP INDEX
-----------
-
-[ todo ]
-
-ALTER INDEX online
-------------------
-
-U: RT_USER, RT_CREATE_INDEX, RT_NODERESTART, RT_SYSTEMRESTART
-
-C: forward request to P's
-P: check and reply
-
-C: send RT_DICT_TC to P's
-P: create index in local TC, and reply
-
-C: invoke CREATE TRIGGER for insert/update/delete triggers
-
-C: invoke BUILD INDEX
-
-C: send RT_DICT_COMMIT to P's
-P: reply
-
-C: reply to U
-
-ALTER INDEX offline
--------------------
-
-[ todo ]
-
-BUILD INDEX
------------
-
-U: RT_USER, RT_ALTER_INDEX
-
-C: forward request to P's
-P: check and reply
-
-C: invoke CREATE TRIGGER for read-only constraint on NDB$PK
-
-C: send RT_DICT_TRIX to P's
-P: build index via local TRIX, and reply
-
-C: invoke DROP TRIGGER for read-only constraint on NDB$PK
-
-C: send RT_DICT_TC to P's
-P: online index in local TC, and reply
-
-CREATE TRIGGER
---------------
-
-U: RT_USER, RT_ALTER_INDEX, RT_BUILD_INDEX
-
-C: forward request to P's
-P: check and reply
-
-C: seize trigger id and send RT_DICT_CREATE to P's
-P: create trigger in DICT (also connect to index record), and reply
-
-C: invoke ALTER TRIGGER online [ not if subscription trigger ]
-
-C: send RT_DICT_COMMIT to P's
-P: reply
-
-C: reply to U
-
-DROP TRIGGER
-------------
-
-[ todo ]
-
-ALTER TRIGGER online
---------------------
-
-U: RT_USER, RT_CREATE_TRIGGER
-
-C: forward request to P's
-P: check and reply
-
-C: send RT_DICT_TC to P's
-P: create trigger in local TC, and reply
-
-C: send RT_DICT_LQH to P's
-P: create trigger in local LQH (which just forwards to TUP), and reply
-
-C: send RT_DICT_COMMIT to P's
-P: reply
-
-C: reply to U
-
-ALTER TRIGGER offline
----------------------
-
-[ todo ]
-
-Ordered Index << under work >>
-=============
-
-created as DICT table, as before, to reuse the code
-
-keep NDB$PK as last attribute (not used but logically correct)
-
-create fragments and attributes must be modified
-
-global metadata? implemented but will use signals anyway
-
-create (after-) insert/update/delete triggers as DICT objects, as before
-
-skip following:
-- create index in TC
-- create triggers in TC
-- read-only constraint on NDB$PK
-
-create (before-) commit trigger in TUP
-
-alter online (in TUX, instead of TC) is needed
diff --git a/storage/ndb/src/kernel/blocks/dbdict/CreateTable.new.txt b/storage/ndb/src/kernel/blocks/dbdict/CreateTable.new.txt
deleted file mode 100644
index d37732dcda1..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/CreateTable.new.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-
-1) Receive from client (sequence of DICTTABINFO)
-
-2) CREATE_FRAGMENTATION_REQ -> local DIH
- Returns all fragments for table + some other stuff
- NOTE without side effects in DIH
-
-3) Pack table description
-
-4) CREATE_TAB -> all DICTs (including table data)
- 1) Write schema file (ADD_STARTED)
- 2) Write table descriptor to file
- 3) CREATE_TAB (DIADDTABREQ) -> local DIH (including fragment info)
- 4) DIH
- 1) write table descriptor
- 2) For each local fragment
- ADD_FRAG -> local DICT
- LQHFRAGREQ -> local LQH
- LQHADDATTREQ -> local LQH
- 5) TAB_COMMITREQ -> local LQH
-
-5) WAIT_GCP
-
-6) ALTER_TAB (activate) -> all DICTs
- 1) Write schema file (CREATED)
- 2) TAB_COMMITREQ -> local DIH
- 3) TC_SCHVERREQ -> local TC
-
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/CreateTable.txt b/storage/ndb/src/kernel/blocks/dbdict/CreateTable.txt
deleted file mode 100644
index 0b37e5d767f..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/CreateTable.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-
-1) Receive from client (sequence of DICTTABINFO)
-
-2) DICT_SCHEMAREQ -> all DICTs
- Write ADD_STARTED in schema file
-
-3) Pack table description
-
-4) DICTTABINFO -> all DICTs (but self) (containing packed table info)
- self -> Write 2 file
- 1) Write 2 file
-
-5) DICT_SCHEMAREQ -> all DICTs
- Write UPDATE_PAGE_COUNT in schema file
-
-6) DIADDTABREQ -> local DIH
- 1) Create fragments
- 2) For each fragment
- DIHADDFRAGREQ -> all DIH
- 3) For each fragment
- DICTFRAGSREQ -> local DICT
- 1) LQHFRAGREQ -> concerned LQH
- 2) For each attribute
- LQHADDATTREQ -> concerned LQH
-
-7) WAIT_GCP -> local DIH
-
-8) DICT_SCHEMAREQ -> all DICTs
- Write TABLE_ADD_COMMITTED in schema file
-
-9) TAB_COMMITREQ -> all LQH & DIH
-
-10) TC_SCHVERREQ -> all TC
-
-11) UNBLO_DICTREQ -> all DICT
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
deleted file mode 100644
index e0e0a496e0a..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ /dev/null
@@ -1,16702 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-
-#define DBDICT_C
-#include "Dbdict.hpp"
-#include "diskpage.hpp"
-
-#include <ndb_limits.h>
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include <Configuration.hpp>
-#include <SectionReader.hpp>
-#include <SimpleProperties.hpp>
-#include <AttributeHeader.hpp>
-#include <KeyDescriptor.hpp>
-#include <signaldata/DictSchemaInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/DropTabFile.hpp>
-
-#include <signaldata/EventReport.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/GetTableId.hpp>
-#include <signaldata/HotSpareRep.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/RelTabMem.hpp>
-#include <signaldata/WaitGCP.hpp>
-#include <signaldata/ListTables.hpp>
-
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/AlterTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/CreateIndx.hpp>
-#include <signaldata/DropIndx.hpp>
-#include <signaldata/BuildIndx.hpp>
-
-#include <signaldata/DropFilegroup.hpp>
-#include <signaldata/CreateFilegroup.hpp>
-#include <signaldata/CreateFilegroupImpl.hpp>
-
-#include <signaldata/CreateEvnt.hpp>
-#include <signaldata/UtilPrepare.hpp>
-#include <signaldata/UtilExecute.hpp>
-#include <signaldata/UtilRelease.hpp>
-#include <signaldata/SumaImpl.hpp>
-
-#include <signaldata/LqhFrag.hpp>
-
-#include <signaldata/DiAddTab.hpp>
-#include <signaldata/DihStartTab.hpp>
-
-#include <signaldata/DropTable.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/PrepDropTab.hpp>
-
-#include <signaldata/CreateTable.hpp>
-#include <signaldata/AlterTable.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/CreateFragmentation.hpp>
-#include <signaldata/CreateTab.hpp>
-#include <NdbSleep.h>
-#include <signaldata/ApiBroadcast.hpp>
-
-#include <signaldata/DropObj.hpp>
-#include <signaldata/CreateObj.hpp>
-#include <SLList.hpp>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-#define ZNOT_FOUND 626
-#define ZALREADYEXIST 630
-
-//#define EVENT_PH2_DEBUG
-//#define EVENT_PH3_DEBUG
-//#define EVENT_DEBUG
-
-static const char EVENT_SYSTEM_TABLE_NAME[] = "sys/def/NDB$EVENTS_0";
-
-#define EVENT_TRACE \
-// ndbout_c("Event debug trace: File: %s Line: %u", __FILE__, __LINE__)
-
-#define DIV(x,y) (((x)+(y)-1)/(y))
-#define WORDS2PAGES(x) DIV(x, (ZSIZE_OF_PAGES_IN_WORDS - ZPAGE_HEADER_SIZE))
-#include <ndb_version.h>
-
-static
-struct {
- Uint32 m_gsn_user_req;
- Uint32 m_gsn_req;
- Uint32 m_gsn_ref;
- Uint32 m_gsn_conf;
- void (Dbdict::* m_trans_commit_start)(Signal*, Dbdict::SchemaTransaction*);
- void (Dbdict::* m_trans_commit_complete)(Signal*,Dbdict::SchemaTransaction*);
- void (Dbdict::* m_trans_abort_start)(Signal*, Dbdict::SchemaTransaction*);
- void (Dbdict::* m_trans_abort_complete)(Signal*, Dbdict::SchemaTransaction*);
-
- void (Dbdict::* m_prepare_start)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_prepare_complete)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_commit)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_commit_start)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_commit_complete)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_abort)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_abort_start)(Signal*, Dbdict::SchemaOp*);
- void (Dbdict::* m_abort_complete)(Signal*, Dbdict::SchemaOp*);
-
-} f_dict_op[] = {
- /**
- * Create filegroup
- */
- {
- GSN_CREATE_FILEGROUP_REQ,
- GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
- 0, 0, 0, 0,
- &Dbdict::create_fg_prepare_start, &Dbdict::create_fg_prepare_complete,
- &Dbdict::createObj_commit,
- 0, 0,
- &Dbdict::createObj_abort,
- &Dbdict::create_fg_abort_start, &Dbdict::create_fg_abort_complete,
- }
-
- /**
- * Create file
- */
- ,{
- GSN_CREATE_FILE_REQ,
- GSN_CREATE_OBJ_REQ, GSN_CREATE_OBJ_REF, GSN_CREATE_OBJ_CONF,
- 0, 0, 0, 0,
- &Dbdict::create_file_prepare_start, &Dbdict::create_file_prepare_complete,
- &Dbdict::createObj_commit,
- &Dbdict::create_file_commit_start, 0,
- &Dbdict::createObj_abort,
- &Dbdict::create_file_abort_start, &Dbdict::create_file_abort_complete,
- }
-
- /**
- * Drop file
- */
- ,{
- GSN_DROP_FILE_REQ,
- GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
- 0, 0, 0, 0,
- &Dbdict::drop_file_prepare_start, 0,
- &Dbdict::dropObj_commit,
- &Dbdict::drop_file_commit_start, &Dbdict::drop_file_commit_complete,
- &Dbdict::dropObj_abort,
- &Dbdict::drop_file_abort_start, 0
- }
-
- /**
- * Drop filegroup
- */
- ,{
- GSN_DROP_FILEGROUP_REQ,
- GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
- 0, 0, 0, 0,
- &Dbdict::drop_fg_prepare_start, 0,
- &Dbdict::dropObj_commit,
- &Dbdict::drop_fg_commit_start, &Dbdict::drop_fg_commit_complete,
- &Dbdict::dropObj_abort,
- &Dbdict::drop_fg_abort_start, 0
- }
-
- /**
- * Drop undofile
- */
- ,{
- GSN_DROP_FILE_REQ,
- GSN_DROP_OBJ_REQ, GSN_DROP_OBJ_REF, GSN_DROP_OBJ_CONF,
- 0, 0, 0, 0,
- &Dbdict::drop_undofile_prepare_start, 0,
- 0,
- 0, &Dbdict::drop_undofile_commit_complete,
- 0, 0, 0
- }
-};
-
-Uint32
-alter_obj_inc_schema_version(Uint32 old)
-{
- return (old & 0x00FFFFFF) + ((old + 0x1000000) & 0xFF000000);
-}
-
-static
-Uint32
-alter_obj_dec_schema_version(Uint32 old)
-{
- return (old & 0x00FFFFFF) + ((old - 0x1000000) & 0xFF000000);
-}
-
-static
-Uint32
-create_obj_inc_schema_version(Uint32 old)
-{
- return (old + 0x00000001) & 0x00FFFFFF;
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: GENERAL MODULE -------------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains general stuff. Mostly debug signals and */
-/* general signals that go into a specific module after checking a */
-/* state variable. Also general subroutines used by many. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// This signal is used to dump states of various variables in the
-// block by command.
-/* ---------------------------------------------------------------- */
-void
-Dbdict::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
-
-#ifdef VM_TRACE
- if(signal->theData[0] == 1222){
- const Uint32 tab = signal->theData[1];
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
- req->senderRef = reference();
- req->senderData = 1222;
- req->tableId = tab;
- sendSignal(DBLQH_REF, GSN_PREP_DROP_TAB_REQ, signal,
- PrepDropTabReq::SignalLength, JBB);
- }
-
- if(signal->theData[0] == 1223){
- const Uint32 tab = signal->theData[1];
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
- req->senderRef = reference();
- req->senderData = 1222;
- req->tableId = tab;
- sendSignal(DBTC_REF, GSN_PREP_DROP_TAB_REQ, signal,
- PrepDropTabReq::SignalLength, JBB);
- }
-
- if(signal->theData[0] == 1224){
- const Uint32 tab = signal->theData[1];
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
- req->senderRef = reference();
- req->senderData = 1222;
- req->tableId = tab;
- sendSignal(DBDIH_REF, GSN_PREP_DROP_TAB_REQ, signal,
- PrepDropTabReq::SignalLength, JBB);
- }
-
- if(signal->theData[0] == 1225){
- const Uint32 tab = signal->theData[1];
- const Uint32 ver = signal->theData[2];
- TableRecordPtr tabRecPtr;
- c_tableRecordPool.getPtr(tabRecPtr, tab);
- DropTableReq * req = (DropTableReq*)signal->getDataPtr();
- req->senderData = 1225;
- req->senderRef = numberToRef(1,1);
- req->tableId = tab;
- req->tableVersion = tabRecPtr.p->tableVersion + ver;
- sendSignal(DBDICT_REF, GSN_DROP_TABLE_REQ, signal,
- DropTableReq::SignalLength, JBB);
- }
-#endif
-#define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree())
- if(signal->theData[0] == 1226){
- MEMINFO("c_obj_pool", c_obj_pool);
- MEMINFO("c_opRecordPool", c_opRecordPool);
- MEMINFO("c_rope_pool", c_rope_pool);
- }
-
- if (signal->theData[0] == 1227)
- {
- DLHashTable<DictObject>::Iterator iter;
- bool ok = c_obj_hash.first(iter);
- for(; ok; ok = c_obj_hash.next(iter))
- {
- Rope name(c_rope_pool, iter.curr.p->m_name);
- char buf[1024];
- name.copy(buf);
- ndbout_c("%s m_ref_count: %d", buf, iter.curr.p->m_ref_count);
- }
- }
-
- return;
-}//Dbdict::execDUMP_STATE_ORD()
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-// CONTINUEB is used when a real-time break is needed for long
-// processes.
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-void Dbdict::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- switch (signal->theData[0]) {
- case ZPACK_TABLE_INTO_PAGES :
- jam();
- packTableIntoPages(signal);
- break;
-
- case ZSEND_GET_TAB_RESPONSE :
- jam();
- sendGetTabResponse(signal);
- break;
-
- case ZDICT_LOCK_POLL:
- jam();
- checkDictLockQueue(signal, true);
- break;
-
- default :
- ndbrequire(false);
- break;
- }//switch
- return;
-}//execCONTINUEB()
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-// Routine to handle pack table into pages.
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-
-void Dbdict::packTableIntoPages(Signal* signal)
-{
- const Uint32 tableId= signal->theData[1];
- const Uint32 type= signal->theData[2];
- const Uint32 pageId= signal->theData[3];
-
- PageRecordPtr pagePtr;
- c_pageRecordArray.getPtr(pagePtr, pageId);
-
- memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
- LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE],
- ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS);
- w.first();
- switch((DictTabInfo::TableType)type) {
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- case DictTabInfo::UniqueHashIndex:
- case DictTabInfo::HashIndex:
- case DictTabInfo::UniqueOrderedIndex:
- case DictTabInfo::OrderedIndex:{
- jam();
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- packTableIntoPages(w, tablePtr, signal);
- break;
- }
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:{
- FilegroupPtr fg_ptr;
- ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
- const Uint32 free_hi= signal->theData[4];
- const Uint32 free_lo= signal->theData[5];
- packFilegroupIntoPages(w, fg_ptr, free_hi, free_lo);
- break;
- }
- case DictTabInfo::Datafile:{
- FilePtr fg_ptr;
- ndbrequire(c_file_hash.find(fg_ptr, tableId));
- const Uint32 free_extents= signal->theData[4];
- packFileIntoPages(w, fg_ptr, free_extents);
- break;
- }
- case DictTabInfo::Undofile:{
- FilePtr fg_ptr;
- ndbrequire(c_file_hash.find(fg_ptr, tableId));
- packFileIntoPages(w, fg_ptr, 0);
- break;
- }
- case DictTabInfo::UndefTableType:
- case DictTabInfo::HashIndexTrigger:
- case DictTabInfo::SubscriptionTrigger:
- case DictTabInfo::ReadOnlyConstraint:
- case DictTabInfo::IndexTrigger:
- ndbrequire(false);
- }
-
- Uint32 wordsOfTable = w.getWordsUsed();
- Uint32 pagesUsed = WORDS2PAGES(wordsOfTable);
- pagePtr.p->word[ZPOS_CHECKSUM] =
- computeChecksum(&pagePtr.p->word[0], pagesUsed * ZSIZE_OF_PAGES_IN_WORDS);
-
- switch (c_packTable.m_state) {
- case PackTable::PTS_IDLE:
- ndbrequire(false);
- break;
- case PackTable::PTS_GET_TAB:
- jam();
- c_retrieveRecord.retrievedNoOfPages = pagesUsed;
- c_retrieveRecord.retrievedNoOfWords = wordsOfTable;
- sendGetTabResponse(signal);
- return;
- break;
- }//switch
- ndbrequire(false);
- return;
-}//packTableIntoPages()
-
-void
-Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
- TableRecordPtr tablePtr,
- Signal* signal){
-
- union {
- char tableName[MAX_TAB_NAME_SIZE];
- char frmData[MAX_FRM_DATA_SIZE];
- char rangeData[16*MAX_NDB_PARTITIONS];
- char ngData[2*MAX_NDB_PARTITIONS];
- char tsData[2*2*MAX_NDB_PARTITIONS];
- char defaultValue[MAX_ATTR_DEFAULT_VALUE_SIZE];
- char attributeName[MAX_ATTR_NAME_SIZE];
- };
- ConstRope r(c_rope_pool, tablePtr.p->tableName);
- r.copy(tableName);
- w.add(DictTabInfo::TableName, tableName);
- w.add(DictTabInfo::TableId, tablePtr.i);
- w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion);
- w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey);
- w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes);
- w.add(DictTabInfo::NoOfNullable, tablePtr.p->noOfNullAttr);
- w.add(DictTabInfo::NoOfVariable, (Uint32)0);
- w.add(DictTabInfo::KeyLength, tablePtr.p->tupKeyLength);
-
- w.add(DictTabInfo::TableLoggedFlag,
- !!(tablePtr.p->m_bits & TableRecord::TR_Logged));
- w.add(DictTabInfo::RowGCIFlag,
- !!(tablePtr.p->m_bits & TableRecord::TR_RowGCI));
- w.add(DictTabInfo::RowChecksumFlag,
- !!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum));
- w.add(DictTabInfo::TableTemporaryFlag,
- !!(tablePtr.p->m_bits & TableRecord::TR_Temporary));
- w.add(DictTabInfo::ForceVarPartFlag,
- !!(tablePtr.p->m_bits & TableRecord::TR_ForceVarPart));
-
- w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor);
- w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor);
- w.add(DictTabInfo::TableKValue, tablePtr.p->kValue);
- w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType);
- w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType);
- w.add(DictTabInfo::MaxRowsLow, tablePtr.p->maxRowsLow);
- w.add(DictTabInfo::MaxRowsHigh, tablePtr.p->maxRowsHigh);
- w.add(DictTabInfo::DefaultNoPartFlag, tablePtr.p->defaultNoPartFlag);
- w.add(DictTabInfo::LinearHashFlag, tablePtr.p->linearHashFlag);
- w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
- w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow);
- w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh);
- w.add(DictTabInfo::SingleUserMode, tablePtr.p->singleUserMode);
-
- if(signal)
- {
- /* Denna branch körs vid GET_TABINFOREQ */
-
- Uint32 * theData = signal->getDataPtrSend();
- CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
- req->senderRef = 0;
- req->senderData = RNIL;
- req->fragmentationType = tablePtr.p->fragmentType;
- req->noOfFragments = 0;
- req->primaryTableId = tablePtr.i;
- EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
- CreateFragmentationReq::SignalLength);
- ndbrequire(signal->theData[0] == 0);
- Uint16 *data = (Uint16*)&signal->theData[25];
- Uint32 count = 2 + (1 + data[0]) * data[1];
- w.add(DictTabInfo::ReplicaDataLen, 2*count);
- for (Uint32 i = 0; i < count; i++)
- data[i] = htons(data[i]);
- w.add(DictTabInfo::ReplicaData, data, 2*count);
- }
- else
- {
- /* Denna del körs vid CREATE_TABLEREQ, ALTER_TABLEREQ */
- ;
- }
-
- if (tablePtr.p->primaryTableId != RNIL){
- TableRecordPtr primTab;
- c_tableRecordPool.getPtr(primTab, tablePtr.p->primaryTableId);
- ConstRope r2(c_rope_pool, primTab.p->tableName);
- r2.copy(tableName);
- w.add(DictTabInfo::PrimaryTable, tableName);
- w.add(DictTabInfo::PrimaryTableId, tablePtr.p->primaryTableId);
- w.add(DictTabInfo::IndexState, tablePtr.p->indexState);
- w.add(DictTabInfo::InsertTriggerId, tablePtr.p->insertTriggerId);
- w.add(DictTabInfo::UpdateTriggerId, tablePtr.p->updateTriggerId);
- w.add(DictTabInfo::DeleteTriggerId, tablePtr.p->deleteTriggerId);
- w.add(DictTabInfo::CustomTriggerId, tablePtr.p->customTriggerId);
- }
-
- ConstRope frm(c_rope_pool, tablePtr.p->frmData);
- frm.copy(frmData);
- w.add(DictTabInfo::FrmLen, frm.size());
- w.add(DictTabInfo::FrmData, frmData, frm.size());
-
- {
- jam();
- ConstRope ts(c_rope_pool, tablePtr.p->tsData);
- ts.copy(tsData);
- w.add(DictTabInfo::TablespaceDataLen, ts.size());
- w.add(DictTabInfo::TablespaceData, tsData, ts.size());
-
- ConstRope ng(c_rope_pool, tablePtr.p->ngData);
- ng.copy(ngData);
- w.add(DictTabInfo::FragmentDataLen, ng.size());
- w.add(DictTabInfo::FragmentData, ngData, ng.size());
-
- ConstRope range(c_rope_pool, tablePtr.p->rangeData);
- range.copy(rangeData);
- w.add(DictTabInfo::RangeListDataLen, range.size());
- w.add(DictTabInfo::RangeListData, rangeData, range.size());
- }
-
- if(tablePtr.p->m_tablespace_id != RNIL)
- {
- w.add(DictTabInfo::TablespaceId, tablePtr.p->m_tablespace_id);
- FilegroupPtr tsPtr;
- ndbrequire(c_filegroup_hash.find(tsPtr, tablePtr.p->m_tablespace_id));
- w.add(DictTabInfo::TablespaceVersion, tsPtr.p->m_version);
- }
-
- AttributeRecordPtr attrPtr;
- LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
- tablePtr.p->m_attributes);
- for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
- jam();
-
- ConstRope name(c_rope_pool, attrPtr.p->attributeName);
- name.copy(attributeName);
-
- w.add(DictTabInfo::AttributeName, attributeName);
- w.add(DictTabInfo::AttributeId, attrPtr.p->attributeId);
- w.add(DictTabInfo::AttributeKeyFlag, attrPtr.p->tupleKey > 0);
-
- const Uint32 desc = attrPtr.p->attributeDescriptor;
- const Uint32 attrType = AttributeDescriptor::getType(desc);
- const Uint32 attrSize = AttributeDescriptor::getSize(desc);
- const Uint32 arraySize = AttributeDescriptor::getArraySize(desc);
- const Uint32 arrayType = AttributeDescriptor::getArrayType(desc);
- const Uint32 nullable = AttributeDescriptor::getNullable(desc);
- const Uint32 DKey = AttributeDescriptor::getDKey(desc);
- const Uint32 disk= AttributeDescriptor::getDiskBased(desc);
-
-
- // AttributeType deprecated
- w.add(DictTabInfo::AttributeSize, attrSize);
- w.add(DictTabInfo::AttributeArraySize, arraySize);
- w.add(DictTabInfo::AttributeArrayType, arrayType);
- w.add(DictTabInfo::AttributeNullableFlag, nullable);
- w.add(DictTabInfo::AttributeDKey, DKey);
- w.add(DictTabInfo::AttributeExtType, attrType);
- w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision);
- w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale);
- w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength);
- w.add(DictTabInfo::AttributeAutoIncrement,
- (Uint32)attrPtr.p->autoIncrement);
-
- if(disk)
- w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_DISK);
- else
- w.add(DictTabInfo::AttributeStorageType, (Uint32)NDB_STORAGETYPE_MEMORY);
-
- ConstRope def(c_rope_pool, attrPtr.p->defaultValue);
- def.copy(defaultValue);
- w.add(DictTabInfo::AttributeDefaultValue, defaultValue);
-
- w.add(DictTabInfo::AttributeEnd, 1);
- }
-
- w.add(DictTabInfo::TableEnd, 1);
-}
-
-void
-Dbdict::packFilegroupIntoPages(SimpleProperties::Writer & w,
- FilegroupPtr fg_ptr,
- const Uint32 undo_free_hi,
- const Uint32 undo_free_lo){
-
- DictFilegroupInfo::Filegroup fg; fg.init();
- ConstRope r(c_rope_pool, fg_ptr.p->m_name);
- r.copy(fg.FilegroupName);
-
- fg.FilegroupId = fg_ptr.p->key;
- fg.FilegroupType = fg_ptr.p->m_type;
- fg.FilegroupVersion = fg_ptr.p->m_version;
-
- switch(fg.FilegroupType){
- case DictTabInfo::Tablespace:
- //fg.TS_DataGrow = group.m_grow_spec;
- fg.TS_ExtentSize = fg_ptr.p->m_tablespace.m_extent_size;
- fg.TS_LogfileGroupId = fg_ptr.p->m_tablespace.m_default_logfile_group_id;
- FilegroupPtr lfg_ptr;
- ndbrequire(c_filegroup_hash.find(lfg_ptr, fg.TS_LogfileGroupId));
- fg.TS_LogfileGroupVersion = lfg_ptr.p->m_version;
- break;
- case DictTabInfo::LogfileGroup:
- fg.LF_UndoBufferSize = fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
- fg.LF_UndoFreeWordsHi= undo_free_hi;
- fg.LF_UndoFreeWordsLo= undo_free_lo;
- //fg.LF_UndoGrow = ;
- break;
- default:
- ndbrequire(false);
- }
-
- SimpleProperties::UnpackStatus s;
- s = SimpleProperties::pack(w,
- &fg,
- DictFilegroupInfo::Mapping,
- DictFilegroupInfo::MappingSize, true);
-
- ndbrequire(s == SimpleProperties::Eof);
-}
-
-void
-Dbdict::packFileIntoPages(SimpleProperties::Writer & w,
- FilePtr f_ptr, const Uint32 free_extents){
-
- DictFilegroupInfo::File f; f.init();
- ConstRope r(c_rope_pool, f_ptr.p->m_path);
- r.copy(f.FileName);
-
- f.FileType = f_ptr.p->m_type;
- f.FilegroupId = f_ptr.p->m_filegroup_id;; //group.m_id;
- f.FileSizeHi = (f_ptr.p->m_file_size >> 32);
- f.FileSizeLo = (f_ptr.p->m_file_size & 0xFFFFFFFF);
- f.FileFreeExtents= free_extents;
- f.FileId = f_ptr.p->key;
- f.FileVersion = f_ptr.p->m_version;
-
- FilegroupPtr lfg_ptr;
- ndbrequire(c_filegroup_hash.find(lfg_ptr, f.FilegroupId));
- f.FilegroupVersion = lfg_ptr.p->m_version;
-
- SimpleProperties::UnpackStatus s;
- s = SimpleProperties::pack(w,
- &f,
- DictFilegroupInfo::FileMapping,
- DictFilegroupInfo::FileMappingSize, true);
-
- ndbrequire(s == SimpleProperties::Eof);
-}
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-// The routines to handle responses from file system.
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-
-/* ---------------------------------------------------------------- */
-// A file was successfully closed.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSCLOSECONF(Signal* signal)
-{
- FsConnectRecordPtr fsPtr;
- FsConf * const fsConf = (FsConf *)&signal->theData[0];
- jamEntry();
- c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::CLOSE_WRITE_SCHEMA:
- jam();
- closeWriteSchemaConf(signal, fsPtr);
- break;
- case FsConnectRecord::CLOSE_READ_SCHEMA:
- jam();
- closeReadSchemaConf(signal, fsPtr);
- break;
- case FsConnectRecord::CLOSE_READ_TAB_FILE:
- jam();
- closeReadTableConf(signal, fsPtr);
- break;
- case FsConnectRecord::CLOSE_WRITE_TAB_FILE:
- jam();
- closeWriteTableConf(signal, fsPtr);
- break;
- case FsConnectRecord::OPEN_READ_SCHEMA2:
- openSchemaFile(signal, 1, fsPtr.i, false, false);
- break;
- case FsConnectRecord::OPEN_READ_TAB_FILE2:
- openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
- break;
- default:
- jamLine((fsPtr.p->fsState & 0xFFF));
- ndbrequire(false);
- break;
- }//switch
-}//execFSCLOSECONF()
-
-
-/* ---------------------------------------------------------------- */
-// A file was successfully opened.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSOPENCONF(Signal* signal)
-{
- FsConnectRecordPtr fsPtr;
- jamEntry();
- FsConf * const fsConf = (FsConf *)&signal->theData[0];
- c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
-
- Uint32 filePointer = fsConf->filePointer;
- fsPtr.p->filePtr = filePointer;
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::OPEN_WRITE_SCHEMA:
- jam();
- fsPtr.p->fsState = FsConnectRecord::WRITE_SCHEMA;
- writeSchemaFile(signal, filePointer, fsPtr.i);
- break;
- case FsConnectRecord::OPEN_READ_SCHEMA1:
- jam();
- fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA1;
- readSchemaFile(signal, filePointer, fsPtr.i);
- break;
- case FsConnectRecord::OPEN_READ_SCHEMA2:
- jam();
- fsPtr.p->fsState = FsConnectRecord::READ_SCHEMA2;
- readSchemaFile(signal, filePointer, fsPtr.i);
- break;
- case FsConnectRecord::OPEN_READ_TAB_FILE1:
- jam();
- fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE1;
- readTableFile(signal, filePointer, fsPtr.i);
- break;
- case FsConnectRecord::OPEN_READ_TAB_FILE2:
- jam();
- fsPtr.p->fsState = FsConnectRecord::READ_TAB_FILE2;
- readTableFile(signal, filePointer, fsPtr.i);
- break;
- case FsConnectRecord::OPEN_WRITE_TAB_FILE:
- jam();
- fsPtr.p->fsState = FsConnectRecord::WRITE_TAB_FILE;
- writeTableFile(signal, filePointer, fsPtr.i);
- break;
- default:
- jamLine((fsPtr.p->fsState & 0xFFF));
- ndbrequire(false);
- break;
- }//switch
-}//execFSOPENCONF()
-
-/* ---------------------------------------------------------------- */
-// An open file was refused.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSOPENREF(Signal* signal)
-{
- jamEntry();
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::OPEN_READ_SCHEMA1:
- jam();
- openReadSchemaRef(signal, fsPtr);
- return;
- case FsConnectRecord::OPEN_READ_TAB_FILE1:
- jam();
- openReadTableRef(signal, fsPtr);
- return;
- default:
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
- fsRefError(signal,__LINE__,msg);
- }
-}//execFSOPENREF()
-
-/* ---------------------------------------------------------------- */
-// A file was successfully read.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSREADCONF(Signal* signal)
-{
- jamEntry();
- FsConf * const fsConf = (FsConf *)&signal->theData[0];
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::READ_SCHEMA1:
- case FsConnectRecord::READ_SCHEMA2:
- readSchemaConf(signal ,fsPtr);
- break;
- case FsConnectRecord::READ_TAB_FILE1:
- if(ERROR_INSERTED(6007)){
- jam();
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = fsConf->userPointer;
- fsRef->setErrorCode(fsRef->errorCode, NDBD_EXIT_AFS_UNKNOWN);
- fsRef->osErrorCode = ~0; // Indicate local error
- execFSREADREF(signal);
- return;
- }//Testing how DICT behave if read of file 1 fails (Bug#28770)
- case FsConnectRecord::READ_TAB_FILE2:
- jam();
- readTableConf(signal ,fsPtr);
- break;
- default:
- jamLine((fsPtr.p->fsState & 0xFFF));
- ndbrequire(false);
- break;
- }//switch
-}//execFSREADCONF()
-
-/* ---------------------------------------------------------------- */
-// A read file was refused.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSREADREF(Signal* signal)
-{
- jamEntry();
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer);
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::READ_SCHEMA1:
- jam();
- readSchemaRef(signal, fsPtr);
- return;
- case FsConnectRecord::READ_TAB_FILE1:
- jam();
- readTableRef(signal, fsPtr);
- return;
- default:
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState);
- fsRefError(signal,__LINE__,msg);
- }
-}//execFSREADREF()
-
-/* ---------------------------------------------------------------- */
-// A file was successfully written.
-/* ---------------------------------------------------------------- */
-void Dbdict::execFSWRITECONF(Signal* signal)
-{
- FsConf * const fsConf = (FsConf *)&signal->theData[0];
- FsConnectRecordPtr fsPtr;
- jamEntry();
- c_fsConnectRecordPool.getPtr(fsPtr, fsConf->userPointer);
- switch (fsPtr.p->fsState) {
- case FsConnectRecord::WRITE_TAB_FILE:
- writeTableConf(signal, fsPtr);
- break;
- case FsConnectRecord::WRITE_SCHEMA:
- jam();
- writeSchemaConf(signal, fsPtr);
- break;
- default:
- jamLine((fsPtr.p->fsState & 0xFFF));
- ndbrequire(false);
- break;
- }//switch
-}//execFSWRITECONF()
-
-
-/* ---------------------------------------------------------------- */
-// Routines to handle Read/Write of Table Files
-/* ---------------------------------------------------------------- */
-void
-Dbdict::writeTableFile(Signal* signal, Uint32 tableId,
- SegmentedSectionPtr tabInfoPtr, Callback* callback){
-
- ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
-
- Uint32 pages = WORDS2PAGES(tabInfoPtr.sz);
- c_writeTableRecord.no_of_words = tabInfoPtr.sz;
- c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
- c_writeTableRecord.m_callback = * callback;
-
- c_writeTableRecord.pageId = 0;
- ndbrequire(pages == 1);
-
- PageRecordPtr pageRecPtr;
- c_pageRecordArray.getPtr(pageRecPtr, c_writeTableRecord.pageId);
- copy(&pageRecPtr.p->word[ZPAGE_HEADER_SIZE], tabInfoPtr);
-
- memset(&pageRecPtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
- pageRecPtr.p->word[ZPOS_CHECKSUM] =
- computeChecksum(&pageRecPtr.p->word[0],
- pages * ZSIZE_OF_PAGES_IN_WORDS);
-
- startWriteTableFile(signal, tableId);
-}
-
-void Dbdict::startWriteTableFile(Signal* signal, Uint32 tableId)
-{
- FsConnectRecordPtr fsPtr;
- c_writeTableRecord.tableId = tableId;
- c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
- fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
- openTableFile(signal, 0, fsPtr.i, tableId, true);
- c_writeTableRecord.noOfTableFilesHandled = 0;
-}//Dbdict::startWriteTableFile()
-
-void Dbdict::openTableFile(Signal* signal,
- Uint32 fileNo,
- Uint32 fsConPtr,
- Uint32 tableId,
- bool writeFlag)
-{
- FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
-
- fsOpenReq->userReference = reference();
- fsOpenReq->userPointer = fsConPtr;
- if (writeFlag) {
- jam();
- fsOpenReq->fileFlags =
- FsOpenReq::OM_WRITEONLY |
- FsOpenReq::OM_TRUNCATE |
- FsOpenReq::OM_CREATE |
- FsOpenReq::OM_SYNC;
- } else {
- jam();
- fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
- }//if
- fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
- FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
- FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_TABLELIST);
- FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
- FsOpenReq::v1_setTable(fsOpenReq->fileNumber, tableId);
- FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
- FsOpenReq::v1_setS(fsOpenReq->fileNumber, 0);
- FsOpenReq::v1_setP(fsOpenReq->fileNumber, 255);
-/* ---------------------------------------------------------------- */
-// File name : D1/DBDICT/T0/S1.TableList
-// D1 means Disk 1 (set by fileNo + 1)
-// T0 means table id = 0
-// S1 means tableVersion 1
-// TableList indicates that this is a file for a table description.
-/* ---------------------------------------------------------------- */
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}//openTableFile()
-
-void Dbdict::writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
-{
- FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
-
- fsRWReq->filePointer = filePtr;
- fsRWReq->userReference = reference();
- fsRWReq->userPointer = fsConPtr;
- fsRWReq->operationFlag = 0; // Initialise before bit changes
- FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
- FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
- FsReadWriteReq::fsFormatArrayOfPages);
- fsRWReq->varIndex = ZBAT_TABLE_FILE;
- fsRWReq->numberOfPages = WORDS2PAGES(c_writeTableRecord.no_of_words);
- fsRWReq->data.arrayOfPages.varIndex = c_writeTableRecord.pageId;
- fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
-}//writeTableFile()
-
-void Dbdict::writeTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_TAB_FILE;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}//Dbdict::writeTableConf()
-
-void Dbdict::closeWriteTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- c_writeTableRecord.noOfTableFilesHandled++;
- if (c_writeTableRecord.noOfTableFilesHandled < 2) {
- jam();
- fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_TAB_FILE;
- openTableFile(signal, 1, fsPtr.i, c_writeTableRecord.tableId, true);
- return;
- }
- ndbrequire(c_writeTableRecord.noOfTableFilesHandled == 2);
- c_fsConnectRecordPool.release(fsPtr);
- WriteTableRecord::TableWriteState state = c_writeTableRecord.tableWriteState;
- c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
- switch (state) {
- case WriteTableRecord::IDLE:
- case WriteTableRecord::WRITE_ADD_TABLE_MASTER :
- case WriteTableRecord::WRITE_ADD_TABLE_SLAVE :
- case WriteTableRecord::WRITE_RESTART_FROM_MASTER :
- case WriteTableRecord::WRITE_RESTART_FROM_OWN :
- ndbrequire(false);
- break;
- case WriteTableRecord::TWR_CALLBACK:
- jam();
- execute(signal, c_writeTableRecord.m_callback, 0);
- return;
- }
- ndbrequire(false);
-}//Dbdict::closeWriteTableConf()
-
-void Dbdict::startReadTableFile(Signal* signal, Uint32 tableId)
-{
- //globalSignalLoggers.log(number(), "startReadTableFile");
- ndbrequire(!c_readTableRecord.inUse);
-
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
- c_readTableRecord.inUse = true;
- c_readTableRecord.tableId = tableId;
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE1;
- openTableFile(signal, 0, fsPtr.i, tableId, false);
-}//Dbdict::startReadTableFile()
-
-void Dbdict::openReadTableRef(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
- openTableFile(signal, 1, fsPtr.i, c_readTableRecord.tableId, false);
- return;
-}//Dbdict::openReadTableConf()
-
-void Dbdict::readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
-{
- FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
-
- fsRWReq->filePointer = filePtr;
- fsRWReq->userReference = reference();
- fsRWReq->userPointer = fsConPtr;
- fsRWReq->operationFlag = 0; // Initialise before bit changes
- FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
- FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
- FsReadWriteReq::fsFormatArrayOfPages);
- fsRWReq->varIndex = ZBAT_TABLE_FILE;
- fsRWReq->numberOfPages = WORDS2PAGES(c_readTableRecord.no_of_words);
- fsRWReq->data.arrayOfPages.varIndex = c_readTableRecord.pageId;
- fsRWReq->data.arrayOfPages.fileOffset = 0; // Write to file page 0
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
-}//readTableFile()
-
-void Dbdict::readTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- /* ---------------------------------------------------------------- */
- // Verify the data read from disk
- /* ---------------------------------------------------------------- */
- bool crashInd;
- if (fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1) {
- jam();
- crashInd = false;
- } else {
- jam();
- crashInd = true;
- }//if
-
- PageRecordPtr tmpPagePtr;
- c_pageRecordArray.getPtr(tmpPagePtr, c_readTableRecord.pageId);
- Uint32 sz =
- WORDS2PAGES(c_readTableRecord.no_of_words)*ZSIZE_OF_PAGES_IN_WORDS;
- Uint32 chk = computeChecksum((const Uint32*)tmpPagePtr.p, sz);
-
- ndbrequire((chk == 0) || !crashInd);
- if(chk != 0){
- jam();
- ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_TAB_FILE1);
- readTableRef(signal, fsPtr);
- return;
- }//if
-
- fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_TAB_FILE;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}//Dbdict::readTableConf()
-
-void Dbdict::readTableRef(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- /**
- * First close corrupt file
- */
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_TAB_FILE2;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}//Dbdict::readTableRef()
-
-void Dbdict::closeReadTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- c_fsConnectRecordPool.release(fsPtr);
- c_readTableRecord.inUse = false;
-
- execute(signal, c_readTableRecord.m_callback, 0);
- return;
-}//Dbdict::closeReadTableConf()
-
-/* ---------------------------------------------------------------- */
-// Routines to handle Read/Write of Schema Files
-/* ---------------------------------------------------------------- */
-void
-Dbdict::updateSchemaState(Signal* signal, Uint32 tableId,
- SchemaFile::TableEntry* te, Callback* callback,
- bool savetodisk){
- jam();
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
-
- SchemaFile::TableState newState =
- (SchemaFile::TableState)te->m_tableState;
- SchemaFile::TableState oldState =
- (SchemaFile::TableState)tableEntry->m_tableState;
-
- Uint32 newVersion = te->m_tableVersion;
- Uint32 oldVersion = tableEntry->m_tableVersion;
-
- bool ok = false;
- switch(newState){
- case SchemaFile::ADD_STARTED:
- jam();
- ok = true;
- ndbrequire(create_obj_inc_schema_version(oldVersion) == newVersion);
- ndbrequire(oldState == SchemaFile::INIT ||
- oldState == SchemaFile::DROP_TABLE_COMMITTED);
- break;
- case SchemaFile::TABLE_ADD_COMMITTED:
- jam();
- ok = true;
- ndbrequire(newVersion == oldVersion);
- ndbrequire(oldState == SchemaFile::ADD_STARTED ||
- oldState == SchemaFile::DROP_TABLE_STARTED);
- break;
- case SchemaFile::ALTER_TABLE_COMMITTED:
- jam();
- ok = true;
- ndbrequire(alter_obj_inc_schema_version(oldVersion) == newVersion);
- ndbrequire(oldState == SchemaFile::TABLE_ADD_COMMITTED ||
- oldState == SchemaFile::ALTER_TABLE_COMMITTED);
- break;
- case SchemaFile::DROP_TABLE_STARTED:
- jam();
- case SchemaFile::DROP_TABLE_COMMITTED:
- jam();
- ok = true;
- break;
- case SchemaFile::TEMPORARY_TABLE_COMMITTED:
- jam();
- ndbrequire(oldState == SchemaFile::ADD_STARTED ||
- oldState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
- ok = true;
- break;
- case SchemaFile::INIT:
- jam();
- ok = true;
- ndbrequire((oldState == SchemaFile::ADD_STARTED));
- }//if
- ndbrequire(ok);
-
- * tableEntry = * te;
- computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
-
- if (savetodisk)
- {
- ndbrequire(c_writeSchemaRecord.inUse == false);
- c_writeSchemaRecord.inUse = true;
-
- c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
- c_writeSchemaRecord.newFile = false;
- c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
- c_writeSchemaRecord.noOfPages = 1;
- c_writeSchemaRecord.m_callback = * callback;
-
- startWriteSchemaFile(signal);
- }
- else
- {
- execute(signal, *callback, 0);
- }
-}
-
-void Dbdict::startWriteSchemaFile(Signal* signal)
-{
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
- fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
- openSchemaFile(signal, 0, fsPtr.i, true, c_writeSchemaRecord.newFile);
- c_writeSchemaRecord.noOfSchemaFilesHandled = 0;
-}//Dbdict::startWriteSchemaFile()
-
-void Dbdict::openSchemaFile(Signal* signal,
- Uint32 fileNo,
- Uint32 fsConPtr,
- bool writeFlag,
- bool newFile)
-{
- FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
- fsOpenReq->userReference = reference();
- fsOpenReq->userPointer = fsConPtr;
- if (writeFlag) {
- jam();
- fsOpenReq->fileFlags =
- FsOpenReq::OM_WRITEONLY |
- FsOpenReq::OM_SYNC;
- if (newFile)
- fsOpenReq->fileFlags |=
- FsOpenReq::OM_TRUNCATE |
- FsOpenReq::OM_CREATE;
- } else {
- jam();
- fsOpenReq->fileFlags = FsOpenReq::OM_READONLY;
- }//if
- fsOpenReq->fileNumber[3] = 0; // Initialise before byte changes
- FsOpenReq::setVersion(fsOpenReq->fileNumber, 1);
- FsOpenReq::setSuffix(fsOpenReq->fileNumber, FsOpenReq::S_SCHEMALOG);
- FsOpenReq::v1_setDisk(fsOpenReq->fileNumber, (fileNo + 1));
- FsOpenReq::v1_setTable(fsOpenReq->fileNumber, (Uint32)-1);
- FsOpenReq::v1_setFragment(fsOpenReq->fileNumber, (Uint32)-1);
- FsOpenReq::v1_setS(fsOpenReq->fileNumber, (Uint32)-1);
- FsOpenReq::v1_setP(fsOpenReq->fileNumber, 0);
-/* ---------------------------------------------------------------- */
-// File name : D1/DBDICT/P0.SchemaLog
-// D1 means Disk 1 (set by fileNo + 1). Writes to both D1 and D2
-// SchemaLog indicates that this is a file giving a list of current tables.
-/* ---------------------------------------------------------------- */
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}//openSchemaFile()
-
-void Dbdict::writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
-{
- FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
-
- // check write record
- WriteSchemaRecord & wr = c_writeSchemaRecord;
- ndbrequire(wr.pageId == (wr.pageId != 0) * NDB_SF_MAX_PAGES);
- ndbrequire(wr.noOfPages != 0);
- ndbrequire(wr.firstPage + wr.noOfPages <= NDB_SF_MAX_PAGES);
-
- fsRWReq->filePointer = filePtr;
- fsRWReq->userReference = reference();
- fsRWReq->userPointer = fsConPtr;
- fsRWReq->operationFlag = 0; // Initialise before bit changes
- FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 1);
- FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
- FsReadWriteReq::fsFormatArrayOfPages);
- fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
- fsRWReq->numberOfPages = wr.noOfPages;
- // Write from memory page
- fsRWReq->data.arrayOfPages.varIndex = wr.pageId + wr.firstPage;
- fsRWReq->data.arrayOfPages.fileOffset = wr.firstPage;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
-}//writeSchemaFile()
-
-void Dbdict::writeSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- fsPtr.p->fsState = FsConnectRecord::CLOSE_WRITE_SCHEMA;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}//Dbdict::writeSchemaConf()
-
-void Dbdict::closeFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
-{
- FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
- fsCloseReq->filePointer = filePtr;
- fsCloseReq->userReference = reference();
- fsCloseReq->userPointer = fsConPtr;
- FsCloseReq::setRemoveFileFlag(fsCloseReq->fileFlag, false);
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
- return;
-}//closeFile()
-
-void Dbdict::closeWriteSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- c_writeSchemaRecord.noOfSchemaFilesHandled++;
- if (c_writeSchemaRecord.noOfSchemaFilesHandled < 2) {
- jam();
- fsPtr.p->fsState = FsConnectRecord::OPEN_WRITE_SCHEMA;
- openSchemaFile(signal, 1, fsPtr.i, true, c_writeSchemaRecord.newFile);
- return;
- }
- ndbrequire(c_writeSchemaRecord.noOfSchemaFilesHandled == 2);
-
- c_fsConnectRecordPool.release(fsPtr);
-
- c_writeSchemaRecord.inUse = false;
- execute(signal, c_writeSchemaRecord.m_callback, 0);
- return;
-}//Dbdict::closeWriteSchemaConf()
-
-void Dbdict::startReadSchemaFile(Signal* signal)
-{
- //globalSignalLoggers.log(number(), "startReadSchemaFile");
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.getPtr(fsPtr, getFsConnRecord());
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA1;
- openSchemaFile(signal, 0, fsPtr.i, false, false);
-}//Dbdict::startReadSchemaFile()
-
-void Dbdict::openReadSchemaRef(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
- openSchemaFile(signal, 1, fsPtr.i, false, false);
-}//Dbdict::openReadSchemaRef()
-
-void Dbdict::readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsConPtr)
-{
- FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
-
- // check read record
- ReadSchemaRecord & rr = c_readSchemaRecord;
- ndbrequire(rr.pageId == (rr.pageId != 0) * NDB_SF_MAX_PAGES);
- ndbrequire(rr.noOfPages != 0);
- ndbrequire(rr.firstPage + rr.noOfPages <= NDB_SF_MAX_PAGES);
-
- fsRWReq->filePointer = filePtr;
- fsRWReq->userReference = reference();
- fsRWReq->userPointer = fsConPtr;
- fsRWReq->operationFlag = 0; // Initialise before bit changes
- FsReadWriteReq::setSyncFlag(fsRWReq->operationFlag, 0);
- FsReadWriteReq::setFormatFlag(fsRWReq->operationFlag,
- FsReadWriteReq::fsFormatArrayOfPages);
- fsRWReq->varIndex = ZBAT_SCHEMA_FILE;
- fsRWReq->numberOfPages = rr.noOfPages;
- fsRWReq->data.arrayOfPages.varIndex = rr.pageId + rr.firstPage;
- fsRWReq->data.arrayOfPages.fileOffset = rr.firstPage;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
-}//readSchemaFile()
-
-void Dbdict::readSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
-/* ---------------------------------------------------------------- */
-// Verify the data read from disk
-/* ---------------------------------------------------------------- */
- bool crashInd;
- if (fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1) {
- jam();
- crashInd = false;
- } else {
- jam();
- crashInd = true;
- }//if
-
- ReadSchemaRecord & rr = c_readSchemaRecord;
- XSchemaFile * xsf = &c_schemaFile[rr.pageId != 0];
-
- if (rr.schemaReadState == ReadSchemaRecord::INITIAL_READ_HEAD) {
- jam();
- ndbrequire(rr.firstPage == 0);
- SchemaFile * sf = &xsf->schemaPage[0];
- Uint32 noOfPages;
- if (sf->NdbVersion < NDB_SF_VERSION_5_0_6) {
- jam();
- const Uint32 pageSize_old = 32 * 1024;
- noOfPages = pageSize_old / NDB_SF_PAGE_SIZE - 1;
- } else {
- noOfPages = sf->FileSize / NDB_SF_PAGE_SIZE - 1;
- }
- rr.schemaReadState = ReadSchemaRecord::INITIAL_READ;
- if (noOfPages != 0) {
- rr.firstPage = 1;
- rr.noOfPages = noOfPages;
- readSchemaFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
- }
- }
-
- SchemaFile * sf0 = &xsf->schemaPage[0];
- xsf->noOfPages = sf0->FileSize / NDB_SF_PAGE_SIZE;
-
- if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6 &&
- ! convertSchemaFileTo_5_0_6(xsf)) {
- jam();
- ndbrequire(! crashInd);
- ndbrequire(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1);
- readSchemaRef(signal, fsPtr);
- return;
- }
-
- for (Uint32 n = 0; n < xsf->noOfPages; n++) {
- SchemaFile * sf = &xsf->schemaPage[n];
- bool ok = false;
- const char *reason;
- if (memcmp(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic)) != 0)
- { jam(); reason = "magic code"; }
- else if (sf->FileSize == 0)
- { jam(); reason = "file size == 0"; }
- else if (sf->FileSize % NDB_SF_PAGE_SIZE != 0)
- { jam(); reason = "invalid size multiple"; }
- else if (sf->FileSize != sf0->FileSize)
- { jam(); reason = "invalid size"; }
- else if (sf->PageNumber != n)
- { jam(); reason = "invalid page number"; }
- else if (computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS) != 0)
- { jam(); reason = "invalid checksum"; }
- else
- ok = true;
-
- if (!ok)
- {
- char reason_msg[128];
- snprintf(reason_msg, sizeof(reason_msg),
- "schema file corrupt, page %u (%s, "
- "sz=%u sz0=%u pn=%u)",
- n, reason, sf->FileSize, sf0->FileSize, sf->PageNumber);
- if (crashInd)
- progError(__LINE__, NDBD_EXIT_SR_SCHEMAFILE, reason_msg);
- ndbrequireErr(fsPtr.p->fsState == FsConnectRecord::READ_SCHEMA1,
- NDBD_EXIT_SR_SCHEMAFILE);
- jam();
- infoEvent("primary %s, trying backup", reason_msg);
- readSchemaRef(signal, fsPtr);
- return;
- }
- }
-
- fsPtr.p->fsState = FsConnectRecord::CLOSE_READ_SCHEMA;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}//Dbdict::readSchemaConf()
-
-void Dbdict::readSchemaRef(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- /**
- * First close corrupt file
- */
- fsPtr.p->fsState = FsConnectRecord::OPEN_READ_SCHEMA2;
- closeFile(signal, fsPtr.p->filePtr, fsPtr.i);
- return;
-}
-
-void Dbdict::closeReadSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr)
-{
- c_fsConnectRecordPool.release(fsPtr);
- ReadSchemaRecord::SchemaReadState state = c_readSchemaRecord.schemaReadState;
- c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
-
- switch(state) {
- case ReadSchemaRecord::INITIAL_READ :
- jam();
- {
- // write back both copies
-
- ndbrequire(c_writeSchemaRecord.inUse == false);
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0 ];
- Uint32 noOfPages =
- (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1) /
- NDB_SF_PAGE_ENTRIES;
- resizeSchemaFile(xsf, noOfPages);
-
- c_writeSchemaRecord.inUse = true;
- c_writeSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
- c_writeSchemaRecord.newFile = true;
- c_writeSchemaRecord.firstPage = 0;
- c_writeSchemaRecord.noOfPages = xsf->noOfPages;
-
- c_writeSchemaRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::initSchemaFile_conf);
-
- startWriteSchemaFile(signal);
- }
- break;
-
- default :
- ndbrequire(false);
- break;
-
- }//switch
-}//Dbdict::closeReadSchemaConf()
-
-bool
-Dbdict::convertSchemaFileTo_5_0_6(XSchemaFile * xsf)
-{
- const Uint32 pageSize_old = 32 * 1024;
- Uint32 page_old[pageSize_old >> 2];
- SchemaFile * sf_old = (SchemaFile *)page_old;
-
- if (xsf->noOfPages * NDB_SF_PAGE_SIZE != pageSize_old)
- return false;
- SchemaFile * sf0 = &xsf->schemaPage[0];
- memcpy(sf_old, sf0, pageSize_old);
-
- // init max number new pages needed
- xsf->noOfPages = (sf_old->NoOfTableEntries + NDB_SF_PAGE_ENTRIES - 1) /
- NDB_SF_PAGE_ENTRIES;
- initSchemaFile(xsf, 0, xsf->noOfPages, true);
-
- Uint32 noOfPages = 1;
- Uint32 n, i, j;
- for (n = 0; n < xsf->noOfPages; n++) {
- jam();
- for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
- j = n * NDB_SF_PAGE_ENTRIES + i;
- if (j >= sf_old->NoOfTableEntries)
- continue;
- const SchemaFile::TableEntry_old & te_old = sf_old->TableEntries_old[j];
- if (te_old.m_tableState == SchemaFile::INIT ||
- te_old.m_tableState == SchemaFile::DROP_TABLE_COMMITTED ||
- te_old.m_noOfPages == 0)
- continue;
- SchemaFile * sf = &xsf->schemaPage[n];
- SchemaFile::TableEntry & te = sf->TableEntries[i];
- te.m_tableState = te_old.m_tableState;
- te.m_tableVersion = te_old.m_tableVersion;
- te.m_tableType = te_old.m_tableType;
- te.m_info_words = te_old.m_noOfPages * ZSIZE_OF_PAGES_IN_WORDS -
- ZPAGE_HEADER_SIZE;
- te.m_gcp = te_old.m_gcp;
- if (noOfPages < n)
- noOfPages = n;
- }
- }
- xsf->noOfPages = noOfPages;
- initSchemaFile(xsf, 0, xsf->noOfPages, false);
-
- return true;
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: INITIALISATION MODULE ------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains initialisation of data at start/restart. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-Dbdict::Dbdict(Block_context& ctx):
- SimulatedBlock(DBDICT, ctx),
- c_attributeRecordHash(c_attributeRecordPool),
- c_file_hash(c_file_pool),
- c_filegroup_hash(c_filegroup_pool),
- c_obj_hash(c_obj_pool),
- c_opCreateTable(c_opRecordPool),
- c_opDropTable(c_opRecordPool),
- c_opCreateIndex(c_opRecordPool),
- c_opDropIndex(c_opRecordPool),
- c_opAlterIndex(c_opRecordPool),
- c_opBuildIndex(c_opRecordPool),
- c_opCreateEvent(c_opRecordPool),
- c_opSubEvent(c_opRecordPool),
- c_opDropEvent(c_opRecordPool),
- c_opSignalUtil(c_opRecordPool),
- c_opCreateTrigger(c_opRecordPool),
- c_opDropTrigger(c_opRecordPool),
- c_opAlterTrigger(c_opRecordPool),
- c_schemaOp(c_opRecordPool),
- c_Trans(c_opRecordPool),
- c_opCreateObj(c_schemaOp),
- c_opDropObj(c_schemaOp),
- c_opRecordSequence(0),
- c_dictLockQueue(c_dictLockPool),
- c_dictLockPoll(false)
-{
- BLOCK_CONSTRUCTOR(Dbdict);
-
- // Transit signals
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD);
- addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ);
- addRecSignal(GSN_GET_TABLEID_REQ, &Dbdict::execGET_TABLEDID_REQ);
- addRecSignal(GSN_GET_TABINFO_CONF, &Dbdict::execGET_TABINFO_CONF);
- addRecSignal(GSN_CONTINUEB, &Dbdict::execCONTINUEB);
-
- addRecSignal(GSN_CREATE_TABLE_REQ, &Dbdict::execCREATE_TABLE_REQ);
- addRecSignal(GSN_CREATE_TAB_REQ, &Dbdict::execCREATE_TAB_REQ);
- addRecSignal(GSN_CREATE_TAB_REF, &Dbdict::execCREATE_TAB_REF);
- addRecSignal(GSN_CREATE_TAB_CONF, &Dbdict::execCREATE_TAB_CONF);
- addRecSignal(GSN_CREATE_FRAGMENTATION_REF, &Dbdict::execCREATE_FRAGMENTATION_REF);
- addRecSignal(GSN_CREATE_FRAGMENTATION_CONF, &Dbdict::execCREATE_FRAGMENTATION_CONF);
- addRecSignal(GSN_DIADDTABCONF, &Dbdict::execDIADDTABCONF);
- addRecSignal(GSN_DIADDTABREF, &Dbdict::execDIADDTABREF);
- addRecSignal(GSN_ADD_FRAGREQ, &Dbdict::execADD_FRAGREQ);
- addRecSignal(GSN_TAB_COMMITCONF, &Dbdict::execTAB_COMMITCONF);
- addRecSignal(GSN_TAB_COMMITREF, &Dbdict::execTAB_COMMITREF);
- addRecSignal(GSN_ALTER_TABLE_REQ, &Dbdict::execALTER_TABLE_REQ);
- addRecSignal(GSN_ALTER_TAB_REQ, &Dbdict::execALTER_TAB_REQ);
- addRecSignal(GSN_ALTER_TAB_REF, &Dbdict::execALTER_TAB_REF);
- addRecSignal(GSN_ALTER_TAB_CONF, &Dbdict::execALTER_TAB_CONF);
-
- // Index signals
- addRecSignal(GSN_CREATE_INDX_REQ, &Dbdict::execCREATE_INDX_REQ);
- addRecSignal(GSN_CREATE_INDX_CONF, &Dbdict::execCREATE_INDX_CONF);
- addRecSignal(GSN_CREATE_INDX_REF, &Dbdict::execCREATE_INDX_REF);
-
- addRecSignal(GSN_ALTER_INDX_REQ, &Dbdict::execALTER_INDX_REQ);
- addRecSignal(GSN_ALTER_INDX_CONF, &Dbdict::execALTER_INDX_CONF);
- addRecSignal(GSN_ALTER_INDX_REF, &Dbdict::execALTER_INDX_REF);
-
- addRecSignal(GSN_CREATE_TABLE_CONF, &Dbdict::execCREATE_TABLE_CONF);
- addRecSignal(GSN_CREATE_TABLE_REF, &Dbdict::execCREATE_TABLE_REF);
-
- addRecSignal(GSN_DROP_INDX_REQ, &Dbdict::execDROP_INDX_REQ);
- addRecSignal(GSN_DROP_INDX_CONF, &Dbdict::execDROP_INDX_CONF);
- addRecSignal(GSN_DROP_INDX_REF, &Dbdict::execDROP_INDX_REF);
-
- addRecSignal(GSN_DROP_TABLE_CONF, &Dbdict::execDROP_TABLE_CONF);
- addRecSignal(GSN_DROP_TABLE_REF, &Dbdict::execDROP_TABLE_REF);
-
- addRecSignal(GSN_BUILDINDXREQ, &Dbdict::execBUILDINDXREQ);
- addRecSignal(GSN_BUILDINDXCONF, &Dbdict::execBUILDINDXCONF);
- addRecSignal(GSN_BUILDINDXREF, &Dbdict::execBUILDINDXREF);
-
- // Util signals
- addRecSignal(GSN_UTIL_PREPARE_CONF, &Dbdict::execUTIL_PREPARE_CONF);
- addRecSignal(GSN_UTIL_PREPARE_REF, &Dbdict::execUTIL_PREPARE_REF);
-
- addRecSignal(GSN_UTIL_EXECUTE_CONF, &Dbdict::execUTIL_EXECUTE_CONF);
- addRecSignal(GSN_UTIL_EXECUTE_REF, &Dbdict::execUTIL_EXECUTE_REF);
-
- addRecSignal(GSN_UTIL_RELEASE_CONF, &Dbdict::execUTIL_RELEASE_CONF);
- addRecSignal(GSN_UTIL_RELEASE_REF, &Dbdict::execUTIL_RELEASE_REF);
-
- // Event signals
- addRecSignal(GSN_CREATE_EVNT_REQ, &Dbdict::execCREATE_EVNT_REQ);
- addRecSignal(GSN_CREATE_EVNT_CONF, &Dbdict::execCREATE_EVNT_CONF);
- addRecSignal(GSN_CREATE_EVNT_REF, &Dbdict::execCREATE_EVNT_REF);
-
- addRecSignal(GSN_CREATE_SUBID_CONF, &Dbdict::execCREATE_SUBID_CONF);
- addRecSignal(GSN_CREATE_SUBID_REF, &Dbdict::execCREATE_SUBID_REF);
-
- addRecSignal(GSN_SUB_CREATE_CONF, &Dbdict::execSUB_CREATE_CONF);
- addRecSignal(GSN_SUB_CREATE_REF, &Dbdict::execSUB_CREATE_REF);
-
- addRecSignal(GSN_SUB_START_REQ, &Dbdict::execSUB_START_REQ);
- addRecSignal(GSN_SUB_START_CONF, &Dbdict::execSUB_START_CONF);
- addRecSignal(GSN_SUB_START_REF, &Dbdict::execSUB_START_REF);
-
- addRecSignal(GSN_SUB_STOP_REQ, &Dbdict::execSUB_STOP_REQ);
- addRecSignal(GSN_SUB_STOP_CONF, &Dbdict::execSUB_STOP_CONF);
- addRecSignal(GSN_SUB_STOP_REF, &Dbdict::execSUB_STOP_REF);
-
- addRecSignal(GSN_DROP_EVNT_REQ, &Dbdict::execDROP_EVNT_REQ);
-
- addRecSignal(GSN_SUB_REMOVE_REQ, &Dbdict::execSUB_REMOVE_REQ);
- addRecSignal(GSN_SUB_REMOVE_CONF, &Dbdict::execSUB_REMOVE_CONF);
- addRecSignal(GSN_SUB_REMOVE_REF, &Dbdict::execSUB_REMOVE_REF);
-
- // Trigger signals
- addRecSignal(GSN_CREATE_TRIG_REQ, &Dbdict::execCREATE_TRIG_REQ);
- addRecSignal(GSN_CREATE_TRIG_CONF, &Dbdict::execCREATE_TRIG_CONF);
- addRecSignal(GSN_CREATE_TRIG_REF, &Dbdict::execCREATE_TRIG_REF);
- addRecSignal(GSN_ALTER_TRIG_REQ, &Dbdict::execALTER_TRIG_REQ);
- addRecSignal(GSN_ALTER_TRIG_CONF, &Dbdict::execALTER_TRIG_CONF);
- addRecSignal(GSN_ALTER_TRIG_REF, &Dbdict::execALTER_TRIG_REF);
- addRecSignal(GSN_DROP_TRIG_REQ, &Dbdict::execDROP_TRIG_REQ);
- addRecSignal(GSN_DROP_TRIG_CONF, &Dbdict::execDROP_TRIG_CONF);
- addRecSignal(GSN_DROP_TRIG_REF, &Dbdict::execDROP_TRIG_REF);
-
- // Received signals
- addRecSignal(GSN_HOT_SPAREREP, &Dbdict::execHOT_SPAREREP);
- addRecSignal(GSN_GET_SCHEMA_INFOREQ, &Dbdict::execGET_SCHEMA_INFOREQ);
- addRecSignal(GSN_SCHEMA_INFO, &Dbdict::execSCHEMA_INFO);
- addRecSignal(GSN_SCHEMA_INFOCONF, &Dbdict::execSCHEMA_INFOCONF);
- addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ);
- addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF);
- addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF);
- addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true);
- addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF);
- addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF);
- addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF);
- addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true);
- addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF);
- addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF);
- addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF);
- addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF);
- addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR);
- 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);
- addRecSignal(GSN_INCL_NODEREQ, &Dbdict::execINCL_NODEREQ);
- addRecSignal(GSN_API_FAILREQ, &Dbdict::execAPI_FAILREQ);
-
- addRecSignal(GSN_WAIT_GCP_REF, &Dbdict::execWAIT_GCP_REF);
- addRecSignal(GSN_WAIT_GCP_CONF, &Dbdict::execWAIT_GCP_CONF);
-
- addRecSignal(GSN_LIST_TABLES_REQ, &Dbdict::execLIST_TABLES_REQ);
-
- addRecSignal(GSN_DROP_TABLE_REQ, &Dbdict::execDROP_TABLE_REQ);
-
- addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dbdict::execPREP_DROP_TAB_REQ);
- addRecSignal(GSN_PREP_DROP_TAB_REF, &Dbdict::execPREP_DROP_TAB_REF);
- addRecSignal(GSN_PREP_DROP_TAB_CONF, &Dbdict::execPREP_DROP_TAB_CONF);
-
- addRecSignal(GSN_DROP_TAB_REQ, &Dbdict::execDROP_TAB_REQ);
- addRecSignal(GSN_DROP_TAB_REF, &Dbdict::execDROP_TAB_REF);
- addRecSignal(GSN_DROP_TAB_CONF, &Dbdict::execDROP_TAB_CONF);
-
- addRecSignal(GSN_CREATE_FILE_REQ, &Dbdict::execCREATE_FILE_REQ);
- addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Dbdict::execCREATE_FILEGROUP_REQ);
-
- addRecSignal(GSN_DROP_FILE_REQ, &Dbdict::execDROP_FILE_REQ);
- addRecSignal(GSN_DROP_FILE_REF, &Dbdict::execDROP_FILE_REF);
- addRecSignal(GSN_DROP_FILE_CONF, &Dbdict::execDROP_FILE_CONF);
-
- addRecSignal(GSN_DROP_FILEGROUP_REQ, &Dbdict::execDROP_FILEGROUP_REQ);
- addRecSignal(GSN_DROP_FILEGROUP_REF, &Dbdict::execDROP_FILEGROUP_REF);
- addRecSignal(GSN_DROP_FILEGROUP_CONF, &Dbdict::execDROP_FILEGROUP_CONF);
-
- addRecSignal(GSN_CREATE_OBJ_REQ, &Dbdict::execCREATE_OBJ_REQ);
- addRecSignal(GSN_CREATE_OBJ_REF, &Dbdict::execCREATE_OBJ_REF);
- addRecSignal(GSN_CREATE_OBJ_CONF, &Dbdict::execCREATE_OBJ_CONF);
- addRecSignal(GSN_DROP_OBJ_REQ, &Dbdict::execDROP_OBJ_REQ);
- addRecSignal(GSN_DROP_OBJ_REF, &Dbdict::execDROP_OBJ_REF);
- addRecSignal(GSN_DROP_OBJ_CONF, &Dbdict::execDROP_OBJ_CONF);
-
- addRecSignal(GSN_CREATE_FILE_REF, &Dbdict::execCREATE_FILE_REF);
- addRecSignal(GSN_CREATE_FILE_CONF, &Dbdict::execCREATE_FILE_CONF);
- addRecSignal(GSN_CREATE_FILEGROUP_REF, &Dbdict::execCREATE_FILEGROUP_REF);
- addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Dbdict::execCREATE_FILEGROUP_CONF);
-
- addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Dbdict::execBACKUP_FRAGMENT_REQ);
-
- addRecSignal(GSN_DICT_COMMIT_REQ, &Dbdict::execDICT_COMMIT_REQ);
- addRecSignal(GSN_DICT_COMMIT_REF, &Dbdict::execDICT_COMMIT_REF);
- addRecSignal(GSN_DICT_COMMIT_CONF, &Dbdict::execDICT_COMMIT_CONF);
-
- addRecSignal(GSN_DICT_ABORT_REQ, &Dbdict::execDICT_ABORT_REQ);
- addRecSignal(GSN_DICT_ABORT_REF, &Dbdict::execDICT_ABORT_REF);
- addRecSignal(GSN_DICT_ABORT_CONF, &Dbdict::execDICT_ABORT_CONF);
-
- addRecSignal(GSN_DICT_LOCK_REQ, &Dbdict::execDICT_LOCK_REQ);
- addRecSignal(GSN_DICT_UNLOCK_ORD, &Dbdict::execDICT_UNLOCK_ORD);
-}//Dbdict::Dbdict()
-
-Dbdict::~Dbdict()
-{
-}//Dbdict::~Dbdict()
-
-BLOCK_FUNCTIONS(Dbdict)
-
-void Dbdict::initCommonData()
-{
-/* ---------------------------------------------------------------- */
-// Initialise all common variables.
-/* ---------------------------------------------------------------- */
- initRetrieveRecord(0, 0, 0);
- initSchemaRecord();
- initRestartRecord();
- initSendSchemaRecord();
- initReadTableRecord();
- initWriteTableRecord();
- initReadSchemaRecord();
- initWriteSchemaRecord();
-
- c_masterNodeId = ZNIL;
- c_numberNode = 0;
- c_noNodesFailed = 0;
- c_failureNr = 0;
- c_blockState = BS_IDLE;
- c_packTable.m_state = PackTable::PTS_IDLE;
- c_startPhase = 0;
- c_restartType = 255; //Ensure not used restartType
- c_tabinfoReceived = 0;
- c_initialStart = false;
- c_systemRestart = false;
- c_initialNodeRestart = false;
- c_nodeRestart = false;
-}//Dbdict::initCommonData()
-
-void Dbdict::initRecords()
-{
- initNodeRecords();
- initPageRecords();
- initTableRecords();
- initTriggerRecords();
-}//Dbdict::initRecords()
-
-void Dbdict::initSendSchemaRecord()
-{
- c_sendSchemaRecord.noOfWords = (Uint32)-1;
- c_sendSchemaRecord.pageId = RNIL;
- c_sendSchemaRecord.noOfWordsCurrentlySent = 0;
- c_sendSchemaRecord.noOfSignalsSentSinceDelay = 0;
- c_sendSchemaRecord.inUse = false;
- //c_sendSchemaRecord.sendSchemaState = SendSchemaRecord::IDLE;
-}//initSendSchemaRecord()
-
-void Dbdict::initReadTableRecord()
-{
- c_readTableRecord.no_of_words= 0;
- c_readTableRecord.pageId = RNIL;
- c_readTableRecord.tableId = ZNIL;
- c_readTableRecord.inUse = false;
-}//initReadTableRecord()
-
-void Dbdict::initWriteTableRecord()
-{
- c_writeTableRecord.no_of_words= 0;
- c_writeTableRecord.pageId = RNIL;
- c_writeTableRecord.noOfTableFilesHandled = 3;
- c_writeTableRecord.tableId = ZNIL;
- c_writeTableRecord.tableWriteState = WriteTableRecord::IDLE;
-}//initWriteTableRecord()
-
-void Dbdict::initReadSchemaRecord()
-{
- c_readSchemaRecord.pageId = RNIL;
- c_readSchemaRecord.schemaReadState = ReadSchemaRecord::IDLE;
-}//initReadSchemaRecord()
-
-void Dbdict::initWriteSchemaRecord()
-{
- c_writeSchemaRecord.inUse = false;
- c_writeSchemaRecord.pageId = RNIL;
- c_writeSchemaRecord.noOfSchemaFilesHandled = 3;
-}//initWriteSchemaRecord()
-
-void Dbdict::initRetrieveRecord(Signal* signal, Uint32 i, Uint32 returnCode)
-{
- c_retrieveRecord.busyState = false;
- c_retrieveRecord.blockRef = 0;
- c_retrieveRecord.m_senderData = RNIL;
- c_retrieveRecord.tableId = RNIL;
- c_retrieveRecord.currentSent = 0;
- c_retrieveRecord.retrievedNoOfPages = 0;
- c_retrieveRecord.retrievedNoOfWords = 0;
- c_retrieveRecord.m_useLongSig = false;
-}//initRetrieveRecord()
-
-void Dbdict::initSchemaRecord()
-{
- c_schemaRecord.schemaPage = RNIL;
- c_schemaRecord.oldSchemaPage = RNIL;
-}//Dbdict::initSchemaRecord()
-
-void Dbdict::initRestartRecord()
-{
- c_restartRecord.gciToRestart = 0;
- c_restartRecord.activeTable = ZNIL;
- c_restartRecord.m_pass = 0;
-}//Dbdict::initRestartRecord()
-
-void Dbdict::initNodeRecords()
-{
- jam();
- for (unsigned i = 1; i < MAX_NODES; i++) {
- NodeRecordPtr nodePtr;
- c_nodes.getPtr(nodePtr, i);
- nodePtr.p->hotSpare = false;
- nodePtr.p->nodeState = NodeRecord::API_NODE;
- }//for
-}//Dbdict::initNodeRecords()
-
-void Dbdict::initPageRecords()
-{
- c_retrieveRecord.retrievePage = ZMAX_PAGES_OF_TABLE_DEFINITION;
- ndbrequire(ZNUMBER_OF_PAGES >= (ZMAX_PAGES_OF_TABLE_DEFINITION + 1));
- c_schemaRecord.schemaPage = 0;
- c_schemaRecord.oldSchemaPage = NDB_SF_MAX_PAGES;
-}//Dbdict::initPageRecords()
-
-void Dbdict::initTableRecords()
-{
- TableRecordPtr tablePtr;
- while (1) {
- jam();
- refresh_watch_dog();
- c_tableRecordPool.seize(tablePtr);
- if (tablePtr.i == RNIL) {
- jam();
- break;
- }//if
- initialiseTableRecord(tablePtr);
- }//while
-}//Dbdict::initTableRecords()
-
-void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr)
-{
- new (tablePtr.p) TableRecord();
- tablePtr.p->activePage = RNIL;
- tablePtr.p->filePtr[0] = RNIL;
- tablePtr.p->filePtr[1] = RNIL;
- tablePtr.p->firstPage = RNIL;
- tablePtr.p->tableId = tablePtr.i;
- tablePtr.p->tableVersion = (Uint32)-1;
- tablePtr.p->tabState = TableRecord::NOT_DEFINED;
- tablePtr.p->tabReturnState = TableRecord::TRS_IDLE;
- tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable;
- tablePtr.p->gciTableCreated = 0;
- tablePtr.p->noOfAttributes = ZNIL;
- tablePtr.p->noOfNullAttr = 0;
- tablePtr.p->fragmentCount = 0;
- /*
- tablePtr.p->lh3PageIndexBits = 0;
- tablePtr.p->lh3DistrBits = 0;
- tablePtr.p->lh3PageBits = 6;
- */
- tablePtr.p->kValue = 6;
- tablePtr.p->localKeyLen = 1;
- tablePtr.p->maxLoadFactor = 80;
- tablePtr.p->minLoadFactor = 70;
- tablePtr.p->noOfPrimkey = 1;
- tablePtr.p->tupKeyLength = 1;
- tablePtr.p->maxRowsLow = 0;
- tablePtr.p->maxRowsHigh = 0;
- tablePtr.p->defaultNoPartFlag = true;
- tablePtr.p->linearHashFlag = true;
- tablePtr.p->m_bits = 0;
- tablePtr.p->minRowsLow = 0;
- tablePtr.p->minRowsHigh = 0;
- tablePtr.p->singleUserMode = 0;
- tablePtr.p->tableType = DictTabInfo::UserTable;
- tablePtr.p->primaryTableId = RNIL;
- // volatile elements
- tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
- tablePtr.p->insertTriggerId = RNIL;
- tablePtr.p->updateTriggerId = RNIL;
- tablePtr.p->deleteTriggerId = RNIL;
- tablePtr.p->customTriggerId = RNIL;
- tablePtr.p->buildTriggerId = RNIL;
- tablePtr.p->indexLocal = 0;
-}//Dbdict::initialiseTableRecord()
-
-void Dbdict::initTriggerRecords()
-{
- TriggerRecordPtr triggerPtr;
- while (1) {
- jam();
- refresh_watch_dog();
- c_triggerRecordPool.seize(triggerPtr);
- if (triggerPtr.i == RNIL) {
- jam();
- break;
- }//if
- initialiseTriggerRecord(triggerPtr);
- }//while
-}
-
-void Dbdict::initialiseTriggerRecord(TriggerRecordPtr triggerPtr)
-{
- new (triggerPtr.p) TriggerRecord();
- triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
- triggerPtr.p->triggerLocal = 0;
- triggerPtr.p->triggerId = RNIL;
- triggerPtr.p->tableId = RNIL;
- triggerPtr.p->triggerType = (TriggerType::Value)~0;
- triggerPtr.p->triggerActionTime = (TriggerActionTime::Value)~0;
- triggerPtr.p->triggerEvent = (TriggerEvent::Value)~0;
- triggerPtr.p->monitorReplicas = false;
- triggerPtr.p->monitorAllAttributes = false;
- triggerPtr.p->attributeMask.clear();
- triggerPtr.p->indexId = RNIL;
-}
-
-Uint32 Dbdict::getFsConnRecord()
-{
- FsConnectRecordPtr fsPtr;
- c_fsConnectRecordPool.seize(fsPtr);
- ndbrequire(fsPtr.i != RNIL);
- fsPtr.p->filePtr = (Uint32)-1;
- fsPtr.p->ownerPtr = RNIL;
- fsPtr.p->fsState = FsConnectRecord::IDLE;
- return fsPtr.i;
-}//Dbdict::getFsConnRecord()
-
-/*
- * Search schemafile for free entry. Its index is used as 'logical id'
- * of new disk-stored object.
- */
-Uint32 Dbdict::getFreeObjId(Uint32 minId)
-{
- const XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- Uint32 noOfPages = xsf->noOfPages;
- Uint32 n, i;
- for (n = 0; n < noOfPages; n++) {
- jam();
- const SchemaFile * sf = &xsf->schemaPage[n];
- for (i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
- const SchemaFile::TableEntry& te = sf->TableEntries[i];
- if (te.m_tableState == (Uint32)SchemaFile::INIT ||
- te.m_tableState == (Uint32)SchemaFile::DROP_TABLE_COMMITTED) {
- // minId is obsolete anyway
- if (minId <= n * NDB_SF_PAGE_ENTRIES + i)
- return n * NDB_SF_PAGE_ENTRIES + i;
- }
- }
- }
- return RNIL;
-}
-
-Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId)
-{
- Uint32 minId = (primaryTableId == RNIL ? 0 : primaryTableId + 1);
- Uint32 i = getFreeObjId(minId);
- if (i == RNIL) {
- jam();
- return RNIL;
- }
- if (i >= c_tableRecordPool.getSize()) {
- jam();
- return RNIL;
- }
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, i);
- ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
- initialiseTableRecord(tablePtr);
- tablePtr.p->tabState = TableRecord::DEFINING;
- return i;
-}
-
-Uint32 Dbdict::getFreeTriggerRecord()
-{
- const Uint32 size = c_triggerRecordPool.getSize();
- TriggerRecordPtr triggerPtr;
- for (triggerPtr.i = 0; triggerPtr.i < size; triggerPtr.i++) {
- jam();
- c_triggerRecordPool.getPtr(triggerPtr);
- if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
- jam();
- initialiseTriggerRecord(triggerPtr);
- return triggerPtr.i;
- }
- }
- return RNIL;
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: START/RESTART HANDLING ------------------------ */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code that is common for all */
-/* start/restart types. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// This is sent as the first signal during start/restart.
-/* ---------------------------------------------------------------- */
-void Dbdict::execSTTOR(Signal* signal)
-{
- jamEntry();
- c_startPhase = signal->theData[1];
- switch (c_startPhase) {
- case 1:
- break;
- case 3:
- c_restartType = signal->theData[7]; /* valid if 3 */
- ndbrequire(c_restartType == NodeState::ST_INITIAL_START ||
- c_restartType == NodeState::ST_SYSTEM_RESTART ||
- c_restartType == NodeState::ST_INITIAL_NODE_RESTART ||
- c_restartType == NodeState::ST_NODE_RESTART);
- break;
- }
- sendSTTORRY(signal);
-}//execSTTOR()
-
-void Dbdict::sendSTTORRY(Signal* signal)
-{
- signal->theData[0] = 0; /* garbage SIGNAL KEY */
- signal->theData[1] = 0; /* garbage SIGNAL VERSION NUMBER */
- signal->theData[2] = 0; /* garbage */
- signal->theData[3] = 1; /* first wanted start phase */
- signal->theData[4] = 3; /* get type of start */
- signal->theData[5] = ZNOMOREPHASES;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
-}
-
-/* ---------------------------------------------------------------- */
-// We receive information about sizes of records.
-/* ---------------------------------------------------------------- */
-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();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint32 attributesize, tablerecSize;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS,
- &c_maxNoOfTriggers));
- 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);
- c_fsConnectRecordPool.setSize(ZFS_CONNECT_SIZE);
- c_nodes.setSize(MAX_NODES);
- c_pageRecordArray.setSize(ZNUMBER_OF_PAGES);
- c_schemaPageRecordArray.setSize(2 * NDB_SF_MAX_PAGES);
- c_tableRecordPool.setSize(tablerecSize);
- g_key_descriptor_pool.setSize(tablerecSize);
- c_triggerRecordPool.setSize(c_maxNoOfTriggers);
-
- c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers);
- c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
-
- Pool_context pc;
- pc.m_block = this;
-
- c_file_hash.setSize(16);
- c_filegroup_hash.setSize(16);
-
- c_file_pool.init(RT_DBDICT_FILE, pc);
- c_filegroup_pool.init(RT_DBDICT_FILEGROUP, pc);
-
- c_opRecordPool.setSize(256); // XXX need config params
- c_opCreateTable.setSize(8);
- c_opDropTable.setSize(8);
- c_opCreateIndex.setSize(8);
- c_opCreateEvent.setSize(2);
- c_opSubEvent.setSize(2);
- c_opDropEvent.setSize(2);
- c_opSignalUtil.setSize(8);
- c_opDropIndex.setSize(8);
- c_opAlterIndex.setSize(8);
- c_opBuildIndex.setSize(8);
- c_opCreateTrigger.setSize(8);
- c_opDropTrigger.setSize(8);
- c_opAlterTrigger.setSize(8);
-
- c_dictLockPool.setSize(32);
-
- // Initialize schema file copies
- c_schemaFile[0].schemaPage =
- (SchemaFile*)c_schemaPageRecordArray.getPtr(0 * NDB_SF_MAX_PAGES);
- c_schemaFile[0].noOfPages = 0;
- c_schemaFile[1].schemaPage =
- (SchemaFile*)c_schemaPageRecordArray.getPtr(1 * NDB_SF_MAX_PAGES);
- c_schemaFile[1].noOfPages = 0;
-
- c_schemaOp.setSize(8);
- //c_opDropObj.setSize(8);
- c_Trans.setSize(8);
-
- Uint32 rps = 0;
- rps += tablerecSize * (MAX_TAB_NAME_SIZE + MAX_FRM_DATA_SIZE);
- rps += attributesize * (MAX_ATTR_NAME_SIZE + MAX_ATTR_DEFAULT_VALUE_SIZE);
- rps += c_maxNoOfTriggers * MAX_TAB_NAME_SIZE;
- rps += (10 + 10) * MAX_TAB_NAME_SIZE;
-
- Uint32 sm = 5;
- ndb_mgm_get_int_parameter(p, CFG_DB_STRING_MEMORY, &sm);
- if (sm == 0)
- sm = 5;
-
- Uint32 sb = 0;
- if (sm < 100)
- {
- sb = (rps * sm) / 100;
- }
- else
- {
- sb = sm;
- }
-
- c_rope_pool.setSize(sb/28 + 100);
-
- // Initialize BAT for interface to file system
- NewVARIABLE* bat = allocateBat(2);
- bat[0].WA = &c_schemaPageRecordArray.getPtr(0)->word[0];
- bat[0].nrr = 2 * NDB_SF_MAX_PAGES;
- bat[0].ClusterSize = NDB_SF_PAGE_SIZE;
- bat[0].bits.q = NDB_SF_PAGE_SIZE_IN_WORDS_LOG2;
- bat[0].bits.v = 5; // 32 bits per element
- bat[1].WA = &c_pageRecordArray.getPtr(0)->word[0];
- bat[1].nrr = ZNUMBER_OF_PAGES;
- bat[1].ClusterSize = ZSIZE_OF_PAGES_IN_WORDS * 4;
- 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();
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-
- {
- Ptr<DictObject> ptr;
- SLList<DictObject> objs(c_obj_pool);
- while(objs.seize(ptr))
- new (ptr.p) DictObject();
- objs.release();
- }
-}//execSIZEALT_REP()
-
-/* ---------------------------------------------------------------- */
-// Start phase signals sent by CNTR. We reply with NDB_STTORRY when
-// we completed this phase.
-/* ---------------------------------------------------------------- */
-void Dbdict::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
- c_startPhase = signal->theData[2];
- const Uint32 restartType = signal->theData[3];
- if (restartType == NodeState::ST_INITIAL_START) {
- jam();
- c_initialStart = true;
- } else if (restartType == NodeState::ST_SYSTEM_RESTART) {
- jam();
- c_systemRestart = true;
- } else if (restartType == NodeState::ST_INITIAL_NODE_RESTART) {
- jam();
- c_initialNodeRestart = true;
- } else if (restartType == NodeState::ST_NODE_RESTART) {
- jam();
- c_nodeRestart = true;
- } else {
- ndbrequire(false);
- }//if
- switch (c_startPhase) {
- case 1:
- jam();
- initSchemaFile(signal);
- break;
- case 3:
- jam();
- signal->theData[0] = reference();
- sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
- break;
- case 6:
- jam();
- c_initialStart = false;
- c_systemRestart = false;
- c_initialNodeRestart = false;
- c_nodeRestart = false;
- sendNDB_STTORRY(signal);
- break;
- case 7:
- // uses c_restartType
- if(restartType == NodeState::ST_SYSTEM_RESTART &&
- c_masterNodeId == getOwnNodeId()){
- rebuildIndexes(signal, 0);
- return;
- }
- sendNDB_STTORRY(signal);
- break;
- default:
- jam();
- sendNDB_STTORRY(signal);
- break;
- }//switch
-}//execNDB_STTOR()
-
-void Dbdict::sendNDB_STTORRY(Signal* signal)
-{
- signal->theData[0] = reference();
- sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
- return;
-}//sendNDB_STTORRY()
-
-/* ---------------------------------------------------------------- */
-// We receive the information about which nodes that are up and down.
-/* ---------------------------------------------------------------- */
-void Dbdict::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
-
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
- c_numberNode = readNodes->noOfNodes;
- c_masterNodeId = readNodes->masterNodeId;
-
- c_noNodesFailed = 0;
- c_aliveNodes.clear();
- for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- NodeRecordPtr nodePtr;
- c_nodes.getPtr(nodePtr, i);
-
- if (NodeBitmask::get(readNodes->allNodes, i)) {
- jam();
- nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
- if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
- jam();
- /**-------------------------------------------------------------------
- *
- * THIS NODE IS DEFINED IN THE CLUSTER BUT IS NOT ALIVE CURRENTLY.
- * WE ADD THE NODE TO THE SET OF FAILED NODES AND ALSO SET THE
- * BLOCKSTATE TO BUSY TO AVOID ADDING TABLES WHILE NOT ALL NODES ARE
- * ALIVE.
- *------------------------------------------------------------------*/
- nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
- c_noNodesFailed++;
- } else {
- c_aliveNodes.set(i);
- }
- }//if
- }//for
- sendNDB_STTORRY(signal);
-}//execREAD_NODESCONF()
-
-/* ---------------------------------------------------------------- */
-// HOT_SPAREREP informs DBDICT about which nodes that have become
-// hot spare nodes.
-/* ---------------------------------------------------------------- */
-void Dbdict::execHOT_SPAREREP(Signal* signal)
-{
- Uint32 hotSpareNodes = 0;
- jamEntry();
- HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
- for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
- if (NodeBitmask::get(hotSpare->theHotSpareNodes, i)) {
- NodeRecordPtr nodePtr;
- c_nodes.getPtr(nodePtr, i);
- nodePtr.p->hotSpare = true;
- hotSpareNodes++;
- }//if
- }//for
- ndbrequire(hotSpareNodes == hotSpare->noHotSpareNodes);
- c_noHotSpareNodes = hotSpareNodes;
- return;
-}//execHOT_SPAREREP()
-
-void Dbdict::initSchemaFile(Signal* signal)
-{
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- xsf->noOfPages = (c_tableRecordPool.getSize() + NDB_SF_PAGE_ENTRIES - 1)
- / NDB_SF_PAGE_ENTRIES;
- initSchemaFile(xsf, 0, xsf->noOfPages, true);
- // init alt copy too for INR
- XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
- oldxsf->noOfPages = xsf->noOfPages;
- memcpy(&oldxsf->schemaPage[0], &xsf->schemaPage[0], xsf->schemaPage[0].FileSize);
-
- if (c_initialStart || c_initialNodeRestart) {
- jam();
- ndbrequire(c_writeSchemaRecord.inUse == false);
- c_writeSchemaRecord.inUse = true;
- c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
- c_writeSchemaRecord.newFile = true;
- c_writeSchemaRecord.firstPage = 0;
- c_writeSchemaRecord.noOfPages = xsf->noOfPages;
-
- c_writeSchemaRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::initSchemaFile_conf);
-
- startWriteSchemaFile(signal);
- } else if (c_systemRestart || c_nodeRestart) {
- jam();
- ndbrequire(c_readSchemaRecord.schemaReadState == ReadSchemaRecord::IDLE);
- c_readSchemaRecord.pageId = c_schemaRecord.oldSchemaPage;
- c_readSchemaRecord.firstPage = 0;
- c_readSchemaRecord.noOfPages = 1;
- c_readSchemaRecord.schemaReadState = ReadSchemaRecord::INITIAL_READ_HEAD;
- startReadSchemaFile(signal);
- } else {
- ndbrequire(false);
- }//if
-}//Dbdict::initSchemaFile()
-
-void
-Dbdict::initSchemaFile_conf(Signal* signal, Uint32 callbackData, Uint32 rv){
- jam();
- sendNDB_STTORRY(signal);
-}
-
-void
-Dbdict::activateIndexes(Signal* signal, Uint32 i)
-{
- AlterIndxReq* req = (AlterIndxReq*)signal->getDataPtrSend();
- TableRecordPtr tablePtr;
- for (; i < c_tableRecordPool.getSize(); i++) {
- tablePtr.i = i;
- c_tableRecordPool.getPtr(tablePtr);
- if (tablePtr.p->tabState != TableRecord::DEFINED)
- continue;
- if (! tablePtr.p->isIndex())
- continue;
- jam();
- req->setUserRef(reference());
- req->setConnectionPtr(i);
- req->setTableId(tablePtr.p->primaryTableId);
- req->setIndexId(tablePtr.i);
- req->setIndexVersion(tablePtr.p->tableVersion);
- req->setOnline(true);
- if (c_restartType == NodeState::ST_SYSTEM_RESTART) {
- if (c_masterNodeId != getOwnNodeId())
- continue;
- // from file index state is not defined currently
- req->setRequestType(AlterIndxReq::RT_SYSTEMRESTART);
- req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
- }
- else if (
- c_restartType == NodeState::ST_NODE_RESTART ||
- c_restartType == NodeState::ST_INITIAL_NODE_RESTART) {
- // from master index must be online
- if (tablePtr.p->indexState != TableRecord::IS_ONLINE)
- continue;
- req->setRequestType(AlterIndxReq::RT_NODERESTART);
- // activate locally, rebuild not needed
- req->addRequestFlag((Uint32)RequestFlag::RF_LOCAL);
- req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
- } else {
- ndbrequire(false);
- }
- sendSignal(reference(), GSN_ALTER_INDX_REQ,
- signal, AlterIndxReq::SignalLength, JBB);
- return;
- }
- signal->theData[0] = reference();
- sendSignal(c_restartRecord.returnBlockRef, GSN_DICTSTARTCONF,
- signal, 1, JBB);
-}
-
-void
-Dbdict::rebuildIndexes(Signal* signal, Uint32 i){
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
-
- TableRecordPtr indexPtr;
- for (; i < c_tableRecordPool.getSize(); i++) {
- indexPtr.i = i;
- c_tableRecordPool.getPtr(indexPtr);
- if (indexPtr.p->tabState != TableRecord::DEFINED)
- continue;
- if (! indexPtr.p->isIndex())
- continue;
-
- jam();
-
- req->setUserRef(reference());
- req->setConnectionPtr(i);
- req->setRequestType(BuildIndxReq::RT_SYSTEMRESTART);
- req->setBuildId(0); // not used
- req->setBuildKey(0); // not used
- req->setIndexType(indexPtr.p->tableType);
- req->setIndexId(indexPtr.i);
- req->setTableId(indexPtr.p->primaryTableId);
- req->setParallelism(16);
-
- // from file index state is not defined currently
- if (indexPtr.p->m_bits & TableRecord::TR_Logged) {
- // rebuild not needed
- req->addRequestFlag((Uint32)RequestFlag::RF_NOBUILD);
- }
-
- // send
- sendSignal(reference(), GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
- return;
- }
- sendNDB_STTORRY(signal);
-}
-
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: SYSTEM RESTART MODULE ------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains code specific for system restart */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// DIH asks DICT to read in table data from disk during system
-// restart. DIH also asks DICT to send information about which
-// tables that should be started as part of this system restart.
-// DICT will also activate the tables in TC as part of this process.
-/* ---------------------------------------------------------------- */
-void Dbdict::execDICTSTARTREQ(Signal* signal)
-{
- jamEntry();
- c_restartRecord.gciToRestart = signal->theData[0];
- c_restartRecord.returnBlockRef = signal->theData[1];
- if (c_nodeRestart || c_initialNodeRestart) {
- jam();
-
- CRASH_INSERTION(6000);
-
- BlockReference dictRef = calcDictBlockRef(c_masterNodeId);
- signal->theData[0] = getOwnNodeId();
- sendSignal(dictRef, GSN_GET_SCHEMA_INFOREQ, signal, 1, JBB);
- return;
- }
- ndbrequire(c_systemRestart);
- ndbrequire(c_masterNodeId == getOwnNodeId());
-
- c_schemaRecord.m_callback.m_callbackData = 0;
- c_schemaRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::masterRestart_checkSchemaStatusComplete);
-
- c_restartRecord.m_pass = 0;
- c_restartRecord.activeTable = 0;
- c_schemaRecord.schemaPage = c_schemaRecord.oldSchemaPage; // ugly
- checkSchemaStatus(signal);
-}//execDICTSTARTREQ()
-
-void
-Dbdict::masterRestart_checkSchemaStatusComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
-
- c_schemaRecord.schemaPage = 0; // ugly
- XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
- ndbrequire(oldxsf->noOfPages != 0);
-
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)&oldxsf->schemaPage[0];
- ptr[0].sz = oldxsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
-
- c_sendSchemaRecord.m_SCHEMAINFO_Counter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
-
- rg.m_nodes.clear(getOwnNodeId());
- Callback c = { 0, 0 };
- sendFragmentedSignal(rg,
- GSN_SCHEMA_INFO,
- signal,
- 1, //SchemaInfo::SignalLength,
- JBB,
- ptr,
- 1,
- c);
-
- XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- newxsf->noOfPages = oldxsf->noOfPages;
- memcpy(&newxsf->schemaPage[0], &oldxsf->schemaPage[0],
- oldxsf->noOfPages * NDB_SF_PAGE_SIZE);
-
- signal->theData[0] = getOwnNodeId();
- sendSignal(reference(), GSN_SCHEMA_INFOCONF, signal, 1, JBB);
-}
-
-void
-Dbdict::execGET_SCHEMA_INFOREQ(Signal* signal){
-
- const Uint32 ref = signal->getSendersBlockRef();
- //const Uint32 senderData = signal->theData[0];
-
- ndbrequire(c_sendSchemaRecord.inUse == false);
- c_sendSchemaRecord.inUse = true;
-
- LinearSectionPtr ptr[3];
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- ndbrequire(xsf->noOfPages != 0);
-
- ptr[0].p = (Uint32*)&xsf->schemaPage[0];
- ptr[0].sz = xsf->noOfPages * NDB_SF_PAGE_SIZE_IN_WORDS;
-
- Callback c = { safe_cast(&Dbdict::sendSchemaComplete), 0 };
- sendFragmentedSignal(ref,
- GSN_SCHEMA_INFO,
- signal,
- 1, //GetSchemaInfoConf::SignalLength,
- JBB,
- ptr,
- 1,
- c);
-}//Dbdict::execGET_SCHEMA_INFOREQ()
-
-void
-Dbdict::sendSchemaComplete(Signal * signal,
- Uint32 callbackData,
- Uint32 returnCode){
- ndbrequire(c_sendSchemaRecord.inUse == true);
- c_sendSchemaRecord.inUse = false;
-
-}
-
-
-/* ---------------------------------------------------------------- */
-// We receive the schema info from master as part of all restarts
-// except the initial start where no tables exists.
-/* ---------------------------------------------------------------- */
-void Dbdict::execSCHEMA_INFO(Signal* signal)
-{
- jamEntry();
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- if(getNodeState().getNodeRestartInProgress()){
- CRASH_INSERTION(6001);
- }
-
- SegmentedSectionPtr schemaDataPtr;
- signal->getSection(schemaDataPtr, 0);
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- ndbrequire(schemaDataPtr.sz % NDB_SF_PAGE_SIZE_IN_WORDS == 0);
- xsf->noOfPages = schemaDataPtr.sz / NDB_SF_PAGE_SIZE_IN_WORDS;
- copy((Uint32*)&xsf->schemaPage[0], schemaDataPtr);
- releaseSections(signal);
-
- SchemaFile * sf0 = &xsf->schemaPage[0];
- if (sf0->NdbVersion < NDB_SF_VERSION_5_0_6) {
- bool ok = convertSchemaFileTo_5_0_6(xsf);
- ndbrequire(ok);
- }
-
- validateChecksum(xsf);
-
- XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
- resizeSchemaFile(xsf, oldxsf->noOfPages);
-
- ndbrequire(signal->getSendersBlockRef() != reference());
-
- /* ---------------------------------------------------------------- */
- // Synchronise our view on data with other nodes in the cluster.
- // This is an important part of restart handling where we will handle
- // cases where the table have been added but only partially, where
- // tables have been deleted but not completed the deletion yet and
- // other scenarios needing synchronisation.
- /* ---------------------------------------------------------------- */
- c_schemaRecord.m_callback.m_callbackData = 0;
- c_schemaRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restart_checkSchemaStatusComplete);
-
- c_restartRecord.m_pass= 0;
- c_restartRecord.activeTable = 0;
- checkSchemaStatus(signal);
-}//execSCHEMA_INFO()
-
-void
-Dbdict::restart_checkSchemaStatusComplete(Signal * signal,
- Uint32 callbackData,
- Uint32 returnCode){
-
- ndbrequire(c_writeSchemaRecord.inUse == false);
- c_writeSchemaRecord.inUse = true;
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
- c_writeSchemaRecord.newFile = true;
- c_writeSchemaRecord.firstPage = 0;
- c_writeSchemaRecord.noOfPages = xsf->noOfPages;
- c_writeSchemaRecord.m_callback.m_callbackData = 0;
- c_writeSchemaRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restart_writeSchemaConf);
-
- for(Uint32 i = 0; i<xsf->noOfPages; i++)
- computeChecksum(xsf, i);
-
- startWriteSchemaFile(signal);
-}
-
-void
-Dbdict::restart_writeSchemaConf(Signal * signal,
- Uint32 callbackData,
- Uint32 returnCode){
-
- if(c_systemRestart){
- jam();
- signal->theData[0] = getOwnNodeId();
- sendSignal(calcDictBlockRef(c_masterNodeId), GSN_SCHEMA_INFOCONF,
- signal, 1, JBB);
- return;
- }
-
- ndbrequire(c_nodeRestart || c_initialNodeRestart);
- c_blockState = BS_IDLE;
- activateIndexes(signal, 0);
- return;
-}
-
-void Dbdict::execSCHEMA_INFOCONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
-
-/* ---------------------------------------------------------------- */
-// This signal is received in the master as part of system restart
-// from all nodes (including the master) after they have synchronised
-// their data with the master node's schema information.
-/* ---------------------------------------------------------------- */
- const Uint32 nodeId = signal->theData[0];
- c_sendSchemaRecord.m_SCHEMAINFO_Counter.clearWaitingFor(nodeId);
-
- if (!c_sendSchemaRecord.m_SCHEMAINFO_Counter.done()){
- jam();
- return;
- }//if
- activateIndexes(signal, 0);
-}//execSCHEMA_INFOCONF()
-
-static bool
-checkSchemaStatus(Uint32 tableType, Uint32 pass)
-{
- switch(tableType){
- case DictTabInfo::UndefTableType:
- return true;
- case DictTabInfo::HashIndexTrigger:
- case DictTabInfo::SubscriptionTrigger:
- case DictTabInfo::ReadOnlyConstraint:
- case DictTabInfo::IndexTrigger:
- return false;
- case DictTabInfo::LogfileGroup:
- return pass == 0 || pass == 9 || pass == 10;
- case DictTabInfo::Tablespace:
- return pass == 1 || pass == 8 || pass == 11;
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- return pass == 2 || pass == 7 || pass == 12;
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- return /* pass == 3 || pass == 6 || */ pass == 13;
- case DictTabInfo::UniqueHashIndex:
- case DictTabInfo::HashIndex:
- case DictTabInfo::UniqueOrderedIndex:
- case DictTabInfo::OrderedIndex:
- return /* pass == 4 || pass == 5 || */ pass == 14;
- }
-
- return false;
-}
-
-static const Uint32 CREATE_OLD_PASS = 4;
-static const Uint32 DROP_OLD_PASS = 9;
-static const Uint32 CREATE_NEW_PASS = 14;
-static const Uint32 LAST_PASS = 14;
-
-NdbOut&
-operator<<(NdbOut& out, const SchemaFile::TableEntry entry)
-{
- out << "[";
- out << " state: " << entry.m_tableState;
- out << " version: " << hex << entry.m_tableVersion << dec;
- out << " type: " << entry.m_tableType;
- out << " words: " << entry.m_info_words;
- out << " gcp: " << entry.m_gcp;
- out << " ]";
- return out;
-}
-
-/**
- * Pass 0 Create old LogfileGroup
- * Pass 1 Create old Tablespace
- * Pass 2 Create old Datafile/Undofile
- * Pass 3 Create old Table // NOT DONE DUE TO DIH
- * Pass 4 Create old Index // NOT DONE DUE TO DIH
-
- * Pass 5 Drop old Index // NOT DONE DUE TO DIH
- * Pass 6 Drop old Table // NOT DONE DUE TO DIH
- * Pass 7 Drop old Datafile/Undofile
- * Pass 8 Drop old Tablespace
- * Pass 9 Drop old Logfilegroup
-
- * Pass 10 Create new LogfileGroup
- * Pass 11 Create new Tablespace
- * Pass 12 Create new Datafile/Undofile
- * Pass 13 Create new Table
- * Pass 14 Create new Index
- */
-
-void Dbdict::checkSchemaStatus(Signal* signal)
-{
- XSchemaFile * newxsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- XSchemaFile * oldxsf = &c_schemaFile[c_schemaRecord.oldSchemaPage != 0];
- ndbrequire(newxsf->noOfPages == oldxsf->noOfPages);
- const Uint32 noOfEntries = newxsf->noOfPages * NDB_SF_PAGE_ENTRIES;
-
- for (; c_restartRecord.activeTable < noOfEntries;
- c_restartRecord.activeTable++) {
- jam();
-
- Uint32 tableId = c_restartRecord.activeTable;
- SchemaFile::TableEntry *newEntry = getTableEntry(newxsf, tableId);
- SchemaFile::TableEntry *oldEntry = getTableEntry(oldxsf, tableId);
- SchemaFile::TableState newSchemaState =
- (SchemaFile::TableState)newEntry->m_tableState;
- SchemaFile::TableState oldSchemaState =
- (SchemaFile::TableState)oldEntry->m_tableState;
-
- if (c_restartRecord.activeTable >= c_tableRecordPool.getSize()) {
- jam();
- ndbrequire(newSchemaState == SchemaFile::INIT);
- ndbrequire(oldSchemaState == SchemaFile::INIT);
- continue;
- }//if
-
-//#define PRINT_SCHEMA_RESTART
-#ifdef PRINT_SCHEMA_RESTART
- char buf[100];
- snprintf(buf, sizeof(buf), "checkSchemaStatus: pass: %d table: %d",
- c_restartRecord.m_pass, tableId);
-#endif
-
- if (c_restartRecord.m_pass <= CREATE_OLD_PASS)
- {
- if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
- continue;
-
- switch(oldSchemaState){
- case SchemaFile::INIT: jam();
- case SchemaFile::DROP_TABLE_COMMITTED: jam();
- case SchemaFile::ADD_STARTED: jam();
- case SchemaFile::DROP_TABLE_STARTED: jam();
- case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
- continue;
- case SchemaFile::TABLE_ADD_COMMITTED: jam();
- case SchemaFile::ALTER_TABLE_COMMITTED: jam();
- jam();
-#ifdef PRINT_SCHEMA_RESTART
- ndbout_c("%s -> restartCreateTab", buf);
- ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
- restartCreateTab(signal, tableId, oldEntry, oldEntry, true);
- return;
- }
- }
-
- if (c_restartRecord.m_pass <= DROP_OLD_PASS)
- {
- if (!::checkSchemaStatus(oldEntry->m_tableType, c_restartRecord.m_pass))
- continue;
-
- switch(oldSchemaState){
- case SchemaFile::INIT: jam();
- case SchemaFile::DROP_TABLE_COMMITTED: jam();
- case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
- continue;
- case SchemaFile::ADD_STARTED: jam();
- case SchemaFile::DROP_TABLE_STARTED: jam();
-#ifdef PRINT_SCHEMA_RESTART
- ndbout_c("%s -> restartDropTab", buf);
- ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
- restartDropTab(signal, tableId, oldEntry, newEntry);
- return;
- case SchemaFile::TABLE_ADD_COMMITTED: jam();
- case SchemaFile::ALTER_TABLE_COMMITTED: jam();
- if (! (* oldEntry == * newEntry))
- {
-#ifdef PRINT_SCHEMA_RESTART
- ndbout_c("%s -> restartDropTab", buf);
- ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
- restartDropTab(signal, tableId, oldEntry, newEntry);
- return;
- }
- continue;
- }
- }
-
- if (c_restartRecord.m_pass <= CREATE_NEW_PASS)
- {
- if (!::checkSchemaStatus(newEntry->m_tableType, c_restartRecord.m_pass))
- continue;
-
- switch(newSchemaState){
- case SchemaFile::INIT: jam();
- case SchemaFile::DROP_TABLE_COMMITTED: jam();
- case SchemaFile::TEMPORARY_TABLE_COMMITTED: jam();
- * oldEntry = * newEntry;
- continue;
- case SchemaFile::ADD_STARTED: jam();
- case SchemaFile::DROP_TABLE_STARTED: jam();
- ndbrequire(DictTabInfo::isTable(newEntry->m_tableType) ||
- DictTabInfo::isIndex(newEntry->m_tableType));
- newEntry->m_tableState = SchemaFile::INIT;
- continue;
- case SchemaFile::TABLE_ADD_COMMITTED: jam();
- case SchemaFile::ALTER_TABLE_COMMITTED: jam();
- if (DictTabInfo::isIndex(newEntry->m_tableType) ||
- DictTabInfo::isTable(newEntry->m_tableType))
- {
- bool file = * oldEntry == *newEntry &&
- (!DictTabInfo::isIndex(newEntry->m_tableType) || c_systemRestart);
-
-#ifdef PRINT_SCHEMA_RESTART
- ndbout_c("%s -> restartCreateTab (file: %d)", buf, file);
- ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
- restartCreateTab(signal, tableId, newEntry, newEntry, file);
- * oldEntry = * newEntry;
- return;
- }
- else if (! (* oldEntry == *newEntry))
- {
-#ifdef PRINT_SCHEMA_RESTART
- ndbout_c("%s -> restartCreateTab", buf);
- ndbout << *newEntry << " " << *oldEntry << endl;
-#endif
- restartCreateTab(signal, tableId, oldEntry, newEntry, false);
- * oldEntry = * newEntry;
- return;
- }
- * oldEntry = * newEntry;
- continue;
- }
- }
- }
-
- c_restartRecord.m_pass++;
- c_restartRecord.activeTable= 0;
- if(c_restartRecord.m_pass <= LAST_PASS)
- {
- checkSchemaStatus(signal);
- }
- else
- {
- execute(signal, c_schemaRecord.m_callback, 0);
- }
-}//checkSchemaStatus()
-
-void
-Dbdict::restartCreateTab(Signal* signal, Uint32 tableId,
- const SchemaFile::TableEntry * old_entry,
- const SchemaFile::TableEntry * new_entry,
- bool file){
- jam();
-
- switch(new_entry->m_tableType){
- case DictTabInfo::UndefTableType:
- case DictTabInfo::HashIndexTrigger:
- case DictTabInfo::SubscriptionTrigger:
- case DictTabInfo::ReadOnlyConstraint:
- case DictTabInfo::IndexTrigger:
- ndbrequire(false);
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- case DictTabInfo::UniqueHashIndex:
- case DictTabInfo::HashIndex:
- case DictTabInfo::UniqueOrderedIndex:
- case DictTabInfo::OrderedIndex:
- break;
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- restartCreateObj(signal, tableId, old_entry, new_entry, file);
- return;
- }
-
- CreateTableRecordPtr createTabPtr;
- c_opCreateTable.seize(createTabPtr);
- ndbrequire(!createTabPtr.isNull());
-
- createTabPtr.p->key = ++c_opRecordSequence;
- c_opCreateTable.add(createTabPtr);
-
- createTabPtr.p->m_errorCode = 0;
- createTabPtr.p->m_tablePtrI = tableId;
- createTabPtr.p->m_coordinatorRef = reference();
- createTabPtr.p->m_senderRef = 0;
- createTabPtr.p->m_senderData = RNIL;
- createTabPtr.p->m_tabInfoPtrI = RNIL;
- createTabPtr.p->m_dihAddFragPtr = RNIL;
-
- if(file && !ERROR_INSERTED(6002)){
- jam();
-
- c_readTableRecord.no_of_words = old_entry->m_info_words;
- c_readTableRecord.pageId = 0;
- c_readTableRecord.m_callback.m_callbackData = createTabPtr.p->key;
- c_readTableRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateTab_readTableConf);
-
- startReadTableFile(signal, tableId);
- return;
- } else {
-
- ndbrequire(c_masterNodeId != getOwnNodeId());
-
- /**
- * Get from master
- */
- GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = createTabPtr.p->key;
- req->requestType = GetTabInfoReq::RequestById |
- GetTabInfoReq::LongSignalConf;
- req->tableId = tableId;
- sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
-
- if(ERROR_INSERTED(6002)){
- NdbSleep_MilliSleep(10);
- CRASH_INSERTION(6002);
- }
- }
-}
-
-void
-Dbdict::restartCreateTab_readTableConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- PageRecordPtr pageRecPtr;
- c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
-
- ParseDictTabInfoRecord parseRecord;
- parseRecord.requestType = DictTabInfo::GetTabInfoConf;
- parseRecord.errorCode = 0;
-
- Uint32 sz = c_readTableRecord.no_of_words;
- SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz);
- handleTabInfoInit(r, &parseRecord);
- if (parseRecord.errorCode != 0)
- {
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Unable to restart, fail while creating table %d"
- " error: %d. Most likely change of configuration",
- c_readTableRecord.tableId,
- parseRecord.errorCode);
- progError(__LINE__,
- NDBD_EXIT_INVALID_CONFIG,
- buf);
- ndbrequire(parseRecord.errorCode == 0);
- }
-
- /* ---------------------------------------------------------------- */
- // We have read the table description from disk as part of system restart.
- // We will also write it back again to ensure that both copies are ok.
- /* ---------------------------------------------------------------- */
- ndbrequire(c_writeTableRecord.tableWriteState == WriteTableRecord::IDLE);
- c_writeTableRecord.no_of_words = c_readTableRecord.no_of_words;
- c_writeTableRecord.pageId = c_readTableRecord.pageId;
- c_writeTableRecord.tableWriteState = WriteTableRecord::TWR_CALLBACK;
- c_writeTableRecord.m_callback.m_callbackData = callbackData;
- c_writeTableRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateTab_writeTableConf);
- startWriteTableFile(signal, c_readTableRecord.tableId);
-}
-
-void
-Dbdict::execGET_TABINFO_CONF(Signal* signal){
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
-
- switch(conf->tableType){
- case DictTabInfo::UndefTableType:
- case DictTabInfo::HashIndexTrigger:
- case DictTabInfo::SubscriptionTrigger:
- case DictTabInfo::ReadOnlyConstraint:
- case DictTabInfo::IndexTrigger:
- ndbrequire(false);
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- case DictTabInfo::UniqueHashIndex:
- case DictTabInfo::HashIndex:
- case DictTabInfo::UniqueOrderedIndex:
- case DictTabInfo::OrderedIndex:
- break;
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- if(refToBlock(conf->senderRef) == TSMAN
- && (refToNode(conf->senderRef) == 0
- || refToNode(conf->senderRef) == getOwnNodeId()))
- {
- jam();
- FilePtr fg_ptr;
- ndbrequire(c_file_hash.find(fg_ptr, conf->tableId));
- const Uint32 free_extents= conf->freeExtents;
- const Uint32 id= conf->tableId;
- const Uint32 type= conf->tableType;
- const Uint32 data= conf->senderData;
- signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
- signal->theData[1]= id;
- signal->theData[2]= type;
- signal->theData[3]= data;
- signal->theData[4]= free_extents;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
- }
- else if(refToBlock(conf->senderRef) == LGMAN
- && (refToNode(conf->senderRef) == 0
- || refToNode(conf->senderRef) == getOwnNodeId()))
- {
- jam();
- FilegroupPtr fg_ptr;
- ndbrequire(c_filegroup_hash.find(fg_ptr, conf->tableId));
- const Uint32 free_hi= conf->freeWordsHi;
- const Uint32 free_lo= conf->freeWordsLo;
- const Uint32 id= conf->tableId;
- const Uint32 type= conf->tableType;
- const Uint32 data= conf->senderData;
- signal->theData[0]= ZPACK_TABLE_INTO_PAGES;
- signal->theData[1]= id;
- signal->theData[2]= type;
- signal->theData[3]= data;
- signal->theData[4]= free_hi;
- signal->theData[5]= free_lo;
- sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
- }
- else
- {
- jam();
- restartCreateObj_getTabInfoConf(signal);
- }
- return;
- }
-
- const Uint32 tableId = conf->tableId;
- const Uint32 senderData = conf->senderData;
-
- SegmentedSectionPtr tabInfoPtr;
- signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
- ndbrequire(!createTabPtr.isNull());
- ndbrequire(createTabPtr.p->m_tablePtrI == tableId);
-
- /**
- * Put data into table record
- */
- ParseDictTabInfoRecord parseRecord;
- parseRecord.requestType = DictTabInfo::GetTabInfoConf;
- parseRecord.errorCode = 0;
-
- SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
- handleTabInfoInit(r, &parseRecord);
- ndbrequire(parseRecord.errorCode == 0);
-
- // save to disk
-
- ndbrequire(tableId < c_tableRecordPool.getSize());
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
- tableEntry->m_info_words= tabInfoPtr.sz;
-
- Callback callback;
- callback.m_callbackData = createTabPtr.p->key;
- 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
-Dbdict::restartCreateTab_writeTableConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- Callback callback;
- callback.m_callbackData = callbackData;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateTab_dihComplete);
-
- SegmentedSectionPtr fragDataPtr;
- fragDataPtr.sz = 0;
- fragDataPtr.setNull();
- createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
-}
-
-void
-Dbdict::restartCreateTab_dihComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- if(createTabPtr.p->m_errorCode)
- {
- char buf[100];
- BaseString::snprintf(buf, sizeof(buf), "Failed to create table during"
- " restart, Error: %u",
- createTabPtr.p->m_errorCode);
- progError(__LINE__, NDBD_EXIT_RESOURCE_ALLOC_ERROR, buf);
- }
-
- Callback callback;
- callback.m_callbackData = callbackData;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateTab_activateComplete);
-
- alterTab_activate(signal, createTabPtr, &callback);
-}
-
-void
-Dbdict::restartCreateTab_activateComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- tabPtr.p->tabState = TableRecord::DEFINED;
-
- releaseCreateTableOp(signal,createTabPtr);
-
- c_restartRecord.activeTable++;
- checkSchemaStatus(signal);
-}
-
-void
-Dbdict::releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr)
-{
- if (createTabPtr.p->m_tabInfoPtrI != RNIL)
- {
- jam();
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
- signal->setSection(tabInfoPtr, 0);
- releaseSections(signal);
- }
- c_opCreateTable.release(createTabPtr);
-}
-
-void
-Dbdict::restartDropTab(Signal* signal, Uint32 tableId,
- const SchemaFile::TableEntry * old_entry,
- const SchemaFile::TableEntry * new_entry)
-{
- switch(old_entry->m_tableType){
- case DictTabInfo::UndefTableType:
- case DictTabInfo::HashIndexTrigger:
- case DictTabInfo::SubscriptionTrigger:
- case DictTabInfo::ReadOnlyConstraint:
- case DictTabInfo::IndexTrigger:
- ndbrequire(false);
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- case DictTabInfo::UniqueHashIndex:
- case DictTabInfo::HashIndex:
- case DictTabInfo::UniqueOrderedIndex:
- case DictTabInfo::OrderedIndex:
- break;
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- restartDropObj(signal, tableId, old_entry);
- return;
- }
-
- const Uint32 key = ++c_opRecordSequence;
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.seize(dropTabPtr));
-
- dropTabPtr.p->key = key;
- c_opDropTable.add(dropTabPtr);
-
- dropTabPtr.p->m_errorCode = 0;
- dropTabPtr.p->m_request.tableId = tableId;
- dropTabPtr.p->m_coordinatorRef = 0;
- dropTabPtr.p->m_requestType = DropTabReq::RestartDropTab;
- dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
-
- dropTabPtr.p->m_participantData.m_block = 0;
- dropTabPtr.p->m_participantData.m_callback.m_callbackData = key;
- dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartDropTab_complete);
- dropTab_nextStep(signal, dropTabPtr);
-}
-
-void
-Dbdict::restartDropTab_complete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
-
- //@todo check error
-
- releaseTableObject(c_restartRecord.activeTable);
- c_opDropTable.release(dropTabPtr);
-
- c_restartRecord.activeTable++;
- checkSchemaStatus(signal);
-}
-
-/**
- * Create Obj during NR/SR
- */
-void
-Dbdict::restartCreateObj(Signal* signal,
- Uint32 tableId,
- const SchemaFile::TableEntry * old_entry,
- const SchemaFile::TableEntry * new_entry,
- bool file){
- jam();
-
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.seize(createObjPtr));
-
- const Uint32 key = ++c_opRecordSequence;
- createObjPtr.p->key = key;
- c_opCreateObj.add(createObjPtr);
- createObjPtr.p->m_errorCode = 0;
- createObjPtr.p->m_senderRef = reference();
- createObjPtr.p->m_senderData = tableId;
- createObjPtr.p->m_clientRef = reference();
- createObjPtr.p->m_clientData = tableId;
-
- createObjPtr.p->m_obj_id = tableId;
- createObjPtr.p->m_obj_type = new_entry->m_tableType;
- createObjPtr.p->m_obj_version = new_entry->m_tableVersion;
-
- createObjPtr.p->m_callback.m_callbackData = key;
- createObjPtr.p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::restartCreateObj_prepare_start_done);
-
- createObjPtr.p->m_restart= file ? 1 : 2;
- switch(new_entry->m_tableType){
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- createObjPtr.p->m_vt_index = 0;
- break;
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- createObjPtr.p->m_vt_index = 1;
- break;
- default:
- ndbrequire(false);
- }
-
- createObjPtr.p->m_obj_info_ptr_i = RNIL;
- if(file)
- {
- c_readTableRecord.no_of_words = old_entry->m_info_words;
- c_readTableRecord.pageId = 0;
- c_readTableRecord.m_callback.m_callbackData = key;
- c_readTableRecord.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateObj_readConf);
-
- startReadTableFile(signal, tableId);
- }
- else
- {
- /**
- * Get from master
- */
- GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = key;
- req->requestType = GetTabInfoReq::RequestById |
- GetTabInfoReq::LongSignalConf;
- req->tableId = tableId;
- sendSignal(calcDictBlockRef(c_masterNodeId), GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- }
-}
-
-void
-Dbdict::restartCreateObj_getTabInfoConf(Signal* signal)
-{
- jam();
-
- GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
-
- const Uint32 objId = conf->tableId;
- const Uint32 senderData = conf->senderData;
-
- SegmentedSectionPtr objInfoPtr;
- signal->getSection(objInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
-
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, senderData));
- ndbrequire(createObjPtr.p->m_obj_id == objId);
-
- createObjPtr.p->m_obj_info_ptr_i= objInfoPtr.i;
- signal->header.m_noOfSections = 0;
-
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
- (signal, createObjPtr.p);
-}
-
-void
-Dbdict::restartCreateObj_readConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- PageRecordPtr pageRecPtr;
- c_pageRecordArray.getPtr(pageRecPtr, c_readTableRecord.pageId);
-
- Uint32 sz = c_readTableRecord.no_of_words;
-
- Ptr<SectionSegment> ptr;
- ndbrequire(import(ptr, pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz));
- createObjPtr.p->m_obj_info_ptr_i= ptr.i;
-
- if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
- (signal, createObjPtr.p);
- else
- execute(signal, createObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartCreateObj_prepare_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- Callback callback;
- callback.m_callbackData = callbackData;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateObj_write_complete);
-
- SegmentedSectionPtr objInfoPtr;
- getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
-
- writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
-}
-
-void
-Dbdict::restartCreateObj_write_complete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- SegmentedSectionPtr objInfoPtr;
- getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
- signal->setSection(objInfoPtr, 0);
- releaseSections(signal);
- createObjPtr.p->m_obj_info_ptr_i = RNIL;
-
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateObj_prepare_complete_done);
-
- if (f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
- (signal, createObjPtr.p);
- else
- execute(signal, createObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartCreateObj_prepare_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateObj_commit_start_done);
-
- if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_start)
- (signal, createObjPtr.p);
- else
- execute(signal, createObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartCreateObj_commit_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartCreateObj_commit_complete_done);
-
- if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
- (signal, createObjPtr.p);
- else
- execute(signal, createObjPtr.p->m_callback, 0);
-}
-
-
-void
-Dbdict::restartCreateObj_commit_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- ndbrequire(createObjPtr.p->m_errorCode == 0);
-
- c_opCreateObj.release(createObjPtr);
-
- c_restartRecord.activeTable++;
- checkSchemaStatus(signal);
-}
-
-/**
- * Drop object during NR/SR
- */
-void
-Dbdict::restartDropObj(Signal* signal,
- Uint32 tableId,
- const SchemaFile::TableEntry * entry)
-{
- jam();
-
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.seize(dropObjPtr));
-
- const Uint32 key = ++c_opRecordSequence;
- dropObjPtr.p->key = key;
- c_opDropObj.add(dropObjPtr);
- dropObjPtr.p->m_errorCode = 0;
- dropObjPtr.p->m_senderRef = reference();
- dropObjPtr.p->m_senderData = tableId;
- dropObjPtr.p->m_clientRef = reference();
- dropObjPtr.p->m_clientData = tableId;
-
- dropObjPtr.p->m_obj_id = tableId;
- dropObjPtr.p->m_obj_type = entry->m_tableType;
- dropObjPtr.p->m_obj_version = entry->m_tableVersion;
-
- dropObjPtr.p->m_callback.m_callbackData = key;
- dropObjPtr.p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::restartDropObj_prepare_start_done);
-
- ndbout_c("Dropping %d %d", tableId, entry->m_tableType);
- switch(entry->m_tableType){
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:{
- jam();
- Ptr<Filegroup> fg_ptr;
- ndbrequire(c_filegroup_hash.find(fg_ptr, tableId));
- dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
- dropObjPtr.p->m_vt_index = 3;
- break;
- }
- case DictTabInfo::Datafile:{
- jam();
- Ptr<File> file_ptr;
- dropObjPtr.p->m_vt_index = 2;
- ndbrequire(c_file_hash.find(file_ptr, tableId));
- dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
- break;
- }
- case DictTabInfo::Undofile:{
- jam();
- Ptr<File> file_ptr;
- dropObjPtr.p->m_vt_index = 4;
- ndbrequire(c_file_hash.find(file_ptr, tableId));
- dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
-
- /**
- * Undofiles are only removed from logfile groups file list
- * as drop undofile is currently not supported...
- * file will be dropped by lgman when dropping filegroup
- */
- dropObjPtr.p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::restartDropObj_commit_complete_done);
-
- if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- (signal, dropObjPtr.p);
- else
- execute(signal, dropObjPtr.p->m_callback, 0);
- return;
- }
- default:
- jamLine(entry->m_tableType);
- ndbrequire(false);
- }
-
- if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
- (signal, dropObjPtr.p);
- else
- execute(signal, dropObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartDropObj_prepare_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- ndbrequire(dropObjPtr.p->m_errorCode == 0);
-
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartDropObj_prepare_complete_done);
-
- if (f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
- (signal, dropObjPtr.p);
- else
- execute(signal, dropObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartDropObj_prepare_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- ndbrequire(dropObjPtr.p->m_errorCode == 0);
-
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartDropObj_commit_start_done);
-
- if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_start)
- (signal, dropObjPtr.p);
- else
- execute(signal, dropObjPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::restartDropObj_commit_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- ndbrequire(dropObjPtr.p->m_errorCode == 0);
-
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::restartDropObj_commit_complete_done);
-
- if (f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- (signal, dropObjPtr.p);
- else
- execute(signal, dropObjPtr.p->m_callback, 0);
-}
-
-
-void
-Dbdict::restartDropObj_commit_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- ndbrequire(returnCode == 0);
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- ndbrequire(dropObjPtr.p->m_errorCode == 0);
-
- c_opDropObj.release(dropObjPtr);
-
- c_restartRecord.activeTable++;
- checkSchemaStatus(signal);
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: NODE FAILURE HANDLING ------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code that is used when nodes */
-/* (kernel/api) fails. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// We receive a report of an API that failed.
-/* ---------------------------------------------------------------- */
-void Dbdict::execAPI_FAILREQ(Signal* signal)
-{
- jamEntry();
- Uint32 failedApiNode = signal->theData[0];
- BlockReference retRef = signal->theData[1];
-
-#if 0
- Uint32 userNode = refToNode(c_connRecord.userBlockRef);
- if (userNode == failedApiNode) {
- jam();
- c_connRecord.userBlockRef = (Uint32)-1;
- }//if
-#endif
-
- signal->theData[0] = failedApiNode;
- signal->theData[1] = reference();
- sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB);
-}//execAPI_FAILREQ()
-
-/* ---------------------------------------------------------------- */
-// We receive a report of one or more node failures of kernel nodes.
-/* ---------------------------------------------------------------- */
-void Dbdict::execNODE_FAILREP(Signal* signal)
-{
- jamEntry();
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- c_failureNr = nodeFail->failNo;
- const Uint32 numberOfFailedNodes = nodeFail->noOfNodes;
- const bool masterFailed = (c_masterNodeId != nodeFail->masterNodeId);
- c_masterNodeId = nodeFail->masterNodeId;
-
- c_noNodesFailed += numberOfFailedNodes;
- Uint32 theFailedNodes[NodeBitmask::Size];
- memcpy(theFailedNodes, nodeFail->theNodes, sizeof(theFailedNodes));
-
- c_counterMgr.execNODE_FAILREP(signal);
-
- bool ok = false;
- switch(c_blockState){
- case BS_IDLE:
- jam();
- ok = true;
- if(c_opRecordPool.getSize() !=
- (c_opRecordPool.getNoOfFree() +
- c_opSubEvent.get_count() + c_opCreateEvent.get_count() +
- c_opDropEvent.get_count() + c_opSignalUtil.get_count()))
- {
- jam();
- c_blockState = BS_NODE_FAILURE;
- }
- break;
- case BS_CREATE_TAB:
- jam();
- ok = true;
- if(!masterFailed)
- break;
- // fall through
- case BS_BUSY:
- case BS_NODE_FAILURE:
- jam();
- c_blockState = BS_NODE_FAILURE;
- ok = true;
- break;
- case BS_NODE_RESTART:
- jam();
- ok = true;
- break;
- }
- ndbrequire(ok);
-
- for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if(NodeBitmask::get(theFailedNodes, i)) {
- jam();
- NodeRecordPtr nodePtr;
- c_nodes.getPtr(nodePtr, i);
-
- nodePtr.p->nodeState = NodeRecord::NDB_NODE_DEAD;
- NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0];
- nfCompRep->blockNo = DBDICT;
- nfCompRep->nodeId = getOwnNodeId();
- nfCompRep->failedNodeId = nodePtr.i;
- sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
-
- c_aliveNodes.clear(i);
- }//if
- }//for
-
- /*
- * NODE_FAILREP guarantees that no "in flight" signal from
- * a dead node is accepted, and also that the job buffer contains
- * no such (un-executed) signals. Therefore no DICT_UNLOCK_ORD
- * from a dead node (leading to master crash) is possible after
- * this clean-up removes the lock record.
- */
- removeStaleDictLocks(signal, theFailedNodes);
-
-}//execNODE_FAILREP()
-
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: NODE START HANDLING --------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code that is used when kernel nodes */
-/* starts. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// Include a starting node in list of nodes to be part of adding
-// and dropping tables.
-/* ---------------------------------------------------------------- */
-void Dbdict::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
- NodeRecordPtr nodePtr;
- BlockReference retRef = signal->theData[0];
- nodePtr.i = signal->theData[1];
-
- ndbrequire(c_noNodesFailed > 0);
- c_noNodesFailed--;
-
- c_nodes.getPtr(nodePtr);
- ndbrequire(nodePtr.p->nodeState == NodeRecord::NDB_NODE_DEAD);
- nodePtr.p->nodeState = NodeRecord::NDB_NODE_ALIVE;
- signal->theData[0] = nodePtr.i;
- signal->theData[1] = reference();
- sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB);
-
- c_aliveNodes.set(nodePtr.i);
-}//execINCL_NODEREQ()
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: ADD TABLE HANDLING ---------------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code that is used when adding a table. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-/* ---------------------------------------------------------------- */
-// This signal receives information about a table from either:
-// API, Ndbcntr or from other DICT.
-/* ---------------------------------------------------------------- */
-void
-Dbdict::execCREATE_TABLE_REQ(Signal* signal){
- jamEntry();
- if(!assembleFragments(signal)){
- return;
- }
-
- CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
-
- ParseDictTabInfoRecord parseRecord;
- do {
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- parseRecord.errorCode = CreateTableRef::NotMaster;
- break;
- }
-
- if (c_blockState == BS_NODE_RESTART){
- jam();
- parseRecord.errorCode = CreateTableRef::BusyWithNR;
- break;
- }
-
- if (c_blockState != BS_IDLE){
- jam();
- parseRecord.errorCode = CreateTableRef::Busy;
- break;
- }
-
- if (checkSingleUserMode(signal->getSendersBlockRef()))
- {
- jam();
- parseRecord.errorCode = CreateTableRef::SingleUser;
- break;
- }
-
- CreateTableRecordPtr createTabPtr;
- c_opCreateTable.seize(createTabPtr);
-
- if(createTabPtr.isNull()){
- jam();
- parseRecord.errorCode = CreateTableRef::Busy;
- break;
- }
-
- parseRecord.requestType = DictTabInfo::CreateTableFromAPI;
- parseRecord.errorCode = 0;
-
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
- SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
-
- handleTabInfoInit(r, &parseRecord);
- releaseSections(signal);
-
- if(parseRecord.errorCode != 0){
- jam();
- c_opCreateTable.release(createTabPtr);
- break;
- }
-
- createTabPtr.p->m_errorCode = 0;
- createTabPtr.p->m_senderRef = senderRef;
- createTabPtr.p->m_senderData = senderData;
- createTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
- createTabPtr.p->m_coordinatorRef = reference();
- createTabPtr.p->m_fragmentsPtrI = RNIL;
- createTabPtr.p->m_dihAddFragPtr = RNIL;
-
- Uint32 key = c_opRecordSequence + 1;
- Uint32 *theData = signal->getDataPtrSend();
- Uint16 *frag_data= (Uint16*)&signal->theData[25];
- CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
- req->senderRef = reference();
- req->senderData = key;
- req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
- req->noOfFragments = parseRecord.tablePtr.p->fragmentCount;
- req->fragmentationType = parseRecord.tablePtr.p->fragmentType;
- MEMCOPY_NO_WORDS(frag_data, c_fragData, c_fragDataLen);
-
- if (parseRecord.tablePtr.p->isOrderedIndex()) {
- jam();
- // ordered index has same fragmentation as the table
- req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
- req->fragmentationType = DictTabInfo::DistrKeyOrderedIndex;
- }
- else if (parseRecord.tablePtr.p->isHashIndex())
- {
- jam();
- /*
- Unique hash indexes has same amount of fragments as primary table
- and distributed in the same manner but has always a normal hash
- fragmentation.
- */
- req->primaryTableId = parseRecord.tablePtr.p->primaryTableId;
- req->fragmentationType = DictTabInfo::DistrKeyUniqueHashIndex;
- }
- else
- {
- jam();
- /*
- Blob tables come here with primaryTableId != RNIL but we only need
- it for creating the fragments so we set it to RNIL now that we got
- what we wanted from it to avoid other side effects.
- */
- parseRecord.tablePtr.p->primaryTableId = RNIL;
- }
- EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
- CreateFragmentationReq::SignalLength);
- jamEntry();
- if (signal->theData[0] != 0)
- {
- jam();
- parseRecord.errorCode= signal->theData[0];
- c_opCreateTable.release(createTabPtr);
- releaseTableObject(parseRecord.tablePtr.i, true);
- break;
- }
- createTabPtr.p->key = key;
- c_opRecordSequence++;
- c_opCreateTable.add(createTabPtr);
- c_blockState = BS_CREATE_TAB;
- return;
- } while(0);
-
- /**
- * Something went wrong
- */
-
- releaseSections(signal);
- CreateTableRef * ref = (CreateTableRef*)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->masterNodeId = c_masterNodeId;
- ref->errorCode = parseRecord.errorCode;
- ref->errorLine = parseRecord.errorLine;
- ref->errorKey = parseRecord.errorKey;
- ref->status = parseRecord.status;
- sendSignal(senderRef, GSN_CREATE_TABLE_REF, signal,
- CreateTableRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execBACKUP_FRAGMENT_REQ(Signal* signal)
-{
- jamEntry();
- Uint32 tableId = signal->theData[0];
- Uint32 lock = signal->theData[1];
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId, true);
-
- if(lock)
- {
- ndbrequire(tablePtr.p->tabState == TableRecord::DEFINED);
- tablePtr.p->tabState = TableRecord::BACKUP_ONGOING;
- }
- else if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
- {
- tablePtr.p->tabState = TableRecord::DEFINED;
- }
-}
-
-bool
-Dbdict::check_ndb_versions() const
-{
- Uint32 node = 0;
- Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
- while((node = c_aliveNodes.find(node + 1)) != BitmaskImpl::NotFound)
- {
- if(getNodeInfo(node).m_version != version)
- {
- return false;
- }
- }
- return true;
-}
-
-void
-Dbdict::execALTER_TABLE_REQ(Signal* signal)
-{
- // Received by master
- jamEntry();
- if(!assembleFragments(signal)){
- return;
- }
- AlterTableReq* const req = (AlterTableReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- ParseDictTabInfoRecord* aParseRecord;
-
- // Get table definition
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId, false);
- if(tablePtr.isNull()){
- jam();
- alterTableRef(signal, req, AlterTableRef::NoSuchTable);
- return;
- }
-
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- alterTableRef(signal, req, AlterTableRef::NotMaster);
- return;
- }
-
- if(c_blockState == BS_NODE_RESTART){
- jam();
- alterTableRef(signal, req, AlterTableRef::BusyWithNR);
- return;
- }
-
- if(c_blockState != BS_IDLE){
- jam();
- alterTableRef(signal, req, AlterTableRef::Busy);
- return;
- }
-
- if (!check_ndb_versions())
- {
- jam();
- alterTableRef(signal, req, AlterTableRef::IncompatibleVersions);
- return;
- }
-
- if (checkSingleUserMode(signal->getSendersBlockRef()))
- {
- jam();
- alterTableRef(signal, req, AlterTableRef::SingleUser);
- return;
- }
-
- const TableRecord::TabState tabState = tablePtr.p->tabState;
- bool ok = false;
- switch(tabState){
- case TableRecord::NOT_DEFINED:
- case TableRecord::DEFINING:
- jam();
- alterTableRef(signal, req, AlterTableRef::NoSuchTable);
- return;
- case TableRecord::DEFINED:
- ok = true;
- jam();
- break;
- case TableRecord::BACKUP_ONGOING:
- jam();
- alterTableRef(signal, req, AlterTableRef::BackupInProgress);
- return;
- case TableRecord::PREPARE_DROPPING:
- case TableRecord::DROPPING:
- jam();
- alterTableRef(signal, req, AlterTableRef::DropInProgress);
- return;
- }
- ndbrequire(ok);
-
- if(tablePtr.p->tableVersion != tableVersion){
- jam();
- alterTableRef(signal, req, AlterTableRef::InvalidTableVersion);
- return;
- }
- // Parse new table defintion
- ParseDictTabInfoRecord parseRecord;
- aParseRecord = &parseRecord;
-
- CreateTableRecordPtr alterTabPtr; // Reuse create table records
- c_opCreateTable.seize(alterTabPtr);
-
- if(alterTabPtr.isNull()){
- jam();
- alterTableRef(signal, req, AlterTableRef::Busy);
- return;
- }
-
- alterTabPtr.p->m_changeMask = changeMask;
- parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
- parseRecord.errorCode = 0;
-
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
- SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
-
- handleTabInfoInit(r, &parseRecord, false); // Will not save info
-
- if(parseRecord.errorCode != 0){
- jam();
- c_opCreateTable.release(alterTabPtr);
- alterTableRef(signal, req,
- (AlterTableRef::ErrorCode) parseRecord.errorCode,
- aParseRecord);
- return;
- }
-
- releaseSections(signal);
- alterTabPtr.p->key = ++c_opRecordSequence;
- c_opCreateTable.add(alterTabPtr);
- ndbrequire(c_opCreateTable.find(alterTabPtr, alterTabPtr.p->key));
- alterTabPtr.p->m_errorCode = 0;
- alterTabPtr.p->m_senderRef = senderRef;
- alterTabPtr.p->m_senderData = senderData;
- alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
- alterTabPtr.p->m_alterTableFailed = false;
- alterTabPtr.p->m_coordinatorRef = reference();
- alterTabPtr.p->m_fragmentsPtrI = RNIL;
- alterTabPtr.p->m_dihAddFragPtr = RNIL;
- alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
-
- // Send prepare request to all alive nodes
- SimplePropertiesSectionWriter w(getSectionSegmentPool());
- packTableIntoPages(w, parseRecord.tablePtr);
-
- SegmentedSectionPtr tabInfoPtr;
- w.getPtr(tabInfoPtr);
-
- alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
-
- // Alter table on all nodes
- c_blockState = BS_BUSY;
-
- Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
- Callback c = { safe_cast(&Dbdict::alterTable_backup_mutex_locked),
- alterTabPtr.p->key };
-
- ndbrequire(mutex.lock(c));
-}
-
-void
-Dbdict::alterTable_backup_mutex_locked(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue)
-{
- jamEntry();
-
- ndbrequire(retValue == 0);
-
- CreateTableRecordPtr alterTabPtr;
- ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId, true);
-
- Mutex mutex(signal, c_mutexMgr, alterTabPtr.p->m_startLcpMutex);
- mutex.unlock(); // ignore response
-
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
- signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-
- alterTabPtr.p->m_tabInfoPtrI = RNIL;
-
- if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
- {
- jam();
- AlterTableReq* req = (AlterTableReq*)signal->getDataPtr();
- req->senderData = alterTabPtr.p->m_senderData;
- req->senderRef = alterTabPtr.p->m_senderRef;
- alterTableRef(signal, req, AlterTableRef::BackupInProgress);
-
- c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_tablePtrI);
- releaseTableObject(tablePtr.i, false);
-
- c_opCreateTable.release(alterTabPtr);
- c_blockState = BS_IDLE;
- return;
- }
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
- SafeCounter safeCounter(c_counterMgr,
- alterTabPtr.p->m_coordinatorData.m_counter);
- safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
-
- AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
- lreq->senderRef = reference();
- lreq->senderData = alterTabPtr.p->key;
- lreq->clientRef = alterTabPtr.p->m_senderRef;
- lreq->clientData = alterTabPtr.p->m_senderData;
- lreq->changeMask = alterTabPtr.p->m_changeMask;
- lreq->tableId = tablePtr.p->tableId;
- lreq->tableVersion = alter_obj_inc_schema_version(tablePtr.p->tableVersion);
- lreq->gci = tablePtr.p->gciTableCreated;
- lreq->requestType = AlterTabReq::AlterTablePrepare;
-
- sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
-}
-
-void Dbdict::alterTableRef(Signal * signal,
- AlterTableReq * req,
- AlterTableRef::ErrorCode errCode,
- ParseDictTabInfoRecord* parseRecord)
-{
- jam();
- releaseSections(signal);
- AlterTableRef * ref = (AlterTableRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- ref->senderData = req->senderData;
- ref->senderRef = reference();
- ref->masterNodeId = c_masterNodeId;
- if (parseRecord) {
- ref->errorCode = parseRecord->errorCode;
- ref->errorLine = parseRecord->errorLine;
- ref->errorKey = parseRecord->errorKey;
- ref->status = parseRecord->status;
- }
- else {
- ref->errorCode = errCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->status = 0;
- }
- sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
- AlterTableRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execALTER_TAB_REQ(Signal * signal)
-{
- // Received in all nodes to handle change locally
- jamEntry();
-
- if(!assembleFragments(signal)){
- return;
- }
- AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- const Uint32 gci = req->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) req->requestType;
-
- SegmentedSectionPtr tabInfoPtr;
- signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-
- CreateTableRecordPtr alterTabPtr; // Reuse create table records
-
- if (senderRef != reference()) {
- jam();
- c_blockState = BS_BUSY;
- }
- if ((requestType == AlterTabReq::AlterTablePrepare)
- && (senderRef != reference())) {
- jam();
- c_opCreateTable.seize(alterTabPtr);
- if(!alterTabPtr.isNull())
- alterTabPtr.p->m_changeMask = changeMask;
- }
- else {
- jam();
- ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
- }
- if(alterTabPtr.isNull()){
- jam();
- alterTabRef(signal, req, AlterTableRef::Busy);
- return;
- }
-
- if (!check_ndb_versions())
- {
- jam();
- alterTabRef(signal, req, AlterTableRef::IncompatibleVersions);
- return;
- }
-
- alterTabPtr.p->m_alterTableId = tableId;
- alterTabPtr.p->m_coordinatorRef = senderRef;
-
- // Get table definition
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId, false);
- if(tablePtr.isNull()){
- jam();
- alterTabRef(signal, req, AlterTableRef::NoSuchTable);
- return;
- }
-
- switch(requestType) {
- case(AlterTabReq::AlterTablePrepare): {
- ParseDictTabInfoRecord* aParseRecord;
-
- const TableRecord::TabState tabState = tablePtr.p->tabState;
- bool ok = false;
- switch(tabState){
- case TableRecord::NOT_DEFINED:
- case TableRecord::DEFINING:
- jam();
- alterTabRef(signal, req, AlterTableRef::NoSuchTable);
- return;
- case TableRecord::DEFINED:
- ok = true;
- jam();
- break;
- case TableRecord::PREPARE_DROPPING:
- case TableRecord::DROPPING:
- jam();
- alterTabRef(signal, req, AlterTableRef::DropInProgress);
- return;
- case TableRecord::BACKUP_ONGOING:
- jam();
- alterTabRef(signal, req, AlterTableRef::BackupInProgress);
- return;
- }
- ndbrequire(ok);
-
- if(alter_obj_inc_schema_version(tablePtr.p->tableVersion) != tableVersion){
- jam();
- alterTabRef(signal, req, AlterTableRef::InvalidTableVersion);
- return;
- }
- TableRecordPtr newTablePtr;
- if (senderRef != reference()) {
- jam();
- // Parse altered table defintion
- ParseDictTabInfoRecord parseRecord;
- aParseRecord = &parseRecord;
-
- parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
- parseRecord.errorCode = 0;
-
- SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
-
- handleTabInfoInit(r, &parseRecord, false); // Will not save info
-
- if(parseRecord.errorCode != 0){
- jam();
- c_opCreateTable.release(alterTabPtr);
- alterTabRef(signal, req,
- (AlterTableRef::ErrorCode) parseRecord.errorCode,
- aParseRecord);
- return;
- }
- alterTabPtr.p->key = senderData;
- c_opCreateTable.add(alterTabPtr);
- alterTabPtr.p->m_errorCode = 0;
- alterTabPtr.p->m_senderRef = senderRef;
- alterTabPtr.p->m_senderData = senderData;
- alterTabPtr.p->m_tablePtrI = parseRecord.tablePtr.i;
- alterTabPtr.p->m_fragmentsPtrI = RNIL;
- alterTabPtr.p->m_dihAddFragPtr = RNIL;
- newTablePtr = parseRecord.tablePtr;
- newTablePtr.p->tableVersion = tableVersion;
- }
- else { // (req->senderRef == reference())
- jam();
- c_tableRecordPool.getPtr(newTablePtr, alterTabPtr.p->m_tablePtrI);
- newTablePtr.p->tableVersion = tableVersion;
- }
- if (handleAlterTab(req, alterTabPtr.p, tablePtr, newTablePtr) == -1) {
- jam();
- c_opCreateTable.release(alterTabPtr);
- alterTabRef(signal, req, AlterTableRef::UnsupportedChange);
- return;
- }
- releaseSections(signal);
- // Propagate alter table to other local blocks
- AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- req->changeMask = changeMask;
- req->tableId = tableId;
- req->tableVersion = tableVersion;
- req->gci = gci;
- req->requestType = requestType;
- sendSignal(DBLQH_REF, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- return;
- }
- case(AlterTabReq::AlterTableCommit): {
- jam();
- // Write schema for altered table to disk
- SegmentedSectionPtr tabInfoPtr;
- signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
- alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
- bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
-
- signal->header.m_noOfSections = 0;
-
- // Update table record
- tablePtr.p->packedSize = tabInfoPtr.sz;
- tablePtr.p->tableVersion = tableVersion;
- tablePtr.p->gciTableCreated = gci;
-
- SchemaFile::TableEntry tabEntry;
- tabEntry.m_tableVersion = tableVersion;
- tabEntry.m_tableType = tablePtr.p->tableType;
- if (savetodisk)
- tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED;
- else
- tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED;
- tabEntry.m_gcp = gci;
- tabEntry.m_info_words = tabInfoPtr.sz;
- memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
-
- Callback callback;
- callback.m_callbackData = senderData;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::alterTab_writeSchemaConf);
-
- updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
- break;
- }
- case(AlterTabReq::AlterTableRevert): {
- jam();
- // Revert failed alter table
- revertAlterTable(signal, changeMask, tableId, alterTabPtr.p);
- // Acknowledge the reverted alter table
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
- break;
- }
- default: ndbrequire(false);
- }
-}
-
-void Dbdict::alterTabRef(Signal * signal,
- AlterTabReq * req,
- AlterTableRef::ErrorCode errCode,
- ParseDictTabInfoRecord* parseRecord)
-{
- jam();
- releaseSections(signal);
- AlterTabRef * ref = (AlterTabRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- ref->senderData = req->senderData;
- ref->senderRef = reference();
- if (parseRecord) {
- jam();
- ref->errorCode = parseRecord->errorCode;
- ref->errorLine = parseRecord->errorLine;
- ref->errorKey = parseRecord->errorKey;
- ref->errorStatus = parseRecord->status;
- }
- else {
- jam();
- ref->errorCode = errCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->errorStatus = 0;
- }
- sendSignal(senderRef, GSN_ALTER_TAB_REF, signal,
- AlterTabRef::SignalLength, JBB);
-
- c_blockState = BS_IDLE;
-}
-
-void Dbdict::execALTER_TAB_REF(Signal * signal){
- jamEntry();
-
- AlterTabRef * ref = (AlterTabRef*)signal->getDataPtr();
-
- Uint32 senderRef = ref->senderRef;
- Uint32 senderData = ref->senderData;
- Uint32 errorCode = ref->errorCode;
- Uint32 errorLine = ref->errorLine;
- Uint32 errorKey = ref->errorKey;
- Uint32 errorStatus = ref->errorStatus;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) ref->requestType;
- CreateTableRecordPtr alterTabPtr;
- ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
- Uint32 changeMask = alterTabPtr.p->m_changeMask;
- SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
- safeCounter.clearWaitingFor(refToNode(senderRef));
- switch (requestType) {
- case(AlterTabReq::AlterTablePrepare): {
- if (safeCounter.done()) {
- jam();
- // Send revert request to all alive nodes
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
- Uint32 tableId = tablePtr.p->tableId;
- Uint32 tableVersion = tablePtr.p->tableVersion;
- Uint32 gci = tablePtr.p->gciTableCreated;
- SimplePropertiesSectionWriter w(getSectionSegmentPool());
- packTableIntoPages(w, tablePtr);
- SegmentedSectionPtr spDataPtr;
- w.getPtr(spDataPtr);
- signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
- safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
-
- AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
- lreq->senderRef = reference();
- lreq->senderData = alterTabPtr.p->key;
- lreq->clientRef = alterTabPtr.p->m_senderRef;
- lreq->clientData = alterTabPtr.p->m_senderData;
- lreq->changeMask = changeMask;
- lreq->tableId = tableId;
- lreq->tableVersion = tableVersion;
- lreq->gci = gci;
- lreq->requestType = AlterTabReq::AlterTableRevert;
-
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- }
- else {
- jam();
- alterTabPtr.p->m_alterTableFailed = true;
- }
- break;
- }
- case(AlterTabReq::AlterTableCommit):
- jam();
- case(AlterTabReq::AlterTableRevert): {
- AlterTableRef * apiRef = (AlterTableRef*)signal->getDataPtrSend();
-
- apiRef->senderData = senderData;
- apiRef->senderRef = reference();
- apiRef->masterNodeId = c_masterNodeId;
- apiRef->errorCode = errorCode;
- apiRef->errorLine = errorLine;
- apiRef->errorKey = errorKey;
- apiRef->status = errorStatus;
- if (safeCounter.done()) {
- jam();
- sendSignal(senderRef, GSN_ALTER_TABLE_REF, signal,
- AlterTableRef::SignalLength, JBB);
- c_blockState = BS_IDLE;
- }
- else {
- jam();
- alterTabPtr.p->m_alterTableFailed = true;
- alterTabPtr.p->m_alterTableRef = *apiRef;
- }
- break;
- }
- default: ndbrequire(false);
- }
-}
-
-void
-Dbdict::execALTER_TAB_CONF(Signal * signal){
- jamEntry();
- AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr();
- Uint32 senderRef = conf->senderRef;
- Uint32 senderData = conf->senderData;
- Uint32 changeMask = conf->changeMask;
- Uint32 tableId = conf->tableId;
- Uint32 tableVersion = conf->tableVersion;
- Uint32 gci = conf->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) conf->requestType;
- CreateTableRecordPtr alterTabPtr;
- ndbrequire(c_opCreateTable.find(alterTabPtr, senderData));
-
- switch (requestType) {
- case(AlterTabReq::AlterTablePrepare): {
- switch(refToBlock(signal->getSendersBlockRef())) {
- case DBLQH: {
- jam();
- AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- req->changeMask = changeMask;
- req->tableId = tableId;
- req->tableVersion = tableVersion;
- req->gci = gci;
- req->requestType = requestType;
- sendSignal(DBDIH_REF, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- return;
- }
- case DBDIH: {
- jam();
- AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- req->changeMask = changeMask;
- req->tableId = tableId;
- req->tableVersion = tableVersion;
- req->gci = gci;
- req->requestType = requestType;
- sendSignal(DBTC_REF, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- return;
- }
- case DBTC: {
- jam();
- // Participant is done with prepare phase, send conf to coordinator
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(alterTabPtr.p->m_coordinatorRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
- return;
- }
- default :break;
- }
- // Coordinator only
- SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
- safeCounter.clearWaitingFor(refToNode(senderRef));
- if (safeCounter.done()) {
- jam();
- // We have received all local confirmations
- if (alterTabPtr.p->m_alterTableFailed) {
- jam();
- // Send revert request to all alive nodes
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, alterTabPtr.p->m_alterTableId);
- Uint32 tableId = tablePtr.p->tableId;
- Uint32 tableVersion = tablePtr.p->tableVersion;
- Uint32 gci = tablePtr.p->gciTableCreated;
- SimplePropertiesSectionWriter w(getSectionSegmentPool());
- packTableIntoPages(w, tablePtr);
- SegmentedSectionPtr spDataPtr;
- w.getPtr(spDataPtr);
- signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
- safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
-
- AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
- lreq->senderRef = reference();
- lreq->senderData = alterTabPtr.p->key;
- lreq->clientRef = alterTabPtr.p->m_senderRef;
- lreq->clientData = alterTabPtr.p->m_senderData;
- lreq->changeMask = changeMask;
- lreq->tableId = tableId;
- lreq->tableVersion = tableVersion;
- lreq->gci = gci;
- lreq->requestType = AlterTabReq::AlterTableRevert;
-
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- }
- else {
- jam();
- // Send commit request to all alive nodes
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- SimplePropertiesSectionWriter w(getSectionSegmentPool());
- packTableIntoPages(w, tablePtr);
- SegmentedSectionPtr spDataPtr;
- w.getPtr(spDataPtr);
- signal->setSection(spDataPtr, AlterTabReq::DICT_TAB_INFO);
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- alterTabPtr.p->m_coordinatorData.m_gsn = GSN_ALTER_TAB_REQ;
- safeCounter.init<AlterTabRef>(rg, alterTabPtr.p->key);
-
- AlterTabReq * const lreq = (AlterTabReq*)signal->getDataPtrSend();
- lreq->senderRef = reference();
- lreq->senderData = alterTabPtr.p->key;
- lreq->clientRef = alterTabPtr.p->m_senderRef;
- lreq->clientData = alterTabPtr.p->m_senderData;
- lreq->changeMask = changeMask;
- lreq->tableId = tableId;
- lreq->tableVersion = tableVersion;
- lreq->gci = gci;
- lreq->requestType = AlterTabReq::AlterTableCommit;
-
- sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
- }
- }
- else {
- // (!safeCounter.done())
- jam();
- }
- break;
- }
- case(AlterTabReq::AlterTableRevert):
- jam();
- case(AlterTabReq::AlterTableCommit): {
- SafeCounter safeCounter(c_counterMgr, alterTabPtr.p->m_coordinatorData.m_counter);
- safeCounter.clearWaitingFor(refToNode(senderRef));
- if (safeCounter.done()) {
- jam();
- // We have received all local confirmations
- releaseSections(signal);
- if (alterTabPtr.p->m_alterTableFailed) {
- jam();
- AlterTableRef * apiRef =
- (AlterTableRef*)signal->getDataPtrSend();
- *apiRef = alterTabPtr.p->m_alterTableRef;
- sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_REF, signal,
- AlterTableRef::SignalLength, JBB);
- }
- else {
- jam();
- // Alter table completed, inform API
- AlterTableConf * const apiConf =
- (AlterTableConf*)signal->getDataPtrSend();
- apiConf->senderRef = reference();
- apiConf->senderData = alterTabPtr.p->m_senderData;
- apiConf->tableId = tableId;
- apiConf->tableVersion = tableVersion;
-
- //@todo check api failed
- sendSignal(alterTabPtr.p->m_senderRef, GSN_ALTER_TABLE_CONF, signal,
- AlterTableConf::SignalLength, JBB);
- }
-
- // Release resources
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
- releaseTableObject(tabPtr.i, false);
- releaseCreateTableOp(signal,alterTabPtr);
- c_blockState = BS_IDLE;
- }
- else {
- // (!safeCounter.done())
- jam();
- }
- break;
- }
- default: ndbrequire(false);
- }
-}
-
-// For debugging
-inline
-void Dbdict::printTables()
-{
- DLHashTable<DictObject>::Iterator iter;
- bool moreTables = c_obj_hash.first(iter);
- printf("OBJECTS IN DICT:\n");
- char name[MAX_TAB_NAME_SIZE];
- while (moreTables) {
- Ptr<DictObject> tablePtr = iter.curr;
- ConstRope r(c_rope_pool, tablePtr.p->m_name);
- r.copy(name);
- printf("%s ", name);
- moreTables = c_obj_hash.next(iter);
- }
- printf("\n");
-}
-
-int Dbdict::handleAlterTab(AlterTabReq * req,
- CreateTableRecord * alterTabPtrP,
- TableRecordPtr origTablePtr,
- TableRecordPtr newTablePtr)
-{
- bool supportedAlteration = false;
- Uint32 changeMask = req->changeMask;
-
- if (AlterTableReq::getNameFlag(changeMask)) {
- jam();
- // Table rename
- supportedAlteration = true;
- // Remove from hashtable
- Ptr<DictObject> obj_ptr;
- c_obj_pool.getPtr(obj_ptr, origTablePtr.p->m_obj_ptr_i);
- c_obj_hash.remove(obj_ptr);
- {
- Rope org(c_rope_pool, origTablePtr.p->tableName);
- org.copy(alterTabPtrP->previousTableName);
-
- ConstRope src(c_rope_pool, newTablePtr.p->tableName);
- char tmp[MAX_TAB_NAME_SIZE];
- const int len = src.size();
- src.copy(tmp);
- ndbrequire(org.assign(tmp, len));
- }
- obj_ptr.p->m_name = origTablePtr.p->tableName;
- // Put it back
- c_obj_hash.add(obj_ptr);
- }
-
- if (AlterTableReq::getFrmFlag(changeMask)) {
- // Table definition changed (new frm)
- supportedAlteration = true;
- // Save old definition
- Rope org(c_rope_pool, origTablePtr.p->frmData);
- org.copy(alterTabPtrP->previousFrmData);
- alterTabPtrP->previousFrmLen = org.size();
-
- // Set new definition
- ConstRope src(c_rope_pool, newTablePtr.p->frmData);
- char tmp[MAX_FRM_DATA_SIZE];
- src.copy(tmp);
- ndbrequire(org.assign(tmp, src.size()));
- }
-
-/*
- TODO RONM: Lite ny kod för FragmentData och RangeOrListData
-*/
- if (supportedAlteration)
- {
- // Set new schema version
- origTablePtr.p->tableVersion = newTablePtr.p->tableVersion;
- return 0;
- }
- else
- {
- jam();
- return -1;
- }
-}
-
-void Dbdict::revertAlterTable(Signal * signal,
- Uint32 changeMask,
- Uint32 tableId,
- CreateTableRecord * alterTabPtrP)
-{
- bool supportedAlteration = false;
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
-
- if (AlterTableReq::getNameFlag(changeMask)) {
- jam();
- // Table rename
- supportedAlteration = true;
- // Restore previous name
-
- Ptr<DictObject> obj_ptr;
- c_obj_pool.getPtr(obj_ptr, tablePtr.p->m_obj_ptr_i);
- c_obj_hash.remove(obj_ptr);
-
- {
- // Restore name
- Rope org(c_rope_pool, tablePtr.p->tableName);
- ndbrequire(org.assign(alterTabPtrP->previousTableName));
- }
- obj_ptr.p->m_name = tablePtr.p->tableName;
- // Put it back
- c_obj_hash.add(obj_ptr);
- }
-
- if (AlterTableReq::getFrmFlag(changeMask))
- {
- jam();
- // Table redefinition
- supportedAlteration = true;
- // Restore previous frm
- Rope org(c_rope_pool, tablePtr.p->tableName);
- ndbrequire(org.assign(alterTabPtrP->previousFrmData,
- alterTabPtrP->previousFrmLen));
-
- }
-
-
- if (supportedAlteration)
- {
- tablePtr.p->tableVersion =
- alter_obj_dec_schema_version(tablePtr.p->tableVersion);
- return;
- }
-
- ndbrequire(false);
-}
-
-void
-Dbdict::alterTab_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- Uint32 key = callbackData;
- CreateTableRecordPtr alterTabPtr;
- ndbrequire(c_opCreateTable.find(alterTabPtr, key));
- Uint32 tableId = alterTabPtr.p->m_alterTableId;
-
- Callback callback;
- callback.m_callbackData = alterTabPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::alterTab_writeTableConf);
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
- if (savetodisk)
- {
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
- writeTableFile(signal, tableId, tabInfoPtr, &callback);
- }
- else
- {
- execute(signal, callback, 0);
- }
-}
-
-void
-Dbdict::alterTab_writeTableConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- CreateTableRecordPtr alterTabPtr;
- ndbrequire(c_opCreateTable.find(alterTabPtr, callbackData));
- Uint32 coordinatorRef = alterTabPtr.p->m_coordinatorRef;
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_alterTableId);
- // Alter table commit request handled successfully
- // Inform Suma so it can send events to any subscribers of the table
- AlterTabReq * req = (AlterTabReq*)signal->getDataPtrSend();
- if (coordinatorRef == reference())
- req->senderRef = alterTabPtr.p->m_senderRef;
- else
- req->senderRef = 0;
- req->senderData = callbackData;
- req->tableId = tabPtr.p->tableId;
- req->tableVersion = tabPtr.p->tableVersion;
- req->gci = tabPtr.p->gciTableCreated;
- req->requestType = AlterTabReq::AlterTableCommit;
- req->changeMask = alterTabPtr.p->m_changeMask;
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI);
- signal->setSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
- EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength);
- releaseSections(signal);
- alterTabPtr.p->m_tabInfoPtrI = RNIL;
- jamEntry();
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = callbackData;
- conf->tableId = tabPtr.p->tableId;
- conf->tableVersion = tabPtr.p->tableVersion;
- conf->gci = tabPtr.p->gciTableCreated;
- conf->requestType = AlterTabReq::AlterTableCommit;
- conf->changeMask = alterTabPtr.p->m_changeMask;
- sendSignal(coordinatorRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
-
-
- {
- ApiBroadcastRep* api= (ApiBroadcastRep*)signal->getDataPtrSend();
- api->gsn = GSN_ALTER_TABLE_REP;
- api->minVersion = MAKE_VERSION(4,1,15);
-
- AlterTableRep* rep = (AlterTableRep*)api->theData;
- rep->tableId = tabPtr.p->tableId;
- rep->tableVersion = alter_obj_dec_schema_version(tabPtr.p->tableVersion);
- rep->changeType = AlterTableRep::CT_ALTERED;
-
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)alterTabPtr.p->previousTableName;
- ptr[0].sz = (sizeof(alterTabPtr.p->previousTableName) + 3) >> 2;
-
- sendSignal(QMGR_REF, GSN_API_BROADCAST_REP, signal,
- ApiBroadcastRep::SignalLength + AlterTableRep::SignalLength,
- JBB, ptr,1);
- }
-
- if(coordinatorRef != reference()) {
- jam();
- // Release resources
- c_tableRecordPool.getPtr(tabPtr, alterTabPtr.p->m_tablePtrI);
- releaseTableObject(tabPtr.i, false);
- releaseCreateTableOp(signal,alterTabPtr);
- c_blockState = BS_IDLE;
- }
-}
-
-void
-Dbdict::execCREATE_FRAGMENTATION_REF(Signal * signal){
- jamEntry();
- const Uint32 * theData = signal->getDataPtr();
- CreateFragmentationRef * const ref = (CreateFragmentationRef*)theData;
- (void)ref;
- ndbrequire(false);
-}
-
-void
-Dbdict::execCREATE_FRAGMENTATION_CONF(Signal* signal){
- jamEntry();
- const Uint32 * theData = signal->getDataPtr();
- CreateFragmentationConf * const conf = (CreateFragmentationConf*)theData;
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
-
- ndbrequire(signal->getNoOfSections() == 1);
-
- SegmentedSectionPtr fragDataPtr;
- signal->getSection(fragDataPtr, CreateFragmentationConf::FRAGMENTS);
- signal->header.m_noOfSections = 0;
-
- /**
- * Get table
- */
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-
- /**
- * Save fragment count
- */
- tabPtr.p->fragmentCount = conf->noOfFragments;
-
- /**
- * Update table version
- */
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tabEntry = getTableEntry(xsf, tabPtr.i);
-
- tabPtr.p->tableVersion =
- create_obj_inc_schema_version(tabEntry->m_tableVersion);
-
- /**
- * Pack
- */
- SimplePropertiesSectionWriter w(getSectionSegmentPool());
- packTableIntoPages(w, tabPtr);
-
- SegmentedSectionPtr spDataPtr;
- w.getPtr(spDataPtr);
-
- signal->setSection(spDataPtr, CreateTabReq::DICT_TAB_INFO);
- signal->setSection(fragDataPtr, CreateTabReq::FRAGMENTATION);
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
- createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
- createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTablePrepare;
- tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
-
- CreateTabReq * const req = (CreateTabReq*)theData;
- req->senderRef = reference();
- req->senderData = createTabPtr.p->key;
- req->clientRef = createTabPtr.p->m_senderRef;
- req->clientData = createTabPtr.p->m_senderData;
- req->requestType = CreateTabReq::CreateTablePrepare;
-
- req->gci = 0;
- req->tableId = tabPtr.i;
- req->tableVersion = create_obj_inc_schema_version(tabEntry->m_tableVersion);
-
- sendFragmentedSignal(rg, GSN_CREATE_TAB_REQ, signal,
- CreateTabReq::SignalLength, JBB);
-
- return;
-}
-
-void
-Dbdict::execCREATE_TAB_REF(Signal* signal){
- jamEntry();
-
- CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
-
- ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
-
- if(ref->errorCode != CreateTabRef::NF_FakeErrorREF){
- createTabPtr.p->setErrorCode(ref->errorCode);
- }
- createTab_reply(signal, createTabPtr, refToNode(ref->senderRef));
-}
-
-void
-Dbdict::execCREATE_TAB_CONF(Signal* signal){
- jamEntry();
-
- ndbrequire(signal->getNoOfSections() == 0);
-
- CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
-
- ndbrequire(createTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(createTabPtr.p->m_coordinatorData.m_gsn == GSN_CREATE_TAB_REQ);
-
- createTab_reply(signal, createTabPtr, refToNode(conf->senderRef));
-}
-
-void
-Dbdict::createTab_reply(Signal* signal,
- CreateTableRecordPtr createTabPtr,
- Uint32 nodeId)
-{
-
- SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
- if(!tmp.clearWaitingFor(nodeId)){
- jam();
- return;
- }
-
- switch(createTabPtr.p->m_coordinatorData.m_requestType){
- case CreateTabReq::CreateTablePrepare:{
-
- if(createTabPtr.p->m_errorCode != 0){
- jam();
- /**
- * Failed to prepare on atleast one node -> abort on all
- */
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
- createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableDrop;
- ndbrequire(tmp.init<CreateTabRef>(rg, createTabPtr.p->key));
-
- CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = createTabPtr.p->key;
- req->requestType = CreateTabReq::CreateTableDrop;
-
- sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
- CreateTabReq::SignalLength, JBB);
- return;
- }
-
- /**
- * Lock mutex before commiting table
- */
- Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
- Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_locked),
- createTabPtr.p->key};
-
- ndbrequire(mutex.lock(c));
- return;
- }
- case CreateTabReq::CreateTableCommit:{
- jam();
- ndbrequire(createTabPtr.p->m_errorCode == 0);
-
- /**
- * Unlock mutex before commiting table
- */
- Mutex mutex(signal, c_mutexMgr, createTabPtr.p->m_startLcpMutex);
- Callback c = { safe_cast(&Dbdict::createTab_startLcpMutex_unlocked),
- createTabPtr.p->key};
- mutex.unlock(c);
- return;
- }
- case CreateTabReq::CreateTableDrop:{
- jam();
- CreateTableRef * const ref = (CreateTableRef*)signal->getDataPtr();
- ref->senderRef = reference();
- ref->senderData = createTabPtr.p->m_senderData;
- ref->errorCode = createTabPtr.p->m_errorCode;
- ref->masterNodeId = c_masterNodeId;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = 0;
-
- //@todo check api failed
- sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_REF, signal,
- CreateTableRef::SignalLength, JBB);
- releaseCreateTableOp(signal,createTabPtr);
- c_blockState = BS_IDLE;
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::createTab_startLcpMutex_locked(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue){
- jamEntry();
-
- ndbrequire(retValue == 0);
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- createTabPtr.p->m_coordinatorData.m_gsn = GSN_CREATE_TAB_REQ;
- createTabPtr.p->m_coordinatorData.m_requestType = CreateTabReq::CreateTableCommit;
- SafeCounter tmp(c_counterMgr, createTabPtr.p->m_coordinatorData.m_counter);
- tmp.init<CreateTabRef>(rg, GSN_CREATE_TAB_REF, createTabPtr.p->key);
-
- CreateTabReq * const req = (CreateTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = createTabPtr.p->key;
- req->requestType = CreateTabReq::CreateTableCommit;
-
- sendSignal(rg, GSN_CREATE_TAB_REQ, signal,
- CreateTabReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createTab_startLcpMutex_unlocked(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue){
- jamEntry();
-
- ndbrequire(retValue == 0);
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- createTabPtr.p->m_startLcpMutex.release(c_mutexMgr);
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-
- CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createTabPtr.p->m_senderData;
- conf->tableId = createTabPtr.p->m_tablePtrI;
- conf->tableVersion = tabPtr.p->tableVersion;
-
- //@todo check api failed
- sendSignal(createTabPtr.p->m_senderRef, GSN_CREATE_TABLE_CONF, signal,
- CreateTableConf::SignalLength, JBB);
- releaseCreateTableOp(signal,createTabPtr);
- c_blockState = BS_IDLE;
- return;
-}
-
-/***********************************************************
- * CreateTable participant code
- **********************************************************/
-void
-Dbdict::execCREATE_TAB_REQ(Signal* signal){
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- CreateTabReq * const req = (CreateTabReq*)signal->getDataPtr();
-
- CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType;
- switch(rt){
- case CreateTabReq::CreateTablePrepare:
- CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId);
- createTab_prepare(signal, req);
- return;
- case CreateTabReq::CreateTableCommit:
- CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId);
- createTab_commit(signal, req);
- return;
- case CreateTabReq::CreateTableDrop:
- CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId);
- createTab_drop(signal, req);
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){
-
- const Uint32 gci = req->gci;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
-
- SegmentedSectionPtr tabInfoPtr;
- signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
-
- CreateTableRecordPtr createTabPtr;
- if(req->senderRef == reference()){
- jam();
- ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
- } else {
- jam();
- c_opCreateTable.seize(createTabPtr);
-
- ndbrequire(!createTabPtr.isNull());
-
- createTabPtr.p->key = req->senderData;
- c_opCreateTable.add(createTabPtr);
- createTabPtr.p->m_errorCode = 0;
- createTabPtr.p->m_tablePtrI = tableId;
- createTabPtr.p->m_coordinatorRef = req->senderRef;
- createTabPtr.p->m_senderRef = req->clientRef;
- createTabPtr.p->m_senderData = req->clientData;
- createTabPtr.p->m_dihAddFragPtr = RNIL;
-
- /**
- * Put data into table record
- */
- ParseDictTabInfoRecord parseRecord;
- parseRecord.requestType = DictTabInfo::AddTableFromDict;
- parseRecord.errorCode = 0;
-
- SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
-
- handleTabInfoInit(r, &parseRecord);
-
- ndbrequire(parseRecord.errorCode == 0);
- }
-
- ndbrequire(!createTabPtr.isNull());
-
- SegmentedSectionPtr fragPtr;
- signal->getSection(fragPtr, CreateTabReq::FRAGMENTATION);
-
- createTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i;
- createTabPtr.p->m_fragmentsPtrI = fragPtr.i;
-
- signal->header.m_noOfSections = 0;
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, tableId);
- tabPtr.p->packedSize = tabInfoPtr.sz;
- tabPtr.p->tableVersion = tableVersion;
- tabPtr.p->gciTableCreated = gci;
-
- SchemaFile::TableEntry tabEntry;
- tabEntry.m_tableVersion = tableVersion;
- tabEntry.m_tableType = tabPtr.p->tableType;
- tabEntry.m_tableState = SchemaFile::ADD_STARTED;
- tabEntry.m_gcp = gci;
- tabEntry.m_info_words = tabInfoPtr.sz;
- memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
-
- Callback callback;
- callback.m_callbackData = createTabPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createTab_writeSchemaConf1);
-
- bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
- updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk);
-}
-
-void getSection(SegmentedSectionPtr & ptr, Uint32 i);
-
-void
-Dbdict::createTab_writeSchemaConf1(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- Callback callback;
- callback.m_callbackData = createTabPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createTab_writeTableConf);
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
- if (savetodisk)
- {
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
- writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback);
- }
- else
- {
- execute(signal, callback, 0);
- }
-#if 0
- createTabPtr.p->m_tabInfoPtrI = RNIL;
- signal->setSection(tabInfoPtr, 0);
- releaseSections(signal);
-#endif
-}
-
-void
-Dbdict::createTab_writeTableConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- SegmentedSectionPtr fragDataPtr;
- getSection(fragDataPtr, createTabPtr.p->m_fragmentsPtrI);
-
- Callback callback;
- callback.m_callbackData = callbackData;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createTab_dihComplete);
-
- createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
-}
-
-void
-Dbdict::createTab_dih(Signal* signal,
- CreateTableRecordPtr createTabPtr,
- SegmentedSectionPtr fragDataPtr,
- Callback * c){
- jam();
-
- createTabPtr.p->m_callback = * c;
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-
- DiAddTabReq * req = (DiAddTabReq*)signal->getDataPtrSend();
- req->connectPtr = createTabPtr.p->key;
- req->tableId = tabPtr.i;
- req->fragType = tabPtr.p->fragmentType;
- req->kValue = tabPtr.p->kValue;
- req->noOfReplicas = 0;
- req->loggedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged);
- req->tableType = tabPtr.p->tableType;
- req->schemaVersion = tabPtr.p->tableVersion;
- req->primaryTableId = tabPtr.p->primaryTableId;
- req->temporaryTable = !!(tabPtr.p->m_bits & TableRecord::TR_Temporary);
-
-/*
- Behöver fiska upp fragDataPtr från table object istället
-*/
- if(!fragDataPtr.isNull()){
- signal->setSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
- }
-
- sendSignal(DBDIH_REF, GSN_DIADDTABREQ, signal,
- DiAddTabReq::SignalLength, JBB);
-
- /**
- * Create KeyDescriptor
- */
- KeyDescriptor* desc= g_key_descriptor_pool.getPtr(tabPtr.i);
- new (desc) KeyDescriptor();
-
- Uint32 key = 0;
- Ptr<AttributeRecord> attrPtr;
- LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
- tabPtr.p->m_attributes);
- for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr))
- {
- AttributeRecord* aRec = attrPtr.p;
- if (aRec->tupleKey)
- {
- Uint32 attr = aRec->attributeDescriptor;
-
- desc->noOfKeyAttr ++;
- desc->keyAttr[key].attributeDescriptor = attr;
- Uint32 csNumber = (aRec->extPrecision >> 16);
- if (csNumber)
- {
- desc->keyAttr[key].charsetInfo = all_charsets[csNumber];
- ndbrequire(all_charsets[csNumber] != 0);
- desc->hasCharAttr = 1;
- }
- else
- {
- desc->keyAttr[key].charsetInfo = 0;
- }
- if (AttributeDescriptor::getDKey(attr))
- {
- desc->noOfDistrKeys ++;
- }
- if (AttributeDescriptor::getArrayType(attr) != NDB_ARRAYTYPE_FIXED)
- {
- desc->noOfVarKeys ++;
- }
- key++;
- }
- }
- ndbrequire(key == tabPtr.p->noOfPrimkey);
-}
-
-static
-void
-calcLHbits(Uint32 * lhPageBits, Uint32 * lhDistrBits,
- Uint32 fid, Uint32 totalFragments)
-{
- Uint32 distrBits = 0;
- Uint32 pageBits = 0;
-
- Uint32 tmp = 1;
- while (tmp < totalFragments) {
- jam();
- tmp <<= 1;
- distrBits++;
- }//while
-#ifdef ndb_classical_lhdistrbits
- if (tmp != totalFragments) {
- tmp >>= 1;
- if ((fid >= (totalFragments - tmp)) && (fid < (tmp - 1))) {
- distrBits--;
- }//if
- }//if
-#endif
- * lhPageBits = pageBits;
- * lhDistrBits = distrBits;
-
-}//calcLHbits()
-
-
-void
-Dbdict::execADD_FRAGREQ(Signal* signal) {
- jamEntry();
-
- AddFragReq * const req = (AddFragReq*)signal->getDataPtr();
-
- Uint32 dihPtr = req->dihPtr;
- Uint32 senderData = req->senderData;
- Uint32 tableId = req->tableId;
- Uint32 fragId = req->fragmentId;
- Uint32 node = req->nodeId;
- Uint32 lcpNo = req->nextLCP;
- Uint32 fragCount = req->totalFragments;
- Uint32 requestInfo = req->requestInfo;
- Uint32 startGci = req->startGci;
- Uint32 logPart = req->logPartId;
-
- ndbrequire(node == getOwnNodeId());
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, senderData));
-
- createTabPtr.p->m_dihAddFragPtr = dihPtr;
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, tableId);
-
-#if 0
- tabPtr.p->gciTableCreated = (startGci > tabPtr.p->gciTableCreated ? startGci:
- startGci > tabPtr.p->gciTableCreated);
-#endif
-
- /**
- * Calc lh3PageBits
- */
- Uint32 lhDistrBits = 0;
- Uint32 lhPageBits = 0;
- ::calcLHbits(&lhPageBits, &lhDistrBits, fragId, fragCount);
-
- Uint64 maxRows = tabPtr.p->maxRowsLow +
- (((Uint64)tabPtr.p->maxRowsHigh) << 32);
- Uint64 minRows = tabPtr.p->minRowsLow +
- (((Uint64)tabPtr.p->minRowsHigh) << 32);
- maxRows = (maxRows + fragCount - 1) / fragCount;
- minRows = (minRows + fragCount - 1) / fragCount;
-
- {
- LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend();
- req->senderData = senderData;
- req->senderRef = reference();
- req->fragmentId = fragId;
- req->requestInfo = requestInfo;
- req->tableId = tableId;
- req->localKeyLength = tabPtr.p->localKeyLen;
- req->maxLoadFactor = tabPtr.p->maxLoadFactor;
- req->minLoadFactor = tabPtr.p->minLoadFactor;
- req->kValue = tabPtr.p->kValue;
- req->lh3DistrBits = 0; //lhDistrBits;
- req->lh3PageBits = 0; //lhPageBits;
- req->noOfAttributes = tabPtr.p->noOfAttributes;
- req->noOfNullAttributes = tabPtr.p->noOfNullBits;
- req->maxRowsLow = maxRows & 0xFFFFFFFF;
- req->maxRowsHigh = maxRows >> 32;
- req->minRowsLow = minRows & 0xFFFFFFFF;
- req->minRowsHigh = minRows >> 32;
- req->schemaVersion = tabPtr.p->tableVersion;
- Uint32 keyLen = tabPtr.p->tupKeyLength;
- req->keyLength = keyLen; // wl-2066 no more "long keys"
- req->nextLCP = lcpNo;
-
- req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
- req->noOfCharsets = tabPtr.p->noOfCharsets;
- req->checksumIndicator = 1;
- req->GCPIndicator = 1;
- req->startGci = startGci;
- req->tableType = tabPtr.p->tableType;
- req->primaryTableId = tabPtr.p->primaryTableId;
- req->tablespace_id= tabPtr.p->m_tablespace_id;
- req->logPartId = logPart;
- req->forceVarPartFlag = !!(tabPtr.p->m_bits& TableRecord::TR_ForceVarPart);
- sendSignal(DBLQH_REF, GSN_LQHFRAGREQ, signal,
- LqhFragReq::SignalLength, JBB);
- }
-}
-
-void
-Dbdict::execLQHFRAGREF(Signal * signal){
- jamEntry();
- LqhFragRef * const ref = (LqhFragRef*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
-
- createTabPtr.p->setErrorCode(ref->errorCode);
-
- {
- AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
- ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
- sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
- AddFragRef::SignalLength, JBB);
- }
-}
-
-void
-Dbdict::execLQHFRAGCONF(Signal * signal){
- jamEntry();
- LqhFragConf * const conf = (LqhFragConf*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
-
- createTabPtr.p->m_lqhFragPtr = conf->lqhFragPtr;
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- sendLQHADDATTRREQ(signal, createTabPtr, tabPtr.p->m_attributes.firstItem);
-}
-
-void
-Dbdict::sendLQHADDATTRREQ(Signal* signal,
- CreateTableRecordPtr createTabPtr,
- Uint32 attributePtrI){
- jam();
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtrSend();
- Uint32 i = 0;
- for(i = 0; i<LqhAddAttrReq::MAX_ATTRIBUTES && attributePtrI != RNIL; i++){
- jam();
- AttributeRecordPtr attrPtr;
- c_attributeRecordPool.getPtr(attrPtr, attributePtrI);
- LqhAddAttrReq::Entry& entry = req->attributes[i];
- entry.attrId = attrPtr.p->attributeId;
- entry.attrDescriptor = attrPtr.p->attributeDescriptor;
- entry.extTypeInfo = 0;
- // charset number passed to TUP, TUX in upper half
- entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF);
- if (tabPtr.p->isIndex()) {
- Uint32 primaryAttrId;
- if (attrPtr.p->nextList != RNIL) {
- getIndexAttr(tabPtr, attributePtrI, &primaryAttrId);
- } else {
- primaryAttrId = ZNIL;
- if (tabPtr.p->isOrderedIndex())
- entry.attrId = 0; // attribute goes to TUP
- }
- entry.attrId |= (primaryAttrId << 16);
- }
- attributePtrI = attrPtr.p->nextList;
- }
- req->lqhFragPtr = createTabPtr.p->m_lqhFragPtr;
- req->senderData = createTabPtr.p->key;
- req->senderAttrPtr = attributePtrI;
- req->noOfAttributes = i;
-
- sendSignal(DBLQH_REF, GSN_LQHADDATTREQ, signal,
- LqhAddAttrReq::HeaderLength + LqhAddAttrReq::EntryLength * i, JBB);
-}
-
-void
-Dbdict::execLQHADDATTREF(Signal * signal){
- jamEntry();
- LqhAddAttrRef * const ref = (LqhAddAttrRef*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
-
- createTabPtr.p->setErrorCode(ref->errorCode);
-
- {
- AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
- ref->dihPtr = createTabPtr.p->m_dihAddFragPtr;
- sendSignal(DBDIH_REF, GSN_ADD_FRAGREF, signal,
- AddFragRef::SignalLength, JBB);
- }
-
-}
-
-void
-Dbdict::execLQHADDATTCONF(Signal * signal){
- jamEntry();
- LqhAddAttrConf * const conf = (LqhAddAttrConf*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
-
- const Uint32 fragId = conf->fragId;
- const Uint32 nextAttrPtr = conf->senderAttrPtr;
- if(nextAttrPtr != RNIL){
- jam();
- sendLQHADDATTRREQ(signal, createTabPtr, nextAttrPtr);
- return;
- }
-
- {
- AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
- conf->dihPtr = createTabPtr.p->m_dihAddFragPtr;
- conf->fragId = fragId;
- sendSignal(DBDIH_REF, GSN_ADD_FRAGCONF, signal,
- AddFragConf::SignalLength, JBB);
- }
-}
-
-void
-Dbdict::execDIADDTABREF(Signal* signal){
- jam();
-
- DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, ref->senderData));
-
- createTabPtr.p->setErrorCode(ref->errorCode);
- execute(signal, createTabPtr.p->m_callback, 0);
-}
-
-void
-Dbdict::execDIADDTABCONF(Signal* signal){
- jam();
-
- DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, conf->senderData));
-
- signal->theData[0] = createTabPtr.p->key;
- signal->theData[1] = reference();
- signal->theData[2] = createTabPtr.p->m_tablePtrI;
-
- if(createTabPtr.p->m_dihAddFragPtr != RNIL){
- jam();
-
- /**
- * We did perform at least one LQHFRAGREQ
- */
- sendSignal(DBLQH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
- return;
- } else {
- /**
- * No local fragment (i.e. no LQHFRAGREQ)
- */
- execute(signal, createTabPtr.p->m_callback, 0);
- return;
- //sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
- }
-}
-
-void
-Dbdict::execTAB_COMMITREF(Signal* signal) {
- jamEntry();
- ndbrequire(false);
-}//execTAB_COMMITREF()
-
-void
-Dbdict::execTAB_COMMITCONF(Signal* signal){
- jamEntry();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[0]));
-
- if(refToBlock(signal->getSendersBlockRef()) == DBLQH){
-
- execute(signal, createTabPtr.p->m_callback, 0);
- return;
- }
-
- if(refToBlock(signal->getSendersBlockRef()) == DBDIH){
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-
- signal->theData[0] = tabPtr.i;
- signal->theData[1] = tabPtr.p->tableVersion;
- signal->theData[2] = (Uint32)!!(tabPtr.p->m_bits & TableRecord::TR_Logged);
- signal->theData[3] = reference();
- signal->theData[4] = (Uint32)tabPtr.p->tableType;
- signal->theData[5] = createTabPtr.p->key;
- signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey;
- signal->theData[7] = (Uint32)tabPtr.p->singleUserMode;
-
- sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 8, JBB);
- return;
- }
-
- ndbrequire(false);
-}
-
-void
-Dbdict::createTab_dihComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- //@todo check for master failed
-
- if(createTabPtr.p->m_errorCode == 0){
- jam();
-
- CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createTabPtr.p->key;
- sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
- signal, CreateTabConf::SignalLength, JBB);
- return;
- }
-
- CreateTabRef * const ref = (CreateTabRef*)signal->getDataPtr();
- ref->senderRef = reference();
- ref->senderData = createTabPtr.p->key;
- ref->errorCode = createTabPtr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->errorStatus = 0;
-
- sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_REF,
- signal, CreateTabRef::SignalLength, JBB);
-}
-
-void
-Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, req->senderData));
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary);
-
- SchemaFile::TableEntry tabEntry;
- tabEntry.m_tableVersion = tabPtr.p->tableVersion;
- tabEntry.m_tableType = tabPtr.p->tableType;
- if (savetodisk)
- tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
- else
- tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED;
-
- tabEntry.m_gcp = tabPtr.p->gciTableCreated;
- tabEntry.m_info_words = tabPtr.p->packedSize;
- memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused));
-
- Callback callback;
- callback.m_callbackData = createTabPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createTab_writeSchemaConf2);
-
- updateSchemaState(signal, tabPtr.i, &tabEntry, &callback, savetodisk);
-}
-
-void
-Dbdict::createTab_writeSchemaConf2(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- Callback c;
- c.m_callbackData = callbackData;
- c.m_callbackFunction = safe_cast(&Dbdict::createTab_alterComplete);
- alterTab_activate(signal, createTabPtr, &c);
-}
-
-void
-Dbdict::createTab_alterComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- tabPtr.p->tabState = TableRecord::DEFINED;
-
- //@todo check error
- //@todo check master failed
-
- CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createTabPtr.p->key;
- {
- CreateTabConf tmp= *conf;
- conf->senderData = createTabPtr.p->m_tablePtrI;
-#if 0
- signal->header.m_noOfSections = 1;
- SegmentedSectionPtr tabInfoPtr;
- getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI);
- signal->setSection(tabInfoPtr, 0);
-#endif
- sendSignal(SUMA_REF, GSN_CREATE_TAB_CONF, signal,
- CreateTabConf::SignalLength, JBB);
- *conf= tmp;
-#if 0
- signal->header.m_noOfSections = 0;
-#endif
- }
- sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
- signal, CreateTabConf::SignalLength, JBB);
-
- if(createTabPtr.p->m_coordinatorRef != reference()){
- jam();
- releaseCreateTableOp(signal,createTabPtr);
- }
-}
-
-void
-Dbdict::createTab_drop(Signal* signal, CreateTabReq * req){
- jam();
-
- const Uint32 key = req->senderData;
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, key));
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
- tabPtr.p->tabState = TableRecord::DROPPING;
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.seize(dropTabPtr));
-
- dropTabPtr.p->key = key;
- c_opDropTable.add(dropTabPtr);
-
- dropTabPtr.p->m_errorCode = 0;
- dropTabPtr.p->m_request.tableId = createTabPtr.p->m_tablePtrI;
- dropTabPtr.p->m_requestType = DropTabReq::CreateTabDrop;
- dropTabPtr.p->m_coordinatorRef = createTabPtr.p->m_coordinatorRef;
- dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
-
- dropTabPtr.p->m_participantData.m_block = 0;
- dropTabPtr.p->m_participantData.m_callback.m_callbackData = req->senderData;
- dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createTab_dropComplete);
- dropTab_nextStep(signal, dropTabPtr);
-
- if (tabPtr.p->m_tablespace_id != RNIL)
- {
- FilegroupPtr ptr;
- ndbrequire(c_filegroup_hash.find(ptr, tabPtr.p->m_tablespace_id));
- decrease_ref_count(ptr.p->m_obj_ptr_i);
- }
-}
-
-void
-Dbdict::createTab_dropComplete(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode){
- jam();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, callbackData));
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
-
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI);
-
- releaseTableObject(tabPtr.i);
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tabPtr.i);
- tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
-
- //@todo check error
- //@todo check master failed
-
- CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createTabPtr.p->key;
- sendSignal(createTabPtr.p->m_coordinatorRef, GSN_CREATE_TAB_CONF,
- signal, CreateTabConf::SignalLength, JBB);
-
- if(createTabPtr.p->m_coordinatorRef != reference()){
- jam();
- releaseCreateTableOp(signal,createTabPtr);
- }
-
- c_opDropTable.release(dropTabPtr);
-}
-
-void
-Dbdict::alterTab_activate(Signal* signal, CreateTableRecordPtr createTabPtr,
- Callback * c){
-
- createTabPtr.p->m_callback = * c;
-
- signal->theData[0] = createTabPtr.p->key;
- signal->theData[1] = reference();
- signal->theData[2] = createTabPtr.p->m_tablePtrI;
- sendSignal(DBDIH_REF, GSN_TAB_COMMITREQ, signal, 3, JBB);
-}
-
-void
-Dbdict::execTC_SCHVERCONF(Signal* signal){
- jamEntry();
-
- CreateTableRecordPtr createTabPtr;
- ndbrequire(c_opCreateTable.find(createTabPtr, signal->theData[1]));
-
- execute(signal, createTabPtr.p->m_callback, 0);
-}
-
-#define tabRequire(cond, error) \
- if (!(cond)) { \
- jam(); \
- parseP->errorCode = error; parseP->errorLine = __LINE__; \
- parseP->errorKey = it.getKey(); \
- return; \
- }//if
-
-// handleAddTableFailure(signal, __LINE__, allocatedTable);
-
-Dbdict::DictObject *
-Dbdict::get_object(const char * name, Uint32 len, Uint32 hash){
- DictObject key;
- key.m_key.m_name_ptr = name;
- key.m_key.m_name_len = len;
- key.m_key.m_pool = &c_rope_pool;
- key.m_name.m_hash = hash;
- Ptr<DictObject> old_ptr;
- c_obj_hash.find(old_ptr, key);
- return old_ptr.p;
-}
-
-void
-Dbdict::release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p){
- Rope name(c_rope_pool, obj_ptr_p->m_name);
- name.erase();
-
- Ptr<DictObject> ptr = { obj_ptr_p, obj_ptr_i };
- c_obj_hash.release(ptr);
-}
-
-void
-Dbdict::increase_ref_count(Uint32 obj_ptr_i)
-{
- DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
- ptr->m_ref_count++;
-}
-
-void
-Dbdict::decrease_ref_count(Uint32 obj_ptr_i)
-{
- DictObject* ptr = c_obj_pool.getPtr(obj_ptr_i);
- ndbrequire(ptr->m_ref_count);
- ptr->m_ref_count--;
-}
-
-void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it,
- ParseDictTabInfoRecord * parseP,
- bool checkExist)
-{
-/* ---------------------------------------------------------------- */
-// We always start by handling table name since this must be the first
-// item in the list. Through the table name we can derive if it is a
-// correct name, a new name or an already existing table.
-/* ---------------------------------------------------------------- */
-
- it.first();
-
- SimpleProperties::UnpackStatus status;
- c_tableDesc.init();
- status = SimpleProperties::unpack(it, &c_tableDesc,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
-
- if(status != SimpleProperties::Break){
- parseP->errorCode = CreateTableRef::InvalidFormat;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
-
- if(parseP->requestType == DictTabInfo::AlterTableFromAPI)
- {
- ndbrequire(!checkExist);
- }
- if(!checkExist)
- {
- ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI);
- }
-
- /* ---------------------------------------------------------------- */
- // Verify that table name is an allowed table name.
- // TODO
- /* ---------------------------------------------------------------- */
- const Uint32 tableNameLength = strlen(c_tableDesc.TableName) + 1;
- const Uint32 name_hash = Rope::hash(c_tableDesc.TableName, tableNameLength);
-
- if(checkExist){
- jam();
- tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0,
- CreateTableRef::TableAlreadyExist);
- }
-
- TableRecordPtr tablePtr;
- switch (parseP->requestType) {
- case DictTabInfo::CreateTableFromAPI: {
- jam();
- }
- case DictTabInfo::AlterTableFromAPI:{
- jam();
- tablePtr.i = getFreeTableRecord(c_tableDesc.PrimaryTableId);
- /* ---------------------------------------------------------------- */
- // Check if no free tables existed.
- /* ---------------------------------------------------------------- */
- tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords);
-
- c_tableRecordPool.getPtr(tablePtr);
- break;
- }
- case DictTabInfo::AddTableFromDict:
- case DictTabInfo::ReadTableFromDiskSR:
- case DictTabInfo::GetTabInfoConf:
- {
-/* ---------------------------------------------------------------- */
-// Get table id and check that table doesn't already exist
-/* ---------------------------------------------------------------- */
- tablePtr.i = c_tableDesc.TableId;
-
- if (parseP->requestType == DictTabInfo::ReadTableFromDiskSR) {
- ndbrequire(tablePtr.i == c_restartRecord.activeTable);
- }//if
- if (parseP->requestType == DictTabInfo::GetTabInfoConf) {
- ndbrequire(tablePtr.i == c_restartRecord.activeTable);
- }//if
-
- c_tableRecordPool.getPtr(tablePtr);
- ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
-
- //Uint32 oldTableVersion = tablePtr.p->tableVersion;
- initialiseTableRecord(tablePtr);
- if (parseP->requestType == DictTabInfo::AddTableFromDict) {
- jam();
- tablePtr.p->tabState = TableRecord::DEFINING;
- }//if
-
-/* ---------------------------------------------------------------- */
-// Set table version
-/* ---------------------------------------------------------------- */
- Uint32 tableVersion = c_tableDesc.TableVersion;
- tablePtr.p->tableVersion = tableVersion;
-
- break;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
- parseP->tablePtr = tablePtr;
-
- {
- Rope name(c_rope_pool, tablePtr.p->tableName);
- tabRequire(name.assign(c_tableDesc.TableName, tableNameLength, name_hash),
- CreateTableRef::OutOfStringBuffer);
- }
-
- Ptr<DictObject> obj_ptr;
- if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
- jam();
- ndbrequire(c_obj_hash.seize(obj_ptr));
- obj_ptr.p->m_id = tablePtr.i;
- obj_ptr.p->m_type = c_tableDesc.TableType;
- obj_ptr.p->m_name = tablePtr.p->tableName;
- obj_ptr.p->m_ref_count = 0;
- c_obj_hash.add(obj_ptr);
- tablePtr.p->m_obj_ptr_i = obj_ptr.i;
-
-#ifdef VM_TRACE
- ndbout_c("Dbdict: name=%s,id=%u,obj_ptr_i=%d",
- c_tableDesc.TableName, tablePtr.i, tablePtr.p->m_obj_ptr_i);
-#endif
- }
-
- // Disallow logging of a temporary table.
- tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag),
- CreateTableRef::NoLoggingTemporaryTable);
-
- tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes;
- tablePtr.p->m_bits |=
- (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0);
- tablePtr.p->m_bits |=
- (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0);
- tablePtr.p->m_bits |=
- (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0);
- tablePtr.p->m_bits |=
- (c_tableDesc.TableTemporaryFlag ? TableRecord::TR_Temporary : 0);
- tablePtr.p->m_bits |=
- (c_tableDesc.ForceVarPartFlag ? TableRecord::TR_ForceVarPart : 0);
- tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor;
- tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor;
- tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType;
- tablePtr.p->tableType = (DictTabInfo::TableType)c_tableDesc.TableType;
- tablePtr.p->kValue = c_tableDesc.TableKValue;
- tablePtr.p->fragmentCount = c_tableDesc.FragmentCount;
- tablePtr.p->m_tablespace_id = c_tableDesc.TablespaceId;
- tablePtr.p->maxRowsLow = c_tableDesc.MaxRowsLow;
- tablePtr.p->maxRowsHigh = c_tableDesc.MaxRowsHigh;
- tablePtr.p->minRowsLow = c_tableDesc.MinRowsLow;
- tablePtr.p->minRowsHigh = c_tableDesc.MinRowsHigh;
- tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag;
- tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag;
- tablePtr.p->singleUserMode = c_tableDesc.SingleUserMode;
-
- {
- Rope frm(c_rope_pool, tablePtr.p->frmData);
- tabRequire(frm.assign(c_tableDesc.FrmData, c_tableDesc.FrmLen),
- CreateTableRef::OutOfStringBuffer);
- Rope range(c_rope_pool, tablePtr.p->rangeData);
- tabRequire(range.assign(c_tableDesc.RangeListData,
- c_tableDesc.RangeListDataLen),
- CreateTableRef::OutOfStringBuffer);
- Rope fd(c_rope_pool, tablePtr.p->ngData);
- tabRequire(fd.assign((const char*)c_tableDesc.FragmentData,
- c_tableDesc.FragmentDataLen),
- CreateTableRef::OutOfStringBuffer);
- Rope ts(c_rope_pool, tablePtr.p->tsData);
- tabRequire(ts.assign((const char*)c_tableDesc.TablespaceData,
- c_tableDesc.TablespaceDataLen),
- CreateTableRef::OutOfStringBuffer);
- }
-
- c_fragDataLen = c_tableDesc.FragmentDataLen;
- memcpy(c_fragData, c_tableDesc.FragmentData,
- c_tableDesc.FragmentDataLen);
-
- if(c_tableDesc.PrimaryTableId != RNIL) {
-
- tablePtr.p->primaryTableId = c_tableDesc.PrimaryTableId;
- tablePtr.p->indexState = (TableRecord::IndexState)c_tableDesc.IndexState;
- tablePtr.p->insertTriggerId = c_tableDesc.InsertTriggerId;
- tablePtr.p->updateTriggerId = c_tableDesc.UpdateTriggerId;
- tablePtr.p->deleteTriggerId = c_tableDesc.DeleteTriggerId;
- tablePtr.p->customTriggerId = c_tableDesc.CustomTriggerId;
- } else {
- tablePtr.p->primaryTableId = RNIL;
- tablePtr.p->indexState = TableRecord::IS_UNDEFINED;
- tablePtr.p->insertTriggerId = RNIL;
- tablePtr.p->updateTriggerId = RNIL;
- tablePtr.p->deleteTriggerId = RNIL;
- tablePtr.p->customTriggerId = RNIL;
- }
- tablePtr.p->buildTriggerId = RNIL;
- tablePtr.p->indexLocal = 0;
-
- handleTabInfo(it, parseP, c_tableDesc);
-
- if(parseP->errorCode != 0)
- {
- /**
- * Release table
- */
- releaseTableObject(tablePtr.i, checkExist);
- return;
- }
-
- if (checkExist && tablePtr.p->m_tablespace_id != RNIL)
- {
- /**
- * Increase ref count
- */
- FilegroupPtr ptr;
- ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
- increase_ref_count(ptr.p->m_obj_ptr_i);
- }
-}//handleTabInfoInit()
-
-void Dbdict::handleTabInfo(SimpleProperties::Reader & it,
- ParseDictTabInfoRecord * parseP,
- DictTabInfo::Table &tableDesc)
-{
- TableRecordPtr tablePtr = parseP->tablePtr;
-
- SimpleProperties::UnpackStatus status;
-
- Uint32 keyCount = 0;
- Uint32 keyLength = 0;
- Uint32 attrCount = tablePtr.p->noOfAttributes;
- Uint32 nullCount = 0;
- Uint32 nullBits = 0;
- Uint32 noOfCharsets = 0;
- Uint16 charsets[128];
- Uint32 recordLength = 0;
- AttributeRecordPtr attrPtr;
- c_attributeRecordHash.removeAll();
-
- LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
- tablePtr.p->m_attributes);
-
- Uint32 counts[] = {0,0,0,0,0};
-
- for(Uint32 i = 0; i<attrCount; i++){
- /**
- * Attribute Name
- */
- DictTabInfo::Attribute attrDesc; attrDesc.init();
- status = SimpleProperties::unpack(it, &attrDesc,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
-
- if(status != SimpleProperties::Break){
- parseP->errorCode = CreateTableRef::InvalidFormat;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
-
- /**
- * Check that attribute is not defined twice
- */
- const size_t len = strlen(attrDesc.AttributeName)+1;
- const Uint32 name_hash = Rope::hash(attrDesc.AttributeName, len);
- {
- AttributeRecord key;
- key.m_key.m_name_ptr = attrDesc.AttributeName;
- key.m_key.m_name_len = len;
- key.attributeName.m_hash = name_hash;
- key.m_key.m_pool = &c_rope_pool;
- Ptr<AttributeRecord> old_ptr;
- c_attributeRecordHash.find(old_ptr, key);
-
- if(old_ptr.i != RNIL){
- parseP->errorCode = CreateTableRef::AttributeNameTwice;
- return;
- }
- }
-
- list.seize(attrPtr);
- if(attrPtr.i == RNIL){
- jam();
- parseP->errorCode = CreateTableRef::NoMoreAttributeRecords;
- return;
- }
-
- new (attrPtr.p) AttributeRecord();
- attrPtr.p->attributeDescriptor = 0x00012255; //Default value
- attrPtr.p->tupleKey = 0;
-
- /**
- * TmpAttrib to Attribute mapping
- */
- {
- Rope name(c_rope_pool, attrPtr.p->attributeName);
- if (!name.assign(attrDesc.AttributeName, len, name_hash))
- {
- jam();
- parseP->errorCode = CreateTableRef::OutOfStringBuffer;
- parseP->errorLine = __LINE__;
- return;
- }
- }
- attrPtr.p->attributeId = i;
- //attrPtr.p->attributeId = attrDesc.AttributeId;
- attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag;
-
- attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision;
- attrPtr.p->extScale = attrDesc.AttributeExtScale;
- attrPtr.p->extLength = attrDesc.AttributeExtLength;
- // charset in upper half of precision
- unsigned csNumber = (attrPtr.p->extPrecision >> 16);
- if (csNumber != 0) {
- /*
- * A new charset is first accessed here on this node.
- * TODO use separate thread (e.g. via NDBFS) if need to load from file
- */
- CHARSET_INFO* cs = get_charset(csNumber, MYF(0));
- if (cs == NULL) {
- parseP->errorCode = CreateTableRef::InvalidCharset;
- parseP->errorLine = __LINE__;
- return;
- }
- // XXX should be done somewhere in mysql
- all_charsets[cs->number] = cs;
- unsigned i = 0;
- while (i < noOfCharsets) {
- if (charsets[i] == csNumber)
- break;
- i++;
- }
- if (i == noOfCharsets) {
- noOfCharsets++;
- if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) {
- parseP->errorCode = CreateTableRef::InvalidFormat;
- parseP->errorLine = __LINE__;
- return;
- }
- charsets[i] = csNumber;
- }
- }
-
- // compute attribute size and array size
- bool translateOk = attrDesc.translateExtType();
- tabRequire(translateOk, CreateTableRef::Inconsistency);
-
- if(attrDesc.AttributeArraySize > 65535){
- parseP->errorCode = CreateTableRef::ArraySizeTooBig;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
-
- // XXX old test option, remove
- if(!attrDesc.AttributeKeyFlag &&
- tablePtr.i > 1 &&
- !tablePtr.p->isIndex())
- {
- //attrDesc.AttributeStorageType= NDB_STORAGETYPE_DISK;
- }
-
- Uint32 desc = 0;
- AttributeDescriptor::setType(desc, attrDesc.AttributeExtType);
- AttributeDescriptor::setSize(desc, attrDesc.AttributeSize);
- AttributeDescriptor::setArraySize(desc, attrDesc.AttributeArraySize);
- AttributeDescriptor::setArrayType(desc, attrDesc.AttributeArrayType);
- AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag);
- AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey);
- AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag);
- AttributeDescriptor::setDiskBased(desc, attrDesc.AttributeStorageType == NDB_STORAGETYPE_DISK);
- attrPtr.p->attributeDescriptor = desc;
- attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement;
- {
- Rope defaultValue(c_rope_pool, attrPtr.p->defaultValue);
- defaultValue.assign(attrDesc.AttributeDefaultValue);
- }
-
- keyCount += attrDesc.AttributeKeyFlag;
- nullCount += attrDesc.AttributeNullableFlag;
-
- const Uint32 aSz = (1 << attrDesc.AttributeSize);
- Uint32 sz;
- if(aSz != 1)
- {
- sz = ((aSz * attrDesc.AttributeArraySize) + 31) >> 5;
- }
- else
- {
- sz = 0;
- nullBits += attrDesc.AttributeArraySize;
- }
-
- if(attrDesc.AttributeArraySize == 0)
- {
- parseP->errorCode = CreateTableRef::InvalidArraySize;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
-
- recordLength += sz;
- if(attrDesc.AttributeKeyFlag){
- keyLength += sz;
-
- if(attrDesc.AttributeNullableFlag){
- parseP->errorCode = CreateTableRef::NullablePrimaryKey;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
- }
-
- c_attributeRecordHash.add(attrPtr);
-
- int a= AttributeDescriptor::getDiskBased(desc);
- int b= AttributeDescriptor::getArrayType(desc);
- Uint32 pos= 2*(a ? 1 : 0) + (b == NDB_ARRAYTYPE_FIXED ? 0 : 1);
- counts[pos+1]++;
-
- if(b != NDB_ARRAYTYPE_FIXED && sz == 0)
- {
- parseP->errorCode = CreateTableRef::VarsizeBitfieldNotSupported;
- parseP->status = status;
- parseP->errorKey = it.getKey();
- parseP->errorLine = __LINE__;
- return;
- }
-
- if(!it.next())
- break;
-
- if(it.getKey() != DictTabInfo::AttributeName)
- break;
- }//while
-
- tablePtr.p->noOfPrimkey = keyCount;
- tablePtr.p->noOfNullAttr = nullCount;
- tablePtr.p->noOfCharsets = noOfCharsets;
- tablePtr.p->tupKeyLength = keyLength;
- tablePtr.p->noOfNullBits = nullCount + nullBits;
-
- tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS,
- CreateTableRef::RecordTooBig);
- tabRequire(keyLength <= MAX_KEY_SIZE_IN_WORDS,
- CreateTableRef::InvalidPrimaryKeySize);
- tabRequire(keyLength > 0,
- CreateTableRef::InvalidPrimaryKeySize);
-
- if(tablePtr.p->m_tablespace_id != RNIL || counts[3] || counts[4])
- {
- FilegroupPtr tablespacePtr;
- if(!c_filegroup_hash.find(tablespacePtr, tablePtr.p->m_tablespace_id))
- {
- tabRequire(false, CreateTableRef::InvalidTablespace);
- }
-
- if(tablespacePtr.p->m_type != DictTabInfo::Tablespace)
- {
- tabRequire(false, CreateTableRef::NotATablespace);
- }
-
- if(tablespacePtr.p->m_version != tableDesc.TablespaceVersion)
- {
- tabRequire(false, CreateTableRef::InvalidTablespaceVersion);
- }
- }
-}//handleTabInfo()
-
-
-/* ---------------------------------------------------------------- */
-// DICTTABCONF is sent when participants have received all DICTTABINFO
-// and successfully handled it.
-// Also sent to self (DICT master) when index table creation ready.
-/* ---------------------------------------------------------------- */
-void Dbdict::execCREATE_TABLE_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
-
- CreateTableConf * const conf = (CreateTableConf *)signal->getDataPtr();
- // assume part of create index operation
- OpCreateIndexPtr opPtr;
- c_opCreateIndex.find(opPtr, conf->senderData);
- ndbrequire(! opPtr.isNull());
- opPtr.p->m_request.setIndexId(conf->tableId);
- opPtr.p->m_request.setIndexVersion(conf->tableVersion);
- createIndex_fromCreateTable(signal, opPtr);
-}//execCREATE_TABLE_CONF()
-
-void Dbdict::execCREATE_TABLE_REF(Signal* signal)
-{
- jamEntry();
-
- CreateTableRef * const ref = (CreateTableRef *)signal->getDataPtr();
- // assume part of create index operation
- OpCreateIndexPtr opPtr;
- c_opCreateIndex.find(opPtr, ref->senderData);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- createIndex_fromCreateTable(signal, opPtr);
-}//execCREATE_TABLE_REF()
-
-/* ---------------------------------------------------------------- */
-// New global checkpoint created.
-/* ---------------------------------------------------------------- */
-void Dbdict::execWAIT_GCP_CONF(Signal* signal)
-{
-#if 0
- TableRecordPtr tablePtr;
- jamEntry();
- WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
- c_tableRecordPool.getPtr(tablePtr, c_connRecord.connTableId);
- tablePtr.p->gciTableCreated = conf->gcp;
- sendUpdateSchemaState(signal,
- tablePtr.i,
- SchemaFile::TABLE_ADD_COMMITTED,
- c_connRecord.noOfPagesForTable,
- conf->gcp);
-#endif
-}//execWAIT_GCP_CONF()
-
-/* ---------------------------------------------------------------- */
-// Refused new global checkpoint.
-/* ---------------------------------------------------------------- */
-void Dbdict::execWAIT_GCP_REF(Signal* signal)
-{
- jamEntry();
- WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
-/* ---------------------------------------------------------------- */
-// Error Handling code needed
-/* ---------------------------------------------------------------- */
- char buf[32];
- BaseString::snprintf(buf, sizeof(buf), "WAIT_GCP_REF ErrorCode=%d",
- ref->errorCode);
- progError(__LINE__, NDBD_EXIT_NDBREQUIRE, buf);
-}//execWAIT_GCP_REF()
-
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: DROP TABLE -------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code used to drop a table. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-void
-Dbdict::execDROP_TABLE_REQ(Signal* signal){
- jamEntry();
- DropTableReq* req = (DropTableReq*)signal->getDataPtr();
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, req->tableId, false);
- if(tablePtr.isNull()){
- jam();
- dropTableRef(signal, req, DropTableRef::NoSuchTable);
- return;
- }
-
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- dropTableRef(signal, req, DropTableRef::NotMaster);
- return;
- }
-
- if(c_blockState == BS_NODE_RESTART){
- jam();
- dropTableRef(signal, req, DropTableRef::BusyWithNR);
- return;
- }
-
- if(c_blockState != BS_IDLE){
- jam();
- dropTableRef(signal, req, DropTableRef::Busy);
- return;
- }
-
- if (checkSingleUserMode(signal->getSendersBlockRef()))
- {
- jam();
- dropTableRef(signal, req, DropTableRef::SingleUser);
- return;
- }
-
- const TableRecord::TabState tabState = tablePtr.p->tabState;
- bool ok = false;
- switch(tabState){
- case TableRecord::NOT_DEFINED:
- case TableRecord::DEFINING:
- jam();
- dropTableRef(signal, req, DropTableRef::NoSuchTable);
- return;
- case TableRecord::DEFINED:
- ok = true;
- jam();
- break;
- case TableRecord::PREPARE_DROPPING:
- case TableRecord::DROPPING:
- jam();
- dropTableRef(signal, req, DropTableRef::DropInProgress);
- return;
- case TableRecord::BACKUP_ONGOING:
- jam();
- dropTableRef(signal, req, DropTableRef::BackupInProgress);
- return;
- }
- ndbrequire(ok);
-
- if(tablePtr.p->tableVersion != req->tableVersion){
- jam();
- dropTableRef(signal, req, DropTableRef::InvalidTableVersion);
- return;
- }
-
- /**
- * Seems ok
- */
- DropTableRecordPtr dropTabPtr;
- c_opDropTable.seize(dropTabPtr);
-
- if(dropTabPtr.isNull()){
- jam();
- dropTableRef(signal, req, DropTableRef::NoDropTableRecordAvailable);
- return;
- }
-
- c_blockState = BS_BUSY;
-
- dropTabPtr.p->key = ++c_opRecordSequence;
- c_opDropTable.add(dropTabPtr);
-
- dropTabPtr.p->m_request = * req;
- dropTabPtr.p->m_errorCode = 0;
- dropTabPtr.p->m_requestType = DropTabReq::OnlineDropTab;
- dropTabPtr.p->m_coordinatorRef = reference();
- dropTabPtr.p->m_coordinatorData.m_gsn = GSN_PREP_DROP_TAB_REQ;
- dropTabPtr.p->m_coordinatorData.m_block = 0;
-
- Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
- Callback c = { safe_cast(&Dbdict::dropTable_backup_mutex_locked),
- dropTabPtr.p->key};
-
- ndbrequire(mutex.lock(c));
-
-}
-
-void
-Dbdict::dropTable_backup_mutex_locked(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue){
- jamEntry();
-
- ndbrequire(retValue == 0);
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, callbackData));
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId, true);
-
- Mutex mutex(signal, c_mutexMgr, dropTabPtr.p->m_define_backup_mutex);
- mutex.unlock(); // ignore response
-
- if(tablePtr.p->tabState == TableRecord::BACKUP_ONGOING)
- {
- jam();
- dropTableRef(signal, &dropTabPtr.p->m_request,
- DropTableRef::BackupInProgress);
-
- c_blockState = BS_IDLE;
- c_opDropTable.release(dropTabPtr);
- }
- else
- {
- jam();
- tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
- prepDropTab_nextStep(signal, dropTabPtr);
- }
-}
-
-void
-Dbdict::dropTableRef(Signal * signal,
- DropTableReq * req, DropTableRef::ErrorCode errCode){
-
- Uint32 tableId = req->tableId;
- Uint32 tabVersion = req->tableVersion;
- Uint32 senderData = req->senderData;
- Uint32 senderRef = req->senderRef;
-
- DropTableRef * ref = (DropTableRef*)signal->getDataPtrSend();
- ref->tableId = tableId;
- ref->tableVersion = tabVersion;
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = errCode;
- ref->masterNodeId = c_masterNodeId;
- sendSignal(senderRef, GSN_DROP_TABLE_REF, signal,
- DropTableRef::SignalLength, JBB);
-}
-
-void
-Dbdict::prepDropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
-
- /**
- * No errors currently allowed
- */
- ndbrequire(dropTabPtr.p->m_errorCode == 0);
-
- Uint32 block = 0;
- switch(dropTabPtr.p->m_coordinatorData.m_block){
- case 0:
- jam();
- block = dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
- break;
- case DBDICT:
- jam();
- block = dropTabPtr.p->m_coordinatorData.m_block = DBLQH;
- break;
- case DBLQH:
- jam();
- block = dropTabPtr.p->m_coordinatorData.m_block = DBTC;
- break;
- case DBTC:
- jam();
- block = dropTabPtr.p->m_coordinatorData.m_block = DBDIH;
- break;
- case DBDIH:
- jam();
- prepDropTab_complete(signal, dropTabPtr);
- return;
- default:
- ndbrequire(false);
- }
-
- PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
- prep->senderRef = reference();
- prep->senderData = dropTabPtr.p->key;
- prep->tableId = dropTabPtr.p->m_request.tableId;
- prep->requestType = dropTabPtr.p->m_requestType;
-
- dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(block, c_aliveNodes);
- sendSignal(rg, GSN_PREP_DROP_TAB_REQ, signal,
- PrepDropTabReq::SignalLength, JBB);
-
-#if 0
- for (Uint32 i = 1; i < MAX_NDB_NODES; i++){
- if(c_aliveNodes.get(i)){
- jam();
- BlockReference ref = numberToRef(block, i);
-
- dropTabPtr.p->m_coordinatorData.m_signalCounter.setWaitingFor(i);
- }
- }
-#endif
-}
-
-void
-Dbdict::execPREP_DROP_TAB_CONF(Signal * signal){
- jamEntry();
-
- PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
-
- ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
- ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
-
- Uint32 nodeId = refToNode(prep->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
- if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
- jam();
- return;
- }
- prepDropTab_nextStep(signal, dropTabPtr);
-}
-
-void
-Dbdict::execPREP_DROP_TAB_REF(Signal* signal){
- jamEntry();
-
- PrepDropTabRef * prep = (PrepDropTabRef*)signal->getDataPtr();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
-
- ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(dropTabPtr.p->m_request.tableId == prep->tableId);
- ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_PREP_DROP_TAB_REQ);
-
- Uint32 nodeId = refToNode(prep->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
- 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;
- }
- prepDropTab_nextStep(signal, dropTabPtr);
-}
-
-void
-Dbdict::prepDropTab_complete(Signal* signal, DropTableRecordPtr dropTabPtr){
- jam();
-
- dropTabPtr.p->m_coordinatorData.m_gsn = GSN_DROP_TAB_REQ;
- dropTabPtr.p->m_coordinatorData.m_block = DBDICT;
-
- DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = dropTabPtr.p->key;
- req->tableId = dropTabPtr.p->m_request.tableId;
- req->requestType = dropTabPtr.p->m_requestType;
-
- dropTabPtr.p->m_coordinatorData.m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_DROP_TAB_REQ, signal,
- DropTabReq::SignalLength, JBB);
-}
-
-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);
-}
-
-void
-Dbdict::execDROP_TAB_CONF(Signal* signal){
- jamEntry();
-
- DropTabConf * const req = (DropTabConf*)signal->getDataPtr();
-
- if(refToBlock(req->senderRef) != DBDICT){
- jam();
- ndbrequire(refToNode(req->senderRef) == getOwnNodeId());
- dropTab_localDROP_TAB_CONF(signal);
- return;
- }
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
-
- ndbrequire(dropTabPtr.p->m_coordinatorRef == reference());
- ndbrequire(dropTabPtr.p->m_request.tableId == req->tableId);
- ndbrequire(dropTabPtr.p->m_coordinatorData.m_gsn == GSN_DROP_TAB_REQ);
-
- Uint32 nodeId = refToNode(req->senderRef);
- dropTabPtr.p->m_coordinatorData.m_signalCounter.clearWaitingFor(nodeId);
-
- if(!dropTabPtr.p->m_coordinatorData.m_signalCounter.done()){
- jam();
- return;
- }
-
- DropTableConf* conf = (DropTableConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = dropTabPtr.p->m_request.senderData;
- conf->tableId = dropTabPtr.p->m_request.tableId;
- conf->tableVersion = dropTabPtr.p->m_request.tableVersion;
- Uint32 ref = dropTabPtr.p->m_request.senderRef;
- sendSignal(ref, GSN_DROP_TABLE_CONF, signal,
- DropTableConf::SignalLength, JBB);
-
- c_opDropTable.release(dropTabPtr);
- c_blockState = BS_IDLE;
-}
-
-/**
- * DROP TABLE PARTICIPANT CODE
- */
-void
-Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){
- jamEntry();
- PrepDropTabReq * prep = (PrepDropTabReq*)signal->getDataPtrSend();
-
- DropTableRecordPtr dropTabPtr;
- if(prep->senderRef == reference()){
- jam();
- ndbrequire(c_opDropTable.find(dropTabPtr, prep->senderData));
- ndbrequire(dropTabPtr.p->m_requestType == prep->requestType);
- } else {
- jam();
- c_opDropTable.seize(dropTabPtr);
- if(!dropTabPtr.isNull()){
- dropTabPtr.p->key = prep->senderData;
- c_opDropTable.add(dropTabPtr);
- }
- }
-
- ndbrequire(!dropTabPtr.isNull());
-
- dropTabPtr.p->m_errorCode = 0;
- dropTabPtr.p->m_request.tableId = prep->tableId;
- dropTabPtr.p->m_requestType = prep->requestType;
- dropTabPtr.p->m_coordinatorRef = prep->senderRef;
- dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_REQ;
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, prep->tableId);
- tablePtr.p->tabState = TableRecord::PREPARE_DROPPING;
-
- /**
- * Modify schema
- */
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tablePtr.i);
- SchemaFile::TableState tabState =
- (SchemaFile::TableState)tableEntry->m_tableState;
- ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED ||
- tabState == SchemaFile::ALTER_TABLE_COMMITTED ||
- tabState == SchemaFile::TEMPORARY_TABLE_COMMITTED);
- tableEntry->m_tableState = SchemaFile::DROP_TABLE_STARTED;
- computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES);
-
- bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
- Callback callback;
- callback.m_callbackData = dropTabPtr.p->key;
- callback.m_callbackFunction = safe_cast(&Dbdict::prepDropTab_writeSchemaConf);
- if (savetodisk)
- {
- ndbrequire(c_writeSchemaRecord.inUse == false);
- c_writeSchemaRecord.inUse = true;
-
- c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
- c_writeSchemaRecord.newFile = false;
- c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES;
- c_writeSchemaRecord.noOfPages = 1;
- c_writeSchemaRecord.m_callback = callback;
- startWriteSchemaFile(signal);
- }
- else
- {
- execute(signal, callback, 0);
- }
-}
-
-void
-Dbdict::prepDropTab_writeSchemaConf(Signal* signal,
- Uint32 dropTabPtrI,
- Uint32 returnCode){
- jam();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
-
- ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_REQ);
-
- /**
- * There probably should be node fail handlign here
- *
- * To check that coordinator hasn't died
- */
-
- PrepDropTabConf * prep = (PrepDropTabConf*)signal->getDataPtr();
- prep->senderRef = reference();
- prep->senderData = dropTabPtrI;
- prep->tableId = dropTabPtr.p->m_request.tableId;
-
- dropTabPtr.p->m_participantData.m_gsn = GSN_PREP_DROP_TAB_CONF;
- sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_PREP_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
-}
-
-void
-Dbdict::execDROP_TAB_REQ(Signal* signal){
- jamEntry();
- DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, req->senderData));
-
- ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_PREP_DROP_TAB_CONF);
- dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_REQ;
-
- ndbrequire(dropTabPtr.p->m_requestType == req->requestType);
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
- tablePtr.p->tabState = TableRecord::DROPPING;
-
- dropTabPtr.p->m_participantData.m_block = 0;
- dropTabPtr.p->m_participantData.m_callback.m_callbackData = dropTabPtr.p->key;
- dropTabPtr.p->m_participantData.m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropTab_complete);
- dropTab_nextStep(signal, dropTabPtr);
-
- if (tablePtr.p->m_tablespace_id != RNIL)
- {
- FilegroupPtr ptr;
- ndbrequire(c_filegroup_hash.find(ptr, tablePtr.p->m_tablespace_id));
- decrease_ref_count(ptr.p->m_obj_ptr_i);
- }
-}
-
-#include <DebuggerNames.hpp>
-
-void
-Dbdict::dropTab_nextStep(Signal* signal, DropTableRecordPtr dropTabPtr){
-
- /**
- * No errors currently allowed
- */
- ndbrequire(dropTabPtr.p->m_errorCode == 0);
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, dropTabPtr.p->m_request.tableId);
-
- Uint32 block = 0;
- switch(dropTabPtr.p->m_participantData.m_block){
- case 0:
- jam();
- block = DBTC;
- break;
- case DBTC:
- jam();
- if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
- block = DBACC;
- if (tablePtr.p->isOrderedIndex())
- block = DBTUP;
- break;
- case DBACC:
- jam();
- block = DBTUP;
- break;
- case DBTUP:
- jam();
- if (tablePtr.p->isTable() || tablePtr.p->isHashIndex())
- block = DBLQH;
- if (tablePtr.p->isOrderedIndex())
- block = DBTUX;
- break;
- case DBTUX:
- jam();
- block = DBLQH;
- break;
- case DBLQH:
- jam();
- block = DBDIH;
- break;
- case DBDIH:
- jam();
- execute(signal, dropTabPtr.p->m_participantData.m_callback, 0);
- return;
- }
- ndbrequire(block != 0);
- dropTabPtr.p->m_participantData.m_block = block;
-
- DropTabReq * req = (DropTabReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = dropTabPtr.p->key;
- req->tableId = dropTabPtr.p->m_request.tableId;
- req->requestType = dropTabPtr.p->m_requestType;
-
- const Uint32 nodeId = getOwnNodeId();
- dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor();
- dropTabPtr.p->m_participantData.m_signalCounter.setWaitingFor(nodeId);
- BlockReference ref = numberToRef(block, 0);
- sendSignal(ref, GSN_DROP_TAB_REQ, signal, DropTabReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropTab_localDROP_TAB_CONF(Signal* signal){
- jamEntry();
-
- DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, conf->senderData));
-
- ndbrequire(dropTabPtr.p->m_request.tableId == conf->tableId);
- ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
-
- Uint32 nodeId = refToNode(conf->senderRef);
- dropTabPtr.p->m_participantData.m_signalCounter.clearWaitingFor(nodeId);
-
- if(!dropTabPtr.p->m_participantData.m_signalCounter.done()){
- jam();
- ndbrequire(false);
- return;
- }
- dropTab_nextStep(signal, dropTabPtr);
-}
-
-void
-Dbdict::dropTab_complete(Signal* signal,
- Uint32 dropTabPtrI,
- Uint32 returnCode){
- jam();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
-
- Uint32 tableId = dropTabPtr.p->m_request.tableId;
-
- /**
- * Write to schema file
- */
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId);
- SchemaFile::TableState tabState =
- (SchemaFile::TableState)tableEntry->m_tableState;
- ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED);
- tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
- computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES);
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary);
- Callback callback;
- callback.m_callbackData = dropTabPtr.p->key;
- callback.m_callbackFunction = safe_cast(&Dbdict::dropTab_writeSchemaConf);
- if (savetodisk)
- {
- ndbrequire(c_writeSchemaRecord.inUse == false);
- c_writeSchemaRecord.inUse = true;
-
- c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage;
- c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES;
- c_writeSchemaRecord.noOfPages = 1;
- c_writeSchemaRecord.m_callback = callback;
- startWriteSchemaFile(signal);
- }
- else
- {
- execute(signal, callback, 0);
- }
-}
-
-void
-Dbdict::dropTab_writeSchemaConf(Signal* signal,
- Uint32 dropTabPtrI,
- Uint32 returnCode){
- jam();
-
- DropTableRecordPtr dropTabPtr;
- ndbrequire(c_opDropTable.find(dropTabPtr, dropTabPtrI));
-
- ndbrequire(dropTabPtr.p->m_participantData.m_gsn == GSN_DROP_TAB_REQ);
-
- dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
-
- releaseTableObject(dropTabPtr.p->m_request.tableId);
-
- DropTabConf * conf = (DropTabConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = dropTabPtrI;
- conf->tableId = dropTabPtr.p->m_request.tableId;
- {
- DropTabConf tmp= *conf;
- if (dropTabPtr.p->m_coordinatorRef == reference())
- conf->senderRef = dropTabPtr.p->m_request.senderRef;
- else
- conf->senderRef = 0;
- EXECUTE_DIRECT(SUMA, GSN_DROP_TAB_CONF, signal,
- DropTabConf::SignalLength);
- jamEntry();
- *conf= tmp;
- }
- dropTabPtr.p->m_participantData.m_gsn = GSN_DROP_TAB_CONF;
- sendSignal(dropTabPtr.p->m_coordinatorRef, GSN_DROP_TAB_CONF, signal,
- DropTabConf::SignalLength, JBB);
-
- if(dropTabPtr.p->m_coordinatorRef != reference()){
- c_opDropTable.release(dropTabPtr);
- }
-}
-
-void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash)
-{
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- if (removeFromHash)
- {
- jam();
- release_object(tablePtr.p->m_obj_ptr_i);
- }
- else
- {
- Rope tmp(c_rope_pool, tablePtr.p->tableName);
- tmp.erase();
- }
-
- {
- Rope tmp(c_rope_pool, tablePtr.p->frmData);
- tmp.erase();
- }
-
- {
- Rope tmp(c_rope_pool, tablePtr.p->tsData);
- tmp.erase();
- }
-
- {
- Rope tmp(c_rope_pool, tablePtr.p->ngData);
- tmp.erase();
- }
-
- {
- Rope tmp(c_rope_pool, tablePtr.p->rangeData);
- tmp.erase();
- }
-
- tablePtr.p->tabState = TableRecord::NOT_DEFINED;
-
- LocalDLFifoList<AttributeRecord> list(c_attributeRecordPool,
- tablePtr.p->m_attributes);
- AttributeRecordPtr attrPtr;
- for(list.first(attrPtr); !attrPtr.isNull(); list.next(attrPtr)){
- Rope name(c_rope_pool, attrPtr.p->attributeName);
- Rope def(c_rope_pool, attrPtr.p->defaultValue);
- name.erase();
- def.erase();
- }
- list.release();
-}//releaseTableObject()
-
-/**
- * DICT receives these on index create and drop.
- */
-void Dbdict::execDROP_TABLE_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
-
- DropTableConf * const conf = (DropTableConf *)signal->getDataPtr();
- // assume part of drop index operation
- OpDropIndexPtr opPtr;
- c_opDropIndex.find(opPtr, conf->senderData);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_request.getIndexId() == conf->tableId);
- ndbrequire(opPtr.p->m_request.getIndexVersion() == conf->tableVersion);
- dropIndex_fromDropTable(signal, opPtr);
-}
-
-void Dbdict::execDROP_TABLE_REF(Signal* signal)
-{
- jamEntry();
-
- DropTableRef * const ref = (DropTableRef *)signal->getDataPtr();
- // assume part of drop index operation
- OpDropIndexPtr opPtr;
- c_opDropIndex.find(opPtr, ref->senderData);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- opPtr.p->m_errorLine = __LINE__;
- dropIndex_fromDropTable(signal, opPtr);
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: EXTERNAL INTERFACE TO DATA -------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* This module contains the code that is used by other modules to. */
-/* access the data within DBDICT. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-void Dbdict::execGET_TABLEDID_REQ(Signal * signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 1);
- GetTableIdReq const * req = (GetTableIdReq *)signal->getDataPtr();
- Uint32 senderData = req->senderData;
- Uint32 senderRef = req->senderRef;
- Uint32 len = req->len;
-
- if(len>MAX_TAB_NAME_SIZE)
- {
- jam();
- sendGET_TABLEID_REF((Signal*)signal,
- (GetTableIdReq *)req,
- GetTableIdRef::TableNameTooLong);
- return;
- }
-
- char tableName[MAX_TAB_NAME_SIZE];
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr,GetTableIdReq::TABLE_NAME);
- copy((Uint32*)tableName, ssPtr);
- releaseSections(signal);
-
- DictObject * obj_ptr_p = get_object(tableName, len);
- if(obj_ptr_p == 0 || !DictTabInfo::isTable(obj_ptr_p->m_type)){
- jam();
- sendGET_TABLEID_REF(signal,
- (GetTableIdReq *)req,
- GetTableIdRef::TableNotDefined);
- return;
- }
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id);
-
- GetTableIdConf * conf = (GetTableIdConf *)req;
- conf->tableId = tablePtr.p->tableId;
- conf->schemaVersion = tablePtr.p->tableVersion;
- conf->senderData = senderData;
- sendSignal(senderRef, GSN_GET_TABLEID_CONF, signal,
- GetTableIdConf::SignalLength, JBB);
-}
-
-
-void Dbdict::sendGET_TABLEID_REF(Signal* signal,
- GetTableIdReq * req,
- GetTableIdRef::ErrorCode errorCode)
-{
- GetTableIdRef * const ref = (GetTableIdRef *)req;
- /**
- * The format of GetTabInfo Req/Ref is the same
- */
- BlockReference retRef = req->senderRef;
- ref->err = errorCode;
- sendSignal(retRef, GSN_GET_TABLEID_REF, signal,
- GetTableIdRef::SignalLength, JBB);
-}//sendGET_TABINFOREF()
-
-/* ---------------------------------------------------------------- */
-// Get a full table description.
-/* ---------------------------------------------------------------- */
-void Dbdict::execGET_TABINFOREQ(Signal* signal)
-{
- jamEntry();
- if(!assembleFragments(signal))
- {
- return;
- }
-
- GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
-
- /**
- * If I get a GET_TABINFO_REQ from myself
- * it's is a one from the time queue
- */
- bool fromTimeQueue = (signal->senderBlockRef() == reference());
-
- if (c_retrieveRecord.busyState && fromTimeQueue == true) {
- jam();
-
- sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
- signal->length());
- return;
- }//if
-
- const Uint32 MAX_WAITERS = 5;
-
- if(c_retrieveRecord.busyState && fromTimeQueue == false){
- jam();
- if(c_retrieveRecord.noOfWaiters < MAX_WAITERS){
- jam();
- c_retrieveRecord.noOfWaiters++;
-
- sendSignalWithDelay(reference(), GSN_GET_TABINFOREQ, signal, 30,
- signal->length());
- return;
- }
-
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::Busy);
- return;
- }
-
- if(fromTimeQueue){
- jam();
- c_retrieveRecord.noOfWaiters--;
- }
-
- const bool useLongSig = (req->requestType & GetTabInfoReq::LongSignalConf);
- const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
-
- Uint32 obj_id = RNIL;
- if(reqType == GetTabInfoReq::RequestByName){
- jam();
- ndbrequire(signal->getNoOfSections() == 1);
- const Uint32 len = req->tableNameLen;
-
- if(len > MAX_TAB_NAME_SIZE){
- jam();
- releaseSections(signal);
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNameTooLong);
- return;
- }
-
- char tableName[MAX_TAB_NAME_SIZE];
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
- r0.reset(); // undo implicit first()
- if(!r0.getWords((Uint32*)tableName, (len+3)/4)){
- jam();
- releaseSections(signal);
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
- return;
- }
- releaseSections(signal);
-
- DictObject * old_ptr_p = get_object(tableName, len);
- if(old_ptr_p)
- obj_id = old_ptr_p->m_id;
- } else {
- jam();
- obj_id = req->tableId;
- }
-
- SchemaFile::TableEntry *objEntry = 0;
- if(obj_id != RNIL){
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- objEntry = getTableEntry(xsf, obj_id);
- }
-
- // The table seached for was not found
- if(objEntry == 0){
- jam();
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
- return;
- }//if
-
- // If istable/index, allow ADD_STARTED (not to ref)
-
- if (objEntry->m_tableState != SchemaFile::TABLE_ADD_COMMITTED &&
- objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED &&
- objEntry->m_tableState != SchemaFile::TEMPORARY_TABLE_COMMITTED){
- jam();
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
- return;
- }//if
-
- if (DictTabInfo::isTable(objEntry->m_tableType) ||
- DictTabInfo::isIndex(objEntry->m_tableType))
- {
- jam();
- TableRecordPtr tabPtr;
- c_tableRecordPool.getPtr(tabPtr, obj_id);
- if (tabPtr.p->tabState != TableRecord::DEFINED &&
- tabPtr.p->tabState != TableRecord::BACKUP_ONGOING)
- {
- jam();
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined);
- return;
- }
- ndbrequire(objEntry->m_tableState == SchemaFile::TEMPORARY_TABLE_COMMITTED ||
- !(tabPtr.p->m_bits & TableRecord::TR_Temporary));
- }
-
- c_retrieveRecord.busyState = true;
- c_retrieveRecord.blockRef = req->senderRef;
- c_retrieveRecord.m_senderData = req->senderData;
- c_retrieveRecord.tableId = obj_id;
- c_retrieveRecord.currentSent = 0;
- c_retrieveRecord.m_useLongSig = useLongSig;
- c_retrieveRecord.m_table_type = objEntry->m_tableType;
- c_packTable.m_state = PackTable::PTS_GET_TAB;
-
- if(objEntry->m_tableType==DictTabInfo::Datafile)
- {
- jam();
- GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
- req->senderData= c_retrieveRecord.retrievePage;
- req->senderRef= reference();
- req->requestType= GetTabInfoReq::RequestById;
- req->tableId= obj_id;
-
- sendSignal(TSMAN_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- }
- else if(objEntry->m_tableType==DictTabInfo::LogfileGroup)
- {
- jam();
- GetTabInfoReq *req= (GetTabInfoReq*)signal->getDataPtrSend();
- req->senderData= c_retrieveRecord.retrievePage;
- req->senderRef= reference();
- req->requestType= GetTabInfoReq::RequestById;
- req->tableId= obj_id;
-
- sendSignal(LGMAN_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- }
- else
- {
- jam();
- signal->theData[0] = ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = obj_id;
- signal->theData[2] = objEntry->m_tableType;
- signal->theData[3] = c_retrieveRecord.retrievePage;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- }
- jam();
-}//execGET_TABINFOREQ()
-
-void Dbdict::sendGetTabResponse(Signal* signal)
-{
- PageRecordPtr pagePtr;
- DictTabInfo * const conf = (DictTabInfo *)&signal->theData[0];
- conf->senderRef = reference();
- conf->senderData = c_retrieveRecord.m_senderData;
- conf->requestType = DictTabInfo::GetTabInfoConf;
- conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
-
- c_pageRecordArray.getPtr(pagePtr, c_retrieveRecord.retrievePage);
- Uint32* pagePointer = (Uint32*)&pagePtr.p->word[0] + ZPAGE_HEADER_SIZE;
-
- if(c_retrieveRecord.m_useLongSig){
- jam();
- GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
- conf->gci = 0;
- conf->tableId = c_retrieveRecord.tableId;
- conf->senderData = c_retrieveRecord.m_senderData;
- conf->totalLen = c_retrieveRecord.retrievedNoOfWords;
- conf->tableType = c_retrieveRecord.m_table_type;
-
- Callback c = { safe_cast(&Dbdict::initRetrieveRecord), 0 };
- LinearSectionPtr ptr[3];
- ptr[0].p = pagePointer;
- ptr[0].sz = c_retrieveRecord.retrievedNoOfWords;
- sendFragmentedSignal(c_retrieveRecord.blockRef,
- GSN_GET_TABINFO_CONF,
- signal,
- GetTabInfoConf::SignalLength,
- JBB,
- ptr,
- 1,
- c);
- return;
- }
-
- ndbrequire(false);
-}//sendGetTabResponse()
-
-void Dbdict::sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq * req,
- GetTabInfoRef::ErrorCode errorCode)
-{
- jamEntry();
- GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
- /**
- * The format of GetTabInfo Req/Ref is the same
- */
- BlockReference retRef = req->senderRef;
- ref->errorCode = errorCode;
-
- sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
-}//sendGET_TABINFOREF()
-
-void
-Dbdict::execLIST_TABLES_REQ(Signal* signal)
-{
- jamEntry();
- ListTablesReq * req = (ListTablesReq*)signal->getDataPtr();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- // save req flags
- const Uint32 reqTableId = req->getTableId();
- const Uint32 reqTableType = req->getTableType();
- const bool reqListNames = req->getListNames();
- const bool reqListIndexes = req->getListIndexes();
- // init the confs
- ListTablesConf * conf = (ListTablesConf *)signal->getDataPtrSend();
- conf->senderData = senderData;
- conf->counter = 0;
- Uint32 pos = 0;
-
- DLHashTable<DictObject>::Iterator iter;
- bool ok = c_obj_hash.first(iter);
- for(; ok; ok = c_obj_hash.next(iter)){
- Uint32 type = iter.curr.p->m_type;
- if ((reqTableType != (Uint32)0) && (reqTableType != type))
- continue;
-
- if (reqListIndexes && !DictTabInfo::isIndex(type))
- continue;
-
- TableRecordPtr tablePtr;
- if (DictTabInfo::isTable(type) || DictTabInfo::isIndex(type)){
- c_tableRecordPool.getPtr(tablePtr, iter.curr.p->m_id);
-
- if(reqListIndexes && (reqTableId != tablePtr.p->primaryTableId))
- continue;
-
- conf->tableData[pos] = 0;
- conf->setTableId(pos, tablePtr.i); // id
- conf->setTableType(pos, type); // type
- // state
-
- if(DictTabInfo::isTable(type)){
- switch (tablePtr.p->tabState) {
- case TableRecord::DEFINING:
- conf->setTableState(pos, DictTabInfo::StateBuilding);
- break;
- case TableRecord::PREPARE_DROPPING:
- case TableRecord::DROPPING:
- conf->setTableState(pos, DictTabInfo::StateDropping);
- break;
- case TableRecord::DEFINED:
- conf->setTableState(pos, DictTabInfo::StateOnline);
- break;
- case TableRecord::BACKUP_ONGOING:
- conf->setTableState(pos, DictTabInfo::StateBackup);
- break;
- default:
- conf->setTableState(pos, DictTabInfo::StateBroken);
- break;
- }
- }
- if (tablePtr.p->isIndex()) {
- switch (tablePtr.p->indexState) {
- case TableRecord::IS_OFFLINE:
- conf->setTableState(pos, DictTabInfo::StateOffline);
- break;
- case TableRecord::IS_BUILDING:
- conf->setTableState(pos, DictTabInfo::StateBuilding);
- break;
- case TableRecord::IS_DROPPING:
- conf->setTableState(pos, DictTabInfo::StateDropping);
- break;
- case TableRecord::IS_ONLINE:
- conf->setTableState(pos, DictTabInfo::StateOnline);
- break;
- default:
- conf->setTableState(pos, DictTabInfo::StateBroken);
- break;
- }
- }
- // Logging status
- if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) {
- conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
- } else {
- conf->setTableStore(pos, DictTabInfo::StorePermanent);
- }
- // Temporary status
- if (tablePtr.p->m_bits & TableRecord::TR_Temporary) {
- conf->setTableTemp(pos, NDB_TEMP_TAB_TEMPORARY);
- } else {
- conf->setTableTemp(pos, NDB_TEMP_TAB_PERMANENT);
- }
- pos++;
- }
- if(DictTabInfo::isTrigger(type)){
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, iter.curr.p->m_id);
-
- conf->tableData[pos] = 0;
- conf->setTableId(pos, triggerPtr.i);
- conf->setTableType(pos, type);
- switch (triggerPtr.p->triggerState) {
- case TriggerRecord::TS_OFFLINE:
- conf->setTableState(pos, DictTabInfo::StateOffline);
- break;
- case TriggerRecord::TS_ONLINE:
- conf->setTableState(pos, DictTabInfo::StateOnline);
- break;
- default:
- conf->setTableState(pos, DictTabInfo::StateBroken);
- break;
- }
- conf->setTableStore(pos, DictTabInfo::StoreNotLogged);
- pos++;
- }
- if (DictTabInfo::isFilegroup(type)){
- jam();
- conf->tableData[pos] = 0;
- conf->setTableId(pos, iter.curr.p->m_id);
- conf->setTableType(pos, type); // type
- conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
- pos++;
- }
- if (DictTabInfo::isFile(type)){
- jam();
- conf->tableData[pos] = 0;
- conf->setTableId(pos, iter.curr.p->m_id);
- conf->setTableType(pos, type); // type
- conf->setTableState(pos, DictTabInfo::StateOnline); // XXX todo
- pos++;
- }
-
- if (pos >= ListTablesConf::DataLength) {
- sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
- ListTablesConf::SignalLength, JBB);
- conf->counter++;
- pos = 0;
- }
-
- if (! reqListNames)
- continue;
-
- Rope name(c_rope_pool, iter.curr.p->m_name);
- const Uint32 size = name.size();
- conf->tableData[pos] = size;
- pos++;
- if (pos >= ListTablesConf::DataLength) {
- sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
- ListTablesConf::SignalLength, JBB);
- conf->counter++;
- pos = 0;
- }
- Uint32 i = 0;
- char tmp[MAX_TAB_NAME_SIZE];
- name.copy(tmp);
- while (i < size) {
- char* p = (char*)&conf->tableData[pos];
- for (Uint32 j = 0; j < 4; j++) {
- if (i < size)
- *p++ = tmp[i++];
- else
- *p++ = 0;
- }
- pos++;
- if (pos >= ListTablesConf::DataLength) {
- sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
- ListTablesConf::SignalLength, JBB);
- conf->counter++;
- pos = 0;
- }
- }
- }
- // last signal must have less than max length
- sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
- ListTablesConf::HeaderLength + pos, JBB);
-}
-
-/**
- * MODULE: Create index
- *
- * Create index in DICT via create table operation. Then invoke alter
- * index opearation to online the index.
- *
- * Request type in CREATE_INDX signals:
- *
- * RT_USER - from API to DICT master
- * RT_DICT_PREPARE - prepare participants
- * RT_DICT_COMMIT - commit participants
- * RT_TC - create index in TC (part of alter index operation)
- */
-
-void
-Dbdict::execCREATE_INDX_REQ(Signal* signal)
-{
- jamEntry();
- CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
- OpCreateIndexPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const CreateIndxReq::RequestType requestType = req->getRequestType();
- if (requestType == CreateIndxReq::RT_USER) {
- jam();
- if (! assembleFragments(signal)) {
- jam();
- return;
- }
- if (signal->getLength() == CreateIndxReq::SignalLength) {
- jam();
- CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError;
- if (getOwnNodeId() != c_masterNodeId) {
- jam();
- tmperr = CreateIndxRef::NotMaster;
- } else if (c_blockState == BS_NODE_RESTART) {
- jam();
- tmperr = CreateIndxRef::BusyWithNR;
- } else if (c_blockState != BS_IDLE) {
- jam();
- tmperr = CreateIndxRef::Busy;
- }
- else if (checkSingleUserMode(senderRef))
- {
- jam();
- tmperr = CreateIndxRef::SingleUser;
- }
- if (tmperr != CreateIndxRef::NoError) {
- releaseSections(signal);
- OpCreateIndex opBusy;
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = 0;
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
- opPtr.p->m_errorCode = tmperr;
- opPtr.p->m_errorLine = __LINE__;
- opPtr.p->m_errorNode = c_masterNodeId;
- createIndex_sendReply(signal, opPtr, true);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_CREATE_INDX_REQ,
- signal, CreateIndxReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == CreateIndxReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpCreateIndex opBusy;
- if (! c_opCreateIndex.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opCreateIndex.add(opPtr);
- // save attribute list
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
- r0.reset(); // undo implicit first()
- if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
- ! r0.getWords(opPtr.p->m_attrList.id, opPtr.p->m_attrList.sz)) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- // save name and index table properties
- signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
- SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
- c_tableDesc.init();
- SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
- r1, &c_tableDesc,
- DictTabInfo::TableMapping, DictTabInfo::TableMappingSize,
- true, true);
- if (status != SimpleProperties::Eof) {
- opPtr.p->m_errorCode = CreateIndxRef::InvalidName;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE);
- opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag;
- opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag;
- releaseSections(signal);
- // master expects to hear from all
- if (opPtr.p->m_isMaster)
- opPtr.p->m_signalCounter = c_aliveNodes;
- createIndex_slavePrepare(signal, opPtr);
- createIndex_sendReply(signal, opPtr, false);
- return;
- }
- c_opCreateIndex.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
- requestType == CreateIndxReq::RT_DICT_ABORT) {
- jam();
- if (requestType == CreateIndxReq::RT_DICT_COMMIT) {
- opPtr.p->m_request.setIndexId(req->getIndexId());
- opPtr.p->m_request.setIndexVersion(req->getIndexVersion());
- createIndex_slaveCommit(signal, opPtr);
- } else {
- createIndex_slaveAbort(signal, opPtr);
- }
- createIndex_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opCreateIndex.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- releaseSections(signal);
- OpCreateIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- createIndex_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execCREATE_INDX_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
- CreateIndxConf* conf = (CreateIndxConf*)signal->getDataPtrSend();
- createIndex_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execCREATE_INDX_REF(Signal* signal)
-{
- jamEntry();
- CreateIndxRef* ref = (CreateIndxRef*)signal->getDataPtrSend();
- createIndex_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::createIndex_recvReply(Signal* signal, const CreateIndxConf* conf,
- const CreateIndxRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const CreateIndxReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == CreateIndxReq::RT_TC) {
- jam();
- // part of alter index operation
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterIndex_fromCreateTc(signal, opPtr);
- return;
- }
- OpCreateIndexPtr opPtr;
- c_opCreateIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == CreateIndxReq::RT_DICT_COMMIT ||
- requestType == CreateIndxReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- createIndex_sendReply(signal, opPtr, true);
- c_opCreateIndex.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
- createIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == CreateIndxReq::RT_DICT_PREPARE) {
- jam();
- // start index table create
- createIndex_toCreateTable(signal, opPtr);
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
- createIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- if (ERROR_INSERTED(6006) && ! opPtr.p->m_isMaster) {
- ndbrequire(false);
- }
-}
-
-void
-Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
-{
- union {
- char tableName[MAX_TAB_NAME_SIZE];
- char attributeName[MAX_ATTR_NAME_SIZE];
- };
- Uint32 k;
- Uint32 attrid_map[MAX_ATTRIBUTES_IN_INDEX];
-
- jam();
- const CreateIndxReq* const req = &opPtr.p->m_request;
- // signal data writer
- Uint32* wbuffer = &c_indexPage.word[0];
- LinearWriter w(wbuffer, sizeof(c_indexPage) >> 2);
- w.first();
- // get table being indexed
- if (! (req->getTableId() < c_tableRecordPool.getSize())) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, req->getTableId());
- if (tablePtr.p->tabState != TableRecord::DEFINED &&
- tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- if (! tablePtr.p->isTable()) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidPrimaryTable;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
-
- // Check that the temporary status of index is compatible with table.
- if (!opPtr.p->m_temporaryIndex &&
- tablePtr.p->m_bits & TableRecord::TR_Temporary)
- {
- jam();
- opPtr.p->m_errorCode= CreateIndxRef::TableIsTemporary;
- opPtr.p->m_errorLine= __LINE__;
- return;
- }
- if (opPtr.p->m_temporaryIndex &&
- !(tablePtr.p->m_bits & TableRecord::TR_Temporary))
- {
- // This could be implemented later, but mysqld does currently not detect
- // that the index disappears after SR, and it appears not too useful.
- jam();
- opPtr.p->m_errorCode= CreateIndxRef::TableIsNotTemporary;
- opPtr.p->m_errorLine= __LINE__;
- return;
- }
- if (opPtr.p->m_temporaryIndex && opPtr.p->m_loggedIndex)
- {
- jam();
- opPtr.p->m_errorCode= CreateIndxRef::NoLoggingTemporaryIndex;
- opPtr.p->m_errorLine= __LINE__;
- return;
- }
-
- // compute index table record
- TableRecord indexRec;
- TableRecordPtr indexPtr;
- indexPtr.i = RNIL; // invalid
- indexPtr.p = &indexRec;
- initialiseTableRecord(indexPtr);
- indexPtr.p->m_bits = TableRecord::TR_RowChecksum;
- if (req->getIndexType() == DictTabInfo::UniqueHashIndex) {
- indexPtr.p->m_bits |= (opPtr.p->m_loggedIndex ? TableRecord::TR_Logged:0);
- indexPtr.p->m_bits |=
- (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
- indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex;
- } else if (req->getIndexType() == DictTabInfo::OrderedIndex) {
- // first version will not supported logging
- if (opPtr.p->m_loggedIndex) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- indexPtr.p->m_bits |=
- (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0);
- indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex;
- } else {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- indexPtr.p->tableType = (DictTabInfo::TableType)req->getIndexType();
- indexPtr.p->primaryTableId = req->getTableId();
- indexPtr.p->noOfAttributes = opPtr.p->m_attrList.sz;
- indexPtr.p->tupKeyLength = 0;
- if (indexPtr.p->noOfAttributes == 0) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
-
- if (indexPtr.p->isOrderedIndex()) {
- // tree node size in words (make configurable later)
- indexPtr.p->tupKeyLength = MAX_TTREE_NODE_SIZE;
- }
-
- AttributeMask mask;
- mask.clear();
- for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
- jam();
- unsigned current_id= opPtr.p->m_attrList.id[k];
- Uint32 tAttr = tablePtr.p->m_attributes.firstItem;
- AttributeRecord* aRec = NULL;
- for (; tAttr != RNIL; )
- {
- aRec = c_attributeRecordPool.getPtr(tAttr);
- if (aRec->attributeId != current_id)
- {
- tAttr= aRec->nextList;
- continue;
- }
- jam();
- break;
- }
- if (tAttr == RNIL) {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- if (mask.get(current_id))
- {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::DuplicateAttributes;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- const Uint32 a = aRec->attributeDescriptor;
-
- if (AttributeDescriptor::getDiskBased(a))
- {
- jam();
- opPtr.p->m_errorCode = CreateIndxRef::IndexOnDiskAttributeError;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
-
- mask.set(current_id);
- unsigned kk= k;
- if (indexPtr.p->isHashIndex()) {
- const Uint32 s1 = AttributeDescriptor::getSize(a);
- const Uint32 s2 = AttributeDescriptor::getArraySize(a);
- indexPtr.p->tupKeyLength += ((1 << s1) * s2 + 31) >> 5;
-
- for (; kk > 0 && current_id < attrid_map[kk-1]>>16; kk--)
- attrid_map[kk]= attrid_map[kk-1];
- }
- attrid_map[kk]= k | (current_id << 16);
- }
-
- indexPtr.p->noOfPrimkey = indexPtr.p->noOfAttributes;
- // plus concatenated primary table key attribute
- indexPtr.p->noOfAttributes += 1;
- indexPtr.p->noOfNullAttr = 0;
- // write index table
- w.add(DictTabInfo::TableName, opPtr.p->m_indexName);
- w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged));
- w.add(DictTabInfo::TableTemporaryFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Temporary));
- w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType);
- w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType);
- Rope name(c_rope_pool, tablePtr.p->tableName);
- name.copy(tableName);
- w.add(DictTabInfo::PrimaryTable, tableName);
- w.add(DictTabInfo::PrimaryTableId, tablePtr.i);
- w.add(DictTabInfo::NoOfAttributes, indexPtr.p->noOfAttributes);
- w.add(DictTabInfo::NoOfKeyAttr, indexPtr.p->noOfPrimkey);
- w.add(DictTabInfo::NoOfNullable, indexPtr.p->noOfNullAttr);
- w.add(DictTabInfo::KeyLength, indexPtr.p->tupKeyLength);
- w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
- // write index key attributes
- for (k = 0; k < opPtr.p->m_attrList.sz; k++) {
- // insert the attributes in the order decided above in attrid_map
- // k is new order, current_id is in previous order
- // ToDo: make sure "current_id" is stored with the table and
- // passed up to NdbDictionary
- unsigned current_id= opPtr.p->m_attrList.id[attrid_map[k] & 0xffff];
- jam();
- for (Uint32 tAttr = tablePtr.p->m_attributes.firstItem; tAttr != RNIL; ) {
- AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr);
- tAttr = aRec->nextList;
- if (aRec->attributeId != current_id)
- continue;
- jam();
- const Uint32 a = aRec->attributeDescriptor;
- bool isNullable = AttributeDescriptor::getNullable(a);
- Uint32 arrayType = AttributeDescriptor::getArrayType(a);
- Rope attrName(c_rope_pool, aRec->attributeName);
- attrName.copy(attributeName);
- w.add(DictTabInfo::AttributeName, attributeName);
- Uint32 attrType = AttributeDescriptor::getType(a);
- // computed
- w.add(DictTabInfo::AttributeId, k);
- if (indexPtr.p->isHashIndex()) {
- w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
- w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
- }
- if (indexPtr.p->isOrderedIndex()) {
- w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
- w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable);
- }
- w.add(DictTabInfo::AttributeArrayType, arrayType);
- w.add(DictTabInfo::AttributeExtType, attrType);
- w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision);
- w.add(DictTabInfo::AttributeExtScale, aRec->extScale);
- w.add(DictTabInfo::AttributeExtLength, aRec->extLength);
- w.add(DictTabInfo::AttributeEnd, (Uint32)true);
- }
- }
- if (indexPtr.p->isHashIndex()) {
- jam();
-
- Uint32 key_type = NDB_ARRAYTYPE_FIXED;
- AttributeRecordPtr attrPtr;
- LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
- tablePtr.p->m_attributes);
- for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr))
- {
- const Uint32 desc = attrPtr.p->attributeDescriptor;
- if (AttributeDescriptor::getPrimaryKey(desc) &&
- AttributeDescriptor::getArrayType(desc) != NDB_ARRAYTYPE_FIXED)
- {
- key_type = NDB_ARRAYTYPE_MEDIUM_VAR;
- break;
- }
- }
-
- // write concatenated primary table key attribute i.e. keyinfo
- w.add(DictTabInfo::AttributeName, "NDB$PK");
- w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
- w.add(DictTabInfo::AttributeArrayType, key_type);
- w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false);
- w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
- w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
- w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength+1);
- w.add(DictTabInfo::AttributeEnd, (Uint32)true);
- }
- if (indexPtr.p->isOrderedIndex()) {
- jam();
- // write index tree node as Uint32 array attribute
- w.add(DictTabInfo::AttributeName, "NDB$TNODE");
- w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz);
- // should not matter but VAR crashes in TUP
- w.add(DictTabInfo::AttributeArrayType, (Uint32)NDB_ARRAYTYPE_FIXED);
- w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true);
- w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false);
- w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned);
- w.add(DictTabInfo::AttributeExtLength, indexPtr.p->tupKeyLength);
- w.add(DictTabInfo::AttributeEnd, (Uint32)true);
- }
- // finish
- w.add(DictTabInfo::TableEnd, (Uint32)true);
- // remember to...
- releaseSections(signal);
- // send create index table request
- CreateTableReq * const cre = (CreateTableReq*)signal->getDataPtrSend();
- cre->senderRef = reference();
- cre->senderData = opPtr.p->key;
- LinearSectionPtr lsPtr[3];
- lsPtr[0].p = wbuffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ,
- signal, CreateTableReq::SignalLength, JBB, lsPtr, 1);
-}
-
-void
-Dbdict::createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
- createIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- if (! opPtr.p->m_request.getOnline()) {
- jam();
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
- createIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- createIndex_toAlterIndex(signal, opPtr);
-}
-
-void
-Dbdict::createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(AlterIndxReq::RT_CREATE_INDEX);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setIndexId(opPtr.p->m_request.getIndexId());
- req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
- req->setOnline(true);
- sendSignal(reference(), GSN_ALTER_INDX_REQ,
- signal, AlterIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_ABORT;
- createIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = CreateIndxReq::RT_DICT_COMMIT;
- createIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- const Uint32 indexId = opPtr.p->m_request.getIndexId();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, indexId);
- if (! opPtr.p->m_request.getOnline()) {
- ndbrequire(indexPtr.p->indexState == TableRecord::IS_UNDEFINED);
- indexPtr.p->indexState = TableRecord::IS_OFFLINE;
- } else {
- ndbrequire(indexPtr.p->indexState == TableRecord::IS_ONLINE);
- }
-}
-
-void
-Dbdict::createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- CreateIndxReq* const req = &opPtr.p->m_request;
- const Uint32 indexId = req->getIndexId();
- if (indexId >= c_tableRecordPool.getSize()) {
- jam();
- return;
- }
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, indexId);
- if (! indexPtr.p->isIndex()) {
- jam();
- return;
- }
- indexPtr.p->indexState = TableRecord::IS_BROKEN;
-}
-
-void
-Dbdict::createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr)
-{
- jam();
- CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- opPtr.p->m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_CREATE_INDX_REQ,
- signal, CreateIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr,
- bool toUser)
-{
- CreateIndxRef* rep = (CreateIndxRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_CREATE_INDX_CONF;
- Uint32 length = CreateIndxConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == CreateIndxReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = CreateIndxConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0)
- opPtr.p->m_errorNode = getOwnNodeId();
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_CREATE_INDX_REF;
- length = CreateIndxRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Drop index.
- *
- * Drop index. First alters the index offline (i.e. drops metadata in
- * other blocks) and then drops the index table.
- */
-
-void
-Dbdict::execDROP_INDX_REQ(Signal* signal)
-{
- jamEntry();
- DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
- OpDropIndexPtr opPtr;
-
- int err = DropIndxRef::BadRequestType;
- const Uint32 senderRef = signal->senderBlockRef();
- const DropIndxReq::RequestType requestType = req->getRequestType();
- if (requestType == DropIndxReq::RT_USER) {
- jam();
- if (signal->getLength() == DropIndxReq::SignalLength) {
- jam();
- DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError;
- if (getOwnNodeId() != c_masterNodeId) {
- jam();
- tmperr = DropIndxRef::NotMaster;
- } else if (c_blockState == BS_NODE_RESTART) {
- jam();
- tmperr = DropIndxRef::BusyWithNR;
- } else if (c_blockState != BS_IDLE) {
- jam();
- tmperr = DropIndxRef::Busy;
- }
- else if (checkSingleUserMode(senderRef))
- {
- jam();
- tmperr = DropIndxRef::SingleUser;
- }
- if (tmperr != DropIndxRef::NoError) {
- err = tmperr;
- goto error;
- }
- // forward initial request plus operation key to all
- Uint32 indexId= req->getIndexId();
- Uint32 indexVersion= req->getIndexVersion();
-
- if(indexId >= c_tableRecordPool.getSize())
- {
- err = DropIndxRef::IndexNotFound;
- goto error;
- }
-
- TableRecordPtr tmp;
- c_tableRecordPool.getPtr(tmp, indexId);
- if(tmp.p->tabState == TableRecord::NOT_DEFINED ||
- tmp.p->tableVersion != indexVersion)
- {
- err = DropIndxRef::InvalidIndexVersion;
- goto error;
- }
-
- if (! tmp.p->isIndex()) {
- jam();
- err = DropIndxRef::NotAnIndex;
- goto error;
- }
-
- if (tmp.p->indexState != TableRecord::IS_ONLINE)
- req->addRequestFlag(RequestFlag::RF_FORCE);
-
- tmp.p->indexState = TableRecord::IS_DROPPING;
-
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_DROP_INDX_REQ,
- signal, DropIndxReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == DropIndxReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpDropIndex opBusy;
- if (! c_opDropIndex.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = DropIndxReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = DropIndxRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- dropIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opDropIndex.add(opPtr);
- // master expects to hear from all
- if (opPtr.p->m_isMaster)
- opPtr.p->m_signalCounter = c_aliveNodes;
- dropIndex_slavePrepare(signal, opPtr);
- dropIndex_sendReply(signal, opPtr, false);
- return;
- }
- c_opDropIndex.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == DropIndxReq::RT_DICT_COMMIT ||
- requestType == DropIndxReq::RT_DICT_ABORT) {
- jam();
- if (requestType == DropIndxReq::RT_DICT_COMMIT)
- dropIndex_slaveCommit(signal, opPtr);
- else
- dropIndex_slaveAbort(signal, opPtr);
- dropIndex_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opDropIndex.release(opPtr);
- return;
- }
- }
-error:
- jam();
- // return to sender
- OpDropIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = (DropIndxRef::ErrorCode)err;
- opPtr.p->m_errorLine = __LINE__;
- opPtr.p->m_errorNode = c_masterNodeId;
- dropIndex_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execDROP_INDX_CONF(Signal* signal)
-{
- jamEntry();
- DropIndxConf* conf = (DropIndxConf*)signal->getDataPtrSend();
- dropIndex_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execDROP_INDX_REF(Signal* signal)
-{
- jamEntry();
- DropIndxRef* ref = (DropIndxRef*)signal->getDataPtrSend();
- dropIndex_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::dropIndex_recvReply(Signal* signal, const DropIndxConf* conf,
- const DropIndxRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const DropIndxReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == DropIndxReq::RT_TC) {
- jam();
- // part of alter index operation
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterIndex_fromDropTc(signal, opPtr);
- return;
- }
- OpDropIndexPtr opPtr;
- c_opDropIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == DropIndxReq::RT_DICT_COMMIT ||
- requestType == DropIndxReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- dropIndex_sendReply(signal, opPtr, true);
- c_opDropIndex.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
- dropIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == DropIndxReq::RT_DICT_PREPARE) {
- jam();
- // start alter offline
- dropIndex_toAlterIndex(signal, opPtr);
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- DropIndxReq* const req = &opPtr.p->m_request;
- // check index exists
- TableRecordPtr indexPtr;
- if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
- jam();
- opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
- if (indexPtr.p->tabState != TableRecord::DEFINED) {
- jam();
- opPtr.p->m_errorCode = DropIndxRef::IndexNotFound;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- if (! indexPtr.p->isIndex()) {
- jam();
- opPtr.p->m_errorCode = DropIndxRef::NotAnIndex;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- // ignore incoming primary table id
- req->setTableId(indexPtr.p->primaryTableId);
-}
-
-void
-Dbdict::dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(AlterIndxReq::RT_DROP_INDEX);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setIndexId(opPtr.p->m_request.getIndexId());
- req->setIndexVersion(opPtr.p->m_request.getIndexVersion());
- req->setOnline(false);
- sendSignal(reference(), GSN_ALTER_INDX_REQ,
- signal, AlterIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
- dropIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- dropIndex_toDropTable(signal, opPtr);
-}
-
-void
-Dbdict::dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- DropTableReq* const req = (DropTableReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = opPtr.p->key;
- req->tableId = opPtr.p->m_request.getIndexId();
- req->tableVersion = opPtr.p->m_request.getIndexVersion();
- sendSignal(reference(), GSN_DROP_TABLE_REQ,
- signal,DropTableReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = DropIndxReq::RT_DICT_ABORT;
- dropIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = DropIndxReq::RT_DICT_COMMIT;
- dropIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
-}
-
-void
-Dbdict::dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr)
-{
- jam();
- DropIndxReq* const req = &opPtr.p->m_request;
- const Uint32 indexId = req->getIndexId();
- if (indexId >= c_tableRecordPool.getSize()) {
- jam();
- return;
- }
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, indexId);
- indexPtr.p->indexState = TableRecord::IS_BROKEN;
-}
-
-void
-Dbdict::dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr)
-{
- DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- opPtr.p->m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_DROP_INDX_REQ,
- signal, DropIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr,
- bool toUser)
-{
- DropIndxRef* rep = (DropIndxRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_DROP_INDX_CONF;
- Uint32 length = DropIndxConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == DropIndxReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = DropIndxConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- rep->setIndexVersion(opPtr.p->m_request.getIndexVersion());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0)
- opPtr.p->m_errorNode = getOwnNodeId();
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_DROP_INDX_REF;
- length = DropIndxRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/*****************************************************
- *
- * Util signalling
- *
- *****************************************************/
-
-int
-Dbdict::sendSignalUtilReq(Callback *pcallback,
- BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections)
-{
- jam();
- EVENT_TRACE;
- OpSignalUtilPtr utilRecPtr;
-
- // Seize a Util Send record
- if (!c_opSignalUtil.seize(utilRecPtr)) {
- // Failed to allocate util record
- return -1;
- }
- utilRecPtr.p->m_callback = *pcallback;
-
- // should work for all util signal classes
- UtilPrepareReq *req = (UtilPrepareReq*)signal->getDataPtrSend();
- utilRecPtr.p->m_userData = req->getSenderData();
- req->setSenderData(utilRecPtr.i);
-
- if (ptr) {
- jam();
- sendSignal(ref, gsn, signal, length, jbuf, ptr, noOfSections);
- } else {
- jam();
- sendSignal(ref, gsn, signal, length, jbuf);
- }
-
- return 0;
-}
-
-int
-Dbdict::recvSignalUtilReq(Signal* signal, Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- UtilPrepareConf * const req = (UtilPrepareConf*)signal->getDataPtr();
- OpSignalUtilPtr utilRecPtr;
- utilRecPtr.i = req->getSenderData();
- if ((utilRecPtr.p = c_opSignalUtil.getPtr(utilRecPtr.i)) == NULL) {
- jam();
- return -1;
- }
-
- req->setSenderData(utilRecPtr.p->m_userData);
- Callback c = utilRecPtr.p->m_callback;
- c_opSignalUtil.release(utilRecPtr);
-
- execute(signal, c, returnCode);
- return 0;
-}
-
-void Dbdict::execUTIL_PREPARE_CONF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
- ndbrequire(recvSignalUtilReq(signal, 0) == 0);
-}
-
-void
-Dbdict::execUTIL_PREPARE_REF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
- ndbrequire(recvSignalUtilReq(signal, 1) == 0);
-}
-
-void Dbdict::execUTIL_EXECUTE_CONF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
- ndbrequire(recvSignalUtilReq(signal, 0) == 0);
-}
-
-void Dbdict::execUTIL_EXECUTE_REF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
-
-#ifdef EVENT_DEBUG
- UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
-
- ndbout_c("execUTIL_EXECUTE_REF");
- ndbout_c("senderData %u",ref->getSenderData());
- ndbout_c("errorCode %u",ref->getErrorCode());
- ndbout_c("TCErrorCode %u",ref->getTCErrorCode());
-#endif
-
- ndbrequire(recvSignalUtilReq(signal, 1) == 0);
-}
-void Dbdict::execUTIL_RELEASE_CONF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
- ndbrequire(false);
- ndbrequire(recvSignalUtilReq(signal, 0) == 0);
-}
-void Dbdict::execUTIL_RELEASE_REF(Signal *signal)
-{
- jamEntry();
- EVENT_TRACE;
- ndbrequire(false);
- ndbrequire(recvSignalUtilReq(signal, 1) == 0);
-}
-
-/**
- * MODULE: Create event
- *
- * Create event in DICT.
- *
- *
- * Request type in CREATE_EVNT signals:
- *
- * Signalflow see Dbdict.txt
- *
- */
-
-/*****************************************************************
- *
- * Systable stuff
- *
- */
-
-const Uint32 Dbdict::sysTab_NDBEVENTS_0_szs[EVENT_SYSTEM_TABLE_LENGTH] = {
- sizeof(((sysTab_NDBEVENTS_0*)0)->NAME),
- sizeof(((sysTab_NDBEVENTS_0*)0)->EVENT_TYPE),
- sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEID),
- sizeof(((sysTab_NDBEVENTS_0*)0)->TABLEVERSION),
- sizeof(((sysTab_NDBEVENTS_0*)0)->TABLE_NAME),
- sizeof(((sysTab_NDBEVENTS_0*)0)->ATTRIBUTE_MASK),
- sizeof(((sysTab_NDBEVENTS_0*)0)->SUBID),
- sizeof(((sysTab_NDBEVENTS_0*)0)->SUBKEY)
-};
-
-void
-Dbdict::prepareTransactionEventSysTable (Callback *pcallback,
- Signal* signal,
- Uint32 senderData,
- UtilPrepareReq::OperationTypeValue prepReq)
-{
- // find table id for event system table
- DictObject * opj_ptr_p = get_object(EVENT_SYSTEM_TABLE_NAME,
- sizeof(EVENT_SYSTEM_TABLE_NAME));
-
- ndbrequire(opj_ptr_p != 0);
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, opj_ptr_p->m_id);
- ndbrequire(tablePtr.i != RNIL); // system table must exist
-
- Uint32 tableId = tablePtr.p->tableId; /* System table */
- Uint32 noAttr = tablePtr.p->noOfAttributes;
- ndbrequire(noAttr == EVENT_SYSTEM_TABLE_LENGTH);
-
- switch (prepReq) {
- case UtilPrepareReq::Update:
- case UtilPrepareReq::Insert:
- case UtilPrepareReq::Write:
- case UtilPrepareReq::Read:
- jam();
- break;
- case UtilPrepareReq::Delete:
- jam();
- noAttr = 1; // only involves Primary key which should be the first
- break;
- }
- prepareUtilTransaction(pcallback, signal, senderData, tableId, NULL,
- prepReq, noAttr, NULL, NULL);
-}
-
-void
-Dbdict::prepareUtilTransaction(Callback *pcallback,
- Signal* signal,
- Uint32 senderData,
- Uint32 tableId,
- const char* tableName,
- UtilPrepareReq::OperationTypeValue prepReq,
- Uint32 noAttr,
- Uint32 attrIds[],
- const char *attrNames[])
-{
- jam();
- EVENT_TRACE;
-
- UtilPrepareReq * utilPrepareReq =
- (UtilPrepareReq *)signal->getDataPtrSend();
-
- utilPrepareReq->setSenderRef(reference());
- utilPrepareReq->setSenderData(senderData);
-
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, prepReq);
- if (tableName) {
- jam();
- w.add(UtilPrepareReq::TableName, tableName);
- } else {
- jam();
- w.add(UtilPrepareReq::TableId, tableId);
- }
- for(Uint32 i = 0; i < noAttr; i++)
- if (tableName) {
- jam();
- w.add(UtilPrepareReq::AttributeName, attrNames[i]);
- } else {
- if (attrIds) {
- jam();
- w.add(UtilPrepareReq::AttributeId, attrIds[i]);
- } else {
- jam();
- w.add(UtilPrepareReq::AttributeId, i);
- }
- }
-#ifdef EVENT_DEBUG
- // Debugging
- SimplePropertiesLinearReader reader(propPage, w.getWordsUsed());
- printf("Dict::prepareInsertTransactions: Sent SimpleProperties:\n");
- reader.printAll(ndbout);
-#endif
-
- struct LinearSectionPtr sectionsPtr[UtilPrepareReq::NoOfSections];
- sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].p = propPage;
- sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].sz = w.getWordsUsed();
-
- sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_PREPARE_REQ, signal,
- UtilPrepareReq::SignalLength, JBB,
- sectionsPtr, UtilPrepareReq::NoOfSections);
-}
-
-/*****************************************************************
- *
- * CREATE_EVNT_REQ has three types RT_CREATE, RT_GET (from user)
- * and RT_DICT_AFTER_GET send from master DICT to slaves
- *
- * This function just dscpaches these to
- *
- * createEvent_RT_USER_CREATE
- * createEvent_RT_USER_GET
- * createEvent_RT_DICT_AFTER_GET
- *
- * repectively
- *
- */
-
-void
-Dbdict::execCREATE_EVNT_REQ(Signal* signal)
-{
- jamEntry();
-
-#if 0
- {
- SafeCounterHandle handle;
- {
- SafeCounter tmp(c_counterMgr, handle);
- tmp.init<CreateEvntRef>(CMVMI, GSN_DUMP_STATE_ORD, /* senderData */ 13);
- tmp.clearWaitingFor();
- tmp.setWaitingFor(3);
- ndbrequire(!tmp.done());
- ndbout_c("Allocted");
- }
- ndbrequire(!handle.done());
- {
- SafeCounter tmp(c_counterMgr, handle);
- tmp.clearWaitingFor(3);
- ndbrequire(tmp.done());
- ndbout_c("Deallocted");
- }
- ndbrequire(handle.done());
- }
- {
- NodeBitmask nodes;
- nodes.clear();
-
- nodes.set(2);
- nodes.set(3);
- nodes.set(4);
- nodes.set(5);
-
- {
- Uint32 i = 0;
- while((i = nodes.find(i)) != NodeBitmask::NotFound){
- ndbout_c("1 Node id = %u", i);
- i++;
- }
- }
-
- NodeReceiverGroup rg(DBDICT, nodes);
- RequestTracker rt2;
- ndbrequire(rt2.done());
- ndbrequire(!rt2.hasRef());
- ndbrequire(!rt2.hasConf());
- rt2.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
-
- RequestTracker rt3;
- rt3.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF, 13);
-
- ndbrequire(!rt2.done());
- ndbrequire(!rt3.done());
-
- rt2.reportRef(c_counterMgr, 2);
- rt3.reportConf(c_counterMgr, 2);
-
- ndbrequire(!rt2.done());
- ndbrequire(!rt3.done());
-
- rt2.reportConf(c_counterMgr, 3);
- rt3.reportConf(c_counterMgr, 3);
-
- ndbrequire(!rt2.done());
- ndbrequire(!rt3.done());
-
- rt2.reportConf(c_counterMgr, 4);
- rt3.reportConf(c_counterMgr, 4);
-
- ndbrequire(!rt2.done());
- ndbrequire(!rt3.done());
-
- rt2.reportConf(c_counterMgr, 5);
- rt3.reportConf(c_counterMgr, 5);
-
- ndbrequire(rt2.done());
- ndbrequire(rt3.done());
- }
-#endif
-
- if (! assembleFragments(signal)) {
- jam();
- return;
- }
-
- CreateEvntReq *req = (CreateEvntReq*)signal->getDataPtr();
- const CreateEvntReq::RequestType requestType = req->getRequestType();
- const Uint32 requestFlag = req->getRequestFlag();
-
- if (refToBlock(signal->senderBlockRef()) != DBDICT &&
- getOwnNodeId() != c_masterNodeId)
- {
- jam();
- releaseSections(signal);
-
- CreateEvntRef * ref = (CreateEvntRef *)signal->getDataPtrSend();
- ref->setUserRef(reference());
- ref->setErrorCode(CreateEvntRef::NotMaster);
- ref->setErrorLine(__LINE__);
- ref->setErrorNode(reference());
- ref->setMasterNode(c_masterNodeId);
- sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
- CreateEvntRef::SignalLength2, JBB);
- return;
- }
-
- OpCreateEventPtr evntRecPtr;
- // Seize a Create Event record
- if (!c_opCreateEvent.seize(evntRecPtr)) {
- // Failed to allocate event record
- jam();
- releaseSections(signal);
-
- CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
- ret->senderRef = reference();
- ret->setErrorCode(747);
- ret->setErrorLine(__LINE__);
- ret->setErrorNode(reference());
- sendSignal(signal->senderBlockRef(), GSN_CREATE_EVNT_REF, signal,
- CreateEvntRef::SignalLength, JBB);
- return;
- }
-
-#ifdef EVENT_DEBUG
- ndbout_c("DBDICT::execCREATE_EVNT_REQ from %u evntRecId = (%d)", refToNode(signal->getSendersBlockRef()), evntRecPtr.i);
-#endif
-
- ndbrequire(req->getUserRef() == signal->getSendersBlockRef());
-
- evntRecPtr.p->init(req,this);
-
- if (requestFlag & (Uint32)CreateEvntReq::RT_DICT_AFTER_GET) {
- jam();
- EVENT_TRACE;
- createEvent_RT_DICT_AFTER_GET(signal, evntRecPtr);
- return;
- }
- if (requestType == CreateEvntReq::RT_USER_GET) {
- jam();
- EVENT_TRACE;
- createEvent_RT_USER_GET(signal, evntRecPtr);
- return;
- }
- if (requestType == CreateEvntReq::RT_USER_CREATE) {
- jam();
- EVENT_TRACE;
- createEvent_RT_USER_CREATE(signal, evntRecPtr);
- return;
- }
-
-#ifdef EVENT_DEBUG
- ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ other" << endl;
-#endif
- jam();
- releaseSections(signal);
-
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
-}
-
-/********************************************************************
- *
- * Event creation
- *
- *****************************************************************/
-
-void
-Dbdict::createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr)
-{
- jam();
- DBUG_ENTER("Dbdict::createEvent_RT_USER_CREATE");
- evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
-
-#ifdef EVENT_DEBUG
- ndbout << "Dbdict.cpp: Dbdict::execCREATE_EVNT_REQ RT_USER" << endl;
- char buf[128] = {0};
- AttributeMask mask = evntRecPtr.p->m_request.getAttrListBitmask();
- mask.getText(buf);
- ndbout_c("mask = %s", buf);
-#endif
-
- // Interpret the long signal
-
- SegmentedSectionPtr ssPtr;
- // save name and event properties
- signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
-
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
-#ifdef EVENT_DEBUG
- r0.printAll(ndbout);
-#endif
- // event name
- if ((!r0.first()) ||
- (r0.getValueType() != SimpleProperties::StringValue) ||
- (r0.getValueLen() <= 0)) {
- jam();
- releaseSections(signal);
-
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
- }
- r0.getString(evntRecPtr.p->m_eventRec.NAME);
- {
- int len = strlen(evntRecPtr.p->m_eventRec.NAME);
- memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
-#ifdef EVENT_DEBUG
- printf("CreateEvntReq::RT_USER_CREATE; EventName %s, len %u\n",
- evntRecPtr.p->m_eventRec.NAME, len);
- for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
- printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
- printf("\n");
-#endif
- }
- // table name
- if ((!r0.next()) ||
- (r0.getValueType() != SimpleProperties::StringValue) ||
- (r0.getValueLen() <= 0)) {
- jam();
- releaseSections(signal);
-
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
- }
- r0.getString(evntRecPtr.p->m_eventRec.TABLE_NAME);
- {
- int len = strlen(evntRecPtr.p->m_eventRec.TABLE_NAME);
- memset(evntRecPtr.p->m_eventRec.TABLE_NAME+len, 0, MAX_TAB_NAME_SIZE-len);
- }
-
- releaseSections(signal);
-
- // Send request to SUMA
-
- CreateSubscriptionIdReq * sumaIdReq =
- (CreateSubscriptionIdReq *)signal->getDataPtrSend();
-
- // make sure we save the original sender for later
- sumaIdReq->senderRef = reference();
- sumaIdReq->senderData = evntRecPtr.i;
-#ifdef EVENT_DEBUG
- ndbout << "sumaIdReq->senderData = " << sumaIdReq->senderData << endl;
-#endif
- sendSignal(SUMA_REF, GSN_CREATE_SUBID_REQ, signal,
- CreateSubscriptionIdReq::SignalLength, JBB);
- // we should now return in either execCREATE_SUBID_CONF
- // or execCREATE_SUBID_REF
- DBUG_VOID_RETURN;
-}
-
-void Dbdict::execCREATE_SUBID_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execCREATE_SUBID_REF");
- CreateSubscriptionIdRef * const ref =
- (CreateSubscriptionIdRef *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
-
- evntRecPtr.i = ref->senderData;
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
- if (ref->errorCode)
- {
- evntRecPtr.p->m_errorCode = ref->errorCode;
- evntRecPtr.p->m_errorLine = __LINE__;
- }
- else
- {
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- }
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
-}
-
-void Dbdict::execCREATE_SUBID_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execCREATE_SUBID_CONF");
-
- CreateSubscriptionIdConf const * sumaIdConf =
- (CreateSubscriptionIdConf *)signal->getDataPtr();
-
- Uint32 evntRecId = sumaIdConf->senderData;
- OpCreateEvent *evntRec;
-
- ndbrequire((evntRec = c_opCreateEvent.getPtr(evntRecId)) != NULL);
-
- evntRec->m_request.setEventId(sumaIdConf->subscriptionId);
- evntRec->m_request.setEventKey(sumaIdConf->subscriptionKey);
-
- releaseSections(signal);
-
- Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
-
- prepareTransactionEventSysTable(&c, signal, evntRecId,
- UtilPrepareReq::Insert);
- DBUG_VOID_RETURN;
-}
-
-void
-Dbdict::createEventComplete_RT_USER_CREATE(Signal* signal,
- OpCreateEventPtr evntRecPtr){
- jam();
- createEvent_sendReply(signal, evntRecPtr);
-}
-
-/*********************************************************************
- *
- * UTIL_PREPARE, UTIL_EXECUTE
- *
- * insert or read systable NDB$EVENTS_0
- */
-
-void interpretUtilPrepareErrorCode(UtilPrepareRef::ErrorCode errorCode,
- Uint32& error, Uint32& line)
-{
- DBUG_ENTER("interpretUtilPrepareErrorCode");
- switch (errorCode) {
- case UtilPrepareRef::NO_ERROR:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- case UtilPrepareRef::PREPARE_SEIZE_ERROR:
- jam();
- error = 748;
- line = __LINE__;
- DBUG_VOID_RETURN;
- case UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- case UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- case UtilPrepareRef::DICT_TAB_INFO_ERROR:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- case UtilPrepareRef::MISSING_PROPERTIES_SECTION:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- default:
- jam();
- error = 1;
- line = __LINE__;
- DBUG_VOID_RETURN;
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Dbdict::createEventUTIL_PREPARE(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode == 0) {
- UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
- jam();
- evntRecPtr.i = req->getSenderData();
- const Uint32 prepareId = req->getPrepareId();
-
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
- Callback c = { safe_cast(&Dbdict::createEventUTIL_EXECUTE), 0 };
-
- switch (evntRecPtr.p->m_requestType) {
- case CreateEvntReq::RT_USER_GET:
- jam();
- executeTransEventSysTable(&c, signal,
- evntRecPtr.i, evntRecPtr.p->m_eventRec,
- prepareId, UtilPrepareReq::Read);
- break;
- case CreateEvntReq::RT_USER_CREATE:
- {
- evntRecPtr.p->m_eventRec.EVENT_TYPE =
- evntRecPtr.p->m_request.getEventType() | evntRecPtr.p->m_request.getReportFlags();
- evntRecPtr.p->m_eventRec.TABLEID = evntRecPtr.p->m_request.getTableId();
- evntRecPtr.p->m_eventRec.TABLEVERSION=evntRecPtr.p->m_request.getTableVersion();
- AttributeMask m = evntRecPtr.p->m_request.getAttrListBitmask();
- memcpy(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK, &m,
- sizeof(evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK));
- evntRecPtr.p->m_eventRec.SUBID = evntRecPtr.p->m_request.getEventId();
- evntRecPtr.p->m_eventRec.SUBKEY = evntRecPtr.p->m_request.getEventKey();
- DBUG_PRINT("info",
- ("CREATE: event name: %s table name: %s table id: %u table version: %u",
- evntRecPtr.p->m_eventRec.NAME,
- evntRecPtr.p->m_eventRec.TABLE_NAME,
- evntRecPtr.p->m_eventRec.TABLEID,
- evntRecPtr.p->m_eventRec.TABLEVERSION));
-
- }
- jam();
- executeTransEventSysTable(&c, signal,
- evntRecPtr.i, evntRecPtr.p->m_eventRec,
- prepareId, UtilPrepareReq::Insert);
- break;
- default:
-#ifdef EVENT_DEBUG
- printf("type = %d\n", evntRecPtr.p->m_requestType);
- printf("bet type = %d\n", CreateEvntReq::RT_USER_GET);
- printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
-#endif
- ndbrequire(false);
- }
- } else { // returnCode != 0
- UtilPrepareRef* const ref = (UtilPrepareRef*)signal->getDataPtr();
-
- const UtilPrepareRef::ErrorCode errorCode =
- (UtilPrepareRef::ErrorCode)ref->getErrorCode();
-
- OpCreateEventPtr evntRecPtr;
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
- interpretUtilPrepareErrorCode(errorCode, evntRecPtr.p->m_errorCode,
- evntRecPtr.p->m_errorLine);
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- }
-}
-
-void Dbdict::executeTransEventSysTable(Callback *pcallback, Signal *signal,
- const Uint32 ptrI,
- sysTab_NDBEVENTS_0& m_eventRec,
- const Uint32 prepareId,
- UtilPrepareReq::OperationTypeValue prepReq)
-{
- jam();
- const Uint32 noAttr = EVENT_SYSTEM_TABLE_LENGTH;
- Uint32 total_len = 0;
-
- Uint32* attrHdr = signal->theData + 25;
- Uint32* attrPtr = attrHdr;
-
- Uint32 id=0;
- // attribute 0 event name: Primary Key
- {
- AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
- total_len += sysTab_NDBEVENTS_0_szs[id];
- attrPtr++; id++;
- }
-
- switch (prepReq) {
- case UtilPrepareReq::Read:
- jam();
- EVENT_TRACE;
- // no more
- while ( id < noAttr )
- AttributeHeader::init(attrPtr++, id++, 0);
- ndbrequire(id == (Uint32) noAttr);
- break;
- case UtilPrepareReq::Insert:
- jam();
- EVENT_TRACE;
- while ( id < noAttr ) {
- AttributeHeader::init(attrPtr, id, sysTab_NDBEVENTS_0_szs[id]);
- total_len += sysTab_NDBEVENTS_0_szs[id];
- attrPtr++; id++;
- }
- ndbrequire(id == (Uint32) noAttr);
- break;
- case UtilPrepareReq::Delete:
- ndbrequire(id == 1);
- break;
- default:
- ndbrequire(false);
- }
-
- LinearSectionPtr headerPtr;
- LinearSectionPtr dataPtr;
-
- headerPtr.p = attrHdr;
- headerPtr.sz = noAttr;
-
- dataPtr.p = (Uint32*)&m_eventRec;
- dataPtr.sz = total_len/4;
-
- ndbrequire((total_len == sysTab_NDBEVENTS_0_szs[0]) ||
- (total_len == sizeof(sysTab_NDBEVENTS_0)));
-
-#if 0
- printf("Header size %u\n", headerPtr.sz);
- for(int i = 0; i < (int)headerPtr.sz; i++)
- printf("H'%.8x ", attrHdr[i]);
- printf("\n");
-
- printf("Data size %u\n", dataPtr.sz);
- for(int i = 0; i < (int)dataPtr.sz; i++)
- printf("H'%.8x ", dataPage[i]);
- printf("\n");
-#endif
-
- executeTransaction(pcallback, signal,
- ptrI,
- prepareId,
- id,
- headerPtr,
- dataPtr);
-}
-
-void Dbdict::executeTransaction(Callback *pcallback,
- Signal* signal,
- Uint32 senderData,
- Uint32 prepareId,
- Uint32 noAttr,
- LinearSectionPtr headerPtr,
- LinearSectionPtr dataPtr)
-{
- jam();
- EVENT_TRACE;
-
- UtilExecuteReq * utilExecuteReq =
- (UtilExecuteReq *)signal->getDataPtrSend();
-
- utilExecuteReq->setSenderRef(reference());
- utilExecuteReq->setSenderData(senderData);
- utilExecuteReq->setPrepareId(prepareId);
- utilExecuteReq->setReleaseFlag(); // must be done after setting prepareId
-
-#if 0
- printf("Header size %u\n", headerPtr.sz);
- for(int i = 0; i < (int)headerPtr.sz; i++)
- printf("H'%.8x ", headerBuffer[i]);
- printf("\n");
-
- printf("Data size %u\n", dataPtr.sz);
- for(int i = 0; i < (int)dataPtr.sz; i++)
- printf("H'%.8x ", dataBuffer[i]);
- printf("\n");
-#endif
-
- struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = headerPtr.p;
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].p = dataPtr.p;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataPtr.sz;
-
- sendSignalUtilReq(pcallback, DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal,
- UtilExecuteReq::SignalLength, JBB,
- sectionsPtr, UtilExecuteReq::NoOfSections);
-}
-
-void Dbdict::parseReadEventSys(Signal* signal, sysTab_NDBEVENTS_0& m_eventRec)
-{
- SegmentedSectionPtr headerPtr, dataPtr;
- jam();
- signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
- SectionReader headerReader(headerPtr, getSectionSegmentPool());
-
- signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
- SectionReader dataReader(dataPtr, getSectionSegmentPool());
-
- AttributeHeader header;
- Uint32 *dst = (Uint32*)&m_eventRec;
-
- for (int i = 0; i < EVENT_SYSTEM_TABLE_LENGTH; i++) {
- headerReader.getWord((Uint32 *)&header);
- int sz = header.getDataSize();
- for (int i=0; i < sz; i++)
- dataReader.getWord(dst++);
- }
-
- ndbrequire( ((char*)dst-(char*)&m_eventRec) == sizeof(m_eventRec) );
-
- releaseSections(signal);
-}
-
-void Dbdict::createEventUTIL_EXECUTE(Signal *signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode == 0) {
- // Entry into system table all set
- UtilExecuteConf* const conf = (UtilExecuteConf*)signal->getDataPtr();
- jam();
- OpCreateEventPtr evntRecPtr;
- evntRecPtr.i = conf->getSenderData();
-
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
- OpCreateEvent *evntRec = evntRecPtr.p;
-
- switch (evntRec->m_requestType) {
- case CreateEvntReq::RT_USER_GET: {
- parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
-
- evntRec->m_request.setEventType(evntRecPtr.p->m_eventRec.EVENT_TYPE);
- evntRec->m_request.setReportFlags(evntRecPtr.p->m_eventRec.EVENT_TYPE);
- evntRec->m_request.setTableId(evntRecPtr.p->m_eventRec.TABLEID);
- evntRec->m_request.setTableVersion(evntRecPtr.p->m_eventRec.TABLEVERSION);
- evntRec->m_request.setAttrListBitmask(*(AttributeMask*)
- evntRecPtr.p->m_eventRec.ATTRIBUTE_MASK);
- evntRec->m_request.setEventId(evntRecPtr.p->m_eventRec.SUBID);
- evntRec->m_request.setEventKey(evntRecPtr.p->m_eventRec.SUBKEY);
-
- DBUG_PRINT("info",
- ("GET: event name: %s table name: %s table id: %u table version: %u",
- evntRecPtr.p->m_eventRec.NAME,
- evntRecPtr.p->m_eventRec.TABLE_NAME,
- evntRecPtr.p->m_eventRec.TABLEID,
- evntRecPtr.p->m_eventRec.TABLEVERSION));
-
- // find table id for event table
- DictObject* obj_ptr_p = get_object(evntRecPtr.p->m_eventRec.TABLE_NAME);
- if(!obj_ptr_p){
- jam();
- evntRecPtr.p->m_errorCode = 723;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- return;
- }
-
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, obj_ptr_p->m_id);
- evntRec->m_request.setTableId(tablePtr.p->tableId);
- evntRec->m_request.setTableVersion(tablePtr.p->tableVersion);
-
- createEventComplete_RT_USER_GET(signal, evntRecPtr);
- return;
- }
- case CreateEvntReq::RT_USER_CREATE: {
-#ifdef EVENT_DEBUG
- printf("create type = %d\n", CreateEvntReq::RT_USER_CREATE);
-#endif
- jam();
- createEventComplete_RT_USER_CREATE(signal, evntRecPtr);
- return;
- }
- break;
- default:
- ndbrequire(false);
- }
- } else { // returnCode != 0
- UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
- jam();
- evntRecPtr.p->m_errorNode = reference();
- evntRecPtr.p->m_errorLine = __LINE__;
-
- switch (ref->getErrorCode()) {
- case UtilExecuteRef::TCError:
- switch (ref->getTCErrorCode()) {
- case ZNOT_FOUND:
- jam();
- evntRecPtr.p->m_errorCode = 4710;
- break;
- case ZALREADYEXIST:
- jam();
- evntRecPtr.p->m_errorCode = 746;
- break;
- default:
- jam();
- evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
- break;
- }
- break;
- default:
- jam();
- evntRecPtr.p->m_errorCode = ref->getErrorCode();
- break;
- }
-
- createEvent_sendReply(signal, evntRecPtr);
- }
-}
-
-/***********************************************************************
- *
- * NdbEventOperation, reading systable, creating event in suma
- *
- */
-
-void
-Dbdict::createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
- jam();
- EVENT_TRACE;
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REQ::RT_USER_GET evntRecPtr.i = (%d), ref = %u", evntRecPtr.i, evntRecPtr.p->m_request.getUserRef());
-#endif
-
- SegmentedSectionPtr ssPtr;
-
- signal->getSection(ssPtr, 0);
-
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
-#ifdef EVENT_DEBUG
- r0.printAll(ndbout);
-#endif
- if ((!r0.first()) ||
- (r0.getValueType() != SimpleProperties::StringValue) ||
- (r0.getValueLen() <= 0)) {
- jam();
- releaseSections(signal);
-
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- return;
- }
-
- r0.getString(evntRecPtr.p->m_eventRec.NAME);
- int len = strlen(evntRecPtr.p->m_eventRec.NAME);
- memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
-
- releaseSections(signal);
-
- Callback c = { safe_cast(&Dbdict::createEventUTIL_PREPARE), 0 };
-
- prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
- UtilPrepareReq::Read);
- /*
- * Will read systable and fill an OpCreateEventPtr
- * and return below
- */
-}
-
-void
-Dbdict::createEventComplete_RT_USER_GET(Signal* signal,
- OpCreateEventPtr evntRecPtr){
- jam();
-
- // Send to oneself and the other DICT's
- CreateEvntReq * req = (CreateEvntReq *)signal->getDataPtrSend();
-
- *req = evntRecPtr.p->m_request;
- req->senderRef = reference();
- req->senderData = evntRecPtr.i;
-
- req->addRequestFlag(CreateEvntReq::RT_DICT_AFTER_GET);
-
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT(Coordinator) sending GSN_CREATE_EVNT_REQ::RT_DICT_AFTER_GET to DBDICT participants evntRecPtr.i = (%d)", evntRecPtr.i);
-#endif
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- RequestTracker & p = evntRecPtr.p->m_reqTracker;
- if (!p.init<CreateEvntRef>(c_counterMgr, rg, GSN_CREATE_EVNT_REF,
- evntRecPtr.i))
- {
- jam();
- evntRecPtr.p->m_errorCode = 701;
- createEvent_sendReply(signal, evntRecPtr);
- return;
- }
-
- sendSignal(rg, GSN_CREATE_EVNT_REQ, signal, CreateEvntReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
- Uint32 returnCode){
- OpCreateEventPtr evntRecPtr;
- c_opCreateEvent.getPtr(evntRecPtr, eventRecPtrI);
- createEvent_sendReply(signal, evntRecPtr);
-}
-
-void Dbdict::execCREATE_EVNT_REF(Signal* signal)
-{
- jamEntry();
- EVENT_TRACE;
- CreateEvntRef * const ref = (CreateEvntRef *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
-
- evntRecPtr.i = ref->getUserData();
-
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REF evntRecPtr.i = (%d)", evntRecPtr.i);
-#endif
-
- if (ref->errorCode == CreateEvntRef::NF_FakeErrorREF){
- jam();
- evntRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(ref->senderRef));
- } else {
- jam();
- evntRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(ref->senderRef));
- }
- createEvent_sendReply(signal, evntRecPtr);
-
- return;
-}
-
-void Dbdict::execCREATE_EVNT_CONF(Signal* signal)
-{
- jamEntry();
- EVENT_TRACE;
- CreateEvntConf * const conf = (CreateEvntConf *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
-
- evntRecPtr.i = conf->getUserData();
-
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_CONF evntRecPtr.i = (%d)", evntRecPtr.i);
-#endif
-
- evntRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(conf->senderRef));
-
- // we will only have a valid tablename if it the master DICT sending this
- // but that's ok
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32 *)evntRecPtr.p->m_eventRec.TABLE_NAME;
- ptr[0].sz =
- (strlen(evntRecPtr.p->m_eventRec.TABLE_NAME)+4)/4; // to make sure we have a null
-
- createEvent_sendReply(signal, evntRecPtr, ptr, 1);
-
- return;
-}
-
-/************************************************
- *
- * Participant stuff
- *
- */
-
-void
-Dbdict::createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr){
- DBUG_ENTER("Dbdict::createEvent_RT_DICT_AFTER_GET");
- jam();
- evntRecPtr.p->m_request.setUserRef(signal->senderBlockRef());
-
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT(Participant) got CREATE_EVNT_REQ::RT_DICT_AFTER_GET evntRecPtr.i = (%d)", evntRecPtr.i);
-#endif
-
- // the signal comes from the DICT block that got the first user request!
- // This code runs on all DICT nodes, including oneself
-
- // Seize a Create Event record, the Coordinator will now have two seized
- // but that's ok, it's like a recursion
-
- CRASH_INSERTION2(6009, getOwnNodeId() != c_masterNodeId);
-
- SubCreateReq * sumaReq = (SubCreateReq *)signal->getDataPtrSend();
-
- sumaReq->senderRef = reference(); // reference to DICT
- sumaReq->senderData = evntRecPtr.i;
- sumaReq->subscriptionId = evntRecPtr.p->m_request.getEventId();
- sumaReq->subscriptionKey = evntRecPtr.p->m_request.getEventKey();
- sumaReq->subscriptionType = SubCreateReq::TableEvent;
- if (evntRecPtr.p->m_request.getReportAll())
- sumaReq->subscriptionType|= SubCreateReq::ReportAll;
- if (evntRecPtr.p->m_request.getReportSubscribe())
- sumaReq->subscriptionType|= SubCreateReq::ReportSubscribe;
- sumaReq->tableId = evntRecPtr.p->m_request.getTableId();
-
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("sending GSN_SUB_CREATE_REQ");
-#endif
-
- sendSignal(SUMA_REF, GSN_SUB_CREATE_REQ, signal,
- SubCreateReq::SignalLength, JBB);
- DBUG_VOID_RETURN;
-}
-
-void Dbdict::execSUB_CREATE_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execSUB_CREATE_REF");
-
- SubCreateRef * const ref = (SubCreateRef *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
-
- evntRecPtr.i = ref->senderData;
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
- if (ref->errorCode == 1415) {
- jam();
- createEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
- }
-
- if (ref->errorCode)
- {
- evntRecPtr.p->m_errorCode = ref->errorCode;
- evntRecPtr.p->m_errorLine = __LINE__;
- }
- else
- {
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- }
- evntRecPtr.p->m_errorNode = reference();
-
- createEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
-}
-
-void Dbdict::execSUB_CREATE_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execSUB_CREATE_CONF");
- EVENT_TRACE;
-
- SubCreateConf * const sumaConf = (SubCreateConf *)signal->getDataPtr();
- OpCreateEventPtr evntRecPtr;
- evntRecPtr.i = sumaConf->senderData;
- ndbrequire((evntRecPtr.p = c_opCreateEvent.getPtr(evntRecPtr.i)) != NULL);
-
- createEvent_sendReply(signal, evntRecPtr);
-
- DBUG_VOID_RETURN;
-}
-
-/****************************************************
- *
- * common create reply method
- *
- *******************************************************/
-
-void Dbdict::createEvent_sendReply(Signal* signal,
- OpCreateEventPtr evntRecPtr,
- LinearSectionPtr *ptr, int noLSP)
-{
- jam();
- EVENT_TRACE;
-
- // check if we're ready to sent reply
- // if we are the master dict we might be waiting for conf/ref
-
- if (!evntRecPtr.p->m_reqTracker.done()) {
- jam();
- return; // there's more to come
- }
-
- if (evntRecPtr.p->m_reqTracker.hasRef()) {
- ptr = NULL; // we don't want to return anything if there's an error
- if (!evntRecPtr.p->hasError()) {
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
- jam();
- } else
- jam();
- }
-
- // reference to API if master DICT
- // else reference to master DICT
- Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
- Uint32 signalLength;
- Uint32 gsn;
-
- if (evntRecPtr.p->hasError()) {
- jam();
- EVENT_TRACE;
- CreateEvntRef * ret = (CreateEvntRef *)signal->getDataPtrSend();
-
- ret->setEventId(evntRecPtr.p->m_request.getEventId());
- ret->setEventKey(evntRecPtr.p->m_request.getEventKey());
- ret->setUserData(evntRecPtr.p->m_request.getUserData());
- ret->senderRef = reference();
- ret->setTableId(evntRecPtr.p->m_request.getTableId());
- ret->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
- ret->setEventType(evntRecPtr.p->m_request.getEventType());
- ret->setRequestType(evntRecPtr.p->m_request.getRequestType());
-
- ret->setErrorCode(evntRecPtr.p->m_errorCode);
- ret->setErrorLine(evntRecPtr.p->m_errorLine);
- ret->setErrorNode(evntRecPtr.p->m_errorNode);
-
- signalLength = CreateEvntRef::SignalLength;
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT sending GSN_CREATE_EVNT_REF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
- ndbout_c("errorCode = %u", evntRecPtr.p->m_errorCode);
- ndbout_c("errorLine = %u", evntRecPtr.p->m_errorLine);
-#endif
- gsn = GSN_CREATE_EVNT_REF;
-
- } else {
- jam();
- EVENT_TRACE;
- CreateEvntConf * evntConf = (CreateEvntConf *)signal->getDataPtrSend();
-
- evntConf->setEventId(evntRecPtr.p->m_request.getEventId());
- evntConf->setEventKey(evntRecPtr.p->m_request.getEventKey());
- evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
- evntConf->senderRef = reference();
- evntConf->setTableId(evntRecPtr.p->m_request.getTableId());
- evntConf->setTableVersion(evntRecPtr.p->m_request.getTableVersion());
- evntConf->setAttrListBitmask(evntRecPtr.p->m_request.getAttrListBitmask());
- evntConf->setEventType(evntRecPtr.p->m_request.getEventType());
- evntConf->setRequestType(evntRecPtr.p->m_request.getRequestType());
-
- signalLength = CreateEvntConf::SignalLength;
-#ifdef EVENT_PH2_DEBUG
- ndbout_c("DBDICT sending GSN_CREATE_EVNT_CONF to evntRecPtr.i = (%d) node = %u ref = %u", evntRecPtr.i, refToNode(senderRef), senderRef);
-#endif
- gsn = GSN_CREATE_EVNT_CONF;
- }
-
- if (ptr) {
- jam();
- sendSignal(senderRef, gsn, signal, signalLength, JBB, ptr, noLSP);
- } else {
- jam();
- sendSignal(senderRef, gsn, signal, signalLength, JBB);
- }
-
- c_opCreateEvent.release(evntRecPtr);
-}
-
-/*************************************************************/
-
-/********************************************************************
- *
- * Start event
- *
- *******************************************************************/
-
-void Dbdict::execSUB_START_REQ(Signal* signal)
-{
- jamEntry();
-
- Uint32 origSenderRef = signal->senderBlockRef();
-
- if (refToBlock(origSenderRef) != DBDICT &&
- getOwnNodeId() != c_masterNodeId)
- {
- /*
- * Coordinator but not master
- */
- SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = SubStartRef::NotMaster;
- ref->m_masterNodeId = c_masterNodeId;
- sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
- SubStartRef::SignalLength2, JBB);
- return;
- }
- OpSubEventPtr subbPtr;
- Uint32 errCode = 0;
-
- DictLockPtr loopPtr;
- if (c_dictLockQueue.first(loopPtr) &&
- loopPtr.p->lt->lockType == DictLockReq::NodeRestartLock)
- {
- jam();
- errCode = 1405;
- goto busy;
- }
-
- if (!c_opSubEvent.seize(subbPtr)) {
- errCode = SubStartRef::Busy;
-busy:
- jam();
- SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
-
- { // fix
- Uint32 subcriberRef = ((SubStartReq*)signal->getDataPtr())->subscriberRef;
- ref->subscriberRef = subcriberRef;
- }
- jam();
- // ret->setErrorCode(SubStartRef::SeizeError);
- // ret->setErrorLine(__LINE__);
- // ret->setErrorNode(reference());
- ref->senderRef = reference();
- ref->errorCode = errCode;
-
- sendSignal(origSenderRef, GSN_SUB_START_REF, signal,
- SubStartRef::SignalLength2, JBB);
- return;
- }
-
- {
- const SubStartReq* req = (SubStartReq*) signal->getDataPtr();
- subbPtr.p->m_senderRef = req->senderRef;
- subbPtr.p->m_senderData = req->senderData;
- subbPtr.p->m_errorCode = 0;
- }
-
- if (refToBlock(origSenderRef) != DBDICT) {
- /*
- * Coordinator
- */
- jam();
-
- subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- RequestTracker & p = subbPtr.p->m_reqTracker;
- if (!p.init<SubStartRef>(c_counterMgr, rg, GSN_SUB_START_REF, subbPtr.i))
- {
- c_opSubEvent.release(subbPtr);
- errCode = SubStartRef::Busy;
- goto busy;
- }
-
- SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
-
- req->senderRef = reference();
- req->senderData = subbPtr.i;
-
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Coordinator) sending GSN_SUB_START_REQ to DBDICT participants subbPtr.i = (%d)", subbPtr.i);
-#endif
-
- sendSignal(rg, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
- return;
- }
- /*
- * Participant
- */
- ndbrequire(refToBlock(origSenderRef) == DBDICT);
-
- CRASH_INSERTION(6007);
-
- {
- SubStartReq* req = (SubStartReq*) signal->getDataPtrSend();
-
- req->senderRef = reference();
- req->senderData = subbPtr.i;
-
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Participant) sending GSN_SUB_START_REQ to SUMA subbPtr.i = (%d)", subbPtr.i);
-#endif
- sendSignal(SUMA_REF, GSN_SUB_START_REQ, signal, SubStartReq::SignalLength2, JBB);
- }
-}
-
-void Dbdict::execSUB_START_REF(Signal* signal)
-{
- jamEntry();
-
- const SubStartRef* ref = (SubStartRef*) signal->getDataPtr();
- Uint32 senderRef = ref->senderRef;
- Uint32 err = ref->errorCode;
-
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, ref->senderData);
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
-
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Participant) got GSN_SUB_START_REF = (%d)", subbPtr.i);
-#endif
-
- jam();
- SubStartRef* ref = (SubStartRef*) signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = subbPtr.p->m_senderData;
- ref->errorCode = err;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
- signal, SubStartRef::SignalLength2, JBB);
- c_opSubEvent.release(subbPtr);
- return;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_REF = (%d)", subbPtr.i);
-#endif
- if (err == SubStartRef::NF_FakeErrorREF){
- jam();
- subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
- } else {
- jam();
- if (subbPtr.p->m_errorCode == 0)
- {
- subbPtr.p->m_errorCode= err ? err : 1;
- }
- subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
- }
- completeSubStartReq(signal,subbPtr.i,0);
-}
-
-void Dbdict::execSUB_START_CONF(Signal* signal)
-{
- jamEntry();
-
- const SubStartConf* conf = (SubStartConf*) signal->getDataPtr();
- Uint32 senderRef = conf->senderRef;
-
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, conf->senderData);
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
- SubStartConf* conf = (SubStartConf*) signal->getDataPtrSend();
-
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Participant) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
-#endif
-
- conf->senderRef = reference();
- conf->senderData = subbPtr.p->m_senderData;
-
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
- signal, SubStartConf::SignalLength2, JBB);
- c_opSubEvent.release(subbPtr);
- return;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
-#ifdef EVENT_PH3_DEBUG
- ndbout_c("DBDICT(Coordinator) got GSN_SUB_START_CONF = (%d)", subbPtr.i);
-#endif
- subbPtr.p->m_sub_start_conf = *conf;
- subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
- completeSubStartReq(signal,subbPtr.i,0);
-}
-
-/*
- * Coordinator
- */
-void Dbdict::completeSubStartReq(Signal* signal,
- Uint32 ptrI,
- Uint32 returnCode){
- jam();
-
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, ptrI);
-
- if (!subbPtr.p->m_reqTracker.done()){
- jam();
- return;
- }
-
- if (subbPtr.p->m_reqTracker.hasRef()) {
- jam();
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_START_REF");
-#endif
- SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = subbPtr.p->m_errorCode;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_REF,
- signal, SubStartRef::SignalLength, JBB);
- if (subbPtr.p->m_reqTracker.hasConf()) {
- // stopStartedNodes(signal);
- }
- c_opSubEvent.release(subbPtr);
- return;
- }
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_START_CONF");
-#endif
-
- SubStartConf* conf = (SubStartConf*)signal->getDataPtrSend();
- * conf = subbPtr.p->m_sub_start_conf;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_START_CONF,
- signal, SubStartConf::SignalLength, JBB);
- c_opSubEvent.release(subbPtr);
-}
-
-/********************************************************************
- *
- * Stop event
- *
- *******************************************************************/
-
-void Dbdict::execSUB_STOP_REQ(Signal* signal)
-{
- jamEntry();
-
- Uint32 origSenderRef = signal->senderBlockRef();
-
- if (refToBlock(origSenderRef) != DBDICT &&
- getOwnNodeId() != c_masterNodeId)
- {
- /*
- * Coordinator but not master
- */
- SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = SubStopRef::NotMaster;
- ref->m_masterNodeId = c_masterNodeId;
- sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
- SubStopRef::SignalLength2, JBB);
- return;
- }
- OpSubEventPtr subbPtr;
- Uint32 errCode = 0;
- if (!c_opSubEvent.seize(subbPtr)) {
- errCode = SubStopRef::Busy;
-busy:
- SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
- jam();
- // ret->setErrorCode(SubStartRef::SeizeError);
- // ret->setErrorLine(__LINE__);
- // ret->setErrorNode(reference());
- ref->senderRef = reference();
- ref->errorCode = errCode;
-
- sendSignal(origSenderRef, GSN_SUB_STOP_REF, signal,
- SubStopRef::SignalLength, JBB);
- return;
- }
-
- {
- const SubStopReq* req = (SubStopReq*) signal->getDataPtr();
- subbPtr.p->m_senderRef = req->senderRef;
- subbPtr.p->m_senderData = req->senderData;
- subbPtr.p->m_errorCode = 0;
- }
-
- if (refToBlock(origSenderRef) != DBDICT) {
- /*
- * Coordinator
- */
- jam();
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_STOP_REQ 1");
-#endif
- subbPtr.p->m_senderRef = origSenderRef; // not sure if API sets correctly
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- RequestTracker & p = subbPtr.p->m_reqTracker;
- if (!p.init<SubStopRef>(c_counterMgr, rg, GSN_SUB_STOP_REF, subbPtr.i))
- {
- jam();
- c_opSubEvent.release(subbPtr);
- errCode = SubStopRef::Busy;
- goto busy;
- }
-
- SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
-
- req->senderRef = reference();
- req->senderData = subbPtr.i;
-
- sendSignal(rg, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
- return;
- }
- /*
- * Participant
- */
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_STOP_REQ 2");
-#endif
- ndbrequire(refToBlock(origSenderRef) == DBDICT);
-
- CRASH_INSERTION(6008);
-
- {
- SubStopReq* req = (SubStopReq*) signal->getDataPtrSend();
-
- req->senderRef = reference();
- req->senderData = subbPtr.i;
-
- sendSignal(SUMA_REF, GSN_SUB_STOP_REQ, signal, SubStopReq::SignalLength, JBB);
- }
-}
-
-void Dbdict::execSUB_STOP_REF(Signal* signal)
-{
- jamEntry();
- const SubStopRef* ref = (SubStopRef*) signal->getDataPtr();
- Uint32 senderRef = ref->senderRef;
- Uint32 err = ref->errorCode;
-
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, ref->senderData);
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
- SubStopRef* ref = (SubStopRef*) signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = subbPtr.p->m_senderData;
- ref->errorCode = err;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
- signal, SubStopRef::SignalLength, JBB);
- c_opSubEvent.release(subbPtr);
- return;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
- if (err == SubStopRef::NF_FakeErrorREF){
- jam();
- subbPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
- } else {
- jam();
- if (subbPtr.p->m_errorCode == 0)
- {
- subbPtr.p->m_errorCode= err ? err : 1;
- }
- subbPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
- }
- completeSubStopReq(signal,subbPtr.i,0);
-}
-
-void Dbdict::execSUB_STOP_CONF(Signal* signal)
-{
- jamEntry();
-
- const SubStopConf* conf = (SubStopConf*) signal->getDataPtr();
- Uint32 senderRef = conf->senderRef;
-
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, conf->senderData);
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
- SubStopConf* conf = (SubStopConf*) signal->getDataPtrSend();
-
- conf->senderRef = reference();
- conf->senderData = subbPtr.p->m_senderData;
-
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
- signal, SubStopConf::SignalLength, JBB);
- c_opSubEvent.release(subbPtr);
- return;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
- subbPtr.p->m_sub_stop_conf = *conf;
- subbPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
- completeSubStopReq(signal,subbPtr.i,0);
-}
-
-/*
- * Coordinator
- */
-void Dbdict::completeSubStopReq(Signal* signal,
- Uint32 ptrI,
- Uint32 returnCode){
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, ptrI);
-
- if (!subbPtr.p->m_reqTracker.done()){
- jam();
- return;
- }
-
- if (subbPtr.p->m_reqTracker.hasRef()) {
- jam();
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_STOP_REF");
-#endif
- SubStopRef* ref = (SubStopRef*)signal->getDataPtrSend();
-
- ref->senderRef = reference();
- ref->senderData = subbPtr.p->m_senderData;
- ref->errorCode = subbPtr.p->m_errorCode;
-
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_REF,
- signal, SubStopRef::SignalLength, JBB);
- if (subbPtr.p->m_reqTracker.hasConf()) {
- // stopStartedNodes(signal);
- }
- c_opSubEvent.release(subbPtr);
- return;
- }
-#ifdef EVENT_DEBUG
- ndbout_c("SUB_STOP_CONF");
-#endif
- SubStopConf* conf = (SubStopConf*)signal->getDataPtrSend();
- * conf = subbPtr.p->m_sub_stop_conf;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_STOP_CONF,
- signal, SubStopConf::SignalLength, JBB);
- c_opSubEvent.release(subbPtr);
-}
-
-/***************************************************************
- * MODULE: Drop event.
- *
- * Drop event.
- *
- * TODO
- */
-
-void
-Dbdict::execDROP_EVNT_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execDROP_EVNT_REQ");
-
- DropEvntReq *req = (DropEvntReq*)signal->getDataPtr();
- const Uint32 senderRef = signal->senderBlockRef();
- OpDropEventPtr evntRecPtr;
-
- if (refToBlock(senderRef) != DBDICT &&
- getOwnNodeId() != c_masterNodeId)
- {
- jam();
- releaseSections(signal);
-
- DropEvntRef * ref = (DropEvntRef *)signal->getDataPtrSend();
- ref->setUserRef(reference());
- ref->setErrorCode(DropEvntRef::NotMaster);
- ref->setErrorLine(__LINE__);
- ref->setErrorNode(reference());
- ref->setMasterNode(c_masterNodeId);
- sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
- DropEvntRef::SignalLength2, JBB);
- return;
- }
-
- // Seize a Create Event record
- if (!c_opDropEvent.seize(evntRecPtr)) {
- // Failed to allocate event record
- jam();
- releaseSections(signal);
-
- DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
- ret->setErrorCode(747);
- ret->setErrorLine(__LINE__);
- ret->setErrorNode(reference());
- sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
- DropEvntRef::SignalLength, JBB);
- DBUG_VOID_RETURN;
- }
-
-#ifdef EVENT_DEBUG
- ndbout_c("DBDICT::execDROP_EVNT_REQ evntRecId = (%d)", evntRecPtr.i);
-#endif
-
- OpDropEvent* evntRec = evntRecPtr.p;
- evntRec->init(req);
-
- SegmentedSectionPtr ssPtr;
-
- signal->getSection(ssPtr, 0);
-
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
-#ifdef EVENT_DEBUG
- r0.printAll(ndbout);
-#endif
- // event name
- if ((!r0.first()) ||
- (r0.getValueType() != SimpleProperties::StringValue) ||
- (r0.getValueLen() <= 0)) {
- jam();
- releaseSections(signal);
-
- evntRecPtr.p->m_errorCode = 1;
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorNode = reference();
-
- dropEvent_sendReply(signal, evntRecPtr);
- DBUG_VOID_RETURN;
- }
- r0.getString(evntRecPtr.p->m_eventRec.NAME);
- {
- int len = strlen(evntRecPtr.p->m_eventRec.NAME);
- memset(evntRecPtr.p->m_eventRec.NAME+len, 0, MAX_TAB_NAME_SIZE-len);
-#ifdef EVENT_DEBUG
- printf("DropEvntReq; EventName %s, len %u\n",
- evntRecPtr.p->m_eventRec.NAME, len);
- for(int i = 0; i < MAX_TAB_NAME_SIZE/4; i++)
- printf("H'%.8x ", ((Uint32*)evntRecPtr.p->m_eventRec.NAME)[i]);
- printf("\n");
-#endif
- }
-
- releaseSections(signal);
-
- Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_READ), 0 };
-
- prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
- UtilPrepareReq::Read);
- DBUG_VOID_RETURN;
-}
-
-void
-Dbdict::dropEventUTIL_PREPARE_READ(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode != 0) {
- EVENT_TRACE;
- dropEventUtilPrepareRef(signal, callbackData, returnCode);
- return;
- }
-
- UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
- OpDropEventPtr evntRecPtr;
- evntRecPtr.i = req->getSenderData();
- const Uint32 prepareId = req->getPrepareId();
-
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-
- Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_READ), 0 };
-
- executeTransEventSysTable(&c, signal,
- evntRecPtr.i, evntRecPtr.p->m_eventRec,
- prepareId, UtilPrepareReq::Read);
-}
-
-void
-Dbdict::dropEventUTIL_EXECUTE_READ(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode != 0) {
- EVENT_TRACE;
- dropEventUtilExecuteRef(signal, callbackData, returnCode);
- return;
- }
-
- OpDropEventPtr evntRecPtr;
- UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
- jam();
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-
- parseReadEventSys(signal, evntRecPtr.p->m_eventRec);
-
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- RequestTracker & p = evntRecPtr.p->m_reqTracker;
- if (!p.init<SubRemoveRef>(c_counterMgr, rg, GSN_SUB_REMOVE_REF,
- evntRecPtr.i))
- {
- evntRecPtr.p->m_errorCode = 701;
- dropEvent_sendReply(signal, evntRecPtr);
- return;
- }
-
- SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
-
- req->senderRef = reference();
- req->senderData = evntRecPtr.i;
- req->subscriptionId = evntRecPtr.p->m_eventRec.SUBID;
- req->subscriptionKey = evntRecPtr.p->m_eventRec.SUBKEY;
-
- sendSignal(rg, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
-}
-
-/*
- * Participant
- */
-
-void
-Dbdict::execSUB_REMOVE_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execSUB_REMOVE_REQ");
-
- Uint32 origSenderRef = signal->senderBlockRef();
-
- OpSubEventPtr subbPtr;
- if (!c_opSubEvent.seize(subbPtr)) {
- SubRemoveRef * ref = (SubRemoveRef *)signal->getDataPtrSend();
- jam();
- ref->senderRef = reference();
- ref->errorCode = SubRemoveRef::Busy;
-
- sendSignal(origSenderRef, GSN_SUB_REMOVE_REF, signal,
- SubRemoveRef::SignalLength, JBB);
- DBUG_VOID_RETURN;
- }
-
- {
- const SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtr();
- subbPtr.p->m_senderRef = req->senderRef;
- subbPtr.p->m_senderData = req->senderData;
- subbPtr.p->m_errorCode = 0;
- }
-
- CRASH_INSERTION2(6010, getOwnNodeId() != c_masterNodeId);
-
- SubRemoveReq* req = (SubRemoveReq*) signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = subbPtr.i;
-
- sendSignal(SUMA_REF, GSN_SUB_REMOVE_REQ, signal, SubRemoveReq::SignalLength, JBB);
- DBUG_VOID_RETURN;
-}
-
-/*
- * Coordintor/Participant
- */
-
-void
-Dbdict::execSUB_REMOVE_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Dbdict::execSUB_REMOVE_REF");
-
- const SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtr();
- Uint32 senderRef = ref->senderRef;
- Uint32 err= ref->errorCode;
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, ref->senderData);
- if (err == 1407) {
- // conf this since this may occur if a nodefailure has occured
- // earlier so that the systable was not cleared
- SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
- signal, SubRemoveConf::SignalLength, JBB);
- } else {
- SubRemoveRef* ref = (SubRemoveRef*) signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = subbPtr.p->m_senderData;
- ref->errorCode = err;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_REF,
- signal, SubRemoveRef::SignalLength, JBB);
- }
- c_opSubEvent.release(subbPtr);
- DBUG_VOID_RETURN;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
- OpDropEventPtr eventRecPtr;
- c_opDropEvent.getPtr(eventRecPtr, ref->senderData);
- if (err == SubRemoveRef::NF_FakeErrorREF){
- jam();
- eventRecPtr.p->m_reqTracker.ignoreRef(c_counterMgr, refToNode(senderRef));
- } else {
- jam();
- if (eventRecPtr.p->m_errorCode == 0)
- {
- eventRecPtr.p->m_errorCode= err ? err : 1;
- eventRecPtr.p->m_errorLine= __LINE__;
- eventRecPtr.p->m_errorNode= reference();
- }
- eventRecPtr.p->m_reqTracker.reportRef(c_counterMgr, refToNode(senderRef));
- }
- completeSubRemoveReq(signal,eventRecPtr.i,0);
- DBUG_VOID_RETURN;
-}
-
-void
-Dbdict::execSUB_REMOVE_CONF(Signal* signal)
-{
- jamEntry();
- const SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtr();
- Uint32 senderRef = conf->senderRef;
-
- if (refToBlock(senderRef) == SUMA) {
- /*
- * Participant
- */
- jam();
- OpSubEventPtr subbPtr;
- c_opSubEvent.getPtr(subbPtr, conf->senderData);
- SubRemoveConf* conf = (SubRemoveConf*) signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_REMOVE_CONF,
- signal, SubRemoveConf::SignalLength, JBB);
- c_opSubEvent.release(subbPtr);
- return;
- }
- /*
- * Coordinator
- */
- ndbrequire(refToBlock(senderRef) == DBDICT);
- OpDropEventPtr eventRecPtr;
- c_opDropEvent.getPtr(eventRecPtr, conf->senderData);
- eventRecPtr.p->m_reqTracker.reportConf(c_counterMgr, refToNode(senderRef));
- completeSubRemoveReq(signal,eventRecPtr.i,0);
-}
-
-void
-Dbdict::completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 xxx)
-{
- OpDropEventPtr evntRecPtr;
- c_opDropEvent.getPtr(evntRecPtr, ptrI);
-
- if (!evntRecPtr.p->m_reqTracker.done()){
- jam();
- return;
- }
-
- if (evntRecPtr.p->m_reqTracker.hasRef()) {
- jam();
- if ( evntRecPtr.p->m_errorCode == 0 )
- {
- evntRecPtr.p->m_errorNode = reference();
- evntRecPtr.p->m_errorLine = __LINE__;
- evntRecPtr.p->m_errorCode = 1;
- }
- dropEvent_sendReply(signal, evntRecPtr);
- return;
- }
-
- Callback c = { safe_cast(&Dbdict::dropEventUTIL_PREPARE_DELETE), 0 };
-
- prepareTransactionEventSysTable(&c, signal, evntRecPtr.i,
- UtilPrepareReq::Delete);
-}
-
-void
-Dbdict::dropEventUTIL_PREPARE_DELETE(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode != 0) {
- EVENT_TRACE;
- dropEventUtilPrepareRef(signal, callbackData, returnCode);
- return;
- }
-
- UtilPrepareConf* const req = (UtilPrepareConf*)signal->getDataPtr();
- OpDropEventPtr evntRecPtr;
- jam();
- evntRecPtr.i = req->getSenderData();
- const Uint32 prepareId = req->getPrepareId();
-
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-#ifdef EVENT_DEBUG
- printf("DropEvntUTIL_PREPARE; evntRecPtr.i len %u\n",evntRecPtr.i);
-#endif
-
- Callback c = { safe_cast(&Dbdict::dropEventUTIL_EXECUTE_DELETE), 0 };
-
- executeTransEventSysTable(&c, signal,
- evntRecPtr.i, evntRecPtr.p->m_eventRec,
- prepareId, UtilPrepareReq::Delete);
-}
-
-void
-Dbdict::dropEventUTIL_EXECUTE_DELETE(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- if (returnCode != 0) {
- EVENT_TRACE;
- dropEventUtilExecuteRef(signal, callbackData, returnCode);
- return;
- }
-
- OpDropEventPtr evntRecPtr;
- UtilExecuteConf * const ref = (UtilExecuteConf *)signal->getDataPtr();
- jam();
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-
- dropEvent_sendReply(signal, evntRecPtr);
-}
-
-void
-Dbdict::dropEventUtilPrepareRef(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- UtilPrepareRef * const ref = (UtilPrepareRef *)signal->getDataPtr();
- OpDropEventPtr evntRecPtr;
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-
- interpretUtilPrepareErrorCode((UtilPrepareRef::ErrorCode)ref->getErrorCode(),
- evntRecPtr.p->m_errorCode, evntRecPtr.p->m_errorLine);
- evntRecPtr.p->m_errorNode = reference();
-
- dropEvent_sendReply(signal, evntRecPtr);
-}
-
-void
-Dbdict::dropEventUtilExecuteRef(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- jam();
- EVENT_TRACE;
- OpDropEventPtr evntRecPtr;
- UtilExecuteRef * const ref = (UtilExecuteRef *)signal->getDataPtr();
- jam();
- evntRecPtr.i = ref->getSenderData();
- ndbrequire((evntRecPtr.p = c_opDropEvent.getPtr(evntRecPtr.i)) != NULL);
-
- evntRecPtr.p->m_errorNode = reference();
- evntRecPtr.p->m_errorLine = __LINE__;
-
- switch (ref->getErrorCode()) {
- case UtilExecuteRef::TCError:
- switch (ref->getTCErrorCode()) {
- case ZNOT_FOUND:
- jam();
- evntRecPtr.p->m_errorCode = 4710;
- break;
- default:
- jam();
- evntRecPtr.p->m_errorCode = ref->getTCErrorCode();
- break;
- }
- break;
- default:
- jam();
- evntRecPtr.p->m_errorCode = ref->getErrorCode();
- break;
- }
- dropEvent_sendReply(signal, evntRecPtr);
-}
-
-void Dbdict::dropEvent_sendReply(Signal* signal,
- OpDropEventPtr evntRecPtr)
-{
- jam();
- EVENT_TRACE;
- Uint32 senderRef = evntRecPtr.p->m_request.getUserRef();
-
- if (evntRecPtr.p->hasError()) {
- jam();
- DropEvntRef * ret = (DropEvntRef *)signal->getDataPtrSend();
-
- ret->setUserData(evntRecPtr.p->m_request.getUserData());
- ret->setUserRef(evntRecPtr.p->m_request.getUserRef());
-
- ret->setErrorCode(evntRecPtr.p->m_errorCode);
- ret->setErrorLine(evntRecPtr.p->m_errorLine);
- ret->setErrorNode(evntRecPtr.p->m_errorNode);
-
- sendSignal(senderRef, GSN_DROP_EVNT_REF, signal,
- DropEvntRef::SignalLength, JBB);
- } else {
- jam();
- DropEvntConf * evntConf = (DropEvntConf *)signal->getDataPtrSend();
-
- evntConf->setUserData(evntRecPtr.p->m_request.getUserData());
- evntConf->setUserRef(evntRecPtr.p->m_request.getUserRef());
-
- sendSignal(senderRef, GSN_DROP_EVNT_CONF, signal,
- DropEvntConf::SignalLength, JBB);
- }
-
- c_opDropEvent.release(evntRecPtr);
-}
-
-/**
- * MODULE: Alter index
- *
- * Alter index state. Alter online creates the index in each TC and
- * then invokes create trigger and alter trigger protocols to activate
- * the 3 triggers. Alter offline does the opposite.
- *
- * Request type received in REQ and returned in CONF/REF:
- *
- * RT_USER - from API to DICT master
- * RT_CREATE_INDEX - part of create index operation
- * RT_DROP_INDEX - part of drop index operation
- * RT_NODERESTART - node restart, activate locally only
- * RT_SYSTEMRESTART - system restart, activate and build if not logged
- * RT_DICT_PREPARE - prepare participants
- * RT_DICT_TC - to local TC via each participant
- * RT_DICT_COMMIT - commit in each participant
- */
-
-void
-Dbdict::execALTER_INDX_REQ(Signal* signal)
-{
- jamEntry();
- AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
- OpAlterIndexPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const AlterIndxReq::RequestType requestType = req->getRequestType();
- if (requestType == AlterIndxReq::RT_USER ||
- requestType == AlterIndxReq::RT_CREATE_INDEX ||
- requestType == AlterIndxReq::RT_DROP_INDEX ||
- requestType == AlterIndxReq::RT_NODERESTART ||
- requestType == AlterIndxReq::RT_SYSTEMRESTART) {
- jam();
- const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (isLocal) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
- if (signal->getLength() == AlterIndxReq::SignalLength) {
- jam();
- if (! isLocal && getOwnNodeId() != c_masterNodeId) {
- jam();
-
- releaseSections(signal);
- OpAlterIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = AlterIndxRef::NotMaster;
- opPtr.p->m_errorLine = __LINE__;
- opPtr.p->m_errorNode = c_masterNodeId;
- alterIndex_sendReply(signal, opPtr, true);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_ALTER_INDX_REQ,
- signal, AlterIndxReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == AlterIndxReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpAlterIndex opBusy;
- if (! c_opAlterIndex.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = AlterIndxRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- alterIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opAlterIndex.add(opPtr);
- // master expects to hear from all
- if (opPtr.p->m_isMaster)
- opPtr.p->m_signalCounter = receiverNodes;
- // check request in all participants
- alterIndex_slavePrepare(signal, opPtr);
- alterIndex_sendReply(signal, opPtr, false);
- return;
- }
- c_opAlterIndex.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == AlterIndxReq::RT_DICT_TC) {
- jam();
- if (opPtr.p->m_request.getOnline())
- alterIndex_toCreateTc(signal, opPtr);
- else
- alterIndex_toDropTc(signal, opPtr);
- return;
- }
- if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
- requestType == AlterIndxReq::RT_DICT_ABORT) {
- jam();
- if (requestType == AlterIndxReq::RT_DICT_COMMIT)
- alterIndex_slaveCommit(signal, opPtr);
- else
- alterIndex_slaveAbort(signal, opPtr);
- alterIndex_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opAlterIndex.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- OpAlterIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = AlterIndxRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- alterIndex_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execALTER_INDX_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
- AlterIndxConf* conf = (AlterIndxConf*)signal->getDataPtrSend();
- alterIndex_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execALTER_INDX_REF(Signal* signal)
-{
- jamEntry();
- AlterIndxRef* ref = (AlterIndxRef*)signal->getDataPtrSend();
- alterIndex_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf,
- const AlterIndxRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const AlterIndxReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == AlterIndxReq::RT_CREATE_INDEX) {
- jam();
- // part of create index operation
- OpCreateIndexPtr opPtr;
- c_opCreateIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- createIndex_fromAlterIndex(signal, opPtr);
- return;
- }
- if (requestType == AlterIndxReq::RT_DROP_INDEX) {
- jam();
- // part of drop index operation
- OpDropIndexPtr opPtr;
- c_opDropIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- dropIndex_fromAlterIndex(signal, opPtr);
- return;
- }
- if (requestType == AlterIndxReq::RT_TC ||
- requestType == AlterIndxReq::RT_TUX) {
- jam();
- // part of build index operation
- OpBuildIndexPtr opPtr;
- c_opBuildIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- buildIndex_fromOnline(signal, opPtr);
- return;
- }
- if (requestType == AlterIndxReq::RT_NODERESTART) {
- jam();
- if (ref == 0) {
- infoEvent("DICT: index %u activated", (unsigned)key);
- } else {
- warningEvent("DICT: index %u activation failed: code=%d line=%d",
- (unsigned)key,
- ref->getErrorCode(), ref->getErrorLine());
- }
- activateIndexes(signal, key + 1);
- return;
- }
- if (requestType == AlterIndxReq::RT_SYSTEMRESTART) {
- jam();
- if (ref == 0) {
- infoEvent("DICT: index %u activated done", (unsigned)key);
- } else {
- warningEvent("DICT: index %u activated failed: code=%d line=%d node=%d",
- (unsigned)key,
- ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode());
- }
- activateIndexes(signal, key + 1);
- return;
- }
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == AlterIndxReq::RT_DICT_COMMIT ||
- requestType == AlterIndxReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- alterIndex_sendReply(signal, opPtr, true);
- c_opAlterIndex.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
- alterIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- if (indexPtr.p->isHashIndex()) {
- if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
- alterIndex_sendSlaveReq(signal, opPtr);
- } else {
- // start drop triggers
- alterIndex_toDropTrigger(signal, opPtr);
- }
- return;
- }
- if (requestType == AlterIndxReq::RT_DICT_TC) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- // start create triggers
- alterIndex_toCreateTrigger(signal, opPtr);
- } else {
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
- alterIndex_sendSlaveReq(signal, opPtr);
- }
- return;
- }
- }
- if (indexPtr.p->isOrderedIndex()) {
- if (requestType == AlterIndxReq::RT_DICT_PREPARE) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- // start create triggers
- alterIndex_toCreateTrigger(signal, opPtr);
- } else {
- // start drop triggers
- alterIndex_toDropTrigger(signal, opPtr);
- }
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- const AlterIndxReq* const req = &opPtr.p->m_request;
- if (! (req->getIndexId() < c_tableRecordPool.getSize())) {
- jam();
- opPtr.p->m_errorCode = AlterIndxRef::Inconsistency;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, req->getIndexId());
- if (indexPtr.p->tabState != TableRecord::DEFINED) {
- jam();
- opPtr.p->m_errorCode = AlterIndxRef::IndexNotFound;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- if (! indexPtr.p->isIndex()) {
- jam();
- opPtr.p->m_errorCode = AlterIndxRef::NotAnIndex;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- if (req->getOnline())
- indexPtr.p->indexState = TableRecord::IS_BUILDING;
- else
- indexPtr.p->indexState = TableRecord::IS_DROPPING;
-}
-
-void
-Dbdict::alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // request to create index in local TC
- CreateIndxReq* const req = (CreateIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(CreateIndxReq::RT_TC);
- req->setIndexType(indexPtr.p->tableType);
- req->setTableId(indexPtr.p->primaryTableId);
- req->setIndexId(indexPtr.i);
- req->setOnline(true);
- getIndexAttrList(indexPtr, opPtr.p->m_attrList);
- // send
- LinearSectionPtr lsPtr[3];
- lsPtr[0].p = (Uint32*)&opPtr.p->m_attrList;
- lsPtr[0].sz = 1 + opPtr.p->m_attrList.sz;
- sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_CREATE_INDX_REQ,
- signal, CreateIndxReq::SignalLength, JBB, lsPtr, 1);
-}
-
-void
-Dbdict::alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- // mark created in local TC
- if (! opPtr.p->hasLastError()) {
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- indexPtr.p->indexLocal |= TableRecord::IL_CREATED_TC;
- }
- // forward CONF or REF to master
- ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
- alterIndex_sendReply(signal, opPtr, false);
-}
-
-void
-Dbdict::alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // broken index allowed if force
- if (! (indexPtr.p->indexLocal & TableRecord::IL_CREATED_TC)) {
- jam();
- ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
- alterIndex_sendReply(signal, opPtr, false);
- return;
- }
- // request to drop in local TC
- DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(DropIndxReq::RT_TC);
- req->setTableId(indexPtr.p->primaryTableId);
- req->setIndexId(indexPtr.i);
- req->setIndexVersion(indexPtr.p->tableVersion);
- // send
- sendSignal(calcTcBlockRef(getOwnNodeId()), GSN_DROP_INDX_REQ,
- signal, DropIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- ndbrequire(opPtr.p->m_requestType == AlterIndxReq::RT_DICT_TC);
- // mark dropped locally
- if (! opPtr.p->hasLastError()) {
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- indexPtr.p->indexLocal &= ~TableRecord::IL_CREATED_TC;
- }
- // forward CONF or REF to master
- alterIndex_sendReply(signal, opPtr, false);
-}
-
-void
-Dbdict::alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // start creation of index triggers
- CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(CreateTrigReq::RT_ALTER_INDEX);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setIndexId(opPtr.p->m_request.getIndexId());
- req->setTriggerId(RNIL);
- req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
- req->setMonitorAllAttributes(false);
- req->setOnline(true); // alter online after create
- req->setReceiverRef(0); // implicit for index triggers
- getIndexAttrMask(indexPtr, req->getAttributeMask());
- // name section
- char triggerName[MAX_TAB_NAME_SIZE];
- Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
- LinearWriter w(buffer, sizeof(buffer) >> 2);
- LinearSectionPtr lsPtr[3];
- if (indexPtr.p->isHashIndex()) {
- req->setTriggerType(TriggerType::SECONDARY_INDEX);
- req->setMonitorReplicas(false);
- req->setReportAllMonitoredAttributes(true);
- // insert
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
- req->setTriggerId(indexPtr.p->insertTriggerId);
- req->setTriggerEvent(TriggerEvent::TE_INSERT);
- sprintf(triggerName, "NDB$INDEX_%u_INSERT", opPtr.p->m_request.getIndexId());
- w.reset();
- w.add(CreateTrigReq::TriggerNameKey, triggerName);
- lsPtr[0].p = buffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(reference(), GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
- // update
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
- req->setTriggerId(indexPtr.p->updateTriggerId);
- req->setTriggerEvent(TriggerEvent::TE_UPDATE);
- sprintf(triggerName, "NDB$INDEX_%u_UPDATE", opPtr.p->m_request.getIndexId());
- w.reset();
- w.add(CreateTrigReq::TriggerNameKey, triggerName);
- lsPtr[0].p = buffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(reference(), GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
- // delete
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
- req->setTriggerId(indexPtr.p->deleteTriggerId);
- req->setTriggerEvent(TriggerEvent::TE_DELETE);
- sprintf(triggerName, "NDB$INDEX_%u_DELETE", opPtr.p->m_request.getIndexId());
- w.reset();
- w.add(CreateTrigReq::TriggerNameKey, triggerName);
- lsPtr[0].p = buffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(reference(), GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
- // triggers left to create
- opPtr.p->m_triggerCounter = 3;
- return;
- }
- if (indexPtr.p->isOrderedIndex()) {
- req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
- req->setTriggerType(TriggerType::ORDERED_INDEX);
- req->setTriggerActionTime(TriggerActionTime::TA_CUSTOM);
- req->setMonitorReplicas(true);
- req->setReportAllMonitoredAttributes(true);
- // one trigger for 5 events (insert, update, delete, commit, abort)
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
- req->setTriggerId(indexPtr.p->customTriggerId);
- req->setTriggerEvent(TriggerEvent::TE_CUSTOM);
- sprintf(triggerName, "NDB$INDEX_%u_CUSTOM", opPtr.p->m_request.getIndexId());
- w.reset();
- w.add(CreateTrigReq::TriggerNameKey, triggerName);
- lsPtr[0].p = buffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(reference(), GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
- // triggers left to create
- opPtr.p->m_triggerCounter = 1;
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- ndbrequire(opPtr.p->m_triggerCounter != 0);
- if (--opPtr.p->m_triggerCounter != 0) {
- jam();
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
- alterIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- if(opPtr.p->m_requestType != AlterIndxReq::RT_SYSTEMRESTART){
- // send build request
- alterIndex_toBuildIndex(signal, opPtr);
- return;
- }
-
- /**
- * During system restart,
- * leave index in activated but not build state.
- *
- * Build a bit later when REDO has been run
- */
- alterIndex_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // start drop of index triggers
- DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(DropTrigReq::RT_ALTER_INDEX);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setIndexId(opPtr.p->m_request.getIndexId());
- req->setTriggerInfo(0); // not used
- opPtr.p->m_triggerCounter = 0;
- if (indexPtr.p->isHashIndex()) {
- // insert
- req->setTriggerId(indexPtr.p->insertTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- // update
- req->setTriggerId(indexPtr.p->updateTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- // delete
- req->setTriggerId(indexPtr.p->deleteTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- // build
- if (indexPtr.p->buildTriggerId != RNIL) {
- req->setTriggerId(indexPtr.p->buildTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- }
- return;
- }
- if (indexPtr.p->isOrderedIndex()) {
- // custom
- req->addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
- req->setTriggerId(indexPtr.p->customTriggerId);
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- opPtr.p->m_triggerCounter++;
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- ndbrequire(opPtr.p->m_triggerCounter != 0);
- if (--opPtr.p->m_triggerCounter != 0) {
- jam();
- return;
- }
- // finally drop index in each TC
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- const bool isHashIndex = indexPtr.p->isHashIndex();
- const bool isOrderedIndex = indexPtr.p->isOrderedIndex();
- ndbrequire(isHashIndex != isOrderedIndex); // xor
- if (isHashIndex)
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_TC;
- if (isOrderedIndex)
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
- alterIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- // get index and table records
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
- // build request to self (short signal)
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(BuildIndxReq::RT_ALTER_INDEX);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setBuildId(0); // not used
- req->setBuildKey(0); // not used
- req->setIndexType(indexPtr.p->tableType);
- req->setIndexId(indexPtr.i);
- req->setTableId(indexPtr.p->primaryTableId);
- req->setParallelism(16);
- // send
- sendSignal(reference(), GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_ABORT;
- alterIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = AlterIndxReq::RT_DICT_COMMIT;
- alterIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- // get index record
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- indexPtr.p->indexState = TableRecord::IS_ONLINE;
-}
-
-void
-Dbdict::alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr)
-{
- jam();
- // find index record
- const Uint32 indexId = opPtr.p->m_request.getIndexId();
- if (indexId >= c_tableRecordPool.getSize())
- return;
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, indexId);
- if (! indexPtr.p->isIndex())
- return;
- // mark broken
- indexPtr.p->indexState = TableRecord::IS_BROKEN;
-}
-
-void
-Dbdict::alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr)
-{
- AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
- opPtr.p->m_signalCounter = receiverNodes;
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_ALTER_INDX_REQ,
- signal, AlterIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr,
- bool toUser)
-{
- AlterIndxRef* rep = (AlterIndxRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_ALTER_INDX_CONF;
- Uint32 length = AlterIndxConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == AlterIndxReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = AlterIndxConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0)
- opPtr.p->m_errorNode = getOwnNodeId();
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_ALTER_INDX_REF;
- length = AlterIndxRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Build index
- *
- * Build index or all indexes on a table. Request type:
- *
- * RT_USER - normal user request, not yet used
- * RT_ALTER_INDEX - from alter index
- * RT_SYSTEM_RESTART -
- * RT_DICT_PREPARE - prepare participants
- * RT_DICT_TRIX - to participant on way to local TRIX
- * RT_DICT_COMMIT - commit in each participant
- * RT_DICT_ABORT - abort
- * RT_TRIX - to local TRIX
- */
-
-void
-Dbdict::execBUILDINDXREQ(Signal* signal)
-{
- jamEntry();
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
- OpBuildIndexPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const BuildIndxReq::RequestType requestType = req->getRequestType();
- if (requestType == BuildIndxReq::RT_USER ||
- requestType == BuildIndxReq::RT_ALTER_INDEX ||
- requestType == BuildIndxReq::RT_SYSTEMRESTART) {
- jam();
-
- const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (isLocal) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
-
- if (signal->getLength() == BuildIndxReq::SignalLength) {
- jam();
-
- if (!isLocal && getOwnNodeId() != c_masterNodeId) {
- jam();
-
- releaseSections(signal);
- OpBuildIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = BuildIndxRef::NotMaster;
- opPtr.p->m_errorLine = __LINE__;
- opPtr.p->m_errorNode = c_masterNodeId;
- buildIndex_sendReply(signal, opPtr, true);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == BuildIndxReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpBuildIndex opBusy;
- if (! c_opBuildIndex.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = BuildIndxRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- buildIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opBuildIndex.add(opPtr);
- // master expects to hear from all
- opPtr.p->m_signalCounter = receiverNodes;
- buildIndex_sendReply(signal, opPtr, false);
- return;
- }
- c_opBuildIndex.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == BuildIndxReq::RT_DICT_TRIX) {
- jam();
- buildIndex_buildTrix(signal, opPtr);
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_TC ||
- requestType == BuildIndxReq::RT_DICT_TUX) {
- jam();
- buildIndex_toOnline(signal, opPtr);
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
- requestType == BuildIndxReq::RT_DICT_ABORT) {
- jam();
- buildIndex_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opBuildIndex.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- OpBuildIndex opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = BuildIndxRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- buildIndex_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execBUILDINDXCONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
- BuildIndxConf* conf = (BuildIndxConf*)signal->getDataPtrSend();
- buildIndex_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execBUILDINDXREF(Signal* signal)
-{
- jamEntry();
- BuildIndxRef* ref = (BuildIndxRef*)signal->getDataPtrSend();
- buildIndex_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf,
- const BuildIndxRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const BuildIndxReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == BuildIndxReq::RT_ALTER_INDEX) {
- jam();
- // part of alter index operation
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterIndex_fromBuildIndex(signal, opPtr);
- return;
- }
-
- if (requestType == BuildIndxReq::RT_SYSTEMRESTART) {
- jam();
- if (ref == 0) {
- infoEvent("DICT: index %u rebuild done", (unsigned)key);
- } else {
- warningEvent("DICT: index %u rebuild failed: code=%d line=%d node=%d",
- (unsigned)key, ref->getErrorCode());
- }
- rebuildIndexes(signal, key + 1);
- return;
- }
-
- OpBuildIndexPtr opPtr;
- c_opBuildIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- if (requestType == BuildIndxReq::RT_TRIX) {
- jam();
- // forward to master
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
- buildIndex_sendReply(signal, opPtr, false);
- return;
- }
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_COMMIT ||
- requestType == BuildIndxReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- buildIndex_sendReply(signal, opPtr, true);
- c_opBuildIndex.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- if (indexPtr.p->isHashIndex()) {
- if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
- jam();
- if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
- buildIndex_toCreateConstr(signal, opPtr);
- } else {
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
- buildIndex_sendSlaveReq(signal, opPtr);
- }
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_TRIX) {
- jam();
- ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
- buildIndex_toDropConstr(signal, opPtr);
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_TC) {
- jam();
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- }
- if (indexPtr.p->isOrderedIndex()) {
- if (requestType == BuildIndxReq::RT_DICT_PREPARE) {
- jam();
- if (! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD)) {
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
- buildIndex_sendSlaveReq(signal, opPtr);
- } else {
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
- buildIndex_sendSlaveReq(signal, opPtr);
- }
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_TRIX) {
- jam();
- ndbrequire(! (opPtr.p->m_requestFlag & RequestFlag::RF_NOBUILD));
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TUX;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == BuildIndxReq::RT_DICT_TUX) {
- jam();
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_COMMIT;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // request to create constraint trigger
- CreateTrigReq* req = (CreateTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(CreateTrigReq::RT_BUILD_INDEX);
- req->addRequestFlag(0); // none
- req->setTableId(indexPtr.i);
- req->setIndexId(RNIL);
- req->setTriggerId(RNIL);
- req->setTriggerType(TriggerType::READ_ONLY_CONSTRAINT);
- req->setTriggerActionTime(TriggerActionTime::TA_AFTER);
- req->setTriggerEvent(TriggerEvent::TE_UPDATE);
- req->setMonitorReplicas(false);
- req->setMonitorAllAttributes(false);
- req->setReportAllMonitoredAttributes(true);
- req->setOnline(true); // alter online after create
- req->setReceiverRef(0); // no receiver, REF-ed by TUP
- req->getAttributeMask().clear();
- // NDB$PK is last attribute
- req->getAttributeMask().set(indexPtr.p->noOfAttributes - 1);
- // name section
- char triggerName[MAX_TAB_NAME_SIZE];
- Uint32 buffer[2 + ((MAX_TAB_NAME_SIZE + 3) >> 2)]; // SP string
- LinearWriter w(buffer, sizeof(buffer) >> 2);
- LinearSectionPtr lsPtr[3];
- sprintf(triggerName, "NDB$INDEX_%u_BUILD", indexPtr.i);
- w.reset();
- w.add(CreateTrigReq::TriggerNameKey, triggerName);
- lsPtr[0].p = buffer;
- lsPtr[0].sz = w.getWordsUsed();
- sendSignal(reference(), GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB, lsPtr, 1);
-}
-
-void
-Dbdict::buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TRIX;
- buildIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
- // build request
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(BuildIndxReq::RT_TRIX);
- req->setBuildId(0); // not yet..
- req->setBuildKey(0); // ..in use
- req->setIndexType(indexPtr.p->tableType);
- req->setIndexId(indexPtr.i);
- req->setTableId(indexPtr.p->primaryTableId);
- req->setParallelism(16);
- if (indexPtr.p->isHashIndex()) {
- jam();
- getIndexAttrList(indexPtr, opPtr.p->m_attrList);
- getTableKeyList(tablePtr, opPtr.p->m_tableKeyList);
- // send
- LinearSectionPtr lsPtr[3];
- lsPtr[0].sz = opPtr.p->m_attrList.sz;
- lsPtr[0].p = opPtr.p->m_attrList.id;
- lsPtr[1].sz = opPtr.p->m_tableKeyList.sz;
- lsPtr[1].p = opPtr.p->m_tableKeyList.id;
- sendSignal(calcTrixBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB, lsPtr, 2);
- return;
- }
- if (indexPtr.p->isOrderedIndex()) {
- jam();
- sendSignal(calcTupBlockRef(getOwnNodeId()), GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- // request to drop constraint trigger
- DropTrigReq* req = (DropTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(DropTrigReq::RT_BUILD_INDEX);
- req->addRequestFlag(0); // none
- req->setTableId(indexPtr.i);
- req->setIndexId(RNIL);
- req->setTriggerId(opPtr.p->m_constrTriggerId);
- req->setTriggerInfo(0); // not used
- sendSignal(reference(), GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_ABORT;
- buildIndex_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = BuildIndxReq::RT_DICT_TC;
- buildIndex_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, opPtr.p->m_request.getIndexId());
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
- // request to set index online in TC or TUX
- AlterIndxReq* const req = (AlterIndxReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
- jam();
- req->setRequestType(AlterIndxReq::RT_TC);
- } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
- jam();
- req->setRequestType(AlterIndxReq::RT_TUX);
- } else {
- ndbrequire(false);
- }
- req->setTableId(tablePtr.i);
- req->setIndexId(indexPtr.i);
- req->setIndexVersion(indexPtr.p->tableVersion);
- req->setOnline(true);
- BlockReference blockRef = 0;
- if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TC) {
- jam();
- blockRef = calcTcBlockRef(getOwnNodeId());
- } else if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_TUX) {
- jam();
- blockRef = calcTuxBlockRef(getOwnNodeId());
- } else {
- ndbrequire(false);
- }
- // send
- sendSignal(blockRef, GSN_ALTER_INDX_REQ,
- signal, BuildIndxReq::SignalLength, JBB);
-}
-
-void
-Dbdict::buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr)
-{
- jam();
- // forward to master
- buildIndex_sendReply(signal, opPtr, false);
-}
-
-void
-Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
-{
- BuildIndxReq* const req = (BuildIndxReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
- jam();
- opPtr.p->m_signalCounter.clearWaitingFor();
- opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
- sendSignal(reference(), GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
- } else {
- jam();
- opPtr.p->m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
- }
-}
-
-void
-Dbdict::buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr,
- bool toUser)
-{
- BuildIndxRef* rep = (BuildIndxRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_BUILDINDXCONF;
- Uint32 length = BuildIndxConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == BuildIndxReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = BuildIndxConf::SignalLength;
- }
- rep->setIndexType(opPtr.p->m_request.getIndexType());
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- if (sendRef) {
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->masterNodeId = opPtr.p->m_errorNode;
- gsn = GSN_BUILDINDXREF;
- length = BuildIndxRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Create trigger
- *
- * Create trigger in all DICT blocks. Optionally start alter trigger
- * operation to set the trigger online.
- *
- * Request type received in REQ and returned in CONF/REF:
- *
- * RT_USER - normal user e.g. BACKUP
- * RT_ALTER_INDEX - from alter index online
- * RT_DICT_PREPARE - seize operation in each DICT
- * RT_DICT_COMMIT - commit create in each DICT
- * RT_TC - sending to TC (operation alter trigger)
- * RT_LQH - sending to LQH (operation alter trigger)
- */
-
-void
-Dbdict::execCREATE_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
- OpCreateTriggerPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const CreateTrigReq::RequestType requestType = req->getRequestType();
- if (requestType == CreateTrigReq::RT_USER ||
- requestType == CreateTrigReq::RT_ALTER_INDEX ||
- requestType == CreateTrigReq::RT_BUILD_INDEX) {
- jam();
- if (! assembleFragments(signal)) {
- jam();
- return;
- }
- const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (isLocal) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
- if (signal->getLength() == CreateTrigReq::SignalLength) {
- jam();
- if (! isLocal && getOwnNodeId() != c_masterNodeId) {
- jam();
-
- releaseSections(signal);
- OpCreateTrigger opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = CreateTrigRef::NotMaster;
- opPtr.p->m_errorLine = __LINE__;
- opPtr.p->m_errorNode = c_masterNodeId;
- createTrigger_sendReply(signal, opPtr, true);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == CreateTrigReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpCreateTrigger opBusy;
- if (! c_opCreateTrigger.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opCreateTrigger.add(opPtr);
- {
- // save name
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
- SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
- if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
- ! ssReader.getString(opPtr.p->m_triggerName)) {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::InvalidName;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- }
- releaseSections(signal);
- if(get_object(opPtr.p->m_triggerName) != 0){
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::TriggerExists;
- opPtr.p->m_errorLine = __LINE__;
- createTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
-
- // master expects to hear from all
- if (opPtr.p->m_isMaster)
- opPtr.p->m_signalCounter = receiverNodes;
- // check request in all participants
- createTrigger_slavePrepare(signal, opPtr);
- createTrigger_sendReply(signal, opPtr, false);
- return;
- }
- c_opCreateTrigger.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == CreateTrigReq::RT_DICT_CREATE) {
- jam();
- // master has set trigger id
- opPtr.p->m_request.setTriggerId(req->getTriggerId());
- createTrigger_slaveCreate(signal, opPtr);
- createTrigger_sendReply(signal, opPtr, false);
- return;
- }
- if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
- requestType == CreateTrigReq::RT_DICT_ABORT) {
- jam();
- if (requestType == CreateTrigReq::RT_DICT_COMMIT)
- createTrigger_slaveCommit(signal, opPtr);
- else
- createTrigger_slaveAbort(signal, opPtr);
- createTrigger_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opCreateTrigger.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- releaseSections(signal);
- OpCreateTrigger opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = CreateTrigRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- createTrigger_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execCREATE_TRIG_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(signal->getNoOfSections() == 0);
- CreateTrigConf* conf = (CreateTrigConf*)signal->getDataPtrSend();
- createTrigger_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execCREATE_TRIG_REF(Signal* signal)
-{
- jamEntry();
- CreateTrigRef* ref = (CreateTrigRef*)signal->getDataPtrSend();
- createTrigger_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf,
- const CreateTrigRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const CreateTrigReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == CreateTrigReq::RT_ALTER_INDEX) {
- jam();
- // part of alter index operation
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterIndex_fromCreateTrigger(signal, opPtr);
- return;
- }
- if (requestType == CreateTrigReq::RT_BUILD_INDEX) {
- jam();
- // part of build index operation
- OpBuildIndexPtr opPtr;
- c_opBuildIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- // fill in trigger id
- opPtr.p->m_constrTriggerId = conf->getTriggerId();
- buildIndex_fromCreateConstr(signal, opPtr);
- return;
- }
- if (requestType == CreateTrigReq::RT_TC ||
- requestType == CreateTrigReq::RT_LQH) {
- jam();
- // part of alter trigger operation
- OpAlterTriggerPtr opPtr;
- c_opAlterTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterTrigger_fromCreateLocal(signal, opPtr);
- return;
- }
- OpCreateTriggerPtr opPtr;
- c_opCreateTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == CreateTrigReq::RT_DICT_COMMIT ||
- requestType == CreateTrigReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- createTrigger_sendReply(signal, opPtr, true);
- c_opCreateTrigger.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
- createTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == CreateTrigReq::RT_DICT_PREPARE) {
- jam();
- // seize trigger id in master
- createTrigger_masterSeize(signal, opPtr);
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
- createTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_CREATE;
- createTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == CreateTrigReq::RT_DICT_CREATE) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- jam();
- // start alter online
- createTrigger_toAlterTrigger(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
- createTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
- const CreateTrigReq* const req = &opPtr.p->m_request;
- // check trigger type
- if (req->getRequestType() == CreateTrigReq::RT_USER &&
- req->getTriggerType() == TriggerType::SUBSCRIPTION ||
- req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
- req->getTriggerType() == TriggerType::SECONDARY_INDEX ||
- req->getRequestType() == CreateTrigReq::RT_ALTER_INDEX &&
- req->getTriggerType() == TriggerType::ORDERED_INDEX ||
- req->getRequestType() == CreateTrigReq::RT_BUILD_INDEX &&
- req->getTriggerType() == TriggerType::READ_ONLY_CONSTRAINT) {
- ;
- } else {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::UnsupportedTriggerType;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- // check the table
- const Uint32 tableId = req->getTableId();
- if (! (tableId < c_tableRecordPool.getSize())) {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- TableRecordPtr tablePtr;
- c_tableRecordPool.getPtr(tablePtr, tableId);
- if (tablePtr.p->tabState != TableRecord::DEFINED &&
- tablePtr.p->tabState != TableRecord::BACKUP_ONGOING) {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::InvalidTable;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
-}
-
-void
-Dbdict::createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- TriggerRecordPtr triggerPtr;
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
- triggerPtr.i = opPtr.p->m_request.getTriggerId();
- } else {
- triggerPtr.i = getFreeTriggerRecord();
- if (triggerPtr.i == RNIL) {
- jam();
- opPtr.p->m_errorCode = CreateTrigRef::TooManyTriggers;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- }
- c_triggerRecordPool.getPtr(triggerPtr);
- initialiseTriggerRecord(triggerPtr);
- triggerPtr.p->triggerState = TriggerRecord::TS_DEFINING;
- opPtr.p->m_request.setTriggerId(triggerPtr.i);
-}
-
-void
-Dbdict::createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
- const CreateTrigReq* const req = &opPtr.p->m_request;
- // get the trigger record
- const Uint32 triggerId = req->getTriggerId();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, triggerId);
- initialiseTriggerRecord(triggerPtr);
- // fill in trigger data
- {
- Rope name(c_rope_pool, triggerPtr.p->triggerName);
- if(!name.assign(opPtr.p->m_triggerName))
- {
- opPtr.p->m_errorCode = (CreateTrigRef::ErrorCode)CreateTableRef::OutOfStringBuffer;
- return;
- }
- }
- triggerPtr.p->triggerId = triggerId;
- triggerPtr.p->tableId = req->getTableId();
- triggerPtr.p->indexId = RNIL;
- triggerPtr.p->triggerType = req->getTriggerType();
- triggerPtr.p->triggerActionTime = req->getTriggerActionTime();
- triggerPtr.p->triggerEvent = req->getTriggerEvent();
- triggerPtr.p->monitorReplicas = req->getMonitorReplicas();
- triggerPtr.p->monitorAllAttributes = req->getMonitorAllAttributes();
- triggerPtr.p->reportAllMonitoredAttributes = req->getReportAllMonitoredAttributes();
- triggerPtr.p->attributeMask = req->getAttributeMask();
- triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
- // add to hash table
- // ndbout_c("++++++++++++ Adding trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
- {
- Ptr<DictObject> obj_ptr;
- ndbrequire(c_obj_hash.seize(obj_ptr));
- obj_ptr.p->m_name = triggerPtr.p->triggerName;
- obj_ptr.p->m_id = triggerId;
- obj_ptr.p->m_type = triggerPtr.p->triggerType;
- obj_ptr.p->m_ref_count = 0;
- c_obj_hash.add(obj_ptr);
- triggerPtr.p->m_obj_ptr_i = obj_ptr.i;
- }
- if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
- triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
- jam();
- // connect to index record XXX should be done in caller instead
- triggerPtr.p->indexId = req->getIndexId();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
- switch (triggerPtr.p->triggerEvent) {
- case TriggerEvent::TE_INSERT:
- indexPtr.p->insertTriggerId = triggerPtr.p->triggerId;
- break;
- case TriggerEvent::TE_UPDATE:
- indexPtr.p->updateTriggerId = triggerPtr.p->triggerId;
- break;
- case TriggerEvent::TE_DELETE:
- indexPtr.p->deleteTriggerId = triggerPtr.p->triggerId;
- break;
- case TriggerEvent::TE_CUSTOM:
- indexPtr.p->customTriggerId = triggerPtr.p->triggerId;
- break;
- default:
- ndbrequire(false);
- break;
- }
- }
- if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
- jam();
- // connect to index record XXX should be done in caller instead
- triggerPtr.p->indexId = req->getTableId();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
- indexPtr.p->buildTriggerId = triggerPtr.p->triggerId;
- }
-}
-
-void
-Dbdict::createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
- AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(AlterTrigReq::RT_CREATE_TRIGGER);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setTriggerId(opPtr.p->m_request.getTriggerId());
- req->setTriggerInfo(0); // not used
- req->setOnline(true);
- req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
- sendSignal(reference(), GSN_ALTER_TRIG_REQ,
- signal, AlterTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_ABORT;
- createTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- opPtr.p->m_requestType = CreateTrigReq::RT_DICT_COMMIT;
- createTrigger_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
- const CreateTrigReq* const req = &opPtr.p->m_request;
- // get the trigger record
- const Uint32 triggerId = req->getTriggerId();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, triggerId);
- if (! req->getOnline()) {
- triggerPtr.p->triggerState = TriggerRecord::TS_OFFLINE;
- } else {
- ndbrequire(triggerPtr.p->triggerState == TriggerRecord::TS_ONLINE);
- }
-}
-
-void
-Dbdict::createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- jam();
-}
-
-void
-Dbdict::createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr)
-{
- CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
- opPtr.p->m_signalCounter = receiverNodes;
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr,
- bool toUser)
-{
- CreateTrigRef* rep = (CreateTrigRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_CREATE_TRIG_CONF;
- Uint32 length = CreateTrigConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == CreateTrigReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = CreateTrigConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- rep->setTriggerId(opPtr.p->m_request.getTriggerId());
- rep->setTriggerInfo(opPtr.p->m_request.getTriggerInfo());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0)
- opPtr.p->m_errorNode = getOwnNodeId();
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_CREATE_TRIG_REF;
- length = CreateTrigRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Drop trigger.
- */
-
-void
-Dbdict::execDROP_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
- OpDropTriggerPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const DropTrigReq::RequestType requestType = req->getRequestType();
-
- if (signal->getNoOfSections() > 0) {
- ndbrequire(signal->getNoOfSections() == 1);
- jam();
- char triggerName[MAX_TAB_NAME_SIZE];
- OpDropTrigger opTmp;
- opPtr.p=&opTmp;
-
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
- SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
- if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
- ! ssReader.getString(triggerName)) {
- jam();
- opPtr.p->m_errorCode = DropTrigRef::InvalidName;
- opPtr.p->m_errorLine = __LINE__;
- releaseSections(signal);
- dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- releaseSections(signal);
-
- //ndbout_c("++++++++++++++ Looking for trigger %s", keyRecord.triggerName);
- DictObject * obj_ptr_p = get_object(triggerName);
- if (obj_ptr_p == 0){
- jam();
- req->setTriggerId(RNIL);
- } else {
- jam();
- //ndbout_c("++++++++++ Found trigger %s", triggerPtr.p->triggerName);
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, obj_ptr_p->m_id);
- req->setTriggerId(triggerPtr.p->triggerId);
- req->setTableId(triggerPtr.p->tableId);
- }
- }
- if (requestType == DropTrigReq::RT_USER ||
- requestType == DropTrigReq::RT_ALTER_INDEX ||
- requestType == DropTrigReq::RT_BUILD_INDEX) {
- jam();
- if (signal->getLength() == DropTrigReq::SignalLength) {
- if (getOwnNodeId() != c_masterNodeId) {
- jam();
- // forward to DICT master
- sendSignal(calcDictBlockRef(c_masterNodeId), GSN_DROP_TRIG_REQ,
- signal, signal->getLength(), JBB);
- return;
- }
- if (!c_triggerRecordPool.findId(req->getTriggerId())) {
- jam();
- // return to sender
- OpDropTrigger opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- if (! (req->getRequestFlag() & RequestFlag::RF_FORCE)) {
- opPtr.p->m_errorCode = DropTrigRef::TriggerNotFound;
- opPtr.p->m_errorLine = __LINE__;
- }
- dropTrigger_sendReply(signal, opPtr, true);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == DropTrigReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpDropTrigger opBusy;
- if (! c_opDropTrigger.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = DropTrigReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = DropTrigRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- dropTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opDropTrigger.add(opPtr);
- // master expects to hear from all
- if (opPtr.p->m_isMaster)
- opPtr.p->m_signalCounter = c_aliveNodes;
- dropTrigger_slavePrepare(signal, opPtr);
- dropTrigger_sendReply(signal, opPtr, false);
- return;
- }
- c_opDropTrigger.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == DropTrigReq::RT_DICT_COMMIT ||
- requestType == DropTrigReq::RT_DICT_ABORT) {
- jam();
- if (requestType == DropTrigReq::RT_DICT_COMMIT)
- dropTrigger_slaveCommit(signal, opPtr);
- else
- dropTrigger_slaveAbort(signal, opPtr);
- dropTrigger_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opDropTrigger.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- OpDropTrigger opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = DropTrigRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- dropTrigger_sendReply(signal, opPtr, true);
-}
-
-void
-Dbdict::execDROP_TRIG_CONF(Signal* signal)
-{
- jamEntry();
- DropTrigConf* conf = (DropTrigConf*)signal->getDataPtrSend();
- dropTrigger_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execDROP_TRIG_REF(Signal* signal)
-{
- jamEntry();
- DropTrigRef* ref = (DropTrigRef*)signal->getDataPtrSend();
- dropTrigger_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf,
- const DropTrigRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const DropTrigReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == DropTrigReq::RT_ALTER_INDEX) {
- jam();
- // part of alter index operation
- OpAlterIndexPtr opPtr;
- c_opAlterIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterIndex_fromDropTrigger(signal, opPtr);
- return;
- }
- if (requestType == DropTrigReq::RT_BUILD_INDEX) {
- jam();
- // part of build index operation
- OpBuildIndexPtr opPtr;
- c_opBuildIndex.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- buildIndex_fromDropConstr(signal, opPtr);
- return;
- }
- if (requestType == DropTrigReq::RT_TC ||
- requestType == DropTrigReq::RT_LQH) {
- jam();
- // part of alter trigger operation
- OpAlterTriggerPtr opPtr;
- c_opAlterTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- alterTrigger_fromDropLocal(signal, opPtr);
- return;
- }
- OpDropTriggerPtr opPtr;
- c_opDropTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == DropTrigReq::RT_DICT_COMMIT ||
- requestType == DropTrigReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- dropTrigger_sendReply(signal, opPtr, true);
- c_opDropTrigger.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = DropTrigReq::RT_DICT_ABORT;
- dropTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == DropTrigReq::RT_DICT_PREPARE) {
- jam();
- // start alter offline
- dropTrigger_toAlterTrigger(signal, opPtr);
- return;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr)
-{
- jam();
-}
-
-void
-Dbdict::dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
-{
- jam();
- AlterTrigReq* req = (AlterTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(AlterTrigReq::RT_DROP_TRIGGER);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- req->setTableId(opPtr.p->m_request.getTableId());
- req->setTriggerId(opPtr.p->m_request.getTriggerId());
- req->setTriggerInfo(0); // not used
- req->setOnline(false);
- req->setReceiverRef(0);
- sendSignal(reference(), GSN_ALTER_TRIG_REQ,
- signal, AlterTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr)
-{
- jam();
- // remove in all
- opPtr.p->m_requestType = DropTrigReq::RT_DICT_COMMIT;
- dropTrigger_sendSlaveReq(signal, opPtr);
-}
-
-void
-Dbdict::dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr)
-{
- DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- opPtr.p->m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr)
-{
- jam();
- const DropTrigReq* const req = &opPtr.p->m_request;
- // get trigger record
- const Uint32 triggerId = req->getTriggerId();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, triggerId);
- if (triggerPtr.p->triggerType == TriggerType::SECONDARY_INDEX ||
- triggerPtr.p->triggerType == TriggerType::ORDERED_INDEX) {
- jam();
- // disconnect from index if index trigger XXX move to drop index
- triggerPtr.p->indexId = req->getIndexId();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
- ndbrequire(! indexPtr.isNull());
- switch (triggerPtr.p->triggerEvent) {
- case TriggerEvent::TE_INSERT:
- indexPtr.p->insertTriggerId = RNIL;
- break;
- case TriggerEvent::TE_UPDATE:
- indexPtr.p->updateTriggerId = RNIL;
- break;
- case TriggerEvent::TE_DELETE:
- indexPtr.p->deleteTriggerId = RNIL;
- break;
- case TriggerEvent::TE_CUSTOM:
- indexPtr.p->customTriggerId = RNIL;
- break;
- default:
- ndbrequire(false);
- break;
- }
- }
- if (triggerPtr.p->triggerType == TriggerType::READ_ONLY_CONSTRAINT) {
- jam();
- // disconnect from index record XXX should be done in caller instead
- triggerPtr.p->indexId = req->getTableId();
- TableRecordPtr indexPtr;
- c_tableRecordPool.getPtr(indexPtr, triggerPtr.p->indexId);
- indexPtr.p->buildTriggerId = RNIL;
- }
- //remove trigger
- //ndbout_c("++++++++++++ Removing trigger id %u, %s", triggerPtr.p->triggerId, triggerPtr.p->triggerName);
- release_object(triggerPtr.p->m_obj_ptr_i);
- triggerPtr.p->triggerState = TriggerRecord::TS_NOT_DEFINED;
-}
-
-void
-Dbdict::dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr)
-{
- jam();
-}
-
-void
-Dbdict::dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr,
- bool toUser)
-{
- DropTrigRef* rep = (DropTrigRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_DROP_TRIG_CONF;
- Uint32 length = DropTrigConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == DropTrigReq::RT_DICT_ABORT)
- sendRef = false;
- } else {
- sendRef = opPtr.p->hasError();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = DropTrigConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setIndexId(opPtr.p->m_request.getIndexId());
- rep->setTriggerId(opPtr.p->m_request.getTriggerId());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0)
- opPtr.p->m_errorNode = getOwnNodeId();
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_DROP_TRIG_REF;
- length = CreateTrigRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Alter trigger.
- *
- * Alter trigger state. Alter online creates the trigger first in all
- * TC (if index trigger) and then in all LQH-TUP.
- *
- * Request type received in REQ and returned in CONF/REF:
- *
- * RT_USER - normal user e.g. BACKUP
- * RT_CREATE_TRIGGER - from create trigger
- * RT_DROP_TRIGGER - from drop trigger
- * RT_DICT_PREPARE - seize operations and check request
- * RT_DICT_TC - master to each DICT on way to TC
- * RT_DICT_LQH - master to each DICT on way to LQH-TUP
- * RT_DICT_COMMIT - commit state change in each DICT (no reply)
- */
-
-void
-Dbdict::execALTER_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
- OpAlterTriggerPtr opPtr;
- const Uint32 senderRef = signal->senderBlockRef();
- const AlterTrigReq::RequestType requestType = req->getRequestType();
- if (requestType == AlterTrigReq::RT_USER ||
- requestType == AlterTrigReq::RT_CREATE_TRIGGER ||
- requestType == AlterTrigReq::RT_DROP_TRIGGER) {
- jam();
- const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (isLocal) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- }
- if (signal->getLength() == AlterTrigReq::SignalLength) {
- jam();
- if (! isLocal && getOwnNodeId() != c_masterNodeId) {
- jam();
- // forward to DICT master
- sendSignal(calcDictBlockRef(c_masterNodeId), GSN_ALTER_TRIG_REQ,
- signal, AlterTrigReq::SignalLength, JBB);
- return;
- }
- // forward initial request plus operation key to all
- req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_ALTER_TRIG_REQ,
- signal, AlterTrigReq::SignalLength + 1, JBB);
- return;
- }
- // seize operation record
- ndbrequire(signal->getLength() == AlterTrigReq::SignalLength + 1);
- const Uint32 opKey = req->getOpKey();
- OpAlterTrigger opBusy;
- if (! c_opAlterTrigger.seize(opPtr))
- opPtr.p = &opBusy;
- opPtr.p->save(req);
- opPtr.p->m_coordinatorRef = senderRef;
- opPtr.p->m_isMaster = (senderRef == reference());
- opPtr.p->key = opKey;
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_PREPARE;
- if (opPtr.p == &opBusy) {
- jam();
- opPtr.p->m_errorCode = AlterTrigRef::Busy;
- opPtr.p->m_errorLine = __LINE__;
- alterTrigger_sendReply(signal, opPtr, opPtr.p->m_isMaster);
- return;
- }
- c_opAlterTrigger.add(opPtr);
- // master expects to hear from all
- if (opPtr.p->m_isMaster) {
- opPtr.p->m_nodes = receiverNodes;
- opPtr.p->m_signalCounter = receiverNodes;
- }
- alterTrigger_slavePrepare(signal, opPtr);
- alterTrigger_sendReply(signal, opPtr, false);
- return;
- }
- c_opAlterTrigger.find(opPtr, req->getConnectionPtr());
- if (! opPtr.isNull()) {
- opPtr.p->m_requestType = requestType;
- if (requestType == AlterTrigReq::RT_DICT_TC ||
- requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- if (req->getOnline())
- alterTrigger_toCreateLocal(signal, opPtr);
- else
- alterTrigger_toDropLocal(signal, opPtr);
- return;
- }
- if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
- requestType == AlterTrigReq::RT_DICT_ABORT) {
- jam();
- if (requestType == AlterTrigReq::RT_DICT_COMMIT)
- alterTrigger_slaveCommit(signal, opPtr);
- else
- alterTrigger_slaveAbort(signal, opPtr);
- alterTrigger_sendReply(signal, opPtr, false);
- // done in slave
- if (! opPtr.p->m_isMaster)
- c_opAlterTrigger.release(opPtr);
- return;
- }
- }
- jam();
- // return to sender
- OpAlterTrigger opBad;
- opPtr.p = &opBad;
- opPtr.p->save(req);
- opPtr.p->m_errorCode = AlterTrigRef::BadRequestType;
- opPtr.p->m_errorLine = __LINE__;
- alterTrigger_sendReply(signal, opPtr, true);
- return;
-}
-
-void
-Dbdict::execALTER_TRIG_CONF(Signal* signal)
-{
- jamEntry();
- AlterTrigConf* conf = (AlterTrigConf*)signal->getDataPtrSend();
- alterTrigger_recvReply(signal, conf, 0);
-}
-
-void
-Dbdict::execALTER_TRIG_REF(Signal* signal)
-{
- jamEntry();
- AlterTrigRef* ref = (AlterTrigRef*)signal->getDataPtrSend();
- alterTrigger_recvReply(signal, ref->getConf(), ref);
-}
-
-void
-Dbdict::alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
- const AlterTrigRef* ref)
-{
- jam();
- const Uint32 senderRef = signal->senderBlockRef();
- const AlterTrigReq::RequestType requestType = conf->getRequestType();
- const Uint32 key = conf->getConnectionPtr();
- if (requestType == AlterTrigReq::RT_CREATE_TRIGGER) {
- jam();
- // part of create trigger operation
- OpCreateTriggerPtr opPtr;
- c_opCreateTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- createTrigger_fromAlterTrigger(signal, opPtr);
- return;
- }
- if (requestType == AlterTrigReq::RT_DROP_TRIGGER) {
- jam();
- // part of drop trigger operation
- OpDropTriggerPtr opPtr;
- c_opDropTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- opPtr.p->setError(ref);
- dropTrigger_fromAlterTrigger(signal, opPtr);
- return;
- }
- OpAlterTriggerPtr opPtr;
- c_opAlterTrigger.find(opPtr, key);
- ndbrequire(! opPtr.isNull());
- ndbrequire(opPtr.p->m_isMaster);
- ndbrequire(opPtr.p->m_requestType == requestType);
- /*
- * If refuse on drop trig, because of non-existent trigger,
- * comes from anyone but the master node - ignore it and
- * remove the node from forter ALTER_TRIG communication
- * This will happen if a new node has started since the
- * trigger whas created.
- */
- if (ref &&
- refToNode(senderRef) != refToNode(reference()) &&
- opPtr.p->m_request.getRequestType() == AlterTrigReq::RT_DROP_TRIGGER &&
- ref->getErrorCode() == AlterTrigRef::TriggerNotFound) {
- jam();
- ref = 0; // ignore this error
- opPtr.p->m_nodes.clear(refToNode(senderRef)); // remove this from group
- }
- opPtr.p->setError(ref);
- opPtr.p->m_signalCounter.clearWaitingFor(refToNode(senderRef));
- if (! opPtr.p->m_signalCounter.done()) {
- jam();
- return;
- }
- if (requestType == AlterTrigReq::RT_DICT_COMMIT ||
- requestType == AlterTrigReq::RT_DICT_ABORT) {
- jam();
- // send reply to user
- alterTrigger_sendReply(signal, opPtr, true);
- c_opAlterTrigger.release(opPtr);
- return;
- }
- if (opPtr.p->hasError()) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_ABORT;
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (! (opPtr.p->m_request.getRequestFlag() & RequestFlag::RF_NOTCTRIGGER)) {
- if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
- } else {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
- }
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
- } else {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
- }
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- if (opPtr.p->m_request.getOnline()) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
- } else {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_TC;
- }
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- } else {
- if (requestType == AlterTrigReq::RT_DICT_PREPARE) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_LQH;
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- if (requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- opPtr.p->m_requestType = AlterTrigReq::RT_DICT_COMMIT;
- alterTrigger_sendSlaveReq(signal, opPtr);
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- const AlterTrigReq* const req = &opPtr.p->m_request;
- const Uint32 triggerId = req->getTriggerId();
- TriggerRecordPtr triggerPtr;
- if (! (triggerId < c_triggerRecordPool.getSize())) {
- jam();
- opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
- c_triggerRecordPool.getPtr(triggerPtr, triggerId);
- if (triggerPtr.p->triggerState == TriggerRecord::TS_NOT_DEFINED) {
- jam();
- opPtr.p->m_errorCode = AlterTrigRef::TriggerNotFound;
- opPtr.p->m_errorLine = __LINE__;
- return;
- }
-
- if (triggerPtr.p->triggerType == TriggerType::SUBSCRIPTION)
- {
- opPtr.p->m_request.addRequestFlag(RequestFlag::RF_NOTCTRIGGER);
- }
-}
-
-void
-Dbdict::alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- // find trigger record
- const Uint32 triggerId = opPtr.p->m_request.getTriggerId();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, triggerId);
- CreateTrigReq* const req = (CreateTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- req->setRequestType(CreateTrigReq::RT_TC);
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- req->setRequestType(CreateTrigReq::RT_LQH);
- } else {
- ndbassert(false);
- }
- req->setTableId(triggerPtr.p->tableId);
- req->setIndexId(triggerPtr.p->indexId);
- req->setTriggerId(triggerPtr.i);
- req->setTriggerType(triggerPtr.p->triggerType);
- req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
- req->setTriggerEvent(triggerPtr.p->triggerEvent);
- req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
- req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
- req->setReportAllMonitoredAttributes(triggerPtr.p->reportAllMonitoredAttributes);
- req->setOnline(true);
- req->setReceiverRef(opPtr.p->m_request.getReceiverRef());
- BlockReference blockRef = 0;
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- blockRef = calcTcBlockRef(getOwnNodeId());
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- blockRef = calcLqhBlockRef(getOwnNodeId());
- } else {
- ndbassert(false);
- }
- req->setAttributeMask(triggerPtr.p->attributeMask);
- sendSignal(blockRef, GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- if (! opPtr.p->hasLastError()) {
- // mark created locally
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_TC;
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- triggerPtr.p->triggerLocal |= TriggerRecord::TL_CREATED_LQH;
- } else {
- ndbrequire(false);
- }
- }
- // forward CONF or REF to master
- alterTrigger_sendReply(signal, opPtr, false);
-}
-
-void
-Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
- DropTrigReq* const req = (DropTrigReq*)signal->getDataPtrSend();
- req->setUserRef(reference());
- req->setConnectionPtr(opPtr.p->key);
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- // broken trigger allowed if force
- if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_TC)) {
- jam();
- ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
- alterTrigger_sendReply(signal, opPtr, false);
- return;
- }
- req->setRequestType(DropTrigReq::RT_TC);
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- // broken trigger allowed if force
- if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) {
- jam();
- ndbassert(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE);
- alterTrigger_sendReply(signal, opPtr, false);
- return;
- }
- req->setRequestType(DropTrigReq::RT_LQH);
- } else {
- ndbassert(false);
- }
- req->setTableId(triggerPtr.p->tableId);
- req->setIndexId(triggerPtr.p->indexId);
- req->setTriggerId(triggerPtr.i);
- req->setTriggerType(triggerPtr.p->triggerType);
- req->setTriggerActionTime(triggerPtr.p->triggerActionTime);
- req->setTriggerEvent(triggerPtr.p->triggerEvent);
- req->setMonitorReplicas(triggerPtr.p->monitorReplicas);
- req->setMonitorAllAttributes(triggerPtr.p->monitorAllAttributes);
- BlockReference blockRef = 0;
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- blockRef = calcTcBlockRef(getOwnNodeId());
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- blockRef = calcLqhBlockRef(getOwnNodeId());
- } else {
- ndbassert(false);
- }
- sendSignal(blockRef, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- if (! opPtr.p->hasLastError()) {
- // mark dropped locally
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_TC) {
- jam();
- triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_TC;
- } else if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_LQH) {
- jam();
- triggerPtr.p->triggerLocal &= ~TriggerRecord::TL_CREATED_LQH;
- } else {
- ndbrequire(false);
- }
- }
- // forward CONF or REF to master
- alterTrigger_sendReply(signal, opPtr, false);
-}
-
-void
-Dbdict::alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
- TriggerRecordPtr triggerPtr;
- c_triggerRecordPool.getPtr(triggerPtr, opPtr.p->m_request.getTriggerId());
- // set state
- triggerPtr.p->triggerState = TriggerRecord::TS_ONLINE;
-}
-
-void
-Dbdict::alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- jam();
-}
-
-void
-Dbdict::alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr)
-{
- AlterTrigReq* const req = (AlterTrigReq*)signal->getDataPtrSend();
- *req = opPtr.p->m_request;
- req->setUserRef(opPtr.p->m_coordinatorRef);
- req->setConnectionPtr(opPtr.p->key);
- req->setRequestType(opPtr.p->m_requestType);
- req->addRequestFlag(opPtr.p->m_requestFlag);
- NdbNodeBitmask receiverNodes = c_aliveNodes;
- if (opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL) {
- receiverNodes.clear();
- receiverNodes.set(getOwnNodeId());
- } else {
- opPtr.p->m_nodes.bitAND(receiverNodes);
- receiverNodes = opPtr.p->m_nodes;
- }
- opPtr.p->m_signalCounter = receiverNodes;
- NodeReceiverGroup rg(DBDICT, receiverNodes);
- sendSignal(rg, GSN_ALTER_TRIG_REQ,
- signal, AlterTrigReq::SignalLength, JBB);
-}
-
-void
-Dbdict::alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr,
- bool toUser)
-{
- jam();
- AlterTrigRef* rep = (AlterTrigRef*)signal->getDataPtrSend();
- Uint32 gsn = GSN_ALTER_TRIG_CONF;
- Uint32 length = AlterTrigConf::InternalLength;
- bool sendRef;
- if (! toUser) {
- sendRef = opPtr.p->hasLastError();
- rep->setUserRef(opPtr.p->m_coordinatorRef);
- rep->setConnectionPtr(opPtr.p->key);
- rep->setRequestType(opPtr.p->m_requestType);
- if (opPtr.p->m_requestType == AlterTrigReq::RT_DICT_ABORT) {
- jam();
- sendRef = false;
- } else {
- jam();
- }
- } else {
- sendRef = opPtr.p->hasError();
- jam();
- rep->setUserRef(opPtr.p->m_request.getUserRef());
- rep->setConnectionPtr(opPtr.p->m_request.getConnectionPtr());
- rep->setRequestType(opPtr.p->m_request.getRequestType());
- length = AlterTrigConf::SignalLength;
- }
- rep->setTableId(opPtr.p->m_request.getTableId());
- rep->setTriggerId(opPtr.p->m_request.getTriggerId());
- if (sendRef) {
- if (opPtr.p->m_errorNode == 0) {
- jam();
- opPtr.p->m_errorNode = getOwnNodeId();
- } else {
- jam();
- }
- rep->setErrorCode(opPtr.p->m_errorCode);
- rep->setErrorLine(opPtr.p->m_errorLine);
- rep->setErrorNode(opPtr.p->m_errorNode);
- gsn = GSN_ALTER_TRIG_REF;
- length = AlterTrigRef::SignalLength;
- }
- sendSignal(rep->getUserRef(), gsn, signal, length, JBB);
-}
-
-/**
- * MODULE: Support routines for index and trigger.
- */
-
-/*
- This routine is used to set-up the primary key attributes of the unique
- hash index. Since we store fragment id as part of the primary key here
- we insert the pseudo column for getting fragment id first in the array.
- This routine is used as part of the building of the index.
-*/
-
-void
-Dbdict::getTableKeyList(TableRecordPtr tablePtr,
- Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list)
-{
- jam();
- list.sz = 0;
- list.id[list.sz++] = AttributeHeader::FRAGMENT;
- LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
- tablePtr.p->m_attributes);
- AttributeRecordPtr attrPtr;
- for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
- if (attrPtr.p->tupleKey) {
- list.id[list.sz++] = attrPtr.p->attributeId;
- }
- }
- ndbrequire(list.sz == (uint)(tablePtr.p->noOfPrimkey + 1));
- ndbrequire(list.sz <= MAX_ATTRIBUTES_IN_INDEX + 1);
-}
-
-// XXX should store the primary attribute id
-void
-Dbdict::getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id)
-{
- jam();
-
- Uint32 len;
- char name[MAX_ATTR_NAME_SIZE];
- TableRecordPtr tablePtr;
- AttributeRecordPtr attrPtr;
-
- c_tableRecordPool.getPtr(tablePtr, indexPtr.p->primaryTableId);
- AttributeRecord* iaRec = c_attributeRecordPool.getPtr(itAttr);
- {
- ConstRope tmp(c_rope_pool, iaRec->attributeName);
- tmp.copy(name);
- len = tmp.size();
- }
- LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
- tablePtr.p->m_attributes);
- for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)){
- ConstRope tmp(c_rope_pool, attrPtr.p->attributeName);
- if(tmp.compare(name, len) == 0){
- id[0] = attrPtr.p->attributeId;
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list)
-{
- jam();
- list.sz = 0;
- memset(list.id, 0, sizeof(list.id));
- ndbrequire(indexPtr.p->noOfAttributes >= 2);
-
- LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
- indexPtr.p->m_attributes);
- AttributeRecordPtr attrPtr;
- for (alist.first(attrPtr); !attrPtr.isNull(); alist.next(attrPtr)) {
- // skip last
- AttributeRecordPtr tempPtr = attrPtr;
- if (! alist.next(tempPtr))
- break;
- getIndexAttr(indexPtr, attrPtr.i, &list.id[list.sz++]);
- }
- ndbrequire(indexPtr.p->noOfAttributes == list.sz + 1);
-}
-
-void
-Dbdict::getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask)
-{
- jam();
- mask.clear();
- ndbrequire(indexPtr.p->noOfAttributes >= 2);
-
- AttributeRecordPtr attrPtr, currPtr;
- LocalDLFifoList<AttributeRecord> alist(c_attributeRecordPool,
- indexPtr.p->m_attributes);
-
-
- for (alist.first(attrPtr); currPtr = attrPtr, alist.next(attrPtr); ){
- Uint32 id;
- getIndexAttr(indexPtr, currPtr.i, &id);
- mask.set(id);
- }
-}
-
-// DICT lock master
-
-const Dbdict::DictLockType*
-Dbdict::getDictLockType(Uint32 lockType)
-{
- static const DictLockType lt[] = {
- { DictLockReq::NodeRestartLock, BS_NODE_RESTART, "NodeRestart" }
- };
- for (unsigned int i = 0; i < sizeof(lt)/sizeof(lt[0]); i++) {
- if ((Uint32) lt[i].lockType == lockType)
- return &lt[i];
- }
- return NULL;
-}
-
-void
-Dbdict::sendDictLockInfoEvent(Uint32 pollCount)
-{
- DictLockPtr loopPtr;
- c_dictLockQueue.first(loopPtr);
- unsigned count = 0;
-
- char queue_buf[100];
- char *p = &queue_buf[0];
- const char *const q = &queue_buf[sizeof(queue_buf)];
- *p = 0;
-
- while (loopPtr.i != RNIL) {
- jam();
- my_snprintf(p, q-p, "%s%u%s",
- ++count == 1 ? "" : " ",
- (unsigned)refToNode(loopPtr.p->req.userRef),
- loopPtr.p->locked ? "L" : "");
- p += strlen(p);
- c_dictLockQueue.next(loopPtr);
- }
-
- infoEvent("DICT: lock bs: %d ops: %d poll: %d cnt: %d queue: %s",
- (int)c_blockState,
- c_opRecordPool.getSize() - c_opRecordPool.getNoOfFree(),
- c_dictLockPoll, (int)pollCount, queue_buf);
-}
-
-void
-Dbdict::sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text)
-{
- infoEvent("DICT: %s %u for %s",
- text,
- (unsigned)refToNode(lockPtr.p->req.userRef), lockPtr.p->lt->text);
-}
-
-void
-Dbdict::execDICT_LOCK_REQ(Signal* signal)
-{
- jamEntry();
- const DictLockReq* req = (const DictLockReq*)&signal->theData[0];
-
- // make sure bad request crashes slave, not master (us)
-
- if (getOwnNodeId() != c_masterNodeId) {
- jam();
- sendDictLockRef(signal, *req, DictLockRef::NotMaster);
- return;
- }
-
- const DictLockType* lt = getDictLockType(req->lockType);
- if (lt == NULL) {
- jam();
- sendDictLockRef(signal, *req, DictLockRef::InvalidLockType);
- return;
- }
-
- if (req->userRef != signal->getSendersBlockRef() ||
- getNodeInfo(refToNode(req->userRef)).m_type != NodeInfo::DB) {
- jam();
- sendDictLockRef(signal, *req, DictLockRef::BadUserRef);
- return;
- }
-
- if (c_aliveNodes.get(refToNode(req->userRef))) {
- jam();
- sendDictLockRef(signal, *req, DictLockRef::TooLate);
- return;
- }
-
- DictLockPtr lockPtr;
- if (! c_dictLockQueue.seize(lockPtr)) {
- jam();
- sendDictLockRef(signal, *req, DictLockRef::TooManyRequests);
- return;
- }
-
- lockPtr.p->req = *req;
- lockPtr.p->locked = false;
- lockPtr.p->lt = lt;
-
- checkDictLockQueue(signal, false);
-
- if (! lockPtr.p->locked)
- sendDictLockInfoEvent(lockPtr, "lock request by node");
-}
-
-// only table and index ops are checked
-bool
-Dbdict::hasDictLockSchemaOp()
-{
- return
- ! c_opCreateTable.isEmpty() ||
- ! c_opDropTable.isEmpty() ||
- ! c_opCreateIndex.isEmpty() ||
- ! c_opDropIndex.isEmpty();
-}
-
-void
-Dbdict::checkDictLockQueue(Signal* signal, bool poll)
-{
- Uint32 pollCount = ! poll ? 0 : signal->theData[1];
-
- DictLockPtr lockPtr;
-
- do {
- if (! c_dictLockQueue.first(lockPtr)) {
- jam();
- setDictLockPoll(signal, false, pollCount);
- return;
- }
-
- if (lockPtr.p->locked) {
- jam();
- ndbrequire(c_blockState == lockPtr.p->lt->blockState);
- break;
- }
-
- if (hasDictLockSchemaOp()) {
- jam();
- break;
- }
-
- if (c_blockState != BS_IDLE)
- {
- /**
- * If state is BS_NODE_FAILURE, it might be that no op is running
- */
- jam();
- break;
- }
-
- ndbrequire(c_blockState == BS_IDLE);
- lockPtr.p->locked = true;
- c_blockState = lockPtr.p->lt->blockState;
- sendDictLockConf(signal, lockPtr);
-
- sendDictLockInfoEvent(lockPtr, "locked by node");
- } while (0);
-
- // poll while first request is open
- // this routine is called again when it is removed for any reason
-
- bool on = ! lockPtr.p->locked;
- setDictLockPoll(signal, on, pollCount);
-}
-
-void
-Dbdict::execDICT_UNLOCK_ORD(Signal* signal)
-{
- jamEntry();
- const DictUnlockOrd* ord = (const DictUnlockOrd*)&signal->theData[0];
-
- DictLockPtr lockPtr;
- c_dictLockQueue.getPtr(lockPtr, ord->lockPtr);
- ndbrequire((Uint32) lockPtr.p->lt->lockType == ord->lockType);
-
- if (lockPtr.p->locked) {
- jam();
- ndbrequire(c_blockState == lockPtr.p->lt->blockState);
- ndbrequire(! hasDictLockSchemaOp());
- ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
-
- c_blockState = BS_IDLE;
- sendDictLockInfoEvent(lockPtr, "unlocked by node");
- } else {
- sendDictLockInfoEvent(lockPtr, "lock request removed by node");
- }
-
- c_dictLockQueue.release(lockPtr);
-
- checkDictLockQueue(signal, false);
-}
-
-void
-Dbdict::sendDictLockConf(Signal* signal, DictLockPtr lockPtr)
-{
- DictLockConf* conf = (DictLockConf*)&signal->theData[0];
- const DictLockReq& req = lockPtr.p->req;
-
- conf->userPtr = req.userPtr;
- conf->lockType = req.lockType;
- conf->lockPtr = lockPtr.i;
-
- sendSignal(req.userRef, GSN_DICT_LOCK_CONF, signal,
- DictLockConf::SignalLength, JBB);
-}
-
-void
-Dbdict::sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode)
-{
- DictLockRef* ref = (DictLockRef*)&signal->theData[0];
-
- ref->userPtr = req.userPtr;
- ref->lockType = req.lockType;
- ref->errorCode = errorCode;
-
- sendSignal(req.userRef, GSN_DICT_LOCK_REF, signal,
- DictLockRef::SignalLength, JBB);
-}
-
-// control polling
-
-void
-Dbdict::setDictLockPoll(Signal* signal, bool on, Uint32 pollCount)
-{
- if (on) {
- jam();
- signal->theData[0] = ZDICT_LOCK_POLL;
- signal->theData[1] = pollCount + 1;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- }
-
- bool change = (c_dictLockPoll != on);
-
- if (change) {
- jam();
- c_dictLockPoll = on;
- }
-
- // avoid too many messages if master is stuck busy (BS_NODE_FAILURE)
- bool periodic =
- pollCount < 8 ||
- pollCount < 64 && pollCount % 8 == 0 ||
- pollCount < 512 && pollCount % 64 == 0 ||
- pollCount < 4096 && pollCount % 512 == 0 ||
- pollCount % 4096 == 0; // about every 6 minutes
-
- if (change || periodic)
- sendDictLockInfoEvent(pollCount);
-}
-
-// NF handling
-
-void
-Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes)
-{
- DictLockPtr loopPtr;
- c_dictLockQueue.first(loopPtr);
-
- if (getOwnNodeId() != c_masterNodeId) {
- ndbrequire(loopPtr.i == RNIL);
- return;
- }
-
- while (loopPtr.i != RNIL) {
- jam();
- DictLockPtr lockPtr = loopPtr;
- c_dictLockQueue.next(loopPtr);
-
- Uint32 nodeId = refToNode(lockPtr.p->req.userRef);
-
- if (NodeBitmask::get(theFailedNodes, nodeId)) {
- if (lockPtr.p->locked) {
- jam();
- ndbrequire(c_blockState == lockPtr.p->lt->blockState);
- ndbrequire(! hasDictLockSchemaOp());
- ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
-
- c_blockState = BS_IDLE;
-
- sendDictLockInfoEvent(lockPtr, "remove lock by failed node");
- } else {
- sendDictLockInfoEvent(lockPtr, "remove lock request by failed node");
- }
-
- c_dictLockQueue.release(lockPtr);
- }
- }
-
- checkDictLockQueue(signal, false);
-}
-
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* MODULE: STORE/RESTORE SCHEMA FILE---------------------- */
-/* ---------------------------------------------------------------- */
-/* */
-/* General module used to store the schema file on disk and */
-/* similar function to restore it from disk. */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-void
-Dbdict::initSchemaFile(XSchemaFile * xsf, Uint32 firstPage, Uint32 lastPage,
- bool initEntries)
-{
- ndbrequire(lastPage <= xsf->noOfPages);
- for (Uint32 n = firstPage; n < lastPage; n++) {
- SchemaFile * sf = &xsf->schemaPage[n];
- if (initEntries)
- memset(sf, 0, NDB_SF_PAGE_SIZE);
-
- Uint32 ndb_version = NDB_VERSION;
- if (ndb_version < NDB_SF_VERSION_5_0_6)
- ndb_version = NDB_SF_VERSION_5_0_6;
-
- memcpy(sf->Magic, NDB_SF_MAGIC, sizeof(sf->Magic));
- sf->ByteOrder = 0x12345678;
- sf->NdbVersion = ndb_version;
- sf->FileSize = xsf->noOfPages * NDB_SF_PAGE_SIZE;
- sf->PageNumber = n;
- sf->CheckSum = 0;
- sf->NoOfTableEntries = NDB_SF_PAGE_ENTRIES;
-
- computeChecksum(xsf, n);
- }
-}
-
-void
-Dbdict::resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages)
-{
- ndbrequire(noOfPages <= NDB_SF_MAX_PAGES);
- if (xsf->noOfPages < noOfPages) {
- jam();
- Uint32 firstPage = xsf->noOfPages;
- xsf->noOfPages = noOfPages;
- initSchemaFile(xsf, 0, firstPage, false);
- initSchemaFile(xsf, firstPage, xsf->noOfPages, true);
- }
- if (xsf->noOfPages > noOfPages) {
- jam();
- Uint32 tableId = noOfPages * NDB_SF_PAGE_ENTRIES;
- while (tableId < xsf->noOfPages * NDB_SF_PAGE_ENTRIES) {
- SchemaFile::TableEntry * te = getTableEntry(xsf, tableId);
- if (te->m_tableState != SchemaFile::INIT &&
- te->m_tableState != SchemaFile::DROP_TABLE_COMMITTED) {
- ndbrequire(false);
- }
- tableId++;
- }
- xsf->noOfPages = noOfPages;
- initSchemaFile(xsf, 0, xsf->noOfPages, false);
- }
-}
-
-void
-Dbdict::computeChecksum(XSchemaFile * xsf, Uint32 pageNo){
- SchemaFile * sf = &xsf->schemaPage[pageNo];
- sf->CheckSum = 0;
- sf->CheckSum = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
-}
-
-bool
-Dbdict::validateChecksum(const XSchemaFile * xsf){
-
- for (Uint32 n = 0; n < xsf->noOfPages; n++) {
- SchemaFile * sf = &xsf->schemaPage[n];
- Uint32 c = computeChecksum((Uint32*)sf, NDB_SF_PAGE_SIZE_IN_WORDS);
- if ( c != 0)
- return false;
- }
- return true;
-}
-
-Uint32
-Dbdict::computeChecksum(const Uint32 * src, Uint32 len){
- Uint32 ret = 0;
- for(Uint32 i = 0; i<len; i++)
- ret ^= src[i];
- return ret;
-}
-
-SchemaFile::TableEntry *
-Dbdict::getTableEntry(XSchemaFile * xsf, Uint32 tableId)
-{
- Uint32 n = tableId / NDB_SF_PAGE_ENTRIES;
- Uint32 i = tableId % NDB_SF_PAGE_ENTRIES;
- ndbrequire(n < xsf->noOfPages);
-
- SchemaFile * sf = &xsf->schemaPage[n];
- return &sf->TableEntries[i];
-}
-
-//******************************************
-void
-Dbdict::execCREATE_FILE_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- CreateFileReq * req = (CreateFileReq*)signal->getDataPtr();
- CreateFileRef * ref = (CreateFileRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 type = req->objType;
- Uint32 requestInfo = req->requestInfo;
-
- do {
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- ref->errorCode = CreateFileRef::NotMaster;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (c_blockState != BS_IDLE){
- jam();
- ref->errorCode = CreateFileRef::Busy;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (checkSingleUserMode(senderRef))
- {
- ref->errorCode = CreateFileRef::SingleUser;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<SchemaTransaction> trans_ptr;
- if (! c_Trans.seize(trans_ptr)){
- jam();
- ref->errorCode = CreateFileRef::Busy;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
- jam();
- const Uint32 trans_key = ++c_opRecordSequence;
- trans_ptr.p->key = trans_key;
- trans_ptr.p->m_senderRef = senderRef;
- trans_ptr.p->m_senderData = senderData;
- trans_ptr.p->m_nodes = c_aliveNodes;
- trans_ptr.p->m_errorCode = 0;
-// trans_ptr.p->m_nodes.clear();
-// trans_ptr.p->m_nodes.set(getOwnNodeId());
- c_Trans.add(trans_ptr);
-
- const Uint32 op_key = ++c_opRecordSequence;
- trans_ptr.p->m_op.m_key = op_key;
- trans_ptr.p->m_op.m_vt_index = 1;
- trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
-
- CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
- create_obj->op_key = op_key;
- create_obj->senderRef = reference();
- create_obj->senderData = trans_key;
- create_obj->clientRef = senderRef;
- create_obj->clientData = senderData;
-
- create_obj->objType = type;
- create_obj->requestInfo = requestInfo;
-
- {
- Uint32 objId = getFreeObjId(0);
- if (objId == RNIL) {
- jam();
- ref->errorCode = CreateFileRef::NoMoreObjectRecords;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- create_obj->objId = objId;
- trans_ptr.p->m_op.m_obj_id = objId;
- create_obj->gci = 0;
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);
- create_obj->objVersion =
- create_obj_inc_schema_version(objEntry->m_tableVersion);
- }
-
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
- sendSignal(rg, GSN_CREATE_OBJ_REQ, signal,
- CreateObjReq::SignalLength, JBB);
-
- c_blockState = BS_CREATE_TAB;
- return;
- } while(0);
-
- ref->senderData = senderData;
- ref->masterNodeId = c_masterNodeId;
- sendSignal(senderRef, GSN_CREATE_FILE_REF,signal,
- CreateFileRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execCREATE_FILEGROUP_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtr();
- CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 type = req->objType;
-
- do {
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- ref->errorCode = CreateFilegroupRef::NotMaster;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (c_blockState != BS_IDLE){
- jam();
- ref->errorCode = CreateFilegroupRef::Busy;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (checkSingleUserMode(senderRef))
- {
- ref->errorCode = CreateFilegroupRef::SingleUser;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<SchemaTransaction> trans_ptr;
- if (! c_Trans.seize(trans_ptr)){
- jam();
- ref->errorCode = CreateFilegroupRef::Busy;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
- jam();
- const Uint32 trans_key = ++c_opRecordSequence;
- trans_ptr.p->key = trans_key;
- trans_ptr.p->m_senderRef = senderRef;
- trans_ptr.p->m_senderData = senderData;
- trans_ptr.p->m_nodes = c_aliveNodes;
- trans_ptr.p->m_errorCode = 0;
- c_Trans.add(trans_ptr);
-
- const Uint32 op_key = ++c_opRecordSequence;
- trans_ptr.p->m_op.m_key = op_key;
- trans_ptr.p->m_op.m_vt_index = 0;
- trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
-
- CreateObjReq* create_obj = (CreateObjReq*)signal->getDataPtrSend();
- create_obj->op_key = op_key;
- create_obj->senderRef = reference();
- create_obj->senderData = trans_key;
- create_obj->clientRef = senderRef;
- create_obj->clientData = senderData;
-
- create_obj->objType = type;
-
- {
- Uint32 objId = getFreeObjId(0);
- if (objId == RNIL) {
- jam();
- ref->errorCode = CreateFilegroupRef::NoMoreObjectRecords;
- ref->status = 0;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- create_obj->objId = objId;
- trans_ptr.p->m_op.m_obj_id = objId;
- create_obj->gci = 0;
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry *objEntry = getTableEntry(xsf, objId);
- create_obj->objVersion =
- create_obj_inc_schema_version(objEntry->m_tableVersion);
- }
-
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- tmp.init<CreateObjRef>(rg, GSN_CREATE_OBJ_REF, trans_key);
- sendSignal(rg, GSN_CREATE_OBJ_REQ, signal,
- CreateObjReq::SignalLength, JBB);
-
- c_blockState = BS_CREATE_TAB;
- return;
- } while(0);
-
- ref->senderData = senderData;
- ref->masterNodeId = c_masterNodeId;
- sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF,signal,
- CreateFilegroupRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execDROP_FILE_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- DropFileReq * req = (DropFileReq*)signal->getDataPtr();
- DropFileRef * ref = (DropFileRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 objId = req->file_id;
- Uint32 version = req->file_version;
-
- do {
- if(getOwnNodeId() != c_masterNodeId){
- jam();
- ref->errorCode = DropFileRef::NotMaster;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (c_blockState != BS_IDLE)
- {
- jam();
- ref->errorCode = DropFileRef::Busy;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (checkSingleUserMode(senderRef))
- {
- jam();
- ref->errorCode = DropFileRef::SingleUser;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<File> file_ptr;
- if (!c_file_hash.find(file_ptr, objId))
- {
- jam();
- ref->errorCode = DropFileRef::NoSuchFile;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (file_ptr.p->m_version != version)
- {
- jam();
- ref->errorCode = DropFileRef::InvalidSchemaObjectVersion;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<SchemaTransaction> trans_ptr;
- if (! c_Trans.seize(trans_ptr))
- {
- jam();
- ref->errorCode = DropFileRef::Busy;
- ref->errorLine = __LINE__;
- break;
- }
- jam();
-
- const Uint32 trans_key = ++c_opRecordSequence;
- trans_ptr.p->key = trans_key;
- trans_ptr.p->m_senderRef = senderRef;
- trans_ptr.p->m_senderData = senderData;
- trans_ptr.p->m_nodes = c_aliveNodes;
- trans_ptr.p->m_errorCode = 0;
- c_Trans.add(trans_ptr);
-
- const Uint32 op_key = ++c_opRecordSequence;
- trans_ptr.p->m_op.m_key = op_key;
- trans_ptr.p->m_op.m_vt_index = 2;
- trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
-
- DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
- drop_obj->op_key = op_key;
- drop_obj->objVersion = version;
- drop_obj->objId = objId;
- drop_obj->objType = file_ptr.p->m_type;
- trans_ptr.p->m_op.m_obj_id = objId;
-
- drop_obj->senderRef = reference();
- drop_obj->senderData = trans_key;
- drop_obj->clientRef = senderRef;
- drop_obj->clientData = senderData;
-
- drop_obj->requestInfo = 0;
-
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
- sendSignal(rg, GSN_DROP_OBJ_REQ, signal,
- DropObjReq::SignalLength, JBB);
-
- c_blockState = BS_CREATE_TAB;
- return;
- } while(0);
-
- ref->senderData = senderData;
- ref->masterNodeId = c_masterNodeId;
- sendSignal(senderRef, GSN_DROP_FILE_REF,signal,
- DropFileRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execDROP_FILEGROUP_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- DropFilegroupReq * req = (DropFilegroupReq*)signal->getDataPtr();
- DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtrSend();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 objId = req->filegroup_id;
- Uint32 version = req->filegroup_version;
-
- do {
- if(getOwnNodeId() != c_masterNodeId)
- {
- jam();
- ref->errorCode = DropFilegroupRef::NotMaster;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (c_blockState != BS_IDLE)
- {
- jam();
- ref->errorCode = DropFilegroupRef::Busy;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (checkSingleUserMode(senderRef))
- {
- jam();
- ref->errorCode = DropFilegroupRef::SingleUser;
- ref->errorKey = 0;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<Filegroup> filegroup_ptr;
- if (!c_filegroup_hash.find(filegroup_ptr, objId))
- {
- jam();
- ref->errorCode = DropFilegroupRef::NoSuchFilegroup;
- ref->errorLine = __LINE__;
- break;
- }
-
- if (filegroup_ptr.p->m_version != version)
- {
- jam();
- ref->errorCode = DropFilegroupRef::InvalidSchemaObjectVersion;
- ref->errorLine = __LINE__;
- break;
- }
-
- Ptr<SchemaTransaction> trans_ptr;
- if (! c_Trans.seize(trans_ptr))
- {
- jam();
- ref->errorCode = DropFilegroupRef::Busy;
- ref->errorLine = __LINE__;
- break;
- }
- jam();
-
- const Uint32 trans_key = ++c_opRecordSequence;
- trans_ptr.p->key = trans_key;
- trans_ptr.p->m_senderRef = senderRef;
- trans_ptr.p->m_senderData = senderData;
- trans_ptr.p->m_nodes = c_aliveNodes;
- trans_ptr.p->m_errorCode = 0;
- c_Trans.add(trans_ptr);
-
- const Uint32 op_key = ++c_opRecordSequence;
- trans_ptr.p->m_op.m_key = op_key;
- trans_ptr.p->m_op.m_vt_index = 3;
- trans_ptr.p->m_op.m_state = DictObjOp::Preparing;
-
- DropObjReq* drop_obj = (DropObjReq*)signal->getDataPtrSend();
- drop_obj->op_key = op_key;
- drop_obj->objVersion = version;
- drop_obj->objId = objId;
- drop_obj->objType = filegroup_ptr.p->m_type;
- trans_ptr.p->m_op.m_obj_id = objId;
-
- drop_obj->senderRef = reference();
- drop_obj->senderData = trans_key;
- drop_obj->clientRef = senderRef;
- drop_obj->clientData = senderData;
-
- drop_obj->requestInfo = 0;
-
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- tmp.init<CreateObjRef>(rg, GSN_DROP_OBJ_REF, trans_key);
- sendSignal(rg, GSN_DROP_OBJ_REQ, signal,
- DropObjReq::SignalLength, JBB);
-
- c_blockState = BS_CREATE_TAB;
- return;
- } while(0);
-
- ref->senderData = senderData;
- ref->masterNodeId = c_masterNodeId;
- sendSignal(senderRef, GSN_DROP_FILEGROUP_REF,signal,
- DropFilegroupRef::SignalLength, JBB);
-}
-
-void
-Dbdict::execCREATE_OBJ_REF(Signal* signal)
-{
- CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
- if(ref->errorCode != CreateObjRef::NF_FakeErrorREF){
- jam();
- trans_ptr.p->setErrorCode(ref->errorCode);
- }
- Uint32 node = refToNode(ref->senderRef);
- schemaOp_reply(signal, trans_ptr.p, node);
-}
-
-void
-Dbdict::execCREATE_OBJ_CONF(Signal* signal)
-{
- Ptr<SchemaTransaction> trans_ptr;
- CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
- schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
-}
-
-void
-Dbdict::schemaOp_reply(Signal* signal,
- SchemaTransaction * trans_ptr_p,
- Uint32 nodeId)
-{
- jam();
- {
- SafeCounter tmp(c_counterMgr, trans_ptr_p->m_counter);
- if(!tmp.clearWaitingFor(nodeId)){
- jam();
- return;
- }
- }
-
- switch(trans_ptr_p->m_op.m_state){
- case DictObjOp::Preparing:{
- if(trans_ptr_p->m_errorCode != 0)
- {
- /**
- * Failed to prepare on atleast one node -> abort on all
- */
- trans_ptr_p->m_op.m_state = DictObjOp::Aborting;
- trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
- trans_ptr_p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::trans_abort_start_done);
-
- if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
- {
- jam();
- (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
- (signal, trans_ptr_p);
- }
- else
- {
- jam();
- execute(signal, trans_ptr_p->m_callback, 0);
- }
- return;
- }
-
- trans_ptr_p->m_op.m_state = DictObjOp::Prepared;
- trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
- trans_ptr_p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::trans_commit_start_done);
-
- if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
- {
- jam();
- (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
- (signal, trans_ptr_p);
- }
- else
- {
- jam();
- execute(signal, trans_ptr_p->m_callback, 0);
- }
- return;
- }
- case DictObjOp::Committing: {
- ndbrequire(trans_ptr_p->m_errorCode == 0);
-
- trans_ptr_p->m_op.m_state = DictObjOp::Committed;
- trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
- trans_ptr_p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::trans_commit_complete_done);
-
- if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
- {
- jam();
- (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
- (signal, trans_ptr_p);
- }
- else
- {
- jam();
- execute(signal, trans_ptr_p->m_callback, 0);
- }
- return;
- }
- case DictObjOp::Aborting:{
- trans_ptr_p->m_op.m_state = DictObjOp::Committed;
- trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
- trans_ptr_p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::trans_abort_complete_done);
-
- if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
- {
- jam();
- (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
- (signal, trans_ptr_p);
- }
- else
- {
- jam();
- execute(signal, trans_ptr_p->m_callback, 0);
- }
- return;
- }
- case DictObjOp::Defined:
- case DictObjOp::Prepared:
- case DictObjOp::Committed:
- case DictObjOp::Aborted:
- jam();
- break;
- }
- ndbrequire(false);
-}
-
-void
-Dbdict::trans_commit_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue)
-{
- Ptr<SchemaTransaction> trans_ptr;
-
- jam();
- ndbrequire(retValue == 0);
- ndbrequire(c_Trans.find(trans_ptr, callbackData));
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- tmp.init<DictCommitRef>(rg, GSN_DICT_COMMIT_REF, trans_ptr.p->key);
-
- DictCommitReq * const req = (DictCommitReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = trans_ptr.p->key;
- req->op_key = trans_ptr.p->m_op.m_key;
- sendSignal(rg, GSN_DICT_COMMIT_REQ, signal, DictCommitReq::SignalLength,
- JBB);
- trans_ptr.p->m_op.m_state = DictObjOp::Committing;
-}
-
-void
-Dbdict::trans_commit_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue)
-{
- Ptr<SchemaTransaction> trans_ptr;
-
- jam();
- ndbrequire(retValue == 0);
- ndbrequire(c_Trans.find(trans_ptr, callbackData));
-
- switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
- case GSN_CREATE_FILEGROUP_REQ:{
- FilegroupPtr fg_ptr;
- jam();
- ndbrequire(c_filegroup_hash.find(fg_ptr, trans_ptr.p->m_op.m_obj_id));
-
- CreateFilegroupConf * conf = (CreateFilegroupConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = trans_ptr.p->m_senderData;
- conf->filegroupId = fg_ptr.p->key;
- conf->filegroupVersion = fg_ptr.p->m_version;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_CONF, signal,
- CreateFilegroupConf::SignalLength, JBB);
- break;
- }
- case GSN_CREATE_FILE_REQ:{
- FilePtr f_ptr;
- jam();
- ndbrequire(c_file_hash.find(f_ptr, trans_ptr.p->m_op.m_obj_id));
- CreateFileConf * conf = (CreateFileConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = trans_ptr.p->m_senderData;
- conf->fileId = f_ptr.p->key;
- conf->fileVersion = f_ptr.p->m_version;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileConf::SignalLength, JBB);
- break;
- }
- case GSN_DROP_FILE_REQ:{
- DropFileConf * conf = (DropFileConf*)signal->getDataPtr();
- jam();
- conf->senderRef = reference();
- conf->senderData = trans_ptr.p->m_senderData;
- conf->fileId = trans_ptr.p->m_op.m_obj_id;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_CONF, signal,
- DropFileConf::SignalLength, JBB);
- break;
- }
- case GSN_DROP_FILEGROUP_REQ:{
- DropFilegroupConf * conf = (DropFilegroupConf*)signal->getDataPtr();
- jam();
- conf->senderRef = reference();
- conf->senderData = trans_ptr.p->m_senderData;
- conf->filegroupId = trans_ptr.p->m_op.m_obj_id;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_CONF, signal,
- DropFilegroupConf::SignalLength, JBB);
- break;
- }
- default:
- ndbrequire(false);
- }
-
- c_Trans.release(trans_ptr);
- ndbrequire(c_blockState == BS_CREATE_TAB);
- c_blockState = BS_IDLE;
- return;
-}
-
-void
-Dbdict::trans_abort_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue)
-{
- Ptr<SchemaTransaction> trans_ptr;
-
- jam();
- ndbrequire(retValue == 0);
- ndbrequire(c_Trans.find(trans_ptr, callbackData));
-
- NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
- SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
- ndbrequire(tmp.init<DictAbortRef>(rg, trans_ptr.p->key));
-
- DictAbortReq * const req = (DictAbortReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = trans_ptr.p->key;
- req->op_key = trans_ptr.p->m_op.m_key;
-
- sendSignal(rg, GSN_DICT_ABORT_REQ, signal, DictAbortReq::SignalLength, JBB);
-}
-
-void
-Dbdict::trans_abort_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 retValue)
-{
- Ptr<SchemaTransaction> trans_ptr;
-
- jam();
- ndbrequire(retValue == 0);
- ndbrequire(c_Trans.find(trans_ptr, callbackData));
-
- switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
- case GSN_CREATE_FILEGROUP_REQ:
- {
- //
- CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtr();
- jam();
- ref->senderRef = reference();
- ref->senderData = trans_ptr.p->m_senderData;
- ref->masterNodeId = c_masterNodeId;
- ref->errorCode = trans_ptr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->status = 0;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_REF, signal,
- CreateFilegroupRef::SignalLength, JBB);
- break;
- }
- case GSN_CREATE_FILE_REQ:
- {
- CreateFileRef * ref = (CreateFileRef*)signal->getDataPtr();
- jam();
- ref->senderRef = reference();
- ref->senderData = trans_ptr.p->m_senderData;
- ref->masterNodeId = c_masterNodeId;
- ref->errorCode = trans_ptr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->status = 0;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileRef::SignalLength, JBB);
- break;
- }
- case GSN_DROP_FILE_REQ:
- {
- DropFileRef * ref = (DropFileRef*)signal->getDataPtr();
- jam();
- ref->senderRef = reference();
- ref->senderData = trans_ptr.p->m_senderData;
- ref->masterNodeId = c_masterNodeId;
- ref->errorCode = trans_ptr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_REF, signal,
- DropFileRef::SignalLength, JBB);
- break;
- }
- case GSN_DROP_FILEGROUP_REQ:
- {
- //
- DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtr();
- jam();
- ref->senderRef = reference();
- ref->senderData = trans_ptr.p->m_senderData;
- ref->masterNodeId = c_masterNodeId;
- ref->errorCode = trans_ptr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
-
- //@todo check api failed
- sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_REF, signal,
- DropFilegroupRef::SignalLength, JBB);
- break;
- }
- default:
- ndbrequire(false);
- }
-
- c_Trans.release(trans_ptr);
- ndbrequire(c_blockState == BS_CREATE_TAB);
- c_blockState = BS_IDLE;
- return;
-}
-
-void
-Dbdict::execCREATE_OBJ_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- CreateObjReq * const req = (CreateObjReq*)signal->getDataPtr();
- const Uint32 gci = req->gci;
- const Uint32 objId = req->objId;
- const Uint32 objVersion = req->objVersion;
- const Uint32 objType = req->objType;
- const Uint32 requestInfo = req->requestInfo;
-
- SegmentedSectionPtr objInfoPtr;
- signal->getSection(objInfoPtr, CreateObjReq::DICT_OBJ_INFO);
-
- CreateObjRecordPtr createObjPtr;
- ndbrequire(c_opCreateObj.seize(createObjPtr));
-
- const Uint32 key = req->op_key;
- createObjPtr.p->key = key;
- c_opCreateObj.add(createObjPtr);
- createObjPtr.p->m_errorCode = 0;
- createObjPtr.p->m_senderRef = req->senderRef;
- createObjPtr.p->m_senderData = req->senderData;
- createObjPtr.p->m_clientRef = req->clientRef;
- createObjPtr.p->m_clientData = req->clientData;
-
- createObjPtr.p->m_gci = gci;
- createObjPtr.p->m_obj_id = objId;
- createObjPtr.p->m_obj_type = objType;
- createObjPtr.p->m_obj_version = objVersion;
- createObjPtr.p->m_obj_info_ptr_i = objInfoPtr.i;
- createObjPtr.p->m_obj_ptr_i = RNIL;
-
- createObjPtr.p->m_callback.m_callbackData = key;
- createObjPtr.p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::createObj_prepare_start_done);
-
- createObjPtr.p->m_restart= 0;
- switch(objType){
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- jam();
- createObjPtr.p->m_vt_index = 0;
- break;
- case DictTabInfo::Datafile:
- case DictTabInfo::Undofile:
- /**
- * Use restart code to impl. ForceCreateFile
- */
- if (requestInfo & CreateFileReq::ForceCreateFile)
- {
- jam();
- createObjPtr.p->m_restart= 2;
- }
- jam();
- createObjPtr.p->m_vt_index = 1;
- break;
- default:
- ndbrequire(false);
- }
-
- signal->header.m_noOfSections = 0;
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_start)
- (signal, createObjPtr.p);
-}
-
-void
-Dbdict::execDICT_COMMIT_REQ(Signal* signal)
-{
- DictCommitReq* req = (DictCommitReq*)signal->getDataPtr();
- Ptr<SchemaOp> op;
-
- jamEntry();
- ndbrequire(c_schemaOp.find(op, req->op_key));
- (this->*f_dict_op[op.p->m_vt_index].m_commit)(signal, op.p);
-}
-
-void
-Dbdict::execDICT_ABORT_REQ(Signal* signal)
-{
- DictAbortReq* req = (DictAbortReq*)signal->getDataPtr();
- Ptr<SchemaOp> op;
-
- jamEntry();
- ndbrequire(c_schemaOp.find(op, req->op_key));
- (this->*f_dict_op[op.p->m_vt_index].m_abort)(signal, op.p);
-}
-
-void
-Dbdict::execDICT_COMMIT_REF(Signal* signal)
-{
- DictCommitRef * const ref = (DictCommitRef*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
- if(ref->errorCode != DictCommitRef::NF_FakeErrorREF){
- jam();
- trans_ptr.p->setErrorCode(ref->errorCode);
- }
- Uint32 node = refToNode(ref->senderRef);
- schemaOp_reply(signal, trans_ptr.p, node);
-}
-
-void
-Dbdict::execDICT_COMMIT_CONF(Signal* signal)
-{
- Ptr<SchemaTransaction> trans_ptr;
- DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
- schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
-}
-
-void
-Dbdict::execDICT_ABORT_REF(Signal* signal)
-{
- DictAbortRef * const ref = (DictAbortRef*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
- if(ref->errorCode != DictAbortRef::NF_FakeErrorREF){
- jam();
- trans_ptr.p->setErrorCode(ref->errorCode);
- }
- Uint32 node = refToNode(ref->senderRef);
- schemaOp_reply(signal, trans_ptr.p, node);
-}
-
-void
-Dbdict::execDICT_ABORT_CONF(Signal* signal)
-{
- DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
- schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
-}
-
-void
-Dbdict::createObj_prepare_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
- SegmentedSectionPtr objInfoPtr;
-
- ndbrequire(returnCode == 0);
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- jam();
- getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
- if(createObjPtr.p->m_errorCode != 0){
- jam();
- createObjPtr.p->m_obj_info_ptr_i= RNIL;
- signal->setSection(objInfoPtr, 0);
- releaseSections(signal);
- createObj_prepare_complete_done(signal, callbackData, 0);
- return;
- }
-
- SchemaFile::TableEntry tabEntry;
- bzero(&tabEntry, sizeof(tabEntry));
- tabEntry.m_tableVersion = createObjPtr.p->m_obj_version;
- tabEntry.m_tableType = createObjPtr.p->m_obj_type;
- tabEntry.m_tableState = SchemaFile::ADD_STARTED;
- tabEntry.m_gcp = createObjPtr.p->m_gci;
- tabEntry.m_info_words = objInfoPtr.sz;
-
- Callback cb;
- cb.m_callbackData = createObjPtr.p->key;
- cb.m_callbackFunction = safe_cast(&Dbdict::createObj_writeSchemaConf1);
-
- updateSchemaState(signal, createObjPtr.p->m_obj_id, &tabEntry, &cb);
-}
-
-void
-Dbdict::createObj_writeSchemaConf1(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
- Callback callback;
- SegmentedSectionPtr objInfoPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
- callback.m_callbackData = createObjPtr.p->key;
- callback.m_callbackFunction = safe_cast(&Dbdict::createObj_writeObjConf);
-
- getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
- writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
-
- signal->setSection(objInfoPtr, 0);
- releaseSections(signal);
- createObjPtr.p->m_obj_info_ptr_i = RNIL;
-}
-
-void
-Dbdict::createObj_writeObjConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_prepare_complete_done);
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
- (signal, createObjPtr.p);
-}
-
-void
-Dbdict::createObj_prepare_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
- //@todo check for master failed
-
- if(createObjPtr.p->m_errorCode == 0){
- jam();
-
- CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createObjPtr.p->m_senderData;
- sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_CONF,
- signal, CreateObjConf::SignalLength, JBB);
- return;
- }
-
- CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
- ref->senderRef = reference();
- ref->senderData = createObjPtr.p->m_senderData;
- ref->errorCode = createObjPtr.p->m_errorCode;
- ref->errorLine = 0;
- ref->errorKey = 0;
- ref->errorStatus = 0;
-
- sendSignal(createObjPtr.p->m_senderRef, GSN_CREATE_OBJ_REF,
- signal, CreateObjRef::SignalLength, JBB);
-}
-
-void
-Dbdict::createObj_commit(Signal * signal, SchemaOp * op)
-{
- OpCreateObj * createObj = (OpCreateObj*)op;
-
- createObj->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_commit_start_done);
- if (f_dict_op[createObj->m_vt_index].m_commit_start)
- {
- jam();
- (this->*f_dict_op[createObj->m_vt_index].m_commit_start)(signal, createObj);
- }
- else
- {
- jam();
- execute(signal, createObj->m_callback, 0);
- }
-}
-
-void
-Dbdict::createObj_commit_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
- Uint32 objId = createObjPtr.p->m_obj_id;
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
- objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
-
- Callback callback;
- callback.m_callbackData = createObjPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_writeSchemaConf2);
-
- updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
-
-}
-
-void
-Dbdict::createObj_writeSchemaConf2(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_commit_complete_done);
- if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
- {
- jam();
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
- (signal, createObjPtr.p);
- }
- else
- {
- jam();
- execute(signal, createObjPtr.p->m_callback, 0);
- }
-
-}
-
-void
-Dbdict::createObj_commit_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
- //@todo check error
- //@todo check master failed
-
- DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createObjPtr.p->m_senderData;
- sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
- signal, DictCommitConf::SignalLength, JBB);
-
- c_opCreateObj.release(createObjPtr);
-}
-
-void
-Dbdict::createObj_abort(Signal* signal, SchemaOp* op)
-{
- OpCreateObj * createObj = (OpCreateObj*)op;
-
- createObj->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_abort_start_done);
- if (f_dict_op[createObj->m_vt_index].m_abort_start)
- {
- jam();
- (this->*f_dict_op[createObj->m_vt_index].m_abort_start)(signal, createObj);
- }
- else
- {
- jam();
- execute(signal, createObj->m_callback, 0);
- }
-}
-
-void
-Dbdict::createObj_abort_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry objEntry = * getTableEntry(xsf,
- createObjPtr.p->m_obj_id);
- objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
-
- Callback callback;
- callback.m_callbackData = createObjPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_abort_writeSchemaConf);
-
- updateSchemaState(signal, createObjPtr.p->m_obj_id, &objEntry, &callback);
-}
-
-void
-Dbdict::createObj_abort_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
- createObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::createObj_abort_complete_done);
-
- if (f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
- {
- jam();
- (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
- (signal, createObjPtr.p);
- }
- else
- {
- jam();
- execute(signal, createObjPtr.p->m_callback, 0);
- }
-}
-
-void
-Dbdict::createObj_abort_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- CreateObjRecordPtr createObjPtr;
-
- jam();
- ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
- DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = createObjPtr.p->m_senderData;
- sendSignal(createObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
- signal, DictAbortConf::SignalLength, JBB);
-
- c_opCreateObj.release(createObjPtr);
-}
-
-void
-Dbdict::execDROP_OBJ_REQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- DropObjReq * const req = (DropObjReq*)signal->getDataPtr();
-
- const Uint32 objId = req->objId;
- const Uint32 objVersion = req->objVersion;
- const Uint32 objType = req->objType;
-
- DropObjRecordPtr dropObjPtr;
- ndbrequire(c_opDropObj.seize(dropObjPtr));
-
- const Uint32 key = req->op_key;
- dropObjPtr.p->key = key;
- c_opDropObj.add(dropObjPtr);
- dropObjPtr.p->m_errorCode = 0;
- dropObjPtr.p->m_senderRef = req->senderRef;
- dropObjPtr.p->m_senderData = req->senderData;
- dropObjPtr.p->m_clientRef = req->clientRef;
- dropObjPtr.p->m_clientData = req->clientData;
-
- dropObjPtr.p->m_obj_id = objId;
- dropObjPtr.p->m_obj_type = objType;
- dropObjPtr.p->m_obj_version = objVersion;
-
- dropObjPtr.p->m_callback.m_callbackData = key;
- dropObjPtr.p->m_callback.m_callbackFunction=
- safe_cast(&Dbdict::dropObj_prepare_start_done);
-
- switch(objType){
- case DictTabInfo::Tablespace:
- case DictTabInfo::LogfileGroup:
- {
- Ptr<Filegroup> fg_ptr;
- jam();
- dropObjPtr.p->m_vt_index = 3;
- ndbrequire(c_filegroup_hash.find(fg_ptr, objId));
- dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
- break;
-
- }
- case DictTabInfo::Datafile:
- {
- Ptr<File> file_ptr;
- jam();
- dropObjPtr.p->m_vt_index = 2;
- ndbrequire(c_file_hash.find(file_ptr, objId));
- dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
- break;
- }
- case DictTabInfo::Undofile:
- {
- jam();
- dropObjPtr.p->m_vt_index = 4;
- return;
- }
- default:
- ndbrequire(false);
- }
-
- signal->header.m_noOfSections = 0;
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_start)
- (signal, dropObjPtr.p);
-}
-
-void
-Dbdict::dropObj_prepare_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
- Callback cb;
-
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-
- cb.m_callbackData = callbackData;
- cb.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_prepare_writeSchemaConf);
-
- if(dropObjPtr.p->m_errorCode != 0)
- {
- jam();
- dropObj_prepare_complete_done(signal, callbackData, 0);
- return;
- }
- jam();
- Uint32 objId = dropObjPtr.p->m_obj_id;
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry objEntry = *getTableEntry(xsf, objId);
- objEntry.m_tableState = SchemaFile::DROP_TABLE_STARTED;
- updateSchemaState(signal, objId, &objEntry, &cb);
-}
-
-void
-Dbdict::dropObj_prepare_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_prepare_complete_done);
- if(f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
- {
- jam();
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
- (signal, dropObjPtr.p);
- }
- else
- {
- jam();
- execute(signal, dropObjPtr.p->m_callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_prepare_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- jam();
-
- //@todo check for master failed
-
- if(dropObjPtr.p->m_errorCode == 0){
- jam();
-
- DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = dropObjPtr.p->m_senderData;
- sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_CONF,
- signal, DropObjConf::SignalLength, JBB);
- return;
- }
-
- DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
- ref->senderRef = reference();
- ref->senderData = dropObjPtr.p->m_senderData;
- ref->errorCode = dropObjPtr.p->m_errorCode;
-
- sendSignal(dropObjPtr.p->m_senderRef, GSN_DROP_OBJ_REF,
- signal, DropObjRef::SignalLength, JBB);
-
-}
-
-void
-Dbdict::dropObj_commit(Signal * signal, SchemaOp * op)
-{
- OpDropObj * dropObj = (OpDropObj*)op;
-
- dropObj->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_commit_start_done);
- if (f_dict_op[dropObj->m_vt_index].m_commit_start)
- {
- jam();
- (this->*f_dict_op[dropObj->m_vt_index].m_commit_start)(signal, dropObj);
- }
- else
- {
- jam();
- execute(signal, dropObj->m_callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_commit_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-
- Uint32 objId = dropObjPtr.p->m_obj_id;
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry objEntry = * getTableEntry(xsf, objId);
- objEntry.m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
-
- Callback callback;
- callback.m_callbackData = dropObjPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_commit_writeSchemaConf);
-
- updateSchemaState(signal, objId, &objEntry, &callback);
-}
-
-void
-Dbdict::dropObj_commit_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_commit_complete_done);
-
- if(f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- {
- jam();
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
- (signal, dropObjPtr.p);
- }
- else
- {
- jam();
- execute(signal, dropObjPtr.p->m_callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_commit_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- jam();
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-
- //@todo check error
- //@todo check master failed
-
- DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
- conf->senderRef = reference();
- conf->senderData = dropObjPtr.p->m_senderData;
- sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
- signal, DictCommitConf::SignalLength, JBB);
- c_opDropObj.release(dropObjPtr);
-}
-
-void
-Dbdict::dropObj_abort(Signal * signal, SchemaOp * op)
-{
- OpDropObj * dropObj = (OpDropObj*)op;
-
- dropObj->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_abort_start_done);
- if (f_dict_op[dropObj->m_vt_index].m_abort_start)
- {
- jam();
- (this->*f_dict_op[dropObj->m_vt_index].m_abort_start)(signal, dropObj);
- }
- else
- {
- jam();
- execute(signal, dropObj->m_callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_abort_start_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- jam();
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- SchemaFile::TableEntry objEntry = * getTableEntry(xsf,
- dropObjPtr.p->m_obj_id);
-
- Callback callback;
- callback.m_callbackData = dropObjPtr.p->key;
- callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_abort_writeSchemaConf);
-
- if (objEntry.m_tableState == SchemaFile::DROP_TABLE_STARTED)
- {
- jam();
- objEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED;
-
- updateSchemaState(signal, dropObjPtr.p->m_obj_id, &objEntry, &callback);
- }
- else
- {
- jam();
- execute(signal, callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_abort_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
-
- ndbrequire(returnCode == 0);
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- dropObjPtr.p->m_callback.m_callbackFunction =
- safe_cast(&Dbdict::dropObj_abort_complete_done);
-
- if(f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
- {
- jam();
- (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
- (signal, dropObjPtr.p);
- }
- else
- {
- jam();
- execute(signal, dropObjPtr.p->m_callback, 0);
- }
-}
-
-void
-Dbdict::dropObj_abort_complete_done(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode)
-{
- DropObjRecordPtr dropObjPtr;
- DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
-
- ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
- jam();
- conf->senderRef = reference();
- conf->senderData = dropObjPtr.p->m_senderData;
- sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
- signal, DictAbortConf::SignalLength, JBB);
- c_opDropObj.release(dropObjPtr);
-}
-
-void
-Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op)
-{
- /**
- * Put data into table record
- */
- SegmentedSectionPtr objInfoPtr;
- jam();
- getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
- SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
-
- Ptr<DictObject> obj_ptr; obj_ptr.setNull();
- FilegroupPtr fg_ptr; fg_ptr.setNull();
-
- SimpleProperties::UnpackStatus status;
- DictFilegroupInfo::Filegroup fg; fg.init();
- do {
- status = SimpleProperties::unpack(it, &fg,
- DictFilegroupInfo::Mapping,
- DictFilegroupInfo::MappingSize,
- true, true);
-
- if(status != SimpleProperties::Eof)
- {
- jam();
- op->m_errorCode = CreateTableRef::InvalidFormat;
- break;
- }
-
- if(fg.FilegroupType == DictTabInfo::Tablespace)
- {
- if(!fg.TS_ExtentSize)
- {
- jam();
- op->m_errorCode = CreateFilegroupRef::InvalidExtentSize;
- break;
- }
- }
- else if(fg.FilegroupType == DictTabInfo::LogfileGroup)
- {
- /**
- * undo_buffer_size can't be less than 96KB in LGMAN block
- */
- if(fg.LF_UndoBufferSize < 3 * File_formats::NDB_PAGE_SIZE)
- {
- jam();
- op->m_errorCode = CreateFilegroupRef::InvalidUndoBufferSize;
- break;
- }
- }
-
- Uint32 len = strlen(fg.FilegroupName) + 1;
- Uint32 hash = Rope::hash(fg.FilegroupName, len);
- if(get_object(fg.FilegroupName, len, hash) != 0){
- jam();
- op->m_errorCode = CreateTableRef::TableAlreadyExist;
- break;
- }
-
- if(!c_obj_pool.seize(obj_ptr)){
- jam();
- op->m_errorCode = CreateTableRef::NoMoreTableRecords;
- break;
- }
-
- if(!c_filegroup_pool.seize(fg_ptr)){
- jam();
- op->m_errorCode = CreateTableRef::NoMoreTableRecords;
- break;
- }
-
- new (fg_ptr.p) Filegroup();
-
- {
- Rope name(c_rope_pool, obj_ptr.p->m_name);
- if(!name.assign(fg.FilegroupName, len, hash)){
- jam();
- op->m_errorCode = CreateTableRef::OutOfStringBuffer;
- break;
- }
- }
-
- fg_ptr.p->key = op->m_obj_id;
- fg_ptr.p->m_obj_ptr_i = obj_ptr.i;
- fg_ptr.p->m_type = fg.FilegroupType;
- fg_ptr.p->m_version = op->m_obj_version;
- fg_ptr.p->m_name = obj_ptr.p->m_name;
-
- switch(fg.FilegroupType){
- case DictTabInfo::Tablespace:
- {
- //fg.TS_DataGrow = group.m_grow_spec;
- fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
- fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
-
- Ptr<Filegroup> lg_ptr;
- if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
- {
- jam();
- op->m_errorCode = CreateFilegroupRef::NoSuchLogfileGroup;
- goto error;
- }
-
- if (lg_ptr.p->m_version != fg.TS_LogfileGroupVersion)
- {
- jam();
- op->m_errorCode = CreateFilegroupRef::InvalidFilegroupVersion;
- goto error;
- }
- increase_ref_count(lg_ptr.p->m_obj_ptr_i);
- break;
- }
- case DictTabInfo::LogfileGroup:
- {
- jam();
- fg_ptr.p->m_logfilegroup.m_undo_buffer_size = fg.LF_UndoBufferSize;
- fg_ptr.p->m_logfilegroup.m_files.init();
- //fg.LF_UndoGrow = ;
- break;
- }
- default:
- ndbrequire(false);
- }
-
- obj_ptr.p->m_id = op->m_obj_id;
- obj_ptr.p->m_type = fg.FilegroupType;
- obj_ptr.p->m_ref_count = 0;
- c_obj_hash.add(obj_ptr);
- c_filegroup_hash.add(fg_ptr);
-
- op->m_obj_ptr_i = fg_ptr.i;
- } while(0);
-
-error:
- if (op->m_errorCode)
- {
- jam();
- if (!fg_ptr.isNull())
- {
- jam();
- c_filegroup_pool.release(fg_ptr);
- }
-
- if (!obj_ptr.isNull())
- {
- jam();
- c_obj_pool.release(obj_ptr);
- }
- }
-
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::create_fg_prepare_complete(Signal* signal, SchemaOp* op)
-{
- /**
- * CONTACT TSMAN LGMAN PGMAN
- */
- CreateFilegroupImplReq* req =
- (CreateFilegroupImplReq*)signal->getDataPtrSend();
- jam();
- req->senderData = op->key;
- req->senderRef = reference();
- req->filegroup_id = op->m_obj_id;
- req->filegroup_version = op->m_obj_version;
-
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-
- Uint32 ref= 0;
- Uint32 len= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Tablespace:
- {
- jam();
- ref = TSMAN_REF;
- len = CreateFilegroupImplReq::TablespaceLength;
- req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
- req->tablespace.logfile_group_id =
- fg_ptr.p->m_tablespace.m_default_logfile_group_id;
- break;
- }
- case DictTabInfo::LogfileGroup:
- {
- jam();
- ref = LGMAN_REF;
- len = CreateFilegroupImplReq::LogfileGroupLength;
- req->logfile_group.buffer_size =
- fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
- break;
- }
- default:
- ndbrequire(false);
- }
-
- sendSignal(ref, GSN_CREATE_FILEGROUP_REQ, signal, len, JBB);
-}
-
-void
-Dbdict::execCREATE_FILEGROUP_REF(Signal* signal)
-{
- CreateFilegroupImplRef * ref = (CreateFilegroupImplRef*)signal->getDataPtr();
- CreateObjRecordPtr op_ptr;
- jamEntry();
- ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
- op_ptr.p->m_errorCode = ref->errorCode;
-
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal)
-{
- CreateFilegroupImplConf * rep =
- (CreateFilegroupImplConf*)signal->getDataPtr();
- CreateObjRecordPtr op_ptr;
- jamEntry();
- ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
-
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
- (void) signal->getDataPtrSend();
-
- if (op->m_obj_ptr_i != RNIL)
- {
- jam();
- send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
- return;
- }
- jam();
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op)
-{
- if (op->m_obj_ptr_i != RNIL)
- {
- jam();
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-
- release_object(fg_ptr.p->m_obj_ptr_i);
- c_filegroup_hash.release(fg_ptr);
- }
- jam();
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op)
-{
- /**
- * Put data into table record
- */
- SegmentedSectionPtr objInfoPtr;
- getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
- SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
-
- Ptr<DictObject> obj_ptr; obj_ptr.setNull();
- FilePtr filePtr; filePtr.setNull();
-
- DictFilegroupInfo::File f; f.init();
- SimpleProperties::UnpackStatus status;
- status = SimpleProperties::unpack(it, &f,
- DictFilegroupInfo::FileMapping,
- DictFilegroupInfo::FileMappingSize,
- true, true);
-
- do {
- if(status != SimpleProperties::Eof){
- jam();
- op->m_errorCode = CreateFileRef::InvalidFormat;
- break;
- }
-
- // Get Filegroup
- FilegroupPtr fg_ptr;
- if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
- jam();
- op->m_errorCode = CreateFileRef::NoSuchFilegroup;
- break;
- }
-
- if(fg_ptr.p->m_version != f.FilegroupVersion){
- jam();
- op->m_errorCode = CreateFileRef::InvalidFilegroupVersion;
- break;
- }
-
- switch(f.FileType){
- case DictTabInfo::Datafile:
- {
- if(fg_ptr.p->m_type != DictTabInfo::Tablespace)
- {
- jam();
- op->m_errorCode = CreateFileRef::InvalidFileType;
- }
- jam();
- break;
- }
- case DictTabInfo::Undofile:
- {
- if(fg_ptr.p->m_type != DictTabInfo::LogfileGroup)
- {
- jam();
- op->m_errorCode = CreateFileRef::InvalidFileType;
- }
- jam();
- break;
- }
- default:
- jam();
- op->m_errorCode = CreateFileRef::InvalidFileType;
- }
-
- if(op->m_errorCode)
- {
- jam();
- break;
- }
-
- Uint32 len = strlen(f.FileName) + 1;
- Uint32 hash = Rope::hash(f.FileName, len);
- if(get_object(f.FileName, len, hash) != 0){
- jam();
- op->m_errorCode = CreateFileRef::FilenameAlreadyExists;
- break;
- }
-
- {
- Uint32 dl;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- if(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl)
- {
- jam();
- op->m_errorCode = CreateFileRef::NotSupportedWhenDiskless;
- break;
- }
- }
-
- // Loop through all filenames...
- if(!c_obj_pool.seize(obj_ptr)){
- jam();
- op->m_errorCode = CreateTableRef::NoMoreTableRecords;
- break;
- }
-
- if (! c_file_pool.seize(filePtr)){
- jam();
- op->m_errorCode = CreateFileRef::OutOfFileRecords;
- break;
- }
-
- new (filePtr.p) File();
-
- {
- Rope name(c_rope_pool, obj_ptr.p->m_name);
- if(!name.assign(f.FileName, len, hash)){
- jam();
- op->m_errorCode = CreateTableRef::OutOfStringBuffer;
- break;
- }
- }
-
- switch(fg_ptr.p->m_type){
- case DictTabInfo::Tablespace:
- {
- jam();
- increase_ref_count(fg_ptr.p->m_obj_ptr_i);
- break;
- }
- case DictTabInfo::LogfileGroup:
- {
- jam();
- Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
- list.add(filePtr);
- break;
- }
- default:
- ndbrequire(false);
- }
-
- /**
- * Init file
- */
- filePtr.p->key = op->m_obj_id;
- filePtr.p->m_file_size = ((Uint64)f.FileSizeHi) << 32 | f.FileSizeLo;
- filePtr.p->m_path = obj_ptr.p->m_name;
- filePtr.p->m_obj_ptr_i = obj_ptr.i;
- filePtr.p->m_filegroup_id = f.FilegroupId;
- filePtr.p->m_type = f.FileType;
- filePtr.p->m_version = op->m_obj_version;
-
- obj_ptr.p->m_id = op->m_obj_id;
- obj_ptr.p->m_type = f.FileType;
- obj_ptr.p->m_ref_count = 0;
- c_obj_hash.add(obj_ptr);
- c_file_hash.add(filePtr);
-
- op->m_obj_ptr_i = filePtr.i;
- } while(0);
-
- if (op->m_errorCode)
- {
- jam();
- if (!filePtr.isNull())
- {
- jam();
- c_file_pool.release(filePtr);
- }
-
- if (!obj_ptr.isNull())
- {
- jam();
- c_obj_pool.release(obj_ptr);
- }
- }
- execute(signal, op->m_callback, 0);
-}
-
-
-void
-Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op)
-{
- /**
- * CONTACT TSMAN LGMAN PGMAN
- */
- CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
-
- req->senderData = op->key;
- req->senderRef = reference();
- switch(((OpCreateObj*)op)->m_restart){
- case 0:
- {
- jam();
- req->requestInfo = CreateFileImplReq::Create;
- break;
- }
- case 1:
- {
- jam();
- req->requestInfo = CreateFileImplReq::Open;
- break;
- }
- case 2:
- {
- jam();
- req->requestInfo = CreateFileImplReq::CreateForce;
- break;
- }
- }
-
- req->file_id = f_ptr.p->key;
- req->filegroup_id = f_ptr.p->m_filegroup_id;
- req->filegroup_version = fg_ptr.p->m_version;
- req->file_size_hi = f_ptr.p->m_file_size >> 32;
- req->file_size_lo = f_ptr.p->m_file_size & 0xFFFFFFFF;
-
- Uint32 ref= 0;
- Uint32 len= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Datafile:
- {
- jam();
- ref = TSMAN_REF;
- len = CreateFileImplReq::DatafileLength;
- req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
- break;
- }
- case DictTabInfo::Undofile:
- {
- jam();
- ref = LGMAN_REF;
- len = CreateFileImplReq::UndofileLength;
- break;
- }
- default:
- ndbrequire(false);
- }
-
- char name[MAX_TAB_NAME_SIZE];
- ConstRope tmp(c_rope_pool, f_ptr.p->m_path);
- tmp.copy(name);
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)&name[0];
- ptr[0].sz = (strlen(name)+1+3)/4;
- sendSignal(ref, GSN_CREATE_FILE_REQ, signal, len, JBB, ptr, 1);
-}
-
-void
-Dbdict::execCREATE_FILE_REF(Signal* signal)
-{
- CreateFileImplRef * ref = (CreateFileImplRef*)signal->getDataPtr();
- CreateObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
- op_ptr.p->m_errorCode = ref->errorCode;
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::execCREATE_FILE_CONF(Signal* signal)
-{
- CreateFileImplConf * rep =
- (CreateFileImplConf*)signal->getDataPtr();
- CreateObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::create_file_commit_start(Signal* signal, SchemaOp* op)
-{
- /**
- * CONTACT TSMAN LGMAN PGMAN
- */
- CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
-
- req->senderData = op->key;
- req->senderRef = reference();
- req->requestInfo = CreateFileImplReq::Commit;
-
- req->file_id = f_ptr.p->key;
- req->filegroup_id = f_ptr.p->m_filegroup_id;
- req->filegroup_version = fg_ptr.p->m_version;
-
- Uint32 ref= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Datafile:
- {
- jam();
- ref = TSMAN_REF;
- break;
- }
- case DictTabInfo::Undofile:
- {
- jam();
- ref = LGMAN_REF;
- break;
- }
- default:
- ndbrequire(false);
- }
- sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
- CreateFileImplReq::CommitLength, JBB);
-}
-
-void
-Dbdict::create_file_abort_start(Signal* signal, SchemaOp* op)
-{
- CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
-
- if (op->m_obj_ptr_i != RNIL)
- {
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
-
- req->senderData = op->key;
- req->senderRef = reference();
- req->requestInfo = CreateFileImplReq::Abort;
-
- req->file_id = f_ptr.p->key;
- req->filegroup_id = f_ptr.p->m_filegroup_id;
- req->filegroup_version = fg_ptr.p->m_version;
-
- Uint32 ref= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Datafile:
- {
- jam();
- ref = TSMAN_REF;
- break;
- }
- case DictTabInfo::Undofile:
- {
- jam();
- ref = LGMAN_REF;
- break;
- }
- default:
- ndbrequire(false);
- }
- sendSignal(ref, GSN_CREATE_FILE_REQ, signal,
- CreateFileImplReq::AbortLength, JBB);
- return;
- }
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
-{
- if (op->m_obj_ptr_i != RNIL)
- {
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
- switch(fg_ptr.p->m_type){
- case DictTabInfo::Tablespace:
- {
- jam();
- decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
- break;
- }
- case DictTabInfo::LogfileGroup:
- {
- jam();
- Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
- list.remove(f_ptr);
- break;
- }
- default:
- ndbrequire(false);
- }
-
- release_object(f_ptr.p->m_obj_ptr_i);
- c_file_hash.release(f_ptr);
- }
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
-{
- jam();
- send_drop_file(signal, op, DropFileImplReq::Prepare);
-}
-
-void
-Dbdict::drop_undofile_prepare_start(Signal* signal, SchemaOp* op)
-{
- jam();
- op->m_errorCode = DropFileRef::DropUndoFileNotSupported;
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::drop_file_commit_start(Signal* signal, SchemaOp* op)
-{
- jam();
- send_drop_file(signal, op, DropFileImplReq::Commit);
-}
-
-void
-Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
-{
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
- decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
- release_object(f_ptr.p->m_obj_ptr_i);
- c_file_hash.release(f_ptr);
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::drop_undofile_commit_complete(Signal* signal, SchemaOp* op)
-{
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
- Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
- list.remove(f_ptr);
- release_object(f_ptr.p->m_obj_ptr_i);
- c_file_hash.release(f_ptr);
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op)
-{
- jam();
- send_drop_file(signal, op, DropFileImplReq::Abort);
-}
-
-void
-Dbdict::send_drop_file(Signal* signal, SchemaOp* op,
- DropFileImplReq::RequestInfo type)
-{
- DropFileImplReq* req = (DropFileImplReq*)signal->getDataPtrSend();
- FilePtr f_ptr;
- FilegroupPtr fg_ptr;
-
- jam();
- c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
- ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
-
- req->senderData = op->key;
- req->senderRef = reference();
- req->requestInfo = type;
-
- req->file_id = f_ptr.p->key;
- req->filegroup_id = f_ptr.p->m_filegroup_id;
- req->filegroup_version = fg_ptr.p->m_version;
-
- Uint32 ref= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Datafile:
- {
- jam();
- ref = TSMAN_REF;
- break;
- }
- case DictTabInfo::Undofile:
- {
- jam();
- ref = LGMAN_REF;
- break;
- }
- default:
- ndbrequire(false);
- }
- sendSignal(ref, GSN_DROP_FILE_REQ, signal,
- DropFileImplReq::SignalLength, JBB);
-}
-
-void
-Dbdict::execDROP_OBJ_REF(Signal* signal)
-{
- DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
- if(ref->errorCode != DropObjRef::NF_FakeErrorREF){
- jam();
- trans_ptr.p->setErrorCode(ref->errorCode);
- }
- Uint32 node = refToNode(ref->senderRef);
- schemaOp_reply(signal, trans_ptr.p, node);
-}
-
-void
-Dbdict::execDROP_OBJ_CONF(Signal* signal)
-{
- DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
- Ptr<SchemaTransaction> trans_ptr;
-
- jamEntry();
- ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
- schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
-}
-
-void
-Dbdict::execDROP_FILE_REF(Signal* signal)
-{
- DropFileImplRef * ref = (DropFileImplRef*)signal->getDataPtr();
- DropObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
- op_ptr.p->m_errorCode = ref->errorCode;
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::execDROP_FILE_CONF(Signal* signal)
-{
- DropFileImplConf * rep =
- (DropFileImplConf*)signal->getDataPtr();
- DropObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::execDROP_FILEGROUP_REF(Signal* signal)
-{
- DropFilegroupImplRef * ref = (DropFilegroupImplRef*)signal->getDataPtr();
- DropObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
- op_ptr.p->m_errorCode = ref->errorCode;
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::execDROP_FILEGROUP_CONF(Signal* signal)
-{
- DropFilegroupImplConf * rep =
- (DropFilegroupImplConf*)signal->getDataPtr();
- DropObjRecordPtr op_ptr;
-
- jamEntry();
- ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
- execute(signal, op_ptr.p->m_callback, 0);
-}
-
-void
-Dbdict::drop_fg_prepare_start(Signal* signal, SchemaOp* op)
-{
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-
- DictObject * obj = c_obj_pool.getPtr(fg_ptr.p->m_obj_ptr_i);
- if (obj->m_ref_count)
- {
- jam();
- op->m_errorCode = DropFilegroupRef::FilegroupInUse;
- execute(signal, op->m_callback, 0);
- }
- else
- {
- jam();
- send_drop_fg(signal, op, DropFilegroupImplReq::Prepare);
- }
-}
-
-void
-Dbdict::drop_fg_commit_start(Signal* signal, SchemaOp* op)
-{
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
- if (op->m_obj_type == DictTabInfo::LogfileGroup)
- {
- jam();
- /**
- * Mark all undofiles as dropped
- */
- Ptr<File> filePtr;
- Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
- XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
- for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
- {
- jam();
- Uint32 objId = filePtr.p->key;
- SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, objId);
- tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
- computeChecksum(xsf, objId / NDB_SF_PAGE_ENTRIES);
- release_object(filePtr.p->m_obj_ptr_i);
- c_file_hash.remove(filePtr);
- }
- list.release();
- }
- else if(op->m_obj_type == DictTabInfo::Tablespace)
- {
- FilegroupPtr lg_ptr;
- jam();
- ndbrequire(c_filegroup_hash.
- find(lg_ptr,
- fg_ptr.p->m_tablespace.m_default_logfile_group_id));
-
- decrease_ref_count(lg_ptr.p->m_obj_ptr_i);
- }
- jam();
- send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
-}
-
-void
-Dbdict::drop_fg_commit_complete(Signal* signal, SchemaOp* op)
-{
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-
- jam();
- release_object(fg_ptr.p->m_obj_ptr_i);
- c_filegroup_hash.release(fg_ptr);
- execute(signal, op->m_callback, 0);
-}
-
-void
-Dbdict::drop_fg_abort_start(Signal* signal, SchemaOp* op)
-{
- jam();
- send_drop_fg(signal, op, DropFilegroupImplReq::Abort);
-}
-
-void
-Dbdict::send_drop_fg(Signal* signal, SchemaOp* op,
- DropFilegroupImplReq::RequestInfo type)
-{
- DropFilegroupImplReq* req = (DropFilegroupImplReq*)signal->getDataPtrSend();
-
- FilegroupPtr fg_ptr;
- c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-
- req->senderData = op->key;
- req->senderRef = reference();
- req->requestInfo = type;
-
- req->filegroup_id = fg_ptr.p->key;
- req->filegroup_version = fg_ptr.p->m_version;
-
- Uint32 ref= 0;
- switch(op->m_obj_type){
- case DictTabInfo::Tablespace:
- ref = TSMAN_REF;
- break;
- case DictTabInfo::LogfileGroup:
- ref = LGMAN_REF;
- break;
- default:
- ndbrequire(false);
- }
-
- sendSignal(ref, GSN_DROP_FILEGROUP_REQ, signal,
- DropFilegroupImplReq::SignalLength, JBB);
-}
-
-/*
- return 1 if all of the below is true
- a) node in single user mode
- b) senderRef is not a db node
- c) senderRef nodeid is not the singleUserApi
-*/
-int Dbdict::checkSingleUserMode(Uint32 senderRef)
-{
- Uint32 nodeId = refToNode(senderRef);
- return
- getNodeState().getSingleUserMode() &&
- (getNodeInfo(nodeId).m_type != NodeInfo::DB) &&
- (nodeId != getNodeState().getSingleUserApi());
-}
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
deleted file mode 100644
index 6d738740e87..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
+++ /dev/null
@@ -1,2707 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBDICT_H
-#define DBDICT_H
-
-/**
- * Dict : Dictionary Block
- */
-#include <ndb_limits.h>
-#include <trigger_definitions.h>
-#include <pc.hpp>
-#include <DLHashTable.hpp>
-#include <DLFifoList.hpp>
-#include <CArray.hpp>
-#include <KeyTable.hpp>
-#include <KeyTable2.hpp>
-#include <KeyTable2Ref.hpp>
-#include <SimulatedBlock.hpp>
-#include <SimpleProperties.hpp>
-#include <SignalCounter.hpp>
-#include <Bitmask.hpp>
-#include <AttributeList.hpp>
-#include <signaldata/GetTableId.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/CreateTable.hpp>
-#include <signaldata/CreateTab.hpp>
-#include <signaldata/DropTable.hpp>
-#include <signaldata/AlterTable.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/CreateIndx.hpp>
-#include <signaldata/DropIndx.hpp>
-#include <signaldata/AlterIndx.hpp>
-#include <signaldata/BuildIndx.hpp>
-#include <signaldata/UtilPrepare.hpp>
-#include <signaldata/CreateEvnt.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/AlterTrig.hpp>
-#include <signaldata/DictLock.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include "SchemaFile.hpp"
-#include <blocks/mutexes.hpp>
-#include <SafeCounter.hpp>
-#include <RequestTracker.hpp>
-#include <Rope.hpp>
-#include <signaldata/DictObjOp.hpp>
-#include <signaldata/DropFilegroupImpl.hpp>
-#include <SLList.hpp>
-
-#ifdef DBDICT_C
-// Debug Macros
-
-/*--------------------------------------------------------------*/
-// Constants for CONTINUEB
-/*--------------------------------------------------------------*/
-#define ZPACK_TABLE_INTO_PAGES 0
-#define ZSEND_GET_TAB_RESPONSE 3
-#define ZDICT_LOCK_POLL 4
-
-
-/*--------------------------------------------------------------*/
-// Other constants in alphabetical order
-/*--------------------------------------------------------------*/
-#define ZNOMOREPHASES 255
-
-/*--------------------------------------------------------------*/
-// Schema file defines
-/*--------------------------------------------------------------*/
-#define ZSCHEMA_WORDS 4
-
-/*--------------------------------------------------------------*/
-// Page constants
-/*--------------------------------------------------------------*/
-#define ZBAT_SCHEMA_FILE 0 //Variable number of page for NDBFS
-#define ZBAT_TABLE_FILE 1 //Variable number of page for NDBFS
-#define ZPAGE_HEADER_SIZE 32
-#define ZPOS_PAGE_SIZE 16
-#define ZPOS_CHECKSUM 17
-#define ZPOS_VERSION 18
-#define ZPOS_PAGE_HEADER_SIZE 19
-
-/*--------------------------------------------------------------*/
-// Size constants
-/*--------------------------------------------------------------*/
-#define ZFS_CONNECT_SIZE 4
-#define ZSIZE_OF_PAGES_IN_WORDS 8192
-#define ZLOG_SIZE_OF_PAGES_IN_WORDS 13
-#define ZMAX_PAGES_OF_TABLE_DEFINITION 8
-#define ZNUMBER_OF_PAGES (ZMAX_PAGES_OF_TABLE_DEFINITION + 1)
-#define ZNO_OF_FRAGRECORD 5
-
-/*--------------------------------------------------------------*/
-// Error codes
-/*--------------------------------------------------------------*/
-#define ZNODE_FAILURE_ERROR 704
-#endif
-
-/**
- * Systable NDB$EVENTS_0
- */
-#define EVENT_SYSTEM_TABLE_LENGTH 8
-
-struct sysTab_NDBEVENTS_0 {
- char NAME[MAX_TAB_NAME_SIZE];
- Uint32 EVENT_TYPE;
- Uint32 TABLEID;
- Uint32 TABLEVERSION;
- char TABLE_NAME[MAX_TAB_NAME_SIZE];
- Uint32 ATTRIBUTE_MASK[MAXNROFATTRIBUTESINWORDS];
- Uint32 SUBID;
- Uint32 SUBKEY;
-};
-
-/**
- * DICT - This blocks handles all metadata
- */
-class Dbdict: public SimulatedBlock {
-public:
- /*
- * 2.3 RECORD AND FILESIZES
- */
-
- /**
- * Table attributes. Permanent data.
- *
- * Indexes have an attribute list which duplicates primary table
- * attributes. This is wrong but convenient.
- */
- struct AttributeRecord {
- AttributeRecord(){}
-
- /* attribute id */
- Uint16 attributeId;
-
- /* Attribute number within tuple key (counted from 1) */
- Uint16 tupleKey;
-
- /* Attribute name (unique within table) */
- RopeHandle attributeName;
-
- /* Attribute description (old-style packed descriptor) */
- Uint32 attributeDescriptor;
-
- /* Extended attributes */
- Uint32 extType;
- Uint32 extPrecision;
- Uint32 extScale;
- Uint32 extLength;
-
- /* Autoincrement flag, only for ODBC/SQL */
- bool autoIncrement;
-
- /* Default value as null-terminated string, only for ODBC/SQL */
- RopeHandle defaultValue;
-
- struct {
- Uint32 m_name_len;
- const char * m_name_ptr;
- RopePool * m_pool;
- } m_key;
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- Uint32 nextHash;
- Uint32 prevHash;
-
- Uint32 hashValue() const { return attributeName.hashValue();}
- bool equal(const AttributeRecord& obj) const {
- if(obj.hashValue() == hashValue()){
- ConstRope r(* m_key.m_pool, obj.attributeName);
- return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
- }
- return false;
- }
-
- /** Singly linked in internal (attributeId) order */
- // TODO use DL template when possible to have more than 1
- Uint32 nextAttributeIdPtrI;
- };
- typedef Ptr<AttributeRecord> AttributeRecordPtr;
- ArrayPool<AttributeRecord> c_attributeRecordPool;
- DLHashTable<AttributeRecord> c_attributeRecordHash;
-
- /**
- * Shared table / index record. Most of this is permanent data stored
- * on disk. Index trigger ids are volatile.
- */
- struct TableRecord {
- TableRecord(){}
- Uint32 maxRowsLow;
- Uint32 maxRowsHigh;
- Uint32 minRowsLow;
- Uint32 minRowsHigh;
- /* Table id (array index in DICT and other blocks) */
- Uint32 tableId;
- Uint32 m_obj_ptr_i;
-
- /* Table version (incremented when tableId is re-used) */
- Uint32 tableVersion;
-
- /* Table name (may not be unique under "alter table") */
- RopeHandle tableName;
-
- /* Type of table or index */
- DictTabInfo::TableType tableType;
-
- /* Is table or index online (this flag is not used in DICT) */
- bool online;
-
- /* Primary table of index otherwise RNIL */
- Uint32 primaryTableId;
-
- /* Type of fragmentation (small/medium/large) */
- DictTabInfo::FragmentType fragmentType;
-
- /* Global checkpoint identity when table created */
- Uint32 gciTableCreated;
-
- /* Is the table logged (i.e. data survives system restart) */
- enum Bits
- {
- TR_Logged = 0x1,
- TR_RowGCI = 0x2,
- TR_RowChecksum = 0x4,
- TR_Temporary = 0x8,
- TR_ForceVarPart = 0x10
- };
- Uint16 m_bits;
-
- /* Number of attibutes in table */
- Uint16 noOfAttributes;
-
- /* Number of null attributes in table (should be computed) */
- Uint16 noOfNullAttr;
-
- /* Number of primary key attributes (should be computed) */
- Uint16 noOfPrimkey;
-
- /* Length of primary key in words (should be computed) */
- /* For ordered index this is tree node size in words */
- Uint16 tupKeyLength;
-
- /** */
- Uint16 noOfCharsets;
-
- /* K value for LH**3 algorithm (only 6 allowed currently) */
- Uint8 kValue;
-
- /* Local key length in words (currently 1) */
- Uint8 localKeyLen;
-
- /*
- * Parameter for hash algorithm that specifies the load factor in
- * percentage of fill level in buckets. A high value means we are
- * splitting early and that buckets are only lightly used. A high
- * value means that we have fill the buckets more and get more
- * likelihood of overflow buckets.
- */
- Uint8 maxLoadFactor;
-
- /*
- Flag to indicate default number of partitions
- */
- bool defaultNoPartFlag;
-
- /*
- Flag to indicate using linear hash function
- */
- bool linearHashFlag;
-
- /*
- * Used when shrinking to decide when to merge buckets. Hysteresis
- * is thus possible. Should be smaller but not much smaller than
- * maxLoadFactor
- */
- Uint8 minLoadFactor;
-
- /* Convenience routines */
- bool isTable() const;
- bool isIndex() const;
- bool isUniqueIndex() const;
- bool isNonUniqueIndex() const;
- bool isHashIndex() const;
- bool isOrderedIndex() const;
-
- /****************************************************
- * Support variables for table handling
- ****************************************************/
-
- /* Active page which is sent to disk */
- Uint32 activePage;
-
- /** File pointer received from disk */
- Uint32 filePtr[2];
-
- /** Pointer to first attribute in table */
- DLFifoList<AttributeRecord>::Head m_attributes;
-
- /* Pointer to first page of table description */
- Uint32 firstPage;
-
- Uint32 nextPool;
-
- enum TabState {
- NOT_DEFINED = 0,
- DEFINING = 2,
- DEFINED = 4,
- PREPARE_DROPPING = 5,
- DROPPING = 6,
- BACKUP_ONGOING = 7
- };
- TabState tabState;
-
- /* State when returning from TC_SCHVERREQ */
- enum TabReturnState {
- TRS_IDLE = 0,
- ADD_TABLE = 1,
- SLAVE_SYSTEM_RESTART = 2,
- MASTER_SYSTEM_RESTART = 3
- };
- TabReturnState tabReturnState;
-
- /** Number of words */
- Uint32 packedSize;
-
- /** Index state (volatile data) */
- enum IndexState {
- IS_UNDEFINED = 0, // initial
- IS_OFFLINE = 1, // index table created
- IS_BUILDING = 2, // building (local state)
- IS_DROPPING = 3, // dropping (local state)
- IS_ONLINE = 4, // online
- IS_BROKEN = 9 // build or drop aborted
- };
- IndexState indexState;
-
- /** Trigger ids of index (volatile data) */
- Uint32 insertTriggerId;
- Uint32 updateTriggerId;
- Uint32 deleteTriggerId;
- Uint32 customTriggerId; // ordered index
- Uint32 buildTriggerId; // temp during build
-
- /** Index state in other blocks on this node */
- enum IndexLocal {
- IL_CREATED_TC = 1 << 0 // created in TC
- };
- Uint32 indexLocal;
-
- Uint32 noOfNullBits;
-
- /** frm data for this table */
- RopeHandle frmData;
- RopeHandle tsData;
- RopeHandle ngData;
- RopeHandle rangeData;
-
- Uint32 fragmentCount;
- Uint32 m_tablespace_id;
-
- /*
- * Access rights to table during single user mode
- */
- Uint8 singleUserMode;
- };
-
- typedef Ptr<TableRecord> TableRecordPtr;
- ArrayPool<TableRecord> c_tableRecordPool;
-
- /** Node Group and Tablespace id+version + range or list data.
- * This is only stored temporarily in DBDICT during an ongoing
- * change.
- * TODO RONM: Look into improvements of this
- */
- Uint32 c_fragDataLen;
- Uint16 c_fragData[MAX_NDB_PARTITIONS];
- Uint32 c_tsIdData[2*MAX_NDB_PARTITIONS];
-
- /**
- * Triggers. This is volatile data not saved on disk. Setting a
- * trigger online creates the trigger in TC (if index) and LQH-TUP.
- */
- struct TriggerRecord {
- TriggerRecord() {}
-
- /** Trigger state */
- enum TriggerState {
- TS_NOT_DEFINED = 0,
- TS_DEFINING = 1,
- TS_OFFLINE = 2, // created globally in DICT
- TS_BUILDING = 3,
- TS_DROPPING = 4,
- TS_ONLINE = 5 // activated globally
- };
- TriggerState triggerState;
-
- /** Trigger state in other blocks on this node */
- enum IndexLocal {
- TL_CREATED_TC = 1 << 0, // created in TC
- TL_CREATED_LQH = 1 << 1 // created in LQH-TUP
- };
- Uint32 triggerLocal;
-
- /** Trigger name, used by DICT to identify the trigger */
- RopeHandle triggerName;
-
- /** Trigger id, used by TRIX, TC, LQH, and TUP to identify the trigger */
- Uint32 triggerId;
- Uint32 m_obj_ptr_i;
-
- /** Table id, the table the trigger is defined on */
- Uint32 tableId;
-
- /** Trigger type, defines what the trigger is used for */
- TriggerType::Value triggerType;
-
- /** Trigger action time, defines when the trigger should fire */
- TriggerActionTime::Value triggerActionTime;
-
- /** Trigger event, defines what events the trigger should monitor */
- TriggerEvent::Value triggerEvent;
-
- /** Monitor all replicas */
- bool monitorReplicas;
-
- /** Monitor all, the trigger monitors changes of all attributes in table */
- bool monitorAllAttributes;
-
- /** Monitor all, the trigger monitors changes of all attributes in table */
- bool reportAllMonitoredAttributes;
-
- /**
- * Attribute mask, defines what attributes are to be monitored.
- * Can be seen as a compact representation of SQL column name list.
- */
- AttributeMask attributeMask;
-
- /** Index id, only used by secondary_index triggers */
- Uint32 indexId;
-
- /** Pointer to the next attribute used by ArrayPool */
- Uint32 nextPool;
- };
-
- Uint32 c_maxNoOfTriggers;
- typedef Ptr<TriggerRecord> TriggerRecordPtr;
- ArrayPool<TriggerRecord> c_triggerRecordPool;
-
- /**
- * Information for each FS connection.
- ***************************************************************************/
- struct FsConnectRecord {
- enum FsState {
- IDLE = 0,
- OPEN_WRITE_SCHEMA = 1,
- WRITE_SCHEMA = 2,
- CLOSE_WRITE_SCHEMA = 3,
- OPEN_READ_SCHEMA1 = 4,
- OPEN_READ_SCHEMA2 = 5,
- READ_SCHEMA1 = 6,
- READ_SCHEMA2 = 7,
- CLOSE_READ_SCHEMA = 8,
- OPEN_READ_TAB_FILE1 = 9,
- OPEN_READ_TAB_FILE2 = 10,
- READ_TAB_FILE1 = 11,
- READ_TAB_FILE2 = 12,
- CLOSE_READ_TAB_FILE = 13,
- OPEN_WRITE_TAB_FILE = 14,
- WRITE_TAB_FILE = 15,
- CLOSE_WRITE_TAB_FILE = 16
- };
- /** File Pointer for this file system connection */
- Uint32 filePtr;
-
- /** Reference of owner record */
- Uint32 ownerPtr;
-
- /** State of file system connection */
- FsState fsState;
-
- /** Used by Array Pool for free list handling */
- Uint32 nextPool;
- };
-
- typedef Ptr<FsConnectRecord> FsConnectRecordPtr;
- ArrayPool<FsConnectRecord> c_fsConnectRecordPool;
-
- /**
- * This record stores all the information about a node and all its attributes
- ***************************************************************************/
- struct NodeRecord {
- enum NodeState {
- API_NODE = 0,
- NDB_NODE_ALIVE = 1,
- NDB_NODE_DEAD = 2
- };
- bool hotSpare;
- NodeState nodeState;
- };
-
- typedef Ptr<NodeRecord> NodeRecordPtr;
- CArray<NodeRecord> c_nodes;
- NdbNodeBitmask c_aliveNodes;
-
- struct PageRecord {
- Uint32 word[8192];
- };
-
- typedef Ptr<PageRecord> PageRecordPtr;
- CArray<PageRecord> c_pageRecordArray;
-
- struct SchemaPageRecord {
- Uint32 word[NDB_SF_PAGE_SIZE_IN_WORDS];
- };
-
- CArray<SchemaPageRecord> c_schemaPageRecordArray;
-
- DictTabInfo::Table c_tableDesc;
-
- /**
- * A page for create index table signal.
- */
- PageRecord c_indexPage;
-
- struct File {
- File() {}
-
- Uint32 key;
- Uint32 m_magic;
- Uint32 m_version;
- Uint32 m_obj_ptr_i;
- Uint32 m_filegroup_id;
- Uint32 m_type;
- Uint64 m_file_size;
- Uint64 m_file_free;
- RopeHandle m_path;
-
- Uint32 nextList;
- union {
- Uint32 prevList;
- Uint32 nextPool;
- };
- Uint32 nextHash, prevHash;
-
- Uint32 hashValue() const { return key;}
- bool equal(const File& obj) const { return key == obj.key;}
- };
- typedef Ptr<File> FilePtr;
- typedef RecordPool<File, RWPool> File_pool;
- typedef DLListImpl<File_pool, File> File_list;
- typedef LocalDLListImpl<File_pool, File> Local_file_list;
- typedef KeyTableImpl<File_pool, File> File_hash;
-
- struct Filegroup {
- Filegroup(){}
-
- Uint32 key;
- Uint32 m_obj_ptr_i;
- Uint32 m_magic;
-
- Uint32 m_type;
- Uint32 m_version;
- RopeHandle m_name;
-
- union {
- struct {
- Uint32 m_extent_size;
- Uint32 m_default_logfile_group_id;
- } m_tablespace;
-
- struct {
- Uint32 m_undo_buffer_size;
- File_list::HeadPOD m_files;
- } m_logfilegroup;
- };
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- Uint32 nextHash;
- };
- Uint32 prevHash;
-
- Uint32 hashValue() const { return key;}
- bool equal(const Filegroup& obj) const { return key == obj.key;}
- };
- typedef Ptr<Filegroup> FilegroupPtr;
- typedef RecordPool<Filegroup, RWPool> Filegroup_pool;
- typedef KeyTableImpl<Filegroup_pool, Filegroup> Filegroup_hash;
-
- File_pool c_file_pool;
- Filegroup_pool c_filegroup_pool;
- File_hash c_file_hash;
- Filegroup_hash c_filegroup_hash;
-
- RopePool c_rope_pool;
-
- struct DictObject {
- DictObject() {}
- Uint32 m_id;
- Uint32 m_type;
- Uint32 m_ref_count;
- RopeHandle m_name;
- union {
- struct {
- Uint32 m_name_len;
- const char * m_name_ptr;
- RopePool * m_pool;
- } m_key;
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 nextHash;
- Uint32 prevHash;
-
- Uint32 hashValue() const { return m_name.hashValue();}
- bool equal(const DictObject& obj) const {
- if(obj.hashValue() == hashValue()){
- ConstRope r(* m_key.m_pool, obj.m_name);
- return r.compare(m_key.m_name_ptr, m_key.m_name_len) == 0;
- }
- return false;
- }
- };
-
- DLHashTable<DictObject> c_obj_hash; // Name
- ArrayPool<DictObject> c_obj_pool;
-
- DictObject * get_object(const char * name){
- return get_object(name, strlen(name) + 1);
- }
-
- DictObject * get_object(const char * name, Uint32 len){
- return get_object(name, len, Rope::hash(name, len));
- }
-
- DictObject * get_object(const char * name, Uint32 len, Uint32 hash);
-
- void release_object(Uint32 obj_ptr_i){
- release_object(obj_ptr_i, c_obj_pool.getPtr(obj_ptr_i));
- }
-
- void release_object(Uint32 obj_ptr_i, DictObject* obj_ptr_p);
-
- void increase_ref_count(Uint32 obj_ptr_i);
- void decrease_ref_count(Uint32 obj_ptr_i);
-
-public:
- Dbdict(Block_context& ctx);
- virtual ~Dbdict();
-
-private:
- BLOCK_DEFINES(Dbdict);
-
- // Signal receivers
- void execDICTSTARTREQ(Signal* signal);
-
- void execGET_TABINFOREQ(Signal* signal);
- void execGET_TABLEDID_REQ(Signal* signal);
- void execGET_TABINFO_REF(Signal* signal);
- void execGET_TABINFO_CONF(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- void execDUMP_STATE_ORD(Signal* signal);
- void execHOT_SPAREREP(Signal* signal);
- void execDIADDTABCONF(Signal* signal);
- void execDIADDTABREF(Signal* signal);
- void execTAB_COMMITCONF(Signal* signal);
- void execTAB_COMMITREF(Signal* signal);
- void execGET_SCHEMA_INFOREQ(Signal* signal);
- void execSCHEMA_INFO(Signal* signal);
- void execSCHEMA_INFOCONF(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execFSCLOSECONF(Signal* signal);
- void execFSOPENCONF(Signal* signal);
- void execFSOPENREF(Signal* signal);
- void execFSREADCONF(Signal* signal);
- void execFSREADREF(Signal* signal);
- void execFSWRITECONF(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execTC_SCHVERCONF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
- void execAPI_FAILREQ(Signal* signal);
-
- void execWAIT_GCP_REF(Signal* signal);
- void execWAIT_GCP_CONF(Signal* signal);
-
- void execLIST_TABLES_REQ(Signal* signal);
-
- // Index signals
- void execCREATE_INDX_REQ(Signal* signal);
- void execCREATE_INDX_CONF(Signal* signal);
- void execCREATE_INDX_REF(Signal* signal);
-
- void execALTER_INDX_REQ(Signal* signal);
- void execALTER_INDX_CONF(Signal* signal);
- void execALTER_INDX_REF(Signal* signal);
-
- void execCREATE_TABLE_CONF(Signal* signal);
- void execCREATE_TABLE_REF(Signal* signal);
-
- void execDROP_INDX_REQ(Signal* signal);
- void execDROP_INDX_CONF(Signal* signal);
- void execDROP_INDX_REF(Signal* signal);
-
- void execDROP_TABLE_CONF(Signal* signal);
- void execDROP_TABLE_REF(Signal* signal);
-
- void execBUILDINDXREQ(Signal* signal);
- void execBUILDINDXCONF(Signal* signal);
- void execBUILDINDXREF(Signal* signal);
-
- void execBACKUP_FRAGMENT_REQ(Signal*);
-
- // Util signals used by Event code
- void execUTIL_PREPARE_CONF(Signal* signal);
- void execUTIL_PREPARE_REF (Signal* signal);
- void execUTIL_EXECUTE_CONF(Signal* signal);
- void execUTIL_EXECUTE_REF (Signal* signal);
- void execUTIL_RELEASE_CONF(Signal* signal);
- void execUTIL_RELEASE_REF (Signal* signal);
-
-
- // Event signals from API
- void execCREATE_EVNT_REQ (Signal* signal);
- void execCREATE_EVNT_CONF(Signal* signal);
- void execCREATE_EVNT_REF (Signal* signal);
-
- void execDROP_EVNT_REQ (Signal* signal);
-
- void execSUB_START_REQ (Signal* signal);
- void execSUB_START_CONF (Signal* signal);
- void execSUB_START_REF (Signal* signal);
-
- void execSUB_STOP_REQ (Signal* signal);
- void execSUB_STOP_CONF (Signal* signal);
- void execSUB_STOP_REF (Signal* signal);
-
- // Event signals from SUMA
-
- void execCREATE_SUBID_CONF(Signal* signal);
- void execCREATE_SUBID_REF (Signal* signal);
-
- void execSUB_CREATE_CONF(Signal* signal);
- void execSUB_CREATE_REF (Signal* signal);
-
- void execSUB_REMOVE_REQ(Signal* signal);
- void execSUB_REMOVE_CONF(Signal* signal);
- void execSUB_REMOVE_REF(Signal* signal);
-
- // Trigger signals
- void execCREATE_TRIG_REQ(Signal* signal);
- void execCREATE_TRIG_CONF(Signal* signal);
- void execCREATE_TRIG_REF(Signal* signal);
- void execALTER_TRIG_REQ(Signal* signal);
- void execALTER_TRIG_CONF(Signal* signal);
- void execALTER_TRIG_REF(Signal* signal);
- void execDROP_TRIG_REQ(Signal* signal);
- void execDROP_TRIG_CONF(Signal* signal);
- void execDROP_TRIG_REF(Signal* signal);
-
- void execDROP_TABLE_REQ(Signal* signal);
-
- void execPREP_DROP_TAB_REQ(Signal* signal);
- void execPREP_DROP_TAB_REF(Signal* signal);
- void execPREP_DROP_TAB_CONF(Signal* signal);
-
- void execDROP_TAB_REQ(Signal* signal);
- void execDROP_TAB_REF(Signal* signal);
- void execDROP_TAB_CONF(Signal* signal);
-
- void execCREATE_TABLE_REQ(Signal* signal);
- void execALTER_TABLE_REQ(Signal* signal);
- void execCREATE_FRAGMENTATION_REF(Signal*);
- void execCREATE_FRAGMENTATION_CONF(Signal*);
- void execCREATE_TAB_REQ(Signal* signal);
- void execADD_FRAGREQ(Signal* signal);
- void execLQHFRAGREF(Signal* signal);
- void execLQHFRAGCONF(Signal* signal);
- void execLQHADDATTREF(Signal* signal);
- void execLQHADDATTCONF(Signal* signal);
- void execCREATE_TAB_REF(Signal* signal);
- void execCREATE_TAB_CONF(Signal* signal);
- void execALTER_TAB_REQ(Signal* signal);
- void execALTER_TAB_REF(Signal* signal);
- void execALTER_TAB_CONF(Signal* signal);
- bool check_ndb_versions() const;
-
- void execCREATE_FILE_REQ(Signal* signal);
- void execCREATE_FILEGROUP_REQ(Signal* signal);
- void execDROP_FILE_REQ(Signal* signal);
- void execDROP_FILEGROUP_REQ(Signal* signal);
-
- // Internal
- void execCREATE_FILE_REF(Signal* signal);
- void execCREATE_FILE_CONF(Signal* signal);
- void execCREATE_FILEGROUP_REF(Signal* signal);
- void execCREATE_FILEGROUP_CONF(Signal* signal);
- void execDROP_FILE_REF(Signal* signal);
- void execDROP_FILE_CONF(Signal* signal);
- void execDROP_FILEGROUP_REF(Signal* signal);
- void execDROP_FILEGROUP_CONF(Signal* signal);
-
- void execDICT_LOCK_REQ(Signal* signal);
- void execDICT_UNLOCK_ORD(Signal* signal);
-
- /*
- * 2.4 COMMON STORED VARIABLES
- */
-
- /**
- * This record stores all the state needed
- * when the schema page is being sent to other nodes
- ***************************************************************************/
- struct SendSchemaRecord {
- /** Number of words of schema data */
- Uint32 noOfWords;
- /** Page Id of schema data */
- Uint32 pageId;
-
- Uint32 nodeId;
- SignalCounter m_SCHEMAINFO_Counter;
-
- Uint32 noOfWordsCurrentlySent;
- Uint32 noOfSignalsSentSinceDelay;
-
- bool inUse;
- };
- SendSchemaRecord c_sendSchemaRecord;
-
- /**
- * This record stores all the state needed
- * when a table file is being read from disk
- ****************************************************************************/
- struct ReadTableRecord {
- /** Number of Pages */
- Uint32 no_of_words;
- /** Page Id*/
- Uint32 pageId;
- /** Table Id of read table */
- Uint32 tableId;
-
- bool inUse;
- Callback m_callback;
- };
- ReadTableRecord c_readTableRecord;
-
- /**
- * This record stores all the state needed
- * when a table file is being written to disk
- ****************************************************************************/
- struct WriteTableRecord {
- /** Number of Pages */
- Uint32 no_of_words;
- /** Page Id*/
- Uint32 pageId;
- /** Table Files Handled, local state variable */
- Uint32 noOfTableFilesHandled;
- /** Table Id of written table */
- Uint32 tableId;
- /** State, indicates from where it was called */
- enum TableWriteState {
- IDLE = 0,
- WRITE_ADD_TABLE_MASTER = 1,
- WRITE_ADD_TABLE_SLAVE = 2,
- WRITE_RESTART_FROM_MASTER = 3,
- WRITE_RESTART_FROM_OWN = 4,
- TWR_CALLBACK = 5
- };
- TableWriteState tableWriteState;
- Callback m_callback;
- };
- WriteTableRecord c_writeTableRecord;
-
- /**
- * This record stores all the state needed
- * when a schema file is being read from disk
- ****************************************************************************/
- struct ReadSchemaRecord {
- /** Page Id of schema page */
- Uint32 pageId;
- /** First page to read */
- Uint32 firstPage;
- /** Number of pages to read */
- Uint32 noOfPages;
- /** State, indicates from where it was called */
- enum SchemaReadState {
- IDLE = 0,
- INITIAL_READ_HEAD = 1,
- INITIAL_READ = 2
- };
- SchemaReadState schemaReadState;
- };
- ReadSchemaRecord c_readSchemaRecord;
-
- /**
- * This record stores all the state needed
- * when a schema file is being written to disk
- ****************************************************************************/
- struct WriteSchemaRecord {
- /** Page Id of schema page */
- Uint32 pageId;
- /** Rewrite entire file */
- Uint32 newFile;
- /** First page to write */
- Uint32 firstPage;
- /** Number of pages to write */
- Uint32 noOfPages;
- /** Schema Files Handled, local state variable */
- Uint32 noOfSchemaFilesHandled;
-
- bool inUse;
- Callback m_callback;
- };
- WriteSchemaRecord c_writeSchemaRecord;
-
- /**
- * This record stores all the information needed
- * when a file is being read from disk
- ****************************************************************************/
- struct RestartRecord {
- /** Global check point identity */
- Uint32 gciToRestart;
-
- /** The active table at restart process */
- Uint32 activeTable;
-
- /** The active table at restart process */
- BlockReference returnBlockRef;
-
- Uint32 m_pass; // 0 tablespaces/logfilegroups, 1 tables, 2 indexes
- };
- RestartRecord c_restartRecord;
-
- /**
- * This record stores all the information needed
- * when a file is being read from disk
- ****************************************************************************/
- struct RetrieveRecord {
- RetrieveRecord(){ noOfWaiters = 0;}
-
- /** Only one retrieve table definition at a time */
- bool busyState;
-
- /**
- * No of waiting in time queue
- */
- Uint32 noOfWaiters;
-
- /** Block Reference of retriever */
- BlockReference blockRef;
-
- /** Id of retriever */
- Uint32 m_senderData;
-
- /** Table id of retrieved table */
- Uint32 tableId;
-
- Uint32 m_table_type;
-
- /** Starting page to retrieve data from */
- Uint32 retrievePage;
-
- /** Number of pages retrieved */
- Uint32 retrievedNoOfPages;
-
- /** Number of words retrieved */
- Uint32 retrievedNoOfWords;
-
- /** Number of words sent currently */
- Uint32 currentSent;
-
- /**
- * Long signal stuff
- */
- bool m_useLongSig;
- };
- RetrieveRecord c_retrieveRecord;
-
- /**
- * This record stores all the information needed
- * when a file is being read from disk
- *
- * This is the info stored in one entry of the schema
- * page. Each table has 4 words of info.
- * Word 1: Schema version (upper 16 bits)
- * Table State (lower 16 bits)
- * Word 2: Number of pages of table description
- * Word 3: Global checkpoint id table was created
- * Word 4: Currently zero
- ****************************************************************************/
- struct SchemaRecord {
- /** Schema file first page (0) */
- Uint32 schemaPage;
-
- /** Old Schema file first page (used at node restart) */
- Uint32 oldSchemaPage;
-
- Callback m_callback;
- };
- SchemaRecord c_schemaRecord;
-
- /*
- * Schema file, list of schema pages. Use an array until a pool
- * exists and NDBFS interface can use it.
- */
- struct XSchemaFile {
- SchemaFile* schemaPage;
- Uint32 noOfPages;
- };
- // 0-normal 1-old
- XSchemaFile c_schemaFile[2];
-
- void initSchemaFile(XSchemaFile *, Uint32 firstPage, Uint32 lastPage,
- bool initEntries);
- void resizeSchemaFile(XSchemaFile * xsf, Uint32 noOfPages);
- void computeChecksum(XSchemaFile *, Uint32 pageNo);
- bool validateChecksum(const XSchemaFile *);
- SchemaFile::TableEntry * getTableEntry(XSchemaFile *, Uint32 tableId);
-
- Uint32 computeChecksum(const Uint32 * src, Uint32 len);
-
-
- /* ----------------------------------------------------------------------- */
- // Node References
- /* ----------------------------------------------------------------------- */
- Uint16 c_masterNodeId;
-
- /* ----------------------------------------------------------------------- */
- // Various current system properties
- /* ----------------------------------------------------------------------- */
- Uint16 c_numberNode;
- Uint16 c_noHotSpareNodes;
- Uint16 c_noNodesFailed;
- Uint32 c_failureNr;
-
- /* ----------------------------------------------------------------------- */
- // State variables
- /* ----------------------------------------------------------------------- */
-
-#ifndef ndb_dbdict_log_block_state
- enum BlockState {
- BS_IDLE = 0,
- BS_CREATE_TAB = 1,
- BS_BUSY = 2,
- BS_NODE_FAILURE = 3,
- BS_NODE_RESTART = 4
- };
-#else // quick hack to log changes
- enum {
- BS_IDLE = 0,
- BS_CREATE_TAB = 1,
- BS_BUSY = 2,
- BS_NODE_FAILURE = 3,
- BS_NODE_RESTART = 4
- };
- struct BlockState;
- friend struct BlockState;
- struct BlockState {
- BlockState() :
- m_value(BS_IDLE) {
- }
- BlockState(int value) :
- m_value(value) {
- }
- operator int() const {
- return m_value;
- }
- BlockState& operator=(const BlockState& bs) {
- Dbdict* dict = (Dbdict*)globalData.getBlock(DBDICT);
- dict->infoEvent("DICT: bs %d->%d", m_value, bs.m_value);
- globalSignalLoggers.log(DBDICT, "bs %d->%d", m_value, bs.m_value);
- m_value = bs.m_value;
- return *this;
- }
- int m_value;
- };
-#endif
- BlockState c_blockState;
-
- struct PackTable {
-
- enum PackTableState {
- PTS_IDLE = 0,
- PTS_GET_TAB = 3
- } m_state;
-
- } c_packTable;
-
- Uint32 c_startPhase;
- Uint32 c_restartType;
- bool c_initialStart;
- bool c_systemRestart;
- bool c_nodeRestart;
- bool c_initialNodeRestart;
- Uint32 c_tabinfoReceived;
-
- /**
- * Temporary structure used when parsing table info
- */
- struct ParseDictTabInfoRecord {
- DictTabInfo::RequestType requestType;
- Uint32 errorCode;
- Uint32 errorLine;
-
- SimpleProperties::UnpackStatus status;
- Uint32 errorKey;
- TableRecordPtr tablePtr;
- };
-
- // Operation records
-
- /**
- * Common part of operation records. Uses KeyTable2. Note that each
- * seize/release invokes ctor/dtor automatically.
- */
- struct OpRecordCommon {
- OpRecordCommon() {}
- Uint32 key; // key shared between master and slaves
- Uint32 nextHash;
- Uint32 prevHash;
- Uint32 hashValue() const {
- return key;
- }
- bool equal(const OpRecordCommon& rec) const {
- return key == rec.key;
- }
- };
-
- /**
- * Create table record
- */
- struct CreateTableRecord : OpRecordCommon {
- CreateTableRecord() {}
- Uint32 m_senderRef;
- Uint32 m_senderData;
- Uint32 m_coordinatorRef;
-
- Uint32 m_errorCode;
- void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;}
-
- // For alter table
- Uint32 m_changeMask;
- bool m_alterTableFailed;
- AlterTableRef m_alterTableRef;
- Uint32 m_alterTableId;
-
- /* Previous table name (used for reverting failed table rename) */
- char previousTableName[MAX_TAB_NAME_SIZE];
-
- /* Previous table definition, frm (used for reverting) */
- /** TODO Could preferrably be made dynamic size */
- Uint32 previousFrmLen;
- char previousFrmData[MAX_FRM_DATA_SIZE];
-
- Uint32 m_tablePtrI;
- Uint32 m_tabInfoPtrI;
- Uint32 m_fragmentsPtrI;
-
- Uint32 m_dihAddFragPtr; // Connect ptr towards DIH
- Uint32 m_lqhFragPtr; // Connect ptr towards LQH
-
- Callback m_callback; // Who's using local create tab
- MutexHandle2<DIH_START_LCP_MUTEX> m_startLcpMutex;
-
- struct CoordinatorData {
- Uint32 m_gsn;
- SafeCounterHandle m_counter;
- CreateTabReq::RequestType m_requestType;
- } m_coordinatorData;
- };
- typedef Ptr<CreateTableRecord> CreateTableRecordPtr;
-
- /**
- * Drop table record
- */
- struct DropTableRecord : OpRecordCommon {
- DropTableRecord() {}
- DropTableReq m_request;
-
- Uint32 m_requestType;
- Uint32 m_coordinatorRef;
-
- Uint32 m_errorCode;
- void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;}
-
- MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
-
- /**
- * When sending stuff around
- */
- struct CoordinatorData {
- Uint32 m_gsn;
- Uint32 m_block;
- SignalCounter m_signalCounter;
- } m_coordinatorData;
-
- struct ParticipantData {
- Uint32 m_gsn;
- Uint32 m_block;
- SignalCounter m_signalCounter;
-
- Callback m_callback;
- } m_participantData;
- };
- typedef Ptr<DropTableRecord> DropTableRecordPtr;
-
- /**
- * Request flags passed in signals along with request type and
- * propagated across operations.
- */
- struct RequestFlag {
- enum {
- RF_LOCAL = 1 << 0, // create on local node only
- RF_NOBUILD = 1 << 1, // no need to build index
- RF_NOTCTRIGGER = 1 << 2, // alter trigger: no trigger in TC
- RF_FORCE = 1 << 4 // force drop
- };
- };
-
- /**
- * Operation record for create index.
- */
- struct OpCreateIndex : OpRecordCommon {
- // original request (index id will be added)
- CreateIndxReq m_request;
- AttributeList m_attrList;
- char m_indexName[MAX_TAB_NAME_SIZE];
- bool m_loggedIndex;
- bool m_temporaryIndex;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- CreateIndxReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- CreateIndxRef::ErrorCode m_lastError;
- CreateIndxRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpCreateIndex() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = CreateIndxReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = CreateIndxRef::NoError;
- m_errorCode = CreateIndxRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const CreateIndxReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != CreateIndxRef::NoError;
- }
- bool hasError() {
- return m_errorCode != CreateIndxRef::NoError;
- }
- void setError(const CreateIndxRef* ref) {
- m_lastError = CreateIndxRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const CreateTableRef* ref) {
- m_lastError = CreateIndxRef::NoError;
- if (ref != 0) {
- switch (ref->getErrorCode()) {
- case CreateTableRef::TableAlreadyExist:
- m_lastError = CreateIndxRef::IndexExists;
- break;
- default:
- m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode();
- break;
- }
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- }
- }
- }
- void setError(const AlterIndxRef* ref) {
- m_lastError = CreateIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (CreateIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpCreateIndex> OpCreateIndexPtr;
-
- /**
- * Operation record for drop index.
- */
- struct OpDropIndex : OpRecordCommon {
- // original request
- DropIndxReq m_request;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- DropIndxReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- DropIndxRef::ErrorCode m_lastError;
- DropIndxRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpDropIndex() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = DropIndxReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = DropIndxRef::NoError;
- m_errorCode = DropIndxRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const DropIndxReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != DropIndxRef::NoError;
- }
- bool hasError() {
- return m_errorCode != DropIndxRef::NoError;
- }
- void setError(const DropIndxRef* ref) {
- m_lastError = DropIndxRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const AlterIndxRef* ref) {
- m_lastError = DropIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (DropIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const DropTableRef* ref) {
- m_lastError = DropIndxRef::NoError;
- if (ref != 0) {
- switch (ref->errorCode) {
- case DropTableRef::Busy:
- m_lastError = DropIndxRef::Busy;
- break;
- case DropTableRef::NoSuchTable:
- m_lastError = DropIndxRef::IndexNotFound;
- break;
- case DropTableRef::DropInProgress:
- m_lastError = DropIndxRef::Busy;
- break;
- case DropTableRef::NoDropTableRecordAvailable:
- m_lastError = DropIndxRef::Busy;
- break;
- default:
- m_lastError = (DropIndxRef::ErrorCode)ref->errorCode;
- break;
- }
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- }
- }
- };
- typedef Ptr<OpDropIndex> OpDropIndexPtr;
-
- /**
- * Operation record for alter index.
- */
- struct OpAlterIndex : OpRecordCommon {
- // original request plus buffer for attribute lists
- AlterIndxReq m_request;
- AttributeList m_attrList;
- AttributeList m_tableKeyList;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- AlterIndxReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- AlterIndxRef::ErrorCode m_lastError;
- AlterIndxRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- Uint32 m_triggerCounter;
- // ctor
- OpAlterIndex() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = AlterIndxReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = AlterIndxRef::NoError;
- m_errorCode = AlterIndxRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- m_triggerCounter = 0;
- }
- void save(const AlterIndxReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != AlterIndxRef::NoError;
- }
- bool hasError() {
- return m_errorCode != AlterIndxRef::NoError;
- }
- void setError(const AlterIndxRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const CreateIndxRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const DropIndxRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const BuildIndxRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- }
- }
- void setError(const CreateTrigRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const DropTrigRef* ref) {
- m_lastError = AlterIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpAlterIndex> OpAlterIndexPtr;
-
- /**
- * Operation record for build index.
- */
- struct OpBuildIndex : OpRecordCommon {
- // original request plus buffer for attribute lists
- BuildIndxReq m_request;
- AttributeList m_attrList;
- Id_array<MAX_ATTRIBUTES_IN_INDEX+1> m_tableKeyList;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- BuildIndxReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- Uint32 m_constrTriggerId;
- // error info
- BuildIndxRef::ErrorCode m_lastError;
- BuildIndxRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpBuildIndex() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = BuildIndxReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = BuildIndxRef::NoError;
- m_errorCode = BuildIndxRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const BuildIndxReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != BuildIndxRef::NoError;
- }
- bool hasError() {
- return m_errorCode != BuildIndxRef::NoError;
- }
- void setError(const BuildIndxRef* ref) {
- m_lastError = BuildIndxRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- }
- }
- void setError(const AlterIndxRef* ref) {
- m_lastError = BuildIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const CreateTrigRef* ref) {
- m_lastError = BuildIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const DropTrigRef* ref) {
- m_lastError = BuildIndxRef::NoError;
- if (ref != 0) {
- m_lastError = (BuildIndxRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpBuildIndex> OpBuildIndexPtr;
-
- /**
- * Operation record for Util Signals.
- */
- struct OpSignalUtil : OpRecordCommon{
- Callback m_callback;
- Uint32 m_userData;
- };
- typedef Ptr<OpSignalUtil> OpSignalUtilPtr;
-
- /**
- * Operation record for subscribe-start-stop
- */
- struct OpSubEvent : OpRecordCommon {
- Uint32 m_senderRef;
- Uint32 m_senderData;
- Uint32 m_errorCode;
- union {
- SubStartConf m_sub_start_conf;
- SubStopConf m_sub_stop_conf;
- };
- RequestTracker m_reqTracker;
- };
- typedef Ptr<OpSubEvent> OpSubEventPtr;
-
- static const Uint32 sysTab_NDBEVENTS_0_szs[];
-
- /**
- * Operation record for create event.
- */
- struct OpCreateEvent : OpRecordCommon {
- // original request (event id will be added)
- CreateEvntReq m_request;
- //AttributeMask m_attrListBitmask;
- // AttributeList m_attrList;
- sysTab_NDBEVENTS_0 m_eventRec;
- // char m_eventName[MAX_TAB_NAME_SIZE];
- // char m_tableName[MAX_TAB_NAME_SIZE];
-
- // coordinator DICT
- RequestTracker m_reqTracker;
- // state info
- CreateEvntReq::RequestType m_requestType;
- // error info
- Uint32 m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode; /* also used to store master node id
- in case of NotMaster */
- // ctor
- OpCreateEvent() {
- memset(&m_request, 0, sizeof(m_request));
- m_requestType = CreateEvntReq::RT_UNDEFINED;
- m_errorCode = CreateEvntRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void init(const CreateEvntReq* req, Dbdict* dp) {
- m_request = *req;
- m_errorCode = CreateEvntRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- m_requestType = req->getRequestType();
- }
- bool hasError() {
- return m_errorCode != CreateEvntRef::NoError;
- }
- void setError(const CreateEvntRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
-
- };
- typedef Ptr<OpCreateEvent> OpCreateEventPtr;
-
- /**
- * Operation record for drop event.
- */
- struct OpDropEvent : OpRecordCommon {
- // original request
- DropEvntReq m_request;
- // char m_eventName[MAX_TAB_NAME_SIZE];
- sysTab_NDBEVENTS_0 m_eventRec;
- RequestTracker m_reqTracker;
- // error info
- Uint32 m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // ctor
- OpDropEvent() {
- memset(&m_request, 0, sizeof(m_request));
- m_errorCode = 0;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void init(const DropEvntReq* req) {
- m_request = *req;
- m_errorCode = 0;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- bool hasError() {
- return m_errorCode != 0;
- }
- void setError(const DropEvntRef* ref) {
- if (ref != 0 && ! hasError()) {
- m_errorCode = ref->getErrorCode();
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- };
- typedef Ptr<OpDropEvent> OpDropEventPtr;
-
- /**
- * Operation record for create trigger.
- */
- struct OpCreateTrigger : OpRecordCommon {
- // original request (trigger id will be added)
- CreateTrigReq m_request;
- char m_triggerName[MAX_TAB_NAME_SIZE];
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- CreateTrigReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- CreateTrigRef::ErrorCode m_lastError;
- CreateTrigRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpCreateTrigger() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = CreateTrigReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = CreateTrigRef::NoError;
- m_errorCode = CreateTrigRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const CreateTrigReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != CreateTrigRef::NoError;
- }
- bool hasError() {
- return m_errorCode != CreateTrigRef::NoError;
- }
- void setError(const CreateTrigRef* ref) {
- m_lastError = CreateTrigRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const AlterTrigRef* ref) {
- m_lastError = CreateTrigRef::NoError;
- if (ref != 0) {
- m_lastError = (CreateTrigRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpCreateTrigger> OpCreateTriggerPtr;
-
- /**
- * Operation record for drop trigger.
- */
- struct OpDropTrigger : OpRecordCommon {
- // original request
- DropTrigReq m_request;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- DropTrigReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- DropTrigRef::ErrorCode m_lastError;
- DropTrigRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpDropTrigger() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = DropTrigReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = DropTrigRef::NoError;
- m_errorCode = DropTrigRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const DropTrigReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != DropTrigRef::NoError;
- }
- bool hasError() {
- return m_errorCode != DropTrigRef::NoError;
- }
- void setError(const DropTrigRef* ref) {
- m_lastError = DropTrigRef::NoError;
- if (ref != 0) {
- m_lastError = ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const AlterTrigRef* ref) {
- m_lastError = DropTrigRef::NoError;
- if (ref != 0) {
- m_lastError = (DropTrigRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpDropTrigger> OpDropTriggerPtr;
-
- /**
- * Operation record for alter trigger.
- */
- struct OpAlterTrigger : OpRecordCommon {
- // original request
- AlterTrigReq m_request;
- // nodes participating in operation
- NdbNodeBitmask m_nodes;
- // coordinator DICT
- Uint32 m_coordinatorRef;
- bool m_isMaster;
- // state info
- AlterTrigReq::RequestType m_requestType;
- Uint32 m_requestFlag;
- // error info
- AlterTrigRef::ErrorCode m_lastError;
- AlterTrigRef::ErrorCode m_errorCode;
- Uint32 m_errorLine;
- Uint32 m_errorNode;
- // counters
- SignalCounter m_signalCounter;
- // ctor
- OpAlterTrigger() {
- memset(&m_request, 0, sizeof(m_request));
- m_coordinatorRef = 0;
- m_requestType = AlterTrigReq::RT_UNDEFINED;
- m_requestFlag = 0;
- m_lastError = AlterTrigRef::NoError;
- m_errorCode = AlterTrigRef::NoError;
- m_errorLine = 0;
- m_errorNode = 0;
- }
- void save(const AlterTrigReq* req) {
- m_request = *req;
- m_requestType = req->getRequestType();
- m_requestFlag = req->getRequestFlag();
- }
- bool hasLastError() {
- return m_lastError != AlterTrigRef::NoError;
- }
- bool hasError() {
- return m_errorCode != AlterTrigRef::NoError;
- }
- void setError(const AlterTrigRef* ref) {
- m_lastError = AlterTrigRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const CreateTrigRef* ref) {
- m_lastError = AlterTrigRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- void setError(const DropTrigRef* ref) {
- m_lastError = AlterTrigRef::NoError;
- if (ref != 0) {
- m_lastError = (AlterTrigRef::ErrorCode)ref->getErrorCode();
- if (! hasError()) {
- m_errorCode = m_lastError;
- m_errorLine = ref->getErrorLine();
- m_errorNode = ref->getErrorNode();
- }
- }
- }
- };
- typedef Ptr<OpAlterTrigger> OpAlterTriggerPtr;
-
-public:
- struct SchemaOp : OpRecordCommon {
-
- Uint32 m_clientRef; // API (for take-over)
- Uint32 m_clientData;// API
-
- Uint32 m_senderRef; //
- Uint32 m_senderData;// transaction key value
-
- Uint32 m_errorCode;
-
- Uint32 m_obj_id;
- Uint32 m_obj_type;
- Uint32 m_obj_version;
- Uint32 m_obj_ptr_i;
- Uint32 m_vt_index;
- Callback m_callback;
- };
- typedef Ptr<SchemaOp> SchemaOpPtr;
-
- struct SchemaTransaction : OpRecordCommon {
- Uint32 m_senderRef; // API
- Uint32 m_senderData;// API
-
- Callback m_callback;
- SafeCounterHandle m_counter;
- NodeBitmask m_nodes;
-
- Uint32 m_errorCode;
- SchemaTransaction() {}
- void setErrorCode(Uint32 c){ if(m_errorCode == 0) m_errorCode = c;}
-
- /**
- * This should contain "lists" with operations
- */
- struct {
- Uint32 m_key; // Operation key
- Uint32 m_vt_index; // Operation type
- Uint32 m_obj_id;
- DictObjOp::State m_state;
- } m_op;
- };
-private:
-
- struct OpCreateObj : public SchemaOp {
- Uint32 m_gci;
- Uint32 m_obj_info_ptr_i;
- Uint32 m_restart;
- };
- typedef Ptr<OpCreateObj> CreateObjRecordPtr;
-
- struct OpDropObj : public SchemaOp
- {
- };
- typedef Ptr<OpDropObj> DropObjRecordPtr;
-
- /**
- * Only used at coordinator/master
- */
- // Common operation record pool
-public:
- STATIC_CONST( opCreateTableSize = sizeof(CreateTableRecord) );
- STATIC_CONST( opDropTableSize = sizeof(DropTableRecord) );
- STATIC_CONST( opCreateIndexSize = sizeof(OpCreateIndex) );
- STATIC_CONST( opDropIndexSize = sizeof(OpDropIndex) );
- STATIC_CONST( opAlterIndexSize = sizeof(OpAlterIndex) );
- STATIC_CONST( opBuildIndexSize = sizeof(OpBuildIndex) );
- STATIC_CONST( opCreateEventSize = sizeof(OpCreateEvent) );
- STATIC_CONST( opSubEventSize = sizeof(OpSubEvent) );
- STATIC_CONST( opDropEventSize = sizeof(OpDropEvent) );
- STATIC_CONST( opSignalUtilSize = sizeof(OpSignalUtil) );
- STATIC_CONST( opCreateTriggerSize = sizeof(OpCreateTrigger) );
- STATIC_CONST( opDropTriggerSize = sizeof(OpDropTrigger) );
- STATIC_CONST( opAlterTriggerSize = sizeof(OpAlterTrigger) );
- STATIC_CONST( opCreateObjSize = sizeof(OpCreateObj) );
-private:
-#define PTR_ALIGN(n) ((((n)+sizeof(void*)-1)>>2)&~((sizeof(void*)-1)>>2))
- union OpRecordUnion {
- Uint32 u_opCreateTable [PTR_ALIGN(opCreateTableSize)];
- Uint32 u_opDropTable [PTR_ALIGN(opDropTableSize)];
- Uint32 u_opCreateIndex [PTR_ALIGN(opCreateIndexSize)];
- Uint32 u_opDropIndex [PTR_ALIGN(opDropIndexSize)];
- Uint32 u_opCreateEvent [PTR_ALIGN(opCreateEventSize)];
- Uint32 u_opSubEvent [PTR_ALIGN(opSubEventSize)];
- Uint32 u_opDropEvent [PTR_ALIGN(opDropEventSize)];
- Uint32 u_opSignalUtil [PTR_ALIGN(opSignalUtilSize)];
- Uint32 u_opAlterIndex [PTR_ALIGN(opAlterIndexSize)];
- Uint32 u_opBuildIndex [PTR_ALIGN(opBuildIndexSize)];
- Uint32 u_opCreateTrigger[PTR_ALIGN(opCreateTriggerSize)];
- Uint32 u_opDropTrigger [PTR_ALIGN(opDropTriggerSize)];
- Uint32 u_opAlterTrigger [PTR_ALIGN(opAlterTriggerSize)];
- Uint32 u_opCreateObj [PTR_ALIGN(opCreateObjSize)];
- Uint32 nextPool;
- };
- ArrayPool<OpRecordUnion> c_opRecordPool;
-
- // Operation records
- KeyTable2<CreateTableRecord, OpRecordUnion> c_opCreateTable;
- KeyTable2<DropTableRecord, OpRecordUnion> c_opDropTable;
- KeyTable2<OpCreateIndex, OpRecordUnion> c_opCreateIndex;
- KeyTable2<OpDropIndex, OpRecordUnion> c_opDropIndex;
- KeyTable2<OpAlterIndex, OpRecordUnion> c_opAlterIndex;
- KeyTable2<OpBuildIndex, OpRecordUnion> c_opBuildIndex;
- KeyTable2C<OpCreateEvent, OpRecordUnion> c_opCreateEvent;
- KeyTable2C<OpSubEvent, OpRecordUnion> c_opSubEvent;
- KeyTable2C<OpDropEvent, OpRecordUnion> c_opDropEvent;
- KeyTable2C<OpSignalUtil, OpRecordUnion> c_opSignalUtil;
- KeyTable2<OpCreateTrigger, OpRecordUnion> c_opCreateTrigger;
- KeyTable2<OpDropTrigger, OpRecordUnion> c_opDropTrigger;
- KeyTable2<OpAlterTrigger, OpRecordUnion> c_opAlterTrigger;
- KeyTable2<SchemaOp, OpRecordUnion> c_schemaOp;
- KeyTable2<SchemaTransaction, OpRecordUnion> c_Trans;
- KeyTable2Ref<OpCreateObj, SchemaOp, OpRecordUnion> c_opCreateObj;
- KeyTable2Ref<OpDropObj, SchemaOp, OpRecordUnion> c_opDropObj;
-
- // Unique key for operation XXX move to some system table
- Uint32 c_opRecordSequence;
-
- /*
- * Master DICT can be locked in 2 mutually exclusive ways:
- *
- * 1) for schema ops, via operation records
- * 2) against schema ops, via a lock queue
- *
- * Current use of 2) is by a starting node, to prevent schema ops
- * until started. The ops are refused (BlockState != BS_IDLE),
- * not queued.
- *
- * Master failure is not handled, in node start case the starting
- * node will crash too anyway. Use lock table in future..
- *
- * The lock queue is "serial" but other behaviour is possible
- * by checking lock types e.g. to allow parallel node starts.
- *
- * Checking release of last op record is not convenient with
- * current structure (5.0). Instead we poll via continueB.
- *
- * XXX only table ops check BlockState
- */
- struct DictLockType;
- friend struct DictLockType;
-
- struct DictLockType {
- DictLockReq::LockType lockType;
- BlockState blockState;
- const char* text;
- };
-
- struct DictLockRecord;
- friend struct DictLockRecord;
-
- struct DictLockRecord {
- DictLockReq req;
- const DictLockType* lt;
- bool locked;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- typedef Ptr<DictLockRecord> DictLockPtr;
- ArrayPool<DictLockRecord> c_dictLockPool;
- DLFifoList<DictLockRecord> c_dictLockQueue;
- bool c_dictLockPoll;
-
- static const DictLockType* getDictLockType(Uint32 lockType);
- void sendDictLockInfoEvent(Uint32 pollCount);
- void sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text);
-
- // check if any schema op exists (conflicting with dict lock)
- bool hasDictLockSchemaOp();
-
- void checkDictLockQueue(Signal* signal, bool poll);
- void sendDictLockConf(Signal* signal, DictLockPtr lockPtr);
- void sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode);
-
- // control polling i.e. continueB loop
- void setDictLockPoll(Signal* signal, bool on, Uint32 pollCount);
-
- // NF handling
- void removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes);
-
-
- // Statement blocks
-
- /* ------------------------------------------------------------ */
- // Start/Restart Handling
- /* ------------------------------------------------------------ */
- void sendSTTORRY(Signal* signal);
- void sendNDB_STTORRY(Signal* signal);
- void initSchemaFile(Signal* signal);
-
- /* ------------------------------------------------------------ */
- // Drop Table Handling
- /* ------------------------------------------------------------ */
- void releaseTableObject(Uint32 tableId, bool removeFromHash = true);
-
- /* ------------------------------------------------------------ */
- // General Stuff
- /* ------------------------------------------------------------ */
- Uint32 getFreeObjId(Uint32 minId);
- Uint32 getFreeTableRecord(Uint32 primaryTableId);
- Uint32 getFreeTriggerRecord();
- bool getNewAttributeRecord(TableRecordPtr tablePtr,
- AttributeRecordPtr & attrPtr);
- void packTableIntoPages(Signal* signal);
- void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0);
- void packFilegroupIntoPages(SimpleProperties::Writer &,
- FilegroupPtr,
- const Uint32 undo_free_hi,
- const Uint32 undo_free_lo);
- void packFileIntoPages(SimpleProperties::Writer &, FilePtr, const Uint32);
-
- void sendGET_TABINFOREQ(Signal* signal,
- Uint32 tableId);
- void sendTC_SCHVERREQ(Signal* signal,
- Uint32 tableId,
- BlockReference tcRef);
-
- /* ------------------------------------------------------------ */
- // System Restart Handling
- /* ------------------------------------------------------------ */
- void initSendSchemaData(Signal* signal);
- void sendSchemaData(Signal* signal);
- Uint32 sendSCHEMA_INFO(Signal* signal, Uint32 nodeId, Uint32* pagePointer);
- void checkSchemaStatus(Signal* signal);
- void sendDIHSTARTTAB_REQ(Signal* signal);
-
- /* ------------------------------------------------------------ */
- // Receive Table Handling
- /* ------------------------------------------------------------ */
- void handleTabInfoInit(SimpleProperties::Reader &,
- ParseDictTabInfoRecord *,
- bool checkExist = true);
- void handleTabInfo(SimpleProperties::Reader & it, ParseDictTabInfoRecord *,
- DictTabInfo::Table & tableDesc);
-
- void handleAddTableFailure(Signal* signal,
- Uint32 failureLine,
- Uint32 tableId);
- bool verifyTableCorrect(Signal* signal, Uint32 tableId);
-
- /* ------------------------------------------------------------ */
- // Add Table Handling
- /* ------------------------------------------------------------ */
- void releaseCreateTableOp(Signal* signal, CreateTableRecordPtr createTabPtr);
-
- /* ------------------------------------------------------------ */
- // Add Fragment Handling
- /* ------------------------------------------------------------ */
- void sendLQHADDATTRREQ(Signal*, CreateTableRecordPtr, Uint32 attributePtrI);
-
- /* ------------------------------------------------------------ */
- // Read/Write Schema and Table files
- /* ------------------------------------------------------------ */
- void updateSchemaState(Signal* signal, Uint32 tableId,
- SchemaFile::TableEntry*, Callback*,
- bool savetodisk = 1);
- void startWriteSchemaFile(Signal* signal);
- void openSchemaFile(Signal* signal,
- Uint32 fileNo,
- Uint32 fsPtr,
- bool writeFlag,
- bool newFile);
- void writeSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
- void writeSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void closeFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
- void closeWriteSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void initSchemaFile_conf(Signal* signal, Uint32 i, Uint32 returnCode);
-
- void writeTableFile(Signal* signal, Uint32 tableId,
- SegmentedSectionPtr tabInfo, Callback*);
- void startWriteTableFile(Signal* signal, Uint32 tableId);
- void openTableFile(Signal* signal,
- Uint32 fileNo,
- Uint32 fsPtr,
- Uint32 tableId,
- bool writeFlag);
- void writeTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
- void writeTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void closeWriteTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
-
- void startReadTableFile(Signal* signal, Uint32 tableId);
- void openReadTableRef(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void readTableFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
- void readTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void readTableRef(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void closeReadTableConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
-
- void startReadSchemaFile(Signal* signal);
- void openReadSchemaRef(Signal* signal,
- FsConnectRecordPtr fsPtr);
- void readSchemaFile(Signal* signal, Uint32 filePtr, Uint32 fsPtr);
- void readSchemaConf(Signal* signal, FsConnectRecordPtr fsPtr);
- void readSchemaRef(Signal* signal, FsConnectRecordPtr fsPtr);
- void closeReadSchemaConf(Signal* signal,
- FsConnectRecordPtr fsPtr);
- bool convertSchemaFileTo_5_0_6(XSchemaFile*);
-
- /* ------------------------------------------------------------ */
- // Get table definitions
- /* ------------------------------------------------------------ */
- void sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq*,
- GetTabInfoRef::ErrorCode errorCode);
-
- void sendGET_TABLEID_REF(Signal* signal,
- GetTableIdReq * req,
- GetTableIdRef::ErrorCode errorCode);
-
- void sendGetTabResponse(Signal* signal);
-
- /* ------------------------------------------------------------ */
- // Indexes and triggers
- /* ------------------------------------------------------------ */
-
- // reactivate and rebuild indexes on start up
- void activateIndexes(Signal* signal, Uint32 i);
- void rebuildIndexes(Signal* signal, Uint32 i);
-
- // create index
- void createIndex_recvReply(Signal* signal, const CreateIndxConf* conf,
- const CreateIndxRef* ref);
- void createIndex_slavePrepare(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_fromCreateTable(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_toAlterIndex(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_fromAlterIndex(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_slaveCommit(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_slaveAbort(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_sendSlaveReq(Signal* signal, OpCreateIndexPtr opPtr);
- void createIndex_sendReply(Signal* signal, OpCreateIndexPtr opPtr, bool);
- // drop index
- void dropIndex_recvReply(Signal* signal, const DropIndxConf* conf,
- const DropIndxRef* ref);
- void dropIndex_slavePrepare(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_toAlterIndex(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_fromAlterIndex(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_toDropTable(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_fromDropTable(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_slaveCommit(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_slaveAbort(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_sendSlaveReq(Signal* signal, OpDropIndexPtr opPtr);
- void dropIndex_sendReply(Signal* signal, OpDropIndexPtr opPtr, bool);
- // alter index
- void alterIndex_recvReply(Signal* signal, const AlterIndxConf* conf,
- const AlterIndxRef* ref);
- void alterIndex_slavePrepare(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_toCreateTc(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_fromCreateTc(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_toDropTc(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_fromDropTc(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_toCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_fromCreateTrigger(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_toDropTrigger(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_fromDropTrigger(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_toBuildIndex(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_fromBuildIndex(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_slaveCommit(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_slaveAbort(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_sendSlaveReq(Signal* signal, OpAlterIndexPtr opPtr);
- void alterIndex_sendReply(Signal* signal, OpAlterIndexPtr opPtr, bool);
- // build index
- void buildIndex_recvReply(Signal* signal, const BuildIndxConf* conf,
- const BuildIndxRef* ref);
- void buildIndex_toCreateConstr(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_fromCreateConstr(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_buildTrix(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_toDropConstr(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_fromDropConstr(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_toOnline(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_fromOnline(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr);
- void buildIndex_sendReply(Signal* signal, OpBuildIndexPtr opPtr, bool);
-
- // Events
- void
- createEventUTIL_PREPARE(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- createEventUTIL_EXECUTE(Signal *signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUTIL_PREPARE_READ(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUTIL_EXECUTE_READ(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUTIL_PREPARE_DELETE(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUTIL_EXECUTE_DELETE(Signal *signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUtilPrepareRef(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void
- dropEventUtilExecuteRef(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- int
- sendSignalUtilReq(Callback *c,
- BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections);
- int
- recvSignalUtilReq(Signal* signal, Uint32 returnCode);
-
- void completeSubStartReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
- void completeSubStopReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
- void completeSubRemoveReq(Signal* signal, Uint32 ptrI, Uint32 returnCode);
-
- void dropEvent_sendReply(Signal* signal,
- OpDropEventPtr evntRecPtr);
-
- void createEvent_RT_USER_CREATE(Signal* signal, OpCreateEventPtr evntRecPtr);
- void createEventComplete_RT_USER_CREATE(Signal* signal,
- OpCreateEventPtr evntRecPtr);
- void createEvent_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
- void createEventComplete_RT_USER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
-
- void createEvent_RT_DICT_AFTER_GET(Signal* signal, OpCreateEventPtr evntRecPtr);
-
- void createEvent_nodeFailCallback(Signal* signal, Uint32 eventRecPtrI,
- Uint32 returnCode);
- void createEvent_sendReply(Signal* signal, OpCreateEventPtr evntRecPtr,
- LinearSectionPtr *ptr = NULL, int noLSP = 0);
-
- void prepareTransactionEventSysTable (Callback *c,
- Signal* signal,
- Uint32 senderData,
- UtilPrepareReq::OperationTypeValue prepReq);
- void prepareUtilTransaction(Callback *c,
- Signal* signal,
- Uint32 senderData,
- Uint32 tableId,
- const char *tableName,
- UtilPrepareReq::OperationTypeValue prepReq,
- Uint32 noAttr,
- Uint32 attrIds[],
- const char *attrNames[]);
-
- void executeTransEventSysTable(Callback *c,
- Signal *signal,
- const Uint32 ptrI,
- sysTab_NDBEVENTS_0& m_eventRec,
- const Uint32 prepareId,
- UtilPrepareReq::OperationTypeValue prepReq);
- void executeTransaction(Callback *c,
- Signal* signal,
- Uint32 senderData,
- Uint32 prepareId,
- Uint32 noAttr,
- LinearSectionPtr headerPtr,
- LinearSectionPtr dataPtr);
-
- void parseReadEventSys(Signal *signal, sysTab_NDBEVENTS_0& m_eventRec);
-
- // create trigger
- void createTrigger_recvReply(Signal* signal, const CreateTrigConf* conf,
- const CreateTrigRef* ref);
- void createTrigger_slavePrepare(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_masterSeize(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_slaveCreate(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_toAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_fromAlterTrigger(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_slaveCommit(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_slaveAbort(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_sendSlaveReq(Signal* signal, OpCreateTriggerPtr opPtr);
- void createTrigger_sendReply(Signal* signal, OpCreateTriggerPtr opPtr, bool);
- // drop trigger
- void dropTrigger_recvReply(Signal* signal, const DropTrigConf* conf,
- const DropTrigRef* ref);
- void dropTrigger_slavePrepare(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_toAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_fromAlterTrigger(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_slaveCommit(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_slaveAbort(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_sendSlaveReq(Signal* signal, OpDropTriggerPtr opPtr);
- void dropTrigger_sendReply(Signal* signal, OpDropTriggerPtr opPtr, bool);
- // alter trigger
- void alterTrigger_recvReply(Signal* signal, const AlterTrigConf* conf,
- const AlterTrigRef* ref);
- void alterTrigger_slavePrepare(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_toCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_fromCreateLocal(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_fromDropLocal(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_slaveCommit(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_slaveAbort(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_sendSlaveReq(Signal* signal, OpAlterTriggerPtr opPtr);
- void alterTrigger_sendReply(Signal* signal, OpAlterTriggerPtr opPtr, bool);
- // support
- void getTableKeyList(TableRecordPtr,
- Id_array<MAX_ATTRIBUTES_IN_INDEX+1>& list);
- void getIndexAttr(TableRecordPtr indexPtr, Uint32 itAttr, Uint32* id);
- void getIndexAttrList(TableRecordPtr indexPtr, AttributeList& list);
- void getIndexAttrMask(TableRecordPtr indexPtr, AttributeMask& mask);
-
- /* ------------------------------------------------------------ */
- // Initialisation
- /* ------------------------------------------------------------ */
- void initCommonData();
- void initRecords();
- void initConnectRecord();
- void initRetrieveRecord(Signal*, Uint32, Uint32 returnCode);
- void initSchemaRecord();
- void initRestartRecord();
- void initSendSchemaRecord();
- void initReadTableRecord();
- void initWriteTableRecord();
- void initReadSchemaRecord();
- void initWriteSchemaRecord();
-
- void initNodeRecords();
- void initTableRecords();
- void initialiseTableRecord(TableRecordPtr tablePtr);
- void initTriggerRecords();
- void initialiseTriggerRecord(TriggerRecordPtr triggerPtr);
- void initPageRecords();
-
- Uint32 getFsConnRecord();
-
- bool getIsFailed(Uint32 nodeId) const;
-
- void dropTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
- void dropTableRef(Signal * signal, DropTableReq *, DropTableRef::ErrorCode);
- void printTables(); // For debugging only
- int handleAlterTab(AlterTabReq * req,
- CreateTableRecord * regAlterTabPtr,
- TableRecordPtr origTablePtr,
- TableRecordPtr newTablePtr);
- void revertAlterTable(Signal * signal,
- Uint32 changeMask,
- Uint32 tableId,
- CreateTableRecord * regAlterTabPtr);
- void alterTable_backup_mutex_locked(Signal* signal, Uint32, Uint32);
- void alterTableRef(Signal * signal,
- AlterTableReq *, AlterTableRef::ErrorCode,
- ParseDictTabInfoRecord* parseRecord = NULL);
- void alterTabRef(Signal * signal,
- AlterTabReq *, AlterTableRef::ErrorCode,
- ParseDictTabInfoRecord* parseRecord = NULL);
- void alterTab_writeSchemaConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
- void alterTab_writeTableConf(Signal* signal,
- Uint32 callbackData,
- Uint32 returnCode);
-
- void prepDropTab_nextStep(Signal* signal, DropTableRecordPtr);
- void prepDropTab_complete(Signal* signal, DropTableRecordPtr);
- void prepDropTab_writeSchemaConf(Signal* signal, Uint32 dropTabPtrI, Uint32);
-
- void dropTab_localDROP_TAB_CONF(Signal* signal);
- void dropTab_nextStep(Signal* signal, DropTableRecordPtr);
- void dropTab_complete(Signal* signal, Uint32 dropTabPtrI, Uint32);
- void dropTab_writeSchemaConf(Signal* signal, Uint32 dropTabPtrI, Uint32);
-
- void createTab_prepare(Signal* signal, CreateTabReq * req);
- void createTab_writeSchemaConf1(Signal* signal, Uint32 callback, Uint32);
- void createTab_writeTableConf(Signal* signal, Uint32 callbackData, Uint32);
- void createTab_dih(Signal*, CreateTableRecordPtr,
- SegmentedSectionPtr, Callback*);
- void createTab_dihComplete(Signal* signal, Uint32 callbackData, Uint32);
-
- void createTab_startLcpMutex_locked(Signal* signal, Uint32, Uint32);
- void createTab_startLcpMutex_unlocked(Signal* signal, Uint32, Uint32);
-
- void createTab_commit(Signal* signal, CreateTabReq * req);
- void createTab_writeSchemaConf2(Signal* signal, Uint32 callbackData, Uint32);
- void createTab_alterComplete(Signal*, Uint32 callbackData, Uint32);
-
- void createTab_drop(Signal* signal, CreateTabReq * req);
- void createTab_dropComplete(Signal* signal, Uint32 callbackData, Uint32);
-
- void createTab_reply(Signal* signal, CreateTableRecordPtr, Uint32 nodeId);
- void alterTab_activate(Signal*, CreateTableRecordPtr, Callback*);
-
- void restartCreateTab(Signal*, Uint32,
- const SchemaFile::TableEntry *,
- const SchemaFile::TableEntry *, bool);
- void restartCreateTab_readTableConf(Signal* signal, Uint32 callback, Uint32);
- void restartCreateTab_writeTableConf(Signal* signal, Uint32 callback, Uint32);
- void restartCreateTab_dihComplete(Signal* signal, Uint32 callback, Uint32);
- void restartCreateTab_activateComplete(Signal*, Uint32 callback, Uint32);
-
- void restartDropTab(Signal* signal, Uint32 tableId,
- const SchemaFile::TableEntry *,
- const SchemaFile::TableEntry *);
- void restartDropTab_complete(Signal*, Uint32 callback, Uint32);
-
- void restartDropObj(Signal*, Uint32, const SchemaFile::TableEntry *);
- void restartDropObj_prepare_start_done(Signal*, Uint32, Uint32);
- void restartDropObj_prepare_complete_done(Signal*, Uint32, Uint32);
- void restartDropObj_commit_start_done(Signal*, Uint32, Uint32);
- void restartDropObj_commit_complete_done(Signal*, Uint32, Uint32);
-
- void restart_checkSchemaStatusComplete(Signal*, Uint32 callback, Uint32);
- void restart_writeSchemaConf(Signal*, Uint32 callbackData, Uint32);
- void masterRestart_checkSchemaStatusComplete(Signal*, Uint32, Uint32);
-
- void sendSchemaComplete(Signal*, Uint32 callbackData, Uint32);
-
- void execCREATE_OBJ_REQ(Signal* signal);
- void execCREATE_OBJ_REF(Signal* signal);
- void execCREATE_OBJ_CONF(Signal* signal);
-
- void createObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32);
- void createObj_writeSchemaConf1(Signal* signal, Uint32 callback, Uint32);
- void createObj_writeObjConf(Signal* signal, Uint32 callbackData, Uint32);
- void createObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32);
- void createObj_commit_start_done(Signal* signal, Uint32 callback, Uint32);
- void createObj_writeSchemaConf2(Signal* signal, Uint32 callbackData, Uint32);
- void createObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
- void createObj_abort(Signal*, struct CreateObjReq*);
- void createObj_abort_start_done(Signal*, Uint32 callbackData, Uint32);
- void createObj_abort_writeSchemaConf(Signal*, Uint32 callbackData, Uint32);
- void createObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32);
-
- void schemaOp_reply(Signal* signal, SchemaTransaction *, Uint32);
- void trans_commit_start_done(Signal*, Uint32 callbackData, Uint32);
- void trans_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
- void trans_abort_start_done(Signal*, Uint32 callbackData, Uint32);
- void trans_abort_complete_done(Signal*, Uint32 callbackData, Uint32);
-
- void execDROP_OBJ_REQ(Signal* signal);
- void execDROP_OBJ_REF(Signal* signal);
- void execDROP_OBJ_CONF(Signal* signal);
-
- void dropObj_prepare_start_done(Signal* signal, Uint32 callback, Uint32);
- void dropObj_prepare_writeSchemaConf(Signal*, Uint32 callback, Uint32);
- void dropObj_prepare_complete_done(Signal*, Uint32 callbackData, Uint32);
- void dropObj_commit_start_done(Signal*, Uint32 callbackData, Uint32);
- void dropObj_commit_writeSchemaConf(Signal*, Uint32 callback, Uint32);
- void dropObj_commit_complete_done(Signal*, Uint32 callbackData, Uint32);
- void dropObj_abort_start_done(Signal*, Uint32 callbackData, Uint32);
- void dropObj_abort_writeSchemaConf(Signal*, Uint32 callback, Uint32);
- void dropObj_abort_complete_done(Signal*, Uint32 callbackData, Uint32);
-
- void restartCreateObj(Signal*, Uint32,
- const SchemaFile::TableEntry *,
- const SchemaFile::TableEntry *, bool);
- void restartCreateObj_readConf(Signal*, Uint32, Uint32);
- void restartCreateObj_getTabInfoConf(Signal*);
- void restartCreateObj_prepare_start_done(Signal*, Uint32, Uint32);
- void restartCreateObj_write_complete(Signal*, Uint32, Uint32);
- void restartCreateObj_prepare_complete_done(Signal*, Uint32, Uint32);
- void restartCreateObj_commit_start_done(Signal*, Uint32, Uint32);
- void restartCreateObj_commit_complete_done(Signal*, Uint32, Uint32);
-
- void execDICT_COMMIT_REQ(Signal*);
- void execDICT_COMMIT_REF(Signal*);
- void execDICT_COMMIT_CONF(Signal*);
-
- void execDICT_ABORT_REQ(Signal*);
- void execDICT_ABORT_REF(Signal*);
- void execDICT_ABORT_CONF(Signal*);
-
-public:
- void createObj_commit(Signal*, struct SchemaOp*);
- void createObj_abort(Signal*, struct SchemaOp*);
-
- void create_fg_prepare_start(Signal* signal, SchemaOp*);
- void create_fg_prepare_complete(Signal* signal, SchemaOp*);
- void create_fg_abort_start(Signal* signal, SchemaOp*);
- void create_fg_abort_complete(Signal* signal, SchemaOp*);
-
- void create_file_prepare_start(Signal* signal, SchemaOp*);
- void create_file_prepare_complete(Signal* signal, SchemaOp*);
- void create_file_commit_start(Signal* signal, SchemaOp*);
- void create_file_abort_start(Signal* signal, SchemaOp*);
- void create_file_abort_complete(Signal* signal, SchemaOp*);
-
- void dropObj_commit(Signal*, struct SchemaOp*);
- void dropObj_abort(Signal*, struct SchemaOp*);
- void drop_file_prepare_start(Signal* signal, SchemaOp*);
- void drop_file_commit_start(Signal* signal, SchemaOp*);
- void drop_file_commit_complete(Signal* signal, SchemaOp*);
- void drop_file_abort_start(Signal* signal, SchemaOp*);
- void send_drop_file(Signal*, SchemaOp*, DropFileImplReq::RequestInfo);
-
- void drop_fg_prepare_start(Signal* signal, SchemaOp*);
- void drop_fg_commit_start(Signal* signal, SchemaOp*);
- void drop_fg_commit_complete(Signal* signal, SchemaOp*);
- void drop_fg_abort_start(Signal* signal, SchemaOp*);
- void send_drop_fg(Signal*, SchemaOp*, DropFilegroupImplReq::RequestInfo);
-
- void drop_undofile_prepare_start(Signal* signal, SchemaOp*);
- void drop_undofile_commit_complete(Signal* signal, SchemaOp*);
-
- int checkSingleUserMode(Uint32 senderRef);
-};
-
-inline bool
-Dbdict::TableRecord::isTable() const
-{
- return DictTabInfo::isTable(tableType);
-}
-
-inline bool
-Dbdict::TableRecord::isIndex() const
-{
- return DictTabInfo::isIndex(tableType);
-}
-
-inline bool
-Dbdict::TableRecord::isUniqueIndex() const
-{
- return DictTabInfo::isUniqueIndex(tableType);
-}
-
-inline bool
-Dbdict::TableRecord::isNonUniqueIndex() const
-{
- return DictTabInfo::isNonUniqueIndex(tableType);
-}
-
-inline bool
-Dbdict::TableRecord::isHashIndex() const
-{
- return DictTabInfo::isHashIndex(tableType);
-}
-
-inline bool
-Dbdict::TableRecord::isOrderedIndex() const
-{
- return DictTabInfo::isOrderedIndex(tableType);
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.txt b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.txt
deleted file mode 100644
index 8d4267a1c42..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-
-Event creation
-
-USER DICT(Master) UTIL SUMA
-================================================================================
-CREATE_EVENT_REQ::create
--------------------------->
- - Get ID
- CREATE_SUBID
- ----------------------------------------------->
- <-----------------------------------------------
- - insert into system table
- UTIL_PREPARE::insert
- ------------------------>
- <------------------------
- UTIL_EXECUTE
- ------------------------>
- <------------------------
-CREATE_EVENT_CONF
-<--------------------------
-
-
-Event dropping
-
-USER DICT(Master) UTIL SUMA
-================================================================================
-DROP_EVENT_REQ
--------------------------->
- - remove from system table
- UTIL_PREPARE::delete
- ------------------------>
- <------------------------
- UTIL_EXECUTE
- ------------------------>
- <------------------------
-DROP_EVENT_CONF
-<--------------------------
-
-
-
-create NdbEventOperation
-
-USER DICT(Master) (Slaves) UTIL
-=======================================================================
-CREATE_EVENT_REQ::get
--------------------------->
- - read from system table
- UTIL_PREPARE::read
- ---------------------------------------->
- <----------------------------------------
- UTIL_EXECUTE
- ---------------------------------------->
- <----------------------------------------
- SUMA
- CREATE_EVENT_REQ::after_get ======
- ---------------------->
- SUB_CREATE
- ------------------>
- <------------------
- SUB_SYNC
- ------------------>
- <------------------
- CREATE_EVENT_CONF
- <----------------------
-CREATE_EVENT_CONF
-<-------------------------
-
-
-
-USER DICT(Master) (Slaves) SUMA
-=======================================================================
-SUB_START_REQ
--------------------------->
- SUB_START_REQ
- ---------------------->
- SUB_START
- ------------------>
- <------------------
- SUB_START_CONF
- <----------------------
-SUB_START_CONF
-<-------------------------
-
-
-SUB_STOP analogous to SUB_STOP
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt b/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt
deleted file mode 100644
index 72e23ed15a5..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-Lock master DICT against schema operations
-
-Implementation
---------------
-
-[ see comments in Dbdict.hpp ]
-
-Use case: Node startup INR / NR
--------------------------------
-
-Master DICT (like any block) keeps list of alive nodes (c_aliveNodes).
-These are participants in schema ops.
-
-(1) c_aliveNodes is initialized when DICT starts
- in sp3 in READ_NODESCONF from CNTR
-
-(2) when slave node fails (in any sp of the slave node)
- it is removed from c_aliveNodes in NODE_FAILREP
-
-(3) when slave starts, it is added to c_aliveNodes
- in sp4 of the starting node in INCL_NODEREQ
-
-Slave DIH locks master DICT in sp2 and releases the lock when started.
-Based on the constraints:
-
-- the lock is taken when master DICT is known
- DIH reads this in sp2 in READ_NODESCONF
-
-- the lock is taken before (3)
-
-- the lock is taken before copying starts and held until it is done
- in sp4 DIH meta, DICT meta, tuple data
-
-- on INR in sp2 in START_PERMREQ the LCP info of the slave is erased
- in all DIH in invalidateNodeLCP() - not safe under schema ops
-
-Signals:
-
-All but DICT_LOCK are standard v5.0 signals.
-s=starting node, m=master, a=all participants, l=local block.
-
-* sp2 - DICT_LOCK and START_PERM
-
-DIH/s
- DICT_LOCK_REQ
- DICT/m
- DICT_LOCK_CONF
-DIH/s
- START_PERMREQ
- DIH/m
- START_INFOREQ
- DIH/a
- invalidateNodeLCP() if INR
- DIH/a
- START_INFOCONF
- DIH/m
- START_PERMCONF
-DIH/s
-
-* sp4 - START_ME (copy metadata, no changes)
-
-DIH/s
- START_MEREQ
- DIH/m
- COPY_TABREQ
- DIH/s
- COPY_TABCONF
- DIH/m
- DICTSTARTREQ
- DICT/s
- GET_SCHEMA_INFOREQ
- DICT/m
- SCHEMA_INFO
- DICT/s
- DICTSTARTCONF
- DIH/m
- INCL_NODEREQ
- DIH/a
- INCL_NODEREQ
- ANY/l
- INCL_NODECONF
- DIH/a
- INCL_NODECONF
- DIH/m
- START_MECONF
-DIH/s
-
-* (copy data, omitted)
-
-* SL_STARTED - release DICT lock
-
-CNTR/s
- NODE_START_REP
- DIH/s
- DICT_UNLOCK_ORD
- DICT/m
-
-# vim: set et sw=4:
diff --git a/storage/ndb/src/kernel/blocks/dbdict/DropTable.txt b/storage/ndb/src/kernel/blocks/dbdict/DropTable.txt
deleted file mode 100644
index 8d364d15c57..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/DropTable.txt
+++ /dev/null
@@ -1,140 +0,0 @@
-DROP TABLE DESCRIPTION
-----------------------
-
-Drop table is controlled by DICT.
-
-Drop table is used in the following cases in some sort.
- - Drop Table
- - Abort Add Table
- - Drop table in node restart
- - Drop table in system restart
-
-Sequence of Drop Table:
------------------------
-
-1) PREP_DROP_TAB_REQ -> all DICT
- Update schema files on disk
- Table status = DROPPING
-
-2) Controlling DICT only
- Report Table Dropped secured but not yet completed.
-
------- PREP DROP
-
-4) PREP_DROP_TAB_REQ -> all LQHs
-
-5) PREP_DROP_TAB_REQ -> all TCs
-
-6) PREP_DROP_TAB_REQ -> all DIHs
-
-
---- LQH::PREP_DROP_TAB_REQ
-
-*) Mark the table so that no new operations will start
-*) Mark all fragments so that new LCP_FRAG_ORD gets replied directly
- w.o actually checkpointing the fragment
-2) Start waiting for completion
-3) Reply PREP_DROP_TAB_CONF
-
-- After this LQH accepts WAIT_DROP_TAB_REQ
-
---- TC::PREP_DROP_TAB_REQ
-
-1) Mark the table so that no new transactions will start on the table
-2) Send WAIT_DROP_TAB_REQ -> all connected LQH's
-3) Wait for CONF (including NF-handling) from LQH:s
-4) Reply PREP_DROP_TAB_CONF
-
---- DIH::PREP_DROP_TAB_REQ
-
-1) Mark the table so that no new LCP will start on the table
-2) If master (unlink any queued LCP_FRAG_ORD)
-3) Send WAIT_DROP_TAB_REQ -> all connected LQH's
-4) Wait for CONF (including NF-handling) from LQH:s
-5) Reply PREP_DROP_TAB_CONF
-
---- LQH::WAIT_DROP_TAB_REQ
-
-1) Wait for running operations
- Wait for running LCP
-
-2) Reply
-
------- PREP_DROP
-
-7) DROP_TAB_REQ -> all DICT's
- *) DROP_TAB_REQ -> TC
- *) DROP_TAB_REQ -> ACC
- *) DROP_TAB_REQ -> TUP
- *) DROP_TAB_REQ -> DIH
- *) DROP_TAB_REQ -> LQH
- *) Update schema files on disk DROPPED
-
-8) DICT_SCHEMAREQ -> all DICT
- Table status = DROPPED
-
----------------------------------
-
-Sequence of Drop table in node/system restart
----------------------------------------------
-
-In both node and system restart the node receives the schema information from
-the master. If the table is in a state where it needs to complete the drop
-table activity then DBACC, DBTUP, DBDIH, DBDICT is contacted to drop all files
-related to the table. After this the schema information is updated with the new
-state. Since all nodes receive the same schema information there is no risk of
-different behaviour in the various NDB nodes.
-
-API Requirements for Drop Table
--------------------------------
-Definition:
-
- Two tables are NOT the same if they were created with two create
- tables at different points in time, even if the two create tables
- had exactly the same definition.
-
-Requirements:
-
-1. Each operation in a transaction refering to a table (by name or by id)
- should operate on the same table. (This is probably necessary.)
-
-2. Each operation in a transaction refering to a table (by name or by
- id) should operate on the same table as were defined at the
- startTransaction timepoint. (This is not strictly necessary for
- API consistency.)
-
- Example 1:
-
- startTransaction()
-
- drop("TableName1")
- create("TableName1")
-
- getNdbOperation("TableName1")
-
- execute(commit)
-
- - If both requirements 1 and 2 are fulfilled, then this should lead
- to "Error: Invalid Schema Version" or similar error
-
- - If only requirement 1 is fulfilled, then this may be executed
- without any errors.
-
-
- Example 2:
-
- startTransaction()
-
- getNdbOperation("TableName1")
- execute(NoCommit)
-
- drop("TableName1")
- create("TableName1")
-
- getNdbOperation("TableName1")
-
- execute(commit)
-
- - This should always lead to "Error: Invalid Schema Version" or
- similar error.
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Event.txt b/storage/ndb/src/kernel/blocks/dbdict/Event.txt
deleted file mode 100644
index 553c915d9c5..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Event.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-
-Event creation
-
-USER DICT(Master) UTIL SUMA
-================================================================================
-CREATE_EVENT_REQ::create
--------------------------->
- - Get ID
- CREATE_SUBID
- ----------------------------------------------->
- <-----------------------------------------------
- - insert into system table
- UTIL_PREPARE::insert
- ------------------------>
- <------------------------
- UTIL_EXECUTE
- ------------------------>
- <------------------------
-CREATE_EVENT_CONF
-<--------------------------
-
-
-Event dropping
-
-USER DICT(Master) (Slaves) UTIL SUMA
-================================================================================
-DROP_EVENT_REQ
--------------------------->
- - read from system table
- UTIL_PREPARE::read
- ------------------------------------>
- <------------------------------------
- UTIL_EXECUTE
- ------------------------------------>
- <------------------------------------
- SUB_REMOVE_REQ
- -------------------->
- SUB_REMOVE
- ------------------------------>
- <------------------------------
- SUB_REMOVE_CONF
- <--------------------
- - remove from system table
- UTIL_PREPARE::delete
- ------------------------------------>
- <------------------------------------
- UTIL_EXECUTE
- ------------------------------------>
- <------------------------------------
-DROP_EVENT_CONF
-<--------------------------
-
-
-
-create NdbEventOperation
-
-USER DICT(Master) (Slaves) UTIL
-=======================================================================
-CREATE_EVENT_REQ::get
--------------------------->
- - read from system table
- UTIL_PREPARE::read
- ---------------------------------------->
- <----------------------------------------
- UTIL_EXECUTE
- ---------------------------------------->
- <----------------------------------------
- SUMA
- CREATE_EVENT_REQ::after_get ======
- ---------------------->
- SUB_CREATE
- ------------------>
- <------------------
- SUB_SYNC
- ------------------>
- <------------------
- CREATE_EVENT_CONF
- <----------------------
-CREATE_EVENT_CONF
-<-------------------------
-
-
-
-USER DICT(Master) (Slaves) SUMA
-=======================================================================
-SUB_START_REQ
--------------------------->
- SUB_START_REQ
- ---------------------->
- SUB_START
- ------------------>
- <------------------
- SUB_START_CONF
- <----------------------
-SUB_START_CONF
-<-------------------------
-
-
-SUB_STOP analogous to SUB_STOP
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am b/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
deleted file mode 100644
index 6b900369b10..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-LDADD += \
- $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
- $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
-
-ndbtools_PROGRAMS = ndb_print_schema_file
-ndb_print_schema_file_SOURCES = printSchemaFile.cpp
-ndb_print_schema_file_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Master_AddTable.sfl b/storage/ndb/src/kernel/blocks/dbdict/Master_AddTable.sfl
deleted file mode 100644
index 69fbb973133..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Master_AddTable.sfl
+++ /dev/null
@@ -1,765 +0,0 @@
-// Copyright (C) 2004 MySQL AB
-// Use is subject to license terms
-//
-// 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; version 2 of the License.
-//
-// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// ---------------------------------------------------------------------------
-// This file contains a signal log trace for DBDICT at the master for a
-// create table. Another file contains the signal log for the participant
-// node. Master node is 2, participant node 4 and api node is 3.
-
-// ---------------------------------------------------------------------------
-// First arrives the table description in a number of DICTTABINFO signals.
-// These have a header of 5 words (see DictTabInfo.hpp for details) and
-// upto 20 words of property data per signal. The property data is packed
-// by the SimpleProperties class.
-// ---------------------------------------------------------------------------
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57069 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 0 "API", s.proc: 3, s.sigId: 940284 length: 25 trace: 0
- H'00010003 H'00047700 H'00000001 H'00000042 H'00000000 H'4e444250 H'524f5053
- H'00010000 H'00000000 H'1c0a1203 H'524f4c46 H'00020001 H'0000000a H'56504e5f
- H'55534552 H'53000000 H'0001000a H'0000004b H'000203e8 H'00000007 H'56504e5f
- H'49440000 H'000103ee H'00000001 H'000203e8
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57069 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 0 "API", s.proc: 3, s.sigId: 940284 length: 25 trace: 0
- H'00010003 H'00047700 H'00000001 H'00000042 H'00000014 H'00000007 H'56504e5f
- H'4e420000 H'000103ee H'00000001 H'000203e8 H'0000000d H'44495245 H'43544f52
- H'595f4e42 H'00000000 H'000103eb H'00000003 H'000103ed H'0000000a H'000103ec
- H'00000002 H'000203e8 H'00000010 H'4c415354
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57069 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 0 "API", s.proc: 3, s.sigId: 940284 length: 25 trace: 0
- H'00010003 H'00047700 H'00000001 H'00000042 H'00000028 H'5f43414c H'4c5f5041
- H'52545900 H'000103eb H'00000003 H'000103ed H'0000000a H'000103ec H'00000002
- H'000203e8 H'00000006 H'44455343 H'52000000 H'000103eb H'00000003 H'000103ed
- H'00000064 H'000103ec H'00000002 H'00010005
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57069 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 0 "API", s.proc: 3, s.sigId: 940284 length: 11 trace: 0
- H'00010003 H'00047700 H'00000001 H'00000042 H'0000003c H'00000002 H'00010006
- H'00000005 H'0001000c H'00000002 H'0000ffff
-
-// ---------------------------------------------------------------------------
-// Send DICT_SCHEMAREQ to all nodes including ourselves to write the state
-// ADD_STARTED in the schema file for the new table.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57069 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000000 H'00000000 H'00000001
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57069 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000000 H'00000000 H'00000001
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57069 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57077 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000000 H'00000000 H'00000001
-
-// ---------------------------------------------------------------------------
-// Write both schema files with new state of table added.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57069 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57081 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57082 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 99
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57081 length: 8 trace: 0
- FilePointer: 99
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57090 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57091 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57090 length: 4 trace: 0
- FilePointer: 99
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57099 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57100 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57099 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57111 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57112 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 100
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57111 length: 8 trace: 0
- FilePointer: 100
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57123 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57124 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57123 length: 4 trace: 0
- FilePointer: 100
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57133 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57135 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, s.sigId: 46718 length: 1 trace: 0
- H'00000004
-
-// ---------------------------------------------------------------------------
-// Pack Table description into pages in DICT using SimpleProperties class.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 3 trace: 0
- H'00000001 H'00000002 H'00000000
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57140 length: 3 trace: 0
- H'00000001 H'00000002 H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57141 length: 2 trace: 0
- H'00000002 H'00000002
-
-// ---------------------------------------------------------------------------
-// Send the table description over to the other NDB nodes.
-// A CONTINUEB is sent for each signal sent to avoid overloading the
-// transporters.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000000 H'4e444250 H'524f5053
- H'00002000 H'0000001c H'1c0a1203 H'524f4c46 H'00020001 H'0000000a H'56504e5f
- H'55534552 H'53000000 H'0001000a H'0000004b H'000203e8 H'00000007 H'56504e5f
- H'49440000 H'1cc03924 H'00000001 H'000203e8
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57142 length: 2 trace: 0
- H'00000002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000014 H'00000007 H'56504e5f
- H'4e420000 H'000103ee H'00000001 H'000203e8 H'0000000d H'44495245 H'43544f52
- H'595f4e42 H'00000000 H'000103eb H'00000003 H'524f4c46 H'00020001 H'0000000a
- H'56504e5f H'55534552 H'53000010 H'00010002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57143 length: 2 trace: 0
- H'00000002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000028 H'00000002 H'00010011
- H'00000003 H'00010003 H'00000001 H'00010005 H'00000002 H'00010006 H'00000005
- H'0001000a H'0000004b H'0001000c H'00000002 H'000203e8 H'00000007 H'56504e5f
- H'49440064 H'000103e9 H'00000000 H'000103ee
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57144 length: 2 trace: 0
- H'00000002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'0000003c H'00000001 H'000203e8
- H'00000007 H'56504e5f H'4e420002 H'000103e9 H'00000001 H'000103ee H'00000001
- H'000203e8 H'0000000d H'44495245 H'43544f52 H'595f4e42 H'00000000 H'000103e9
- H'00000002 H'000103eb H'00000003 H'000103ec
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57145 length: 2 trace: 0
- H'00000002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000050 H'00000002 H'000103ed
- H'0000000a H'000203e8 H'00000010 H'4c415354 H'5f43414c H'4c5f5041 H'52545900
- H'000103e9 H'00000003 H'000103eb H'00000003 H'000103ec H'00000002 H'000103ed
- H'0000000a H'000203e8 H'00000006 H'44455343
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 2 trace: 0
- H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57132 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57146 length: 2 trace: 0
- H'00000002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 15 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000064 H'52000000 H'000103e9
- H'00000004 H'000103eb H'00000003 H'000103ec H'00000002 H'000103ed H'00000064
- H'0000ffff
-
-// ---------------------------------------------------------------------------
-// In parallel with sending the table description to other nodes we will also
-// write the table description to our local file system.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57132 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'00000002 H'ffffffff H'00000001 H'010401ff
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57165 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57166 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 101
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57165 length: 8 trace: 0
- FilePointer: 101
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000000, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57177 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57178 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57177 length: 4 trace: 0
- FilePointer: 101
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57186 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57187 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57186 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'00000002 H'ffffffff H'00000001 H'010402ff
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57195 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57196 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 102
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57195 length: 8 trace: 0
- FilePointer: 102
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000000, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57204 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57205 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57204 length: 4 trace: 0
- FilePointer: 102
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57218 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57219 length: 1 trace: 0
- UserPointer: H'00000000
-
-// ---------------------------------------------------------------------------
-// Completed writing to our file system the table description.
-// ---------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57229 gsn: 24 "DICTTABCONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, s.sigId: 46803 length: 2 trace: 0
- H'00000002 H'00000004
-
-// ---------------------------------------------------------------------------
-// Also the participant have completed writing the table description to file.
-// ---------------------------------------------------------------------------
-
-// ---------------------------------------------------------------------------
-// Write the state UPDATE_PAGE_COUNT to schema file for the new table.
-// This also contains the number of pages used for the table description.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57229 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'00000000 H'00000002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57229 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'00000000 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57229 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57234 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'00000000 H'00000002
-
-// ---------------------------------------------------------------------------
-// Write schema file to disk
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57229 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57238 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57239 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 103
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57238 length: 8 trace: 0
- FilePointer: 103
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57247 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57248 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57247 length: 4 trace: 0
- FilePointer: 103
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57257 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57258 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57257 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57267 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57268 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 104
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57267 length: 8 trace: 0
- FilePointer: 104
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57279 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57283 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57279 length: 4 trace: 0
- FilePointer: 104
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57290 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 57291 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57290 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57290 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57293 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57299 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, s.sigId: 46860 length: 1 trace: 0
- H'00000004
-
-// ---------------------------------------------------------------------------
-// All schema files in the system have been updated.
-// ---------------------------------------------------------------------------
-
-// ---------------------------------------------------------------------------
-// Now control is given to DIH for adding the fragments needed by this table.
-// We first seize a record in DIH and then we send the add table request with
-// the needed table parameters.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 238 "DISEIZEREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57299 length: 2 trace: 0
- H'00000000 H'00fa0002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57299 gsn: 236 "DISEIZECONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 57304 length: 2 trace: 0
- H'00000000 H'00000210
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 187 "DIADDTABREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57299 length: 6 trace: 0
- H'00000210 H'00000002 H'00000000 H'00000006 H'00000000 H'00000001
-
-// ---------------------------------------------------------------------------
-// DIH requests us to add a certain fragment replica.
-// ---------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57400 gsn: 195 "DICTFRAGSREQ" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 57418 length: 7 trace: 0
- H'00000000 H'00000000 H'00000000 H'00000002 H'00150040 H'00000001 H'00000002
-
-// ---------------------------------------------------------------------------
-// We add the fragment by contacting LQH through sending a LQHFRAGREQ and
-// a number of LQHADDATTREQ (in this case only one since not more than 8
-// attributes).
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 247 "DBLQH", r.proc: 2, gsn: 313 "LQHFRAGREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57400 length: 17 trace: 0
- H'00000000 H'00fa0002 H'00000000 H'00000000 H'00000002 H'00000001 H'00000050
- H'0000004b H'00000006 H'00000001 H'00000000 H'00000005 H'00000000 H'00000000
- H'00000001 H'00000002 H'00000000
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57400 gsn: 311 "LQHFRAGCONF" prio: 1
-s.bn: 247 "DBLQH", s.proc: 2, s.sigId: 57428 length: 2 trace: 0
- H'00000000 H'00000000
----- Send ----- Signal ----------------
-r.bn: 247 "DBLQH", r.proc: 2, gsn: 310 "LQHADDATTREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57400 length: 12 trace: 0
- H'00000000 H'00000005 H'00000000 H'00012255 H'00000001 H'00012255 H'00000002
- H'000a2236 H'00000003 H'000a2236 H'00000004 H'00642236
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57400 gsn: 308 "LQHADDATTCONF" prio: 1
-s.bn: 247 "DBLQH", s.proc: 2, s.sigId: 57450 length: 1 trace: 0
- H'00000000
-
-// ---------------------------------------------------------------------------
-// When we have completed adding the fragment we send DINEXTNODEREQ (should
-// change name to DICTFRAGSCONF) to DIH indicate we have completed the task.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 231 "DINEXTNODEREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57400 length: 4 trace: 0
- H'00000210 H'00000000 H'00000001 H'00000000
-
-// ---------------------------------------------------------------------------
-// We continue by performing the same task again for the next fragment replica.
-// We skip this from this log since they contain no more interesting stuff.
-// ---------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 57618 gsn: 185 "DIADDTABCONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 57655 length: 2 trace: 0
- H'00000000 H'00000002
-
-// ---------------------------------------------------------------------------
-// Now that we have added all fragments DIH gives back control to DICT by
-// sending DIADDTABCONF.
-// ---------------------------------------------------------------------------
-
-// ---------------------------------------------------------------------------
-// It is now time to decide which global checkpoint this table will be born.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 499 "WAIT_GCP_REQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 57618 length: 3 trace: 0
- H'00fa0002 H'00000000 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58288 gsn: 501 "WAIT_GCP_CONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 58296 length: 2 trace: 0
- H'00000000 H'0000000c
-
-// ---------------------------------------------------------------------------
-// We can update all schema files in the system with this global checkpoint
-// number. We are certain that no transaction will be performed on the table
-// before this global checkpoint.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58288 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'0000000c H'00000003
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58288 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'0000000c H'00000003
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58288 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 58298 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'0000000c H'00000003
-
-// ---------------------------------------------------------------------------
-// Write schema files as usual when updating schema file state.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58288 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58304 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58305 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 117
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58304 length: 8 trace: 0
- FilePointer: 117
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58315 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58316 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58315 length: 4 trace: 0
- FilePointer: 117
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58326 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58327 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58326 length: 7 trace: 0
- UserReference: H'00fa0002, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58339 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58340 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 118
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58339 length: 8 trace: 0
- FilePointer: 118
- UserReference: H'00fa0002, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58348 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58349 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 2, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58348 length: 4 trace: 0
- FilePointer: 118
- UserReference: H'00fa0002, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 2, s.sigId: 58360 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 58364 length: 1 trace: 0
- H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, s.sigId: 47846 length: 1 trace: 0
- H'00000004
-
-// ---------------------------------------------------------------------------
-// Commit the table for usage in DIH and LQH in all nodes.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 247 "DBLQH", r.proc: 2, gsn: 398 "TAB_COMMITREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00000000 H'00fa0002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 398 "TAB_COMMITREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00000001 H'00fa0002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 247 "DBLQH", r.proc: 4, gsn: 398 "TAB_COMMITREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00000000 H'00fa0002 H'00000002
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 4, gsn: 398 "TAB_COMMITREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00000001 H'00fa0002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 396 "TAB_COMMITCONF" prio: 1
-s.bn: 247 "DBLQH", s.proc: 2, s.sigId: 58370 length: 3 trace: 0
- H'00000000 H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 396 "TAB_COMMITCONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 58371 length: 3 trace: 0
- H'00000001 H'00000002 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 396 "TAB_COMMITCONF" prio: 1
-s.bn: 247 "DBLQH", s.proc: 4, s.sigId: 47846 length: 3 trace: 0
- H'00000000 H'00000004 H'00000002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 396 "TAB_COMMITCONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 4, s.sigId: 47846 length: 3 trace: 0
- H'00000001 H'00000004 H'00000002
-
-// ---------------------------------------------------------------------------
-// Finally also open the table for usage from TC in all nodes.
-// After this signal is received in TC it is ok to execute transactions on
-// this new empty table.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 245 "DBTC", r.proc: 2, gsn: 404 "TC_SCHVERREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 5 trace: 0
- H'00000002 H'00000001 H'00000001 H'00fa0002 H'00000000
----- Send ----- Signal ----------------
-r.bn: 245 "DBTC", r.proc: 4, gsn: 404 "TC_SCHVERREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 5 trace: 0
- H'00000002 H'00000001 H'00000001 H'00fa0002 H'00000000
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 403 "TC_SCHVERCONF" prio: 1
-s.bn: 245 "DBTC", s.proc: 2, s.sigId: 58376 length: 2 trace: 0
- H'00000002 H'00000000
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 403 "TC_SCHVERCONF" prio: 1
-s.bn: 245 "DBTC", s.proc: 4, s.sigId: 47846 length: 2 trace: 0
- H'00000002 H'00000001
-
-// ---------------------------------------------------------------------------
-// Unblock dictionary to allow for another add table.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 444 "UNBLO_DICTREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 1 trace: 0
- H'00fa0002
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 444 "UNBLO_DICTREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 1 trace: 0
- H'00fa0002
-
-// ---------------------------------------------------------------------------
-// Send the confirmation to the requesting application process.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 1 "API", r.proc: 3, gsn: 24 "DICTTABCONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00047700 H'00000002 H'00000001
-
-// ---------------------------------------------------------------------------
-// Also release the connection in DIH that was previously established.
-// ---------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 246 "DBDIH", r.proc: 2, gsn: 234 "DIRELEASEREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, sigId: 58359 length: 3 trace: 0
- H'00000210 H'00000000 H'00fa0002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 444 "UNBLO_DICTREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 58378 length: 1 trace: 0
- H'00fa0002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, sigId: 58359 gsn: 232 "DIRELEASECONF" prio: 1
-s.bn: 246 "DBDIH", s.proc: 2, s.sigId: 58380 length: 1 trace: 0
- H'00000000
-
-// ---------------------------------------------------------------------------
-// Now all actions regarding this add table have completed.
-// ---------------------------------------------------------------------------
diff --git a/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp b/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp
deleted file mode 100644
index 42c6e30792f..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBDICT_SCHEMA_FILE_HPP
-#define DBDICT_SCHEMA_FILE_HPP
-
-#include <ndb_types.h>
-#include <ndb_version.h>
-#include <string.h>
-
-#define NDB_SF_MAGIC "NDBSCHMA"
-
-// page size 4k
-#define NDB_SF_PAGE_SIZE_IN_WORDS_LOG2 10
-#define NDB_SF_PAGE_SIZE_IN_WORDS (1 << NDB_SF_PAGE_SIZE_IN_WORDS_LOG2)
-#define NDB_SF_PAGE_SIZE (NDB_SF_PAGE_SIZE_IN_WORDS << 2)
-
-// 4k = (1 + 127) * 32
-#define NDB_SF_PAGE_ENTRIES 127
-
-// 160 pages = 20320 objects
-#define NDB_SF_MAX_PAGES 160
-
-// versions where format changed
-#define NDB_SF_VERSION_5_0_6 MAKE_VERSION(5, 0, 6)
-
-// One page in schema file.
-struct SchemaFile {
- // header size 32 bytes
- char Magic[8];
- Uint32 ByteOrder;
- Uint32 NdbVersion;
- Uint32 FileSize; // In bytes
- Uint32 PageNumber;
- Uint32 CheckSum; // Of this page
- Uint32 NoOfTableEntries; // On this page (NDB_SF_PAGE_ENTRIES)
-
- enum TableState {
- INIT = 0,
- ADD_STARTED = 1,
- TABLE_ADD_COMMITTED = 2,
- DROP_TABLE_STARTED = 3,
- DROP_TABLE_COMMITTED = 4,
- ALTER_TABLE_COMMITTED = 5,
- TEMPORARY_TABLE_COMMITTED = 6
- };
-
- // entry size 32 bytes
- struct TableEntry {
- Uint32 m_tableState;
- Uint32 m_tableVersion;
- Uint32 m_tableType;
- Uint32 m_info_words;
- Uint32 m_gcp;
- Uint32 m_unused[3];
-
- bool operator==(const TableEntry& o) const {
- return memcmp(this, &o, sizeof(* this))== 0;
- }
- };
-
- // pre-5.0.6
- struct TableEntry_old {
- Uint32 m_tableState;
- Uint32 m_tableVersion;
- Uint32 m_tableType;
- Uint32 m_noOfPages;
- Uint32 m_gcp;
- };
-
- union {
- TableEntry TableEntries[NDB_SF_PAGE_ENTRIES];
- TableEntry_old TableEntries_old[1];
- };
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Slave_AddTable.sfl b/storage/ndb/src/kernel/blocks/dbdict/Slave_AddTable.sfl
deleted file mode 100644
index 20512b6f975..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/Slave_AddTable.sfl
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright (C) 2004 MySQL AB
-// Use is subject to license terms
-//
-// 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; version 2 of the License.
-//
-// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// ---------------------------------------------------------------------------
-// This file contains a signal log trace for DBDICT at the master for a
-// create table. Another file contains the signal log for the participant
-// node. Master node is 2, participant node 4 and api node is 3.
-
-// ---------------------------------------------------------------------------
-// This file contains a signal log trace for DBDICT at the participant for a
-// add table. Another file contains the signal log for the master
-// node. Master node is 2, participant node 4 and api node is 3.
-//
-
-// ---------------------------------------------------------------------------
-//--------------------------------------------------------------------------
-// Master requests us to save a new state of the table in the schema file
-// == ADD_STARTED
-//--------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46661 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57069 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000000 H'00000000 H'00000001
-
-//--------------------------------------------------------------------------
-// Write the new state to the schema files.
-//--------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46661 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46669 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46670 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 99
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46669 length: 8 trace: 0
- FilePointer: 99
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46679 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46680 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46679 length: 4 trace: 0
- FilePointer: 99
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46690 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46691 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46690 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46700 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46701 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 100
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46700 length: 8 trace: 0
- FilePointer: 100
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46709 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46710 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46709 length: 4 trace: 0
- FilePointer: 100
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46719 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46718 length: 1 trace: 0
- H'00000004
-
-//--------------------------------------------------------------------------
-// We receive the table description from the master node.
-// We set the data in the DICT block. (table and attribute records).
-//--------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000000 H'4e444250 H'524f5053
- H'00002000 H'0000001c H'1c0a1203 H'524f4c46 H'00020001 H'0000000a H'56504e5f
- H'55534552 H'53000000 H'0001000a H'0000004b H'000203e8 H'00000007 H'56504e5f
- H'49440000 H'1cc03924 H'00000001 H'000203e8
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000014 H'00000007 H'56504e5f
- H'4e420000 H'000103ee H'00000001 H'000203e8 H'0000000d H'44495245 H'43544f52
- H'595f4e42 H'00000000 H'000103eb H'00000003 H'524f4c46 H'00020001 H'0000000a
- H'56504e5f H'55534552 H'53000010 H'00010002
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000028 H'00000002 H'00010011
- H'00000003 H'00010003 H'00000001 H'00010005 H'00000002 H'00010006 H'00000005
- H'0001000a H'0000004b H'0001000c H'00000002 H'000203e8 H'00000007 H'56504e5f
- H'49440064 H'000103e9 H'00000000 H'000103ee
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'0000003c H'00000001 H'000203e8
- H'00000007 H'56504e5f H'4e420002 H'000103e9 H'00000001 H'000103ee H'00000001
- H'000203e8 H'0000000d H'44495245 H'43544f52 H'595f4e42 H'00000000 H'000103e9
- H'00000002 H'000103eb H'00000003 H'000103ec
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 25 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000050 H'00000002 H'000103ed
- H'0000000a H'000203e8 H'00000010 H'4c415354 H'5f43414c H'4c5f5041 H'52545900
- H'000103e9 H'00000003 H'000103eb H'00000003 H'000103ec H'00000002 H'000103ed
- H'0000000a H'000203e8 H'00000006 H'44455343
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 204 "DICTTABINFO" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57132 length: 15 trace: 0
- H'00fa0002 H'00000000 H'00000002 H'0000006e H'00000064 H'52000000 H'000103e9
- H'00000004 H'000103eb H'00000003 H'000103ec H'00000002 H'000103ed H'00000064
- H'0000ffff
-
-//--------------------------------------------------------------------------
-// Pack the table description into pages.
-//--------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46718 length: 3 trace: 0
- H'00000001 H'00000002 H'00000000
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46718 gsn: 164 "CONTINUEB" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, s.sigId: 46730 length: 3 trace: 0
- H'00000001 H'00000002 H'00000000
-
-//--------------------------------------------------------------------------
-// Write the pages of the table description to disk.
-//--------------------------------------------------------------------------
-
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46718 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'00000002 H'ffffffff H'00000001 H'010401ff
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46748 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46749 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 101
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46748 length: 8 trace: 0
- FilePointer: 101
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000000, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46757 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46758 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46757 length: 4 trace: 0
- FilePointer: 101
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46766 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46767 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46766 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'00000002 H'ffffffff H'00000001 H'010402ff
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46783 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46784 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 102
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46783 length: 8 trace: 0
- FilePointer: 102
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000000, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46794 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46795 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46794 length: 4 trace: 0
- FilePointer: 102
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46803 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46804 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 24 "DICTTABCONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46803 length: 2 trace: 0
- H'00000002 H'00000004
-
-//--------------------------------------------------------------------------
-// Update schema file ín memory and on disk to UPDATE_PAGE_COUNT.
-//--------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46803 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 57229 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'00000000 H'00000002
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46803 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46813 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46814 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 103
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46813 length: 8 trace: 0
- FilePointer: 103
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46823 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46824 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46823 length: 4 trace: 0
- FilePointer: 103
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46833 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46834 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46833 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46842 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46843 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 104
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46842 length: 8 trace: 0
- FilePointer: 104
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46851 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46852 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46851 length: 4 trace: 0
- FilePointer: 104
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 46860 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 46861 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 46860 length: 1 trace: 0
- H'00000004
-
-//--------------------------------------------------------------------------
-// Update schema file with information about the starting global checkpoint
-// identity.
-//--------------------------------------------------------------------------
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47782 gsn: 132 "DICT_SCHEMAREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 58288 length: 7 trace: 0
- H'00010003 H'00047700 H'00000002 H'00000001 H'00000001 H'0000000c H'00000003
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47782 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050100
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47793 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47794 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 117
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47793 length: 8 trace: 0
- FilePointer: 117
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47804 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47805 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47804 length: 4 trace: 0
- FilePointer: 117
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47817 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47818 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 261 "FSOPENREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47817 length: 7 trace: 0
- UserReference: H'00fa0004, userPointer: H'00000000
- FileNumber[1-4]: H'ffffffff H'ffffffff H'ffffffff H'01050200
- FileFlags: H'00000311 Open write only, Create new file, Truncate existing file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47826 gsn: 259 "FSOPENCONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47827 length: 3 trace: 0
- UserPointer: H'00000000
- FilePointer: 118
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 272 "FSWRITEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47826 length: 8 trace: 0
- FilePointer: 118
- UserReference: H'00fa0004, UserPointer: H'00000000
- Operation flag: H'00000011, Sync, Format=Array of pages
- varIndex: 1
- numberOfPages: 1
- pageData: H'00000008, H'00000000
-
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47836 gsn: 270 "FSWRITECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47837 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 253 "NDBFS", r.proc: 4, gsn: 257 "FSCLOSEREQ" prio: 0
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47836 length: 4 trace: 0
- FilePointer: 118
- UserReference: H'00fa0004, userPointer: H'00000000
- Flags: H'00000000, Don't remove file
----- Received - Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47846 gsn: 255 "FSCLOSECONF" prio: 1
-s.bn: 253 "NDBFS", s.proc: 4, s.sigId: 47847 length: 1 trace: 0
- UserPointer: H'00000000
----- Send ----- Signal ----------------
-r.bn: 250 "DBDICT", r.proc: 2, gsn: 133 "DICT_SCHEMACONF" prio: 1
-s.bn: 250 "DBDICT", s.proc: 4, sigId: 47846 length: 1 trace: 0
- H'00000004
----- Received - Signal ----------------
-
-//--------------------------------------------------------------------------
-// Finally unblock the DICT block so that it can handle add table as master
-// if it becomes master in the future.
-//--------------------------------------------------------------------------
-
-r.bn: 250 "DBDICT", r.proc: 4, sigId: 47846 gsn: 444 "UNBLO_DICTREQ" prio: 1
-s.bn: 250 "DBDICT", s.proc: 2, s.sigId: 58359 length: 1 trace: 0
- H'00fa0002
-
-//--------------------------------------------------------------------------
-// We completed the add table operation.
-//--------------------------------------------------------------------------
-
diff --git a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
deleted file mode 100644
index 55c42ee88e7..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <util/version.h>
-
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <SchemaFile.hpp>
-#include <kernel_types.h>
-
-static const char* progname = 0;
-static bool allflag = false;
-static bool checkonly = false;
-static bool equalcontents = false;
-static bool okquiet = false;
-
-static void
-usage()
-{
- ndbout
- << "Usage: " << progname << " [-aceq]" << " file ..." << endl
- << "-a print also unused slots" << endl
- << "-c check only (return status 1 on error)" << endl
- << "-e check also that the files have identical contents" << endl
- << "-q no output if file is ok" << endl
- << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
-}
-
-#ifdef NOT_USED
-
-static void
-fill(const char * buf, int mod)
-{
- int len = strlen(buf)+1;
- ndbout << buf << " ";
- while((len % mod) != 0){
- ndbout << " ";
- len++;
- }
-}
-#endif
-
-static const char*
-version(Uint32 v)
-{
- static char buf[40];
- sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
- return buf;
-}
-
-static int
-print_head(const char * filename, const SchemaFile * sf)
-{
- int retcode = 0;
-
- if (! checkonly) {
- ndbout << "----- Schemafile: " << filename << " -----" << endl;
- ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
- (int) sizeof(sf->Magic),
- sf->Magic,
- sf->ByteOrder,
- version(sf->NdbVersion),
- sf->FileSize);
- }
-
- if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
- ndbout << filename << ": invalid header magic" << endl;
- retcode = 1;
- }
-
- if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
- ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
- retcode = 1;
- }
-
- return retcode;
-}
-
-inline
-Uint32
-table_version_minor(Uint32 ver)
-{
- return ver >> 24;
-}
-
-static int
-print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
-{
- int retcode = 0;
-
- if (print_head(filename, sf) != 0)
- retcode = 1;
-
- for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
- SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
- if (allflag ||
- (te.m_tableState != SchemaFile::INIT &&
- te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
- if (! checkonly)
- ndbout << "Table " << i << ":"
- << " State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion)
- << "(" << table_version_minor(te.m_tableVersion) << ")"
- << " type = " << te.m_tableType
- << " noOfPages = " << te.m_noOfPages
- << " gcp: " << te.m_gcp << endl;
- }
- }
- return retcode;
-}
-
-static int
-print(const char * filename, const SchemaFile * xsf, Uint32 sz)
-{
- int retcode = 0;
-
- if (print_head(filename, xsf) != 0)
- retcode = 1;
-
- assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
- if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
- ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
- retcode = 1;
- }
- Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
- for (Uint32 n = 0; n < noOfPages; n++) {
- if (! checkonly) {
- ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
- }
- const SchemaFile * sf = &xsf[n];
- if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
- ndbout << filename << ": page " << n << " invalid magic" << endl;
- retcode = 1;
- }
- if (sf->FileSize != xsf->FileSize) {
- ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
- retcode = 1;
- }
- Uint32 cs = 0;
- for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
- cs ^= ((const Uint32*)sf)[j];
- if (cs != 0) {
- ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
- retcode = 1;
- }
- if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
- ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
- retcode = 1;
- }
- for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
- SchemaFile::TableEntry te = sf->TableEntries[i];
- Uint32 j = n * NDB_SF_PAGE_ENTRIES + i;
- if (allflag ||
- (te.m_tableState != SchemaFile::INIT &&
- te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
- if (! checkonly)
- ndbout << "Table " << j << ":"
- << " State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion)
- << "(" << table_version_minor(te.m_tableVersion) << ")"
- << " type = " << te.m_tableType
- << " noOfWords = " << te.m_info_words
- << " gcp: " << te.m_gcp << endl;
- }
- if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) {
- ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl;
- retcode = 1;
- }
- }
- }
-
- return retcode;
-}
-
-NDB_COMMAND(printSchemafile,
- "printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
-{
- progname = argv[0];
- int exitcode = 0;
-
- while (argc > 1 && argv[1][0] == '-') {
- if (strchr(argv[1], 'a') != 0)
- allflag = true;
- if (strchr(argv[1], 'c') != 0)
- checkonly = true;
- if (strchr(argv[1], 'e') != 0)
- equalcontents = true;
- if (strchr(argv[1], 'q') != 0)
- okquiet = true;
- if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
- usage();
- return 0;
- }
- argc--, argv++;
- }
-
- const char * prevfilename = 0;
- Uint32 * prevbuf = 0;
- Uint32 prevbytes = 0;
-
- while (argc > 1) {
- const char * filename = argv[1];
- argc--, argv++;
-
- struct stat sbuf;
- const int res = stat(filename, &sbuf);
- if (res != 0) {
- ndbout << filename << ": not found errno=" << errno << endl;
- exitcode = 1;
- continue;
- }
- const Uint32 bytes = sbuf.st_size;
-
- Uint32 * buf = new Uint32[bytes/4+1];
-
- FILE * f = fopen(filename, "rb");
- if (f == 0) {
- ndbout << filename << ": open failed errno=" << errno << endl;
- delete [] buf;
- exitcode = 1;
- continue;
- }
- Uint32 sz = fread(buf, 1, bytes, f);
- fclose(f);
- if (sz != bytes) {
- ndbout << filename << ": read failed errno=" << errno << endl;
- delete [] buf;
- exitcode = 1;
- continue;
- }
-
- if (sz < 32) {
- ndbout << filename << ": too short (no header)" << endl;
- delete [] buf;
- exitcode = 1;
- continue;
- }
-
- SchemaFile* sf = (SchemaFile *)&buf[0];
- int ret;
- if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
- ret = print_old(filename, sf, sz);
- else
- ret = print(filename, sf, sz);
-
- if (ret != 0) {
- ndbout << filename << ": check failed"
- << " version=" << version(sf->NdbVersion) << endl;
- exitcode = 1;
- } else if (! okquiet) {
- ndbout << filename << ": ok"
- << " version=" << version(sf->NdbVersion) << endl;
- }
-
- if (equalcontents && prevfilename != 0) {
- if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
- ndbout << filename << ": differs from " << prevfilename << endl;
- exitcode = 1;
- }
- }
-
- prevfilename = filename;
- delete [] prevbuf;
- prevbuf = buf;
- prevbytes = bytes;
- }
-
- delete [] prevbuf;
- return exitcode;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
deleted file mode 100644
index f27287b79a4..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
+++ /dev/null
@@ -1,1673 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBDIH_H
-#define DBDIH_H
-
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include "Sysfile.hpp"
-#include <SignalCounter.hpp>
-
-#include <signaldata/MasterLCP.hpp>
-#include <signaldata/CopyGCIReq.hpp>
-#include <blocks/mutexes.hpp>
-
-#ifdef DBDIH_C
-
-/*###################*/
-/* FILE SYSTEM FLAGS */
-/*###################*/
-#define ZLIST_OF_PAIRS 0
-#define ZLIST_OF_PAIRS_SYNCH 16
-#define ZOPEN_READ_WRITE 2
-#define ZCREATE_READ_WRITE 0x302
-#define ZCLOSE_NO_DELETE 0
-#define ZCLOSE_DELETE 1
-
-/*###############*/
-/* NODE STATES */
-/*###############*/
-#define ZIDLE 0
-#define ZACTIVE 1
-
-/*#########*/
-/* GENERAL */
-/*#########*/
-#define ZVAR_NO_WORD 1
-#define ZVAR_NO_CRESTART_INFO 20
-#define ZVAR_NO_CRESTART_INFO_TO_FILE 21
-#define ZVALID 1
-#define ZINVALID 2
-
-/*###############*/
-/* ERROR CODES */
-/*###############*/
-// ------------------------------------------
-// Error Codes for Transactions (None sofar)
-// ------------------------------------------
-#define ZUNDEFINED_FRAGMENT_ERROR 311
-
-// --------------------------------------
-// Error Codes for Add Table
-// --------------------------------------
-#define ZREPLERROR1 306
-
-// --------------------------------------
-// Crash Codes
-// --------------------------------------
-#define ZCOULD_NOT_OCCUR_ERROR 300
-#define ZNOT_MASTER_ERROR 301
-#define ZWRONG_FAILURE_NUMBER_ERROR 302
-#define ZWRONG_START_NODE_ERROR 303
-#define ZNO_REPLICA_FOUND_ERROR 304
-
-// --------------------------------------
-// Codes from LQH
-// --------------------------------------
-#define ZNODE_FAILURE_ERROR 400
-
-
-/*#########*/
-/* PHASES */
-/*#########*/
-#define ZNDB_SPH1 1
-#define ZNDB_SPH2 2
-#define ZNDB_SPH3 3
-#define ZNDB_SPH4 4
-#define ZNDB_SPH5 5
-#define ZNDB_SPH6 6
-#define ZNDB_SPH7 7
-#define ZNDB_SPH8 8
-/*#########*/
-/* SIZES */
-/*#########*/
-#define ZPAGEREC 100
-#define ZCREATE_REPLICA_FILE_SIZE 4
-#define ZPROXY_MASTER_FILE_SIZE 10
-#define ZPROXY_FILE_SIZE 10
-#endif
-
-class Dbdih: public SimulatedBlock {
-public:
-
- // Records
-
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
- * THE API CONNECT RECORD IS THE SAME RECORD POINTER AS USED IN THE TC BLOCK
- *
- * IT KEEPS TRACK OF ALL THE OPERATIONS CONNECTED TO THIS TRANSACTION.
- * IT IS LINKED INTO A QUEUE IN CASE THE GLOBAL CHECKPOINT IS CURRENTLY
- * ONGOING */
- struct ApiConnectRecord {
- Uint32 apiGci;
- Uint32 nextApi;
- };
- typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
-
- /*############## CONNECT_RECORD ##############*/
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THE CONNECT RECORD IS CREATED WHEN A TRANSACTION HAS TO START. IT KEEPS
- ALL INTERMEDIATE INFORMATION NECESSARY FOR THE TRANSACTION FROM THE
- DISTRIBUTED MANAGER. THE RECORD KEEPS INFORMATION ABOUT THE
- OPERATIONS THAT HAVE TO BE CARRIED OUT BY THE TRANSACTION AND
- ALSO THE TRAIL OF NODES FOR EACH OPERATION IN THE THE
- TRANSACTION.
- */
- struct ConnectRecord {
- enum ConnectState {
- INUSE = 0,
- FREE = 1,
- STARTED = 2
- };
- Uint32 nodes[MAX_REPLICAS];
- ConnectState connectState;
- Uint32 nfConnect;
- Uint32 table;
- Uint32 userpointer;
- BlockReference userblockref;
- };
- typedef Ptr<ConnectRecord> ConnectRecordPtr;
-
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THESE RECORDS ARE USED WHEN CREATING REPLICAS DURING SYSTEM */
- /* RESTART. I NEED A COMPLEX DATA STRUCTURE DESCRIBING THE REPLICAS */
- /* I WILL TRY TO CREATE FOR EACH FRAGMENT. */
- /* */
- /* I STORE A REFERENCE TO THE FOUR POSSIBLE CREATE REPLICA RECORDS */
- /* IN A COMMON STORED VARIABLE. I ALLOW A MAXIMUM OF 4 REPLICAS TO */
- /* BE RESTARTED PER FRAGMENT. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- struct CreateReplicaRecord {
- Uint32 logStartGci[MAX_LOG_EXEC];
- Uint32 logStopGci[MAX_LOG_EXEC];
- Uint16 logNodeId[MAX_LOG_EXEC];
- Uint32 createLcpId;
-
- bool hotSpareUse;
- Uint32 replicaRec;
- Uint16 dataNodeId;
- Uint16 lcpNo;
- Uint16 noLogNodes;
- };
- typedef Ptr<CreateReplicaRecord> CreateReplicaRecordPtr;
-
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THIS RECORD CONTAINS A FILE DESCRIPTION. THERE ARE TWO */
- /* FILES PER TABLE TO RAISE SECURITY LEVEL AGAINST DISK CRASHES. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- struct FileRecord {
- enum FileStatus {
- CLOSED = 0,
- CRASHED = 1,
- OPEN = 2
- };
- enum FileType {
- TABLE_FILE = 0,
- GCP_FILE = 1
- };
- enum ReqStatus {
- IDLE = 0,
- CREATING_GCP = 1,
- OPENING_GCP = 2,
- OPENING_COPY_GCI = 3,
- WRITING_COPY_GCI = 4,
- CREATING_COPY_GCI = 5,
- OPENING_TABLE = 6,
- READING_GCP = 7,
- READING_TABLE = 8,
- WRITE_INIT_GCP = 9,
- TABLE_CREATE = 10,
- TABLE_WRITE = 11,
- TABLE_CLOSE = 12,
- CLOSING_GCP = 13,
- CLOSING_TABLE_CRASH = 14,
- CLOSING_TABLE_SR = 15,
- CLOSING_GCP_CRASH = 16,
- TABLE_OPEN_FOR_DELETE = 17,
- TABLE_CLOSE_DELETE = 18
- };
- Uint32 fileName[4];
- Uint32 fileRef;
- FileStatus fileStatus;
- FileType fileType;
- Uint32 nextFile;
- ReqStatus reqStatus;
- Uint32 tabRef;
- };
- typedef Ptr<FileRecord> FileRecordPtr;
-
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THIS RECORD KEEPS THE STORAGE AND DECISIONS INFORMATION OF A FRAGMENT */
- /* AND ITS REPLICAS. IF FRAGMENT HAS MORE THAN ONE BACK UP */
- /* REPLICA THEN A LIST OF MORE NODES IS ATTACHED TO THIS RECORD. */
- /* EACH RECORD IN MORE LIST HAS INFORMATION ABOUT ONE BACKUP. THIS RECORD */
- /* ALSO HAVE THE STATUS OF THE FRAGMENT. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* */
- /* FRAGMENTSTORE RECORD ALIGNED TO BE 64 BYTES */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- struct Fragmentstore {
- Uint16 activeNodes[MAX_REPLICAS];
- Uint32 preferredPrimary;
-
- Uint32 oldStoredReplicas; /* "DEAD" STORED REPLICAS */
- Uint32 storedReplicas; /* "ALIVE" STORED REPLICAS */
- Uint32 nextFragmentChunk;
-
- Uint32 m_log_part_id;
-
- Uint8 distributionKey;
- Uint8 fragReplicas;
- Uint8 noOldStoredReplicas; /* NUMBER OF "DEAD" STORED REPLICAS */
- Uint8 noStoredReplicas; /* NUMBER OF "ALIVE" STORED REPLICAS*/
- Uint8 noLcpReplicas; ///< No of replicas remaining to be LCP:ed
- };
- typedef Ptr<Fragmentstore> FragmentstorePtr;
-
- /*########### PAGE RECORD ############*/
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THIS RECORD KEEPS INFORMATION ABOUT NODE GROUPS. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- struct NodeGroupRecord {
- Uint32 nodesInGroup[MAX_REPLICAS + 1];
- Uint32 nextReplicaNode;
- Uint32 nodeCount;
- bool activeTakeOver;
- };
- typedef Ptr<NodeGroupRecord> NodeGroupRecordPtr;
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* THIS RECORD KEEPS INFORMATION ABOUT NODES. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- /* RECORD ALIGNED TO BE 64 BYTES. */
- /*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/
- enum NodefailHandlingStep {
- NF_REMOVE_NODE_FROM_TABLE = 1,
- NF_GCP_TAKE_OVER = 2,
- NF_LCP_TAKE_OVER = 4
- };
-
- struct NodeRecord {
- NodeRecord();
-
- enum NodeStatus {
- NOT_IN_CLUSTER = 0,
- ALIVE = 1,
- STARTING = 2,
- DIED_NOW = 3,
- DYING = 4,
- DEAD = 5
- };
-
- struct FragmentCheckpointInfo {
- Uint32 tableId;
- Uint32 fragId;
- Uint32 replicaPtr;
- };
-
- enum GcpState {
- READY = 0,
- PREPARE_SENT = 1,
- PREPARE_RECEIVED = 2,
- COMMIT_SENT = 3,
- NODE_FINISHED = 4,
- SAVE_REQ_SENT = 5,
- SAVE_RECEIVED = 6,
- COPY_GCI_SENT = 7
- };
-
- GcpState gcpstate;
- Sysfile::ActiveStatus activeStatus;
-
- NodeStatus nodeStatus;
- bool useInTransactions;
- bool allowNodeStart;
- bool copyCompleted;
- bool m_inclDihLcp;
-
- FragmentCheckpointInfo startedChkpt[2];
- FragmentCheckpointInfo queuedChkpt[2];
-
- Bitmask<1> m_nodefailSteps;
- Uint32 activeTabptr;
- Uint32 nextNode;
- Uint32 nodeGroup;
-
- SignalCounter m_NF_COMPLETE_REP;
-
- Uint8 dbtcFailCompleted;
- Uint8 dblqhFailCompleted;
- Uint8 dbdihFailCompleted;
- Uint8 dbdictFailCompleted;
- Uint8 recNODE_FAILREP;
-
- Uint8 noOfQueuedChkpt;
- Uint8 noOfStartedChkpt;
-
- MasterLCPConf::State lcpStateAtTakeOver;
- Uint32 m_remove_node_from_table_lcp_id;
- };
- typedef Ptr<NodeRecord> NodeRecordPtr;
- /**********************************************************************/
- /* THIS RECORD KEEPS THE INFORMATION ABOUT A TABLE AND ITS FRAGMENTS */
- /**********************************************************************/
- struct PageRecord {
- Uint32 word[2048];
- /* 8 KBYTE PAGE*/
- Uint32 nextfreepage;
- };
- typedef Ptr<PageRecord> PageRecordPtr;
-
- /************ REPLICA RECORD *************/
- /**********************************************************************/
- /* THIS RECORD KEEPS THE INFORMATION ABOUT A REPLICA OF A FRAGMENT */
- /**********************************************************************/
- struct ReplicaRecord {
- /* -------------------------------------------------------------------- */
- /* THE GLOBAL CHECKPOINT IDENTITY WHEN THIS REPLICA WAS CREATED. */
- /* THERE IS ONE INDEX PER REPLICA. A REPLICA INDEX IS CREATED WHEN ANODE*/
- /* CRASH OCCURS. */
- /* -------------------------------------------------------------------- */
- Uint32 createGci[8];
- /* -------------------------------------------------------------------- */
- /* THE LAST GLOBAL CHECKPOINT IDENTITY WHICH HAS BEEN SAVED ON DISK. */
- /* THIS VARIABLE IS ONLY VALID FOR REPLICAS WHICH HAVE "DIED". A REPLICA*/
- /* "DIES" EITHER WHEN THE NODE CRASHES THAT KEPT THE REPLICA OR BY BEING*/
- /* STOPPED IN A CONTROLLED MANNER. */
- /* THERE IS ONE INDEX PER REPLICA. A REPLICA INDEX IS CREATED WHEN ANODE*/
- /* CRASH OCCURS. */
- /* -------------------------------------------------------------------- */
- Uint32 replicaLastGci[8];
- /* -------------------------------------------------------------------- */
- /* THE LOCAL CHECKPOINT IDENTITY OF A LOCAL CHECKPOINT. */
- /* -------------------------------------------------------------------- */
- Uint32 lcpId[MAX_LCP_STORED];
- /* -------------------------------------------------------------------- */
- /* THIS VARIABLE KEEPS TRACK OF THE MAXIMUM GLOBAL CHECKPOINT COMPLETED */
- /* FOR EACH OF THE LOCAL CHECKPOINTS IN THIS FRAGMENT REPLICA. */
- /* -------------------------------------------------------------------- */
- Uint32 maxGciCompleted[MAX_LCP_STORED];
- /* -------------------------------------------------------------------- */
- /* THIS VARIABLE KEEPS TRACK OF THE MINIMUM GLOBAL CHECKPOINT STARTEDFOR*/
- /* EACH OF THE LOCAL CHECKPOINTS IN THIS FRAGMENT REPLICA. */
- /* -------------------------------------------------------------------- */
- Uint32 maxGciStarted[MAX_LCP_STORED];
- /* -------------------------------------------------------------------- */
- /* THE GLOBAL CHECKPOINT IDENTITY WHEN THE TABLE WAS CREATED. */
- /* -------------------------------------------------------------------- */
- Uint32 initialGci;
-
- /* -------------------------------------------------------------------- */
- /* THE REFERENCE TO THE NEXT REPLICA. EITHER IT REFERS TO THE NEXT IN */
- /* THE FREE LIST OR IT REFERS TO THE NEXT IN A LIST OF REPLICAS ON A */
- /* FRAGMENT. */
- /* -------------------------------------------------------------------- */
- Uint32 nextReplica;
-
- /* -------------------------------------------------------------------- */
- /* THE NODE ID WHERE THIS REPLICA IS STORED. */
- /* -------------------------------------------------------------------- */
- Uint16 procNode;
-
- /* -------------------------------------------------------------------- */
- /* The last local checkpoint id started or queued on this replica. */
- /* -------------------------------------------------------------------- */
- Uint32 lcpIdStarted; // Started or queued
-
- /* -------------------------------------------------------------------- */
- /* THIS VARIABLE SPECIFIES WHAT THE STATUS OF THE LOCAL CHECKPOINT IS.IT*/
- /* CAN EITHER BE VALID OR INVALID. AT CREATION OF A FRAGMENT REPLICA ALL*/
- /* LCP'S ARE INVALID. ALSO IF IF INDEX >= NO_LCP THEN THELOCALCHECKPOINT*/
- /* IS ALWAYS INVALID. IF THE LCP BEFORE THE NEXT_LCP HAS LCP_ID THAT */
- /* DIFFERS FROM THE LATEST LCP_ID STARTED THEN THE NEXT_LCP IS ALSO */
- /* INVALID */
- /* -------------------------------------------------------------------- */
- Uint8 lcpStatus[MAX_LCP_STORED];
-
- /* -------------------------------------------------------------------- */
- /* THE NEXT LOCAL CHECKPOINT TO EXECUTE IN THIS FRAGMENT REPLICA. */
- /* -------------------------------------------------------------------- */
- Uint8 nextLcp;
-
- /* -------------------------------------------------------------------- */
- /* THE NUMBER OF CRASHED REPLICAS IN THIS REPLICAS SO FAR. */
- /* -------------------------------------------------------------------- */
- Uint8 noCrashedReplicas;
-
- /**
- * Is a LCP currently ongoing on fragment
- */
- Uint8 lcpOngoingFlag;
- };
- typedef Ptr<ReplicaRecord> ReplicaRecordPtr;
-
- /*************************************************************************
- * TAB_DESCRIPTOR IS A DESCRIPTOR OF THE LOCATION OF THE FRAGMENTS BELONGING
- * TO THE TABLE.THE INFORMATION ABOUT FRAGMENTS OF A TABLE ARE STORED IN
- * CHUNKS OF FRAGMENTSTORE RECORDS.
- * THIS RECORD ALSO HAS THE NECESSARY INFORMATION TO LOCATE A FRAGMENT AND
- * TO LOCATE A FRAGMENT AND TO TRANSLATE A KEY OF A TUPLE TO THE FRAGMENT IT
- * BELONGS
- */
- struct TabRecord {
- /**
- * State for copying table description into pages
- */
- enum CopyStatus {
- CS_IDLE,
- CS_SR_PHASE1_READ_PAGES,
- CS_SR_PHASE2_READ_TABLE,
- CS_SR_PHASE3_COPY_TABLE,
- CS_REMOVE_NODE,
- CS_LCP_READ_TABLE,
- CS_COPY_TAB_REQ,
- CS_COPY_NODE_STATE,
- CS_ADD_TABLE_MASTER,
- CS_ADD_TABLE_SLAVE,
- CS_INVALIDATE_NODE_LCP
- };
- /**
- * State for copying pages to disk
- */
- enum UpdateState {
- US_IDLE,
- US_LOCAL_CHECKPOINT,
- US_REMOVE_NODE,
- US_COPY_TAB_REQ,
- US_ADD_TABLE_MASTER,
- US_ADD_TABLE_SLAVE,
- US_INVALIDATE_NODE_LCP
- };
- enum TabLcpStatus {
- TLS_ACTIVE = 1,
- TLS_WRITING_TO_FILE = 2,
- TLS_COMPLETED = 3
- };
- enum TabStatus {
- TS_IDLE = 0,
- TS_ACTIVE = 1,
- TS_CREATING = 2,
- TS_DROPPING = 3
- };
- enum Method {
- LINEAR_HASH = 0,
- NOTDEFINED = 1,
- NORMAL_HASH = 2,
- USER_DEFINED = 3
- };
- enum Storage {
- ST_NOLOGGING = 0, // Table is not logged, but survives SR
- ST_NORMAL = 1, // Normal table, logged and durable
- ST_TEMPORARY = 2 // Table is lost after SR, not logged
- };
- CopyStatus tabCopyStatus;
- UpdateState tabUpdateState;
- TabLcpStatus tabLcpStatus;
- TabStatus tabStatus;
- Method method;
- Storage tabStorage;
-
- Uint32 pageRef[8];
-//-----------------------------------------------------------------------------
-// Each entry in this array contains a reference to 16 fragment records in a
-// row. Thus finding the correct record is very quick provided the fragment id.
-//-----------------------------------------------------------------------------
- Uint32 startFid[MAX_NDB_NODES];
-
- Uint32 tabFile[2];
- Uint32 connectrec;
- Uint32 hashpointer;
- Uint32 mask;
- Uint32 noOfWords;
- Uint32 schemaVersion;
- Uint32 tabRemoveNode;
- Uint32 totalfragments;
- Uint32 noOfFragChunks;
- Uint32 tabErrorCode;
- struct {
- Uint32 tabUserRef;
- Uint32 tabUserPtr;
- } m_dropTab;
-
- struct DropTable {
- Uint32 senderRef;
- Uint32 senderData;
- SignalCounter waitDropTabCount;
- } m_prepDropTab;
-
- Uint8 kvalue;
- Uint8 noOfBackups;
- Uint8 noPages;
- Uint16 tableType;
- Uint16 primaryTableId;
- };
- typedef Ptr<TabRecord> TabRecordPtr;
-
- /***************************************************************************/
- /* THIS RECORD IS USED TO KEEP TRACK OF TAKE OVER AND STARTING A NODE. */
- /* WE KEEP IT IN A RECORD TO ENABLE IT TO BE PARALLELISED IN THE FUTURE. */
- /**************************************************************************/
- struct TakeOverRecord {
- enum ToMasterStatus {
- IDLE = 0,
- TO_WAIT_START_TAKE_OVER = 1,
- TO_START_COPY = 2,
- TO_START_COPY_ONGOING = 3,
- TO_WAIT_START = 4,
- STARTING = 5,
- SELECTING_NEXT = 6,
- TO_WAIT_PREPARE_CREATE = 9,
- PREPARE_CREATE = 10,
- COPY_FRAG = 11,
- TO_WAIT_UPDATE_TO = 12,
- TO_UPDATE_TO = 13,
- COPY_ACTIVE = 14,
- TO_WAIT_COMMIT_CREATE = 15,
- LOCK_MUTEX = 23,
- COMMIT_CREATE = 16,
- TO_COPY_COMPLETED = 17,
- WAIT_LCP = 18,
- TO_END_COPY = 19,
- TO_END_COPY_ONGOING = 20,
- TO_WAIT_ENDING = 21,
- ENDING = 22,
-
- STARTING_LOCAL_FRAGMENTS = 24,
- PREPARE_COPY = 25
- };
- enum ToSlaveStatus {
- TO_SLAVE_IDLE = 0,
- TO_SLAVE_STARTED = 1,
- TO_SLAVE_CREATE_PREPARE = 2,
- TO_SLAVE_COPY_FRAG_COMPLETED = 3,
- TO_SLAVE_CREATE_COMMIT = 4,
- TO_SLAVE_COPY_COMPLETED = 5
- };
- Uint32 startGci;
- Uint32 maxPage;
- Uint32 toCopyNode;
- Uint32 toCurrentFragid;
- Uint32 toCurrentReplica;
- Uint32 toCurrentTabref;
- Uint32 toFailedNode;
- Uint32 toStartingNode;
- Uint32 nextTakeOver;
- Uint32 prevTakeOver;
- bool toNodeRestart;
- ToMasterStatus toMasterStatus;
- ToSlaveStatus toSlaveStatus;
- MutexHandle2<DIH_SWITCH_PRIMARY_MUTEX> m_switchPrimaryMutexHandle;
- };
- typedef Ptr<TakeOverRecord> TakeOverRecordPtr;
-
-public:
- Dbdih(Block_context& ctx);
- virtual ~Dbdih();
-
- struct RWFragment {
- Uint32 pageIndex;
- Uint32 wordIndex;
- Uint32 fragId;
- TabRecordPtr rwfTabPtr;
- PageRecordPtr rwfPageptr;
- };
- struct CopyTableNode {
- Uint32 pageIndex;
- Uint32 wordIndex;
- Uint32 noOfWords;
- TabRecordPtr ctnTabPtr;
- PageRecordPtr ctnPageptr;
- };
-
-private:
- BLOCK_DEFINES(Dbdih);
-
- void execDUMP_STATE_ORD(Signal *);
- void execNDB_TAMPER(Signal *);
- void execDEBUG_SIG(Signal *);
- void execEMPTY_LCP_CONF(Signal *);
- void execMASTER_GCPREF(Signal *);
- void execMASTER_GCPREQ(Signal *);
- void execMASTER_GCPCONF(Signal *);
- void execMASTER_LCPREF(Signal *);
- void execMASTER_LCPREQ(Signal *);
- void execMASTER_LCPCONF(Signal *);
- void execNF_COMPLETEREP(Signal *);
- void execSTART_PERMREQ(Signal *);
- void execSTART_PERMCONF(Signal *);
- void execSTART_PERMREF(Signal *);
- void execINCL_NODEREQ(Signal *);
- void execINCL_NODECONF(Signal *);
- void execEND_TOREQ(Signal *);
- void execEND_TOCONF(Signal *);
- void execSTART_TOREQ(Signal *);
- void execSTART_TOCONF(Signal *);
- void execSTART_MEREQ(Signal *);
- void execSTART_MECONF(Signal *);
- void execSTART_MEREF(Signal *);
- void execSTART_COPYREQ(Signal *);
- void execSTART_COPYCONF(Signal *);
- void execSTART_COPYREF(Signal *);
- void execCREATE_FRAGREQ(Signal *);
- void execCREATE_FRAGCONF(Signal *);
- void execDIVERIFYREQ(Signal *);
- void execGCP_SAVECONF(Signal *);
- void execGCP_PREPARECONF(Signal *);
- void execGCP_PREPARE(Signal *);
- void execGCP_NODEFINISH(Signal *);
- void execGCP_COMMIT(Signal *);
- void execDIHNDBTAMPER(Signal *);
- void execCONTINUEB(Signal *);
- void execCOPY_GCIREQ(Signal *);
- void execCOPY_GCICONF(Signal *);
- void execCOPY_TABREQ(Signal *);
- void execCOPY_TABCONF(Signal *);
- void execTCGETOPSIZECONF(Signal *);
- void execTC_CLOPSIZECONF(Signal *);
-
- int handle_invalid_lcp_no(const class LcpFragRep*, ReplicaRecordPtr);
- void execLCP_FRAG_REP(Signal *);
- void execLCP_COMPLETE_REP(Signal *);
- void execSTART_LCP_REQ(Signal *);
- void execSTART_LCP_CONF(Signal *);
- MutexHandle2<DIH_START_LCP_MUTEX> c_startLcpMutexHandle;
- void startLcpMutex_locked(Signal* signal, Uint32, Uint32);
- void startLcpMutex_unlocked(Signal* signal, Uint32, Uint32);
-
- MutexHandle2<DIH_SWITCH_PRIMARY_MUTEX> c_switchPrimaryMutexHandle;
- void switchPrimaryMutex_locked(Signal* signal, Uint32, Uint32);
- void switchPrimaryMutex_unlocked(Signal* signal, Uint32, Uint32);
- void switch_primary_stop_node(Signal* signal, Uint32, Uint32);
-
- void execBLOCK_COMMIT_ORD(Signal *);
- void execUNBLOCK_COMMIT_ORD(Signal *);
-
- void execDIH_SWITCH_REPLICA_REQ(Signal *);
- void execDIH_SWITCH_REPLICA_REF(Signal *);
- void execDIH_SWITCH_REPLICA_CONF(Signal *);
-
- void execSTOP_PERM_REQ(Signal *);
- void execSTOP_PERM_REF(Signal *);
- void execSTOP_PERM_CONF(Signal *);
-
- void execSTOP_ME_REQ(Signal *);
- void execSTOP_ME_REF(Signal *);
- void execSTOP_ME_CONF(Signal *);
-
- void execREAD_CONFIG_REQ(Signal *);
- void execUNBLO_DICTCONF(Signal *);
- void execCOPY_ACTIVECONF(Signal *);
- void execTAB_COMMITREQ(Signal *);
- void execNODE_FAILREP(Signal *);
- void execCOPY_FRAGCONF(Signal *);
- void execCOPY_FRAGREF(Signal *);
- void execPREPARE_COPY_FRAG_REF(Signal*);
- void execPREPARE_COPY_FRAG_CONF(Signal*);
- void execDIADDTABREQ(Signal *);
- void execDIGETNODESREQ(Signal *);
- void execDIRELEASEREQ(Signal *);
- void execDISEIZEREQ(Signal *);
- void execSTTOR(Signal *);
- void execDI_FCOUNTREQ(Signal *);
- void execDIGETPRIMREQ(Signal *);
- void execGCP_SAVEREF(Signal *);
- void execGCP_TCFINISHED(Signal *);
- void execREAD_NODESCONF(Signal *);
- void execNDB_STTOR(Signal *);
- void execDICTSTARTCONF(Signal *);
- void execNDB_STARTREQ(Signal *);
- void execGETGCIREQ(Signal *);
- void execDIH_RESTARTREQ(Signal *);
- void execSTART_RECCONF(Signal *);
- void execSTART_FRAGREF(Signal *);
- void execSTART_FRAGCONF(Signal *);
- void execADD_FRAGCONF(Signal *);
- void execADD_FRAGREF(Signal *);
- void execFSOPENCONF(Signal *);
- void execFSOPENREF(Signal *);
- void execFSCLOSECONF(Signal *);
- void execFSCLOSEREF(Signal *);
- void execFSREADCONF(Signal *);
- void execFSREADREF(Signal *);
- void execFSWRITECONF(Signal *);
- void execFSWRITEREF(Signal *);
- void execCHECKNODEGROUPSREQ(Signal *);
- void execSTART_INFOREQ(Signal*);
- void execSTART_INFOREF(Signal*);
- void execSTART_INFOCONF(Signal*);
- void execWAIT_GCP_REQ(Signal* signal);
- void execWAIT_GCP_REF(Signal* signal);
- void execWAIT_GCP_CONF(Signal* signal);
- void execUPDATE_TOREQ(Signal* signal);
- void execUPDATE_TOCONF(Signal* signal);
-
- void execPREP_DROP_TAB_REQ(Signal* signal);
- void execWAIT_DROP_TAB_REF(Signal* signal);
- void execWAIT_DROP_TAB_CONF(Signal* signal);
- void execDROP_TAB_REQ(Signal* signal);
-
- void execALTER_TAB_REQ(Signal* signal);
-
- void execCREATE_FRAGMENTATION_REQ(Signal*);
-
- void waitDropTabWritingToFile(Signal *, TabRecordPtr tabPtr);
- void checkPrepDropTabComplete(Signal *, TabRecordPtr tabPtr);
- void checkWaitDropTabFailedLqh(Signal *, Uint32 nodeId, Uint32 tableId);
-
- void execDICT_LOCK_CONF(Signal* signal);
- void execDICT_LOCK_REF(Signal* signal);
-
- // Statement blocks
-//------------------------------------
-// Methods that send signals
-//------------------------------------
- void nullRoutine(Signal *, Uint32 nodeId);
- void sendCOPY_GCIREQ(Signal *, Uint32 nodeId);
- void sendDIH_SWITCH_REPLICA_REQ(Signal *, Uint32 nodeId);
- void sendEMPTY_LCP_REQ(Signal *, Uint32 nodeId);
- void sendEND_TOREQ(Signal *, Uint32 nodeId);
- void sendGCP_COMMIT(Signal *, Uint32 nodeId);
- void sendGCP_PREPARE(Signal *, Uint32 nodeId);
- void sendGCP_SAVEREQ(Signal *, Uint32 nodeId);
- void sendINCL_NODEREQ(Signal *, Uint32 nodeId);
- void sendMASTER_GCPREQ(Signal *, Uint32 nodeId);
- void sendMASTER_LCPREQ(Signal *, Uint32 nodeId);
- void sendMASTER_LCPCONF(Signal * signal);
- void sendSTART_RECREQ(Signal *, Uint32 nodeId);
- void sendSTART_INFOREQ(Signal *, Uint32 nodeId);
- void sendSTART_TOREQ(Signal *, Uint32 nodeId);
- void sendSTOP_ME_REQ(Signal *, Uint32 nodeId);
- void sendTC_CLOPSIZEREQ(Signal *, Uint32 nodeId);
- void sendTCGETOPSIZEREQ(Signal *, Uint32 nodeId);
- void sendUPDATE_TOREQ(Signal *, Uint32 nodeId);
- void sendSTART_LCP_REQ(Signal *, Uint32 nodeId);
-
- void sendLCP_FRAG_ORD(Signal*, NodeRecord::FragmentCheckpointInfo info);
- void sendLastLCP_FRAG_ORD(Signal *);
-
- void sendCopyTable(Signal *, CopyTableNode* ctn,
- BlockReference ref, Uint32 reqinfo);
- void sendCreateFragReq(Signal *,
- Uint32 startGci,
- Uint32 storedType,
- Uint32 takeOverPtr);
- void sendDihfragreq(Signal *,
- TabRecordPtr regTabPtr,
- Uint32 fragId);
- void sendStartFragreq(Signal *,
- TabRecordPtr regTabPtr,
- Uint32 fragId);
- void sendHOT_SPAREREP(Signal *);
- void sendAddFragreq(Signal *,
- TabRecordPtr regTabPtr,
- Uint32 fragId,
- Uint32 lcpNo,
- Uint32 param);
-
- void sendAddFragreq(Signal*, ConnectRecordPtr, TabRecordPtr, Uint32 fragId);
- void addTable_closeConf(Signal* signal, Uint32 tabPtrI);
- void resetReplicaSr(TabRecordPtr tabPtr);
- void resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci);
-
-//------------------------------------
-// Methods for LCP functionality
-//------------------------------------
- void checkKeepGci(TabRecordPtr, Uint32, Fragmentstore*, Uint32);
- void checkLcpStart(Signal *, Uint32 lineNo);
- void checkStartMoreLcp(Signal *, Uint32 nodeId);
- bool reportLcpCompletion(const class LcpFragRep *);
- void sendLCP_COMPLETE_REP(Signal *);
-
-//------------------------------------
-// Methods for Delete Table Files
-//------------------------------------
- void startDeleteFile(Signal* signal, TabRecordPtr tabPtr);
- void openTableFileForDelete(Signal* signal, Uint32 fileIndex);
- void tableOpenLab(Signal* signal, FileRecordPtr regFilePtr);
- void tableDeleteLab(Signal* signal, FileRecordPtr regFilePtr);
-
-//------------------------------------
-// File Record specific methods
-//------------------------------------
- void closeFile(Signal *, FileRecordPtr regFilePtr);
- 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);
-
-//------------------------------------
-// Methods called when completing file
-// operation.
-//------------------------------------
- void creatingGcpLab(Signal *, FileRecordPtr regFilePtr);
- void openingGcpLab(Signal *, FileRecordPtr regFilePtr);
- void openingTableLab(Signal *, FileRecordPtr regFilePtr);
- void tableCreateLab(Signal *, FileRecordPtr regFilePtr);
- void creatingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
- void openingCopyGciErrorLab(Signal *, FileRecordPtr regFilePtr);
- void creatingCopyGciErrorLab(Signal *, FileRecordPtr regFilePtr);
- void openingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
- void openingTableErrorLab(Signal *, FileRecordPtr regFilePtr);
- void tableCreateErrorLab(Signal *, FileRecordPtr regFilePtr);
- void closingGcpLab(Signal *, FileRecordPtr regFilePtr);
- void closingGcpCrashLab(Signal *, FileRecordPtr regFilePtr);
- void closingTableCrashLab(Signal *, FileRecordPtr regFilePtr);
- void closingTableSrLab(Signal *, FileRecordPtr regFilePtr);
- void tableCloseLab(Signal *, FileRecordPtr regFilePtr);
- void tableCloseErrorLab(FileRecordPtr regFilePtr);
- void readingGcpLab(Signal *, FileRecordPtr regFilePtr);
- void readingTableLab(Signal *, FileRecordPtr regFilePtr);
- void readingGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
- void readingTableErrorLab(Signal *, FileRecordPtr regFilePtr);
- void writingCopyGciLab(Signal *, FileRecordPtr regFilePtr);
- void writeInitGcpLab(Signal *, FileRecordPtr regFilePtr);
- void tableWriteLab(Signal *, FileRecordPtr regFilePtr);
- void writeInitGcpErrorLab(Signal *, FileRecordPtr regFilePtr);
-
-
- void calculateHotSpare();
- void checkEscalation();
- void clearRestartInfoBits(Signal *);
- void invalidateLcpInfoAfterSr();
-
- bool isMaster();
- bool isActiveMaster();
-
- void emptyverificbuffer(Signal *, bool aContintueB);
- Uint32 findHotSpare();
- void handleGcpStateInMaster(Signal *, NodeRecordPtr failedNodeptr);
- void initRestartInfo();
- void initRestorableGciFiles();
- void makeNodeGroups(Uint32 nodeArray[]);
- void makePrnList(class ReadNodesConf * readNodes, Uint32 nodeArray[]);
- void nodeResetStart();
- void releaseTabPages(Uint32 tableId);
- void replication(Uint32 noOfReplicas,
- NodeGroupRecordPtr NGPtr,
- FragmentstorePtr regFragptr);
- void selectMasterCandidateAndSend(Signal *);
- void setInitialActiveStatus();
- void setLcpActiveStatusEnd();
- void setLcpActiveStatusStart(Signal *);
- void setNodeActiveStatus();
- void setNodeGroups();
- void setNodeInfo(Signal *);
- void setNodeLcpActiveStatus();
- void setNodeRestartInfoBits();
- void startGcp(Signal *);
-
- void readFragment(RWFragment* rf, FragmentstorePtr regFragptr);
- Uint32 readPageWord(RWFragment* rf);
- void readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr);
- void readReplicas(RWFragment* rf, FragmentstorePtr regFragptr);
- void readRestorableGci(Signal *, FileRecordPtr regFilePtr);
- void readTabfile(Signal *, TabRecord* tab, FileRecordPtr regFilePtr);
- void writeFragment(RWFragment* wf, FragmentstorePtr regFragptr);
- void writePageWord(RWFragment* wf, Uint32 dataWord);
- void writeReplicas(RWFragment* wf, Uint32 replicaStartIndex);
- void writeRestorableGci(Signal *, FileRecordPtr regFilePtr);
- void writeTabfile(Signal *, TabRecord* tab, FileRecordPtr regFilePtr);
- void copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr);
-
- void gcpcommitreqLab(Signal *);
- void gcpsavereqLab(Signal *);
- void copyGciLab(Signal *, CopyGCIReq::CopyReason reason);
- void storeNewLcpIdLab(Signal *);
- void startLcpRoundLoopLab(Signal *, Uint32 startTableId, Uint32 startFragId);
-
- void nodeFailCompletedCheckLab(Signal*, NodeRecordPtr failedNodePtr);
-
- /**
- *
- */
- void setLocalNodefailHandling(Signal*, Uint32 failedNodeId,
- NodefailHandlingStep step);
- void checkLocalNodefailComplete(Signal*, Uint32 failedNodeId,
- NodefailHandlingStep step);
-
- void ndbsttorry10Lab(Signal *, Uint32 _line);
- void createMutexes(Signal* signal, Uint32 no);
- void createMutex_done(Signal* signal, Uint32 no, Uint32 retVal);
- void crashSystemAtGcpStop(Signal *, bool);
- void sendFirstDictfragsreq(Signal *, TabRecordPtr regTabPtr);
- void addtabrefuseLab(Signal *, ConnectRecordPtr regConnectPtr, Uint32 errorCode);
- void GCP_SAVEhandling(Signal *, Uint32 nodeId);
- void packTableIntoPagesLab(Signal *, Uint32 tableId);
- void readPagesIntoTableLab(Signal *, Uint32 tableId);
- void readPagesIntoFragLab(Signal *, RWFragment* rf);
- void readTabDescriptionLab(Signal *, Uint32 tableId);
- void copyTableLab(Signal *, Uint32 tableId);
- void breakCopyTableLab(Signal *,
- TabRecordPtr regTabPtr,
- Uint32 nodeId);
- void checkAddfragCompletedLab(Signal *,
- TabRecordPtr regTabPtr,
- Uint32 fragId);
- void completeRestartLab(Signal *);
- void readTableFromPagesLab(Signal *, TabRecordPtr regTabPtr);
- void srPhase2ReadTableLab(Signal *, TabRecordPtr regTabPtr);
- void checkTcCounterLab(Signal *);
- void calculateKeepGciLab(Signal *, Uint32 tableId, Uint32 fragId);
- void tableUpdateLab(Signal *, TabRecordPtr regTabPtr);
- void checkLcpCompletedLab(Signal *);
- void initLcpLab(Signal *, Uint32 masterRef, Uint32 tableId);
- void startGcpLab(Signal *, Uint32 aWaitTime);
- void checkGcpStopLab(Signal *);
- void MASTER_GCPhandling(Signal *, Uint32 failedNodeId);
- void MASTER_LCPhandling(Signal *, Uint32 failedNodeId);
- void rnfTableNotReadyLab(Signal *, TabRecordPtr regTabPtr, Uint32 removeNodeId);
- void startLcpTakeOverLab(Signal *, Uint32 failedNodeId);
-
- void startLcpMasterTakeOver(Signal *, Uint32 failedNodeId);
- void startGcpMasterTakeOver(Signal *, Uint32 failedNodeId);
- void checkGcpOutstanding(Signal*, Uint32 failedNodeId);
-
- void checkEmptyLcpComplete(Signal *);
- void lcpBlockedLab(Signal *);
- void breakCheckTabCompletedLab(Signal *, TabRecordPtr regTabptr);
- void readGciFileLab(Signal *);
- void openingCopyGciSkipInitLab(Signal *, FileRecordPtr regFilePtr);
- void startLcpRoundLab(Signal *);
- void gcpBlockedLab(Signal *);
- void initialStartCompletedLab(Signal *);
- void allNodesLcpCompletedLab(Signal *);
- void nodeRestartPh2Lab(Signal *);
- void nodeRestartPh2Lab2(Signal *);
- void initGciFilesLab(Signal *);
- void dictStartConfLab(Signal *);
- void nodeDictStartConfLab(Signal *);
- void ndbStartReqLab(Signal *, BlockReference ref);
- void nodeRestartStartRecConfLab(Signal *);
- void dihCopyCompletedLab(Signal *);
- void release_connect(ConnectRecordPtr ptr);
- void copyTableNode(Signal *,
- CopyTableNode* ctn,
- NodeRecordPtr regNodePtr);
- void startFragment(Signal *, Uint32 tableId, Uint32 fragId);
- bool checkLcpAllTablesDoneInLqh();
-
- void lcpStateAtNodeFailureLab(Signal *, Uint32 nodeId);
- void copyNodeLab(Signal *, Uint32 tableId);
- void copyGciReqLab(Signal *);
- void allLab(Signal *,
- ConnectRecordPtr regConnectPtr,
- TabRecordPtr regTabPtr);
- void tableCopyNodeLab(Signal *, TabRecordPtr regTabPtr);
-
- void removeNodeFromTables(Signal *, Uint32 tableId, Uint32 nodeId);
- void removeNodeFromTable(Signal *, Uint32 tableId, TabRecordPtr tabPtr);
- void removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId);
-
- void packFragIntoPagesLab(Signal *, RWFragment* wf);
- void startNextChkpt(Signal *);
- void failedNodeLcpHandling(Signal*, NodeRecordPtr failedNodePtr);
- void failedNodeSynchHandling(Signal *, NodeRecordPtr failedNodePtr);
- void checkCopyTab(NodeRecordPtr failedNodePtr);
-
- void initCommonData();
- void initialiseRecordsLab(Signal *, Uint32 stepNo, Uint32, Uint32);
-
- void findReplica(ReplicaRecordPtr& regReplicaPtr,
- Fragmentstore* fragPtrP,
- Uint32 nodeId,
- bool oldStoredReplicas = false);
-//------------------------------------
-// Node failure handling methods
-//------------------------------------
- void startRemoveFailedNode(Signal *, NodeRecordPtr failedNodePtr);
- void handleGcpTakeOver(Signal *, NodeRecordPtr failedNodePtr);
- void handleLcpTakeOver(Signal *, NodeRecordPtr failedNodePtr);
- void handleNewMaster(Signal *, NodeRecordPtr failedNodePtr);
- void checkTakeOverInMasterAllNodeFailure(Signal*, NodeRecordPtr failedNode);
- void checkTakeOverInMasterCopyNodeFailure(Signal*, Uint32 failedNodeId);
- void checkTakeOverInMasterStartNodeFailure(Signal*, Uint32 takeOverPtr);
- void checkTakeOverInNonMasterStartNodeFailure(Signal*, Uint32 takeOverPtr);
- void handleLcpMasterTakeOver(Signal *, Uint32 nodeId);
-
-//------------------------------------
-// Replica record specific methods
-//------------------------------------
- Uint32 findLogInterval(ConstPtr<ReplicaRecord> regReplicaPtr,
- Uint32 startGci);
- void findMinGci(ReplicaRecordPtr fmgReplicaPtr,
- Uint32& keeGci,
- Uint32& oldestRestorableGci);
- bool findStartGci(ConstPtr<ReplicaRecord> fstReplicaPtr,
- Uint32 tfstStopGci,
- Uint32& tfstStartGci,
- Uint32& tfstLcp);
- void newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr);
- void packCrashedReplicas(ReplicaRecordPtr pcrReplicaPtr);
- void releaseReplicas(Uint32 replicaPtr);
- void removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr);
- void removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr);
- void seizeReplicaRec(ReplicaRecordPtr& replicaPtr);
-
-//------------------------------------
-// Methods operating on a fragment and
-// its connected replicas and nodes.
-//------------------------------------
- void allocStoredReplica(FragmentstorePtr regFragptr,
- ReplicaRecordPtr& newReplicaPtr,
- Uint32 nodeId);
- Uint32 extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[]);
- bool findBestLogNode(CreateReplicaRecord* createReplica,
- FragmentstorePtr regFragptr,
- Uint32 startGci,
- Uint32 stopGci,
- Uint32 logNode,
- Uint32& fblStopGci);
- bool findLogNodes(CreateReplicaRecord* createReplica,
- FragmentstorePtr regFragptr,
- Uint32 startGci,
- Uint32 stopGci);
- void findToReplica(TakeOverRecord* regTakeOver,
- Uint32 replicaType,
- FragmentstorePtr regFragptr,
- ReplicaRecordPtr& ftrReplicaPtr);
- void initFragstore(FragmentstorePtr regFragptr);
- void insertBackup(FragmentstorePtr regFragptr, Uint32 nodeId);
- void insertfraginfo(FragmentstorePtr regFragptr,
- Uint32 noOfBackups,
- Uint32* nodeArray);
- void linkOldStoredReplica(FragmentstorePtr regFragptr,
- ReplicaRecordPtr replicaPtr);
- void linkStoredReplica(FragmentstorePtr regFragptr,
- ReplicaRecordPtr replicaPtr);
- void prepareReplicas(FragmentstorePtr regFragptr);
- void removeNodeFromStored(Uint32 nodeId,
- FragmentstorePtr regFragptr,
- ReplicaRecordPtr replicaPtr,
- bool temporary);
- void removeOldStoredReplica(FragmentstorePtr regFragptr,
- ReplicaRecordPtr replicaPtr);
- void removeStoredReplica(FragmentstorePtr regFragptr,
- ReplicaRecordPtr replicaPtr);
- void searchStoredReplicas(FragmentstorePtr regFragptr);
- bool setup_create_replica(FragmentstorePtr, CreateReplicaRecord*,
- ConstPtr<ReplicaRecord>);
- void updateNodeInfo(FragmentstorePtr regFragptr);
-
-//------------------------------------
-// Fragment allocation, deallocation and
-// find methods
-//------------------------------------
- void allocFragments(Uint32 noOfFragments, TabRecordPtr regTabPtr);
- void releaseFragments(TabRecordPtr regTabPtr);
- void getFragstore(TabRecord *, Uint32 fragNo, FragmentstorePtr & ptr);
- void initialiseFragstore();
-
-//------------------------------------
-// Page Record specific methods
-//------------------------------------
- void allocpage(PageRecordPtr& regPagePtr);
- void releasePage(Uint32 pageIndex);
-
-//------------------------------------
-// Table Record specific methods
-//------------------------------------
- void initTable(TabRecordPtr regTabPtr);
- void initTableFile(TabRecordPtr regTabPtr);
- void releaseTable(TabRecordPtr tabPtr);
- Uint32 findTakeOver(Uint32 failedNodeId);
- void handleTakeOverMaster(Signal *, Uint32 takeOverPtr);
- void handleTakeOverNewMaster(Signal *, Uint32 takeOverPtr);
-
-//------------------------------------
-// TakeOver Record specific methods
-//------------------------------------
- void initTakeOver(TakeOverRecordPtr regTakeOverptr);
- void seizeTakeOver(TakeOverRecordPtr& regTakeOverptr);
- void allocateTakeOver(TakeOverRecordPtr& regTakeOverptr);
- void releaseTakeOver(Uint32 takeOverPtr);
- bool anyActiveTakeOver();
- void checkToCopy();
- void checkToCopyCompleted(Signal *);
- bool checkToInterrupted(TakeOverRecordPtr& regTakeOverptr);
- Uint32 getStartNode(Uint32 takeOverPtr);
-
-//------------------------------------
-// Methods for take over functionality
-//------------------------------------
- void changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver);
- void endTakeOver(Uint32 takeOverPtr);
- void initStartTakeOver(const class StartToReq *,
- TakeOverRecordPtr regTakeOverPtr);
-
- void nodeRestartTakeOver(Signal *, Uint32 startNodeId);
- void systemRestartTakeOverLab(Signal *);
- void startTakeOver(Signal *,
- Uint32 takeOverPtr,
- Uint32 startNode,
- Uint32 toNode);
- void sendStartTo(Signal *, Uint32 takeOverPtr);
- void startNextCopyFragment(Signal *, Uint32 takeOverPtr);
- void toCopyFragLab(Signal *, Uint32 takeOverPtr);
- void toStartCopyFrag(Signal *, TakeOverRecordPtr);
- void startHsAddFragConfLab(Signal *);
- void prepareSendCreateFragReq(Signal *, Uint32 takeOverPtr);
- void sendUpdateTo(Signal *, Uint32 takeOverPtr, Uint32 updateState);
- void toCopyCompletedLab(Signal *, TakeOverRecordPtr regTakeOverptr);
- void takeOverCompleted(Uint32 aNodeId);
- void sendEndTo(Signal *, Uint32 takeOverPtr);
-
-//------------------------------------
-// Node Record specific methods
-//------------------------------------
- void checkStartTakeOver(Signal *);
- void insertAlive(NodeRecordPtr newNodePtr);
- void insertDeadNode(NodeRecordPtr removeNodePtr);
- void removeAlive(NodeRecordPtr removeNodePtr);
- void removeDeadNode(NodeRecordPtr removeNodePtr);
-
- NodeRecord::NodeStatus getNodeStatus(Uint32 nodeId);
- void setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus);
- Sysfile::ActiveStatus getNodeActiveStatus(Uint32 nodeId);
- void setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus);
- void setNodeLcpActiveStatus(Uint32 nodeId, bool newState);
- bool getNodeLcpActiveStatus(Uint32 nodeId);
- bool getAllowNodeStart(Uint32 nodeId);
- void setAllowNodeStart(Uint32 nodeId, bool newState);
- bool getNodeCopyCompleted(Uint32 nodeId);
- void setNodeCopyCompleted(Uint32 nodeId, bool newState);
- bool checkNodeAlive(Uint32 nodeId);
-
- void nr_start_fragments(Signal*, TakeOverRecordPtr);
- void nr_start_fragment(Signal*, TakeOverRecordPtr, ReplicaRecordPtr);
- void nr_run_redo(Signal*, TakeOverRecordPtr);
-
- // Initialisation
- void initData();
- void initRecords();
-
- // Variables to support record structures and their free lists
-
- ApiConnectRecord *apiConnectRecord;
- Uint32 capiConnectFileSize;
-
- ConnectRecord *connectRecord;
- Uint32 cfirstconnect;
- Uint32 cconnectFileSize;
-
- CreateReplicaRecord *createReplicaRecord;
- Uint32 cnoOfCreateReplicas;
-
- FileRecord *fileRecord;
- Uint32 cfirstfreeFile;
- Uint32 cfileFileSize;
-
- Fragmentstore *fragmentstore;
- Uint32 cfirstfragstore;
- Uint32 cfragstoreFileSize;
-
- Uint32 c_nextNodeGroup;
- NodeGroupRecord *nodeGroupRecord;
- Uint32 c_nextLogPart;
-
- NodeRecord *nodeRecord;
-
- PageRecord *pageRecord;
- Uint32 cfirstfreepage;
- Uint32 cpageFileSize;
-
- ReplicaRecord *replicaRecord;
- Uint32 cfirstfreeReplica;
- Uint32 cnoFreeReplicaRec;
- Uint32 creplicaFileSize;
-
- TabRecord *tabRecord;
- Uint32 ctabFileSize;
-
- TakeOverRecord *takeOverRecord;
- Uint32 cfirstfreeTakeOver;
-
- /*
- 2.4 C O M M O N S T O R E D V A R I A B L E S
- ----------------------------------------------------
- */
- Uint32 cfirstVerifyQueue;
- Uint32 clastVerifyQueue;
- Uint32 cverifyQueueCounter;
-
- /*------------------------------------------------------------------------*/
- /* THIS VARIABLE KEEPS THE REFERENCES TO FILE RECORDS THAT DESCRIBE */
- /* THE TWO FILES THAT ARE USED TO STORE THE VARIABLE CRESTART_INFO */
- /* ON DISK. */
- /*------------------------------------------------------------------------*/
- Uint32 crestartInfoFile[2];
- /*------------------------------------------------------------------------*/
- /* THIS VARIABLE KEEPS TRACK OF THE STATUS OF A GLOBAL CHECKPOINT */
- /* PARTICIPANT. THIS IS NEEDED TO HANDLE A NODE FAILURE. WHEN A NODE*/
- /* FAILURE OCCURS IT IS EASY THAT THE PROTOCOL STOPS IF NO ACTION IS*/
- /* TAKEN TO PREVENT THIS. THIS VARIABLE ENSURES SUCH ACTION CAN BE */
- /* TAKEN. */
- /*------------------------------------------------------------------------*/
- enum GcpParticipantState {
- GCP_PARTICIPANT_READY = 0,
- GCP_PARTICIPANT_PREPARE_RECEIVED = 1,
- GCP_PARTICIPANT_COMMIT_RECEIVED = 2,
- GCP_PARTICIPANT_TC_FINISHED = 3,
- GCP_PARTICIPANT_COPY_GCI_RECEIVED = 4
- };
- GcpParticipantState cgcpParticipantState;
- /*------------------------------------------------------------------------*/
- /* THESE VARIABLES ARE USED TO CONTROL THAT GCP PROCESSING DO NOT */
- /*STOP FOR SOME REASON. */
- /*------------------------------------------------------------------------*/
- enum GcpStatus {
- GCP_READY = 0,
- GCP_PREPARE_SENT = 1,
- GCP_COMMIT_SENT = 2,
- GCP_NODE_FINISHED = 3,
- GCP_SAVE_LQH_FINISHED = 4
- };
- GcpStatus cgcpStatus;
- Uint32 cgcpStartCounter;
- Uint32 coldGcpStatus;
- Uint32 coldGcpId;
- /*------------------------------------------------------------------------*/
- /* THIS VARIABLE KEEPS TRACK OF THE STATE OF THIS NODE AS MASTER. */
- /*------------------------------------------------------------------------*/
- enum MasterState {
- MASTER_IDLE = 0,
- MASTER_ACTIVE = 1,
- MASTER_TAKE_OVER_GCP = 2
- };
- MasterState cmasterState;
- Uint16 cmasterTakeOverNode;
- /* NODE IS NOT MASTER */
- /* NODE IS ACTIVE AS MASTER */
- /* NODE IS TAKING OVER AS MASTER */
-
- struct CopyGCIMaster {
- CopyGCIMaster(){ m_copyReason = m_waiting = CopyGCIReq::IDLE;}
- /*------------------------------------------------------------------------*/
- /* THIS STATE VARIABLE IS USED TO INDICATE IF COPYING OF RESTART */
- /* INFO WAS STARTED BY A LOCAL CHECKPOINT OR AS PART OF A SYSTEM */
- /* RESTART. */
- /*------------------------------------------------------------------------*/
- CopyGCIReq::CopyReason m_copyReason;
-
- /*------------------------------------------------------------------------*/
- /* COPYING RESTART INFO CAN BE STARTED BY LOCAL CHECKPOINTS AND BY */
- /* GLOBAL CHECKPOINTS. WE CAN HOWEVER ONLY HANDLE ONE SUCH COPY AT */
- /* THE TIME. THUS WE HAVE TO KEEP WAIT INFORMATION IN THIS VARIABLE.*/
- /*------------------------------------------------------------------------*/
- CopyGCIReq::CopyReason m_waiting;
- } c_copyGCIMaster;
-
- struct CopyGCISlave {
- CopyGCISlave(){ m_copyReason = CopyGCIReq::IDLE; m_expectedNextWord = 0;}
- /*------------------------------------------------------------------------*/
- /* THIS STATE VARIABLE IS USED TO INDICATE IF COPYING OF RESTART */
- /* INFO WAS STARTED BY A LOCAL CHECKPOINT OR AS PART OF A SYSTEM */
- /* RESTART. THIS VARIABLE IS USED BY THE NODE THAT RECEIVES */
- /* COPY_GCI_REQ. */
- /*------------------------------------------------------------------------*/
- Uint32 m_senderData;
- BlockReference m_senderRef;
- CopyGCIReq::CopyReason m_copyReason;
-
- Uint32 m_expectedNextWord;
- } c_copyGCISlave;
-
- /*------------------------------------------------------------------------*/
- /* THIS VARIABLE IS USED TO KEEP TRACK OF THE STATE OF LOCAL */
- /* CHECKPOINTS. */
- /*------------------------------------------------------------------------*/
-public:
- enum LcpStatus {
- LCP_STATUS_IDLE = 0,
- LCP_TCGET = 1, // Only master
- LCP_STATUS_ACTIVE = 2,
- LCP_CALCULATE_KEEP_GCI = 4, // Only master
- LCP_COPY_GCI = 5,
- LCP_INIT_TABLES = 6,
- LCP_TC_CLOPSIZE = 7, // Only master
- LCP_START_LCP_ROUND = 8,
- LCP_TAB_COMPLETED = 9,
- LCP_TAB_SAVED = 10
- };
-private:
-
- struct LcpState {
- LcpState() {}
- LcpStatus lcpStatus;
- Uint32 lcpStatusUpdatedPlace;
-
- struct Save {
- LcpStatus m_status;
- Uint32 m_place;
- } m_saveState[10];
-
- void setLcpStatus(LcpStatus status, Uint32 line){
- for (Uint32 i = 9; i > 0; i--)
- m_saveState[i] = m_saveState[i-1];
- m_saveState[0].m_status = lcpStatus;
- m_saveState[0].m_place = lcpStatusUpdatedPlace;
-
- lcpStatus = status;
- lcpStatusUpdatedPlace = line;
- }
-
- Uint32 lcpStart;
- Uint32 lcpStopGcp;
- Uint32 keepGci; /* USED TO CALCULATE THE GCI TO KEEP AFTER A LCP */
- Uint32 oldestRestorableGci;
-
- struct CurrentFragment {
- Uint32 tableId;
- Uint32 fragmentId;
- } currentFragment;
-
- Uint32 noOfLcpFragRepOutstanding;
-
- /*------------------------------------------------------------------------*/
- /* USED TO ENSURE THAT LCP'S ARE EXECUTED WITH CERTAIN TIMEINTERVALS*/
- /* EVEN WHEN SYSTEM IS NOT DOING ANYTHING. */
- /*------------------------------------------------------------------------*/
- Uint32 ctimer;
- Uint32 ctcCounter;
- Uint32 clcpDelay; /* MAX. 2^(CLCP_DELAY - 2) SEC BETWEEN LCP'S */
-
- /*------------------------------------------------------------------------*/
- /* THIS STATE IS USED TO TELL IF THE FIRST LCP AFTER START/RESTART */
- /* HAS BEEN RUN. AFTER A NODE RESTART THE NODE DOES NOT ENTER */
- /* STARTED STATE BEFORE THIS IS DONE. */
- /*------------------------------------------------------------------------*/
- bool immediateLcpStart;
- bool m_LCP_COMPLETE_REP_From_Master_Received;
- SignalCounter m_LCP_COMPLETE_REP_Counter_DIH;
- SignalCounter m_LCP_COMPLETE_REP_Counter_LQH;
- SignalCounter m_LAST_LCP_FRAG_ORD;
- NdbNodeBitmask m_participatingLQH;
- NdbNodeBitmask m_participatingDIH;
-
- Uint32 m_masterLcpDihRef;
- bool m_MASTER_LCPREQ_Received;
- Uint32 m_MASTER_LCPREQ_FailedNodeId;
- } c_lcpState;
-
- /*------------------------------------------------------------------------*/
- /* THIS VARIABLE KEEPS TRACK OF HOW MANY TABLES ARE ACTIVATED WHEN */
- /* STARTING A LOCAL CHECKPOINT WE SHOULD AVOID STARTING A CHECKPOINT*/
- /* WHEN NO TABLES ARE ACTIVATED. */
- /*------------------------------------------------------------------------*/
- Uint32 cnoOfActiveTables;
- Uint32 cgcpDelay; /* Delay between global checkpoints */
-
- BlockReference cdictblockref; /* DICTIONARY BLOCK REFERENCE */
- Uint32 cfailurenr; /* EVERY TIME WHEN A NODE FAILURE IS REPORTED
- THIS NUMBER IS INCREMENTED. AT THE START OF
- THE SYSTEM THIS NUMBER MUST BE INITIATED TO
- ZERO */
- bool cgckptflag; /* A FLAG WHICH IS SET WHILE A NEW GLOBAL CHECK
- POINT IS BEING CREATED. NO VERIFICATION IS ALLOWED
- IF THE FLAG IS SET*/
- Uint32 cgcpOrderBlocked;
- BlockReference clocallqhblockref;
- BlockReference clocaltcblockref;
- BlockReference cmasterdihref;
- Uint16 cownNodeId;
- Uint32 cnewgcp;
- BlockReference cndbStartReqBlockref;
- BlockReference cntrlblockref;
- Uint32 cgcpSameCounter;
- Uint32 coldgcp;
- Uint32 con_lineNodes;
- Uint32 creceivedfrag;
- Uint32 cremainingfrags;
- Uint32 cstarttype;
- Uint32 csystemnodes;
- Uint32 currentgcp;
- Uint32 c_newest_restorable_gci;
- Uint32 c_set_initial_start_flag;
-
- enum GcpMasterTakeOverState {
- GMTOS_IDLE = 0,
- GMTOS_INITIAL = 1,
- ALL_READY = 2,
- ALL_PREPARED = 3,
- COMMIT_STARTED_NOT_COMPLETED = 4,
- COMMIT_COMPLETED = 5,
- PREPARE_STARTED_NOT_COMMITTED = 6,
- SAVE_STARTED_NOT_COMPLETED = 7
- };
- GcpMasterTakeOverState cgcpMasterTakeOverState;
-
-public:
- enum LcpMasterTakeOverState {
- LMTOS_IDLE = 0,
- LMTOS_WAIT_EMPTY_LCP = 1, // Currently doing empty LCP
- LMTOS_WAIT_LCP_FRAG_REP = 2,// Currently waiting for outst. LCP_FRAG_REP
- LMTOS_INITIAL = 3,
- LMTOS_ALL_IDLE = 4,
- LMTOS_ALL_ACTIVE = 5,
- LMTOS_LCP_CONCLUDING = 6,
- LMTOS_COPY_ONGOING = 7
- };
-private:
- class MasterTakeOverState {
- public:
- MasterTakeOverState() {}
- void set(LcpMasterTakeOverState s, Uint32 line) {
- state = s; updatePlace = line;
- }
-
- LcpMasterTakeOverState state;
- Uint32 updatePlace;
-
- Uint32 minTableId;
- Uint32 minFragId;
- Uint32 failedNodeId;
- } c_lcpMasterTakeOverState;
-
- Uint16 cmasterNodeId;
- Uint8 cnoHotSpare;
-
- struct NodeStartMasterRecord {
- Uint32 startNode;
- Uint32 wait;
- Uint32 failNr;
- bool activeState;
- bool blockLcp;
- bool blockGcp;
- Uint32 startInfoErrorCode;
- Uint32 m_outstandingGsn;
- };
- NodeStartMasterRecord c_nodeStartMaster;
-
- struct NodeStartSlaveRecord {
- NodeStartSlaveRecord() { nodeId = 0;}
-
- Uint32 nodeId;
- };
- NodeStartSlaveRecord c_nodeStartSlave;
-
- Uint32 cfirstAliveNode;
- Uint32 cfirstDeadNode;
- Uint32 cstartPhase;
- Uint32 cnoReplicas;
-
- Uint32 c_startToLock;
- Uint32 c_endToLock;
- Uint32 c_createFragmentLock;
- Uint32 c_updateToLock;
-
- bool cwaitLcpSr;
- Uint32 cnoOfNodeGroups;
- bool cstartGcpNow;
-
- Uint32 crestartGci; /* VALUE OF GCI WHEN SYSTEM RESTARTED OR STARTED */
- Uint32 cminHotSpareNodes;
-
- /**
- * Counter variables keeping track of the number of outstanding signals
- * for particular signals in various protocols.
- */
- SignalCounter c_COPY_GCIREQ_Counter;
- SignalCounter c_COPY_TABREQ_Counter;
- SignalCounter c_CREATE_FRAGREQ_Counter;
- SignalCounter c_DIH_SWITCH_REPLICA_REQ_Counter;
- SignalCounter c_EMPTY_LCP_REQ_Counter;
- SignalCounter c_END_TOREQ_Counter;
- SignalCounter c_GCP_COMMIT_Counter;
- SignalCounter c_GCP_PREPARE_Counter;
- SignalCounter c_GCP_SAVEREQ_Counter;
- SignalCounter c_INCL_NODEREQ_Counter;
- SignalCounter c_MASTER_GCPREQ_Counter;
- SignalCounter c_MASTER_LCPREQ_Counter;
- SignalCounter c_START_INFOREQ_Counter;
- SignalCounter c_START_RECREQ_Counter;
- SignalCounter c_START_TOREQ_Counter;
- SignalCounter c_STOP_ME_REQ_Counter;
- SignalCounter c_TC_CLOPSIZEREQ_Counter;
- SignalCounter c_TCGETOPSIZEREQ_Counter;
- SignalCounter c_UPDATE_TOREQ_Counter;
- SignalCounter c_START_LCP_REQ_Counter;
-
- bool c_blockCommit;
- Uint32 c_blockCommitNo;
-
- bool getBlockCommit() const {
- return c_blockCommit || cgckptflag;
- }
-
- /**
- * SwitchReplicaRecord - Should only be used by master
- */
- struct SwitchReplicaRecord {
- SwitchReplicaRecord() {}
- void clear(){}
-
- Uint32 nodeId;
- Uint32 tableId;
- Uint32 fragNo;
- };
- SwitchReplicaRecord c_switchReplicas;
-
- struct StopPermProxyRecord {
- StopPermProxyRecord() { clientRef = 0; }
-
- Uint32 clientData;
- BlockReference clientRef;
- BlockReference masterRef;
- };
-
- struct StopPermMasterRecord {
- StopPermMasterRecord() { clientRef = 0;}
-
- Uint32 returnValue;
-
- Uint32 clientData;
- BlockReference clientRef;
- };
-
- StopPermProxyRecord c_stopPermProxy;
- StopPermMasterRecord c_stopPermMaster;
-
- void checkStopPermProxy(Signal*, NodeId failedNodeId);
- void checkStopPermMaster(Signal*, NodeRecordPtr failedNodePtr);
-
- void switchReplica(Signal*,
- Uint32 nodeId,
- Uint32 tableId,
- Uint32 fragNo);
-
- void switchReplicaReply(Signal*, NodeId nodeId);
-
- /**
- * Wait GCP (proxy)
- */
- struct WaitGCPProxyRecord {
- WaitGCPProxyRecord() { clientRef = 0;}
-
- Uint32 clientData;
- BlockReference clientRef;
- BlockReference masterRef;
-
- union { Uint32 nextPool; Uint32 nextList; };
- Uint32 prevList;
- };
- typedef Ptr<WaitGCPProxyRecord> WaitGCPProxyPtr;
-
- /**
- * Wait GCP (master)
- */
- struct WaitGCPMasterRecord {
- WaitGCPMasterRecord() { clientRef = 0;}
- Uint32 clientData;
- BlockReference clientRef;
-
- union { Uint32 nextPool; Uint32 nextList; };
- Uint32 prevList;
- };
- typedef Ptr<WaitGCPMasterRecord> WaitGCPMasterPtr;
-
- /**
- * Pool/list of WaitGCPProxyRecord record
- */
- ArrayPool<WaitGCPProxyRecord> waitGCPProxyPool;
- DLList<WaitGCPProxyRecord> c_waitGCPProxyList;
-
- /**
- * Pool/list of WaitGCPMasterRecord record
- */
- ArrayPool<WaitGCPMasterRecord> waitGCPMasterPool;
- DLList<WaitGCPMasterRecord> c_waitGCPMasterList;
-
- void checkWaitGCPProxy(Signal*, NodeId failedNodeId);
- void checkWaitGCPMaster(Signal*, NodeId failedNodeId);
- void emptyWaitGCPMasterQueue(Signal*);
-
- /**
- * Stop me
- */
- struct StopMeRecord {
- StopMeRecord() { clientRef = 0;}
-
- BlockReference clientRef;
- Uint32 clientData;
- };
- StopMeRecord c_stopMe;
-
- void checkStopMe(Signal *, NodeRecordPtr failedNodePtr);
-
-#define DIH_CDATA_SIZE 128
- /**
- * This variable must be atleast the size of Sysfile::SYSFILE_SIZE32
- */
- Uint32 cdata[DIH_CDATA_SIZE]; /* TEMPORARY ARRAY VARIABLE */
-
- /**
- * Sys file data
- */
- Uint32 sysfileData[DIH_CDATA_SIZE];
- Uint32 sysfileDataToFile[DIH_CDATA_SIZE];
-
- /**
- * When a node comes up without filesystem
- * we have to clear all LCP for that node
- */
- void invalidateNodeLCP(Signal *, Uint32 nodeId, Uint32 tableId);
- void invalidateNodeLCP(Signal *, Uint32 nodeId, TabRecordPtr);
-
- /**
- * Reply from nodeId
- */
- void startInfoReply(Signal *, Uint32 nodeId);
-
- void dump_replica_info();
-
- // DIH specifics for execNODE_START_REP (sendDictUnlockOrd)
- void execNODE_START_REP(Signal* signal);
-
- /*
- * Lock master DICT. Only current use is by starting node
- * during NR. A pool of slave records is convenient anyway.
- */
- struct DictLockSlaveRecord {
- Uint32 lockPtr;
- Uint32 lockType;
- bool locked;
- Callback callback;
- Uint32 nextPool;
- };
-
- typedef Ptr<DictLockSlaveRecord> DictLockSlavePtr;
- ArrayPool<DictLockSlaveRecord> c_dictLockSlavePool;
-
- // slave
- void sendDictLockReq(Signal* signal, Uint32 lockType, Callback c);
- void recvDictLockConf(Signal* signal);
- void sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI);
-
- // NR
- Uint32 c_dictLockSlavePtrI_nodeRestart; // userPtr for NR
- void recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret);
-
- Uint32 c_error_7181_ref;
-};
-
-#if (DIH_CDATA_SIZE < _SYSFILE_SIZE32)
-#error "cdata is to small compared to Sysfile size"
-#endif
-
-#endif
-
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp
deleted file mode 100644
index 5560c94cbfa..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBDIH_C
-#include "Dbdih.hpp"
-#include <ndb_limits.h>
-
-#define DEBUG(x) { ndbout << "DIH::" << x << endl; }
-
-void Dbdih::initData()
-{
- cpageFileSize = ZPAGEREC;
-
- // Records with constant sizes
- createReplicaRecord = (CreateReplicaRecord*)
- allocRecord("CreateReplicaRecord", sizeof(CreateReplicaRecord),
- ZCREATE_REPLICA_FILE_SIZE);
-
- nodeGroupRecord = (NodeGroupRecord*)
- allocRecord("NodeGroupRecord", sizeof(NodeGroupRecord), MAX_NDB_NODES);
-
- nodeRecord = (NodeRecord*)
- allocRecord("NodeRecord", sizeof(NodeRecord), MAX_NDB_NODES);
-
- Uint32 i;
- for(i = 0; i<MAX_NDB_NODES; i++){
- new (&nodeRecord[i]) NodeRecord();
- }
-
- takeOverRecord = (TakeOverRecord*)allocRecord("TakeOverRecord",
- sizeof(TakeOverRecord),
- MAX_NDB_NODES);
- for(i = 0; i<MAX_NDB_NODES; i++)
- new (&takeOverRecord[i]) TakeOverRecord();
-
- for(i = 0; i<MAX_NDB_NODES; i++)
- new (&takeOverRecord[i]) TakeOverRecord();
-
- waitGCPProxyPool.setSize(ZPROXY_FILE_SIZE);
- waitGCPMasterPool.setSize(ZPROXY_MASTER_FILE_SIZE);
-
- c_dictLockSlavePool.setSize(1); // assert single usage
- c_dictLockSlavePtrI_nodeRestart = RNIL;
-
- cgcpOrderBlocked = 0;
- c_lcpState.ctcCounter = 0;
- cwaitLcpSr = false;
- c_blockCommit = false;
- c_blockCommitNo = 1;
- cntrlblockref = RNIL;
- c_set_initial_start_flag = FALSE;
-}//Dbdih::initData()
-
-void Dbdih::initRecords()
-{
- // Records with dynamic sizes
- apiConnectRecord = (ApiConnectRecord*)
- allocRecord("ApiConnectRecord",
- sizeof(ApiConnectRecord),
- capiConnectFileSize);
-
- connectRecord = (ConnectRecord*)allocRecord("ConnectRecord",
- sizeof(ConnectRecord),
- cconnectFileSize);
-
- fileRecord = (FileRecord*)allocRecord("FileRecord",
- sizeof(FileRecord),
- cfileFileSize);
-
- fragmentstore = (Fragmentstore*)allocRecord("Fragmentstore",
- sizeof(Fragmentstore),
- cfragstoreFileSize);
-
- pageRecord = (PageRecord*)allocRecord("PageRecord",
- sizeof(PageRecord),
- cpageFileSize);
-
- replicaRecord = (ReplicaRecord*)allocRecord("ReplicaRecord",
- sizeof(ReplicaRecord),
- creplicaFileSize);
-
- tabRecord = (TabRecord*)allocRecord("TabRecord",
- sizeof(TabRecord),
- ctabFileSize);
-
- // Initialize BAT for interface to file system
- NewVARIABLE* bat = allocateBat(22);
- bat[1].WA = &pageRecord->word[0];
- bat[1].nrr = cpageFileSize;
- bat[1].ClusterSize = sizeof(PageRecord);
- bat[1].bits.q = 11;
- bat[1].bits.v = 5;
- bat[20].WA = &sysfileData[0];
- bat[20].nrr = 1;
- bat[20].ClusterSize = sizeof(sysfileData);
- bat[20].bits.q = 7;
- bat[20].bits.v = 5;
- bat[21].WA = &sysfileDataToFile[0];
- bat[21].nrr = 1;
- bat[21].ClusterSize = sizeof(sysfileDataToFile);
- bat[21].bits.q = 7;
- bat[21].bits.v = 5;
-}//Dbdih::initRecords()
-
-Dbdih::Dbdih(Block_context& ctx):
- SimulatedBlock(DBDIH, ctx),
- c_waitGCPProxyList(waitGCPProxyPool),
- c_waitGCPMasterList(waitGCPMasterPool)
-{
- BLOCK_CONSTRUCTOR(Dbdih);
-
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbdih::execDUMP_STATE_ORD);
- addRecSignal(GSN_NDB_TAMPER, &Dbdih::execNDB_TAMPER, true);
- addRecSignal(GSN_DEBUG_SIG, &Dbdih::execDEBUG_SIG);
- addRecSignal(GSN_MASTER_GCPREQ, &Dbdih::execMASTER_GCPREQ);
- addRecSignal(GSN_MASTER_GCPREF, &Dbdih::execMASTER_GCPREF);
- addRecSignal(GSN_MASTER_GCPCONF, &Dbdih::execMASTER_GCPCONF);
- addRecSignal(GSN_EMPTY_LCP_CONF, &Dbdih::execEMPTY_LCP_CONF);
- addRecSignal(GSN_MASTER_LCPREQ, &Dbdih::execMASTER_LCPREQ);
- addRecSignal(GSN_MASTER_LCPREF, &Dbdih::execMASTER_LCPREF);
- addRecSignal(GSN_MASTER_LCPCONF, &Dbdih::execMASTER_LCPCONF);
- addRecSignal(GSN_NF_COMPLETEREP, &Dbdih::execNF_COMPLETEREP);
- addRecSignal(GSN_START_PERMREQ, &Dbdih::execSTART_PERMREQ);
- addRecSignal(GSN_START_PERMCONF, &Dbdih::execSTART_PERMCONF);
- addRecSignal(GSN_START_PERMREF, &Dbdih::execSTART_PERMREF);
- addRecSignal(GSN_INCL_NODEREQ, &Dbdih::execINCL_NODEREQ);
- addRecSignal(GSN_INCL_NODECONF, &Dbdih::execINCL_NODECONF);
- addRecSignal(GSN_END_TOREQ, &Dbdih::execEND_TOREQ);
- addRecSignal(GSN_END_TOCONF, &Dbdih::execEND_TOCONF);
- addRecSignal(GSN_START_TOREQ, &Dbdih::execSTART_TOREQ);
- addRecSignal(GSN_START_TOCONF, &Dbdih::execSTART_TOCONF);
- addRecSignal(GSN_START_MEREQ, &Dbdih::execSTART_MEREQ);
- addRecSignal(GSN_START_MECONF, &Dbdih::execSTART_MECONF);
- addRecSignal(GSN_START_MEREF, &Dbdih::execSTART_MEREF);
- addRecSignal(GSN_START_COPYREQ, &Dbdih::execSTART_COPYREQ);
- addRecSignal(GSN_START_COPYCONF, &Dbdih::execSTART_COPYCONF);
- addRecSignal(GSN_START_COPYREF, &Dbdih::execSTART_COPYREF);
- addRecSignal(GSN_CREATE_FRAGREQ, &Dbdih::execCREATE_FRAGREQ);
- addRecSignal(GSN_CREATE_FRAGCONF, &Dbdih::execCREATE_FRAGCONF);
- addRecSignal(GSN_DIVERIFYREQ, &Dbdih::execDIVERIFYREQ);
- addRecSignal(GSN_GCP_SAVECONF, &Dbdih::execGCP_SAVECONF);
- addRecSignal(GSN_GCP_PREPARECONF, &Dbdih::execGCP_PREPARECONF);
- addRecSignal(GSN_GCP_PREPARE, &Dbdih::execGCP_PREPARE);
- addRecSignal(GSN_GCP_NODEFINISH, &Dbdih::execGCP_NODEFINISH);
- addRecSignal(GSN_GCP_COMMIT, &Dbdih::execGCP_COMMIT);
- addRecSignal(GSN_DIHNDBTAMPER, &Dbdih::execDIHNDBTAMPER);
- addRecSignal(GSN_CONTINUEB, &Dbdih::execCONTINUEB);
- addRecSignal(GSN_COPY_GCIREQ, &Dbdih::execCOPY_GCIREQ);
- addRecSignal(GSN_COPY_GCICONF, &Dbdih::execCOPY_GCICONF);
- addRecSignal(GSN_COPY_TABREQ, &Dbdih::execCOPY_TABREQ);
- addRecSignal(GSN_COPY_TABCONF, &Dbdih::execCOPY_TABCONF);
- addRecSignal(GSN_TCGETOPSIZECONF, &Dbdih::execTCGETOPSIZECONF);
- addRecSignal(GSN_TC_CLOPSIZECONF, &Dbdih::execTC_CLOPSIZECONF);
-
- addRecSignal(GSN_LCP_COMPLETE_REP, &Dbdih::execLCP_COMPLETE_REP);
- addRecSignal(GSN_LCP_FRAG_REP, &Dbdih::execLCP_FRAG_REP);
- addRecSignal(GSN_START_LCP_REQ, &Dbdih::execSTART_LCP_REQ);
- addRecSignal(GSN_START_LCP_CONF, &Dbdih::execSTART_LCP_CONF);
-
- 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);
- addRecSignal(GSN_NODE_FAILREP, &Dbdih::execNODE_FAILREP);
- addRecSignal(GSN_COPY_FRAGCONF, &Dbdih::execCOPY_FRAGCONF);
- addRecSignal(GSN_COPY_FRAGREF, &Dbdih::execCOPY_FRAGREF);
- addRecSignal(GSN_DIADDTABREQ, &Dbdih::execDIADDTABREQ);
- addRecSignal(GSN_DIGETNODESREQ, &Dbdih::execDIGETNODESREQ);
- addRecSignal(GSN_DIRELEASEREQ, &Dbdih::execDIRELEASEREQ);
- addRecSignal(GSN_DISEIZEREQ, &Dbdih::execDISEIZEREQ);
- addRecSignal(GSN_STTOR, &Dbdih::execSTTOR);
- addRecSignal(GSN_DI_FCOUNTREQ, &Dbdih::execDI_FCOUNTREQ);
- addRecSignal(GSN_DIGETPRIMREQ, &Dbdih::execDIGETPRIMREQ);
- addRecSignal(GSN_GCP_SAVEREF, &Dbdih::execGCP_SAVEREF);
- addRecSignal(GSN_GCP_TCFINISHED, &Dbdih::execGCP_TCFINISHED);
- addRecSignal(GSN_READ_NODESCONF, &Dbdih::execREAD_NODESCONF);
- addRecSignal(GSN_NDB_STTOR, &Dbdih::execNDB_STTOR);
- addRecSignal(GSN_DICTSTARTCONF, &Dbdih::execDICTSTARTCONF);
- addRecSignal(GSN_NDB_STARTREQ, &Dbdih::execNDB_STARTREQ);
- addRecSignal(GSN_GETGCIREQ, &Dbdih::execGETGCIREQ);
- addRecSignal(GSN_DIH_RESTARTREQ, &Dbdih::execDIH_RESTARTREQ);
- addRecSignal(GSN_START_RECCONF, &Dbdih::execSTART_RECCONF);
- addRecSignal(GSN_START_FRAGCONF, &Dbdih::execSTART_FRAGCONF);
- addRecSignal(GSN_ADD_FRAGCONF, &Dbdih::execADD_FRAGCONF);
- addRecSignal(GSN_ADD_FRAGREF, &Dbdih::execADD_FRAGREF);
- addRecSignal(GSN_FSOPENCONF, &Dbdih::execFSOPENCONF);
- addRecSignal(GSN_FSOPENREF, &Dbdih::execFSOPENREF, true);
- addRecSignal(GSN_FSCLOSECONF, &Dbdih::execFSCLOSECONF);
- addRecSignal(GSN_FSCLOSEREF, &Dbdih::execFSCLOSEREF, true);
- addRecSignal(GSN_FSREADCONF, &Dbdih::execFSREADCONF);
- addRecSignal(GSN_FSREADREF, &Dbdih::execFSREADREF, true);
- addRecSignal(GSN_FSWRITECONF, &Dbdih::execFSWRITECONF);
- addRecSignal(GSN_FSWRITEREF, &Dbdih::execFSWRITEREF, true);
-
- addRecSignal(GSN_START_INFOREQ,
- &Dbdih::execSTART_INFOREQ);
- addRecSignal(GSN_START_INFOREF,
- &Dbdih::execSTART_INFOREF);
- addRecSignal(GSN_START_INFOCONF,
- &Dbdih::execSTART_INFOCONF);
-
- addRecSignal(GSN_CHECKNODEGROUPSREQ, &Dbdih::execCHECKNODEGROUPSREQ);
-
- addRecSignal(GSN_BLOCK_COMMIT_ORD,
- &Dbdih::execBLOCK_COMMIT_ORD);
- addRecSignal(GSN_UNBLOCK_COMMIT_ORD,
- &Dbdih::execUNBLOCK_COMMIT_ORD);
-
- addRecSignal(GSN_DIH_SWITCH_REPLICA_REQ,
- &Dbdih::execDIH_SWITCH_REPLICA_REQ);
-
- addRecSignal(GSN_DIH_SWITCH_REPLICA_REF,
- &Dbdih::execDIH_SWITCH_REPLICA_REF);
-
- addRecSignal(GSN_DIH_SWITCH_REPLICA_CONF,
- &Dbdih::execDIH_SWITCH_REPLICA_CONF);
-
- addRecSignal(GSN_STOP_PERM_REQ, &Dbdih::execSTOP_PERM_REQ);
- addRecSignal(GSN_STOP_PERM_REF, &Dbdih::execSTOP_PERM_REF);
- addRecSignal(GSN_STOP_PERM_CONF, &Dbdih::execSTOP_PERM_CONF);
-
- addRecSignal(GSN_STOP_ME_REQ, &Dbdih::execSTOP_ME_REQ);
- addRecSignal(GSN_STOP_ME_REF, &Dbdih::execSTOP_ME_REF);
- addRecSignal(GSN_STOP_ME_CONF, &Dbdih::execSTOP_ME_CONF);
-
- addRecSignal(GSN_WAIT_GCP_REQ, &Dbdih::execWAIT_GCP_REQ);
- addRecSignal(GSN_WAIT_GCP_REF, &Dbdih::execWAIT_GCP_REF);
- addRecSignal(GSN_WAIT_GCP_CONF, &Dbdih::execWAIT_GCP_CONF);
-
- addRecSignal(GSN_UPDATE_TOREQ, &Dbdih::execUPDATE_TOREQ);
- 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);
-
- addRecSignal(GSN_ALTER_TAB_REQ, &Dbdih::execALTER_TAB_REQ);
-
- addRecSignal(GSN_CREATE_FRAGMENTATION_REQ,
- &Dbdih::execCREATE_FRAGMENTATION_REQ);
-
- addRecSignal(GSN_DICT_LOCK_CONF, &Dbdih::execDICT_LOCK_CONF);
- addRecSignal(GSN_DICT_LOCK_REF, &Dbdih::execDICT_LOCK_REF);
- addRecSignal(GSN_NODE_START_REP, &Dbdih::execNODE_START_REP, true);
-
- addRecSignal(GSN_START_FRAGREF,
- &Dbdih::execSTART_FRAGREF);
-
- addRecSignal(GSN_PREPARE_COPY_FRAG_REF,
- &Dbdih::execPREPARE_COPY_FRAG_REF);
- addRecSignal(GSN_PREPARE_COPY_FRAG_CONF,
- &Dbdih::execPREPARE_COPY_FRAG_CONF);
-
- apiConnectRecord = 0;
- connectRecord = 0;
- fileRecord = 0;
- fragmentstore = 0;
- pageRecord = 0;
- replicaRecord = 0;
- tabRecord = 0;
- takeOverRecord = 0;
- createReplicaRecord = 0;
- nodeGroupRecord = 0;
- nodeRecord = 0;
- c_nextNodeGroup = 0;
-}//Dbdih::Dbdih()
-
-Dbdih::~Dbdih()
-{
- deallocRecord((void **)&apiConnectRecord, "ApiConnectRecord",
- sizeof(ApiConnectRecord),
- capiConnectFileSize);
-
- deallocRecord((void **)&connectRecord, "ConnectRecord",
- sizeof(ConnectRecord),
- cconnectFileSize);
-
- deallocRecord((void **)&fileRecord, "FileRecord",
- sizeof(FileRecord),
- cfileFileSize);
-
- deallocRecord((void **)&fragmentstore, "Fragmentstore",
- sizeof(Fragmentstore),
- cfragstoreFileSize);
-
- deallocRecord((void **)&pageRecord, "PageRecord",
- sizeof(PageRecord),
- cpageFileSize);
-
- deallocRecord((void **)&replicaRecord, "ReplicaRecord",
- sizeof(ReplicaRecord),
- creplicaFileSize);
-
- deallocRecord((void **)&tabRecord, "TabRecord",
- sizeof(TabRecord),
- ctabFileSize);
-
- // Records with constant sizes
- deallocRecord((void **)&createReplicaRecord,
- "CreateReplicaRecord", sizeof(CreateReplicaRecord),
- ZCREATE_REPLICA_FILE_SIZE);
-
- deallocRecord((void **)&nodeGroupRecord, "NodeGroupRecord",
- sizeof(NodeGroupRecord), MAX_NDB_NODES);
-
- deallocRecord((void **)&nodeRecord, "NodeRecord",
- sizeof(NodeRecord), MAX_NDB_NODES);
-
- deallocRecord((void **)&takeOverRecord, "TakeOverRecord",
- sizeof(TakeOverRecord),
- MAX_NDB_NODES);
-
-}//Dbdih::~Dbdih()
-
-BLOCK_FUNCTIONS(Dbdih)
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
deleted file mode 100644
index fb936fed464..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ /dev/null
@@ -1,15878 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBDIH_C
-#include <ndb_limits.h>
-#include <ndb_version.h>
-#include <NdbOut.hpp>
-
-#include "Dbdih.hpp"
-#include "Configuration.hpp"
-
-#include <signaldata/BlockCommitOrd.hpp>
-#include <signaldata/CheckNodeGroups.hpp>
-#include <signaldata/CreateFrag.hpp>
-#include <signaldata/CopyActive.hpp>
-#include <signaldata/CopyFrag.hpp>
-#include <signaldata/CopyGCIReq.hpp>
-#include <signaldata/DiAddTab.hpp>
-#include <signaldata/DictStart.hpp>
-#include <signaldata/DiGetNodes.hpp>
-#include <signaldata/DihContinueB.hpp>
-#include <signaldata/DihSwitchReplica.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/EmptyLcp.hpp>
-#include <signaldata/EndTo.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/GCPSave.hpp>
-#include <signaldata/HotSpareRep.hpp>
-#include <signaldata/MasterGCP.hpp>
-#include <signaldata/MasterLCP.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/StartFragReq.hpp>
-#include <signaldata/StartInfo.hpp>
-#include <signaldata/StartMe.hpp>
-#include <signaldata/StartPerm.hpp>
-#include <signaldata/StartRec.hpp>
-#include <signaldata/StartTo.hpp>
-#include <signaldata/StopPerm.hpp>
-#include <signaldata/StopMe.hpp>
-#include <signaldata/TestOrd.hpp>
-#include <signaldata/UpdateTo.hpp>
-#include <signaldata/WaitGCP.hpp>
-#include <signaldata/DihStartTab.hpp>
-#include <signaldata/LCP.hpp>
-#include <signaldata/SystemError.hpp>
-
-#include <signaldata/DropTab.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/PrepDropTab.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/CreateFragmentation.hpp>
-#include <signaldata/LqhFrag.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/DihFragCount.hpp>
-#include <signaldata/DictLock.hpp>
-#include <DebuggerNames.hpp>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-#define SYSFILE ((Sysfile *)&sysfileData[0])
-
-#define RETURN_IF_NODE_NOT_ALIVE(node) \
- if (!checkNodeAlive((node))) { \
- jam(); \
- return; \
- } \
-
-#define RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverIndex, regTOPtr) \
- regTOPtr.i = takeOverIndex; \
- ptrCheckGuard(regTOPtr, MAX_NDB_NODES, takeOverRecord); \
- if (checkToInterrupted(regTOPtr)) { \
- jam(); \
- return; \
- } \
-
-#define receiveLoopMacro(sigName, receiveNodeId)\
-{ \
- c_##sigName##_Counter.clearWaitingFor(receiveNodeId); \
- if(c_##sigName##_Counter.done() == false){ \
- jam(); \
- return; \
- } \
-}
-
-#define sendLoopMacro(sigName, signalRoutine) \
-{ \
- c_##sigName##_Counter.clearWaitingFor(); \
- NodeRecordPtr specNodePtr; \
- specNodePtr.i = cfirstAliveNode; \
- do { \
- jam(); \
- ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord); \
- c_##sigName##_Counter.setWaitingFor(specNodePtr.i); \
- signalRoutine(signal, specNodePtr.i); \
- specNodePtr.i = specNodePtr.p->nextNode; \
- } while (specNodePtr.i != RNIL); \
-}
-
-static
-Uint32
-prevLcpNo(Uint32 lcpNo){
- if(lcpNo == 0)
- return MAX_LCP_STORED - 1;
- return lcpNo - 1;
-}
-
-static
-Uint32
-nextLcpNo(Uint32 lcpNo){
- lcpNo++;
- if(lcpNo == MAX_LCP_STORED)
- return 0;
- return lcpNo;
-}
-
-#define gth(x, y) ndbrequire(((int)x)>((int)y))
-
-void Dbdih::nullRoutine(Signal* signal, Uint32 nodeId)
-{
-}//Dbdih::nullRoutine()
-
-void Dbdih::sendCOPY_GCIREQ(Signal* signal, Uint32 nodeId)
-{
- ndbrequire(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE);
-
- const BlockReference ref = calcDihBlockRef(nodeId);
- const Uint32 wordPerSignal = CopyGCIReq::DATA_SIZE;
- const Uint32 noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
- wordPerSignal);
-
- CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
- copyGCI->anyData = nodeId;
- copyGCI->copyReason = c_copyGCIMaster.m_copyReason;
- copyGCI->startWord = 0;
-
- for(Uint32 i = 0; i < noOfSignals; i++) {
- jam();
- { // Do copy
- const int startWord = copyGCI->startWord;
- for(Uint32 j = 0; j < wordPerSignal; j++) {
- copyGCI->data[j] = sysfileData[j+startWord];
- }//for
- }
- sendSignal(ref, GSN_COPY_GCIREQ, signal, 25, JBB);
- copyGCI->startWord += wordPerSignal;
- }//for
-}//Dbdih::sendCOPY_GCIREQ()
-
-
-void Dbdih::sendDIH_SWITCH_REPLICA_REQ(Signal* signal, Uint32 nodeId)
-{
- const BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_DIH_SWITCH_REPLICA_REQ, signal,
- DihSwitchReplicaReq::SignalLength, JBB);
-}//Dbdih::sendDIH_SWITCH_REPLICA_REQ()
-
-void Dbdih::sendEMPTY_LCP_REQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcLqhBlockRef(nodeId);
- sendSignal(ref, GSN_EMPTY_LCP_REQ, signal, EmptyLcpReq::SignalLength, JBB);
-}//Dbdih::sendEMPTY_LCPREQ()
-
-void Dbdih::sendEND_TOREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_END_TOREQ, signal, EndToReq::SignalLength, JBB);
-}//Dbdih::sendEND_TOREQ()
-
-void Dbdih::sendGCP_COMMIT(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- signal->theData[0] = cownNodeId;
- signal->theData[1] = cnewgcp;
- sendSignal(ref, GSN_GCP_COMMIT, signal, 2, JBA);
-}//Dbdih::sendGCP_COMMIT()
-
-void Dbdih::sendGCP_PREPARE(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- signal->theData[0] = cownNodeId;
- signal->theData[1] = cnewgcp;
- sendSignal(ref, GSN_GCP_PREPARE, signal, 2, JBA);
-}//Dbdih::sendGCP_PREPARE()
-
-void Dbdih::sendGCP_SAVEREQ(Signal* signal, Uint32 nodeId)
-{
- GCPSaveReq * const saveReq = (GCPSaveReq*)&signal->theData[0];
- BlockReference ref = calcLqhBlockRef(nodeId);
- saveReq->dihBlockRef = reference();
- saveReq->dihPtr = nodeId;
- saveReq->gci = coldgcp;
- sendSignal(ref, GSN_GCP_SAVEREQ, signal, GCPSaveReq::SignalLength, JBB);
-}//Dbdih::sendGCP_SAVEREQ()
-
-void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference nodeDihRef = calcDihBlockRef(nodeId);
- signal->theData[0] = reference();
- signal->theData[1] = c_nodeStartMaster.startNode;
- signal->theData[2] = c_nodeStartMaster.failNr;
- signal->theData[3] = 0;
- signal->theData[4] = currentgcp;
- sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBA);
-}//Dbdih::sendINCL_NODEREQ()
-
-void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_MASTER_GCPREQ, signal, MasterGCPReq::SignalLength, JBB);
-}//Dbdih::sendMASTER_GCPREQ()
-
-void Dbdih::sendMASTER_LCPREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_MASTER_LCPREQ, signal, MasterLCPReq::SignalLength, JBB);
-}//Dbdih::sendMASTER_LCPREQ()
-
-void Dbdih::sendSTART_INFOREQ(Signal* signal, Uint32 nodeId)
-{
- const BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_START_INFOREQ, signal, StartInfoReq::SignalLength, JBB);
-}//sendSTART_INFOREQ()
-
-void Dbdih::sendSTART_RECREQ(Signal* signal, Uint32 nodeId)
-{
- StartRecReq * const req = (StartRecReq*)&signal->theData[0];
- BlockReference ref = calcLqhBlockRef(nodeId);
- req->receivingNodeId = nodeId;
- req->senderRef = reference();
- req->keepGci = SYSFILE->keepGCI;
- req->lastCompletedGci = SYSFILE->lastCompletedGCI[nodeId];
- req->newestGci = SYSFILE->newestRestorableGCI;
- sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
-
- signal->theData[0] = NDB_LE_StartREDOLog;
- signal->theData[1] = nodeId;
- signal->theData[2] = SYSFILE->keepGCI;
- signal->theData[3] = SYSFILE->lastCompletedGCI[nodeId];
- signal->theData[4] = SYSFILE->newestRestorableGCI;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
-}//Dbdih::sendSTART_RECREQ()
-
-void Dbdih::sendSTART_TOREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_START_TOREQ, signal, StartToReq::SignalLength, JBB);
-}//Dbdih::sendSTART_TOREQ()
-
-void Dbdih::sendSTOP_ME_REQ(Signal* signal, Uint32 nodeId)
-{
- if (nodeId != getOwnNodeId()) {
- jam();
- const BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_STOP_ME_REQ, signal, StopMeReq::SignalLength, JBB);
- }//if
-}//Dbdih::sendSTOP_ME_REQ()
-
-void Dbdih::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcTcBlockRef(nodeId);
- signal->theData[0] = nodeId;
- signal->theData[1] = reference();
- sendSignal(ref, GSN_TC_CLOPSIZEREQ, signal, 2, JBB);
-}//Dbdih::sendTC_CLOPSIZEREQ()
-
-void Dbdih::sendTCGETOPSIZEREQ(Signal* signal, Uint32 nodeId)
-{
- BlockReference ref = calcTcBlockRef(nodeId);
- signal->theData[0] = nodeId;
- signal->theData[1] = reference();
- sendSignal(ref, GSN_TCGETOPSIZEREQ, signal, 2, JBB);
-}//Dbdih::sendTCGETOPSIZEREQ()
-
-void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId)
-{
- const BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB);
-}//sendUPDATE_TOREQ()
-
-void Dbdih::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- switch ((DihContinueB::Type)signal->theData[0]) {
- case DihContinueB::ZPACK_TABLE_INTO_PAGES:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- packTableIntoPagesLab(signal, tableId);
- return;
- break;
- }
- case DihContinueB::ZPACK_FRAG_INTO_PAGES:
- {
- RWFragment wf;
- jam();
- wf.rwfTabPtr.i = signal->theData[1];
- ptrCheckGuard(wf.rwfTabPtr, ctabFileSize, tabRecord);
- wf.fragId = signal->theData[2];
- wf.pageIndex = signal->theData[3];
- wf.wordIndex = signal->theData[4];
- packFragIntoPagesLab(signal, &wf);
- return;
- break;
- }
- case DihContinueB::ZREAD_PAGES_INTO_TABLE:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- readPagesIntoTableLab(signal, tableId);
- return;
- break;
- }
- case DihContinueB::ZREAD_PAGES_INTO_FRAG:
- {
- RWFragment rf;
- jam();
- rf.rwfTabPtr.i = signal->theData[1];
- ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
- rf.fragId = signal->theData[2];
- rf.pageIndex = signal->theData[3];
- rf.wordIndex = signal->theData[4];
- readPagesIntoFragLab(signal, &rf);
- return;
- break;
- }
- case DihContinueB::ZCOPY_TABLE:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- copyTableLab(signal, tableId);
- return;
- }
- case DihContinueB::ZCOPY_TABLE_NODE:
- {
- NodeRecordPtr nodePtr;
- CopyTableNode ctn;
- jam();
- ctn.ctnTabPtr.i = signal->theData[1];
- ptrCheckGuard(ctn.ctnTabPtr, ctabFileSize, tabRecord);
- nodePtr.i = signal->theData[2];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- ctn.pageIndex = signal->theData[3];
- ctn.wordIndex = signal->theData[4];
- ctn.noOfWords = signal->theData[5];
- copyTableNode(signal, &ctn, nodePtr);
- return;
- }
- case DihContinueB::ZSTART_FRAGMENT:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- Uint32 fragId = signal->theData[2];
- startFragment(signal, tableId, fragId);
- return;
- }
- case DihContinueB::ZCOMPLETE_RESTART:
- jam();
- completeRestartLab(signal);
- return;
- case DihContinueB::ZREAD_TABLE_FROM_PAGES:
- {
- TabRecordPtr tabPtr;
- jam();
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- readTableFromPagesLab(signal, tabPtr);
- return;
- }
- case DihContinueB::ZSR_PHASE2_READ_TABLE:
- {
- TabRecordPtr tabPtr;
- jam();
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- srPhase2ReadTableLab(signal, tabPtr);
- return;
- }
- case DihContinueB::ZCHECK_TC_COUNTER:
- jam();
-#ifndef NO_LCP
- checkTcCounterLab(signal);
-#endif
- return;
- case DihContinueB::ZCALCULATE_KEEP_GCI:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- Uint32 fragId = signal->theData[2];
- calculateKeepGciLab(signal, tableId, fragId);
- return;
- }
- case DihContinueB::ZSTORE_NEW_LCP_ID:
- jam();
- storeNewLcpIdLab(signal);
- return;
- case DihContinueB::ZTABLE_UPDATE:
- {
- TabRecordPtr tabPtr;
- jam();
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tableUpdateLab(signal, tabPtr);
- return;
- }
- case DihContinueB::ZCHECK_LCP_COMPLETED:
- {
- jam();
- checkLcpCompletedLab(signal);
- return;
- }
- case DihContinueB::ZINIT_LCP:
- {
- jam();
- Uint32 senderRef = signal->theData[1];
- Uint32 tableId = signal->theData[2];
- initLcpLab(signal, senderRef, tableId);
- return;
- }
- case DihContinueB::ZADD_TABLE_MASTER_PAGES:
- {
- TabRecordPtr tabPtr;
- jam();
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_MASTER;
- tableUpdateLab(signal, tabPtr);
- return;
- break;
- }
- case DihContinueB::ZDIH_ADD_TABLE_MASTER:
- {
- jam();
- addTable_closeConf(signal, signal->theData[1]);
- return;
- }
- case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
- {
- TabRecordPtr tabPtr;
- jam();
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_SLAVE;
- tableUpdateLab(signal, tabPtr);
- return;
- }
- case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
- {
- ndbrequire(false);
- return;
- }
- case DihContinueB::ZSTART_GCP:
- jam();
-#ifndef NO_GCP
- startGcpLab(signal, signal->theData[1]);
-#endif
- return;
- break;
- case DihContinueB::ZCOPY_GCI:{
- jam();
- CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)signal->theData[1];
- ndbrequire(c_copyGCIMaster.m_copyReason == reason);
- sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
- return;
- }
- break;
- case DihContinueB::ZEMPTY_VERIFY_QUEUE:
- jam();
- emptyverificbuffer(signal, true);
- return;
- break;
- case DihContinueB::ZCHECK_GCP_STOP:
- jam();
-#ifndef NO_GCP
- checkGcpStopLab(signal);
-#endif
- return;
- break;
- case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
- {
- jam();
- Uint32 nodeId = signal->theData[1];
- Uint32 tableId = signal->theData[2];
- removeNodeFromTables(signal, nodeId, tableId);
- return;
- }
- case DihContinueB::ZCOPY_NODE:
- {
- jam();
- Uint32 tableId = signal->theData[1];
- copyNodeLab(signal, tableId);
- return;
- }
- case DihContinueB::ZSTART_TAKE_OVER:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- Uint32 startNode = signal->theData[2];
- Uint32 toNode = signal->theData[3];
- startTakeOver(signal, takeOverPtrI, startNode, toNode);
- return;
- break;
- }
- case DihContinueB::ZCHECK_START_TAKE_OVER:
- jam();
- checkStartTakeOver(signal);
- break;
- case DihContinueB::ZTO_START_COPY_FRAG:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- startNextCopyFragment(signal, takeOverPtrI);
- return;
- }
- case DihContinueB::ZINVALIDATE_NODE_LCP:
- {
- jam();
- const Uint32 nodeId = signal->theData[1];
- const Uint32 tableId = signal->theData[2];
- invalidateNodeLCP(signal, nodeId, tableId);
- return;
- }
- case DihContinueB::ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal,
- signal->theData[1],
- signal->theData[2],
- signal->theData[3]);
- return;
- break;
- case DihContinueB::ZSTART_PERMREQ_AGAIN:
- jam();
- nodeRestartPh2Lab2(signal);
- return;
- break;
- case DihContinueB::SwitchReplica:
- {
- jam();
- const Uint32 nodeId = signal->theData[1];
- const Uint32 tableId = signal->theData[2];
- const Uint32 fragNo = signal->theData[3];
- switchReplica(signal, nodeId, tableId, fragNo);
- return;
- }
- case DihContinueB::ZSEND_START_TO:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- sendStartTo(signal, takeOverPtrI);
- return;
- }
- case DihContinueB::ZSEND_ADD_FRAG:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- toCopyFragLab(signal, takeOverPtrI);
- return;
- }
- case DihContinueB::ZSEND_UPDATE_TO:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- Uint32 updateState = signal->theData[4];
- sendUpdateTo(signal, takeOverPtrI, updateState);
- return;
- }
- case DihContinueB::ZSEND_END_TO:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- sendEndTo(signal, takeOverPtrI);
- return;
- }
- case DihContinueB::ZSEND_CREATE_FRAG:
- {
- jam();
- Uint32 takeOverPtrI = signal->theData[1];
- Uint32 storedType = signal->theData[2];
- Uint32 startGci = signal->theData[3];
- sendCreateFragReq(signal, startGci, storedType, takeOverPtrI);
- return;
- }
- case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:{
- jam();
- TabRecordPtr tabPtr;
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- waitDropTabWritingToFile(signal, tabPtr);
- return;
- }
- case DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:{
- jam();
- Uint32 nodeId = signal->theData[1];
- Uint32 tableId = signal->theData[2];
- checkWaitDropTabFailedLqh(signal, nodeId, tableId);
- return;
- }
- case DihContinueB::ZTO_START_FRAGMENTS:
- {
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = signal->theData[1];
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- nr_start_fragments(signal, takeOverPtr);
- return;
- }
- }//switch
-
- ndbrequire(false);
- return;
-}//Dbdih::execCONTINUEB()
-
-void Dbdih::execCOPY_GCIREQ(Signal* signal)
-{
- CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
- jamEntry();
- CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)copyGCI->copyReason;
- const Uint32 tstart = copyGCI->startWord;
-
- ndbrequire(cmasterdihref == signal->senderBlockRef()) ;
- ndbrequire(c_copyGCISlave.m_copyReason == CopyGCIReq::IDLE);
- ndbrequire(c_copyGCISlave.m_expectedNextWord == tstart);
- ndbrequire(reason != CopyGCIReq::IDLE);
- bool isdone = (tstart + CopyGCIReq::DATA_SIZE) >= Sysfile::SYSFILE_SIZE32;
-
- if (ERROR_INSERTED(7177))
- {
- jam();
-
- if (signal->getLength() == 3)
- {
- jam();
- goto done;
- }
- }
-
- arrGuard(tstart + CopyGCIReq::DATA_SIZE, sizeof(sysfileData)/4);
- for(Uint32 i = 0; i<CopyGCIReq::DATA_SIZE; i++)
- cdata[tstart+i] = copyGCI->data[i];
-
- if (ERROR_INSERTED(7177) && isMaster() && isdone)
- {
- sendSignalWithDelay(reference(), GSN_COPY_GCIREQ, signal, 1000, 3);
- return;
- }
-
-done:
- if (isdone)
- {
- jam();
- c_copyGCISlave.m_expectedNextWord = 0;
- }
- else
- {
- jam();
- c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
- return;
- }
-
- if (cmasterdihref != reference())
- {
- jam();
- Uint32 tmp= SYSFILE->m_restart_seq;
- memcpy(sysfileData, cdata, sizeof(sysfileData));
- SYSFILE->m_restart_seq = tmp;
-
- if (c_set_initial_start_flag)
- {
- jam();
- Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
- }
- }
-
- c_copyGCISlave.m_copyReason = reason;
- c_copyGCISlave.m_senderRef = signal->senderBlockRef();
- c_copyGCISlave.m_senderData = copyGCI->anyData;
-
- CRASH_INSERTION2(7020, reason==CopyGCIReq::LOCAL_CHECKPOINT);
- CRASH_INSERTION2(7008, reason==CopyGCIReq::GLOBAL_CHECKPOINT);
-
- /* -------------------------------------------------------------------------*/
- /* WE SET THE REQUESTER OF THE COPY GCI TO THE CURRENT MASTER. IF THE */
- /* CURRENT MASTER WE DO NOT WANT THE NEW MASTER TO RECEIVE CONFIRM OF */
- /* SOMETHING HE HAS NOT SENT. THE TAKE OVER MUST BE CAREFUL. */
- /* -------------------------------------------------------------------------*/
- bool ok = false;
- switch(reason){
- case CopyGCIReq::IDLE:
- ok = true;
- jam();
- ndbrequire(false);
- break;
- case CopyGCIReq::LOCAL_CHECKPOINT: {
- ok = true;
- jam();
- c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
- c_lcpState.m_masterLcpDihRef = cmasterdihref;
- setNodeInfo(signal);
- break;
- }
- case CopyGCIReq::RESTART: {
- ok = true;
- jam();
- coldgcp = SYSFILE->newestRestorableGCI;
- crestartGci = SYSFILE->newestRestorableGCI;
- c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
- Sysfile::setRestartOngoing(SYSFILE->systemRestartBits);
- currentgcp = coldgcp + 1;
- cnewgcp = coldgcp + 1;
- setNodeInfo(signal);
- if ((Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))) {
- jam();
- /* -------------------------------------------------------------------- */
- // IF THERE WAS A LOCAL CHECKPOINT ONGOING AT THE CRASH MOMENT WE WILL
- // INVALIDATE THAT LOCAL CHECKPOINT.
- /* -------------------------------------------------------------------- */
- invalidateLcpInfoAfterSr();
- }//if
- break;
- }
- case CopyGCIReq::GLOBAL_CHECKPOINT: {
- ok = true;
- jam();
- cgcpParticipantState = GCP_PARTICIPANT_COPY_GCI_RECEIVED;
- c_newest_restorable_gci = SYSFILE->newestRestorableGCI;
- setNodeInfo(signal);
- break;
- }//if
- case CopyGCIReq::INITIAL_START_COMPLETED:
- ok = true;
- jam();
- break;
- }
- ndbrequire(ok);
-
- CRASH_INSERTION(7183);
-
- if (ERROR_INSERTED(7185) && reason==CopyGCIReq::GLOBAL_CHECKPOINT)
- {
- jam();
- return;
- }
-
- /* ----------------------------------------------------------------------- */
- /* WE START BY TRYING TO OPEN THE FIRST RESTORABLE GCI FILE. */
- /* ----------------------------------------------------------------------- */
- FileRecordPtr filePtr;
- filePtr.i = crestartInfoFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- if (filePtr.p->fileStatus == FileRecord::OPEN) {
- jam();
- openingCopyGciSkipInitLab(signal, filePtr);
- return;
- }//if
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
- return;
-}//Dbdih::execCOPY_GCIREQ()
-
-void Dbdih::execDICTSTARTCONF(Signal* signal)
-{
- jamEntry();
- Uint32 nodeId = refToNode(signal->getSendersBlockRef());
- if (nodeId != getOwnNodeId()) {
- jam();
- nodeDictStartConfLab(signal);
- } else {
- jam();
- dictStartConfLab(signal);
- }//if
-}//Dbdih::execDICTSTARTCONF()
-
-void Dbdih::execFSCLOSECONF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- filePtr.p->fileStatus = FileRecord::CLOSED;
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::CLOSING_GCP:
- jam();
- closingGcpLab(signal, filePtr);
- break;
- case FileRecord::CLOSING_GCP_CRASH:
- jam();
- closingGcpCrashLab(signal, filePtr);
- break;
- case FileRecord::CLOSING_TABLE_CRASH:
- jam();
- closingTableCrashLab(signal, filePtr);
- break;
- case FileRecord::CLOSING_TABLE_SR:
- jam();
- closingTableSrLab(signal, filePtr);
- break;
- case FileRecord::TABLE_CLOSE:
- jam();
- tableCloseLab(signal, filePtr);
- break;
- case FileRecord::TABLE_CLOSE_DELETE:
- jam();
- tableDeleteLab(signal, filePtr);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbdih::execFSCLOSECONF()
-
-void Dbdih::execFSCLOSEREF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::CLOSING_GCP:
- jam();
- break;
- case FileRecord::CLOSING_GCP_CRASH:
- jam();
- closingGcpCrashLab(signal, filePtr);
- return;
- case FileRecord::CLOSING_TABLE_CRASH:
- jam();
- closingTableCrashLab(signal, filePtr);
- return;
- case FileRecord::CLOSING_TABLE_SR:
- jam();
- break;
- case FileRecord::TABLE_CLOSE:
- jam();
- break;
- case FileRecord::TABLE_CLOSE_DELETE:
- jam();
- break;
- default:
- jam();
- break;
-
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status);
- fsRefError(signal,__LINE__,msg);
- }
-
- return;
-}//Dbdih::execFSCLOSEREF()
-
-void Dbdih::execFSOPENCONF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- filePtr.p->fileRef = signal->theData[1];
- filePtr.p->fileStatus = FileRecord::OPEN;
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::CREATING_GCP:
- jam();
- creatingGcpLab(signal, filePtr);
- break;
- case FileRecord::OPENING_COPY_GCI:
- jam();
- openingCopyGciSkipInitLab(signal, filePtr);
- break;
- case FileRecord::CREATING_COPY_GCI:
- jam();
- openingCopyGciSkipInitLab(signal, filePtr);
- break;
- case FileRecord::OPENING_GCP:
- jam();
- openingGcpLab(signal, filePtr);
- break;
- case FileRecord::OPENING_TABLE:
- jam();
- openingTableLab(signal, filePtr);
- break;
- case FileRecord::TABLE_CREATE:
- jam();
- tableCreateLab(signal, filePtr);
- break;
- case FileRecord::TABLE_OPEN_FOR_DELETE:
- jam();
- tableOpenLab(signal, filePtr);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbdih::execFSOPENCONF()
-
-void Dbdih::execFSOPENREF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::CREATING_GCP:
- /* --------------------------------------------------------------------- */
- /* WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */
- /* WHICH CAUSES A SYSTEM RESTART. */
- /* --------------------------------------------------------------------- */
- jam();
- break;
- case FileRecord::OPENING_COPY_GCI:
- jam();
- openingCopyGciErrorLab(signal, filePtr);
- return;
- case FileRecord::CREATING_COPY_GCI:
- jam();
- break;
- case FileRecord::OPENING_GCP:
- jam();
- openingGcpErrorLab(signal, filePtr);
- return;
- case FileRecord::OPENING_TABLE:
- jam();
- openingTableErrorLab(signal, filePtr);
- return;
- case FileRecord::TABLE_CREATE:
- jam();
- break;
- case FileRecord::TABLE_OPEN_FOR_DELETE:
- jam();
- tableDeleteLab(signal, filePtr);
- return;
- default:
- jam();
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status);
- fsRefError(signal,__LINE__,msg);
- }
- return;
-}//Dbdih::execFSOPENREF()
-
-void Dbdih::execFSREADCONF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::READING_GCP:
- jam();
- readingGcpLab(signal, filePtr);
- break;
- case FileRecord::READING_TABLE:
- jam();
- readingTableLab(signal, filePtr);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbdih::execFSREADCONF()
-
-void Dbdih::execFSREADREF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::READING_GCP:
- jam();
- readingGcpErrorLab(signal, filePtr);
- return;
- case FileRecord::READING_TABLE:
- jam();
- readingTableErrorLab(signal, filePtr);
- return;
- default:
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status);
- fsRefError(signal,__LINE__,msg);
- }
-}//Dbdih::execFSREADREF()
-
-void Dbdih::execFSWRITECONF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::WRITING_COPY_GCI:
- jam();
- writingCopyGciLab(signal, filePtr);
- break;
- case FileRecord::WRITE_INIT_GCP:
- jam();
- writeInitGcpLab(signal, filePtr);
- break;
- case FileRecord::TABLE_WRITE:
- jam();
- tableWriteLab(signal, filePtr);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbdih::execFSWRITECONF()
-
-void Dbdih::execFSWRITEREF(Signal* signal)
-{
- FileRecordPtr filePtr;
- jamEntry();
- filePtr.i = signal->theData[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- FileRecord::ReqStatus status = filePtr.p->reqStatus;
- filePtr.p->reqStatus = FileRecord::IDLE;
- switch (status) {
- case FileRecord::WRITING_COPY_GCI:
- /* --------------------------------------------------------------------- */
- /* EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH. */
- /* ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE. */
- /* --------------------------------------------------------------------- */
- jam();
- break;
- case FileRecord::WRITE_INIT_GCP:
- /* --------------------------------------------------------------------- */
- /* AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR */
- /* THAT CAUSE A SYSTEM RESTART. */
- /* --------------------------------------------------------------------- */
- jam();
- break;
- case FileRecord::TABLE_WRITE:
- jam();
- break;
- default:
- jam();
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status);
- fsRefError(signal,__LINE__,msg);
- }
- return;
-}//Dbdih::execFSWRITEREF()
-
-void Dbdih::execGETGCIREQ(Signal* signal)
-{
-
- jamEntry();
- Uint32 userPtr = signal->theData[0];
- BlockReference userRef = signal->theData[1];
-
- signal->theData[0] = userPtr;
- signal->theData[1] = SYSFILE->newestRestorableGCI;
- sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB);
-}//Dbdih::execGETGCIREQ()
-
-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();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
-
- initData();
-
- ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT,
- &capiConnectFileSize),
- NDBD_EXIT_INVALID_CONFIG);
- ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,
- &cconnectFileSize),
- NDBD_EXIT_INVALID_CONFIG);
- ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT,
- &cfragstoreFileSize),
- NDBD_EXIT_INVALID_CONFIG);
- ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS,
- &creplicaFileSize),
- NDBD_EXIT_INVALID_CONFIG);
- ndbrequireErr(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize),
- NDBD_EXIT_INVALID_CONFIG);
- cfileFileSize = (2 * ctabFileSize) + 2;
- initRecords();
- initialiseRecordsLab(signal, 0, ref, senderData);
- return;
-}//Dbdih::execSIZEALT_REP()
-
-void Dbdih::execSTART_COPYREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dbdih::execSTART_COPYREF()
-
-void Dbdih::execSTART_FRAGCONF(Signal* signal)
-{
- (void)signal; // Don't want compiler warning
- /* ********************************************************************* */
- /* If anyone wants to add functionality in this method, be aware that */
- /* for temporary tables no START_FRAGREQ is sent and therefore no */
- /* START_FRAGCONF signal will be received for those tables!! */
- /* ********************************************************************* */
- jamEntry();
- return;
-}//Dbdih::execSTART_FRAGCONF()
-
-void Dbdih::execSTART_FRAGREF(Signal* signal)
-{
- jamEntry();
-
- /**
- * Kill starting node
- */
- Uint32 errCode = signal->theData[1];
- Uint32 nodeId = signal->theData[2];
-
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::StartFragRefError;
- sysErr->errorRef = reference();
- sysErr->data1 = errCode;
- sysErr->data2 = 0;
- sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBB);
- return;
-}//Dbdih::execSTART_FRAGCONF()
-
-void Dbdih::execSTART_MEREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dbdih::execSTART_MEREF()
-
-void Dbdih::execTAB_COMMITREQ(Signal* signal)
-{
- TabRecordPtr tabPtr;
- jamEntry();
- Uint32 tdictPtr = signal->theData[0];
- BlockReference tdictBlockref = signal->theData[1];
- tabPtr.i = signal->theData[2];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_CREATING);
- tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
- signal->theData[0] = tdictPtr;
- signal->theData[1] = cownNodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(tdictBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
- return;
-}//Dbdih::execTAB_COMMITREQ()
-
-/*
- 3.2 S T A N D A R D S U B P R O G R A M S I N P L E X
- *************************************************************
- */
-/*
- 3.2.1 S T A R T / R E S T A R T
- **********************************
- */
-/*****************************************************************************/
-/* ********** START / RESTART MODULE *************/
-/*****************************************************************************/
-/*
- 3.2.1.1 LOADING O W N B L O C K R E F E R E N C E (ABSOLUTE PHASE 1)
- *****************************************************************************
- */
-void Dbdih::execDIH_RESTARTREQ(Signal* signal)
-{
- jamEntry();
- if (signal->theData[0])
- {
- jam();
- cntrlblockref = signal->theData[0];
- if(m_ctx.m_config.getInitialStart()){
- sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
- } else {
- readGciFileLab(signal);
- }
- }
- else
- {
- /**
- * Precondition, (not checked)
- * atleast 1 node in each node group
- */
- Uint32 i;
- NdbNodeBitmask mask;
- mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
- Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
- Uint32 node_group_gcis[MAX_NDB_NODES+1];
- bzero(node_group_gcis, sizeof(node_group_gcis));
- for (i = 0; i<MAX_NDB_NODES; i++)
- {
- if (mask.get(i))
- {
- jam();
- Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
- ndbrequire(ng < MAX_NDB_NODES);
- Uint32 gci = node_gcis[i];
- if (gci < SYSFILE->lastCompletedGCI[i])
- {
- jam();
- /**
- * Handle case, where *I* know that node complete GCI
- * but node does not...bug#29167
- * i.e node died before it wrote own sysfile
- */
- gci = SYSFILE->lastCompletedGCI[i];
- }
-
- if (gci > node_group_gcis[ng])
- {
- jam();
- node_group_gcis[ng] = gci;
- }
- }
- }
- for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
-
- Uint32 gci = node_group_gcis[i];
- for (i++ ; i<MAX_NDB_NODES; i++)
- {
- jam();
- if (node_group_gcis[i] && node_group_gcis[i] != gci)
- {
- jam();
- signal->theData[0] = i;
- return;
- }
- }
- signal->theData[0] = MAX_NDB_NODES;
- return;
- }
- return;
-}//Dbdih::execDIH_RESTARTREQ()
-
-void Dbdih::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- signal->theData[0] = 0;
- signal->theData[1] = 0;
- signal->theData[2] = 0;
- signal->theData[3] = 1; // Next start phase
- signal->theData[4] = 255; // Next start phase
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- return;
-}//Dbdih::execSTTOR()
-
-void Dbdih::initialStartCompletedLab(Signal* signal)
-{
- /*-------------------------------------------------------------------------*/
- /* NOW THAT (RE)START IS COMPLETED WE CAN START THE LCP.*/
- /*-------------------------------------------------------------------------*/
- return;
-}//Dbdih::initialStartCompletedLab()
-
-/*
- * ***************************************************************************
- * S E N D I N G R E P L Y T O S T A R T / R E S T A R T R E Q U E S T S
- * ****************************************************************************
- */
-void Dbdih::ndbsttorry10Lab(Signal* signal, Uint32 _line)
-{
- /*-------------------------------------------------------------------------*/
- // AN NDB START PHASE HAS BEEN COMPLETED. WHEN START PHASE 6 IS COMPLETED WE
- // RECORD THAT THE SYSTEM IS RUNNING.
- /*-------------------------------------------------------------------------*/
- signal->theData[0] = reference();
- sendSignal(cntrlblockref, GSN_NDB_STTORRY, signal, 1, JBB);
- return;
-}//Dbdih::ndbsttorry10Lab()
-
-/*
-****************************************
-I N T E R N A L P H A S E S
-****************************************
-*/
-/*---------------------------------------------------------------------------*/
-/*NDB_STTOR START SIGNAL AT START/RESTART */
-/*---------------------------------------------------------------------------*/
-void Dbdih::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
- BlockReference cntrRef = signal->theData[0]; /* SENDERS BLOCK REFERENCE */
- Uint32 ownNodeId = signal->theData[1]; /* OWN PROCESSOR ID*/
- Uint32 phase = signal->theData[2]; /* INTERNAL START PHASE*/
- Uint32 typestart = signal->theData[3];
-
- cstarttype = typestart;
- cstartPhase = phase;
-
- switch (phase){
- case ZNDB_SPH1:
- jam();
- /*----------------------------------------------------------------------*/
- /* Set the delay between local checkpoints in ndb startphase 1. */
- /*----------------------------------------------------------------------*/
- cownNodeId = ownNodeId;
- /*-----------------------------------------------------------------------*/
- // Compute all static block references in this node as part of
- // ndb start phase 1.
- /*-----------------------------------------------------------------------*/
- cntrlblockref = cntrRef;
- clocaltcblockref = calcTcBlockRef(ownNodeId);
- clocallqhblockref = calcLqhBlockRef(ownNodeId);
- cdictblockref = calcDictBlockRef(ownNodeId);
- ndbsttorry10Lab(signal, __LINE__);
- break;
-
- case ZNDB_SPH2:
- jam();
- /*-----------------------------------------------------------------------*/
- // Set the number of replicas, maximum is 4 replicas.
- // Read the ndb nodes from the configuration.
- /*-----------------------------------------------------------------------*/
-
- /*-----------------------------------------------------------------------*/
- // For node restarts we will also add a request for permission
- // to continue the system restart.
- // The permission is given by the master node in the alive set.
- /*-----------------------------------------------------------------------*/
- createMutexes(signal, 0);
- if (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)
- {
- jam();
- c_set_initial_start_flag = TRUE; // In sysfile...
- }
- break;
-
- case ZNDB_SPH3:
- jam();
- /*-----------------------------------------------------------------------*/
- // Non-master nodes performing an initial start will execute
- // the start request here since the
- // initial start do not synchronise so much from the master.
- // In the master nodes the start
- // request will be sent directly to dih (in ndb_startreq) when all
- // nodes have completed phase 3 of the start.
- /*-----------------------------------------------------------------------*/
- cmasterState = MASTER_IDLE;
- if(cstarttype == NodeState::ST_INITIAL_START ||
- cstarttype == NodeState::ST_SYSTEM_RESTART){
- jam();
- cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE;
- }
- if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) {
- jam();
- ndbStartReqLab(signal, cntrRef);
- return;
- }//if
- ndbsttorry10Lab(signal, __LINE__);
- break;
-
- case ZNDB_SPH4:
- jam();
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- cmasterTakeOverNode = ZNIL;
- switch(typestart){
- case NodeState::ST_INITIAL_START:
- jam();
- ndbsttorry10Lab(signal, __LINE__);
- return;
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- if (isMaster()) {
- jam();
- systemRestartTakeOverLab(signal);
- if (anyActiveTakeOver())
- {
- jam();
- return;
- }
- }
- ndbsttorry10Lab(signal, __LINE__);
- return;
- case NodeState::ST_INITIAL_NODE_RESTART:
- case NodeState::ST_NODE_RESTART:
- jam();
-
- /***********************************************************************
- * When starting nodes while system is operational we must be controlled
- * by the master since only one node restart is allowed at a time.
- * When this signal is confirmed the master has also copied the
- * dictionary and the distribution information.
- */
- StartMeReq * req = (StartMeReq*)&signal->theData[0];
- req->startingRef = reference();
- req->startingVersion = 0; // Obsolete
- sendSignal(cmasterdihref, GSN_START_MEREQ, signal,
- StartMeReq::SignalLength, JBB);
- return;
- }
- ndbrequire(false);
- break;
- case ZNDB_SPH5:
- jam();
- switch(typestart){
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- jam();
- /*---------------------------------------------------------------------*/
- // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART.
- // THE IDEA IS THAT WE NEED TO
- // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE
- // CRASHES THAT CAUSES THE LOG
- // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW.
- // THIS CAN OTHERWISE GET US INTO
- // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT
- // BEFORE ALLOWING ANY TRANSACTIONS TO START.
- /*---------------------------------------------------------------------*/
- if (!isMaster()) {
- jam();
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }//if
-
- c_lcpState.immediateLcpStart = true;
- cwaitLcpSr = true;
- checkLcpStart(signal, __LINE__);
- return;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- signal->theData[0] = cownNodeId;
- signal->theData[1] = reference();
- sendSignal(cmasterdihref, GSN_START_COPYREQ, signal, 2, JBB);
- return;
- }
- ndbrequire(false);
- case ZNDB_SPH6:
- jam();
- switch(typestart){
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- if(isMaster()){
- jam();
- startGcp(signal);
- }
- ndbsttorry10Lab(signal, __LINE__);
- return;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }
- ndbrequire(false);
- break;
- default:
- jam();
- ndbsttorry10Lab(signal, __LINE__);
- break;
- }//switch
-}//Dbdih::execNDB_STTOR()
-
-void
-Dbdih::execNODE_START_REP(Signal* signal)
-{
- /*
- * Send DICT_UNLOCK_ORD when this node is SL_STARTED.
- *
- * Sending it before (sp 7) conflicts with code which assumes
- * SL_STARTING means we are in copy phase of NR.
- *
- * NodeState::starting.restartType is not supposed to be used
- * when SL_STARTED. Also it seems NODE_START_REP can arrive twice.
- *
- * For these reasons there are no consistency checks and
- * we rely on c_dictLockSlavePtrI_nodeRestart alone.
- */
- if (c_dictLockSlavePtrI_nodeRestart != RNIL) {
- sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
- c_dictLockSlavePtrI_nodeRestart = RNIL;
- }
-}
-
-void
-Dbdih::createMutexes(Signal * signal, Uint32 count){
- Callback c = { safe_cast(&Dbdih::createMutex_done), count };
-
- switch(count){
- case 0:{
- Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
- mutex.create(c);
- return;
- }
- case 1:{
- Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
- mutex.create(c);
- return;
- }
- }
-
- signal->theData[0] = reference();
- sendSignal(cntrlblockref, GSN_READ_NODESREQ, signal, 1, JBB);
-}
-
-void
-Dbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){
- jamEntry();
- ndbrequire(retVal == 0);
-
- switch(senderData){
- case 0:{
- Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
- mutex.release();
- }
- case 1:{
- Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
- mutex.release();
- }
- }
-
- createMutexes(signal, senderData + 1);
-}
-
-/*****************************************************************************/
-/* ------------------------------------------------------------------------- */
-/* WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE */
-/* DATABASE TABLES. */
-/* THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A */
-/* SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN */
-/* INITIAL START. */
-/* ------------------------------------------------------------------------- */
-/*****************************************************************************/
-void Dbdih::execNDB_STARTREQ(Signal* signal)
-{
- jamEntry();
- BlockReference ref = signal->theData[0];
- cstarttype = signal->theData[1];
- ndbStartReqLab(signal, ref);
-}//Dbdih::execNDB_STARTREQ()
-
-void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref)
-{
- cndbStartReqBlockref = ref;
- if (cstarttype == NodeState::ST_INITIAL_START) {
- jam();
- initRestartInfo();
- initGciFilesLab(signal);
- return;
- }
-
- NodeRecordPtr nodePtr;
- Uint32 gci = SYSFILE->lastCompletedGCI[getOwnNodeId()];
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++)
- {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci)
- {
- jam();
- /**
- * Since we're starting(is master) and there
- * there are other nodes with higher GCI...
- * there gci's must be invalidated...
- * and they _must_ do an initial start
- * indicate this by setting lastCompletedGCI = 0
- */
- SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
- ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
- warningEvent("Making filesystem for node %d unusable (need --initial)",
- nodePtr.i);
- }
- else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
- SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
- {
- jam();
- CRASH_INSERTION(7170);
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Cluster requires this node to be started "
- " with --initial as partial start has been performed"
- " and this filesystem is unusable");
- progError(__LINE__,
- NDBD_EXIT_SR_RESTARTCONFLICT,
- buf);
- ndbrequire(false);
- }
- }
-
- /**
- * This set which GCI we will try to restart to
- */
- SYSFILE->newestRestorableGCI = gci;
-
- ndbrequire(isMaster());
- copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
-}//Dbdih::ndbStartReqLab()
-
-void Dbdih::execREAD_NODESCONF(Signal* signal)
-{
- unsigned i;
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
- jamEntry();
- Uint32 nodeArray[MAX_NDB_NODES];
-
- csystemnodes = readNodes->noOfNodes;
- cmasterNodeId = readNodes->masterNodeId;
- int index = 0;
- NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes);
- for (i = 1; i < MAX_NDB_NODES; i++){
- jam();
- if(tmp.get(i)){
- jam();
- nodeArray[index] = i;
- if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){
- jam();
- con_lineNodes++;
- }//if
- index++;
- }//if
- }//for
-
- if(cstarttype == NodeState::ST_SYSTEM_RESTART ||
- cstarttype == NodeState::ST_NODE_RESTART){
-
- for(i = 1; i<MAX_NDB_NODES; i++){
- const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus);
- if(stat == Sysfile::NS_NotDefined && !tmp.get(i)){
- jam();
- continue;
- }
-
- if(tmp.get(i) && stat != Sysfile::NS_NotDefined){
- jam();
- continue;
- }
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Illegal configuration change."
- " Initial start needs to be performed "
- " when changing no of storage nodes (node %d)", i);
- progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
- }
- }
-
- ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES);
- if (cstarttype == NodeState::ST_INITIAL_START) {
- jam();
- ndbrequire(cnoReplicas <= csystemnodes);
- calculateHotSpare();
- ndbrequire(cnoReplicas <= (csystemnodes - cnoHotSpare));
- }//if
-
- cmasterdihref = calcDihBlockRef(cmasterNodeId);
- /*-------------------------------------------------------------------------*/
- /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/
- /*-------------------------------------------------------------------------*/
- makePrnList(readNodes, nodeArray);
- if (cstarttype == NodeState::ST_INITIAL_START) {
- jam();
- /**----------------------------------------------------------------------
- * WHEN WE INITIALLY START A DATABASE WE WILL CREATE NODE GROUPS.
- * ALL NODES ARE PUT INTO NODE GROUPS ALTHOUGH HOT SPARE NODES ARE PUT
- * INTO A SPECIAL NODE GROUP. IN EACH NODE GROUP WE HAVE THE SAME AMOUNT
- * OF NODES AS THERE ARE NUMBER OF REPLICAS.
- * ONE POSSIBLE USAGE OF NODE GROUPS ARE TO MAKE A NODE GROUP A COMPLETE
- * FRAGMENT OF THE DATABASE. THIS MEANS THAT ALL REPLICAS WILL BE STORED
- * IN THE NODE GROUP.
- *-----------------------------------------------------------------------*/
- makeNodeGroups(nodeArray);
- }//if
- ndbrequire(checkNodeAlive(cmasterNodeId));
- if (cstarttype == NodeState::ST_INITIAL_START) {
- jam();
- /**-----------------------------------------------------------------------
- * INITIALISE THE SECOND NODE-LIST AND SET NODE BITS AND SOME NODE STATUS.
- * VERY CONNECTED WITH MAKE_NODE_GROUPS. CHANGING ONE WILL AFFECT THE
- * OTHER AS WELL.
- *-----------------------------------------------------------------------*/
- setInitialActiveStatus();
- } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) {
- jam();
- /*empty*/;
- } else if ((cstarttype == NodeState::ST_NODE_RESTART) ||
- (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- nodeRestartPh2Lab(signal);
- return;
- } else {
- ndbrequire(false);
- }//if
- /**------------------------------------------------------------------------
- * ESTABLISH CONNECTIONS WITH THE OTHER DIH BLOCKS AND INITIALISE THIS
- * NODE-LIST THAT HANDLES CONNECTION WITH OTHER DIH BLOCKS.
- *-------------------------------------------------------------------------*/
- ndbsttorry10Lab(signal, __LINE__);
-}//Dbdih::execREAD_NODESCONF()
-
-/*---------------------------------------------------------------------------*/
-/* START NODE LOGIC FOR NODE RESTART */
-/*---------------------------------------------------------------------------*/
-void Dbdih::nodeRestartPh2Lab(Signal* signal)
-{
- /*
- * Lock master DICT to avoid metadata operations during INR/NR.
- * Done just before START_PERMREQ.
- *
- * It would be more elegant to do this just before START_MEREQ.
- * The problem is, on INR we end up in massive invalidateNodeLCP
- * which is not fully protected against metadata ops.
- */
- ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
-
- // check that we are not yet taking part in schema ops
- CRASH_INSERTION(7174);
-
- Uint32 lockType = DictLockReq::NodeRestartLock;
- Callback c = { safe_cast(&Dbdih::recvDictLockConf_nodeRestart), 0 };
- sendDictLockReq(signal, lockType, c);
-}
-
-void Dbdih::recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret)
-{
- ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
- ndbrequire(data != RNIL);
- c_dictLockSlavePtrI_nodeRestart = data;
-
- nodeRestartPh2Lab2(signal);
-}
-
-void Dbdih::nodeRestartPh2Lab2(Signal* signal)
-{
- /*------------------------------------------------------------------------*/
- // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY
- // RUNNING SYSTEM.
- /*------------------------------------------------------------------------*/
- StartPermReq * const req = (StartPermReq *)&signal->theData[0];
-
- req->blockRef = reference();
- req->nodeId = cownNodeId;
- req->startType = cstarttype;
- sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);
-}
-
-void Dbdih::execSTART_PERMCONF(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(7121);
- Uint32 nodeId = signal->theData[0];
- cfailurenr = signal->theData[1];
- ndbrequire(nodeId == cownNodeId);
- ndbsttorry10Lab(signal, __LINE__);
-}//Dbdih::execSTART_PERMCONF()
-
-void Dbdih::execSTART_PERMREF(Signal* signal)
-{
- jamEntry();
- Uint32 errorCode = signal->theData[1];
- if (errorCode == StartPermRef::ZNODE_ALREADY_STARTING_ERROR ||
- errorCode == StartPermRef::ZNODE_START_DISALLOWED_ERROR) {
- jam();
- /*-----------------------------------------------------------------------*/
- // The master was busy adding another node. We will wait for a second and
- // try again.
- /*-----------------------------------------------------------------------*/
- signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
- return;
- }//if
-
- if (errorCode == StartPermRef::InitialStartRequired)
- {
- CRASH_INSERTION(7170);
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Cluster requires this node to be started "
- " with --initial as partial start has been performed"
- " and this filesystem is unusable");
- progError(__LINE__,
- NDBD_EXIT_SR_RESTARTCONFLICT,
- buf);
- ndbrequire(false);
- }
- /*------------------------------------------------------------------------*/
- // Some node process in another node involving our node was still active. We
- // will recover from this by crashing here.
- // This is controlled restart using the
- // already existing features of node crashes. It is not a bug getting here.
- /*-------------------------------------------------------------------------*/
- ndbrequire(false);
- return;
-}//Dbdih::execSTART_PERMREF()
-
-/*---------------------------------------------------------------------------*/
-/* THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ */
-/* HAS BEEN EXECUTED IN THE MASTER NODE. */
-/*---------------------------------------------------------------------------*/
-void Dbdih::execSTART_MECONF(Signal* signal)
-{
- jamEntry();
- StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
- Uint32 nodeId = startMe->startingNodeId;
- const Uint32 startWord = startMe->startWord;
- Uint32 i;
-
- CRASH_INSERTION(7130);
- ndbrequire(nodeId == cownNodeId);
- arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4);
- for(i = 0; i < StartMeConf::DATA_SIZE; i++)
- cdata[startWord+i] = startMe->data[i];
-
- if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){
- jam();
- /**
- * We are still waiting for data
- */
- return;
- }
- jam();
-
- /**
- * Copy into sysfile
- *
- * But dont copy lastCompletedGCI:s
- */
- Uint32 key = SYSFILE->m_restart_seq;
- Uint32 tempGCP[MAX_NDB_NODES];
- for(i = 0; i < MAX_NDB_NODES; i++)
- tempGCP[i] = SYSFILE->lastCompletedGCI[i];
-
- for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
- sysfileData[i] = cdata[i];
-
- SYSFILE->m_restart_seq = key;
- for(i = 0; i < MAX_NDB_NODES; i++)
- SYSFILE->lastCompletedGCI[i] = tempGCP[i];
-
- setNodeActiveStatus();
- setNodeGroups();
- ndbsttorry10Lab(signal, __LINE__);
-}//Dbdih::execSTART_MECONF()
-
-void Dbdih::execSTART_COPYCONF(Signal* signal)
-{
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- ndbrequire(nodeId == cownNodeId);
- CRASH_INSERTION(7132);
- ndbsttorry10Lab(signal, __LINE__);
- return;
-}//Dbdih::execSTART_COPYCONF()
-
-/*---------------------------------------------------------------------------*/
-/* MASTER LOGIC FOR NODE RESTART */
-/*---------------------------------------------------------------------------*/
-/* NODE RESTART PERMISSION REQUEST */
-/*---------------------------------------------------------------------------*/
-// A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE
-// IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN
-// THIS NODE INVOLVING THE STARTING NODE THIS REQUEST WILL BE GRANTED.
-/*---------------------------------------------------------------------------*/
-void Dbdih::execSTART_PERMREQ(Signal* signal)
-{
- StartPermReq * const req = (StartPermReq*)&signal->theData[0];
- jamEntry();
- const BlockReference retRef = req->blockRef;
- const Uint32 nodeId = req->nodeId;
- const Uint32 typeStart = req->startType;
- CRASH_INSERTION(7122);
- ndbrequire(isMaster());
- ndbrequire(refToNode(retRef) == nodeId);
- if ((c_nodeStartMaster.activeState) ||
- (c_nodeStartMaster.wait != ZFALSE) ||
- ERROR_INSERTED_CLEAR(7175)) {
- jam();
- signal->theData[0] = nodeId;
- signal->theData[1] = StartPermRef::ZNODE_ALREADY_STARTING_ERROR;
- sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
- return;
- }//if
- if (getNodeStatus(nodeId) != NodeRecord::DEAD){
- g_eventLogger.error("nodeStatus in START_PERMREQ = %u",
- (Uint32) getNodeStatus(nodeId));
- ndbrequire(false);
- }//if
-
- if (SYSFILE->lastCompletedGCI[nodeId] == 0 &&
- typeStart != NodeState::ST_INITIAL_NODE_RESTART)
- {
- jam();
- signal->theData[0] = nodeId;
- signal->theData[1] = StartPermRef::InitialStartRequired;
- sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
- return;
- }
-
- /*----------------------------------------------------------------------
- * WE START THE INCLUSION PROCEDURE
- * ---------------------------------------------------------------------*/
- c_nodeStartMaster.failNr = cfailurenr;
- c_nodeStartMaster.wait = ZFALSE;
- 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
- *
- * We first have to clear LCP's
- * For normal node restart we simply ensure that all nodes
- * are informed of the node restart
- */
- StartInfoReq *const r =(StartInfoReq*)&signal->theData[0];
- r->startingNodeId = nodeId;
- r->typeStart = typeStart;
- r->systemFailureNo = cfailurenr;
- sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ);
-}//Dbdih::execSTART_PERMREQ()
-
-void Dbdih::execSTART_INFOREF(Signal* signal)
-{
- StartInfoRef * ref = (StartInfoRef*)&signal->theData[0];
- if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) {
- jam();
- return;
- }//if
- ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId);
- c_nodeStartMaster.startInfoErrorCode = ref->errorCode;
- startInfoReply(signal, ref->sendingNodeId);
-}//Dbdih::execSTART_INFOREF()
-
-void Dbdih::execSTART_INFOCONF(Signal* signal)
-{
- jamEntry();
- StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
- if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) {
- jam();
- return;
- }//if
- ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId);
- startInfoReply(signal, conf->sendingNodeId);
-}//Dbdih::execSTART_INFOCONF()
-
-void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId)
-{
- receiveLoopMacro(START_INFOREQ, nodeId);
- /**
- * We're finished with the START_INFOREQ's
- */
- if (c_nodeStartMaster.startInfoErrorCode == 0) {
- jam();
- /**
- * Everything has been a success so far
- */
- StartPermConf * conf = (StartPermConf*)&signal->theData[0];
- conf->startingNodeId = c_nodeStartMaster.startNode;
- conf->systemFailureNo = cfailurenr;
- sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
- GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB);
- c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF;
- } else {
- jam();
- StartPermRef * ref = (StartPermRef*)&signal->theData[0];
- ref->startingNodeId = c_nodeStartMaster.startNode;
- ref->errorCode = c_nodeStartMaster.startInfoErrorCode;
- sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode),
- GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB);
- nodeResetStart();
- }//if
-}//Dbdih::startInfoReply()
-
-/*---------------------------------------------------------------------------*/
-/* NODE RESTART CONTINUE REQUEST */
-/*---------------------------------------------------------------------------*/
-// THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN
-// REQUESTED TO START UP A NEW NODE. The master instructs the starting node
-// how to set up its log for continued execution.
-/*---------------------------------------------------------------------------*/
-void Dbdih::execSTART_MEREQ(Signal* signal)
-{
- StartMeReq * req = (StartMeReq*)&signal->theData[0];
- jamEntry();
- const BlockReference Tblockref = req->startingRef;
- const Uint32 Tnodeid = refToNode(Tblockref);
-
- ndbrequire(isMaster());
- ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
- ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
-
- c_nodeStartMaster.blockLcp = true;
- if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
- (c_lcpState.lcpStatus != LCP_TCGET)) {
- jam();
- /*-----------------------------------------------------------------------*/
- // WE WILL NOT ALLOW A NODE RESTART TO COME IN WHEN A LOCAL CHECKPOINT IS
- // ONGOING. IT WOULD COMPLICATE THE LCP PROTOCOL TOO MUCH. WE WILL ADD THIS
- // LATER.
- /*-----------------------------------------------------------------------*/
- return;
- }//if
- lcpBlockedLab(signal);
-}//Dbdih::nodeRestartStartRecConfLab()
-
-void Dbdih::lcpBlockedLab(Signal* signal)
-{
- ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING);
- /*------------------------------------------------------------------------*/
- // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL
- // INFORMATION IN DIH TO THE NEW NODE.
- /*------------------------------------------------------------------------*/
- c_nodeStartMaster.wait = 10;
- signal->theData[0] = DihContinueB::ZCOPY_NODE;
- signal->theData[1] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;
-}//Dbdih::lcpBlockedLab()
-
-void Dbdih::nodeDictStartConfLab(Signal* signal)
-{
- /*-------------------------------------------------------------------------*/
- // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO
- // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF
- // THE DICTIONARY AGAIN.
- /*-------------------------------------------------------------------------*/
- c_nodeStartMaster.wait = ZFALSE;
- c_nodeStartMaster.blockGcp = true;
- if (cgcpStatus != GCP_READY) {
- /*-----------------------------------------------------------------------*/
- // The global checkpoint is executing. Wait until it is completed before we
- // continue processing the node recovery.
- /*-----------------------------------------------------------------------*/
- jam();
- return;
- }//if
- gcpBlockedLab(signal);
-
- /*-----------------------------------------------------------------*/
- // Report that node restart has completed copy of dictionary.
- /*-----------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_NR_CopyDict;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-}//Dbdih::nodeDictStartConfLab()
-
-void Dbdih::dihCopyCompletedLab(Signal* signal)
-{
- BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode);
- DictStartReq * req = (DictStartReq*)&signal->theData[0];
- req->restartGci = cnewgcp;
- req->senderRef = reference();
- sendSignal(ref, GSN_DICTSTARTREQ,
- signal, DictStartReq::SignalLength, JBB);
- c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ;
- c_nodeStartMaster.wait = 0;
-}//Dbdih::dihCopyCompletedLab()
-
-void Dbdih::gcpBlockedLab(Signal* signal)
-{
- /*-----------------------------------------------------------------*/
- // Report that node restart has completed copy of distribution info.
- /*-----------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_NR_CopyDistr;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-
- /**
- * The node DIH will be part of LCP
- */
- NodeRecordPtr nodePtr;
- nodePtr.i = c_nodeStartMaster.startNode;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->m_inclDihLcp = true;
-
- /*-------------------------------------------------------------------------*/
- // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED
- // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH.
- /*------------------------------------------------------------------------*/
- sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ);
- /*-------------------------------------------------------------------------*/
- // We also need to send to the starting node to ensure he is aware of the
- // global checkpoint id and the correct state. We do not wait for any reply
- // since the starting node will not send any.
- /*-------------------------------------------------------------------------*/
- Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version;
-
- if ((getMajor(startVersion) == 4 &&
- startVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
- (getMajor(startVersion) == 5 &&
- startVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
- (getMajor(startVersion) > 5))
- {
- c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode);
- }
-
- sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode);
-}//Dbdih::gcpBlockedLab()
-
-/*---------------------------------------------------------------------------*/
-// THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER
-/*---------------------------------------------------------------------------*/
-void Dbdih::execINCL_NODECONF(Signal* signal)
-{
- jamEntry();
- Uint32 TstartNode = signal->theData[0];
- Uint32 TsendNodeId_or_blockref = signal->theData[1];
-
- Uint32 blocklist[6];
- blocklist[0] = clocallqhblockref;
- blocklist[1] = clocaltcblockref;
- blocklist[2] = cdictblockref;
- blocklist[3] = numberToRef(BACKUP, getOwnNodeId());
- blocklist[4] = numberToRef(SUMA, getOwnNodeId());
- blocklist[5] = 0;
-
- for (Uint32 i = 0; blocklist[i] != 0; i++)
- {
- if (TsendNodeId_or_blockref == blocklist[i])
- {
- jam();
-
- if (TstartNode != c_nodeStartSlave.nodeId)
- {
- jam();
- warningEvent("Recevied INCL_NODECONF for %u from %s"
- " while %u is starting",
- TstartNode,
- getBlockName(refToBlock(TsendNodeId_or_blockref)),
- c_nodeStartSlave.nodeId);
- return;
- }
-
- if (getNodeStatus(c_nodeStartSlave.nodeId) == NodeRecord::ALIVE &&
- blocklist[i+1] != 0)
- {
- /**
- * Send to next in block list
- */
- jam();
- signal->theData[0] = reference();
- signal->theData[1] = c_nodeStartSlave.nodeId;
- sendSignal(blocklist[i+1], GSN_INCL_NODEREQ, signal, 2, JBB);
- return;
- }
- else
- {
- /**
- * All done, reply to master
- */
- jam();
- signal->theData[0] = c_nodeStartSlave.nodeId;
- signal->theData[1] = cownNodeId;
- sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
-
- c_nodeStartSlave.nodeId = 0;
- return;
- }
- }
- }
-
- if (c_nodeStartMaster.startNode != TstartNode)
- {
- jam();
- warningEvent("Recevied INCL_NODECONF for %u from %u"
- " while %u is starting",
- TstartNode,
- TsendNodeId_or_blockref,
- c_nodeStartMaster.startNode);
- return;
- }
-
- ndbrequire(cmasterdihref = reference());
- receiveLoopMacro(INCL_NODEREQ, TsendNodeId_or_blockref);
-
- CRASH_INSERTION(7128);
- /*-------------------------------------------------------------------------*/
- // Now that we have included the starting node in the node lists in the
- // various blocks we are ready to start the global checkpoint protocol
- /*------------------------------------------------------------------------*/
- c_nodeStartMaster.wait = 11;
- c_nodeStartMaster.blockGcp = false;
-
- signal->theData[0] = reference();
- sendSignal(reference(), GSN_UNBLO_DICTCONF, signal, 1, JBB);
-}//Dbdih::execINCL_NODECONF()
-
-void Dbdih::execUNBLO_DICTCONF(Signal* signal)
-{
- jamEntry();
- c_nodeStartMaster.wait = ZFALSE;
- if (!c_nodeStartMaster.activeState) {
- jam();
- return;
- }//if
-
- CRASH_INSERTION(7129);
- /**-----------------------------------------------------------------------
- * WE HAVE NOW PREPARED IT FOR INCLUSION IN THE LCP PROTOCOL.
- * WE CAN NOW START THE LCP PROTOCOL AGAIN.
- * WE HAVE ALSO MADE THIS FOR THE GCP PROTOCOL.
- * WE ARE READY TO START THE PROTOCOLS AND RESPOND TO THE START REQUEST
- * FROM THE STARTING NODE.
- *------------------------------------------------------------------------*/
-
- StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
-
- const Uint32 wordPerSignal = StartMeConf::DATA_SIZE;
- const int noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
- wordPerSignal);
-
- startMe->startingNodeId = c_nodeStartMaster.startNode;
- startMe->startWord = 0;
-
- const Uint32 ref = calcDihBlockRef(c_nodeStartMaster.startNode);
- for(int i = 0; i < noOfSignals; i++){
- jam();
- { // Do copy
- const int startWord = startMe->startWord;
- for(Uint32 j = 0; j < wordPerSignal; j++){
- startMe->data[j] = sysfileData[j+startWord];
- }
- }
- sendSignal(ref, GSN_START_MECONF, signal, StartMeConf::SignalLength, JBB);
- startMe->startWord += wordPerSignal;
- }//for
- c_nodeStartMaster.m_outstandingGsn = GSN_START_MECONF;
-}//Dbdih::execUNBLO_DICTCONF()
-
-/*---------------------------------------------------------------------------*/
-/* NODE RESTART COPY REQUEST */
-/*---------------------------------------------------------------------------*/
-// A NODE RESTART HAS REACHED ITS FINAL PHASE WHEN THE DATA IS TO BE COPIED
-// TO THE NODE. START_COPYREQ IS EXECUTED BY THE MASTER NODE.
-/*---------------------------------------------------------------------------*/
-void Dbdih::execSTART_COPYREQ(Signal* signal)
-{
- jamEntry();
- Uint32 startNodeId = signal->theData[0];
- //BlockReference startingRef = signal->theData[1];
- ndbrequire(c_nodeStartMaster.startNode == startNodeId);
- /*-------------------------------------------------------------------------*/
- // REPORT Copy process of node restart is now about to start up.
- /*-------------------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_NR_CopyFragsStarted;
- signal->theData[1] = startNodeId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- CRASH_INSERTION(7131);
- nodeRestartTakeOver(signal, startNodeId);
- // BlockReference ref = calcQmgrBlockRef(startNodeId);
- // signal->theData[0] = cownNodeId;
- // Remove comments as soon as I open up the Qmgr block
- // TODO_RONM
- // sendSignal(ref, GSN_ALLOW_NODE_CRASHORD, signal, 1, JBB);
-}//Dbdih::execSTART_COPYREQ()
-
-/*---------------------------------------------------------------------------*/
-/* SLAVE LOGIC FOR NODE RESTART */
-/*---------------------------------------------------------------------------*/
-void Dbdih::execSTART_INFOREQ(Signal* signal)
-{
- jamEntry();
- StartInfoReq *const req =(StartInfoReq*)&signal->theData[0];
- Uint32 startNode = req->startingNodeId;
- if (cfailurenr != req->systemFailureNo) {
- jam();
- //---------------------------------------------------------------
- // A failure occurred since master sent this request. We will ignore
- // this request since the node is already dead that is starting.
- //---------------------------------------------------------------
- return;
- }//if
- CRASH_INSERTION(7123);
- if (isMaster()) {
- jam();
- ndbrequire(getNodeStatus(startNode) == NodeRecord::STARTING);
- } else {
- jam();
- ndbrequire(getNodeStatus(startNode) == NodeRecord::DEAD);
- }//if
- if ((!getAllowNodeStart(startNode)) ||
- (c_nodeStartSlave.nodeId != 0) ||
- (ERROR_INSERTED(7124))) {
- jam();
- StartInfoRef *const ref =(StartInfoRef*)&signal->theData[0];
- ref->startingNodeId = startNode;
- ref->sendingNodeId = cownNodeId;
- ref->errorCode = StartPermRef::ZNODE_START_DISALLOWED_ERROR;
- sendSignal(cmasterdihref, GSN_START_INFOREF, signal,
- StartInfoRef::SignalLength, JBB);
- return;
- }//if
- setNodeStatus(startNode, NodeRecord::STARTING);
- if (req->typeStart == NodeState::ST_INITIAL_NODE_RESTART) {
- jam();
- setAllowNodeStart(startNode, false);
- invalidateNodeLCP(signal, startNode, 0);
- } else {
- jam();
- StartInfoConf * c = (StartInfoConf*)&signal->theData[0];
- c->sendingNodeId = cownNodeId;
- c->startingNodeId = startNode;
- sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
- StartInfoConf::SignalLength, JBB);
- return;
- }//if
-}//Dbdih::execSTART_INFOREQ()
-
-void Dbdih::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
- Uint32 retRef = signal->theData[0];
- Uint32 nodeId = signal->theData[1];
- if (nodeId == getOwnNodeId() && ERROR_INSERTED(7165))
- {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(reference(), GSN_INCL_NODEREQ, signal, 5000, signal->getLength());
- return;
- }
-
- Uint32 tnodeStartFailNr = signal->theData[2];
- currentgcp = signal->theData[4];
- CRASH_INSERTION(7127);
- cnewgcp = currentgcp;
- coldgcp = currentgcp - 1;
- if (!isMaster()) {
- jam();
- /*-----------------------------------------------------------------------*/
- // We don't want to change the state of the master since he can be in the
- // state LCP_TCGET at this time.
- /*-----------------------------------------------------------------------*/
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- }//if
-
- /*-------------------------------------------------------------------------*/
- // When a node is restarted we must ensure that a lcp will be run
- // as soon as possible and the reset the delay according to the original
- // configuration.
- // Without an initial local checkpoint the new node will not be available.
- /*-------------------------------------------------------------------------*/
- if (getOwnNodeId() == nodeId) {
- jam();
- /*-----------------------------------------------------------------------*/
- // We are the starting node. We came here only to set the global checkpoint
- // id's and the lcp status.
- /*-----------------------------------------------------------------------*/
- CRASH_INSERTION(7171);
- Uint32 masterVersion = getNodeInfo(refToNode(cmasterdihref)).m_version;
-
- if ((NDB_VERSION_MAJOR == 4 &&
- masterVersion >= NDBD_INCL_NODECONF_VERSION_4) ||
- (NDB_VERSION_MAJOR == 5 &&
- masterVersion >= NDBD_INCL_NODECONF_VERSION_5) ||
- (NDB_VERSION_MAJOR > 5))
- {
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = getOwnNodeId();
- sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
- }
- return;
- }//if
- if (getNodeStatus(nodeId) != NodeRecord::STARTING) {
- jam();
- return;
- }//if
- ndbrequire(cfailurenr == tnodeStartFailNr);
- ndbrequire (c_nodeStartSlave.nodeId == 0);
- c_nodeStartSlave.nodeId = nodeId;
-
- ndbrequire (retRef == cmasterdihref);
-
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- Sysfile::ActiveStatus TsaveState = nodePtr.p->activeStatus;
- Uint32 TnodeGroup = nodePtr.p->nodeGroup;
-
- new (nodePtr.p) NodeRecord();
- nodePtr.p->nodeGroup = TnodeGroup;
- nodePtr.p->activeStatus = TsaveState;
- nodePtr.p->nodeStatus = NodeRecord::ALIVE;
- nodePtr.p->useInTransactions = true;
- nodePtr.p->m_inclDihLcp = true;
-
- removeDeadNode(nodePtr);
- insertAlive(nodePtr);
- con_lineNodes++;
-
- /*-------------------------------------------------------------------------*/
- // WE WILL ALSO SEND THE INCLUDE NODE REQUEST TO THE LOCAL LQH BLOCK.
- /*-------------------------------------------------------------------------*/
- signal->theData[0] = reference();
- signal->theData[1] = nodeId;
- signal->theData[2] = currentgcp;
- sendSignal(clocallqhblockref, GSN_INCL_NODEREQ, signal, 3, JBB);
-}//Dbdih::execINCL_NODEREQ()
-
-/* ------------------------------------------------------------------------- */
-// execINCL_NODECONF() is found in the master logic part since it is used by
-// both the master and the slaves.
-/* ------------------------------------------------------------------------- */
-
-/*****************************************************************************/
-/*********** TAKE OVER DECISION MODULE *************/
-/*****************************************************************************/
-// This module contains the subroutines that take the decision whether to take
-// over a node now or not.
-/* ------------------------------------------------------------------------- */
-/* MASTER LOGIC FOR SYSTEM RESTART */
-/* ------------------------------------------------------------------------- */
-// WE ONLY COME HERE IF WE ARE THE MASTER AND WE ARE PERFORMING A SYSTEM
-// RESTART. WE ALSO COME HERE DURING THIS SYSTEM RESTART ONE TIME PER NODE
-// THAT NEEDS TAKE OVER.
-/*---------------------------------------------------------------------------*/
-// WE CHECK IF ANY NODE NEEDS TO BE TAKEN OVER AND THE TAKE OVER HAS NOT YET
-// BEEN STARTED OR COMPLETED.
-/*---------------------------------------------------------------------------*/
-void
-Dbdih::systemRestartTakeOverLab(Signal* signal)
-{
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- jam();
- break;
- /*---------------------------------------------------------------------*/
- // WE HAVE NOT REACHED A STATE YET WHERE THIS NODE NEEDS TO BE TAKEN OVER
- /*---------------------------------------------------------------------*/
- case Sysfile::NS_ActiveMissed_2:
- case Sysfile::NS_NotActive_NotTakenOver:
- jam();
- /*---------------------------------------------------------------------*/
- // THIS NODE IS IN TROUBLE.
- // WE MUST SUCCEED WITH A LOCAL CHECKPOINT WITH THIS NODE TO REMOVE THE
- // DANGER. IF THE NODE IS NOT ALIVE THEN THIS WILL NOT BE
- // POSSIBLE AND WE CAN START THE TAKE OVER IMMEDIATELY IF WE HAVE ANY
- // NODES THAT CAN PERFORM A TAKE OVER.
- /*---------------------------------------------------------------------*/
- if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
- jam();
- Uint32 ThotSpareNode = findHotSpare();
- if (ThotSpareNode != RNIL) {
- jam();
- startTakeOver(signal, RNIL, ThotSpareNode, nodePtr.i);
- }//if
- } else if(nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver){
- jam();
- /*-------------------------------------------------------------------*/
- // NOT ACTIVE NODES THAT HAVE NOT YET BEEN TAKEN OVER NEEDS TAKE OVER
- // IMMEDIATELY. IF WE ARE ALIVE WE TAKE OVER OUR OWN NODE.
- /*-------------------------------------------------------------------*/
- infoEvent("Take over of node %d started",
- nodePtr.i);
- startTakeOver(signal, RNIL, nodePtr.i, nodePtr.i);
- }//if
- break;
- case Sysfile::NS_TakeOver:
- /**-------------------------------------------------------------------
- * WE MUST HAVE FAILED IN THE MIDDLE OF THE TAKE OVER PROCESS.
- * WE WILL CONCLUDE THE TAKE OVER PROCESS NOW.
- *-------------------------------------------------------------------*/
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- Uint32 takeOverNode = Sysfile::getTakeOverNode(nodePtr.i,
- SYSFILE->takeOver);
- if(takeOverNode == 0){
- jam();
- warningEvent("Bug in take-over code restarting");
- takeOverNode = nodePtr.i;
- }
- startTakeOver(signal, RNIL, nodePtr.i, takeOverNode);
- } else {
- jam();
- /**-------------------------------------------------------------------
- * We are not currently taking over, change our active status.
- *-------------------------------------------------------------------*/
- nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- setNodeRestartInfoBits();
- }//if
- break;
- case Sysfile::NS_HotSpare:
- jam();
- break;
- /*---------------------------------------------------------------------*/
- // WE NEED NOT TAKE OVER NODES THAT ARE HOT SPARE.
- /*---------------------------------------------------------------------*/
- case Sysfile::NS_NotDefined:
- jam();
- break;
- /*---------------------------------------------------------------------*/
- // WE NEED NOT TAKE OVER NODES THAT DO NOT EVEN EXIST IN THE CLUSTER.
- /*---------------------------------------------------------------------*/
- default:
- ndbrequire(false);
- break;
- }//switch
- }//for
- /*-------------------------------------------------------------------------*/
- /* NO TAKE OVER HAS BEEN INITIATED. */
- /*-------------------------------------------------------------------------*/
-}//Dbdih::systemRestartTakeOverLab()
-
-/*---------------------------------------------------------------------------*/
-// This subroutine is called as part of node restart in the master node.
-/*---------------------------------------------------------------------------*/
-void Dbdih::nodeRestartTakeOver(Signal* signal, Uint32 startNodeId)
-{
- switch (getNodeActiveStatus(startNodeId)) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- case Sysfile::NS_ActiveMissed_2:
- jam();
- /*-----------------------------------------------------------------------*/
- // AN ACTIVE NODE HAS BEEN STARTED. THE ACTIVE NODE MUST THEN GET ALL DATA
- // IT HAD BEFORE ITS CRASH. WE START THE TAKE OVER IMMEDIATELY.
- // SINCE WE ARE AN ACTIVE NODE WE WILL TAKE OVER OUR OWN NODE THAT
- // PREVIOUSLY CRASHED.
- /*-----------------------------------------------------------------------*/
- startTakeOver(signal, RNIL, startNodeId, startNodeId);
- break;
- case Sysfile::NS_HotSpare:{
- jam();
- /*-----------------------------------------------------------------------*/
- // WHEN STARTING UP A HOT SPARE WE WILL CHECK IF ANY NODE NEEDS TO TAKEN
- // OVER. IF SO THEN WE WILL START THE TAKE OVER.
- /*-----------------------------------------------------------------------*/
- bool takeOverStarted = false;
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
- jam();
- takeOverStarted = true;
- startTakeOver(signal, RNIL, startNodeId, nodePtr.i);
- }//if
- }//for
- if (!takeOverStarted) {
- jam();
- /*-------------------------------------------------------------------*/
- // NO TAKE OVER WAS NEEDED AT THE MOMENT WE START-UP AND WAIT UNTIL A
- // TAKE OVER IS NEEDED.
- /*-------------------------------------------------------------------*/
- BlockReference ref = calcDihBlockRef(startNodeId);
- signal->theData[0] = startNodeId;
- sendSignal(ref, GSN_START_COPYCONF, signal, 1, JBB);
- }//if
- break;
- }
- case Sysfile::NS_NotActive_NotTakenOver:
- jam();
- /*-----------------------------------------------------------------------*/
- // ALL DATA IN THE NODE IS LOST BUT WE HAVE NOT TAKEN OVER YET. WE WILL
- // TAKE OVER OUR OWN NODE
- /*-----------------------------------------------------------------------*/
- startTakeOver(signal, RNIL, startNodeId, startNodeId);
- break;
- case Sysfile::NS_TakeOver:{
- jam();
- /*--------------------------------------------------------------------
- * We were in the process of taking over but it was not completed.
- * We will complete it now instead.
- *--------------------------------------------------------------------*/
- Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId,
- SYSFILE->takeOver);
- if(takeOverNode == 0){
- jam();
- warningEvent("Bug in take-over code restarting");
- takeOverNode = startNodeId;
- }
-
- startTakeOver(signal, RNIL, startNodeId, takeOverNode);
- break;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
- nodeResetStart();
-}//Dbdih::nodeRestartTakeOver()
-
-/*************************************************************************/
-// Ths routine is called when starting a local checkpoint.
-/*************************************************************************/
-void Dbdih::checkStartTakeOver(Signal* signal)
-{
- NodeRecordPtr csoNodeptr;
- Uint32 tcsoHotSpareNode;
- Uint32 tcsoTakeOverNode;
- if (isMaster()) {
- /*-----------------------------------------------------------------*/
- /* WE WILL ONLY START TAKE OVER IF WE ARE MASTER. */
- /*-----------------------------------------------------------------*/
- /* WE WILL ONLY START THE TAKE OVER IF THERE WERE A NEED OF */
- /* A TAKE OVER. */
- /*-----------------------------------------------------------------*/
- /* WE CAN ONLY PERFORM THE TAKE OVER IF WE HAVE A HOT SPARE */
- /* AVAILABLE. */
- /*-----------------------------------------------------------------*/
- tcsoTakeOverNode = 0;
- tcsoHotSpareNode = 0;
- for (csoNodeptr.i = 1; csoNodeptr.i < MAX_NDB_NODES; csoNodeptr.i++) {
- ptrAss(csoNodeptr, nodeRecord);
- if (csoNodeptr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
- jam();
- tcsoTakeOverNode = csoNodeptr.i;
- } else {
- jam();
- if (csoNodeptr.p->activeStatus == Sysfile::NS_HotSpare) {
- jam();
- tcsoHotSpareNode = csoNodeptr.i;
- }//if
- }//if
- }//for
- if ((tcsoTakeOverNode != 0) &&
- (tcsoHotSpareNode != 0)) {
- jam();
- startTakeOver(signal, RNIL, tcsoHotSpareNode, tcsoTakeOverNode);
- }//if
- }//if
-}//Dbdih::checkStartTakeOver()
-
-/*****************************************************************************/
-/*********** NODE ADDING MODULE *************/
-/*********** CODE TO HANDLE TAKE OVER *************/
-/*****************************************************************************/
-// A take over can be initiated by a number of things:
-// 1) A node restart, usually the node takes over itself but can also take
-// over somebody else if its own data was already taken over
-// 2) At system restart it is necessary to use the take over code to recover
-// nodes which had too old checkpoints to be restorable by the usual
-// restoration from disk.
-// 3) When a node has missed too many local checkpoints and is decided by the
-// master to be taken over by a hot spare node that sits around waiting
-// for this to happen.
-//
-// To support multiple node failures efficiently the code is written such that
-// only one take over can handle transitions in state but during a copy
-// fragment other take over's can perform state transitions.
-/*****************************************************************************/
-void Dbdih::startTakeOver(Signal* signal,
- Uint32 takeOverPtrI,
- Uint32 startNode,
- Uint32 nodeTakenOver)
-{
- NodeRecordPtr toNodePtr;
- NodeGroupRecordPtr NGPtr;
- toNodePtr.i = nodeTakenOver;
- ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
- NGPtr.i = toNodePtr.p->nodeGroup;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- TakeOverRecordPtr takeOverPtr;
- if (takeOverPtrI == RNIL) {
- jam();
- setAllowNodeStart(startNode, false);
- seizeTakeOver(takeOverPtr);
- if (startNode == c_nodeStartMaster.startNode) {
- jam();
- takeOverPtr.p->toNodeRestart = true;
- }//if
- takeOverPtr.p->toStartingNode = startNode;
- takeOverPtr.p->toFailedNode = nodeTakenOver;
- } else {
- jam();
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- ndbrequire(takeOverPtr.p->toStartingNode == startNode);
- ndbrequire(takeOverPtr.p->toFailedNode == nodeTakenOver);
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_WAIT_START_TAKE_OVER);
- }//if
- if ((NGPtr.p->activeTakeOver) || (ERROR_INSERTED(7157))) {
- jam();
- /**------------------------------------------------------------------------
- * A take over is already active in this node group. We only allow one
- * take over per node group. Otherwise we will overload the node group and
- * also we will require much more checks when starting up copying of
- * fragments. The parallelism for take over is mainly to ensure that we
- * can handle take over efficiently in large systems with 4 nodes and above
- * A typical case is a 8 node system executing on two 8-cpu boxes.
- * A box crash in one of the boxes will mean 4 nodes crashes.
- * We want to be able to restart those four nodes to some
- * extent in parallel.
- *
- * We will wait for a few seconds and then try again.
- */
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START_TAKE_OVER;
- signal->theData[0] = DihContinueB::ZSTART_TAKE_OVER;
- signal->theData[1] = takeOverPtr.i;
- signal->theData[2] = startNode;
- signal->theData[3] = nodeTakenOver;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 5000, 4);
- return;
- }//if
- NGPtr.p->activeTakeOver = true;
- if (startNode == nodeTakenOver) {
- jam();
- switch (getNodeActiveStatus(nodeTakenOver)) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- case Sysfile::NS_ActiveMissed_2:
- jam();
- break;
- case Sysfile::NS_NotActive_NotTakenOver:
- case Sysfile::NS_TakeOver:
- jam();
- setNodeActiveStatus(nodeTakenOver, Sysfile::NS_TakeOver);
- break;
- default:
- ndbrequire(false);
- }//switch
- } else {
- jam();
- setNodeActiveStatus(nodeTakenOver, Sysfile::NS_HotSpare);
- setNodeActiveStatus(startNode, Sysfile::NS_TakeOver);
- changeNodeGroups(startNode, nodeTakenOver);
- }//if
- setNodeRestartInfoBits();
- /* ---------------------------------------------------------------------- */
- /* WE SET THE RESTART INFORMATION TO INDICATE THAT WE ARE ABOUT TO TAKE */
- /* OVER THE FAILED NODE. WE SET THIS INFORMATION AND WAIT UNTIL THE */
- /* GLOBAL CHECKPOINT HAS WRITTEN THE RESTART INFORMATION. */
- /* ---------------------------------------------------------------------- */
- Sysfile::setTakeOverNode(takeOverPtr.p->toFailedNode, SYSFILE->takeOver,
- startNode);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY;
-
- if (getNodeState().getSystemRestartInProgress())
- {
- jam();
- checkToCopy();
- checkToCopyCompleted(signal);
- return;
- }
- cstartGcpNow = true;
-}//Dbdih::startTakeOver()
-
-void Dbdih::changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver)
-{
- NodeRecordPtr startNodePtr;
- NodeRecordPtr toNodePtr;
- startNodePtr.i = startNode;
- ptrCheckGuard(startNodePtr, MAX_NDB_NODES, nodeRecord);
- toNodePtr.i = nodeTakenOver;
- ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
- ndbrequire(startNodePtr.p->nodeGroup == ZNIL);
- NodeGroupRecordPtr NGPtr;
-
- NGPtr.i = toNodePtr.p->nodeGroup;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- bool nodeFound = false;
- for (Uint32 i = 0; i < NGPtr.p->nodeCount; i++) {
- jam();
- if (NGPtr.p->nodesInGroup[i] == nodeTakenOver) {
- jam();
- NGPtr.p->nodesInGroup[i] = startNode;
- nodeFound = true;
- }//if
- }//for
- ndbrequire(nodeFound);
- Sysfile::setNodeGroup(startNodePtr.i, SYSFILE->nodeGroups, toNodePtr.p->nodeGroup);
- startNodePtr.p->nodeGroup = toNodePtr.p->nodeGroup;
- Sysfile::setNodeGroup(toNodePtr.i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
- toNodePtr.p->nodeGroup = ZNIL;
-}//Dbdih::changeNodeGroups()
-
-void Dbdih::checkToCopy()
-{
- TakeOverRecordPtr takeOverPtr;
- for (takeOverPtr.i = 0;takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
- ptrAss(takeOverPtr, takeOverRecord);
- /*----------------------------------------------------------------------*/
- // TAKE OVER HANDLING WRITES RESTART INFORMATION THROUGH
- // THE GLOBAL CHECKPOINT
- // PROTOCOL. WE CHECK HERE BEFORE STARTING A WRITE OF THE RESTART
- // INFORMATION.
- /*-----------------------------------------------------------------------*/
- if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY_ONGOING;
- } else if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY_ONGOING;
- }//if
- }//for
-}//Dbdih::checkToCopy()
-
-void Dbdih::checkToCopyCompleted(Signal* signal)
-{
- /* ------------------------------------------------------------------------*/
- /* WE CHECK HERE IF THE WRITING OF TAKE OVER INFORMATION ALSO HAS BEEN */
- /* COMPLETED. */
- /* ------------------------------------------------------------------------*/
- TakeOverRecordPtr toPtr;
- for (toPtr.i = 0; toPtr.i < MAX_NDB_NODES; toPtr.i++) {
- ptrAss(toPtr, takeOverRecord);
- if (toPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY_ONGOING){
- jam();
- sendStartTo(signal, toPtr.i);
- } else if (toPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY_ONGOING){
- jam();
- sendEndTo(signal, toPtr.i);
- } else {
- jam();
- }//if
- }//for
-}//Dbdih::checkToCopyCompleted()
-
-bool Dbdih::checkToInterrupted(TakeOverRecordPtr& takeOverPtr)
-{
- if (checkNodeAlive(takeOverPtr.p->toStartingNode)) {
- jam();
- return false;
- } else {
- jam();
- endTakeOver(takeOverPtr.i);
- return true;
- }//if
-}//Dbdih::checkToInterrupted()
-
-void Dbdih::sendStartTo(Signal* signal, Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- CRASH_INSERTION(7155);
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- if ((c_startToLock != RNIL) || (ERROR_INSERTED(7158))) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START;
- signal->theData[0] = DihContinueB::ZSEND_START_TO;
- signal->theData[1] = takeOverPtrI;
- signal->theData[2] = takeOverPtr.p->toStartingNode;
- signal->theData[3] = takeOverPtr.p->toFailedNode;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
- return;
- }//if
- c_startToLock = takeOverPtrI;
-
- takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
- StartToReq * const req = (StartToReq *)&signal->theData[0];
- req->userPtr = takeOverPtr.i;
- req->userRef = reference();
- req->startingNodeId = takeOverPtr.p->toStartingNode;
- req->nodeTakenOver = takeOverPtr.p->toFailedNode;
- req->nodeRestart = takeOverPtr.p->toNodeRestart;
- sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
-}//Dbdih::sendStartTo()
-
-void Dbdih::execSTART_TOREQ(Signal* signal)
-{
- TakeOverRecordPtr takeOverPtr;
- jamEntry();
- const StartToReq * const req = (StartToReq *)&signal->theData[0];
- takeOverPtr.i = req->userPtr;
- BlockReference ref = req->userRef;
- Uint32 startingNode = req->startingNodeId;
-
- CRASH_INSERTION(7133);
- RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- allocateTakeOver(takeOverPtr);
- initStartTakeOver(req, takeOverPtr);
-
- StartToConf * const conf = (StartToConf *)&signal->theData[0];
- conf->userPtr = takeOverPtr.i;
- conf->sendingNodeId = cownNodeId;
- conf->startingNodeId = startingNode;
- sendSignal(ref, GSN_START_TOCONF, signal, StartToConf::SignalLength, JBB);
-}//Dbdih::execSTART_TOREQ()
-
-void Dbdih::execSTART_TOCONF(Signal* signal)
-{
- TakeOverRecordPtr takeOverPtr;
- jamEntry();
- const StartToConf * const conf = (StartToConf *)&signal->theData[0];
-
- CRASH_INSERTION(7147);
-
- RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
-
- takeOverPtr.i = conf->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::STARTING);
- ndbrequire(takeOverPtr.p->toStartingNode == conf->startingNodeId);
- receiveLoopMacro(START_TOREQ, conf->sendingNodeId);
- CRASH_INSERTION(7134);
- c_startToLock = RNIL;
-
- if (takeOverPtr.p->toNodeRestart)
- {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
- nr_start_fragments(signal, takeOverPtr);
- return;
- }
-
- startNextCopyFragment(signal, takeOverPtr.i);
-}//Dbdih::execSTART_TOCONF()
-
-void
-Dbdih::nr_start_fragments(Signal* signal,
- TakeOverRecordPtr takeOverPtr)
-{
- Uint32 loopCount = 0 ;
- TabRecordPtr tabPtr;
- while (loopCount++ < 100) {
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- if (tabPtr.i >= ctabFileSize) {
- jam();
- nr_run_redo(signal, takeOverPtr);
- return;
- }//if
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
- tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
- {
- jam();
- takeOverPtr.p->toCurrentFragid = 0;
- takeOverPtr.p->toCurrentTabref++;
- continue;
- }//if
- Uint32 fragId = takeOverPtr.p->toCurrentFragid;
- if (fragId >= tabPtr.p->totalfragments) {
- jam();
- takeOverPtr.p->toCurrentFragid = 0;
- takeOverPtr.p->toCurrentTabref++;
- continue;
- }//if
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- ReplicaRecordPtr loopReplicaPtr;
- loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- while (loopReplicaPtr.i != RNIL) {
- ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
- if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
- jam();
- nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
- break;
- } else {
- jam();
- loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
- }//if
- }//while
- takeOverPtr.p->toCurrentFragid++;
- }//while
- signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
- signal->theData[1] = takeOverPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Dbdih::nr_start_fragment(Signal* signal,
- TakeOverRecordPtr takeOverPtr,
- ReplicaRecordPtr replicaPtr)
-{
- Uint32 i, j = 0;
- Uint32 maxLcpId = 0;
- Uint32 maxLcpIndex = ~0;
-
- Uint32 restorableGCI = 0;
-
- ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
- takeOverPtr.p->toCurrentTabref,
- takeOverPtr.p->toCurrentFragid,
- replicaPtr.p->nextLcp);
-
- Uint32 idx = replicaPtr.p->nextLcp;
- for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
- {
- ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
- if (replicaPtr.p->lcpStatus[idx] == ZVALID)
- {
- ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
- Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
- for (;j < replicaPtr.p->noCrashedReplicas; j++)
- {
- ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
- j,
- replicaPtr.p->noCrashedReplicas,
- replicaPtr.p->replicaLastGci[j]);
- if (replicaPtr.p->replicaLastGci[j] > stopGci)
- {
- maxLcpId = replicaPtr.p->lcpId[idx];
- maxLcpIndex = idx;
- restorableGCI = replicaPtr.p->replicaLastGci[j];
- break;
- }
- }
- }
- }
-
- if (maxLcpIndex == ~ (Uint32) 0)
- {
- ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
- takeOverPtr.p->toStartingNode,
- takeOverPtr.p->toCurrentTabref,
- takeOverPtr.p->toCurrentFragid);
- replicaPtr.p->lcpIdStarted = 0;
- BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
- StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
- req->userPtr = 0;
- req->userRef = reference();
- req->lcpNo = ZNIL;
- req->lcpId = 0;
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragId = takeOverPtr.p->toCurrentFragid;
- req->noOfLogNodes = 0;
- sendSignal(ref, GSN_START_FRAGREQ, signal,
- StartFragReq::SignalLength, JBB);
- }
- else
- {
- ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
- maxLcpId,
- maxLcpIndex,
- replicaPtr.p->maxGciStarted[maxLcpIndex],
- replicaPtr.p->maxGciCompleted[maxLcpIndex],
- restorableGCI,
- SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
- SYSFILE->newestRestorableGCI);
-
- replicaPtr.p->lcpIdStarted = restorableGCI;
- BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
- StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
- req->userPtr = 0;
- req->userRef = reference();
- req->lcpNo = maxLcpIndex;
- req->lcpId = maxLcpId;
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragId = takeOverPtr.p->toCurrentFragid;
- req->noOfLogNodes = 1;
- req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
- req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
- req->lastGci[0] = restorableGCI;
- sendSignal(ref, GSN_START_FRAGREQ, signal,
- StartFragReq::SignalLength, JBB);
- }
-}
-
-void
-Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
-{
- takeOverPtr.p->toCurrentTabref = 0;
- takeOverPtr.p->toCurrentFragid = 0;
- sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
-}
-
-void Dbdih::initStartTakeOver(const StartToReq * req,
- TakeOverRecordPtr takeOverPtr)
-{
- takeOverPtr.p->toCurrentTabref = 0;
- takeOverPtr.p->toCurrentFragid = 0;
- takeOverPtr.p->toStartingNode = req->startingNodeId;
- takeOverPtr.p->toFailedNode = req->nodeTakenOver;
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_STARTED;
- takeOverPtr.p->toCopyNode = RNIL;
- takeOverPtr.p->toCurrentReplica = RNIL;
- takeOverPtr.p->toNodeRestart = req->nodeRestart;
-}//Dbdih::initStartTakeOver()
-
-void Dbdih::startNextCopyFragment(Signal* signal, Uint32 takeOverPtrI)
-{
- TabRecordPtr tabPtr;
- TakeOverRecordPtr takeOverPtr;
- Uint32 loopCount;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
- loopCount = 0;
- if (ERROR_INSERTED(7159)) {
- loopCount = 100;
- }//if
- while (loopCount++ < 100) {
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- if (tabPtr.i >= ctabFileSize) {
- jam();
- CRASH_INSERTION(7136);
- sendUpdateTo(signal, takeOverPtr.i, UpdateToReq::TO_COPY_COMPLETED);
- return;
- }//if
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
- jam();
- takeOverPtr.p->toCurrentFragid = 0;
- takeOverPtr.p->toCurrentTabref++;
- continue;
- }//if
- Uint32 fragId = takeOverPtr.p->toCurrentFragid;
- if (fragId >= tabPtr.p->totalfragments) {
- jam();
- takeOverPtr.p->toCurrentFragid = 0;
- takeOverPtr.p->toCurrentTabref++;
- if (ERROR_INSERTED(7135)) {
- if (takeOverPtr.p->toCurrentTabref == 1) {
- ndbrequire(false);
- }//if
- }//if
- continue;
- }//if
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- ReplicaRecordPtr loopReplicaPtr;
- loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- while (loopReplicaPtr.i != RNIL) {
- ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
- if (loopReplicaPtr.p->procNode == takeOverPtr.p->toFailedNode) {
- jam();
- /* ----------------------------------------------------------------- */
- /* WE HAVE FOUND A REPLICA THAT BELONGED THE FAILED NODE THAT NEEDS */
- /* TAKE OVER. WE TAKE OVER THIS REPLICA TO THE NEW NODE. */
- /* ----------------------------------------------------------------- */
- takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
- toCopyFragLab(signal, takeOverPtr.i);
- return;
- } else if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
- jam();
- /* ----------------------------------------------------------------- */
- /* WE HAVE OBVIOUSLY STARTED TAKING OVER THIS WITHOUT COMPLETING IT. */
- /* WE */
- /* NEED TO COMPLETE THE TAKE OVER OF THIS REPLICA. */
- /* ----------------------------------------------------------------- */
- takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
- toCopyFragLab(signal, takeOverPtr.i);
- return;
- } else {
- jam();
- loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
- }//if
- }//while
- takeOverPtr.p->toCurrentFragid++;
- }//while
- signal->theData[0] = DihContinueB::ZTO_START_COPY_FRAG;
- signal->theData[1] = takeOverPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}//Dbdih::startNextCopyFragment()
-
-void Dbdih::toCopyFragLab(Signal* signal,
- Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
-
- /**
- * Inform starting node that TakeOver is about to start
- */
- Uint32 nodeId = takeOverPtr.p->toStartingNode;
-
- Uint32 version = getNodeInfo(nodeId).m_version;
- if (ndb_check_prep_copy_frag_version(version))
- {
- jam();
- TabRecordPtr tabPtr;
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
- Uint32 nodes[MAX_REPLICAS];
- extractNodeInfo(fragPtr.p, nodes);
-
- PrepareCopyFragReq* req= (PrepareCopyFragReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = takeOverPtrI;
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragId = takeOverPtr.p->toCurrentFragid;
- req->copyNodeId = nodes[0]; // Src
- req->startingNodeId = takeOverPtr.p->toStartingNode; // Dst
- Uint32 ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
-
- sendSignal(ref, GSN_PREPARE_COPY_FRAG_REQ, signal,
- PrepareCopyFragReq::SignalLength, JBB);
-
- takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_COPY;
- return;
- }
-
- takeOverPtr.p->maxPage = RNIL;
- toStartCopyFrag(signal, takeOverPtr);
-}
-
-void
-Dbdih::execPREPARE_COPY_FRAG_REF(Signal* signal)
-{
- jamEntry();
- PrepareCopyFragRef ref = *(PrepareCopyFragRef*)signal->getDataPtr();
-
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(ref.senderData, takeOverPtr);
-
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_COPY);
-
- /**
- * Treat this as copy frag ref
- */
- CopyFragRef * cfref = (CopyFragRef*)signal->getDataPtrSend();
- cfref->userPtr = ref.senderData;
- cfref->startingNodeId = ref.startingNodeId;
- cfref->errorCode = ref.errorCode;
- cfref->tableId = ref.tableId;
- cfref->fragId = ref.fragId;
- cfref->sendingNodeId = ref.copyNodeId;
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
- execCOPY_FRAGREF(signal);
-}
-
-void
-Dbdih::execPREPARE_COPY_FRAG_CONF(Signal* signal)
-{
- PrepareCopyFragConf conf = *(PrepareCopyFragConf*)signal->getDataPtr();
-
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(conf.senderData, takeOverPtr);
-
- Uint32 version = getNodeInfo(refToNode(conf.senderRef)).m_version;
- if (ndb_check_prep_copy_frag_version(version) >= 2)
- {
- jam();
- takeOverPtr.p->maxPage = conf.maxPageNo;
- }
- else
- {
- jam();
- takeOverPtr.p->maxPage = RNIL;
- }
- toStartCopyFrag(signal, takeOverPtr);
-}
-
-void
-Dbdih::toStartCopyFrag(Signal* signal, TakeOverRecordPtr takeOverPtr)
-{
- CreateReplicaRecordPtr createReplicaPtr;
- createReplicaPtr.i = 0;
- ptrAss(createReplicaPtr, createReplicaRecord);
-
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = takeOverPtr.p->toCurrentReplica;
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
-
- TabRecordPtr tabPtr;
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- /* ----------------------------------------------------------------------- */
- /* WE HAVE FOUND A REPLICA THAT NEEDS TAKE OVER. WE WILL START THIS TAKE */
- /* OVER BY ADDING THE FRAGMENT WHEREAFTER WE WILL ORDER THE PRIMARY */
- /* REPLICA TO COPY ITS CONTENT TO THE NEW STARTING REPLICA. */
- /* THIS OPERATION IS A SINGLE USER OPERATION UNTIL WE HAVE SENT */
- /* COPY_FRAGREQ. AFTER SENDING COPY_FRAGREQ WE ARE READY TO START A NEW */
- /* FRAGMENT REPLICA. WE WILL NOT IMPLEMENT THIS IN THE FIRST PHASE. */
- /* ----------------------------------------------------------------------- */
- cnoOfCreateReplicas = 1;
- createReplicaPtr.p->hotSpareUse = true;
- createReplicaPtr.p->dataNodeId = takeOverPtr.p->toStartingNode;
-
- prepareSendCreateFragReq(signal, takeOverPtr.i);
-}//Dbdih::toStartCopy()
-
-void Dbdih::prepareSendCreateFragReq(Signal* signal, Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
-
- TabRecordPtr tabPtr;
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- FragmentstorePtr fragPtr;
-
- getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
- Uint32 nodes[MAX_REPLICAS];
- extractNodeInfo(fragPtr.p, nodes);
- takeOverPtr.p->toCopyNode = nodes[0];
- sendCreateFragReq(signal, 0, CreateFragReq::STORED, takeOverPtr.i);
-}//Dbdih::prepareSendCreateFragReq()
-
-void Dbdih::sendCreateFragReq(Signal* signal,
- Uint32 startGci,
- Uint32 replicaType,
- Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- if ((c_createFragmentLock != RNIL) ||
- ((ERROR_INSERTED(7161))&&(replicaType == CreateFragReq::STORED)) ||
- ((ERROR_INSERTED(7162))&&(replicaType == CreateFragReq::COMMIT_STORED))){
- if (replicaType == CreateFragReq::STORED) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_PREPARE_CREATE;
- } else {
- ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_COMMIT_CREATE;
- }//if
- signal->theData[0] = DihContinueB::ZSEND_CREATE_FRAG;
- signal->theData[1] = takeOverPtr.i;
- signal->theData[2] = replicaType;
- signal->theData[3] = startGci;
- signal->theData[4] = takeOverPtr.p->toStartingNode;
- signal->theData[5] = takeOverPtr.p->toFailedNode;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 6);
- return;
- }//if
- c_createFragmentLock = takeOverPtr.i;
- sendLoopMacro(CREATE_FRAGREQ, nullRoutine);
-
- CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
- req->userPtr = takeOverPtr.i;
- req->userRef = reference();
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragId = takeOverPtr.p->toCurrentFragid;
- req->startingNodeId = takeOverPtr.p->toStartingNode;
- req->copyNodeId = takeOverPtr.p->toCopyNode;
- req->startGci = startGci;
- req->replicaType = replicaType;
-
- NodeRecordPtr nodePtr;
- nodePtr.i = cfirstAliveNode;
- do {
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- BlockReference ref = calcDihBlockRef(nodePtr.i);
- sendSignal(ref, GSN_CREATE_FRAGREQ, signal,
- CreateFragReq::SignalLength, JBB);
- nodePtr.i = nodePtr.p->nextNode;
- } while (nodePtr.i != RNIL);
-
- if (replicaType == CreateFragReq::STORED) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_CREATE;
- } else {
- ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
- }
-}//Dbdih::sendCreateFragReq()
-
-/* --------------------------------------------------------------------------*/
-/* AN ORDER TO START OR COMMIT THE REPLICA CREATION ARRIVED FROM THE */
-/* MASTER. */
-/* --------------------------------------------------------------------------*/
-void Dbdih::execCREATE_FRAGREQ(Signal* signal)
-{
- jamEntry();
- CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = req->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- BlockReference retRef = req->userRef;
-
- TabRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- Uint32 fragId = req->fragId;
- Uint32 tdestNodeid = req->startingNodeId;
- Uint32 tsourceNodeid = req->copyNodeId;
- Uint32 startGci = req->startGci;
- Uint32 replicaType = req->replicaType;
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- RETURN_IF_NODE_NOT_ALIVE(tdestNodeid);
- ReplicaRecordPtr frReplicaPtr;
- findToReplica(takeOverPtr.p, replicaType, fragPtr, frReplicaPtr);
- ndbrequire(frReplicaPtr.i != RNIL);
-
- switch (replicaType) {
- case CreateFragReq::STORED:
- jam();
- CRASH_INSERTION(7138);
- /* ----------------------------------------------------------------------*/
- /* HERE WE ARE INSERTING THE NEW BACKUP NODE IN THE EXECUTION OF ALL */
- /* OPERATIONS. FROM HERE ON ALL OPERATIONS ON THIS FRAGMENT WILL INCLUDE*/
- /* USE OF THE NEW REPLICA. */
- /* --------------------------------------------------------------------- */
- insertBackup(fragPtr, tdestNodeid);
- takeOverPtr.p->toCopyNode = tsourceNodeid;
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_PREPARE;
-
- fragPtr.p->distributionKey++;
- fragPtr.p->distributionKey &= 255;
- break;
- case CreateFragReq::COMMIT_STORED:
- jam();
- CRASH_INSERTION(7139);
- /* ----------------------------------------------------------------------*/
- /* HERE WE ARE MOVING THE REPLICA TO THE STORED SECTION SINCE IT IS NOW */
- /* FULLY LOADED WITH ALL DATA NEEDED. */
- // We also update the order of the replicas here so that if the new
- // replica is the desired primary we insert it as primary.
- /* ----------------------------------------------------------------------*/
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_COMMIT;
- removeOldStoredReplica(fragPtr, frReplicaPtr);
- linkStoredReplica(fragPtr, frReplicaPtr);
- updateNodeInfo(fragPtr);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
-
- /* ------------------------------------------------------------------------*/
- /* THE NEW NODE OF THIS REPLICA IS THE STARTING NODE. */
- /* ------------------------------------------------------------------------*/
- if (frReplicaPtr.p->procNode != takeOverPtr.p->toStartingNode) {
- jam();
- /* ---------------------------------------------------------------------*/
- /* IF WE ARE STARTING A TAKE OVER NODE WE MUST INVALIDATE ALL LCP'S. */
- /* OTHERWISE WE WILL TRY TO START LCP'S THAT DO NOT EXIST. */
- /* ---------------------------------------------------------------------*/
- frReplicaPtr.p->procNode = takeOverPtr.p->toStartingNode;
- frReplicaPtr.p->noCrashedReplicas = 0;
- frReplicaPtr.p->createGci[0] = startGci;
- ndbrequire(startGci != 0xF1F1F1F1);
- frReplicaPtr.p->replicaLastGci[0] = (Uint32)-1;
- for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
- frReplicaPtr.p->lcpStatus[i] = ZINVALID;
- }//for
- } else {
- jam();
- const Uint32 noCrashed = frReplicaPtr.p->noCrashedReplicas;
- arrGuard(noCrashed, 8);
- frReplicaPtr.p->createGci[noCrashed] = startGci;
- ndbrequire(startGci != 0xF1F1F1F1);
- frReplicaPtr.p->replicaLastGci[noCrashed] = (Uint32)-1;
- }//if
- takeOverPtr.p->toCurrentTabref = tabPtr.i;
- takeOverPtr.p->toCurrentFragid = fragId;
- CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
- conf->userPtr = takeOverPtr.i;
- conf->tableId = tabPtr.i;
- conf->fragId = fragId;
- conf->sendingNodeId = cownNodeId;
- conf->startingNodeId = tdestNodeid;
- sendSignal(retRef, GSN_CREATE_FRAGCONF, signal,
- CreateFragConf::SignalLength, JBB);
-}//Dbdih::execCREATE_FRAGREQ()
-
-void Dbdih::execCREATE_FRAGCONF(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(7148);
- const CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
- Uint32 fragId = conf->fragId;
-
- RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
-
- TabRecordPtr tabPtr;
- tabPtr.i = conf->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = conf->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(tabPtr.i == takeOverPtr.p->toCurrentTabref);
- ndbrequire(fragId == takeOverPtr.p->toCurrentFragid);
- receiveLoopMacro(CREATE_FRAGREQ, conf->sendingNodeId);
- c_createFragmentLock = RNIL;
-
- if (takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_CREATE) {
- jam();
- CRASH_INSERTION(7140);
- /* --------------------------------------------------------------------- */
- /* ALL NODES HAVE PREPARED THE INTRODUCTION OF THIS NEW NODE AND IT IS */
- /* ALREADY IN USE. WE CAN NOW START COPYING THE FRAGMENT. */
- /*---------------------------------------------------------------------- */
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- Uint32 gci = 0;
- if (takeOverPtr.p->toNodeRestart)
- {
- ReplicaRecordPtr replicaPtr;
- findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
- gci = replicaPtr.p->lcpIdStarted;
- replicaPtr.p->lcpIdStarted = 0;
- }
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
- BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
- CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
- copyFragReq->userPtr = takeOverPtr.i;
- copyFragReq->userRef = reference();
- copyFragReq->tableId = tabPtr.i;
- copyFragReq->fragId = fragId;
- copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
- copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
- copyFragReq->distributionKey = fragPtr.p->distributionKey;
- copyFragReq->gci = gci;
- Uint32 len = copyFragReq->nodeCount =
- extractNodeInfo(fragPtr.p,
- copyFragReq->nodeList);
- copyFragReq->nodeList[len] = takeOverPtr.p->maxPage;
- sendSignal(ref, GSN_COPY_FRAGREQ, signal,
- CopyFragReq::SignalLength + len, JBB);
- } else {
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
- jam();
- CRASH_INSERTION(7141);
- /* --------------------------------------------------------------------- */
- // REPORT that copy of fragment has been completed.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NR_CopyFragDone;
- signal->theData[1] = takeOverPtr.p->toStartingNode;
- signal->theData[2] = tabPtr.i;
- signal->theData[3] = takeOverPtr.p->toCurrentFragid;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
- /* --------------------------------------------------------------------- */
- /* WE HAVE NOW CREATED THIS NEW REPLICA AND WE ARE READY TO TAKE THE */
- /* THE NEXT REPLICA. */
- /* --------------------------------------------------------------------- */
-
- Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
- mutex.unlock(); // ignore result
-
- takeOverPtr.p->toCurrentFragid++;
- startNextCopyFragment(signal, takeOverPtr.i);
- }//if
-}//Dbdih::execCREATE_FRAGCONF()
-
-void Dbdih::execCOPY_FRAGREF(Signal* signal)
-{
- const CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
- jamEntry();
- Uint32 takeOverPtrI = ref->userPtr;
- Uint32 startingNodeId = ref->startingNodeId;
- Uint32 errorCode = ref->errorCode;
-
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- ndbrequire(errorCode != ZNODE_FAILURE_ERROR);
- ndbrequire(ref->tableId == takeOverPtr.p->toCurrentTabref);
- ndbrequire(ref->fragId == takeOverPtr.p->toCurrentFragid);
- ndbrequire(ref->startingNodeId == takeOverPtr.p->toStartingNode);
- ndbrequire(ref->sendingNodeId == takeOverPtr.p->toCopyNode);
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
- endTakeOver(takeOverPtrI);
- //--------------------------------------------------------------------------
- // For some reason we did not succeed in copying a fragment. We treat this
- // as a serious failure and crash the starting node.
- //--------------------------------------------------------------------------
- BlockReference cntrRef = calcNdbCntrBlockRef(startingNodeId);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::CopyFragRefError;
- sysErr->errorRef = reference();
- sysErr->data1 = errorCode;
- sysErr->data2 = 0;
- sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBB);
- return;
-}//Dbdih::execCOPY_FRAGREF()
-
-void Dbdih::execCOPY_FRAGCONF(Signal* signal)
-{
- const CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
- jamEntry();
- CRASH_INSERTION(7142);
-
- TakeOverRecordPtr takeOverPtr;
- Uint32 takeOverPtrI = conf->userPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
-
- ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
- ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
- ndbrequire(conf->startingNodeId == takeOverPtr.p->toStartingNode);
- ndbrequire(conf->sendingNodeId == takeOverPtr.p->toCopyNode);
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
- sendUpdateTo(signal, takeOverPtr.i,
- (Uint32)UpdateToReq::TO_COPY_FRAG_COMPLETED);
-}//Dbdih::execCOPY_FRAGCONF()
-
-void Dbdih::sendUpdateTo(Signal* signal,
- Uint32 takeOverPtrI, Uint32 updateState)
-{
- TakeOverRecordPtr takeOverPtr;
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- if ((c_updateToLock != RNIL) ||
- ((ERROR_INSERTED(7163)) &&
- (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED)) ||
- ((ERROR_INSERTED(7169)) &&
- (updateState == UpdateToReq::TO_COPY_COMPLETED))) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_UPDATE_TO;
- signal->theData[0] = DihContinueB::ZSEND_UPDATE_TO;
- signal->theData[1] = takeOverPtrI;
- signal->theData[2] = takeOverPtr.p->toStartingNode;
- signal->theData[3] = takeOverPtr.p->toFailedNode;
- signal->theData[4] = updateState;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 5);
- return;
- }//if
- c_updateToLock = takeOverPtrI;
- if (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_UPDATE_TO;
- } else {
- jam();
- ndbrequire(updateState == UpdateToReq::TO_COPY_COMPLETED);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_COPY_COMPLETED;
- }//if
-
- UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
- req->userPtr = takeOverPtr.i;
- req->userRef = reference();
- req->updateState = (UpdateToReq::UpdateState)updateState;
- req->startingNodeId = takeOverPtr.p->toStartingNode;
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragmentNo = takeOverPtr.p->toCurrentFragid;
- sendLoopMacro(UPDATE_TOREQ, sendUPDATE_TOREQ);
-}//Dbdih::sendUpdateTo()
-
-void Dbdih::execUPDATE_TOREQ(Signal* signal)
-{
- jamEntry();
- const UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
- BlockReference ref = req->userRef;
- ndbrequire(cmasterdihref == ref);
-
- CRASH_INSERTION(7154);
- RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = req->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(req->startingNodeId == takeOverPtr.p->toStartingNode);
- if (req->updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
- jam();
- ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_SLAVE_CREATE_PREPARE);
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED;
- takeOverPtr.p->toCurrentTabref = req->tableId;
- takeOverPtr.p->toCurrentFragid = req->fragmentNo;
- } else {
- jam();
- ndbrequire(req->updateState == UpdateToReq::TO_COPY_COMPLETED);
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_COMPLETED;
- setNodeCopyCompleted(takeOverPtr.p->toStartingNode, true);
- }//if
-
-
- UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
- conf->userPtr = takeOverPtr.i;
- conf->sendingNodeId = cownNodeId;
- conf->startingNodeId = takeOverPtr.p->toStartingNode;
- sendSignal(ref, GSN_UPDATE_TOCONF, signal, UpdateToConf::SignalLength, JBB);
-}//Dbdih::execUPDATE_TOREQ()
-
-void Dbdih::execUPDATE_TOCONF(Signal* signal)
-{
- const UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
- CRASH_INSERTION(7152);
-
- RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = conf->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- receiveLoopMacro(UPDATE_TOREQ, conf->sendingNodeId);
- CRASH_INSERTION(7153);
- c_updateToLock = RNIL;
-
- if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_COPY_COMPLETED) {
- jam();
- toCopyCompletedLab(signal, takeOverPtr);
- return;
- } else {
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_UPDATE_TO);
- }//if
- TabRecordPtr tabPtr;
- tabPtr.i = takeOverPtr.p->toCurrentTabref;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
- BlockReference lqhRef = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
- CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
- req->userPtr = takeOverPtr.i;
- req->userRef = reference();
- req->tableId = takeOverPtr.p->toCurrentTabref;
- req->fragId = takeOverPtr.p->toCurrentFragid;
- req->distributionKey = fragPtr.p->distributionKey;
-
- sendSignal(lqhRef, GSN_COPY_ACTIVEREQ, signal,
- CopyActiveReq::SignalLength, JBB);
-}//Dbdih::execUPDATE_TOCONF()
-
-void Dbdih::execCOPY_ACTIVECONF(Signal* signal)
-{
- const CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
- jamEntry();
- CRASH_INSERTION(7143);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = conf->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
- ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
- ndbrequire(checkNodeAlive(conf->startingNodeId));
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_ACTIVE);
-
- takeOverPtr.p->startGci = conf->startGci;
- takeOverPtr.p->toMasterStatus = TakeOverRecord::LOCK_MUTEX;
-
- Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
- Callback c = { safe_cast(&Dbdih::switchPrimaryMutex_locked), takeOverPtr.i };
- ndbrequire(mutex.lock(c));
-}//Dbdih::execCOPY_ACTIVECONF()
-
-void
-Dbdih::switchPrimaryMutex_locked(Signal* signal, Uint32 toPtrI, Uint32 retVal){
- jamEntry();
- ndbrequire(retVal == 0);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = toPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::LOCK_MUTEX);
-
- if (!checkNodeAlive((takeOverPtr.p->toStartingNode))) {
- // We have mutex
- Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
- mutex.unlock(); // Ignore result
-
- c_createFragmentLock = RNIL;
- c_CREATE_FRAGREQ_Counter.clearWaitingFor();
- endTakeOver(takeOverPtr.i);
- return;
- }
-
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
- sendCreateFragReq(signal, takeOverPtr.p->startGci,
- CreateFragReq::COMMIT_STORED, takeOverPtr.i);
-}
-
-void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
-{
- signal->theData[0] = NDB_LE_NR_CopyFragsCompleted;
- signal->theData[1] = takeOverPtr.p->toStartingNode;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- if (getNodeState().getSystemRestartInProgress())
- {
- jam();
- infoEvent("Take over of node %d complete", takeOverPtr.p->toStartingNode);
- setNodeActiveStatus(takeOverPtr.p->toStartingNode, Sysfile::NS_Active);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
- takeOverCompleted(takeOverPtr.p->toStartingNode);
- checkToCopy();
- checkToCopyCompleted(signal);
- return;
- }
-
- c_lcpState.immediateLcpStart = true;
- takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
-
- /*-----------------------------------------------------------------------*/
- /* NOW WE CAN ALLOW THE NEW NODE TO PARTICIPATE IN LOCAL CHECKPOINTS. */
- /* WHEN THE FIRST LOCAL CHECKPOINT IS READY WE DECLARE THE TAKE OVER AS */
- /* COMPLETED. SINCE LOCAL CHECKPOINTS HAVE BEEN BLOCKED DURING THE COPY */
- /* PROCESS WE MUST ALSO START A NEW LOCAL CHECKPOINT PROCESS BY ENSURING */
- /* THAT IT LOOKS LIKE IT IS TIME FOR A NEW LOCAL CHECKPOINT AND BY */
- /* UNBLOCKING THE LOCAL CHECKPOINT AGAIN. */
- /* --------------------------------------------------------------------- */
-}//Dbdih::toCopyCompletedLab()
-
-void Dbdih::sendEndTo(Signal* signal, Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- CRASH_INSERTION(7156);
- RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
- if ((c_endToLock != RNIL) || (ERROR_INSERTED(7164))) {
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_ENDING;
- signal->theData[0] = DihContinueB::ZSEND_END_TO;
- signal->theData[1] = takeOverPtrI;
- signal->theData[2] = takeOverPtr.p->toStartingNode;
- signal->theData[3] = takeOverPtr.p->toFailedNode;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
- return;
- }//if
- c_endToLock = takeOverPtr.i;
- takeOverPtr.p->toMasterStatus = TakeOverRecord::ENDING;
- EndToReq * const req = (EndToReq *)&signal->theData[0];
- req->userPtr = takeOverPtr.i;
- req->userRef = reference();
- req->startingNodeId = takeOverPtr.p->toStartingNode;
- sendLoopMacro(END_TOREQ, sendEND_TOREQ);
-}//Dbdih::sendStartTo()
-
-void Dbdih::execEND_TOREQ(Signal* signal)
-{
- jamEntry();
- const EndToReq * const req = (EndToReq *)&signal->theData[0];
- BlockReference ref = req->userRef;
- Uint32 startingNodeId = req->startingNodeId;
-
- CRASH_INSERTION(7144);
- RETURN_IF_NODE_NOT_ALIVE(startingNodeId);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = req->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(startingNodeId == takeOverPtr.p->toStartingNode);
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
-
- if (!isMaster()) {
- jam();
- endTakeOver(takeOverPtr.i);
- }//if
-
- EndToConf * const conf = (EndToConf *)&signal->theData[0];
- conf->userPtr = takeOverPtr.i;
- conf->sendingNodeId = cownNodeId;
- conf->startingNodeId = startingNodeId;
- sendSignal(ref, GSN_END_TOCONF, signal, EndToConf::SignalLength, JBB);
-}//Dbdih::execEND_TOREQ()
-
-void Dbdih::execEND_TOCONF(Signal* signal)
-{
- const EndToConf * const conf = (EndToConf *)&signal->theData[0];
- jamEntry();
-
- const Uint32 nodeId = conf->startingNodeId;
- CRASH_INSERTION(7145);
-
- RETURN_IF_NODE_NOT_ALIVE(nodeId);
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = conf->userPtr;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::ENDING);
- ndbrequire(nodeId == takeOverPtr.p->toStartingNode);
-
- receiveLoopMacro(END_TOREQ, conf->sendingNodeId);
- CRASH_INSERTION(7146);
- c_endToLock = RNIL;
-
- /* -----------------------------------------------------------------------*/
- /* WE HAVE FINALLY COMPLETED THE TAKE OVER. WE RESET THE STATUS AND CHECK*/
- /* IF ANY MORE TAKE OVERS ARE NEEDED AT THE MOMENT. */
- /* FIRST WE CHECK IF A RESTART IS ONGOING. IN THAT CASE WE RESTART PHASE */
- /* 4 AND CHECK IF ANY MORE TAKE OVERS ARE NEEDED BEFORE WE START NDB */
- /* CLUSTER. THIS CAN ONLY HAPPEN IN A SYSTEM RESTART. */
- /* ---------------------------------------------------------------------- */
- if (takeOverPtr.p->toNodeRestart) {
- jam();
- /* ----------------------------------------------------------------------*/
- /* THE TAKE OVER NODE WAS A STARTING NODE. WE WILL SEND START_COPYCONF */
- /* TO THE STARTING NODE SUCH THAT THE NODE CAN COMPLETE THE START-UP. */
- /* --------------------------------------------------------------------- */
- BlockReference ref = calcDihBlockRef(takeOverPtr.p->toStartingNode);
- signal->theData[0] = takeOverPtr.p->toStartingNode;
- sendSignal(ref, GSN_START_COPYCONF, signal, 1,JBB);
- }//if
- endTakeOver(takeOverPtr.i);
-
- if (cstartPhase == ZNDB_SPH4) {
- jam();
- if (anyActiveTakeOver()) {
- jam();
- return;
- }//if
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }//if
- checkStartTakeOver(signal);
-}//Dbdih::execEND_TOCONF()
-
-void Dbdih::allocateTakeOver(TakeOverRecordPtr& takeOverPtr)
-{
- if (isMaster()) {
- jam();
- //--------------------------------------------
- // Master already seized the take over record.
- //--------------------------------------------
- return;
- }//if
- if (takeOverPtr.i == cfirstfreeTakeOver) {
- jam();
- seizeTakeOver(takeOverPtr);
- } else {
- TakeOverRecordPtr nextTakeOverptr;
- TakeOverRecordPtr prevTakeOverptr;
- nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
- prevTakeOverptr.i = takeOverPtr.p->prevTakeOver;
- if (prevTakeOverptr.i != RNIL) {
- jam();
- ptrCheckGuard(prevTakeOverptr, MAX_NDB_NODES, takeOverRecord);
- prevTakeOverptr.p->nextTakeOver = nextTakeOverptr.i;
- }//if
- if (nextTakeOverptr.i != RNIL) {
- jam();
- ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
- nextTakeOverptr.p->prevTakeOver = prevTakeOverptr.i;
- }//if
- }//if
-}//Dbdih::allocateTakeOver()
-
-void Dbdih::seizeTakeOver(TakeOverRecordPtr& takeOverPtr)
-{
- TakeOverRecordPtr nextTakeOverptr;
- ndbrequire(cfirstfreeTakeOver != RNIL);
- takeOverPtr.i = cfirstfreeTakeOver;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- cfirstfreeTakeOver = takeOverPtr.p->nextTakeOver;
- nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
- if (nextTakeOverptr.i != RNIL) {
- jam();
- ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
- nextTakeOverptr.p->prevTakeOver = RNIL;
- }//if
- takeOverPtr.p->nextTakeOver = RNIL;
- takeOverPtr.p->prevTakeOver = RNIL;
-}//Dbdih::seizeTakeOver()
-
-void Dbdih::endTakeOver(Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
- (takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
- jam();
- NodeGroupRecordPtr NGPtr;
- NodeRecordPtr nodePtr;
- nodePtr.i = takeOverPtr.p->toStartingNode;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- NGPtr.i = nodePtr.p->nodeGroup;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- NGPtr.p->activeTakeOver = false;
- }//if
- setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
- initTakeOver(takeOverPtr);
- releaseTakeOver(takeOverPtrI);
-}//Dbdih::endTakeOver()
-
-void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- takeOverPtr.p->nextTakeOver = cfirstfreeTakeOver;
- cfirstfreeTakeOver = takeOverPtr.i;
-}//Dbdih::releaseTakeOver()
-
-void Dbdih::initTakeOver(TakeOverRecordPtr takeOverPtr)
-{
- takeOverPtr.p->toCopyNode = RNIL;
- takeOverPtr.p->toCurrentFragid = RNIL;
- takeOverPtr.p->toCurrentReplica = RNIL;
- takeOverPtr.p->toCurrentTabref = RNIL;
- takeOverPtr.p->toFailedNode = RNIL;
- takeOverPtr.p->toStartingNode = RNIL;
- takeOverPtr.p->prevTakeOver = RNIL;
- takeOverPtr.p->nextTakeOver = RNIL;
- takeOverPtr.p->toNodeRestart = false;
- takeOverPtr.p->toMasterStatus = TakeOverRecord::IDLE;
- takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
-}//Dbdih::initTakeOver()
-
-bool Dbdih::anyActiveTakeOver()
-{
- TakeOverRecordPtr takeOverPtr;
- for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
- ptrAss(takeOverPtr, takeOverRecord);
- if (takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) {
- jam();
- return true;
- }//if
- }//for
- return false;
-}//Dbdih::anyActiveTakeOver()
-
-/*****************************************************************************/
-/* ------------------------------------------------------------------------- */
-/* WE HAVE BEEN REQUESTED TO PERFORM A SYSTEM RESTART. WE START BY */
-/* READING THE GCI FILES. THIS REQUEST WILL ONLY BE SENT TO THE MASTER */
-/* DIH. THAT MEANS WE HAVE TO REPLICATE THE INFORMATION WE READ FROM */
-/* OUR FILES TO ENSURE THAT ALL NODES HAVE THE SAME DISTRIBUTION */
-/* INFORMATION. */
-/* ------------------------------------------------------------------------- */
-/*****************************************************************************/
-void Dbdih::readGciFileLab(Signal* signal)
-{
- FileRecordPtr filePtr;
- filePtr.i = crestartInfoFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- filePtr.p->reqStatus = FileRecord::OPENING_GCP;
-
- openFileRo(signal, filePtr);
-}//Dbdih::readGciFileLab()
-
-void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr)
-{
- /* ----------------------------------------------------------------------- */
- /* WE HAVE SUCCESSFULLY OPENED A FILE CONTAINING INFORMATION ABOUT */
- /* THE GLOBAL CHECKPOINTS THAT ARE POSSIBLE TO RESTART. */
- /* ----------------------------------------------------------------------- */
- readRestorableGci(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::READING_GCP;
-}//Dbdih::openingGcpLab()
-
-void Dbdih::readingGcpLab(Signal* signal, FileRecordPtr filePtr)
-{
- /* ----------------------------------------------------------------------- */
- /* WE HAVE NOW SUCCESSFULLY MANAGED TO READ IN THE GLOBAL CHECKPOINT */
- /* INFORMATION FROM FILE. LATER WE WILL ADD SOME FUNCTIONALITY THAT */
- /* CHECKS THE RESTART TIMERS TO DEDUCE FROM WHERE TO RESTART. */
- /* NOW WE WILL SIMPLY RESTART FROM THE NEWEST GLOBAL CHECKPOINT */
- /* POSSIBLE TO RESTORE. */
- /* */
- /* BEFORE WE INVOKE DICT WE NEED TO COPY CRESTART_INFO TO ALL NODES. */
- /* WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE */
- /* START BY CLOSING THIS FILE. */
- /* ----------------------------------------------------------------------- */
- globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
- closeFile(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
-}//Dbdih::readingGcpLab()
-
-void Dbdih::closingGcpLab(Signal* signal, FileRecordPtr filePtr)
-{
- if (Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) == false){
- jam();
- selectMasterCandidateAndSend(signal);
- return;
- } else {
- jam();
- sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
- return;
- }//if
-}//Dbdih::closingGcpLab()
-
-/* ------------------------------------------------------------------------- */
-/* SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::selectMasterCandidateAndSend(Signal* signal)
-{
- setNodeGroups();
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = SYSFILE->lastCompletedGCI[getOwnNodeId()];
- sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
-
- NodeRecordPtr nodePtr;
- Uint32 node_groups[MAX_NDB_NODES];
- memset(node_groups, 0, sizeof(node_groups));
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
- if(ng != NO_NODE_GROUP_ID){
- ndbrequire(ng < MAX_NDB_NODES);
- node_groups[ng]++;
- }
- }
-
- for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- Uint32 count = node_groups[nodePtr.i];
- if(count != 0 && count != cnoReplicas){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Illegal configuration change."
- " Initial start needs to be performed "
- " when changing no of replicas (%d != %d)",
- node_groups[nodePtr.i], cnoReplicas);
- progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
- }
- }
-}//Dbdih::selectMasterCandidate()
-
-/* ------------------------------------------------------------------------- */
-/* ERROR HANDLING DURING READING RESTORABLE GCI FROM FILE. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
-{
- filePtr.p->fileStatus = FileRecord::CRASHED;
- filePtr.p->reqStatus = FileRecord::IDLE;
- if (crestartInfoFile[0] == filePtr.i) {
- jam();
- /* --------------------------------------------------------------------- */
- /* THE FIRST FILE WAS NOT ABLE TO BE OPENED. SET STATUS TO CRASHED AND */
- /* TRY OPEN THE NEXT FILE. */
- /* --------------------------------------------------------------------- */
- filePtr.i = crestartInfoFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRo(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_GCP;
- } else {
- jam();
- /* --------------------------------------------------------------------- */
- /* WE FAILED IN OPENING THE SECOND FILE. BOTH FILES WERE CORRUPTED. WE */
- /* CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR */
- /* FAILURE. */
- /*---------------------------------------------------------------------- */
- sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
- return;
- }//if
-}//Dbdih::openingGcpErrorLab()
-
-void Dbdih::readingGcpErrorLab(Signal* signal, FileRecordPtr filePtr)
-{
- filePtr.p->fileStatus = FileRecord::CRASHED;
- /* ----------------------------------------------------------------------- */
- /* WE FAILED IN READING THE FILE AS WELL. WE WILL CLOSE THIS FILE. */
- /* ----------------------------------------------------------------------- */
- closeFile(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CLOSING_GCP_CRASH;
-}//Dbdih::readingGcpErrorLab()
-
-void Dbdih::closingGcpCrashLab(Signal* signal, FileRecordPtr filePtr)
-{
- if (crestartInfoFile[0] == filePtr.i) {
- jam();
- /* --------------------------------------------------------------------- */
- /* ERROR IN FIRST FILE, TRY THE SECOND FILE. */
- /* --------------------------------------------------------------------- */
- filePtr.i = crestartInfoFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_GCP;
- return;
- }//if
- /* ----------------------------------------------------------------------- */
- /* WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A */
- /* SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR. */
- /* ----------------------------------------------------------------------- */
- sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
-}//Dbdih::closingGcpCrashLab()
-
-/*****************************************************************************/
-/* ------------------------------------------------------------------------- */
-/* THIS IS AN INITIAL RESTART. WE WILL CREATE THE TWO FILES DESCRIBING */
-/* THE GLOBAL CHECKPOINTS THAT ARE RESTORABLE. */
-/* ------------------------------------------------------------------------- */
-/*****************************************************************************/
-void Dbdih::initGciFilesLab(Signal* signal)
-{
- FileRecordPtr filePtr;
- filePtr.i = crestartInfoFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- createFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CREATING_GCP;
-}//Dbdih::initGciFilesLab()
-
-/* ------------------------------------------------------------------------- */
-/* GLOBAL CHECKPOINT FILE HAVE BEEN SUCCESSFULLY CREATED. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::creatingGcpLab(Signal* signal, FileRecordPtr filePtr)
-{
- if (filePtr.i == crestartInfoFile[0]) {
- jam();
- /* --------------------------------------------------------------------- */
- /* IF CREATED FIRST THEN ALSO CREATE THE SECOND FILE. */
- /* --------------------------------------------------------------------- */
- filePtr.i = crestartInfoFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- createFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CREATING_GCP;
- } else {
- jam();
- /* --------------------------------------------------------------------- */
- /* BOTH FILES HAVE BEEN CREATED. NOW WRITE THE INITIAL DATA TO BOTH */
- /* OF THE FILES. */
- /* --------------------------------------------------------------------- */
- filePtr.i = crestartInfoFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- writeRestorableGci(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
- }//if
-}//Dbdih::creatingGcpLab()
-
-/* ------------------------------------------------------------------------- */
-/* WE HAVE SUCCESSFULLY WRITTEN A GCI FILE. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::writeInitGcpLab(Signal* signal, FileRecordPtr filePtr)
-{
- filePtr.p->reqStatus = FileRecord::IDLE;
- if (filePtr.i == crestartInfoFile[0]) {
- jam();
- /* --------------------------------------------------------------------- */
- /* WE HAVE WRITTEN THE FIRST FILE NOW ALSO WRITE THE SECOND FILE. */
- /* --------------------------------------------------------------------- */
- filePtr.i = crestartInfoFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- writeRestorableGci(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
- } else {
- /* --------------------------------------------------------------------- */
- /* WE HAVE WRITTEN BOTH FILES. LEAVE BOTH FILES OPEN AND CONFIRM OUR */
- /* PART OF THE INITIAL START. */
- /* --------------------------------------------------------------------- */
- if (isMaster()) {
- jam();
- /*---------------------------------------------------------------------*/
- // IN MASTER NODES THE START REQUEST IS RECEIVED FROM NDBCNTR AND WE MUST
- // RESPOND WHEN COMPLETED.
- /*---------------------------------------------------------------------*/
- signal->theData[0] = reference();
- sendSignal(cndbStartReqBlockref, GSN_NDB_STARTCONF, signal, 1, JBB);
- } else {
- jam();
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }//if
- }//if
-}//Dbdih::writeInitGcpLab()
-
-/*****************************************************************************/
-/* ********** NODES DELETION MODULE *************/
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/* LOGIC FOR NODE FAILURE */
-/*---------------------------------------------------------------------------*/
-void Dbdih::execNODE_FAILREP(Signal* signal)
-{
- Uint32 i;
- Uint32 failedNodes[MAX_NDB_NODES];
- jamEntry();
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- cfailurenr = nodeFail->failNo;
- Uint32 newMasterId = nodeFail->masterNodeId;
- const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
-
- if (ERROR_INSERTED(7179))
- {
- CLEAR_ERROR_INSERT_VALUE;
- }
-
- if (ERROR_INSERTED(7184))
- {
- SET_ERROR_INSERT_VALUE(7000);
- }
-
- /*-------------------------------------------------------------------------*/
- // The first step is to convert from a bit mask to an array of failed nodes.
- /*-------------------------------------------------------------------------*/
- Uint32 index = 0;
- for (i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if(NodeBitmask::get(nodeFail->theNodes, i)){
- jam();
- failedNodes[index] = i;
- index++;
- }//if
- }//for
- ndbrequire(noOfFailedNodes == index);
- ndbrequire(noOfFailedNodes - 1 < MAX_NDB_NODES);
-
- /*-------------------------------------------------------------------------*/
- // The second step is to update the node status of the failed nodes, remove
- // them from the alive node list and put them into the dead node list. Also
- // update the number of nodes on-line.
- // We also set certain state variables ensuring that the node no longer is
- // used in transactions and also mark that we received this signal.
- /*-------------------------------------------------------------------------*/
- for (i = 0; i < noOfFailedNodes; i++) {
- jam();
- NodeRecordPtr TNodePtr;
- TNodePtr.i = failedNodes[i];
- ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRecord);
- TNodePtr.p->useInTransactions = false;
- TNodePtr.p->m_inclDihLcp = false;
- TNodePtr.p->recNODE_FAILREP = ZTRUE;
- if (TNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- con_lineNodes--;
- TNodePtr.p->nodeStatus = NodeRecord::DIED_NOW;
- removeAlive(TNodePtr);
- insertDeadNode(TNodePtr);
- }//if
- }//for
-
- /*-------------------------------------------------------------------------*/
- // Verify that we can continue to operate the cluster. If we cannot we will
- // not return from checkEscalation.
- /*-------------------------------------------------------------------------*/
- checkEscalation();
-
- /*------------------------------------------------------------------------*/
- // Verify that a starting node has also crashed. Reset the node start record.
- /*-------------------------------------------------------------------------*/
-#if 0
- /**
- * Node will crash by itself...
- * nodeRestart is run then...
- */
- if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE)
- {
- BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::StartInProgressError;
- sysErr->errorRef = reference();
- sysErr->data1= 0;
- sysErr->data2= __LINE__;
- sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA);
- nodeResetStart();
- }//if
-#endif
-
- /*--------------------------------------------------*/
- /* */
- /* WE CHANGE THE REFERENCE TO MASTER DIH */
- /* BLOCK AND POINTER AT THIS PLACE IN THE CODE*/
- /*--------------------------------------------------*/
- Uint32 oldMasterId = cmasterNodeId;
- BlockReference oldMasterRef = cmasterdihref;
- cmasterdihref = calcDihBlockRef(newMasterId);
- cmasterNodeId = newMasterId;
-
- const bool masterTakeOver = (oldMasterId != newMasterId);
-
- for(i = 0; i < noOfFailedNodes; i++) {
- NodeRecordPtr failedNodePtr;
- failedNodePtr.i = failedNodes[i];
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
- Uint32 activeTakeOverPtr = findTakeOver(failedNodes[i]);
- if (oldMasterRef == reference()) {
- /*-------------------------------------------------------*/
- // Functions that need to be called only for master nodes.
- /*-------------------------------------------------------*/
- checkCopyTab(failedNodePtr);
- checkStopPermMaster(signal, failedNodePtr);
- checkWaitGCPMaster(signal, failedNodes[i]);
- checkTakeOverInMasterAllNodeFailure(signal, failedNodePtr);
- checkTakeOverInMasterCopyNodeFailure(signal, failedNodePtr.i);
- checkTakeOverInMasterStartNodeFailure(signal, activeTakeOverPtr);
- checkGcpOutstanding(signal, failedNodePtr.i);
- } else {
- jam();
- /*-----------------------------------------------------------*/
- // Functions that need to be called only for nodes that were
- // not master before these failures.
- /*-----------------------------------------------------------*/
- checkStopPermProxy(signal, failedNodes[i]);
- checkWaitGCPProxy(signal, failedNodes[i]);
- if (isMaster()) {
- /*-----------------------------------------------------------*/
- // We take over as master since old master has failed
- /*-----------------------------------------------------------*/
- handleTakeOverNewMaster(signal, activeTakeOverPtr);
- } else {
- /*-----------------------------------------------------------*/
- // We are not master and will not become master.
- /*-----------------------------------------------------------*/
- checkTakeOverInNonMasterStartNodeFailure(signal, activeTakeOverPtr);
- }//if
- }//if
- /*--------------------------------------------------*/
- // Functions that need to be called for all nodes.
- /*--------------------------------------------------*/
- checkStopMe(signal, failedNodePtr);
- failedNodeLcpHandling(signal, failedNodePtr);
- checkWaitDropTabFailedLqh(signal, failedNodePtr.i, 0); // 0 = start w/ tab 0
- startRemoveFailedNode(signal, failedNodePtr);
-
- /**
- * This is the last function called
- * It modifies failedNodePtr.p->nodeStatus
- */
- failedNodeSynchHandling(signal, failedNodePtr);
- }//for
-
- if(masterTakeOver){
- jam();
- startLcpMasterTakeOver(signal, oldMasterId);
- startGcpMasterTakeOver(signal, oldMasterId);
-
- if(getNodeState().getNodeRestartInProgress()){
- jam();
- progError(__LINE__, NDBD_EXIT_MASTER_FAILURE_DURING_NR);
- }
- }
-
-
- if (isMaster()) {
- jam();
- setNodeRestartInfoBits();
- }//if
-}//Dbdih::execNODE_FAILREP()
-
-void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr)
-{
- jam();
-
- if(c_nodeStartMaster.startNode != failedNodePtr.i){
- jam();
- return;
- }
-
- switch(c_nodeStartMaster.m_outstandingGsn){
- case GSN_COPY_TABREQ:
- jam();
- ndbrequire(c_COPY_TABREQ_Counter.isWaitingFor(failedNodePtr.i));
- releaseTabPages(failedNodePtr.p->activeTabptr);
- 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:
- jam();
- break;
- default:
- g_eventLogger.error("outstanding gsn: %s(%d)",
- getSignalName(c_nodeStartMaster.m_outstandingGsn),
- c_nodeStartMaster.m_outstandingGsn);
- ndbrequire(false);
- }
-
- nodeResetStart();
-}//Dbdih::checkCopyTab()
-
-void Dbdih::checkStopMe(Signal* signal, NodeRecordPtr failedNodePtr)
-{
- jam();
- if (c_STOP_ME_REQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- ndbrequire(c_stopMe.clientRef != 0);
- StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
- stopMeConf->senderRef = calcDihBlockRef(failedNodePtr.i);
- stopMeConf->senderData = c_stopMe.clientData;
- sendSignal(reference(), GSN_STOP_ME_CONF, signal,
- StopMeConf::SignalLength, JBB);
- }//if
-}//Dbdih::checkStopMe()
-
-void Dbdih::checkStopPermMaster(Signal* signal, NodeRecordPtr failedNodePtr)
-{
- DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
- jam();
- if (c_DIH_SWITCH_REPLICA_REQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- ndbrequire(c_stopPermMaster.clientRef != 0);
- ref->senderNode = failedNodePtr.i;
- ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
- sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REF, signal,
- DihSwitchReplicaRef::SignalLength, JBB);
- return;
- }//if
-}//Dbdih::checkStopPermMaster()
-
-void Dbdih::checkStopPermProxy(Signal* signal, NodeId failedNodeId)
-{
- jam();
- if(c_stopPermProxy.clientRef != 0 &&
- refToNode(c_stopPermProxy.masterRef) == failedNodeId){
-
- /**
- * The master has failed report to proxy-client
- */
- jam();
- StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
-
- ref->senderData = c_stopPermProxy.clientData;
- ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
- sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
- c_stopPermProxy.clientRef = 0;
- }//if
-}//Dbdih::checkStopPermProxy()
-
-void
-Dbdih::checkTakeOverInMasterAllNodeFailure(Signal* signal,
- NodeRecordPtr failedNodePtr)
-{
- //------------------------------------------------------------------------
- // This code is used to handle the failure of "all" nodes during the
- // take over when "all" nodes are informed about state changes in
- // the take over protocol.
- //--------------------------------------------------------------------------
- if (c_START_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- StartToConf * const conf = (StartToConf *)&signal->theData[0];
- conf->userPtr = c_startToLock;
- conf->sendingNodeId = failedNodePtr.i;
- conf->startingNodeId = getStartNode(c_startToLock);
- sendSignal(reference(), GSN_START_TOCONF, signal,
- StartToConf::SignalLength, JBB);
- }//if
- if (c_CREATE_FRAGREQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = c_createFragmentLock;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- conf->userPtr = takeOverPtr.i;
- conf->tableId = takeOverPtr.p->toCurrentTabref;
- conf->fragId = takeOverPtr.p->toCurrentFragid;
- conf->sendingNodeId = failedNodePtr.i;
- conf->startingNodeId = takeOverPtr.p->toStartingNode;
- sendSignal(reference(), GSN_CREATE_FRAGCONF, signal,
- CreateFragConf::SignalLength, JBB);
- }//if
- if (c_UPDATE_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
- conf->userPtr = c_updateToLock;
- conf->sendingNodeId = failedNodePtr.i;
- conf->startingNodeId = getStartNode(c_updateToLock);
- sendSignal(reference(), GSN_UPDATE_TOCONF, signal,
- UpdateToConf::SignalLength, JBB);
- }//if
-
- if (c_END_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
- jam();
- EndToConf * const conf = (EndToConf *)&signal->theData[0];
- conf->userPtr = c_endToLock;
- conf->sendingNodeId = failedNodePtr.i;
- conf->startingNodeId = getStartNode(c_endToLock);
- sendSignal(reference(), GSN_END_TOCONF, signal,
- EndToConf::SignalLength, JBB);
- }//if
-}//Dbdih::checkTakeOverInMasterAllNodeFailure()
-
-void Dbdih::checkTakeOverInMasterCopyNodeFailure(Signal* signal,
- Uint32 failedNodeId)
-{
- //---------------------------------------------------------------------------
- // This code is used to handle failure of the copying node during a take over
- //---------------------------------------------------------------------------
- TakeOverRecordPtr takeOverPtr;
- for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
- jam();
- takeOverPtr.i = i;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
- (takeOverPtr.p->toCopyNode == failedNodeId)) {
- jam();
- /**
- * The copying node failed but the system is still operational.
- * We restart the copy process by selecting a new copy node.
- * We do not need to add a fragment however since it is already added.
- * We start again from the prepare create fragment phase.
- */
- prepareSendCreateFragReq(signal, takeOverPtr.i);
- }//if
- }//for
-}//Dbdih::checkTakeOverInMasterCopyNodeFailure()
-
-void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal,
- Uint32 takeOverPtrI)
-{
- jam();
- ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
- takeOverPtrI);
- if (takeOverPtrI == RNIL) {
- jam();
- return;
- }
- //-----------------------------------------------------------------------
- // We are the master and the starting node has failed during a take over.
- // We need to handle this failure in different ways depending on the state.
- //-----------------------------------------------------------------------
-
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
-
- ndbout_c("takeOverPtr.p->toMasterStatus: %x",
- takeOverPtr.p->toMasterStatus);
-
- bool ok = false;
- switch (takeOverPtr.p->toMasterStatus) {
- case TakeOverRecord::IDLE:
- //-----------------------------------------------------------------------
- // The state cannot be idle when it has a starting node.
- //-----------------------------------------------------------------------
- ndbrequire(false);
- break;
- case TakeOverRecord::TO_WAIT_START_TAKE_OVER:
- jam();
- case TakeOverRecord::TO_START_COPY:
- jam();
- case TakeOverRecord::TO_START_COPY_ONGOING:
- jam();
- case TakeOverRecord::TO_WAIT_START:
- jam();
- case TakeOverRecord::TO_WAIT_PREPARE_CREATE:
- jam();
- case TakeOverRecord::TO_WAIT_UPDATE_TO:
- jam();
- case TakeOverRecord::TO_WAIT_COMMIT_CREATE:
- jam();
- case TakeOverRecord::TO_END_COPY:
- jam();
- case TakeOverRecord::TO_END_COPY_ONGOING:
- jam();
- case TakeOverRecord::TO_WAIT_ENDING:
- jam();
- //-----------------------------------------------------------------------
- // We will not do anything since an internal signal process is outstanding.
- // When the signal arrives the take over will be released.
- //-----------------------------------------------------------------------
- ok = true;
- break;
- case TakeOverRecord::STARTING:
- jam();
- ok = true;
- c_startToLock = RNIL;
- c_START_TOREQ_Counter.clearWaitingFor();
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::TO_UPDATE_TO:
- jam();
- ok = true;
- c_updateToLock = RNIL;
- c_UPDATE_TOREQ_Counter.clearWaitingFor();
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::ENDING:
- jam();
- ok = true;
- c_endToLock = RNIL;
- c_END_TOREQ_Counter.clearWaitingFor();
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::COMMIT_CREATE:
- ok = true;
- jam();
- {// We have mutex
- Mutex m(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
- m.unlock(); // Ignore result
- }
- // Fall through
- case TakeOverRecord::PREPARE_CREATE:
- ok = true;
- jam();
- c_createFragmentLock = RNIL;
- c_CREATE_FRAGREQ_Counter.clearWaitingFor();
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::LOCK_MUTEX:
- ok = true;
- jam();
- // Lock mutex will return and do endTakeOver
- break;
-
- //-----------------------------------------------------------------------
- // Signals are outstanding to external nodes. These signals carry the node
- // id of the starting node and will not use the take over record if the
- // starting node has failed.
- //-----------------------------------------------------------------------
- case TakeOverRecord::COPY_FRAG:
- ok = true;
- jam();
- //-----------------------------------------------------------------------
- // The copying node will discover the problem. We will receive either
- // COPY_FRAGREQ or COPY_FRAGCONF and then we can release the take over
- // record and end the process. If the copying node should also die then
- // we will try to send prepare create fragment and will then discover
- // that the starting node has failed.
- //-----------------------------------------------------------------------
- break;
- case TakeOverRecord::PREPARE_COPY:
- ok = true;
- jam();
- /**
- * We're waiting for the starting node...which just died...
- * endTakeOver
- */
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::COPY_ACTIVE:
- ok = true;
- jam();
- //-----------------------------------------------------------------------
- // In this we are waiting for a signal from the starting node. Thus we
- // can release the take over record and end the process.
- //-----------------------------------------------------------------------
- endTakeOver(takeOverPtr.i);
- break;
- case TakeOverRecord::WAIT_LCP:
- ok = true;
- jam();
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- endTakeOver(takeOverPtr.i);
- break;
-
- case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
- ok = true;
- jam();
- endTakeOver(takeOverPtr.i);
- break;
-
- /**
- * The following are states that it should not be possible to "be" in
- */
- case TakeOverRecord::SELECTING_NEXT:
- jam();
- case TakeOverRecord::TO_COPY_COMPLETED:
- jam();
- ndbrequire(false);
- }
- if(!ok){
- jamLine(takeOverPtr.p->toSlaveStatus);
- ndbrequire(ok);
- }
-}//Dbdih::checkTakeOverInMasterStartNodeFailure()
-
-void Dbdih::checkTakeOverInNonMasterStartNodeFailure(Signal* signal,
- Uint32 takeOverPtrI)
-{
- jam();
- if (takeOverPtrI == RNIL) {
- jam();
- return;
- }
- //-----------------------------------------------------------------------
- // We are not master and not taking over as master. A take over was ongoing
- // but the starting node has now failed. Handle it according to the state
- // of the take over.
- //-----------------------------------------------------------------------
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- bool ok = false;
- switch (takeOverPtr.p->toSlaveStatus) {
- case TakeOverRecord::TO_SLAVE_IDLE:
- ndbrequire(false);
- break;
- case TakeOverRecord::TO_SLAVE_STARTED:
- jam();
- case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
- jam();
- case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
- jam();
- case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
- jam();
- case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
- jam();
- ok = true;
- endTakeOver(takeOverPtr.i);
- break;
- }//switch
- if(!ok){
- jamLine(takeOverPtr.p->toSlaveStatus);
- ndbrequire(ok);
- }
-}//Dbdih::checkTakeOverInNonMasterStartNodeFailure()
-
-void Dbdih::failedNodeSynchHandling(Signal* signal,
- NodeRecordPtr failedNodePtr)
-{
- jam();
- /*----------------------------------------------------*/
- /* INITIALISE THE VARIABLES THAT KEEP TRACK OF */
- /* WHEN A NODE FAILURE IS COMPLETED. */
- /*----------------------------------------------------*/
- failedNodePtr.p->dbdictFailCompleted = ZFALSE;
- failedNodePtr.p->dbtcFailCompleted = ZFALSE;
- failedNodePtr.p->dbdihFailCompleted = ZFALSE;
- failedNodePtr.p->dblqhFailCompleted = ZFALSE;
-
- failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor();
-
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- /**
- * We'r waiting for nodePtr.i to complete
- * handling of failedNodePtr.i's death
- */
-
- failedNodePtr.p->m_NF_COMPLETE_REP.setWaitingFor(nodePtr.i);
- } else {
- jam();
- if ((nodePtr.p->nodeStatus == NodeRecord::DYING) &&
- (nodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(failedNodePtr.i))){
- jam();
- /*----------------------------------------------------*/
- /* THE NODE FAILED BEFORE REPORTING THE FAILURE */
- /* HANDLING COMPLETED ON THIS FAILED NODE. */
- /* REPORT THAT NODE FAILURE HANDLING WAS */
- /* COMPLETED ON THE NEW FAILED NODE FOR THIS */
- /* PARTICULAR OLD FAILED NODE. */
- /*----------------------------------------------------*/
- NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
- nf->blockNo = 0;
- nf->nodeId = failedNodePtr.i;
- nf->failedNodeId = nodePtr.i;
- nf->from = __LINE__;
- sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
- }//if
- }//if
- }//for
- if (failedNodePtr.p->nodeStatus == NodeRecord::DIED_NOW) {
- jam();
- failedNodePtr.p->nodeStatus = NodeRecord::DYING;
- } else {
- jam();
- /*----------------------------------------------------*/
- // No more processing needed when node not even started
- // yet. We give the node status to DEAD since we do not
- // care whether all nodes complete the node failure
- // handling. The node have not been included in the
- // node failure protocols.
- /*----------------------------------------------------*/
- failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
- /**-----------------------------------------------------------------------
- * WE HAVE COMPLETED HANDLING THE NODE FAILURE IN DIH. WE CAN REPORT THIS
- * TO DIH THAT WAIT FOR THE OTHER BLOCKS TO BE CONCLUDED AS WELL.
- *-----------------------------------------------------------------------*/
- NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
- nf->blockNo = DBDIH;
- nf->nodeId = cownNodeId;
- nf->failedNodeId = failedNodePtr.i;
- nf->from = __LINE__;
- sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
- }//if
-}//Dbdih::failedNodeSynchHandling()
-
-Uint32 Dbdih::findTakeOver(Uint32 failedNodeId)
-{
- for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
- jam();
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = i;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- if (takeOverPtr.p->toStartingNode == failedNodeId) {
- jam();
- return i;
- }//if
- }//for
- return RNIL;
-}//Dbdih::findTakeOver()
-
-Uint32 Dbdih::getStartNode(Uint32 takeOverPtrI)
-{
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- return takeOverPtr.p->toStartingNode;
-}//Dbdih::getStartNode()
-
-void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
-{
- jam();
- const Uint32 nodeId = failedNodePtr.i;
-
- if (isMaster() && c_lcpState.m_participatingLQH.get(failedNodePtr.i))
- {
- /*----------------------------------------------------*/
- /* THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE */
- /* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT */
- /* THE NODE HAVE MISSED A LOCAL CHECKPOINT. */
- /*----------------------------------------------------*/
-
- /**
- * Bug#28717, Only master should do this, as this status is copied
- * to other nodes
- */
- switch (failedNodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- jam();
- failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
- break;
- case Sysfile::NS_ActiveMissed_1:
- jam();
- failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- break;
- case Sysfile::NS_TakeOver:
- jam();
- failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- break;
- default:
- g_eventLogger.error("activeStatus = %u "
- "at failure after NODE_FAILREP of node = %u",
- (Uint32) failedNodePtr.p->activeStatus,
- failedNodePtr.i);
- ndbrequire(false);
- break;
- }//switch
- }//if
-
- c_lcpState.m_participatingDIH.clear(failedNodePtr.i);
- c_lcpState.m_participatingLQH.clear(failedNodePtr.i);
-
- if(c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.isWaitingFor(failedNodePtr.i)){
- jam();
- LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
- rep->nodeId = failedNodePtr.i;
- rep->lcpId = SYSFILE->latestLCP_ID;
- rep->blockNo = DBDIH;
- sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
- LcpCompleteRep::SignalLength, JBB);
- }
-
- /**
- * Check if we'r waiting for the failed node's LQH to complete
- *
- * Note that this is ran "before" LCP master take over
- */
- if(c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId)){
- jam();
-
- LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
- rep->nodeId = nodeId;
- rep->lcpId = SYSFILE->latestLCP_ID;
- rep->blockNo = DBLQH;
- sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal,
- LcpCompleteRep::SignalLength, JBB);
-
- if(c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId)){
- jam();
- /**
- * Make sure we're ready to accept it
- */
- c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodeId);
- }
- }
-
- if (c_TCGETOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
- jam();
- signal->theData[0] = failedNodePtr.i;
- signal->theData[1] = 0;
- sendSignal(reference(), GSN_TCGETOPSIZECONF, signal, 2, JBB);
- }//if
-
- if (c_TC_CLOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
- jam();
- signal->theData[0] = failedNodePtr.i;
- sendSignal(reference(), GSN_TC_CLOPSIZECONF, signal, 1, JBB);
- }//if
-
- if (c_START_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
- jam();
- StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
- conf->senderRef = numberToRef(DBLQH, failedNodePtr.i);
- conf->lcpId = SYSFILE->latestLCP_ID;
- sendSignal(reference(), GSN_START_LCP_CONF, signal,
- StartLcpConf::SignalLength, JBB);
- }//if
-
- if (c_EMPTY_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
- jam();
- EmptyLcpConf * const rep = (EmptyLcpConf *)&signal->theData[0];
- rep->senderNodeId = failedNodePtr.i;
- rep->tableId = ~0;
- rep->fragmentId = ~0;
- rep->lcpNo = 0;
- rep->lcpId = SYSFILE->latestLCP_ID;
- rep->idle = true;
- sendSignal(reference(), GSN_EMPTY_LCP_CONF, signal,
- EmptyLcpConf::SignalLength, JBB);
- }//if
-
- if (c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i)) {
- jam();
- MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
- ref->senderNodeId = failedNodePtr.i;
- ref->failedNodeId = cmasterTakeOverNode;
- sendSignal(reference(), GSN_MASTER_LCPREF, signal,
- MasterLCPRef::SignalLength, JBB);
- }//if
-
-}//Dbdih::failedNodeLcpHandling()
-
-void Dbdih::checkGcpOutstanding(Signal* signal, Uint32 failedNodeId){
- if (c_GCP_PREPARE_Counter.isWaitingFor(failedNodeId)){
- jam();
- signal->theData[0] = failedNodeId;
- signal->theData[1] = cnewgcp;
- sendSignal(reference(), GSN_GCP_PREPARECONF, signal, 2, JBB);
- }//if
-
- if (c_GCP_COMMIT_Counter.isWaitingFor(failedNodeId)) {
- jam();
- signal->theData[0] = failedNodeId;
- signal->theData[1] = coldgcp;
- signal->theData[2] = cfailurenr;
- sendSignal(reference(), GSN_GCP_NODEFINISH, signal, 3, JBB);
- }//if
-
- if (c_GCP_SAVEREQ_Counter.isWaitingFor(failedNodeId)) {
- jam();
- GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
- saveRef->dihPtr = failedNodeId;
- saveRef->nodeId = failedNodeId;
- saveRef->gci = coldgcp;
- saveRef->errorCode = GCPSaveRef::FakedSignalDueToNodeFailure;
- sendSignal(reference(), GSN_GCP_SAVEREF, signal,
- GCPSaveRef::SignalLength, JBB);
- }//if
-
- if (c_COPY_GCIREQ_Counter.isWaitingFor(failedNodeId)) {
- jam();
- signal->theData[0] = failedNodeId;
- sendSignal(reference(), GSN_COPY_GCICONF, signal, 1, JBB);
- }//if
-
- if (c_MASTER_GCPREQ_Counter.isWaitingFor(failedNodeId)){
- jam();
- MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
- ref->senderNodeId = failedNodeId;
- ref->failedNodeId = cmasterTakeOverNode;
- sendSignal(reference(), GSN_MASTER_GCPREF, signal,
- MasterGCPRef::SignalLength, JBB);
- }//if
-}//Dbdih::handleGcpStateInMaster()
-
-
-void
-Dbdih::startLcpMasterTakeOver(Signal* signal, Uint32 nodeId){
- jam();
-
- Uint32 oldNode = c_lcpMasterTakeOverState.failedNodeId;
-
- c_lcpMasterTakeOverState.minTableId = ~0;
- c_lcpMasterTakeOverState.minFragId = ~0;
- c_lcpMasterTakeOverState.failedNodeId = nodeId;
-
- c_lcpMasterTakeOverState.set(LMTOS_WAIT_EMPTY_LCP, __LINE__);
-
- if(c_EMPTY_LCP_REQ_Counter.done()){
- jam();
- c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor();
-
- EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- sendLoopMacro(EMPTY_LCP_REQ, sendEMPTY_LCP_REQ);
- ndbrequire(!c_EMPTY_LCP_REQ_Counter.done());
- } else {
- /**
- * Node failure during master take over...
- */
- g_eventLogger.info("Nodefail during master take over (old: %d)", oldNode);
- }
-
- NodeRecordPtr nodePtr;
- nodePtr.i = oldNode;
- if (oldNode > 0 && oldNode < MAX_NDB_NODES)
- {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->m_nodefailSteps.get(NF_LCP_TAKE_OVER))
- {
- jam();
- checkLocalNodefailComplete(signal, oldNode, NF_LCP_TAKE_OVER);
- }
- }
-
- setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
-}
-
-void Dbdih::startGcpMasterTakeOver(Signal* signal, Uint32 oldMasterId){
- jam();
- /*--------------------------------------------------*/
- /* */
- /* THE MASTER HAVE FAILED AND WE WERE ELECTED */
- /* TO BE THE NEW MASTER NODE. WE NEED TO QUERY*/
- /* ALL THE OTHER NODES ABOUT THEIR STATUS IN */
- /* ORDER TO BE ABLE TO TAKE OVER CONTROL OF */
- /* THE GLOBAL CHECKPOINT PROTOCOL AND THE */
- /* LOCAL CHECKPOINT PROTOCOL. */
- /*--------------------------------------------------*/
- if(!isMaster()){
- jam();
- return;
- }
- cmasterState = MASTER_TAKE_OVER_GCP;
- cmasterTakeOverNode = oldMasterId;
- MasterGCPReq * const req = (MasterGCPReq *)&signal->theData[0];
- req->masterRef = reference();
- req->failedNodeId = oldMasterId;
- sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ);
- cgcpMasterTakeOverState = GMTOS_INITIAL;
-
- signal->theData[0] = NDB_LE_GCP_TakeoverStarted;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-
- setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
-}//Dbdih::handleNewMaster()
-
-void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
-{
- jam();
- if (takeOverPtrI != RNIL) {
- jam();
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = takeOverPtrI;
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- bool ok = false;
- switch (takeOverPtr.p->toSlaveStatus) {
- case TakeOverRecord::TO_SLAVE_IDLE:
- ndbrequire(false);
- break;
- case TakeOverRecord::TO_SLAVE_STARTED:
- jam();
- case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
- jam();
- case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
- jam();
- case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
- jam();
- ok = true;
- infoEvent("Unhandled MasterTO of TO slaveStatus=%d killing node %d",
- takeOverPtr.p->toSlaveStatus,
- takeOverPtr.p->toStartingNode);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
-
- {
- BlockReference cntrRef = calcNdbCntrBlockRef(takeOverPtr.p->toStartingNode);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::CopyFragRefError;
- sysErr->errorRef = reference();
- sysErr->data1= 0;
- sysErr->data2= __LINE__;
- sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBB);
- }
- break;
- case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
- ok = true;
- jam();
- takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
- break;
- }
- ndbrequire(ok);
- endTakeOver(takeOverPtr.i);
- }//if
-}//Dbdih::handleTakeOverNewMaster()
-
-void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
-{
- Uint32 nodeId = failedNodePtr.i;
- if(failedNodePtr.p->nodeStatus != NodeRecord::DIED_NOW){
- jam();
- /**
- * Is node isn't alive. It can't be part of LCP
- */
- ndbrequire(!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId));
-
- /**
- * And there is no point in removing any replicas
- * It's dead...
- */
- return;
- }
-
- /**
- * If node has node complete LCP
- * we need to remove it as undo might not be complete
- * bug#31257
- */
- failedNodePtr.p->m_remove_node_from_table_lcp_id = RNIL;
- if (c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(failedNodePtr.i))
- {
- jam();
- failedNodePtr.p->m_remove_node_from_table_lcp_id = SYSFILE->latestLCP_ID;
- }
-
- jam();
-
- if (!ERROR_INSERTED(7194))
- {
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = failedNodePtr.i;
- signal->theData[2] = 0; // Tab id
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
- else
- {
- ndbout_c("7194 Not starting ZREMOVE_NODE_FROM_TABLE");
- }
-
- setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
-}//Dbdih::startRemoveFailedNode()
-
-/*--------------------------------------------------*/
-/* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
-/* QUERYING THIS NODE ABOUT THE STATE OF THE */
-/* GLOBAL CHECKPOINT PROTOCOL */
-/*--------------------------------------------------*/
-void Dbdih::execMASTER_GCPREQ(Signal* signal)
-{
- NodeRecordPtr failedNodePtr;
- MasterGCPReq * const masterGCPReq = (MasterGCPReq *)&signal->theData[0];
- jamEntry();
- const BlockReference newMasterBlockref = masterGCPReq->masterRef;
- const Uint32 failedNodeId = masterGCPReq->failedNodeId;
- if (c_copyGCISlave.m_copyReason != CopyGCIReq::IDLE) {
- jam();
- /*--------------------------------------------------*/
- /* WE ARE CURRENTLY WRITING THE RESTART INFO */
- /* IN THIS NODE. SINCE ONLY ONE PROCESS IS */
- /* ALLOWED TO DO THIS AT A TIME WE MUST ENSURE*/
- /* THAT THIS IS NOT ONGOING WHEN THE NEW */
- /* MASTER TAKES OVER CONTROL. IF NOT ALL NODES*/
- /* RECEIVE THE SAME RESTART INFO DUE TO THE */
- /* FAILURE OF THE MASTER IT IS TAKEN CARE OF */
- /* BY THE NEW MASTER. */
- /*--------------------------------------------------*/
- sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
- signal, 10, MasterGCPReq::SignalLength);
- return;
- }//if
- failedNodePtr.i = failedNodeId;
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
- if (failedNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- /*--------------------------------------------------*/
- /* ENSURE THAT WE HAVE PROCESSED THE SIGNAL */
- /* NODE_FAILURE BEFORE WE PROCESS THIS REQUEST*/
- /* FROM THE NEW MASTER. THIS ENSURES THAT WE */
- /* HAVE REMOVED THE FAILED NODE FROM THE LIST */
- /* OF ACTIVE NODES AND SO FORTH. */
- /*--------------------------------------------------*/
- sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
- signal, 10, MasterGCPReq::SignalLength);
- return;
- } else {
- ndbrequire(failedNodePtr.p->nodeStatus == NodeRecord::DYING);
- }//if
-
- if (ERROR_INSERTED(7181))
- {
- ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
- CLEAR_ERROR_INSERT_VALUE;
- signal->theData[0] = c_error_7181_ref;
- signal->theData[1] = coldgcp;
- execGCP_TCFINISHED(signal);
- }
-
- MasterGCPConf::State gcpState;
- switch (cgcpParticipantState) {
- case GCP_PARTICIPANT_READY:
- jam();
- /*--------------------------------------------------*/
- /* THE GLOBAL CHECKPOINT IS NOT ACTIVE SINCE */
- /* THE PREVIOUS GLOBAL CHECKPOINT IS COMPLETED*/
- /* AND THE NEW HAVE NOT STARTED YET. */
- /*--------------------------------------------------*/
- gcpState = MasterGCPConf::GCP_READY;
- break;
- case GCP_PARTICIPANT_PREPARE_RECEIVED:
- jam();
- /*--------------------------------------------------*/
- /* GCP_PREPARE HAVE BEEN RECEIVED AND RESPONSE*/
- /* HAVE BEEN SENT. */
- /*--------------------------------------------------*/
- gcpState = MasterGCPConf::GCP_PREPARE_RECEIVED;
- break;
- case GCP_PARTICIPANT_COMMIT_RECEIVED:
- jam();
- /*------------------------------------------------*/
- /* GCP_COMMIT HAVE BEEN RECEIVED BUT NOT YET*/
- /* GCP_TCFINISHED FROM LOCAL TC. */
- /*------------------------------------------------*/
- gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
- break;
- case GCP_PARTICIPANT_TC_FINISHED:
- jam();
- /*------------------------------------------------*/
- /* GCP_COMMIT HAS BEEN RECEIVED AND ALSO */
- /* GCP_TCFINISHED HAVE BEEN RECEIVED. */
- /*------------------------------------------------*/
- gcpState = MasterGCPConf::GCP_TC_FINISHED;
- break;
- case GCP_PARTICIPANT_COPY_GCI_RECEIVED:
- /*--------------------------------------------------*/
- /* COPY RESTART INFORMATION HAS BEEN RECEIVED */
- /* BUT NOT YET COMPLETED. */
- /*--------------------------------------------------*/
- ndbrequire(false);
- gcpState= MasterGCPConf::GCP_READY; // remove warning
- break;
- default:
- /*------------------------------------------------*/
- /* */
- /* THIS SHOULD NOT OCCUR SINCE THE ABOVE */
- /* STATES ARE THE ONLY POSSIBLE STATES AT A */
- /* NODE WHICH WAS NOT A MASTER NODE. */
- /*------------------------------------------------*/
- ndbrequire(false);
- gcpState= MasterGCPConf::GCP_READY; // remove warning
- break;
- }//switch
- MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
- masterGCPConf->gcpState = gcpState;
- masterGCPConf->senderNodeId = cownNodeId;
- masterGCPConf->failedNodeId = failedNodeId;
- masterGCPConf->newGCP = cnewgcp;
- masterGCPConf->latestLCP = SYSFILE->latestLCP_ID;
- masterGCPConf->oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
- masterGCPConf->keepGCI = SYSFILE->keepGCI;
- for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
- masterGCPConf->lcpActive[i] = SYSFILE->lcpActive[i];
- sendSignal(newMasterBlockref, GSN_MASTER_GCPCONF, signal,
- MasterGCPConf::SignalLength, JBB);
-
- if (ERROR_INSERTED(7182))
- {
- ndbout_c("execGCP_TCFINISHED in MASTER_GCPREQ");
- CLEAR_ERROR_INSERT_VALUE;
- signal->theData[0] = c_error_7181_ref;
- signal->theData[1] = coldgcp;
- execGCP_TCFINISHED(signal);
- }
-}//Dbdih::execMASTER_GCPREQ()
-
-void Dbdih::execMASTER_GCPCONF(Signal* signal)
-{
- NodeRecordPtr senderNodePtr;
- MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
- jamEntry();
- senderNodePtr.i = masterGCPConf->senderNodeId;
- ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRecord);
-
- MasterGCPConf::State gcpState = (MasterGCPConf::State)masterGCPConf->gcpState;
- const Uint32 failedNodeId = masterGCPConf->failedNodeId;
- const Uint32 newGcp = masterGCPConf->newGCP;
- const Uint32 latestLcpId = masterGCPConf->latestLCP;
- const Uint32 oldestRestorableGci = masterGCPConf->oldestRestorableGCI;
- const Uint32 oldestKeepGci = masterGCPConf->keepGCI;
- if (latestLcpId > SYSFILE->latestLCP_ID) {
- jam();
-#if 0
- g_eventLogger.info("Dbdih: Setting SYSFILE->latestLCP_ID to %d",
- latestLcpId);
- SYSFILE->latestLCP_ID = latestLcpId;
-#endif
- SYSFILE->keepGCI = oldestKeepGci;
- SYSFILE->oldestRestorableGCI = oldestRestorableGci;
- for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
- SYSFILE->lcpActive[i] = masterGCPConf->lcpActive[i];
- }//if
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- senderNodePtr.p->gcpstate = NodeRecord::READY;
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- senderNodePtr.p->gcpstate = NodeRecord::PREPARE_RECEIVED;
- cnewgcp = newGcp;
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- jam();
- senderNodePtr.p->gcpstate = NodeRecord::COMMIT_SENT;
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- senderNodePtr.p->gcpstate = NodeRecord::NODE_FINISHED;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- switch (cgcpMasterTakeOverState) {
- case GMTOS_INITIAL:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- cgcpMasterTakeOverState = ALL_READY;
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- cgcpMasterTakeOverState = ALL_PREPARED;
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- jam();
- cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- cgcpMasterTakeOverState = COMMIT_COMPLETED;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case ALL_READY:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- /*empty*/;
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- ndbrequire(false);
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case PREPARE_STARTED_NOT_COMMITTED:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- ndbrequire(false);
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- ndbrequire(false);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case ALL_PREPARED:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- jam();
- cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case COMMIT_STARTED_NOT_COMPLETED:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- ndbrequire(false);
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- jam();
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case COMMIT_COMPLETED:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- jam();
- cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- jam();
- cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- case SAVE_STARTED_NOT_COMPLETED:
- switch (gcpState) {
- case MasterGCPConf::GCP_READY:
- jam();
- break;
- case MasterGCPConf::GCP_PREPARE_RECEIVED:
- ndbrequire(false);
- break;
- case MasterGCPConf::GCP_COMMIT_RECEIVED:
- ndbrequire(false);
- break;
- case MasterGCPConf::GCP_TC_FINISHED:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- receiveLoopMacro(MASTER_GCPREQ, senderNodePtr.i);
- /*-------------------------------------------------------------------------*/
- // We have now received all responses and are ready to take over the GCP
- // protocol as master.
- /*-------------------------------------------------------------------------*/
- MASTER_GCPhandling(signal, failedNodeId);
- return;
-}//Dbdih::execMASTER_GCPCONF()
-
-void Dbdih::execMASTER_GCPREF(Signal* signal)
-{
- const MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
- jamEntry();
- receiveLoopMacro(MASTER_GCPREQ, ref->senderNodeId);
- /*-------------------------------------------------------------------------*/
- // We have now received all responses and are ready to take over the GCP
- // protocol as master.
- /*-------------------------------------------------------------------------*/
- MASTER_GCPhandling(signal, ref->failedNodeId);
-}//Dbdih::execMASTER_GCPREF()
-
-void Dbdih::MASTER_GCPhandling(Signal* signal, Uint32 failedNodeId)
-{
- NodeRecordPtr failedNodePtr;
- cmasterState = MASTER_ACTIVE;
- /*----------------------------------------------------------*/
- /* REMOVE ALL ACTIVE STATUS ON ALREADY FAILED NODES */
- /* THIS IS PERFORMED HERE SINCE WE GET THE LCP ACTIVE */
- /* STATUS AS PART OF THE COPY RESTART INFO AND THIS IS*/
- /* HANDLED BY THE MASTER GCP TAKE OVER PROTOCOL. */
- /*----------------------------------------------------------*/
-
- failedNodePtr.i = failedNodeId;
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
- switch (cgcpMasterTakeOverState) {
- case ALL_READY:
- jam();
- startGcp(signal);
- break;
- case PREPARE_STARTED_NOT_COMMITTED:
- {
- NodeRecordPtr nodePtr;
- jam();
- c_GCP_PREPARE_Counter.clearWaitingFor();
- nodePtr.i = cfirstAliveNode;
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->gcpstate == NodeRecord::READY) {
- jam();
- c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
- sendGCP_PREPARE(signal, nodePtr.i);
- }//if
- nodePtr.i = nodePtr.p->nextNode;
- } while(nodePtr.i != RNIL);
- if (c_GCP_PREPARE_Counter.done()) {
- jam();
- gcpcommitreqLab(signal);
- }//if
- break;
- }
- case ALL_PREPARED:
- jam();
- gcpcommitreqLab(signal);
- break;
- case COMMIT_STARTED_NOT_COMPLETED:
- {
- NodeRecordPtr nodePtr;
- jam();
- c_GCP_COMMIT_Counter.clearWaitingFor();
- nodePtr.i = cfirstAliveNode;
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->gcpstate == NodeRecord::PREPARE_RECEIVED) {
- jam();
- sendGCP_COMMIT(signal, nodePtr.i);
- c_GCP_COMMIT_Counter.setWaitingFor(nodePtr.i);
- } else {
- ndbrequire((nodePtr.p->gcpstate == NodeRecord::NODE_FINISHED) ||
- (nodePtr.p->gcpstate == NodeRecord::COMMIT_SENT));
- }//if
- nodePtr.i = nodePtr.p->nextNode;
- } while(nodePtr.i != RNIL);
- if (c_GCP_COMMIT_Counter.done()){
- jam();
- gcpsavereqLab(signal);
- }//if
- break;
- }
- case COMMIT_COMPLETED:
- jam();
- gcpsavereqLab(signal);
- break;
- case SAVE_STARTED_NOT_COMPLETED:
- {
- NodeRecordPtr nodePtr;
- jam();
- SYSFILE->newestRestorableGCI = coldgcp;
- nodePtr.i = cfirstAliveNode;
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- SYSFILE->lastCompletedGCI[nodePtr.i] = coldgcp;
- nodePtr.i = nodePtr.p->nextNode;
- } while (nodePtr.i != RNIL);
- /**-------------------------------------------------------------------
- * THE FAILED NODE DID ALSO PARTICIPATE IN THIS GLOBAL CHECKPOINT
- * WHICH IS RECORDED.
- *-------------------------------------------------------------------*/
- SYSFILE->lastCompletedGCI[failedNodeId] = coldgcp;
- copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
- break;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
-
- signal->theData[0] = NDB_LE_GCP_TakeoverCompleted;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-
- /*--------------------------------------------------*/
- /* WE SEPARATE HANDLING OF GLOBAL CHECKPOINTS */
- /* AND LOCAL CHECKPOINTS HERE. LCP'S HAVE TO */
- /* REMOVE ALL FAILED FRAGMENTS BEFORE WE CAN */
- /* HANDLE THE LCP PROTOCOL. */
- /*--------------------------------------------------*/
- checkLocalNodefailComplete(signal, failedNodeId, NF_GCP_TAKE_OVER);
-
- return;
-}//Dbdih::masterGcpConfFromFailedLab()
-
-void
-Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, Uint32 tableId)
-{
- jamEntry();
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- const Uint32 RT_BREAK = 64;
- if (ERROR_INSERTED(7125)) {
- return;
- }//if
- for (Uint32 i = 0; i<RT_BREAK; i++) {
- jam();
- if (tabPtr.i >= ctabFileSize){
- jam();
- /**
- * Ready with entire loop
- * Return to master
- */
- setAllowNodeStart(nodeId, true);
- if (getNodeStatus(nodeId) == NodeRecord::STARTING) {
- jam();
- StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
- conf->sendingNodeId = cownNodeId;
- conf->startingNodeId = nodeId;
- sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
- StartInfoConf::SignalLength, JBB);
- }//if
- return;
- }//if
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
- jam();
- invalidateNodeLCP(signal, nodeId, tabPtr);
- return;
- }//if
- tabPtr.i++;
- }//for
- signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}//Dbdih::invalidateNodeLCP()
-
-void
-Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr)
-{
- /**
- * Check so that no one else is using the tab descriptior
- */
- if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
- jam();
- signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
- return;
- }//if
-
- /**
- * For each fragment
- */
- bool modified = false;
- FragmentstorePtr fragPtr;
- for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
- jam();
- getFragstore(tabPtr.p, fragNo, fragPtr);
- /**
- * For each of replica record
- */
- ReplicaRecordPtr replicaPtr;
- for(replicaPtr.i = fragPtr.p->oldStoredReplicas; replicaPtr.i != RNIL;
- replicaPtr.i = replicaPtr.p->nextReplica) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if(replicaPtr.p->procNode == nodeId){
- jam();
- /**
- * Found one with correct node id
- */
- /**
- * Invalidate all LCP's
- */
- modified = true;
- for(int i = 0; i < MAX_LCP_STORED; i++) {
- replicaPtr.p->lcpStatus[i] = ZINVALID;
- }//if
- /**
- * And reset nextLcp
- */
- replicaPtr.p->nextLcp = 0;
- replicaPtr.p->noCrashedReplicas = 0;
- }//if
- }//for
- }//for
-
- if (modified) {
- jam();
- /**
- * Save table description to disk
- */
- tabPtr.p->tabCopyStatus = TabRecord::CS_INVALIDATE_NODE_LCP;
- tabPtr.p->tabUpdateState = TabRecord::US_INVALIDATE_NODE_LCP;
- tabPtr.p->tabRemoveNode = nodeId;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- jam();
- /**
- * Move to next table
- */
- tabPtr.i++;
- signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
-}//Dbdih::invalidateNodeLCP()
-
-/*------------------------------------------------*/
-/* INPUT: TABPTR */
-/* TNODEID */
-/*------------------------------------------------*/
-void Dbdih::removeNodeFromTables(Signal* signal,
- Uint32 nodeId, Uint32 tableId)
-{
- jamEntry();
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- const Uint32 RT_BREAK = 64;
- for (Uint32 i = 0; i<RT_BREAK; i++) {
- jam();
- if (tabPtr.i >= ctabFileSize){
- jam();
- removeNodeFromTablesComplete(signal, nodeId);
- return;
- }//if
-
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
- jam();
- removeNodeFromTable(signal, nodeId, tabPtr);
- return;
- }//if
- tabPtr.i++;
- }//for
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void Dbdih::removeNodeFromTable(Signal* signal,
- Uint32 nodeId, TabRecordPtr tabPtr){
-
- /**
- * Check so that no one else is using the tab descriptior
- */
- if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
- jam();
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
- return;
- }//if
-
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- const Uint32 lcpId = nodePtr.p->m_remove_node_from_table_lcp_id;
-
- /**
- * For each fragment
- */
- Uint32 noOfRemovedReplicas = 0; // No of replicas removed
- Uint32 noOfRemovedLcpReplicas = 0; // No of replicas in LCP removed
- Uint32 noOfRemainingLcpReplicas = 0;// No of replicas in LCP remaining
-
- const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
- const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
-
- FragmentstorePtr fragPtr;
- for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
- jam();
- getFragstore(tabPtr.p, fragNo, fragPtr);
-
- /**
- * For each of replica record
- */
- bool found = false;
- ReplicaRecordPtr replicaPtr;
- for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
- replicaPtr.i = replicaPtr.p->nextReplica) {
- jam();
-
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if(replicaPtr.p->procNode == nodeId){
- jam();
- found = true;
- noOfRemovedReplicas++;
- removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
- if(replicaPtr.p->lcpOngoingFlag){
- jam();
- /**
- * This replica is currently LCP:ed
- */
- ndbrequire(fragPtr.p->noLcpReplicas > 0);
- fragPtr.p->noLcpReplicas --;
-
- noOfRemovedLcpReplicas ++;
- replicaPtr.p->lcpOngoingFlag = false;
- }
-
- if (lcpId != RNIL)
- {
- jam();
- Uint32 lcpNo = prevLcpNo(replicaPtr.p->nextLcp);
- if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
- replicaPtr.p->lcpId[lcpNo] == SYSFILE->latestLCP_ID)
- {
- jam();
- replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
- replicaPtr.p->lcpId[lcpNo] = 0;
- replicaPtr.p->nextLcp = lcpNo;
- ndbout_c("REMOVING lcp: %u from table: %u frag: %u node: %u",
- SYSFILE->latestLCP_ID,
- tabPtr.i, fragNo, nodeId);
- }
- }
- }
- }
- if (!found)
- {
- jam();
- /**
- * Run updateNodeInfo to remove any dead nodes from list of activeNodes
- * see bug#15587
- */
- updateNodeInfo(fragPtr);
- }
- noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas;
- }
-
- if(noOfRemovedReplicas == 0){
- jam();
- /**
- * The table had no replica on the failed node
- * continue with next table
- */
- tabPtr.i++;
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
-
- /**
- * We did remove at least one replica
- */
- bool ok = false;
- switch(tabPtr.p->tabLcpStatus){
- case TabRecord::TLS_COMPLETED:
- ok = true;
- jam();
- /**
- * WE WILL WRITE THE TABLE DESCRIPTION TO DISK AT THIS TIME
- * INDEPENDENT OF WHAT THE LOCAL CHECKPOINT NEEDED.
- * THIS IS TO ENSURE THAT THE FAILED NODES ARE ALSO UPDATED ON DISK
- * IN THE DIH DATA STRUCTURES BEFORE WE COMPLETE HANDLING OF THE
- * NODE FAILURE.
- */
- ndbrequire(noOfRemovedLcpReplicas == 0);
-
- tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
- tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
- tabPtr.p->tabRemoveNode = nodeId;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::TLS_ACTIVE:
- ok = true;
- jam();
- /**
- * The table is participating in an LCP currently
- */
- // Fall through
- break;
- case TabRecord::TLS_WRITING_TO_FILE:
- ok = true;
- jam();
- /**
- * This should never happen since we in the beginning of this function
- * checks the tabCopyStatus
- */
- ndbrequire(lcpOngoingFlag);
- ndbrequire(false);
- break;
- }
- ndbrequire(ok);
-
- /**
- * The table is participating in an LCP currently
- * and we removed some replicas that should have been checkpointed
- */
- ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
- ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE);
-
- /**
- * Save the table
- */
- tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
- tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
- tabPtr.p->tabRemoveNode = nodeId;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-
- if(noOfRemainingLcpReplicas == 0){
- jam();
- /**
- * The removal on the failed node made the LCP complete
- */
- tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
- checkLcpAllTablesDoneInLqh();
- }
-}
-
-void
-Dbdih::removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId){
- jam();
-
- /**
- * Check if we "accidently" completed a LCP
- */
- checkLcpCompletedLab(signal);
-
- /**
- * Check if we (DIH) are finished with node fail handling
- */
- checkLocalNodefailComplete(signal, nodeId, NF_REMOVE_NODE_FROM_TABLE);
-}
-
-void
-Dbdih::checkLocalNodefailComplete(Signal* signal, Uint32 failedNodeId,
- NodefailHandlingStep step){
- jam();
-
- NodeRecordPtr nodePtr;
- nodePtr.i = failedNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- ndbrequire(nodePtr.p->m_nodefailSteps.get(step));
- nodePtr.p->m_nodefailSteps.clear(step);
-
- if(nodePtr.p->m_nodefailSteps.count() > 0){
- jam();
- return;
- }
-
- if (ERROR_INSERTED(7030))
- {
- g_eventLogger.info("Reenable GCP_PREPARE");
- CLEAR_ERROR_INSERT_VALUE;
- }
-
- NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
- nf->blockNo = DBDIH;
- nf->nodeId = cownNodeId;
- nf->failedNodeId = failedNodeId;
- nf->from = __LINE__;
- sendSignal(reference(), GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
-}
-
-
-void
-Dbdih::setLocalNodefailHandling(Signal* signal, Uint32 failedNodeId,
- NodefailHandlingStep step){
- jam();
-
- NodeRecordPtr nodePtr;
- nodePtr.i = failedNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- ndbrequire(!nodePtr.p->m_nodefailSteps.get(step));
- nodePtr.p->m_nodefailSteps.set(step);
-}
-
-void Dbdih::startLcpTakeOverLab(Signal* signal, Uint32 failedNodeId)
-{
- /*--------------------------------------------------------------------*/
- // Start LCP master take over process. Consists of the following steps.
- // 1) Ensure that all LQH's have reported all fragments they have been
- // told to checkpoint. Can be a fairly long step time-wise.
- // 2) Query all nodes about their LCP status.
- // During the query process we do not want our own state to change.
- // This can change due to delayed reception of LCP_REPORT, completed
- // save of table on disk or reception of DIH_LCPCOMPLETE from other
- // node.
- /*--------------------------------------------------------------------*/
-}//Dbdih::startLcpTakeOver()
-
-void Dbdih::execEMPTY_LCP_CONF(Signal* signal)
-{
- jamEntry();
-
- ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_EMPTY_LCP);
-
- const EmptyLcpConf * const conf = (EmptyLcpConf *)&signal->theData[0];
- Uint32 nodeId = conf->senderNodeId;
-
- if(!conf->idle){
- jam();
- if (conf->tableId < c_lcpMasterTakeOverState.minTableId) {
- jam();
- c_lcpMasterTakeOverState.minTableId = conf->tableId;
- c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
- } else if (conf->tableId == c_lcpMasterTakeOverState.minTableId &&
- conf->fragmentId < c_lcpMasterTakeOverState.minFragId) {
- jam();
- c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
- }//if
- if(isMaster()){
- jam();
- c_lcpState.m_LAST_LCP_FRAG_ORD.setWaitingFor(nodeId);
- }
- }
-
- receiveLoopMacro(EMPTY_LCP_REQ, nodeId);
- /*--------------------------------------------------------------------*/
- // Received all EMPTY_LCPCONF. We can continue with next phase of the
- // take over LCP master process.
- /*--------------------------------------------------------------------*/
- c_lcpMasterTakeOverState.set(LMTOS_WAIT_LCP_FRAG_REP, __LINE__);
- checkEmptyLcpComplete(signal);
- return;
-}//Dbdih::execEMPTY_LCPCONF()
-
-void
-Dbdih::checkEmptyLcpComplete(Signal *signal){
-
- ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_LCP_FRAG_REP);
-
- if(c_lcpState.noOfLcpFragRepOutstanding > 0){
- jam();
- return;
- }
-
- if(isMaster()){
- jam();
-
- signal->theData[0] = NDB_LE_LCP_TakeoverStarted;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-
- signal->theData[0] = 7012;
- execDUMP_STATE_ORD(signal);
-
- if (ERROR_INSERTED(7194))
- {
- ndbout_c("7194 starting ZREMOVE_NODE_FROM_TABLE");
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = c_lcpMasterTakeOverState.failedNodeId;
- signal->theData[2] = 0; // Tab id
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
-
- c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
- MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
- req->masterRef = reference();
- req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
- sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ);
-
- } else {
- sendMASTER_LCPCONF(signal);
- }
-}
-
-/*--------------------------------------------------*/
-/* THE MASTER HAS FAILED AND THE NEW MASTER IS*/
-/* QUERYING THIS NODE ABOUT THE STATE OF THE */
-/* LOCAL CHECKPOINT PROTOCOL. */
-/*--------------------------------------------------*/
-void Dbdih::execMASTER_LCPREQ(Signal* signal)
-{
- const MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
- jamEntry();
- const BlockReference newMasterBlockref = req->masterRef;
-
- if (newMasterBlockref != cmasterdihref)
- {
- jam();
- ndbout_c("resending GSN_MASTER_LCPREQ");
- sendSignalWithDelay(reference(), GSN_MASTER_LCPREQ, signal,
- 50, signal->getLength());
- return;
- }
- Uint32 failedNodeId = req->failedNodeId;
-
- /**
- * There can be no take over with the same master
- */
- ndbrequire(c_lcpState.m_masterLcpDihRef != newMasterBlockref);
- c_lcpState.m_masterLcpDihRef = newMasterBlockref;
- c_lcpState.m_MASTER_LCPREQ_Received = true;
- c_lcpState.m_MASTER_LCPREQ_FailedNodeId = failedNodeId;
-
- if(newMasterBlockref != cmasterdihref){
- jam();
- ndbrequire(0);
- }
-
- sendMASTER_LCPCONF(signal);
-}//Dbdih::execMASTER_LCPREQ()
-
-void
-Dbdih::sendMASTER_LCPCONF(Signal * signal){
-
- if(!c_EMPTY_LCP_REQ_Counter.done()){
- /**
- * Have not received all EMPTY_LCP_REP
- * dare not answer MASTER_LCP_CONF yet
- */
- jam();
- return;
- }
-
- if(!c_lcpState.m_MASTER_LCPREQ_Received){
- jam();
- /**
- * Has not received MASTER_LCPREQ yet
- */
- return;
- }
-
- if(c_lcpState.lcpStatus == LCP_INIT_TABLES){
- jam();
- /**
- * Still aborting old initLcpLab
- */
- return;
- }
-
- if(c_lcpState.lcpStatus == LCP_COPY_GCI){
- jam();
- /**
- * Restart it
- */
- //Uint32 lcpId = SYSFILE->latestLCP_ID;
- SYSFILE->latestLCP_ID--;
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
-#if 0
- if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
- g_eventLogger.info("Dbdih: Also resetting c_copyGCISlave");
- c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
- c_copyGCISlave.m_expectedNextWord = 0;
- }
-#endif
- }
-
- MasterLCPConf::State lcpState;
- switch (c_lcpState.lcpStatus) {
- case LCP_STATUS_IDLE:
- jam();
- /*------------------------------------------------*/
- /* LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
- /* SINCE NO COPY OF RESTART INFORMATION HAVE*/
- /* BEEN RECEIVED YET. ALSO THE PREVIOUS */
- /* CHECKPOINT HAVE BEEN FULLY COMPLETED. */
- /*------------------------------------------------*/
- lcpState = MasterLCPConf::LCP_STATUS_IDLE;
- break;
- case LCP_STATUS_ACTIVE:
- jam();
- /*--------------------------------------------------*/
- /* COPY OF RESTART INFORMATION HAS BEEN */
- /* PERFORMED AND ALSO RESPONSE HAVE BEEN SENT.*/
- /*--------------------------------------------------*/
- lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
- break;
- case LCP_TAB_COMPLETED:
- jam();
- /*--------------------------------------------------------*/
- /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
- /* ALL TABLES. SAVE OF AT LEAST ONE TABLE IS */
- /* ONGOING YET. */
- /*--------------------------------------------------------*/
- lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
- break;
- case LCP_TAB_SAVED:
- jam();
- /*--------------------------------------------------------*/
- /* ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR */
- /* ALL TABLES. ALL TABLES HAVE ALSO BEEN SAVED */
- /* ALL OTHER NODES ARE NOT YET FINISHED WITH */
- /* THE LOCAL CHECKPOINT. */
- /*--------------------------------------------------------*/
- lcpState = MasterLCPConf::LCP_TAB_SAVED;
- break;
- case LCP_TCGET:
- case LCP_CALCULATE_KEEP_GCI:
- case LCP_TC_CLOPSIZE:
- case LCP_START_LCP_ROUND:
- /**
- * These should only exists on the master
- * but since this is master take over
- * it not allowed
- */
- ndbrequire(false);
- lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
- break;
- case LCP_COPY_GCI:
- case LCP_INIT_TABLES:
- /**
- * These two states are handled by if statements above
- */
- ndbrequire(false);
- lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
- break;
- default:
- ndbrequire(false);
- lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
- }//switch
-
- Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
- MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
- conf->senderNodeId = cownNodeId;
- conf->lcpState = lcpState;
- conf->failedNodeId = failedNodeId;
- sendSignal(c_lcpState.m_masterLcpDihRef, GSN_MASTER_LCPCONF,
- signal, MasterLCPConf::SignalLength, JBB);
-
- // Answer to MASTER_LCPREQ sent, reset flag so
- // that it's not sent again before another request comes in
- c_lcpState.m_MASTER_LCPREQ_Received = false;
-
- if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
-#ifdef VM_TRACE
- g_eventLogger.info("Sending extra GSN_LCP_COMPLETE_REP to new master");
-#endif
- sendLCP_COMPLETE_REP(signal);
- }
-
- if(!isMaster()){
- c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
- checkLocalNodefailComplete(signal, failedNodeId, NF_LCP_TAKE_OVER);
- }
-
- return;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbdih::LcpMasterTakeOverState state){
- switch(state){
- case Dbdih::LMTOS_IDLE:
- out << "LMTOS_IDLE";
- break;
- case Dbdih::LMTOS_WAIT_EMPTY_LCP:
- out << "LMTOS_WAIT_EMPTY_LCP";
- break;
- case Dbdih::LMTOS_WAIT_LCP_FRAG_REP:
- out << "LMTOS_WAIT_EMPTY_LCP";
- break;
- case Dbdih::LMTOS_INITIAL:
- out << "LMTOS_INITIAL";
- break;
- case Dbdih::LMTOS_ALL_IDLE:
- out << "LMTOS_ALL_IDLE";
- break;
- case Dbdih::LMTOS_ALL_ACTIVE:
- out << "LMTOS_ALL_ACTIVE";
- break;
- case Dbdih::LMTOS_LCP_CONCLUDING:
- out << "LMTOS_LCP_CONCLUDING";
- break;
- case Dbdih::LMTOS_COPY_ONGOING:
- out << "LMTOS_COPY_ONGOING";
- break;
- }
- return out;
-}
-
-struct MASTERLCP_StateTransitions {
- Dbdih::LcpMasterTakeOverState CurrentState;
- MasterLCPConf::State ParticipantState;
- Dbdih::LcpMasterTakeOverState NewState;
-};
-
-static const
-MASTERLCP_StateTransitions g_masterLCPTakeoverStateTransitions[] = {
- /**
- * Current = LMTOS_INITIAL
- */
- { Dbdih::LMTOS_INITIAL,
- MasterLCPConf::LCP_STATUS_IDLE,
- Dbdih::LMTOS_ALL_IDLE },
-
- { Dbdih::LMTOS_INITIAL,
- MasterLCPConf::LCP_STATUS_ACTIVE,
- Dbdih::LMTOS_ALL_ACTIVE },
-
- { Dbdih::LMTOS_INITIAL,
- MasterLCPConf::LCP_TAB_COMPLETED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_INITIAL,
- MasterLCPConf::LCP_TAB_SAVED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- /**
- * Current = LMTOS_ALL_IDLE
- */
- { Dbdih::LMTOS_ALL_IDLE,
- MasterLCPConf::LCP_STATUS_IDLE,
- Dbdih::LMTOS_ALL_IDLE },
-
- { Dbdih::LMTOS_ALL_IDLE,
- MasterLCPConf::LCP_STATUS_ACTIVE,
- Dbdih::LMTOS_COPY_ONGOING },
-
- { Dbdih::LMTOS_ALL_IDLE,
- MasterLCPConf::LCP_TAB_COMPLETED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_ALL_IDLE,
- MasterLCPConf::LCP_TAB_SAVED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- /**
- * Current = LMTOS_COPY_ONGOING
- */
- { Dbdih::LMTOS_COPY_ONGOING,
- MasterLCPConf::LCP_STATUS_IDLE,
- Dbdih::LMTOS_COPY_ONGOING },
-
- { Dbdih::LMTOS_COPY_ONGOING,
- MasterLCPConf::LCP_STATUS_ACTIVE,
- Dbdih::LMTOS_COPY_ONGOING },
-
- /**
- * Current = LMTOS_ALL_ACTIVE
- */
- { Dbdih::LMTOS_ALL_ACTIVE,
- MasterLCPConf::LCP_STATUS_IDLE,
- Dbdih::LMTOS_COPY_ONGOING },
-
- { Dbdih::LMTOS_ALL_ACTIVE,
- MasterLCPConf::LCP_STATUS_ACTIVE,
- Dbdih::LMTOS_ALL_ACTIVE },
-
- { Dbdih::LMTOS_ALL_ACTIVE,
- MasterLCPConf::LCP_TAB_COMPLETED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_ALL_ACTIVE,
- MasterLCPConf::LCP_TAB_SAVED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- /**
- * Current = LMTOS_LCP_CONCLUDING
- */
- { Dbdih::LMTOS_LCP_CONCLUDING,
- MasterLCPConf::LCP_STATUS_IDLE,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_LCP_CONCLUDING,
- MasterLCPConf::LCP_STATUS_ACTIVE,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_LCP_CONCLUDING,
- MasterLCPConf::LCP_TAB_COMPLETED,
- Dbdih::LMTOS_LCP_CONCLUDING },
-
- { Dbdih::LMTOS_LCP_CONCLUDING,
- MasterLCPConf::LCP_TAB_SAVED,
- Dbdih::LMTOS_LCP_CONCLUDING }
-};
-
-const Uint32 g_masterLCPTakeoverStateTransitionsRows =
-sizeof(g_masterLCPTakeoverStateTransitions) / sizeof(struct MASTERLCP_StateTransitions);
-
-void Dbdih::execMASTER_LCPCONF(Signal* signal)
-{
- const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
- jamEntry();
-
- if (ERROR_INSERTED(7194))
- {
- ndbout_c("delaying MASTER_LCPCONF due to error 7194");
- sendSignalWithDelay(reference(), GSN_MASTER_LCPCONF, signal,
- 300, signal->getLength());
- return;
- }
-
- Uint32 senderNodeId = conf->senderNodeId;
- MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
- const Uint32 failedNodeId = conf->failedNodeId;
- NodeRecordPtr nodePtr;
- nodePtr.i = senderNodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->lcpStateAtTakeOver = lcpState;
-
- CRASH_INSERTION(7180);
-
-#ifdef VM_TRACE
- g_eventLogger.info("MASTER_LCPCONF");
- printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
-#endif
-
- bool found = false;
- for(Uint32 i = 0; i<g_masterLCPTakeoverStateTransitionsRows; i++){
- const struct MASTERLCP_StateTransitions * valid =
- &g_masterLCPTakeoverStateTransitions[i];
-
- if(valid->CurrentState == c_lcpMasterTakeOverState.state &&
- valid->ParticipantState == lcpState){
- jam();
- found = true;
- c_lcpMasterTakeOverState.set(valid->NewState, __LINE__);
- break;
- }
- }
- ndbrequire(found);
-
- bool ok = false;
- switch(lcpState){
- case MasterLCPConf::LCP_STATUS_IDLE:
- ok = true;
- break;
- case MasterLCPConf::LCP_STATUS_ACTIVE:
- case MasterLCPConf::LCP_TAB_COMPLETED:
- case MasterLCPConf::LCP_TAB_SAVED:
- ok = true;
- c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.setWaitingFor(nodePtr.i);
- break;
- }
- ndbrequire(ok);
-
- receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
- /*-------------------------------------------------------------------------*/
- // We have now received all responses and are ready to take over the LCP
- // protocol as master.
- /*-------------------------------------------------------------------------*/
- MASTER_LCPhandling(signal, failedNodeId);
-}//Dbdih::execMASTER_LCPCONF()
-
-void Dbdih::execMASTER_LCPREF(Signal* signal)
-{
- const MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
- jamEntry();
- receiveLoopMacro(MASTER_LCPREQ, ref->senderNodeId);
- /*-------------------------------------------------------------------------*/
- // We have now received all responses and are ready to take over the LCP
- // protocol as master.
- /*-------------------------------------------------------------------------*/
- MASTER_LCPhandling(signal, ref->failedNodeId);
-}//Dbdih::execMASTER_LCPREF()
-
-void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId)
-{
- /*-------------------------------------------------------------------------
- *
- * WE ARE NOW READY TO CONCLUDE THE TAKE OVER AS MASTER.
- * WE HAVE ENOUGH INFO TO START UP ACTIVITIES IN THE PROPER PLACE.
- * ALSO SET THE PROPER STATE VARIABLES.
- *------------------------------------------------------------------------*/
- c_lcpState.currentFragment.tableId = c_lcpMasterTakeOverState.minTableId;
- c_lcpState.currentFragment.fragmentId = c_lcpMasterTakeOverState.minFragId;
- c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH;
-
- NodeRecordPtr failedNodePtr;
- failedNodePtr.i = failedNodeId;
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
-
- switch (c_lcpMasterTakeOverState.state) {
- case LMTOS_ALL_IDLE:
- jam();
- /* --------------------------------------------------------------------- */
- // All nodes were idle in the LCP protocol. Start checking for start of LCP
- // protocol.
- /* --------------------------------------------------------------------- */
-#ifdef VM_TRACE
- g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
-#endif
- checkLcpStart(signal, __LINE__);
- break;
- case LMTOS_COPY_ONGOING:
- jam();
- /* --------------------------------------------------------------------- */
- // We were in the starting process of the LCP protocol. We will restart the
- // protocol by calculating the keep gci and storing the new lcp id.
- /* --------------------------------------------------------------------- */
-#ifdef VM_TRACE
- g_eventLogger.info("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
-#endif
- if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
- jam();
- /*---------------------------------------------------------------------*/
- /* WE NEED TO DECREASE THE LATEST LCP ID SINCE WE HAVE ALREADY */
- /* STARTED THIS */
- /* LOCAL CHECKPOINT. */
- /*---------------------------------------------------------------------*/
- Uint32 lcpId = SYSFILE->latestLCP_ID;
-#ifdef VM_TRACE
- g_eventLogger.info("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
-#endif
- SYSFILE->latestLCP_ID--;
- }//if
- storeNewLcpIdLab(signal);
- break;
- case LMTOS_ALL_ACTIVE:
- {
- jam();
- /* -------------------------------------------------------------------
- * Everybody was in the active phase. We will restart sending
- * LCP_FRAGORD to the nodes from the new master.
- * We also need to set dihLcpStatus to ZACTIVE
- * in the master node since the master will wait for all nodes to
- * complete before finalising the LCP process.
- * ------------------------------------------------------------------ */
-#ifdef VM_TRACE
- g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
- "startLcpRoundLoopLab(table=%u, fragment=%u)",
- c_lcpMasterTakeOverState.minTableId,
- c_lcpMasterTakeOverState.minFragId);
-#endif
-
- c_lcpState.keepGci = SYSFILE->keepGCI;
- startLcpRoundLoopLab(signal, 0, 0);
- break;
- }
- case LMTOS_LCP_CONCLUDING:
- {
- jam();
- /* ------------------------------------------------------------------- */
- // The LCP process is in the finalisation phase. We simply wait for it to
- // complete with signals arriving in. We need to check also if we should
- // change state due to table write completion during state
- // collection phase.
- /* ------------------------------------------------------------------- */
- ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
- startLcpRoundLoopLab(signal, 0, 0);
- break;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
- signal->theData[0] = NDB_LE_LCP_TakeoverCompleted;
- signal->theData[1] = c_lcpMasterTakeOverState.state;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- signal->theData[0] = 7012;
- execDUMP_STATE_ORD(signal);
-
- c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
-
- checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
-}
-
-/* ------------------------------------------------------------------------- */
-/* A BLOCK OR A NODE HAS COMPLETED THE HANDLING OF THE NODE FAILURE. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::execNF_COMPLETEREP(Signal* signal)
-{
- NodeRecordPtr failedNodePtr;
- NFCompleteRep * const nfCompleteRep = (NFCompleteRep *)&signal->theData[0];
- jamEntry();
- const Uint32 blockNo = nfCompleteRep->blockNo;
- Uint32 nodeId = nfCompleteRep->nodeId;
- failedNodePtr.i = nfCompleteRep->failedNodeId;
-
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
- switch (blockNo) {
- case DBTC:
- jam();
- ndbrequire(failedNodePtr.p->dbtcFailCompleted == ZFALSE);
- /* -------------------------------------------------------------------- */
- // Report the event that DBTC completed node failure handling.
- /* -------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = DBTC;
- signal->theData[2] = failedNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
-
- failedNodePtr.p->dbtcFailCompleted = ZTRUE;
- break;
- case DBDICT:
- jam();
- ndbrequire(failedNodePtr.p->dbdictFailCompleted == ZFALSE);
- /* --------------------------------------------------------------------- */
- // Report the event that DBDICT completed node failure handling.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = DBDICT;
- signal->theData[2] = failedNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
-
- failedNodePtr.p->dbdictFailCompleted = ZTRUE;
- break;
- case DBDIH:
- jam();
- ndbrequire(failedNodePtr.p->dbdihFailCompleted == ZFALSE);
- /* --------------------------------------------------------------------- */
- // Report the event that DBDIH completed node failure handling.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = DBDIH;
- signal->theData[2] = failedNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
-
- failedNodePtr.p->dbdihFailCompleted = ZTRUE;
- break;
- case DBLQH:
- jam();
- ndbrequire(failedNodePtr.p->dblqhFailCompleted == ZFALSE);
- /* --------------------------------------------------------------------- */
- // Report the event that DBDIH completed node failure handling.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = DBLQH;
- signal->theData[2] = failedNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
-
- failedNodePtr.p->dblqhFailCompleted = ZTRUE;
- break;
- case 0: /* Node has finished */
- jam();
- ndbrequire(nodeId < MAX_NDB_NODES);
-
- if (failedNodePtr.p->recNODE_FAILREP == ZFALSE) {
- jam();
- /* ------------------------------------------------------------------- */
- // We received a report about completion of node failure before we
- // received the message about the NODE failure ourselves.
- // We will send the signal to ourselves with a small delay
- // (10 milliseconds).
- /* ------------------------------------------------------------------- */
- //nf->from = __LINE__;
- sendSignalWithDelay(reference(), GSN_NF_COMPLETEREP, signal, 10,
- signal->length());
- return;
- }//if
-
- if (!failedNodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(nodeId)){
- jam();
- return;
- }
-
- failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor(nodeId);;
-
- /* -------------------------------------------------------------------- */
- // Report the event that nodeId has completed node failure handling.
- /* -------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = 0;
- signal->theData[2] = failedNodePtr.i;
- signal->theData[3] = nodeId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- nodeFailCompletedCheckLab(signal, failedNodePtr);
- return;
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- if (failedNodePtr.p->dbtcFailCompleted == ZFALSE) {
- jam();
- return;
- }//if
- if (failedNodePtr.p->dbdictFailCompleted == ZFALSE) {
- jam();
- return;
- }//if
- if (failedNodePtr.p->dbdihFailCompleted == ZFALSE) {
- jam();
- return;
- }//if
- if (failedNodePtr.p->dblqhFailCompleted == ZFALSE) {
- jam();
- return;
- }//if
- /* ----------------------------------------------------------------------- */
- /* ALL BLOCKS IN THIS NODE HAVE COMPLETED THEIR PART OF HANDLING THE */
- /* NODE FAILURE. WE CAN NOW REPORT THIS COMPLETION TO ALL OTHER NODES. */
- /* ----------------------------------------------------------------------- */
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- BlockReference ref = calcDihBlockRef(nodePtr.i);
- NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
- nf->blockNo = 0;
- nf->nodeId = cownNodeId;
- nf->failedNodeId = failedNodePtr.i;
- nf->from = __LINE__;
- sendSignal(ref, GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
- }//if
- }//for
- return;
-}//Dbdih::execNF_COMPLETEREP()
-
-void Dbdih::nodeFailCompletedCheckLab(Signal* signal,
- NodeRecordPtr failedNodePtr)
-{
- jam();
- if (!failedNodePtr.p->m_NF_COMPLETE_REP.done()){
- jam();
- return;
- }//if
- /* ---------------------------------------------------------------------- */
- /* ALL BLOCKS IN ALL NODES HAVE NOW REPORTED COMPLETION OF THE NODE */
- /* FAILURE HANDLING. WE ARE NOW READY TO ACCEPT THAT THIS NODE STARTS */
- /* AGAIN. */
- /* ---------------------------------------------------------------------- */
- jam();
- failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
- failedNodePtr.p->recNODE_FAILREP = ZFALSE;
-
- /* ---------------------------------------------------------------------- */
- // Report the event that all nodes completed node failure handling.
- /* ---------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_NodeFailCompleted;
- signal->theData[1] = 0;
- signal->theData[2] = failedNodePtr.i;
- signal->theData[3] = 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- /* ---------------------------------------------------------------------- */
- // Report to QMGR that we have concluded recovery handling of this node.
- /* ---------------------------------------------------------------------- */
- signal->theData[0] = failedNodePtr.i;
- sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
-
- if (isMaster()) {
- jam();
- /* --------------------------------------------------------------------- */
- /* IF WE ARE MASTER WE MUST CHECK IF COPY FRAGMENT WAS INTERRUPTED */
- /* BY THE FAILED NODES. */
- /* --------------------------------------------------------------------- */
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = 0;
- ptrAss(takeOverPtr, takeOverRecord);
- if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
- (failedNodePtr.i == takeOverPtr.p->toCopyNode)) {
- jam();
-#ifdef VM_TRACE
- ndbrequire("Tell jonas" == 0);
-#endif
- /*------------------------------------------------------------------*/
- /* WE ARE CURRENTLY IN THE PROCESS OF COPYING A FRAGMENT. WE */
- /* WILL CHECK IF THE COPY NODE HAVE FAILED. */
- /*------------------------------------------------------------------*/
- takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
- startNextCopyFragment(signal, takeOverPtr.i);
- return;
- }//if
- checkStartTakeOver(signal);
- }//if
- return;
-}//Dbdih::nodeFailCompletedCheckLab()
-
-/*****************************************************************************/
-/* ********** SEIZING / RELEASING MODULE *************/
-/*****************************************************************************/
-/*
- 3.4 L O C A L N O D E S E I Z E
- ************************************
- */
-/*
- 3.4.1 L O C A L N O D E S E I Z E R E Q U E S T
- ******************************************************
- */
-void Dbdih::execDISEIZEREQ(Signal* signal)
-{
- ConnectRecordPtr connectPtr;
- jamEntry();
- Uint32 userPtr = signal->theData[0];
- BlockReference userRef = signal->theData[1];
- ndbrequire(cfirstconnect != RNIL);
- connectPtr.i = cfirstconnect;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- cfirstconnect = connectPtr.p->nfConnect;
- connectPtr.p->nfConnect = RNIL;
- connectPtr.p->userpointer = userPtr;
- connectPtr.p->userblockref = userRef;
- connectPtr.p->connectState = ConnectRecord::INUSE;
- signal->theData[0] = connectPtr.p->userpointer;
- signal->theData[1] = connectPtr.i;
- sendSignal(userRef, GSN_DISEIZECONF, signal, 2, JBB);
-}//Dbdih::execDISEIZEREQ()
-
-/*
- 3.5 L O C A L N O D E R E L E A S E
- ****************************************
- */
-/*
- 3.5.1 L O C A L N O D E R E L E A S E R E Q U E S T
- *******************************************************=
- */
-void Dbdih::execDIRELEASEREQ(Signal* signal)
-{
- ConnectRecordPtr connectPtr;
- jamEntry();
- connectPtr.i = signal->theData[0];
- Uint32 userRef = signal->theData[2];
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- ndbrequire(connectPtr.p->connectState != ConnectRecord::FREE);
- ndbrequire(connectPtr.p->userblockref == userRef);
- signal->theData[0] = connectPtr.p->userpointer;
- sendSignal(connectPtr.p->userblockref, GSN_DIRELEASECONF, signal, 1, JBB);
- release_connect(connectPtr);
-}//Dbdih::execDIRELEASEREQ()
-
-/*
- 3.7 A D D T A B L E
- **********************=
- */
-/*****************************************************************************/
-/* ********** TABLE ADDING MODULE *************/
-/*****************************************************************************/
-/*
- 3.7.1 A D D T A B L E M A I N L Y
- ***************************************
- */
-
-static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
-{
- Uint32 next = node + 1;
- node = (next == max_node ? 0 : next);
-}
-
-/*
- Spread fragments in backwards compatible mode
-*/
-static void set_default_node_groups(Signal *signal, Uint32 noFrags)
-{
- Uint16 *node_group_array = (Uint16*)&signal->theData[25];
- Uint32 i;
- node_group_array[0] = 0;
- for (i = 1; i < noFrags; i++)
- node_group_array[i] = UNDEF_NODEGROUP;
-}
-void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
-{
- Uint16 node_group_id[MAX_NDB_PARTITIONS];
- jamEntry();
- CreateFragmentationReq * const req =
- (CreateFragmentationReq*)signal->getDataPtr();
-
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- Uint32 noOfFragments = req->noOfFragments;
- const Uint32 fragType = req->fragmentationType;
- const Uint32 primaryTableId = req->primaryTableId;
-
- Uint32 err = 0;
-
- do {
- NodeGroupRecordPtr NGPtr;
- TabRecordPtr primTabPtr;
- Uint32 count = 2;
- Uint16 noOfReplicas = cnoReplicas;
- Uint16 *fragments = (Uint16*)(signal->theData+25);
- if (primaryTableId == RNIL) {
- jam();
- switch ((DictTabInfo::FragmentType)fragType)
- {
- /*
- Backward compatability and for all places in code not changed.
- */
- case DictTabInfo::AllNodesSmallTable:
- jam();
- noOfFragments = csystemnodes;
- set_default_node_groups(signal, noOfFragments);
- break;
- case DictTabInfo::AllNodesMediumTable:
- jam();
- noOfFragments = 2 * csystemnodes;
- set_default_node_groups(signal, noOfFragments);
- break;
- case DictTabInfo::AllNodesLargeTable:
- jam();
- noOfFragments = 4 * csystemnodes;
- set_default_node_groups(signal, noOfFragments);
- break;
- case DictTabInfo::SingleFragment:
- jam();
- noOfFragments = 1;
- set_default_node_groups(signal, noOfFragments);
- break;
- case DictTabInfo::DistrKeyHash:
- jam();
- case DictTabInfo::DistrKeyLin:
- jam();
- if (noOfFragments == 0)
- {
- jam();
- noOfFragments = csystemnodes;
- set_default_node_groups(signal, noOfFragments);
- }
- break;
- default:
- jam();
- if (noOfFragments == 0)
- {
- jam();
- err = CreateFragmentationRef::InvalidFragmentationType;
- }
- break;
- }
- if (err)
- break;
- /*
- When we come here the the exact partition is specified
- and there is an array of node groups sent along as well.
- */
- memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
- Uint16 next_replica_node[MAX_NDB_NODES];
- memset(next_replica_node,0,sizeof(next_replica_node));
- Uint32 default_node_group= c_nextNodeGroup;
- for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
- {
- jam();
- NGPtr.i = node_group_id[fragNo];
- if (NGPtr.i == UNDEF_NODEGROUP)
- {
- jam();
- NGPtr.i = default_node_group;
- }
- if (NGPtr.i > cnoOfNodeGroups)
- {
- jam();
- err = CreateFragmentationRef::InvalidNodeGroup;
- break;
- }
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- const Uint32 max = NGPtr.p->nodeCount;
-
- fragments[count++] = c_nextLogPart++; // Store logpart first
- Uint32 tmp= next_replica_node[NGPtr.i];
- for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
- {
- jam();
- const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
- fragments[count++]= nodeId;
- inc_node_or_group(tmp, max);
- }
- inc_node_or_group(tmp, max);
- next_replica_node[NGPtr.i]= tmp;
-
- /**
- * Next node group for next fragment
- */
- inc_node_or_group(default_node_group, cnoOfNodeGroups);
- }
- if (err)
- {
- jam();
- break;
- }
- else
- {
- jam();
- c_nextNodeGroup = default_node_group;
- }
- } else {
- if (primaryTableId >= ctabFileSize) {
- jam();
- err = CreateFragmentationRef::InvalidPrimaryTable;
- break;
- }
- primTabPtr.i = primaryTableId;
- ptrAss(primTabPtr, tabRecord);
- if (primTabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
- jam();
- err = CreateFragmentationRef::InvalidPrimaryTable;
- break;
- }
- noOfFragments= primTabPtr.p->totalfragments;
- for (Uint32 fragNo = 0;
- fragNo < noOfFragments; fragNo++) {
- jam();
- FragmentstorePtr fragPtr;
- ReplicaRecordPtr replicaPtr;
- getFragstore(primTabPtr.p, fragNo, fragPtr);
- fragments[count++] = fragPtr.p->m_log_part_id;
- fragments[count++] = fragPtr.p->preferredPrimary;
- for (replicaPtr.i = fragPtr.p->storedReplicas;
- replicaPtr.i != RNIL;
- replicaPtr.i = replicaPtr.p->nextReplica) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
- jam();
- fragments[count++]= replicaPtr.p->procNode;
- }
- }
- for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
- replicaPtr.i != RNIL;
- replicaPtr.i = replicaPtr.p->nextReplica) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
- jam();
- fragments[count++]= replicaPtr.p->procNode;
- }
- }
- }
- }
- if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Illegal configuration change: NoOfReplicas."
- " Can't be applied online ");
- progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
- }
-
- CreateFragmentationConf * const conf =
- (CreateFragmentationConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->noOfReplicas = (Uint32)noOfReplicas;
- conf->noOfFragments = (Uint32)noOfFragments;
-
- fragments[0]= noOfReplicas;
- fragments[1]= noOfFragments;
-
- if(senderRef != 0)
- {
- jam();
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)&fragments[0];
- ptr[0].sz = (count + 1) / 2;
- sendSignal(senderRef,
- GSN_CREATE_FRAGMENTATION_CONF,
- signal,
- CreateFragmentationConf::SignalLength,
- JBB,
- ptr,
- 1);
- }
- // Always ACK/NACK (here ACK)
- signal->theData[0] = 0;
- return;
- } while(false);
- // Always ACK/NACK (here NACK)
- signal->theData[0] = err;
-}
-
-void Dbdih::execDIADDTABREQ(Signal* signal)
-{
- Uint32 fragType;
- jamEntry();
-
- DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
-
- // Seize connect record
- ndbrequire(cfirstconnect != RNIL);
- ConnectRecordPtr connectPtr;
- connectPtr.i = cfirstconnect;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- cfirstconnect = connectPtr.p->nfConnect;
-
- const Uint32 userPtr = req->connectPtr;
- const BlockReference userRef = signal->getSendersBlockRef();
- connectPtr.p->nfConnect = RNIL;
- connectPtr.p->userpointer = userPtr;
- connectPtr.p->userblockref = userRef;
- connectPtr.p->connectState = ConnectRecord::INUSE;
- connectPtr.p->table = req->tableId;
-
- TabRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->connectrec = connectPtr.i;
- tabPtr.p->tableType = req->tableType;
- fragType= req->fragType;
- tabPtr.p->schemaVersion = req->schemaVersion;
- tabPtr.p->primaryTableId = req->primaryTableId;
-
- if(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE){
- jam();
- tabPtr.p->tabStatus = TabRecord::TS_CREATING;
- sendAddFragreq(signal, connectPtr, tabPtr, 0);
- return;
- }
-
- if(getNodeState().getSystemRestartInProgress() &&
- tabPtr.p->tabStatus == TabRecord::TS_IDLE){
- jam();
-
- ndbrequire(cmasterNodeId == getOwnNodeId());
- tabPtr.p->tabStatus = TabRecord::TS_CREATING;
-
- initTableFile(tabPtr);
- FileRecordPtr filePtr;
- filePtr.i = tabPtr.p->tabFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
- return;
- }
-
- /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- /* AT THE TIME OF INITIATING THE FILE OF TABLE */
- /* DESCRIPTION IS CREATED FOR APPROPRIATE SIZE. EACH */
- /* EACH RECORD IN THIS FILE HAS THE INFORMATION ABOUT */
- /* ONE TABLE. THE POINTER TO THIS RECORD IS THE TABLE */
- /* REFERENCE. IN THE BEGINNING ALL RECORDS ARE CREATED */
- /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
- /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- tabPtr.p->tabStatus = TabRecord::TS_CREATING;
- if(req->loggedTable)
- tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
- else if(req->temporaryTable)
- tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
- else
- tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
- tabPtr.p->kvalue = req->kValue;
-
- switch ((DictTabInfo::FragmentType)fragType)
- {
- case DictTabInfo::AllNodesSmallTable:
- case DictTabInfo::AllNodesMediumTable:
- case DictTabInfo::AllNodesLargeTable:
- case DictTabInfo::SingleFragment:
- jam();
- case DictTabInfo::DistrKeyLin:
- jam();
- tabPtr.p->method= TabRecord::LINEAR_HASH;
- break;
- case DictTabInfo::DistrKeyHash:
- case DictTabInfo::DistrKeyUniqueHashIndex:
- case DictTabInfo::DistrKeyOrderedIndex:
- jam();
- tabPtr.p->method= TabRecord::NORMAL_HASH;
- break;
- case DictTabInfo::UserDefined:
- jam();
- tabPtr.p->method= TabRecord::USER_DEFINED;
- break;
- default:
- ndbrequire(false);
- }
-
- union {
- Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
- Uint32 align;
- };
- SegmentedSectionPtr fragDataPtr;
- LINT_INIT(fragDataPtr.i);
- LINT_INIT(fragDataPtr.sz);
- signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
- copy((Uint32*)fragments, fragDataPtr);
- releaseSections(signal);
-
- const Uint32 noReplicas = fragments[0];
- const Uint32 noFragments = fragments[1];
-
- tabPtr.p->noOfBackups = noReplicas - 1;
- tabPtr.p->totalfragments = noFragments;
- ndbrequire(noReplicas == cnoReplicas); // Only allowed
-
- if (ERROR_INSERTED(7173)) {
- CLEAR_ERROR_INSERT_VALUE;
- addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
- return;
- }
- if ((noReplicas * noFragments) > cnoFreeReplicaRec) {
- jam();
- addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
- return;
- }//if
- if (noFragments > cremainingfrags) {
- jam();
- addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
- return;
- }//if
-
- Uint32 logTotalFragments = 1;
- while (logTotalFragments <= tabPtr.p->totalfragments) {
- jam();
- logTotalFragments <<= 1;
- }
- logTotalFragments >>= 1;
- tabPtr.p->mask = logTotalFragments - 1;
- tabPtr.p->hashpointer = tabPtr.p->totalfragments - logTotalFragments;
- allocFragments(tabPtr.p->totalfragments, tabPtr);
-
- Uint32 index = 2;
- for (Uint32 fragId = 0; fragId < noFragments; fragId++) {
- jam();
- FragmentstorePtr fragPtr;
- Uint32 activeIndex = 0;
- getFragstore(tabPtr.p, fragId, fragPtr);
- fragPtr.p->m_log_part_id = fragments[index++];
- fragPtr.p->preferredPrimary = fragments[index];
-
- for (Uint32 i = 0; i<noReplicas; i++) {
- const Uint32 nodeId = fragments[index++];
- ReplicaRecordPtr replicaPtr;
- allocStoredReplica(fragPtr, replicaPtr, nodeId);
- if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
- jam();
- ndbrequire(activeIndex < MAX_REPLICAS);
- fragPtr.p->activeNodes[activeIndex] = nodeId;
- activeIndex++;
- } else {
- jam();
- removeStoredReplica(fragPtr, replicaPtr);
- linkOldStoredReplica(fragPtr, replicaPtr);
- }//if
- }//for
- fragPtr.p->fragReplicas = activeIndex;
- ndbrequire(activeIndex > 0 && fragPtr.p->storedReplicas != RNIL);
- }
- initTableFile(tabPtr);
- tabPtr.p->tabCopyStatus = TabRecord::CS_ADD_TABLE_MASTER;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Dbdih::addTable_closeConf(Signal * signal, Uint32 tabPtrI){
- TabRecordPtr tabPtr;
- tabPtr.i = tabPtrI;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- ConnectRecordPtr connectPtr;
- connectPtr.i = tabPtr.p->connectrec;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
-
- sendAddFragreq(signal, connectPtr, tabPtr, 0);
-}
-
-void
-Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr,
- TabRecordPtr tabPtr, Uint32 fragId){
- jam();
- const Uint32 fragCount = tabPtr.p->totalfragments;
- ReplicaRecordPtr replicaPtr;
- LINT_INIT(replicaPtr.p);
- replicaPtr.i = RNIL;
- FragmentstorePtr fragPtr;
- for(; fragId<fragCount; fragId++){
- jam();
- getFragstore(tabPtr.p, fragId, fragPtr);
-
- replicaPtr.i = fragPtr.p->storedReplicas;
- while(replicaPtr.i != RNIL){
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if(replicaPtr.p->procNode == getOwnNodeId()){
- break;
- }
- replicaPtr.i = replicaPtr.p->nextReplica;
- }
-
- if(replicaPtr.i != RNIL){
- jam();
- break;
- }
-
- replicaPtr.i = fragPtr.p->oldStoredReplicas;
- while(replicaPtr.i != RNIL){
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if(replicaPtr.p->procNode == getOwnNodeId()){
- break;
- }
- replicaPtr.i = replicaPtr.p->nextReplica;
- }
-
- if(replicaPtr.i != RNIL){
- jam();
- break;
- }
- }
-
- if(replicaPtr.i != RNIL){
- jam();
- ndbrequire(fragId < fragCount);
- ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
-
- Uint32 requestInfo = 0;
- if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
- requestInfo |= LqhFragReq::TemporaryTable;
- }
-
- if(getNodeState().getNodeRestartInProgress()){
- requestInfo |= LqhFragReq::CreateInRunning;
- }
-
- AddFragReq* const req = (AddFragReq*)signal->getDataPtr();
- req->dihPtr = connectPtr.i;
- req->senderData = connectPtr.p->userpointer;
- req->fragmentId = fragId;
- req->requestInfo = requestInfo;
- req->tableId = tabPtr.i;
- req->nextLCP = 0;
- req->nodeId = getOwnNodeId();
- req->totalFragments = fragCount;
- req->startGci = SYSFILE->newestRestorableGCI;
- req->logPartId = fragPtr.p->m_log_part_id;
- sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal,
- AddFragReq::SignalLength, JBB);
- return;
- }
-
- // Done
- DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
- conf->senderData = connectPtr.p->userpointer;
- sendSignal(connectPtr.p->userblockref, GSN_DIADDTABCONF, signal,
- DiAddTabConf::SignalLength, JBB);
-
- // Release
- release_connect(connectPtr);
-}
-void
-Dbdih::release_connect(ConnectRecordPtr ptr)
-{
- ptr.p->userblockref = ZNIL;
- ptr.p->userpointer = RNIL;
- ptr.p->connectState = ConnectRecord::FREE;
- ptr.p->nfConnect = cfirstconnect;
- cfirstconnect = ptr.i;
-}
-
-void
-Dbdih::execADD_FRAGCONF(Signal* signal){
- jamEntry();
- AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
-
- ConnectRecordPtr connectPtr;
- connectPtr.i = conf->dihPtr;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
-
- TabRecordPtr tabPtr;
- tabPtr.i = connectPtr.p->table;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- sendAddFragreq(signal, connectPtr, tabPtr, conf->fragId + 1);
-}
-
-void
-Dbdih::execADD_FRAGREF(Signal* signal){
- jamEntry();
- AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
-
- ConnectRecordPtr connectPtr;
- connectPtr.i = ref->dihPtr;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
-
- {
- DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
- ref->senderData = connectPtr.p->userpointer;
- ref->errorCode = ~0;
- sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal,
- DiAddTabRef::SignalLength, JBB);
- }
-
- // Release
- release_connect(connectPtr);
-}
-
-/*
- 3.7.1.3 R E F U S E
- *********************
- */
-void Dbdih::addtabrefuseLab(Signal* signal, ConnectRecordPtr connectPtr, Uint32 errorCode)
-{
- signal->theData[0] = connectPtr.p->userpointer;
- signal->theData[1] = errorCode;
- sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB);
- release_connect(connectPtr);
- return;
-}//Dbdih::addtabrefuseLab()
-
-/*
- 3.7.2 A D D T A B L E D U P L I C A T I O N
- *************************************************
- */
-/*
- 3.7.2.1 A D D T A B L E D U P L I C A T I O N R E Q U E S T
- *******************************************************************=
- */
-
-/*
- D E L E T E T A B L E
- **********************=
- */
-/*****************************************************************************/
-/*********** DELETE TABLE MODULE *************/
-/*****************************************************************************/
-void
-Dbdih::execDROP_TAB_REQ(Signal* signal){
- jamEntry();
- DropTabReq* req = (DropTabReq*)signal->getDataPtr();
-
- TabRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- tabPtr.p->m_dropTab.tabUserRef = req->senderRef;
- tabPtr.p->m_dropTab.tabUserPtr = req->senderData;
-
- DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
-
- switch(rt){
- case DropTabReq::OnlineDropTab:
- jam();
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
- releaseTable(tabPtr);
- break;
- case DropTabReq::CreateTabDrop:
- jam();
- releaseTable(tabPtr);
- break;
- case DropTabReq::RestartDropTab:
- break;
- }
-
- startDeleteFile(signal, tabPtr);
-}
-
-void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
-{
- if (tabPtr.p->tabFile[0] == RNIL) {
- jam();
- initTableFile(tabPtr);
- }//if
- openTableFileForDelete(signal, tabPtr.p->tabFile[0]);
-}//Dbdih::startDeleteFile()
-
-void Dbdih::openTableFileForDelete(Signal* signal, Uint32 fileIndex)
-{
- FileRecordPtr filePtr;
- filePtr.i = fileIndex;
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_OPEN_FOR_DELETE;
-}//Dbdih::openTableFileForDelete()
-
-void Dbdih::tableOpenLab(Signal* signal, FileRecordPtr filePtr)
-{
- closeFileDelete(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_CLOSE_DELETE;
- return;
-}//Dbdih::tableOpenLab()
-
-void Dbdih::tableDeleteLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (filePtr.i == tabPtr.p->tabFile[0]) {
- jam();
- openTableFileForDelete(signal, tabPtr.p->tabFile[1]);
- return;
- }//if
- ndbrequire(filePtr.i == tabPtr.p->tabFile[1]);
-
- releaseFile(tabPtr.p->tabFile[0]);
- releaseFile(tabPtr.p->tabFile[1]);
- tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
-
- tabPtr.p->tabStatus = TabRecord::TS_IDLE;
-
- DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
- dropConf->senderRef = reference();
- dropConf->senderData = tabPtr.p->m_dropTab.tabUserPtr;
- dropConf->tableId = tabPtr.i;
- sendSignal(tabPtr.p->m_dropTab.tabUserRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
-
- tabPtr.p->m_dropTab.tabUserPtr = RNIL;
- tabPtr.p->m_dropTab.tabUserRef = 0;
-}//Dbdih::tableDeleteLab()
-
-
-void Dbdih::releaseTable(TabRecordPtr tabPtr)
-{
- FragmentstorePtr fragPtr;
- if (tabPtr.p->noOfFragChunks > 0) {
- for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
- jam();
- getFragstore(tabPtr.p, fragId, fragPtr);
- releaseReplicas(fragPtr.p->storedReplicas);
- releaseReplicas(fragPtr.p->oldStoredReplicas);
- }//for
- releaseFragments(tabPtr);
- }
- if (tabPtr.p->tabFile[0] != RNIL) {
- jam();
- releaseFile(tabPtr.p->tabFile[0]);
- releaseFile(tabPtr.p->tabFile[1]);
- tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
- }//if
-}//Dbdih::releaseTable()
-
-void Dbdih::releaseReplicas(Uint32 replicaPtrI)
-{
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = replicaPtrI;
- jam();
- while (replicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- Uint32 tmp = replicaPtr.p->nextReplica;
- replicaPtr.p->nextReplica = cfirstfreeReplica;
- cfirstfreeReplica = replicaPtr.i;
- replicaPtr.i = tmp;
- cnoFreeReplicaRec++;
- }//while
-}//Dbdih::releaseReplicas()
-
-void Dbdih::seizeReplicaRec(ReplicaRecordPtr& replicaPtr)
-{
- replicaPtr.i = cfirstfreeReplica;
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- cfirstfreeReplica = replicaPtr.p->nextReplica;
- cnoFreeReplicaRec--;
- replicaPtr.p->nextReplica = RNIL;
-}//Dbdih::seizeReplicaRec()
-
-void Dbdih::releaseFile(Uint32 fileIndex)
-{
- FileRecordPtr filePtr;
- filePtr.i = fileIndex;
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- filePtr.p->nextFile = cfirstfreeFile;
- cfirstfreeFile = filePtr.i;
-}//Dbdih::releaseFile()
-
-
-void Dbdih::execALTER_TAB_REQ(Signal * signal)
-{
- AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- const Uint32 gci = req->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) req->requestType;
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->schemaVersion = tableVersion;
-
- // Request handled successfully
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
-}
-
-/*
- G E T N O D E S
- **********************=
- */
-/*****************************************************************************/
-/* ********** TRANSACTION HANDLING MODULE *************/
-/*****************************************************************************/
-/*
- 3.8.1 G E T N O D E S R E Q U E S T
- ******************************************
- Asks what nodes should be part of a transaction.
-*/
-void Dbdih::execDIGETNODESREQ(Signal* signal)
-{
- const DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
- FragmentstorePtr fragPtr;
- TabRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- Uint32 hashValue = req->hashValue;
- Uint32 ttabFileSize = ctabFileSize;
- Uint32 fragId;
- DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
- TabRecord* regTabDesc = tabRecord;
- jamEntry();
- ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
- if (tabPtr.p->method == TabRecord::LINEAR_HASH)
- {
- jam();
- fragId = hashValue & tabPtr.p->mask;
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
- if (fragId < tabPtr.p->hashpointer) {
- jam();
- fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
- }//if
- }
- else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
- {
- jam();
- fragId= hashValue % tabPtr.p->totalfragments;
- }
- else
- {
- jam();
- ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
- fragId= hashValue;
- if (fragId >= tabPtr.p->totalfragments)
- {
- jam();
- conf->zero= 1; //Indicate error;
- signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
- return;
- }
- }
- getFragstore(tabPtr.p, fragId, fragPtr);
- Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
- Uint32 sig2 = (nodeCount - 1) +
- (fragPtr.p->distributionKey << 16);
- conf->zero = 0;
- conf->reqinfo = sig2;
- conf->fragId = fragId;
-}//Dbdih::execDIGETNODESREQ()
-
-Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[])
-{
- Uint32 nodeCount = 0;
- for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
- jam();
- NodeRecordPtr nodePtr;
- ndbrequire(i < MAX_REPLICAS);
- nodePtr.i = fragPtr->activeNodes[i];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->useInTransactions) {
- jam();
- nodes[nodeCount] = nodePtr.i;
- nodeCount++;
- }//if
- }//for
- ndbrequire(nodeCount > 0);
- return nodeCount;
-}//Dbdih::extractNodeInfo()
-
-void
-Dbdih::getFragstore(TabRecord * tab, //In parameter
- Uint32 fragNo, //In parameter
- FragmentstorePtr & fragptr) //Out parameter
-{
- FragmentstorePtr fragPtr;
- Uint32 chunkNo = fragNo >> LOG_NO_OF_FRAGS_PER_CHUNK;
- Uint32 chunkIndex = fragNo & (NO_OF_FRAGS_PER_CHUNK - 1);
- Uint32 TfragstoreFileSize = cfragstoreFileSize;
- Fragmentstore* TfragStore = fragmentstore;
- if (chunkNo < MAX_NDB_NODES) {
- fragPtr.i = tab->startFid[chunkNo] + chunkIndex;
- ptrCheckGuard(fragPtr, TfragstoreFileSize, TfragStore);
- fragptr = fragPtr;
- return;
- }//if
- ndbrequire(false);
-}//Dbdih::getFragstore()
-
-void Dbdih::allocFragments(Uint32 noOfFragments, TabRecordPtr tabPtr)
-{
- FragmentstorePtr fragPtr;
- Uint32 noOfChunks = (noOfFragments + (NO_OF_FRAGS_PER_CHUNK - 1)) >> LOG_NO_OF_FRAGS_PER_CHUNK;
- ndbrequire(cremainingfrags >= noOfFragments);
- for (Uint32 i = 0; i < noOfChunks; i++) {
- jam();
- Uint32 baseFrag = cfirstfragstore;
- tabPtr.p->startFid[i] = baseFrag;
- fragPtr.i = baseFrag;
- ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
- cfirstfragstore = fragPtr.p->nextFragmentChunk;
- cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
- for (Uint32 j = 0; j < NO_OF_FRAGS_PER_CHUNK; j++) {
- jam();
- fragPtr.i = baseFrag + j;
- ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
- initFragstore(fragPtr);
- }//if
- }//for
- tabPtr.p->noOfFragChunks = noOfChunks;
-}//Dbdih::allocFragments()
-
-void Dbdih::releaseFragments(TabRecordPtr tabPtr)
-{
- FragmentstorePtr fragPtr;
- for (Uint32 i = 0; i < tabPtr.p->noOfFragChunks; i++) {
- jam();
- Uint32 baseFrag = tabPtr.p->startFid[i];
- fragPtr.i = baseFrag;
- ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
- fragPtr.p->nextFragmentChunk = cfirstfragstore;
- cfirstfragstore = baseFrag;
- tabPtr.p->startFid[i] = RNIL;
- cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
- }//for
- tabPtr.p->noOfFragChunks = 0;
-}//Dbdih::releaseFragments()
-
-void Dbdih::initialiseFragstore()
-{
- Uint32 i;
- FragmentstorePtr fragPtr;
- for (i = 0; i < cfragstoreFileSize; i++) {
- fragPtr.i = i;
- ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
- initFragstore(fragPtr);
- }//for
- Uint32 noOfChunks = cfragstoreFileSize >> LOG_NO_OF_FRAGS_PER_CHUNK;
- fragPtr.i = 0;
- cfirstfragstore = RNIL;
- cremainingfrags = 0;
- for (i = 0; i < noOfChunks; i++) {
- refresh_watch_dog();
- ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
- fragPtr.p->nextFragmentChunk = cfirstfragstore;
- cfirstfragstore = fragPtr.i;
- fragPtr.i += NO_OF_FRAGS_PER_CHUNK;
- cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
- }//for
-}//Dbdih::initialiseFragstore()
-
-/*
- 3.9 V E R I F I C A T I O N
- ****************************=
- */
-/****************************************************************************/
-/* ********** VERIFICATION SUB-MODULE *************/
-/****************************************************************************/
-/*
- 3.9.1 R E C E I V I N G O F V E R I F I C A T I O N R E Q U E S T
- *************************************************************************
- */
-void Dbdih::execDIVERIFYREQ(Signal* signal)
-{
-
- jamEntry();
- if ((getBlockCommit() == false) &&
- (cfirstVerifyQueue == RNIL)) {
- jam();
- /*-----------------------------------------------------------------------*/
- // We are not blocked and the verify queue was empty currently so we can
- // simply reply back to TC immediately. The method was called with
- // EXECUTE_DIRECT so we reply back by setting signal data and returning.
- // theData[0] already contains the correct information so
- // we need not touch it.
- /*-----------------------------------------------------------------------*/
- signal->theData[1] = currentgcp;
- signal->theData[2] = 0;
- return;
- }//if
- /*-------------------------------------------------------------------------*/
- // Since we are blocked we need to put this operation last in the verify
- // queue to ensure that operation starts up in the correct order.
- /*-------------------------------------------------------------------------*/
- ApiConnectRecordPtr tmpApiConnectptr;
- ApiConnectRecordPtr localApiConnectptr;
-
- cverifyQueueCounter++;
- localApiConnectptr.i = signal->theData[0];
- tmpApiConnectptr.i = clastVerifyQueue;
- ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
- localApiConnectptr.p->apiGci = cnewgcp;
- localApiConnectptr.p->nextApi = RNIL;
- clastVerifyQueue = localApiConnectptr.i;
- if (tmpApiConnectptr.i == RNIL) {
- jam();
- cfirstVerifyQueue = localApiConnectptr.i;
- } else {
- jam();
- ptrCheckGuard(tmpApiConnectptr, capiConnectFileSize, apiConnectRecord);
- tmpApiConnectptr.p->nextApi = localApiConnectptr.i;
- }//if
- emptyverificbuffer(signal, false);
- signal->theData[2] = 1; // Indicate no immediate return
- return;
-}//Dbdih::execDIVERIFYREQ()
-
-void Dbdih::execDI_FCOUNTREQ(Signal* signal)
-{
- DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtr();
- ConnectRecordPtr connectPtr;
- TabRecordPtr tabPtr;
- const BlockReference senderRef = signal->senderBlockRef();
- const Uint32 senderData = req->m_senderData;
- jamEntry();
- connectPtr.i = req->m_connectionData;
- tabPtr.i = req->m_tableRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
- {
- DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
- //connectPtr.i == RNIL -> question without connect record
- if(connectPtr.i == RNIL)
- ref->m_connectionData = RNIL;
- else
- {
- jam();
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- ref->m_connectionData = connectPtr.p->userpointer;
- }
- ref->m_tableRef = tabPtr.i;
- ref->m_senderData = senderData;
- ref->m_error = DihFragCountRef::ErroneousTableState;
- ref->m_tableStatus = tabPtr.p->tabStatus;
- sendSignal(senderRef, GSN_DI_FCOUNTREF, signal,
- DihFragCountRef::SignalLength, JBB);
- return;
- }
-
- if(connectPtr.i != RNIL){
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- if (connectPtr.p->connectState == ConnectRecord::INUSE) {
- jam();
- DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
- conf->m_connectionData = connectPtr.p->userpointer;
- conf->m_tableRef = tabPtr.i;
- conf->m_senderData = senderData;
- conf->m_fragmentCount = tabPtr.p->totalfragments;
- conf->m_noOfBackups = tabPtr.p->noOfBackups;
- sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,
- DihFragCountConf::SignalLength, JBB);
- return;
- }//if
- DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
- ref->m_connectionData = connectPtr.p->userpointer;
- ref->m_tableRef = tabPtr.i;
- ref->m_senderData = senderData;
- ref->m_error = DihFragCountRef::ErroneousTableState;
- ref->m_tableStatus = tabPtr.p->tabStatus;
- sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal,
- DihFragCountRef::SignalLength, JBB);
- return;
- }//if
- DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
- //connectPtr.i == RNIL -> question without connect record
- conf->m_connectionData = RNIL;
- conf->m_tableRef = tabPtr.i;
- conf->m_senderData = senderData;
- conf->m_fragmentCount = tabPtr.p->totalfragments;
- conf->m_noOfBackups = tabPtr.p->noOfBackups;
- sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal,
- DihFragCountConf::SignalLength, JBB);
-}//Dbdih::execDI_FCOUNTREQ()
-
-void Dbdih::execDIGETPRIMREQ(Signal* signal)
-{
- FragmentstorePtr fragPtr;
- ConnectRecordPtr connectPtr;
- TabRecordPtr tabPtr;
- jamEntry();
- Uint32 passThrough = signal->theData[1];
- tabPtr.i = signal->theData[2];
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType)) {
- jam();
- tabPtr.i = tabPtr.p->primaryTableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- }
- Uint32 fragId = signal->theData[3];
-
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
- connectPtr.i = signal->theData[0];
- if(connectPtr.i != RNIL)
- {
- jam();
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
- signal->theData[0] = connectPtr.p->userpointer;
- }
- else
- {
- jam();
- signal->theData[0] = RNIL;
- }
-
- Uint32 nodes[MAX_REPLICAS];
- getFragstore(tabPtr.p, fragId, fragPtr);
- Uint32 count = extractNodeInfo(fragPtr.p, nodes);
-
- signal->theData[1] = passThrough;
- signal->theData[2] = nodes[0];
- signal->theData[3] = nodes[1];
- signal->theData[4] = nodes[2];
- signal->theData[5] = nodes[3];
- signal->theData[6] = count;
- signal->theData[7] = tabPtr.i;
- signal->theData[8] = fragId;
-
- const BlockReference senderRef = signal->senderBlockRef();
- sendSignal(senderRef, GSN_DIGETPRIMCONF, signal, 9, JBB);
-}//Dbdih::execDIGETPRIMREQ()
-
-/****************************************************************************/
-/* ********** GLOBAL-CHECK-POINT HANDLING MODULE *************/
-/****************************************************************************/
-/*
- 3.10 G L O B A L C H E C K P O I N T ( IN M A S T E R R O L E)
- *******************************************************************
- */
-void Dbdih::checkGcpStopLab(Signal* signal)
-{
- Uint32 tgcpStatus;
-
- tgcpStatus = cgcpStatus;
- if (tgcpStatus == coldGcpStatus) {
- jam();
- if (coldGcpId == cnewgcp) {
- jam();
- if (cgcpStatus != GCP_READY) {
- jam();
- cgcpSameCounter++;
- if (cgcpSameCounter == 1200) {
- jam();
-#ifdef VM_TRACE
- g_eventLogger.error("System crash due to GCP Stop in state = %u",
- (Uint32) cgcpStatus);
-#endif
- crashSystemAtGcpStop(signal, false);
- return;
- }//if
- } else {
- jam();
- if (cgcpOrderBlocked == 0) {
- jam();
- cgcpSameCounter++;
- if (cgcpSameCounter == 1200) {
- jam();
-#ifdef VM_TRACE
- g_eventLogger.error("System crash due to GCP Stop in state = %u",
- (Uint32) cgcpStatus);
-#endif
- crashSystemAtGcpStop(signal, false);
- return;
- }//if
- } else {
- jam();
- cgcpSameCounter = 0;
- }//if
- }//if
- } else {
- jam();
- cgcpSameCounter = 0;
- }//if
- } else {
- jam();
- cgcpSameCounter = 0;
- }//if
- signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
- signal->theData[1] = coldGcpStatus;
- signal->theData[2] = cgcpStatus;
- signal->theData[3] = coldGcpId;
- signal->theData[4] = cnewgcp;
- signal->theData[5] = cgcpSameCounter;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 6);
- coldGcpStatus = cgcpStatus;
- coldGcpId = cnewgcp;
- return;
-}//Dbdih::checkGcpStopLab()
-
-void Dbdih::startGcpLab(Signal* signal, Uint32 aWaitTime)
-{
- if ((cgcpOrderBlocked == 1) ||
- (c_nodeStartMaster.blockGcp == true) ||
- (cfirstVerifyQueue != RNIL)) {
- /*************************************************************************/
- // 1: Global Checkpoint has been stopped by management command
- // 2: Global Checkpoint is blocked by node recovery activity
- // 3: Previous global checkpoint is not yet completed.
- // All this means that global checkpoint cannot start now.
- /*************************************************************************/
- jam();
- cgcpStartCounter++;
- signal->theData[0] = DihContinueB::ZSTART_GCP;
- signal->theData[1] = aWaitTime > 100 ? (aWaitTime - 100) : 0;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- return;
- }//if
- if (cstartGcpNow == false && aWaitTime > 100){
- /*************************************************************************/
- // We still have more than 100 milliseconds before we start the next and
- // nobody has ordered immediate start of a global checkpoint.
- // During initial start we will use continuos global checkpoints to
- // speed it up since we need to complete a global checkpoint after
- // inserting a lot of records.
- /*************************************************************************/
- jam();
- cgcpStartCounter++;
- signal->theData[0] = DihContinueB::ZSTART_GCP;
- signal->theData[1] = (aWaitTime - 100);
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- return;
- }//if
- cgcpStartCounter = 0;
- cstartGcpNow = false;
- /***************************************************************************/
- // Report the event that a global checkpoint has started.
- /***************************************************************************/
- signal->theData[0] = NDB_LE_GlobalCheckpointStarted; //Event type
- signal->theData[1] = cnewgcp;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- CRASH_INSERTION(7000);
- cnewgcp++;
- signal->setTrace(TestOrd::TraceGlobalCheckpoint);
- sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE);
- cgcpStatus = GCP_PREPARE_SENT;
-}//Dbdih::startGcpLab()
-
-void Dbdih::execGCP_PREPARECONF(Signal* signal)
-{
- jamEntry();
- Uint32 senderNodeId = signal->theData[0];
- Uint32 gci = signal->theData[1];
- ndbrequire(gci == cnewgcp);
- receiveLoopMacro(GCP_PREPARE, senderNodeId);
- //-------------------------------------------------------------
- // We have now received all replies. We are ready to continue
- // with committing the global checkpoint.
- //-------------------------------------------------------------
- gcpcommitreqLab(signal);
-}//Dbdih::execGCP_PREPARECONF()
-
-void Dbdih::gcpcommitreqLab(Signal* signal)
-{
- CRASH_INSERTION(7001);
- sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT);
- cgcpStatus = GCP_COMMIT_SENT;
- return;
-}//Dbdih::gcpcommitreqLab()
-
-void Dbdih::execGCP_NODEFINISH(Signal* signal)
-{
- jamEntry();
- const Uint32 senderNodeId = signal->theData[0];
- const Uint32 gci = signal->theData[1];
- const Uint32 failureNr = signal->theData[2];
- if (!isMaster()) {
- jam();
- ndbrequire(failureNr > cfailurenr);
- //-------------------------------------------------------------
- // Another node thinks we are master. This could happen when he
- // has heard of a node failure which I have not heard of. Ignore
- // signal in this case since we will discover it by sending
- // MASTER_GCPREQ to the node.
- //-------------------------------------------------------------
- return;
- } else if (cmasterState == MASTER_TAKE_OVER_GCP) {
- jam();
- //-------------------------------------------------------------
- // We are currently taking over as master. Ignore
- // signal in this case since we will discover it in reception of
- // MASTER_GCPCONF.
- //-------------------------------------------------------------
- return;
- } else {
- ndbrequire(cmasterState == MASTER_ACTIVE);
- }//if
- ndbrequire(gci == coldgcp);
- receiveLoopMacro(GCP_COMMIT, senderNodeId);
- //-------------------------------------------------------------
- // We have now received all replies. We are ready to continue
- // with saving the global checkpoint to disk.
- //-------------------------------------------------------------
- CRASH_INSERTION(7002);
- gcpsavereqLab(signal);
- return;
-}//Dbdih::execGCP_NODEFINISH()
-
-void Dbdih::gcpsavereqLab(Signal* signal)
-{
- sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ);
- cgcpStatus = GCP_NODE_FINISHED;
-}//Dbdih::gcpsavereqLab()
-
-void Dbdih::execGCP_SAVECONF(Signal* signal)
-{
- jamEntry();
- const GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
- ndbrequire(saveConf->gci == coldgcp);
- ndbrequire(saveConf->nodeId == saveConf->dihPtr);
- SYSFILE->lastCompletedGCI[saveConf->nodeId] = saveConf->gci;
- GCP_SAVEhandling(signal, saveConf->nodeId);
-}//Dbdih::execGCP_SAVECONF()
-
-void Dbdih::execGCP_SAVEREF(Signal* signal)
-{
- jamEntry();
- const GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
- ndbrequire(saveRef->gci == coldgcp);
- ndbrequire(saveRef->nodeId == saveRef->dihPtr);
- /**
- * Only allow reason not to save
- */
- ndbrequire(saveRef->errorCode == GCPSaveRef::NodeShutdownInProgress ||
- saveRef->errorCode == GCPSaveRef::FakedSignalDueToNodeFailure ||
- saveRef->errorCode == GCPSaveRef::NodeRestartInProgress);
- GCP_SAVEhandling(signal, saveRef->nodeId);
-}//Dbdih::execGCP_SAVEREF()
-
-void Dbdih::GCP_SAVEhandling(Signal* signal, Uint32 nodeId)
-{
- receiveLoopMacro(GCP_SAVEREQ, nodeId);
- /*-------------------------------------------------------------------------*/
- // All nodes have replied. We are ready to update the system file.
- /*-------------------------------------------------------------------------*/
- cgcpStatus = GCP_SAVE_LQH_FINISHED;
- CRASH_INSERTION(7003);
- checkToCopy();
- /**------------------------------------------------------------------------
- * SET NEW RECOVERABLE GCI. ALSO RESET RESTART COUNTER TO ZERO.
- * THIS INDICATES THAT THE SYSTEM HAS BEEN RECOVERED AND SURVIVED AT
- * LEAST ONE GLOBAL CHECKPOINT PERIOD. WE WILL USE THIS PARAMETER TO
- * SET BACK THE RESTART GCI IF WE ENCOUNTER MORE THAN ONE UNSUCCESSFUL
- * RESTART.
- *------------------------------------------------------------------------*/
- SYSFILE->newestRestorableGCI = coldgcp;
- if(Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) &&
- getNodeState().startLevel == NodeState::SL_STARTED){
- jam();
-#if 0
- g_eventLogger.info("Dbdih: Clearing initial start ongoing");
-#endif
- Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
- }
- copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
-}//Dbdih::GCP_SAVEhandling()
-
-/*
- 3.11 G L O B A L C H E C K P O I N T (N O T - M A S T E R)
- *************************************************************
- */
-void Dbdih::execGCP_PREPARE(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(7005);
-
- if (ERROR_INSERTED(7030))
- {
- cgckptflag = true;
- g_eventLogger.info("Delayed GCP_PREPARE 5s");
- sendSignalWithDelay(reference(), GSN_GCP_PREPARE, signal, 5000,
- signal->getLength());
- return;
- }
-
- Uint32 masterNodeId = signal->theData[0];
- Uint32 gci = signal->theData[1];
- BlockReference retRef = calcDihBlockRef(masterNodeId);
-
- ndbrequire (cmasterdihref == retRef);
- ndbrequire (cgcpParticipantState == GCP_PARTICIPANT_READY);
- ndbrequire (gci == (currentgcp + 1));
-
- cgckptflag = true;
- cgcpParticipantState = GCP_PARTICIPANT_PREPARE_RECEIVED;
- cnewgcp = gci;
-
- if (ERROR_INSERTED(7031))
- {
- g_eventLogger.info("Crashing delayed in GCP_PREPARE 3s");
- signal->theData[0] = 9999;
- sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 3000, 1);
- return;
- }
-
- signal->theData[0] = cownNodeId;
- signal->theData[1] = gci;
- sendSignal(retRef, GSN_GCP_PREPARECONF, signal, 2, JBA);
- return;
-}//Dbdih::execGCP_PREPARE()
-
-void Dbdih::execGCP_COMMIT(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(7006);
- Uint32 masterNodeId = signal->theData[0];
- Uint32 gci = signal->theData[1];
-
- ndbrequire(gci == (currentgcp + 1));
- ndbrequire(masterNodeId = cmasterNodeId);
- ndbrequire(cgcpParticipantState == GCP_PARTICIPANT_PREPARE_RECEIVED);
-
- coldgcp = currentgcp;
- currentgcp = cnewgcp;
- cgckptflag = false;
- emptyverificbuffer(signal, true);
- cgcpParticipantState = GCP_PARTICIPANT_COMMIT_RECEIVED;
- signal->theData[0] = calcDihBlockRef(masterNodeId);
- signal->theData[1] = coldgcp;
- sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal, 2, JBB);
- return;
-}//Dbdih::execGCP_COMMIT()
-
-void Dbdih::execGCP_TCFINISHED(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(7007);
- Uint32 retRef = signal->theData[0];
- Uint32 gci = signal->theData[1];
- ndbrequire(gci == coldgcp);
-
- if (ERROR_INSERTED(7181) || ERROR_INSERTED(7182))
- {
- c_error_7181_ref = retRef; // Save ref
- ndbout_c("killing %d", refToNode(cmasterdihref));
- signal->theData[0] = 9999;
- sendSignal(numberToRef(CMVMI, refToNode(cmasterdihref)),
- GSN_NDB_TAMPER, signal, 1, JBB);
- return;
- }
-
- cgcpParticipantState = GCP_PARTICIPANT_TC_FINISHED;
- signal->theData[0] = cownNodeId;
- signal->theData[1] = coldgcp;
- signal->theData[2] = cfailurenr;
- sendSignal(retRef, GSN_GCP_NODEFINISH, signal, 3, JBB);
-}//Dbdih::execGCP_TCFINISHED()
-
-/*****************************************************************************/
-//****** RECEIVING TAMPER REQUEST FROM NDBAPI ******
-/*****************************************************************************/
-void Dbdih::execDIHNDBTAMPER(Signal* signal)
-{
- jamEntry();
- Uint32 tcgcpblocked = signal->theData[0];
- /* ACTION TO BE TAKEN BY DIH */
- Uint32 tuserpointer = signal->theData[1];
- BlockReference tuserblockref = signal->theData[2];
- switch (tcgcpblocked) {
- case 1:
- jam();
- if (isMaster()) {
- jam();
- cgcpOrderBlocked = 1;
- } else {
- jam();
- /* TRANSFER THE REQUEST */
- /* TO MASTER*/
- signal->theData[0] = tcgcpblocked;
- signal->theData[1] = tuserpointer;
- signal->theData[2] = tuserblockref;
- sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
- }//if
- break;
- case 2:
- jam();
- if (isMaster()) {
- jam();
- cgcpOrderBlocked = 0;
- } else {
- jam();
- /* TRANSFER THE REQUEST */
- /* TO MASTER*/
- signal->theData[0] = tcgcpblocked;
- signal->theData[1] = tuserpointer;
- signal->theData[2] = tuserblockref;
- sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
- }//if
- break;
- case 3:
- ndbrequire(false);
- return;
- break;
- case 4:
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = crestartGci;
- sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 2, JBB);
- break;
-#ifdef ERROR_INSERT
- case 5:
- jam();
- if(tuserpointer == 0)
- {
- jam();
- signal->theData[0] = 0;
- sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- return;
- }
- /*----------------------------------------------------------------------*/
- // Insert errors.
- /*----------------------------------------------------------------------*/
- if (tuserpointer < 1000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into QMGR.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = QMGR_REF;
- } else if (tuserpointer < 2000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into NDBCNTR.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = NDBCNTR_REF;
- } else if (tuserpointer < 3000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into NDBFS.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = NDBFS_REF;
- } else if (tuserpointer < 4000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into DBACC.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = DBACC_REF;
- } else if (tuserpointer < 5000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into DBTUP.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = DBTUP_REF;
- } else if (tuserpointer < 6000) {
- /*---------------------------------------------------------------------*/
- // Insert errors into DBLQH.
- /*---------------------------------------------------------------------*/
- jam();
- tuserblockref = DBLQH_REF;
- } else if (tuserpointer < 7000) {
- /*---------------------------------------------------------------------*/
- // Insert errors into DBDICT.
- /*---------------------------------------------------------------------*/
- jam();
- tuserblockref = DBDICT_REF;
- } else if (tuserpointer < 8000) {
- /*---------------------------------------------------------------------*/
- // Insert errors into DBDIH.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = DBDIH_REF;
- } else if (tuserpointer < 9000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into DBTC.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = DBTC_REF;
- } else if (tuserpointer < 10000) {
- /*--------------------------------------------------------------------*/
- // Insert errors into CMVMI.
- /*--------------------------------------------------------------------*/
- jam();
- tuserblockref = CMVMI_REF;
- } else if (tuserpointer < 11000) {
- jam();
- tuserblockref = BACKUP_REF;
- } else if (tuserpointer < 12000) {
- // DBUTIL_REF ?
- jam();
- } else if (tuserpointer < 13000) {
- jam();
- tuserblockref = DBTUX_REF;
- } else if (tuserpointer < 14000) {
- jam();
- tuserblockref = SUMA_REF;
- } else if (tuserpointer < 15000) {
- jam();
- tuserblockref = DBDICT_REF;
- } else if (tuserpointer < 16000) {
- jam();
- tuserblockref = LGMAN_REF;
- } else if (tuserpointer < 17000) {
- jam();
- tuserblockref = TSMAN_REF;
- } else if (tuserpointer < 30000) {
- /*--------------------------------------------------------------------*/
- // Ignore errors in the 20000-range.
- /*--------------------------------------------------------------------*/
- jam();
- return;
- } else if (tuserpointer < 40000) {
- jam();
- /*--------------------------------------------------------------------*/
- // Redirect errors to master DIH in the 30000-range.
- /*--------------------------------------------------------------------*/
- tuserblockref = cmasterdihref;
- tuserpointer -= 30000;
- signal->theData[0] = 5;
- signal->theData[1] = tuserpointer;
- signal->theData[2] = tuserblockref;
- sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
- return;
- } else if (tuserpointer < 50000) {
- NodeRecordPtr localNodeptr;
- Uint32 Tfound = 0;
- jam();
- /*--------------------------------------------------------------------*/
- // Redirect errors to non-master DIH in the 40000-range.
- /*--------------------------------------------------------------------*/
- tuserpointer -= 40000;
- for (localNodeptr.i = 1;
- localNodeptr.i < MAX_NDB_NODES;
- localNodeptr.i++) {
- jam();
- ptrAss(localNodeptr, nodeRecord);
- if ((localNodeptr.p->nodeStatus == NodeRecord::ALIVE) &&
- (localNodeptr.i != cmasterNodeId)) {
- jam();
- tuserblockref = calcDihBlockRef(localNodeptr.i);
- Tfound = 1;
- break;
- }//if
- }//for
- if (Tfound == 0) {
- jam();
- /*-------------------------------------------------------------------*/
- // Ignore since no non-master node existed.
- /*-------------------------------------------------------------------*/
- return;
- }//if
- signal->theData[0] = 5;
- signal->theData[1] = tuserpointer;
- signal->theData[2] = tuserblockref;
- sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
- return;
- } else {
- jam();
- return;
- }//if
- signal->theData[0] = tuserpointer;
- if (tuserpointer != 0) {
- sendSignal(tuserblockref, GSN_NDB_TAMPER, signal, 1, JBB);
- } else {
- sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
- }//if
- break;
-#endif
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dbdih::execDIHNDBTAMPER()
-
-/*****************************************************************************/
-/* ********** FILE HANDLING MODULE *************/
-/*****************************************************************************/
-void Dbdih::copyGciLab(Signal* signal, CopyGCIReq::CopyReason reason)
-{
- if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE){
- /**
- * There can currently only be one waiting
- */
- ndbrequire(c_copyGCIMaster.m_waiting == CopyGCIReq::IDLE);
- c_copyGCIMaster.m_waiting = reason;
- return;
- }
- c_copyGCIMaster.m_copyReason = reason;
- sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
-
-}//Dbdih::copyGciLab()
-
-/* ------------------------------------------------------------------------- */
-/* COPY_GCICONF RESPONSE TO COPY_GCIREQ */
-/* ------------------------------------------------------------------------- */
-void Dbdih::execCOPY_GCICONF(Signal* signal)
-{
- jamEntry();
- NodeRecordPtr senderNodePtr;
- senderNodePtr.i = signal->theData[0];
- receiveLoopMacro(COPY_GCIREQ, senderNodePtr.i);
-
- CopyGCIReq::CopyReason waiting = c_copyGCIMaster.m_waiting;
- CopyGCIReq::CopyReason current = c_copyGCIMaster.m_copyReason;
-
- c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
- c_copyGCIMaster.m_waiting = CopyGCIReq::IDLE;
-
- bool ok = false;
- switch(current){
- case CopyGCIReq::RESTART:{
- ok = true;
- jam();
- DictStartReq * req = (DictStartReq*)&signal->theData[0];
- req->restartGci = SYSFILE->newestRestorableGCI;
- req->senderRef = reference();
- sendSignal(cdictblockref, GSN_DICTSTARTREQ,
- signal, DictStartReq::SignalLength, JBB);
- break;
- }
- case CopyGCIReq::LOCAL_CHECKPOINT:{
- ok = true;
- jam();
- startLcpRoundLab(signal);
- break;
- }
- case CopyGCIReq::GLOBAL_CHECKPOINT:
- ok = true;
- jam();
- checkToCopyCompleted(signal);
-
- /************************************************************************/
- // Report the event that a global checkpoint has completed.
- /************************************************************************/
- signal->setTrace(0);
- signal->theData[0] = NDB_LE_GlobalCheckpointCompleted; //Event type
- signal->theData[1] = coldgcp;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- c_newest_restorable_gci = coldgcp;
-
- CRASH_INSERTION(7004);
- emptyWaitGCPMasterQueue(signal);
- cgcpStatus = GCP_READY;
- signal->theData[0] = DihContinueB::ZSTART_GCP;
- signal->theData[1] = cgcpDelay;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- if (c_nodeStartMaster.blockGcp == true) {
- jam();
- /* ------------------------------------------------------------------ */
- /* A NEW NODE WANTS IN AND WE MUST ALLOW IT TO COME IN NOW SINCE THE */
- /* GCP IS COMPLETED. */
- /* ------------------------------------------------------------------ */
- gcpBlockedLab(signal);
- }//if
- break;
- case CopyGCIReq::INITIAL_START_COMPLETED:
- ok = true;
- jam();
- initialStartCompletedLab(signal);
- break;
- case CopyGCIReq::IDLE:
- ok = false;
- jam();
- }
- ndbrequire(ok);
-
- /**
- * Pop queue
- */
- if(waiting != CopyGCIReq::IDLE){
- c_copyGCIMaster.m_copyReason = waiting;
- signal->theData[0] = DihContinueB::ZCOPY_GCI;
- signal->theData[1] = waiting;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
-}//Dbdih::execCOPY_GCICONF()
-
-void Dbdih::invalidateLcpInfoAfterSr()
-{
- NodeRecordPtr nodePtr;
- SYSFILE->latestLCP_ID--;
- Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (!NdbNodeBitmask::get(SYSFILE->lcpActive, nodePtr.i)){
- jam();
- /* ------------------------------------------------------------------- */
- // The node was not active in the local checkpoint.
- // To avoid that we step the active status too fast to not
- // active we step back one step from Sysfile::NS_ActiveMissed_x.
- /* ------------------------------------------------------------------- */
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- /* ----------------------------------------------------------------- */
- // When not active in ongoing LCP and still active is a contradiction.
- /* ----------------------------------------------------------------- */
- ndbrequire(false);
- case Sysfile::NS_ActiveMissed_1:
- jam();
- nodePtr.p->activeStatus = Sysfile::NS_Active;
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
- break;
- default:
- jam();
- break;
- }//switch
- }//if
- }//for
- setNodeRestartInfoBits();
-}//Dbdih::invalidateLcpInfoAfterSr()
-
-/* ------------------------------------------------------------------------- */
-/* THE NEXT STEP IS TO WRITE THE FILE. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::openingCopyGciSkipInitLab(Signal* signal, FileRecordPtr filePtr)
-{
- writeRestorableGci(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::WRITING_COPY_GCI;
- return;
-}//Dbdih::openingCopyGciSkipInitLab()
-
-void Dbdih::writingCopyGciLab(Signal* signal, FileRecordPtr filePtr)
-{
- /* ----------------------------------------------------------------------- */
- /* WE HAVE NOW WRITTEN THIS FILE. WRITE ALSO NEXT FILE IF THIS IS NOT */
- /* ALREADY THE LAST. */
- /* ----------------------------------------------------------------------- */
- filePtr.p->reqStatus = FileRecord::IDLE;
- if (filePtr.i == crestartInfoFile[0]) {
- jam();
- filePtr.i = crestartInfoFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- if (filePtr.p->fileStatus == FileRecord::OPEN) {
- jam();
- openingCopyGciSkipInitLab(signal, filePtr);
- return;
- }//if
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
- return;
- }//if
- /* ----------------------------------------------------------------------- */
- /* WE HAVE COMPLETED WRITING BOTH FILES SUCCESSFULLY. NOW REPORT OUR */
- /* SUCCESS TO THE MASTER DIH. BUT FIRST WE NEED TO RESET A NUMBER OF */
- /* VARIABLES USED BY THE LOCAL CHECKPOINT PROCESS (ONLY IF TRIGGERED */
- /* BY LOCAL CHECKPOINT PROCESS. */
- /* ----------------------------------------------------------------------- */
- CopyGCIReq::CopyReason reason = c_copyGCISlave.m_copyReason;
-
- if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
- jam();
- cgcpParticipantState = GCP_PARTICIPANT_READY;
-
- SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
- rep->gci = coldgcp;
- sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal,
- SubGcpCompleteRep::SignalLength, JBB);
-
- EXECUTE_DIRECT(LGMAN, GSN_SUB_GCP_COMPLETE_REP, signal,
- SubGcpCompleteRep::SignalLength);
- jamEntry();
- }
-
- jam();
- c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
-
- if(c_copyGCISlave.m_senderRef == cmasterdihref){
- jam();
- /**
- * Only if same master
- */
- signal->theData[0] = c_copyGCISlave.m_senderData;
- sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
-
- }
- return;
-}//Dbdih::writingCopyGciLab()
-
-void Dbdih::execSTART_LCP_REQ(Signal* signal){
- StartLcpReq * req = (StartLcpReq*)signal->getDataPtr();
-
- CRASH_INSERTION2(7021, isMaster());
- CRASH_INSERTION2(7022, !isMaster());
-
- ndbrequire(c_lcpState.m_masterLcpDihRef = req->senderRef);
- c_lcpState.m_participatingDIH = req->participatingDIH;
- c_lcpState.m_participatingLQH = req->participatingLQH;
-
- c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH = req->participatingLQH;
- if(isMaster()){
- jam();
- ndbrequire(isActiveMaster());
- c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH = req->participatingDIH;
-
- } else {
- c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor();
- }
-
- c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = false;
-
- c_lcpState.setLcpStatus(LCP_INIT_TABLES, __LINE__);
-
- signal->theData[0] = DihContinueB::ZINIT_LCP;
- signal->theData[1] = c_lcpState.m_masterLcpDihRef;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
-
- if(c_lcpState.m_masterLcpDihRef != senderRef){
- jam();
- /**
- * This is LCP master takeover
- */
-#ifdef VM_TRACE
- g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 1");
-#endif
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- sendMASTER_LCPCONF(signal);
- return;
- }
-
- if(c_lcpState.m_masterLcpDihRef != cmasterdihref){
- jam();
- /**
- * Master take over but has not yet received MASTER_LCPREQ
- */
-#ifdef VM_TRACE
- g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 2");
-#endif
- return;
- }
-
- //const Uint32 lcpId = SYSFILE->latestLCP_ID;
-
- for(; tabPtr.i < ctabFileSize; tabPtr.i++){
-
- ptrAss(tabPtr, tabRecord);
-
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
- jam();
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
- continue;
- }
-
- if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
- /**
- * Table is not logged
- */
- jam();
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
- continue;
- }
-
- if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
- /* ----------------------------------------------------------------- */
- // We protect the updates of table data structures by this variable.
- /* ----------------------------------------------------------------- */
- jam();
- signal->theData[0] = DihContinueB::ZINIT_LCP;
- signal->theData[1] = senderRef;
- signal->theData[2] = tabPtr.i;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
- return;
- }//if
-
- /**
- * Found a table
- */
- tabPtr.p->tabLcpStatus = TabRecord::TLS_ACTIVE;
-
- /**
- * For each fragment
- */
- for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
- jam();
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
-
- /**
- * For each of replica record
- */
- Uint32 replicaCount = 0;
- ReplicaRecordPtr replicaPtr;
- for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
- replicaPtr.i = replicaPtr.p->nextReplica) {
- jam();
-
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- Uint32 nodeId = replicaPtr.p->procNode;
- if(c_lcpState.m_participatingLQH.get(nodeId)){
- jam();
- replicaCount++;
- replicaPtr.p->lcpOngoingFlag = true;
- }
- }
-
- fragPtr.p->noLcpReplicas = replicaCount;
- }//for
-
- signal->theData[0] = DihContinueB::ZINIT_LCP;
- signal->theData[1] = senderRef;
- signal->theData[2] = tabPtr.i + 1;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
-
- /**
- * No more tables
- */
- jam();
-
- if (c_lcpState.m_masterLcpDihRef != reference()){
- jam();
- ndbrequire(!isMaster());
- c_lcpState.setLcpStatus(LCP_STATUS_ACTIVE, __LINE__);
- } else {
- jam();
- ndbrequire(isMaster());
- }
-
- CRASH_INSERTION2(7023, isMaster());
- CRASH_INSERTION2(7024, !isMaster());
-
- jam();
- StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- sendSignal(c_lcpState.m_masterLcpDihRef, GSN_START_LCP_CONF, signal,
- StartLcpConf::SignalLength, JBB);
- return;
-}//Dbdih::initLcpLab()
-
-/* ------------------------------------------------------------------------- */
-/* ERROR HANDLING FOR COPY RESTORABLE GCI FILE. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::openingCopyGciErrorLab(Signal* signal, FileRecordPtr filePtr)
-{
- createFileRw(signal, filePtr);
- /* ------------------------------------------------------------------------- */
- /* ERROR IN OPENING FILE. WE WILL TRY BY CREATING FILE INSTEAD. */
- /* ------------------------------------------------------------------------- */
- filePtr.p->reqStatus = FileRecord::CREATING_COPY_GCI;
- return;
-}//Dbdih::openingCopyGciErrorLab()
-
-/* ------------------------------------------------------------------------- */
-/* ENTER DICTSTARTCONF WITH */
-/* TBLOCKREF */
-/* ------------------------------------------------------------------------- */
-void Dbdih::dictStartConfLab(Signal* signal)
-{
- /* ----------------------------------------------------------------------- */
- /* WE HAVE NOW RECEIVED ALL THE TABLES TO RESTART. */
- /* ----------------------------------------------------------------------- */
- signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
- signal->theData[1] = 0; /* START WITH TABLE 0 */
- signal->theData[2] = 0; /* AND FRAGMENT 0 */
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
-}//Dbdih::dictStartConfLab()
-
-
-void Dbdih::openingTableLab(Signal* signal, FileRecordPtr filePtr)
-{
- /* ---------------------------------------------------------------------- */
- /* SUCCESSFULLY OPENED A FILE. READ THE FIRST PAGE OF THIS FILE. */
- /* ---------------------------------------------------------------------- */
- TabRecordPtr tabPtr;
- PageRecordPtr pagePtr;
-
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->noPages = 1;
- allocpage(pagePtr);
- tabPtr.p->pageRef[0] = pagePtr.i;
- readTabfile(signal, tabPtr.p, filePtr);
- filePtr.p->reqStatus = FileRecord::READING_TABLE;
- return;
-}//Dbdih::openingTableLab()
-
-void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- /* ---------------------------------------------------------------------- */
- /* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */
- /* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
- /* ---------------------------------------------------------------------- */
- if (filePtr.i == tabPtr.p->tabFile[0])
- {
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
- }
- else
- {
- char buf[256];
- BaseString::snprintf(buf, sizeof(buf),
- "Error opening DIH schema files for table: %d",
- tabPtr.i);
- progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf);
- }
-}//Dbdih::openingTableErrorLab()
-
-void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- PageRecordPtr pagePtr;
- /* ---------------------------------------------------------------------- */
- /* WE HAVE SUCCESSFULLY READ A NUMBER OF PAGES IN THE TABLE FILE. IF */
- /* MORE PAGES EXIST IN THE FILE THEN READ ALL PAGES IN THE FILE. */
- /* ---------------------------------------------------------------------- */
- filePtr.p->reqStatus = FileRecord::IDLE;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- pagePtr.i = tabPtr.p->pageRef[0];
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- Uint32 noOfStoredPages = pagePtr.p->word[33];
- if (tabPtr.p->noPages < noOfStoredPages) {
- jam();
- ndbrequire(noOfStoredPages <= 8);
- for (Uint32 i = tabPtr.p->noPages; i < noOfStoredPages; i++) {
- jam();
- allocpage(pagePtr);
- tabPtr.p->pageRef[i] = pagePtr.i;
- }//for
- tabPtr.p->noPages = noOfStoredPages;
- readTabfile(signal, tabPtr.p, filePtr);
- filePtr.p->reqStatus = FileRecord::READING_TABLE;
- } else {
- ndbrequire(tabPtr.p->noPages == pagePtr.p->word[33]);
- ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
- jam();
- /* --------------------------------------------------------------------- */
- /* WE HAVE READ ALL PAGES. NOW READ FROM PAGES INTO TABLE AND FRAGMENT */
- /* DATA STRUCTURES. */
- /* --------------------------------------------------------------------- */
- tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE1_READ_PAGES;
- signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- return;
-}//Dbdih::readingTableLab()
-
-void Dbdih::readTableFromPagesLab(Signal* signal, TabRecordPtr tabPtr)
-{
- FileRecordPtr filePtr;
- filePtr.i = tabPtr.p->tabFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- /* ---------------------------------------------------------------------- */
- /* WE HAVE NOW COPIED TO OUR NODE. WE HAVE NOW COMPLETED RESTORING */
- /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
- /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
- /* ---------------------------------------------------------------------- */
- if (filePtr.p->fileStatus != FileRecord::OPEN) {
- jam();
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- }//if
- closeFile(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_SR;
- return;
-}//Dbdih::readTableFromPagesLab()
-
-void Dbdih::closingTableSrLab(Signal* signal, FileRecordPtr filePtr)
-{
- /**
- * Update table/fragment info
- */
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- resetReplicaSr(tabPtr);
-
- signal->theData[0] = DihContinueB::ZCOPY_TABLE;
- signal->theData[1] = filePtr.p->tabRef;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-
- return;
-}//Dbdih::closingTableSrLab()
-
-void
-Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
-
- const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
-
- for(Uint32 i = 0; i<tabPtr.p->totalfragments; i++){
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, i, fragPtr);
-
- /**
- * 1) Start by moving all replicas into oldStoredReplicas
- */
- prepareReplicas(fragPtr);
-
- /**
- * 2) Move all "alive" replicas into storedReplicas
- * + update noCrashedReplicas...
- */
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = fragPtr.p->oldStoredReplicas;
- while (replicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- const Uint32 nextReplicaPtrI = replicaPtr.p->nextReplica;
-
- NodeRecordPtr nodePtr;
- nodePtr.i = replicaPtr.p->procNode;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- const Uint32 noCrashedReplicas = replicaPtr.p->noCrashedReplicas;
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- case Sysfile::NS_ActiveMissed_2:{
- jam();
- /* --------------------------------------------------------------- */
- /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT. */
- /* --------------------------------------------------------------- */
- arrGuardErr(noCrashedReplicas, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
- Uint32 lastGci = replicaPtr.p->replicaLastGci[noCrashedReplicas];
- if(lastGci >= newestRestorableGCI){
- jam();
- /** -------------------------------------------------------------
- * THE REPLICA WAS ALIVE AT THE SYSTEM FAILURE. WE WILL SET THE
- * LAST REPLICA GCI TO MINUS ONE SINCE IT HASN'T FAILED YET IN THE
- * NEW SYSTEM.
- *-------------------------------------------------------------- */
- replicaPtr.p->replicaLastGci[noCrashedReplicas] = (Uint32)-1;
- } else {
- jam();
- /*--------------------------------------------------------------
- * SINCE IT WAS NOT ALIVE AT THE TIME OF THE SYSTEM CRASH THIS IS
- * A COMPLETELY NEW REPLICA. WE WILL SET THE CREATE GCI TO BE THE
- * NEXT GCI TO BE EXECUTED.
- *--------_----------------------------------------------------- */
- const Uint32 nextCrashed = noCrashedReplicas + 1;
- replicaPtr.p->noCrashedReplicas = nextCrashed;
- arrGuardErr(nextCrashed, 8, NDBD_EXIT_MAX_CRASHED_REPLICAS);
- replicaPtr.p->createGci[nextCrashed] = newestRestorableGCI + 1;
- ndbrequire(newestRestorableGCI + 1 != 0xF1F1F1F1);
- replicaPtr.p->replicaLastGci[nextCrashed] = (Uint32)-1;
- }//if
-
- resetReplicaLcp(replicaPtr.p, newestRestorableGCI);
-
- /**
- * Make sure we can also find REDO for restoring replica...
- */
- {
- CreateReplicaRecord createReplica;
- ConstPtr<ReplicaRecord> constReplicaPtr;
- constReplicaPtr.i = replicaPtr.i;
- constReplicaPtr.p = replicaPtr.p;
- if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL ||
- setup_create_replica(fragPtr,
- &createReplica, constReplicaPtr))
- {
- jam();
- removeOldStoredReplica(fragPtr, replicaPtr);
- linkStoredReplica(fragPtr, replicaPtr);
- }
- else
- {
- jam();
- infoEvent("Forcing take-over of node %d due to unsufficient REDO"
- " for table %d fragment: %d",
- nodePtr.i, tabPtr.i, i);
-
- setNodeActiveStatus(nodePtr.i,
- Sysfile::NS_NotActive_NotTakenOver);
- }
- }
- }
- default:
- jam();
- /*empty*/;
- break;
- }
- }
- replicaPtr.i = nextReplicaPtrI;
- }//while
- updateNodeInfo(fragPtr);
- }
-}
-
-void
-Dbdih::resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci){
-
- Uint32 lcpNo = replicaP->nextLcp;
- const Uint32 startLcpNo = lcpNo;
- do {
- lcpNo = prevLcpNo(lcpNo);
- ndbrequire(lcpNo < MAX_LCP_STORED);
- if (replicaP->lcpStatus[lcpNo] == ZVALID) {
- if (replicaP->maxGciStarted[lcpNo] < stopGci) {
- jam();
- /* ----------------------------------------------------------------- */
- /* WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR */
- /* RESTARTING THIS FRAGMENT REPLICA. */
- /* ----------------------------------------------------------------- */
- return ;
- }//if
- }//if
-
- /**
- * WE COULD NOT USE THIS LOCAL CHECKPOINT. IT WAS TOO
- * RECENT OR SIMPLY NOT A VALID CHECKPOINT.
- * WE SHOULD THUS REMOVE THIS LOCAL CHECKPOINT SINCE IT WILL NEVER
- * AGAIN BE USED. SET LCP_STATUS TO INVALID.
- */
- replicaP->nextLcp = lcpNo;
- replicaP->lcpId[lcpNo] = 0;
- replicaP->lcpStatus[lcpNo] = ZINVALID;
- } while (lcpNo != startLcpNo);
-
- replicaP->nextLcp = 0;
-}
-
-void Dbdih::readingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- /* ---------------------------------------------------------------------- */
- /* READING THIS FILE FAILED. CLOSE IT AFTER RELEASING ALL PAGES. */
- /* ---------------------------------------------------------------------- */
- ndbrequire(tabPtr.p->noPages <= 8);
- for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
- jam();
- releasePage(tabPtr.p->pageRef[i]);
- }//for
- closeFile(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_CRASH;
- return;
-}//Dbdih::readingTableErrorLab()
-
-void Dbdih::closingTableCrashLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- /* ---------------------------------------------------------------------- */
- /* WE HAVE NOW CLOSED A FILE WHICH WE HAD A READ ERROR WITH. PROCEED */
- /* WITH NEXT FILE IF NOT THE LAST OTHERWISE REPORT ERROR. */
- /* ---------------------------------------------------------------------- */
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
-}//Dbdih::closingTableCrashLab()
-
-/*****************************************************************************/
-/* ********** COPY TABLE MODULE *************/
-/*****************************************************************************/
-void Dbdih::execCOPY_TABREQ(Signal* signal)
-{
- CRASH_INSERTION(7172);
-
- TabRecordPtr tabPtr;
- PageRecordPtr pagePtr;
- jamEntry();
- BlockReference ref = signal->theData[0];
- Uint32 reqinfo = signal->theData[1];
- tabPtr.i = signal->theData[2];
- Uint32 schemaVersion = signal->theData[3];
- Uint32 noOfWords = signal->theData[4];
- ndbrequire(ref == cmasterdihref);
- ndbrequire(!isMaster());
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (reqinfo == 1) {
- jam();
- tabPtr.p->schemaVersion = schemaVersion;
- initTableFile(tabPtr);
- }//if
- ndbrequire(tabPtr.p->noPages < 8);
- if (tabPtr.p->noOfWords == 0) {
- jam();
- allocpage(pagePtr);
- tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
- tabPtr.p->noPages++;
- } else {
- jam();
- pagePtr.i = tabPtr.p->pageRef[tabPtr.p->noPages - 1];
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- }//if
- ndbrequire(tabPtr.p->noOfWords + 15 < 2048);
- ndbrequire(tabPtr.p->noOfWords < 2048);
- MEMCOPY_NO_WORDS(&pagePtr.p->word[tabPtr.p->noOfWords], &signal->theData[5], 16);
- tabPtr.p->noOfWords += 16;
- if (tabPtr.p->noOfWords == 2048) {
- jam();
- tabPtr.p->noOfWords = 0;
- }//if
- if (noOfWords > 16) {
- jam();
- return;
- }//if
- tabPtr.p->noOfWords = 0;
- ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
- tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TAB_REQ;
- signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}//Dbdih::execCOPY_TABREQ()
-
-void
-Dbdih::copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr){
- if (!isMaster()) {
- jam();
- //----------------------------------------------------------------------------
- // In this particular case we do not release table pages if we are master. The
- // reason is that the master could still be sending the table info to another
- // node.
- //----------------------------------------------------------------------------
- releaseTabPages(tabPtr.i);
- tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
- for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
- jam();
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- updateNodeInfo(fragPtr);
- }//for
- }//if
- signal->theData[0] = cownNodeId;
- signal->theData[1] = tabPtr.i;
- sendSignal(cmasterdihref, GSN_COPY_TABCONF, signal, 2, JBB);
-}
-
-/*****************************************************************************/
-/* ****** READ FROM A NUMBER OF PAGES INTO THE TABLE DATA STRUCTURES ********/
-/*****************************************************************************/
-void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId)
-{
- RWFragment rf;
- rf.wordIndex = 35;
- rf.pageIndex = 0;
- rf.rwfTabPtr.i = tableId;
- ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
- rf.rwfPageptr.i = rf.rwfTabPtr.p->pageRef[0];
- ptrCheckGuard(rf.rwfPageptr, cpageFileSize, pageRecord);
- rf.rwfTabPtr.p->totalfragments = readPageWord(&rf);
- rf.rwfTabPtr.p->noOfBackups = readPageWord(&rf);
- rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
- rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
- rf.rwfTabPtr.p->mask = readPageWord(&rf);
- rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
- /* ------------- */
- /* Type of table */
- /* ------------- */
- rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf));
-
- Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
- ndbrequire(noOfFrags > 0);
- ndbrequire((noOfFrags * (rf.rwfTabPtr.p->noOfBackups + 1)) <= cnoFreeReplicaRec);
- allocFragments(noOfFrags, rf.rwfTabPtr);
-
- signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
- signal->theData[1] = rf.rwfTabPtr.i;
- signal->theData[2] = 0;
- signal->theData[3] = rf.pageIndex;
- signal->theData[4] = rf.wordIndex;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
- return;
-}//Dbdih::readPagesIntoTableLab()
-
-void Dbdih::readPagesIntoFragLab(Signal* signal, RWFragment* rf)
-{
- ndbrequire(rf->pageIndex < 8);
- rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
- ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
- FragmentstorePtr fragPtr;
- getFragstore(rf->rwfTabPtr.p, rf->fragId, fragPtr);
- readFragment(rf, fragPtr);
- readReplicas(rf, fragPtr);
- rf->fragId++;
- if (rf->fragId == rf->rwfTabPtr.p->totalfragments) {
- jam();
- switch (rf->rwfTabPtr.p->tabCopyStatus) {
- case TabRecord::CS_SR_PHASE1_READ_PAGES:
- jam();
- releaseTabPages(rf->rwfTabPtr.i);
- rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- signal->theData[0] = DihContinueB::ZREAD_TABLE_FROM_PAGES;
- signal->theData[1] = rf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::CS_COPY_TAB_REQ:
- jam();
- rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- if(getNodeState().getSystemRestartInProgress()){
- jam();
- copyTabReq_complete(signal, rf->rwfTabPtr);
- return;
- }
- rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- rf->rwfTabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
- signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
- signal->theData[1] = rf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- } else {
- jam();
- signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
- signal->theData[1] = rf->rwfTabPtr.i;
- signal->theData[2] = rf->fragId;
- signal->theData[3] = rf->pageIndex;
- signal->theData[4] = rf->wordIndex;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
- }//if
- return;
-}//Dbdih::readPagesIntoFragLab()
-
-/*****************************************************************************/
-/***** WRITING FROM TABLE DATA STRUCTURES INTO A SET OF PAGES ******/
-// execCONTINUEB(ZPACK_TABLE_INTO_PAGES)
-/*****************************************************************************/
-void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId)
-{
- RWFragment wf;
- TabRecordPtr tabPtr;
- allocpage(wf.rwfPageptr);
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- tabPtr.p->pageRef[0] = wf.rwfPageptr.i;
- tabPtr.p->noPages = 1;
- wf.wordIndex = 35;
- wf.pageIndex = 0;
- writePageWord(&wf, tabPtr.p->totalfragments);
- writePageWord(&wf, tabPtr.p->noOfBackups);
- writePageWord(&wf, tabPtr.p->hashpointer);
- writePageWord(&wf, tabPtr.p->kvalue);
- writePageWord(&wf, tabPtr.p->mask);
- writePageWord(&wf, tabPtr.p->method);
- writePageWord(&wf, tabPtr.p->tabStorage);
-
- signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = 0;
- signal->theData[3] = wf.pageIndex;
- signal->theData[4] = wf.wordIndex;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
-}//Dbdih::packTableIntoPagesLab()
-
-/*****************************************************************************/
-// execCONTINUEB(ZPACK_FRAG_INTO_PAGES)
-/*****************************************************************************/
-void Dbdih::packFragIntoPagesLab(Signal* signal, RWFragment* wf)
-{
- ndbrequire(wf->pageIndex < 8);
- wf->rwfPageptr.i = wf->rwfTabPtr.p->pageRef[wf->pageIndex];
- ptrCheckGuard(wf->rwfPageptr, cpageFileSize, pageRecord);
- FragmentstorePtr fragPtr;
- getFragstore(wf->rwfTabPtr.p, wf->fragId, fragPtr);
- writeFragment(wf, fragPtr);
- writeReplicas(wf, fragPtr.p->storedReplicas);
- writeReplicas(wf, fragPtr.p->oldStoredReplicas);
- wf->fragId++;
- if (wf->fragId == wf->rwfTabPtr.p->totalfragments) {
- jam();
- PageRecordPtr pagePtr;
- pagePtr.i = wf->rwfTabPtr.p->pageRef[0];
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- pagePtr.p->word[33] = wf->rwfTabPtr.p->noPages;
- pagePtr.p->word[34] = ((wf->rwfTabPtr.p->noPages - 1) * 2048) + wf->wordIndex;
- switch (wf->rwfTabPtr.p->tabCopyStatus) {
- case TabRecord::CS_SR_PHASE2_READ_TABLE:
- /* -------------------------------------------------------------------*/
- // We are performing a system restart and we are now ready to copy the
- // table from this node (the master) to all other nodes.
- /* -------------------------------------------------------------------*/
- jam();
- wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- signal->theData[0] = DihContinueB::ZSR_PHASE2_READ_TABLE;
- signal->theData[1] = wf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::CS_COPY_NODE_STATE:
- jam();
- tableCopyNodeLab(signal, wf->rwfTabPtr);
- return;
- break;
- case TabRecord::CS_LCP_READ_TABLE:
- jam();
- signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
- signal->theData[1] = wf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::CS_REMOVE_NODE:
- case TabRecord::CS_INVALIDATE_NODE_LCP:
- jam();
- signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
- signal->theData[1] = wf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::CS_ADD_TABLE_MASTER:
- jam();
- wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- signal->theData[0] = DihContinueB::ZADD_TABLE_MASTER_PAGES;
- signal->theData[1] = wf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::CS_ADD_TABLE_SLAVE:
- jam();
- wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- signal->theData[0] = DihContinueB::ZADD_TABLE_SLAVE_PAGES;
- signal->theData[1] = wf->rwfTabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- } else {
- jam();
- signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
- signal->theData[1] = wf->rwfTabPtr.i;
- signal->theData[2] = wf->fragId;
- signal->theData[3] = wf->pageIndex;
- signal->theData[4] = wf->wordIndex;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
- }//if
- return;
-}//Dbdih::packFragIntoPagesLab()
-
-/*****************************************************************************/
-/* ********** START FRAGMENT MODULE *************/
-/*****************************************************************************/
-void
-Dbdih::dump_replica_info()
-{
- TabRecordPtr tabPtr;
- FragmentstorePtr fragPtr;
-
- for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
- {
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
- continue;
-
- for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
- {
- getFragstore(tabPtr.p, fid, fragPtr);
- ndbout_c("tab: %d frag: %d gci: %d\n -- storedReplicas:",
- tabPtr.i, fid, SYSFILE->newestRestorableGCI);
-
- Uint32 i;
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = fragPtr.p->storedReplicas;
- for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
- {
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- ndbout_c(" node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
- replicaPtr.p->procNode,
- replicaPtr.p->initialGci,
- replicaPtr.p->nextLcp,
- replicaPtr.p->noCrashedReplicas);
- for(i = 0; i<MAX_LCP_STORED; i++)
- {
- ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
- i,
- (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
- replicaPtr.p->lcpId[i],
- replicaPtr.p->maxGciCompleted[i],
- replicaPtr.p->maxGciStarted[i]);
- }
-
- for (i = 0; i < 8; i++)
- {
- ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
- i,
- replicaPtr.p->replicaLastGci[i],
- replicaPtr.p->createGci[i]);
- }
- }
- ndbout_c(" -- oldStoredReplicas");
- replicaPtr.i = fragPtr.p->oldStoredReplicas;
- for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
- {
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- for(i = 0; i<MAX_LCP_STORED; i++)
- {
- ndbout_c(" i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
- i,
- (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
- replicaPtr.p->lcpId[i],
- replicaPtr.p->maxGciCompleted[i],
- replicaPtr.p->maxGciStarted[i]);
- }
-
- for (i = 0; i < 8; i++)
- {
- ndbout_c(" crashed replica: %d replicaLastGci: %d createGci: %d",
- i,
- replicaPtr.p->replicaLastGci[i],
- replicaPtr.p->createGci[i]);
- }
- }
- }
- }
-}
-
-void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId)
-{
- Uint32 TloopCount = 0;
- TabRecordPtr tabPtr;
- while (true) {
- if (TloopCount > 100) {
- jam();
- signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
- signal->theData[1] = tableId;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
-
- if (tableId >= ctabFileSize) {
- jam();
- signal->theData[0] = DihContinueB::ZCOMPLETE_RESTART;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
- return;
- }//if
-
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
- jam();
- TloopCount++;
- tableId++;
- fragId = 0;
- continue;
- }
-
- if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
- jam();
- TloopCount++;
- tableId++;
- fragId = 0;
- continue;
- }
-
- jam();
- break;
- }//while
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- /* ----------------------------------------------------------------------- */
- /* WE NEED TO RESET THE REPLICA DATA STRUCTURES. THIS MEANS THAT WE */
- /* MUST REMOVE REPLICAS THAT WAS NOT STARTED AT THE GCI TO RESTORE. WE */
- /* NEED TO PUT ALL STORED REPLICAS ON THE LIST OF OLD STORED REPLICAS */
- /* RESET THE NUMBER OF REPLICAS TO CREATE. */
- /* ----------------------------------------------------------------------- */
- cnoOfCreateReplicas = 0;
- /* ----------------------------------------------------------------------- */
- /* WE WILL NEVER START MORE THAN FOUR FRAGMENT REPLICAS WHATEVER THE */
- /* DESIRED REPLICATION IS. */
- /* ----------------------------------------------------------------------- */
- ndbrequire(tabPtr.p->noOfBackups < 4);
- /* ----------------------------------------------------------------------- */
- /* SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM. */
- /* ----------------------------------------------------------------------- */
- searchStoredReplicas(fragPtr);
-
- if (cnoOfCreateReplicas == 0) {
- /* --------------------------------------------------------------------- */
- /* THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
- /* RESTART THE SYSTEM FROM. IN A LATER RELEASE WE WILL ADD */
- /* FUNCTIONALITY TO CHECK IF THERE ARE ANY STANDBY NODES THAT COULD DO */
- /* THIS TASK INSTEAD IN THIS IMPLEMENTATION WE SIMPLY CRASH THE SYSTEM.*/
- /* THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT */
- /* POSSIBLE TO RESTORE THE SYSTEM. */
- /* --------------------------------------------------------------------- */
- char buf[64];
- BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
- tableId, fragId, SYSFILE->newestRestorableGCI);
-
- ndbout_c(buf);
- dump_replica_info();
-
- progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
- ndbrequire(false);
- return;
- }//if
-
- /* ----------------------------------------------------------------------- */
- /* WE HAVE CHANGED THE NODE TO BE PRIMARY REPLICA AND THE NODES TO BE */
- /* BACKUP NODES. WE MUST UPDATE THIS NODES DATA STRUCTURE SINCE WE */
- /* WILL NOT COPY THE TABLE DATA TO OURSELF. */
- /* ----------------------------------------------------------------------- */
- updateNodeInfo(fragPtr);
- /* ----------------------------------------------------------------------- */
- /* NOW WE HAVE COLLECTED ALL THE REPLICAS WE COULD GET. WE WILL NOW */
- /* RESTART THE FRAGMENT REPLICAS WE HAVE FOUND IRRESPECTIVE OF IF THERE*/
- /* ARE ENOUGH ACCORDING TO THE DESIRED REPLICATION. */
- /* ----------------------------------------------------------------------- */
- /* WE START BY SENDING ADD_FRAGREQ FOR THOSE REPLICAS THAT NEED IT. */
- /* ----------------------------------------------------------------------- */
- CreateReplicaRecordPtr createReplicaPtr;
- for (createReplicaPtr.i = 0;
- createReplicaPtr.i < cnoOfCreateReplicas;
- createReplicaPtr.i++) {
- jam();
- ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
- createReplicaPtr.p->hotSpareUse = false;
- }//for
-
- sendStartFragreq(signal, tabPtr, fragId);
-
- /**
- * Don't wait for START_FRAGCONF
- */
- fragId++;
- if (fragId >= tabPtr.p->totalfragments) {
- jam();
- tabPtr.i++;
- fragId = 0;
- }//if
- signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragId;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-
- return;
-}//Dbdih::startFragmentLab()
-
-
-/*****************************************************************************/
-/* ********** COMPLETE RESTART MODULE *************/
-/*****************************************************************************/
-void Dbdih::completeRestartLab(Signal* signal)
-{
- sendLoopMacro(START_RECREQ, sendSTART_RECREQ);
-}//completeRestartLab()
-
-/* ------------------------------------------------------------------------- */
-// SYSTEM RESTART:
-/* A NODE HAS COMPLETED RESTORING ALL DATABASE FRAGMENTS. */
-// NODE RESTART:
-// THE STARTING NODE HAS PREPARED ITS LOG FILES TO ENABLE EXECUTION
-// OF TRANSACTIONS.
-// Precondition:
-// This signal must be received by the master node.
-/* ------------------------------------------------------------------------- */
-void Dbdih::execSTART_RECCONF(Signal* signal)
-{
- jamEntry();
- Uint32 senderNodeId = signal->theData[0];
- ndbrequire(isMaster());
- if (getNodeState().startLevel >= NodeState::SL_STARTED){
- /* --------------------------------------------------------------------- */
- // Since our node is already up and running this must be a node restart.
- // This means that we should be the master node,
- // otherwise we have a problem.
- /* --------------------------------------------------------------------- */
- jam();
- ndbout_c("startNextCopyFragment");
- startNextCopyFragment(signal, findTakeOver(senderNodeId));
- return;
- } else {
- /* --------------------------------------------------------------------- */
- // This was the system restart case. We set the state indicating that the
- // node has completed restoration of all fragments.
- /* --------------------------------------------------------------------- */
- receiveLoopMacro(START_RECREQ, senderNodeId);
-
- signal->theData[0] = reference();
- sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal, 1, JBB);
- return;
- }//if
-}//Dbdih::execSTART_RECCONF()
-
-void Dbdih::copyNodeLab(Signal* signal, Uint32 tableId)
-{
- /* ----------------------------------------------------------------------- */
- // This code is executed by the master to assist a node restart in receiving
- // the data in the master.
- /* ----------------------------------------------------------------------- */
- Uint32 TloopCount = 0;
-
- if (!c_nodeStartMaster.activeState) {
- jam();
- /* --------------------------------------------------------------------- */
- // Obviously the node crashed in the middle of its node restart. We will
- // stop this process simply by returning after resetting the wait indicator.
- /* ---------------------------------------------------------------------- */
- c_nodeStartMaster.wait = ZFALSE;
- return;
- }//if
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- while (tabPtr.i < ctabFileSize) {
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
- /* -------------------------------------------------------------------- */
- // The table is defined. We will start by packing the table into pages.
- // The tabCopyStatus indicates to the CONTINUEB(ZPACK_TABLE_INTO_PAGES)
- // who called it. After packing the table into page(s) it will be sent to
- // the starting node by COPY_TABREQ signals. After returning from the
- // starting node we will return to this subroutine and continue
- // with the next table.
- /* -------------------------------------------------------------------- */
- ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
- tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_NODE_STATE;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- if (TloopCount > 100) {
- /* ------------------------------------------------------------------ */
- // Introduce real-time break after looping through 100 not copied tables
- /* ----------------------------------------------------------------- */
- jam();
- signal->theData[0] = DihContinueB::ZCOPY_NODE;
- signal->theData[1] = tabPtr.i + 1;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- TloopCount++;
- tabPtr.i++;
- }//if
- }//if
- }//while
- dihCopyCompletedLab(signal);
- return;
-}//Dbdih::copyNodeLab()
-
-void Dbdih::tableCopyNodeLab(Signal* signal, TabRecordPtr tabPtr)
-{
- /* ----------------------------------------------------------------------- */
- /* COPY PAGES READ TO STARTING NODE. */
- /* ----------------------------------------------------------------------- */
- if (!c_nodeStartMaster.activeState) {
- jam();
- releaseTabPages(tabPtr.i);
- c_nodeStartMaster.wait = ZFALSE;
- return;
- }//if
- NodeRecordPtr copyNodePtr;
- PageRecordPtr pagePtr;
- copyNodePtr.i = c_nodeStartMaster.startNode;
- ptrCheckGuard(copyNodePtr, MAX_NDB_NODES, nodeRecord);
-
- copyNodePtr.p->activeTabptr = tabPtr.i;
- pagePtr.i = tabPtr.p->pageRef[0];
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
-
- signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = copyNodePtr.i;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- signal->theData[5] = pagePtr.p->word[34];
- sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
-}//Dbdih::tableCopyNodeLab()
-
-/* ------------------------------------------------------------------------- */
-// execCONTINUEB(ZCOPY_TABLE)
-// This routine is used to copy the table descriptions from the master to
-// other nodes. It is used in the system restart to copy from master to all
-// starting nodes.
-/* ------------------------------------------------------------------------- */
-void Dbdih::copyTableLab(Signal* signal, Uint32 tableId)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrAss(tabPtr, tabRecord);
-
- ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
- tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE2_READ_TABLE;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dbdih::copyTableLab()
-
-/* ------------------------------------------------------------------------- */
-// execCONTINUEB(ZSR_PHASE2_READ_TABLE)
-/* ------------------------------------------------------------------------- */
-void Dbdih::srPhase2ReadTableLab(Signal* signal, TabRecordPtr tabPtr)
-{
- /* ----------------------------------------------------------------------- */
- // We set the sendCOPY_TABREQState to ZACTIVE for all nodes since it is a long
- // process to send off all table descriptions. Thus we ensure that we do
- // not encounter race conditions where one node is completed before the
- // sending process is completed. This could lead to that we start off the
- // system before we actually finished all copying of table descriptions
- // and could lead to strange errors.
- /* ----------------------------------------------------------------------- */
-
- //sendLoopMacro(COPY_TABREQ, nullRoutine);
-
- breakCopyTableLab(signal, tabPtr, cfirstAliveNode);
- return;
-}//Dbdih::srPhase2ReadTableLab()
-
-/* ------------------------------------------------------------------------- */
-/* COPY PAGES READ TO ALL NODES. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::breakCopyTableLab(Signal* signal, TabRecordPtr tabPtr, Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- while (nodePtr.i != RNIL) {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.i == getOwnNodeId()){
- jam();
- /* ------------------------------------------------------------------- */
- /* NOT NECESSARY TO COPY TO MY OWN NODE. I ALREADY HAVE THE PAGES. */
- /* I DO HOWEVER NEED TO STORE THE TABLE DESCRIPTION ONTO DISK. */
- /* ------------------------------------------------------------------- */
- /* IF WE ARE MASTER WE ONLY NEED TO SAVE THE TABLE ON DISK. WE ALREADY */
- /* HAVE THE TABLE DESCRIPTION IN THE DATA STRUCTURES. */
- // AFTER COMPLETING THE WRITE TO DISK THE MASTER WILL ALSO SEND
- // COPY_TABCONF AS ALL THE OTHER NODES.
- /* ------------------------------------------------------------------- */
- c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
- tabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
- signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- nodePtr.i = nodePtr.p->nextNode;
- } else {
- PageRecordPtr pagePtr;
- /* -------------------------------------------------------------------- */
- // RATHER THAN SENDING ALL COPY_TABREQ IN PARALLEL WE WILL SERIALISE THIS
- // ACTIVITY AND WILL THUS CALL breakCopyTableLab AGAIN WHEN COMPLETED THE
- // SENDING OF COPY_TABREQ'S.
- /* -------------------------------------------------------------------- */
- jam();
- tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE3_COPY_TABLE;
- pagePtr.i = tabPtr.p->pageRef[0];
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = nodePtr.i;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- signal->theData[5] = pagePtr.p->word[34];
- sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
- return;
- }//if
- }//while
- /* ----------------------------------------------------------------------- */
- /* WE HAVE NOW SENT THE TABLE PAGES TO ALL NODES. EXIT AND WAIT FOR ALL */
- /* REPLIES. */
- /* ----------------------------------------------------------------------- */
- return;
-}//Dbdih::breakCopyTableLab()
-
-/* ------------------------------------------------------------------------- */
-// execCONTINUEB(ZCOPY_TABLE_NODE)
-/* ------------------------------------------------------------------------- */
-void Dbdih::copyTableNode(Signal* signal,
- CopyTableNode* ctn, NodeRecordPtr nodePtr)
-{
- if (getNodeState().startLevel >= NodeState::SL_STARTED){
- /* --------------------------------------------------------------------- */
- // We are in the process of performing a node restart and are copying a
- // table description to a starting node. We will check that no nodes have
- // crashed in this process.
- /* --------------------------------------------------------------------- */
- if (!c_nodeStartMaster.activeState) {
- jam();
- /** ------------------------------------------------------------------
- * The starting node crashed. We will release table pages and stop this
- * copy process and allow new node restarts to start.
- * ------------------------------------------------------------------ */
- releaseTabPages(ctn->ctnTabPtr.i);
- c_nodeStartMaster.wait = ZFALSE;
- return;
- }//if
- }//if
- ndbrequire(ctn->pageIndex < 8);
- ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
- ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
- /**
- * If first page & firstWord reqinfo = 1 (first signal)
- */
- Uint32 reqinfo = (ctn->pageIndex == 0) && (ctn->wordIndex == 0);
- if(reqinfo == 1){
- c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
- }
-
- for (Uint32 i = 0; i < 16; i++) {
- jam();
- sendCopyTable(signal, ctn, calcDihBlockRef(nodePtr.i), reqinfo);
- reqinfo = 0;
- if (ctn->noOfWords <= 16) {
- jam();
- switch (ctn->ctnTabPtr.p->tabCopyStatus) {
- case TabRecord::CS_SR_PHASE3_COPY_TABLE:
- /* ------------------------------------------------------------------ */
- // We have copied the table description to this node.
- // We will now proceed
- // with sending the table description to the next node in the node list.
- /* ------------------------------------------------------------------ */
- jam();
- ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- breakCopyTableLab(signal, ctn->ctnTabPtr, nodePtr.p->nextNode);
- return;
- break;
- case TabRecord::CS_COPY_NODE_STATE:
- jam();
- ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- } else {
- jam();
- ctn->wordIndex += 16;
- if (ctn->wordIndex == 2048) {
- jam();
- ctn->wordIndex = 0;
- ctn->pageIndex++;
- ndbrequire(ctn->pageIndex < 8);
- ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
- ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
- }//if
- ctn->noOfWords -= 16;
- }//if
- }//for
- signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
- signal->theData[1] = ctn->ctnTabPtr.i;
- signal->theData[2] = nodePtr.i;
- signal->theData[3] = ctn->pageIndex;
- signal->theData[4] = ctn->wordIndex;
- signal->theData[5] = ctn->noOfWords;
- sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
-}//Dbdih::copyTableNodeLab()
-
-void Dbdih::sendCopyTable(Signal* signal, CopyTableNode* ctn,
- BlockReference ref, Uint32 reqinfo)
-{
- signal->theData[0] = reference();
- signal->theData[1] = reqinfo;
- signal->theData[2] = ctn->ctnTabPtr.i;
- signal->theData[3] = ctn->ctnTabPtr.p->schemaVersion;
- signal->theData[4] = ctn->noOfWords;
- ndbrequire(ctn->wordIndex + 15 < 2048);
- MEMCOPY_NO_WORDS(&signal->theData[5], &ctn->ctnPageptr.p->word[ctn->wordIndex], 16);
- sendSignal(ref, GSN_COPY_TABREQ, signal, 21, JBB);
-}//Dbdih::sendCopyTable()
-
-void Dbdih::execCOPY_TABCONF(Signal* signal)
-{
- NodeRecordPtr nodePtr;
- jamEntry();
- nodePtr.i = signal->theData[0];
- Uint32 tableId = signal->theData[1];
- if (getNodeState().startLevel >= NodeState::SL_STARTED){
- /* --------------------------------------------------------------------- */
- // We are in the process of performing a node restart. Continue by copying
- // the next table to the starting node.
- /* --------------------------------------------------------------------- */
- jam();
- NodeRecordPtr nodePtr;
- nodePtr.i = signal->theData[0];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- c_COPY_TABREQ_Counter.clearWaitingFor(nodePtr.i);
-
- releaseTabPages(tableId);
- signal->theData[0] = DihContinueB::ZCOPY_NODE;
- signal->theData[1] = tableId + 1;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- /* --------------------------------------------------------------------- */
- // We are in the process of performing a system restart. Check if all nodes
- // have saved the new table description to file and then continue with the
- // next table.
- /* --------------------------------------------------------------------- */
- receiveLoopMacro(COPY_TABREQ, nodePtr.i);
- /* --------------------------------------------------------------------- */
- /* WE HAVE NOW COPIED TO ALL NODES. WE HAVE NOW COMPLETED RESTORING */
- /* THIS TABLE. CONTINUE WITH THE NEXT TABLE. */
- /* WE NEED TO RELEASE THE PAGES IN THE TABLE IN THIS NODE HERE. */
- /* WE ALSO NEED TO CLOSE THE TABLE FILE. */
- /* --------------------------------------------------------------------- */
- releaseTabPages(tableId);
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- ConnectRecordPtr connectPtr;
- connectPtr.i = tabPtr.p->connectrec;
- ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
-
- sendAddFragreq(signal, connectPtr, tabPtr, 0);
- return;
- }//if
-}//Dbdih::execCOPY_TABCONF()
-
-/*
- 3.13 L O C A L C H E C K P O I N T (M A S T E R)
- ****************************************************
- */
-/*****************************************************************************/
-/* ********** LOCAL-CHECK-POINT-HANDLING MODULE *************/
-/*****************************************************************************/
-/* ------------------------------------------------------------------------- */
-/* IT IS TIME TO CHECK IF IT IS TIME TO START A LOCAL CHECKPOINT. */
-/* WE WILL EITHER START AFTER 1 MILLION WORDS HAVE ARRIVED OR WE WILL */
-/* EXECUTE AFTER ABOUT 16 MINUTES HAVE PASSED BY. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::checkTcCounterLab(Signal* signal)
-{
- CRASH_INSERTION(7009);
- if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
- g_eventLogger.error("lcpStatus = %u"
- "lcpStatusUpdatedPlace = %d",
- (Uint32) c_lcpState.lcpStatus,
- c_lcpState.lcpStatusUpdatedPlace);
- ndbrequire(false);
- return;
- }//if
- c_lcpState.ctimer += 32;
- if ((c_nodeStartMaster.blockLcp == true) ||
- (c_lcpState.lcpStopGcp >= c_newest_restorable_gci)) {
- jam();
- /* --------------------------------------------------------------------- */
- // No reason to start juggling the states and checking for start of LCP if
- // we are blocked to start an LCP anyway.
- // We also block LCP start if we have not completed one global checkpoints
- // before starting another local checkpoint.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
- signal->theData[1] = __LINE__;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
- return;
- }//if
- c_lcpState.setLcpStatus(LCP_TCGET, __LINE__);
-
- c_lcpState.ctcCounter = c_lcpState.ctimer;
- sendLoopMacro(TCGETOPSIZEREQ, sendTCGETOPSIZEREQ);
-}//Dbdih::checkTcCounterLab()
-
-void Dbdih::checkLcpStart(Signal* signal, Uint32 lineNo)
-{
- /* ----------------------------------------------------------------------- */
- // Verify that we are not attempting to start another instance of the LCP
- // when it is not alright to do so.
- /* ----------------------------------------------------------------------- */
- ndbrequire(c_lcpState.lcpStart == ZIDLE);
- c_lcpState.lcpStart = ZACTIVE;
- signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
- signal->theData[1] = lineNo;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
-}//Dbdih::checkLcpStart()
-
-/* ------------------------------------------------------------------------- */
-/*TCGETOPSIZECONF HOW MUCH OPERATION SIZE HAVE BEEN EXECUTED BY TC */
-/* ------------------------------------------------------------------------- */
-void Dbdih::execTCGETOPSIZECONF(Signal* signal)
-{
- jamEntry();
- Uint32 senderNodeId = signal->theData[0];
- c_lcpState.ctcCounter += signal->theData[1];
-
- receiveLoopMacro(TCGETOPSIZEREQ, senderNodeId);
-
- ndbrequire(c_lcpState.lcpStatus == LCP_TCGET);
- ndbrequire(c_lcpState.lcpStart == ZACTIVE);
- /* ----------------------------------------------------------------------- */
- // We are not actively starting another LCP, still we receive this signal.
- // This is not ok.
- /* ---------------------------------------------------------------------- */
- /* ALL TC'S HAVE RESPONDED NOW. NOW WE WILL CHECK IF ENOUGH OPERATIONS */
- /* HAVE EXECUTED TO ENABLE US TO START A NEW LOCAL CHECKPOINT. */
- /* WHILE COPYING DICTIONARY AND DISTRIBUTION INFO TO A STARTING NODE */
- /* WE WILL ALSO NOT ALLOW THE LOCAL CHECKPOINT TO PROCEED. */
- /*----------------------------------------------------------------------- */
- if (c_lcpState.immediateLcpStart == false) {
- if ((c_lcpState.ctcCounter <
- ((Uint32)1 << c_lcpState.clcpDelay)) ||
- (c_nodeStartMaster.blockLcp == true)) {
- jam();
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
-
- signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
- signal->theData[1] = __LINE__;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
- return;
- }//if
- }//if
- c_lcpState.lcpStart = ZIDLE;
- c_lcpState.immediateLcpStart = false;
- /* -----------------------------------------------------------------------
- * Now the initial lcp is started,
- * we can reset the delay to its orginal value
- * --------------------------------------------------------------------- */
- CRASH_INSERTION(7010);
- /* ----------------------------------------------------------------------- */
- /* IF MORE THAN 1 MILLION WORDS PASSED THROUGH THE TC'S THEN WE WILL */
- /* START A NEW LOCAL CHECKPOINT. CLEAR CTIMER. START CHECKPOINT */
- /* ACTIVITY BY CALCULATING THE KEEP GLOBAL CHECKPOINT. */
- // Also remember the current global checkpoint to ensure that we run at least
- // one global checkpoints between each local checkpoint that we start up.
- /* ----------------------------------------------------------------------- */
- c_lcpState.ctimer = 0;
- c_lcpState.keepGci = coldgcp;
- /* ----------------------------------------------------------------------- */
- /* UPDATE THE NEW LATEST LOCAL CHECKPOINT ID. */
- /* ----------------------------------------------------------------------- */
- cnoOfActiveTables = 0;
- c_lcpState.setLcpStatus(LCP_CALCULATE_KEEP_GCI, __LINE__);
- c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
- ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
-
- if (ERROR_INSERTED(7011)) {
- signal->theData[0] = NDB_LE_LCPStoppedInCalcKeepGci;
- signal->theData[1] = 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- return;
- }//if
- signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
- signal->theData[1] = 0; /* TABLE ID = 0 */
- signal->theData[2] = 0; /* FRAGMENT ID = 0 */
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
-}//Dbdih::execTCGETOPSIZECONF()
-
-/* ------------------------------------------------------------------------- */
-/* WE NEED TO CALCULATE THE OLDEST GLOBAL CHECKPOINT THAT WILL BE */
-/* COMPLETELY RESTORABLE AFTER EXECUTING THIS LOCAL CHECKPOINT. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId)
-{
- TabRecordPtr tabPtr;
- Uint32 TloopCount = 1;
- tabPtr.i = tableId;
- do {
- if (tabPtr.i >= ctabFileSize) {
- if (cnoOfActiveTables > 0) {
- jam();
- signal->theData[0] = DihContinueB::ZSTORE_NEW_LCP_ID;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
- return;
- } else {
- jam();
- /* ------------------------------------------------------------------ */
- /* THERE ARE NO TABLES TO CHECKPOINT. WE STOP THE CHECKPOINT ALREADY */
- /* HERE TO AVOID STRANGE PROBLEMS LATER. */
- /* ------------------------------------------------------------------ */
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- checkLcpStart(signal, __LINE__);
- return;
- }//if
- }//if
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
- tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
- if (TloopCount > 100) {
- jam();
- signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
- signal->theData[1] = tabPtr.i + 1;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- } else {
- jam();
- TloopCount++;
- tabPtr.i++;
- }//if
- } else {
- jam();
- TloopCount = 0;
- }//if
- } while (TloopCount != 0);
- cnoOfActiveTables++;
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->storedReplicas);
- checkKeepGci(tabPtr, fragId, fragPtr.p, fragPtr.p->oldStoredReplicas);
- fragId++;
- if (fragId >= tabPtr.p->totalfragments) {
- jam();
- tabPtr.i++;
- fragId = 0;
- }//if
- signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragId;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
-}//Dbdih::calculateKeepGciLab()
-
-/* ------------------------------------------------------------------------- */
-/* WE NEED TO STORE ON DISK THE FACT THAT WE ARE STARTING THIS LOCAL */
-/* CHECKPOINT ROUND. THIS WILL INVALIDATE ALL THE LOCAL CHECKPOINTS */
-/* THAT WILL EVENTUALLY BE OVERWRITTEN AS PART OF THIS LOCAL CHECKPOINT*/
-/* ------------------------------------------------------------------------- */
-void Dbdih::storeNewLcpIdLab(Signal* signal)
-{
- /***************************************************************************/
- // Report the event that a local checkpoint has started.
- /***************************************************************************/
- signal->theData[0] = NDB_LE_LocalCheckpointStarted; //Event type
- signal->theData[1] = SYSFILE->latestLCP_ID + 1;
- signal->theData[2] = c_lcpState.keepGci;
- signal->theData[3] = c_lcpState.oldestRestorableGci;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- signal->setTrace(TestOrd::TraceLocalCheckpoint);
-
- CRASH_INSERTION(7013);
- SYSFILE->keepGCI = c_lcpState.keepGci;
- //Uint32 lcpId = SYSFILE->latestLCP_ID;
- SYSFILE->latestLCP_ID++;
- SYSFILE->oldestRestorableGCI = c_lcpState.oldestRestorableGci;
-
- const Uint32 oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
- //const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
- //ndbrequire(newestRestorableGCI >= oldestRestorableGCI);
-
- Int32 val = oldestRestorableGCI;
- ndbrequire(val > 0);
-
- /* ----------------------------------------------------------------------- */
- /* SET BIT INDICATING THAT LOCAL CHECKPOINT IS ONGOING. THIS IS CLEARED */
- /* AT THE END OF A LOCAL CHECKPOINT. */
- /* ----------------------------------------------------------------------- */
- SYSFILE->setLCPOngoing(SYSFILE->systemRestartBits);
- /* ---------------------------------------------------------------------- */
- /* CHECK IF ANY NODE MUST BE TAKEN OUT OF SERVICE AND REFILLED WITH */
- /* NEW FRESH DATA FROM AN ACTIVE NODE. */
- /* ---------------------------------------------------------------------- */
- setLcpActiveStatusStart(signal);
- c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
- //#ifdef VM_TRACE
- // infoEvent("LocalCheckpoint %d started", SYSFILE->latestLCP_ID);
- // signal->theData[0] = 7012;
- // execDUMP_STATE_ORD(signal);
- //#endif
-
- copyGciLab(signal, CopyGCIReq::LOCAL_CHECKPOINT);
-}//Dbdih::storeNewLcpIdLab()
-
-void Dbdih::startLcpRoundLab(Signal* signal) {
- jam();
-
- Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
- Callback c = { safe_cast(&Dbdih::startLcpMutex_locked), 0 };
- ndbrequire(mutex.lock(c));
-}
-
-void
-Dbdih::startLcpMutex_locked(Signal* signal, Uint32 senderData, Uint32 retVal){
- jamEntry();
- ndbrequire(retVal == 0);
-
- StartLcpReq* req = (StartLcpReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->lcpId = SYSFILE->latestLCP_ID;
- req->participatingLQH = c_lcpState.m_participatingLQH;
- req->participatingDIH = c_lcpState.m_participatingDIH;
- sendLoopMacro(START_LCP_REQ, sendSTART_LCP_REQ);
-}
-void
-Dbdih::sendSTART_LCP_REQ(Signal* signal, Uint32 nodeId){
- BlockReference ref = calcDihBlockRef(nodeId);
- sendSignal(ref, GSN_START_LCP_REQ, signal, StartLcpReq::SignalLength, JBB);
-}
-
-void
-Dbdih::execSTART_LCP_CONF(Signal* signal){
- StartLcpConf * conf = (StartLcpConf*)signal->getDataPtr();
-
- Uint32 nodeId = refToNode(conf->senderRef);
- receiveLoopMacro(START_LCP_REQ, nodeId);
-
- Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
- Callback c = { safe_cast(&Dbdih::startLcpMutex_unlocked), 0 };
- mutex.unlock(c);
-}
-
-void
-Dbdih::startLcpMutex_unlocked(Signal* signal, Uint32 data, Uint32 retVal){
- jamEntry();
- ndbrequire(retVal == 0);
-
- Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
- mutex.release();
-
- CRASH_INSERTION(7014);
- c_lcpState.setLcpStatus(LCP_TC_CLOPSIZE, __LINE__);
- sendLoopMacro(TC_CLOPSIZEREQ, sendTC_CLOPSIZEREQ);
-}
-
-void Dbdih::execTC_CLOPSIZECONF(Signal* signal) {
- jamEntry();
- Uint32 senderNodeId = signal->theData[0];
- receiveLoopMacro(TC_CLOPSIZEREQ, senderNodeId);
-
- ndbrequire(c_lcpState.lcpStatus == LCP_TC_CLOPSIZE);
- /* ----------------------------------------------------------------------- */
- /* ALL TC'S HAVE CLEARED THEIR OPERATION SIZE COUNTERS. NOW PROCEED BY */
- /* STARTING THE LOCAL CHECKPOINT IN EACH LQH. */
- /* ----------------------------------------------------------------------- */
- c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_participatingLQH;
-
- CRASH_INSERTION(7015);
- c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
- startLcpRoundLoopLab(signal, 0, 0);
-}//Dbdih::execTC_CLOPSIZECONF()
-
-void Dbdih::startLcpRoundLoopLab(Signal* signal,
- Uint32 startTableId, Uint32 startFragId)
-{
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- ndbrequire(nodePtr.p->noOfStartedChkpt == 0);
- ndbrequire(nodePtr.p->noOfQueuedChkpt == 0);
- }//if
- }//if
- c_lcpState.currentFragment.tableId = startTableId;
- c_lcpState.currentFragment.fragmentId = startFragId;
- startNextChkpt(signal);
-}//Dbdih::startLcpRoundLoopLab()
-
-void Dbdih::startNextChkpt(Signal* signal)
-{
- Uint32 lcpId = SYSFILE->latestLCP_ID;
-
- NdbNodeBitmask busyNodes;
- busyNodes.clear();
- const Uint32 lcpNodes = c_lcpState.m_participatingLQH.count();
-
- bool save = true;
- LcpState::CurrentFragment curr = c_lcpState.currentFragment;
-
- while (curr.tableId < ctabFileSize) {
- TabRecordPtr tabPtr;
- tabPtr.i = curr.tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if ((tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) ||
- (tabPtr.p->tabLcpStatus != TabRecord::TLS_ACTIVE)) {
- curr.tableId++;
- curr.fragmentId = 0;
- continue;
- }//if
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, curr.fragmentId, fragPtr);
-
- ReplicaRecordPtr replicaPtr;
- for(replicaPtr.i = fragPtr.p->storedReplicas;
- replicaPtr.i != RNIL ;
- replicaPtr.i = replicaPtr.p->nextReplica){
-
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
-
- NodeRecordPtr nodePtr;
- nodePtr.i = replicaPtr.p->procNode;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- if (c_lcpState.m_participatingLQH.get(nodePtr.i))
- {
- if (replicaPtr.p->lcpOngoingFlag &&
- replicaPtr.p->lcpIdStarted < lcpId)
- {
- jam();
- //-------------------------------------------------------------------
- // We have found a replica on a node that performs local checkpoint
- // that is alive and that have not yet been started.
- //-------------------------------------------------------------------
-
- if (nodePtr.p->noOfStartedChkpt < 2)
- {
- jam();
- /**
- * Send LCP_FRAG_ORD to LQH
- */
-
- /**
- * Mark the replica so with lcpIdStarted == true
- */
- replicaPtr.p->lcpIdStarted = lcpId;
-
- Uint32 i = nodePtr.p->noOfStartedChkpt;
- nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
- nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
- nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
- nodePtr.p->noOfStartedChkpt = i + 1;
-
- sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
- }
- else if (nodePtr.p->noOfQueuedChkpt < 2)
- {
- jam();
- /**
- * Put LCP_FRAG_ORD "in queue"
- */
-
- /**
- * Mark the replica so with lcpIdStarted == true
- */
- replicaPtr.p->lcpIdStarted = lcpId;
-
- Uint32 i = nodePtr.p->noOfQueuedChkpt;
- nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
- nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
- nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
- nodePtr.p->noOfQueuedChkpt = i + 1;
- }
- else
- {
- jam();
-
- if(save)
- {
- /**
- * Stop increasing value on first that was "full"
- */
- c_lcpState.currentFragment = curr;
- save = false;
- }
-
- busyNodes.set(nodePtr.i);
- if(busyNodes.count() == lcpNodes)
- {
- /**
- * There were no possibility to start the local checkpoint
- * and it was not possible to queue it up. In this case we
- * stop the start of local checkpoints until the nodes with a
- * backlog have performed more checkpoints. We will return and
- * will not continue the process of starting any more checkpoints.
- */
- return;
- }//if
- }//if
- }
- }//while
- }
- curr.fragmentId++;
- if (curr.fragmentId >= tabPtr.p->totalfragments) {
- jam();
- curr.fragmentId = 0;
- curr.tableId++;
- }//if
- }//while
-
- sendLastLCP_FRAG_ORD(signal);
-}//Dbdih::startNextChkpt()
-
-void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
-{
- LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
- lcpFragOrd->tableId = RNIL;
- lcpFragOrd->fragmentId = 0;
- lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
- lcpFragOrd->lcpNo = 0;
- lcpFragOrd->keepGci = c_lcpState.keepGci;
- lcpFragOrd->lastFragmentFlag = true;
-
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
-
- if(nodePtr.p->noOfQueuedChkpt == 0 &&
- nodePtr.p->noOfStartedChkpt == 0 &&
- c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodePtr.i)){
- jam();
-
- CRASH_INSERTION(7028);
-
- /**
- * Nothing queued or started <=> Complete on that node
- *
- */
- c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodePtr.i);
- if(ERROR_INSERTED(7075)){
- continue;
- }
-
- CRASH_INSERTION(7193);
- BlockReference ref = calcLqhBlockRef(nodePtr.i);
- sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
- }
- }
- if(ERROR_INSERTED(7075)){
- if(c_lcpState.m_LAST_LCP_FRAG_ORD.done())
- CRASH_INSERTION(7075);
- }
-}//Dbdih::sendLastLCP_FRAGORD()
-
-/* ------------------------------------------------------------------------- */
-/* A FRAGMENT REPLICA HAS COMPLETED EXECUTING ITS LOCAL CHECKPOINT. */
-/* CHECK IF ALL REPLICAS IN THE TABLE HAVE COMPLETED. IF SO STORE THE */
-/* THE TABLE DISTRIBUTION ON DISK. ALSO SEND LCP_REPORT TO ALL OTHER */
-/* NODES SO THAT THEY CAN STORE THE TABLE ONTO DISK AS WELL. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::execLCP_FRAG_REP(Signal* signal)
-{
- jamEntry();
- ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
-
-#if 0
- printLCP_FRAG_REP(stdout,
- signal->getDataPtr(),
- signal->length(), number());
-#endif
-
- LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
- Uint32 nodeId = lcpReport->nodeId;
- Uint32 tableId = lcpReport->tableId;
- Uint32 fragId = lcpReport->fragId;
-
- jamEntry();
-
- if (ERROR_INSERTED(7178) && nodeId != getOwnNodeId())
- {
- jam();
- Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
- Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
- if (owng == nodeg)
- {
- jam();
- ndbout_c("throwing away LCP_FRAG_REP from (and killing) %d", nodeId);
- SET_ERROR_INSERT_VALUE(7179);
- signal->theData[0] = 9999;
- sendSignal(numberToRef(CMVMI, nodeId),
- GSN_NDB_TAMPER, signal, 1, JBA);
- return;
- }
- }
-
- if (ERROR_INSERTED(7179) && nodeId != getOwnNodeId())
- {
- jam();
- Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
- Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
- if (owng == nodeg)
- {
- jam();
- ndbout_c("throwing away LCP_FRAG_REP from %d", nodeId);
- return;
- }
- }
-
- CRASH_INSERTION2(7025, isMaster());
- CRASH_INSERTION2(7016, !isMaster());
-
- bool fromTimeQueue = (signal->senderBlockRef() == reference());
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if(tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
- jam();
- /*-----------------------------------------------------------------------*/
- // If the table is currently copied to disk we also
- // stop already here to avoid strange half-way updates
- // of the table data structures.
- /*-----------------------------------------------------------------------*/
- /*
- We need to send this signal without a delay since we have discovered
- that we have run out of space in the short time queue. This problem
- is very erunlikely to happen but it has and it results in a node crash.
- This should be considered a "quick fix" and not a permanent solution.
- A cleaner/better way would be to check the time queue if it is full or
- not before sending this signal.
- */
- sendSignal(reference(), GSN_LCP_FRAG_REP, signal, signal->length(), JBB);
- /* Kept here for reference
- sendSignalWithDelay(reference(), GSN_LCP_FRAG_REP,
- signal, 20, signal->length());
- */
-
- if(!fromTimeQueue){
- c_lcpState.noOfLcpFragRepOutstanding++;
- }
-
- return;
- }//if
-
- if(fromTimeQueue){
- jam();
-
- ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
- c_lcpState.noOfLcpFragRepOutstanding--;
- }
-
- bool tableDone = reportLcpCompletion(lcpReport);
-
- Uint32 started = lcpReport->maxGciStarted;
- Uint32 completed = lcpReport->maxGciCompleted;
-
- if (started > c_lcpState.lcpStopGcp)
- {
- jam();
- c_lcpState.lcpStopGcp = started;
- }
-
- if(tableDone){
- jam();
-
- if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
- jam();
- g_eventLogger.info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
- tableId, fragId);
- } else {
- jam();
- /**
- * Write table description to file
- */
- tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
- tabPtr.p->tabCopyStatus = TabRecord::CS_LCP_READ_TABLE;
- tabPtr.p->tabUpdateState = TabRecord::US_LOCAL_CHECKPOINT;
- signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-
- checkLcpAllTablesDoneInLqh();
- }
- }
-
-#ifdef VM_TRACE
- /* --------------------------------------------------------------------- */
- // REPORT that local checkpoint have completed this fragment.
- /* --------------------------------------------------------------------- */
- signal->theData[0] = NDB_LE_LCPFragmentCompleted;
- signal->theData[1] = nodeId;
- signal->theData[2] = tableId;
- signal->theData[3] = fragId;
- signal->theData[4] = started;
- signal->theData[5] = completed;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
-#endif
-
- bool ok = false;
- switch(c_lcpMasterTakeOverState.state){
- case LMTOS_IDLE:
- ok = true;
- jam();
- /**
- * Fall through
- */
- break;
- case LMTOS_WAIT_EMPTY_LCP: // LCP Take over waiting for EMPTY_LCPCONF
- jam();
- return;
- case LMTOS_WAIT_LCP_FRAG_REP:
- jam();
- checkEmptyLcpComplete(signal);
- return;
- case LMTOS_INITIAL:
- case LMTOS_ALL_IDLE:
- case LMTOS_ALL_ACTIVE:
- case LMTOS_LCP_CONCLUDING:
- case LMTOS_COPY_ONGOING:
- ndbrequire(false);
- }
- ndbrequire(ok);
-
- /* ----------------------------------------------------------------------- */
- // Check if there are more LCP's to start up.
- /* ----------------------------------------------------------------------- */
- if(isMaster()){
- jam();
-
- /**
- * Remove from "running" array
- */
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- const Uint32 outstanding = nodePtr.p->noOfStartedChkpt;
- ndbrequire(outstanding > 0);
- if(nodePtr.p->startedChkpt[0].tableId != tableId ||
- nodePtr.p->startedChkpt[0].fragId != fragId){
- jam();
- ndbrequire(outstanding > 1);
- ndbrequire(nodePtr.p->startedChkpt[1].tableId == tableId);
- ndbrequire(nodePtr.p->startedChkpt[1].fragId == fragId);
- } else {
- jam();
- nodePtr.p->startedChkpt[0] = nodePtr.p->startedChkpt[1];
- }
- nodePtr.p->noOfStartedChkpt--;
- checkStartMoreLcp(signal, nodeId);
- }
-}
-
-bool
-Dbdih::checkLcpAllTablesDoneInLqh(){
- TabRecordPtr tabPtr;
-
- /**
- * Check if finished with all tables
- */
- for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
- jam();
- ptrAss(tabPtr, tabRecord);
- if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
- (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE)) {
- jam();
- /**
- * Nope, not finished with all tables
- */
- return false;
- }//if
- }//for
-
- CRASH_INSERTION2(7026, isMaster());
- CRASH_INSERTION2(7017, !isMaster());
-
- c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__);
-
- if (ERROR_INSERTED(7194))
- {
- ndbout_c("CLEARING 7194");
- CLEAR_ERROR_INSERT_VALUE;
- }
-
- return true;
-}
-
-void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr,
- Fragmentstore* fragPtrP,
- Uint32 nodeId,
- bool old)
-{
- replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
- while(replicaPtr.i != RNIL){
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if (replicaPtr.p->procNode == nodeId) {
- jam();
- return;
- } else {
- jam();
- replicaPtr.i = replicaPtr.p->nextReplica;
- }//if
- };
-
-#ifdef VM_TRACE
- g_eventLogger.info("Fragment Replica(node=%d) not found", nodeId);
- replicaPtr.i = fragPtrP->oldStoredReplicas;
- while(replicaPtr.i != RNIL){
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- if (replicaPtr.p->procNode == nodeId) {
- jam();
- break;
- } else {
- jam();
- replicaPtr.i = replicaPtr.p->nextReplica;
- }//if
- };
- if(replicaPtr.i != RNIL){
- g_eventLogger.info("...But was found in oldStoredReplicas");
- } else {
- g_eventLogger.info("...And wasn't found in oldStoredReplicas");
- }
-#endif
- ndbrequire(false);
-}//Dbdih::findReplica()
-
-
-int
-Dbdih::handle_invalid_lcp_no(const LcpFragRep* rep,
- ReplicaRecordPtr replicaPtr)
-{
- ndbrequire(!isMaster());
- Uint32 lcpNo = rep->lcpNo;
- Uint32 lcpId = rep->lcpId;
-
- warningEvent("Detected previous node failure of %d during lcp",
- rep->nodeId);
- replicaPtr.p->nextLcp = lcpNo;
- replicaPtr.p->lcpId[lcpNo] = 0;
- replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
-
- for (Uint32 i = lcpNo; i != lcpNo; i = nextLcpNo(i))
- {
- jam();
- if (replicaPtr.p->lcpStatus[i] == ZVALID &&
- replicaPtr.p->lcpId[i] >= lcpId)
- {
- ndbout_c("i: %d lcpId: %d", i, replicaPtr.p->lcpId[i]);
- ndbrequire(false);
- }
- }
-
- return 0;
-}
-
-/**
- * Return true if table is all fragment replicas have been checkpointed
- * to disk (in all LQHs)
- * false otherwise
- */
-bool
-Dbdih::reportLcpCompletion(const LcpFragRep* lcpReport)
-{
- Uint32 lcpNo = lcpReport->lcpNo;
- Uint32 lcpId = lcpReport->lcpId;
- Uint32 maxGciStarted = lcpReport->maxGciStarted;
- Uint32 maxGciCompleted = lcpReport->maxGciCompleted;
- Uint32 tableId = lcpReport->tableId;
- Uint32 fragId = lcpReport->fragId;
- Uint32 nodeId = lcpReport->nodeId;
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
-
- ReplicaRecordPtr replicaPtr;
- findReplica(replicaPtr, fragPtr.p, nodeId);
-
- ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
- if(lcpNo != replicaPtr.p->nextLcp){
- if (handle_invalid_lcp_no(lcpReport, replicaPtr))
- {
- g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d",
- lcpNo, replicaPtr.p->nextLcp);
- ndbrequire(false);
- }
- }
- ndbrequire(lcpNo == replicaPtr.p->nextLcp);
- ndbrequire(lcpNo < MAX_LCP_STORED);
- ndbrequire(replicaPtr.p->lcpId[lcpNo] != lcpId);
-
- replicaPtr.p->lcpIdStarted = lcpId;
- replicaPtr.p->lcpOngoingFlag = false;
-
- removeOldCrashedReplicas(replicaPtr);
- replicaPtr.p->lcpId[lcpNo] = lcpId;
- replicaPtr.p->lcpStatus[lcpNo] = ZVALID;
- replicaPtr.p->maxGciStarted[lcpNo] = maxGciStarted;
- gth(maxGciStarted + 1, 0);
- replicaPtr.p->maxGciCompleted[lcpNo] = maxGciCompleted;
- replicaPtr.p->nextLcp = nextLcpNo(replicaPtr.p->nextLcp);
-
- ndbrequire(fragPtr.p->noLcpReplicas > 0);
- fragPtr.p->noLcpReplicas --;
-
- if(fragPtr.p->noLcpReplicas > 0){
- jam();
- return false;
- }
-
- for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
- jam();
- getFragstore(tabPtr.p, fid, fragPtr);
- if (fragPtr.p->noLcpReplicas > 0){
- jam();
- /* ----------------------------------------------------------------- */
- // Not all fragments in table have been checkpointed.
- /* ----------------------------------------------------------------- */
- if(0)
- g_eventLogger.info("reportLcpCompletion: fragment %d not ready", fid);
- return false;
- }//if
- }//for
- return true;
-}//Dbdih::reportLcpCompletion()
-
-void Dbdih::checkStartMoreLcp(Signal* signal, Uint32 nodeId)
-{
- ndbrequire(isMaster());
-
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- ndbrequire(nodePtr.p->noOfStartedChkpt < 2);
-
- if (nodePtr.p->noOfQueuedChkpt > 0) {
- jam();
- nodePtr.p->noOfQueuedChkpt--;
- Uint32 i = nodePtr.p->noOfStartedChkpt;
- nodePtr.p->startedChkpt[i] = nodePtr.p->queuedChkpt[0];
- nodePtr.p->queuedChkpt[0] = nodePtr.p->queuedChkpt[1];
- //-------------------------------------------------------------------
- // We can send a LCP_FRAGORD to the node ordering it to perform a
- // local checkpoint on this fragment replica.
- //-------------------------------------------------------------------
- nodePtr.p->noOfStartedChkpt = i + 1;
-
- sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
- }
-
- /* ----------------------------------------------------------------------- */
- // When there are no more outstanding LCP reports and there are no one queued
- // in at least one node, then we are ready to make sure all nodes have at
- // least two outstanding LCP requests per node and at least two queued for
- // sending.
- /* ----------------------------------------------------------------------- */
- startNextChkpt(signal);
-}//Dbdih::checkStartMoreLcp()
-
-void
-Dbdih::sendLCP_FRAG_ORD(Signal* signal,
- NodeRecord::FragmentCheckpointInfo info){
-
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = info.replicaPtr;
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
-
- BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
-
- if (ERROR_INSERTED(7193) && replicaPtr.p->procNode == getOwnNodeId())
- {
- return;
- }
-
- LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
- lcpFragOrd->tableId = info.tableId;
- lcpFragOrd->fragmentId = info.fragId;
- lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
- lcpFragOrd->lcpNo = replicaPtr.p->nextLcp;
- lcpFragOrd->keepGci = c_lcpState.keepGci;
- lcpFragOrd->lastFragmentFlag = false;
- sendSignal(ref, GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB);
-}
-
-void Dbdih::checkLcpCompletedLab(Signal* signal)
-{
- if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED){
- jam();
- return;
- }
-
- TabRecordPtr tabPtr;
- for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
- jam();
- ptrAss(tabPtr, tabRecord);
- if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
- if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED) {
- jam();
- return;
- }//if
- }//if
- }//for
-
- CRASH_INSERTION2(7027, isMaster());
- CRASH_INSERTION2(7018, !isMaster());
-
- if(c_lcpState.lcpStatus == LCP_TAB_COMPLETED){
- /**
- * We'r done
- */
- c_lcpState.setLcpStatus(LCP_TAB_SAVED, __LINE__);
- sendLCP_COMPLETE_REP(signal);
- return;
- }
-
- ndbrequire(c_lcpState.lcpStatus == LCP_TAB_SAVED);
- allNodesLcpCompletedLab(signal);
- return;
-}//Dbdih::checkLcpCompletedLab()
-
-void
-Dbdih::sendLCP_COMPLETE_REP(Signal* signal){
- jam();
- LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
- rep->nodeId = getOwnNodeId();
- rep->lcpId = SYSFILE->latestLCP_ID;
- rep->blockNo = DBDIH;
-
- sendSignal(c_lcpState.m_masterLcpDihRef, GSN_LCP_COMPLETE_REP, signal,
- LcpCompleteRep::SignalLength, JBB);
-
- /**
- * Say that an initial node restart does not need to be redone
- * once node has been part of first LCP
- */
- if (c_set_initial_start_flag &&
- c_lcpState.m_participatingLQH.get(getOwnNodeId()))
- {
- jam();
- c_set_initial_start_flag = FALSE;
- }
-}
-
-/*-------------------------------------------------------------------------- */
-/* COMP_LCP_ROUND A LQH HAS COMPLETED A LOCAL CHECKPOINT */
-/*------------------------------------------------------------------------- */
-void Dbdih::execLCP_COMPLETE_REP(Signal* signal)
-{
- jamEntry();
-
- CRASH_INSERTION(7191);
-
-#if 0
- g_eventLogger.info("LCP_COMPLETE_REP");
- printLCP_COMPLETE_REP(stdout,
- signal->getDataPtr(),
- signal->length(), number());
-#endif
-
- LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtr();
- Uint32 lcpId = rep->lcpId;
- Uint32 nodeId = rep->nodeId;
- Uint32 blockNo = rep->blockNo;
-
- if(c_lcpMasterTakeOverState.state > LMTOS_WAIT_LCP_FRAG_REP){
- jam();
- /**
- * Don't allow LCP_COMPLETE_REP to arrive during
- * LCP master take over
- */
- ndbrequire(isMaster());
- ndbrequire(blockNo == DBDIH);
- sendSignalWithDelay(reference(), GSN_LCP_COMPLETE_REP, signal, 100,
- signal->length());
- return;
- }
-
- ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
-
- switch(blockNo){
- case DBLQH:
- jam();
- c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(nodeId);
- ndbrequire(!c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId));
- break;
- case DBDIH:
- jam();
- ndbrequire(isMaster());
- c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor(nodeId);
- break;
- case 0:
- jam();
- ndbrequire(!isMaster());
- ndbrequire(c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false);
- c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = true;
- break;
- default:
- ndbrequire(false);
- }
- ndbrequire(lcpId == SYSFILE->latestLCP_ID);
-
- allNodesLcpCompletedLab(signal);
- return;
-}
-
-void Dbdih::allNodesLcpCompletedLab(Signal* signal)
-{
- jam();
-
- if (c_lcpState.lcpStatus != LCP_TAB_SAVED) {
- jam();
- /**
- * We have not sent LCP_COMPLETE_REP to master DIH yet
- */
- return;
- }//if
-
- if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.done()){
- jam();
- return;
- }
-
- if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.done()){
- jam();
- return;
- }
-
- if (!isMaster() &&
- c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false){
- jam();
- /**
- * Wait until master DIH has signaled lcp is complete
- */
- return;
- }
-
- if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
- jam();
-#ifdef VM_TRACE
- g_eventLogger.info("Exiting from allNodesLcpCompletedLab");
-#endif
- return;
- }
-
-
- /*------------------------------------------------------------------------ */
- /* WE HAVE NOW COMPLETED A LOCAL CHECKPOINT. WE ARE NOW READY TO WAIT */
- /* FOR THE NEXT LOCAL CHECKPOINT. SEND WITHOUT TIME-OUT SINCE IT MIGHT */
- /* BE TIME TO START THE NEXT LOCAL CHECKPOINT IMMEDIATELY. */
- /* CLEAR BIT 3 OF SYSTEM RESTART BITS TO INDICATE THAT THERE IS NO */
- /* LOCAL CHECKPOINT ONGOING. THIS WILL BE WRITTEN AT SOME LATER TIME */
- /* DURING A GLOBAL CHECKPOINT. IT IS NOT NECESSARY TO WRITE IT */
- /* IMMEDIATELY. WE WILL ALSO CLEAR BIT 2 OF SYSTEM RESTART BITS IF ALL */
- /* CURRENTLY ACTIVE NODES COMPLETED THE LOCAL CHECKPOINT. */
- /*------------------------------------------------------------------------ */
- CRASH_INSERTION(7019);
- signal->setTrace(0);
-
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- setLcpActiveStatusEnd();
- Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
-
- if(!isMaster()){
- jam();
- /**
- * We're not master, be content
- */
- return;
- }
-
- // Send LCP_COMPLETE_REP to all other nodes
- // allowing them to set their lcpStatus to LCP_STATUS_IDLE
- LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
- rep->nodeId = getOwnNodeId();
- rep->lcpId = SYSFILE->latestLCP_ID;
- rep->blockNo = 0; // 0 = Sent from master
-
- NodeRecordPtr nodePtr;
- nodePtr.i = cfirstAliveNode;
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.i != cownNodeId){
- BlockReference ref = calcDihBlockRef(nodePtr.i);
- sendSignal(ref, GSN_LCP_COMPLETE_REP, signal,
- LcpCompleteRep::SignalLength, JBB);
- }
- nodePtr.i = nodePtr.p->nextNode;
- } while (nodePtr.i != RNIL);
-
-
- jam();
- /***************************************************************************/
- // Report the event that a local checkpoint has completed.
- /***************************************************************************/
- signal->theData[0] = NDB_LE_LocalCheckpointCompleted; //Event type
- signal->theData[1] = SYSFILE->latestLCP_ID;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- if (c_newest_restorable_gci > c_lcpState.lcpStopGcp)
- {
- jam();
- c_lcpState.lcpStopGcp = c_newest_restorable_gci;
- }
-
- /**
- * Start checking for next LCP
- */
- checkLcpStart(signal, __LINE__);
-
- if (cwaitLcpSr == true) {
- jam();
- cwaitLcpSr = false;
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }//if
-
- if (c_nodeStartMaster.blockLcp == true) {
- jam();
- lcpBlockedLab(signal);
- return;
- }//if
- return;
-}//Dbdih::allNodesLcpCompletedLab()
-
-/******************************************************************************/
-/* ********** TABLE UPDATE MODULE *************/
-/* ****************************************************************************/
-/* ------------------------------------------------------------------------- */
-/* THIS MODULE IS USED TO UPDATE THE TABLE DESCRIPTION. IT STARTS BY */
-/* CREATING THE FIRST TABLE FILE, THEN UPDATES THIS FILE AND CLOSES IT.*/
-/* AFTER THAT THE SAME HAPPENS WITH THE SECOND FILE. AFTER THAT THE */
-/* TABLE DISTRIBUTION HAS BEEN UPDATED. */
-/* */
-/* THE REASON FOR CREATING THE FILE AND NOT OPENING IT IS TO ENSURE */
-/* THAT WE DO NOT GET A MIX OF OLD AND NEW INFORMATION IN THE FILE IN */
-/* ERROR SITUATIONS. */
-/* ------------------------------------------------------------------------- */
-void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
- FileRecordPtr filePtr;
- if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
- // For temporary tables we do not write to disk. Mark both copies 0 and 1
- // as done, and go straight to the after-close code.
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- tableCloseLab(signal, filePtr);
- return;
- }
- filePtr.i = tabPtr.p->tabFile[0];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- createFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
- return;
-}//Dbdih::tableUpdateLab()
-
-void Dbdih::tableCreateLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- writeTabfile(signal, tabPtr.p, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_WRITE;
- return;
-}//Dbdih::tableCreateLab()
-
-void Dbdih::tableWriteLab(Signal* signal, FileRecordPtr filePtr)
-{
- closeFile(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_CLOSE;
- return;
-}//Dbdih::tableWriteLab()
-
-void Dbdih::tableCloseLab(Signal* signal, FileRecordPtr filePtr)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = filePtr.p->tabRef;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- if (filePtr.i == tabPtr.p->tabFile[0]) {
- jam();
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- createFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
- return;
- }//if
- switch (tabPtr.p->tabUpdateState) {
- case TabRecord::US_LOCAL_CHECKPOINT:
- jam();
- releaseTabPages(tabPtr.i);
- signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
-
- tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
- return;
- break;
- case TabRecord::US_REMOVE_NODE:
- jam();
- releaseTabPages(tabPtr.i);
- for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
- jam();
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragId, fragPtr);
- updateNodeInfo(fragPtr);
- }//for
- tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE) {
- jam();
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
- signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
- }//if
- signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
- signal->theData[1] = tabPtr.p->tabRemoveNode;
- signal->theData[2] = tabPtr.i + 1;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- break;
- case TabRecord::US_INVALIDATE_NODE_LCP:
- jam();
- releaseTabPages(tabPtr.i);
- tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
-
- signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
- signal->theData[1] = tabPtr.p->tabRemoveNode;
- signal->theData[2] = tabPtr.i + 1;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- return;
- case TabRecord::US_COPY_TAB_REQ:
- jam();
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- copyTabReq_complete(signal, tabPtr);
- return;
- break;
- case TabRecord::US_ADD_TABLE_MASTER:
- jam();
- releaseTabPages(tabPtr.i);
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_MASTER;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- case TabRecord::US_ADD_TABLE_SLAVE:
- jam();
- releaseTabPages(tabPtr.i);
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_SLAVE;
- signal->theData[1] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
-}//Dbdih::tableCloseLab()
-
-/**
- * GCP stop detected,
- * send SYSTEM_ERROR to all other alive nodes
- */
-void Dbdih::crashSystemAtGcpStop(Signal* signal, bool local)
-{
- if (local)
- goto dolocal;
-
- switch(cgcpStatus){
- case GCP_PREPARE_SENT:
- {
- jam();
- /**
- * We're waiting for a GCP PREPARE CONF
- */
- infoEvent("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_PREPARE_Counter.getText());
- ndbout_c("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_PREPARE_Counter.getText());
-
- {
- NodeReceiverGroup rg(DBDIH, c_GCP_PREPARE_Counter);
- signal->theData[0] = 7022;
- sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
- }
-
- {
- NodeReceiverGroup rg(NDBCNTR, c_GCP_PREPARE_Counter);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::GCPStopDetected;
- sysErr->errorRef = reference();
- sysErr->data1 = cgcpStatus;
- sysErr->data2 = cgcpOrderBlocked;
- sendSignal(rg, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBA);
- }
- ndbrequire(!c_GCP_PREPARE_Counter.done());
- return;
- }
- case GCP_COMMIT_SENT:
- {
- jam();
- /**
- * We're waiting for a GCP_NODEFINISH
- */
- infoEvent("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_COMMIT_Counter.getText());
- ndbout_c("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_COMMIT_Counter.getText());
-
- {
- NodeReceiverGroup rg(DBDIH, c_GCP_COMMIT_Counter);
- signal->theData[0] = 7022;
- sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
- }
-
- {
- NodeReceiverGroup rg(NDBCNTR, c_GCP_COMMIT_Counter);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::GCPStopDetected;
- sysErr->errorRef = reference();
- sysErr->data1 = cgcpStatus;
- sysErr->data2 = cgcpOrderBlocked;
- sendSignal(rg, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBA);
- }
- ndbrequire(!c_GCP_COMMIT_Counter.done());
- return;
- }
- case GCP_NODE_FINISHED:
- {
- jam();
- /**
- * We're waiting for a GCP save conf
- */
- NodeReceiverGroup rg(DBLQH, c_GCP_SAVEREQ_Counter);
- signal->theData[0] = 2305;
- sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
-
- infoEvent("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
- ndbout_c("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_GCP_SAVEREQ_Counter.getText());
- ndbrequire(!c_GCP_SAVEREQ_Counter.done());
- return;
- }
- case GCP_SAVE_LQH_FINISHED:
- {
- jam();
- /**
- * We're waiting for a COPY_GCICONF
- */
- infoEvent("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_COPY_GCIREQ_Counter.getText());
- ndbout_c("Detected GCP stop(%d)...sending kill to %s",
- cgcpStatus, c_COPY_GCIREQ_Counter.getText());
-
- {
- NodeReceiverGroup rg(DBDIH, c_COPY_GCIREQ_Counter);
- signal->theData[0] = 7022;
- sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBA);
- }
-
- {
- NodeReceiverGroup rg(NDBCNTR, c_COPY_GCIREQ_Counter);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::GCPStopDetected;
- sysErr->errorRef = reference();
- sysErr->data1 = cgcpStatus;
- sysErr->data2 = cgcpOrderBlocked;
- sendSignal(rg, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBA);
- }
- ndbrequire(!c_COPY_GCIREQ_Counter.done());
- return;
- }
- case GCP_READY: (void)1;
- }
-
-dolocal:
- ndbout_c("m_copyReason: %d m_waiting: %d",
- c_copyGCIMaster.m_copyReason,
- c_copyGCIMaster.m_waiting);
-
- ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
- c_copyGCISlave.m_senderData,
- c_copyGCISlave.m_senderRef,
- c_copyGCISlave.m_copyReason,
- c_copyGCISlave.m_expectedNextWord);
-
- FileRecordPtr file0Ptr;
- file0Ptr.i = crestartInfoFile[0];
- ptrCheckGuard(file0Ptr, cfileFileSize, fileRecord);
- FileRecordPtr file1Ptr;
- file1Ptr.i = crestartInfoFile[1];
- ptrCheckGuard(file1Ptr, cfileFileSize, fileRecord);
-
- ndbout_c("file[0] status: %d type: %d reqStatus: %d file1: %d %d %d",
- file0Ptr.p->fileStatus, file0Ptr.p->fileType, file0Ptr.p->reqStatus,
- file1Ptr.p->fileStatus, file1Ptr.p->fileType, file1Ptr.p->reqStatus
- );
-
- signal->theData[0] = 404;
- signal->theData[1] = file0Ptr.p->fileRef;
- EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
-
- signal->theData[0] = 404;
- signal->theData[1] = file1Ptr.p->fileRef;
- EXECUTE_DIRECT(NDBFS, GSN_DUMP_STATE_ORD, signal, 2);
-
- ndbout_c("c_COPY_GCIREQ_Counter = %s",
- c_COPY_GCIREQ_Counter.getText());
- ndbout_c("c_COPY_TABREQ_Counter = %s",
- c_COPY_TABREQ_Counter.getText());
- ndbout_c("c_CREATE_FRAGREQ_Counter = %s",
- c_CREATE_FRAGREQ_Counter.getText());
- ndbout_c("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
- c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
- ndbout_c("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
- ndbout_c("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
- ndbout_c("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
- ndbout_c("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
- ndbout_c("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
- ndbout_c("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
- ndbout_c("c_MASTER_GCPREQ_Counter = %s",
- c_MASTER_GCPREQ_Counter.getText());
- ndbout_c("c_MASTER_LCPREQ_Counter = %s",
- c_MASTER_LCPREQ_Counter.getText());
- ndbout_c("c_START_INFOREQ_Counter = %s",
- c_START_INFOREQ_Counter.getText());
- ndbout_c("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
- ndbout_c("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
- ndbout_c("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
- ndbout_c("c_TC_CLOPSIZEREQ_Counter = %s",
- c_TC_CLOPSIZEREQ_Counter.getText());
- ndbout_c("c_TCGETOPSIZEREQ_Counter = %s",
- c_TCGETOPSIZEREQ_Counter.getText());
- ndbout_c("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
-
- if (local == false)
- {
- jam();
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- const BlockReference ref =
- numberToRef(refToBlock(cntrlblockref), nodePtr.i);
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::GCPStopDetected;
- sysErr->errorRef = reference();
- sysErr->data1 = cgcpStatus;
- sysErr->data2 = cgcpOrderBlocked;
- sendSignal(ref, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBA);
- }//if
- }//for
- }
- else
- {
- jam();
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::GCPStopDetected;
- sysErr->errorRef = reference();
- sysErr->data1 = cgcpStatus;
- sysErr->data2 = cgcpOrderBlocked;
- EXECUTE_DIRECT(NDBCNTR, GSN_SYSTEM_ERROR,
- signal, SystemError::SignalLength);
- ndbrequire(false);
- }
- return;
-}//Dbdih::crashSystemAtGcpStop()
-
-/*************************************************************************/
-/* */
-/* MODULE: ALLOCPAGE */
-/* DESCRIPTION: THE SUBROUTINE IS CALLED WITH POINTER TO PAGE */
-/* RECORD. A PAGE RECORD IS TAKEN FROM */
-/* THE FREE PAGE LIST */
-/*************************************************************************/
-void Dbdih::allocpage(PageRecordPtr& pagePtr)
-{
- ndbrequire(cfirstfreepage != RNIL);
- pagePtr.i = cfirstfreepage;
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- cfirstfreepage = pagePtr.p->nextfreepage;
- pagePtr.p->nextfreepage = RNIL;
-}//Dbdih::allocpage()
-
-/*************************************************************************/
-/* */
-/* MODULE: ALLOC_STORED_REPLICA */
-/* DESCRIPTION: THE SUBROUTINE IS CALLED TO GET A REPLICA RECORD, */
-/* TO INITIALISE IT AND TO LINK IT INTO THE FRAGMENT */
-/* STORE RECORD. USED FOR STORED REPLICAS. */
-/*************************************************************************/
-void Dbdih::allocStoredReplica(FragmentstorePtr fragPtr,
- ReplicaRecordPtr& newReplicaPtr,
- Uint32 nodeId)
-{
- Uint32 i;
- ReplicaRecordPtr arrReplicaPtr;
- ReplicaRecordPtr arrPrevReplicaPtr;
-
- seizeReplicaRec(newReplicaPtr);
- for (i = 0; i < MAX_LCP_STORED; i++) {
- newReplicaPtr.p->maxGciCompleted[i] = 0;
- newReplicaPtr.p->maxGciStarted[i] = 0;
- newReplicaPtr.p->lcpId[i] = 0;
- newReplicaPtr.p->lcpStatus[i] = ZINVALID;
- }//for
- newReplicaPtr.p->noCrashedReplicas = 0;
- newReplicaPtr.p->initialGci = currentgcp;
- for (i = 0; i < 8; i++) {
- newReplicaPtr.p->replicaLastGci[i] = (Uint32)-1;
- newReplicaPtr.p->createGci[i] = 0;
- }//for
- newReplicaPtr.p->createGci[0] = currentgcp;
- ndbrequire(currentgcp != 0xF1F1F1F1);
- newReplicaPtr.p->nextLcp = 0;
- newReplicaPtr.p->procNode = nodeId;
- newReplicaPtr.p->lcpOngoingFlag = false;
- newReplicaPtr.p->lcpIdStarted = 0;
-
- arrPrevReplicaPtr.i = RNIL;
- arrReplicaPtr.i = fragPtr.p->storedReplicas;
- while (arrReplicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(arrReplicaPtr, creplicaFileSize, replicaRecord);
- arrPrevReplicaPtr = arrReplicaPtr;
- arrReplicaPtr.i = arrReplicaPtr.p->nextReplica;
- }//while
- if (arrPrevReplicaPtr.i == RNIL) {
- jam();
- fragPtr.p->storedReplicas = newReplicaPtr.i;
- } else {
- jam();
- arrPrevReplicaPtr.p->nextReplica = newReplicaPtr.i;
- }//if
- fragPtr.p->noStoredReplicas++;
-}//Dbdih::allocStoredReplica()
-
-/*************************************************************************/
-/* CALCULATE HOW MANY HOT SPARES THAT ARE TO BE ASSIGNED IN THIS SYSTEM */
-/*************************************************************************/
-void Dbdih::calculateHotSpare()
-{
- Uint32 tchsTmp;
- Uint32 tchsNoNodes;
-
- switch (cnoReplicas) {
- case 1:
- jam();
- cnoHotSpare = 0;
- break;
- case 2:
- case 3:
- case 4:
- jam();
- if (csystemnodes > cnoReplicas) {
- jam();
- /* --------------------------------------------------------------------- */
- /* WITH MORE NODES THAN REPLICAS WE WILL ALWAYS USE AT LEAST ONE HOT */
- /* SPARE IF THAT HAVE BEEN REQUESTED BY THE CONFIGURATION FILE. THE */
- /* NUMBER OF NODES TO BE USED FOR NORMAL OPERATION IS ALWAYS */
- /* A MULTIPLE OF THE NUMBER OF REPLICAS SINCE WE WILL ORGANISE NODES */
- /* INTO NODE GROUPS. THE REMAINING NODES WILL BE HOT SPARE NODES. */
- /* --------------------------------------------------------------------- */
- if ((csystemnodes - cnoReplicas) >= cminHotSpareNodes) {
- jam();
- /* --------------------------------------------------------------------- */
- // We set the minimum number of hot spares according to users request
- // through the configuration file.
- /* --------------------------------------------------------------------- */
- tchsNoNodes = csystemnodes - cminHotSpareNodes;
- cnoHotSpare = cminHotSpareNodes;
- } else if (cminHotSpareNodes > 0) {
- jam();
- /* --------------------------------------------------------------------- */
- // The user requested at least one hot spare node and we will support him
- // in that.
- /* --------------------------------------------------------------------- */
- tchsNoNodes = csystemnodes - 1;
- cnoHotSpare = 1;
- } else {
- jam();
- /* --------------------------------------------------------------------- */
- // The user did not request any hot spare nodes so in this case we will
- // only use hot spare nodes if the number of nodes is such that we cannot
- // use all nodes as normal nodes.
- /* --------------------------------------------------------------------- */
- tchsNoNodes = csystemnodes;
- cnoHotSpare = 0;
- }//if
- } else {
- jam();
- /* --------------------------------------------------------------------- */
- // We only have enough to support the replicas. We will not have any hot
- // spares.
- /* --------------------------------------------------------------------- */
- tchsNoNodes = csystemnodes;
- cnoHotSpare = 0;
- }//if
- tchsTmp = tchsNoNodes - (cnoReplicas * (tchsNoNodes / cnoReplicas));
- cnoHotSpare = cnoHotSpare + tchsTmp;
- break;
- default:
- jam();
- ndbrequire(false);
- break;
- }//switch
-}//Dbdih::calculateHotSpare()
-
-/*************************************************************************/
-/* CHECK IF THE NODE CRASH IS TO ESCALATE INTO A SYSTEM CRASH. WE COULD */
-/* DO THIS BECAUSE ALL REPLICAS OF SOME FRAGMENT ARE LOST. WE COULD ALSO */
-/* DO IT AFTER MANY NODE FAILURES THAT MAKE IT VERY DIFFICULT TO RESTORE */
-/* DATABASE AFTER A SYSTEM CRASH. IT MIGHT EVEN BE IMPOSSIBLE AND THIS */
-/* MUST BE AVOIDED EVEN MORE THAN AVOIDING SYSTEM CRASHES. */
-/*************************************************************************/
-void Dbdih::checkEscalation()
-{
- Uint32 TnodeGroup[MAX_NDB_NODES];
- NodeRecordPtr nodePtr;
- Uint32 i;
- for (i = 0; i < MAX_NDB_NODES; i++) {
- TnodeGroup[i] = ZFALSE;
- }//for
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
- nodePtr.p->activeStatus == Sysfile::NS_Active){
- ndbrequire(nodePtr.p->nodeGroup < MAX_NDB_NODES);
- TnodeGroup[nodePtr.p->nodeGroup] = ZTRUE;
- }
- }
- for (i = 0; i < cnoOfNodeGroups; i++) {
- jam();
- if (TnodeGroup[i] == ZFALSE) {
- jam();
- progError(__LINE__, NDBD_EXIT_LOST_NODE_GROUP, "Lost node group");
- }//if
- }//for
-}//Dbdih::checkEscalation()
-
-/*************************************************************************/
-/* */
-/* MODULE: CHECK_KEEP_GCI */
-/* DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL */
-/* CHECKPOINT. */
-/*************************************************************************/
-void Dbdih::checkKeepGci(TabRecordPtr tabPtr, Uint32 fragId, Fragmentstore*,
- Uint32 replicaStartIndex)
-{
- ReplicaRecordPtr ckgReplicaPtr;
- ckgReplicaPtr.i = replicaStartIndex;
- while (ckgReplicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(ckgReplicaPtr, creplicaFileSize, replicaRecord);
- Uint32 keepGci;
- Uint32 oldestRestorableGci;
- findMinGci(ckgReplicaPtr, keepGci, oldestRestorableGci);
- if (keepGci < c_lcpState.keepGci) {
- jam();
- /* ------------------------------------------------------------------- */
- /* WE MUST KEEP LOG RECORDS SO THAT WE CAN USE ALL LOCAL CHECKPOINTS */
- /* THAT ARE AVAILABLE. THUS WE NEED TO CALCULATE THE MINIMUM OVER ALL */
- /* FRAGMENTS. */
- /* ------------------------------------------------------------------- */
- c_lcpState.keepGci = keepGci;
- }//if
- if (oldestRestorableGci > c_lcpState.oldestRestorableGci) {
- jam();
- c_lcpState.oldestRestorableGci = oldestRestorableGci;
- }//if
- ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica;
- }//while
-}//Dbdih::checkKeepGci()
-
-void Dbdih::closeFile(Signal* signal, FileRecordPtr filePtr)
-{
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZCLOSE_NO_DELETE;
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
-}//Dbdih::closeFile()
-
-void Dbdih::closeFileDelete(Signal* signal, FileRecordPtr filePtr)
-{
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZCLOSE_DELETE;
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
-}//Dbdih::closeFileDelete()
-
-void Dbdih::createFileRw(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] = ZCREATE_READ_WRITE;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
-}//Dbdih::createFileRw()
-
-void Dbdih::emptyverificbuffer(Signal* signal, bool aContinueB)
-{
- if(cfirstVerifyQueue == RNIL){
- jam();
- return;
- }//if
- ApiConnectRecordPtr localApiConnectptr;
- if(getBlockCommit() == false){
- jam();
- ndbrequire(cverifyQueueCounter > 0);
- cverifyQueueCounter--;
- localApiConnectptr.i = cfirstVerifyQueue;
- ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
- ndbrequire(localApiConnectptr.p->apiGci <= currentgcp);
- cfirstVerifyQueue = localApiConnectptr.p->nextApi;
- if (cfirstVerifyQueue == RNIL) {
- jam();
- ndbrequire(cverifyQueueCounter == 0);
- clastVerifyQueue = RNIL;
- }//if
- signal->theData[0] = localApiConnectptr.i;
- signal->theData[1] = currentgcp;
- sendSignal(clocaltcblockref, GSN_DIVERIFYCONF, signal, 2, JBB);
- if (aContinueB == true) {
- jam();
- //-----------------------------------------------------------------------
- // This emptying happened as part of a take-out process by continueb signals.
- // This ensures that we will empty the queue eventually. We will also empty
- // one item every time we insert one item to ensure that the list doesn't
- // grow when it is not blocked.
- //-----------------------------------------------------------------------
- signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
- }//if
- } else {
- jam();
- //-----------------------------------------------------------------------
- // We are blocked so it is no use in continuing the emptying of the
- // verify buffer. Whenever the block is removed the emptying will
- // restart.
- //-----------------------------------------------------------------------
- }
- return;
-}//Dbdih::emptyverificbuffer()
-
-/*----------------------------------------------------------------*/
-/* FIND A FREE HOT SPARE IF AVAILABLE AND ALIVE. */
-/*----------------------------------------------------------------*/
-Uint32 Dbdih::findHotSpare()
-{
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- if (nodePtr.p->activeStatus == Sysfile::NS_HotSpare) {
- jam();
- return nodePtr.i;
- }//if
- }//if
- }//for
- return RNIL;
-}//Dbdih::findHotSpare()
-
-/*************************************************************************/
-/* FIND THE NODES FROM WHICH WE CAN EXECUTE THE LOG TO RESTORE THE */
-/* DATA NODE IN A SYSTEM RESTART. */
-/*************************************************************************/
-bool Dbdih::findLogNodes(CreateReplicaRecord* createReplica,
- FragmentstorePtr fragPtr,
- Uint32 startGci,
- Uint32 stopGci)
-{
- ConstPtr<ReplicaRecord> flnReplicaPtr;
- flnReplicaPtr.i = createReplica->replicaRec;
- ptrCheckGuard(flnReplicaPtr, creplicaFileSize, replicaRecord);
- /* --------------------------------------------------------------------- */
- /* WE START BY CHECKING IF THE DATA NODE CAN HANDLE THE LOG ALL BY */
- /* ITSELF. THIS IS THE DESIRED BEHAVIOUR. IF THIS IS NOT POSSIBLE */
- /* THEN WE SEARCH FOR THE BEST POSSIBLE NODES AMONG THE NODES THAT */
- /* ARE PART OF THIS SYSTEM RESTART. */
- /* THIS CAN ONLY BE HANDLED BY THE LAST CRASHED REPLICA. */
- /* The condition is that the replica was created before or at the */
- /* time of the starting gci, in addition it must have been alive */
- /* at the time of the stopping gci. This is checked by two */
- /* conditions, the first checks replicaLastGci and the second */
- /* checks that it is also smaller than the last gci the node was */
- /* involved in. This is necessary to check since createGci is set */
- /* Last + 1 and sometimes startGci = stopGci + 1 and in that case */
- /* it could happen that replicaLastGci is set to -1 with CreateGci */
- /* set to LastGci + 1. */
- /* --------------------------------------------------------------------- */
- arrGuard(flnReplicaPtr.p->noCrashedReplicas, 8);
- const Uint32 noCrashed = flnReplicaPtr.p->noCrashedReplicas;
-
- if (!(ERROR_INSERTED(7073) || ERROR_INSERTED(7074))&&
- (startGci >= flnReplicaPtr.p->createGci[noCrashed]) &&
- (stopGci <= flnReplicaPtr.p->replicaLastGci[noCrashed]) &&
- (stopGci <= SYSFILE->lastCompletedGCI[flnReplicaPtr.p->procNode])) {
- jam();
- /* --------------------------------------------------------------------- */
- /* WE FOUND ALL THE LOG RECORDS NEEDED IN THE DATA NODE. WE WILL */
- /* USE THOSE. */
- /* --------------------------------------------------------------------- */
- createReplica->noLogNodes = 1;
- createReplica->logStartGci[0] = startGci;
- createReplica->logStopGci[0] = stopGci;
- createReplica->logNodeId[0] = flnReplicaPtr.p->procNode;
- return true;
- }//if
- Uint32 logNode = 0;
- do {
- Uint32 fblStopGci;
- jam();
- if(!findBestLogNode(createReplica,
- fragPtr,
- startGci,
- stopGci,
- logNode,
- fblStopGci)){
- jam();
- return false;
- }
-
- logNode++;
- if (fblStopGci >= stopGci) {
- jam();
- createReplica->noLogNodes = logNode;
- return true;
- }//if
- startGci = fblStopGci + 1;
- if (logNode >= 4) { // Why??
- jam();
- break;
- }//if
- } while (1);
- /* --------------------------------------------------------------------- */
- /* IT WAS NOT POSSIBLE TO RESTORE THE REPLICA. THIS CAN EITHER BE */
- /* BECAUSE OF LACKING NODES OR BECAUSE OF A REALLY SERIOUS PROBLEM.*/
- /* --------------------------------------------------------------------- */
- return false;
-}//Dbdih::findLogNodes()
-
-/*************************************************************************/
-/* FIND THE BEST POSSIBLE LOG NODE TO EXECUTE THE LOG AS SPECIFIED */
-/* BY THE INPUT PARAMETERS. WE SCAN THROUGH ALL ALIVE REPLICAS. */
-/* THIS MEANS STORED, OLD_STORED */
-/*************************************************************************/
-bool
-Dbdih::findBestLogNode(CreateReplicaRecord* createReplica,
- FragmentstorePtr fragPtr,
- Uint32 startGci,
- Uint32 stopGci,
- Uint32 logNode,
- Uint32& fblStopGci)
-{
- ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
- ConstPtr<ReplicaRecord> fblReplicaPtr;
- LINT_INIT(fblFoundReplicaPtr.p);
-
- /* --------------------------------------------------------------------- */
- /* WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE */
- /* BETTER. */
- /* --------------------------------------------------------------------- */
- fblStopGci = 0;
- fblReplicaPtr.i = fragPtr.p->storedReplicas;
- while (fblReplicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
- if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
- jam();
- Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
- if (fliStopGci > fblStopGci) {
- jam();
- fblStopGci = fliStopGci;
- fblFoundReplicaPtr = fblReplicaPtr;
- }//if
- }//if
- fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
- }//while
- fblReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- while (fblReplicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
- if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
- jam();
- Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
- if (fliStopGci > fblStopGci) {
- jam();
- fblStopGci = fliStopGci;
- fblFoundReplicaPtr = fblReplicaPtr;
- }//if
- }//if
- fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
- }//while
- if (fblStopGci != 0) {
- jam();
- ndbrequire(logNode < MAX_LOG_EXEC);
- createReplica->logNodeId[logNode] = fblFoundReplicaPtr.p->procNode;
- createReplica->logStartGci[logNode] = startGci;
- if (fblStopGci >= stopGci) {
- jam();
- createReplica->logStopGci[logNode] = stopGci;
- } else {
- jam();
- createReplica->logStopGci[logNode] = fblStopGci;
- }//if
- }//if
-
- return fblStopGci != 0;
-}//Dbdih::findBestLogNode()
-
-Uint32 Dbdih::findLogInterval(ConstPtr<ReplicaRecord> replicaPtr,
- Uint32 startGci)
-{
- ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
- Uint32 loopLimit = replicaPtr.p->noCrashedReplicas + 1;
- for (Uint32 i = 0; i < loopLimit; i++) {
- jam();
- if (replicaPtr.p->createGci[i] <= startGci) {
- if (replicaPtr.p->replicaLastGci[i] >= startGci) {
- jam();
- return replicaPtr.p->replicaLastGci[i];
- }//if
- }//if
- }//for
- return 0;
-}//Dbdih::findLogInterval()
-
-/*************************************************************************/
-/* */
-/* MODULE: FIND THE MINIMUM GCI THAT THIS NODE HAS LOG RECORDS FOR.*/
-/*************************************************************************/
-void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
- Uint32& keepGci,
- Uint32& oldestRestorableGci)
-{
- Uint32 nextLcpNo;
- Uint32 lcpNo;
- for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
- jam();
- if ((fmgReplicaPtr.p->lcpStatus[i] == ZVALID) &&
- ((fmgReplicaPtr.p->lcpId[i] + MAX_LCP_STORED) <= (SYSFILE->latestLCP_ID + 1))) {
- jam();
- /*--------------------------------------------------------------------*/
- // We invalidate the checkpoint we are preparing to overwrite.
- // The LCP id is still the old lcp id,
- // this is the reason of comparing with lcpId + 1.
- /*---------------------------------------------------------------------*/
- fmgReplicaPtr.p->lcpStatus[i] = ZINVALID;
- }//if
- }//for
- keepGci = (Uint32)-1;
- oldestRestorableGci = 0;
- nextLcpNo = fmgReplicaPtr.p->nextLcp;
- lcpNo = fmgReplicaPtr.p->nextLcp;
- do {
- ndbrequire(lcpNo < MAX_LCP_STORED);
- if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID)
- {
- jam();
- keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo];
- oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo];
- ndbassert(fmgReplicaPtr.p->maxGciStarted[lcpNo] <c_newest_restorable_gci);
- return;
- } else {
- jam();
- if (fmgReplicaPtr.p->createGci[0] == fmgReplicaPtr.p->initialGci) {
- jam();
- /*-------------------------------------------------------------------
- * WE CAN STILL RESTORE THIS REPLICA WITHOUT ANY LOCAL CHECKPOINTS BY
- * ONLY USING THE LOG. IF THIS IS NOT POSSIBLE THEN WE REPORT THE LAST
- * VALID LOCAL CHECKPOINT AS THE MINIMUM GCI RECOVERABLE.
- *-----------------------------------------------------------------*/
- keepGci = fmgReplicaPtr.p->createGci[0];
- }//if
- }//if
- lcpNo = prevLcpNo(lcpNo);
- } while (lcpNo != nextLcpNo);
- return;
-}//Dbdih::findMinGci()
-
-bool Dbdih::findStartGci(ConstPtr<ReplicaRecord> replicaPtr,
- Uint32 stopGci,
- Uint32& startGci,
- Uint32& lcpNo)
-{
- lcpNo = replicaPtr.p->nextLcp;
- const Uint32 startLcpNo = lcpNo;
- do {
- lcpNo = prevLcpNo(lcpNo);
- ndbrequire(lcpNo < MAX_LCP_STORED);
- if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID) {
- if (replicaPtr.p->maxGciStarted[lcpNo] < stopGci) {
- jam();
- /* ----------------------------------------------------------------- */
- /* WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR */
- /* RESTARTING THIS FRAGMENT REPLICA. */
- /* ----------------------------------------------------------------- */
- startGci = replicaPtr.p->maxGciCompleted[lcpNo] + 1;
- return true;
- }
- }
- } while (lcpNo != startLcpNo);
- /* --------------------------------------------------------------------- */
- /* NO VALID LOCAL CHECKPOINT WAS AVAILABLE. WE WILL ADD THE */
- /* FRAGMENT. THUS THE NEXT LCP MUST BE SET TO ZERO. */
- /* WE MUST EXECUTE THE LOG FROM THE INITIAL GLOBAL CHECKPOINT WHEN */
- /* THE TABLE WAS CREATED. */
- /* --------------------------------------------------------------------- */
- startGci = replicaPtr.p->initialGci;
- ndbrequire(replicaPtr.p->nextLcp == 0);
- return false;
-}//Dbdih::findStartGci()
-
-/**************************************************************************/
-/* ---------------------------------------------------------------------- */
-/* FIND A TAKE OVER REPLICA WHICH IS TO BE STARTED OR COMMITTED WHEN*/
-/* TAKING OVER A FAILED NODE. */
-/* ---------------------------------------------------------------------- */
-/*************************************************************************/
-void Dbdih::findToReplica(TakeOverRecord* regTakeOver,
- Uint32 replicaType,
- FragmentstorePtr fragPtr,
- ReplicaRecordPtr& ftrReplicaPtr)
-{
- switch (replicaType) {
- case CreateFragReq::STORED:
- case CreateFragReq::COMMIT_STORED:
- /* ----------------------------------------------------------------------*/
- /* HERE WE SEARCH FOR STORED REPLICAS. THE REPLICA MUST BE STORED IN THE */
- /* SECTION FOR OLD STORED REPLICAS SINCE WE HAVE NOT TAKEN OVER YET. */
- /* ----------------------------------------------------------------------*/
- ftrReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- while (ftrReplicaPtr.i != RNIL) {
- ptrCheckGuard(ftrReplicaPtr, creplicaFileSize, replicaRecord);
- if (ftrReplicaPtr.p->procNode == regTakeOver->toStartingNode) {
- jam();
- return;
- } else {
- if (ftrReplicaPtr.p->procNode == regTakeOver->toFailedNode) {
- jam();
- return;
- } else {
- jam();
- ftrReplicaPtr.i = ftrReplicaPtr.p->nextReplica;
- }//if
- }//if
- }//while
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
-}//Dbdih::findToReplica()
-
-void Dbdih::initCommonData()
-{
- c_blockCommit = false;
- c_blockCommitNo = 0;
- c_createFragmentLock = RNIL;
- c_endToLock = RNIL;
- cfailurenr = 1;
- cfirstAliveNode = RNIL;
- cfirstDeadNode = RNIL;
- cfirstVerifyQueue = RNIL;
- cgckptflag = false;
- cgcpDelay = 0;
- cgcpMasterTakeOverState = GMTOS_IDLE;
- cgcpOrderBlocked = 0;
- cgcpParticipantState = GCP_PARTICIPANT_READY;
- cgcpSameCounter = 0;
- cgcpStartCounter = 0;
- cgcpStatus = GCP_READY;
-
- clastVerifyQueue = RNIL;
- c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
-
- c_lcpState.clcpDelay = 0;
- c_lcpState.lcpStart = ZIDLE;
- c_lcpState.lcpStopGcp = 0;
- c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
- c_lcpState.currentFragment.tableId = 0;
- c_lcpState.currentFragment.fragmentId = 0;
- c_lcpState.noOfLcpFragRepOutstanding = 0;
- c_lcpState.keepGci = 0;
- c_lcpState.oldestRestorableGci = 0;
- c_lcpState.ctcCounter = 0;
- c_lcpState.ctimer = 0;
- c_lcpState.immediateLcpStart = false;
- c_lcpState.m_MASTER_LCPREQ_Received = false;
-
- cmasterdihref = 0;
- cmasterNodeId = 0;
- cmasterState = MASTER_IDLE;
- cmasterTakeOverNode = 0;
- cnewgcp = 0;
- cnoHotSpare = 0;
- cnoOfActiveTables = 0;
- cnoOfNodeGroups = 0;
- c_nextNodeGroup = 0;
- cnoReplicas = 0;
- coldgcp = 0;
- coldGcpId = 0;
- coldGcpStatus = cgcpStatus;
- con_lineNodes = 0;
- creceivedfrag = 0;
- crestartGci = 0;
- crestartInfoFile[0] = RNIL;
- crestartInfoFile[1] = RNIL;
- cstartGcpNow = false;
- cstartPhase = 0;
- c_startToLock = RNIL;
- cstarttype = (Uint32)-1;
- csystemnodes = 0;
- c_updateToLock = RNIL;
- currentgcp = 0;
- c_newest_restorable_gci = 0;
- cverifyQueueCounter = 0;
- cwaitLcpSr = false;
- c_nextLogPart = 0;
-
- nodeResetStart();
- c_nodeStartMaster.wait = ZFALSE;
-
- memset(&sysfileData[0], 0, sizeof(sysfileData));
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.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);
- if (cnoReplicas > 4)
- {
- progError(__LINE__, NDBD_EXIT_INVALID_CONFIG,
- "Only up to four replicas are supported. Check NoOfReplicas.");
- }
-
- 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)
-{
- fragPtr.p->storedReplicas = RNIL;
- fragPtr.p->oldStoredReplicas = RNIL;
-
- fragPtr.p->noStoredReplicas = 0;
- fragPtr.p->noOldStoredReplicas = 0;
- fragPtr.p->fragReplicas = 0;
- fragPtr.p->preferredPrimary = 0;
-
- for (Uint32 i = 0; i < MAX_REPLICAS; i++)
- fragPtr.p->activeNodes[i] = 0;
-
- fragPtr.p->noLcpReplicas = 0;
- fragPtr.p->distributionKey = 0;
-}//Dbdih::initFragstore()
-
-/*************************************************************************/
-/* */
-/* MODULE: INIT_RESTART_INFO */
-/* DESCRIPTION: INITIATE RESTART INFO VARIABLE AND VARIABLES FOR */
-/* GLOBAL CHECKPOINTS. */
-/*************************************************************************/
-void Dbdih::initRestartInfo()
-{
- Uint32 i;
- for (i = 0; i < MAX_NDB_NODES; i++) {
- SYSFILE->lastCompletedGCI[i] = 0;
- }//for
- NodeRecordPtr nodePtr;
- nodePtr.i = cfirstAliveNode;
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- SYSFILE->lastCompletedGCI[nodePtr.i] = 1;
- /* FIRST GCP = 1 ALREADY SET BY LQH */
- nodePtr.i = nodePtr.p->nextNode;
- } while (nodePtr.i != RNIL);
- coldgcp = 1;
- currentgcp = 2;
- cnewgcp = 2;
- crestartGci = 1;
- c_newest_restorable_gci = 1;
-
- SYSFILE->keepGCI = 1;
- SYSFILE->oldestRestorableGCI = 1;
- SYSFILE->newestRestorableGCI = 1;
- SYSFILE->systemRestartBits = 0;
- for (i = 0; i < NodeBitmask::Size; i++) {
- SYSFILE->lcpActive[0] = 0;
- }//for
- for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
- SYSFILE->takeOver[i] = 0;
- }//for
- Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
- srand(time(0));
- globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
-}//Dbdih::initRestartInfo()
-
-/*--------------------------------------------------------------------*/
-/* NODE GROUP BITS ARE INITIALISED BEFORE THIS. */
-/* NODE ACTIVE BITS ARE INITIALISED BEFORE THIS. */
-/*--------------------------------------------------------------------*/
-/*************************************************************************/
-/* */
-/* MODULE: INIT_RESTORABLE_GCI_FILES */
-/* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
-/* FILES THAT KEEP THE VARIABLE CRESTART_INFO */
-/*************************************************************************/
-void Dbdih::initRestorableGciFiles()
-{
- Uint32 tirgTmp;
- FileRecordPtr filePtr;
- seizeFile(filePtr);
- filePtr.p->tabRef = RNIL;
- filePtr.p->fileType = FileRecord::GCP_FILE;
- filePtr.p->reqStatus = FileRecord::IDLE;
- filePtr.p->fileStatus = FileRecord::CLOSED;
- crestartInfoFile[0] = filePtr.i;
- filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
- filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
- filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
- tirgTmp = 1; /* FILE NAME VERSION 1 */
- tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
- tirgTmp = (tirgTmp << 8) + 1; /* D1 DIRECTORY */
- tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
- filePtr.p->fileName[3] = tirgTmp;
- /* --------------------------------------------------------------------- */
- /* THE NAME BECOMES /D1/DBDICT/S0.SYSFILE */
- /* --------------------------------------------------------------------- */
- seizeFile(filePtr);
- filePtr.p->tabRef = RNIL;
- filePtr.p->fileType = FileRecord::GCP_FILE;
- filePtr.p->reqStatus = FileRecord::IDLE;
- filePtr.p->fileStatus = FileRecord::CLOSED;
- crestartInfoFile[1] = filePtr.i;
- filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
- filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
- filePtr.p->fileName[2] = (Uint32)-1; /* S PART IGNORED */
- tirgTmp = 1; /* FILE NAME VERSION 1 */
- tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE */
- tirgTmp = (tirgTmp << 8) + 2; /* D1 DIRECTORY */
- tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME */
- filePtr.p->fileName[3] = tirgTmp;
- /* --------------------------------------------------------------------- */
- /* THE NAME BECOMES /D2/DBDICT/P0.SYSFILE */
- /* --------------------------------------------------------------------- */
-}//Dbdih::initRestorableGciFiles()
-
-void Dbdih::initTable(TabRecordPtr tabPtr)
-{
- tabPtr.p->noOfFragChunks = 0;
- tabPtr.p->method = TabRecord::NOTDEFINED;
- tabPtr.p->tabStatus = TabRecord::TS_IDLE;
- tabPtr.p->noOfWords = 0;
- tabPtr.p->noPages = 0;
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
- tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
- tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
- tabPtr.p->noOfBackups = 0;
- tabPtr.p->kvalue = 0;
- tabPtr.p->hashpointer = (Uint32)-1;
- tabPtr.p->mask = 0;
- tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
- tabPtr.p->tabErrorCode = 0;
- tabPtr.p->schemaVersion = (Uint32)-1;
- tabPtr.p->tabRemoveNode = RNIL;
- tabPtr.p->totalfragments = (Uint32)-1;
- tabPtr.p->connectrec = RNIL;
- tabPtr.p->tabFile[0] = RNIL;
- tabPtr.p->tabFile[1] = RNIL;
- tabPtr.p->m_dropTab.tabUserRef = 0;
- tabPtr.p->m_dropTab.tabUserPtr = RNIL;
- Uint32 i;
- for (i = 0; i < MAX_NDB_NODES; i++) {
- tabPtr.p->startFid[i] = RNIL;
- }//for
- for (i = 0; i < 8; i++) {
- tabPtr.p->pageRef[i] = RNIL;
- }//for
- tabPtr.p->tableType = DictTabInfo::UndefTableType;
-}//Dbdih::initTable()
-
-/*************************************************************************/
-/* */
-/* MODULE: INIT_TABLE_FILES */
-/* DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
-/* FILES THAT KEEP THE TABLE FRAGMENTATION DESCRIPTION. */
-/*************************************************************************/
-void Dbdih::initTableFile(TabRecordPtr tabPtr)
-{
- Uint32 titfTmp;
- FileRecordPtr filePtr;
- seizeFile(filePtr);
- filePtr.p->tabRef = tabPtr.i;
- filePtr.p->fileType = FileRecord::TABLE_FILE;
- filePtr.p->reqStatus = FileRecord::IDLE;
- filePtr.p->fileStatus = FileRecord::CLOSED;
- tabPtr.p->tabFile[0] = filePtr.i;
- filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
- filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
- filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
- titfTmp = 1; /* FILE NAME VERSION 1 */
- titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
- titfTmp = (titfTmp << 8) + 1; /* D1 DIRECTORY */
- titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
- filePtr.p->fileName[3] = titfTmp;
- /* --------------------------------------------------------------------- */
- /* THE NAME BECOMES /D1/DBDICT/Stid.FRAGLIST */
- /* --------------------------------------------------------------------- */
- seizeFile(filePtr);
- filePtr.p->tabRef = tabPtr.i;
- filePtr.p->fileType = FileRecord::TABLE_FILE;
- filePtr.p->reqStatus = FileRecord::IDLE;
- filePtr.p->fileStatus = FileRecord::CLOSED;
- tabPtr.p->tabFile[1] = filePtr.i;
- filePtr.p->fileName[0] = (Uint32)-1; /* T DIRECTORY NOT USED */
- filePtr.p->fileName[1] = (Uint32)-1; /* F DIRECTORY NOT USED */
- filePtr.p->fileName[2] = tabPtr.i; /* Stid FILE NAME */
- titfTmp = 1; /* FILE NAME VERSION 1 */
- titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST */
- titfTmp = (titfTmp << 8) + 2; /* D2 DIRECTORY */
- titfTmp = (titfTmp << 8) + 255; /* P PART IGNORED */
- filePtr.p->fileName[3] = titfTmp;
- /* --------------------------------------------------------------------- */
- /* THE NAME BECOMES /D2/DBDICT/Stid.FRAGLIST */
- /* --------------------------------------------------------------------- */
-}//Dbdih::initTableFile()
-
-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++) {
- refresh_watch_dog();
- 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++) {
- refresh_watch_dog();
- 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;
- ptrAss(connectPtr, connectRecord);
- connectPtr.p->nfConnect = RNIL;
- cfirstconnect = 0;
- break;
- }
- case 3:
- {
- FileRecordPtr filePtr;
- jam();
- /******** INTIALIZING FILE RECORDS ********/
- for (filePtr.i = 0; filePtr.i < cfileFileSize; filePtr.i++) {
- ptrAss(filePtr, fileRecord);
- filePtr.p->nextFile = filePtr.i + 1;
- filePtr.p->fileStatus = FileRecord::CLOSED;
- filePtr.p->reqStatus = FileRecord::IDLE;
- }//for
- filePtr.i = cfileFileSize - 1;
- ptrAss(filePtr, fileRecord);
- filePtr.p->nextFile = RNIL;
- cfirstfreeFile = 0;
- initRestorableGciFiles();
- break;
- }
- case 4:
- jam();
- initialiseFragstore();
- break;
- case 5:
- {
- jam();
- /******* NODE GROUP RECORD ******/
- /******* NODE RECORD ******/
- NodeGroupRecordPtr loopNGPtr;
- for (loopNGPtr.i = 0; loopNGPtr.i < MAX_NDB_NODES; loopNGPtr.i++) {
- ptrAss(loopNGPtr, nodeGroupRecord);
- loopNGPtr.p->nodesInGroup[0] = RNIL;
- loopNGPtr.p->nodesInGroup[1] = RNIL;
- loopNGPtr.p->nodesInGroup[2] = RNIL;
- loopNGPtr.p->nodesInGroup[3] = RNIL;
- loopNGPtr.p->nextReplicaNode = 0;
- loopNGPtr.p->nodeCount = 0;
- loopNGPtr.p->activeTakeOver = false;
- }//for
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRecord);
- new (nodePtr.p) NodeRecord();
- }//for
- break;
- }
- case 6:
- {
- PageRecordPtr pagePtr;
- jam();
- /******* PAGE RECORD ******/
- for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) {
- refresh_watch_dog();
- ptrAss(pagePtr, pageRecord);
- pagePtr.p->nextfreepage = pagePtr.i + 1;
- }//for
- pagePtr.i = cpageFileSize - 1;
- ptrAss(pagePtr, pageRecord);
- pagePtr.p->nextfreepage = RNIL;
- cfirstfreepage = 0;
- break;
- }
- case 7:
- {
- ReplicaRecordPtr initReplicaPtr;
- jam();
- /******* REPLICA RECORD ******/
- for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize;
- initReplicaPtr.i++) {
- refresh_watch_dog();
- ptrAss(initReplicaPtr, replicaRecord);
- initReplicaPtr.p->lcpIdStarted = 0;
- initReplicaPtr.p->lcpOngoingFlag = false;
- initReplicaPtr.p->nextReplica = initReplicaPtr.i + 1;
- }//for
- initReplicaPtr.i = creplicaFileSize - 1;
- ptrAss(initReplicaPtr, replicaRecord);
- initReplicaPtr.p->nextReplica = RNIL;
- cnoFreeReplicaRec = creplicaFileSize;
- cfirstfreeReplica = 0;
- break;
- }
- case 8:
- {
- TabRecordPtr loopTabptr;
- jam();
- /********* TAB-DESCRIPTOR ********/
- for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) {
- ptrAss(loopTabptr, tabRecord);
- refresh_watch_dog();
- initTable(loopTabptr);
- }//for
- break;
- }
- case 9:
- {
- TakeOverRecordPtr takeOverPtr;
- jam();
- cfirstfreeTakeOver = RNIL;
- for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
- ptrAss(takeOverPtr, takeOverRecord);
- initTakeOver(takeOverPtr);
- releaseTakeOver(takeOverPtr.i);
- }//for
-
- 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
- jam();
- /* ---------------------------------------------------------------------- */
- /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */
- /* ---------------------------------------------------------------------- */
- signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS;
- signal->theData[1] = stepNo + 1;
- signal->theData[2] = retRef;
- signal->theData[3] = retData;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
-}//Dbdih::initialiseRecordsLab()
-
-/*************************************************************************/
-/* INSERT THE NODE INTO THE LINKED LIST OF NODES INVOLVED ALL */
-/* DISTRIBUTED PROTOCOLS (EXCEPT GCP PROTOCOL THAT USES THE DIH */
-/* LINKED LIST INSTEAD). */
-/*************************************************************************/
-void Dbdih::insertAlive(NodeRecordPtr newNodePtr)
-{
- NodeRecordPtr nodePtr;
-
- nodePtr.i = cfirstAliveNode;
- if (nodePtr.i == RNIL) {
- jam();
- cfirstAliveNode = newNodePtr.i;
- } else {
- do {
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nextNode == RNIL) {
- jam();
- nodePtr.p->nextNode = newNodePtr.i;
- break;
- } else {
- jam();
- nodePtr.i = nodePtr.p->nextNode;
- }//if
- } while (1);
- }//if
- newNodePtr.p->nextNode = RNIL;
-}//Dbdih::insertAlive()
-
-void Dbdih::insertBackup(FragmentstorePtr fragPtr, Uint32 nodeId)
-{
- for (Uint32 i = fragPtr.p->fragReplicas; i > 1; i--) {
- jam();
- ndbrequire(i < MAX_REPLICAS && i > 0);
- fragPtr.p->activeNodes[i] = fragPtr.p->activeNodes[i - 1];
- }//for
- fragPtr.p->activeNodes[1] = nodeId;
- fragPtr.p->fragReplicas++;
-}//Dbdih::insertBackup()
-
-void Dbdih::insertDeadNode(NodeRecordPtr newNodePtr)
-{
- NodeRecordPtr nodePtr;
-
- nodePtr.i = cfirstDeadNode;
- if (nodePtr.i == RNIL) {
- jam();
- cfirstDeadNode = newNodePtr.i;
- } else {
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nextNode == RNIL) {
- jam();
- nodePtr.p->nextNode = newNodePtr.i;
- break;
- } else {
- jam();
- nodePtr.i = nodePtr.p->nextNode;
- }//if
- } while (1);
- }//if
- newNodePtr.p->nextNode = RNIL;
-}//Dbdih::insertDeadNode()
-
-void Dbdih::linkOldStoredReplica(FragmentstorePtr fragPtr,
- ReplicaRecordPtr replicatePtr)
-{
- ReplicaRecordPtr losReplicaPtr;
-
- replicatePtr.p->nextReplica = RNIL;
- fragPtr.p->noOldStoredReplicas++;
- losReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- if (losReplicaPtr.i == RNIL) {
- jam();
- fragPtr.p->oldStoredReplicas = replicatePtr.i;
- return;
- }//if
- ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
- while (losReplicaPtr.p->nextReplica != RNIL) {
- jam();
- losReplicaPtr.i = losReplicaPtr.p->nextReplica;
- ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
- }//if
- losReplicaPtr.p->nextReplica = replicatePtr.i;
-}//Dbdih::linkOldStoredReplica()
-
-void Dbdih::linkStoredReplica(FragmentstorePtr fragPtr,
- ReplicaRecordPtr replicatePtr)
-{
- ReplicaRecordPtr lsrReplicaPtr;
-
- fragPtr.p->noStoredReplicas++;
- replicatePtr.p->nextReplica = RNIL;
- lsrReplicaPtr.i = fragPtr.p->storedReplicas;
- if (fragPtr.p->storedReplicas == RNIL) {
- jam();
- fragPtr.p->storedReplicas = replicatePtr.i;
- return;
- }//if
- ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
- while (lsrReplicaPtr.p->nextReplica != RNIL) {
- jam();
- lsrReplicaPtr.i = lsrReplicaPtr.p->nextReplica;
- ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
- }//if
- lsrReplicaPtr.p->nextReplica = replicatePtr.i;
-}//Dbdih::linkStoredReplica()
-
-/*************************************************************************/
-/* MAKE NODE GROUPS BASED ON THE LIST OF NODES RECEIVED FROM CNTR */
-/*************************************************************************/
-void Dbdih::makeNodeGroups(Uint32 nodeArray[])
-{
- NodeRecordPtr mngNodeptr;
- Uint32 tmngNode;
- Uint32 tmngNodeGroup;
- Uint32 tmngLimit;
- Uint32 i, j;
-
- /**-----------------------------------------------------------------------
- * ASSIGN ALL ACTIVE NODES INTO NODE GROUPS. HOT SPARE NODES ARE ASSIGNED
- * TO NODE GROUP ZNIL
- *-----------------------------------------------------------------------*/
- tmngNodeGroup = 0;
- tmngLimit = csystemnodes - cnoHotSpare;
- ndbrequire(tmngLimit < MAX_NDB_NODES);
- for (i = 0; i < tmngLimit; i++) {
- NodeGroupRecordPtr NGPtr;
- jam();
- tmngNode = nodeArray[i];
- mngNodeptr.i = tmngNode;
- ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
- mngNodeptr.p->nodeGroup = tmngNodeGroup;
- NGPtr.i = tmngNodeGroup;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- arrGuard(NGPtr.p->nodeCount, MAX_REPLICAS);
- NGPtr.p->nodesInGroup[NGPtr.p->nodeCount++] = mngNodeptr.i;
- if (NGPtr.p->nodeCount == cnoReplicas) {
- jam();
- tmngNodeGroup++;
- }//if
- }//for
- cnoOfNodeGroups = tmngNodeGroup;
- ndbrequire(csystemnodes < MAX_NDB_NODES);
- for (i = tmngLimit + 1; i < csystemnodes; i++) {
- jam();
- tmngNode = nodeArray[i];
- mngNodeptr.i = tmngNode;
- ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
- mngNodeptr.p->nodeGroup = ZNIL;
- }//for
- for(i = 0; i < MAX_NDB_NODES; i++){
- jam();
- Sysfile::setNodeGroup(i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
- }//for
- for (mngNodeptr.i = 1; mngNodeptr.i < MAX_NDB_NODES; mngNodeptr.i++) {
- jam();
- ptrAss(mngNodeptr, nodeRecord);
- if (mngNodeptr.p->nodeGroup != ZNIL) {
- jam();
- Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups, mngNodeptr.p->nodeGroup);
- }//if
- }//for
-
- for (i = 0; i<cnoOfNodeGroups; i++)
- {
- jam();
- bool alive = false;
- NodeGroupRecordPtr NGPtr;
- NGPtr.i = i;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- for (j = 0; j<NGPtr.p->nodeCount; j++)
- {
- jam();
- mngNodeptr.i = NGPtr.p->nodesInGroup[j];
- ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
- if (checkNodeAlive(NGPtr.p->nodesInGroup[j]))
- {
- alive = true;
- break;
- }
- }
-
- if (!alive)
- {
- char buf[255];
- BaseString::snprintf
- (buf, sizeof(buf),
- "Illegal initial start, no alive node in nodegroup %u", i);
- progError(__LINE__,
- NDBD_EXIT_INSUFFICENT_NODES,
- buf);
-
- }
- }
-}//Dbdih::makeNodeGroups()
-
-/**
- * On node failure QMGR asks DIH about node groups. This is
- * a direct signal (function call in same process). Input is
- * bitmask of surviving nodes. The routine is not concerned
- * about node count. Reply is one of:
- * 1) win - we can survive, and nobody else can
- * 2) lose - we cannot survive
- * 3) partition - we can survive but there could be others
- */
-void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
-{
- jamEntry();
- CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
-
- bool direct = (sd->requestType & CheckNodeGroups::Direct);
- bool ok = false;
- switch(sd->requestType & ~CheckNodeGroups::Direct){
- case CheckNodeGroups::ArbitCheck:{
- ok = true;
- jam();
- unsigned missall = 0;
- unsigned haveall = 0;
- for (Uint32 i = 0; i < cnoOfNodeGroups; i++) {
- jam();
- NodeGroupRecordPtr ngPtr;
- ngPtr.i = i;
- ptrAss(ngPtr, nodeGroupRecord);
- Uint32 count = 0;
- for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
- jam();
- Uint32 nodeId = ngPtr.p->nodesInGroup[j];
- if (sd->mask.get(nodeId)) {
- jam();
- count++;
- }//if
- }//for
- if (count == 0) {
- jam();
- missall++;
- }//if
- if (count == ngPtr.p->nodeCount) {
- haveall++;
- }//if
- }//for
-
- if (missall) {
- jam();
- sd->output = CheckNodeGroups::Lose;
- } else if (haveall) {
- jam();
- sd->output = CheckNodeGroups::Win;
- } else {
- jam();
- sd->output = CheckNodeGroups::Partitioning;
- }//if
- }
- break;
- case CheckNodeGroups::GetNodeGroup:
- ok = true;
- sd->output = Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
- break;
- case CheckNodeGroups::GetNodeGroupMembers: {
- ok = true;
- Uint32 ownNodeGroup =
- Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
-
- sd->output = ownNodeGroup;
- sd->mask.clear();
-
- NodeGroupRecordPtr ngPtr;
- ngPtr.i = ownNodeGroup;
- ptrAss(ngPtr, nodeGroupRecord);
- for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
- jam();
- sd->mask.set(ngPtr.p->nodesInGroup[j]);
- }
-#if 0
- for (int i = 0; i < MAX_NDB_NODES; i++) {
- if (ownNodeGroup ==
- Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) {
- sd->mask.set(i);
- }
- }
-#endif
- }
- break;
- }
- ndbrequire(ok);
-
- if (!direct)
- sendSignal(sd->blockRef, GSN_CHECKNODEGROUPSCONF, signal,
- CheckNodeGroups::SignalLength, JBB);
-}//Dbdih::execCHECKNODEGROUPSREQ()
-
-void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[])
-{
- cfirstAliveNode = RNIL;
- ndbrequire(con_lineNodes > 0);
- ndbrequire(csystemnodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < csystemnodes; i++) {
- NodeRecordPtr nodePtr;
- jam();
- nodePtr.i = nodeArray[i];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- new (nodePtr.p) NodeRecord();
- if (NodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
- jam();
- nodePtr.p->nodeStatus = NodeRecord::ALIVE;
- nodePtr.p->useInTransactions = true;
- nodePtr.p->copyCompleted = true;
- nodePtr.p->m_inclDihLcp = true;
- insertAlive(nodePtr);
- } else {
- jam();
- nodePtr.p->nodeStatus = NodeRecord::DEAD;
- insertDeadNode(nodePtr);
- }//if
- }//for
-}//Dbdih::makePrnList()
-
-/*************************************************************************/
-/* A NEW CRASHED REPLICA IS ADDED BY A NODE FAILURE. */
-/*************************************************************************/
-void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
-{
- /*----------------------------------------------------------------------*/
- /* SET THE REPLICA_LAST_GCI OF THE CRASHED REPLICA TO LAST GCI */
- /* EXECUTED BY THE FAILED NODE. */
- /*----------------------------------------------------------------------*/
- /* WE HAVE A NEW CRASHED REPLICA. INITIATE CREATE GCI TO INDICATE */
- /* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
- /* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
- /*----------------------------------------------------------------------*/
- Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
- arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
- NDBD_EXIT_MAX_CRASHED_REPLICAS);
- ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
- lastGCI;
- ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
- ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
- ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
- (Uint32)-1;
-
- if (ncrReplicaPtr.p->noCrashedReplicas == 7 && lastGCI)
- {
- jam();
- SYSFILE->lastCompletedGCI[nodeId] = 0;
- warningEvent("Making filesystem for node %d unusable (need --initial)",
- nodeId);
- }
-}//Dbdih::newCrashedReplica()
-
-/*************************************************************************/
-/* AT NODE FAILURE DURING START OF A NEW NODE WE NEED TO RESET A */
-/* SET OF VARIABLES CONTROLLING THE START AND INDICATING ONGOING */
-/* START OF A NEW NODE. */
-/*************************************************************************/
-void Dbdih::nodeResetStart()
-{
- jam();
- c_nodeStartSlave.nodeId = 0;
- c_nodeStartMaster.startNode = RNIL;
- c_nodeStartMaster.failNr = cfailurenr;
- c_nodeStartMaster.activeState = false;
- c_nodeStartMaster.blockGcp = false;
- c_nodeStartMaster.blockLcp = false;
- c_nodeStartMaster.m_outstandingGsn = 0;
-}//Dbdih::nodeResetStart()
-
-void Dbdih::openFileRw(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_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()
-
-/*************************************************************************/
-/* REMOVE A CRASHED REPLICA BY PACKING THE ARRAY OF CREATED GCI AND*/
-/* THE LAST GCI OF THE CRASHED REPLICA. */
-/*************************************************************************/
-void Dbdih::packCrashedReplicas(ReplicaRecordPtr replicaPtr)
-{
- ndbrequire(replicaPtr.p->noCrashedReplicas > 0);
- ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
- for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
- jam();
- replicaPtr.p->createGci[i] = replicaPtr.p->createGci[i + 1];
- replicaPtr.p->replicaLastGci[i] = replicaPtr.p->replicaLastGci[i + 1];
- }//for
- replicaPtr.p->noCrashedReplicas--;
-
-#ifdef VM_TRACE
- for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
- jam();
- ndbrequire(replicaPtr.p->createGci[i] != 0xF1F1F1F1);
- ndbrequire(replicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
- }//for
-#endif
-}//Dbdih::packCrashedReplicas()
-
-void Dbdih::prepareReplicas(FragmentstorePtr fragPtr)
-{
- ReplicaRecordPtr prReplicaPtr;
- Uint32 prevReplica = RNIL;
-
- /* --------------------------------------------------------------------- */
- /* BEGIN BY LINKING ALL REPLICA RECORDS ONTO THE OLD STORED REPLICA*/
- /* LIST. */
- /* AT A SYSTEM RESTART OBVIOUSLY ALL NODES ARE OLD. */
- /* --------------------------------------------------------------------- */
- prReplicaPtr.i = fragPtr.p->storedReplicas;
- while (prReplicaPtr.i != RNIL) {
- jam();
- prevReplica = prReplicaPtr.i;
- ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
- prReplicaPtr.i = prReplicaPtr.p->nextReplica;
- }//while
- /* --------------------------------------------------------------------- */
- /* LIST OF STORED REPLICAS WILL BE EMPTY NOW. */
- /* --------------------------------------------------------------------- */
- if (prevReplica != RNIL) {
- prReplicaPtr.i = prevReplica;
- ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
- prReplicaPtr.p->nextReplica = fragPtr.p->oldStoredReplicas;
- fragPtr.p->oldStoredReplicas = fragPtr.p->storedReplicas;
- fragPtr.p->storedReplicas = RNIL;
- fragPtr.p->noOldStoredReplicas += fragPtr.p->noStoredReplicas;
- fragPtr.p->noStoredReplicas = 0;
- }//if
-}//Dbdih::prepareReplicas()
-
-void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
-{
- Uint32 TreadFid = readPageWord(rf);
- fragPtr.p->preferredPrimary = readPageWord(rf);
- fragPtr.p->noStoredReplicas = readPageWord(rf);
- fragPtr.p->noOldStoredReplicas = readPageWord(rf);
- Uint32 TdistKey = readPageWord(rf);
-
- ndbrequire(fragPtr.p->noStoredReplicas > 0);
- ndbrequire(TreadFid == rf->fragId);
- ndbrequire(TdistKey < 256);
- if ((cstarttype == NodeState::ST_NODE_RESTART) ||
- (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- fragPtr.p->distributionKey = TdistKey;
- }//if
-
- fragPtr.p->m_log_part_id = readPageWord(rf);
-}//Dbdih::readFragment()
-
-Uint32 Dbdih::readPageWord(RWFragment* rf)
-{
- if (rf->wordIndex >= 2048) {
- jam();
- ndbrequire(rf->wordIndex == 2048);
- rf->pageIndex++;
- ndbrequire(rf->pageIndex < 8);
- rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
- ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
- rf->wordIndex = 32;
- }//if
- Uint32 dataWord = rf->rwfPageptr.p->word[rf->wordIndex];
- rf->wordIndex++;
- return dataWord;
-}//Dbdih::readPageWord()
-
-void Dbdih::readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr)
-{
- Uint32 i;
- readReplicaPtr.p->procNode = readPageWord(rf);
- readReplicaPtr.p->initialGci = readPageWord(rf);
- readReplicaPtr.p->noCrashedReplicas = readPageWord(rf);
- readReplicaPtr.p->nextLcp = readPageWord(rf);
-
- for (i = 0; i < MAX_LCP_STORED; i++) {
- readReplicaPtr.p->maxGciCompleted[i] = readPageWord(rf);
- readReplicaPtr.p->maxGciStarted[i] = readPageWord(rf);
- readReplicaPtr.p->lcpId[i] = readPageWord(rf);
- readReplicaPtr.p->lcpStatus[i] = readPageWord(rf);
- }//for
- const Uint32 noCrashedReplicas = readReplicaPtr.p->noCrashedReplicas;
- ndbrequire(noCrashedReplicas < 8);
- for (i = 0; i < noCrashedReplicas; i++) {
- readReplicaPtr.p->createGci[i] = readPageWord(rf);
- readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
- ndbrequire(readReplicaPtr.p->createGci[i] != 0xF1F1F1F1);
- ndbrequire(readReplicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
- }//for
- for(i = noCrashedReplicas; i<8; i++){
- readReplicaPtr.p->createGci[i] = readPageWord(rf);
- readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
- // They are not initialized...
- readReplicaPtr.p->createGci[i] = 0;
- readReplicaPtr.p->replicaLastGci[i] = ~0;
- }
- /* ---------------------------------------------------------------------- */
- /* IF THE LAST COMPLETED LOCAL CHECKPOINT IS VALID AND LARGER THAN */
- /* THE LAST COMPLETED CHECKPOINT THEN WE WILL INVALIDATE THIS LOCAL */
- /* CHECKPOINT FOR THIS REPLICA. */
- /* ---------------------------------------------------------------------- */
- Uint32 trraLcp = prevLcpNo(readReplicaPtr.p->nextLcp);
- ndbrequire(trraLcp < MAX_LCP_STORED);
- if ((readReplicaPtr.p->lcpStatus[trraLcp] == ZVALID) &&
- (readReplicaPtr.p->lcpId[trraLcp] > SYSFILE->latestLCP_ID)) {
- jam();
- readReplicaPtr.p->lcpStatus[trraLcp] = ZINVALID;
- }//if
- /* ---------------------------------------------------------------------- */
- /* WE ALSO HAVE TO INVALIDATE ANY LOCAL CHECKPOINTS THAT HAVE BEEN */
- /* INVALIDATED BY MOVING BACK THE RESTART GCI. */
- /* ---------------------------------------------------------------------- */
- for (i = 0; i < MAX_LCP_STORED; i++) {
- jam();
- if ((readReplicaPtr.p->lcpStatus[i] == ZVALID) &&
- (readReplicaPtr.p->maxGciStarted[i] > SYSFILE->newestRestorableGCI)) {
- jam();
- readReplicaPtr.p->lcpStatus[i] = ZINVALID;
- }//if
- }//for
- /* ---------------------------------------------------------------------- */
- /* WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED */
- /* THAT ARE NO LONGER VALID DUE TO MOVING RESTART GCI BACKWARDS. */
- /* ---------------------------------------------------------------------- */
- removeTooNewCrashedReplicas(readReplicaPtr);
- /* ---------------------------------------------------------------------- */
- /* WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED */
- /* THAT ARE NO LONGER VALID SINCE THEY ARE NO LONGER RESTORABLE. */
- /* ---------------------------------------------------------------------- */
- removeOldCrashedReplicas(readReplicaPtr);
- /* --------------------------------------------------------------------- */
- // We set the last GCI of the replica that was alive before the node
- // crashed last time. We set it to the last GCI which the node participated in.
- /* --------------------------------------------------------------------- */
- ndbrequire(readReplicaPtr.p->noCrashedReplicas < 8);
- readReplicaPtr.p->replicaLastGci[readReplicaPtr.p->noCrashedReplicas] =
- SYSFILE->lastCompletedGCI[readReplicaPtr.p->procNode];
- /* ---------------------------------------------------------------------- */
- /* FIND PROCESSOR RECORD */
- /* ---------------------------------------------------------------------- */
-}//Dbdih::readReplica()
-
-void Dbdih::readReplicas(RWFragment* rf, FragmentstorePtr fragPtr)
-{
- Uint32 i;
- ReplicaRecordPtr newReplicaPtr;
- Uint32 noStoredReplicas = fragPtr.p->noStoredReplicas;
- Uint32 noOldStoredReplicas = fragPtr.p->noOldStoredReplicas;
- /* ----------------------------------------------------------------------- */
- /* WE CLEAR THE NUMBER OF STORED REPLICAS SINCE IT WILL BE CALCULATED */
- /* BY THE LINKING SUBROUTINES. */
- /* ----------------------------------------------------------------------- */
- fragPtr.p->noStoredReplicas = 0;
- fragPtr.p->noOldStoredReplicas = 0;
- Uint32 replicaIndex = 0;
- ndbrequire(noStoredReplicas + noOldStoredReplicas <= MAX_REPLICAS);
- for (i = 0; i < noStoredReplicas; i++) {
- seizeReplicaRec(newReplicaPtr);
- readReplica(rf, newReplicaPtr);
- if (checkNodeAlive(newReplicaPtr.p->procNode)) {
- jam();
- ndbrequire(replicaIndex < MAX_REPLICAS);
- fragPtr.p->activeNodes[replicaIndex] = newReplicaPtr.p->procNode;
- replicaIndex++;
- linkStoredReplica(fragPtr, newReplicaPtr);
- } else {
- jam();
- linkOldStoredReplica(fragPtr, newReplicaPtr);
- }//if
- }//for
- fragPtr.p->fragReplicas = noStoredReplicas;
- for (i = 0; i < noOldStoredReplicas; i++) {
- jam();
- seizeReplicaRec(newReplicaPtr);
- readReplica(rf, newReplicaPtr);
- linkOldStoredReplica(fragPtr, newReplicaPtr);
- }//for
-}//Dbdih::readReplicas()
-
-void Dbdih::readRestorableGci(Signal* signal, FileRecordPtr filePtr)
-{
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS;
- signal->theData[4] = ZVAR_NO_CRESTART_INFO;
- signal->theData[5] = 1;
- signal->theData[6] = 0;
- signal->theData[7] = 0;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
-}//Dbdih::readRestorableGci()
-
-void Dbdih::readTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
-{
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS;
- signal->theData[4] = ZVAR_NO_WORD;
- signal->theData[5] = tab->noPages;
- for (Uint32 i = 0; i < tab->noPages; i++) {
- signal->theData[6 + (2 * i)] = tab->pageRef[i];
- signal->theData[7 + (2 * i)] = i;
- }//for
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 22, JBA);
-}//Dbdih::readTabfile()
-
-void Dbdih::releasePage(Uint32 pageIndex)
-{
- PageRecordPtr pagePtr;
- pagePtr.i = pageIndex;
- ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
- pagePtr.p->nextfreepage = cfirstfreepage;
- cfirstfreepage = pagePtr.i;
-}//Dbdih::releasePage()
-
-void Dbdih::releaseTabPages(Uint32 tableId)
-{
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
- ndbrequire(tabPtr.p->noPages <= 8);
- for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
- jam();
- releasePage(tabPtr.p->pageRef[i]);
- }//for
- tabPtr.p->noPages = 0;
-}//Dbdih::releaseTabPages()
-
-/*************************************************************************/
-/* REMOVE NODE FROM SET OF ALIVE NODES. */
-/*************************************************************************/
-void Dbdih::removeAlive(NodeRecordPtr removeNodePtr)
-{
- NodeRecordPtr nodePtr;
-
- nodePtr.i = cfirstAliveNode;
- if (nodePtr.i == removeNodePtr.i) {
- jam();
- cfirstAliveNode = removeNodePtr.p->nextNode;
- return;
- }//if
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nextNode == removeNodePtr.i) {
- jam();
- nodePtr.p->nextNode = removeNodePtr.p->nextNode;
- break;
- } else {
- jam();
- nodePtr.i = nodePtr.p->nextNode;
- }//if
- } while (1);
-}//Dbdih::removeAlive()
-
-/*************************************************************************/
-/* REMOVE NODE FROM SET OF DEAD NODES. */
-/*************************************************************************/
-void Dbdih::removeDeadNode(NodeRecordPtr removeNodePtr)
-{
- NodeRecordPtr nodePtr;
-
- nodePtr.i = cfirstDeadNode;
- if (nodePtr.i == removeNodePtr.i) {
- jam();
- cfirstDeadNode = removeNodePtr.p->nextNode;
- return;
- }//if
- do {
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nextNode == removeNodePtr.i) {
- jam();
- nodePtr.p->nextNode = removeNodePtr.p->nextNode;
- break;
- } else {
- jam();
- nodePtr.i = nodePtr.p->nextNode;
- }//if
- } while (1);
-}//Dbdih::removeDeadNode()
-
-/*---------------------------------------------------------------*/
-/* REMOVE REPLICAS OF A FAILED NODE FROM LIST OF STORED */
-/* REPLICAS AND MOVE IT TO THE LIST OF OLD STORED REPLICAS.*/
-/* ALSO UPDATE THE CRASHED REPLICA INFORMATION. */
-/*---------------------------------------------------------------*/
-void Dbdih::removeNodeFromStored(Uint32 nodeId,
- FragmentstorePtr fragPtr,
- ReplicaRecordPtr replicatePtr,
- bool temporary)
-{
- if (!temporary)
- {
- jam();
- newCrashedReplica(nodeId, replicatePtr);
- }
- else
- {
- jam();
- }
- removeStoredReplica(fragPtr, replicatePtr);
- linkOldStoredReplica(fragPtr, replicatePtr);
- ndbrequire(fragPtr.p->storedReplicas != RNIL);
-}//Dbdih::removeNodeFromStored()
-
-/*************************************************************************/
-/* REMOVE ANY OLD CRASHED REPLICAS THAT ARE NOT RESTORABLE ANY MORE*/
-/*************************************************************************/
-void Dbdih::removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr)
-{
- while (rocReplicaPtr.p->noCrashedReplicas > 0) {
- jam();
- /* --------------------------------------------------------------------- */
- /* ONLY IF THERE IS AT LEAST ONE REPLICA THEN CAN WE REMOVE ANY. */
- /* --------------------------------------------------------------------- */
- if (rocReplicaPtr.p->replicaLastGci[0] < SYSFILE->oldestRestorableGCI){
- jam();
- /* ------------------------------------------------------------------- */
- /* THIS CRASHED REPLICA HAS BECOME EXTINCT AND MUST BE REMOVED TO */
- /* GIVE SPACE FOR NEW CRASHED REPLICAS. */
- /* ------------------------------------------------------------------- */
- packCrashedReplicas(rocReplicaPtr);
- } else {
- break;
- }//if
- }//while
- if (rocReplicaPtr.p->createGci[0] < SYSFILE->keepGCI){
- jam();
- /* --------------------------------------------------------------------- */
- /* MOVE FORWARD THE CREATE GCI TO A GCI THAT CAN BE USED. WE HAVE */
- /* NO CERTAINTY IN FINDING ANY LOG RECORDS FROM OLDER GCI'S. */
- /* --------------------------------------------------------------------- */
- rocReplicaPtr.p->createGci[0] = SYSFILE->keepGCI;
- ndbrequire(SYSFILE->keepGCI != 0xF1F1F1F1);
- }//if
-}//Dbdih::removeOldCrashedReplicas()
-
-void Dbdih::removeOldStoredReplica(FragmentstorePtr fragPtr,
- ReplicaRecordPtr replicatePtr)
-{
- ReplicaRecordPtr rosTmpReplicaPtr;
- ReplicaRecordPtr rosPrevReplicaPtr;
-
- fragPtr.p->noOldStoredReplicas--;
- if (fragPtr.p->oldStoredReplicas == replicatePtr.i) {
- jam();
- fragPtr.p->oldStoredReplicas = replicatePtr.p->nextReplica;
- } else {
- rosPrevReplicaPtr.i = fragPtr.p->oldStoredReplicas;
- ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
- rosTmpReplicaPtr.i = rosPrevReplicaPtr.p->nextReplica;
- while (rosTmpReplicaPtr.i != replicatePtr.i) {
- jam();
- rosPrevReplicaPtr.i = rosTmpReplicaPtr.i;
- ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
- ptrCheckGuard(rosTmpReplicaPtr, creplicaFileSize, replicaRecord);
- rosTmpReplicaPtr.i = rosTmpReplicaPtr.p->nextReplica;
- }//if
- rosPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
- }//if
-}//Dbdih::removeOldStoredReplica()
-
-void Dbdih::removeStoredReplica(FragmentstorePtr fragPtr,
- ReplicaRecordPtr replicatePtr)
-{
- ReplicaRecordPtr rsrTmpReplicaPtr;
- ReplicaRecordPtr rsrPrevReplicaPtr;
-
- fragPtr.p->noStoredReplicas--;
- if (fragPtr.p->storedReplicas == replicatePtr.i) {
- jam();
- fragPtr.p->storedReplicas = replicatePtr.p->nextReplica;
- } else {
- jam();
- rsrPrevReplicaPtr.i = fragPtr.p->storedReplicas;
- rsrTmpReplicaPtr.i = fragPtr.p->storedReplicas;
- ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
- rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
- while (rsrTmpReplicaPtr.i != replicatePtr.i) {
- jam();
- rsrPrevReplicaPtr.i = rsrTmpReplicaPtr.i;
- ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
- rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
- }//while
- ptrCheckGuard(rsrPrevReplicaPtr, creplicaFileSize, replicaRecord);
- rsrPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
- }//if
-}//Dbdih::removeStoredReplica()
-
-/*************************************************************************/
-/* REMOVE ALL TOO NEW CRASHED REPLICAS THAT IS IN THIS REPLICA. */
-/*************************************************************************/
-void Dbdih::removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr)
-{
- while (rtnReplicaPtr.p->noCrashedReplicas > 0) {
- jam();
- /* --------------------------------------------------------------------- */
- /* REMOVE ALL REPLICAS THAT ONLY LIVED IN A PERIOD THAT HAVE BEEN */
- /* REMOVED FROM THE RESTART INFORMATION SINCE THE RESTART FAILED */
- /* TOO MANY TIMES. */
- /* --------------------------------------------------------------------- */
- arrGuard(rtnReplicaPtr.p->noCrashedReplicas - 1, 8);
- if (rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] >
- SYSFILE->newestRestorableGCI){
- jam();
- rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
- (Uint32)-1;
- rtnReplicaPtr.p->replicaLastGci[rtnReplicaPtr.p->noCrashedReplicas - 1] =
- (Uint32)-1;
- rtnReplicaPtr.p->noCrashedReplicas--;
- } else {
- break;
- }//if
- }//while
-}//Dbdih::removeTooNewCrashedReplicas()
-
-/*************************************************************************/
-/* */
-/* MODULE: SEARCH FOR POSSIBLE REPLICAS THAT CAN HANDLE THE GLOBAL */
-/* CHECKPOINT WITHOUT NEEDING ANY EXTRA LOGGING FACILITIES.*/
-/* A MAXIMUM OF FOUR NODES IS RETRIEVED. */
-/*************************************************************************/
-bool
-Dbdih::setup_create_replica(FragmentstorePtr fragPtr,
- CreateReplicaRecord* createReplicaPtrP,
- ConstPtr<ReplicaRecord> replicaPtr)
-{
- createReplicaPtrP->dataNodeId = replicaPtr.p->procNode;
- createReplicaPtrP->replicaRec = replicaPtr.i;
-
- /* ----------------------------------------------------------------- */
- /* WE NEED TO SEARCH FOR A PROPER LOCAL CHECKPOINT TO USE FOR THE */
- /* SYSTEM RESTART. */
- /* ----------------------------------------------------------------- */
- Uint32 startGci;
- Uint32 startLcpNo;
- Uint32 stopGci = SYSFILE->newestRestorableGCI;
- bool result = findStartGci(replicaPtr,
- stopGci,
- startGci,
- startLcpNo);
- if (!result)
- {
- jam();
- /* --------------------------------------------------------------- */
- /* WE COULD NOT FIND ANY LOCAL CHECKPOINT. THE FRAGMENT THUS DO NOT*/
- /* CONTAIN ANY VALID LOCAL CHECKPOINT. IT DOES HOWEVER CONTAIN A */
- /* VALID FRAGMENT LOG. THUS BY FIRST CREATING THE FRAGMENT AND THEN*/
- /* EXECUTING THE FRAGMENT LOG WE CAN CREATE THE FRAGMENT AS */
- /* DESIRED. THIS SHOULD ONLY OCCUR AFTER CREATING A FRAGMENT. */
- /* */
- /* TO INDICATE THAT NO LOCAL CHECKPOINT IS TO BE USED WE SET THE */
- /* LOCAL CHECKPOINT TO ZNIL. */
- /* --------------------------------------------------------------- */
- createReplicaPtrP->lcpNo = ZNIL;
- }
- else
- {
- jam();
- /* --------------------------------------------------------------- */
- /* WE FOUND A PROPER LOCAL CHECKPOINT TO RESTART FROM. */
- /* SET LOCAL CHECKPOINT ID AND LOCAL CHECKPOINT NUMBER. */
- /* --------------------------------------------------------------- */
- createReplicaPtrP->lcpNo = startLcpNo;
- arrGuard(startLcpNo, MAX_LCP_STORED);
- createReplicaPtrP->createLcpId = replicaPtr.p->lcpId[startLcpNo];
- }//if
-
-
- /* ----------------------------------------------------------------- */
- /* WE HAVE EITHER FOUND A LOCAL CHECKPOINT OR WE ARE PLANNING TO */
- /* EXECUTE THE LOG FROM THE INITIAL CREATION OF THE TABLE. IN BOTH */
- /* CASES WE NEED TO FIND A SET OF LOGS THAT CAN EXECUTE SUCH THAT */
- /* WE RECOVER TO THE SYSTEM RESTART GLOBAL CHECKPOINT. */
- /* -_--------------------------------------------------------------- */
- return findLogNodes(createReplicaPtrP, fragPtr, startGci, stopGci);
-}
-
-void Dbdih::searchStoredReplicas(FragmentstorePtr fragPtr)
-{
- Uint32 nextReplicaPtrI;
- Ptr<ReplicaRecord> replicaPtr;
-
- replicaPtr.i = fragPtr.p->storedReplicas;
- while (replicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- nextReplicaPtrI = replicaPtr.p->nextReplica;
- ConstPtr<ReplicaRecord> constReplicaPtr;
- constReplicaPtr.i = replicaPtr.i;
- constReplicaPtr.p = replicaPtr.p;
- NodeRecordPtr nodePtr;
- nodePtr.i = replicaPtr.p->procNode;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
- jam();
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- case Sysfile::NS_ActiveMissed_2:{
- /* ----------------------------------------------------------------- */
- /* INITIALISE THE CREATE REPLICA STRUCTURE THAT IS USED FOR SENDING*/
- /* TO LQH START_FRAGREQ. */
- /* SET THE DATA NODE WHERE THE LOCAL CHECKPOINT IS FOUND. ALSO */
- /* SET A REFERENCE TO THE REPLICA POINTER OF THAT. */
- /* ----------------------------------------------------------------- */
- CreateReplicaRecordPtr createReplicaPtr;
- createReplicaPtr.i = cnoOfCreateReplicas;
- ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
- cnoOfCreateReplicas++;
-
- /**
- * Should have been checked in resetReplicaSr
- */
- ndbrequire(setup_create_replica(fragPtr,
- createReplicaPtr.p,
- constReplicaPtr));
- break;
- }
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- }
- replicaPtr.i = nextReplicaPtrI;
- }//while
-}//Dbdih::searchStoredReplicas()
-
-/*************************************************************************/
-/* */
-/* MODULE: SEIZE_FILE */
-/* DESCRIPTION: THE SUBROUTINE SEIZES A FILE RECORD FROM THE */
-/* FREE LIST. */
-/*************************************************************************/
-void Dbdih::seizeFile(FileRecordPtr& filePtr)
-{
- filePtr.i = cfirstfreeFile;
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- cfirstfreeFile = filePtr.p->nextFile;
- filePtr.p->nextFile = RNIL;
-}//Dbdih::seizeFile()
-
-/*************************************************************************/
-/* SEND CREATE_FRAGREQ TO ALL NODES IN THE NDB CLUSTER. */
-/*************************************************************************/
-/*************************************************************************/
-/* */
-/* MODULE: FIND THE START GCI AND LOCAL CHECKPOINT TO USE. */
-/*************************************************************************/
-void Dbdih::sendStartFragreq(Signal* signal,
- TabRecordPtr tabPtr, Uint32 fragId)
-{
- CreateReplicaRecordPtr replicaPtr;
- for (replicaPtr.i = 0; replicaPtr.i < cnoOfCreateReplicas; replicaPtr.i++) {
- jam();
- ptrAss(replicaPtr, createReplicaRecord);
- BlockReference ref = calcLqhBlockRef(replicaPtr.p->dataNodeId);
- StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
- startFragReq->userPtr = replicaPtr.p->replicaRec;
- startFragReq->userRef = reference();
- startFragReq->lcpNo = replicaPtr.p->lcpNo;
- startFragReq->lcpId = replicaPtr.p->createLcpId;
- startFragReq->tableId = tabPtr.i;
- startFragReq->fragId = fragId;
-
- if(ERROR_INSERTED(7072) || ERROR_INSERTED(7074)){
- jam();
- const Uint32 noNodes = replicaPtr.p->noLogNodes;
- Uint32 start = replicaPtr.p->logStartGci[noNodes - 1];
- const Uint32 stop = replicaPtr.p->logStopGci[noNodes - 1];
-
- for(Uint32 i = noNodes; i < 4 && (stop - start) > 0; i++){
- replicaPtr.p->noLogNodes++;
- replicaPtr.p->logStopGci[i - 1] = start;
-
- replicaPtr.p->logNodeId[i] = replicaPtr.p->logNodeId[i-1];
- replicaPtr.p->logStartGci[i] = start + 1;
- replicaPtr.p->logStopGci[i] = stop;
- start += 1;
- }
- }
-
- startFragReq->noOfLogNodes = replicaPtr.p->noLogNodes;
-
- for (Uint32 i = 0; i < 4 ; i++) {
- startFragReq->lqhLogNode[i] = replicaPtr.p->logNodeId[i];
- startFragReq->startGci[i] = replicaPtr.p->logStartGci[i];
- startFragReq->lastGci[i] = replicaPtr.p->logStopGci[i];
- }//for
-
- sendSignal(ref, GSN_START_FRAGREQ, signal,
- StartFragReq::SignalLength, JBB);
- }//for
-}//Dbdih::sendStartFragreq()
-
-/*************************************************************************/
-/* SET THE INITIAL ACTIVE STATUS ON ALL NODES AND PUT INTO LISTS. */
-/*************************************************************************/
-void Dbdih::setInitialActiveStatus()
-{
- NodeRecordPtr siaNodeptr;
- Uint32 tsiaNoActiveNodes;
-
- tsiaNoActiveNodes = csystemnodes - cnoHotSpare;
- for(Uint32 i = 0; i<Sysfile::NODE_STATUS_SIZE; i++)
- SYSFILE->nodeStatus[i] = 0;
- for (siaNodeptr.i = 1; siaNodeptr.i < MAX_NDB_NODES; siaNodeptr.i++) {
- ptrAss(siaNodeptr, nodeRecord);
- switch(siaNodeptr.p->nodeStatus){
- case NodeRecord::ALIVE:
- case NodeRecord::DEAD:
- if (tsiaNoActiveNodes == 0) {
- jam();
- siaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
- } else {
- jam();
- tsiaNoActiveNodes = tsiaNoActiveNodes - 1;
- if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE)
- {
- jam();
- siaNodeptr.p->activeStatus = Sysfile::NS_Active;
- }
- else
- {
- siaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- }
- }
- break;
- default:
- jam();
- siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
- break;
- }//if
- Sysfile::setNodeStatus(siaNodeptr.i,
- SYSFILE->nodeStatus,
- siaNodeptr.p->activeStatus);
- }//for
-}//Dbdih::setInitialActiveStatus()
-
-/*************************************************************************/
-/* SET LCP ACTIVE STATUS AT THE END OF A LOCAL CHECKPOINT. */
-/*************************************************************************/
-void Dbdih::setLcpActiveStatusEnd()
-{
- NodeRecordPtr nodePtr;
-
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- case Sysfile::NS_ActiveMissed_1:
- case Sysfile::NS_ActiveMissed_2:
- jam();
- /*-------------------------------------------------------------------*/
- /* THE NODE PARTICIPATED IN THIS CHECKPOINT.
- * WE CAN SET ITS STATUS TO ACTIVE */
- /*-------------------------------------------------------------------*/
- nodePtr.p->activeStatus = Sysfile::NS_Active;
- takeOverCompleted(nodePtr.i);
- break;
- case Sysfile::NS_TakeOver:
- jam();
- /*-------------------------------------------------------------------*/
- /* THE NODE HAS COMPLETED A CHECKPOINT AFTER TAKE OVER. WE CAN NOW */
- /* SET ITS STATUS TO ACTIVE. WE CAN ALSO COMPLETE THE TAKE OVER */
- /* AND ALSO WE CLEAR THE TAKE OVER NODE IN THE RESTART INFO. */
- /*-------------------------------------------------------------------*/
- nodePtr.p->activeStatus = Sysfile::NS_Active;
- takeOverCompleted(nodePtr.i);
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- }//if
- }//for
-
- if(getNodeState().getNodeRestartInProgress()){
- jam();
- if(c_lcpState.m_participatingLQH.get(getOwnNodeId())){
- nodePtr.i = getOwnNodeId();
- ptrAss(nodePtr, nodeRecord);
- ndbrequire(nodePtr.p->activeStatus == Sysfile::NS_Active);
- g_eventLogger.info("NR: setLcpActiveStatusEnd - m_participatingLQH");
- } else {
- g_eventLogger.info("NR: setLcpActiveStatusEnd - !m_participatingLQH");
- }
- }
-
- c_lcpState.m_participatingDIH.clear();
- c_lcpState.m_participatingLQH.clear();
- if (isMaster()) {
- jam();
- setNodeRestartInfoBits();
- }//if
-}//Dbdih::setLcpActiveStatusEnd()
-
-void Dbdih::takeOverCompleted(Uint32 aNodeId)
-{
- TakeOverRecordPtr takeOverPtr;
- takeOverPtr.i = findTakeOver(aNodeId);
- if (takeOverPtr.i != RNIL) {
- jam();
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- if (takeOverPtr.p->toMasterStatus != TakeOverRecord::WAIT_LCP) {
- jam();
- ndbrequire(!isMaster());
- return;
- }//if
- ndbrequire(isMaster());
- Sysfile::setTakeOverNode(aNodeId, SYSFILE->takeOver, 0);
- takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY;
- cstartGcpNow = true;
- }//if
-}//Dbdih::takeOverCompleted()
-
-/*************************************************************************/
-/* SET LCP ACTIVE STATUS BEFORE STARTING A LOCAL CHECKPOINT. */
-/*************************************************************************/
-void Dbdih::setLcpActiveStatusStart(Signal* signal)
-{
- NodeRecordPtr nodePtr;
-
- c_lcpState.m_participatingLQH.clear();
- c_lcpState.m_participatingDIH.clear();
-
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRecord);
-#if 0
- if(nodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER){
- infoEvent("Node %d nodeStatus=%d activeStatus=%d copyCompleted=%d lcp=%d",
- nodePtr.i,
- nodePtr.p->nodeStatus,
- nodePtr.p->activeStatus,
- nodePtr.p->copyCompleted,
- nodePtr.p->m_inclDihLcp);
- }
-#endif
- if(nodePtr.p->nodeStatus == NodeRecord::ALIVE && nodePtr.p->m_inclDihLcp){
- jam();
- c_lcpState.m_participatingDIH.set(nodePtr.i);
- }
-
- if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
- (nodePtr.p->copyCompleted)) {
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- jam();
- /*-------------------------------------------------------------------*/
- // The normal case. Starting a LCP for a started node which hasn't
- // missed the previous LCP.
- /*-------------------------------------------------------------------*/
- c_lcpState.m_participatingLQH.set(nodePtr.i);
- break;
- case Sysfile::NS_ActiveMissed_1:
- jam();
- /*-------------------------------------------------------------------*/
- // The node is starting up and is participating in a local checkpoint
- // as the final phase of the start-up. We can still use the checkpoints
- // on the node after a system restart.
- /*-------------------------------------------------------------------*/
- c_lcpState.m_participatingLQH.set(nodePtr.i);
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- /*-------------------------------------------------------------------*/
- // The node is starting up and is participating in a local checkpoint
- // as the final phase of the start-up. We have missed so
- // many checkpoints that we no longer can use this node to
- // recreate fragments from disk.
- // It must be taken over with the copy fragment process after a system
- // crash. We indicate this by setting the active status to TAKE_OVER.
- /*-------------------------------------------------------------------*/
- c_lcpState.m_participatingLQH.set(nodePtr.i);
- nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
- //break; // Fall through
- case Sysfile::NS_TakeOver:{
- TakeOverRecordPtr takeOverPtr;
- jam();
- /*-------------------------------------------------------------------*/
- /* THIS NODE IS CURRENTLY TAKING OVER A FAILED NODE. */
- /*-------------------------------------------------------------------*/
- takeOverPtr.i = findTakeOver(nodePtr.i);
- if (takeOverPtr.i != RNIL) {
- jam();
- ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
- if (takeOverPtr.p->toMasterStatus == TakeOverRecord::WAIT_LCP) {
- jam();
- /*---------------------------------------------------------------
- * ALL THE INFORMATION HAVE BEEN REPLICATED TO THE NEW
- * NODE AND WE ARE ONLY WAITING FOR A LOCAL CHECKPOINT TO BE
- * PERFORMED ON THE NODE TO SET ITS STATUS TO ACTIVE.
- */
- infoEvent("Node %d is WAIT_LCP including in LCP", nodePtr.i);
- c_lcpState.m_participatingLQH.set(nodePtr.i);
- }//if
- }//if
- break;
- }
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- } else {
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- jam();
- nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
- break;
- case Sysfile::NS_ActiveMissed_1:
- jam();
- nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- CRASH_INSERTION(7192);
- if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
- (!nodePtr.p->copyCompleted)) {
- jam();
- /*-----------------------------------------------------------------*/
- // The node is currently starting up and has not completed the
- // copy phase.
- // It will thus be in the TAKE_OVER state.
- /*-----------------------------------------------------------------*/
- ndbrequire(findTakeOver(nodePtr.i) != RNIL);
- nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
- } else {
- jam();
- /*-----------------------------------------------------------------*/
- /* THE NODE IS ACTIVE AND HAS NOT COMPLETED ANY OF THE LAST 3
- * CHECKPOINTS */
- /* WE MUST TAKE IT OUT OF ACTION AND START A NEW NODE TO TAKE OVER.*/
- /*-----------------------------------------------------------------*/
- nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- }//if
- break;
- case Sysfile::NS_TakeOver:
- jam();
- break;
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- }//if
- }//for
- if (isMaster()) {
- jam();
- checkStartTakeOver(signal);
- setNodeRestartInfoBits();
- }//if
-}//Dbdih::setLcpActiveStatusStart()
-
-/*************************************************************************/
-/* SET NODE ACTIVE STATUS AT SYSTEM RESTART AND WHEN UPDATED BY MASTER */
-/*************************************************************************/
-void Dbdih::setNodeActiveStatus()
-{
- NodeRecordPtr snaNodeptr;
-
- for (snaNodeptr.i = 1; snaNodeptr.i < MAX_NDB_NODES; snaNodeptr.i++) {
- ptrAss(snaNodeptr, nodeRecord);
- const Uint32 tsnaNodeBits = Sysfile::getNodeStatus(snaNodeptr.i,
- SYSFILE->nodeStatus);
- switch (tsnaNodeBits) {
- case Sysfile::NS_Active:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_Active;
- break;
- case Sysfile::NS_ActiveMissed_1:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
- break;
- case Sysfile::NS_TakeOver:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_TakeOver;
- break;
- case Sysfile::NS_HotSpare:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
- break;
- case Sysfile::NS_NotActive_NotTakenOver:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
- break;
- case Sysfile::NS_NotDefined:
- jam();
- snaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- }//for
-}//Dbdih::setNodeActiveStatus()
-
-/***************************************************************************/
-/* SET THE NODE GROUP BASED ON THE RESTART INFORMATION OR AS SET BY MASTER */
-/***************************************************************************/
-void Dbdih::setNodeGroups()
-{
- NodeGroupRecordPtr NGPtr;
- NodeRecordPtr sngNodeptr;
- Uint32 Ti;
-
- for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
- NGPtr.i = Ti;
- ptrAss(NGPtr, nodeGroupRecord);
- NGPtr.p->nodeCount = 0;
- }//for
- for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) {
- ptrAss(sngNodeptr, nodeRecord);
- 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:
- case Sysfile::NS_NotActive_NotTakenOver:
- case Sysfile::NS_TakeOver:
- jam();
- sngNodeptr.p->nodeGroup = Sysfile::getNodeGroup(sngNodeptr.i,
- SYSFILE->nodeGroups);
- NGPtr.i = sngNodeptr.p->nodeGroup;
- ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
- NGPtr.p->nodesInGroup[NGPtr.p->nodeCount] = sngNodeptr.i;
- NGPtr.p->nodeCount++;
- break;
- case Sysfile::NS_HotSpare:
- case Sysfile::NS_NotDefined:
- jam();
- sngNodeptr.p->nodeGroup = ZNIL;
- break;
- default:
- ndbrequire(false);
- return;
- break;
- }//switch
- }//for
- cnoOfNodeGroups = 0;
- for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
- jam();
- NGPtr.i = Ti;
- ptrAss(NGPtr, nodeGroupRecord);
- if (NGPtr.p->nodeCount != 0) {
- jam();
- cnoOfNodeGroups++;
- }//if
- }//for
- cnoHotSpare = csystemnodes - (cnoOfNodeGroups * cnoReplicas);
-}//Dbdih::setNodeGroups()
-
-/*************************************************************************/
-/* SET NODE INFORMATION AFTER RECEIVING RESTART INFORMATION FROM MASTER. */
-/* WE TAKE THE OPPORTUNITY TO SYNCHRONISE OUR DATA WITH THE MASTER. IT */
-/* IS ONLY THE MASTER THAT WILL ACT ON THIS DATA. WE WILL KEEP THEM */
-/* UPDATED FOR THE CASE WHEN WE HAVE TO BECOME MASTER. */
-/*************************************************************************/
-void Dbdih::setNodeInfo(Signal* signal)
-{
- setNodeActiveStatus();
- setNodeGroups();
- sendHOT_SPAREREP(signal);
-}//Dbdih::setNodeInfo()
-
-/*************************************************************************/
-// Keep also DBDICT informed about the Hot Spare situation in the cluster.
-/*************************************************************************/
-void Dbdih::sendHOT_SPAREREP(Signal* signal)
-{
- NodeRecordPtr locNodeptr;
- Uint32 Ti = 0;
- HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
- NodeBitmask::clear(hotSpare->theHotSpareNodes);
- for (locNodeptr.i = 1; locNodeptr.i < MAX_NDB_NODES; locNodeptr.i++) {
- ptrAss(locNodeptr, nodeRecord);
- switch (locNodeptr.p->activeStatus) {
- case Sysfile::NS_HotSpare:
- jam();
- NodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
- Ti++;
- break;
- default:
- jam();
- break;
- }//switch
- }//for
- hotSpare->noHotSpareNodes = Ti;
- sendSignal(DBDICT_REF, GSN_HOT_SPAREREP,
- signal, HotSpareRep::SignalLength, JBB);
-}//Dbdih::sendHOT_SPAREREP()
-
-/*************************************************************************/
-/* SET LCP ACTIVE STATUS FOR ALL NODES BASED ON THE INFORMATION IN */
-/* THE RESTART INFORMATION. */
-/*************************************************************************/
-#if 0
-void Dbdih::setNodeLcpActiveStatus()
-{
- c_lcpState.m_lcpActiveStatus.clear();
- for (Uint32 i = 1; i < MAX_NDB_NODES; i++) {
- if (NodeBitmask::get(SYSFILE->lcpActive, i)) {
- jam();
- c_lcpState.m_lcpActiveStatus.set(i);
- }//if
- }//for
-}//Dbdih::setNodeLcpActiveStatus()
-#endif
-
-/*************************************************************************/
-/* SET THE RESTART INFO BITS BASED ON THE NODES ACTIVE STATUS. */
-/*************************************************************************/
-void Dbdih::setNodeRestartInfoBits()
-{
- NodeRecordPtr nodePtr;
- Uint32 tsnrNodeGroup;
- Uint32 tsnrNodeActiveStatus;
- Uint32 i;
- for(i = 1; i < MAX_NDB_NODES; i++){
- Sysfile::setNodeStatus(i, SYSFILE->nodeStatus, Sysfile::NS_Active);
- }//for
- for(i = 1; i < Sysfile::NODE_GROUPS_SIZE; i++){
- SYSFILE->nodeGroups[i] = 0;
- }//for
- NdbNodeBitmask::clear(SYSFILE->lcpActive);
-
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRecord);
- switch (nodePtr.p->activeStatus) {
- case Sysfile::NS_Active:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_Active;
- break;
- case Sysfile::NS_ActiveMissed_1:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_1;
- break;
- case Sysfile::NS_ActiveMissed_2:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_2;
- break;
- case Sysfile::NS_HotSpare:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_HotSpare;
- break;
- case Sysfile::NS_TakeOver:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_TakeOver;
- break;
- case Sysfile::NS_NotActive_NotTakenOver:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_NotActive_NotTakenOver;
- break;
- case Sysfile::NS_NotDefined:
- jam();
- tsnrNodeActiveStatus = Sysfile::NS_NotDefined;
- break;
- default:
- ndbrequire(false);
- tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning
- break;
- }//switch
- Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus,
- tsnrNodeActiveStatus);
- if (nodePtr.p->nodeGroup == ZNIL) {
- jam();
- tsnrNodeGroup = NO_NODE_GROUP_ID;
- } else {
- jam();
- tsnrNodeGroup = nodePtr.p->nodeGroup;
- }//if
- Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
- if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
- jam();
- NodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
- }//if
- }//for
-}//Dbdih::setNodeRestartInfoBits()
-
-/*************************************************************************/
-/* START THE GLOBAL CHECKPOINT PROTOCOL IN MASTER AT START-UP */
-/*************************************************************************/
-void Dbdih::startGcp(Signal* signal)
-{
- cgcpStatus = GCP_READY;
- coldGcpStatus = cgcpStatus;
- coldGcpId = cnewgcp;
- cgcpSameCounter = 0;
- signal->theData[0] = DihContinueB::ZSTART_GCP;
- signal->theData[1] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
-}//Dbdih::startGcp()
-
-void Dbdih::updateNodeInfo(FragmentstorePtr fragPtr)
-{
- ReplicaRecordPtr replicatePtr;
- Uint32 index = 0;
- replicatePtr.i = fragPtr.p->storedReplicas;
- do {
- jam();
- ptrCheckGuard(replicatePtr, creplicaFileSize, replicaRecord);
- ndbrequire(index < MAX_REPLICAS);
- fragPtr.p->activeNodes[index] = replicatePtr.p->procNode;
- index++;
- replicatePtr.i = replicatePtr.p->nextReplica;
- } while (replicatePtr.i != RNIL);
- fragPtr.p->fragReplicas = index;
-
- /* ----------------------------------------------------------------------- */
- // We switch primary to the preferred primary if the preferred primary is
- // in the list.
- /* ----------------------------------------------------------------------- */
- const Uint32 prefPrim = fragPtr.p->preferredPrimary;
- for (Uint32 i = 1; i < index; i++) {
- jam();
- ndbrequire(i < MAX_REPLICAS);
- if (fragPtr.p->activeNodes[i] == prefPrim){
- jam();
- Uint32 switchNode = fragPtr.p->activeNodes[0];
- fragPtr.p->activeNodes[0] = prefPrim;
- fragPtr.p->activeNodes[i] = switchNode;
- break;
- }//if
- }//for
-}//Dbdih::updateNodeInfo()
-
-void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr)
-{
- writePageWord(wf, wf->fragId);
- writePageWord(wf, fragPtr.p->preferredPrimary);
- writePageWord(wf, fragPtr.p->noStoredReplicas);
- writePageWord(wf, fragPtr.p->noOldStoredReplicas);
- writePageWord(wf, fragPtr.p->distributionKey);
- writePageWord(wf, fragPtr.p->m_log_part_id);
-}//Dbdih::writeFragment()
-
-void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
-{
- if (wf->wordIndex >= 2048) {
- jam();
- ndbrequire(wf->wordIndex == 2048);
- allocpage(wf->rwfPageptr);
- wf->wordIndex = 32;
- wf->pageIndex++;
- ndbrequire(wf->pageIndex < 8);
- wf->rwfTabPtr.p->pageRef[wf->pageIndex] = wf->rwfPageptr.i;
- wf->rwfTabPtr.p->noPages++;
- }//if
- wf->rwfPageptr.p->word[wf->wordIndex] = dataWord;
- wf->wordIndex++;
-}//Dbdih::writePageWord()
-
-void Dbdih::writeReplicas(RWFragment* wf, Uint32 replicaStartIndex)
-{
- ReplicaRecordPtr wfReplicaPtr;
- wfReplicaPtr.i = replicaStartIndex;
- while (wfReplicaPtr.i != RNIL) {
- jam();
- ptrCheckGuard(wfReplicaPtr, creplicaFileSize, replicaRecord);
- writePageWord(wf, wfReplicaPtr.p->procNode);
- writePageWord(wf, wfReplicaPtr.p->initialGci);
- writePageWord(wf, wfReplicaPtr.p->noCrashedReplicas);
- writePageWord(wf, wfReplicaPtr.p->nextLcp);
- Uint32 i;
- for (i = 0; i < MAX_LCP_STORED; i++) {
- writePageWord(wf, wfReplicaPtr.p->maxGciCompleted[i]);
- writePageWord(wf, wfReplicaPtr.p->maxGciStarted[i]);
- writePageWord(wf, wfReplicaPtr.p->lcpId[i]);
- writePageWord(wf, wfReplicaPtr.p->lcpStatus[i]);
- }//if
- for (i = 0; i < 8; i++) {
- writePageWord(wf, wfReplicaPtr.p->createGci[i]);
- writePageWord(wf, wfReplicaPtr.p->replicaLastGci[i]);
- }//if
-
- wfReplicaPtr.i = wfReplicaPtr.p->nextReplica;
- }//while
-}//Dbdih::writeReplicas()
-
-void Dbdih::writeRestorableGci(Signal* signal, FileRecordPtr filePtr)
-{
- for (Uint32 i = 0; i < Sysfile::SYSFILE_SIZE32; i++) {
- sysfileDataToFile[i] = sysfileData[i];
- }//for
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
- signal->theData[4] = ZVAR_NO_CRESTART_INFO_TO_FILE;
- signal->theData[5] = 1; /* AMOUNT OF PAGES */
- signal->theData[6] = 0; /* MEMORY PAGE = 0 SINCE COMMON STORED VARIABLE */
- signal->theData[7] = 0;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
-}//Dbdih::writeRestorableGci()
-
-void Dbdih::writeTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr)
-{
- signal->theData[0] = filePtr.p->fileRef;
- signal->theData[1] = reference();
- signal->theData[2] = filePtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
- signal->theData[4] = ZVAR_NO_WORD;
- signal->theData[5] = tab->noPages;
- for (Uint32 i = 0; i < tab->noPages; i++) {
- jam();
- signal->theData[6 + (2 * i)] = tab->pageRef[i];
- signal->theData[7 + (2 * i)] = i;
- }//for
- Uint32 length = 6 + (2 * tab->noPages);
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, length, JBA);
-}//Dbdih::writeTabfile()
-
-void Dbdih::execDEBUG_SIG(Signal* signal)
-{
- signal = signal; //Avoid compiler warnings
-}//Dbdih::execDEBUG_SIG()
-
-void
-Dbdih::execDUMP_STATE_ORD(Signal* signal)
-{
- DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
- Uint32 arg = dumpState->args[0];
- if (arg == DumpStateOrd::DihDumpNodeRestartInfo) {
- infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
- c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
- infoEvent("cstartGcpNow = %d, cgcpStatus = %d",
- cstartGcpNow, cgcpStatus);
- infoEvent("cfirstVerifyQueue = %d, cverifyQueueCounter = %d",
- cfirstVerifyQueue, cverifyQueueCounter);
- infoEvent("cgcpOrderBlocked = %d, cgcpStartCounter = %d",
- cgcpOrderBlocked, cgcpStartCounter);
- }//if
- if (arg == DumpStateOrd::DihDumpNodeStatusInfo) {
- NodeRecordPtr localNodePtr;
- infoEvent("Printing nodeStatus of all nodes");
- for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
- ptrAss(localNodePtr, nodeRecord);
- if (localNodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER) {
- infoEvent("Node = %d has status = %d",
- localNodePtr.i, localNodePtr.p->nodeStatus);
- }//if
- }//for
- }//if
-
- if (arg == DumpStateOrd::DihPrintFragmentation){
- infoEvent("Printing fragmentation of all tables --");
- for(Uint32 i = 0; i<ctabFileSize; i++){
- TabRecordPtr tabPtr;
- tabPtr.i = i;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
- continue;
-
- for(Uint32 j = 0; j < tabPtr.p->totalfragments; j++){
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, j, fragPtr);
-
- Uint32 nodeOrder[MAX_REPLICAS];
- const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, nodeOrder);
- char buf[100];
- BaseString::snprintf(buf, sizeof(buf), " Table %d Fragment %d - ", tabPtr.i, j);
- for(Uint32 k = 0; k < noOfReplicas; k++){
- char tmp[100];
- BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]);
- strcat(buf, tmp);
- }
- infoEvent(buf);
- }
- }
- }
-
- if (signal->theData[0] == 7000) {
- infoEvent("ctimer = %d, cgcpParticipantState = %d, cgcpStatus = %d",
- c_lcpState.ctimer, cgcpParticipantState, cgcpStatus);
- infoEvent("coldGcpStatus = %d, coldGcpId = %d, cmasterState = %d",
- coldGcpStatus, coldGcpId, cmasterState);
- infoEvent("cmasterTakeOverNode = %d, ctcCounter = %d",
- cmasterTakeOverNode, c_lcpState.ctcCounter);
- }//if
- if (signal->theData[0] == 7001) {
- infoEvent("c_lcpState.keepGci = %d",
- c_lcpState.keepGci);
- infoEvent("c_lcpState.lcpStatus = %d, clcpStopGcp = %d",
- c_lcpState.lcpStatus,
- c_lcpState.lcpStopGcp);
- infoEvent("cgcpStartCounter = %d, cimmediateLcpStart = %d",
- cgcpStartCounter, c_lcpState.immediateLcpStart);
- }//if
- if (signal->theData[0] == 7002) {
- infoEvent("cnoOfActiveTables = %d, cgcpDelay = %d",
- cnoOfActiveTables, cgcpDelay);
- infoEvent("cdictblockref = %d, cfailurenr = %d",
- cdictblockref, cfailurenr);
- infoEvent("con_lineNodes = %d, reference() = %d, creceivedfrag = %d",
- con_lineNodes, reference(), creceivedfrag);
- }//if
- if (signal->theData[0] == 7003) {
- infoEvent("cfirstAliveNode = %d, cgckptflag = %d",
- cfirstAliveNode, cgckptflag);
- infoEvent("clocallqhblockref = %d, clocaltcblockref = %d, cgcpOrderBlocked = %d",
- clocallqhblockref, clocaltcblockref, cgcpOrderBlocked);
- infoEvent("cstarttype = %d, csystemnodes = %d, currentgcp = %d",
- cstarttype, csystemnodes, currentgcp);
- }//if
- if (signal->theData[0] == 7004) {
- infoEvent("cmasterdihref = %d, cownNodeId = %d, cnewgcp = %d",
- cmasterdihref, cownNodeId, cnewgcp);
- infoEvent("cndbStartReqBlockref = %d, cremainingfrags = %d",
- cndbStartReqBlockref, cremainingfrags);
- infoEvent("cntrlblockref = %d, cgcpSameCounter = %d, coldgcp = %d",
- cntrlblockref, cgcpSameCounter, coldgcp);
- }//if
- if (signal->theData[0] == 7005) {
- infoEvent("crestartGci = %d",
- crestartGci);
- }//if
- if (signal->theData[0] == 7006) {
- infoEvent("clcpDelay = %d, cgcpMasterTakeOverState = %d",
- c_lcpState.clcpDelay, cgcpMasterTakeOverState);
- infoEvent("cmasterNodeId = %d", cmasterNodeId);
- infoEvent("cnoHotSpare = %d, c_nodeStartMaster.startNode = %d, c_nodeStartMaster.wait = %d",
- cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait);
- }//if
- if (signal->theData[0] == 7007) {
- 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",
- c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp);
- }//if
- if (signal->theData[0] == 7008) {
- infoEvent("cfirstDeadNode = %d, cstartPhase = %d, cnoReplicas = %d",
- cfirstDeadNode, cstartPhase, cnoReplicas);
- infoEvent("cwaitLcpSr = %d",cwaitLcpSr);
- }//if
- if (signal->theData[0] == 7009) {
- infoEvent("ccalcOldestRestorableGci = %d, cnoOfNodeGroups = %d",
- c_lcpState.oldestRestorableGci, cnoOfNodeGroups);
- infoEvent("cstartGcpNow = %d",
- cstartGcpNow);
- infoEvent("crestartGci = %d",
- crestartGci);
- }//if
- if (signal->theData[0] == 7010) {
- infoEvent("cminHotSpareNodes = %d, c_lcpState.lcpStatusUpdatedPlace = %d, cLcpStart = %d",
- cminHotSpareNodes, c_lcpState.lcpStatusUpdatedPlace, c_lcpState.lcpStart);
- infoEvent("c_blockCommit = %d, c_blockCommitNo = %d",
- c_blockCommit, c_blockCommitNo);
- }//if
- if (signal->theData[0] == 7011){
- infoEvent("c_COPY_GCIREQ_Counter = %s",
- c_COPY_GCIREQ_Counter.getText());
- infoEvent("c_COPY_TABREQ_Counter = %s",
- c_COPY_TABREQ_Counter.getText());
- infoEvent("c_CREATE_FRAGREQ_Counter = %s",
- c_CREATE_FRAGREQ_Counter.getText());
- infoEvent("c_DIH_SWITCH_REPLICA_REQ_Counter = %s",
- c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
- infoEvent("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
- infoEvent("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
- infoEvent("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
- infoEvent("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
- infoEvent("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
- infoEvent("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
- infoEvent("c_MASTER_GCPREQ_Counter = %s",
- c_MASTER_GCPREQ_Counter.getText());
- infoEvent("c_MASTER_LCPREQ_Counter = %s",
- c_MASTER_LCPREQ_Counter.getText());
- infoEvent("c_START_INFOREQ_Counter = %s",
- c_START_INFOREQ_Counter.getText());
- infoEvent("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
- infoEvent("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
- infoEvent("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
- infoEvent("c_TC_CLOPSIZEREQ_Counter = %s",
- c_TC_CLOPSIZEREQ_Counter.getText());
- infoEvent("c_TCGETOPSIZEREQ_Counter = %s",
- c_TCGETOPSIZEREQ_Counter.getText());
- infoEvent("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
- }
-
- if(signal->theData[0] == 7012){
- char buf[8*_NDB_NODE_BITMASK_SIZE+1];
- infoEvent("ParticipatingDIH = %s", c_lcpState.m_participatingDIH.getText(buf));
- infoEvent("ParticipatingLQH = %s", c_lcpState.m_participatingLQH.getText(buf));
- infoEvent("m_LCP_COMPLETE_REP_Counter_DIH = %s",
- c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.getText());
- infoEvent("m_LCP_COMPLETE_REP_Counter_LQH = %s",
- c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.getText());
- infoEvent("m_LAST_LCP_FRAG_ORD = %s",
- c_lcpState.m_LAST_LCP_FRAG_ORD.getText());
- infoEvent("m_LCP_COMPLETE_REP_From_Master_Received = %d",
- c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received);
-
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if(nodePtr.p->nodeStatus == NodeRecord::ALIVE){
- Uint32 i;
- for(i = 0; i<nodePtr.p->noOfStartedChkpt; i++){
- infoEvent("Node %d: started: table=%d fragment=%d replica=%d",
- nodePtr.i,
- nodePtr.p->startedChkpt[i].tableId,
- nodePtr.p->startedChkpt[i].fragId,
- nodePtr.p->startedChkpt[i].replicaPtr);
- }
-
- for(i = 0; i<nodePtr.p->noOfQueuedChkpt; i++){
- infoEvent("Node %d: queued: table=%d fragment=%d replica=%d",
- nodePtr.i,
- nodePtr.p->queuedChkpt[i].tableId,
- nodePtr.p->queuedChkpt[i].fragId,
- nodePtr.p->queuedChkpt[i].replicaPtr);
- }
- }
- }
- }
-
- if(arg == 7019 && signal->getLength() == 2)
- {
- char buf2[8+1];
- NodeRecordPtr nodePtr;
- nodePtr.i = signal->theData[1];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- infoEvent("NF Node %d tc: %d lqh: %d dih: %d dict: %d recNODE_FAILREP: %d",
- nodePtr.i,
- nodePtr.p->dbtcFailCompleted,
- nodePtr.p->dblqhFailCompleted,
- nodePtr.p->dbdihFailCompleted,
- nodePtr.p->dbdictFailCompleted,
- nodePtr.p->recNODE_FAILREP);
- infoEvent(" m_NF_COMPLETE_REP: %s m_nodefailSteps: %s",
- nodePtr.p->m_NF_COMPLETE_REP.getText(),
- nodePtr.p->m_nodefailSteps.getText(buf2));
- }
-
- if(arg == 7020 && signal->getLength() > 3)
- {
- Uint32 gsn= signal->theData[1];
- Uint32 block= signal->theData[2];
- Uint32 length= signal->length() - 3;
- memmove(signal->theData, signal->theData+3, 4*length);
- sendSignal(numberToRef(block, getOwnNodeId()), gsn, signal, length, JBB);
-
- warningEvent("-- SENDING CUSTOM SIGNAL --");
- char buf[100], buf2[100];
- buf2[0]= 0;
- for(Uint32 i = 0; i<length; i++)
- {
- snprintf(buf, 100, "%s %.8x", buf2, signal->theData[i]);
- snprintf(buf2, 100, "%s", buf);
- }
- warningEvent("gsn: %d block: %s, length: %d theData: %s",
- gsn, getBlockName(block, "UNKNOWN"), length, buf);
-
- g_eventLogger.warning("-- SENDING CUSTOM SIGNAL --");
- g_eventLogger.warning("gsn: %d block: %s, length: %d theData: %s",
- gsn, getBlockName(block, "UNKNOWN"), length, buf);
- }
-
- if(arg == DumpStateOrd::DihDumpLCPState){
- infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
- infoEvent("lcpStatus = %d (update place = %d) ",
- c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
- infoEvent
- ("lcpStart = %d lcpStopGcp = %d keepGci = %d oldestRestorable = %d",
- c_lcpState.lcpStart, c_lcpState.lcpStopGcp,
- c_lcpState.keepGci, c_lcpState.oldestRestorableGci);
-
- infoEvent
- ("immediateLcpStart = %d masterLcpNodeId = %d",
- c_lcpState.immediateLcpStart,
- refToNode(c_lcpState.m_masterLcpDihRef));
-
- for (Uint32 i = 0; i<10; i++)
- {
- infoEvent("%u : status: %u place: %u", i,
- c_lcpState.m_saveState[i].m_status,
- c_lcpState.m_saveState[i].m_place);
- }
-
- infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
- }
-
- if(arg == DumpStateOrd::DihDumpLCPMasterTakeOver){
- infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
- infoEvent
- ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
- c_lcpMasterTakeOverState.state,
- c_lcpMasterTakeOverState.updatePlace,
- c_lcpMasterTakeOverState.failedNodeId);
-
- infoEvent("c_lcpMasterTakeOverState.minTableId = %u minFragId = %u",
- c_lcpMasterTakeOverState.minTableId,
- c_lcpMasterTakeOverState.minFragId);
-
- infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
- }
-
- if (signal->theData[0] == 7015)
- {
- if (signal->getLength() == 1)
- {
- signal->theData[1] = 0;
- }
-
- Uint32 tableId = signal->theData[1];
- if (tableId < ctabFileSize)
- {
- signal->theData[0] = 7021;
- execDUMP_STATE_ORD(signal);
- signal->theData[0] = 7015;
- signal->theData[1] = tableId + 1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- }
-
- if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
- g_eventLogger.info("Dbdih:: delay write of datapages for table = %d",
- dumpState->args[1]);
- // Send this dump to ACC and TUP
- EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
- EXECUTE_DIRECT(DBTUP, GSN_DUMP_STATE_ORD, signal, 2);
-
- // Start immediate LCP
- c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
- return;
- }
-
- if (signal->theData[0] == DumpStateOrd::DihAllAllowNodeStart) {
- for (Uint32 i = 1; i < MAX_NDB_NODES; i++)
- setAllowNodeStart(i, true);
- return;
- }//if
- if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
- // Set time between LCP to min value
- g_eventLogger.info("Set time between LCP to min value");
- c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
- return;
- }
- if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
- // Set time between LCP to max value
- g_eventLogger.info("Set time between LCP to max value");
- c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
- return;
- }
-
- if(arg == 7098){
- if(signal->length() == 3){
- jam();
- infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
- signal->theData[1], signal->theData[2]);
- startLcpRoundLoopLab(signal, signal->theData[1], signal->theData[2]);
- return;
- } else {
- infoEvent("Invalid no of arguments to 7098 - startLcpRoundLoopLab -"
- " expected 2 (tableId, fragmentId)");
- }
- }
-
- if(arg == DumpStateOrd::DihStartLcpImmediately){
- c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
- return;
- }
-
- if (arg == DumpStateOrd::DihSetTimeBetweenGcp)
- {
- if (signal->getLength() == 1)
- {
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
- ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
- }
- else
- {
- cgcpDelay = signal->theData[1];
- }
- g_eventLogger.info("Setting time between gcp : %d", cgcpDelay);
- }
-
- if (arg == 7021 && signal->getLength() == 2)
- {
- TabRecordPtr tabPtr;
- tabPtr.i = signal->theData[1];
- if (tabPtr.i >= ctabFileSize)
- return;
-
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
- return;
-
- infoEvent
- ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
- tabPtr.i,
- tabPtr.p->tabCopyStatus,
- tabPtr.p->tabUpdateState,
- tabPtr.p->tabLcpStatus);
-
- FragmentstorePtr fragPtr;
- for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
- jam();
- getFragstore(tabPtr.p, fid, fragPtr);
-
- char buf[100], buf2[100];
- BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ",
- fid, fragPtr.p->noLcpReplicas);
-
- Uint32 num=0;
- ReplicaRecordPtr replicaPtr;
- replicaPtr.i = fragPtr.p->storedReplicas;
- do {
- ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
- BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
- buf, num,
- replicaPtr.p->procNode,
- replicaPtr.p->lcpIdStarted,
- replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
- BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
-
- num++;
- replicaPtr.i = replicaPtr.p->nextReplica;
- } while (replicaPtr.i != RNIL);
- infoEvent(buf);
- }
- }
-
- if (arg == 7022)
- {
- jam();
- crashSystemAtGcpStop(signal, true);
- }
-}//Dbdih::execDUMP_STATE_ORD()
-
-void
-Dbdih::execPREP_DROP_TAB_REQ(Signal* signal){
- jamEntry();
-
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
-
- TabRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- PrepDropTabRef::ErrorCode err = PrepDropTabRef::OK;
- { /**
- * Check table state
- */
- bool ok = false;
- switch(tabPtr.p->tabStatus){
- case TabRecord::TS_IDLE:
- ok = true;
- jam();
- err = PrepDropTabRef::NoSuchTable;
- break;
- case TabRecord::TS_DROPPING:
- ok = true;
- jam();
- err = PrepDropTabRef::PrepDropInProgress;
- break;
- case TabRecord::TS_CREATING:
- jam();
- ok = true;
- break;
- case TabRecord::TS_ACTIVE:
- ok = true;
- jam();
- break;
- }
- ndbrequire(ok);
- }
-
- if(err != PrepDropTabRef::OK){
- jam();
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = err;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
- tabPtr.p->m_prepDropTab.senderRef = senderRef;
- tabPtr.p->m_prepDropTab.senderData = senderData;
-
- if(isMaster()){
- /**
- * Remove from queue
- */
- NodeRecordPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRecord);
- if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
-
- Uint32 index = 0;
- Uint32 count = nodePtr.p->noOfQueuedChkpt;
- while(index < count){
- if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
- jam();
- // g_eventLogger.info("Unqueuing %d", index);
-
- count--;
- for(Uint32 i = index; i<count; i++){
- jam();
- nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
- }
- } else {
- index++;
- }
- }
- nodePtr.p->noOfQueuedChkpt = count;
- }
- }
- }
-
- { /**
- * Check table lcp state
- */
-
- bool ok = false;
- switch(tabPtr.p->tabLcpStatus){
- case TabRecord::TLS_COMPLETED:
- case TabRecord::TLS_WRITING_TO_FILE:
- ok = true;
- jam();
- break;
- return;
- case TabRecord::TLS_ACTIVE:
- ok = true;
- jam();
-
- tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
-
- /**
- * First check if all fragments are done
- */
- if(checkLcpAllTablesDoneInLqh()){
- jam();
-
- g_eventLogger.info("This is the last table");
-
- /**
- * Then check if saving of tab info is done for all tables
- */
- LcpStatus a = c_lcpState.lcpStatus;
- checkLcpCompletedLab(signal);
-
- if(a != c_lcpState.lcpStatus){
- g_eventLogger.info("And all tables are written to already written disk");
- }
- }
- break;
- }
- ndbrequire(ok);
- }
-
- { /**
- * Send WaitDropTabReq to all LQH
- */
- WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
- req->tableId = tabPtr.i;
- req->senderRef = reference();
-
- NodeRecordPtr nodePtr;
- nodePtr.i = cfirstAliveNode;
- tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor();
- while(nodePtr.i != RNIL){
- jam();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
-
- tabPtr.p->m_prepDropTab.waitDropTabCount.setWaitingFor(nodePtr.i);
- sendSignal(calcLqhBlockRef(nodePtr.i), GSN_WAIT_DROP_TAB_REQ,
- signal, WaitDropTabReq::SignalLength, JBB);
-
- nodePtr.i = nodePtr.p->nextNode;
- }
- }
-
- waitDropTabWritingToFile(signal, tabPtr);
-}
-
-void
-Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
-
- if(tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE){
- jam();
- signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
- signal->theData[1] = tabPtr.i;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- return;
- }
-
- ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_COMPLETED);
- checkPrepDropTabComplete(signal, tabPtr);
-}
-
-void
-Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){
-
- if(tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED){
- jam();
- return;
- }
-
- if(!tabPtr.p->m_prepDropTab.waitDropTabCount.done()){
- jam();
- return;
- }
-
- const Uint32 ref = tabPtr.p->m_prepDropTab.senderRef;
- if(ref != 0){
- PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = tabPtr.p->m_prepDropTab.senderData;
- sendSignal(tabPtr.p->m_prepDropTab.senderRef, GSN_PREP_DROP_TAB_CONF,
- signal, PrepDropTabConf::SignalLength, JBB);
- tabPtr.p->m_prepDropTab.senderRef = 0;
- }
-}
-
-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();
-
- TabRecordPtr tabPtr;
- tabPtr.i = conf->tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
- Uint32 nodeId = refToNode(conf->senderRef);
- tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
- checkPrepDropTabComplete(signal, tabPtr);
-}
-
-void
-Dbdih::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId){
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
-
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
- conf->tableId = tableId;
-
- const Uint32 RT_BREAK = 16;
- for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabFileSize; i++, tabPtr.i++){
- ptrAss(tabPtr, tabRecord);
- if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
- if(tabPtr.p->m_prepDropTab.waitDropTabCount.isWaitingFor(nodeId)){
- conf->senderRef = calcLqhBlockRef(nodeId);
- execWAIT_DROP_TAB_CONF(signal);
- tabPtr.i++;
- break;
- }
- }
- }
-
- if(tabPtr.i == ctabFileSize){
- /**
- * Finished
- */
- jam();
- return;
- }
-
- signal->theData[0] = DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-
-void
-Dbdih::execNDB_TAMPER(Signal* signal)
-{
- if ((ERROR_INSERTED(7011)) &&
- (signal->theData[0] == 7012)) {
- CLEAR_ERROR_INSERT_VALUE;
- calculateKeepGciLab(signal, 0, 0);
- return;
- }//if
- SET_ERROR_INSERT_VALUE(signal->theData[0]);
- return;
-}//Dbdih::execNDB_TAMPER()
-
-void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){
- BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
-
- jamEntry();
-#if 0
- ndbrequire(c_blockCommit == false ||
- c_blockCommitNo == block->failNo);
-#else
- if(!(c_blockCommit == false || c_blockCommitNo == block->failNo)){
- infoEvent("Possible bug in Dbdih::execBLOCK_COMMIT_ORD c_blockCommit = %d c_blockCommitNo = %d"
- " sig->failNo = %d", c_blockCommit, c_blockCommitNo, block->failNo);
- }
-#endif
- c_blockCommit = true;
- c_blockCommitNo = block->failNo;
-}
-
-void Dbdih::execUNBLOCK_COMMIT_ORD(Signal* signal){
- UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
- (void)unblock;
-
- jamEntry();
-
- if(c_blockCommit == true){
- jam();
- // ndbrequire(c_blockCommitNo == unblock->failNo);
-
- c_blockCommit = false;
- emptyverificbuffer(signal, true);
- }
-}
-
-void Dbdih::execSTOP_PERM_REQ(Signal* signal){
-
- jamEntry();
-
- StopPermReq* const req = (StopPermReq*)&signal->theData[0];
- StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
-
- const Uint32 senderData = req->senderData;
- const BlockReference senderRef = req->senderRef;
- const NodeId nodeId = refToNode(senderRef);
-
- if (isMaster()) {
- /**
- * Master
- */
- jam();
- CRASH_INSERTION(7065);
- if (c_stopPermMaster.clientRef != 0) {
- jam();
-
- ref->senderData = senderData;
- ref->errorCode = StopPermRef::NodeShutdownInProgress;
- sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
- StopPermRef::SignalLength, JBB);
- return;
- }//if
-
- if (c_nodeStartMaster.activeState) {
- jam();
- ref->senderData = senderData;
- ref->errorCode = StopPermRef::NodeStartInProgress;
- sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
- StopPermRef::SignalLength, JBB);
- return;
- }//if
-
- /**
- * Lock
- */
- c_nodeStartMaster.activeState = true;
- c_stopPermMaster.clientRef = senderRef;
-
- c_stopPermMaster.clientData = senderData;
- c_stopPermMaster.returnValue = 0;
- c_switchReplicas.clear();
-
- Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
- Callback c = { safe_cast(&Dbdih::switch_primary_stop_node), nodeId };
- ndbrequire(mutex.lock(c));
- } else {
- /**
- * Proxy part
- */
- jam();
- CRASH_INSERTION(7066);
- if(c_stopPermProxy.clientRef != 0){
- jam();
- ref->senderData = senderData;
- ref->errorCode = StopPermRef::NodeShutdownInProgress;
- sendSignal(senderRef, GSN_STOP_PERM_REF, signal, 2, JBB);
- return;
- }//if
-
- c_stopPermProxy.clientRef = senderRef;
- c_stopPermProxy.masterRef = cmasterdihref;
- c_stopPermProxy.clientData = senderData;
-
- req->senderRef = reference();
- req->senderData = senderData;
- sendSignal(cmasterdihref, GSN_STOP_PERM_REQ, signal,
- StopPermReq::SignalLength, JBB);
- }//if
-}//Dbdih::execSTOP_PERM_REQ()
-
-void
-Dbdih::switch_primary_stop_node(Signal* signal, Uint32 node_id, Uint32 ret_val)
-{
- ndbrequire(ret_val == 0);
- signal->theData[0] = DihContinueB::SwitchReplica;
- signal->theData[1] = node_id;
- signal->theData[2] = 0; // table id
- signal->theData[3] = 0; // fragment id
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
-}
-
-void Dbdih::execSTOP_PERM_REF(Signal* signal)
-{
- jamEntry();
- ndbrequire(c_stopPermProxy.clientRef != 0);
- ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
- sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
- c_stopPermProxy.clientRef = 0;
-}//Dbdih::execSTOP_PERM_REF()
-
-void Dbdih::execSTOP_PERM_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(c_stopPermProxy.clientRef != 0);
- ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
- sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_CONF, signal, 1, JBB);
- c_stopPermProxy.clientRef = 0;
-}//Dbdih::execSTOP_PERM_CONF()
-
-void Dbdih::execDIH_SWITCH_REPLICA_REQ(Signal* signal)
-{
- jamEntry();
- DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
- const Uint32 tableId = req->tableId;
- const Uint32 fragNo = req->fragNo;
- const BlockReference senderRef = req->senderRef;
-
- CRASH_INSERTION(7067);
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
- if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
- jam();
- sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REQ, signal,
- DihSwitchReplicaReq::SignalLength, JBB);
- return;
- }//if
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragNo, fragPtr);
-
- /**
- * Do funky stuff
- */
- Uint32 oldOrder[MAX_REPLICAS];
- const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
-
- if (noOfReplicas < req->noOfReplicas) {
- jam();
- //---------------------------------------------------------------------
- // A crash occurred in the middle of our switch handling.
- //---------------------------------------------------------------------
- DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
- ref->senderNode = cownNodeId;
- ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
- sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_REF, signal,
- DihSwitchReplicaRef::SignalLength, JBB);
- }//if
- for (Uint32 i = 0; i < noOfReplicas; i++) {
- jam();
- ndbrequire(i < MAX_REPLICAS);
- fragPtr.p->activeNodes[i] = req->newNodeOrder[i];
- }//for
- /**
- * Reply
- */
- DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
- conf->senderNode = cownNodeId;
- sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_CONF, signal,
- DihSwitchReplicaConf::SignalLength, JBB);
-}//Dbdih::execDIH_SWITCH_REPLICA_REQ()
-
-void Dbdih::execDIH_SWITCH_REPLICA_CONF(Signal* signal)
-{
- jamEntry();
- /**
- * Response to master
- */
- CRASH_INSERTION(7068);
- DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
- switchReplicaReply(signal, conf->senderNode);
-}//Dbdih::execDIH_SWITCH_REPLICA_CONF()
-
-void Dbdih::execDIH_SWITCH_REPLICA_REF(Signal* signal)
-{
- jamEntry();
- DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
- if(c_stopPermMaster.returnValue == 0){
- jam();
- c_stopPermMaster.returnValue = ref->errorCode;
- }//if
- switchReplicaReply(signal, ref->senderNode);
-}//Dbdih::execDIH_SWITCH_REPLICA_REF()
-
-void Dbdih::switchReplicaReply(Signal* signal,
- NodeId nodeId){
- jam();
- receiveLoopMacro(DIH_SWITCH_REPLICA_REQ, nodeId);
- //------------------------------------------------------
- // We have received all responses from the nodes. Thus
- // we have completed switching replica roles. Continue
- // with the next fragment.
- //------------------------------------------------------
- if(c_stopPermMaster.returnValue != 0){
- jam();
- c_switchReplicas.tableId = ctabFileSize + 1;
- }//if
- c_switchReplicas.fragNo++;
-
- signal->theData[0] = DihContinueB::SwitchReplica;
- signal->theData[1] = c_switchReplicas.nodeId;
- signal->theData[2] = c_switchReplicas.tableId;
- signal->theData[3] = c_switchReplicas.fragNo;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
-}//Dbdih::switchReplicaReply()
-
-void
-Dbdih::switchReplica(Signal* signal,
- Uint32 nodeId,
- Uint32 tableId,
- Uint32 fragNo){
- jam();
- DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
-
- const Uint32 RT_BREAK = 64;
-
- for (Uint32 i = 0; i < RT_BREAK; i++) {
- jam();
- if (tableId >= ctabFileSize) {
- jam();
- StopPermConf* const conf = (StopPermConf*)&signal->theData[0];
- StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
- /**
- * Finished with all tables
- */
- if(c_stopPermMaster.returnValue == 0) {
- jam();
- conf->senderData = c_stopPermMaster.clientData;
- sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_CONF,
- signal, 1, JBB);
- } else {
- jam();
- ref->senderData = c_stopPermMaster.clientData;
- ref->errorCode = c_stopPermMaster.returnValue;
- sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_REF, signal, 2,JBB);
- }//if
-
- /**
- * UnLock
- */
- c_nodeStartMaster.activeState = false;
- c_stopPermMaster.clientRef = 0;
- c_stopPermMaster.clientData = 0;
- c_stopPermMaster.returnValue = 0;
- Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
- mutex.unlock(); // ignore result
- return;
- }//if
-
- TabRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
-
- if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
- jam();
- tableId++;
- fragNo = 0;
- continue;
- }//if
- if (fragNo >= tabPtr.p->totalfragments) {
- jam();
- tableId++;
- fragNo = 0;
- continue;
- }//if
- FragmentstorePtr fragPtr;
- getFragstore(tabPtr.p, fragNo, fragPtr);
-
- Uint32 oldOrder[MAX_REPLICAS];
- const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
-
- if(oldOrder[0] != nodeId) {
- jam();
- fragNo++;
- continue;
- }//if
- req->tableId = tableId;
- req->fragNo = fragNo;
- req->noOfReplicas = noOfReplicas;
- for (Uint32 i = 0; i < (noOfReplicas - 1); i++) {
- req->newNodeOrder[i] = oldOrder[i+1];
- }//for
- req->newNodeOrder[noOfReplicas-1] = nodeId;
- req->senderRef = reference();
-
- /**
- * Initialize struct
- */
- c_switchReplicas.tableId = tableId;
- c_switchReplicas.fragNo = fragNo;
- c_switchReplicas.nodeId = nodeId;
-
- sendLoopMacro(DIH_SWITCH_REPLICA_REQ, sendDIH_SWITCH_REPLICA_REQ);
- return;
- }//for
-
- signal->theData[0] = DihContinueB::SwitchReplica;
- signal->theData[1] = nodeId;
- signal->theData[2] = tableId;
- signal->theData[3] = fragNo;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
-}//Dbdih::switchReplica()
-
-void Dbdih::execSTOP_ME_REQ(Signal* signal)
-{
- jamEntry();
- StopMeReq* const req = (StopMeReq*)&signal->theData[0];
- const BlockReference senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 nodeId = refToNode(senderRef);
- {
- /**
- * Set node dead (remove from operations)
- */
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->useInTransactions = false;
- }
- if (nodeId != getOwnNodeId()) {
- jam();
- StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
- stopMeConf->senderData = senderData;
- stopMeConf->senderRef = reference();
- sendSignal(senderRef, GSN_STOP_ME_CONF, signal,
- StopMeConf::SignalLength, JBB);
- return;
- }//if
-
- /**
- * Local signal
- */
- jam();
- ndbrequire(c_stopMe.clientRef == 0);
-
- c_stopMe.clientData = senderData;
- c_stopMe.clientRef = senderRef;
-
- req->senderData = senderData;
- req->senderRef = reference();
-
- sendLoopMacro(STOP_ME_REQ, sendSTOP_ME_REQ);
-
- /**
- * Send conf to self
- */
- StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
- stopMeConf->senderData = senderData;
- stopMeConf->senderRef = reference();
- sendSignal(reference(), GSN_STOP_ME_CONF, signal,
- StopMeConf::SignalLength, JBB);
-}//Dbdih::execSTOP_ME_REQ()
-
-void Dbdih::execSTOP_ME_REF(Signal* signal)
-{
- ndbrequire(false);
-}
-
-void Dbdih::execSTOP_ME_CONF(Signal* signal)
-{
- jamEntry();
- StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
-
- const Uint32 senderRef = stopMeConf->senderRef;
- const Uint32 senderData = stopMeConf->senderData;
- const Uint32 nodeId = refToNode(senderRef);
-
- ndbrequire(c_stopMe.clientRef != 0);
- ndbrequire(c_stopMe.clientData == senderData);
-
- receiveLoopMacro(STOP_ME_REQ, nodeId);
- //---------------------------------------------------------
- // All STOP_ME_REQ have been received. We will send the
- // confirmation back to the requesting block.
- //---------------------------------------------------------
-
- stopMeConf->senderRef = reference();
- stopMeConf->senderData = c_stopMe.clientData;
- sendSignal(c_stopMe.clientRef, GSN_STOP_ME_CONF, signal,
- StopMeConf::SignalLength, JBB);
- c_stopMe.clientRef = 0;
-}//Dbdih::execSTOP_ME_CONF()
-
-void Dbdih::execWAIT_GCP_REQ(Signal* signal)
-{
- jamEntry();
- WaitGCPReq* const req = (WaitGCPReq*)&signal->theData[0];
- WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
- WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
- const Uint32 senderData = req->senderData;
- const BlockReference senderRef = req->senderRef;
- const Uint32 requestType = req->requestType;
-
- if(requestType == WaitGCPReq::CurrentGCI) {
- jam();
- conf->senderData = senderData;
- conf->gcp = cnewgcp;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
- return;
- }//if
-
- if (requestType == WaitGCPReq::BlockStartGcp)
- {
- jam();
- conf->senderData = senderData;
- conf->gcp = cnewgcp;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
- cgcpOrderBlocked = 1;
- return;
- }
-
- if (requestType == WaitGCPReq::UnblockStartGcp)
- {
- jam();
- conf->senderData = senderData;
- conf->gcp = cnewgcp;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
- cgcpOrderBlocked = 0;
- return;
- }
-
- if(isMaster()) {
- /**
- * Master
- */
- jam();
-
- if((requestType == WaitGCPReq::CompleteIfRunning) &&
- (cgcpStatus == GCP_READY)) {
- jam();
- conf->senderData = senderData;
- conf->gcp = coldgcp;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
- return;
- }//if
-
- WaitGCPMasterPtr ptr;
- if(c_waitGCPMasterList.seize(ptr) == false){
- jam();
- ref->senderData = senderData;
- ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
- sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
- WaitGCPRef::SignalLength, JBB);
- return;
- }//if
- ptr.p->clientRef = senderRef;
- ptr.p->clientData = senderData;
-
- if((requestType == WaitGCPReq::CompleteForceStart) &&
- (cgcpStatus == GCP_READY)) {
- jam();
- cstartGcpNow = true;
- }//if
- return;
- } else {
- /**
- * Proxy part
- */
- jam();
- WaitGCPProxyPtr ptr;
- if (c_waitGCPProxyList.seize(ptr) == false) {
- jam();
- ref->senderData = senderData;
- ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
- sendSignal(senderRef, GSN_WAIT_GCP_REF, signal,
- WaitGCPRef::SignalLength, JBB);
- return;
- }//if
- ptr.p->clientRef = senderRef;
- ptr.p->clientData = senderData;
- ptr.p->masterRef = cmasterdihref;
-
- req->senderData = ptr.i;
- req->senderRef = reference();
- req->requestType = requestType;
-
- sendSignal(cmasterdihref, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
- return;
- }//if
-}//Dbdih::execWAIT_GCP_REQ()
-
-void Dbdih::execWAIT_GCP_REF(Signal* signal)
-{
- jamEntry();
- ndbrequire(!isMaster());
- WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
-
- const Uint32 proxyPtr = ref->senderData;
- const Uint32 errorCode = ref->errorCode;
-
- WaitGCPProxyPtr ptr;
- ptr.i = proxyPtr;
- c_waitGCPProxyList.getPtr(ptr);
-
- ref->senderData = ptr.p->clientData;
- ref->errorCode = errorCode;
- sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_REF, signal,
- WaitGCPRef::SignalLength, JBB);
-
- c_waitGCPProxyList.release(ptr);
-}//Dbdih::execWAIT_GCP_REF()
-
-void Dbdih::execWAIT_GCP_CONF(Signal* signal)
-{
- jamEntry();
- ndbrequire(!isMaster());
- WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
- const Uint32 proxyPtr = conf->senderData;
- const Uint32 gcp = conf->gcp;
- WaitGCPProxyPtr ptr;
-
- ptr.i = proxyPtr;
- c_waitGCPProxyList.getPtr(ptr);
-
- conf->senderData = ptr.p->clientData;
- conf->gcp = gcp;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
-
- c_waitGCPProxyList.release(ptr);
-}//Dbdih::execWAIT_GCP_CONF()
-
-void Dbdih::checkWaitGCPProxy(Signal* signal, NodeId failedNodeId)
-{
- jam();
- WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
- ref->errorCode = WaitGCPRef::NF_CausedAbortOfProcedure;
-
- WaitGCPProxyPtr ptr;
- c_waitGCPProxyList.first(ptr);
- while(ptr.i != RNIL) {
- jam();
- const Uint32 i = ptr.i;
- const Uint32 clientData = ptr.p->clientData;
- const BlockReference clientRef = ptr.p->clientRef;
- const BlockReference masterRef = ptr.p->masterRef;
-
- c_waitGCPProxyList.next(ptr);
- if(refToNode(masterRef) == failedNodeId) {
- jam();
- c_waitGCPProxyList.release(i);
- ref->senderData = clientData;
- sendSignal(clientRef, GSN_WAIT_GCP_REF, signal,
- WaitGCPRef::SignalLength, JBB);
- }//if
- }//while
-}//Dbdih::checkWaitGCPProxy()
-
-void Dbdih::checkWaitGCPMaster(Signal* signal, NodeId failedNodeId)
-{
- jam();
- WaitGCPMasterPtr ptr;
- c_waitGCPMasterList.first(ptr);
-
- while (ptr.i != RNIL) {
- jam();
- const Uint32 i = ptr.i;
- const NodeId nodeId = refToNode(ptr.p->clientRef);
-
- c_waitGCPMasterList.next(ptr);
- if (nodeId == failedNodeId) {
- jam()
- c_waitGCPMasterList.release(i);
- }//if
- }//while
-}//Dbdih::checkWaitGCPMaster()
-
-void Dbdih::emptyWaitGCPMasterQueue(Signal* signal)
-{
- jam();
- WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
- conf->gcp = coldgcp;
-
- WaitGCPMasterPtr ptr;
- c_waitGCPMasterList.first(ptr);
- while(ptr.i != RNIL) {
- jam();
- const Uint32 i = ptr.i;
- const Uint32 clientData = ptr.p->clientData;
- const BlockReference clientRef = ptr.p->clientRef;
-
- c_waitGCPMasterList.next(ptr);
- conf->senderData = clientData;
- conf->blockStatus = cgcpOrderBlocked;
- sendSignal(clientRef, GSN_WAIT_GCP_CONF, signal,
- WaitGCPConf::SignalLength, JBB);
-
- c_waitGCPMasterList.release(i);
- }//while
-}//Dbdih::emptyWaitGCPMasterQueue()
-
-void Dbdih::setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus newStatus)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->nodeStatus = newStatus;
-}//Dbdih::setNodeStatus()
-
-Dbdih::NodeRecord::NodeStatus Dbdih::getNodeStatus(Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- return nodePtr.p->nodeStatus;
-}//Dbdih::getNodeStatus()
-
-Sysfile::ActiveStatus
-Dbdih::getNodeActiveStatus(Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- return nodePtr.p->activeStatus;
-}//Dbdih::getNodeActiveStatus()
-
-
-void
-Dbdih::setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->activeStatus = newStatus;
-}//Dbdih::setNodeActiveStatus()
-
-void Dbdih::setAllowNodeStart(Uint32 nodeId, bool newState)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->allowNodeStart = newState;
-}//Dbdih::setAllowNodeStart()
-
-void Dbdih::setNodeCopyCompleted(Uint32 nodeId, bool newState)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- nodePtr.p->copyCompleted = newState;
-}//Dbdih::setNodeCopyCompleted()
-
-bool Dbdih::getAllowNodeStart(Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- return nodePtr.p->allowNodeStart;
-}//Dbdih::getAllowNodeStart()
-
-bool Dbdih::getNodeCopyCompleted(Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- return nodePtr.p->copyCompleted;
-}//Dbdih::getNodeCopyCompleted()
-
-bool Dbdih::checkNodeAlive(Uint32 nodeId)
-{
- NodeRecordPtr nodePtr;
- nodePtr.i = nodeId;
- ndbrequire(nodeId > 0);
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
- if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
- return false;
- } else {
- return true;
- }//if
-}//Dbdih::checkNodeAlive()
-
-bool Dbdih::isMaster()
-{
- return (reference() == cmasterdihref);
-}//Dbdih::isMaster()
-
-bool Dbdih::isActiveMaster()
-{
- return ((reference() == cmasterdihref) && (cmasterState == MASTER_ACTIVE));
-}//Dbdih::isActiveMaster()
-
-Dbdih::NodeRecord::NodeRecord(){
- m_nodefailSteps.clear();
- gcpstate = NodeRecord::READY;
-
- activeStatus = Sysfile::NS_NotDefined;
- recNODE_FAILREP = ZFALSE;
- nodeGroup = ZNIL;
- dbtcFailCompleted = ZTRUE;
- dbdictFailCompleted = ZTRUE;
- dbdihFailCompleted = ZTRUE;
- dblqhFailCompleted = ZTRUE;
- noOfStartedChkpt = 0;
- noOfQueuedChkpt = 0;
- lcpStateAtTakeOver = (MasterLCPConf::State)255;
-
- activeTabptr = RNIL;
- nodeStatus = NodeRecord::NOT_IN_CLUSTER;
- useInTransactions = false;
- copyCompleted = false;
- allowNodeStart = true;
-}
-
-// DICT lock slave
-
-void
-Dbdih::sendDictLockReq(Signal* signal, Uint32 lockType, Callback c)
-{
- DictLockReq* req = (DictLockReq*)&signal->theData[0];
- DictLockSlavePtr lockPtr;
-
- c_dictLockSlavePool.seize(lockPtr);
- ndbrequire(lockPtr.i != RNIL);
-
- req->userPtr = lockPtr.i;
- req->lockType = lockType;
- req->userRef = reference();
-
- lockPtr.p->lockPtr = RNIL;
- lockPtr.p->lockType = lockType;
- lockPtr.p->locked = false;
- lockPtr.p->callback = c;
-
- // handle rolling upgrade
- {
- Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
-
- const unsigned int get_major = getMajor(masterVersion);
- const unsigned int get_minor = getMinor(masterVersion);
- const unsigned int get_build = getBuild(masterVersion);
- ndbrequire(get_major >= 4);
-
- if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
- masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
- get_major == 5 && get_minor == 1 ||
- ERROR_INSERTED(7176)) {
- jam();
-
- infoEvent("DIH: detect upgrade: master node %u old version %u.%u.%u",
- (unsigned int)cmasterNodeId, get_major, get_minor, get_build);
-
- DictLockConf* conf = (DictLockConf*)&signal->theData[0];
- conf->userPtr = lockPtr.i;
- conf->lockType = lockType;
- conf->lockPtr = ZNIL;
-
- sendSignal(reference(), GSN_DICT_LOCK_CONF, signal,
- DictLockConf::SignalLength, JBB);
- return;
- }
- }
-
- BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
- sendSignal(dictMasterRef, GSN_DICT_LOCK_REQ, signal,
- DictLockReq::SignalLength, JBB);
-}
-
-void
-Dbdih::execDICT_LOCK_CONF(Signal* signal)
-{
- jamEntry();
- recvDictLockConf(signal);
-}
-
-void
-Dbdih::execDICT_LOCK_REF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}
-
-void
-Dbdih::recvDictLockConf(Signal* signal)
-{
- const DictLockConf* conf = (const DictLockConf*)&signal->theData[0];
-
- DictLockSlavePtr lockPtr;
- c_dictLockSlavePool.getPtr(lockPtr, conf->userPtr);
-
- lockPtr.p->lockPtr = conf->lockPtr;
- ndbrequire(lockPtr.p->lockType == conf->lockType);
- ndbrequire(lockPtr.p->locked == false);
- lockPtr.p->locked = true;
-
- lockPtr.p->callback.m_callbackData = lockPtr.i;
- execute(signal, lockPtr.p->callback, 0);
-}
-
-void
-Dbdih::sendDictUnlockOrd(Signal* signal, Uint32 lockSlavePtrI)
-{
- DictUnlockOrd* ord = (DictUnlockOrd*)&signal->theData[0];
-
- DictLockSlavePtr lockPtr;
- c_dictLockSlavePool.getPtr(lockPtr, lockSlavePtrI);
-
- ord->lockPtr = lockPtr.p->lockPtr;
- ord->lockType = lockPtr.p->lockType;
-
- c_dictLockSlavePool.release(lockPtr);
-
- // handle rolling upgrade
- {
- Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
-
- const unsigned int get_major = getMajor(masterVersion);
- const unsigned int get_minor = getMinor(masterVersion);
- ndbrequire(get_major >= 4);
-
- if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
- masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
- get_major == 5 && get_minor == 1 ||
- ERROR_INSERTED(7176)) {
- return;
- }
- }
-
- BlockReference dictMasterRef = calcDictBlockRef(cmasterNodeId);
- sendSignal(dictMasterRef, GSN_DICT_UNLOCK_ORD, signal,
- DictUnlockOrd::SignalLength, JBB);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbdih/LCP.txt b/storage/ndb/src/kernel/blocks/dbdih/LCP.txt
deleted file mode 100644
index 500c82f6baf..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/LCP.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-
-Master DIH LQH
-========== ==========
-
-1) TCGETOPSIZEREQ -> all TC
-
-2) If sum(operation size) < Threshold
- Goto 1
-
-3) For each table
- Calc Keep GCI (local using CONTINUEB)
-
-4) COPY_GCIREQ -> all DIH
-
-5) TC_CLOPSIZEREQ -> all TC
-
-6) For each fragment
- LCP_FRAG_ORD -> LQH
-
- Do LCP...
- 1) LCP_FRAG_REP -> all DIH
- 2) If last fragment
- LCP_COMPLETE_REP -> all DIH
-
-7) When receiving LCP_COMPLETE_REP from DIH
- 1) If all DIHs have completed
- Goto 1
-
-All DIHs
-==========
-1) When receiving LCP_FRAG_REP
- If all fragments & replicas done in table
- 1) Save Table descriptor
- 2) If all tables done + LCP_COMPLETE_REP(from lqh) has arrived
- LCP_COMPLETE_REP -> master DIH
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Makefile.am b/storage/ndb/src/kernel/blocks/dbdih/Makefile.am
deleted file mode 100644
index 7e667878d83..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-ndbtools_PROGRAMS = ndb_print_sys_file
-ndb_print_sys_file_SOURCES = printSysfile.cpp
-ndb_print_sys_file_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
-
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp b/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp
deleted file mode 100644
index ae489bafa90..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SYSFILE_HPP
-#define SYSFILE_HPP
-
-#include <ndb_types.h>
-#include <ndb_limits.h>
-#include <NodeBitmask.hpp>
-
-/**
- * No bits in Sysfile to represent nodeid
- */
-#define NODEID_BITS 8
-
-/**
- * Constant representing that node do not belong to
- * any node group
- */
-#define NO_NODE_GROUP_ID ((1 << NODEID_BITS) - 1)
-
-/**
- * No of 32 bits word in sysfile
- *
- * 6 + // was 5 in < version 5.1
- * MAX_NDB_NODES + // lastCompletedGCI
- * NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) + // nodeStatus
- * NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + // nodeGroups
- * NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + // takeOver
- * NodeBitmask::NDB_NODE_BITMASK_SIZE // Lcp Active
- */
-#define _SYSFILE_SIZE32 (6 + \
- MAX_NDB_NODES + \
- NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) + \
- NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + \
- NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + \
- _NDB_NODE_BITMASK_SIZE)
-
-/**
- * This struct defines the format of P<X>.sysfile
- */
-struct Sysfile {
-public:
-
- /**
- * No of 32 bits words in the sysfile
- */
- STATIC_CONST( SYSFILE_SIZE32 = _SYSFILE_SIZE32 );
-
- Uint32 systemRestartBits;
-
- /**
- * Restart seq for _this_ node...
- */
- Uint32 m_restart_seq;
-
- static bool getInitialStartOngoing(const Uint32 & systemRestartBits);
- static void setInitialStartOngoing(Uint32 & systemRestartBits);
- static void clearInitialStartOngoing(Uint32 & systemRestartBits);
-
- static bool getRestartOngoing(const Uint32 & systemRestartBits);
- static void setRestartOngoing(Uint32 & systemRestartBits);
- static void clearRestartOngoing(Uint32 & systemRestartBits);
-
- static bool getLCPOngoing(const Uint32 & systemRestartBits);
- static void setLCPOngoing(Uint32 & systemRestartBits);
- static void clearLCPOngoing(Uint32 & systemRestartBits);
-
- Uint32 keepGCI;
- Uint32 oldestRestorableGCI;
- Uint32 newestRestorableGCI;
- Uint32 latestLCP_ID;
-
- /**
- * Last completed GCI for each node
- */
- Uint32 lastCompletedGCI[MAX_NDB_NODES];
-
- /**
- * Active status bits
- *
- * It takes 4 bits to represent it
- */
- enum ActiveStatus {
- NS_Active = 0
- ,NS_ActiveMissed_1 = 1
- ,NS_ActiveMissed_2 = 2
- ,NS_ActiveMissed_3 = 3
- ,NS_HotSpare = 4
- ,NS_NotActive_NotTakenOver = 5
- ,NS_TakeOver = 6
- ,NS_NotActive_TakenOver = 7
- ,NS_NotDefined = 8
- ,NS_Standby = 9
- };
- STATIC_CONST( NODE_STATUS_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) );
- Uint32 nodeStatus[NODE_STATUS_SIZE];
-
- static Uint32 getNodeStatus(NodeId, const Uint32 nodeStatus[]);
- static void setNodeStatus(NodeId, Uint32 nodeStatus[], Uint32 status);
-
- /**
- * The node group of each node
- * Sizeof(NodeGroup) = 8 Bit
- */
- STATIC_CONST( NODE_GROUPS_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES,
- NODEID_BITS) );
- Uint32 nodeGroups[NODE_GROUPS_SIZE];
-
- static Uint16 getNodeGroup(NodeId, const Uint32 nodeGroups[]);
- static void setNodeGroup(NodeId, Uint32 nodeGroups[], Uint16 group);
-
- /**
- * Any node can take over for any node
- */
- STATIC_CONST( TAKE_OVER_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES,
- NODEID_BITS) );
- Uint32 takeOver[TAKE_OVER_SIZE];
-
- static NodeId getTakeOverNode(NodeId, const Uint32 takeOver[]);
- static void setTakeOverNode(NodeId, Uint32 takeOver[], NodeId toNode);
-
- /**
- * Is a node running a LCP
- */
- Uint32 lcpActive[NdbNodeBitmask::Size];
-};
-
-#if (MAX_NDB_NODES > (1<<NODEID_BITS))
-#error "Sysfile node id is too small"
-#endif
-
-/**
- * Restart Info
- *
- * i = Initial start completed
- * r = Crash during system restart
- * l = Crash during local checkpoint
-
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * irl
- */
-inline
-bool
-Sysfile::getInitialStartOngoing(const Uint32 & systemRestartBits){
- return systemRestartBits & 1;
-}
-
-inline
-void
-Sysfile::setInitialStartOngoing(Uint32 & systemRestartBits){
- systemRestartBits |= 1;
-}
-
-inline
-void
-Sysfile::clearInitialStartOngoing(Uint32 & systemRestartBits){
- systemRestartBits &= ~1;
-}
-
-inline
-bool
-Sysfile::getRestartOngoing(const Uint32 & systemRestartBits){
- return (systemRestartBits & 2) != 0;
-}
-
-inline
-void
-Sysfile::setRestartOngoing(Uint32 & systemRestartBits){
- systemRestartBits |= 2;
-}
-
-inline
-void
-Sysfile::clearRestartOngoing(Uint32 & systemRestartBits){
- systemRestartBits &= ~2;
-}
-
-inline
-bool
-Sysfile::getLCPOngoing(const Uint32 & systemRestartBits){
- return systemRestartBits & 4;
-}
-
-inline
-void
-Sysfile::setLCPOngoing(Uint32 & systemRestartBits){
- systemRestartBits |= 4;
-}
-
-inline
-void
-Sysfile::clearLCPOngoing(Uint32 & systemRestartBits){
- systemRestartBits &= ~4;
-}
-
-inline
-Uint32
-Sysfile::getNodeStatus(NodeId nodeId, const Uint32 nodeStatus[]){
- const int word = nodeId >> 3;
- const int shift = (nodeId & 7) << 2;
-
- return (nodeStatus[word] >> shift) & 15;
-}
-
-inline
-void
-Sysfile::setNodeStatus(NodeId nodeId, Uint32 nodeStatus[], Uint32 status){
- const int word = nodeId >> 3;
- const int shift = (nodeId & 7) << 2;
-
- const Uint32 mask = ~(((Uint32)15) << shift);
- const Uint32 tmp = nodeStatus[word];
-
- nodeStatus[word] = (tmp & mask) | ((status & 15) << shift);
-}
-
-inline
-Uint16
-Sysfile::getNodeGroup(NodeId nodeId, const Uint32 nodeGroups[]){
- const int word = nodeId >> 2;
- const int shift = (nodeId & 3) << 3;
-
- return (nodeGroups[word] >> shift) & 255;
-}
-
-inline
-void
-Sysfile::setNodeGroup(NodeId nodeId, Uint32 nodeGroups[], Uint16 group){
- const int word = nodeId >> 2;
- const int shift = (nodeId & 3) << 3;
-
- const Uint32 mask = ~(((Uint32)255) << shift);
- const Uint32 tmp = nodeGroups[word];
-
- nodeGroups[word] = (tmp & mask) | ((group & 255) << shift);
-}
-
-inline
-NodeId
-Sysfile::getTakeOverNode(NodeId nodeId, const Uint32 takeOver[]){
- const int word = nodeId >> 2;
- const int shift = (nodeId & 3) << 3;
-
- return (takeOver[word] >> shift) & 255;
-}
-
-inline
-void
-Sysfile::setTakeOverNode(NodeId nodeId, Uint32 takeOver[], NodeId toNode){
- const int word = nodeId >> 2;
- const int shift = (nodeId & 3) << 3;
-
- const Uint32 mask = ~(((Uint32)255) << shift);
- const Uint32 tmp = takeOver[word];
-
- takeOver[word] = (tmp & mask) | ((toNode & 255) << shift);
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp b/storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp
deleted file mode 100644
index 13aeac81f81..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <Sysfile.hpp>
-
-void
-usage(const char * prg){
- ndbout << "Usage " << prg
- << " P[0-1].sysfile" << endl;
-}
-
-struct NSString {
- Sysfile::ActiveStatus NodeStatus;
- const char * desc;
-};
-
-static const
-NSString NodeStatusStrings[] = {
- { Sysfile::NS_Active, "Active " },
- { Sysfile::NS_ActiveMissed_1, "Active missed 1" },
- { Sysfile::NS_ActiveMissed_2, "Active missed 2" },
- { Sysfile::NS_ActiveMissed_3, "Active missed 3" },
- { Sysfile::NS_HotSpare, "Hot spare " },
- { Sysfile::NS_NotActive_NotTakenOver, "Not active " },
- { Sysfile::NS_TakeOver, "Take over " },
- { Sysfile::NS_NotActive_TakenOver, "Taken over " },
- { Sysfile::NS_NotDefined, "Not defined " },
- { Sysfile::NS_Standby, "Stand by " }
-};
-
-const
-char * getNSString(Uint32 ns){
- for(Uint32 i = 0; i<(sizeof(NodeStatusStrings)/sizeof(NSString)); i++)
- if((Uint32)NodeStatusStrings[i].NodeStatus == ns)
- return NodeStatusStrings[i].desc;
- return "<Unknown state>";
-}
-
-void
-fill(const char * buf, int mod){
- int len = strlen(buf)+1;
- ndbout << buf << " ";
- while((len % mod) != 0){
- ndbout << " ";
- len++;
- }
-}
-
-void
-print(const char * filename, const Sysfile * sysfile){
- char buf[255];
- ndbout << "----- Sysfile: " << filename
- << " seq: " << hex << sysfile->m_restart_seq
- << " -----" << endl;
- ndbout << "Initial start ongoing: "
- << Sysfile::getInitialStartOngoing(sysfile->systemRestartBits)
- << ", ";
-
- ndbout << "Restart Ongoing: "
- << Sysfile::getRestartOngoing(sysfile->systemRestartBits)
- << ", ";
-
- ndbout << "LCP Ongoing: "
- << Sysfile::getLCPOngoing(sysfile->systemRestartBits)
- << endl;
-
-
- ndbout << "-- Global Checkpoint Identities: --" << endl;
- sprintf(buf, "keepGCI = %u", sysfile->keepGCI);
- fill(buf, 40);
- ndbout << " -- Tail of REDO log" << endl;
-
- sprintf(buf, "oldestRestorableGCI = %u", sysfile->oldestRestorableGCI);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- sprintf(buf, "newestRestorableGCI = %u", sysfile->newestRestorableGCI);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- sprintf(buf, "latestLCP = %u", sysfile->latestLCP_ID);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- ndbout << "-- Node status: --" << endl;
- for(int i = 1; i < MAX_NDB_NODES; i++){
- if(Sysfile::getNodeStatus(i, sysfile->nodeStatus) !=Sysfile::NS_NotDefined){
- sprintf(buf,
- "Node %.2d -- %s GCP: %d, NodeGroup: %d, TakeOverNode: %d, "
- "LCP Ongoing: %s",
- i,
- getNSString(Sysfile::getNodeStatus(i,sysfile->nodeStatus)),
- sysfile->lastCompletedGCI[i],
- Sysfile::getNodeGroup(i, sysfile->nodeGroups),
- Sysfile::getTakeOverNode(i, sysfile->takeOver),
- BitmaskImpl::get(NdbNodeBitmask::Size,
- sysfile->lcpActive, i) != 0 ? "yes" : "no");
- ndbout << buf << endl;
- }
- }
-}
-
-NDB_COMMAND(printSysfile,
- "printSysfile", "printSysfile", "Prints a sysfile", 16384){
- if(argc < 2){
- usage(argv[0]);
- return 0;
- }
-
- for(int i = 1; i<argc; i++){
- const char * filename = argv[i];
-
- struct stat sbuf;
- const int res = stat(filename, &sbuf);
- if(res != 0){
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- continue;
- }
- const Uint32 bytes = sbuf.st_size;
-
- Uint32 * buf = new Uint32[bytes/4+1];
-
- FILE * f = fopen(filename, "rb");
- if(f == 0){
- ndbout << "Failed to open file" << endl;
- delete [] buf;
- continue;
- }
- Uint32 sz = fread(buf, 1, bytes, f);
- fclose(f);
- if(sz != bytes){
- ndbout << "Failure while reading file" << endl;
- delete [] buf;
- continue;
- }
-
- print(filename, (Sysfile *)&buf[0]);
- delete [] buf;
- continue;
- }
- return 0;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbdih/printSysfile/Makefile b/storage/ndb/src/kernel/blocks/dbdih/printSysfile/Makefile
deleted file mode 100644
index 4c4b1026aff..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/printSysfile/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := printSysfile
-BIN_TARGET_ARCHIVES := portlib general
-
-CCFLAGS_LOC += -I..
-
-SOURCES := printSysfile.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp b/storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp
deleted file mode 100644
index 49322252349..00000000000
--- a/storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <Sysfile.hpp>
-
-void
-usage(const char * prg){
- ndbout << "Usage " << prg
- << " P[0-1].sysfile" << endl;
-}
-
-struct NSString {
- Sysfile::ActiveStatus NodeStatus;
- const char * desc;
-};
-
-static const
-NSString NodeStatusStrings[] = {
- { Sysfile::NS_Active, "Active " },
- { Sysfile::NS_ActiveMissed_1, "Active missed 1" },
- { Sysfile::NS_ActiveMissed_2, "Active missed 2" },
- { Sysfile::NS_ActiveMissed_3, "Active missed 3" },
- { Sysfile::NS_HotSpare, "Hot spare " },
- { Sysfile::NS_NotActive_NotTakenOver, "Not active " },
- { Sysfile::NS_TakeOver, "Take over " },
- { Sysfile::NS_NotActive_TakenOver, "Taken over " },
- { Sysfile::NS_NotDefined, "Not defined " },
- { Sysfile::NS_Standby, "Stand by " }
-};
-
-const
-char * getNSString(Uint32 ns){
- for(Uint32 i = 0; i<(sizeof(NodeStatusStrings)/sizeof(NSString)); i++)
- if((Uint32)NodeStatusStrings[i].NodeStatus == ns)
- return NodeStatusStrings[i].desc;
- return "<Unknown state>";
-}
-
-void
-fill(const char * buf, int mod){
- int len = strlen(buf)+1;
- ndbout << buf << " ";
- while((len % mod) != 0){
- ndbout << " ";
- len++;
- }
-}
-
-void
-print(const char * filename, const Sysfile * sysfile){
- char buf[255];
- ndbout << "----- Sysfile: " << filename << " -----" << endl;
- ndbout << "Initial start ongoing: "
- << Sysfile::getInitialStartOngoing(sysfile->systemRestartBits)
- << ", ";
-
- ndbout << "Restart Ongoing: "
- << Sysfile::getRestartOngoing(sysfile->systemRestartBits)
- << ", ";
-
- ndbout << "LCP Ongoing: "
- << Sysfile::getLCPOngoing(sysfile->systemRestartBits)
- << endl;
-
-
- ndbout << "-- Global Checkpoint Identities: --" << endl;
- sprintf(buf, "keepGCI = %u", sysfile->keepGCI);
- fill(buf, 40);
- ndbout << " -- Tail of REDO log" << endl;
-
- sprintf(buf, "oldestRestorableGCI = %u", sysfile->oldestRestorableGCI);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- sprintf(buf, "newestRestorableGCI = %u", sysfile->newestRestorableGCI);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- sprintf(buf, "latestLCP = %u", sysfile->latestLCP_ID);
- fill(buf, 40);
- ndbout << " -- " << endl;
-
- ndbout << "-- Node status: --" << endl;
- for(int i = 1; i < MAX_NDB_NODES; i++){
- if(Sysfile::getNodeStatus(i, sysfile->nodeStatus) !=Sysfile::NS_NotDefined){
- sprintf(buf,
- "Node %.2d -- %s GCP: %d, NodeGroup: %d, TakeOverNode: %d, "
- "LCP Ongoing: %s",
- i,
- getNSString(Sysfile::getNodeStatus(i,sysfile->nodeStatus)),
- sysfile->lastCompletedGCI[i],
- Sysfile::getNodeGroup(i, sysfile->nodeGroups),
- Sysfile::getTakeOverNode(i, sysfile->takeOver),
- BitmaskImpl::get(NdbNodeBitmask::Size,
- sysfile->lcpActive, i) != 0 ? "yes" : "no");
- ndbout << buf << endl;
- }
- }
-}
-
-NDB_COMMAND(printSysfile,
- "printSysfile", "printSysfile", "Prints a sysfile", 16384){
- if(argc < 2){
- usage(argv[0]);
- return 0;
- }
-
- for(int i = 1; i<argc; i++){
- const char * filename = argv[i];
-
- struct stat sbuf;
- const int res = stat(filename, &sbuf);
- if(res != 0){
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- continue;
- }
- const Uint32 bytes = sbuf.st_size;
-
- Uint32 * buf = new Uint32[bytes/4+1];
-
- FILE * f = fopen(filename, "rb");
- if(f == 0){
- ndbout << "Failed to open file" << endl;
- delete [] buf;
- continue;
- }
- Uint32 sz = fread(buf, 1, bytes, f);
- fclose(f);
- if(sz != bytes){
- ndbout << "Failure while reading file" << endl;
- delete [] buf;
- continue;
- }
-
- print(filename, (Sysfile *)&buf[0]);
- delete [] buf;
- continue;
- }
- return 0;
-}
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
deleted file mode 100644
index 399460078c2..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ /dev/null
@@ -1,3029 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBLQH_H
-#define DBLQH_H
-
-#include <pc.hpp>
-#include <ndb_limits.h>
-#include <SimulatedBlock.hpp>
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <DLFifoList.hpp>
-#include <DLHashTable.hpp>
-
-#include <NodeBitmask.hpp>
-#include <signaldata/LCP.hpp>
-#include <signaldata/LqhTransConf.hpp>
-#include <signaldata/LqhFrag.hpp>
-#include <signaldata/FsOpenReq.hpp>
-
-// primary key is stored in TUP
-#include "../dbtup/Dbtup.hpp"
-
-class Dbacc;
-class Dbtup;
-
-#ifdef DBLQH_C
-// Constants
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS USED WHEN MASTER REQUESTS STATE OF COPY FRAGMENTS. */
-/* ------------------------------------------------------------------------- */
-#define ZCOPY_CLOSING 0
-#define ZCOPY_ONGOING 1
-#define ZCOPY_ACTIVATION 2
-/* ------------------------------------------------------------------------- */
-/* STATES FOR THE VARIABLE GCP_LOG_PART_STATE */
-/* ------------------------------------------------------------------------- */
-#define ZIDLE 0
-#define ZWAIT_DISK 1
-#define ZON_DISK 2
-#define ZACTIVE 1
-/* ------------------------------------------------------------------------- */
-/* STATES FOR THE VARIABLE CSR_PHASES_STARTED */
-/* ------------------------------------------------------------------------- */
-#define ZSR_NO_PHASE_STARTED 0
-#define ZSR_PHASE1_COMPLETED 1
-#define ZSR_PHASE2_COMPLETED 2
-#define ZSR_BOTH_PHASES_STARTED 3
-/* ------------------------------------------------------------------------- */
-/* THE NUMBER OF PAGES IN A MBYTE, THE TWO LOGARITHM OF THIS. */
-/* THE NUMBER OF MBYTES IN A LOG FILE. */
-/* THE MAX NUMBER OF PAGES READ/WRITTEN FROM/TO DISK DURING */
-/* A WRITE OR READ. */
-/* ------------------------------------------------------------------------- */
-#define ZNOT_DIRTY 0
-#define ZDIRTY 1
-#define ZREAD_AHEAD_SIZE 8
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS OF THE LOG PAGES */
-/* ------------------------------------------------------------------------- */
-#define ZPAGE_HEADER_SIZE 32
-#define ZPAGE_SIZE 8192
-#define ZPAGES_IN_MBYTE 32
-#define ZTWOLOG_NO_PAGES_IN_MBYTE 5
-#define ZTWOLOG_PAGE_SIZE 13
-#define ZMAX_MM_BUFFER_SIZE 32 // Main memory window during log execution
-
-#define ZMAX_PAGES_WRITTEN 8 // Max pages before writing to disk (=> config)
-#define ZMIN_READ_BUFFER_SIZE 2 // Minimum number of pages to execute log
-#define ZMIN_LOG_PAGES_OPERATION 10 // Minimum no of pages before stopping
-
-#define ZPOS_CHECKSUM 0
-#define ZPOS_LOG_LAP 1
-#define ZPOS_MAX_GCI_COMPLETED 2
-#define ZPOS_MAX_GCI_STARTED 3
-#define ZNEXT_PAGE 4
-#define ZPREV_PAGE 5
-#define ZPOS_VERSION 6
-#define ZPOS_NO_LOG_FILES 7
-#define ZCURR_PAGE_INDEX 8
-#define ZLAST_LOG_PREP_REF 10
-#define ZPOS_DIRTY 11
-/* A number of debug items written in the page header of all log files */
-#define ZPOS_LOG_TIMER 12
-#define ZPOS_PAGE_I 13
-#define ZPOS_PLACE_WRITTEN_FROM 14
-#define ZPOS_PAGE_NO 15
-#define ZPOS_PAGE_FILE_NO 16
-#define ZPOS_WORD_WRITTEN 17
-#define ZPOS_IN_WRITING 18
-#define ZPOS_PREV_PAGE_NO 19
-#define ZPOS_IN_FREE_LIST 20
-
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS FOR THE VARIOUS REPLICA AND NODE TYPES. */
-/* ------------------------------------------------------------------------- */
-#define ZPRIMARY_NODE 0
-#define ZBACKUP_NODE 1
-#define ZSTANDBY_NODE 2
-#define ZTC_NODE 3
-#define ZLOG_NODE 3
-/* ------------------------------------------------------------------------- */
-/* VARIOUS CONSTANTS USED AS FLAGS TO THE FILE MANAGER. */
-/* ------------------------------------------------------------------------- */
-#define ZVAR_NO_LOG_PAGE_WORD 1
-#define ZLIST_OF_PAIRS 0
-#define ZLIST_OF_PAIRS_SYNCH 16
-#define ZARRAY_OF_PAGES 1
-#define ZLIST_OF_MEM_PAGES 2
-#define ZLIST_OF_MEM_PAGES_SYNCH 18
-#define ZCLOSE_NO_DELETE 0
-#define ZCLOSE_DELETE 1
-#define ZPAGE_ZERO 0
-/* ------------------------------------------------------------------------- */
-/* THE FOLLOWING CONSTANTS ARE USED TO DESCRIBE THE TYPES OF */
-/* LOG RECORDS, THE SIZE OF THE VARIOUS LOG RECORD TYPES AND */
-/* THE POSITIONS WITHIN THOSE LOG RECORDS. */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* THESE CONSTANTS DESCRIBE THE SIZES OF VARIOUS TYPES OF LOG REORDS. */
-/* NEXT_LOG_SIZE IS ACTUALLY ONE. THE REASON WE SET IT TO 2 IS TO */
-/* SIMPLIFY THE CODE SINCE OTHERWISE HAVE TO USE A SPECIAL VERSION */
-/* OF READ_LOGWORD WHEN READING LOG RECORD TYPE */
-/* SINCE NEXT MBYTE TYPE COULD BE THE VERY LAST WORD IN THE MBYTE. */
-/* BY SETTING IT TO 2 WE ENSURE IT IS NEVER THE VERY LAST WORD */
-/* IN THE MBYTE. */
-/* ------------------------------------------------------------------------- */
-#define ZFD_HEADER_SIZE 3
-#define ZFD_MBYTE_SIZE 3
-#define ZLOG_HEAD_SIZE 8
-#define ZNEXT_LOG_SIZE 2
-#define ZABORT_LOG_SIZE 3
-#define ZCOMMIT_LOG_SIZE 9
-#define ZCOMPLETED_GCI_LOG_SIZE 2
-/* ------------------------------------------------------------------------- */
-/* THESE CONSTANTS DESCRIBE THE TYPE OF A LOG RECORD. */
-/* THIS IS THE FIRST WORD OF A LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZNEW_PREP_OP_TYPE 0
-#define ZPREP_OP_TYPE 1
-#define ZCOMMIT_TYPE 2
-#define ZABORT_TYPE 3
-#define ZFD_TYPE 4
-#define ZFRAG_SPLIT_TYPE 5
-#define ZNEXT_LOG_RECORD_TYPE 6
-#define ZNEXT_MBYTE_TYPE 7
-#define ZCOMPLETED_GCI_TYPE 8
-#define ZINVALID_COMMIT_TYPE 9
-/* ------------------------------------------------------------------------- */
-/* THE POSITIONS OF LOGGED DATA IN A FILE DESCRIPTOR LOG RECORD HEADER.*/
-/* ALSO THE MAXIMUM NUMBER OF FILE DESCRIPTORS IN A LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_LOG_TYPE 0
-#define ZPOS_NO_FD 1
-#define ZPOS_FILE_NO 2
-/* ------------------------------------------------------------------------- */
-/* THE POSITIONS WITHIN A PREPARE LOG RECORD AND A NEW PREPARE */
-/* LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_HASH_VALUE 2
-#define ZPOS_SCHEMA_VERSION 3
-#define ZPOS_TRANS_TICKET 4
-#define ZPOS_OP_TYPE 5
-#define ZPOS_NO_ATTRINFO 6
-#define ZPOS_NO_KEYINFO 7
-/* ------------------------------------------------------------------------- */
-/* THE POSITIONS WITHIN A COMMIT LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_COMMIT_TRANSID1 1
-#define ZPOS_COMMIT_TRANSID2 2
-#define ZPOS_COMMIT_GCI 3
-#define ZPOS_COMMIT_TABLE_REF 4
-#define ZPOS_COMMIT_FRAGID 5
-#define ZPOS_COMMIT_FILE_NO 6
-#define ZPOS_COMMIT_START_PAGE_NO 7
-#define ZPOS_COMMIT_START_PAGE_INDEX 8
-#define ZPOS_COMMIT_STOP_PAGE_NO 9
-/* ------------------------------------------------------------------------- */
-/* THE POSITIONS WITHIN A ABORT LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_ABORT_TRANSID1 1
-#define ZPOS_ABORT_TRANSID2 2
-/* ------------------------------------------------------------------------- */
-/* THE POSITION WITHIN A COMPLETED GCI LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_COMPLETED_GCI 1
-/* ------------------------------------------------------------------------- */
-/* THE POSITIONS WITHIN A NEW PREPARE LOG RECORD. */
-/* ------------------------------------------------------------------------- */
-#define ZPOS_NEW_PREP_FILE_NO 8
-#define ZPOS_NEW_PREP_PAGE_REF 9
-
-#define ZLAST_WRITE_IN_FILE 1
-#define ZENFORCE_WRITE 2
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS USED AS INPUT TO SUBROUTINE WRITE_LOG_PAGES AMONG OTHERS. */
-/* ------------------------------------------------------------------------- */
-#define ZNORMAL 0
-#define ZINIT 1
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS USED BY CONTINUEB TO DEDUCE WHICH CONTINUE SIGNAL IS TO */
-/* BE EXECUTED AS A RESULT OF THIS CONTINUEB SIGNAL. */
-/* ------------------------------------------------------------------------- */
-#define ZLOG_LQHKEYREQ 0
-#define ZPACK_LQHKEYREQ 1
-#define ZSEND_ATTRINFO 2
-#define ZSR_GCI_LIMITS 3
-#define ZSR_LOG_LIMITS 4
-#define ZSEND_EXEC_CONF 5
-#define ZEXEC_SR 6
-#define ZSR_FOURTH_COMP 7
-#define ZINIT_FOURTH 8
-#define ZTIME_SUPERVISION 9
-#define ZSR_PHASE3_START 10
-#define ZLQH_TRANS_NEXT 11
-#define ZLQH_RELEASE_AT_NODE_FAILURE 12
-#define ZSCAN_TC_CONNECT 13
-#define ZINITIALISE_RECORDS 14
-#define ZINIT_GCP_REC 15
-#define ZCHECK_LCP_STOP_BLOCKED 17
-#define ZSCAN_MARKERS 18
-#define ZOPERATION_EVENT_REP 19
-#define ZPREP_DROP_TABLE 20
-#define ZENABLE_EXPAND_CHECK 21
-#define ZRETRY_TCKEYREF 22
-
-/* ------------------------------------------------------------------------- */
-/* NODE STATE DURING SYSTEM RESTART, VARIABLES CNODES_SR_STATE */
-/* AND CNODES_EXEC_SR_STATE. */
-/* ------------------------------------------------------------------------- */
-#define ZSTART_SR 1
-#define ZEXEC_SR_COMPLETED 2
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS USED BY NODE STATUS TO DEDUCE THE STATUS OF A NODE. */
-/* ------------------------------------------------------------------------- */
-#define ZNODE_UP 0
-#define ZNODE_DOWN 1
-/* ------------------------------------------------------------------------- */
-/* START PHASES */
-/* ------------------------------------------------------------------------- */
-#define ZLAST_START_PHASE 255
-#define ZSTART_PHASE1 1
-#define ZSTART_PHASE2 2
-#define ZSTART_PHASE3 3
-#define ZSTART_PHASE4 4
-#define ZSTART_PHASE6 6
-/* ------------------------------------------------------------------------- */
-/* CONSTANTS USED BY SCAN AND COPY FRAGMENT PROCEDURES */
-/* ------------------------------------------------------------------------- */
-#define ZSTORED_PROC_SCAN 0
-#define ZSTORED_PROC_COPY 2
-#define ZDELETE_STORED_PROC_ID 3
-#define ZWRITE_LOCK 1
-#define ZSCAN_FRAG_CLOSED 2
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES ADDED IN VERSION 0.1 AND 0.2 */
-/* ------------------------------------------------------------------------- */
-#define ZNOT_FOUND 1 // Not an error code, a return value
-#define ZNO_FREE_LQH_CONNECTION 414
-#define ZGET_DATAREC_ERROR 418
-#define ZGET_ATTRINBUF_ERROR 419
-#define ZNO_FREE_FRAGMENTREC 460 // Insert new fragment error code
-#define ZTAB_FILE_SIZE 464 // Insert new fragment error code + Start kernel
-#define ZNO_ADD_FRAGREC 465 // Insert new fragment error code
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES ADDED IN VERSION 0.3 */
-/* ------------------------------------------------------------------------- */
-#define ZTAIL_PROBLEM_IN_LOG_ERROR 410
-#define ZGCI_TOO_LOW_ERROR 429 // GCP_SAVEREF error code
-#define ZTAB_STATE_ERROR 474 // Insert new fragment error code
-#define ZTOO_NEW_GCI_ERROR 479 // LCP Start error
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES ADDED IN VERSION 0.4 */
-/* ------------------------------------------------------------------------- */
-
-#define ZNO_FREE_FRAG_SCAN_REC_ERROR 490 // SCAN_FRAGREF error code
-#define ZCOPY_NO_FRAGMENT_ERROR 491 // COPY_FRAGREF error code
-#define ZTAKE_OVER_ERROR 499
-#define ZCOPY_NODE_ERROR 1204
-#define ZTOO_MANY_COPY_ACTIVE_ERROR 1208 // COPY_FRAG and COPY_ACTIVEREF code
-#define ZCOPY_ACTIVE_ERROR 1210 // COPY_ACTIVEREF error code
-#define ZNO_TC_CONNECT_ERROR 1217 // Simple Read + SCAN
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES ADDED IN VERSION 1.X */
-/* ------------------------------------------------------------------------- */
-//#define ZSCAN_BOOK_ACC_OP_ERROR 1219 // SCAN_FRAGREF error code
-#define ZFILE_CHANGE_PROBLEM_IN_LOG_ERROR 1220
-#define ZTEMPORARY_REDO_LOG_FAILURE 1221
-#define ZNO_FREE_MARKER_RECORDS_ERROR 1222
-#define ZNODE_SHUTDOWN_IN_PROGESS 1223
-#define ZTOO_MANY_FRAGMENTS 1224
-#define ZTABLE_NOT_DEFINED 1225
-#define ZDROP_TABLE_IN_PROGRESS 1226
-#define ZINVALID_SCHEMA_VERSION 1227
-
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES ADDED IN VERSION 2.X */
-/* ------------------------------------------------------------------------- */
-#define ZNODE_FAILURE_ERROR 400
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES FROM ACC */
-/* ------------------------------------------------------------------------- */
-#define ZNO_TUPLE_FOUND 626
-#define ZTUPLE_ALREADY_EXIST 630
-/* ------------------------------------------------------------------------- */
-/* ERROR CODES FROM TUP */
-/* ------------------------------------------------------------------------- */
-#define ZSEARCH_CONDITION_FALSE 899
-#define ZUSER_ERROR_CODE_LIMIT 6000
-#endif
-
-/**
- * @class dblqh
- *
- * @section secIntro Introduction
- *
- * Dblqh is the coordinator of the LDM. Dblqh is responsible for
- * performing operations on tuples. It does this job with help of
- * Dbacc block (that manages the index structures) and Dbtup
- * (that manages the tuples).
- *
- * Dblqh also keeps track of the participants and acts as a coordinator of
- * 2-phase commits. Logical redo logging is also handled by the Dblqh
- * block.
- *
- * @section secModules Modules
- *
- * The code is partitioned into the following modules:
- * - START / RESTART
- * - Start phase 1: Load our block reference and our processor id
- * - Start phase 2: Initiate all records within the block
- * Connect LQH with ACC and TUP.
- * - Start phase 4: Connect LQH with LQH. Connect every LQH with
- * every LQH in the database system.
- * If initial start, then create the fragment log files.
- * If system restart or node restart,
- * then open the fragment log files and
- * find the end of the log files.
- * - ADD / DELETE FRAGMENT<br>
- * Used by dictionary to create new fragments and delete old fragments.
- * - EXECUTION<br>
- * handles the reception of lqhkeyreq and all processing
- * of operations on behalf of this request.
- * This does also involve reception of various types of attrinfo
- * and keyinfo.
- * It also involves communication with ACC and TUP.
- * - LOG<br>
- * The log module handles the reading and writing of the log.
- * It is also responsible for handling system restart.
- * It controls the system restart in TUP and ACC as well.
- * - TRANSACTION<br>
- * This module handles the commit and the complete phases.
- * - MODULE TO HANDLE TC FAILURE<br>
- * - SCAN<br>
- * This module contains the code that handles a scan of a particular
- * fragment.
- * It operates under the control of TC and orders ACC to
- * perform a scan of all tuples in the fragment.
- * TUP performs the necessary search conditions
- * to ensure that only valid tuples are returned to the application.
- * - NODE RECOVERY<br>
- * Used when a node has failed.
- * It performs a copy of a fragment to a new replica of the fragment.
- * It does also shut down all connections to the failed node.
- * - LOCAL CHECKPOINT<br>
- * Handles execution and control of LCPs
- * It controls the LCPs in TUP and ACC.
- * It also interacts with DIH to control which GCPs are recoverable.
- * - GLOBAL CHECKPOINT<br>
- * Helps DIH in discovering when GCPs are recoverable.
- * It handles the request gcp_savereq that requests LQH to
- * save a particular GCP to disk and respond when completed.
- * - FILE HANDLING<br>
- * With submodules:
- * - SIGNAL RECEPTION
- * - NORMAL OPERATION
- * - FILE CHANGE
- * - INITIAL START
- * - SYSTEM RESTART PHASE ONE
- * - SYSTEM RESTART PHASE TWO,
- * - SYSTEM RESTART PHASE THREE
- * - SYSTEM RESTART PHASE FOUR
- * - ERROR
- * - TEST
- * - LOG
- */
-class Dblqh: public SimulatedBlock {
-public:
- enum LcpCloseState {
- LCP_IDLE = 0,
- LCP_RUNNING = 1, // LCP is running
- LCP_CLOSE_STARTED = 2, // Completion(closing of files) has started
- ACC_LCP_CLOSE_COMPLETED = 3,
- TUP_LCP_CLOSE_COMPLETED = 4
- };
-
- enum ExecUndoLogState {
- EULS_IDLE = 0,
- EULS_STARTED = 1,
- EULS_COMPLETED = 2
- };
-
- struct AddFragRecord {
- enum AddFragStatus {
- FREE = 0,
- ACC_ADDFRAG = 1,
- WAIT_TUP = 3,
- WAIT_TUX = 5,
- WAIT_ADD_ATTR = 6,
- TUP_ATTR_WAIT = 7,
- TUX_ATTR_WAIT = 9
- };
- LqhAddAttrReq::Entry attributes[LqhAddAttrReq::MAX_ATTRIBUTES];
- UintR accConnectptr;
- AddFragStatus addfragStatus;
- UintR dictConnectptr;
- UintR fragmentPtr;
- UintR nextAddfragrec;
- UintR schemaVer;
- UintR tupConnectptr;
- UintR tuxConnectptr;
- UintR checksumIndicator;
- UintR GCPIndicator;
- BlockReference dictBlockref;
- Uint32 m_senderAttrPtr;
- Uint16 addfragErrorCode;
- Uint16 attrSentToTup;
- Uint16 attrReceived;
- Uint16 addFragid;
- Uint16 noOfAttr;
- Uint16 noOfNull;
- Uint16 tabId;
- Uint16 totalAttrReceived;
- Uint16 fragCopyCreation;
- Uint16 noOfKeyAttr;
- Uint16 noOfCharsets;
- Uint16 lh3DistrBits;
- Uint16 tableType;
- Uint16 primaryTableId;
- Uint32 tablespace_id;
- Uint32 maxRowsLow;
- Uint32 maxRowsHigh;
- Uint32 minRowsLow;
- Uint32 minRowsHigh;
- Uint32 forceVarPartFlag;
- };
- typedef Ptr<AddFragRecord> AddFragRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ ATTRIBUTE INFORMATION RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * Can contain one (1) attrinfo signal.
- * One signal contains 24 attr. info words.
- * But 32 elements are used to make plex happy.
- * Some of the elements are used to the following things:
- * - Data length in this record is stored in the
- * element indexed by ZINBUF_DATA_LEN.
- * - Next attrinbuf is pointed out by the element
- * indexed by ZINBUF_NEXT.
- */
- struct Attrbuf {
- UintR attrbuf[32];
- }; // Size 128 bytes
- typedef Ptr<Attrbuf> AttrbufPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ DATA BUFFER $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This buffer is used as a general data storage.
- */
- struct Databuf {
- UintR data[4];
- UintR nextDatabuf;
- }; // size 20 bytes
- typedef Ptr<Databuf> DatabufPtr;
-
- struct ScanRecord {
- ScanRecord() {}
- enum ScanState {
- SCAN_FREE = 0,
- WAIT_STORED_PROC_COPY = 1,
- WAIT_STORED_PROC_SCAN = 2,
- WAIT_NEXT_SCAN_COPY = 3,
- WAIT_NEXT_SCAN = 4,
- WAIT_DELETE_STORED_PROC_ID_SCAN = 5,
- WAIT_DELETE_STORED_PROC_ID_COPY = 6,
- WAIT_ACC_COPY = 7,
- WAIT_ACC_SCAN = 8,
- WAIT_SCAN_NEXTREQ = 10,
- WAIT_CLOSE_SCAN = 12,
- WAIT_CLOSE_COPY = 13,
- WAIT_RELEASE_LOCK = 14,
- WAIT_TUPKEY_COPY = 15,
- WAIT_LQHKEY_COPY = 16,
- IN_QUEUE = 17
- };
- enum ScanType {
- ST_IDLE = 0,
- SCAN = 1,
- COPY = 2
- };
-
- UintR scan_acc_op_ptr[32];
- Uint32 scan_acc_index;
- Uint32 scan_acc_attr_recs;
- UintR scanApiOpPtr;
- Local_key m_row_id;
-
- Uint32 m_max_batch_size_rows;
- Uint32 m_max_batch_size_bytes;
-
- Uint32 m_curr_batch_size_rows;
- Uint32 m_curr_batch_size_bytes;
-
- bool check_scan_batch_completed() const;
-
- UintR copyPtr;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- Uint32 nextHash;
- Uint32 prevHash;
- bool equal(const ScanRecord & key) const {
- return scanNumber == key.scanNumber && fragPtrI == key.fragPtrI;
- }
- Uint32 hashValue() const {
- return fragPtrI ^ scanNumber;
- }
-
- UintR scanAccPtr;
- UintR scanAiLength;
- UintR scanErrorCounter;
- UintR scanSchemaVersion;
-
- /**
- * This is _always_ main table, even in range scan
- * in which case scanTcrec->fragmentptr is different
- */
- Uint32 fragPtrI;
- UintR scanStoredProcId;
- ScanState scanState;
- UintR scanTcrec;
- ScanType scanType;
- BlockReference scanApiBlockref;
- NodeId scanNodeId;
- Uint16 scanReleaseCounter;
- Uint16 scanNumber;
-
- // scan source block ACC TUX TUP
- BlockReference scanBlockref;
-
- Uint8 scanCompletedStatus;
- Uint8 scanFlag;
- Uint8 scanLockHold;
- Uint8 scanLockMode;
- Uint8 readCommitted;
- Uint8 rangeScan;
- Uint8 descending;
- Uint8 tupScan;
- Uint8 lcpScan;
- Uint8 scanTcWaiting;
- Uint8 scanKeyinfoFlag;
- Uint8 m_last_row;
- }; // Size 272 bytes
- typedef Ptr<ScanRecord> ScanRecordPtr;
-
- struct Fragrecord {
- Fragrecord() {}
-
- enum ExecSrStatus {
- IDLE = 0,
- ACTIVE = 2
- };
- /**
- * Possible state transitions are:
- * - FREE -> DEFINED Fragment record is allocated
- * - DEFINED -> ACTIVE Add fragment is completed and
- * fragment is ready to
- * receive operations.
- * - DEFINED -> ACTIVE_CREATION Add fragment is completed and
- * fragment is ready to
- * receive operations in parallel
- * with a copy fragment
- * which is performed from the
- * primary replica
- * - DEFINED -> CRASH_RECOVERING A fragment is ready to be
- * recovered from a local
- * checkpoint on disk
- * - ACTIVE -> BLOCKED A local checkpoint is to be
- * started. No more operations
- * are allowed to be started until
- * the local checkpoint
- * has been started.
- * - ACTIVE -> REMOVING A fragment is removed from the node
- * - BLOCKED -> ACTIVE Operations are allowed again in
- * the fragment.
- * - CRASH_RECOVERING -> ACTIVE A fragment has been recovered and
- * are now ready for
- * operations again.
- * - CRASH_RECOVERING -> REMOVING Fragment recovery failed or
- * was cancelled.
- * - ACTIVE_CREATION -> ACTIVE A fragment is now copied and now
- * is a normal fragment
- * - ACTIVE_CREATION -> REMOVING Copying of the fragment failed
- * - REMOVING -> FREE Removing of the fragment is
- * completed and the fragment
- * is now free again.
- */
- enum FragStatus {
- FREE = 0, ///< Fragment record is currently not in use
- FSACTIVE = 1, ///< Fragment is defined and usable for operations
- DEFINED = 2, ///< Fragment is defined but not yet usable by
- ///< operations
- BLOCKED = 3, ///< LQH is waiting for all active operations to
- ///< complete the current phase so that the
- ///< local checkpoint can be started.
- ACTIVE_CREATION = 4, ///< Fragment is defined and active but is under
- ///< creation by the primary LQH.
- CRASH_RECOVERING = 5, ///< Fragment is recovering after a crash by
- ///< executing the fragment log and so forth.
- ///< Will need further breakdown.
- REMOVING = 6 ///< The fragment is currently removed.
- ///< Operations are not allowed.
- };
- enum LogFlag {
- STATE_TRUE = 0,
- STATE_FALSE = 1
- };
- enum SrStatus {
- SS_IDLE = 0,
- SS_STARTED = 1,
- SS_COMPLETED = 2
- };
- enum LcpFlag {
- LCP_STATE_TRUE = 0,
- LCP_STATE_FALSE = 1
- };
- /**
- * Last GCI for executing the fragment log in this phase.
- */
- UintR execSrLastGci[4];
- /**
- * Start GCI for executing the fragment log in this phase.
- */
- UintR execSrStartGci[4];
- /**
- * Requesting user pointer for executing the fragment log in
- * this phase
- */
- UintR execSrUserptr[4];
- /**
- * The LCP identifier of the LCP's.
- * =0 means that the LCP number has not been stored.
- * The LCP identifier is supplied by DIH when starting the LCP.
- */
- UintR lcpId[MAX_LCP_STORED];
- UintR maxGciInLcp;
- /**
- * This variable contains the maximum global checkpoint
- * identifier that exists in a certain local checkpoint.
- * Maximum 4 local checkpoints is possible in this release.
- */
- UintR maxGciCompletedInLcp;
- UintR srLastGci[4];
- UintR srStartGci[4];
- /**
- * The fragment pointers in ACC
- */
- UintR accFragptr;
- /**
- * The EXEC_SR variables are used to keep track of which fragments
- * that are interested in being executed as part of executing the
- * fragment loop.
- * It is initialised for every phase of executing the
- * fragment log (the fragment log can be executed upto four times).
- *
- * Each execution is capable of executing the log records on four
- * fragment replicas.
- */
- /**
- * Requesting block reference for executing the fragment log
- * in this phase.
- */
- BlockReference execSrBlockref[4];
- /**
- * This variable contains references to active scan and copy
- * fragment operations on the fragment.
- * A maximum of four concurrently active is allowed.
- */
- typedef Bitmask<4> ScanNumberMask;
- ScanNumberMask m_scanNumberMask;
- DLList<ScanRecord>::Head m_activeScans;
- DLFifoList<ScanRecord>::Head m_queuedScans;
-
- Uint16 srLqhLognode[4];
- /**
- * The fragment pointers in TUP and TUX
- */
- UintR tupFragptr;
- UintR tuxFragptr;
-
- /**
- * This variable keeps track of how many operations that are
- * active that have skipped writing the log but not yet committed
- * or aborted. This is used during start of fragment.
- */
- UintR activeTcCounter;
-
- /**
- * This status specifies whether this fragment is actively
- * engaged in executing the fragment log.
- */
- ExecSrStatus execSrStatus;
-
- /**
- * The fragment id of this fragment.
- */
- UintR fragId;
-
- /**
- * Status of fragment
- */
- FragStatus fragStatus;
-
- /**
- * 0 = undefined i.e fragStatus != ACTIVE_CREATION
- * 1 = yes
- * 2 = no
- */
- enum ActiveCreat {
- AC_NORMAL = 0, // fragStatus != ACTIVE_CREATION
- AC_IGNORED = 1, // Operation that got ignored during NR
- AC_NR_COPY = 2 // Operation that got performed during NR
- };
- Uint8 m_copy_started_state;
-
- /**
- * This flag indicates whether logging is currently activated at
- * the fragment.
- * During a system restart it is temporarily shut off.
- * Some fragments have it permanently shut off.
- */
- LogFlag logFlag;
- UintR masterPtr;
- /**
- * This variable contains the maximum global checkpoint identifier
- * which was completed when the local checkpoint was started.
- */
- /**
- * Reference to the next fragment record in a free list of fragment
- * records.
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
-
- /**
- * The newest GCI that has been committed on fragment
- */
- UintR newestGci;
- SrStatus srStatus;
- UintR srUserptr;
- /**
- * The starting global checkpoint of this fragment.
- */
- UintR startGci;
- /**
- * A reference to the table owning this fragment.
- */
- UintR tabRef;
-
- /**
- * This is the queue to put operations that have been blocked
- * during start of a local chkp.
- */
- UintR firstWaitQueue;
- UintR lastWaitQueue;
-
- /**
- * The block reference to ACC on the fragment makes it
- * possible to have different ACC blocks for different
- * fragments in the future.
- */
- BlockReference accBlockref;
-
- /**
- * Ordered index block.
- */
- BlockReference tuxBlockref;
- /**
- * The master block reference as sent in COPY_ACTIVEREQ.
- */
- BlockReference masterBlockref;
- /**
- * These variables are used during system restart to recall
- * from which node to execute the fragment log and which GCI's
- * this node should start and stop from. Also to remember who
- * to send the response to when system restart is completed.
- */
- BlockReference srBlockref;
- /**
- * The block reference to TUP on the fragment makes it
- * possible to have different TUP blocks for different
- * fragments in the future.
- */
- BlockReference tupBlockref;
- /**
- * This state indicates if the fragment will participate in a
- * checkpoint.
- * Temporary tables with Fragrecord::logFlag permanently off
- * will also have Fragrecord::lcpFlag off.
- */
- LcpFlag lcpFlag;
- /**
- * Used to ensure that updates started with old
- * configuration do not arrive here after the copy fragment
- * has started.
- * If they are allowed to arrive after they
- * could update a record that has already been replicated to
- * the new node. This type of arrival should be extremely
- * rare but we must anyway ensure that no harm is done.
- */
- Uint16 copyNode;
- /**
- * This variable ensures that only one copy fragment is
- * active at a time on the fragment.
- */
- Uint8 copyFragState;
- /**
- * The number of fragment replicas that will execute the log
- * records in this round of executing the fragment
- * log. Maximum four is possible.
- */
- Uint8 execSrNoReplicas;
- /**
- * This variable contains what type of replica this fragment
- * is. Two types are possible:
- * - Primary/Backup replica = 0
- * - Stand-by replica = 1
- *
- * It is not possible to distinguish between primary and
- * backup on a fragment.
- * This can only be done per transaction.
- * DIH can change from primary to backup without informing
- * the various replicas about this change.
- */
- Uint8 fragCopy;
- /**
- * This is the last fragment distribution key that we have
- * heard of.
- */
- Uint8 fragDistributionKey;
- /**
- * How many local checkpoints does the fragment contain
- */
- Uint8 srChkpnr;
- Uint8 srNoLognodes;
- /**
- * Table type.
- */
- Uint8 tableType;
- /**
- * For ordered index fragment, i-value of corresponding
- * fragment in primary table.
- */
- UintR tableFragptr;
-
- /**
- * Log part
- */
- Uint32 m_log_part_ptr_i;
- };
- typedef Ptr<Fragrecord> FragrecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ GLOBAL CHECKPOINT RECORD $$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record describes a global checkpoint that is
- * completed. It waits for all log records belonging to this
- * global checkpoint to be saved on disk.
- */
- struct GcpRecord {
- /**
- * The file number within each log part where the log was
- * located when gcp_savereq was received. The last record
- * belonging to this global checkpoint is certainly before
- * this place in the log. We could come even closer but it
- * would cost performance and doesn't seem like a good
- * idea. This is simple and it works.
- */
- Uint16 gcpFilePtr[4];
- /**
- * The page number within the file for each log part.
- */
- Uint16 gcpPageNo[4];
- /**
- * The word number within the last page that was written for
- * each log part.
- */
- Uint16 gcpWordNo[4];
- /**
- * The identity of this global checkpoint.
- */
- UintR gcpId;
- /**
- * The state of this global checkpoint, one for each log part.
- */
- Uint8 gcpLogPartState[4];
- /**
- * The sync state of this global checkpoint, one for each
- * log part.
- */
- Uint8 gcpSyncReady[4];
- /**
- * User pointer of the sender of gcp_savereq (= master DIH).
- */
- UintR gcpUserptr;
- /**
- * Block reference of the sender of gcp_savereq
- * (= master DIH).
- */
- BlockReference gcpBlockref;
- }; // Size 44 bytes
- typedef Ptr<GcpRecord> GcpRecordPtr;
-
- struct HostRecord {
- bool inPackedList;
- UintR noOfPackedWordsLqh;
- UintR packedWordsLqh[30];
- UintR noOfPackedWordsTc;
- UintR packedWordsTc[29];
- BlockReference hostLqhBlockRef;
- BlockReference hostTcBlockRef;
- };// Size 128 bytes
- typedef Ptr<HostRecord> HostRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$ LOCAL CHECKPOINT SUPPORT RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record contains the information about an outstanding
- * request to TUP or ACC. Used for both local checkpoints and
- * system restart.
- */
- struct LcpLocRecord {
- enum LcpLocstate {
- IDLE = 0,
- WAIT_TUP_PREPLCP = 1,
- WAIT_LCPHOLDOP = 2,
- HOLDOP_READY = 3,
- ACC_WAIT_STARTED = 4,
- ACC_STARTED = 5,
- ACC_COMPLETED = 6,
- TUP_WAIT_STARTED = 7,
- TUP_STARTED = 8,
- TUP_COMPLETED = 9,
- SR_ACC_STARTED = 10,
- SR_TUP_STARTED = 11,
- SR_ACC_COMPLETED = 12,
- SR_TUP_COMPLETED = 13
- };
- LcpLocstate lcpLocstate;
- Uint32 lcpRef;
- }; // 28 bytes
- typedef Ptr<LcpLocRecord> LcpLocRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ LOCAL CHECKPOINT RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record contains the information about a local
- * checkpoint that is ongoing. This record is also used as a
- * system restart record.
- */
- struct LcpRecord {
- LcpRecord() { m_EMPTY_LCP_REQ.clear(); }
-
- enum LcpState {
- LCP_IDLE = 0,
- LCP_COMPLETED = 2,
- LCP_WAIT_FRAGID = 3,
- LCP_WAIT_TUP_PREPLCP = 4,
- LCP_WAIT_HOLDOPS = 5,
- LCP_START_CHKP = 7,
- LCP_BLOCKED_COMP = 8,
- LCP_SR_WAIT_FRAGID = 9,
- LCP_SR_STARTED = 10,
- LCP_SR_COMPLETED = 11
- };
-
- LcpState lcpState;
- bool firstFragmentFlag;
- bool lastFragmentFlag;
-
- struct FragOrd {
- Uint32 fragPtrI;
- LcpFragOrd lcpFragOrd;
- };
- FragOrd currentFragment;
-
- bool lcpQueued;
- FragOrd queuedFragment;
-
- bool reportEmpty;
- NdbNodeBitmask m_EMPTY_LCP_REQ;
-
- Uint32 m_error;
- Uint32 m_outstanding;
- }; // Size 76 bytes
- typedef Ptr<LcpRecord> LcpRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* */
- /* THE RECORDS THAT START BY LOG_ ARE A PART OF THE LOG MANAGER. */
- /* THESE RECORDS ARE USED TO HANDLE THE FRAGMENT LOG. */
- /* */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ LOG RECORD $$$$$$$ */
- /* */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* THIS RECORD IS ALIGNED TO BE 256 BYTES. */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record describes the current state of a log.
- * A log consists of a number of log files.
- * These log files are described by the log file record.
- *
- * There will be 4 sets of log files.
- * Different tables will use different log files dependent
- * on the table id.
- * This ensures that more than one outstanding request can
- * be sent to the file system.
- * The log file to use is found by performing a very simple hash
- * function.
- */
- struct LogPartRecord {
- enum LogPartState {
- IDLE = 0, ///< Nothing happens at the moment
- ACTIVE = 1, ///< An operation is active logging
- SR_FIRST_PHASE = 2, ///< Finding the end of the log and
- ///< the information about global
- ///< checkpoints in the log is ongoing.
- SR_FIRST_PHASE_COMPLETED = 3, ///< First phase completed
- SR_THIRD_PHASE_STARTED = 4, ///< Executing fragment log is in 3rd ph
- SR_THIRD_PHASE_COMPLETED = 5,
- SR_FOURTH_PHASE_STARTED = 6, ///< Finding the log tail and head
- ///< is the fourth phase.
- SR_FOURTH_PHASE_COMPLETED = 7,
- FILE_CHANGE_PROBLEM = 8, ///< For some reason the write to
- ///< page zero in file zero have not
- ///< finished after 15 mbyte of
- ///< log data have been written
- TAIL_PROBLEM = 9 ///< Only 1 mbyte of log left.
- ///< No operations allowed to enter the
- ///< log. Only special log records
- ///< are allowed
- };
- enum WaitWriteGciLog {
- WWGL_TRUE = 0,
- WWGL_FALSE = 1
- };
- enum LogExecState {
- LES_IDLE = 0,
- LES_SEARCH_STOP = 1,
- LES_SEARCH_START = 2,
- LES_EXEC_LOG = 3,
- LES_EXEC_LOG_NEW_MBYTE = 4,
- LES_EXEC_LOG_NEW_FILE = 5,
- LES_EXEC_LOGREC_FROM_FILE = 6,
- LES_EXEC_LOG_COMPLETED = 7,
- LES_WAIT_READ_EXEC_SR_NEW_MBYTE = 8,
- LES_WAIT_READ_EXEC_SR = 9,
- LES_EXEC_LOG_INVALIDATE = 10
- };
-
- /**
- * Is a CONTINUEB(ZLOG_LQHKEYREQ) signal sent and
- * outstanding. We do not want several instances of this
- * signal out in the air since that would create multiple
- * writers of the list.
- */
- UintR LogLqhKeyReqSent;
- /**
- * Contains the current log file where log records are
- * written. During system restart it is used to indicate the
- * last log file.
- */
- UintR currentLogfile;
- /**
- * The log file used to execute log records from far behind.
- */
- UintR execSrExecLogFile;
- /**
- * The currently executing prepare record starts in this log
- * page. This variable is used to enable that a log record is
- * executed multiple times in execution of the log.
- */
- UintR execSrLogPage;
- /**
- * This variable keeps track of the lfo record where the
- * pages that were read from disk when an operations log
- * record were not found in the main memory buffer for log
- * pages.
- */
- UintR execSrLfoRec;
- /**
- * The starting page number when reading log from far behind.
- */
- UintR execSrStartPageNo;
- /**
- * The last page number when reading log from far behind.
- */
- UintR execSrStopPageNo;
- /**
- * Contains a reference to the first log file, file number 0.
- */
- UintR firstLogfile;
- /**
- * The head of the operations queued for logging.
- */
- UintR firstLogQueue;
- /**
- * This variable contains the oldest operation in this log
- * part which have not been committed yet.
- */
- UintR firstLogTcrec;
- /**
- * The first reference to a set of 8 pages. These are used
- * during execution of the log to keep track of which pages
- * are in memory and which are not.
- */
- UintR firstPageRef;
- /**
- * This variable contains the global checkpoint record
- * waiting for disk writes to complete.
- */
- UintR gcprec;
- /**
- * The last reference to a set of 8 pages. These are used
- * during execution of the log to keep track of which pages
- * are in memory and which are not.
- */
- UintR lastPageRef;
- /**
- * The tail of the operations queued for logging.
- */
- UintR lastLogQueue;
- /**
- * This variable contains the newest operation in this log
- * part which have not been committed yet.
- */
- UintR lastLogTcrec;
- /**
- * This variable indicates which was the last mbyte that was
- * written before the system crashed. Discovered during
- * system restart.
- */
- UintR lastLogfile;
- /**
- * This variable is used to keep track of the state during
- * the third phase of the system restart, i.e. when
- * LogPartRecord::logPartState ==
- * LogPartRecord::SR_THIRD_PHASE_STARTED.
- */
- LogExecState logExecState;
- /**
- * This variable contains the lap number of this log part.
- */
- UintR logLap;
- /**
- * This variable contains the place to stop executing the log
- * in this phase.
- */
- UintR logLastGci;
- /**
- * This variable contains the place to start executing the
- * log in this phase.
- */
- UintR logStartGci;
- /**
- * The latest GCI completed in this log part.
- */
- UintR logPartNewestCompletedGCI;
- /**
- * The current state of this log part.
- */
- LogPartState logPartState;
- /**
- * A timer that is set every time a log page is sent to disk.
- * Ensures that log pages are not kept in main memory for
- * more than a certain time.
- */
- UintR logPartTimer;
- /**
- * The current timer which is set by the periodic signal
- * received by LQH
- */
- UintR logTimer;
- /**
- * Contains the number of the log tail file and the mbyte
- * reference within that file. This information ensures that
- * the tail is not overwritten when writing new log records.
- */
- UintR logTailFileNo;
- /**
- * The TcConnectionrec used during execution of this log part.
- */
- UintR logTcConrec;
- /**
- * The number of pages that currently resides in the main
- * memory buffer. It does not refer pages that are currently
- * read from the log files. Only to pages already read
- * from the log file.
- */
- UintR mmBufferSize;
- /**
- * Contains the current number of log files in this log part.
- */
- UintR noLogFiles;
- /**
- * This variable is used only during execution of a log
- * record. It keeps track of in which page record a log
- * record was started. It is used then to deduce which
- * pages that are dirty after that the log records on the
- * page have been executed.
- *
- * It is also used to find out where to write the invalidate
- * command when that is needed.
- */
- UintR prevLogpage;
- /**
- * The number of files remaining to gather GCI information
- * for during system restart. Only used if number of files
- * is larger than 60.
- */
- UintR srRemainingFiles;
- /**
- * The log file where to start executing the log during
- * system restart.
- */
- UintR startLogfile;
- /**
- * The last log file in which to execute the log during system
- * restart.
- */
- UintR stopLogfile;
- /**
- * This variable keeps track of when we want to write a complete
- * gci log record but have been blocked by an ongoing log operation.
- */
- WaitWriteGciLog waitWriteGciLog;
- /**
- * The currently executing prepare record starts in this index
- * in the log page.
- */
- Uint16 execSrLogPageIndex;
- /**
- * Which of the four exec_sr's in the fragment is currently executing
- */
- Uint16 execSrExecuteIndex;
- /**
- * The number of pages executed in the current mbyte.
- */
- Uint16 execSrPagesExecuted;
- /**
- * The number of pages read from disk that have arrived and are
- * currently awaiting execution of the log.
- */
- Uint16 execSrPagesRead;
- /**
- * The number of pages read from disk and currently not arrived
- * to the block.
- */
- Uint16 execSrPagesReading;
- /**
- * This variable refers to the new header file where we will
- * start writing the log after a system restart have been completed.
- */
- Uint16 headFileNo;
- /**
- * This variable refers to the page number within the header file.
- */
- Uint16 headPageNo;
- /**
- * This variable refers to the index within the new header
- * page.
- */
- Uint16 headPageIndex;
- /**
- * This variables indicates which was the last mbyte in the last
- * logfile before a system crash. Discovered during system restart.
- */
- Uint16 lastMbyte;
- /**
- * This variable is used only during execution of a log
- * record. It keeps track of in which file page a log
- * record was started. It is used if it is needed to write a
- * dirty page to disk during log execution (this happens when
- * commit records are invalidated).
- */
- Uint16 prevFilepage;
- /**
- * This is used to save where we were in the execution of log
- * records when we find a commit record that needs to be
- * executed.
- *
- * This variable is also used to remember the index where the
- * log type was in the log record. It is only used in this
- * role when finding a commit record that needs to be
- * invalidated.
- */
- Uint16 savePageIndex;
- Uint8 logTailMbyte;
- /**
- * The mbyte within the starting log file where to start
- * executing the log.
- */
- Uint8 startMbyte;
- /**
- * The last mbyte in which to execute the log during system
- * restart.
- */
- Uint8 stopMbyte;
- /**
- * This variable refers to the file where invalidation is
- * occuring during system/node restart.
- */
- Uint16 invalidateFileNo;
- /**
- * This variable refers to the page where invalidation is
- * occuring during system/node restart.
- */
- Uint16 invalidatePageNo;
- }; // Size 164 Bytes
- typedef Ptr<LogPartRecord> LogPartRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ LOG FILE RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* THIS RECORD IS ALIGNED TO BE 288 (256 + 32) BYTES. */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record contains information about a log file.
- * A log file contains log records from several tables and
- * fragments of a table. LQH can contain more than
- * one log file to ensure faster log processing.
- *
- * The number of pages to write to disk at a time is
- * configurable.
- */
- struct LogFileRecord {
- enum FileChangeState {
- NOT_ONGOING = 0,
- BOTH_WRITES_ONGOING = 1,
- LAST_WRITE_ONGOING = 2,
- FIRST_WRITE_ONGOING = 3,
- WRITE_PAGE_ZERO_ONGOING = 4
- };
- enum LogFileStatus {
- LFS_IDLE = 0, ///< Log file record not in use
- CLOSED = 1, ///< Log file closed
- OPENING_INIT = 2,
- OPEN_SR_FRONTPAGE = 3, ///< Log file opened as part of system
- ///< restart. Open file 0 to find
- ///< the front page of the log part.
- OPEN_SR_LAST_FILE = 4, ///< Open last log file that was written
- ///< before the system restart.
- OPEN_SR_NEXT_FILE = 5, ///< Open a log file which is 16 files
- ///< backwards to find the next
- ///< information about GCPs.
- OPEN_EXEC_SR_START = 6, ///< Log file opened as part of
- ///< executing
- ///< log during system restart.
- OPEN_EXEC_SR_NEW_MBYTE = 7,
- OPEN_SR_FOURTH_PHASE = 8,
- OPEN_SR_FOURTH_NEXT = 9,
- OPEN_SR_FOURTH_ZERO = 10,
- OPENING_WRITE_LOG = 11, ///< Log file opened as part of writing
- ///< log during normal operation.
- OPEN_EXEC_LOG = 12,
- CLOSING_INIT = 13,
- CLOSING_SR = 14, ///< Log file closed as part of system
- ///< restart. Currently trying to
- ///< find where to start executing the
- ///< log
- CLOSING_EXEC_SR = 15, ///< Log file closed as part of
- ///< executing log during system restart
- CLOSING_EXEC_SR_COMPLETED = 16,
- CLOSING_WRITE_LOG = 17, ///< Log file closed as part of writing
- ///< log during normal operation.
- CLOSING_EXEC_LOG = 18,
- OPEN_INIT = 19,
- OPEN = 20, ///< Log file open
- OPEN_SR_INVALIDATE_PAGES = 21,
- CLOSE_SR_INVALIDATE_PAGES = 22
- };
-
- /**
- * When a new mbyte is started in the log we have to find out
- * how far back in the log we still have prepared operations
- * which have been neither committed or aborted. This variable
- * keeps track of this value for each of the mbytes in this
- * log file. This is used in writing down these values in the
- * header of each log file. That information is used during
- * system restart to find the tail of the log.
- */
- UintR *logLastPrepRef;
- /**
- * The max global checkpoint completed before the mbyte in the
- * log file was started. One variable per mbyte.
- */
- UintR *logMaxGciCompleted;
- /**
- * The max global checkpoint started before the mbyte in the log
- * file was started. One variable per mbyte.
- */
- UintR *logMaxGciStarted;
- /**
- * This variable contains the file name as needed by the file
- * system when opening the file.
- */
- UintR fileName[4];
- /**
- * This variable has a reference to the log page which is
- * currently in use by the log.
- */
- UintR currentLogpage;
- /**
- * The number of the current mbyte in the log file.
- */
- UintR currentMbyte;
- /**
- * This variable is used when changing files. It is to find
- * out when both the last write in the previous file and the
- * first write in this file has been completed. After these
- * writes have completed the variable keeps track of when the
- * write to page zero in file zero is completed.
- */
- FileChangeState fileChangeState;
- /**
- * The number of the file within this log part.
- */
- UintR fileNo;
- /**
- * This variable shows where to read/write the next pages into
- * the log. Used when writing the log during normal operation
- * and when reading the log during system restart. It
- * specifies the page position where each page is 8 kbyte.
- */
- UintR filePosition;
- /**
- * This contains the file pointer needed by the file system
- * when reading/writing/closing and synching.
- */
- UintR fileRef;
- /**
- * The head of the pages waiting for shipment to disk.
- * They are filled with log info.
- */
- UintR firstFilledPage;
- /**
- * A list of active read/write operations on the log file.
- * Operations are always put in last and the first should
- * always complete first.
- */
- UintR firstLfo;
- UintR lastLfo;
- /**
- * The tail of the pages waiting for shipment to disk.
- * They are filled with log info.
- */
- UintR lastFilledPage;
- /**
- * This variable keeps track of the last written page in the
- * file while writing page zero in file zero when changing log
- * file.
- */
- UintR lastPageWritten;
- /**
- * This variable keeps track of the last written word in the
- * last page written in the file while writing page zero in
- * file zero when changing log file.
- */
- UintR lastWordWritten;
- /**
- * This variable contains the last word written in the last page.
- */
- LogFileStatus logFileStatus;
- /**
- * A reference to page zero in this file.
- * This page is written before the file is closed.
- */
- UintR logPageZero;
- /**
- * This variable contains a reference to the record describing
- * this log part. One of four records (0,1,2 or 3).
- */
- UintR logPartRec;
- /**
- * Next free log file record or next log file in this log.
- */
- UintR nextLogFile;
- /**
- * The previous log file.
- */
- UintR prevLogFile;
- /**
- * The number of remaining words in this mbyte of the log file.
- */
- UintR remainingWordsInMbyte;
- /**
- * The current file page within the current log file. This is
- * a reference within the file and not a reference to a log
- * page record. It is used to deduce where log records are
- * written. Particularly completed gcp records and prepare log
- * records.
- */
- Uint16 currentFilepage;
- /**
- * The number of pages in the list referenced by
- * LOG_PAGE_BUFFER.
- */
- Uint16 noLogpagesInBuffer;
- }; // Size 288 bytes
- typedef Ptr<LogFileRecord> LogFileRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ LOG OPERATION RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * This record contains a currently active file operation
- * that has started by the log module.
- */
- struct LogFileOperationRecord {
- enum LfoState {
- IDLE = 0, ///< Operation is not used at the moment
- INIT_WRITE_AT_END = 1, ///< Write in file so that it grows to
- ///< 16 Mbyte
- INIT_FIRST_PAGE = 2, ///< Initialise the first page in a file
- WRITE_GCI_ZERO = 3,
- WRITE_INIT_MBYTE = 4,
- WRITE_DIRTY = 5,
- READ_SR_FRONTPAGE = 6, ///< Read page zero in file zero during
- ///< system restart
- READ_SR_LAST_FILE = 7, ///< Read page zero in last file open
- ///< before system crash
- READ_SR_NEXT_FILE = 8, ///< Read 60 files backwards to find
- ///< further information GCPs in page
- ///< zero
- READ_SR_LAST_MBYTE = 9,
- READ_EXEC_SR = 10,
- READ_EXEC_LOG = 11,
- READ_SR_FOURTH_PHASE = 12,
- READ_SR_FOURTH_ZERO = 13,
- FIRST_PAGE_WRITE_IN_LOGFILE = 14,
- LAST_WRITE_IN_FILE = 15,
- WRITE_PAGE_ZERO = 16,
- ACTIVE_WRITE_LOG = 17, ///< A write operation during
- ///< writing of log
- READ_SR_INVALIDATE_PAGES = 18,
- WRITE_SR_INVALIDATE_PAGES = 19,
- WRITE_SR_INVALIDATE_PAGES_UPDATE_PAGE0 = 20
- };
- /**
- * We have to remember the log pages read.
- * Otherwise we cannot build the linked list after the pages have
- * arrived to main memory.
- */
- UintR logPageArray[16];
- /**
- * A list of the pages that are part of this active operation.
- */
- UintR firstLfoPage;
- /**
- * A timer to ensure that records are not lost.
- */
- UintR lfoTimer;
- /**
- * The word number of the last written word in the last during
- * a file write.
- */
- UintR lfoWordWritten;
- /**
- * This variable contains the state of the log file operation.
- */
- LfoState lfoState;
- /**
- * The log file that the file operation affects.
- */
- UintR logFileRec;
- /**
- * The log file operations on a file are kept in a linked list.
- */
- UintR nextLfo;
- /**
- * The page number of the first read/written page during a file
- * read/write.
- */
- Uint16 lfoPageNo;
- /**
- * The number of pages written or read during an operation to
- * the log file.
- */
- Uint16 noPagesRw;
- }; // 92 bytes
- typedef Ptr<LogFileOperationRecord> LogFileOperationRecordPtr;
-
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /* $$$$$$$ LOG PAGE RECORD $$$$$$$ */
- /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
- /**
- * These are the 8 k pages used to store log records before storing
- * them in the file system.
- * Since 64 kbyte is sent to disk at a time it is necessary to have
- * at least 4*64 kbytes of log pages.
- * To handle multiple outstanding requests we need some additional pages.
- * Thus we allocate 1 mbyte to ensure that we do not get problems with
- * insufficient number of pages.
- */
- struct LogPageRecord {
- /**
- * This variable contains the pages that are sent to disk.
- *
- * All pages contain a header of 12 words:
- * - WORD 0: CHECKSUM Calculated before storing on disk and
- * checked when read from disk.
- * - WORD 1: LAP How many wraparounds have the log
- * experienced since initial start of the
- * system.
- * - WORD 2: MAX_GCI_COMPLETED Which is the maximum gci which have
- * completed before this page. This
- * gci will not be found in this
- * page and hereafter in the log.
- * - WORD 3: MAX_GCI_STARTED The maximum gci which have started
- * before this page.
- * - WORD 4: NEXT_PAGE Pointer to the next page.
- * Only used in main memory
- * - WORD 5: PREVIOUS_PAGE Pointer to the previous page.
- * Currently not used.
- * - WORD 6: VERSION NDB version that wrote the page.
- * - WORD 7: NO_LOG_FILES Number of log files in this log part.
- * - WORD 8: CURRENT PAGE INDEX This keeps track of where we are in the
- * page.
- * This is only used when pages is in
- * memory.
- * - WORD 9: OLD PREPARE FILE NO This keeps track of the oldest prepare
- * operation still alive (not committed
- * or aborted) when this mbyte started.
- * - WORD 10: OLD PREPARE PAGE REF File page reference within this file
- * number.
- * Page no + Page index.
- * If no prepare was alive then these
- * values points this mbyte.
- * - WORD 11: DIRTY FLAG = 0 means not dirty and
- * = 1 means the page is dirty.
- * Is used when executing log when
- * a need to write invalid commit
- * records arise.
- *
- * The remaining 2036 words are used for log information, i.e.
- * log records.
- *
- * A log record on this page has the following layout:
- * - WORD 0: LOG RECORD TYPE
- * The following types are supported:
- * - PREPARE OPERATION An operation not yet committed.
- * - NEW PREPARE OPERATION A prepared operation already
- * logged is inserted
- * into the log again so that the
- * log tail can be advanced.
- * This can happen when a transaction is
- * committed for a long time.
- * - ABORT TRANSACTION A previously prepared transaction
- * was aborted.
- * - COMMIT TRANSACTION A previously prepared transaction
- * was committed.
- * - INVALID COMMIT A previous commit record was
- * invalidated by a
- * subsequent system restart.
- * A log record must be invalidated
- * in a system restart if it belongs
- * to a global checkpoint id which
- * is not included in the system
- * restart.
- * Otherwise it will be included in
- * a subsequent system restart since
- * it will then most likely belong
- * to a global checkpoint id which
- * is part of that system
- * restart.
- * This is not a correct behaviour
- * since this operation is lost in a
- * system restart and should not
- * reappear at a later system
- * restart.
- * - COMPLETED GCI A GCI has now been completed.
- * - FRAGMENT SPLIT A fragment has been split
- * (not implemented yet)
- * - FILE DESCRIPTOR This is always the first log record
- * in a file.
- * It is always placed on page 0 after
- * the header.
- * It is written when the file is
- * opened and when the file is closed.
- * - NEXT LOG RECORD This log record only records where
- * the next log record starts.
- * - NEXT MBYTE RECORD This log record specifies that there
- * are no more log records in this mbyte.
- *
- *
- * A FILE DESCRIPTOR log record continues as follows:
- * - WORD 1: NO_LOG_DESCRIPTORS This defines the number of
- * descriptors of log files that
- * will follow hereafter (max 32).
- * the log descriptor will describe
- * information about
- * max_gci_completed,
- * max_gci_started and log_lap at
- * every 1 mbyte of the log file
- * since a log file is 16 mbyte
- * always, i need 16 entries in the
- * array with max_gci_completed,
- * max_gci_started and log_lap. thus
- * 32 entries per log file
- * descriptor (max 32*48 = 1536,
- * always fits in page 0).
- * - WORD 2: LAST LOG FILE The number of the log file currently
- * open. This is only valid in file 0.
- * - WORD 3 - WORD 18: MAX_GCI_COMPLETED for every 1 mbyte
- * in this log file.
- * - WORD 19 - WORD 34: MAX_GCI_STARTED for every 1 mbyte
- * in this log file.
- *
- * Then it continues for NO_LOG_DESCRIPTORS until all subsequent
- * log files (max 32) have been properly described.
- *
- *
- * A PREPARE OPERATION log record continues as follows:
- * - WORD 1: LOG RECORD SIZE
- * - WORD 2: HASH VALUE
- * - WORD 3: SCHEMA VERSION
- * - WORD 4: OPERATION TYPE
- * = 0 READ,
- * = 1 UPDATE,
- * = 2 INSERT,
- * = 3 DELETE
- * - WORD 5: NUMBER OF WORDS IN ATTRINFO PART
- * - WORD 6: KEY LENGTH IN WORDS
- * - WORD 7 - (WORD 7 + KEY_LENGTH - 1) The tuple key
- * - (WORD 7 + KEY_LENGTH) -
- * (WORD 7 + KEY_LENGTH + ATTRINFO_LENGTH - 1) The attrinfo
- *
- * A log record can be spread in several pages in some cases.
- * The next log record always starts immediately after this log record.
- * A log record does however never traverse a 1 mbyte boundary.
- * This is used to ensure that we can always come back if something
- * strange occurs in the log file.
- * To ensure this we also have log records which only records
- * the next log record.
- *
- *
- * A COMMIT TRANSACTION log record continues as follows:
- * - WORD 1: TRANSACTION ID PART 1
- * - WORD 2: TRANSACTION ID PART 2
- * - WORD 3: FRAGMENT ID OF THE OPERATION
- * - WORD 4: TABLE ID OF THE OPERATION
- * - WORD 5: THE FILE NUMBER OF THE PREPARE RECORD
- * - WORD 6: THE STARTING PAGE NUMBER OF THE PREPARE RECORD
- * - WORD 7: THE STARTING PAGE INDEX OF THE PREPARE RECORD
- * - WORD 8: THE STOP PAGE NUMBER OF THE PREPARE RECORD
- * - WORD 9: GLOBAL CHECKPOINT OF THE TRANSACTION
- *
- *
- * An ABORT TRANSACTION log record continues as follows:
- * - WORD 1: TRANSACTION ID PART 1
- * - WORD 2: TRANSACTION ID PART 2
- *
- *
- * A COMPLETED CGI log record continues as follows:
- * - WORD 1: THE COMPLETED GCI
- *
- *
- * A NEXT LOG RECORD log record continues as follows:
- * - There is no more information needed.
- * The next log record will always refer to the start of the next page.
- *
- * A NEXT MBYTE RECORD log record continues as follows:
- * - There is no more information needed.
- * The next mbyte will always refer to the start of the next mbyte.
- */
- UintR logPageWord[8192]; // Size 32 kbytes
- };
- typedef Ptr<LogPageRecord> LogPageRecordPtr;
-
- struct PageRefRecord {
- UintR pageRef[8];
- UintR prNext;
- UintR prPrev;
- Uint16 prFileNo;
- Uint16 prPageNo;
- }; // size 44 bytes
- typedef Ptr<PageRefRecord> PageRefRecordPtr;
-
- struct Tablerec {
- enum TableStatus {
- TABLE_DEFINED = 0,
- NOT_DEFINED = 1,
- ADD_TABLE_ONGOING = 2,
- PREP_DROP_TABLE_ONGOING = 3,
- PREP_DROP_TABLE_DONE = 4
- };
-
- UintR fragrec[MAX_FRAG_PER_NODE];
- Uint16 fragid[MAX_FRAG_PER_NODE];
- /**
- * Status of the table
- */
- TableStatus tableStatus;
- /**
- * Table type and target table of index.
- */
- Uint16 tableType;
- Uint16 primaryTableId;
- Uint32 schemaVersion;
- Uint8 m_disk_table;
-
- Uint32 usageCount;
- NdbNodeBitmask waitingTC;
- NdbNodeBitmask waitingDIH;
- }; // Size 100 bytes
- typedef Ptr<Tablerec> TablerecPtr;
-
- struct TcConnectionrec {
- enum ListState {
- NOT_IN_LIST = 0,
- WAIT_QUEUE_LIST = 3
- };
- enum LogWriteState {
- NOT_STARTED = 0,
- NOT_WRITTEN = 1,
- NOT_WRITTEN_WAIT = 2,
- WRITTEN = 3
- };
- enum AbortState {
- ABORT_IDLE = 0,
- ABORT_ACTIVE = 1,
- NEW_FROM_TC = 2,
- REQ_FROM_TC = 3,
- ABORT_FROM_TC = 4,
- ABORT_FROM_LQH = 5
- };
- enum TransactionState {
- IDLE = 0,
-
- /* -------------------------------------------------------------------- */
- // Transaction in progress states
- /* -------------------------------------------------------------------- */
- WAIT_ACC = 1,
- WAIT_TUPKEYINFO = 2,
- WAIT_ATTR = 3,
- WAIT_TUP = 4,
- STOPPED = 5,
- LOG_QUEUED = 6,
- PREPARED = 7,
- LOG_COMMIT_WRITTEN_WAIT_SIGNAL = 8,
- LOG_COMMIT_QUEUED_WAIT_SIGNAL = 9,
-
- /* -------------------------------------------------------------------- */
- // Commit in progress states
- /* -------------------------------------------------------------------- */
- COMMIT_STOPPED = 10,
- LOG_COMMIT_QUEUED = 11,
- COMMIT_QUEUED = 12,
- COMMITTED = 13,
- WAIT_TUP_COMMIT= 35,
-
- /* -------------------------------------------------------------------- */
- // Abort in progress states
- /* -------------------------------------------------------------------- */
- WAIT_ACC_ABORT = 14,
- ABORT_QUEUED = 15,
- ABORT_STOPPED = 16,
- WAIT_AI_AFTER_ABORT = 17,
- LOG_ABORT_QUEUED = 18,
- WAIT_TUP_TO_ABORT = 19,
-
- /* -------------------------------------------------------------------- */
- // Scan in progress states
- /* -------------------------------------------------------------------- */
- WAIT_SCAN_AI = 20,
- SCAN_STATE_USED = 21,
- SCAN_FIRST_STOPPED = 22,
- SCAN_CHECK_STOPPED = 23,
- SCAN_STOPPED = 24,
- SCAN_RELEASE_STOPPED = 25,
- SCAN_CLOSE_STOPPED = 26,
- COPY_CLOSE_STOPPED = 27,
- COPY_FIRST_STOPPED = 28,
- COPY_STOPPED = 29,
- SCAN_TUPKEY = 30,
- COPY_TUPKEY = 31,
-
- TC_NOT_CONNECTED = 32,
- PREPARED_RECEIVED_COMMIT = 33, // Temporary state in write commit log
- LOG_COMMIT_WRITTEN = 34 // Temporary state in write commit log
- };
- enum ConnectState {
- DISCONNECTED = 0,
- CONNECTED = 1,
- COPY_CONNECTED = 2,
- LOG_CONNECTED = 3
- };
- ConnectState connectState;
- UintR copyCountWords;
- UintR firstAttrinfo[5];
- UintR tupkeyData[4];
- UintR transid[2];
- AbortState abortState;
- UintR accConnectrec;
- UintR applOprec;
- UintR clientConnectrec;
- UintR tcTimer;
- UintR currReclenAi;
- UintR currTupAiLen;
- UintR firstAttrinbuf;
- UintR firstTupkeybuf;
- UintR fragmentid;
- UintR fragmentptr;
- UintR gci;
- UintR hashValue;
- UintR lastTupkeybuf;
- UintR lastAttrinbuf;
- /**
- * Each operation (TcConnectrec) can be stored in max one out of many
- * lists.
- * This variable keeps track of which list it is in.
- */
- ListState listState;
-
- UintR logStartFileNo;
- LogWriteState logWriteState;
- UintR nextHashRec;
- UintR nextLogTcrec;
- UintR nextTcLogQueue;
- UintR nextTc;
- UintR nextTcConnectrec;
- UintR prevHashRec;
- UintR prevLogTcrec;
- UintR prevTc;
- UintR readlenAi;
- UintR reqRef;
- UintR reqinfo;
- UintR schemaVersion;
- UintR storedProcId;
- UintR simpleTcConnect;
- UintR tableref;
- UintR tcOprec;
- UintR tcScanInfo;
- UintR tcScanRec;
- UintR totReclenAi;
- UintR totSendlenAi;
- UintR tupConnectrec;
- UintR savePointId;
- TransactionState transactionState;
- BlockReference applRef;
- BlockReference clientBlockref;
-
- BlockReference reqBlockref;
- BlockReference tcBlockref;
- BlockReference tcAccBlockref;
- BlockReference tcTuxBlockref;
- BlockReference tcTupBlockref;
- Uint32 commitAckMarker;
- union {
- Uint32 m_scan_curr_range_no;
- UintR noFiredTriggers;
- };
- Uint16 errorCode;
- Uint16 logStartPageIndex;
- Uint16 logStartPageNo;
- Uint16 logStopPageNo;
- Uint16 nextReplica;
- Uint16 primKeyLen;
- Uint16 save1;
- Uint16 nodeAfterNext[3];
-
- Uint8 activeCreat;
- Uint8 apiVersionNo;
- Uint8 dirtyOp;
- Uint8 indTakeOver;
- Uint8 lastReplicaNo;
- Uint8 lockType;
- Uint8 nextSeqNoReplica;
- Uint8 opSimple;
- Uint8 opExec;
- Uint8 operation;
- Uint8 reclenAiLqhkey;
- Uint8 m_offset_current_keybuf;
- Uint8 replicaType;
- Uint8 seqNoReplica;
- Uint8 tcNodeFailrec;
- Uint8 m_disk_table;
- Uint8 m_use_rowid;
- Uint8 m_dealloc;
- Uint32 m_log_part_ptr_i;
- Local_key m_row_id;
-
- struct {
- Uint32 m_cnt;
- Uint32 m_page_id[2];
- Local_key m_disk_ref[2];
- } m_nr_delete;
- }; /* p2c: size = 280 bytes */
-
- typedef Ptr<TcConnectionrec> TcConnectionrecPtr;
-
- struct TcNodeFailRecord {
- enum TcFailStatus {
- TC_STATE_TRUE = 0,
- TC_STATE_FALSE = 1,
- TC_STATE_BREAK = 2
- };
- UintR lastNewTcRef;
- UintR newTcRef;
- TcFailStatus tcFailStatus;
- UintR tcRecNow;
- BlockReference lastNewTcBlockref;
- BlockReference newTcBlockref;
- Uint16 oldNodeId;
- }; // Size 28 bytes
- typedef Ptr<TcNodeFailRecord> TcNodeFailRecordPtr;
-
- struct CommitLogRecord {
- Uint32 startPageNo;
- Uint32 startPageIndex;
- Uint32 stopPageNo;
- Uint32 fileNo;
- };
-
-public:
- Dblqh(Block_context& ctx);
- virtual ~Dblqh();
-
- void receive_keyinfo(Signal*, Uint32 * data, Uint32 len);
- void receive_attrinfo(Signal*, Uint32 * data, Uint32 len);
-
-private:
- BLOCK_DEFINES(Dblqh);
-
- void execPACKED_SIGNAL(Signal* signal);
- void execDEBUG_SIG(Signal* signal);
- void execATTRINFO(Signal* signal);
- void execKEYINFO(Signal* signal);
- void execLQHKEYREQ(Signal* signal);
- void execLQHKEYREF(Signal* signal);
- void execCOMMIT(Signal* signal);
- void execCOMPLETE(Signal* signal);
- void execLQHKEYCONF(Signal* signal);
- void execTESTSIG(Signal* signal);
- void execLQH_RESTART_OP(Signal* signal);
- void execCONTINUEB(Signal* signal);
- void execSTART_RECREQ(Signal* signal);
- void execSTART_RECCONF(Signal* signal);
- void execEXEC_FRAGREQ(Signal* signal);
- void execEXEC_FRAGCONF(Signal* signal);
- void execEXEC_FRAGREF(Signal* signal);
- void execSTART_EXEC_SR(Signal* signal);
- void execEXEC_SRREQ(Signal* signal);
- void execEXEC_SRCONF(Signal* signal);
- void execREAD_PSEUDO_REQ(Signal* signal);
-
- void execDUMP_STATE_ORD(Signal* signal);
- void execACC_ABORTCONF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execCHECK_LCP_STOP(Signal* signal);
- void execSEND_PACKED(Signal* signal);
- void execTUP_ATTRINFO(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execLQHFRAGREQ(Signal* signal);
- void execLQHADDATTREQ(Signal* signal);
- void execTUP_ADD_ATTCONF(Signal* signal);
- void execTUP_ADD_ATTRREF(Signal* signal);
- void execACCFRAGCONF(Signal* signal);
- void execACCFRAGREF(Signal* signal);
- void execTUPFRAGCONF(Signal* signal);
- void execTUPFRAGREF(Signal* signal);
- void execTAB_COMMITREQ(Signal* signal);
- void execACCSEIZECONF(Signal* signal);
- void execACCSEIZEREF(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execREAD_NODESREF(Signal* signal);
- void execSTTOR(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execTUPSEIZECONF(Signal* signal);
- void execTUPSEIZEREF(Signal* signal);
- void execACCKEYCONF(Signal* signal);
- void execACCKEYREF(Signal* signal);
- void execTUPKEYCONF(Signal* signal);
- void execTUPKEYREF(Signal* signal);
- void execABORT(Signal* signal);
- void execABORTREQ(Signal* signal);
- void execCOMMITREQ(Signal* signal);
- void execCOMPLETEREQ(Signal* signal);
- void execMEMCHECKREQ(Signal* signal);
- void execSCAN_FRAGREQ(Signal* signal);
- void execSCAN_NEXTREQ(Signal* signal);
- void execACC_SCANCONF(Signal* signal);
- void execACC_SCANREF(Signal* signal);
- void execNEXT_SCANCONF(Signal* signal);
- void execNEXT_SCANREF(Signal* signal);
- void execACC_TO_REF(Signal* signal);
- void execSTORED_PROCCONF(Signal* signal);
- void execSTORED_PROCREF(Signal* signal);
- void execCOPY_FRAGREQ(Signal* signal);
- void execPREPARE_COPY_FRAG_REQ(Signal* signal);
- void execUPDATE_FRAG_DIST_KEY_ORD(Signal*);
- void execCOPY_ACTIVEREQ(Signal* signal);
- void execCOPY_STATEREQ(Signal* signal);
- void execLQH_TRANSREQ(Signal* signal);
- void execTRANSID_AI(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
-
- void execLCP_FRAG_ORD(Signal* signal);
- void execEMPTY_LCP_REQ(Signal* signal);
-
- void execSTART_FRAGREQ(Signal* signal);
- void execSTART_RECREF(Signal* signal);
-
- void execGCP_SAVEREQ(Signal* signal);
- void execFSOPENREF(Signal* signal);
- void execFSOPENCONF(Signal* signal);
- void execFSCLOSECONF(Signal* signal);
- void execFSWRITECONF(Signal* signal);
- void execFSWRITEREF(Signal* signal);
- void execFSREADCONF(Signal* signal);
- void execFSREADREF(Signal* signal);
- void execSCAN_HBREP(Signal* signal);
- void execTIME_SIGNAL(Signal* signal);
- void execFSSYNCCONF(Signal* signal);
-
- void execALTER_TAB_REQ(Signal* signal);
- void execALTER_TAB_CONF(Signal* signal);
-
- void execCREATE_TRIG_CONF(Signal* signal);
- void execCREATE_TRIG_REF(Signal* signal);
- void execCREATE_TRIG_REQ(Signal* signal);
-
- void execDROP_TRIG_CONF(Signal* signal);
- void execDROP_TRIG_REF(Signal* signal);
- void execDROP_TRIG_REQ(Signal* signal);
-
- void execPREP_DROP_TAB_REQ(Signal* signal);
- void execWAIT_DROP_TAB_REQ(Signal* signal);
- void execDROP_TAB_REQ(Signal* signal);
-
- void execLQH_ALLOCREQ(Signal* signal);
- void execTUP_DEALLOCREQ(Signal* signal);
- void execLQH_WRITELOG_REQ(Signal* signal);
-
- void execTUXFRAGCONF(Signal* signal);
- void execTUXFRAGREF(Signal* signal);
- void execTUX_ADD_ATTRCONF(Signal* signal);
- void execTUX_ADD_ATTRREF(Signal* signal);
-
- // Statement blocks
-
- void init_acc_ptr_list(ScanRecord*);
- bool seize_acc_ptr_list(ScanRecord*, Uint32);
- void release_acc_ptr_list(ScanRecord*);
- Uint32 get_acc_ptr_from_scan_record(ScanRecord*, Uint32, bool);
- void set_acc_ptr_in_scan_record(ScanRecord*, Uint32, Uint32);
- void i_get_acc_ptr(ScanRecord*, Uint32*&, Uint32);
-
- void removeTable(Uint32 tableId);
- void sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId);
- void sendEMPTY_LCP_CONF(Signal* signal, bool idle);
- void sendLCP_FRAGIDREQ(Signal* signal);
- void sendLCP_FRAG_REP(Signal * signal, const LcpRecord::FragOrd &) const;
-
- void updatePackedList(Signal* signal, HostRecord * ahostptr, Uint16 hostId);
- void LQHKEY_abort(Signal* signal, int errortype);
- void LQHKEY_error(Signal* signal, int errortype);
- void nextRecordCopy(Signal* signal);
- Uint32 calculateHash(Uint32 tableId, const Uint32* src);
- void continueAfterCheckLcpStopBlocked(Signal* signal);
- void checkLcpStopBlockedLab(Signal* signal);
- void sendCommittedTc(Signal* signal, BlockReference atcBlockref);
- void sendCompletedTc(Signal* signal, BlockReference atcBlockref);
- void sendLqhkeyconfTc(Signal* signal, BlockReference atcBlockref);
- void sendCommitLqh(Signal* signal, BlockReference alqhBlockref);
- void sendCompleteLqh(Signal* signal, BlockReference alqhBlockref);
- void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
- void sendPackedSignalTc(Signal* signal, HostRecord * ahostptr);
- void cleanUp(Signal* signal);
- void sendAttrinfoLoop(Signal* signal);
- void sendAttrinfoSignal(Signal* signal);
- void sendLqhAttrinfoSignal(Signal* signal);
- void sendKeyinfoAcc(Signal* signal, Uint32 pos);
- Uint32 initScanrec(const class ScanFragReq *);
- void initScanTc(const class ScanFragReq *,
- Uint32 transid1,
- Uint32 transid2,
- Uint32 fragId,
- Uint32 nodeId);
- void finishScanrec(Signal* signal);
- void releaseScanrec(Signal* signal);
- void seizeScanrec(Signal* signal);
- Uint32 sendKeyinfo20(Signal* signal, ScanRecord *, TcConnectionrec *);
- void sendTCKEYREF(Signal*, Uint32 dst, Uint32 route, Uint32 cnt);
- void sendScanFragConf(Signal* signal, Uint32 scanCompleted);
- void initCopyrec(Signal* signal);
- void initCopyTc(Signal* signal, Operation_t);
- void sendCopyActiveConf(Signal* signal,Uint32 tableId);
- void checkLcpCompleted(Signal* signal);
- void checkLcpHoldop(Signal* signal);
- bool checkLcpStarted(Signal* signal);
- void checkLcpTupprep(Signal* signal);
- void getNextFragForLcp(Signal* signal);
- void sendAccContOp(Signal* signal);
- void sendStartLcp(Signal* signal);
- void setLogTail(Signal* signal, Uint32 keepGci);
- Uint32 remainingLogSize(const LogFileRecordPtr &sltCurrLogFilePtr,
- const LogPartRecordPtr &sltLogPartPtr);
- void checkGcpCompleted(Signal* signal, Uint32 pageWritten, Uint32 wordWritten);
- void initFsopenconf(Signal* signal);
- void initFsrwconf(Signal* signal, bool write);
- void initLfo(Signal* signal);
- void initLogfile(Signal* signal, Uint32 fileNo);
- void initLogpage(Signal* signal);
- void openFileRw(Signal* signal, LogFileRecordPtr olfLogFilePtr);
- void openLogfileInit(Signal* signal);
- void openNextLogfile(Signal* signal);
- void releaseLfo(Signal* signal);
- void releaseLfoPages(Signal* signal);
- void releaseLogpage(Signal* signal);
- void seizeLfo(Signal* signal);
- void seizeLogfile(Signal* signal);
- void seizeLogpage(Signal* signal);
- void writeFileDescriptor(Signal* signal);
- void writeFileHeaderOpen(Signal* signal, Uint32 type);
- void writeInitMbyte(Signal* signal);
- void writeSinglePage(Signal* signal, Uint32 pageNo,
- Uint32 wordWritten, Uint32 place);
- void buildLinkedLogPageList(Signal* signal);
- void changeMbyte(Signal* signal);
- Uint32 checkIfExecLog(Signal* signal);
- void checkNewMbyte(Signal* signal);
- void checkReadExecSr(Signal* signal);
- void checkScanTcCompleted(Signal* signal);
- void closeFile(Signal* signal, LogFileRecordPtr logFilePtr, Uint32 place);
- void completedLogPage(Signal* signal, Uint32 clpType, Uint32 place);
- void deleteFragrec(Uint32 fragId);
- void deleteTransidHash(Signal* signal);
- void findLogfile(Signal* signal,
- Uint32 fileNo,
- LogPartRecordPtr flfLogPartPtr,
- LogFileRecordPtr* parLogFilePtr);
- void findPageRef(Signal* signal, CommitLogRecord* commitLogRecord);
- int findTransaction(UintR Transid1, UintR Transid2, UintR TcOprec);
- void getFirstInLogQueue(Signal* signal);
- bool getFragmentrec(Signal* signal, Uint32 fragId);
- void initialiseAddfragrec(Signal* signal);
- void initialiseAttrbuf(Signal* signal);
- void initialiseDatabuf(Signal* signal);
- void initialiseFragrec(Signal* signal);
- void initialiseGcprec(Signal* signal);
- void initialiseLcpRec(Signal* signal);
- void initialiseLfo(Signal* signal);
- void initialiseLogFile(Signal* signal);
- void initialiseLogPage(Signal* signal);
- void initialiseLogPart(Signal* signal);
- void initialisePageRef(Signal* signal);
- void initialiseScanrec(Signal* signal);
- void initialiseTabrec(Signal* signal);
- void initialiseTcrec(Signal* signal);
- void initialiseTcNodeFailRec(Signal* signal);
- void initFragrec(Signal* signal,
- Uint32 tableId,
- Uint32 fragId,
- Uint32 copyType);
- void initFragrecSr(Signal* signal);
- void initGciInLogFileRec(Signal* signal, Uint32 noFdDesc);
- void initLcpSr(Signal* signal,
- Uint32 lcpNo,
- Uint32 lcpId,
- Uint32 tableId,
- Uint32 fragId,
- Uint32 fragPtr);
- void initLogpart(Signal* signal);
- void initLogPointers(Signal* signal);
- void initReqinfoExecSr(Signal* signal);
- bool insertFragrec(Signal* signal, Uint32 fragId);
- void linkFragQueue(Signal* signal);
- void linkWaitLog(Signal* signal, LogPartRecordPtr regLogPartPtr);
- void logNextStart(Signal* signal);
- void moveToPageRef(Signal* signal);
- void readAttrinfo(Signal* signal);
- void readCommitLog(Signal* signal, CommitLogRecord* commitLogRecord);
- void readExecLog(Signal* signal);
- void readExecSrNewMbyte(Signal* signal);
- void readExecSr(Signal* signal);
- void readKey(Signal* signal);
- void readLogData(Signal* signal, Uint32 noOfWords, Uint32* dataPtr);
- void readLogHeader(Signal* signal);
- Uint32 readLogword(Signal* signal);
- Uint32 readLogwordExec(Signal* signal);
- void readSinglePage(Signal* signal, Uint32 pageNo);
- void releaseActiveCopy(Signal* signal);
- void releaseAddfragrec(Signal* signal);
- void releaseFragrec();
- void releaseOprec(Signal* signal);
- void releasePageRef(Signal* signal);
- void releaseMmPages(Signal* signal);
- void releasePrPages(Signal* signal);
- void releaseTcrec(Signal* signal, TcConnectionrecPtr tcConnectptr);
- void releaseTcrecLog(Signal* signal, TcConnectionrecPtr tcConnectptr);
- void releaseWaitQueue(Signal* signal);
- void removeLogTcrec(Signal* signal);
- void removePageRef(Signal* signal);
- Uint32 returnExecLog(Signal* signal);
- int saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 length);
- void seizeAddfragrec(Signal* signal);
- void seizeAttrinbuf(Signal* signal);
- Uint32 seize_attrinbuf();
- Uint32 release_attrinbuf(Uint32);
- Uint32 copy_bounds(Uint32 * dst, TcConnectionrec*);
-
- void seizeFragmentrec(Signal* signal);
- void seizePageRef(Signal* signal);
- void seizeTcrec();
- void seizeTupkeybuf(Signal* signal);
- void sendAborted(Signal* signal);
- void sendLqhTransconf(Signal* signal, LqhTransConf::OperationStatus);
- void sendTupkey(Signal* signal);
- void startExecSr(Signal* signal);
- void startNextExecSr(Signal* signal);
- void startTimeSupervision(Signal* signal);
- void stepAhead(Signal* signal, Uint32 stepAheadWords);
- void systemError(Signal* signal, int line);
- void writeAbortLog(Signal* signal);
- void writeCommitLog(Signal* signal, LogPartRecordPtr regLogPartPtr);
- void writeCompletedGciLog(Signal* signal);
- void writeDbgInfoPageHeader(LogPageRecordPtr logPagePtr, Uint32 place,
- Uint32 pageNo, Uint32 wordWritten);
- void writeDirty(Signal* signal, Uint32 place);
- void writeKey(Signal* signal);
- void writeLogHeader(Signal* signal);
- void writeLogWord(Signal* signal, Uint32 data);
- void writeNextLog(Signal* signal);
- void errorReport(Signal* signal, int place);
- void warningReport(Signal* signal, int place);
- void invalidateLogAfterLastGCI(Signal *signal);
- void readFileInInvalidate(Signal *signal, bool stepNext);
- void exitFromInvalidate(Signal* signal);
- Uint32 calcPageCheckSum(LogPageRecordPtr logP);
- Uint32 handleLongTupKey(Signal* signal, Uint32* dataPtr, Uint32 len);
-
- // Generated statement blocks
- void systemErrorLab(Signal* signal, int line);
- void initFourth(Signal* signal);
- void packLqhkeyreqLab(Signal* signal);
- void sendNdbSttorryLab(Signal* signal);
- void execSrCompletedLab(Signal* signal);
- void execLogRecord(Signal* signal);
- void srPhase3Comp(Signal* signal);
- void srLogLimits(Signal* signal);
- void srGciLimits(Signal* signal);
- void srPhase3Start(Signal* signal);
- void checkStartCompletedLab(Signal* signal);
- void continueAbortLab(Signal* signal);
- void abortContinueAfterBlockedLab(Signal* signal, bool canBlock);
- void abortCommonLab(Signal* signal);
- void localCommitLab(Signal* signal);
- void abortErrorLab(Signal* signal);
- void continueAfterReceivingAllAiLab(Signal* signal);
- void abortStateHandlerLab(Signal* signal);
- void writeAttrinfoLab(Signal* signal);
- void scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length);
- void abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode);
- void localAbortStateHandlerLab(Signal* signal);
- void logLqhkeyreqLab(Signal* signal);
- void lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length);
- void rwConcludedAiLab(Signal* signal);
- void aiStateErrorCheckLab(Signal* signal, Uint32* dataPtr, Uint32 length);
- void takeOverErrorLab(Signal* signal);
- void endgettupkeyLab(Signal* signal);
- void noFreeRecordLab(Signal* signal,
- const class LqhKeyReq * lqhKeyReq,
- Uint32 errorCode);
- void logLqhkeyrefLab(Signal* signal);
- void closeCopyLab(Signal* signal);
- void commitReplyLab(Signal* signal);
- void completeUnusualLab(Signal* signal);
- void completeTransNotLastLab(Signal* signal);
- void completedLab(Signal* signal);
- void copyCompletedLab(Signal* signal);
- void completeLcpRoundLab(Signal* signal, Uint32 lcpId);
- void continueAfterLogAbortWriteLab(Signal* signal);
- void sendAttrinfoLab(Signal* signal);
- void sendExecConf(Signal* signal);
- void execSr(Signal* signal);
- void srFourthComp(Signal* signal);
- void timeSup(Signal* signal);
- void closeCopyRequestLab(Signal* signal);
- void closeScanRequestLab(Signal* signal);
- void scanTcConnectLab(Signal* signal, Uint32 startTcCon, Uint32 fragId);
- void initGcpRecLab(Signal* signal);
- void prepareContinueAfterBlockedLab(Signal* signal);
- void commitContinueAfterBlockedLab(Signal* signal);
- void continueCopyAfterBlockedLab(Signal* signal);
- void continueFirstCopyAfterBlockedLab(Signal* signal);
- void continueFirstScanAfterBlockedLab(Signal* signal);
- void continueScanAfterBlockedLab(Signal* signal);
- void continueScanReleaseAfterBlockedLab(Signal* signal);
- void continueCloseScanAfterBlockedLab(Signal* signal);
- void continueCloseCopyAfterBlockedLab(Signal* signal);
- void sendExecFragRefLab(Signal* signal);
- void fragrefLab(Signal* signal, BlockReference retRef,
- Uint32 retPtr, Uint32 errorCode);
- void abortAddFragOps(Signal* signal);
- void rwConcludedLab(Signal* signal);
- void sendsttorryLab(Signal* signal);
- void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32);
- void startphase2Lab(Signal* signal, Uint32 config);
- void startphase3Lab(Signal* signal);
- void startphase4Lab(Signal* signal);
- void startphase6Lab(Signal* signal);
- void moreconnectionsLab(Signal* signal);
- void scanReleaseLocksLab(Signal* signal);
- void closeScanLab(Signal* signal);
- void nextScanConfLoopLab(Signal* signal);
- void scanNextLoopLab(Signal* signal);
- void commitReqLab(Signal* signal, Uint32 gci);
- void completeTransLastLab(Signal* signal);
- void tupScanCloseConfLab(Signal* signal);
- void tupCopyCloseConfLab(Signal* signal);
- void accScanCloseConfLab(Signal* signal);
- void accCopyCloseConfLab(Signal* signal);
- void nextScanConfScanLab(Signal* signal);
- void nextScanConfCopyLab(Signal* signal);
- void continueScanNextReqLab(Signal* signal);
- void keyinfoLab(const Uint32 * src, const Uint32 * end);
- void copySendTupkeyReqLab(Signal* signal);
- void storedProcConfScanLab(Signal* signal);
- void storedProcConfCopyLab(Signal* signal);
- void copyStateFinishedLab(Signal* signal);
- void lcpCompletedLab(Signal* signal);
- void lcpStartedLab(Signal* signal);
- void contChkpNextFragLab(Signal* signal);
- void startLcpRoundLab(Signal* signal);
- void startFragRefLab(Signal* signal);
- void srCompletedLab(Signal* signal);
- void openFileInitLab(Signal* signal);
- void openSrFrontpageLab(Signal* signal);
- void openSrLastFileLab(Signal* signal);
- void openSrNextFileLab(Signal* signal);
- void openExecSrStartLab(Signal* signal);
- void openExecSrNewMbyteLab(Signal* signal);
- void openSrFourthPhaseLab(Signal* signal);
- void openSrFourthZeroSkipInitLab(Signal* signal);
- void openSrFourthZeroLab(Signal* signal);
- void openExecLogLab(Signal* signal);
- void checkInitCompletedLab(Signal* signal);
- void closingSrLab(Signal* signal);
- void closeExecSrLab(Signal* signal);
- void execLogComp(Signal* signal);
- void closeWriteLogLab(Signal* signal);
- void closeExecLogLab(Signal* signal);
- void writePageZeroLab(Signal* signal);
- void lastWriteInFileLab(Signal* signal);
- void initWriteEndLab(Signal* signal);
- void initFirstPageLab(Signal* signal);
- void writeGciZeroLab(Signal* signal);
- void writeDirtyLab(Signal* signal);
- void writeInitMbyteLab(Signal* signal);
- void writeLogfileLab(Signal* signal);
- void firstPageWriteLab(Signal* signal);
- void readSrLastMbyteLab(Signal* signal);
- void readSrLastFileLab(Signal* signal);
- void readSrNextFileLab(Signal* signal);
- void readExecSrLab(Signal* signal);
- void readExecLogLab(Signal* signal);
- void readSrFourthPhaseLab(Signal* signal);
- void readSrFourthZeroLab(Signal* signal);
- void copyLqhKeyRefLab(Signal* signal);
- void restartOperationsLab(Signal* signal);
- void lqhTransNextLab(Signal* signal);
- void restartOperationsAfterStopLab(Signal* signal);
- void startphase1Lab(Signal* signal, Uint32 config, Uint32 nodeId);
- void tupkeyConfLab(Signal* signal);
- void copyTupkeyConfLab(Signal* signal);
- void scanTupkeyConfLab(Signal* signal);
- void scanTupkeyRefLab(Signal* signal);
- void accScanConfScanLab(Signal* signal);
- void accScanConfCopyLab(Signal* signal);
- void scanLockReleasedLab(Signal* signal);
- void openSrFourthNextLab(Signal* signal);
- void closingInitLab(Signal* signal);
- void closeExecSrCompletedLab(Signal* signal);
- void readSrFrontpageLab(Signal* signal);
-
- void sendAddFragReq(Signal* signal);
- void sendAddAttrReq(Signal* signal);
- void checkDropTab(Signal*);
- Uint32 checkDropTabState(Tablerec::TableStatus, Uint32) const;
-
- // Initialisation
- void initData();
- void initRecords();
-
- void define_backup(Signal*);
- void execDEFINE_BACKUP_REF(Signal*);
- void execDEFINE_BACKUP_CONF(Signal*);
- void execBACKUP_FRAGMENT_REF(Signal* signal);
- void execBACKUP_FRAGMENT_CONF(Signal* signal);
- void execLCP_PREPARE_REF(Signal* signal);
- void execLCP_PREPARE_CONF(Signal* signal);
- void execEND_LCPREF(Signal* signal);
- void execEND_LCPCONF(Signal* signal);
- Uint32 m_backup_ptr;
-
- void send_restore_lcp(Signal * signal);
- void execRESTORE_LCP_REF(Signal* signal);
- void execRESTORE_LCP_CONF(Signal* signal);
-
- Dbtup* c_tup;
- Dbacc* c_acc;
-
- /**
- * Read primary key from tup
- */
- Uint32 readPrimaryKeys(ScanRecord*, TcConnectionrec*, Uint32 * dst);
-
- /**
- * Read primary key from operation
- */
-public:
- Uint32 readPrimaryKeys(Uint32 opPtrI, Uint32 * dst, bool xfrm);
-private:
-
- void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
- void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
-
- void handle_nr_copy(Signal*, Ptr<TcConnectionrec>);
- void exec_acckeyreq(Signal*, Ptr<TcConnectionrec>);
- int compare_key(const TcConnectionrec*, const Uint32 * ptr, Uint32 len);
- void nr_copy_delete_row(Signal*, Ptr<TcConnectionrec>, Local_key*, Uint32);
-public:
- struct Nr_op_info
- {
- Uint32 m_ptr_i;
- Uint32 m_tup_frag_ptr_i;
- Uint32 m_gci;
- Uint32 m_page_id;
- Local_key m_disk_ref;
- };
- void get_nr_op_info(Nr_op_info*, Uint32 page_id = RNIL);
- void nr_delete_complete(Signal*, Nr_op_info*);
-
-public:
- void acckeyconf_load_diskpage_callback(Signal*, Uint32, Uint32);
-
-private:
- void next_scanconf_load_diskpage(Signal* signal,
- ScanRecordPtr scanPtr,
- Ptr<TcConnectionrec> regTcPtr,
- Fragrecord* fragPtrP);
-
- void next_scanconf_tupkeyreq(Signal* signal, ScanRecordPtr,
- TcConnectionrec * regTcPtr,
- Fragrecord* fragPtrP,
- Uint32 disk_page);
-
-public:
- void next_scanconf_load_diskpage_callback(Signal* signal, Uint32, Uint32);
-
- void tupcommit_conf_callback(Signal* signal, Uint32 tcPtrI);
-private:
- void tupcommit_conf(Signal* signal, TcConnectionrec *,Fragrecord *);
-
-// ----------------------------------------------------------------
-// These are variables handling the records. For most records one
-// pointer to the array of structs, one pointer-struct, a file size
-// and a first free record variable. The pointer struct are temporary
-// variables that are kept on the class object since there are often a
-// great deal of those variables that exist simultaneously and
-// thus no perfect solution of handling them is currently available.
-// ----------------------------------------------------------------
-/* ------------------------------------------------------------------------- */
-/* POSITIONS WITHIN THE ATTRINBUF AND THE MAX SIZE OF DATA WITHIN AN */
-/* ATTRINBUF. */
-/* ------------------------------------------------------------------------- */
-
-
-#define ZADDFRAGREC_FILE_SIZE 1
- AddFragRecord *addFragRecord;
- AddFragRecordPtr addfragptr;
- UintR cfirstfreeAddfragrec;
- UintR caddfragrecFileSize;
-
-#define ZATTRINBUF_FILE_SIZE 12288 // 1.5 MByte
-#define ZINBUF_DATA_LEN 24 /* POSITION OF 'DATA LENGHT'-VARIABLE. */
-#define ZINBUF_NEXT 25 /* POSITION OF 'NEXT'-VARIABLE. */
- Attrbuf *attrbuf;
- AttrbufPtr attrinbufptr;
- UintR cfirstfreeAttrinbuf;
- UintR cattrinbufFileSize;
- Uint32 c_no_attrinbuf_recs;
-
-#define ZDATABUF_FILE_SIZE 10000 // 200 kByte
- Databuf *databuf;
- DatabufPtr databufptr;
- UintR cfirstfreeDatabuf;
- UintR cdatabufFileSize;
-
-// Configurable
- FragrecordPtr fragptr;
- ArrayPool<Fragrecord> c_fragment_pool;
-
-#define ZGCPREC_FILE_SIZE 1
- GcpRecord *gcpRecord;
- GcpRecordPtr gcpPtr;
- UintR cgcprecFileSize;
-
-// MAX_NDB_NODES is the size of this array
- HostRecord *hostRecord;
- UintR chostFileSize;
-
-#define ZNO_CONCURRENT_LCP 1
- LcpRecord *lcpRecord;
- LcpRecordPtr lcpPtr;
- UintR cfirstfreeLcpLoc;
- UintR clcpFileSize;
-
-#define ZLOG_PART_FILE_SIZE 4
- LogPartRecord *logPartRecord;
- LogPartRecordPtr logPartPtr;
- UintR clogPartFileSize;
- Uint32 clogFileSize; // In MBYTE
- Uint32 cmaxLogFilesInPageZero; //
-
-// Configurable
- LogFileRecord *logFileRecord;
- LogFileRecordPtr logFilePtr;
- UintR cfirstfreeLogFile;
- UintR clogFileFileSize;
-
-#define ZLFO_MIN_FILE_SIZE 256
-// RedoBuffer/32K minimum ZLFO_MIN_FILE_SIZE
- LogFileOperationRecord *logFileOperationRecord;
- LogFileOperationRecordPtr lfoPtr;
- UintR cfirstfreeLfo;
- UintR clfoFileSize;
-
- LogPageRecord *logPageRecord;
- void *logPageRecordUnaligned;
- LogPageRecordPtr logPagePtr;
- UintR cfirstfreeLogPage;
- UintR clogPageFileSize;
-
-#define ZPAGE_REF_FILE_SIZE 20
- PageRefRecord *pageRefRecord;
- PageRefRecordPtr pageRefPtr;
- UintR cfirstfreePageRef;
- UintR cpageRefFileSize;
-
-// Configurable
- ArrayPool<ScanRecord> c_scanRecordPool;
- ScanRecordPtr scanptr;
- UintR cscanNoFreeRec;
- Uint32 cscanrecFileSize;
-
-// Configurable
- Tablerec *tablerec;
- TablerecPtr tabptr;
- UintR ctabrecFileSize;
-
-// Configurable
- TcConnectionrec *tcConnectionrec;
- TcConnectionrecPtr tcConnectptr;
- UintR cfirstfreeTcConrec;
- UintR ctcConnectrecFileSize;
-
-// MAX_NDB_NODES is the size of this array
- TcNodeFailRecord *tcNodeFailRecord;
- TcNodeFailRecordPtr tcNodeFailptr;
- UintR ctcNodeFailrecFileSize;
-
- Uint16 terrorCode;
-
- Uint32 c_firstInNodeGroup;
-
-// ------------------------------------------------------------------------
-// These variables are used to store block state which do not need arrays
-// of struct's.
-// ------------------------------------------------------------------------
- Uint32 c_lcpId;
- Uint32 cnoOfFragsCheckpointed;
-
-/* ------------------------------------------------------------------------- */
-// cmaxWordsAtNodeRec keeps track of how many words that currently are
-// outstanding in a node recovery situation.
-// cbookedAccOps keeps track of how many operation records that have been
-// booked in ACC for the scan processes.
-// cmaxAccOps contains the maximum number of operation records which can be
-// allocated for scan purposes in ACC.
-/* ------------------------------------------------------------------------- */
- UintR cmaxWordsAtNodeRec;
- UintR cbookedAccOps;
- UintR cmaxAccOps;
-/* ------------------------------------------------------------------------- */
-/*THIS STATE VARIABLE IS ZTRUE IF AN ADD NODE IS ONGOING. ADD NODE MEANS */
-/*THAT CONNECTIONS ARE SET-UP TO THE NEW NODE. */
-/* ------------------------------------------------------------------------- */
- Uint8 caddNodeState;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE SPECIFIES WHICH TYPE OF RESTART THAT IS ONGOING */
-/* ------------------------------------------------------------------------- */
- Uint16 cstartType;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE INDICATES WHETHER AN INITIAL RESTART IS ONGOING OR NOT. */
-/* ------------------------------------------------------------------------- */
- Uint8 cinitialStartOngoing;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE KEEPS TRACK OF WHEN TUP AND ACC HAVE COMPLETED EXECUTING */
-/*THEIR UNDO LOG. */
-/* ------------------------------------------------------------------------- */
- ExecUndoLogState csrExecUndoLogState;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE KEEPS TRACK OF WHEN TUP AND ACC HAVE CONFIRMED COMPLETION */
-/*OF A LOCAL CHECKPOINT ROUND. */
-/* ------------------------------------------------------------------------- */
- LcpCloseState clcpCompletedState;
-/* ------------------------------------------------------------------------- */
-/*DURING CONNECTION PROCESSES IN SYSTEM RESTART THESE VARIABLES KEEP TRACK */
-/*OF HOW MANY CONNECTIONS AND RELEASES THAT ARE TO BE PERFORMED. */
-/* ------------------------------------------------------------------------- */
-/***************************************************************************>*/
-/*THESE VARIABLES CONTAIN INFORMATION USED DURING SYSTEM RESTART. */
-/***************************************************************************>*/
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE IS ZTRUE IF THE SIGNAL START_REC_REQ HAVE BEEN RECEIVED. */
-/*RECEPTION OF THIS SIGNAL INDICATES THAT ALL FRAGMENTS THAT THIS NODE */
-/*SHOULD START HAVE BEEN RECEIVED. */
-/* ------------------------------------------------------------------------- */
- Uint8 cstartRecReq;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE KEEPS TRACK OF HOW MANY FRAGMENTS THAT PARTICIPATE IN */
-/*EXECUTING THE LOG. IF ZERO WE DON'T NEED TO EXECUTE THE LOG AT ALL. */
-/* ------------------------------------------------------------------------- */
- Uint32 cnoFragmentsExecSr;
-
- /**
- * This is no of sent GSN_EXEC_FRAGREQ during this log phase
- */
- Uint32 cnoOutstandingExecFragReq;
-
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE KEEPS TRACK OF WHICH OF THE FIRST TWO RESTART PHASES THAT */
-/*HAVE COMPLETED. */
-/* ------------------------------------------------------------------------- */
- Uint8 csrPhaseStarted;
-/* ------------------------------------------------------------------------- */
-/*NUMBER OF PHASES COMPLETED OF EXECUTING THE FRAGMENT LOG. */
-/* ------------------------------------------------------------------------- */
- Uint8 csrPhasesCompleted;
-/* ------------------------------------------------------------------------- */
-/*THE BLOCK REFERENCE OF THE MASTER DIH DURING SYSTEM RESTART. */
-/* ------------------------------------------------------------------------- */
- BlockReference cmasterDihBlockref;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE IS THE HEAD OF A LINKED LIST OF FRAGMENTS WAITING TO BE */
-/*RESTORED FROM DISK. */
-/* ------------------------------------------------------------------------- */
- DLFifoList<Fragrecord> c_lcp_waiting_fragments; // StartFragReq'ed
- DLFifoList<Fragrecord> c_lcp_restoring_fragments; // Restoring as we speek
- DLFifoList<Fragrecord> c_lcp_complete_fragments; // Restored
-
-/* ------------------------------------------------------------------------- */
-/*USED DURING SYSTEM RESTART, INDICATES THE OLDEST GCI THAT CAN BE RESTARTED */
-/*FROM AFTER THIS SYSTEM RESTART. USED TO FIND THE LOG TAIL. */
-/* ------------------------------------------------------------------------- */
- UintR crestartOldestGci;
-/* ------------------------------------------------------------------------- */
-/*USED DURING SYSTEM RESTART, INDICATES THE NEWEST GCI THAT CAN BE RESTARTED */
-/*AFTER THIS SYSTEM RESTART. USED TO FIND THE LOG HEAD. */
-/* ------------------------------------------------------------------------- */
- UintR crestartNewestGci;
-/* ------------------------------------------------------------------------- */
-/*THE NUMBER OF LOG FILES. SET AS A PARAMETER WHEN NDB IS STARTED. */
-/* ------------------------------------------------------------------------- */
- UintR cnoLogFiles;
-/* ------------------------------------------------------------------------- */
-/*THESE TWO VARIABLES CONTAIN THE NEWEST GCI RECEIVED IN THE BLOCK AND THE */
-/*NEWEST COMPLETED GCI IN THE BLOCK. */
-/* ------------------------------------------------------------------------- */
- UintR cnewestGci;
- UintR cnewestCompletedGci;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE ONLY PASSES INFORMATION FROM STTOR TO STTORRY = TEMPORARY */
-/* ------------------------------------------------------------------------- */
- Uint16 csignalKey;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE CONTAINS THE CURRENT START PHASE IN THE BLOCK. IS ZNIL IF */
-/*NO SYSTEM RESTART IS ONGOING. */
-/* ------------------------------------------------------------------------- */
- Uint16 cstartPhase;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE CONTAIN THE CURRENT GLOBAL CHECKPOINT RECORD. IT'S RNIL IF */
-/*NOT A GCP SAVE IS ONGOING. */
-/* ------------------------------------------------------------------------- */
- UintR ccurrentGcprec;
-/* ------------------------------------------------------------------------- */
-/*THESE VARIABLES ARE USED TO KEEP TRACK OF ALL ACTIVE COPY FRAGMENTS IN LQH.*/
-/* ------------------------------------------------------------------------- */
- Uint8 cnoActiveCopy;
- UintR cactiveCopy[4];
-
-/* ------------------------------------------------------------------------- */
-/*THESE VARIABLES CONTAIN THE BLOCK REFERENCES OF THE OTHER NDB BLOCKS. */
-/*ALSO THE BLOCK REFERENCE OF MY OWN BLOCK = LQH */
-/* ------------------------------------------------------------------------- */
- BlockReference caccBlockref;
- BlockReference ctupBlockref;
- BlockReference ctuxBlockref;
- BlockReference cownref;
- UintR cLqhTimeOutCount;
- UintR cLqhTimeOutCheckCount;
- UintR cnoOfLogPages;
-/* ------------------------------------------------------------------------- */
-/*THIS VARIABLE CONTAINS MY OWN PROCESSOR ID. */
-/* ------------------------------------------------------------------------- */
- NodeId cownNodeid;
-
-/* ------------------------------------------------------------------------- */
-/*THESE VARIABLES CONTAIN INFORMATION ABOUT THE OTHER NODES IN THE SYSTEM */
-/*THESE VARIABLES ARE MOSTLY USED AT SYSTEM RESTART AND ADD NODE TO SET-UP */
-/*AND RELEASE CONNECTIONS TO OTHER NODES IN THE CLUSTER. */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/*THIS ARRAY CONTAINS THE PROCESSOR ID'S OF THE NODES THAT ARE ALIVE. */
-/*CNO_OF_NODES SPECIFIES HOW MANY NODES THAT ARE CURRENTLY ALIVE. */
-/*CNODE_VERSION SPECIFIES THE NDB VERSION EXECUTING ON THE NODE. */
-/* ------------------------------------------------------------------------- */
- UintR cpackedListIndex;
- Uint16 cpackedList[MAX_NDB_NODES];
- UintR cnodeData[MAX_NDB_NODES];
- UintR cnodeStatus[MAX_NDB_NODES];
- UintR cnoOfNodes;
-
- NdbNodeBitmask m_sr_nodes;
- NdbNodeBitmask m_sr_exec_sr_req;
- NdbNodeBitmask m_sr_exec_sr_conf;
-
-/* ------------------------------------------------------------------------- */
-/* THIS VARIABLE CONTAINS THE DIRECTORY OF A HASH TABLE OF ALL ACTIVE */
-/* OPERATION IN THE BLOCK. IT IS USED TO BE ABLE TO QUICKLY ABORT AN */
-/* OPERATION WHERE THE CONNECTION WAS LOST DUE TO NODE FAILURES. IT IS */
-/* ACTUALLY USED FOR ALL ABORTS COMMANDED BY TC. */
-/* ------------------------------------------------------------------------- */
- UintR preComputedRequestInfoMask;
- UintR ctransidHash[1024];
-
- Uint32 c_diskless;
- Uint32 c_o_direct;
- Uint32 c_error_insert_table_id;
-
-public:
- bool is_same_trans(Uint32 opId, Uint32 trid1, Uint32 trid2);
- void get_op_info(Uint32 opId, Uint32 *hash, Uint32* gci);
- void accminupdate(Signal*, Uint32 opPtrI, const Local_key*);
-
- /**
- *
- */
- struct CommitAckMarker {
- CommitAckMarker() {}
- Uint32 transid1;
- Uint32 transid2;
-
- Uint32 apiRef; // Api block ref
- Uint32 apiOprec; // Connection Object in NDB API
- Uint32 tcNodeId;
- union { Uint32 nextPool; Uint32 nextHash; };
- Uint32 prevHash;
-
- inline bool equal(const CommitAckMarker & p) const {
- return ((p.transid1 == transid1) && (p.transid2 == transid2));
- }
-
- inline Uint32 hashValue() const {
- return transid1;
- }
- };
-
- typedef Ptr<CommitAckMarker> CommitAckMarkerPtr;
- ArrayPool<CommitAckMarker> m_commitAckMarkerPool;
- DLHashTable<CommitAckMarker> m_commitAckMarkerHash;
- typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator;
- void execREMOVE_MARKER_ORD(Signal* signal);
- void scanMarkers(Signal* signal, Uint32 tcNodeFail, Uint32 bucket, Uint32 i);
-
- struct Counters {
- Counters() {}
- Uint32 operations;
-
- inline void clear(){
- operations = 0;
- }
- };
-
- Counters c_Counters;
-
- inline bool getAllowRead() const {
- return getNodeState().startLevel < NodeState::SL_STOPPING_3;
- }
-
- DLHashTable<ScanRecord> c_scanTakeOverHash;
-
- inline bool TRACE_OP_CHECK(const TcConnectionrec* regTcPtr);
-#ifdef ERROR_INSERT
- void TRACE_OP_DUMP(const TcConnectionrec* regTcPtr, const char * pos);
-#endif
-};
-
-inline
-bool
-Dblqh::ScanRecord::check_scan_batch_completed() const
-{
- Uint32 max_rows = m_max_batch_size_rows;
- Uint32 max_bytes = m_max_batch_size_bytes;
-
- return (max_rows > 0 && (m_curr_batch_size_rows >= max_rows)) ||
- (max_bytes > 0 && (m_curr_batch_size_bytes >= max_bytes));
-}
-
-inline
-void
-Dblqh::i_get_acc_ptr(ScanRecord* scanP, Uint32* &acc_ptr, Uint32 index)
-{
- if (index == 0) {
- acc_ptr= (Uint32*)&scanP->scan_acc_op_ptr[0];
- } else {
- Uint32 attr_buf_index, attr_buf_rec;
-
- AttrbufPtr regAttrPtr;
- jam();
- attr_buf_rec= (index + 31) / 32;
- attr_buf_index= (index - 1) & 31;
- regAttrPtr.i= scanP->scan_acc_op_ptr[attr_buf_rec];
- ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf);
- acc_ptr= (Uint32*)&regAttrPtr.p->attrbuf[attr_buf_index];
- }
-}
-
-inline
-bool
-Dblqh::is_same_trans(Uint32 opId, Uint32 trid1, Uint32 trid2)
-{
- TcConnectionrecPtr regTcPtr;
- regTcPtr.i= opId;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
- return ((regTcPtr.p->transid[0] == trid1) &&
- (regTcPtr.p->transid[1] == trid2));
-}
-
-inline
-void
-Dblqh::get_op_info(Uint32 opId, Uint32 *hash, Uint32* gci)
-{
- TcConnectionrecPtr regTcPtr;
- regTcPtr.i= opId;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
- *hash= regTcPtr.p->hashValue;
- *gci= regTcPtr.p->gci;
-}
-
-#include "../dbacc/Dbacc.hpp"
-
-inline
-void
-Dblqh::accminupdate(Signal* signal, Uint32 opId, const Local_key* key)
-{
- TcConnectionrecPtr regTcPtr;
- regTcPtr.i= opId;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
- signal->theData[0] = regTcPtr.p->accConnectrec;
- signal->theData[1] = key->m_page_no << MAX_TUPLES_BITS | key->m_page_idx;
- c_acc->execACCMINUPDATE(signal);
-
- if (ERROR_INSERTED(5712) || ERROR_INSERTED(5713))
- ndbout << " LK: " << *key;
- regTcPtr.p->m_row_id = *key;
-}
-
-inline
-bool
-Dblqh::TRACE_OP_CHECK(const TcConnectionrec* regTcPtr)
-{
- return (ERROR_INSERTED(5712) &&
- (regTcPtr->operation == ZINSERT ||
- regTcPtr->operation == ZDELETE)) ||
- ERROR_INSERTED(5713);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
deleted file mode 100644
index 79b3c6ce8d8..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <pc.hpp>
-#define DBLQH_C
-#include "Dblqh.hpp"
-#include <ndb_limits.h>
-
-#define DEBUG(x) { ndbout << "LQH::" << x << endl; }
-
-void Dblqh::initData()
-{
- caddfragrecFileSize = ZADDFRAGREC_FILE_SIZE;
- cattrinbufFileSize = ZATTRINBUF_FILE_SIZE;
- c_no_attrinbuf_recs= ZATTRINBUF_FILE_SIZE;
- cdatabufFileSize = ZDATABUF_FILE_SIZE;
- cgcprecFileSize = ZGCPREC_FILE_SIZE;
- chostFileSize = MAX_NDB_NODES;
- clcpFileSize = ZNO_CONCURRENT_LCP;
- clfoFileSize = 0;
- clogFileFileSize = 0;
- clogPartFileSize = ZLOG_PART_FILE_SIZE;
- cpageRefFileSize = ZPAGE_REF_FILE_SIZE;
- cscanrecFileSize = 0;
- ctabrecFileSize = 0;
- ctcConnectrecFileSize = 0;
- ctcNodeFailrecFileSize = MAX_NDB_NODES;
-
- addFragRecord = 0;
- attrbuf = 0;
- databuf = 0;
- gcpRecord = 0;
- hostRecord = 0;
- lcpRecord = 0;
- logPartRecord = 0;
- logFileRecord = 0;
- logFileOperationRecord = 0;
- logPageRecord = 0;
- logPageRecordUnaligned= 0;
- pageRefRecord = 0;
- tablerec = 0;
- tcConnectionrec = 0;
- tcNodeFailRecord = 0;
-
- // Records with constant sizes
-
- cLqhTimeOutCount = 0;
- cLqhTimeOutCheckCount = 0;
- cbookedAccOps = 0;
- m_backup_ptr = RNIL;
- clogFileSize = 16;
- cmaxLogFilesInPageZero = 40;
-}//Dblqh::initData()
-
-void Dblqh::initRecords()
-{
- // Records with dynamic sizes
- addFragRecord = (AddFragRecord*)allocRecord("AddFragRecord",
- sizeof(AddFragRecord),
- caddfragrecFileSize);
- attrbuf = (Attrbuf*)allocRecord("Attrbuf",
- sizeof(Attrbuf),
- cattrinbufFileSize);
-
- databuf = (Databuf*)allocRecord("Databuf",
- sizeof(Databuf),
- cdatabufFileSize);
-
- gcpRecord = (GcpRecord*)allocRecord("GcpRecord",
- sizeof(GcpRecord),
- cgcprecFileSize);
-
- hostRecord = (HostRecord*)allocRecord("HostRecord",
- sizeof(HostRecord),
- chostFileSize);
-
- lcpRecord = (LcpRecord*)allocRecord("LcpRecord",
- sizeof(LcpRecord),
- clcpFileSize);
-
- for(Uint32 i = 0; i<clcpFileSize; i++){
- new (&lcpRecord[i])LcpRecord();
- }
-
- logPartRecord = (LogPartRecord*)allocRecord("LogPartRecord",
- sizeof(LogPartRecord),
- clogPartFileSize);
-
- logFileRecord = (LogFileRecord*)allocRecord("LogFileRecord",
- sizeof(LogFileRecord),
- clogFileFileSize);
-
- logFileOperationRecord = (LogFileOperationRecord*)
- allocRecord("LogFileOperationRecord",
- sizeof(LogFileOperationRecord),
- clfoFileSize);
-
- logPageRecord =
- (LogPageRecord*)allocRecordAligned("LogPageRecord",
- sizeof(LogPageRecord),
- clogPageFileSize,
- &logPageRecordUnaligned,
- NDB_O_DIRECT_WRITE_ALIGNMENT,
- false);
-
- pageRefRecord = (PageRefRecord*)allocRecord("PageRefRecord",
- sizeof(PageRefRecord),
- cpageRefFileSize);
-
- cscanNoFreeRec = cscanrecFileSize;
- c_scanRecordPool.setSize(cscanrecFileSize);
- c_scanTakeOverHash.setSize(64);
-
- tablerec = (Tablerec*)allocRecord("Tablerec",
- sizeof(Tablerec),
- ctabrecFileSize);
-
- tcConnectionrec = (TcConnectionrec*)allocRecord("TcConnectionrec",
- sizeof(TcConnectionrec),
- ctcConnectrecFileSize);
-
- m_commitAckMarkerPool.setSize(ctcConnectrecFileSize);
- m_commitAckMarkerHash.setSize(1024);
-
- tcNodeFailRecord = (TcNodeFailRecord*)allocRecord("TcNodeFailRecord",
- sizeof(TcNodeFailRecord),
- ctcNodeFailrecFileSize);
-
- /*
- ndbout << "FRAGREC SIZE = " << sizeof(Fragrecord) << endl;
- ndbout << "TAB SIZE = " << sizeof(Tablerec) << endl;
- ndbout << "GCP SIZE = " << sizeof(GcpRecord) << endl;
- ndbout << "LCP SIZE = " << sizeof(LcpRecord) << endl;
- ndbout << "LCPLOC SIZE = " << sizeof(LcpLocRecord) << endl;
- ndbout << "LOGPART SIZE = " << sizeof(LogPartRecord) << endl;
- ndbout << "LOGFILE SIZE = " << sizeof(LogFileRecord) << endl;
- ndbout << "TC SIZE = " << sizeof(TcConnectionrec) << endl;
- ndbout << "HOST SIZE = " << sizeof(HostRecord) << endl;
- ndbout << "LFO SIZE = " << sizeof(LogFileOperationRecord) << endl;
- ndbout << "PR SIZE = " << sizeof(PageRefRecord) << endl;
- ndbout << "SCAN SIZE = " << sizeof(ScanRecord) << endl;
-*/
-
- // Initialize BAT for interface to file system
- NewVARIABLE* bat = allocateBat(2);
- bat[1].WA = &logPageRecord->logPageWord[0];
- bat[1].nrr = clogPageFileSize;
- bat[1].ClusterSize = sizeof(LogPageRecord);
- bat[1].bits.q = ZTWOLOG_PAGE_SIZE;
- bat[1].bits.v = 5;
-}//Dblqh::initRecords()
-
-Dblqh::Dblqh(Block_context& ctx):
- SimulatedBlock(DBLQH, ctx),
- c_lcp_waiting_fragments(c_fragment_pool),
- c_lcp_restoring_fragments(c_fragment_pool),
- c_lcp_complete_fragments(c_fragment_pool),
- m_commitAckMarkerHash(m_commitAckMarkerPool),
- c_scanTakeOverHash(c_scanRecordPool)
-{
- BLOCK_CONSTRUCTOR(Dblqh);
-
- addRecSignal(GSN_PACKED_SIGNAL, &Dblqh::execPACKED_SIGNAL);
- addRecSignal(GSN_DEBUG_SIG, &Dblqh::execDEBUG_SIG);
- addRecSignal(GSN_ATTRINFO, &Dblqh::execATTRINFO);
- addRecSignal(GSN_KEYINFO, &Dblqh::execKEYINFO);
- addRecSignal(GSN_LQHKEYREQ, &Dblqh::execLQHKEYREQ);
- addRecSignal(GSN_LQHKEYREF, &Dblqh::execLQHKEYREF);
- addRecSignal(GSN_COMMIT, &Dblqh::execCOMMIT);
- addRecSignal(GSN_COMPLETE, &Dblqh::execCOMPLETE);
- addRecSignal(GSN_LQHKEYCONF, &Dblqh::execLQHKEYCONF);
-#ifdef VM_TRACE
- addRecSignal(GSN_TESTSIG, &Dblqh::execTESTSIG);
-#endif
- addRecSignal(GSN_CONTINUEB, &Dblqh::execCONTINUEB);
- addRecSignal(GSN_START_RECREQ, &Dblqh::execSTART_RECREQ);
- addRecSignal(GSN_START_RECCONF, &Dblqh::execSTART_RECCONF);
- addRecSignal(GSN_EXEC_FRAGREQ, &Dblqh::execEXEC_FRAGREQ);
- addRecSignal(GSN_EXEC_FRAGCONF, &Dblqh::execEXEC_FRAGCONF);
- addRecSignal(GSN_EXEC_FRAGREF, &Dblqh::execEXEC_FRAGREF);
- addRecSignal(GSN_START_EXEC_SR, &Dblqh::execSTART_EXEC_SR);
- addRecSignal(GSN_EXEC_SRREQ, &Dblqh::execEXEC_SRREQ);
- addRecSignal(GSN_EXEC_SRCONF, &Dblqh::execEXEC_SRCONF);
- addRecSignal(GSN_SCAN_HBREP, &Dblqh::execSCAN_HBREP);
-
- addRecSignal(GSN_ALTER_TAB_REQ, &Dblqh::execALTER_TAB_REQ);
-
- // Trigger signals, transit to from TUP
- addRecSignal(GSN_CREATE_TRIG_REQ, &Dblqh::execCREATE_TRIG_REQ);
- addRecSignal(GSN_CREATE_TRIG_CONF, &Dblqh::execCREATE_TRIG_CONF);
- addRecSignal(GSN_CREATE_TRIG_REF, &Dblqh::execCREATE_TRIG_REF);
-
- addRecSignal(GSN_DROP_TRIG_REQ, &Dblqh::execDROP_TRIG_REQ);
- addRecSignal(GSN_DROP_TRIG_CONF, &Dblqh::execDROP_TRIG_CONF);
- addRecSignal(GSN_DROP_TRIG_REF, &Dblqh::execDROP_TRIG_REF);
-
- addRecSignal(GSN_DUMP_STATE_ORD, &Dblqh::execDUMP_STATE_ORD);
- addRecSignal(GSN_NODE_FAILREP, &Dblqh::execNODE_FAILREP);
- 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_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);
- addRecSignal(GSN_TUP_ADD_ATTRREF, &Dblqh::execTUP_ADD_ATTRREF);
- addRecSignal(GSN_ACCFRAGCONF, &Dblqh::execACCFRAGCONF);
- addRecSignal(GSN_ACCFRAGREF, &Dblqh::execACCFRAGREF);
- addRecSignal(GSN_TUPFRAGCONF, &Dblqh::execTUPFRAGCONF);
- addRecSignal(GSN_TUPFRAGREF, &Dblqh::execTUPFRAGREF);
- addRecSignal(GSN_TAB_COMMITREQ, &Dblqh::execTAB_COMMITREQ);
- addRecSignal(GSN_ACCSEIZECONF, &Dblqh::execACCSEIZECONF);
- addRecSignal(GSN_ACCSEIZEREF, &Dblqh::execACCSEIZEREF);
- addRecSignal(GSN_READ_NODESCONF, &Dblqh::execREAD_NODESCONF);
- addRecSignal(GSN_READ_NODESREF, &Dblqh::execREAD_NODESREF);
- addRecSignal(GSN_STTOR, &Dblqh::execSTTOR);
- addRecSignal(GSN_NDB_STTOR, &Dblqh::execNDB_STTOR);
- addRecSignal(GSN_TUPSEIZECONF, &Dblqh::execTUPSEIZECONF);
- addRecSignal(GSN_TUPSEIZEREF, &Dblqh::execTUPSEIZEREF);
- addRecSignal(GSN_ACCKEYCONF, &Dblqh::execACCKEYCONF);
- addRecSignal(GSN_ACCKEYREF, &Dblqh::execACCKEYREF);
- addRecSignal(GSN_TUPKEYCONF, &Dblqh::execTUPKEYCONF);
- addRecSignal(GSN_TUPKEYREF, &Dblqh::execTUPKEYREF);
- addRecSignal(GSN_ABORT, &Dblqh::execABORT);
- addRecSignal(GSN_ABORTREQ, &Dblqh::execABORTREQ);
- addRecSignal(GSN_COMMITREQ, &Dblqh::execCOMMITREQ);
- addRecSignal(GSN_COMPLETEREQ, &Dblqh::execCOMPLETEREQ);
-#ifdef VM_TRACE
- addRecSignal(GSN_MEMCHECKREQ, &Dblqh::execMEMCHECKREQ);
-#endif
- addRecSignal(GSN_SCAN_FRAGREQ, &Dblqh::execSCAN_FRAGREQ);
- addRecSignal(GSN_SCAN_NEXTREQ, &Dblqh::execSCAN_NEXTREQ);
- addRecSignal(GSN_ACC_SCANCONF, &Dblqh::execACC_SCANCONF);
- addRecSignal(GSN_ACC_SCANREF, &Dblqh::execACC_SCANREF);
- addRecSignal(GSN_NEXT_SCANCONF, &Dblqh::execNEXT_SCANCONF);
- addRecSignal(GSN_NEXT_SCANREF, &Dblqh::execNEXT_SCANREF);
- addRecSignal(GSN_STORED_PROCCONF, &Dblqh::execSTORED_PROCCONF);
- addRecSignal(GSN_STORED_PROCREF, &Dblqh::execSTORED_PROCREF);
- addRecSignal(GSN_COPY_FRAGREQ, &Dblqh::execCOPY_FRAGREQ);
- addRecSignal(GSN_COPY_ACTIVEREQ, &Dblqh::execCOPY_ACTIVEREQ);
- addRecSignal(GSN_COPY_STATEREQ, &Dblqh::execCOPY_STATEREQ);
- addRecSignal(GSN_LQH_TRANSREQ, &Dblqh::execLQH_TRANSREQ);
- addRecSignal(GSN_TRANSID_AI, &Dblqh::execTRANSID_AI);
- addRecSignal(GSN_INCL_NODEREQ, &Dblqh::execINCL_NODEREQ);
- addRecSignal(GSN_LCP_PREPARE_REF, &Dblqh::execLCP_PREPARE_REF);
- addRecSignal(GSN_LCP_PREPARE_CONF, &Dblqh::execLCP_PREPARE_CONF);
- addRecSignal(GSN_END_LCPCONF, &Dblqh::execEND_LCPCONF);
-
- addRecSignal(GSN_EMPTY_LCP_REQ, &Dblqh::execEMPTY_LCP_REQ);
- addRecSignal(GSN_LCP_FRAG_ORD, &Dblqh::execLCP_FRAG_ORD);
-
- addRecSignal(GSN_START_FRAGREQ, &Dblqh::execSTART_FRAGREQ);
- addRecSignal(GSN_START_RECREF, &Dblqh::execSTART_RECREF);
- addRecSignal(GSN_GCP_SAVEREQ, &Dblqh::execGCP_SAVEREQ);
- addRecSignal(GSN_FSOPENREF, &Dblqh::execFSOPENREF, true);
- addRecSignal(GSN_FSOPENCONF, &Dblqh::execFSOPENCONF);
- addRecSignal(GSN_FSCLOSECONF, &Dblqh::execFSCLOSECONF);
- addRecSignal(GSN_FSWRITECONF, &Dblqh::execFSWRITECONF);
- addRecSignal(GSN_FSWRITEREF, &Dblqh::execFSWRITEREF, true);
- addRecSignal(GSN_FSREADCONF, &Dblqh::execFSREADCONF);
- addRecSignal(GSN_FSREADREF, &Dblqh::execFSREADREF, true);
- addRecSignal(GSN_ACC_ABORTCONF, &Dblqh::execACC_ABORTCONF);
- addRecSignal(GSN_TIME_SIGNAL, &Dblqh::execTIME_SIGNAL);
- addRecSignal(GSN_FSSYNCCONF, &Dblqh::execFSSYNCCONF);
- addRecSignal(GSN_REMOVE_MARKER_ORD, &Dblqh::execREMOVE_MARKER_ORD);
-
- //addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ);
- addRecSignal(GSN_PREP_DROP_TAB_REQ, &Dblqh::execPREP_DROP_TAB_REQ);
- addRecSignal(GSN_WAIT_DROP_TAB_REQ, &Dblqh::execWAIT_DROP_TAB_REQ);
- addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ);
-
- addRecSignal(GSN_LQH_ALLOCREQ, &Dblqh::execLQH_ALLOCREQ);
- addRecSignal(GSN_LQH_WRITELOG_REQ, &Dblqh::execLQH_WRITELOG_REQ);
- addRecSignal(GSN_TUP_DEALLOCREQ, &Dblqh::execTUP_DEALLOCREQ);
-
- // TUX
- addRecSignal(GSN_TUXFRAGCONF, &Dblqh::execTUXFRAGCONF);
- addRecSignal(GSN_TUXFRAGREF, &Dblqh::execTUXFRAGREF);
- addRecSignal(GSN_TUX_ADD_ATTRCONF, &Dblqh::execTUX_ADD_ATTRCONF);
- addRecSignal(GSN_TUX_ADD_ATTRREF, &Dblqh::execTUX_ADD_ATTRREF);
-
- addRecSignal(GSN_READ_PSEUDO_REQ, &Dblqh::execREAD_PSEUDO_REQ);
-
- addRecSignal(GSN_DEFINE_BACKUP_REF, &Dblqh::execDEFINE_BACKUP_REF);
- addRecSignal(GSN_DEFINE_BACKUP_CONF, &Dblqh::execDEFINE_BACKUP_CONF);
-
- addRecSignal(GSN_BACKUP_FRAGMENT_REF, &Dblqh::execBACKUP_FRAGMENT_REF);
- addRecSignal(GSN_BACKUP_FRAGMENT_CONF, &Dblqh::execBACKUP_FRAGMENT_CONF);
-
- addRecSignal(GSN_RESTORE_LCP_REF, &Dblqh::execRESTORE_LCP_REF);
- addRecSignal(GSN_RESTORE_LCP_CONF, &Dblqh::execRESTORE_LCP_CONF);
-
- addRecSignal(GSN_UPDATE_FRAG_DIST_KEY_ORD,
- &Dblqh::execUPDATE_FRAG_DIST_KEY_ORD);
-
- addRecSignal(GSN_PREPARE_COPY_FRAG_REQ,
- &Dblqh::execPREPARE_COPY_FRAG_REQ);
-
- initData();
-
-#ifdef VM_TRACE
- {
- void* tmp[] = {
- &addfragptr,
- &attrinbufptr,
- &databufptr,
- &fragptr,
- &gcpPtr,
- &lcpPtr,
- &logPartPtr,
- &logFilePtr,
- &lfoPtr,
- &logPagePtr,
- &pageRefPtr,
- &scanptr,
- &tabptr,
- &tcConnectptr,
- &tcNodeFailptr,
- };
- init_globals_list(tmp, sizeof(tmp)/sizeof(tmp[0]));
- }
-#endif
-
-}//Dblqh::Dblqh()
-
-Dblqh::~Dblqh()
-{
- // Records with dynamic sizes
- deallocRecord((void **)&addFragRecord, "AddFragRecord",
- sizeof(AddFragRecord),
- caddfragrecFileSize);
-
- deallocRecord((void**)&attrbuf,
- "Attrbuf",
- sizeof(Attrbuf),
- cattrinbufFileSize);
-
- deallocRecord((void**)&databuf,
- "Databuf",
- sizeof(Databuf),
- cdatabufFileSize);
-
- deallocRecord((void**)&gcpRecord,
- "GcpRecord",
- sizeof(GcpRecord),
- cgcprecFileSize);
-
- deallocRecord((void**)&hostRecord,
- "HostRecord",
- sizeof(HostRecord),
- chostFileSize);
-
- deallocRecord((void**)&lcpRecord,
- "LcpRecord",
- sizeof(LcpRecord),
- clcpFileSize);
-
- deallocRecord((void**)&logPartRecord,
- "LogPartRecord",
- sizeof(LogPartRecord),
- clogPartFileSize);
-
- deallocRecord((void**)&logFileRecord,
- "LogFileRecord",
- sizeof(LogFileRecord),
- clogFileFileSize);
-
- deallocRecord((void**)&logFileOperationRecord,
- "LogFileOperationRecord",
- sizeof(LogFileOperationRecord),
- clfoFileSize);
-
- deallocRecord((void**)&logPageRecordUnaligned,
- "LogPageRecord",
- sizeof(LogPageRecord),
- clogPageFileSize);
-
- deallocRecord((void**)&pageRefRecord,
- "PageRefRecord",
- sizeof(PageRefRecord),
- cpageRefFileSize);
-
-
- deallocRecord((void**)&tablerec,
- "Tablerec",
- sizeof(Tablerec),
- ctabrecFileSize);
-
- deallocRecord((void**)&tcConnectionrec,
- "TcConnectionrec",
- sizeof(TcConnectionrec),
- ctcConnectrecFileSize);
-
- deallocRecord((void**)&tcNodeFailRecord,
- "TcNodeFailRecord",
- sizeof(TcNodeFailRecord),
- ctcNodeFailrecFileSize);
-}//Dblqh::~Dblqh()
-
-BLOCK_FUNCTIONS(Dblqh)
-
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
deleted file mode 100644
index e76ad2530aa..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ /dev/null
@@ -1,19357 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBLQH_C
-#include "Dblqh.hpp"
-#include <ndb_limits.h>
-#include <md5_hash.hpp>
-
-#include <ndb_version.h>
-#include <signaldata/TuxBound.hpp>
-#include <signaldata/AccScan.hpp>
-#include <signaldata/CopyActive.hpp>
-#include <signaldata/CopyFrag.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/EmptyLcp.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/ExecFragReq.hpp>
-#include <signaldata/GCPSave.hpp>
-#include <signaldata/TcKeyRef.hpp>
-#include <signaldata/LqhKey.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/SrFragidConf.hpp>
-#include <signaldata/StartFragReq.hpp>
-#include <signaldata/StartRec.hpp>
-#include <signaldata/TupKey.hpp>
-#include <signaldata/TupCommit.hpp>
-#include <signaldata/LqhFrag.hpp>
-#include <signaldata/AccFrag.hpp>
-#include <signaldata/TupFrag.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/PackedSignal.hpp>
-
-#include <signaldata/PrepDropTab.hpp>
-#include <signaldata/DropTab.hpp>
-
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/DictTabInfo.hpp>
-
-#include <signaldata/LCP.hpp>
-#include <DebuggerNames.hpp>
-#include <signaldata/BackupImpl.hpp>
-#include <signaldata/RestoreImpl.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <KeyDescriptor.hpp>
-#include <signaldata/RouteOrd.hpp>
-#include <signaldata/FsRef.hpp>
-
-// Use DEBUG to print messages that should be
-// seen only when we debug the product
-#ifdef VM_TRACE
-#define DEBUG(x) ndbout << "DBLQH: "<< x << endl;
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::TcConnectionrec::TransactionState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::TcConnectionrec::LogWriteState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::TcConnectionrec::ListState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::TcConnectionrec::AbortState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::ScanRecord::ScanState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::LogFileOperationRecord::LfoState state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Dblqh::ScanRecord::ScanType state){
- out << (int)state;
- return out;
-}
-
-static
-NdbOut &
-operator<<(NdbOut& out, Operation_t op)
-{
- switch(op){
- case ZREAD: out << "READ"; break;
- case ZREAD_EX: out << "READ-EX"; break;
- case ZINSERT: out << "INSERT"; break;
- case ZUPDATE: out << "UPDATE"; break;
- case ZDELETE: out << "DELETE"; break;
- case ZWRITE: out << "WRITE"; break;
- }
- return out;
-}
-
-#else
-#define DEBUG(x)
-#endif
-
-//#define MARKER_TRACE 1
-//#define TRACE_SCAN_TAKEOVER 1
-
-#ifndef DEBUG_REDO
-#define DEBUG_REDO 0
-#endif
-
-const Uint32 NR_ScanNo = 0;
-
-#if defined VM_TRACE || defined ERROR_INSERT || defined NDBD_TRACENR
-#include <NdbConfig.h>
-static NdbOut * tracenrout = 0;
-static int TRACENR_FLAG = 0;
-#define TRACENR(x) (* tracenrout) << x
-#define SET_TRACENR_FLAG TRACENR_FLAG = 1
-#define CLEAR_TRACENR_FLAG TRACENR_FLAG = 0
-#else
-#define TRACENR_FLAG 0
-#define TRACENR(x)
-#define SET_TRACENR_FLAG
-#define CLEAR_TRACENR_FLAG
-#endif
-
-#ifdef ERROR_INSERT
-static NdbOut * traceopout = 0;
-#define TRACE_OP(regTcPtr, place) do { if (TRACE_OP_CHECK(regTcPtr)) TRACE_OP_DUMP(regTcPtr, place); } while(0)
-#else
-#define TRACE_OP(x, y) {}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEND SYSTEM ERROR ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::systemError(Signal* signal, int line)
-{
- signal->theData[0] = 2304;
- execDUMP_STATE_ORD(signal);
- progError(line, NDBD_EXIT_NDBREQUIRE);
-}//Dblqh::systemError()
-
-/* *************** */
-/* ACCSEIZEREF > */
-/* *************** */
-void Dblqh::execACCSEIZEREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dblqh::execACCSEIZEREF()
-
-/* ******************************************************>> */
-/* THIS SIGNAL IS USED TO HANDLE REAL-TIME */
-/* BREAKS THAT ARE NECESSARY TO ENSURE REAL-TIME */
-/* OPERATION OF LQH. */
-/* This signal is also used for signal loops, for example */
-/* the timeout handling for writing logs every second. */
-/* ******************************************************>> */
-void Dblqh::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- Uint32 tcase = signal->theData[0];
- Uint32 data0 = signal->theData[1];
- Uint32 data1 = signal->theData[2];
- Uint32 data2 = signal->theData[3];
-#if 0
- if (tcase == RNIL) {
- tcConnectptr.i = data0;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- ndbout << "State = " << tcConnectptr.p->transactionState;
- ndbout << " seqNoReplica = " << tcConnectptr.p->seqNoReplica;
- ndbout << " tcNodeFailrec = " << tcConnectptr.p->tcNodeFailrec;
- ndbout << " activeCreat = " << tcConnectptr.p->activeCreat;
- ndbout << endl;
- ndbout << "tupkeyData0 = " << tcConnectptr.p->tupkeyData[0];
- ndbout << "tupkeyData1 = " << tcConnectptr.p->tupkeyData[1];
- ndbout << "tupkeyData2 = " << tcConnectptr.p->tupkeyData[2];
- ndbout << "tupkeyData3 = " << tcConnectptr.p->tupkeyData[3];
- ndbout << endl;
- ndbout << "abortState = " << tcConnectptr.p->abortState;
- ndbout << "listState = " << tcConnectptr.p->listState;
- ndbout << endl;
- return;
- }//if
-#endif
- switch (tcase) {
- case ZLOG_LQHKEYREQ:
- if (cnoOfLogPages == 0) {
- jam();
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
- return;
- }//if
- logPartPtr.i = data0;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
-
- tcConnectptr.i = logPartPtr.p->firstLogQueue;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- logPartPtr.p->LogLqhKeyReqSent = ZFALSE;
- getFirstInLogQueue(signal);
-
- switch (tcConnectptr.p->transactionState) {
- case TcConnectionrec::LOG_QUEUED:
- if (tcConnectptr.p->abortState != TcConnectionrec::ABORT_IDLE) {
- jam();
- logNextStart(signal);
- abortCommonLab(signal);
- return;
- } else {
- jam();
-/*------------------------------------------------------------*/
-/* WE MUST SET THE STATE OF THE LOG PART TO IDLE TO */
-/* ENSURE THAT WE ARE NOT QUEUED AGAIN ON THE LOG PART */
-/* WE WILL SET THE LOG PART STATE TO ACTIVE IMMEDIATELY */
-/* SO NO OTHER PROCESS WILL SEE THIS STATE. IT IS MERELY*/
-/* USED TO ENABLE REUSE OF CODE. */
-/*------------------------------------------------------------*/
- if (logPartPtr.p->logPartState == LogPartRecord::ACTIVE) {
- jam();
- logPartPtr.p->logPartState = LogPartRecord::IDLE;
- }//if
- logLqhkeyreqLab(signal);
- return;
- }//if
- break;
- case TcConnectionrec::LOG_ABORT_QUEUED:
- jam();
- writeAbortLog(signal);
- removeLogTcrec(signal);
- logNextStart(signal);
- continueAfterLogAbortWriteLab(signal);
- return;
- break;
- case TcConnectionrec::LOG_COMMIT_QUEUED:
- case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
- jam();
- writeCommitLog(signal, logPartPtr);
- logNextStart(signal);
- if (tcConnectptr.p->transactionState == TcConnectionrec::LOG_COMMIT_QUEUED) {
- if (tcConnectptr.p->seqNoReplica == 0 ||
- tcConnectptr.p->activeCreat == Fragrecord::AC_NR_COPY) {
- jam();
- localCommitLab(signal);
- } else {
- jam();
- commitReplyLab(signal);
- }//if
- return;
- } else {
- jam();
- tcConnectptr.p->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL;
- return;
- }//if
- break;
- case TcConnectionrec::COMMIT_QUEUED:
- jam();
- logNextStart(signal);
- localCommitLab(signal);
- break;
- case TcConnectionrec::ABORT_QUEUED:
- jam();
- logNextStart(signal);
- abortCommonLab(signal);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
- break;
- case ZSR_GCI_LIMITS:
- jam();
- signal->theData[0] = data0;
- srGciLimits(signal);
- return;
- break;
- case ZSR_LOG_LIMITS:
- jam();
- signal->theData[0] = data0;
- signal->theData[1] = data1;
- signal->theData[2] = data2;
- srLogLimits(signal);
- return;
- break;
- case ZSEND_EXEC_CONF:
- jam();
- signal->theData[0] = data0;
- sendExecConf(signal);
- return;
- break;
- case ZEXEC_SR:
- jam();
- signal->theData[0] = data0;
- execSr(signal);
- return;
- break;
- case ZSR_FOURTH_COMP:
- jam();
- signal->theData[0] = data0;
- srFourthComp(signal);
- return;
- break;
- case ZINIT_FOURTH:
- jam();
- signal->theData[0] = data0;
- initFourth(signal);
- return;
- break;
- case ZTIME_SUPERVISION:
- jam();
- signal->theData[0] = data0;
- timeSup(signal);
- return;
- break;
- case ZSR_PHASE3_START:
- jam();
- srPhase3Start(signal);
- return;
- break;
- case ZLQH_TRANS_NEXT:
- jam();
- tcNodeFailptr.i = data0;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- lqhTransNextLab(signal);
- return;
- break;
- case ZSCAN_TC_CONNECT:
- jam();
- tabptr.i = data1;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- scanTcConnectLab(signal, data0, data2);
- return;
- break;
- case ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal, data0, data2, signal->theData[4]);
- return;
- break;
- case ZINIT_GCP_REC:
- jam();
- gcpPtr.i = 0;
- ptrAss(gcpPtr, gcpRecord);
- initGcpRecLab(signal);
- return;
- break;
- case ZCHECK_LCP_STOP_BLOCKED:
- jam();
- c_scanRecordPool.getPtr(scanptr, data0);
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- checkLcpStopBlockedLab(signal);
- return;
- case ZSCAN_MARKERS:
- jam();
- scanMarkers(signal, data0, data1, data2);
- return;
- break;
-
- case ZOPERATION_EVENT_REP:
- jam();
- /* --------------------------------------------------------------------- */
- // Report information about transaction activity once per second.
- /* --------------------------------------------------------------------- */
- if (signal->theData[1] == 0) {
- signal->theData[0] = NDB_LE_OperationReportCounters;
- signal->theData[1] = c_Counters.operations;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- }//if
- c_Counters.clear();
- signal->theData[0] = ZOPERATION_EVENT_REP;
- signal->theData[1] = 0;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 2);
- break;
- case ZPREP_DROP_TABLE:
- jam();
- checkDropTab(signal);
- return;
- break;
- case ZENABLE_EXPAND_CHECK:
- {
- jam();
- fragptr.i = signal->theData[1];
- if (fragptr.i != RNIL)
- {
- jam();
- c_lcp_complete_fragments.getPtr(fragptr);
- signal->theData[0] = fragptr.p->tabRef;
- signal->theData[1] = fragptr.p->fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
- Ptr<Fragrecord> save = fragptr;
-
- c_lcp_complete_fragments.next(fragptr);
- signal->theData[0] = ZENABLE_EXPAND_CHECK;
- signal->theData[1] = fragptr.i;
- sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
-
- c_lcp_complete_fragments.remove(save);
- return;
- }
- else
- {
- jam();
- cstartRecReq = 2;
- ndbrequire(c_lcp_complete_fragments.isEmpty());
- StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
- conf->startingNodeId = getOwnNodeId();
- sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
- StartRecConf::SignalLength, JBB);
- return;
- }
- }
- case ZRETRY_TCKEYREF:
- {
- jam();
- Uint32 cnt = signal->theData[1];
- Uint32 ref = signal->theData[2];
- if (cnt < (10 * 60 * 5))
- {
- jam();
- /**
- * Only retry for 5 minutes...then hope that API has handled it..somehow
- */
- memmove(signal->theData, signal->theData+3, 4*TcKeyRef::SignalLength);
- sendTCKEYREF(signal, ref, 0, cnt);
- }
- return;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
-}//Dblqh::execCONTINUEB()
-
-/* *********************************************************> */
-/* Request from DBDIH to include a new node in the node list */
-/* and so forth. */
-/* *********************************************************> */
-void Dblqh::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
- BlockReference retRef = signal->theData[0];
- Uint32 nodeId = signal->theData[1];
- cnewestGci = signal->theData[2];
- cnewestCompletedGci = signal->theData[2] - 1;
- ndbrequire(cnoOfNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- if (cnodeData[i] == nodeId) {
- jam();
- cnodeStatus[i] = ZNODE_UP;
- }//if
- }//for
- signal->theData[0] = nodeId;
- signal->theData[1] = cownref;
- sendSignal(retRef, GSN_INCL_NODECONF, signal, 2, JBB);
- return;
-}//Dblqh::execINCL_NODEREQ()
-
-void Dblqh::execTUPSEIZEREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dblqh::execTUPSEIZEREF()
-
-/* ########################################################################## */
-/* ####### START / RESTART MODULE ####### */
-/* ########################################################################## */
-/* ************************************************************************>> */
-/* This is first signal that arrives in a start / restart. Sender is NDBCNTR_REF. */
-/* ************************************************************************>> */
-void Dblqh::execSTTOR(Signal* signal)
-{
- UintR tstartPhase;
-
- jamEntry();
- /* START CASE */
- tstartPhase = signal->theData[1];
- /* SYSTEM RESTART RANK */
- csignalKey = signal->theData[6];
-#if defined VM_TRACE || defined ERROR_INSERT || defined NDBD_TRACENR
- char *name;
- FILE *out = 0;
-#endif
- switch (tstartPhase) {
- case ZSTART_PHASE1:
- jam();
- cstartPhase = tstartPhase;
- c_tup = (Dbtup*)globalData.getBlock(DBTUP);
- c_acc = (Dbacc*)globalData.getBlock(DBACC);
- ndbrequire(c_tup != 0 && c_acc != 0);
- sendsttorryLab(signal);
-
-#if defined VM_TRACE || defined ERROR_INSERT || defined NDBD_TRACENR
-#ifdef VM_TRACE
- out = globalSignalLoggers.getOutputStream();
-#endif
- if (out == 0) {
- name = NdbConfig_SignalLogFileName(getOwnNodeId());
- out = fopen(name, "a");
- }
- tracenrout = new NdbOut(* new FileOutputStream(out));
-#endif
-
-#ifdef ERROR_INSERT
- traceopout = &ndbout;
-#endif
-
- return;
- break;
- case 4:
- jam();
- define_backup(signal);
- break;
- default:
- jam();
- /*empty*/;
- sendsttorryLab(signal);
- return;
- break;
- }//switch
-}//Dblqh::execSTTOR()
-
-void
-Dblqh::define_backup(Signal* signal)
-{
- DefineBackupReq * req = (DefineBackupReq*)signal->getDataPtrSend();
- req->backupId = 0;
- req->clientRef = 0;
- req->clientData = 0;
- req->senderRef = reference();
- req->backupPtr = 0;
- req->backupKey[0] = 0;
- req->backupKey[1] = 0;
- req->nodes.clear();
- req->nodes.set(getOwnNodeId());
- req->backupDataLen = ~0;
-
- sendSignal(BACKUP_REF, GSN_DEFINE_BACKUP_REQ, signal,
- DefineBackupReq::SignalLength, JBB);
-}
-
-void
-Dblqh::execDEFINE_BACKUP_REF(Signal* signal)
-{
- jamEntry();
- m_backup_ptr = RNIL;
- DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
- int err_code = 0;
- char * extra_msg = NULL;
-
- switch(ref->errorCode){
- case DefineBackupRef::Undefined:
- case DefineBackupRef::FailedToSetupFsBuffers:
- case DefineBackupRef::FailedToAllocateBuffers:
- case DefineBackupRef::FailedToAllocateTables:
- case DefineBackupRef::FailedAllocateTableMem:
- case DefineBackupRef::FailedToAllocateFileRecord:
- case DefineBackupRef::FailedToAllocateAttributeRecord:
- case DefineBackupRef::FailedInsertFileHeader:
- case DefineBackupRef::FailedInsertTableList:
- jam();
- err_code = NDBD_EXIT_INVALID_CONFIG;
- extra_msg = (char*) "Probably Backup parameters configuration error, Please consult the manual";
- progError(__LINE__, err_code, extra_msg);
- }
-
- sendsttorryLab(signal);
-}
-
-void
-Dblqh::execDEFINE_BACKUP_CONF(Signal* signal)
-{
- jamEntry();
- DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtrSend();
- m_backup_ptr = conf->backupPtr;
- sendsttorryLab(signal);
-}
-
-/* ***************************************> */
-/* Restart phases 1 - 6, sender is Ndbcntr */
-/* ***************************************> */
-void Dblqh::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
- Uint32 ownNodeId = signal->theData[1]; /* START PHASE*/
- cstartPhase = signal->theData[2]; /* MY NODE ID */
- cstartType = signal->theData[3]; /* START TYPE */
-
- switch (cstartPhase) {
- case ZSTART_PHASE1:
- jam();
- preComputedRequestInfoMask = 0;
- LqhKeyReq::setKeyLen(preComputedRequestInfoMask, RI_KEYLEN_MASK);
- LqhKeyReq::setLastReplicaNo(preComputedRequestInfoMask, RI_LAST_REPL_MASK);
- // Dont LqhKeyReq::setApplicationAddressFlag
- LqhKeyReq::setDirtyFlag(preComputedRequestInfoMask, 1);
- // Dont LqhKeyReq::setInterpretedFlag
- LqhKeyReq::setSimpleFlag(preComputedRequestInfoMask, 1);
- LqhKeyReq::setOperation(preComputedRequestInfoMask, RI_OPERATION_MASK);
- LqhKeyReq::setGCIFlag(preComputedRequestInfoMask, 1);
- LqhKeyReq::setNrCopyFlag(preComputedRequestInfoMask, 1);
- // Dont setAIInLqhKeyReq
- // Dont setSeqNoReplica
- // Dont setSameClientAndTcFlag
- // Dont setReturnedReadLenAIFlag
- // Dont setAPIVersion
- LqhKeyReq::setMarkerFlag(preComputedRequestInfoMask, 1);
- //preComputedRequestInfoMask = 0x003d7fff;
- startphase1Lab(signal, /* dummy */ ~0, ownNodeId);
-
- signal->theData[0] = ZOPERATION_EVENT_REP;
- signal->theData[1] = 1;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
- return;
- break;
- case ZSTART_PHASE2:
- jam();
- startphase2Lab(signal, /* dummy */ ~0);
- return;
- break;
- case ZSTART_PHASE3:
- jam();
- startphase3Lab(signal);
- return;
- break;
- case ZSTART_PHASE4:
- jam();
- startphase4Lab(signal);
- return;
- break;
- case ZSTART_PHASE6:
- jam();
- startphase6Lab(signal);
- return;
- break;
- default:
- jam();
- /*empty*/;
- sendNdbSttorryLab(signal);
- return;
- break;
- }//switch
-}//Dblqh::execNDB_STTOR()
-
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* +++++++ START PHASE 2 +++++++ */
-/* */
-/* INITIATE ALL RECORDS WITHIN THE BLOCK */
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-void Dblqh::startphase1Lab(Signal* signal, Uint32 _dummy, Uint32 ownNodeId)
-{
- UintR Ti;
- HostRecordPtr ThostPtr;
-
-/* ------- INITIATE ALL RECORDS ------- */
- cownNodeid = ownNodeId;
- caccBlockref = calcAccBlockRef (cownNodeid);
- ctupBlockref = calcTupBlockRef (cownNodeid);
- ctuxBlockref = calcTuxBlockRef (cownNodeid);
- cownref = calcLqhBlockRef (cownNodeid);
- for (Ti = 0; Ti < chostFileSize; Ti++) {
- ThostPtr.i = Ti;
- ptrCheckGuard(ThostPtr, chostFileSize, hostRecord);
- ThostPtr.p->hostLqhBlockRef = calcLqhBlockRef(ThostPtr.i);
- ThostPtr.p->hostTcBlockRef = calcTcBlockRef(ThostPtr.i);
- ThostPtr.p->inPackedList = false;
- ThostPtr.p->noOfPackedWordsLqh = 0;
- ThostPtr.p->noOfPackedWordsTc = 0;
- }//for
- cpackedListIndex = 0;
- sendNdbSttorryLab(signal);
- return;
-}//Dblqh::startphase1Lab()
-
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* +++++++ START PHASE 2 +++++++ */
-/* */
-/* CONNECT LQH WITH ACC AND TUP. */
-/* EVERY CONNECTION RECORD IN LQH IS ASSIGNED TO ONE ACC CONNECTION RECORD */
-/* AND ONE TUP CONNECTION RECORD. */
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-void Dblqh::startphase2Lab(Signal* signal, Uint32 _dummy)
-{
- cmaxWordsAtNodeRec = MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT;
-/* -- ACC AND TUP CONNECTION PROCESS -- */
- tcConnectptr.i = 0;
- ptrAss(tcConnectptr, tcConnectionrec);
- moreconnectionsLab(signal);
- return;
-}//Dblqh::startphase2Lab()
-
-void Dblqh::moreconnectionsLab(Signal* signal)
-{
- tcConnectptr.p->tcAccBlockref = caccBlockref;
- // set TUX block here (no operation is seized in TUX)
- tcConnectptr.p->tcTuxBlockref = ctuxBlockref;
-/* NO STATE CHECKING IS PERFORMED, ASSUMED TO WORK */
-/* *************** */
-/* ACCSEIZEREQ < */
-/* *************** */
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- sendSignal(caccBlockref, GSN_ACCSEIZEREQ, signal, 2, JBB);
- return;
-}//Dblqh::moreconnectionsLab()
-
-/* ***************> */
-/* ACCSEIZECONF > */
-/* ***************> */
-void Dblqh::execACCSEIZECONF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- tcConnectptr.p->accConnectrec = signal->theData[1];
-/* *************** */
-/* TUPSEIZEREQ < */
-/* *************** */
- tcConnectptr.p->tcTupBlockref = ctupBlockref;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- sendSignal(ctupBlockref, GSN_TUPSEIZEREQ, signal, 2, JBB);
- return;
-}//Dblqh::execACCSEIZECONF()
-
-/* ***************> */
-/* TUPSEIZECONF > */
-/* ***************> */
-void Dblqh::execTUPSEIZECONF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- tcConnectptr.p->tupConnectrec = signal->theData[1];
-/* ------- CHECK IF THERE ARE MORE CONNECTIONS TO BE CONNECTED ------- */
- tcConnectptr.i = tcConnectptr.p->nextTcConnectrec;
- if (tcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- moreconnectionsLab(signal);
- return;
- }//if
-/* ALL LQH_CONNECT RECORDS ARE CONNECTED TO ACC AND TUP ---- */
- sendNdbSttorryLab(signal);
- return;
-}//Dblqh::execTUPSEIZECONF()
-
-/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* +++++++ START PHASE 4 +++++++ */
-/* */
-/* CONNECT LQH WITH LQH. */
-/* CONNECT EACH LQH WITH EVERY LQH IN THE DATABASE SYSTEM. */
-/* IF INITIAL START THEN CREATE THE FRAGMENT LOG FILES */
-/*IF SYSTEM RESTART OR NODE RESTART THEN OPEN THE FRAGMENT LOG FILES AND */
-/*FIND THE END OF THE LOG FILES. */
-/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* WAIT UNTIL ADD NODE PROCESSES ARE COMPLETED */
-/* IF INITIAL START ALSO WAIT FOR LOG FILES TO INITIALISED */
-/*START TIME SUPERVISION OF LOG FILES. WE HAVE TO WRITE LOG PAGES TO DISK */
-/*EVEN IF THE PAGES ARE NOT FULL TO ENSURE THAT THEY COME TO DISK ASAP. */
-/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-void Dblqh::startphase3Lab(Signal* signal)
-{
- LogFileRecordPtr prevLogFilePtr;
- LogFileRecordPtr zeroLogFilePtr;
-
- caddNodeState = ZTRUE;
-/* ***************<< */
-/* READ_NODESREQ < */
-/* ***************<< */
- cinitialStartOngoing = ZTRUE;
- ndbrequire(cnoLogFiles != 0);
-
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- initLogpart(signal);
- for (Uint32 fileNo = 0; fileNo < cnoLogFiles; fileNo++) {
- seizeLogfile(signal);
- if (fileNo != 0) {
- jam();
- prevLogFilePtr.p->nextLogFile = logFilePtr.i;
- logFilePtr.p->prevLogFile = prevLogFilePtr.i;
- } else {
- jam();
- logPartPtr.p->firstLogfile = logFilePtr.i;
- logPartPtr.p->currentLogfile = logFilePtr.i;
- zeroLogFilePtr.i = logFilePtr.i;
- zeroLogFilePtr.p = logFilePtr.p;
- }//if
- prevLogFilePtr.i = logFilePtr.i;
- prevLogFilePtr.p = logFilePtr.p;
- initLogfile(signal, fileNo);
- if ((cstartType == NodeState::ST_INITIAL_START) ||
- (cstartType == NodeState::ST_INITIAL_NODE_RESTART)) {
- if (logFilePtr.i == zeroLogFilePtr.i) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*IN AN INITIAL START WE START BY CREATING ALL LOG FILES AND SETTING THEIR */
-/*PROPER SIZE AND INITIALISING PAGE ZERO IN ALL FILES. */
-/*WE START BY CREATING FILE ZERO IN EACH LOG PART AND THEN PROCEED */
-/*SEQUENTIALLY THROUGH ALL LOG FILES IN THE LOG PART. */
-/* ------------------------------------------------------------------------- */
- openLogfileInit(signal);
- }//if
- }//if
- }//for
- zeroLogFilePtr.p->prevLogFile = logFilePtr.i;
- logFilePtr.p->nextLogFile = zeroLogFilePtr.i;
- }//for
- if (cstartType != NodeState::ST_INITIAL_START &&
- cstartType != NodeState::ST_INITIAL_NODE_RESTART) {
- jam();
- ndbrequire(cstartType == NodeState::ST_NODE_RESTART ||
- cstartType == NodeState::ST_SYSTEM_RESTART);
- /** --------------------------------------------------------------------
- * THIS CODE KICKS OFF THE SYSTEM RESTART AND NODE RESTART. IT STARTS UP
- * THE RESTART BY FINDING THE END OF THE LOG AND FROM THERE FINDING THE
- * INFO ABOUT THE GLOBAL CHECKPOINTS IN THE FRAGMENT LOG.
- --------------------------------------------------------------------- */
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- LogFileRecordPtr locLogFilePtr;
- ptrAss(logPartPtr, logPartRecord);
- locLogFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FRONTPAGE;
- openFileRw(signal, locLogFilePtr);
- }//for
- }//if
-
- signal->theData[0] = cownref;
- sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
- return;
-}//Dblqh::startphase3Lab()
-
-/* ****************** */
-/* READ_NODESCONF > */
-/* ****************** */
-void Dblqh::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
-
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
- cnoOfNodes = readNodes->noOfNodes;
-
- unsigned ind = 0;
- unsigned i = 0;
- for (i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if (NodeBitmask::get(readNodes->allNodes, i)) {
- jam();
- cnodeData[ind] = i;
- cnodeStatus[ind] = NodeBitmask::get(readNodes->inactiveNodes, i);
- //readNodes->getVersionId(i, readNodes->theVersionIds) not used
- if (!NodeBitmask::get(readNodes->inactiveNodes, i))
- {
- jam();
- m_sr_nodes.set(i);
- }
- ind++;
- }//if
- }//for
- ndbrequire(ind == cnoOfNodes);
- ndbrequire(cnoOfNodes >= 1 && cnoOfNodes < MAX_NDB_NODES);
- ndbrequire(!(cnoOfNodes == 1 && cstartType == NodeState::ST_NODE_RESTART));
-
- caddNodeState = ZFALSE;
- if (cstartType == NodeState::ST_SYSTEM_RESTART)
- {
- jam();
- sendNdbSttorryLab(signal);
- return;
- }
- else if (cstartType == NodeState::ST_NODE_RESTART)
- {
- jam();
- SET_TRACENR_FLAG;
- m_sr_nodes.clear();
- m_sr_nodes.set(getOwnNodeId());
- sendNdbSttorryLab(signal);
- return;
- }
- SET_TRACENR_FLAG;
-
- checkStartCompletedLab(signal);
- return;
-}//Dblqh::execREAD_NODESCONF()
-
-void Dblqh::checkStartCompletedLab(Signal* signal)
-{
- if (caddNodeState == ZFALSE) {
- if (cinitialStartOngoing == ZFALSE) {
- jam();
- sendNdbSttorryLab(signal);
- return;
- }//if
- }//if
- return;
-}//Dblqh::checkStartCompletedLab()
-
-void Dblqh::startphase4Lab(Signal* signal)
-{
- sendNdbSttorryLab(signal);
- return;
-}//Dblqh::startphase4Lab()
-
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* SET CONCURRENCY OF LOCAL CHECKPOINTS TO BE USED AFTER SYSTEM RESTART. */
-/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-void Dblqh::startphase6Lab(Signal* signal)
-{
- cstartPhase = ZNIL;
- cstartType = ZNIL;
- CLEAR_TRACENR_FLAG;
- sendNdbSttorryLab(signal);
- return;
-}//Dblqh::startphase6Lab()
-
-void Dblqh::sendNdbSttorryLab(Signal* signal)
-{
- signal->theData[0] = cownref;
- sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
- return;
-}//Dblqh::sendNdbSttorryLab()
-
-void Dblqh::sendsttorryLab(Signal* signal)
-{
-/* *********<< */
-/* STTORRY < */
-/* *********<< */
- signal->theData[0] = csignalKey; /* SIGNAL KEY */
- signal->theData[1] = 3; /* BLOCK CATEGORY */
- signal->theData[2] = 2; /* SIGNAL VERSION NUMBER */
- signal->theData[3] = ZSTART_PHASE1;
- signal->theData[4] = 4;
- signal->theData[5] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
- return;
-}//Dblqh::sendsttorryLab()
-
-/* ***************>> */
-/* READ_NODESREF > */
-/* ***************>> */
-void Dblqh::execREAD_NODESREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dblqh::execREAD_NODESREF()
-
-/* *************** */
-/* SIZEALT_REP > */
-/* *************** */
-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();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- cnoLogFiles = 8;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_REDOLOG_FILES,
- &cnoLogFiles));
- ndbrequire(cnoLogFiles > 0);
-
- Uint32 log_page_size= 0;
- ndb_mgm_get_int_parameter(p, CFG_DB_REDO_BUFFER,
- &log_page_size);
-
- /**
- * Always set page size in half MBytes
- */
- clogPageFileSize= (log_page_size / sizeof(LogPageRecord));
- Uint32 mega_byte_part= clogPageFileSize & 15;
- if (mega_byte_part != 0) {
- jam();
- clogPageFileSize+= (16 - mega_byte_part);
- }
-
- /* maximum number of log file operations */
- clfoFileSize = clogPageFileSize;
- if (clfoFileSize < ZLFO_MIN_FILE_SIZE)
- clfoFileSize = ZLFO_MIN_FILE_SIZE;
-
- 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_OP_PER_SCAN;
-
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &c_diskless));
- c_o_direct = true;
- ndb_mgm_get_int_parameter(p, CFG_DB_O_DIRECT, &c_o_direct);
-
- Uint32 tmp= 0;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &tmp));
- c_fragment_pool.setSize(tmp);
-
- if (!ndb_mgm_get_int_parameter(p, CFG_DB_REDOLOG_FILE_SIZE,
- &clogFileSize))
- {
- // convert to mbyte
- clogFileSize = (clogFileSize + 1024*1024 - 1) / (1024 * 1024);
- ndbrequire(clogFileSize >= 4 && clogFileSize <= 1024);
- }
-
- cmaxLogFilesInPageZero = (ZPAGE_SIZE - ZPAGE_HEADER_SIZE - 128) /
- (ZFD_MBYTE_SIZE * clogFileSize);
-
- /**
- * "Old" cmaxLogFilesInPageZero was 40
- * Each FD need 3 words per mb, require that they can fit into 1 page
- * (atleast 1 FD)
- * Is also checked in ConfigInfo.cpp (max FragmentLogFileSize = 1Gb)
- * 1Gb = 1024Mb => 3(ZFD_MBYTE_SIZE) * 1024 < 8192 (ZPAGE_SIZE)
- */
- if (cmaxLogFilesInPageZero > 40)
- {
- jam();
- cmaxLogFilesInPageZero = 40;
- }
- else
- {
- ndbrequire(cmaxLogFilesInPageZero);
- }
-
- initRecords();
- initialiseRecordsLab(signal, 0, ref, senderData);
-
- return;
-}//Dblqh::execSIZEALT_REP()
-
-/* ########################################################################## */
-/* ####### ADD/DELETE FRAGMENT MODULE ####### */
-/* THIS MODULE IS USED BY DICTIONARY TO CREATE NEW FRAGMENTS AND DELETE */
-/* OLD FRAGMENTS. */
-/* */
-/* ########################################################################## */
-/* -------------------------------------------------------------- */
-/* FRAG REQ */
-/* -------------------------------------------------------------- */
-/* *********************************************************> */
-/* LQHFRAGREQ: Create new fragments for a table. Sender DICT */
-/* *********************************************************> */
-
-// this unbelievable mess could be replaced by one signal to LQH
-// and execute direct to local DICT to get everything at once
-
-void Dblqh::execLQHFRAGREQ(Signal* signal)
-{
- jamEntry();
- LqhFragReq * req = (LqhFragReq*)signal->getDataPtr();
-
- Uint32 retPtr = req->senderData;
- BlockReference retRef = req->senderRef;
- Uint32 fragId = req->fragmentId;
- Uint32 reqinfo = req->requestInfo;
- tabptr.i = req->tableId;
- Uint16 tlocalKeylen = req->localKeyLength;
- Uint32 tmaxLoadFactor = req->maxLoadFactor;
- Uint32 tminLoadFactor = req->minLoadFactor;
- Uint8 tk = req->kValue;
- Uint8 tlhstar = req->lh3DistrBits;
- Uint8 tlh = req->lh3PageBits;
- Uint32 tnoOfAttr = req->noOfAttributes;
- Uint32 tnoOfNull = req->noOfNullAttributes;
- Uint32 maxRowsLow = req->maxRowsLow;
- Uint32 maxRowsHigh = req->maxRowsHigh;
- Uint32 minRowsLow = req->minRowsLow;
- Uint32 minRowsHigh = req->minRowsHigh;
- Uint32 tschemaVersion = req->schemaVersion;
- Uint32 ttupKeyLength = req->keyLength;
- Uint32 noOfKeyAttr = req->noOfKeyAttr;
- Uint32 noOfCharsets = req->noOfCharsets;
- Uint32 checksumIndicator = req->checksumIndicator;
- Uint32 gcpIndicator = req->GCPIndicator;
- Uint32 startGci = req->startGci;
- Uint32 tableType = req->tableType;
- Uint32 primaryTableId = req->primaryTableId;
- Uint32 tablespace= req->tablespace_id;
- Uint32 logPart = req->logPartId;
- Uint32 forceVarPartFlag = req->forceVarPartFlag;
-
- if (signal->getLength() < 20)
- {
- logPart = (fragId & 1) + 2 * (tabptr.i & 1);
- }
- logPart &= 3;
-
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- bool tempTable = ((reqinfo & LqhFragReq::TemporaryTable) != 0);
-
- /* Temporary tables set to defined in system restart */
- if (tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
- tabptr.p->tableStatus = Tablerec::ADD_TABLE_ONGOING;
- tabptr.p->tableType = tableType;
- tabptr.p->primaryTableId =
- (primaryTableId == RNIL ? tabptr.i : primaryTableId);
- tabptr.p->schemaVersion = tschemaVersion;
- tabptr.p->m_disk_table= 0;
- }//if
-
- if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING){
- jam();
- fragrefLab(signal, retRef, retPtr, ZTAB_STATE_ERROR);
- return;
- }//if
- //--------------------------------------------------------------------
- // We could arrive here if we create the fragment as part of a take
- // over by a hot spare node. The table is then is already created
- // and bit 31 is set, thus indicating that we are creating a fragment
- // by copy creation. Also since the node has already been started we
- // know that it is not a node restart ongoing.
- //--------------------------------------------------------------------
-
- if (getFragmentrec(signal, fragId)) {
- jam();
- fragrefLab(signal, retRef, retPtr, terrorCode);
- return;
- }//if
- if (!insertFragrec(signal, fragId)) {
- jam();
- fragrefLab(signal, retRef, retPtr, terrorCode);
- return;
- }//if
- Uint32 copyType = reqinfo & 3;
- initFragrec(signal, tabptr.i, fragId, copyType);
- fragptr.p->startGci = startGci;
- fragptr.p->newestGci = startGci;
- fragptr.p->tableType = tableType;
- fragptr.p->m_log_part_ptr_i = logPart; // assumes array
-
- if (DictTabInfo::isOrderedIndex(tableType)) {
- jam();
- // find corresponding primary table fragment
- TablerecPtr tTablePtr;
- tTablePtr.i = primaryTableId;
- ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
- FragrecordPtr tFragPtr;
- tFragPtr.i = RNIL;
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- if (tTablePtr.p->fragid[i] == fragptr.p->fragId) {
- jam();
- tFragPtr.i = tTablePtr.p->fragrec[i];
- break;
- }
- }
- ndbrequire(tFragPtr.i != RNIL);
- // store it
- fragptr.p->tableFragptr = tFragPtr.i;
- } else {
- fragptr.p->tableFragptr = fragptr.i;
- }
-
- if (tempTable) {
-//--------------------------------------------
-// reqinfo bit 3-4 = 2 means temporary table
-// without logging or checkpointing.
-//--------------------------------------------
- jam();
- fragptr.p->logFlag = Fragrecord::STATE_FALSE;
- fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE;
- }//if
-
-//----------------------------------------------
-// For node restarts it is not necessarily zero
-//----------------------------------------------
- if (cfirstfreeAddfragrec == RNIL) {
- jam();
- deleteFragrec(fragId);
- fragrefLab(signal, retRef, retPtr, ZNO_ADD_FRAGREC);
- return;
- }//if
- seizeAddfragrec(signal);
- addfragptr.p->addFragid = fragId;
- addfragptr.p->fragmentPtr = fragptr.i;
- addfragptr.p->dictBlockref = retRef;
- addfragptr.p->dictConnectptr = retPtr;
- addfragptr.p->m_senderAttrPtr = RNIL;
- addfragptr.p->noOfAttr = tnoOfAttr;
- addfragptr.p->noOfNull = tnoOfNull;
- addfragptr.p->maxRowsLow = maxRowsLow;
- addfragptr.p->maxRowsHigh = maxRowsHigh;
- addfragptr.p->minRowsLow = minRowsLow;
- addfragptr.p->minRowsHigh = minRowsHigh;
- addfragptr.p->tabId = tabptr.i;
- addfragptr.p->totalAttrReceived = 0;
- addfragptr.p->attrSentToTup = ZNIL;/* TO FIND PROGRAMMING ERRORS QUICKLY */
- addfragptr.p->schemaVer = tschemaVersion;
- Uint32 tmp = (reqinfo & LqhFragReq::CreateInRunning);
- addfragptr.p->fragCopyCreation = (tmp == 0 ? 0 : 1);
- addfragptr.p->addfragErrorCode = 0;
- addfragptr.p->noOfKeyAttr = noOfKeyAttr;
- addfragptr.p->noOfCharsets = noOfCharsets;
- addfragptr.p->checksumIndicator = checksumIndicator;
- addfragptr.p->GCPIndicator = gcpIndicator;
- addfragptr.p->lh3DistrBits = tlhstar;
- addfragptr.p->tableType = tableType;
- addfragptr.p->primaryTableId = primaryTableId;
- addfragptr.p->tablespace_id= tablespace;
- addfragptr.p->forceVarPartFlag = forceVarPartFlag;
- //
- addfragptr.p->tupConnectptr = RNIL;
- addfragptr.p->tuxConnectptr = RNIL;
-
- if (DictTabInfo::isTable(tableType) ||
- DictTabInfo::isHashIndex(tableType)) {
- jam();
- AccFragReq* const accreq = (AccFragReq*)signal->getDataPtrSend();
- accreq->userPtr = addfragptr.i;
- accreq->userRef = cownref;
- accreq->tableId = tabptr.i;
- accreq->reqInfo = copyType << 4;
- accreq->fragId = fragId;
- accreq->localKeyLen = tlocalKeylen;
- accreq->maxLoadFactor = tmaxLoadFactor;
- accreq->minLoadFactor = tminLoadFactor;
- accreq->kValue = tk;
- accreq->lhFragBits = tlhstar;
- accreq->lhDirBits = tlh;
- accreq->keyLength = ttupKeyLength;
- /* --------------------------------------------------------------------- */
- /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to */
- /* create 2 tuple fragments on this node. */
- /* --------------------------------------------------------------------- */
- addfragptr.p->addfragStatus = AddFragRecord::ACC_ADDFRAG;
- sendSignal(fragptr.p->accBlockref, GSN_ACCFRAGREQ,
- signal, AccFragReq::SignalLength, JBB);
- return;
- }
- if (DictTabInfo::isOrderedIndex(tableType)) {
- jam();
- addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
- sendAddFragReq(signal);
- return;
- }
- ndbrequire(false);
-}//Dblqh::execLQHFRAGREQ()
-
-/* *************** */
-/* ACCFRAGCONF > */
-/* *************** */
-void Dblqh::execACCFRAGCONF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- Uint32 taccConnectptr = signal->theData[1];
- //Uint32 fragId1 = signal->theData[2];
- Uint32 accFragPtr1 = signal->theData[4];
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
-
- addfragptr.p->accConnectptr = taccConnectptr;
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- fragptr.p->accFragptr = accFragPtr1;
-
- addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUP;
- sendAddFragReq(signal);
-}//Dblqh::execACCFRAGCONF()
-
-/* *************** */
-/* TUPFRAGCONF > */
-/* *************** */
-void Dblqh::execTUPFRAGCONF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- Uint32 tupConnectptr = signal->theData[1];
- Uint32 tupFragPtr = signal->theData[2]; /* TUP FRAGMENT POINTER */
- //Uint32 localFragId = signal->theData[3]; /* LOCAL FRAGMENT ID */
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- fragptr.p->tupFragptr = tupFragPtr;
- switch (addfragptr.p->addfragStatus) {
- case AddFragRecord::WAIT_TUP:
- jam();
- fragptr.p->tupFragptr = tupFragPtr;
- addfragptr.p->tupConnectptr = tupConnectptr;
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
- addfragptr.p->addfragStatus = AddFragRecord::WAIT_TUX;
- sendAddFragReq(signal);
- break;
- }
- goto done_with_frag;
- break;
- case AddFragRecord::WAIT_TUX:
- jam();
- fragptr.p->tuxFragptr = tupFragPtr;
- addfragptr.p->tuxConnectptr = tupConnectptr;
- goto done_with_frag;
- break;
- done_with_frag:
- /* ---------------------------------------------------------------- */
- /* Finished create of fragments. Now ready for creating attributes. */
- /* ---------------------------------------------------------------- */
- addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
- {
- LqhFragConf* conf = (LqhFragConf*)signal->getDataPtrSend();
- conf->senderData = addfragptr.p->dictConnectptr;
- conf->lqhFragPtr = addfragptr.i;
- sendSignal(addfragptr.p->dictBlockref, GSN_LQHFRAGCONF,
- signal, LqhFragConf::SignalLength, JBB);
- }
- break;
- default:
- ndbrequire(false);
- break;
- }
-}//Dblqh::execTUPFRAGCONF()
-
-/* *************** */
-/* TUXFRAGCONF > */
-/* *************** */
-void Dblqh::execTUXFRAGCONF(Signal* signal)
-{
- jamEntry();
- execTUPFRAGCONF(signal);
-}//Dblqh::execTUXFRAGCONF
-
-/*
- * Add fragment in TUP or TUX. Called up to 4 times.
- */
-void
-Dblqh::sendAddFragReq(Signal* signal)
-{
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUP){
- TupFragReq* const tupFragReq = (TupFragReq*)signal->getDataPtrSend();
- if (DictTabInfo::isTable(addfragptr.p->tableType) ||
- DictTabInfo::isHashIndex(addfragptr.p->tableType)) {
- jam();
- tupFragReq->userPtr = addfragptr.i;
- tupFragReq->userRef = cownref;
- tupFragReq->reqInfo = 0; /* ADD TABLE */
- tupFragReq->tableId = addfragptr.p->tabId;
- tupFragReq->noOfAttr = addfragptr.p->noOfAttr;
- tupFragReq->fragId = addfragptr.p->addFragid;
- tupFragReq->maxRowsLow = addfragptr.p->maxRowsLow;
- tupFragReq->maxRowsHigh = addfragptr.p->maxRowsHigh;
- tupFragReq->minRowsLow = addfragptr.p->minRowsLow;
- tupFragReq->minRowsHigh = addfragptr.p->minRowsHigh;
- tupFragReq->noOfNullAttr = addfragptr.p->noOfNull;
- tupFragReq->schemaVersion = addfragptr.p->schemaVer;
- tupFragReq->noOfKeyAttr = addfragptr.p->noOfKeyAttr;
- tupFragReq->noOfCharsets = addfragptr.p->noOfCharsets;
- tupFragReq->checksumIndicator = addfragptr.p->checksumIndicator;
- tupFragReq->globalCheckpointIdIndicator = addfragptr.p->GCPIndicator;
- tupFragReq->tablespaceid = addfragptr.p->tablespace_id;
- tupFragReq->forceVarPartFlag = addfragptr.p->forceVarPartFlag;
- sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
- signal, TupFragReq::SignalLength, JBB);
- return;
- }
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
- jam();
- tupFragReq->userPtr = addfragptr.i;
- tupFragReq->userRef = cownref;
- tupFragReq->reqInfo = 0; /* ADD TABLE */
- tupFragReq->tableId = addfragptr.p->tabId;
- tupFragReq->noOfAttr = 1; /* ordered index: one array attr */
- tupFragReq->fragId = addfragptr.p->addFragid;
- tupFragReq->maxRowsLow = addfragptr.p->maxRowsLow;
- tupFragReq->maxRowsHigh = addfragptr.p->maxRowsHigh;
- tupFragReq->minRowsLow = addfragptr.p->minRowsLow;
- tupFragReq->minRowsHigh = addfragptr.p->minRowsHigh;
- tupFragReq->noOfNullAttr = 0; /* ordered index: no nullable */
- tupFragReq->schemaVersion = addfragptr.p->schemaVer;
- tupFragReq->noOfKeyAttr = 1; /* ordered index: one key */
- tupFragReq->noOfCharsets = addfragptr.p->noOfCharsets;
- tupFragReq->checksumIndicator = addfragptr.p->checksumIndicator;
- tupFragReq->globalCheckpointIdIndicator = addfragptr.p->GCPIndicator;
- tupFragReq->forceVarPartFlag = addfragptr.p->forceVarPartFlag;
- sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
- signal, TupFragReq::SignalLength, JBB);
- return;
- }
- }
- if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TUX) {
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
- jam();
- TuxFragReq* const tuxreq = (TuxFragReq*)signal->getDataPtrSend();
- tuxreq->userPtr = addfragptr.i;
- tuxreq->userRef = cownref;
- tuxreq->reqInfo = 0; /* ADD TABLE */
- tuxreq->tableId = addfragptr.p->tabId;
- ndbrequire(addfragptr.p->noOfAttr >= 2);
- tuxreq->noOfAttr = addfragptr.p->noOfAttr - 1; /* skip NDB$TNODE */
- tuxreq->fragId = addfragptr.p->addFragid;
- tuxreq->fragOff = addfragptr.p->lh3DistrBits;
- tuxreq->tableType = addfragptr.p->tableType;
- tuxreq->primaryTableId = addfragptr.p->primaryTableId;
- // pointer to index fragment in TUP
- tuxreq->tupIndexFragPtrI = fragptr.p->tupFragptr;
- // pointers to table fragments in TUP and ACC
- FragrecordPtr tFragPtr;
- tFragPtr.i = fragptr.p->tableFragptr;
- c_fragment_pool.getPtr(tFragPtr);
- tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr;
- tuxreq->tupTableFragPtrI[1] = RNIL;
- tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr;
- tuxreq->accTableFragPtrI[1] = RNIL;
- sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ,
- signal, TuxFragReq::SignalLength, JBB);
- return;
- }
- }
- ndbrequire(false);
-}//Dblqh::sendAddFragReq
-
-/* ************************************************************************> */
-/* LQHADDATTRREQ: Request from DICT to create attributes for the new table. */
-/* ************************************************************************> */
-void Dblqh::execLQHADDATTREQ(Signal* signal)
-{
- jamEntry();
- LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtr();
-
- addfragptr.i = req->lqhFragPtr;
- const Uint32 tnoOfAttr = req->noOfAttributes;
- const Uint32 senderData = req->senderData;
- const Uint32 senderAttrPtr = req->senderAttrPtr;
-
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::WAIT_ADD_ATTR);
- ndbrequire((tnoOfAttr != 0) && (tnoOfAttr <= LqhAddAttrReq::MAX_ATTRIBUTES));
- addfragptr.p->totalAttrReceived += tnoOfAttr;
- ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
-
- addfragptr.p->attrReceived = tnoOfAttr;
- for (Uint32 i = 0; i < tnoOfAttr; i++) {
- addfragptr.p->attributes[i] = req->attributes[i];
- if(AttributeDescriptor::getDiskBased(req->attributes[i].attrDescriptor))
- {
- TablerecPtr tabPtr;
- tabPtr.i = addfragptr.p->tabId;
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
- tabPtr.p->m_disk_table = 1;
- }
- }//for
- addfragptr.p->attrSentToTup = 0;
- ndbrequire(addfragptr.p->dictConnectptr == senderData);
- addfragptr.p->m_senderAttrPtr = senderAttrPtr;
- addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
- sendAddAttrReq(signal);
-}//Dblqh::execLQHADDATTREQ()
-
-/* *********************>> */
-/* TUP_ADD_ATTCONF > */
-/* *********************>> */
-void Dblqh::execTUP_ADD_ATTCONF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- // implies that operation was released on the other side
- const bool lastAttr = signal->theData[1];
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- switch (addfragptr.p->addfragStatus) {
- case AddFragRecord::TUP_ATTR_WAIT:
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
- addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT;
- sendAddAttrReq(signal);
- break;
- }
- goto done_with_attr;
- break;
- case AddFragRecord::TUX_ATTR_WAIT:
- jam();
- if (lastAttr)
- addfragptr.p->tuxConnectptr = RNIL;
- goto done_with_attr;
- break;
- done_with_attr:
- addfragptr.p->attrSentToTup = addfragptr.p->attrSentToTup + 1;
- ndbrequire(addfragptr.p->attrSentToTup <= addfragptr.p->attrReceived);
- ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
- if (addfragptr.p->attrSentToTup < addfragptr.p->attrReceived) {
- // more in this batch
- jam();
- addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT;
- sendAddAttrReq(signal);
- } else if (addfragptr.p->totalAttrReceived < addfragptr.p->noOfAttr) {
- // more batches to receive
- jam();
- addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
- LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
- conf->senderData = addfragptr.p->dictConnectptr;
- conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
- conf->fragId = addfragptr.p->addFragid;
- sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF,
- signal, LqhAddAttrConf::SignalLength, JBB);
- } else {
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- /* ------------------------------------------------------------------
- * WE HAVE NOW COMPLETED ADDING THIS FRAGMENT. WE NOW NEED TO SET THE
- * PROPER STATE IN FRAG_STATUS DEPENDENT ON IF WE ARE CREATING A NEW
- * REPLICA OR IF WE ARE CREATING A TABLE. FOR FRAGMENTS IN COPY
- * PROCESS WE DO NOT WANT LOGGING ACTIVATED.
- * ----------------------------------------------------------------- */
- if (addfragptr.p->fragCopyCreation == 1) {
- jam();
- if (! DictTabInfo::isOrderedIndex(addfragptr.p->tableType))
- {
- fragptr.p->m_copy_started_state = Fragrecord::AC_IGNORED;
- //fragptr.p->m_copy_started_state = Fragrecord::AC_NR_COPY;
- fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
- }
- else
- {
- fragptr.p->fragStatus = Fragrecord::FSACTIVE;
- }
- fragptr.p->logFlag = Fragrecord::STATE_FALSE;
- } else {
- jam();
- fragptr.p->fragStatus = Fragrecord::FSACTIVE;
- }//if
- LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
- conf->senderData = addfragptr.p->dictConnectptr;
- conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
- conf->fragId = addfragptr.p->addFragid;
- sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF, signal,
- LqhAddAttrConf::SignalLength, JBB);
- releaseAddfragrec(signal);
- }//if
- break;
- default:
- ndbrequire(false);
- break;
- }
-}
-
-/* **********************>> */
-/* TUX_ADD_ATTRCONF > */
-/* **********************>> */
-void Dblqh::execTUX_ADD_ATTRCONF(Signal* signal)
-{
- jamEntry();
- execTUP_ADD_ATTCONF(signal);
-}//Dblqh::execTUX_ADD_ATTRCONF
-
-/*
- * Add attribute in TUP or TUX. Called up to 4 times.
- */
-void
-Dblqh::sendAddAttrReq(Signal* signal)
-{
- arrGuard(addfragptr.p->attrSentToTup, LqhAddAttrReq::MAX_ATTRIBUTES);
- LqhAddAttrReq::Entry& entry =
- addfragptr.p->attributes[addfragptr.p->attrSentToTup];
- const Uint32 attrId = entry.attrId & 0xffff;
- const Uint32 primaryAttrId = entry.attrId >> 16;
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT) {
- if (DictTabInfo::isTable(addfragptr.p->tableType) ||
- DictTabInfo::isHashIndex(addfragptr.p->tableType) ||
- (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
- primaryAttrId == ZNIL)) {
- jam();
- TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
- tupreq->tupConnectPtr = addfragptr.p->tupConnectptr;
- tupreq->notused1 = 0;
- tupreq->attrId = attrId;
- tupreq->attrDescriptor = entry.attrDescriptor;
- tupreq->extTypeInfo = entry.extTypeInfo;
- sendSignal(fragptr.p->tupBlockref, GSN_TUP_ADD_ATTRREQ,
- signal, TupAddAttrReq::SignalLength, JBB);
- return;
- }
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
- primaryAttrId != ZNIL) {
- // this attribute is not for TUP
- jam();
- TupAddAttrConf* tupconf = (TupAddAttrConf*)signal->getDataPtrSend();
- tupconf->userPtr = addfragptr.i;
- tupconf->lastAttr = false;
- sendSignal(reference(), GSN_TUP_ADD_ATTCONF,
- signal, TupAddAttrConf::SignalLength, JBB);
- return;
- }
- }
- if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT) {
- jam();
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
- primaryAttrId != ZNIL) {
- jam();
- TuxAddAttrReq* const tuxreq = (TuxAddAttrReq*)signal->getDataPtrSend();
- tuxreq->tuxConnectPtr = addfragptr.p->tuxConnectptr;
- tuxreq->notused1 = 0;
- tuxreq->attrId = attrId;
- tuxreq->attrDescriptor = entry.attrDescriptor;
- tuxreq->extTypeInfo = entry.extTypeInfo;
- tuxreq->primaryAttrId = primaryAttrId;
- sendSignal(fragptr.p->tuxBlockref, GSN_TUX_ADD_ATTRREQ,
- signal, TuxAddAttrReq::SignalLength, JBB);
- return;
- }
- if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
- primaryAttrId == ZNIL) {
- // this attribute is not for TUX
- jam();
- TuxAddAttrConf* tuxconf = (TuxAddAttrConf*)signal->getDataPtrSend();
- tuxconf->userPtr = addfragptr.i;
- tuxconf->lastAttr = false;
- sendSignal(reference(), GSN_TUX_ADD_ATTRCONF,
- signal, TuxAddAttrConf::SignalLength, JBB);
- return;
- }
- }
- ndbrequire(false);
-}//Dblqh::sendAddAttrReq
-
-/* ************************************************************************>> */
-/* TAB_COMMITREQ: Commit the new table for use in transactions. Sender DICT. */
-/* ************************************************************************>> */
-void Dblqh::execTAB_COMMITREQ(Signal* signal)
-{
- jamEntry();
- Uint32 dihPtr = signal->theData[0];
- BlockReference dihBlockref = signal->theData[1];
- tabptr.i = signal->theData[2];
-
- if (tabptr.i >= ctabrecFileSize) {
- jam();
- terrorCode = ZTAB_FILE_SIZE;
- signal->theData[0] = dihPtr;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = tabptr.i;
- signal->theData[3] = terrorCode;
- sendSignal(dihBlockref, GSN_TAB_COMMITREF, signal, 4, JBB);
- return;
- }//if
- ptrAss(tabptr, tablerec);
- if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING) {
- jam();
- terrorCode = ZTAB_STATE_ERROR;
- signal->theData[0] = dihPtr;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = tabptr.i;
- signal->theData[3] = terrorCode;
- signal->theData[4] = tabptr.p->tableStatus;
- sendSignal(dihBlockref, GSN_TAB_COMMITREF, signal, 5, JBB);
- ndbrequire(false);
- return;
- }//if
- tabptr.p->usageCount = 0;
- tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
- signal->theData[0] = dihPtr;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = tabptr.i;
- sendSignal(dihBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
- return;
-}//Dblqh::execTAB_COMMITREQ()
-
-
-void Dblqh::fragrefLab(Signal* signal,
- BlockReference fragBlockRef,
- Uint32 fragConPtr,
- Uint32 errorCode)
-{
- LqhFragRef * ref = (LqhFragRef*)signal->getDataPtrSend();
- ref->senderData = fragConPtr;
- ref->errorCode = errorCode;
- sendSignal(fragBlockRef, GSN_LQHFRAGREF, signal,
- LqhFragRef::SignalLength, JBB);
- return;
-}//Dblqh::fragrefLab()
-
-/*
- * Abort on-going ops.
- */
-void Dblqh::abortAddFragOps(Signal* signal)
-{
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- if (addfragptr.p->tupConnectptr != RNIL) {
- jam();
- TupFragReq* const tupFragReq = (TupFragReq*)signal->getDataPtrSend();
- tupFragReq->userPtr = (Uint32)-1;
- tupFragReq->userRef = addfragptr.p->tupConnectptr;
- sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
- addfragptr.p->tupConnectptr = RNIL;
- }
- if (addfragptr.p->tuxConnectptr != RNIL) {
- jam();
- TuxFragReq* const tuxFragReq = (TuxFragReq*)signal->getDataPtrSend();
- tuxFragReq->userPtr = (Uint32)-1;
- tuxFragReq->userRef = addfragptr.p->tuxConnectptr;
- sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
- addfragptr.p->tuxConnectptr = RNIL;
- }
-}
-
-/* ************>> */
-/* ACCFRAGREF > */
-/* ************>> */
-void Dblqh::execACCFRAGREF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- terrorCode = signal->theData[1];
- ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
- addfragptr.p->addfragErrorCode = terrorCode;
-
- const Uint32 ref = addfragptr.p->dictBlockref;
- const Uint32 senderData = addfragptr.p->dictConnectptr;
- const Uint32 errorCode = addfragptr.p->addfragErrorCode;
- releaseAddfragrec(signal);
- fragrefLab(signal, ref, senderData, errorCode);
-
- return;
-}//Dblqh::execACCFRAGREF()
-
-/* ************>> */
-/* TUPFRAGREF > */
-/* ************>> */
-void Dblqh::execTUPFRAGREF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- terrorCode = signal->theData[1];
- fragptr.i = addfragptr.p->fragmentPtr;
- c_fragment_pool.getPtr(fragptr);
- addfragptr.p->addfragErrorCode = terrorCode;
-
- // no operation to release, just add some jams
- switch (addfragptr.p->addfragStatus) {
- case AddFragRecord::WAIT_TUP:
- jam();
- break;
- case AddFragRecord::WAIT_TUX:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }
- abortAddFragOps(signal);
-
- const Uint32 ref = addfragptr.p->dictBlockref;
- const Uint32 senderData = addfragptr.p->dictConnectptr;
- const Uint32 errorCode = addfragptr.p->addfragErrorCode;
- releaseAddfragrec(signal);
- fragrefLab(signal, ref, senderData, errorCode);
-
-}//Dblqh::execTUPFRAGREF()
-
-/* ************>> */
-/* TUXFRAGREF > */
-/* ************>> */
-void Dblqh::execTUXFRAGREF(Signal* signal)
-{
- jamEntry();
- execTUPFRAGREF(signal);
-}//Dblqh::execTUXFRAGREF
-
-/* *********************> */
-/* TUP_ADD_ATTREF > */
-/* *********************> */
-void Dblqh::execTUP_ADD_ATTRREF(Signal* signal)
-{
- jamEntry();
- addfragptr.i = signal->theData[0];
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- terrorCode = signal->theData[1];
- addfragptr.p->addfragErrorCode = terrorCode;
-
- // operation was released on the other side
- switch (addfragptr.p->addfragStatus) {
- case AddFragRecord::TUP_ATTR_WAIT:
- jam();
- ndbrequire(addfragptr.p->tupConnectptr != RNIL);
- addfragptr.p->tupConnectptr = RNIL;
- break;
- case AddFragRecord::TUX_ATTR_WAIT:
- jam();
- ndbrequire(addfragptr.p->tuxConnectptr != RNIL);
- addfragptr.p->tuxConnectptr = RNIL;
- break;
- default:
- ndbrequire(false);
- break;
- }
- abortAddFragOps(signal);
-
- const Uint32 Ref = addfragptr.p->dictBlockref;
- const Uint32 senderData = addfragptr.p->dictConnectptr;
- const Uint32 errorCode = addfragptr.p->addfragErrorCode;
- releaseAddfragrec(signal);
-
- LqhAddAttrRef *const ref = (LqhAddAttrRef*)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->errorCode = errorCode;
- sendSignal(Ref, GSN_LQHADDATTREF, signal,
- LqhAddAttrRef::SignalLength, JBB);
-
-}//Dblqh::execTUP_ADD_ATTRREF()
-
-/* **********************> */
-/* TUX_ADD_ATTRREF > */
-/* **********************> */
-void Dblqh::execTUX_ADD_ATTRREF(Signal* signal)
-{
- jamEntry();
- execTUP_ADD_ATTRREF(signal);
-}//Dblqh::execTUX_ADD_ATTRREF
-
-void
-Dblqh::execPREP_DROP_TAB_REQ(Signal* signal){
- jamEntry();
-
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- TablerecPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
-
- Uint32 errCode = 0;
- errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_PREP_DROP_TAB_REQ);
- if(errCode != 0){
- jam();
-
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = errCode;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_ONGOING;
- tabPtr.p->waitingTC.clear();
- tabPtr.p->waitingDIH.clear();
-
- PrepDropTabConf * conf = (PrepDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
-
- signal->theData[0] = ZPREP_DROP_TABLE;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = senderRef;
- signal->theData[3] = senderData;
- checkDropTab(signal);
-}
-
-void
-Dblqh::checkDropTab(Signal* signal){
-
- TablerecPtr tabPtr;
- tabPtr.i = signal->theData[1];
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
-
- ndbrequire(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING);
-
- if(tabPtr.p->usageCount > 0){
- jam();
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
- return;
- }
-
- bool lcpDone = true;
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- if(lcpPtr.p->lcpState != LcpRecord::LCP_IDLE){
- jam();
-
- if(lcpPtr.p->currentFragment.lcpFragOrd.tableId == tabPtr.i){
- jam();
- lcpDone = false;
- }
-
- if(lcpPtr.p->lcpQueued &&
- lcpPtr.p->queuedFragment.lcpFragOrd.tableId == tabPtr.i){
- jam();
- lcpDone = false;
- }
- }
-
- if(!lcpDone){
- jam();
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
- return;
- }
-
- tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_DONE;
-
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- for(Uint32 i = 1; i<MAX_NDB_NODES; i++){
- if(tabPtr.p->waitingTC.get(i)){
- tabPtr.p->waitingTC.clear(i);
- sendSignal(calcTcBlockRef(i), GSN_WAIT_DROP_TAB_CONF, signal,
- WaitDropTabConf::SignalLength, JBB);
- }
- if(tabPtr.p->waitingDIH.get(i)){
- tabPtr.p->waitingDIH.clear(i);
- sendSignal(calcDihBlockRef(i), GSN_WAIT_DROP_TAB_CONF, signal,
- WaitDropTabConf::SignalLength, JBB);
- }
- }
-}
-
-void
-Dblqh::execWAIT_DROP_TAB_REQ(Signal* signal){
- jamEntry();
- WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtr();
-
- TablerecPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
-
- Uint32 senderRef = req->senderRef;
- Uint32 nodeId = refToNode(senderRef);
- Uint32 blockNo = refToBlock(senderRef);
-
- if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING){
- jam();
- switch(blockNo){
- case DBTC:
- tabPtr.p->waitingTC.set(nodeId);
- break;
- case DBDIH:
- tabPtr.p->waitingDIH.set(nodeId);
- break;
- default:
- ndbrequire(false);
- }
- return;
- }
-
- if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
- jam();
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_WAIT_DROP_TAB_CONF, signal,
- WaitDropTabConf::SignalLength, JBB);
- return;
- }
-
- WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtrSend();
- ref->tableId = tabPtr.i;
- ref->senderRef = reference();
-
- bool ok = false;
- switch(tabPtr.p->tableStatus){
- case Tablerec::TABLE_DEFINED:
- ok = true;
- ref->errorCode = WaitDropTabRef::IllegalTableState;
- break;
- case Tablerec::NOT_DEFINED:
- ok = true;
- ref->errorCode = WaitDropTabRef::NoSuchTable;
- break;
- case Tablerec::ADD_TABLE_ONGOING:
- ok = true;
- ref->errorCode = WaitDropTabRef::IllegalTableState;
- break;
- case Tablerec::PREP_DROP_TABLE_ONGOING:
- case Tablerec::PREP_DROP_TABLE_DONE:
- // Should have been take care of above
- ndbrequire(false);
- }
- ndbrequire(ok);
- ref->tableStatus = tabPtr.p->tableStatus;
- sendSignal(senderRef, GSN_WAIT_DROP_TAB_REF, signal,
- WaitDropTabRef::SignalLength, JBB);
- return;
-}
-
-void
-Dblqh::execDROP_TAB_REQ(Signal* signal){
- jamEntry();
-
- DropTabReq* req = (DropTabReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- TablerecPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
-
- do {
- if(req->requestType == DropTabReq::RestartDropTab){
- jam();
- break;
- }
-
- if(req->requestType == DropTabReq::OnlineDropTab){
- jam();
- Uint32 errCode = 0;
- errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_DROP_TAB_REQ);
- if(errCode != 0){
- jam();
-
- DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = errCode;
- sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
- DropTabRef::SignalLength, JBB);
- return;
- }
- }
-
- removeTable(tabPtr.i);
-
- } while(false);
-
- ndbrequire(tabPtr.p->usageCount == 0);
- tabPtr.p->tableStatus = Tablerec::NOT_DEFINED;
-
- DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
- dropConf->senderRef = reference();
- dropConf->senderData = senderData;
- dropConf->tableId = tabPtr.i;
- sendSignal(senderRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
-}
-
-Uint32
-Dblqh::checkDropTabState(Tablerec::TableStatus status, Uint32 gsn) const{
-
- if(gsn == GSN_PREP_DROP_TAB_REQ){
- switch(status){
- case Tablerec::NOT_DEFINED:
- jam();
- // Fall through
- case Tablerec::ADD_TABLE_ONGOING:
- jam();
- return PrepDropTabRef::NoSuchTable;
- break;
- case Tablerec::PREP_DROP_TABLE_ONGOING:
- jam();
- return PrepDropTabRef::PrepDropInProgress;
- break;
- case Tablerec::PREP_DROP_TABLE_DONE:
- jam();
- return PrepDropTabRef::DropInProgress;
- break;
- case Tablerec::TABLE_DEFINED:
- jam();
- return 0;
- break;
- }
- ndbrequire(0);
- }
-
- if(gsn == GSN_DROP_TAB_REQ){
- switch(status){
- case Tablerec::NOT_DEFINED:
- jam();
- // Fall through
- case Tablerec::ADD_TABLE_ONGOING:
- jam();
- return DropTabRef::NoSuchTable;
- break;
- case Tablerec::PREP_DROP_TABLE_ONGOING:
- jam();
- return DropTabRef::PrepDropInProgress;
- break;
- case Tablerec::PREP_DROP_TABLE_DONE:
- jam();
- return 0;
- break;
- case Tablerec::TABLE_DEFINED:
- jam();
- return DropTabRef::DropWoPrep;
- }
- ndbrequire(0);
- }
- ndbrequire(0);
- return RNIL;
-}
-
-void Dblqh::removeTable(Uint32 tableId)
-{
- tabptr.i = tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragid[i] != ZNIL) {
- jam();
- deleteFragrec(tabptr.p->fragid[i]);
- }//if
- }//for
-}//Dblqh::removeTable()
-
-void
-Dblqh::execALTER_TAB_REQ(Signal* signal)
-{
- jamEntry();
- AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- const Uint32 gci = req->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) req->requestType;
-
- TablerecPtr tablePtr;
- tablePtr.i = tableId;
- ptrCheckGuard(tablePtr, ctabrecFileSize, tablerec);
- tablePtr.p->schemaVersion = tableVersion;
-
- // Request handled successfully
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
-}
-
-/* ************************************************************************>>
- * TIME_SIGNAL: Handles time-out of local operations. This is a clean-up
- * handler. If no other measure has succeeded in cleaning up after time-outs
- * or else then this routine will remove the transaction after 120 seconds of
- * inactivity. The check is performed once per 10 second. Sender is QMGR.
- * ************************************************************************>> */
-void Dblqh::execTIME_SIGNAL(Signal* signal)
-{
- jamEntry();
- cLqhTimeOutCount++;
- cLqhTimeOutCheckCount++;
- if (cLqhTimeOutCheckCount < 10) {
- jam();
- return;
- }//if
- cLqhTimeOutCheckCount = 0;
-#ifdef VM_TRACE
- TcConnectionrecPtr tTcConptr;
-
- for (tTcConptr.i = 0; tTcConptr.i < ctcConnectrecFileSize;
- tTcConptr.i++) {
- jam();
- ptrAss(tTcConptr, tcConnectionrec);
- if ((tTcConptr.p->tcTimer != 0) &&
- ((tTcConptr.p->tcTimer + 120) < cLqhTimeOutCount)) {
- ndbout << "Dblqh::execTIME_SIGNAL"<<endl
- << "Timeout found in tcConnectRecord " <<tTcConptr.i<<endl
- << " cLqhTimeOutCount = " << cLqhTimeOutCount << endl
- << " tcTimer="<<tTcConptr.p->tcTimer<<endl
- << " tcTimer+120="<<tTcConptr.p->tcTimer + 120<<endl;
-
- signal->theData[0] = 2307;
- signal->theData[1] = tTcConptr.i;
- execDUMP_STATE_ORD(signal);
-
- // Reset the timer
- tTcConptr.p->tcTimer = 0;
- }//if
- }//for
-#endif
-#ifdef VM_TRACE
- for (lfoPtr.i = 0; lfoPtr.i < clfoFileSize; lfoPtr.i++) {
- ptrAss(lfoPtr, logFileOperationRecord);
- if ((lfoPtr.p->lfoTimer != 0) &&
- ((lfoPtr.p->lfoTimer + 120) < cLqhTimeOutCount)) {
- ndbout << "We have lost LFO record" << endl;
- ndbout << "index = " << lfoPtr.i;
- ndbout << "State = " << lfoPtr.p->lfoState;
- ndbout << " Page No = " << lfoPtr.p->lfoPageNo;
- ndbout << " noPagesRw = " << lfoPtr.p->noPagesRw;
- ndbout << "lfoWordWritten = " << lfoPtr.p->lfoWordWritten << endl;
- lfoPtr.p->lfoTimer = cLqhTimeOutCount;
- }//if
- }//for
-
-#endif
-
-#if 0
- LcpRecordPtr TlcpPtr;
- // Print information about the current local checkpoint
- TlcpPtr.i = 0;
- ptrAss(TlcpPtr, lcpRecord);
- ndbout << "Information about LCP in this LQH" << endl
- << " lcpState="<<TlcpPtr.p->lcpState<<endl
- << " firstLcpLocAcc="<<TlcpPtr.p->firstLcpLocAcc<<endl
- << " firstLcpLocTup="<<TlcpPtr.p->firstLcpLocTup<<endl
- << " lcpAccptr="<<TlcpPtr.p->lcpAccptr<<endl
- << " lastFragmentFlag="<<TlcpPtr.p->lastFragmentFlag<<endl
- << " lcpQueued="<<TlcpPtr.p->lcpQueued<<endl
- << " reportEmptyref="<< TlcpPtr.p->reportEmptyRef<<endl
- << " reportEmpty="<<TlcpPtr.p->reportEmpty<<endl;
-#endif
-}//Dblqh::execTIME_SIGNAL()
-
-/* ######################################################################### */
-/* ####### EXECUTION MODULE ####### */
-/* THIS MODULE HANDLES THE RECEPTION OF LQHKEYREQ AND ALL PROCESSING */
-/* OF OPERATIONS ON BEHALF OF THIS REQUEST. THIS DOES ALSO INVOLVE */
-/* RECEPTION OF VARIOUS TYPES OF ATTRINFO AND KEYINFO. IT DOES ALSO */
-/* INVOLVE COMMUNICATION WITH ACC AND TUP. */
-/* ######################################################################### */
-
-void Dblqh::noFreeRecordLab(Signal* signal,
- const LqhKeyReq * lqhKeyReq,
- Uint32 errCode)
-{
- jamEntry();
- const Uint32 transid1 = lqhKeyReq->transId1;
- const Uint32 transid2 = lqhKeyReq->transId2;
- const Uint32 reqInfo = lqhKeyReq->requestInfo;
-
- if(errCode == ZNO_FREE_MARKER_RECORDS_ERROR ||
- errCode == ZNODE_SHUTDOWN_IN_PROGESS){
- releaseTcrec(signal, tcConnectptr);
- }
-
- if (LqhKeyReq::getSimpleFlag(reqInfo) &&
- LqhKeyReq::getOperation(reqInfo) == ZREAD){
- jam();
- ndbrequire(LqhKeyReq::getApplicationAddressFlag(reqInfo));
- const Uint32 apiRef = lqhKeyReq->variableData[0];
- const Uint32 apiOpRec = lqhKeyReq->variableData[1];
-
- TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend();
-
- tcKeyRef->connectPtr = apiOpRec;
- tcKeyRef->transId[0] = transid1;
- tcKeyRef->transId[1] = transid2;
- tcKeyRef->errorCode = errCode;
- sendTCKEYREF(signal, apiRef, signal->getSendersBlockRef(), 0);
- } else {
- jam();
-
- const Uint32 clientPtr = lqhKeyReq->clientConnectPtr;
- Uint32 TcOprec = clientPtr;
- if(LqhKeyReq::getSameClientAndTcFlag(reqInfo) == 1){
- if(LqhKeyReq::getApplicationAddressFlag(reqInfo))
- TcOprec = lqhKeyReq->variableData[2];
- else
- TcOprec = lqhKeyReq->variableData[0];
- }
-
- LqhKeyRef * const ref = (LqhKeyRef*)signal->getDataPtrSend();
- ref->userRef = clientPtr;
- ref->connectPtr = TcOprec;
- ref->errorCode = errCode;
- ref->transId1 = transid1;
- ref->transId2 = transid2;
- sendSignal(signal->senderBlockRef(), GSN_LQHKEYREF, signal,
- LqhKeyRef::SignalLength, JBB);
- }//if
- return;
-}//Dblqh::noFreeRecordLab()
-
-void Dblqh::LQHKEY_abort(Signal* signal, int errortype)
-{
- switch (errortype) {
- case 0:
- jam();
- terrorCode = ZCOPY_NODE_ERROR;
- break;
- case 1:
- jam();
- terrorCode = ZNO_FREE_LQH_CONNECTION;
- break;
- case 2:
- jam();
- terrorCode = signal->theData[1];
- break;
- case 3:
- jam();
- ndbrequire((tcConnectptr.p->transactionState == TcConnectionrec::WAIT_ACC_ABORT) ||
- (tcConnectptr.p->transactionState == TcConnectionrec::ABORT_STOPPED) ||
- (tcConnectptr.p->transactionState == TcConnectionrec::ABORT_QUEUED));
- return;
- break;
- case 4:
- jam();
- if(tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
- jam();
- terrorCode = ZTABLE_NOT_DEFINED;
- } else if (tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
- tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
- jam();
- terrorCode = ZDROP_TABLE_IN_PROGRESS;
- } else {
- ndbrequire(0);
- }
- break;
- case 5:
- jam();
- terrorCode = ZINVALID_SCHEMA_VERSION;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- abortErrorLab(signal);
-}//Dblqh::LQHKEY_abort()
-
-void Dblqh::LQHKEY_error(Signal* signal, int errortype)
-{
- switch (errortype) {
- case 0:
- jam();
- break;
- case 1:
- jam();
- break;
- case 2:
- jam();
- break;
- case 3:
- jam();
- break;
- case 4:
- jam();
- break;
- case 5:
- jam();
- break;
- case 6:
- jam();
- break;
- default:
- jam();
- break;
- }//switch
- ndbrequire(false);
-}//Dblqh::LQHKEY_error()
-
-void Dblqh::execLQHKEYREF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- terrorCode = signal->theData[2];
- Uint32 transid1 = signal->theData[3];
- Uint32 transid2 = signal->theData[4];
- if (tcConnectptr.i >= ctcConnectrecFileSize) {
- errorReport(signal, 3);
- return;
- }//if
-/*------------------------------------------------------------------*/
-/* WE HAVE TO CHECK THAT THE SIGNAL DO NOT BELONG TO SOMETHING*/
-/* REMOVED DUE TO A TIME-OUT. */
-/*------------------------------------------------------------------*/
- ptrAss(tcConnectptr, tcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- switch (regTcPtr->connectState) {
- case TcConnectionrec::CONNECTED:
- jam();
- if ((regTcPtr->transid[0] != transid1) ||
- (regTcPtr->transid[1] != transid2)) {
- warningReport(signal, 14);
- return;
- }//if
- if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
- warningReport(signal, 15);
- return;
- }//if
- abortErrorLab(signal);
- return;
- break;
- case TcConnectionrec::LOG_CONNECTED:
- jam();
- logLqhkeyrefLab(signal);
- return;
- break;
- case TcConnectionrec::COPY_CONNECTED:
- jam();
- copyLqhKeyRefLab(signal);
- return;
- break;
- default:
- warningReport(signal, 16);
- return;
- break;
- }//switch
-}//Dblqh::execLQHKEYREF()
-
-/* -------------------------------------------------------------------------- */
-/* ------- ENTER PACKED_SIGNAL ------- */
-/* Execution of packed signal. The packed signal can contain COMMIT, COMPLETE */
-/* or LQHKEYCONF signals. These signals will be executed by their resp. exec */
-/* functions. */
-/* -------------------------------------------------------------------------- */
-void Dblqh::execPACKED_SIGNAL(Signal* signal)
-{
- Uint32 Tstep = 0;
- Uint32 Tlength;
- Uint32 TpackedData[28];
- Uint32 sig0, sig1, sig2, sig3 ,sig4, sig5, sig6;
-
- jamEntry();
- Tlength = signal->length();
- ndbrequire(Tlength <= 25);
- MEMCOPY_NO_WORDS(&TpackedData[0], &signal->theData[0], Tlength);
- while (Tlength > Tstep) {
- switch (TpackedData[Tstep] >> 28) {
- case ZCOMMIT:
- jam();
- sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
- sig1 = TpackedData[Tstep + 1];
- sig2 = TpackedData[Tstep + 2];
- sig3 = TpackedData[Tstep + 3];
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->theData[2] = sig2;
- signal->theData[3] = sig3;
- signal->header.theLength = 4;
- execCOMMIT(signal);
- Tstep += 4;
- break;
- case ZCOMPLETE:
- jam();
- sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
- sig1 = TpackedData[Tstep + 1];
- sig2 = TpackedData[Tstep + 2];
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->theData[2] = sig2;
- signal->header.theLength = 3;
- execCOMPLETE(signal);
- Tstep += 3;
- break;
- case ZLQHKEYCONF: {
- jam();
- LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
-
- sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
- sig1 = TpackedData[Tstep + 1];
- sig2 = TpackedData[Tstep + 2];
- sig3 = TpackedData[Tstep + 3];
- sig4 = TpackedData[Tstep + 4];
- sig5 = TpackedData[Tstep + 5];
- sig6 = TpackedData[Tstep + 6];
- lqhKeyConf->connectPtr = sig0;
- lqhKeyConf->opPtr = sig1;
- lqhKeyConf->userRef = sig2;
- lqhKeyConf->readLen = sig3;
- lqhKeyConf->transId1 = sig4;
- lqhKeyConf->transId2 = sig5;
- lqhKeyConf->noFiredTriggers = sig6;
- execLQHKEYCONF(signal);
- Tstep += LqhKeyConf::SignalLength;
- break;
- }
- case ZREMOVE_MARKER:
- jam();
- sig0 = TpackedData[Tstep + 1];
- sig1 = TpackedData[Tstep + 2];
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->header.theLength = 2;
- execREMOVE_MARKER_ORD(signal);
- Tstep += 3;
- break;
- default:
- ndbrequire(false);
- return;
- }//switch
- }//while
- ndbrequire(Tlength == Tstep);
- return;
-}//Dblqh::execPACKED_SIGNAL()
-
-void
-Dblqh::execREMOVE_MARKER_ORD(Signal* signal)
-{
- CommitAckMarker key;
- key.transid1 = signal->theData[0];
- key.transid2 = signal->theData[1];
- jamEntry();
-
- CommitAckMarkerPtr removedPtr;
- m_commitAckMarkerHash.remove(removedPtr, key);
-#if defined VM_TRACE || defined ERROR_INSERT
- ndbrequire(removedPtr.i != RNIL);
- m_commitAckMarkerPool.release(removedPtr);
-#else
- if (removedPtr.i != RNIL)
- {
- jam();
- m_commitAckMarkerPool.release(removedPtr);
- }
-#endif
-#ifdef MARKER_TRACE
- ndbout_c("Rem marker[%.8x %.8x]", key.transid1, key.transid2);
-#endif
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* ------- ENTER SEND_PACKED ------- */
-/* Used to force a packed signal to be sent if local signal buffer is not */
-/* empty. */
-/* -------------------------------------------------------------------------- */
-void Dblqh::execSEND_PACKED(Signal* signal)
-{
- HostRecordPtr Thostptr;
- UintR i;
- UintR TpackedListIndex = cpackedListIndex;
- jamEntry();
- for (i = 0; i < TpackedListIndex; i++) {
- Thostptr.i = cpackedList[i];
- ptrAss(Thostptr, hostRecord);
- jam();
- ndbrequire(Thostptr.i - 1 < MAX_NDB_NODES - 1);
- if (Thostptr.p->noOfPackedWordsLqh > 0) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- }//if
- if (Thostptr.p->noOfPackedWordsTc > 0) {
- jam();
- sendPackedSignalTc(signal, Thostptr.p);
- }//if
- Thostptr.p->inPackedList = false;
- }//for
- cpackedListIndex = 0;
- return;
-}//Dblqh::execSEND_PACKED()
-
-void
-Dblqh::updatePackedList(Signal* signal, HostRecord * ahostptr, Uint16 hostId)
-{
- Uint32 TpackedListIndex = cpackedListIndex;
- if (ahostptr->inPackedList == false) {
- jam();
- ahostptr->inPackedList = true;
- cpackedList[TpackedListIndex] = hostId;
- cpackedListIndex = TpackedListIndex + 1;
- }//if
-}//Dblqh::updatePackedList()
-
-void
-Dblqh::execREAD_PSEUDO_REQ(Signal* signal){
- jamEntry();
- TcConnectionrecPtr regTcPtr;
- regTcPtr.i = signal->theData[0];
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- if (signal->theData[1] == AttributeHeader::RANGE_NO) {
- signal->theData[0] = regTcPtr.p->m_scan_curr_range_no;
- }
- else if (signal->theData[1] != AttributeHeader::RECORDS_IN_RANGE)
- {
- jam();
- FragrecordPtr regFragptr;
- regFragptr.i = regTcPtr.p->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
-
- signal->theData[0] = regFragptr.p->accFragptr;
- EXECUTE_DIRECT(DBACC, GSN_READ_PSEUDO_REQ, signal, 2);
- }
- else
- {
- jam();
- // scanptr gets reset somewhere within the timeslice
- ScanRecordPtr tmp;
- tmp.i = regTcPtr.p->tcScanRec;
- c_scanRecordPool.getPtr(tmp);
- signal->theData[0] = tmp.p->scanAccPtr;
- EXECUTE_DIRECT(DBTUX, GSN_READ_PSEUDO_REQ, signal, 2);
- }
-}
-
-/* ************>> */
-/* TUPKEYCONF > */
-/* ************>> */
-void Dblqh::execTUPKEYCONF(Signal* signal)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- const TupKeyConf * const tupKeyConf = (TupKeyConf *)signal->getDataPtr();
- Uint32 tcIndex = tupKeyConf->userPtr;
- jamEntry();
- tcConnectptr.i = tcIndex;
- ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
- TcConnectionrec * regTcPtr = tcConnectptr.p;
- Uint32 activeCreat = regTcPtr->activeCreat;
-
- FragrecordPtr regFragptr;
- regFragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
- fragptr = regFragptr;
-
- switch (tcConnectptr.p->transactionState) {
- case TcConnectionrec::WAIT_TUP:
- jam();
- if (tcConnectptr.p->seqNoReplica == 0) // Primary replica
- tcConnectptr.p->noFiredTriggers = tupKeyConf->noFiredTriggers;
- tupkeyConfLab(signal);
- break;
- case TcConnectionrec::COPY_TUPKEY:
- jam();
- copyTupkeyConfLab(signal);
- break;
- case TcConnectionrec::SCAN_TUPKEY:
- jam();
- scanTupkeyConfLab(signal);
- break;
- case TcConnectionrec::WAIT_TUP_TO_ABORT:
- jam();
-/* ------------------------------------------------------------------------- */
-// Abort was not ready to start until this signal came back. Now we are ready
-// to start the abort.
-/* ------------------------------------------------------------------------- */
- if (unlikely(activeCreat == Fragrecord::AC_NR_COPY))
- {
- jam();
- ndbrequire(regTcPtr->m_nr_delete.m_cnt);
- regTcPtr->m_nr_delete.m_cnt--;
- if (regTcPtr->m_nr_delete.m_cnt)
- {
- jam();
- /**
- * Let operation wait for pending NR operations
- * even for before writing log...(as it's simpler)
- */
-
-#ifdef VM_TRACE
- /**
- * Only disk table can have pending ops...
- */
- TablerecPtr tablePtr;
- tablePtr.i = regTcPtr->tableref;
- ptrCheckGuard(tablePtr, ctabrecFileSize, tablerec);
- ndbrequire(tablePtr.p->m_disk_table);
-#endif
- return;
- }
- }
-
- abortCommonLab(signal);
- break;
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::ABORT_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/* IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY. */
-/* ------------------------------------------------------------------------- */
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
-
-}//Dblqh::execTUPKEYCONF()
-
-/* ************> */
-/* TUPKEYREF > */
-/* ************> */
-void Dblqh::execTUPKEYREF(Signal* signal)
-{
- const TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtr();
-
- jamEntry();
- tcConnectptr.i = tupKeyRef->userRef;
- terrorCode = tupKeyRef->errorCode;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec* regTcPtr = tcConnectptr.p;
- Uint32 activeCreat = regTcPtr->activeCreat;
-
- FragrecordPtr regFragptr;
- regFragptr.i = regTcPtr->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
- fragptr = regFragptr;
-
- TRACE_OP(regTcPtr, "TUPKEYREF");
-
- if (unlikely(activeCreat == Fragrecord::AC_NR_COPY))
- {
- jam();
- ndbrequire(regTcPtr->m_nr_delete.m_cnt);
- regTcPtr->m_nr_delete.m_cnt--;
- ndbassert(regTcPtr->transactionState == TcConnectionrec::WAIT_TUP ||
- regTcPtr->transactionState ==TcConnectionrec::WAIT_TUP_TO_ABORT);
- }
-
- switch (tcConnectptr.p->transactionState) {
- case TcConnectionrec::WAIT_TUP:
- jam();
- abortErrorLab(signal);
- break;
- case TcConnectionrec::COPY_TUPKEY:
- ndbrequire(false);
- break;
- case TcConnectionrec::SCAN_TUPKEY:
- jam();
- scanTupkeyRefLab(signal);
- break;
- case TcConnectionrec::WAIT_TUP_TO_ABORT:
- jam();
-/* ------------------------------------------------------------------------- */
-// Abort was not ready to start until this signal came back. Now we are ready
-// to start the abort.
-/* ------------------------------------------------------------------------- */
- abortCommonLab(signal);
- break;
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::ABORT_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/* IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY. */
-/* ------------------------------------------------------------------------- */
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
-}//Dblqh::execTUPKEYREF()
-
-void Dblqh::sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr)
-{
- Uint32 noOfWords = ahostptr->noOfPackedWordsLqh;
- BlockReference hostRef = ahostptr->hostLqhBlockRef;
- MEMCOPY_NO_WORDS(&signal->theData[0],
- &ahostptr->packedWordsLqh[0],
- noOfWords);
- sendSignal(hostRef, GSN_PACKED_SIGNAL, signal, noOfWords, JBB);
- ahostptr->noOfPackedWordsLqh = 0;
-}//Dblqh::sendPackedSignalLqh()
-
-void Dblqh::sendPackedSignalTc(Signal* signal, HostRecord * ahostptr)
-{
- Uint32 noOfWords = ahostptr->noOfPackedWordsTc;
- BlockReference hostRef = ahostptr->hostTcBlockRef;
- MEMCOPY_NO_WORDS(&signal->theData[0],
- &ahostptr->packedWordsTc[0],
- noOfWords);
- sendSignal(hostRef, GSN_PACKED_SIGNAL, signal, noOfWords, JBB);
- ahostptr->noOfPackedWordsTc = 0;
-}//Dblqh::sendPackedSignalTc()
-
-void Dblqh::sendCommitLqh(Signal* signal, BlockReference alqhBlockref)
-{
- HostRecordPtr Thostptr;
- Thostptr.i = refToNode(alqhBlockref);
- ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
- if (Thostptr.p->noOfPackedWordsLqh > 21) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- Uint32 pos = Thostptr.p->noOfPackedWordsLqh;
- Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMMIT << 28);
- Uint32 gci = tcConnectptr.p->gci;
- Uint32 transid1 = tcConnectptr.p->transid[0];
- Uint32 transid2 = tcConnectptr.p->transid[1];
- Thostptr.p->packedWordsLqh[pos] = ptrAndType;
- Thostptr.p->packedWordsLqh[pos + 1] = gci;
- Thostptr.p->packedWordsLqh[pos + 2] = transid1;
- Thostptr.p->packedWordsLqh[pos + 3] = transid2;
- Thostptr.p->noOfPackedWordsLqh = pos + 4;
-}//Dblqh::sendCommitLqh()
-
-void Dblqh::sendCompleteLqh(Signal* signal, BlockReference alqhBlockref)
-{
- HostRecordPtr Thostptr;
- Thostptr.i = refToNode(alqhBlockref);
- ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
- if (Thostptr.p->noOfPackedWordsLqh > 22) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- Uint32 pos = Thostptr.p->noOfPackedWordsLqh;
- Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMPLETE << 28);
- Uint32 transid1 = tcConnectptr.p->transid[0];
- Uint32 transid2 = tcConnectptr.p->transid[1];
- Thostptr.p->packedWordsLqh[pos] = ptrAndType;
- Thostptr.p->packedWordsLqh[pos + 1] = transid1;
- Thostptr.p->packedWordsLqh[pos + 2] = transid2;
- Thostptr.p->noOfPackedWordsLqh = pos + 3;
-}//Dblqh::sendCompleteLqh()
-
-void Dblqh::sendCommittedTc(Signal* signal, BlockReference atcBlockref)
-{
- HostRecordPtr Thostptr;
- Thostptr.i = refToNode(atcBlockref);
- ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
- if (Thostptr.p->noOfPackedWordsTc > 22) {
- jam();
- sendPackedSignalTc(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- Uint32 pos = Thostptr.p->noOfPackedWordsTc;
- Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMMITTED << 28);
- Uint32 transid1 = tcConnectptr.p->transid[0];
- Uint32 transid2 = tcConnectptr.p->transid[1];
- Thostptr.p->packedWordsTc[pos] = ptrAndType;
- Thostptr.p->packedWordsTc[pos + 1] = transid1;
- Thostptr.p->packedWordsTc[pos + 2] = transid2;
- Thostptr.p->noOfPackedWordsTc = pos + 3;
-}//Dblqh::sendCommittedTc()
-
-void Dblqh::sendCompletedTc(Signal* signal, BlockReference atcBlockref)
-{
- HostRecordPtr Thostptr;
- Thostptr.i = refToNode(atcBlockref);
- ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
- if (Thostptr.p->noOfPackedWordsTc > 22) {
- jam();
- sendPackedSignalTc(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- Uint32 pos = Thostptr.p->noOfPackedWordsTc;
- Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMPLETED << 28);
- Uint32 transid1 = tcConnectptr.p->transid[0];
- Uint32 transid2 = tcConnectptr.p->transid[1];
- Thostptr.p->packedWordsTc[pos] = ptrAndType;
- Thostptr.p->packedWordsTc[pos + 1] = transid1;
- Thostptr.p->packedWordsTc[pos + 2] = transid2;
- Thostptr.p->noOfPackedWordsTc = pos + 3;
-}//Dblqh::sendCompletedTc()
-
-void Dblqh::sendLqhkeyconfTc(Signal* signal, BlockReference atcBlockref)
-{
- LqhKeyConf* lqhKeyConf;
- HostRecordPtr Thostptr;
-
- bool packed= true;
- Thostptr.i = refToNode(atcBlockref);
- ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
- if (refToBlock(atcBlockref) == DBTC) {
- jam();
-/*******************************************************************
-// This signal was intended for DBTC as part of the normal transaction
-// execution.
-********************************************************************/
- if (Thostptr.p->noOfPackedWordsTc > (25 - LqhKeyConf::SignalLength)) {
- jam();
- sendPackedSignalTc(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- lqhKeyConf = (LqhKeyConf *)
- &Thostptr.p->packedWordsTc[Thostptr.p->noOfPackedWordsTc];
- Thostptr.p->noOfPackedWordsTc += LqhKeyConf::SignalLength;
- } else if(refToBlock(atcBlockref) == DBLQH){
- jam();
-/*******************************************************************
-// This signal was intended for DBLQH as part of log execution or
-// node recovery.
-********************************************************************/
- if (Thostptr.p->noOfPackedWordsLqh > (25 - LqhKeyConf::SignalLength)) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- lqhKeyConf = (LqhKeyConf *)
- &Thostptr.p->packedWordsLqh[Thostptr.p->noOfPackedWordsLqh];
- Thostptr.p->noOfPackedWordsLqh += LqhKeyConf::SignalLength;
- } else {
- packed= false;
- lqhKeyConf = (LqhKeyConf *)signal->getDataPtrSend();
- }
- Uint32 ptrAndType = tcConnectptr.i | (ZLQHKEYCONF << 28);
- Uint32 tcOprec = tcConnectptr.p->tcOprec;
- Uint32 ownRef = cownref;
- Uint32 readlenAi = tcConnectptr.p->readlenAi;
- Uint32 transid1 = tcConnectptr.p->transid[0];
- Uint32 transid2 = tcConnectptr.p->transid[1];
- Uint32 noFiredTriggers = tcConnectptr.p->noFiredTriggers;
- lqhKeyConf->connectPtr = ptrAndType;
- lqhKeyConf->opPtr = tcOprec;
- lqhKeyConf->userRef = ownRef;
- lqhKeyConf->readLen = readlenAi;
- lqhKeyConf->transId1 = transid1;
- lqhKeyConf->transId2 = transid2;
- lqhKeyConf->noFiredTriggers = noFiredTriggers;
-
- if(!packed)
- {
- lqhKeyConf->connectPtr = tcConnectptr.i;
- if(Thostptr.i == 0 || Thostptr.i == getOwnNodeId())
- {
- EXECUTE_DIRECT(refToBlock(atcBlockref), GSN_LQHKEYCONF,
- signal, LqhKeyConf::SignalLength);
- }
- else
- {
- sendSignal(atcBlockref, GSN_LQHKEYCONF,
- signal, LqhKeyConf::SignalLength, JBB);
- }
- }
-}//Dblqh::sendLqhkeyconfTc()
-
-/* ************************************************************************>>
- * KEYINFO: Get tuple request from DBTC. Next step is to contact DBACC to get
- * key to tuple if all key/attrinfo has been received, else for more attrinfo
- * signals.
- * ************************************************************************>> */
-void Dblqh::execKEYINFO(Signal* signal)
-{
- Uint32 tcOprec = signal->theData[0];
- Uint32 transid1 = signal->theData[1];
- Uint32 transid2 = signal->theData[2];
- jamEntry();
- if (findTransaction(transid1, transid2, tcOprec) != ZOK) {
- jam();
- return;
- }//if
-
- receive_keyinfo(signal,
- signal->theData+KeyInfo::HeaderLength,
- signal->getLength()-KeyInfo::HeaderLength);
-}
-
-void
-Dblqh::receive_keyinfo(Signal* signal,
- Uint32 * data, Uint32 len)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TcConnectionrec::TransactionState state = regTcPtr->transactionState;
- if (state != TcConnectionrec::WAIT_TUPKEYINFO &&
- state != TcConnectionrec::WAIT_SCAN_AI)
- {
- jam();
-/*****************************************************************************/
-/* TRANSACTION WAS ABORTED, THIS IS MOST LIKELY A SIGNAL BELONGING TO THE */
-/* ABORTED TRANSACTION. THUS IGNORE THE SIGNAL. */
-/*****************************************************************************/
- return;
- }//if
-
- Uint32 errorCode =
- handleLongTupKey(signal, data, len);
-
- if (errorCode != 0) {
- if (errorCode == 1) {
- jam();
- return;
- }//if
- jam();
- terrorCode = errorCode;
- if(state == TcConnectionrec::WAIT_TUPKEYINFO)
- abortErrorLab(signal);
- else
- abort_scan(signal, regTcPtr->tcScanRec, errorCode);
- return;
- }//if
- if(state == TcConnectionrec::WAIT_TUPKEYINFO)
- {
- FragrecordPtr regFragptr;
- regFragptr.i = regTcPtr->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
- fragptr = regFragptr;
- endgettupkeyLab(signal);
- }
- return;
-}//Dblqh::execKEYINFO()
-
-/* ------------------------------------------------------------------------- */
-/* FILL IN KEY DATA INTO DATA BUFFERS. */
-/* ------------------------------------------------------------------------- */
-Uint32 Dblqh::handleLongTupKey(Signal* signal,
- Uint32* dataPtr,
- Uint32 len)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 dataPos = 0;
- Uint32 total = regTcPtr->save1 + len;
- Uint32 primKeyLen = regTcPtr->primKeyLen;
- while (dataPos < len) {
- if (cfirstfreeDatabuf == RNIL) {
- jam();
- return ZGET_DATAREC_ERROR;
- }//if
- seizeTupkeybuf(signal);
- Databuf * const regDataPtr = databufptr.p;
- Uint32 data0 = dataPtr[dataPos];
- Uint32 data1 = dataPtr[dataPos + 1];
- Uint32 data2 = dataPtr[dataPos + 2];
- Uint32 data3 = dataPtr[dataPos + 3];
- regDataPtr->data[0] = data0;
- regDataPtr->data[1] = data1;
- regDataPtr->data[2] = data2;
- regDataPtr->data[3] = data3;
- dataPos += 4;
- }
-
- regTcPtr->save1 = total;
- return (total >= primKeyLen ? 0 : 1);
-}//Dblqh::handleLongTupKey()
-
-/* ------------------------------------------------------------------------- */
-/* ------- HANDLE ATTRINFO SIGNALS ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ************************************************************************>> */
-/* ATTRINFO: Continuation of KEYINFO signal (except for scans that do not use*/
-/* any KEYINFO). When all key and attribute info is received we contact DBACC*/
-/* for index handling. */
-/* ************************************************************************>> */
-void Dblqh::execATTRINFO(Signal* signal)
-{
- Uint32 tcOprec = signal->theData[0];
- Uint32 transid1 = signal->theData[1];
- Uint32 transid2 = signal->theData[2];
- jamEntry();
- if (findTransaction(transid1,
- transid2,
- tcOprec) != ZOK) {
- jam();
- return;
- }//if
-
- receive_attrinfo(signal,
- signal->getDataPtrSend()+AttrInfo::HeaderLength,
- signal->getLength()-AttrInfo::HeaderLength);
-}//Dblqh::execATTRINFO()
-
-void
-Dblqh::receive_attrinfo(Signal* signal, Uint32 * dataPtr, Uint32 length)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 totReclenAi = regTcPtr->totReclenAi;
- Uint32 currReclenAi = regTcPtr->currReclenAi + length;
- regTcPtr->currReclenAi = currReclenAi;
- if (totReclenAi == currReclenAi) {
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::WAIT_ATTR:
- {
- jam();
- fragptr.i = regTcPtr->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- lqhAttrinfoLab(signal, dataPtr, length);
- endgettupkeyLab(signal);
- return;
- break;
- }
- case TcConnectionrec::WAIT_SCAN_AI:
- jam();
- scanAttrinfoLab(signal, dataPtr, length);
- return;
- break;
- case TcConnectionrec::WAIT_TUP_TO_ABORT:
- case TcConnectionrec::LOG_ABORT_QUEUED:
- case TcConnectionrec::ABORT_QUEUED:
- case TcConnectionrec::ABORT_STOPPED:
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::WAIT_AI_AFTER_ABORT:
- jam();
- aiStateErrorCheckLab(signal, dataPtr,length);
- return;
- break;
- default:
- jam();
- ndbrequire(regTcPtr->abortState != TcConnectionrec::ABORT_IDLE);
- break;
- }//switch
- } else if (currReclenAi < totReclenAi) {
- jam();
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::WAIT_ATTR:
- jam();
- lqhAttrinfoLab(signal, dataPtr, length);
- return;
- break;
- case TcConnectionrec::WAIT_SCAN_AI:
- jam();
- scanAttrinfoLab(signal, dataPtr, length);
- return;
- break;
- case TcConnectionrec::WAIT_TUP_TO_ABORT:
- case TcConnectionrec::LOG_ABORT_QUEUED:
- case TcConnectionrec::ABORT_QUEUED:
- case TcConnectionrec::ABORT_STOPPED:
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::WAIT_AI_AFTER_ABORT:
- jam();
- aiStateErrorCheckLab(signal, dataPtr, length);
- return;
- break;
- default:
- jam();
- ndbrequire(regTcPtr->abortState != TcConnectionrec::ABORT_IDLE);
- break;
- }//switch
- } else {
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::WAIT_SCAN_AI:
- jam();
- scanAttrinfoLab(signal, dataPtr, length);
- return;
- break;
- default:
- ndbout_c("%d", regTcPtr->transactionState);
- ndbrequire(false);
- break;
- }//switch
- }//if
- return;
-}
-
-/* ************************************************************************>> */
-/* TUP_ATTRINFO: Interpreted execution in DBTUP generates redo-log info */
-/* which is sent back to DBLQH for logging. This is because the decision */
-/* to execute or not is made in DBTUP and thus we cannot start logging until */
-/* DBTUP part has been run. */
-/* ************************************************************************>> */
-void Dblqh::execTUP_ATTRINFO(Signal* signal)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 length = signal->length() - 3;
- Uint32 tcIndex = signal->theData[0];
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- jamEntry();
- tcConnectptr.i = tcIndex;
- ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
- ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_TUP);
- if (saveTupattrbuf(signal, &signal->theData[3], length) == ZOK) {
- return;
- } else {
- jam();
-/* ------------------------------------------------------------------------- */
-/* WE ARE WAITING FOR RESPONSE FROM TUP HERE. THUS WE NEED TO */
-/* GO THROUGH THE STATE MACHINE FOR THE OPERATION. */
-/* ------------------------------------------------------------------------- */
- localAbortStateHandlerLab(signal);
- }//if
-}//Dblqh::execTUP_ATTRINFO()
-
-/* ------------------------------------------------------------------------- */
-/* ------- HANDLE ATTRINFO FROM LQH ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::lqhAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->operation != ZREAD) {
- if (regTcPtr->operation != ZDELETE)
- {
- if (regTcPtr->opExec != 1) {
- if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
- ;
- } else {
- jam();
-/* ------------------------------------------------------------------------- */
-/* WE MIGHT BE WAITING FOR RESPONSE FROM SOME BLOCK HERE. THUS WE NEED TO */
-/* GO THROUGH THE STATE MACHINE FOR THE OPERATION. */
-/* ------------------------------------------------------------------------- */
- localAbortStateHandlerLab(signal);
- return;
- }//if
- }//if
- }//if
- }
- c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec, dataPtr, length);
-}//Dblqh::lqhAttrinfoLab()
-
-/* ------------------------------------------------------------------------- */
-/* ------ FIND TRANSACTION BY USING HASH TABLE ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-int Dblqh::findTransaction(UintR Transid1, UintR Transid2, UintR TcOprec)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- TcConnectionrecPtr locTcConnectptr;
-
- Uint32 ThashIndex = (Transid1 ^ TcOprec) & 1023;
- locTcConnectptr.i = ctransidHash[ThashIndex];
- while (locTcConnectptr.i != RNIL) {
- ptrCheckGuard(locTcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
- if ((locTcConnectptr.p->transid[0] == Transid1) &&
- (locTcConnectptr.p->transid[1] == Transid2) &&
- (locTcConnectptr.p->tcOprec == TcOprec)) {
-/* FIRST PART OF TRANSACTION CORRECT */
-/* SECOND PART ALSO CORRECT */
-/* THE OPERATION RECORD POINTER IN TC WAS ALSO CORRECT */
- jam();
- tcConnectptr.i = locTcConnectptr.i;
- tcConnectptr.p = locTcConnectptr.p;
- return (int)ZOK;
- }//if
- jam();
-/* THIS WAS NOT THE TRANSACTION WHICH WAS SOUGHT */
- locTcConnectptr.i = locTcConnectptr.p->nextHashRec;
- }//while
-/* WE DID NOT FIND THE TRANSACTION, REPORT NOT FOUND */
- return (int)ZNOT_FOUND;
-}//Dblqh::findTransaction()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SAVE ATTRINFO FROM TUP IN ATTRINBUF ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-int Dblqh::saveTupattrbuf(Signal* signal, Uint32* dataPtr, Uint32 len)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- while(len)
- {
- Uint32 length = len > AttrInfo::DataLength ? AttrInfo::DataLength : len;
- Uint32 tfirstfreeAttrinbuf = cfirstfreeAttrinbuf;
- Uint32 currTupAiLen = regTcPtr->currTupAiLen;
- if (tfirstfreeAttrinbuf == RNIL) {
- jam();
- terrorCode = ZGET_ATTRINBUF_ERROR;
- return ZGET_ATTRINBUF_ERROR;
- }//if
- seizeAttrinbuf(signal);
- Attrbuf * const regAttrPtr = attrinbufptr.p;
- MEMCOPY_NO_WORDS(&regAttrPtr->attrbuf[0], dataPtr, length);
- regTcPtr->currTupAiLen = currTupAiLen + length;
- regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = length;
-
- len -= length;
- dataPtr += length;
- }
- return ZOK;
-}//Dblqh::saveTupattrbuf()
-
-/* ==========================================================================
- * ======= SEIZE ATTRIBUTE IN BUFFER =======
- *
- * GET A NEW ATTRINBUF AND SETS ATTRINBUFPTR.
- * ========================================================================= */
-void Dblqh::seizeAttrinbuf(Signal* signal)
-{
- AttrbufPtr tmpAttrinbufptr;
- AttrbufPtr regAttrinbufptr;
- Attrbuf *regAttrbuf = attrbuf;
- Uint32 tattrinbufFileSize = cattrinbufFileSize;
-
- regAttrinbufptr.i = seize_attrinbuf();
- tmpAttrinbufptr.i = tcConnectptr.p->lastAttrinbuf;
- ptrCheckGuard(regAttrinbufptr, tattrinbufFileSize, regAttrbuf);
- tcConnectptr.p->lastAttrinbuf = regAttrinbufptr.i;
- regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN] = 0;
- if (tmpAttrinbufptr.i == RNIL) {
- jam();
- tcConnectptr.p->firstAttrinbuf = regAttrinbufptr.i;
- } else {
- jam();
- ptrCheckGuard(tmpAttrinbufptr, tattrinbufFileSize, regAttrbuf);
- tmpAttrinbufptr.p->attrbuf[ZINBUF_NEXT] = regAttrinbufptr.i;
- }//if
- regAttrinbufptr.p->attrbuf[ZINBUF_NEXT] = RNIL;
- attrinbufptr = regAttrinbufptr;
-}//Dblqh::seizeAttrinbuf()
-
-/* ==========================================================================
- * ======= SEIZE TC CONNECT RECORD =======
- *
- * GETS A NEW TC CONNECT RECORD FROM FREELIST.
- * ========================================================================= */
-void Dblqh::seizeTcrec()
-{
- TcConnectionrecPtr locTcConnectptr;
-
- locTcConnectptr.i = cfirstfreeTcConrec;
- ptrCheckGuard(locTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- Uint32 nextTc = locTcConnectptr.p->nextTcConnectrec;
- locTcConnectptr.p->nextTcConnectrec = RNIL;
- locTcConnectptr.p->clientConnectrec = RNIL;
- locTcConnectptr.p->clientBlockref = RNIL;
- locTcConnectptr.p->abortState = TcConnectionrec::ABORT_IDLE;
- locTcConnectptr.p->tcTimer = cLqhTimeOutCount;
- locTcConnectptr.p->tableref = RNIL;
- locTcConnectptr.p->savePointId = 0;
- locTcConnectptr.p->gci = 0;
- cfirstfreeTcConrec = nextTc;
- tcConnectptr = locTcConnectptr;
- locTcConnectptr.p->connectState = TcConnectionrec::CONNECTED;
-}//Dblqh::seizeTcrec()
-
-/* ==========================================================================
- * ======= SEIZE DATA BUFFER =======
- * ========================================================================= */
-void Dblqh::seizeTupkeybuf(Signal* signal)
-{
- Databuf *regDatabuf = databuf;
- DatabufPtr tmpDatabufptr;
- DatabufPtr regDatabufptr;
- Uint32 tdatabufFileSize = cdatabufFileSize;
-
-/* ------- GET A DATABUF. ------- */
- regDatabufptr.i = cfirstfreeDatabuf;
- tmpDatabufptr.i = tcConnectptr.p->lastTupkeybuf;
- ptrCheckGuard(regDatabufptr, tdatabufFileSize, regDatabuf);
- Uint32 nextFirst = regDatabufptr.p->nextDatabuf;
- tcConnectptr.p->lastTupkeybuf = regDatabufptr.i;
- if (tmpDatabufptr.i == RNIL) {
- jam();
- tcConnectptr.p->firstTupkeybuf = regDatabufptr.i;
- } else {
- jam();
- ptrCheckGuard(tmpDatabufptr, tdatabufFileSize, regDatabuf);
- tmpDatabufptr.p->nextDatabuf = regDatabufptr.i;
- }//if
- cfirstfreeDatabuf = nextFirst;
- regDatabufptr.p->nextDatabuf = RNIL;
- databufptr = regDatabufptr;
-}//Dblqh::seizeTupkeybuf()
-
-/* ------------------------------------------------------------------------- */
-/* ------- TAKE CARE OF LQHKEYREQ ------- */
-/* LQHKEYREQ IS THE SIGNAL THAT STARTS ALL OPERATIONS IN THE LQH BLOCK */
-/* THIS SIGNAL CONTAINS A LOT OF INFORMATION ABOUT WHAT TYPE OF OPERATION, */
-/* KEY INFORMATION, ATTRIBUTE INFORMATION, NODE INFORMATION AND A LOT MORE */
-/* ------------------------------------------------------------------------- */
-void Dblqh::execLQHKEYREQ(Signal* signal)
-{
- UintR sig0, sig1, sig2, sig3, sig4, sig5;
- Uint8 tfragDistKey;
-
- const LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtr();
-
- sig0 = lqhKeyReq->clientConnectPtr;
- if (cfirstfreeTcConrec != RNIL && !ERROR_INSERTED(5031)) {
- jamEntry();
- seizeTcrec();
- } else {
-/* ------------------------------------------------------------------------- */
-/* NO FREE TC RECORD AVAILABLE, THUS WE CANNOT HANDLE THE REQUEST. */
-/* ------------------------------------------------------------------------- */
- if (ERROR_INSERTED(5031)) {
- CLEAR_ERROR_INSERT_VALUE;
- }
- noFreeRecordLab(signal, lqhKeyReq, ZNO_TC_CONNECT_ERROR);
- return;
- }//if
-
- if(ERROR_INSERTED(5038) &&
- refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
- jam();
- SET_ERROR_INSERT_VALUE(5039);
- return;
- }
-
- c_Counters.operations++;
-
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 senderRef = regTcPtr->clientBlockref = signal->senderBlockRef();
- regTcPtr->clientConnectrec = sig0;
- regTcPtr->tcOprec = sig0;
- regTcPtr->storedProcId = ZNIL;
-
- UintR TtotReclenAi = lqhKeyReq->attrLen;
- sig1 = lqhKeyReq->savePointId;
- sig2 = lqhKeyReq->hashValue;
- UintR Treqinfo = lqhKeyReq->requestInfo;
- sig4 = lqhKeyReq->tableSchemaVersion;
- sig5 = lqhKeyReq->tcBlockref;
-
- regTcPtr->savePointId = sig1;
- regTcPtr->hashValue = sig2;
- const Uint32 schemaVersion = regTcPtr->schemaVersion = LqhKeyReq::getSchemaVersion(sig4);
- tabptr.i = LqhKeyReq::getTableId(sig4);
- regTcPtr->tcBlockref = sig5;
-
- const Uint8 op = LqhKeyReq::getOperation(Treqinfo);
- if ((op == ZREAD || op == ZREAD_EX) && !getAllowRead()){
- noFreeRecordLab(signal, lqhKeyReq, ZNODE_SHUTDOWN_IN_PROGESS);
- return;
- }
-
- Uint32 senderVersion = getNodeInfo(refToNode(senderRef)).m_version;
-
- regTcPtr->totReclenAi = LqhKeyReq::getAttrLen(TtotReclenAi);
- regTcPtr->tcScanInfo = lqhKeyReq->scanInfo;
- regTcPtr->indTakeOver = LqhKeyReq::getScanTakeOverFlag(TtotReclenAi);
-
- regTcPtr->readlenAi = 0;
- regTcPtr->currTupAiLen = 0;
- regTcPtr->listState = TcConnectionrec::NOT_IN_LIST;
- regTcPtr->logWriteState = TcConnectionrec::NOT_STARTED;
- regTcPtr->fragmentptr = RNIL;
-
- sig0 = lqhKeyReq->fragmentData;
- sig1 = lqhKeyReq->transId1;
- sig2 = lqhKeyReq->transId2;
- sig3 = lqhKeyReq->variableData[0];
- sig4 = lqhKeyReq->variableData[1];
-
- regTcPtr->fragmentid = LqhKeyReq::getFragmentId(sig0);
- regTcPtr->nextReplica = LqhKeyReq::getNextReplicaNodeId(sig0);
- regTcPtr->transid[0] = sig1;
- regTcPtr->transid[1] = sig2;
- regTcPtr->applRef = sig3;
- regTcPtr->applOprec = sig4;
-
- regTcPtr->commitAckMarker = RNIL;
- if(LqhKeyReq::getMarkerFlag(Treqinfo)){
- jam();
-
- CommitAckMarkerPtr markerPtr;
- m_commitAckMarkerHash.seize(markerPtr);
- if(markerPtr.i == RNIL){
- noFreeRecordLab(signal, lqhKeyReq, ZNO_FREE_MARKER_RECORDS_ERROR);
- return;
- }
- markerPtr.p->transid1 = sig1;
- markerPtr.p->transid2 = sig2;
- markerPtr.p->apiRef = sig3;
- markerPtr.p->apiOprec = sig4;
- const NodeId tcNodeId = refToNode(sig5);
- markerPtr.p->tcNodeId = tcNodeId;
-
- CommitAckMarkerPtr tmp;
-#if defined VM_TRACE || defined ERROR_INSERT
-#ifdef MARKER_TRACE
- ndbout_c("Add marker[%.8x %.8x]", markerPtr.p->transid1, markerPtr.p->transid2);
-#endif
- 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->dirtyOp = LqhKeyReq::getDirtyFlag(Treqinfo);
- regTcPtr->opExec = LqhKeyReq::getInterpretedFlag(Treqinfo);
- regTcPtr->opSimple = LqhKeyReq::getSimpleFlag(Treqinfo);
- regTcPtr->seqNoReplica = LqhKeyReq::getSeqNoReplica(Treqinfo);
- UintR TreclenAiLqhkey = LqhKeyReq::getAIInLqhKeyReq(Treqinfo);
- regTcPtr->apiVersionNo = 0;
- regTcPtr->m_use_rowid = LqhKeyReq::getRowidFlag(Treqinfo);
- regTcPtr->m_dealloc = 0;
- if (unlikely(senderVersion < NDBD_ROWID_VERSION))
- {
- regTcPtr->operation = op;
- regTcPtr->lockType = LqhKeyReq::getLockType(Treqinfo);
- }
- else
- {
- regTcPtr->operation = (Operation_t) op == ZREAD_EX ? ZREAD : (Operation_t) op;
- regTcPtr->lockType =
- op == ZREAD_EX ? ZUPDATE : (Operation_t) op == ZWRITE ? ZINSERT : (Operation_t) op;
- }
-
- if (regTcPtr->dirtyOp)
- {
- ndbrequire(regTcPtr->opSimple);
- }
-
- CRASH_INSERTION2(5041, (op == ZREAD &&
- (regTcPtr->opSimple || regTcPtr->dirtyOp) &&
- refToNode(signal->senderBlockRef()) != cownNodeid));
-
- regTcPtr->reclenAiLqhkey = TreclenAiLqhkey;
- regTcPtr->currReclenAi = TreclenAiLqhkey;
- UintR TitcKeyLen = LqhKeyReq::getKeyLen(Treqinfo);
- regTcPtr->primKeyLen = TitcKeyLen;
- regTcPtr->noFiredTriggers = lqhKeyReq->noFiredTriggers;
-
- UintR TapplAddressInd = LqhKeyReq::getApplicationAddressFlag(Treqinfo);
- UintR nextPos = (TapplAddressInd << 1);
- UintR TsameClientAndTcOprec = LqhKeyReq::getSameClientAndTcFlag(Treqinfo);
- if (TsameClientAndTcOprec == 1) {
- regTcPtr->tcOprec = lqhKeyReq->variableData[nextPos];
- nextPos++;
- }//if
- UintR TnextReplicasIndicator = regTcPtr->lastReplicaNo -
- regTcPtr->seqNoReplica;
- if (TnextReplicasIndicator > 1) {
- regTcPtr->nodeAfterNext[0] = lqhKeyReq->variableData[nextPos] & 0xFFFF;
- regTcPtr->nodeAfterNext[1] = lqhKeyReq->variableData[nextPos] >> 16;
- nextPos++;
- }//if
- UintR TstoredProcIndicator = LqhKeyReq::getStoredProcFlag(TtotReclenAi);
- if (TstoredProcIndicator == 1) {
- regTcPtr->storedProcId = lqhKeyReq->variableData[nextPos] & ZNIL;
- nextPos++;
- }//if
- UintR TreadLenAiIndicator = LqhKeyReq::getReturnedReadLenAIFlag(Treqinfo);
- if (TreadLenAiIndicator == 1) {
- regTcPtr->readlenAi = lqhKeyReq->variableData[nextPos] & ZNIL;
- nextPos++;
- }//if
- sig0 = lqhKeyReq->variableData[nextPos + 0];
- sig1 = lqhKeyReq->variableData[nextPos + 1];
- sig2 = lqhKeyReq->variableData[nextPos + 2];
- sig3 = lqhKeyReq->variableData[nextPos + 3];
-
- regTcPtr->tupkeyData[0] = sig0;
- regTcPtr->tupkeyData[1] = sig1;
- regTcPtr->tupkeyData[2] = sig2;
- regTcPtr->tupkeyData[3] = sig3;
-
- if (TitcKeyLen > 0) {
- if (TitcKeyLen < 4) {
- nextPos += TitcKeyLen;
- } else {
- nextPos += 4;
- }//if
- }
- else if (! (LqhKeyReq::getNrCopyFlag(Treqinfo)))
- {
- LQHKEY_error(signal, 3);
- return;
- }//if
-
- sig0 = lqhKeyReq->variableData[nextPos + 0];
- sig1 = lqhKeyReq->variableData[nextPos + 1];
- regTcPtr->m_row_id.m_page_no = sig0;
- regTcPtr->m_row_id.m_page_idx = sig1;
- nextPos += 2 * LqhKeyReq::getRowidFlag(Treqinfo);
-
- sig2 = lqhKeyReq->variableData[nextPos + 0];
- sig3 = cnewestGci;
- regTcPtr->gci = LqhKeyReq::getGCIFlag(Treqinfo) ? sig2 : sig3;
- nextPos += LqhKeyReq::getGCIFlag(Treqinfo);
-
- if (LqhKeyReq::getRowidFlag(Treqinfo))
- {
- ndbassert(refToBlock(senderRef) != DBTC);
- }
- else if(op == ZINSERT)
- {
- ndbassert(refToBlock(senderRef) == DBTC);
- }
-
- if ((LqhKeyReq::FixedSignalLength + nextPos + TreclenAiLqhkey) !=
- signal->length()) {
- LQHKEY_error(signal, 2);
- return;
- }//if
- UintR TseqNoReplica = regTcPtr->seqNoReplica;
- UintR TlastReplicaNo = regTcPtr->lastReplicaNo;
- if (TseqNoReplica == TlastReplicaNo) {
- jam();
- regTcPtr->nextReplica = ZNIL;
- } else {
- if (TseqNoReplica < TlastReplicaNo) {
- jam();
- regTcPtr->nextSeqNoReplica = TseqNoReplica + 1;
- if ((regTcPtr->nextReplica == 0) ||
- (regTcPtr->nextReplica == cownNodeid)) {
- LQHKEY_error(signal, 0);
- }//if
- } else {
- LQHKEY_error(signal, 4);
- return;
- }//if
- }//if
- TcConnectionrecPtr localNextTcConnectptr;
- Uint32 hashIndex = (regTcPtr->transid[0] ^ regTcPtr->tcOprec) & 1023;
- localNextTcConnectptr.i = ctransidHash[hashIndex];
- ctransidHash[hashIndex] = tcConnectptr.i;
- regTcPtr->prevHashRec = RNIL;
- regTcPtr->nextHashRec = localNextTcConnectptr.i;
- if (localNextTcConnectptr.i != RNIL) {
-/* -------------------------------------------------------------------------- */
-/* ENSURE THAT THE NEXT RECORD HAS SET PREVIOUS TO OUR RECORD IF IT EXISTS */
-/* -------------------------------------------------------------------------- */
- ptrCheckGuard(localNextTcConnectptr,
- ctcConnectrecFileSize, tcConnectionrec);
- jam();
- localNextTcConnectptr.p->prevHashRec = tcConnectptr.i;
- }//if
- if (tabptr.i >= ctabrecFileSize) {
- LQHKEY_error(signal, 5);
- return;
- }//if
- ptrAss(tabptr, tablerec);
- if(tabptr.p->tableStatus != Tablerec::TABLE_DEFINED){
- LQHKEY_abort(signal, 4);
- return;
- }
- if(table_version_major(tabptr.p->schemaVersion) !=
- table_version_major(schemaVersion)){
- LQHKEY_abort(signal, 5);
- return;
- }
-
- regTcPtr->tableref = tabptr.i;
- regTcPtr->m_disk_table = tabptr.p->m_disk_table;
- if(refToBlock(signal->senderBlockRef()) == RESTORE)
- regTcPtr->m_disk_table &= !LqhKeyReq::getNoDiskFlag(Treqinfo);
- else if(op == ZREAD || op == ZREAD_EX || op == ZUPDATE)
- regTcPtr->m_disk_table &= !LqhKeyReq::getNoDiskFlag(Treqinfo);
-
- tabptr.p->usageCount++;
-
- if (!getFragmentrec(signal, regTcPtr->fragmentid)) {
- LQHKEY_error(signal, 6);
- return;
- }//if
-
- if (LqhKeyReq::getNrCopyFlag(Treqinfo))
- {
- ndbassert(refToBlock(senderRef) == DBLQH);
- ndbassert(LqhKeyReq::getRowidFlag(Treqinfo));
- if (! (fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION))
- {
- ndbout_c("fragptr.p->fragStatus: %d",
- fragptr.p->fragStatus);
- CRASH_INSERTION(5046);
- }
- ndbassert(fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION);
- fragptr.p->m_copy_started_state = Fragrecord::AC_NR_COPY;
- }
-
- Uint8 TcopyType = fragptr.p->fragCopy;
- Uint32 logPart = fragptr.p->m_log_part_ptr_i;
- tfragDistKey = fragptr.p->fragDistributionKey;
- if (fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION) {
- jam();
- regTcPtr->activeCreat = fragptr.p->m_copy_started_state;
- CRASH_INSERTION(5002);
- CRASH_INSERTION2(5042, tabptr.i == c_error_insert_table_id);
- } else {
- regTcPtr->activeCreat = Fragrecord::AC_NORMAL;
- }//if
- regTcPtr->replicaType = TcopyType;
- regTcPtr->fragmentptr = fragptr.i;
- regTcPtr->m_log_part_ptr_i = logPart;
- Uint8 TdistKey = LqhKeyReq::getDistributionKey(TtotReclenAi);
- if ((tfragDistKey != TdistKey) &&
- (regTcPtr->seqNoReplica == 0) &&
- (regTcPtr->dirtyOp == ZFALSE))
- {
- /* ----------------------------------------------------------------------
- * WE HAVE DIFFERENT OPINION THAN THE DIH THAT STARTED THE TRANSACTION.
- * THE REASON COULD BE THAT THIS IS AN OLD DISTRIBUTION WHICH IS NO LONGER
- * VALID TO USE. THIS MUST BE CHECKED.
- * ONE IS ADDED TO THE DISTRIBUTION KEY EVERY TIME WE ADD A NEW REPLICA.
- * FAILED REPLICAS DO NOT AFFECT THE DISTRIBUTION KEY. THIS MEANS THAT THE
- * MAXIMUM DEVIATION CAN BE ONE BETWEEN THOSE TWO VALUES.
- * --------------------------------------------------------------------- */
- Int32 tmp = TdistKey - tfragDistKey;
- tmp = (tmp < 0 ? - tmp : tmp);
- if ((tmp <= 1) || (tfragDistKey == 0)) {
- LQHKEY_abort(signal, 0);
- return;
- }//if
- LQHKEY_error(signal, 1);
- }//if
- if (TreclenAiLqhkey != 0) {
- if (regTcPtr->operation != ZREAD) {
- if (regTcPtr->operation != ZDELETE) {
- if (regTcPtr->opExec != 1) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* */
-/* UPDATES, WRITES AND INSERTS THAT ARE NOT INTERPRETED WILL USE THE */
-/* SAME ATTRINFO IN ALL REPLICAS. THUS WE SAVE THE ATTRINFO ALREADY */
-/* TO SAVE A SIGNAL FROM TUP TO LQH. INTERPRETED EXECUTION IN TUP */
-/* WILL CREATE NEW ATTRINFO FOR THE OTHER REPLICAS AND IT IS THUS NOT */
-/* A GOOD IDEA TO SAVE THE INFORMATION HERE. READS WILL ALSO BE */
-/* UNNECESSARY TO SAVE SINCE THAT ATTRINFO WILL NEVER BE SENT TO ANY */
-/* MORE REPLICAS. */
-/*---------------------------------------------------------------------------*/
-/* READS AND DELETES CAN ONLY HAVE INFORMATION ABOUT WHAT IS TO BE READ. */
-/* NO INFORMATION THAT NEEDS LOGGING. */
-/*---------------------------------------------------------------------------*/
- sig0 = lqhKeyReq->variableData[nextPos + 0];
- sig1 = lqhKeyReq->variableData[nextPos + 1];
- sig2 = lqhKeyReq->variableData[nextPos + 2];
- sig3 = lqhKeyReq->variableData[nextPos + 3];
- sig4 = lqhKeyReq->variableData[nextPos + 4];
-
- regTcPtr->firstAttrinfo[0] = sig0;
- regTcPtr->firstAttrinfo[1] = sig1;
- regTcPtr->firstAttrinfo[2] = sig2;
- regTcPtr->firstAttrinfo[3] = sig3;
- regTcPtr->firstAttrinfo[4] = sig4;
- regTcPtr->currTupAiLen = TreclenAiLqhkey;
- } else {
- jam();
- regTcPtr->reclenAiLqhkey = 0;
- }//if
- } else {
- jam();
- regTcPtr->reclenAiLqhkey = 0;
- }//if
- }//if
- sig0 = lqhKeyReq->variableData[nextPos + 0];
- sig1 = lqhKeyReq->variableData[nextPos + 1];
- sig2 = lqhKeyReq->variableData[nextPos + 2];
- sig3 = lqhKeyReq->variableData[nextPos + 3];
- sig4 = lqhKeyReq->variableData[nextPos + 4];
-
- c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec,
- lqhKeyReq->variableData+nextPos, TreclenAiLqhkey);
-
- if (signal->theData[0] == (UintR)-1) {
- LQHKEY_abort(signal, 2);
- return;
- }//if
- }//if
-/* ------- TAKE CARE OF PRIM KEY DATA ------- */
- if (regTcPtr->primKeyLen <= 4) {
- endgettupkeyLab(signal);
- return;
- } else {
- jam();
-/*--------------------------------------------------------------------*/
-/* KEY LENGTH WAS MORE THAN 4 WORDS (WORD = 4 BYTE). THUS WE */
-/* HAVE TO ALLOCATE A DATA BUFFER TO STORE THE KEY DATA AND */
-/* WAIT FOR THE KEYINFO SIGNAL. */
-/*--------------------------------------------------------------------*/
- regTcPtr->save1 = 4;
- regTcPtr->transactionState = TcConnectionrec::WAIT_TUPKEYINFO;
- return;
- }//if
- return;
-}//Dblqh::execLQHKEYREQ()
-
-void Dblqh::endgettupkeyLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->totReclenAi == regTcPtr->currReclenAi) {
- ;
- } else {
- jam();
- ndbrequire(regTcPtr->currReclenAi < regTcPtr->totReclenAi);
- regTcPtr->transactionState = TcConnectionrec::WAIT_ATTR;
- return;
- }//if
-
-/* ---------------------------------------------------------------------- */
-/* NOW RECEPTION OF LQHKEYREQ IS COMPLETED THE NEXT STEP IS TO START*/
-/* PROCESSING THE MESSAGE. IF THE MESSAGE IS TO A STAND-BY NODE */
-/* WITHOUT NETWORK REDUNDANCY OR PREPARE-TO-COMMIT ACTIVATED THE */
-/* PREPARATION TO SEND TO THE NEXT NODE WILL START IMMEDIATELY. */
-/* */
-/* OTHERWISE THE PROCESSING WILL START AFTER SETTING THE PROPER */
-/* STATE. HOWEVER BEFORE PROCESSING THE MESSAGE */
-/* IT IS NECESSARY TO CHECK THAT THE FRAGMENT IS NOT PERFORMING */
-/* A CHECKPOINT. THE OPERATION SHALL ALSO BE LINKED INTO THE */
-/* FRAGMENT QUEUE OR LIST OF ACTIVE OPERATIONS. */
-/* */
-/* THE FIRST STEP IN PROCESSING THE MESSAGE IS TO CONTACT DBACC. */
-/*------------------------------------------------------------------------*/
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- case Fragrecord::CRASH_RECOVERING:
- case Fragrecord::ACTIVE_CREATION:
- prepareContinueAfterBlockedLab(signal);
- return;
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- regTcPtr->transactionState = TcConnectionrec::STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dblqh::endgettupkeyLab()
-
-void Dblqh::prepareContinueAfterBlockedLab(Signal* signal)
-{
- UintR ttcScanOp;
-
-/* -------------------------------------------------------------------------- */
-/* INPUT: TC_CONNECTPTR ACTIVE CONNECTION RECORD */
-/* FRAGPTR FRAGMENT RECORD */
-/* -------------------------------------------------------------------------- */
-/* -------------------------------------------------------------------------- */
-/* CONTINUE HERE AFTER BEING BLOCKED FOR A WHILE DURING LOCAL CHECKPOINT. */
-/* -------------------------------------------------------------------------- */
-/* ALSO AFTER NORMAL PROCEDURE WE CONTINUE HERE */
-/* -------------------------------------------------------------------------- */
- Uint32 tc_ptr_i = tcConnectptr.i;
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 activeCreat = regTcPtr->activeCreat;
- if (regTcPtr->indTakeOver == ZTRUE) {
- jam();
- ttcScanOp = KeyInfo20::getScanOp(regTcPtr->tcScanInfo);
- scanptr.i = RNIL;
- {
- ScanRecord key;
- key.scanNumber = KeyInfo20::getScanNo(regTcPtr->tcScanInfo);
- key.fragPtrI = fragptr.i;
- c_scanTakeOverHash.find(scanptr, key);
-#ifdef TRACE_SCAN_TAKEOVER
- if(scanptr.i == RNIL)
- ndbout_c("not finding (%d %d)", key.scanNumber, key.fragPtrI);
-#endif
- }
- if (scanptr.i == RNIL) {
- jam();
- takeOverErrorLab(signal);
- return;
- }//if
- Uint32 accOpPtr= get_acc_ptr_from_scan_record(scanptr.p,
- ttcScanOp,
- true);
- if (accOpPtr == RNIL) {
- jam();
- takeOverErrorLab(signal);
- return;
- }//if
- signal->theData[1] = accOpPtr;
- signal->theData[2] = regTcPtr->transid[0];
- signal->theData[3] = regTcPtr->transid[1];
- EXECUTE_DIRECT(refToBlock(regTcPtr->tcAccBlockref), GSN_ACC_TO_REQ,
- signal, 4);
- if (signal->theData[0] == (UintR)-1) {
- execACC_TO_REF(signal);
- return;
- }//if
- jamEntry();
- }//if
-/*-------------------------------------------------------------------*/
-/* IT IS NOW TIME TO CONTACT ACC. THE TUPLE KEY WILL BE SENT */
-/* AND THIS WILL BE TRANSLATED INTO A LOCAL KEY BY USING THE */
-/* LOCAL PART OF THE LH3-ALGORITHM. ALSO PROPER LOCKS ON THE */
-/* TUPLE WILL BE SET. FOR INSERTS AND DELETES THE MESSAGE WILL */
-/* START AN INSERT/DELETE INTO THE HASH TABLE. */
-/* */
-/* BEFORE SENDING THE MESSAGE THE REQUEST INFORMATION IS SET */
-/* PROPERLY. */
-/* ----------------------------------------------------------------- */
- if (TRACENR_FLAG)
- {
- TRACE_OP(regTcPtr, "RECEIVED");
- switch (regTcPtr->operation) {
- case ZREAD: TRACENR("READ"); break;
- case ZUPDATE: TRACENR("UPDATE"); break;
- case ZWRITE: TRACENR("WRITE"); break;
- case ZINSERT: TRACENR("INSERT"); break;
- case ZDELETE: TRACENR("DELETE"); break;
- default: TRACENR("<Unknown: " << regTcPtr->operation << ">"); break;
- }
-
- TRACENR(" tab: " << regTcPtr->tableref
- << " frag: " << regTcPtr->fragmentid
- << " activeCreat: " << (Uint32)activeCreat);
- if (LqhKeyReq::getNrCopyFlag(regTcPtr->reqinfo))
- TRACENR(" NrCopy");
- if (LqhKeyReq::getRowidFlag(regTcPtr->reqinfo))
- TRACENR(" rowid: " << regTcPtr->m_row_id);
- TRACENR(" key: " << regTcPtr->tupkeyData[0]);
- }
-
- if (likely(activeCreat == Fragrecord::AC_NORMAL))
- {
- if (TRACENR_FLAG)
- TRACENR(endl);
- ndbassert(!LqhKeyReq::getNrCopyFlag(regTcPtr->reqinfo));
- exec_acckeyreq(signal, tcConnectptr);
- }
- else if (activeCreat == Fragrecord::AC_NR_COPY)
- {
- regTcPtr->totSendlenAi = regTcPtr->totReclenAi;
- handle_nr_copy(signal, tcConnectptr);
- }
- else
- {
- ndbassert(activeCreat == Fragrecord::AC_IGNORED);
- if (TRACENR_FLAG)
- TRACENR(" IGNORING (activeCreat == 2)" << endl);
-
- signal->theData[0] = tc_ptr_i;
- regTcPtr->transactionState = TcConnectionrec::WAIT_ACC_ABORT;
-
- signal->theData[0] = regTcPtr->tupConnectrec;
- EXECUTE_DIRECT(DBTUP, GSN_TUP_ABORTREQ, signal, 1);
- jamEntry();
-
- regTcPtr->totSendlenAi = regTcPtr->totReclenAi;
- packLqhkeyreqLab(signal);
- }
-}
-
-void
-Dblqh::exec_acckeyreq(Signal* signal, TcConnectionrecPtr regTcPtr)
-{
- Uint32 taccreq;
- regTcPtr.p->transactionState = TcConnectionrec::WAIT_ACC;
- taccreq = regTcPtr.p->operation;
- taccreq = taccreq + (regTcPtr.p->opSimple << 3);
- taccreq = taccreq + (regTcPtr.p->lockType << 4);
- taccreq = taccreq + (regTcPtr.p->dirtyOp << 6);
- taccreq = taccreq + (regTcPtr.p->replicaType << 7);
- taccreq = taccreq + (regTcPtr.p->apiVersionNo << 9);
-/* ************ */
-/* ACCKEYREQ < */
-/* ************ */
- Uint32 sig0, sig1, sig2, sig3, sig4;
- sig0 = regTcPtr.p->accConnectrec;
- sig1 = fragptr.p->accFragptr;
- sig2 = regTcPtr.p->hashValue;
- sig3 = regTcPtr.p->primKeyLen;
- sig4 = regTcPtr.p->transid[0];
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->theData[2] = taccreq;
- signal->theData[3] = sig2;
- signal->theData[4] = sig3;
- signal->theData[5] = sig4;
-
- sig0 = regTcPtr.p->transid[1];
- sig1 = regTcPtr.p->tupkeyData[0];
- sig2 = regTcPtr.p->tupkeyData[1];
- sig3 = regTcPtr.p->tupkeyData[2];
- sig4 = regTcPtr.p->tupkeyData[3];
- signal->theData[6] = sig0;
- signal->theData[7] = sig1;
- signal->theData[8] = sig2;
- signal->theData[9] = sig3;
- signal->theData[10] = sig4;
-
- TRACE_OP(regTcPtr.p, "ACC");
-
- if (regTcPtr.p->primKeyLen > 4) {
- sendKeyinfoAcc(signal, 11);
- }//if
- EXECUTE_DIRECT(refToBlock(regTcPtr.p->tcAccBlockref), GSN_ACCKEYREQ,
- signal, 7 + regTcPtr.p->primKeyLen);
- if (signal->theData[0] < RNIL) {
- signal->theData[0] = regTcPtr.i;
- execACCKEYCONF(signal);
- return;
- } else if (signal->theData[0] == RNIL) {
- ;
- } else {
- ndbrequire(signal->theData[0] == (UintR)-1);
- signal->theData[0] = regTcPtr.i;
- execACCKEYREF(signal);
- }//if
- return;
-}//Dblqh::prepareContinueAfterBlockedLab()
-
-void
-Dblqh::handle_nr_copy(Signal* signal, Ptr<TcConnectionrec> regTcPtr)
-{
- jam();
- Uint32 fragPtr = fragptr.p->tupFragptr;
- Uint32 op = regTcPtr.p->operation;
-
- const bool copy = LqhKeyReq::getNrCopyFlag(regTcPtr.p->reqinfo);
-
- if (!LqhKeyReq::getRowidFlag(regTcPtr.p->reqinfo))
- {
- /**
- * Rowid not set, that mean that primary has finished copying...
- */
- jam();
- if (TRACENR_FLAG)
- TRACENR(" Waiting for COPY_ACTIVEREQ" << endl);
- ndbassert(!LqhKeyReq::getNrCopyFlag(regTcPtr.p->reqinfo));
- regTcPtr.p->activeCreat = Fragrecord::AC_NORMAL;
- exec_acckeyreq(signal, regTcPtr);
- return;
- }
-
- regTcPtr.p->m_nr_delete.m_cnt = 1; // Wait for real op aswell
- Uint32* dst = signal->theData+24;
- bool uncommitted;
- const int len = c_tup->nr_read_pk(fragPtr, &regTcPtr.p->m_row_id, dst,
- uncommitted);
- const bool match = (len>0) ? compare_key(regTcPtr.p, dst, len) == 0 : false;
-
- if (TRACENR_FLAG)
- TRACENR(" len: " << len << " match: " << match
- << " uncommitted: " << uncommitted);
-
- if (copy)
- {
- ndbassert(LqhKeyReq::getGCIFlag(regTcPtr.p->reqinfo));
- if (match)
- {
- /**
- * Case 1
- */
- jam();
- ndbassert(op == ZINSERT);
- if (TRACENR_FLAG)
- TRACENR(" Changing from INSERT to ZUPDATE" << endl);
- regTcPtr.p->operation = ZUPDATE;
- goto run;
- }
- else if (len > 0 && op == ZDELETE)
- {
- /**
- * Case 4
- * Perform delete using rowid
- * primKeyLen == 0
- * tupkeyData[0] == rowid
- */
- jam();
- ndbassert(regTcPtr.p->primKeyLen == 0);
- if (TRACENR_FLAG)
- TRACENR(" performing DELETE key: "
- << dst[0] << endl);
-
- nr_copy_delete_row(signal, regTcPtr, &regTcPtr.p->m_row_id, len);
- ndbassert(regTcPtr.p->m_nr_delete.m_cnt);
- regTcPtr.p->m_nr_delete.m_cnt--; // No real op is run
- if (regTcPtr.p->m_nr_delete.m_cnt)
- {
- jam();
- return;
- }
- packLqhkeyreqLab(signal);
- return;
- }
- else if (len == 0 && op == ZDELETE)
- {
- /**
- * Case 7
- */
- jam();
- if (TRACENR_FLAG)
- TRACENR(" UPDATE_GCI" << endl);
- c_tup->nr_update_gci(fragPtr, &regTcPtr.p->m_row_id, regTcPtr.p->gci);
- goto update_gci_ignore;
- }
-
- /**
- * 1) Delete row at specified rowid (if len > 0)
- * 2) Delete specified row at different rowid (if exists)
- * 3) Run insert
- */
- if (len > 0)
- {
- /**
- * 1) Delete row at specified rowid (if len > 0)
- */
- jam();
- nr_copy_delete_row(signal, regTcPtr, &regTcPtr.p->m_row_id, len);
- }
- /**
- * 2) Delete specified row at different rowid (if exists)
- */
- jam();
- nr_copy_delete_row(signal, regTcPtr, 0, 0);
- if (TRACENR_FLAG)
- TRACENR(" RUN INSERT" << endl);
- goto run;
- }
- else
- {
- if (!match && op != ZINSERT)
- {
- jam();
- if (TRACENR_FLAG)
- TRACENR(" IGNORE " << endl);
- goto ignore;
- }
- if (match)
- {
- jam();
- if (op != ZDELETE)
- {
- if (TRACENR_FLAG)
- TRACENR(" Changing from to ZWRITE" << endl);
- regTcPtr.p->operation = ZWRITE;
- }
- goto run;
- }
-
- /**
- * 1) Delete row at specified rowid (if len > 0)
- * 2) Delete specified row at different rowid (if exists)
- * 3) Run insert
- */
- if (len > 0)
- {
- /**
- * 1) Delete row at specified rowid (if len > 0)
- */
- jam();
- nr_copy_delete_row(signal, regTcPtr, &regTcPtr.p->m_row_id, len);
- }
-
- /**
- * 2) Delete specified row at different rowid (if exists)
- */
- jam();
- nr_copy_delete_row(signal, regTcPtr, 0, 0);
- if (TRACENR_FLAG)
- TRACENR(" RUN op: " << op << endl);
- goto run;
- }
-
-run:
- jam();
- exec_acckeyreq(signal, regTcPtr);
- return;
-
-ignore:
- jam();
- ndbassert(!LqhKeyReq::getNrCopyFlag(regTcPtr.p->reqinfo));
-update_gci_ignore:
- regTcPtr.p->activeCreat = Fragrecord::AC_IGNORED;
- signal->theData[0] = regTcPtr.p->tupConnectrec;
- EXECUTE_DIRECT(DBTUP, GSN_TUP_ABORTREQ, signal, 1);
-
- packLqhkeyreqLab(signal);
-}
-
-int
-Dblqh::compare_key(const TcConnectionrec* regTcPtr,
- const Uint32 * ptr, Uint32 len)
-{
- if (regTcPtr->primKeyLen != len)
- return 1;
-
- if (len <= 4)
- return memcmp(ptr, regTcPtr->tupkeyData, 4*len);
-
- if (memcmp(ptr, regTcPtr->tupkeyData, sizeof(regTcPtr->tupkeyData)))
- return 1;
-
- len -= (sizeof(regTcPtr->tupkeyData) >> 2);
- ptr += (sizeof(regTcPtr->tupkeyData) >> 2);
-
- DatabufPtr regDatabufptr;
- regDatabufptr.i = tcConnectptr.p->firstTupkeybuf;
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- while(len > 4)
- {
- if (memcmp(ptr, regDatabufptr.p, 4*4))
- return 1;
-
- ptr += 4;
- len -= 4;
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- }
-
- if (memcmp(ptr, regDatabufptr.p, 4*len))
- return 1;
-
- return 0;
-}
-
-void
-Dblqh::nr_copy_delete_row(Signal* signal,
- Ptr<TcConnectionrec> regTcPtr,
- Local_key* rowid, Uint32 len)
-{
- Ptr<Fragrecord> fragPtr = fragptr;
-
- Uint32 keylen;
- Uint32 tableId = regTcPtr.p->tableref;
- Uint32 accPtr = regTcPtr.p->accConnectrec;
-
- signal->theData[0] = accPtr;
- signal->theData[1] = fragptr.p->accFragptr;
- signal->theData[2] = ZDELETE + (ZDELETE << 4);
- signal->theData[5] = regTcPtr.p->transid[0];
- signal->theData[6] = regTcPtr.p->transid[1];
-
- if (rowid)
- {
- jam();
- keylen = 1;
- if (g_key_descriptor_pool.getPtr(tableId)->hasCharAttr)
- {
- signal->theData[3] = calculateHash(tableId, signal->theData+24);
- }
- else
- {
- signal->theData[3] = md5_hash((Uint64*)(signal->theData+24), len);
- }
- signal->theData[4] = 0; // seach by local key
- signal->theData[7] = rowid->ref();
- }
- else
- {
- jam();
- keylen = regTcPtr.p->primKeyLen;
- signal->theData[3] = regTcPtr.p->hashValue;
- signal->theData[4] = keylen;
- signal->theData[7] = regTcPtr.p->tupkeyData[0];
- signal->theData[8] = regTcPtr.p->tupkeyData[1];
- signal->theData[9] = regTcPtr.p->tupkeyData[2];
- signal->theData[10] = regTcPtr.p->tupkeyData[3];
- if (keylen > 4)
- sendKeyinfoAcc(signal, 11);
- }
- const Uint32 ref = refToBlock(regTcPtr.p->tcAccBlockref);
- EXECUTE_DIRECT(ref, GSN_ACCKEYREQ, signal, 7 + keylen);
- jamEntry();
-
- Uint32 retValue = signal->theData[0];
- ndbrequire(retValue != RNIL); // This should never block...
- ndbrequire(retValue != (Uint32)-1 || rowid == 0); // rowid should never fail
-
- if (retValue == (Uint32)-1)
- {
- /**
- * Only delete by pk, may fail
- */
- jam();
- ndbrequire(rowid == 0);
- signal->theData[0] = accPtr;
- signal->theData[1] = 0;
- EXECUTE_DIRECT(ref, GSN_ACC_ABORTREQ, signal, 2);
- jamEntry();
- return;
- }
-
- /**
- * We found row (and have it locked in ACC)
- */
- ndbrequire(regTcPtr.p->m_dealloc == 0);
- Local_key save = regTcPtr.p->m_row_id;
-
- c_acc->execACCKEY_ORD(signal, accPtr);
- signal->theData[0] = accPtr;
- EXECUTE_DIRECT(ref, GSN_ACC_COMMITREQ, signal, 1);
- jamEntry();
-
- ndbrequire(regTcPtr.p->m_dealloc == 1);
- int ret = c_tup->nr_delete(signal, regTcPtr.i,
- fragPtr.p->tupFragptr, &regTcPtr.p->m_row_id,
- regTcPtr.p->gci);
- jamEntry();
-
- if (ret)
- {
- ndbassert(ret == 1);
- Uint32 pos = regTcPtr.p->m_nr_delete.m_cnt - 1;
- memcpy(regTcPtr.p->m_nr_delete.m_disk_ref + pos,
- signal->theData, sizeof(Local_key));
- regTcPtr.p->m_nr_delete.m_page_id[pos] = RNIL;
- regTcPtr.p->m_nr_delete.m_cnt = pos + 2;
- if (0) ndbout << "PENDING DISK DELETE: " <<
- regTcPtr.p->m_nr_delete.m_disk_ref[pos] << endl;
- }
-
- TRACENR("DELETED: " << regTcPtr.p->m_row_id << endl);
-
- regTcPtr.p->m_dealloc = 0;
- regTcPtr.p->m_row_id = save;
- fragptr = fragPtr;
- tcConnectptr = regTcPtr;
-}
-
-void
-Dblqh::get_nr_op_info(Nr_op_info* op, Uint32 page_id)
-{
- Ptr<TcConnectionrec> tcPtr;
- tcPtr.i = op->m_ptr_i;
- ptrCheckGuard(tcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- Ptr<Fragrecord> fragPtr;
- c_fragment_pool.getPtr(fragPtr, tcPtr.p->fragmentptr);
-
- op->m_gci = tcPtr.p->gci;
- op->m_tup_frag_ptr_i = fragPtr.p->tupFragptr;
-
- ndbrequire(tcPtr.p->activeCreat == Fragrecord::AC_NR_COPY);
- ndbrequire(tcPtr.p->m_nr_delete.m_cnt);
-
-
- if (page_id == RNIL)
- {
- // get log buffer callback
- for (Uint32 i = 0; i<2; i++)
- {
- if (tcPtr.p->m_nr_delete.m_page_id[i] != RNIL)
- {
- op->m_page_id = tcPtr.p->m_nr_delete.m_page_id[i];
- op->m_disk_ref = tcPtr.p->m_nr_delete.m_disk_ref[i];
- return;
- }
- }
- }
- else
- {
- // get page callback
- for (Uint32 i = 0; i<2; i++)
- {
- Local_key key = tcPtr.p->m_nr_delete.m_disk_ref[i];
- if (op->m_disk_ref.m_page_no == key.m_page_no &&
- op->m_disk_ref.m_file_no == key.m_file_no &&
- tcPtr.p->m_nr_delete.m_page_id[i] == RNIL)
- {
- op->m_disk_ref = key;
- tcPtr.p->m_nr_delete.m_page_id[i] = page_id;
- return;
- }
- }
- }
- ndbrequire(false);
-}
-
-void
-Dblqh::nr_delete_complete(Signal* signal, Nr_op_info* op)
-{
- jamEntry();
- Ptr<TcConnectionrec> tcPtr;
- tcPtr.i = op->m_ptr_i;
- ptrCheckGuard(tcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- ndbrequire(tcPtr.p->activeCreat == Fragrecord::AC_NR_COPY);
- ndbrequire(tcPtr.p->m_nr_delete.m_cnt);
-
- tcPtr.p->m_nr_delete.m_cnt--;
- if (tcPtr.p->m_nr_delete.m_cnt == 0)
- {
- jam();
- tcConnectptr = tcPtr;
- c_fragment_pool.getPtr(fragptr, tcPtr.p->fragmentptr);
-
- if (tcPtr.p->abortState != TcConnectionrec::ABORT_IDLE)
- {
- jam();
- tcPtr.p->activeCreat = Fragrecord::AC_NORMAL;
- abortCommonLab(signal);
- }
- else if (tcPtr.p->operation == ZDELETE &&
- LqhKeyReq::getNrCopyFlag(tcPtr.p->reqinfo))
- {
- /**
- * This is run directly in handle_nr_copy
- */
- jam();
- packLqhkeyreqLab(signal);
- }
- else
- {
- jam();
- rwConcludedLab(signal);
- }
- return;
- }
-
- if (memcmp(&tcPtr.p->m_nr_delete.m_disk_ref[0],
- &op->m_disk_ref, sizeof(Local_key)) == 0)
- {
- jam();
- ndbassert(tcPtr.p->m_nr_delete.m_page_id[0] != RNIL);
- tcPtr.p->m_nr_delete.m_page_id[0] = tcPtr.p->m_nr_delete.m_page_id[1];
- tcPtr.p->m_nr_delete.m_disk_ref[0] = tcPtr.p->m_nr_delete.m_disk_ref[1];
- }
-}
-
-Uint32
-Dblqh::readPrimaryKeys(Uint32 opPtrI, Uint32 * dst, bool xfrm)
-{
- TcConnectionrecPtr regTcPtr;
- DatabufPtr regDatabufptr;
- Uint64 Tmp[MAX_KEY_SIZE_IN_WORDS >> 1];
-
- jamEntry();
- regTcPtr.i = opPtrI;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- Uint32 tableId = regTcPtr.p->tableref;
- Uint32 keyLen = regTcPtr.p->primKeyLen;
- regDatabufptr.i = regTcPtr.p->firstTupkeybuf;
- Uint32 * tmp = xfrm ? (Uint32*)Tmp : dst;
-
- memcpy(tmp, regTcPtr.p->tupkeyData, sizeof(regTcPtr.p->tupkeyData));
- if (keyLen > 4)
- {
- tmp += 4;
- Uint32 pos = 4;
- do {
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- memcpy(tmp, regDatabufptr.p->data, sizeof(regDatabufptr.p->data));
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
- tmp += sizeof(regDatabufptr.p->data) >> 2;
- pos += sizeof(regDatabufptr.p->data) >> 2;
- } while(pos < keyLen);
- }
-
- if (xfrm)
- {
- jam();
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
- return xfrm_key(tableId, (Uint32*)Tmp, dst, ~0, keyPartLen);
- }
-
- return keyLen;
-}
-
-/* =*======================================================================= */
-/* ======= SEND KEYINFO TO ACC ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::sendKeyinfoAcc(Signal* signal, Uint32 Ti)
-{
- DatabufPtr regDatabufptr;
- regDatabufptr.i = tcConnectptr.p->firstTupkeybuf;
-
- do {
- jam();
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- Uint32 sig0 = regDatabufptr.p->data[0];
- Uint32 sig1 = regDatabufptr.p->data[1];
- Uint32 sig2 = regDatabufptr.p->data[2];
- Uint32 sig3 = regDatabufptr.p->data[3];
- signal->theData[Ti] = sig0;
- signal->theData[Ti + 1] = sig1;
- signal->theData[Ti + 2] = sig2;
- signal->theData[Ti + 3] = sig3;
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
- Ti += 4;
- } while (regDatabufptr.i != RNIL);
-}//Dblqh::sendKeyinfoAcc()
-
-void Dblqh::execLQH_ALLOCREQ(Signal* signal)
-{
- TcConnectionrecPtr regTcPtr;
- FragrecordPtr regFragptr;
-
- jamEntry();
- regTcPtr.i = signal->theData[0];
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- regFragptr.i = regTcPtr.p->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
-
- signal->theData[0] = regTcPtr.p->tupConnectrec;
- signal->theData[1] = regFragptr.p->tupFragptr;
- signal->theData[2] = regTcPtr.p->tableref;
- Uint32 tup = refToBlock(regTcPtr.p->tcTupBlockref);
- EXECUTE_DIRECT(tup, GSN_TUP_ALLOCREQ, signal, 3);
-}//Dblqh::execTUP_ALLOCREQ()
-
-void Dblqh::execTUP_DEALLOCREQ(Signal* signal)
-{
- TcConnectionrecPtr regTcPtr;
-
- jamEntry();
- regTcPtr.i = signal->theData[4];
-
- if (TRACENR_FLAG)
- {
- Local_key tmp;
- tmp.m_page_no = signal->theData[2];
- tmp.m_page_idx = signal->theData[3];
- TRACENR("TUP_DEALLOC: " << tmp <<
- (signal->theData[5] ? " DIRECT " : " DELAYED") << endl);
- }
-
- if (signal->theData[5])
- {
- jam();
- Local_key tmp;
- tmp.m_page_no = signal->theData[2];
- tmp.m_page_idx = signal->theData[3];
- EXECUTE_DIRECT(DBTUP, GSN_TUP_DEALLOCREQ, signal, signal->getLength());
- return;
- }
- else
- {
- jam();
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
- regTcPtr.p->m_row_id.m_page_no = signal->theData[2];
- regTcPtr.p->m_row_id.m_page_idx = signal->theData[3];
-
- ndbrequire(regTcPtr.p->m_dealloc == 0);
- regTcPtr.p->m_dealloc = 1;
- }
-}//Dblqh::execTUP_ALLOCREQ()
-
-/* ************>> */
-/* ACCKEYCONF > */
-/* ************>> */
-void Dblqh::execACCKEYCONF(Signal* signal)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- Uint32 tcIndex = signal->theData[0];
- Uint32 localKey1 = signal->theData[3];
- //Uint32 localKey2 = signal->theData[4];
- Uint32 localKeyFlag = signal->theData[5];
- jamEntry();
- tcConnectptr.i = tcIndex;
- ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->transactionState != TcConnectionrec::WAIT_ACC) {
- LQHKEY_abort(signal, 3);
- return;
- }//if
-
- /* ------------------------------------------------------------------------
- * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
- * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
- * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA
- * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
- * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
- * TABLE.
- * ----------------------------------------------------------------------- */
- if (regTcPtr->operation == ZWRITE)
- {
- ndbassert(regTcPtr->seqNoReplica == 0 ||
- regTcPtr->activeCreat == Fragrecord::AC_NR_COPY);
- Uint32 op= signal->theData[1];
- Uint32 requestInfo = regTcPtr->reqinfo;
- if(likely(op == ZINSERT || op == ZUPDATE))
- {
- jam();
- regTcPtr->operation = op;
- }
- else
- {
- jam();
- warningEvent("Convering %d to ZUPDATE", op);
- op = regTcPtr->operation = ZUPDATE;
- }
- if (regTcPtr->seqNoReplica == 0)
- {
- jam();
- requestInfo &= ~(RI_OPERATION_MASK << RI_OPERATION_SHIFT);
- LqhKeyReq::setOperation(requestInfo, op);
- regTcPtr->reqinfo = requestInfo;
- }
- }//if
-
- /* ------------------------------------------------------------------------
- * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
- * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
- * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA
- * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
- * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
- * TABLE.
- * ----------------------------------------------------------------------- */
- FragrecordPtr regFragptr;
- regFragptr.i = regTcPtr->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
-
- ndbrequire(localKeyFlag == 1);
- if(!regTcPtr->m_disk_table)
- acckeyconf_tupkeyreq(signal, regTcPtr, regFragptr.p, localKey1, RNIL);
- else
- acckeyconf_load_diskpage(signal, tcConnectptr, regFragptr.p, localKey1);
-}
-
-void
-Dblqh::acckeyconf_tupkeyreq(Signal* signal, TcConnectionrec* regTcPtr,
- Fragrecord* regFragptrP,
- Uint32 local_key,
- Uint32 disk_page)
-{
- Uint32 op = regTcPtr->operation;
- regTcPtr->transactionState = TcConnectionrec::WAIT_TUP;
- /* ------------------------------------------------------------------------
- * IT IS NOW TIME TO CONTACT THE TUPLE MANAGER. THE TUPLE MANAGER NEEDS THE
- * INFORMATION ON WHICH TABLE AND FRAGMENT, THE LOCAL KEY AND IT NEEDS TO
- * KNOW THE TYPE OF OPERATION TO PERFORM. TUP CAN SEND THE ATTRINFO DATA
- * EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
- * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
- * TABLE.
- * ----------------------------------------------------------------------- */
- Uint32 page_idx = local_key & MAX_TUPLES_PER_PAGE;
- Uint32 page_no = local_key >> MAX_TUPLES_BITS;
- Uint32 Ttupreq = regTcPtr->dirtyOp;
- Ttupreq = Ttupreq + (regTcPtr->opSimple << 1);
- Ttupreq = Ttupreq + (op << 6);
- Ttupreq = Ttupreq + (regTcPtr->opExec << 10);
- Ttupreq = Ttupreq + (regTcPtr->apiVersionNo << 11);
- Ttupreq = Ttupreq + (regTcPtr->m_use_rowid << 11);
-
- /* ---------------------------------------------------------------------
- * Clear interpreted mode bit since we do not want the next replica to
- * use interpreted mode. The next replica will receive a normal write.
- * --------------------------------------------------------------------- */
- regTcPtr->opExec = 0;
- /* ************< */
- /* TUPKEYREQ < */
- /* ************< */
- Uint32 sig0, sig1, sig2, sig3;
- sig0 = regTcPtr->tupConnectrec;
-
- TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
- tupKeyReq->connectPtr = sig0;
- tupKeyReq->request = Ttupreq;
- tupKeyReq->keyRef1 = page_no;
- tupKeyReq->keyRef2 = page_idx;
-
- sig0 = regTcPtr->totReclenAi;
- sig1 = regTcPtr->applOprec;
- sig2 = regTcPtr->applRef;
-
- tupKeyReq->attrBufLen = sig0;
- tupKeyReq->opRef = sig1;
- tupKeyReq->applRef = sig2;
-
- sig0 = regTcPtr->storedProcId;
- sig1 = regTcPtr->transid[0];
- sig2 = regTcPtr->transid[1];
- sig3 = regFragptrP->tupFragptr;
- Uint32 tup = refToBlock(regTcPtr->tcTupBlockref);
-
- tupKeyReq->storedProcedure = sig0;
- tupKeyReq->transId1 = sig1;
- tupKeyReq->transId2 = sig2;
- tupKeyReq->fragPtr = sig3;
-
- sig0 = regTcPtr->m_row_id.m_page_no;
- sig1 = regTcPtr->m_row_id.m_page_idx;
-
- tupKeyReq->primaryReplica = (tcConnectptr.p->seqNoReplica == 0)?true:false;
- tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
- tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
- tupKeyReq->savePointId = tcConnectptr.p->savePointId;
- tupKeyReq->disk_page= disk_page;
-
- tupKeyReq->m_row_id_page_no = sig0;
- tupKeyReq->m_row_id_page_idx = sig1;
-
- TRACE_OP(regTcPtr, "TUPKEYREQ");
-
- regTcPtr->m_use_rowid |= (op == ZINSERT);
- regTcPtr->m_row_id.m_page_no = page_no;
- regTcPtr->m_row_id.m_page_idx = page_idx;
-
- EXECUTE_DIRECT(tup, GSN_TUPKEYREQ, signal, TupKeyReq::SignalLength);
-}//Dblqh::execACCKEYCONF()
-
-void
-Dblqh::acckeyconf_load_diskpage(Signal* signal, TcConnectionrecPtr regTcPtr,
- Fragrecord* regFragptrP, Uint32 local_key)
-{
- int res;
- if((res= c_tup->load_diskpage(signal,
- regTcPtr.p->tupConnectrec,
- regFragptrP->tupFragptr,
- local_key,
- regTcPtr.p->operation)) > 0)
- {
- acckeyconf_tupkeyreq(signal, regTcPtr.p, regFragptrP, local_key, res);
- }
- else if(res == 0)
- {
- regTcPtr.p->transactionState = TcConnectionrec::WAIT_TUP;
- regTcPtr.p->m_row_id.assref(local_key);
- }
- else
- {
- regTcPtr.p->transactionState = TcConnectionrec::WAIT_TUP;
- TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
- ref->userRef= regTcPtr.i;
- ref->errorCode= ~0;
- execTUPKEYREF(signal);
- }
-}
-
-void
-Dblqh::acckeyconf_load_diskpage_callback(Signal* signal,
- Uint32 callbackData,
- Uint32 disk_page)
-{
- jamEntry();
- tcConnectptr.i = callbackData;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
-
- TcConnectionrec::TransactionState state = regTcPtr->transactionState;
- if (likely(disk_page > 0 && state == TcConnectionrec::WAIT_TUP))
- {
- FragrecordPtr fragPtr;
- c_fragment_pool.getPtr(fragPtr, regTcPtr->fragmentptr);
-
- acckeyconf_tupkeyreq(signal, regTcPtr, fragPtr.p,
- regTcPtr->m_row_id.ref(),
- disk_page);
- }
- else if (state != TcConnectionrec::WAIT_TUP)
- {
- ndbrequire(state == TcConnectionrec::WAIT_TUP_TO_ABORT);
- abortCommonLab(signal);
- return;
- }
- else
- {
- regTcPtr->transactionState = TcConnectionrec::WAIT_TUP;
- TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
- ref->userRef= callbackData;
- ref->errorCode= disk_page;
- execTUPKEYREF(signal);
- }
-}
-
-/* --------------------------------------------------------------------------
- * ------- ENTER TUP... -------
- * ENTER TUPKEYCONF WITH
- * TC_CONNECTPTR,
- * TDATA2, LOCAL KEY REFERENCE 1, ONLY INTERESTING AFTER INSERT
- * TDATA3, LOCAL KEY REFERENCE 1, ONLY INTERESTING AFTER INSERT
- * TDATA4, TOTAL LENGTH OF READ DATA SENT TO TC/APPLICATION
- * TDATA5 TOTAL LENGTH OF UPDATE DATA SENT TO/FROM TUP
- * GOTO TUPKEY_CONF
- *
- * TAKE CARE OF RESPONSES FROM TUPLE MANAGER.
- * -------------------------------------------------------------------------- */
-void Dblqh::tupkeyConfLab(Signal* signal)
-{
-/* ---- GET OPERATION TYPE AND CHECK WHAT KIND OF OPERATION IS REQUESTED --- */
- const TupKeyConf * const tupKeyConf = (TupKeyConf *)&signal->theData[0];
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 activeCreat = regTcPtr->activeCreat;
- Uint32 readLen = tupKeyConf->readLength;
- Uint32 writeLen = tupKeyConf->writeLength;
-
- Uint32 accOp = regTcPtr->accConnectrec;
- c_acc->execACCKEY_ORD(signal, accOp);
-
- TRACE_OP(regTcPtr, "TUPKEYCONF");
-
- if (readLen != 0)
- {
- jam();
-
- /* SET BIT 15 IN REQINFO */
- LqhKeyReq::setApplicationAddressFlag(regTcPtr->reqinfo, 1);
- regTcPtr->readlenAi = readLen;
- }//if
-
- if (regTcPtr->operation == ZREAD &&
- (regTcPtr->opSimple || regTcPtr->dirtyOp))
- {
- jam();
- /* ----------------------------------------------------------------------
- * THE OPERATION IS A SIMPLE READ.
- * WE WILL IMMEDIATELY COMMIT THE OPERATION.
- * SINCE WE HAVE NOT RELEASED THE FRAGMENT LOCK
- * (FOR LOCAL CHECKPOINTS) YET
- * WE CAN GO IMMEDIATELY TO COMMIT_CONTINUE_AFTER_BLOCKED.
- * WE HAVE ALREADY SENT THE RESPONSE SO WE ARE NOT INTERESTED IN
- * READ LENGTH
- * --------------------------------------------------------------------- */
- commitContinueAfterBlockedLab(signal);
- return;
- }//if
- regTcPtr->totSendlenAi = writeLen;
- ndbrequire(regTcPtr->totSendlenAi == regTcPtr->currTupAiLen);
-
- if (unlikely(activeCreat == Fragrecord::AC_NR_COPY))
- {
- jam();
- ndbrequire(regTcPtr->m_nr_delete.m_cnt);
- regTcPtr->m_nr_delete.m_cnt--;
- if (regTcPtr->m_nr_delete.m_cnt)
- {
- jam();
- /**
- * Let operation wait for pending NR operations
- * even for before writing log...(as it's simpler)
- */
-
-#ifdef VM_TRACE
- /**
- * Only disk table can have pending ops...
- */
- TablerecPtr tablePtr;
- tablePtr.i = regTcPtr->tableref;
- ptrCheckGuard(tablePtr, ctabrecFileSize, tablerec);
- ndbrequire(tablePtr.p->m_disk_table);
-#endif
-
- return;
- }
- }
-
- rwConcludedLab(signal);
- return;
-}//Dblqh::tupkeyConfLab()
-
-/* --------------------------------------------------------------------------
- * THE CODE IS FOUND IN THE SIGNAL RECEPTION PART OF LQH
- * -------------------------------------------------------------------------- */
-void Dblqh::rwConcludedLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- /* ------------------------------------------------------------------------
- * WE HAVE NOW CONCLUDED READING/WRITING IN ACC AND TUP FOR THIS OPERATION.
- * IT IS NOW TIME TO LOG THE OPERATION, SEND REQUEST TO NEXT NODE OR TC AND
- * FOR SOME TYPES OF OPERATIONS IT IS EVEN TIME TO COMMIT THE OPERATION.
- * ------------------------------------------------------------------------ */
- if (regTcPtr->operation == ZREAD) {
- jam();
- /* ----------------------------------------------------------------------
- * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL THE
- * COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.
- * ---------------------------------------------------------------------- */
- packLqhkeyreqLab(signal);
- return;
- } else {
- FragrecordPtr regFragptr = fragptr;
- if (regFragptr.p->logFlag == Fragrecord::STATE_FALSE){
- if (regTcPtr->dirtyOp == ZTRUE) {
- jam();
- /* ------------------------------------------------------------------
- * THIS OPERATION WAS A WRITE OPERATION THAT DO NOT NEED LOGGING AND
- * THAT CAN CAN BE COMMITTED IMMEDIATELY.
- * ----------------------------------------------------------------- */
- commitContinueAfterBlockedLab(signal);
- return;
- } else {
- jam();
- /* ------------------------------------------------------------------
- * A NORMAL WRITE OPERATION ON A FRAGMENT WHICH DO NOT NEED LOGGING.
- * WE WILL PACK THE REQUEST/RESPONSE TO THE NEXT NODE/TO TC.
- * ------------------------------------------------------------------ */
- regTcPtr->logWriteState = TcConnectionrec::NOT_WRITTEN;
- packLqhkeyreqLab(signal);
- return;
- }//if
- } else {
- jam();
- /* --------------------------------------------------------------------
- * A DIRTY OPERATION WHICH NEEDS LOGGING. WE START BY LOGGING THE
- * REQUEST. IN THIS CASE WE WILL RELEASE THE FRAGMENT LOCK FIRST.
- * --------------------------------------------------------------------
- * A NORMAL WRITE OPERATION THAT NEEDS LOGGING AND WILL NOT BE
- * PREMATURELY COMMITTED.
- * -------------------------------------------------------------------- */
- logLqhkeyreqLab(signal);
- return;
- }//if
- }//if
-}//Dblqh::rwConcludedLab()
-
-void Dblqh::rwConcludedAiLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- fragptr.i = regTcPtr->fragmentptr;
- /* ------------------------------------------------------------------------
- * WE HAVE NOW CONCLUDED READING/WRITING IN ACC AND TUP FOR THIS OPERATION.
- * IT IS NOW TIME TO LOG THE OPERATION, SEND REQUEST TO NEXT NODE OR TC AND
- * FOR SOME TYPES OF OPERATIONS IT IS EVEN TIME TO COMMIT THE OPERATION.
- * IN THIS CASE WE HAVE ALREADY RELEASED THE FRAGMENT LOCK.
- * ERROR CASES AT FRAGMENT CREATION AND STAND-BY NODES ARE THE REASONS FOR
- * COMING HERE.
- * ------------------------------------------------------------------------ */
- if (regTcPtr->operation == ZREAD) {
- if (regTcPtr->opSimple == 1) {
- jam();
- /* --------------------------------------------------------------------
- * THE OPERATION IS A SIMPLE READ. WE WILL IMMEDIATELY COMMIT THE
- * OPERATION.
- * -------------------------------------------------------------------- */
- localCommitLab(signal);
- return;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * A NORMAL READ OPERATION IS NOT LOGGED BUT IS NOT COMMITTED UNTIL
- * THE COMMIT SIGNAL ARRIVES. THUS WE CONTINUE PACKING THE RESPONSE.
- * -------------------------------------------------------------------- */
- c_fragment_pool.getPtr(fragptr);
- packLqhkeyreqLab(signal);
- return;
- }//if
- } else {
- jam();
- c_fragment_pool.getPtr(fragptr);
- if (fragptr.p->logFlag == Fragrecord::STATE_FALSE) {
- if (regTcPtr->dirtyOp == ZTRUE) {
- /* ------------------------------------------------------------------
- * THIS OPERATION WAS A WRITE OPERATION THAT DO NOT NEED LOGGING AND
- * THAT CAN CAN BE COMMITTED IMMEDIATELY.
- * ----------------------------------------------------------------- */
- jam();
- /* ----------------------------------------------------------------
- * IT MUST BE ACTIVE CREATION OF A FRAGMENT.
- * ---------------------------------------------------------------- */
- localCommitLab(signal);
- return;
- } else {
- /* ------------------------------------------------------------------
- * A NORMAL WRITE OPERATION ON A FRAGMENT WHICH DO NOT NEED LOGGING.
- * WE WILL PACK THE REQUEST/RESPONSE TO THE NEXT NODE/TO TC.
- * ------------------------------------------------------------------ */
- jam();
- /* ---------------------------------------------------------------
- * IT MUST BE ACTIVE CREATION OF A FRAGMENT.
- * NOT A DIRTY OPERATION THUS PACK REQUEST/RESPONSE.
- * ---------------------------------------------------------------- */
- regTcPtr->logWriteState = TcConnectionrec::NOT_WRITTEN;
- packLqhkeyreqLab(signal);
- return;
- }//if
- } else {
- jam();
- /* --------------------------------------------------------------------
- * A DIRTY OPERATION WHICH NEEDS LOGGING. WE START BY LOGGING THE
- * REQUEST. IN THIS CASE WE WILL RELEASE THE FRAGMENT LOCK FIRST.
- * -------------------------------------------------------------------- */
- /* A NORMAL WRITE OPERATION THAT NEEDS LOGGING AND WILL NOT BE
- * PREMATURELY COMMITTED.
- * -------------------------------------------------------------------- */
- logLqhkeyreqLab(signal);
- return;
- }//if
- }//if
-}//Dblqh::rwConcludedAiLab()
-
-/* ##########################################################################
- * ####### LOG MODULE #######
- *
- * ##########################################################################
- * --------------------------------------------------------------------------
- * THE LOG MODULE HANDLES THE READING AND WRITING OF THE LOG
- * IT IS ALSO RESPONSIBLE FOR HANDLING THE SYSTEM RESTART.
- * IT CONTROLS THE SYSTEM RESTART IN TUP AND ACC AS WELL.
- * -------------------------------------------------------------------------- */
-void Dblqh::logLqhkeyreqLab(Signal* signal)
-{
- UintR tcurrentFilepage;
- TcConnectionrecPtr tmpTcConnectptr;
-
- if (cnoOfLogPages < ZMIN_LOG_PAGES_OPERATION || ERROR_INSERTED(5032)) {
- jam();
- if(ERROR_INSERTED(5032)){
- CLEAR_ERROR_INSERT_VALUE;
- }
-/*---------------------------------------------------------------------------*/
-// The log disk is having problems in catching up with the speed of execution.
-// We must wait with writing the log of this operation to ensure we do not
-// overload the log.
-/*---------------------------------------------------------------------------*/
- terrorCode = ZTEMPORARY_REDO_LOG_FAILURE;
- abortErrorLab(signal);
- return;
- }//if
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- logPartPtr.i = regTcPtr->m_log_part_ptr_i;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
-/* -------------------------------------------------- */
-/* THIS PART IS USED TO WRITE THE LOG */
-/* -------------------------------------------------- */
-/* -------------------------------------------------- */
-/* CHECK IF A LOG OPERATION IS ONGOING ALREADY. */
-/* IF SO THEN QUEUE THE OPERATION FOR LATER */
-/* RESTART WHEN THE LOG PART IS FREE AGAIN. */
-/* -------------------------------------------------- */
- LogPartRecord * const regLogPartPtr = logPartPtr.p;
-
- if(ERROR_INSERTED(5033)){
- jam();
- CLEAR_ERROR_INSERT_VALUE;
-
- if ((regLogPartPtr->firstLogQueue != RNIL) &&
- (regLogPartPtr->LogLqhKeyReqSent == ZFALSE)) {
- /* -------------------------------------------------- */
- /* WE HAVE A PROBLEM IN THAT THE LOG HAS NO */
- /* ROOM FOR ADDITIONAL OPERATIONS AT THE MOMENT.*/
- /* -------------------------------------------------- */
- /* -------------------------------------------------- */
- /* WE MUST STILL RESTART QUEUED OPERATIONS SO */
- /* THEY ALSO CAN BE ABORTED. */
- /* -------------------------------------------------- */
- regLogPartPtr->LogLqhKeyReqSent = ZTRUE;
- signal->theData[0] = ZLOG_LQHKEYREQ;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
-
- terrorCode = ZTAIL_PROBLEM_IN_LOG_ERROR;
- abortErrorLab(signal);
- return;
- }
-
- if (regLogPartPtr->logPartState == LogPartRecord::IDLE) {
- ;
- } else if (regLogPartPtr->logPartState == LogPartRecord::ACTIVE) {
- jam();
- linkWaitLog(signal, logPartPtr);
- regTcPtr->transactionState = TcConnectionrec::LOG_QUEUED;
- return;
- } else {
- if ((regLogPartPtr->firstLogQueue != RNIL) &&
- (regLogPartPtr->LogLqhKeyReqSent == ZFALSE)) {
-/* -------------------------------------------------- */
-/* WE HAVE A PROBLEM IN THAT THE LOG HAS NO */
-/* ROOM FOR ADDITIONAL OPERATIONS AT THE MOMENT.*/
-/* -------------------------------------------------- */
-/* -------------------------------------------------- */
-/* WE MUST STILL RESTART QUEUED OPERATIONS SO */
-/* THEY ALSO CAN BE ABORTED. */
-/* -------------------------------------------------- */
- regLogPartPtr->LogLqhKeyReqSent = ZTRUE;
- signal->theData[0] = ZLOG_LQHKEYREQ;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
- if (regLogPartPtr->logPartState == LogPartRecord::TAIL_PROBLEM) {
- jam();
- terrorCode = ZTAIL_PROBLEM_IN_LOG_ERROR;
- } else {
- ndbrequire(regLogPartPtr->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM);
- jam();
- terrorCode = ZFILE_CHANGE_PROBLEM_IN_LOG_ERROR;
- }//if
- abortErrorLab(signal);
- return;
- }//if
- regLogPartPtr->logPartState = LogPartRecord::ACTIVE;
- logFilePtr.i = regLogPartPtr->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
-/* -------------------------------------------------- */
-/* CHECK IF A NEW MBYTE IS TO BE STARTED. IF */
-/* SO INSERT A NEXT LOG RECORD, WRITE THE LOG */
-/* AND PLACE THE LOG POINTER ON THE NEW POSITION*/
-/* IF A NEW FILE IS TO BE USED, CHANGE FILE AND */
-/* ALSO START OPENING THE NEXT LOG FILE. IF A */
-/* LAP HAS BEEN COMPLETED THEN ADD ONE TO LAP */
-/* COUNTER. */
-/* -------------------------------------------------- */
- checkNewMbyte(signal);
-/* -------------------------------------------------- */
-/* INSERT THE OPERATION RECORD LAST IN THE LIST */
-/* OF NOT COMPLETED OPERATIONS. ALSO RECORD THE */
-/* FILE NO, PAGE NO AND PAGE INDEX OF THE START */
-/* OF THIS LOG RECORD. */
-/* IT IS NOT ALLOWED TO INSERT IT INTO THE LIST */
-/* BEFORE CHECKING THE NEW MBYTE SINCE THAT WILL*/
-/* CAUSE THE OLD VALUES OF TC_CONNECTPTR TO BE */
-/* USED IN WRITE_FILE_DESCRIPTOR. */
-/* -------------------------------------------------- */
- Uint32 tcIndex = tcConnectptr.i;
- tmpTcConnectptr.i = regLogPartPtr->lastLogTcrec;
- regLogPartPtr->lastLogTcrec = tcIndex;
- if (tmpTcConnectptr.i == RNIL) {
- jam();
- regLogPartPtr->firstLogTcrec = tcIndex;
- } else {
- ptrCheckGuard(tmpTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- tmpTcConnectptr.p->nextLogTcrec = tcIndex;
- }//if
- Uint32 fileNo = logFilePtr.p->fileNo;
- tcurrentFilepage = logFilePtr.p->currentFilepage;
- logPagePtr.i = logFilePtr.p->currentLogpage;
- regTcPtr->nextLogTcrec = RNIL;
- regTcPtr->prevLogTcrec = tmpTcConnectptr.i;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- Uint32 pageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- regTcPtr->logStartFileNo = fileNo;
- regTcPtr->logStartPageNo = tcurrentFilepage;
- regTcPtr->logStartPageIndex = pageIndex;
-/* -------------------------------------------------- */
-/* WRITE THE LOG HEADER OF THIS OPERATION. */
-/* -------------------------------------------------- */
- writeLogHeader(signal);
-/* -------------------------------------------------- */
-/* WRITE THE TUPLE KEY OF THIS OPERATION. */
-/* -------------------------------------------------- */
- writeKey(signal);
-/* -------------------------------------------------- */
-/* WRITE THE ATTRIBUTE INFO OF THIS OPERATION. */
-/* -------------------------------------------------- */
- writeAttrinfoLab(signal);
-
- logNextStart(signal);
-/* -------------------------------------------------- */
-/* RESET THE STATE OF THE LOG PART. IF ANY */
-/* OPERATIONS HAVE QUEUED THEN START THE FIRST */
-/* OF THESE. */
-/* -------------------------------------------------- */
-/* -------------------------------------------------- */
-/* CONTINUE WITH PACKING OF LQHKEYREQ */
-/* -------------------------------------------------- */
- tcurrentFilepage = logFilePtr.p->currentFilepage;
- if (logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == ZPAGE_HEADER_SIZE) {
- jam();
- tcurrentFilepage--;
- }//if
- regTcPtr->logStopPageNo = tcurrentFilepage;
- regTcPtr->logWriteState = TcConnectionrec::WRITTEN;
- if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
-/* -------------------------------------------------- */
-/* AN ABORT HAVE BEEN ORDERED. THE ABORT WAITED */
-/* FOR THE LOG WRITE TO BE COMPLETED. NOW WE */
-/* CAN PROCEED WITH THE NORMAL ABORT HANDLING. */
-/* -------------------------------------------------- */
- abortCommonLab(signal);
- return;
- }//if
- if (regTcPtr->dirtyOp != ZTRUE) {
- packLqhkeyreqLab(signal);
- } else {
- /* ----------------------------------------------------------------------
- * I NEED TO INSERT A COMMIT LOG RECORD SINCE WE ARE WRITING LOG IN THIS
- * TRANSACTION. SINCE WE RELEASED THE LOG LOCK JUST NOW NO ONE ELSE CAN BE
- * ACTIVE IN WRITING THE LOG. WE THUS WRITE THE LOG WITHOUT GETTING A LOCK
- * SINCE WE ARE ONLY WRITING A COMMIT LOG RECORD.
- * ---------------------------------------------------------------------- */
- writeCommitLog(signal, logPartPtr);
- /* ----------------------------------------------------------------------
- * DIRTY OPERATIONS SHOULD COMMIT BEFORE THEY PACK THE REQUEST/RESPONSE.
- * ---------------------------------------------------------------------- */
- localCommitLab(signal);
- }//if
-}//Dblqh::logLqhkeyreqLab()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEND LQHKEYREQ */
-/* */
-/* NO STATE CHECKING SINCE THE SIGNAL IS A LOCAL SIGNAL. THE EXECUTION OF */
-/* THE OPERATION IS COMPLETED. IT IS NOW TIME TO SEND THE OPERATION TO THE */
-/* NEXT REPLICA OR TO TC. */
-/* ------------------------------------------------------------------------- */
-void Dblqh::packLqhkeyreqLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->nextReplica == ZNIL) {
-/* ------------------------------------------------------------------------- */
-/* ------- SEND LQHKEYCONF ------- */
-/* */
-/* ------------------------------------------------------------------------- */
- sendLqhkeyconfTc(signal, regTcPtr->tcBlockref);
- if (! (regTcPtr->dirtyOp ||
- (regTcPtr->operation == ZREAD && regTcPtr->opSimple)))
- {
- jam();
- regTcPtr->transactionState = TcConnectionrec::PREPARED;
- releaseOprec(signal);
- } else {
- jam();
-
-/*************************************************************>*/
-/* DIRTY WRITES ARE USED IN TWO SITUATIONS. THE FIRST */
-/* SITUATION IS WHEN THEY ARE USED TO UPDATE COUNTERS AND*/
-/* OTHER ATTRIBUTES WHICH ARE NOT SENSITIVE TO CONSISTE- */
-/* NCY. THE SECOND SITUATION IS BY OPERATIONS THAT ARE */
-/* SENT AS PART OF A COPY FRAGMENT PROCESS. */
-/* */
-/* DURING A COPY FRAGMENT PROCESS THERE IS NO LOGGING */
-/* ONGOING SINCE THE FRAGMENT IS NOT COMPLETE YET. THE */
-/* LOGGING STARTS AFTER COMPLETING THE LAST COPY TUPLE */
-/* OPERATION. THE EXECUTION OF THE LAST COPY TUPLE DOES */
-/* ALSO START A LOCAL CHECKPOINT SO THAT THE FRAGMENT */
-/* REPLICA IS RECOVERABLE. THUS GLOBAL CHECKPOINT ID FOR */
-/* THOSE OPERATIONS ARE NOT INTERESTING. */
-/* */
-/* A DIRTY WRITE IS BY DEFINITION NOT CONSISTENT. THUS */
-/* IT CAN USE ANY GLOBAL CHECKPOINT. THE IDEA HERE IS TO */
-/* ALWAYS USE THE LATEST DEFINED GLOBAL CHECKPOINT ID IN */
-/* THIS NODE. */
-/*************************************************************>*/
- cleanUp(signal);
- }//if
- return;
- }//if
-/* ------------------------------------------------------------------------- */
-/* ------- SEND LQHKEYREQ ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* THERE ARE MORE REPLICAS TO SEND THE OPERATION TO. A NEW LQHKEYREQ WILL BE */
-/* PREPARED FOR THE NEXT REPLICA. */
-/* ------------------------------------------------------------------------- */
-/* CLEAR REPLICA TYPE, ATTRINFO INDICATOR (IN LQHKEYREQ), */
-/* INTERPRETED EXECUTION, SEQUENTIAL NUMBER OF REPLICA. */
-// Set bit indicating Client and TC record not the same.
-// Set readlenAi indicator if readlenAi != 0
-// Stored Procedure Indicator not set.
-/* ------------------------------------------------------------------------- */
- LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)&signal->theData[0];
-
- UintR Treqinfo;
- UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
- Treqinfo = preComputedRequestInfoMask & regTcPtr->reqinfo;
-
- Uint32 nextNodeId = regTcPtr->nextReplica;
- Uint32 nextVersion = getNodeInfo(nextNodeId).m_version;
- UintR TAiLen = regTcPtr->reclenAiLqhkey;
-
- UintR TapplAddressIndicator = (regTcPtr->nextSeqNoReplica == 0 ? 0 : 1);
- LqhKeyReq::setApplicationAddressFlag(Treqinfo, TapplAddressIndicator);
- LqhKeyReq::setInterpretedFlag(Treqinfo, regTcPtr->opExec);
- LqhKeyReq::setSeqNoReplica(Treqinfo, regTcPtr->nextSeqNoReplica);
- LqhKeyReq::setAIInLqhKeyReq(Treqinfo, TAiLen);
-
- if (unlikely(nextVersion < NDBD_ROWID_VERSION))
- {
- LqhKeyReq::setLockType(Treqinfo, regTcPtr->lockType);
- }
- else
- {
- regTcPtr->m_use_rowid |=
- fragptr.p->m_copy_started_state == Fragrecord::AC_NR_COPY;
- LqhKeyReq::setRowidFlag(Treqinfo, regTcPtr->m_use_rowid);
- }
-
- if (LqhKeyReq::getRowidFlag(Treqinfo))
- {
- //ndbassert(LqhKeyReq::getOperation(Treqinfo) == ZINSERT);
- }
- else
- {
- ndbassert(LqhKeyReq::getOperation(Treqinfo) != ZINSERT);
- }
-
- UintR TreadLenAiInd = (regTcPtr->readlenAi == 0 ? 0 : 1);
- UintR TsameLqhAndClient = (tcConnectptr.i ==
- regTcPtr->tcOprec ? 0 : 1);
- LqhKeyReq::setSameClientAndTcFlag(Treqinfo, TsameLqhAndClient);
- LqhKeyReq::setReturnedReadLenAIFlag(Treqinfo, TreadLenAiInd);
-
- UintR TotReclenAi = regTcPtr->totSendlenAi;
-/* ------------------------------------------------------------------------- */
-/* WE ARE NOW PREPARED TO SEND THE LQHKEYREQ. WE HAVE TO DECIDE IF ATTRINFO */
-/* IS INCLUDED IN THE LQHKEYREQ SIGNAL AND THEN SEND IT. */
-/* TAKE OVER SCAN OPERATION IS NEVER USED ON BACKUPS, LOG RECORDS AND START-UP*/
-/* OF NEW REPLICA AND THUS ONLY TOT_SENDLEN_AI IS USED THE UPPER 16 BITS ARE */
-/* ZERO. */
-/* ------------------------------------------------------------------------- */
- sig0 = tcConnectptr.i;
- sig1 = regTcPtr->savePointId;
- sig2 = regTcPtr->hashValue;
- sig4 = regTcPtr->tcBlockref;
-
- lqhKeyReq->clientConnectPtr = sig0;
- lqhKeyReq->attrLen = TotReclenAi;
- lqhKeyReq->savePointId = sig1;
- lqhKeyReq->hashValue = sig2;
- lqhKeyReq->requestInfo = Treqinfo;
- lqhKeyReq->tcBlockref = sig4;
-
- sig0 = regTcPtr->tableref + ((regTcPtr->schemaVersion << 16) & 0xFFFF0000);
- sig1 = regTcPtr->fragmentid + (regTcPtr->nodeAfterNext[0] << 16);
- sig2 = regTcPtr->transid[0];
- sig3 = regTcPtr->transid[1];
- sig4 = regTcPtr->applRef;
- sig5 = regTcPtr->applOprec;
- sig6 = regTcPtr->tcOprec;
- UintR nextPos = (TapplAddressIndicator << 1);
-
- lqhKeyReq->tableSchemaVersion = sig0;
- lqhKeyReq->fragmentData = sig1;
- lqhKeyReq->transId1 = sig2;
- lqhKeyReq->transId2 = sig3;
- lqhKeyReq->noFiredTriggers = regTcPtr->noFiredTriggers;
- lqhKeyReq->variableData[0] = sig4;
- lqhKeyReq->variableData[1] = sig5;
- lqhKeyReq->variableData[2] = sig6;
-
- nextPos += TsameLqhAndClient;
-
- if ((regTcPtr->lastReplicaNo - regTcPtr->nextSeqNoReplica) > 1) {
- sig0 = (UintR)regTcPtr->nodeAfterNext[1] +
- (UintR)(regTcPtr->nodeAfterNext[2] << 16);
- lqhKeyReq->variableData[nextPos] = sig0;
- nextPos++;
- }//if
- sig0 = regTcPtr->readlenAi;
- sig1 = regTcPtr->tupkeyData[0];
- sig2 = regTcPtr->tupkeyData[1];
- sig3 = regTcPtr->tupkeyData[2];
- sig4 = regTcPtr->tupkeyData[3];
-
- lqhKeyReq->variableData[nextPos] = sig0;
- nextPos += TreadLenAiInd;
- lqhKeyReq->variableData[nextPos] = sig1;
- lqhKeyReq->variableData[nextPos + 1] = sig2;
- lqhKeyReq->variableData[nextPos + 2] = sig3;
- lqhKeyReq->variableData[nextPos + 3] = sig4;
- UintR TkeyLen = LqhKeyReq::getKeyLen(Treqinfo);
- if (TkeyLen < 4) {
- nextPos += TkeyLen;
- } else {
- nextPos += 4;
- }//if
-
- sig0 = regTcPtr->gci;
- Local_key tmp = regTcPtr->m_row_id;
-
- lqhKeyReq->variableData[nextPos + 0] = tmp.m_page_no;
- lqhKeyReq->variableData[nextPos + 1] = tmp.m_page_idx;
- nextPos += 2*LqhKeyReq::getRowidFlag(Treqinfo);
-
- lqhKeyReq->variableData[nextPos + 0] = sig0;
- nextPos += LqhKeyReq::getGCIFlag(Treqinfo);
-
- BlockReference lqhRef = calcLqhBlockRef(regTcPtr->nextReplica);
-
- if (likely(nextPos + TAiLen + LqhKeyReq::FixedSignalLength <= 25))
- {
- jam();
- sig0 = regTcPtr->firstAttrinfo[0];
- sig1 = regTcPtr->firstAttrinfo[1];
- sig2 = regTcPtr->firstAttrinfo[2];
- sig3 = regTcPtr->firstAttrinfo[3];
- sig4 = regTcPtr->firstAttrinfo[4];
-
- lqhKeyReq->variableData[nextPos] = sig0;
- lqhKeyReq->variableData[nextPos + 1] = sig1;
- lqhKeyReq->variableData[nextPos + 2] = sig2;
- lqhKeyReq->variableData[nextPos + 3] = sig3;
- lqhKeyReq->variableData[nextPos + 4] = sig4;
-
- nextPos += TAiLen;
- TAiLen = 0;
- }
- else
- {
- Treqinfo &= ~(Uint32)(RI_AI_IN_THIS_MASK << RI_AI_IN_THIS_SHIFT);
- lqhKeyReq->requestInfo = Treqinfo;
- }
-
- sendSignal(lqhRef, GSN_LQHKEYREQ, signal,
- nextPos + LqhKeyReq::FixedSignalLength, JBB);
- if (regTcPtr->primKeyLen > 4) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* MORE THAN 4 WORDS OF KEY DATA IS IN THE OPERATION. THEREFORE WE NEED TO */
-/* PREPARE A KEYINFO SIGNAL. MORE THAN ONE KEYINFO SIGNAL CAN BE SENT. */
-/* ------------------------------------------------------------------------- */
- sendTupkey(signal);
- }//if
-/* ------------------------------------------------------------------------- */
-/* NOW I AM PREPARED TO SEND ALL THE ATTRINFO SIGNALS. AT THE MOMENT A LOOP */
-/* SENDS ALL AT ONCE. LATER WE HAVE TO ADDRESS THE PROBLEM THAT THESE COULD */
-/* LEAD TO BUFFER EXPLOSION => NODE CRASH. */
-/* ------------------------------------------------------------------------- */
-/* NEW CODE TO SEND ATTRINFO IN PACK_LQHKEYREQ */
-/* THIS CODE USES A REAL-TIME BREAK AFTER */
-/* SENDING 16 SIGNALS. */
-/* -------------------------------------------------- */
- sig0 = regTcPtr->tcOprec;
- sig1 = regTcPtr->transid[0];
- sig2 = regTcPtr->transid[1];
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->theData[2] = sig2;
-
- if (unlikely(nextPos + TAiLen + LqhKeyReq::FixedSignalLength > 25))
- {
- jam();
- /**
- * 4 replicas...
- */
- memcpy(signal->theData+3, regTcPtr->firstAttrinfo, TAiLen << 2);
- sendSignal(lqhRef, GSN_ATTRINFO, signal, 3 + TAiLen, JBB);
- }
-
- AttrbufPtr regAttrinbufptr;
- regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
- while (regAttrinbufptr.i != RNIL) {
- ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
- jam();
- Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
- ndbrequire(dataLen != 0);
- MEMCOPY_NO_WORDS(&signal->theData[3], &regAttrinbufptr.p->attrbuf[0], dataLen);
- regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
- sendSignal(lqhRef, GSN_ATTRINFO, signal, dataLen + 3, JBB);
- }//while
- regTcPtr->transactionState = TcConnectionrec::PREPARED;
- if (regTcPtr->dirtyOp == ZTRUE) {
- jam();
-/*************************************************************>*/
-/* DIRTY WRITES ARE USED IN TWO SITUATIONS. THE FIRST */
-/* SITUATION IS WHEN THEY ARE USED TO UPDATE COUNTERS AND*/
-/* OTHER ATTRIBUTES WHICH ARE NOT SENSITIVE TO CONSISTE- */
-/* NCY. THE SECOND SITUATION IS BY OPERATIONS THAT ARE */
-/* SENT AS PART OF A COPY FRAGMENT PROCESS. */
-/* */
-/* DURING A COPY FRAGMENT PROCESS THERE IS NO LOGGING */
-/* ONGOING SINCE THE FRAGMENT IS NOT COMPLETE YET. THE */
-/* LOGGING STARTS AFTER COMPLETING THE LAST COPY TUPLE */
-/* OPERATION. THE EXECUTION OF THE LAST COPY TUPLE DOES */
-/* ALSO START A LOCAL CHECKPOINT SO THAT THE FRAGMENT */
-/* REPLICA IS RECOVERABLE. THUS GLOBAL CHECKPOINT ID FOR */
-/* THOSE OPERATIONS ARE NOT INTERESTING. */
-/* */
-/* A DIRTY WRITE IS BY DEFINITION NOT CONSISTENT. THUS */
-/* IT CAN USE ANY GLOBAL CHECKPOINT. THE IDEA HERE IS TO */
-/* ALWAYS USE THE LATEST DEFINED GLOBAL CHECKPOINT ID IN */
-/* THIS NODE. */
-/*************************************************************>*/
- cleanUp(signal);
- return;
- }//if
- /* ------------------------------------------------------------------------
- * ALL INFORMATION NEEDED BY THE COMMIT PHASE AND COMPLETE PHASE IS
- * KEPT IN THE TC_CONNECT RECORD. TO ENSURE PROPER USE OF MEMORY
- * RESOURCES WE DEALLOCATE THE ATTRINFO RECORD AND KEY RECORDS
- * AS SOON AS POSSIBLE.
- * ------------------------------------------------------------------------ */
- releaseOprec(signal);
-}//Dblqh::packLqhkeyreqLab()
-
-/* ========================================================================= */
-/* ==== CHECK IF THE LOG RECORD FITS INTO THE CURRENT MBYTE, ======= */
-/* OTHERWISE SWITCH TO NEXT MBYTE. */
-/* */
-/* ========================================================================= */
-void Dblqh::checkNewMbyte(Signal* signal)
-{
- UintR tcnmTmp;
- UintR ttotalLogSize;
-
-/* -------------------------------------------------- */
-/* CHECK IF A NEW MBYTE OF LOG RECORD IS TO BE */
-/* OPENED BEFORE WRITING THE LOG RECORD. NO LOG */
-/* RECORDS ARE ALLOWED TO SPAN A MBYTE BOUNDARY */
-/* */
-/* INPUT: TC_CONNECTPTR THE OPERATION */
-/* LOG_FILE_PTR THE LOG FILE */
-/* OUTPUT: LOG_FILE_PTR THE NEW LOG FILE */
-/* -------------------------------------------------- */
- ttotalLogSize = ZLOG_HEAD_SIZE + tcConnectptr.p->currTupAiLen;
- ttotalLogSize = ttotalLogSize + tcConnectptr.p->primKeyLen;
- tcnmTmp = logFilePtr.p->remainingWordsInMbyte;
- if ((ttotalLogSize + ZNEXT_LOG_SIZE) <= tcnmTmp) {
- ndbrequire(tcnmTmp >= ttotalLogSize);
- logFilePtr.p->remainingWordsInMbyte = tcnmTmp - ttotalLogSize;
- return;
- } else {
- jam();
-/* -------------------------------------------------- */
-/* IT WAS NOT ENOUGH SPACE IN THIS MBYTE FOR */
-/* THIS LOG RECORD. MOVE TO NEXT MBYTE */
-/* THIS MIGHT INCLUDE CHANGING LOG FILE */
-/* -------------------------------------------------- */
-/* WE HAVE TO INSERT A NEXT LOG RECORD FIRST */
-/* -------------------------------------------------- */
-/* THEN CONTINUE BY WRITING THE FILE DESCRIPTORS*/
-/* -------------------------------------------------- */
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- changeMbyte(signal);
- tcnmTmp = logFilePtr.p->remainingWordsInMbyte;
- }//if
- ndbrequire(tcnmTmp >= ttotalLogSize);
- logFilePtr.p->remainingWordsInMbyte = tcnmTmp - ttotalLogSize;
-}//Dblqh::checkNewMbyte()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE OPERATION HEADER TO LOG -------
- *
- * SUBROUTINE SHORT NAME: WLH
- * ------------------------------------------------------------------------- */
-void Dblqh::writeLogHeader(Signal* signal)
-{
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- Uint32 hashValue = tcConnectptr.p->hashValue;
- Uint32 operation = tcConnectptr.p->operation;
- Uint32 keyLen = tcConnectptr.p->primKeyLen;
- Uint32 aiLen = tcConnectptr.p->currTupAiLen;
- Local_key rowid = tcConnectptr.p->m_row_id;
- Uint32 totLogLen = ZLOG_HEAD_SIZE + aiLen + keyLen;
-
- if ((logPos + ZLOG_HEAD_SIZE) < ZPAGE_SIZE) {
- Uint32* dataPtr = &logPagePtr.p->logPageWord[logPos];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + ZLOG_HEAD_SIZE;
- dataPtr[0] = ZPREP_OP_TYPE;
- dataPtr[1] = totLogLen;
- dataPtr[2] = hashValue;
- dataPtr[3] = operation;
- dataPtr[4] = aiLen;
- dataPtr[5] = keyLen;
- dataPtr[6] = rowid.m_page_no;
- dataPtr[7] = rowid.m_page_idx;
- } else {
- writeLogWord(signal, ZPREP_OP_TYPE);
- writeLogWord(signal, totLogLen);
- writeLogWord(signal, hashValue);
- writeLogWord(signal, operation);
- writeLogWord(signal, aiLen);
- writeLogWord(signal, keyLen);
- writeLogWord(signal, rowid.m_page_no);
- writeLogWord(signal, rowid.m_page_idx);
- }//if
-}//Dblqh::writeLogHeader()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE TUPLE KEY TO LOG -------
- *
- * SUBROUTINE SHORT NAME: WK
- * ------------------------------------------------------------------------- */
-void Dblqh::writeKey(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 logPos, endPos, dataLen;
- Int32 remainingLen;
- logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- remainingLen = regTcPtr->primKeyLen;
- dataLen = remainingLen;
- if (remainingLen > 4)
- dataLen = 4;
- remainingLen -= dataLen;
- endPos = logPos + dataLen;
- if (endPos < ZPAGE_SIZE) {
- MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
- &regTcPtr->tupkeyData[0],
- dataLen);
- } else {
- jam();
- for (Uint32 i = 0; i < dataLen; i++)
- writeLogWord(signal, regTcPtr->tupkeyData[i]);
- endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- }//if
- DatabufPtr regDatabufptr;
- regDatabufptr.i = regTcPtr->firstTupkeybuf;
- while (remainingLen > 0) {
- logPos = endPos;
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- dataLen = remainingLen;
- if (remainingLen > 4)
- dataLen = 4;
- remainingLen -= dataLen;
- endPos += dataLen;
- if (endPos < ZPAGE_SIZE) {
- MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
- &regDatabufptr.p->data[0],
- dataLen);
- } else {
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
- for (Uint32 i = 0; i < dataLen; i++)
- writeLogWord(signal, regDatabufptr.p->data[i]);
- endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- }//if
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
- }//while
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = endPos;
- ndbrequire(regDatabufptr.i == RNIL);
-}//Dblqh::writeKey()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE ATTRINFO TO LOG -------
- *
- * SUBROUTINE SHORT NAME: WA
- * ------------------------------------------------------------------------- */
-void Dblqh::writeAttrinfoLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 totLen = regTcPtr->currTupAiLen;
- if (totLen == 0)
- return;
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- Uint32 lqhLen = regTcPtr->reclenAiLqhkey;
- ndbrequire(totLen >= lqhLen);
- Uint32 endPos = logPos + lqhLen;
- totLen -= lqhLen;
- if (endPos < ZPAGE_SIZE) {
- MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
- &regTcPtr->firstAttrinfo[0],
- lqhLen);
- } else {
- for (Uint32 i = 0; i < lqhLen; i++)
- writeLogWord(signal, regTcPtr->firstAttrinfo[i]);
- endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- }//if
- AttrbufPtr regAttrinbufptr;
- regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
- while (totLen > 0) {
- logPos = endPos;
- ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
- Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
- ndbrequire(totLen >= dataLen);
- ndbrequire(dataLen > 0);
- totLen -= dataLen;
- endPos += dataLen;
- if (endPos < ZPAGE_SIZE) {
- MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[logPos],
- &regAttrinbufptr.p->attrbuf[0],
- dataLen);
- } else {
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
- for (Uint32 i = 0; i < dataLen; i++)
- writeLogWord(signal, regAttrinbufptr.p->attrbuf[i]);
- endPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- }//if
- regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
- }//while
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = endPos;
- ndbrequire(regAttrinbufptr.i == RNIL);
-}//Dblqh::writeAttrinfoLab()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEND TUPLE KEY IN KEYINFO SIGNAL(S) ------- */
-/* */
-/* SUBROUTINE SHORT NAME: STU */
-/* ------------------------------------------------------------------------- */
-void Dblqh::sendTupkey(Signal* signal)
-{
- UintR TdataPos = 3;
- BlockReference lqhRef = calcLqhBlockRef(tcConnectptr.p->nextReplica);
- signal->theData[0] = tcConnectptr.p->tcOprec;
- signal->theData[1] = tcConnectptr.p->transid[0];
- signal->theData[2] = tcConnectptr.p->transid[1];
- databufptr.i = tcConnectptr.p->firstTupkeybuf;
- do {
- ptrCheckGuard(databufptr, cdatabufFileSize, databuf);
- signal->theData[TdataPos] = databufptr.p->data[0];
- signal->theData[TdataPos + 1] = databufptr.p->data[1];
- signal->theData[TdataPos + 2] = databufptr.p->data[2];
- signal->theData[TdataPos + 3] = databufptr.p->data[3];
-
- databufptr.i = databufptr.p->nextDatabuf;
- TdataPos += 4;
- if (databufptr.i == RNIL) {
- jam();
- sendSignal(lqhRef, GSN_KEYINFO, signal, TdataPos, JBB);
- return;
- } else if (TdataPos == 23) {
- jam();
- sendSignal(lqhRef, GSN_KEYINFO, signal, 23, JBB);
- TdataPos = 3;
- }
- } while (1);
-}//Dblqh::sendTupkey()
-
-void Dblqh::cleanUp(Signal* signal)
-{
- releaseOprec(signal);
- deleteTransidHash(signal);
- releaseTcrec(signal, tcConnectptr);
-}//Dblqh::cleanUp()
-
-/* --------------------------------------------------------------------------
- * ---- RELEASE ALL RECORDS CONNECTED TO THE OPERATION RECORD AND THE ----
- * OPERATION RECORD ITSELF
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseOprec(Signal* signal)
-{
- UintR Tmpbuf;
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
-/* ---- RELEASE DATA BUFFERS ------------------- */
- DatabufPtr regDatabufptr;
- regDatabufptr.i = regTcPtr->firstTupkeybuf;
-/* --------------------------------------------------------------------------
- * ------- RELEASE DATA BUFFERS -------
- *
- * ------------------------------------------------------------------------- */
-
- while (regDatabufptr.i != RNIL) {
- jam();
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- Tmpbuf = regDatabufptr.p->nextDatabuf;
- regDatabufptr.p->nextDatabuf = cfirstfreeDatabuf;
- cfirstfreeDatabuf = regDatabufptr.i;
- regDatabufptr.i = Tmpbuf;
- }//while
-/* ---- RELEASE ATTRINFO BUFFERS ------------------- */
- AttrbufPtr regAttrinbufptr;
- regAttrinbufptr.i = regTcPtr->firstAttrinbuf;
- /* ########################################################################
- * ####### RELEASE_ATTRINBUF #######
- *
- * ####################################################################### */
- while (regAttrinbufptr.i != RNIL) {
- jam();
- regAttrinbufptr.i= release_attrinbuf(regAttrinbufptr.i);
- }//while
- regTcPtr->firstAttrinbuf = RNIL;
- regTcPtr->lastAttrinbuf = RNIL;
- regTcPtr->firstTupkeybuf = RNIL;
- regTcPtr->lastTupkeybuf = RNIL;
-
- if (regTcPtr->m_dealloc)
- {
- jam();
- regTcPtr->m_dealloc = 0;
-
- if (TRACENR_FLAG)
- TRACENR("DELETED: " << regTcPtr->m_row_id << endl);
-
- TRACE_OP(regTcPtr, "DEALLOC");
-
- signal->theData[0] = regTcPtr->fragmentid;
- signal->theData[1] = regTcPtr->tableref;
- signal->theData[2] = regTcPtr->m_row_id.m_page_no;
- signal->theData[3] = regTcPtr->m_row_id.m_page_idx;
- signal->theData[4] = RNIL;
- EXECUTE_DIRECT(DBTUP, GSN_TUP_DEALLOCREQ, signal, 5);
- }
-}//Dblqh::releaseOprec()
-
-/* ------------------------------------------------------------------------- */
-/* ------ DELETE TRANSACTION ID FROM HASH TABLE ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::deleteTransidHash(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TcConnectionrecPtr prevHashptr;
- TcConnectionrecPtr nextHashptr;
-
- prevHashptr.i = regTcPtr->prevHashRec;
- nextHashptr.i = regTcPtr->nextHashRec;
- if (prevHashptr.i != RNIL) {
- jam();
- ptrCheckGuard(prevHashptr, ctcConnectrecFileSize, tcConnectionrec);
- prevHashptr.p->nextHashRec = nextHashptr.i;
- } else {
- jam();
-/* ------------------------------------------------------------------------- */
-/* THE OPERATION WAS PLACED FIRST IN THE LIST OF THE HASH TABLE. NEED TO SET */
-/* A NEW LEADER OF THE LIST. */
-/* ------------------------------------------------------------------------- */
- Uint32 hashIndex = (regTcPtr->transid[0] ^ regTcPtr->tcOprec) & 1023;
- ctransidHash[hashIndex] = nextHashptr.i;
- }//if
- if (nextHashptr.i != RNIL) {
- jam();
- ptrCheckGuard(nextHashptr, ctcConnectrecFileSize, tcConnectionrec);
- nextHashptr.p->prevHashRec = prevHashptr.i;
- }//if
-}//Dblqh::deleteTransidHash()
-
-/* -------------------------------------------------------------------------
- * ------- RELEASE OPERATION FROM ACTIVE LIST ON FRAGMENT -------
- *
- * SUBROUTINE SHORT NAME = RAF
- * ------------------------------------------------------------------------- */
-/* ######################################################################### */
-/* ####### TRANSACTION MODULE ####### */
-/* THIS MODULE HANDLES THE COMMIT AND THE COMPLETE PHASE. */
-/* ######################################################################### */
-void Dblqh::warningReport(Signal* signal, int place)
-{
- switch (place) {
- case 0:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMMIT in wrong state in Dblqh" << endl;
-#endif
- break;
- case 1:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMMIT with wrong transid in Dblqh" << endl;
-#endif
- break;
- case 2:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMPLETE in wrong state in Dblqh" << endl;
-#endif
- break;
- case 3:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMPLETE with wrong transid in Dblqh" << endl;
-#endif
- break;
- case 4:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMMITREQ in wrong state in Dblqh" << endl;
-#endif
- break;
- case 5:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMMITREQ with wrong transid in Dblqh" << endl;
-#endif
- break;
- case 6:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMPLETEREQ in wrong state in Dblqh" << endl;
-#endif
- break;
- case 7:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMPLETEREQ with wrong transid in Dblqh" << endl;
-#endif
- break;
- case 8:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received ABORT with non-existing transid in Dblqh" << endl;
-#endif
- break;
- case 9:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received ABORTREQ with non-existing transid in Dblqh" << endl;
-#endif
- break;
- case 10:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received ABORTREQ in wrong state in Dblqh" << endl;
-#endif
- break;
- case 11:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMMIT when tc-rec released in Dblqh" << endl;
-#endif
- break;
- case 12:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received COMPLETE when tc-rec released in Dblqh" << endl;
-#endif
- break;
- case 13:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received LQHKEYREF when tc-rec released in Dblqh" << endl;
-#endif
- break;
- case 14:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received LQHKEYREF with wrong transid in Dblqh" << endl;
-#endif
- break;
- case 15:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "W: Received LQHKEYREF when already aborting in Dblqh" << endl;
-#endif
- break;
- case 16:
- jam();
- ndbrequire(cstartPhase == ZNIL);
-#ifdef ABORT_TRACE
- ndbout << "W: Received LQHKEYREF in wrong state in Dblqh" << endl;
-#endif
- break;
- default:
- jam();
- break;
- }//switch
- return;
-}//Dblqh::warningReport()
-
-void Dblqh::errorReport(Signal* signal, int place)
-{
- switch (place) {
- case 0:
- jam();
- break;
- case 1:
- jam();
- break;
- case 2:
- jam();
- break;
- case 3:
- jam();
- break;
- default:
- jam();
- break;
- }//switch
- systemErrorLab(signal, __LINE__);
- return;
-}//Dblqh::errorReport()
-
-/* ************************************************************************>>
- * COMMIT: Start commit request from TC. This signal is originally sent as a
- * packed signal and this function is called from execPACKED_SIGNAL.
- * This is the normal commit protocol where TC first send this signal to the
- * backup node which then will send COMMIT to the primary node. If
- * everything is ok the primary node send COMMITTED back to TC.
- * ************************************************************************>> */
-void Dblqh::execCOMMIT(Signal* signal)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- Uint32 tcIndex = signal->theData[0];
- Uint32 gci = signal->theData[1];
- Uint32 transid1 = signal->theData[2];
- Uint32 transid2 = signal->theData[3];
- jamEntry();
- if (tcIndex >= ttcConnectrecFileSize) {
- errorReport(signal, 0);
- return;
- }//if
- if (ERROR_INSERTED(5011)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMMIT, signal, 2000, 4);
- return;
- }//if
- if (ERROR_INSERTED(5012)) {
- SET_ERROR_INSERT_VALUE(5017);
- sendSignalWithDelay(cownref, GSN_COMMIT, signal, 2000, 4);
- return;
- }//if
- tcConnectptr.i = tcIndex;
- ptrAss(tcConnectptr, regTcConnectionrec);
- if ((tcConnectptr.p->transid[0] == transid1) &&
- (tcConnectptr.p->transid[1] == transid2)) {
-
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TRACE_OP(regTcPtr, "COMMIT");
-
- CRASH_INSERTION(5048);
- if (ERROR_INSERTED(5049))
- {
- SET_ERROR_INSERT_VALUE(5048);
- }
-
- commitReqLab(signal, gci);
- return;
- }//if
- warningReport(signal, 1);
- return;
-}//Dblqh::execCOMMIT()
-
-/* ************************************************************************>>
- * COMMITREQ: Commit request from TC. This is the commit protocol used if
- * one of the nodes is not behaving correctly. TC explicitly sends COMMITREQ
- * to both the backup and primary node and gets a COMMITCONF back if the
- * COMMIT was ok.
- * ************************************************************************>> */
-void Dblqh::execCOMMITREQ(Signal* signal)
-{
- jamEntry();
- Uint32 reqPtr = signal->theData[0];
- BlockReference reqBlockref = signal->theData[1];
- Uint32 gci = signal->theData[2];
- Uint32 transid1 = signal->theData[3];
- Uint32 transid2 = signal->theData[4];
- Uint32 tcOprec = signal->theData[6];
- if (ERROR_INSERTED(5004)) {
- systemErrorLab(signal, __LINE__);
- }
- if (ERROR_INSERTED(5017)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMMITREQ, signal, 2000, 7);
- return;
- }//if
- if (findTransaction(transid1,
- transid2,
- tcOprec) != ZOK) {
- warningReport(signal, 5);
- return;
- }//if
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::PREPARED:
- case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
- case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
- jam();
-/*-------------------------------------------------------*/
-/* THE NORMAL CASE. */
-/*-------------------------------------------------------*/
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
- commitReqLab(signal, gci);
- return;
- break;
- case TcConnectionrec::COMMITTED:
- jam();
-/*---------------------------------------------------------*/
-/* FOR SOME REASON THE COMMIT PHASE HAVE BEEN */
-/* FINISHED AFTER A TIME OUT. WE NEED ONLY SEND A */
-/* COMMITCONF SIGNAL. */
-/*---------------------------------------------------------*/
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
- signal->theData[0] = regTcPtr->reqRef;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = regTcPtr->transid[0];
- signal->theData[3] = regTcPtr->transid[1];
- sendSignal(regTcPtr->reqBlockref, GSN_COMMITCONF, signal, 4, JBB);
- break;
- case TcConnectionrec::COMMIT_STOPPED:
- case TcConnectionrec::WAIT_TUP_COMMIT:
- jam();
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
- /*empty*/;
- break;
- default:
- jam();
- warningReport(signal, 4);
- return;
- break;
- }//switch
- return;
-}//Dblqh::execCOMMITREQ()
-
-/* ************************************************************************>>
- * COMPLETE : Complete the transaction. Sent as a packed signal from TC.
- * Works the same way as COMMIT protocol. This is the normal case with both
- * primary and backup working (See COMMIT).
- * ************************************************************************>> */
-void Dblqh::execCOMPLETE(Signal* signal)
-{
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- Uint32 tcIndex = signal->theData[0];
- Uint32 transid1 = signal->theData[1];
- Uint32 transid2 = signal->theData[2];
- jamEntry();
- if (tcIndex >= ttcConnectrecFileSize) {
- errorReport(signal, 1);
- return;
- }//if
- if (ERROR_INSERTED(5042)) {
- ndbrequire(false);
- }
- if (ERROR_INSERTED(5013)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
- return;
- }//if
- if (ERROR_INSERTED(5014)) {
- SET_ERROR_INSERT_VALUE(5018);
- sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
- return;
- }//if
- tcConnectptr.i = tcIndex;
- ptrAss(tcConnectptr, regTcConnectionrec);
- if ((tcConnectptr.p->transactionState == TcConnectionrec::COMMITTED) &&
- (tcConnectptr.p->transid[0] == transid1) &&
- (tcConnectptr.p->transid[1] == transid2)) {
-
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TRACE_OP(regTcPtr, "COMPLETE");
-
- if (tcConnectptr.p->seqNoReplica != 0 &&
- tcConnectptr.p->activeCreat == Fragrecord::AC_NORMAL) {
- jam();
- localCommitLab(signal);
- return;
- }
- else if (tcConnectptr.p->seqNoReplica == 0)
- {
- jam();
- completeTransLastLab(signal);
- return;
- }
- else
- {
- jam();
- completeTransNotLastLab(signal);
- return;
- }
- }//if
- if (tcConnectptr.p->transactionState != TcConnectionrec::COMMITTED) {
- warningReport(signal, 2);
- } else {
- warningReport(signal, 3);
- }//if
-}//Dblqh::execCOMPLETE()
-
-/* ************************************************************************>>
- * COMPLETEREQ: Complete request from TC. Same as COMPLETE but used if one
- * node is not working ok (See COMMIT).
- * ************************************************************************>> */
-void Dblqh::execCOMPLETEREQ(Signal* signal)
-{
- jamEntry();
- Uint32 reqPtr = signal->theData[0];
- BlockReference reqBlockref = signal->theData[1];
- Uint32 transid1 = signal->theData[2];
- Uint32 transid2 = signal->theData[3];
- Uint32 tcOprec = signal->theData[5];
- if (ERROR_INSERTED(5005)) {
- systemErrorLab(signal, __LINE__);
- }
- if (ERROR_INSERTED(5018)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMPLETEREQ, signal, 2000, 6);
- return;
- }//if
- if (findTransaction(transid1,
- transid2,
- tcOprec) != ZOK) {
- jam();
-/*---------------------------------------------------------*/
-/* FOR SOME REASON THE COMPLETE PHASE STARTED AFTER */
-/* A TIME OUT. THE TRANSACTION IS GONE. WE NEED TO */
-/* REPORT COMPLETION ANYWAY. */
-/*---------------------------------------------------------*/
- signal->theData[0] = reqPtr;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = transid1;
- signal->theData[3] = transid2;
- sendSignal(reqBlockref, GSN_COMPLETECONF, signal, 4, JBB);
- warningReport(signal, 7);
- return;
- }//if
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::COMMITTED:
- jam();
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
- /*empty*/;
- break;
-/*---------------------------------------------------------*/
-/* THE NORMAL CASE. */
-/*---------------------------------------------------------*/
- case TcConnectionrec::COMMIT_STOPPED:
- case TcConnectionrec::WAIT_TUP_COMMIT:
- jam();
-/*---------------------------------------------------------*/
-/* FOR SOME REASON THE COMPLETE PHASE STARTED AFTER */
-/* A TIME OUT. WE HAVE SET THE PROPER VARIABLES SUCH */
-/* THAT A COMPLETECONF WILL BE SENT WHEN COMPLETE IS */
-/* FINISHED. */
-/*---------------------------------------------------------*/
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
- return;
- break;
- default:
- jam();
- warningReport(signal, 6);
- return;
- break;
- }//switch
- if (regTcPtr->seqNoReplica != 0 &&
- regTcPtr->activeCreat != Fragrecord::AC_NR_COPY) {
- jam();
- localCommitLab(signal);
- }
- else if (regTcPtr->seqNoReplica == 0)
- {
- jam();
- completeTransLastLab(signal);
- }
- else
- {
- jam();
- completeTransNotLastLab(signal);
- }
-}//Dblqh::execCOMPLETEREQ()
-
-/* ************> */
-/* COMPLETED > */
-/* ************> */
-void Dblqh::execLQHKEYCONF(Signal* signal)
-{
- LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
- Uint32 tcIndex = lqhKeyConf->opPtr;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- jamEntry();
- if (tcIndex >= ttcConnectrecFileSize) {
- errorReport(signal, 2);
- return;
- }//if
- tcConnectptr.i = tcIndex;
- ptrAss(tcConnectptr, regTcConnectionrec);
- switch (tcConnectptr.p->connectState) {
- case TcConnectionrec::LOG_CONNECTED:
- jam();
- completedLab(signal);
- return;
- break;
- case TcConnectionrec::COPY_CONNECTED:
- jam();
- copyCompletedLab(signal);
- return;
- break;
- default:
- jam();
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dblqh::execLQHKEYCONF()
-
-/* ------------------------------------------------------------------------- */
-/* ------- COMMIT PHASE ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::commitReqLab(Signal* signal, Uint32 gci)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
- TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
- regTcPtr->gci = gci;
- if (transState == TcConnectionrec::PREPARED) {
- if (logWriteState == TcConnectionrec::WRITTEN) {
- jam();
- regTcPtr->transactionState = TcConnectionrec::PREPARED_RECEIVED_COMMIT;
- TcConnectionrecPtr saveTcPtr = tcConnectptr;
- Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
- signal->theData[0] = regTcPtr->tupConnectrec;
- signal->theData[1] = gci;
- EXECUTE_DIRECT(blockNo, GSN_TUP_WRITELOG_REQ, signal, 2);
- jamEntry();
- if (regTcPtr->transactionState == TcConnectionrec::LOG_COMMIT_QUEUED) {
- jam();
- return;
- }//if
- ndbrequire(regTcPtr->transactionState == TcConnectionrec::LOG_COMMIT_WRITTEN);
- tcConnectptr = saveTcPtr;
- } else if (logWriteState == TcConnectionrec::NOT_STARTED) {
- jam();
- } else if (logWriteState == TcConnectionrec::NOT_WRITTEN) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* IT IS A READ OPERATION OR OTHER OPERATION THAT DO NOT USE THE LOG. */
-/*---------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------*/
-/* THE LOG HAS NOT BEEN WRITTEN SINCE THE LOG FLAG WAS FALSE. THIS CAN OCCUR */
-/* WHEN WE ARE STARTING A NEW FRAGMENT. */
-/*---------------------------------------------------------------------------*/
- regTcPtr->logWriteState = TcConnectionrec::NOT_STARTED;
- } else {
- ndbrequire(logWriteState == TcConnectionrec::NOT_WRITTEN_WAIT);
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE STATE WAS SET TO NOT_WRITTEN BY THE OPERATION BUT LATER A SCAN OF ALL */
-/* OPERATION RECORD CHANGED IT INTO NOT_WRITTEN_WAIT. THIS INDICATES THAT WE */
-/* ARE WAITING FOR THIS OPERATION TO COMMIT OR ABORT SO THAT WE CAN FIND THE */
-/* STARTING GLOBAL CHECKPOINT OF THIS NEW FRAGMENT. */
-/*---------------------------------------------------------------------------*/
- checkScanTcCompleted(signal);
- }//if
- } else if (transState == TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL) {
- jam();
- regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED;
- return;
- } else if (transState == TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL) {
- jam();
- } else {
- warningReport(signal, 0);
- return;
- }//if
- if (regTcPtr->seqNoReplica == 0 ||
- regTcPtr->activeCreat == Fragrecord::AC_NR_COPY) {
- jam();
- localCommitLab(signal);
- return;
- }//if
- commitReplyLab(signal);
- return;
-}//Dblqh::commitReqLab()
-
-void Dblqh::execLQH_WRITELOG_REQ(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Uint32 gci = signal->theData[1];
- Uint32 newestGci = cnewestGci;
- TcConnectionrec::LogWriteState logWriteState = regTcPtr->logWriteState;
- TcConnectionrec::TransactionState transState = regTcPtr->transactionState;
- regTcPtr->gci = gci;
- if (gci > newestGci) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* KEEP TRACK OF NEWEST GLOBAL CHECKPOINT THAT LQH HAS HEARD OF. */
-/* ------------------------------------------------------------------------- */
- cnewestGci = gci;
- }//if
- if (logWriteState == TcConnectionrec::WRITTEN) {
-/*---------------------------------------------------------------------------*/
-/* I NEED TO INSERT A COMMIT LOG RECORD SINCE WE ARE WRITING LOG IN THIS */
-/* TRANSACTION. */
-/*---------------------------------------------------------------------------*/
- jam();
- LogPartRecordPtr regLogPartPtr;
- Uint32 noOfLogPages = cnoOfLogPages;
- jam();
- regLogPartPtr.i = regTcPtr->m_log_part_ptr_i;
- ptrCheckGuard(regLogPartPtr, clogPartFileSize, logPartRecord);
- if ((regLogPartPtr.p->logPartState == LogPartRecord::ACTIVE) ||
- (noOfLogPages == 0)) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS LOG PART WAS CURRENTLY ACTIVE WRITING ANOTHER LOG RECORD. WE MUST */
-/* WAIT UNTIL THIS PART HAS COMPLETED ITS OPERATION. */
-/*---------------------------------------------------------------------------*/
-// We must delay the write of commit info to the log to safe-guard against
-// a crash due to lack of log pages. We temporary stop all log writes to this
-// log part to ensure that we don't get a buffer explosion in the delayed
-// signal buffer instead.
-/*---------------------------------------------------------------------------*/
- linkWaitLog(signal, regLogPartPtr);
- if (transState == TcConnectionrec::PREPARED) {
- jam();
- regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL;
- } else {
- jam();
- ndbrequire(transState == TcConnectionrec::PREPARED_RECEIVED_COMMIT);
- regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_QUEUED;
- }//if
- if (regLogPartPtr.p->logPartState == LogPartRecord::IDLE) {
- jam();
- regLogPartPtr.p->logPartState = LogPartRecord::ACTIVE;
- }//if
- return;
- }//if
- writeCommitLog(signal, regLogPartPtr);
- if (transState == TcConnectionrec::PREPARED) {
- jam();
- regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL;
- } else {
- jam();
- ndbrequire(transState == TcConnectionrec::PREPARED_RECEIVED_COMMIT);
- regTcPtr->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN;
- }//if
- }//if
-}//Dblqh::execLQH_WRITELOG_REQ()
-
-void Dblqh::localCommitLab(Signal* signal)
-{
- FragrecordPtr regFragptr;
- regFragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
- Fragrecord::FragStatus status = regFragptr.p->fragStatus;
- fragptr = regFragptr;
- switch (status) {
- case Fragrecord::FSACTIVE:
- case Fragrecord::CRASH_RECOVERING:
- case Fragrecord::ACTIVE_CREATION:
- jam();
- commitContinueAfterBlockedLab(signal);
- return;
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::COMMIT_STOPPED;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- break;
- }//switch
-}//Dblqh::localCommitLab()
-
-void Dblqh::commitContinueAfterBlockedLab(Signal* signal)
-{
-/* ------------------------------------------------------------------------- */
-/*INPUT: TC_CONNECTPTR ACTIVE OPERATION RECORD */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/*CONTINUE HERE AFTER BEING BLOCKED FOR A WHILE DURING LOCAL CHECKPOINT. */
-/*The operation is already removed from the active list since there is no */
-/*chance for any real-time breaks before we need to release it. */
-/* ------------------------------------------------------------------------- */
-/*ALSO AFTER NORMAL PROCEDURE WE CONTINUE */
-/*WE MUST COMMIT TUP BEFORE ACC TO ENSURE THAT NO ONE RACES IN AND SEES A */
-/*DIRTY STATE IN TUP. */
-/* ------------------------------------------------------------------------- */
- Ptr<TcConnectionrec> regTcPtr = tcConnectptr;
- Ptr<Fragrecord> regFragptr = fragptr;
- Uint32 operation = regTcPtr.p->operation;
- Uint32 dirtyOp = regTcPtr.p->dirtyOp;
- Uint32 opSimple = regTcPtr.p->opSimple;
- if (regTcPtr.p->activeCreat != Fragrecord::AC_IGNORED) {
- if (operation != ZREAD) {
- TupCommitReq * const tupCommitReq =
- (TupCommitReq *)signal->getDataPtrSend();
- Uint32 sig0 = regTcPtr.p->tupConnectrec;
- Uint32 tup = refToBlock(regTcPtr.p->tcTupBlockref);
- jam();
- tupCommitReq->opPtr = sig0;
- tupCommitReq->gci = regTcPtr.p->gci;
- tupCommitReq->hashValue = regTcPtr.p->hashValue;
- tupCommitReq->diskpage = RNIL;
- EXECUTE_DIRECT(tup, GSN_TUP_COMMITREQ, signal,
- TupCommitReq::SignalLength);
-
- if(signal->theData[0] != 0)
- {
- regTcPtr.p->transactionState = TcConnectionrec::WAIT_TUP_COMMIT;
- return; // TUP_COMMIT was timesliced
- }
-
- if (TRACENR_FLAG)
- {
- TRACENR("COMMIT: ");
- switch (regTcPtr.p->operation) {
- case ZREAD: TRACENR("READ"); break;
- case ZUPDATE: TRACENR("UPDATE"); break;
- case ZWRITE: TRACENR("WRITE"); break;
- case ZINSERT: TRACENR("INSERT"); break;
- case ZDELETE: TRACENR("DELETE"); break;
- }
-
- TRACENR(" tab: " << regTcPtr.p->tableref
- << " frag: " << regTcPtr.p->fragmentid
- << " activeCreat: " << (Uint32)regTcPtr.p->activeCreat);
- if (LqhKeyReq::getNrCopyFlag(regTcPtr.p->reqinfo))
- TRACENR(" NrCopy");
- if (LqhKeyReq::getRowidFlag(regTcPtr.p->reqinfo))
- TRACENR(" rowid: " << regTcPtr.p->m_row_id);
- TRACENR(" key: " << regTcPtr.p->tupkeyData[0]);
- TRACENR(endl);
- }
-
- TRACE_OP(regTcPtr.p, "ACC_COMMITREQ");
-
- Uint32 acc = refToBlock(regTcPtr.p->tcAccBlockref);
- signal->theData[0] = regTcPtr.p->accConnectrec;
- EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
-
- } else {
- if(!dirtyOp){
- TRACE_OP(regTcPtr.p, "ACC_COMMITREQ");
-
- Uint32 acc = refToBlock(regTcPtr.p->tcAccBlockref);
- signal->theData[0] = regTcPtr.p->accConnectrec;
- EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
- }
-
- if (dirtyOp)
- {
- jam();
- /**
- * The dirtyRead does not send anything but TRANSID_AI from LDM
- */
- fragptr = regFragptr;
- tcConnectptr = regTcPtr;
- cleanUp(signal);
- return;
- }
-
- /**
- * The simpleRead will send a LQHKEYCONF
- * but have already released the locks
- */
- if (opSimple)
- {
- fragptr = regFragptr;
- tcConnectptr = regTcPtr;
- packLqhkeyreqLab(signal);
- return;
- }
- }
- }//if
- jamEntry();
- fragptr = regFragptr;
- tcConnectptr = regTcPtr;
- tupcommit_conf(signal, regTcPtr.p, regFragptr.p);
-}
-
-void
-Dblqh::tupcommit_conf_callback(Signal* signal, Uint32 tcPtrI)
-{
- jamEntry();
-
- tcConnectptr.i = tcPtrI;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * tcPtr = tcConnectptr.p;
-
- ndbrequire(tcPtr->transactionState == TcConnectionrec::WAIT_TUP_COMMIT);
-
- FragrecordPtr regFragptr;
- regFragptr.i = tcPtr->fragmentptr;
- c_fragment_pool.getPtr(regFragptr);
- fragptr = regFragptr;
-
- TRACE_OP(tcPtr, "ACC_COMMITREQ");
-
- Uint32 acc = refToBlock(tcPtr->tcAccBlockref);
- signal->theData[0] = tcPtr->accConnectrec;
- EXECUTE_DIRECT(acc, GSN_ACC_COMMITREQ, signal, 1);
- jamEntry();
-
- tcConnectptr.i = tcPtrI;
- tcConnectptr.p = tcPtr;
- tupcommit_conf(signal, tcPtr, regFragptr.p);
-}
-
-void
-Dblqh::tupcommit_conf(Signal* signal,
- TcConnectionrec * tcPtrP,
- Fragrecord * regFragptr)
-{
- Uint32 dirtyOp = tcPtrP->dirtyOp;
- Uint32 seqNoReplica = tcPtrP->seqNoReplica;
- Uint32 activeCreat = tcPtrP->activeCreat;
- if (tcPtrP->gci > regFragptr->newestGci) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*IT IS THE FIRST TIME THIS GLOBAL CHECKPOINT IS INVOLVED IN UPDATING THIS */
-/*FRAGMENT. UPDATE THE VARIABLE THAT KEEPS TRACK OF NEWEST GCI IN FRAGMENT */
-/* ------------------------------------------------------------------------- */
- regFragptr->newestGci = tcPtrP->gci;
- }//if
- if (dirtyOp != ZTRUE)
- {
- if (seqNoReplica == 0 || activeCreat == Fragrecord::AC_NR_COPY)
- {
- jam();
- commitReplyLab(signal);
- return;
- }//if
- if (seqNoReplica == 0)
- {
- jam();
- completeTransLastLab(signal);
- }
- else
- {
- jam();
- completeTransNotLastLab(signal);
- }
- return;
- } else {
-/* ------------------------------------------------------------------------- */
-/*WE MUST HANDLE DIRTY WRITES IN A SPECIAL WAY. THESE OPERATIONS WILL NOT */
-/*SEND ANY COMMIT OR COMPLETE MESSAGES TO OTHER NODES. THEY WILL MERELY SEND */
-/*THOSE SIGNALS INTERNALLY. */
-/* ------------------------------------------------------------------------- */
- if (tcPtrP->abortState == TcConnectionrec::ABORT_IDLE)
- {
- jam();
- if (activeCreat == Fragrecord::AC_NR_COPY)
- {
- jam();
- ndbrequire(LqhKeyReq::getNrCopyFlag(tcPtrP->reqinfo));
- ndbrequire(tcPtrP->m_nr_delete.m_cnt == 0);
- }
- packLqhkeyreqLab(signal);
- }
- else
- {
- ndbrequire(tcPtrP->abortState != TcConnectionrec::NEW_FROM_TC);
- jam();
- sendLqhTransconf(signal, LqhTransConf::Committed);
- cleanUp(signal);
- }//if
- }//if
-}//Dblqh::commitContinueAfterBlockedLab()
-
-void Dblqh::commitReplyLab(Signal* signal)
-{
-/* -------------------------------------------------------------- */
-/* BACKUP AND STAND-BY REPLICAS ONLY UPDATE THE TRANSACTION STATE */
-/* -------------------------------------------------------------- */
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- TcConnectionrec::AbortState abortState = regTcPtr->abortState;
- regTcPtr->transactionState = TcConnectionrec::COMMITTED;
- if (abortState == TcConnectionrec::ABORT_IDLE) {
- Uint32 clientBlockref = regTcPtr->clientBlockref;
- if (regTcPtr->seqNoReplica == 0) {
- jam();
- sendCommittedTc(signal, clientBlockref);
- return;
- } else {
- jam();
- sendCommitLqh(signal, clientBlockref);
- return;
- }//if
- } else if (regTcPtr->abortState == TcConnectionrec::REQ_FROM_TC) {
- jam();
- signal->theData[0] = regTcPtr->reqRef;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = regTcPtr->transid[0];
- signal->theData[3] = regTcPtr->transid[1];
- sendSignal(tcConnectptr.p->reqBlockref, GSN_COMMITCONF, signal, 4, JBB);
- } else {
- ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
- jam();
- sendLqhTransconf(signal, LqhTransConf::Committed);
- }//if
- return;
-}//Dblqh::commitReplyLab()
-
-/* ------------------------------------------------------------------------- */
-/* ------- COMPLETE PHASE ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::completeTransNotLastLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
- Uint32 clientBlockref = regTcPtr->clientBlockref;
- jam();
- sendCompleteLqh(signal, clientBlockref);
- cleanUp(signal);
- return;
- } else {
- jam();
- completeUnusualLab(signal);
- return;
- }//if
-}//Dblqh::completeTransNotLastLab()
-
-void Dblqh::completeTransLastLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
- Uint32 clientBlockref = regTcPtr->clientBlockref;
- jam();
-/* ------------------------------------------------------------------------- */
-/*DIRTY WRITES WHICH ARE LAST IN THE CHAIN OF REPLICAS WILL SEND COMPLETED */
-/*INSTEAD OF SENDING PREPARED TO THE TC (OR OTHER INITIATOR OF OPERATION). */
-/* ------------------------------------------------------------------------- */
- sendCompletedTc(signal, clientBlockref);
- cleanUp(signal);
- return;
- } else {
- jam();
- completeUnusualLab(signal);
- return;
- }//if
-}//Dblqh::completeTransLastLab()
-
-void Dblqh::completeUnusualLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->abortState == TcConnectionrec::ABORT_FROM_TC) {
- jam();
- sendAborted(signal);
- } else if (regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- sendLqhTransconf(signal, LqhTransConf::Committed);
- } else {
- ndbrequire(regTcPtr->abortState == TcConnectionrec::REQ_FROM_TC);
- jam();
- signal->theData[0] = regTcPtr->reqRef;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = regTcPtr->transid[0];
- signal->theData[3] = regTcPtr->transid[1];
- sendSignal(regTcPtr->reqBlockref,
- GSN_COMPLETECONF, signal, 4, JBB);
- }//if
- cleanUp(signal);
- return;
-}//Dblqh::completeUnusualLab()
-
-/* ========================================================================= */
-/* ======= RELEASE TC CONNECT RECORD ======= */
-/* */
-/* RELEASE A TC CONNECT RECORD TO THE FREELIST. */
-/* ========================================================================= */
-void Dblqh::releaseTcrec(Signal* signal, TcConnectionrecPtr locTcConnectptr)
-{
- jam();
- locTcConnectptr.p->tcTimer = 0;
- locTcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED;
- locTcConnectptr.p->nextTcConnectrec = cfirstfreeTcConrec;
- cfirstfreeTcConrec = locTcConnectptr.i;
-
- TablerecPtr tabPtr;
- tabPtr.i = locTcConnectptr.p->tableref;
- if(tabPtr.i == RNIL)
- return;
-
- ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
-
- /**
- * Normal case
- */
- ndbrequire(tabPtr.p->usageCount > 0);
- tabPtr.p->usageCount--;
-}//Dblqh::releaseTcrec()
-
-void Dblqh::releaseTcrecLog(Signal* signal, TcConnectionrecPtr locTcConnectptr)
-{
- jam();
- locTcConnectptr.p->tcTimer = 0;
- locTcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED;
- locTcConnectptr.p->nextTcConnectrec = cfirstfreeTcConrec;
- cfirstfreeTcConrec = locTcConnectptr.i;
-
- TablerecPtr tabPtr;
- tabPtr.i = locTcConnectptr.p->tableref;
- if(tabPtr.i == RNIL)
- return;
-
-}//Dblqh::releaseTcrecLog()
-
-/* ------------------------------------------------------------------------- */
-/* ------- ABORT PHASE ------- */
-/* */
-/*THIS PART IS USED AT ERRORS THAT CAUSE ABORT OF TRANSACTION. */
-/* ------------------------------------------------------------------------- */
-/* ***************************************************>> */
-/* ABORT: Abort transaction in connection. Sender TC. */
-/* This is the normal protocol (See COMMIT) */
-/* ***************************************************>> */
-void Dblqh::execABORT(Signal* signal)
-{
- jamEntry();
- Uint32 tcOprec = signal->theData[0];
- BlockReference tcBlockref = signal->theData[1];
- Uint32 transid1 = signal->theData[2];
- Uint32 transid2 = signal->theData[3];
- CRASH_INSERTION(5003);
- if (ERROR_INSERTED(5015)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_ABORT, signal, 2000, 4);
- return;
- }//if
- if (findTransaction(transid1,
- transid2,
- tcOprec) != ZOK) {
- jam();
-
- if(ERROR_INSERTED(5039) &&
- refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
- jam();
- SET_ERROR_INSERT_VALUE(5040);
- return;
- }
-
- if(ERROR_INSERTED(5040) &&
- refToNode(signal->getSendersBlockRef()) != getOwnNodeId()){
- jam();
- SET_ERROR_INSERT_VALUE(5003);
- return;
- }
-
-/* ------------------------------------------------------------------------- */
-// SEND ABORTED EVEN IF NOT FOUND.
-//THE TRANSACTION MIGHT NEVER HAVE ARRIVED HERE.
-/* ------------------------------------------------------------------------- */
- signal->theData[0] = tcOprec;
- signal->theData[1] = transid1;
- signal->theData[2] = transid2;
- signal->theData[3] = cownNodeid;
- signal->theData[4] = ZTRUE;
- sendSignal(tcBlockref, GSN_ABORTED, signal, 5, JBB);
- warningReport(signal, 8);
- return;
- }//if
-
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (ERROR_INSERTED(5100))
- {
- SET_ERROR_INSERT_VALUE(5101);
- return;
- }
- CRASH_INSERTION2(5101, regTcPtr->nextReplica != ZNIL);
-
-/* ------------------------------------------------------------------------- */
-/*A GUIDING DESIGN PRINCIPLE IN HANDLING THESE ERROR SITUATIONS HAVE BEEN */
-/*KEEP IT SIMPLE. THUS WE RATHER INSERT A WAIT AND SET THE ABORT_STATE TO */
-/*ACTIVE RATHER THAN WRITE NEW CODE TO HANDLE EVERY SPECIAL SITUATION. */
-/* ------------------------------------------------------------------------- */
- if (regTcPtr->nextReplica != ZNIL) {
-/* ------------------------------------------------------------------------- */
-// We will immediately send the ABORT message also to the next LQH node in line.
-/* ------------------------------------------------------------------------- */
- BlockReference TLqhRef = calcLqhBlockRef(regTcPtr->nextReplica);
- signal->theData[0] = regTcPtr->tcOprec;
- signal->theData[1] = regTcPtr->tcBlockref;
- signal->theData[2] = regTcPtr->transid[0];
- signal->theData[3] = regTcPtr->transid[1];
- sendSignal(TLqhRef, GSN_ABORT, signal, 4, JBB);
- }//if
- regTcPtr->abortState = TcConnectionrec::ABORT_FROM_TC;
-
- const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- if(commitAckMarker != RNIL)
- {
- jam();
-#ifdef MARKER_TRACE
- {
- CommitAckMarkerPtr tmp;
- m_commitAckMarkerHash.getPtr(tmp, commitAckMarker);
- ndbout_c("Ab2 marker[%.8x %.8x]", tmp.p->transid1, tmp.p->transid2);
- }
-#endif
- m_commitAckMarkerHash.release(commitAckMarker);
- regTcPtr->commitAckMarker = RNIL;
- }
-
- TRACE_OP(regTcPtr, "ABORT");
-
- abortStateHandlerLab(signal);
-
- return;
-}//Dblqh::execABORT()
-
-/* ************************************************************************>>
- * ABORTREQ: Same as ABORT but used in case one node isn't working ok.
- * (See COMMITREQ)
- * ************************************************************************>> */
-void Dblqh::execABORTREQ(Signal* signal)
-{
- jamEntry();
- Uint32 reqPtr = signal->theData[0];
- BlockReference reqBlockref = signal->theData[1];
- Uint32 transid1 = signal->theData[2];
- Uint32 transid2 = signal->theData[3];
- Uint32 tcOprec = signal->theData[5];
- if (ERROR_INSERTED(5006)) {
- systemErrorLab(signal, __LINE__);
- }
- if (ERROR_INSERTED(5016)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_ABORTREQ, signal, 2000, 6);
- return;
- }//if
- if (findTransaction(transid1,
- transid2,
- tcOprec) != ZOK) {
- signal->theData[0] = reqPtr;
- signal->theData[2] = cownNodeid;
- signal->theData[3] = transid1;
- signal->theData[4] = transid2;
- sendSignal(reqBlockref, GSN_ABORTCONF, signal, 5, JBB);
- warningReport(signal, 9);
- return;
- }//if
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->transactionState != TcConnectionrec::PREPARED) {
- warningReport(signal, 10);
- return;
- }//if
- regTcPtr->reqBlockref = reqBlockref;
- regTcPtr->reqRef = reqPtr;
- regTcPtr->abortState = TcConnectionrec::REQ_FROM_TC;
-
- abortCommonLab(signal);
- return;
-}//Dblqh::execABORTREQ()
-
-/* ************>> */
-/* ACC_TO_REF > */
-/* ************>> */
-void Dblqh::execACC_TO_REF(Signal* signal)
-{
- jamEntry();
- terrorCode = signal->theData[1];
- abortErrorLab(signal);
- return;
-}//Dblqh::execACC_TO_REF()
-
-/* ************> */
-/* ACCKEYREF > */
-/* ************> */
-void Dblqh::execACCKEYREF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- terrorCode = signal->theData[1];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * const tcPtr = tcConnectptr.p;
- switch (tcPtr->transactionState) {
- case TcConnectionrec::WAIT_ACC:
- jam();
- break;
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::ABORT_STOPPED:
- case TcConnectionrec::ABORT_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/*IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY. */
-/* ------------------------------------------------------------------------- */
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- const Uint32 errCode = terrorCode;
- tcPtr->errorCode = errCode;
-
- if (TRACENR_FLAG)
- {
- TRACENR("ACCKEYREF: " << errCode << " ");
- switch (tcPtr->operation) {
- case ZREAD: TRACENR("READ"); break;
- case ZUPDATE: TRACENR("UPDATE"); break;
- case ZWRITE: TRACENR("WRITE"); break;
- case ZINSERT: TRACENR("INSERT"); break;
- case ZDELETE: TRACENR("DELETE"); break;
- default: TRACENR("<Unknown: " << tcPtr->operation << ">"); break;
- }
-
- TRACENR(" tab: " << tcPtr->tableref
- << " frag: " << tcPtr->fragmentid
- << " activeCreat: " << (Uint32)tcPtr->activeCreat);
- if (LqhKeyReq::getNrCopyFlag(tcPtr->reqinfo))
- TRACENR(" NrCopy");
- if (LqhKeyReq::getRowidFlag(tcPtr->reqinfo))
- TRACENR(" rowid: " << tcPtr->m_row_id);
- TRACENR(" key: " << tcPtr->tupkeyData[0]);
- TRACENR(endl);
-
- }
-
- ndbrequire(tcPtr->activeCreat == Fragrecord::AC_NORMAL);
- ndbrequire(!LqhKeyReq::getNrCopyFlag(tcPtr->reqinfo));
-
- /**
- * Only primary replica can get ZTUPLE_ALREADY_EXIST || ZNO_TUPLE_FOUND
- *
- * Unless it's a simple or dirty read
- *
- * NOT TRUE!
- * 1) op1 - primary insert ok
- * 2) op1 - backup insert fail (log full or what ever)
- * 3) op1 - delete ok @ primary
- * 4) op1 - delete fail @ backup
- *
- * -> ZNO_TUPLE_FOUND is possible
- */
- ndbrequire
- (tcPtr->seqNoReplica == 0 ||
- errCode != ZTUPLE_ALREADY_EXIST ||
- (tcPtr->operation == ZREAD && (tcPtr->dirtyOp || tcPtr->opSimple)));
-
- tcPtr->abortState = TcConnectionrec::ABORT_FROM_LQH;
- abortCommonLab(signal);
- return;
-}//Dblqh::execACCKEYREF()
-
-void Dblqh::localAbortStateHandlerLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
- jam();
- return;
- }//if
- regTcPtr->abortState = TcConnectionrec::ABORT_FROM_LQH;
- regTcPtr->errorCode = terrorCode;
- abortStateHandlerLab(signal);
- return;
-}//Dblqh::localAbortStateHandlerLab()
-
-void Dblqh::abortStateHandlerLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- switch (regTcPtr->transactionState) {
- case TcConnectionrec::PREPARED:
- jam();
-/* ------------------------------------------------------------------------- */
-/*THE OPERATION IS ALREADY PREPARED AND SENT TO THE NEXT LQH OR BACK TO TC. */
-/*WE CAN SIMPLY CONTINUE WITH THE ABORT PROCESS. */
-/*IF IT WAS A CHECK FOR TRANSACTION STATUS THEN WE REPORT THE STATUS TO THE */
-/*NEW TC AND CONTINUE WITH THE NEXT OPERATION IN LQH. */
-/* ------------------------------------------------------------------------- */
- if (regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- sendLqhTransconf(signal, LqhTransConf::Prepared);
- return;
- }//if
- break;
- case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
- case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
- jam();
-/* ------------------------------------------------------------------------- */
-// We can only reach these states for multi-updates on a record in a transaction.
-// We know that at least one of those has received the COMMIT signal, thus we
-// declare us only prepared since we then receive the expected COMMIT signal.
-/* ------------------------------------------------------------------------- */
- ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
- sendLqhTransconf(signal, LqhTransConf::Prepared);
- break;
- case TcConnectionrec::WAIT_TUPKEYINFO:
- case TcConnectionrec::WAIT_ATTR:
- jam();
-/* ------------------------------------------------------------------------- */
-/* WE ARE CURRENTLY WAITING FOR MORE INFORMATION. WE CAN START THE ABORT */
-/* PROCESS IMMEDIATELY. THE KEYINFO AND ATTRINFO SIGNALS WILL BE DROPPED */
-/* SINCE THE ABORT STATE WILL BE SET. */
-/* ------------------------------------------------------------------------- */
- break;
- case TcConnectionrec::WAIT_TUP:
- jam();
-/* ------------------------------------------------------------------------- */
-// TUP is currently active. We have to wait for the TUPKEYREF or TUPKEYCONF
-// to arrive since we might otherwise jeopardise the local checkpoint
-// consistency in overload situations.
-/* ------------------------------------------------------------------------- */
- regTcPtr->transactionState = TcConnectionrec::WAIT_TUP_TO_ABORT;
- return;
- case TcConnectionrec::WAIT_ACC:
- jam();
-/* ------------------------------------------------------------------------- */
-// We start the abort immediately since the operation is still in the active
-// list and the fragment cannot have been frozen yet. By sending LCP_HOLDOPCONF
-// as direct signals we avoid the problem that we might find the operation
-// in an unexpected list in ACC.
-// We cannot accept being blocked before aborting ACC here since that would
-// lead to seriously complex issues.
-/* ------------------------------------------------------------------------- */
- abortContinueAfterBlockedLab(signal, false);
- return;
- break;
- case TcConnectionrec::LOG_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/*CURRENTLY QUEUED FOR LOGGING. WAIT UNTIL THE LOG RECORD HAVE BEEN INSERTED */
-/*AND THEN CONTINUE THE ABORT PROCESS. */
-//Could also be waiting for an overloaded log disk. In this case it is easy
-//to abort when CONTINUEB arrives.
-/* ------------------------------------------------------------------------- */
- return;
- break;
- case TcConnectionrec::STOPPED:
- jam();
- /* ---------------------------------------------------------------------
- * WE ARE CURRENTLY QUEUED FOR ACCESS TO THE FRAGMENT BY A LCP
- * Since nothing has been done, just release operation
- * i.e. no prepare log record has been written
- * so no abort log records needs to be written
- */
- releaseWaitQueue(signal);
- continueAfterLogAbortWriteLab(signal);
- return;
- break;
- case TcConnectionrec::WAIT_AI_AFTER_ABORT:
- jam();
-/* ------------------------------------------------------------------------- */
-/* ABORT OF ACC AND TUP ALREADY COMPLETED. THIS STATE IS ONLY USED WHEN */
-/* CREATING A NEW FRAGMENT. */
-/* ------------------------------------------------------------------------- */
- continueAbortLab(signal);
- return;
- break;
- case TcConnectionrec::WAIT_TUP_TO_ABORT:
- case TcConnectionrec::ABORT_STOPPED:
- case TcConnectionrec::LOG_ABORT_QUEUED:
- case TcConnectionrec::WAIT_ACC_ABORT:
- case TcConnectionrec::ABORT_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/*ABORT IS ALREADY ONGOING DUE TO SOME ERROR. WE HAVE ALREADY SET THE STATE */
-/*OF THE ABORT SO THAT WE KNOW THAT TC EXPECTS A REPORT. WE CAN THUS SIMPLY */
-/*EXIT. */
-/* ------------------------------------------------------------------------- */
- return;
- break;
- case TcConnectionrec::WAIT_TUP_COMMIT:
- case TcConnectionrec::COMMIT_STOPPED:
- case TcConnectionrec::LOG_COMMIT_QUEUED:
- case TcConnectionrec::COMMIT_QUEUED:
- jam();
-/* ------------------------------------------------------------------------- */
-/*THIS IS ONLY AN ALLOWED STATE IF A DIRTY WRITE OR SIMPLE READ IS PERFORMED.*/
-/*IF WE ARE MERELY CHECKING THE TRANSACTION STATE IT IS ALSO AN ALLOWED STATE*/
-/* ------------------------------------------------------------------------- */
- if (regTcPtr->dirtyOp == ZTRUE) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*COMPLETE THE DIRTY WRITE AND THEN REPORT COMPLETED BACK TO TC. SINCE IT IS */
-/*A DIRTY WRITE IT IS ALLOWED TO COMMIT EVEN IF THE TRANSACTION ABORTS. */
-/* ------------------------------------------------------------------------- */
- return;
- }//if
- if (regTcPtr->opSimple) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*A SIMPLE READ IS CURRENTLY RELEASING THE LOCKS OR WAITING FOR ACCESS TO */
-/*ACC TO CLEAR THE LOCKS. COMPLETE THIS PROCESS AND THEN RETURN AS NORMAL. */
-/*NO DATA HAS CHANGED DUE TO THIS SIMPLE READ ANYWAY. */
-/* ------------------------------------------------------------------------- */
- return;
- }//if
- ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
- jam();
-/* ------------------------------------------------------------------------- */
-/*WE ARE ONLY CHECKING THE STATUS OF THE TRANSACTION. IT IS COMMITTING. */
-/*COMPLETE THE COMMIT LOCALLY AND THEN SEND REPORT OF COMMITTED TO THE NEW TC*/
-/* ------------------------------------------------------------------------- */
- return;
- break;
- case TcConnectionrec::COMMITTED:
- jam();
- ndbrequire(regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC);
-/* ------------------------------------------------------------------------- */
-/*WE ARE CHECKING TRANSACTION STATUS. REPORT COMMITTED AND CONTINUE WITH THE */
-/*NEXT OPERATION. */
-/* ------------------------------------------------------------------------- */
- sendLqhTransconf(signal, LqhTransConf::Committed);
- return;
- break;
- default:
- ndbrequire(false);
-/* ------------------------------------------------------------------------- */
-/*THE STATE WAS NOT AN ALLOWED STATE ON A NORMAL OPERATION. SCANS AND COPY */
-/*FRAGMENT OPERATIONS SHOULD HAVE EXECUTED IN ANOTHER PATH. */
-/* ------------------------------------------------------------------------- */
- break;
- }//switch
- abortCommonLab(signal);
- return;
-}//Dblqh::abortStateHandlerLab()
-
-void Dblqh::abortErrorLab(Signal* signal)
-{
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->abortState == TcConnectionrec::ABORT_IDLE) {
- jam();
- regTcPtr->abortState = TcConnectionrec::ABORT_FROM_LQH;
- regTcPtr->errorCode = terrorCode;
- }//if
- abortCommonLab(signal);
- return;
-}//Dblqh::abortErrorLab()
-
-void Dblqh::abortCommonLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- const Uint32 activeCreat = regTcPtr->activeCreat;
- if (commitAckMarker != RNIL)
- {
- /**
- * There is no NR ongoing and we have a marker
- */
- jam();
-#ifdef MARKER_TRACE
- {
- CommitAckMarkerPtr tmp;
- m_commitAckMarkerHash.getPtr(tmp, commitAckMarker);
- ndbout_c("Abo marker[%.8x %.8x]", tmp.p->transid1, tmp.p->transid2);
- }
-#endif
- m_commitAckMarkerHash.release(commitAckMarker);
- regTcPtr->commitAckMarker = RNIL;
- }
-
- if (unlikely(activeCreat == Fragrecord::AC_NR_COPY))
- {
- jam();
- if (regTcPtr->m_nr_delete.m_cnt)
- {
- jam();
- /**
- * Let operation wait for pending NR operations
- */
-
-#ifdef VM_TRACE
- /**
- * Only disk table can have pending ops...
- */
- TablerecPtr tablePtr;
- tablePtr.i = regTcPtr->tableref;
- ptrCheckGuard(tablePtr, ctabrecFileSize, tablerec);
- ndbrequire(tablePtr.p->m_disk_table);
-#endif
- return;
- }
- }
-
- fragptr.i = regTcPtr->fragmentptr;
- if (fragptr.i != RNIL) {
- jam();
- c_fragment_pool.getPtr(fragptr);
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- case Fragrecord::CRASH_RECOVERING:
- case Fragrecord::ACTIVE_CREATION:
- jam();
- abortContinueAfterBlockedLab(signal, true);
- return;
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- regTcPtr->transactionState = TcConnectionrec::ABORT_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- break;
- }//switch
- } else {
- jam();
- continueAbortLab(signal);
- }//if
-}//Dblqh::abortCommonLab()
-
-void Dblqh::abortContinueAfterBlockedLab(Signal* signal, bool canBlock)
-{
- /* ------------------------------------------------------------------------
- * INPUT: TC_CONNECTPTR ACTIVE OPERATION RECORD
- * ------------------------------------------------------------------------
- * ------------------------------------------------------------------------
- * CAN COME HERE AS RESTART AFTER BEING BLOCKED BY A LOCAL CHECKPOINT.
- * ------------------------------------------------------------------------
- * ALSO AS PART OF A NORMAL ABORT WITHOUT BLOCKING.
- * WE MUST ABORT TUP BEFORE ACC TO ENSURE THAT NO ONE RACES IN
- * AND SEES A STATE IN TUP.
- * ----------------------------------------------------------------------- */
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
-
- TRACE_OP(regTcPtr, "ACC ABORT");
-
- regTcPtr->transactionState = TcConnectionrec::WAIT_ACC_ABORT;
- signal->theData[0] = regTcPtr->accConnectrec;
- signal->theData[1] = 2; // JOB BUFFER IF NEEDED
- EXECUTE_DIRECT(DBACC, GSN_ACC_ABORTREQ, signal, 2);
-
- if (signal->theData[1] == RNIL)
- {
- jam();
- /* ------------------------------------------------------------------------
- * We need to insert a real-time break by sending ACC_ABORTCONF through the
- * job buffer to ensure that we catch any ACCKEYCONF or TUPKEYCONF or
- * TUPKEYREF that are in the job buffer but not yet processed. Doing
- * everything without that would race and create a state error when they
- * are executed.
- * --------------------------------------------------------------------- */
- return;
- }
-
- execACC_ABORTCONF(signal);
- return;
-}//Dblqh::abortContinueAfterBlockedLab()
-
-/* ******************>> */
-/* ACC_ABORTCONF > */
-/* ******************>> */
-void Dblqh::execACC_ABORTCONF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- ndbrequire(regTcPtr->transactionState == TcConnectionrec::WAIT_ACC_ABORT);
-
- TRACE_OP(regTcPtr, "ACC_ABORTCONF");
- signal->theData[0] = regTcPtr->tupConnectrec;
- EXECUTE_DIRECT(DBTUP, GSN_TUP_ABORTREQ, signal, 1);
-
- jamEntry();
- continueAbortLab(signal);
- return;
-}//Dblqh::execACC_ABORTCONF()
-
-void Dblqh::continueAbortLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- /* ------------------------------------------------------------------------
- * AN ERROR OCCURED IN THE ACTIVE CREATION AFTER THE ABORT PHASE.
- * WE NEED TO CONTINUE WITH A NORMAL ABORT.
- * ------------------------------------------------------------------------
- * ALSO USED FOR NORMAL CLEAN UP AFTER A NORMAL ABORT.
- * ------------------------------------------------------------------------
- * ALSO USED WHEN NO FRAGMENT WAS SET UP ON OPERATION.
- * ------------------------------------------------------------------------ */
- if (regTcPtr->logWriteState == TcConnectionrec::WRITTEN) {
- jam();
- /* ----------------------------------------------------------------------
- * I NEED TO INSERT A ABORT LOG RECORD SINCE WE ARE WRITING LOG IN THIS
- * TRANSACTION.
- * ---------------------------------------------------------------------- */
- initLogPointers(signal);
- if (logPartPtr.p->logPartState == LogPartRecord::ACTIVE) {
- jam();
- /* --------------------------------------------------------------------
- * A PREPARE OPERATION IS CURRENTLY WRITING IN THE LOG.
- * WE MUST WAIT ON OUR TURN TO WRITE THE LOG.
- * IT IS NECESSARY TO WRITE ONE LOG RECORD COMPLETELY
- * AT A TIME OTHERWISE WE WILL SCRAMBLE THE LOG.
- * -------------------------------------------------------------------- */
- linkWaitLog(signal, logPartPtr);
- regTcPtr->transactionState = TcConnectionrec::LOG_ABORT_QUEUED;
- return;
- }//if
- if (cnoOfLogPages == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-// We must delay the write of commit info to the log to safe-guard against
-// a crash due to lack of log pages. We temporary stop all log writes to this
-// log part to ensure that we don't get a buffer explosion in the delayed
-// signal buffer instead.
-/*---------------------------------------------------------------------------*/
- linkWaitLog(signal, logPartPtr);
- regTcPtr->transactionState = TcConnectionrec::LOG_ABORT_QUEUED;
- if (logPartPtr.p->logPartState == LogPartRecord::IDLE) {
- jam();
- logPartPtr.p->logPartState = LogPartRecord::ACTIVE;
- }//if
- return;
- }//if
- writeAbortLog(signal);
- removeLogTcrec(signal);
- } else if (regTcPtr->logWriteState == TcConnectionrec::NOT_STARTED) {
- jam();
- } else if (regTcPtr->logWriteState == TcConnectionrec::NOT_WRITTEN) {
- jam();
- /* ------------------------------------------------------------------
- * IT IS A READ OPERATION OR OTHER OPERATION THAT DO NOT USE THE LOG.
- * ------------------------------------------------------------------ */
- /* ------------------------------------------------------------------
- * THE LOG HAS NOT BEEN WRITTEN SINCE THE LOG FLAG WAS FALSE.
- * THIS CAN OCCUR WHEN WE ARE STARTING A NEW FRAGMENT.
- * ------------------------------------------------------------------ */
- regTcPtr->logWriteState = TcConnectionrec::NOT_STARTED;
- } else {
- ndbrequire(regTcPtr->logWriteState == TcConnectionrec::NOT_WRITTEN_WAIT);
- jam();
- /* ----------------------------------------------------------------
- * THE STATE WAS SET TO NOT_WRITTEN BY THE OPERATION BUT LATER
- * A SCAN OF ALL OPERATION RECORD CHANGED IT INTO NOT_WRITTEN_WAIT.
- * THIS INDICATES THAT WE ARE WAITING FOR THIS OPERATION TO COMMIT
- * OR ABORT SO THAT WE CAN FIND THE
- * STARTING GLOBAL CHECKPOINT OF THIS NEW FRAGMENT.
- * ---------------------------------------------------------------- */
- checkScanTcCompleted(signal);
- }//if
- continueAfterLogAbortWriteLab(signal);
- return;
-}//Dblqh::continueAbortLab()
-
-void Dblqh::continueAfterLogAbortWriteLab(Signal* signal)
-{
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->operation == ZREAD && regTcPtr->dirtyOp)
- {
- jam();
- TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend();
-
- tcKeyRef->connectPtr = regTcPtr->applOprec;
- tcKeyRef->transId[0] = regTcPtr->transid[0];
- tcKeyRef->transId[1] = regTcPtr->transid[1];
- tcKeyRef->errorCode = regTcPtr->errorCode;
- sendTCKEYREF(signal, regTcPtr->applRef, regTcPtr->clientBlockref, 0);
- cleanUp(signal);
- return;
- }//if
- if (regTcPtr->abortState == TcConnectionrec::ABORT_FROM_LQH) {
- LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtrSend();
-
- jam();
- lqhKeyRef->userRef = regTcPtr->clientConnectrec;
- lqhKeyRef->connectPtr = regTcPtr->tcOprec;
- lqhKeyRef->errorCode = regTcPtr->errorCode;
- lqhKeyRef->transId1 = regTcPtr->transid[0];
- lqhKeyRef->transId2 = regTcPtr->transid[1];
- sendSignal(regTcPtr->clientBlockref, GSN_LQHKEYREF, signal,
- LqhKeyRef::SignalLength, JBB);
- } else if (regTcPtr->abortState == TcConnectionrec::ABORT_FROM_TC) {
- jam();
- sendAborted(signal);
- } else if (regTcPtr->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- sendLqhTransconf(signal, LqhTransConf::Aborted);
- } else {
- ndbrequire(regTcPtr->abortState == TcConnectionrec::REQ_FROM_TC);
- jam();
- signal->theData[0] = regTcPtr->reqRef;
- signal->theData[1] = tcConnectptr.i;
- signal->theData[2] = cownNodeid;
- signal->theData[3] = regTcPtr->transid[0];
- signal->theData[4] = regTcPtr->transid[1];
- sendSignal(regTcPtr->reqBlockref, GSN_ABORTCONF,
- signal, 5, JBB);
- }//if
- cleanUp(signal);
-}//Dblqh::continueAfterLogAbortWriteLab()
-
-void
-Dblqh::sendTCKEYREF(Signal* signal, Uint32 ref, Uint32 routeRef, Uint32 cnt)
-{
- const Uint32 nodeId = refToNode(ref);
- const bool connectedToNode = getNodeInfo(nodeId).m_connected;
-
- if (likely(connectedToNode))
- {
- jam();
- sendSignal(ref, GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
- }
- else
- {
- if (routeRef &&
- getNodeInfo(refToNode(routeRef)).m_version >= MAKE_VERSION(5,1,14))
- {
- jam();
- memmove(signal->theData+25, signal->theData, 4*TcKeyRef::SignalLength);
- RouteOrd* ord = (RouteOrd*)signal->getDataPtrSend();
- ord->dstRef = ref;
- ord->srcRef = reference();
- ord->gsn = GSN_TCKEYREF;
- ord->cnt = 0;
- LinearSectionPtr ptr[3];
- ptr[0].p = signal->theData+25;
- ptr[0].sz = TcKeyRef::SignalLength;
- sendSignal(routeRef, GSN_ROUTE_ORD, signal, RouteOrd::SignalLength, JBB,
- ptr, 1);
- }
- else
- {
- jam();
- memmove(signal->theData + 3, signal->theData, 4*TcKeyRef::SignalLength);
- signal->theData[0] = ZRETRY_TCKEYREF;
- signal->theData[1] = cnt + 1;
- signal->theData[2] = ref;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100,
- TcKeyRef::SignalLength + 3);
- }
- }
-}
-
-/* ##########################################################################
- * ####### MODULE TO HANDLE TC FAILURE #######
- *
- * ########################################################################## */
-
-/* ************************************************************************>>
- * NODE_FAILREP: Node failure report. Sender Ndbcntr. Set status of failed
- * node to down and reply with NF_COMPLETEREP to DIH which will report that
- * LQH has completed failure handling.
- * ************************************************************************>> */
-void Dblqh::execNODE_FAILREP(Signal* signal)
-{
- UintR TfoundNodes = 0;
- UintR TnoOfNodes;
- UintR Tdata[MAX_NDB_NODES];
- Uint32 i;
-
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- TnoOfNodes = nodeFail->noOfNodes;
- UintR index = 0;
- for (i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if(NodeBitmask::get(nodeFail->theNodes, i)){
- jam();
- Tdata[index] = i;
- index++;
- }//if
- }//for
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
-
- ndbrequire(index == TnoOfNodes);
- ndbrequire(cnoOfNodes - 1 < MAX_NDB_NODES);
- for (i = 0; i < TnoOfNodes; i++) {
- const Uint32 nodeId = Tdata[i];
- lcpPtr.p->m_EMPTY_LCP_REQ.clear(nodeId);
-
- for (Uint32 j = 0; j < cnoOfNodes; j++) {
- jam();
- if (cnodeData[j] == nodeId){
- jam();
- cnodeStatus[j] = ZNODE_DOWN;
-
- TfoundNodes++;
- }//if
- }//for
- NFCompleteRep * const nfCompRep = (NFCompleteRep *)&signal->theData[0];
- nfCompRep->blockNo = DBLQH;
- nfCompRep->nodeId = cownNodeid;
- nfCompRep->failedNodeId = Tdata[i];
- sendSignal(DBDIH_REF, GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
- }//for
- ndbrequire(TnoOfNodes == TfoundNodes);
-}//Dblqh::execNODE_FAILREP()
-
-/* ************************************************************************>>
- * LQH_TRANSREQ: Report status of all transactions where TC was coordinated
- * by a crashed TC
- * ************************************************************************>> */
-/* ************************************************************************>>
- * THIS SIGNAL IS RECEIVED AFTER A NODE CRASH.
- * THE NODE HAD A TC AND COORDINATED A NUMBER OF TRANSACTIONS.
- * NOW THE MASTER NODE IS PICKING UP THOSE TRANSACTIONS
- * TO COMPLETE THEM. EITHER ABORT THEM OR COMMIT THEM.
- * ************************************************************************>> */
-void Dblqh::execLQH_TRANSREQ(Signal* signal)
-{
- jamEntry();
- Uint32 newTcPtr = signal->theData[0];
- BlockReference newTcBlockref = signal->theData[1];
- Uint32 oldNodeId = signal->theData[2];
- tcNodeFailptr.i = oldNodeId;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- if ((tcNodeFailptr.p->tcFailStatus == TcNodeFailRecord::TC_STATE_TRUE) ||
- (tcNodeFailptr.p->tcFailStatus == TcNodeFailRecord::TC_STATE_BREAK)) {
- jam();
- tcNodeFailptr.p->lastNewTcBlockref = newTcBlockref;
- /* ------------------------------------------------------------------------
- * WE HAVE RECEIVED A SIGNAL SPECIFYING THAT WE NEED TO HANDLE THE FAILURE
- * OF A TC. NOW WE RECEIVE ANOTHER SIGNAL WITH THE SAME ORDER. THIS CAN
- * OCCUR IF THE NEW TC FAILS. WE MUST BE CAREFUL IN THIS CASE SO THAT WE DO
- * NOT START PARALLEL ACTIVITIES TRYING TO DO THE SAME THING. WE SAVE THE
- * NEW BLOCK REFERENCE TO THE LAST NEW TC IN A VARIABLE AND ASSIGN TO IT TO
- * NEW_TC_BLOCKREF WHEN THE OLD PROCESS RETURNS TO LQH_TRANS_NEXT. IT IS
- * CERTAIN TO COME THERE SINCE THIS IS THE ONLY PATH TO TAKE CARE OF THE
- * NEXT TC CONNECT RECORD. WE SET THE STATUS TO BREAK TO INDICATE TO THE OLD
- * PROCESS WHAT IS HAPPENING.
- * ------------------------------------------------------------------------ */
- tcNodeFailptr.p->lastNewTcRef = newTcPtr;
- tcNodeFailptr.p->tcFailStatus = TcNodeFailRecord::TC_STATE_BREAK;
- return;
- }//if
- tcNodeFailptr.p->oldNodeId = oldNodeId;
- tcNodeFailptr.p->newTcBlockref = newTcBlockref;
- tcNodeFailptr.p->newTcRef = newTcPtr;
- tcNodeFailptr.p->tcRecNow = 0;
- tcNodeFailptr.p->tcFailStatus = TcNodeFailRecord::TC_STATE_TRUE;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::execLQH_TRANSREQ()
-
-void Dblqh::lqhTransNextLab(Signal* signal)
-{
- UintR tend;
- UintR tstart;
- UintR guard0;
-
- if (tcNodeFailptr.p->tcFailStatus == TcNodeFailRecord::TC_STATE_BREAK) {
- jam();
- /* ----------------------------------------------------------------------
- * AN INTERRUPTION TO THIS NODE FAIL HANDLING WAS RECEIVED AND A NEW
- * TC HAVE BEEN ASSIGNED TO TAKE OVER THE FAILED TC. PROBABLY THE OLD
- * NEW TC HAVE FAILED.
- * ---------------------------------------------------------------------- */
- tcNodeFailptr.p->newTcBlockref = tcNodeFailptr.p->lastNewTcBlockref;
- tcNodeFailptr.p->newTcRef = tcNodeFailptr.p->lastNewTcRef;
- tcNodeFailptr.p->tcRecNow = 0;
- tcNodeFailptr.p->tcFailStatus = TcNodeFailRecord::TC_STATE_TRUE;
- }//if
- tstart = tcNodeFailptr.p->tcRecNow;
- tend = tstart + 200;
- guard0 = tend;
- for (tcConnectptr.i = tstart; tcConnectptr.i <= guard0; tcConnectptr.i++) {
- jam();
- if (tcConnectptr.i >= ctcConnectrecFileSize) {
- jam();
- /**
- * Finished with scanning operation record
- *
- * now scan markers
- */
- scanMarkers(signal, tcNodeFailptr.i, 0, RNIL);
- return;
- }//if
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- if (tcConnectptr.p->transactionState != TcConnectionrec::IDLE) {
- if (tcConnectptr.p->transactionState != TcConnectionrec::TC_NOT_CONNECTED) {
- if (tcConnectptr.p->tcScanRec == RNIL) {
- if (refToNode(tcConnectptr.p->tcBlockref) == tcNodeFailptr.p->oldNodeId) {
- if (tcConnectptr.p->operation != ZREAD) {
- jam();
- tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
- tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
- abortStateHandlerLab(signal);
- return;
- } else {
- jam();
- if (tcConnectptr.p->opSimple != ZTRUE) {
- jam();
- tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
- tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
- abortStateHandlerLab(signal);
- return;
- }//if
- }//if
- }//if
- } else {
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- switch(scanptr.p->scanType){
- case ScanRecord::COPY:
- {
- jam();
- if (scanptr.p->scanNodeId == tcNodeFailptr.p->oldNodeId) {
- jam();
- /* ------------------------------------------------------------
- * THE RECEIVER OF THE COPY HAVE FAILED.
- * WE HAVE TO CLOSE THE COPY PROCESS.
- * ----------------------------------------------------------- */
- if (0) ndbout_c("close copy");
- tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
- tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
- closeCopyRequestLab(signal);
- return;
- }
- break;
- }
- case ScanRecord::SCAN:
- {
- jam();
- if (refToNode(tcConnectptr.p->tcBlockref) ==
- tcNodeFailptr.p->oldNodeId) {
- jam();
- tcConnectptr.p->tcNodeFailrec = tcNodeFailptr.i;
- tcConnectptr.p->abortState = TcConnectionrec::NEW_FROM_TC;
- closeScanRequestLab(signal);
- return;
- }//if
- break;
- }
- default:
- ndbrequire(false);
- }
- }//if
- }//if
- }//if
- }//for
- tcNodeFailptr.p->tcRecNow = tend + 1;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::lqhTransNextLab()
-
-void
-Dblqh::scanMarkers(Signal* signal,
- Uint32 tcNodeFail,
- Uint32 startBucket,
- Uint32 i){
-
- jam();
-
- TcNodeFailRecordPtr tcNodeFailPtr;
- tcNodeFailPtr.i = tcNodeFail;
- ptrCheckGuard(tcNodeFailPtr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- const Uint32 crashedTcNodeId = tcNodeFailPtr.p->oldNodeId;
-
- CommitAckMarkerIterator iter;
- if(i == RNIL){
- m_commitAckMarkerHash.next(startBucket, iter);
- } else {
- jam();
- iter.curr.i = i;
- iter.bucket = startBucket;
- m_commitAckMarkerHash.getPtr(iter.curr);
- m_commitAckMarkerHash.next(iter);
- }
-
- const Uint32 RT_BREAK = 256;
- for(i = 0; i<RT_BREAK || iter.bucket == startBucket; i++){
- jam();
-
- if(iter.curr.i == RNIL){
- /**
- * Done with iteration
- */
- jam();
-
- tcNodeFailPtr.p->tcFailStatus = TcNodeFailRecord::TC_STATE_FALSE;
- signal->theData[0] = tcNodeFailPtr.p->newTcRef;
- signal->theData[1] = cownNodeid;
- signal->theData[2] = LqhTransConf::LastTransConf;
- sendSignal(tcNodeFailPtr.p->newTcBlockref, GSN_LQH_TRANSCONF,
- signal, 3, JBB);
- return;
- }
-
- if(iter.curr.p->tcNodeId == crashedTcNodeId){
- jam();
-
- /**
- * Found marker belonging to crashed node
- */
- LqhTransConf * const lqhTransConf = (LqhTransConf *)&signal->theData[0];
- lqhTransConf->tcRef = tcNodeFailPtr.p->newTcRef;
- lqhTransConf->lqhNodeId = cownNodeid;
- lqhTransConf->operationStatus = LqhTransConf::Marker;
- lqhTransConf->transId1 = iter.curr.p->transid1;
- lqhTransConf->transId2 = iter.curr.p->transid2;
- lqhTransConf->apiRef = iter.curr.p->apiRef;
- lqhTransConf->apiOpRec = iter.curr.p->apiOprec;
- sendSignal(tcNodeFailPtr.p->newTcBlockref, GSN_LQH_TRANSCONF,
- signal, 7, JBB);
-
- signal->theData[0] = ZSCAN_MARKERS;
- signal->theData[1] = tcNodeFailPtr.i;
- signal->theData[2] = iter.bucket;
- signal->theData[3] = iter.curr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }
-
- m_commitAckMarkerHash.next(iter);
- }
-
- signal->theData[0] = ZSCAN_MARKERS;
- signal->theData[1] = tcNodeFailPtr.i;
- signal->theData[2] = iter.bucket;
- signal->theData[3] = RNIL;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
-}
-
-/* #########################################################################
- * ####### SCAN MODULE #######
- *
- * #########################################################################
- * -------------------------------------------------------------------------
- * THIS MODULE CONTAINS THE CODE THAT HANDLES A SCAN OF A PARTICULAR FRAGMENT
- * IT OPERATES UNDER THE CONTROL OF TC AND ORDERS ACC TO PERFORM A SCAN OF
- * ALL TUPLES IN THE FRAGMENT. TUP PERFORMS THE NECESSARY SEARCH CONDITIONS
- * TO ENSURE THAT ONLY VALID TUPLES ARE RETURNED TO THE APPLICATION.
- * ------------------------------------------------------------------------- */
-/* *************** */
-/* ACC_SCANCONF > */
-/* *************** */
-void Dblqh::execACC_SCANCONF(Signal* signal)
-{
- AccScanConf * const accScanConf = (AccScanConf *)&signal->theData[0];
- jamEntry();
- scanptr.i = accScanConf->scanPtr;
- c_scanRecordPool.getPtr(scanptr);
- if (scanptr.p->scanState == ScanRecord::WAIT_ACC_SCAN) {
- accScanConfScanLab(signal);
- } else {
- ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_ACC_COPY);
- accScanConfCopyLab(signal);
- }//if
-}//Dblqh::execACC_SCANCONF()
-
-/* ************>> */
-/* ACC_SCANREF > */
-/* ************>> */
-void Dblqh::execACC_SCANREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dblqh::execACC_SCANREF()
-
-/* ***************>> */
-/* NEXT_SCANCONF > */
-/* ***************>> */
-void Dblqh::execNEXT_SCANCONF(Signal* signal)
-{
- NextScanConf * const nextScanConf = (NextScanConf *)&signal->theData[0];
- jamEntry();
- scanptr.i = nextScanConf->scanPtr;
- c_scanRecordPool.getPtr(scanptr);
- if (likely(nextScanConf->localKeyLength == 1))
- {
- jam();
- scanptr.p->m_row_id.assref(nextScanConf->localKey[0]);
- }
- else
- {
- jam();
- scanptr.p->m_row_id.m_page_no = nextScanConf->localKey[0];
- scanptr.p->m_row_id.m_page_idx = nextScanConf->localKey[1];
- }
-
-#ifdef VM_TRACE
- if (signal->getLength() > 2 && nextScanConf->accOperationPtr != RNIL)
- {
- Ptr<TcConnectionrec> regTcPtr;
- regTcPtr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
- ndbassert(regTcPtr.p->fragmentid == nextScanConf->fragId);
- }
-#endif
-
- fragptr.i = scanptr.p->fragPtrI;
- c_fragment_pool.getPtr(fragptr);
- switch (scanptr.p->scanState) {
- case ScanRecord::WAIT_CLOSE_SCAN:
- jam();
- accScanCloseConfLab(signal);
- break;
- case ScanRecord::WAIT_CLOSE_COPY:
- jam();
- accCopyCloseConfLab(signal);
- break;
- case ScanRecord::WAIT_NEXT_SCAN:
- jam();
- nextScanConfScanLab(signal);
- break;
- case ScanRecord::WAIT_NEXT_SCAN_COPY:
- jam();
- nextScanConfCopyLab(signal);
- break;
- case ScanRecord::WAIT_RELEASE_LOCK:
- jam();
- ndbrequire(signal->length() == 1);
- scanLockReleasedLab(signal);
- break;
- default:
- ndbout_c("%d", scanptr.p->scanState);
- ndbrequire(false);
- }//switch
-}//Dblqh::execNEXT_SCANCONF()
-
-/* ***************> */
-/* NEXT_SCANREF > */
-/* ***************> */
-void Dblqh::execNEXT_SCANREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Dblqh::execNEXT_SCANREF()
-
-/* ******************> */
-/* STORED_PROCCONF > */
-/* ******************> */
-void Dblqh::execSTORED_PROCCONF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- Uint32 storedProcId = signal->theData[1];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- switch (scanptr.p->scanState) {
- case ScanRecord::WAIT_STORED_PROC_SCAN:
- jam();
- scanptr.p->scanStoredProcId = storedProcId;
- storedProcConfScanLab(signal);
- break;
- case ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN:
- jam();
- tupScanCloseConfLab(signal);
- break;
- case ScanRecord::WAIT_STORED_PROC_COPY:
- jam();
- scanptr.p->scanStoredProcId = storedProcId;
- storedProcConfCopyLab(signal);
- break;
- case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
- jam();
- tupCopyCloseConfLab(signal);
- break;
- default:
- ndbrequire(false);
- }//switch
-}//Dblqh::execSTORED_PROCCONF()
-
-/* ****************** */
-/* STORED_PROCREF > */
-/* ****************** */
-void Dblqh::execSTORED_PROCREF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- Uint32 errorCode = signal->theData[1];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- switch (scanptr.p->scanState) {
- case ScanRecord::WAIT_STORED_PROC_SCAN:
- jam();
- scanptr.p->scanCompletedStatus = ZTRUE;
- scanptr.p->scanStoredProcId = signal->theData[2];
- tcConnectptr.p->errorCode = errorCode;
- closeScanLab(signal);
- break;
- default:
- ndbrequire(false);
- }//switch
-}//Dblqh::execSTORED_PROCREF()
-
-/* --------------------------------------------------------------------------
- * ENTER SCAN_NEXTREQ
- * --------------------------------------------------------------------------
- * PRECONDITION:
- * TRANSACTION_STATE = SCAN_STATE
- * SCAN_STATE = WAIT_SCAN_NEXTREQ
- *
- * Case scanLockHold: ZTRUE = Unlock previous round of
- * scanned row(s) and fetch next set of rows.
- * ZFALSE = Fetch new set of rows.
- * Number of rows to read depends on parallelism and how many rows
- * left to scan in the fragment. SCAN_NEXTREQ can also be sent with
- * closeFlag == ZTRUE to close the scan.
- * ------------------------------------------------------------------------- */
-void Dblqh::execSCAN_NEXTREQ(Signal* signal)
-{
- jamEntry();
- const ScanFragNextReq * const nextReq =
- (ScanFragNextReq*)&signal->theData[0];
- const Uint32 transid1 = nextReq->transId1;
- const Uint32 transid2 = nextReq->transId2;
- const Uint32 senderData = nextReq->senderData;
-
- if (findTransaction(transid1, transid2, senderData) != ZOK){
- jam();
- DEBUG(senderData <<
- " Received SCAN_NEXTREQ in LQH with close flag when closed");
- ndbrequire(nextReq->closeFlag == ZTRUE);
- return;
- }
-
- // Crash node if signal sender is same node
- CRASH_INSERTION2(5021, refToNode(signal->senderBlockRef()) == cownNodeid);
- // Crash node if signal sender is NOT same node
- CRASH_INSERTION2(5022, refToNode(signal->senderBlockRef()) != cownNodeid);
-
- if (ERROR_INSERTED(5023)){
- // Drop signal if sender is same node
- if (refToNode(signal->senderBlockRef()) == cownNodeid) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
- }//if
- if (ERROR_INSERTED(5024)){
- // Drop signal if sender is NOT same node
- if (refToNode(signal->senderBlockRef()) != cownNodeid) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
- }//if
- if (ERROR_INSERTED(5025)){
- // Delay signal if sender is NOT same node
- if (refToNode(signal->senderBlockRef()) != cownNodeid) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_SCAN_NEXTREQ, signal, 1000,
- signal->length());
- return;
- }
- }//if
- if (ERROR_INSERTED(5030)){
- ndbout << "ERROR 5030" << endl;
- CLEAR_ERROR_INSERT_VALUE;
- // Drop signal
- return;
- }//if
-
- if(ERROR_INSERTED(5036)){
- return;
- }
-
- scanptr.i = tcConnectptr.p->tcScanRec;
- ndbrequire(scanptr.i != RNIL);
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanTcWaiting = ZTRUE;
-
- /* ------------------------------------------------------------------
- * If close flag is set this scan should be closed
- * If we are waiting for SCAN_NEXTREQ set flag to stop scanning and
- * continue execution else set flags and wait until the scan
- * completes itself
- * ------------------------------------------------------------------ */
- if (nextReq->closeFlag == ZTRUE){
- jam();
- if(ERROR_INSERTED(5034)){
- CLEAR_ERROR_INSERT_VALUE;
- }
- if(ERROR_INSERTED(5036)){
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
- closeScanRequestLab(signal);
- return;
- }//if
-
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
-
- /**
- * Change parameters while running
- * (is currently not supported)
- */
- const Uint32 max_rows = nextReq->batch_size_rows;
- const Uint32 max_bytes = nextReq->batch_size_bytes;
- ndbrequire(scanptr.p->m_max_batch_size_rows == max_rows);
- ndbrequire(scanptr.p->m_max_batch_size_bytes == max_bytes);
-
- /* --------------------------------------------------------------------
- * If scanLockHold = TRUE we need to unlock previous round of
- * scanned records.
- * scanReleaseLocks will set states for this and send a NEXT_SCANREQ.
- * When confirm signal NEXT_SCANCONF arrives we call
- * continueScanNextReqLab to continue scanning new rows and
- * acquiring new locks.
- * -------------------------------------------------------------------- */
- if ((scanptr.p->scanLockHold == ZTRUE) &&
- (scanptr.p->m_curr_batch_size_rows > 0)) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
-
- /* -----------------------------------------------------------------------
- * We end up here when scanLockHold = FALSE or no rows was locked from
- * previous round.
- * Simply continue scanning.
- * ----------------------------------------------------------------------- */
- continueScanNextReqLab(signal);
-}//Dblqh::execSCAN_NEXTREQ()
-
-void Dblqh::continueScanNextReqLab(Signal* signal)
-{
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
- closeScanLab(signal);
- return;
- }//if
-
- if(scanptr.p->m_last_row){
- jam();
- scanptr.p->scanCompletedStatus = ZTRUE;
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- return;
- }
-
- // Update timer on tcConnectRecord
- tcConnectptr.p->tcTimer = cLqhTimeOutCount;
- init_acc_ptr_list(scanptr.p);
- scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT;
- scanNextLoopLab(signal);
-}//Dblqh::continueScanNextReqLab()
-
-/* -------------------------------------------------------------------------
- * WE NEED TO RELEASE LOCKS BEFORE CONTINUING
- * ------------------------------------------------------------------------- */
-void Dblqh::scanReleaseLocksLab(Signal* signal)
-{
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_RELEASE_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- }//switch
- continueScanReleaseAfterBlockedLab(signal);
-}//Dblqh::scanReleaseLocksLab()
-
-void Dblqh::continueScanReleaseAfterBlockedLab(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanState = ScanRecord::WAIT_RELEASE_LOCK;
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1]=
- get_acc_ptr_from_scan_record(scanptr.p,
- scanptr.p->scanReleaseCounter -1,
- false);
- signal->theData[2] = NextScanReq::ZSCAN_COMMIT;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
-}//Dblqh::continueScanReleaseAfterBlockedLab()
-
-/* -------------------------------------------------------------------------
- * ENTER SCAN_NEXTREQ
- * -------------------------------------------------------------------------
- * SCAN_NEXT_REQ SIGNAL ARRIVED IN THE MIDDLE OF EXECUTION OF THE SCAN.
- * IT WAS A REQUEST TO CLOSE THE SCAN. WE WILL CLOSE THE SCAN IN A
- * CAREFUL MANNER TO ENSURE THAT NO ERROR OCCURS.
- * -------------------------------------------------------------------------
- * PRECONDITION:
- * TRANSACTION_STATE = SCAN_STATE_USED
- * TSCAN_COMPLETED = ZTRUE
- * -------------------------------------------------------------------------
- * WE CAN ALSO ARRIVE AT THIS LABEL AFTER A NODE CRASH OF THE SCAN
- * COORDINATOR.
- * ------------------------------------------------------------------------- */
-void Dblqh::closeScanRequestLab(Signal* signal)
-{
- DEBUG("transactionState = " << tcConnectptr.p->transactionState);
- switch (tcConnectptr.p->transactionState) {
- case TcConnectionrec::SCAN_STATE_USED:
- DEBUG("scanState = " << scanptr.p->scanState);
- switch (scanptr.p->scanState) {
- case ScanRecord::IN_QUEUE:
- jam();
- tupScanCloseConfLab(signal);
- break;
- case ScanRecord::WAIT_NEXT_SCAN:
- jam();
- /* -------------------------------------------------------------------
- * SET COMPLETION STATUS AND WAIT FOR OPPORTUNITY TO STOP THE SCAN.
- * ------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case ScanRecord::WAIT_ACC_SCAN:
- case ScanRecord::WAIT_STORED_PROC_SCAN:
- jam();
- /* -------------------------------------------------------------------
- * WE ARE CURRENTLY STARTING UP THE SCAN. SET COMPLETED STATUS
- * AND WAIT FOR COMPLETION OF STARTUP.
- * ------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case ScanRecord::WAIT_CLOSE_SCAN:
- case ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN:
- jam();
- /*empty*/;
- break;
- /* -------------------------------------------------------------------
- * CLOSE IS ALREADY ONGOING. WE NEED NOT DO ANYTHING.
- * ------------------------------------------------------------------- */
- case ScanRecord::WAIT_RELEASE_LOCK:
- jam();
- /* -------------------------------------------------------------------
- * WE ARE CURRENTLY RELEASING RECORD LOCKS. AFTER COMPLETING THIS
- * WE WILL START TO CLOSE THE SCAN.
- * ------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case ScanRecord::WAIT_SCAN_NEXTREQ:
- jam();
- /* -------------------------------------------------------------------
- * WE ARE WAITING FOR A SCAN_NEXTREQ FROM SCAN COORDINATOR(TC)
- * WICH HAVE CRASHED. CLOSE THE SCAN
- * ------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
-
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
-
- if (scanptr.p->scanLockHold == ZTRUE) {
- if (scanptr.p->m_curr_batch_size_rows > 0) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- }//if
- closeScanLab(signal);
- break;
- default:
- ndbrequire(false);
- }//switch
- break;
- case TcConnectionrec::WAIT_SCAN_AI:
- jam();
- /* ---------------------------------------------------------------------
- * WE ARE STILL WAITING FOR THE ATTRIBUTE INFORMATION THAT
- * OBVIOUSLY WILL NOT ARRIVE. WE CAN QUIT IMMEDIATELY HERE.
- * --------------------------------------------------------------------- */
- //XXX jonas this have to be wrong...
- releaseOprec(signal);
- if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- tcNodeFailptr.p->tcRecNow = tcConnectptr.i + 1;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE;
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
- sendScanFragConf(signal, ZTRUE);
- abort_scan(signal, scanptr.i, 0);
- return;
- break;
- case TcConnectionrec::SCAN_TUPKEY:
- case TcConnectionrec::SCAN_FIRST_STOPPED:
- case TcConnectionrec::SCAN_CHECK_STOPPED:
- case TcConnectionrec::SCAN_STOPPED:
- jam();
- /* ---------------------------------------------------------------------
- * SET COMPLETION STATUS AND WAIT FOR OPPORTUNITY TO STOP THE SCAN.
- * --------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case TcConnectionrec::SCAN_RELEASE_STOPPED:
- jam();
- /* ---------------------------------------------------------------------
- * WE ARE CURRENTLY RELEASING RECORD LOCKS. AFTER COMPLETING
- * THIS WE WILL START TO CLOSE THE SCAN.
- * --------------------------------------------------------------------- */
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case TcConnectionrec::SCAN_CLOSE_STOPPED:
- jam();
- /* ---------------------------------------------------------------------
- * CLOSE IS ALREADY ONGOING. WE NEED NOT DO ANYTHING.
- * --------------------------------------------------------------------- */
- /*empty*/;
- break;
- default:
- ndbrequire(false);
- }//switch
-}//Dblqh::closeScanRequestLab()
-
-/* -------------------------------------------------------------------------
- * ENTER NEXT_SCANCONF
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_RELEASE_LOCK
- * ------------------------------------------------------------------------- */
-void Dblqh::scanLockReleasedLab(Signal* signal)
-{
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-
- if (scanptr.p->scanReleaseCounter == scanptr.p->m_curr_batch_size_rows) {
- if ((scanptr.p->scanErrorCounter > 0) ||
- (scanptr.p->scanCompletedStatus == ZTRUE)) {
- jam();
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes = 0;
- closeScanLab(signal);
- } else if (scanptr.p->m_last_row && !scanptr.p->scanLockHold) {
- jam();
- closeScanLab(signal);
- return;
- } else if (scanptr.p->check_scan_batch_completed() &&
- scanptr.p->scanLockHold != ZTRUE) {
- jam();
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- } else {
- jam();
- /*
- * We came here after releasing locks after
- * receiving SCAN_NEXTREQ from TC. We only come here
- * when scanHoldLock == ZTRUE
- */
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes = 0;
- continueScanNextReqLab(signal);
- }//if
- } else if (scanptr.p->scanReleaseCounter < scanptr.p->m_curr_batch_size_rows) {
- jam();
- scanptr.p->scanReleaseCounter++;
- scanReleaseLocksLab(signal);
- } else {
- jam();
- /*
- We come here when we have been scanning for a long time and not been able
- to find m_max_batch_size_rows records to return. We needed to release
- the record we didn't want, but now we are returning all found records to
- the API.
- */
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- }//if
-}//Dblqh::scanLockReleasedLab()
-
-bool
-Dblqh::seize_acc_ptr_list(ScanRecord* scanP, Uint32 batch_size)
-{
- Uint32 i;
- Uint32 attr_buf_recs= (batch_size + 30) / 32;
-
- if (batch_size > 1) {
- if (c_no_attrinbuf_recs < attr_buf_recs) {
- jam();
- return false;
- }
- for (i= 1; i <= attr_buf_recs; i++) {
- scanP->scan_acc_op_ptr[i]= seize_attrinbuf();
- }
- }
- scanP->scan_acc_attr_recs= attr_buf_recs;
- scanP->scan_acc_index = 0;
- return true;
-}
-
-void
-Dblqh::release_acc_ptr_list(ScanRecord* scanP)
-{
- Uint32 i, attr_buf_recs;
- attr_buf_recs= scanP->scan_acc_attr_recs;
-
- for (i= 1; i <= attr_buf_recs; i++) {
- release_attrinbuf(scanP->scan_acc_op_ptr[i]);
- }
- scanP->scan_acc_attr_recs= 0;
- scanP->scan_acc_index = 0;
-}
-
-Uint32
-Dblqh::seize_attrinbuf()
-{
- AttrbufPtr regAttrPtr;
- Uint32 ret_attr_buf;
- ndbrequire(c_no_attrinbuf_recs > 0);
- c_no_attrinbuf_recs--;
- ret_attr_buf= cfirstfreeAttrinbuf;
- regAttrPtr.i= ret_attr_buf;
- ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf);
- cfirstfreeAttrinbuf= regAttrPtr.p->attrbuf[ZINBUF_NEXT];
- return ret_attr_buf;
-}
-
-Uint32
-Dblqh::release_attrinbuf(Uint32 attr_buf_i)
-{
- Uint32 next_buf;
- AttrbufPtr regAttrPtr;
- c_no_attrinbuf_recs++;
- regAttrPtr.i= attr_buf_i;
- ptrCheckGuard(regAttrPtr, cattrinbufFileSize, attrbuf);
- next_buf= regAttrPtr.p->attrbuf[ZINBUF_NEXT];
- regAttrPtr.p->attrbuf[ZINBUF_NEXT]= cfirstfreeAttrinbuf;
- cfirstfreeAttrinbuf= regAttrPtr.i;
- return next_buf;
-}
-
-void
-Dblqh::init_acc_ptr_list(ScanRecord* scanP)
-{
- scanP->scan_acc_index = 0;
-}
-
-Uint32
-Dblqh::get_acc_ptr_from_scan_record(ScanRecord* scanP,
- Uint32 index,
- bool crash_flag)
-{
- Uint32* acc_ptr;
- if (!((index < MAX_PARALLEL_OP_PER_SCAN) &&
- index < scanP->scan_acc_index)) {
- ndbrequire(crash_flag);
- return RNIL;
- }
- i_get_acc_ptr(scanP, acc_ptr, index);
- return *acc_ptr;
-}
-
-void
-Dblqh::set_acc_ptr_in_scan_record(ScanRecord* scanP,
- Uint32 index, Uint32 acc)
-{
- Uint32 *acc_ptr;
- ndbrequire((index == 0 || scanP->scan_acc_index == index) &&
- (index < MAX_PARALLEL_OP_PER_SCAN));
- scanP->scan_acc_index= index + 1;
- i_get_acc_ptr(scanP, acc_ptr, index);
- *acc_ptr= acc;
-}
-
-/* -------------------------------------------------------------------------
- * SCAN_FRAGREQ: Request to start scanning the specified fragment of a table.
- * ------------------------------------------------------------------------- */
-void Dblqh::execSCAN_FRAGREQ(Signal* signal)
-{
- ScanFragReq * const scanFragReq = (ScanFragReq *)&signal->theData[0];
- ScanFragRef * ref;
- const Uint32 transid1 = scanFragReq->transId1;
- const Uint32 transid2 = scanFragReq->transId2;
- Uint32 errorCode= 0;
- Uint32 senderData;
- Uint32 hashIndex;
- TcConnectionrecPtr nextHashptr;
-
- jamEntry();
- const Uint32 reqinfo = scanFragReq->requestInfo;
- const Uint32 fragId = (scanFragReq->fragmentNoKeyLen & 0xFFFF);
- const Uint32 keyLen = (scanFragReq->fragmentNoKeyLen >> 16);
- tabptr.i = scanFragReq->tableId;
- const Uint32 max_rows = scanFragReq->batch_size_rows;
- const Uint32 scanLockMode = ScanFragReq::getLockMode(reqinfo);
- const Uint8 keyinfo = ScanFragReq::getKeyinfoFlag(reqinfo);
- const Uint8 rangeScan = ScanFragReq::getRangeScanFlag(reqinfo);
-
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if(tabptr.p->tableStatus != Tablerec::TABLE_DEFINED){
- senderData = scanFragReq->senderData;
- goto error_handler_early_1;
- }
-
- if (cfirstfreeTcConrec != RNIL) {
- seizeTcrec();
- tcConnectptr.p->clientConnectrec = scanFragReq->senderData;
- tcConnectptr.p->clientBlockref = signal->senderBlockRef();
- tcConnectptr.p->savePointId = scanFragReq->savePointId;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * NO FREE TC RECORD AVAILABLE, THUS WE CANNOT HANDLE THE REQUEST.
- * -------------------------------------------------------------------- */
- errorCode = ZNO_TC_CONNECT_ERROR;
- senderData = scanFragReq->senderData;
- goto error_handler_early;
- }//if
- /**
- * A write allways have to get keyinfo
- */
- ndbrequire(scanLockMode == 0 || keyinfo);
-
- ndbrequire(max_rows > 0 && max_rows <= MAX_PARALLEL_OP_PER_SCAN);
- if (!getFragmentrec(signal, fragId)) {
- errorCode = 1231;
- goto error_handler;
- }//if
-
- // Verify scan type vs table type (both sides are boolean)
- if (rangeScan != DictTabInfo::isOrderedIndex(fragptr.p->tableType)) {
- errorCode = 1232;
- goto error_handler;
- }//if
-
- // 1 scan record is reserved for node recovery
- if (cscanNoFreeRec < 2) {
- jam();
- errorCode = ScanFragRef::ZNO_FREE_SCANREC_ERROR;
- goto error_handler;
- }
-
- // XXX adjust cmaxAccOps for range scans and remove this comment
- if ((cbookedAccOps + max_rows) > cmaxAccOps) {
- jam();
- errorCode = ScanFragRef::ZSCAN_BOOK_ACC_OP_ERROR;
- goto error_handler;
- }//if
-
- ndbrequire(c_scanRecordPool.seize(scanptr));
- initScanTc(scanFragReq,
- transid1,
- transid2,
- fragId,
- ZNIL);
- tcConnectptr.p->save1 = 4;
- tcConnectptr.p->primKeyLen = keyLen + 4; // hard coded in execKEYINFO
- errorCode = initScanrec(scanFragReq);
- if (errorCode != ZOK) {
- jam();
- goto error_handler2;
- }//if
- cscanNoFreeRec--;
- cbookedAccOps += max_rows;
-
- hashIndex = (tcConnectptr.p->transid[0] ^ tcConnectptr.p->tcOprec) & 1023;
- nextHashptr.i = ctransidHash[hashIndex];
- ctransidHash[hashIndex] = tcConnectptr.i;
- tcConnectptr.p->prevHashRec = RNIL;
- tcConnectptr.p->nextHashRec = nextHashptr.i;
- if (nextHashptr.i != RNIL) {
- jam();
- /* ---------------------------------------------------------------------
- * ENSURE THAT THE NEXT RECORD HAS SET PREVIOUS TO OUR RECORD
- * IF IT EXISTS
- * --------------------------------------------------------------------- */
- ptrCheckGuard(nextHashptr, ctcConnectrecFileSize, tcConnectionrec);
- nextHashptr.p->prevHashRec = tcConnectptr.i;
- }//if
- if (scanptr.p->scanAiLength > 0) {
- jam();
- tcConnectptr.p->transactionState = TcConnectionrec::WAIT_SCAN_AI;
- return;
- }//if
- continueAfterReceivingAllAiLab(signal);
- return;
-
-error_handler2:
- // no scan number allocated
- c_scanRecordPool.release(scanptr);
-error_handler:
- ref = (ScanFragRef*)&signal->theData[0];
- tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE;
- ref->senderData = tcConnectptr.p->clientConnectrec;
- ref->transId1 = transid1;
- ref->transId2 = transid2;
- ref->errorCode = errorCode;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal,
- ScanFragRef::SignalLength, JBB);
- releaseOprec(signal);
- releaseTcrec(signal, tcConnectptr);
- return;
-
- error_handler_early_1:
- if(tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
- jam();
- errorCode = ZTABLE_NOT_DEFINED;
- } else if (tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
- tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
- jam();
- errorCode = ZDROP_TABLE_IN_PROGRESS;
- } else {
- ndbrequire(0);
- }
- error_handler_early:
- ref = (ScanFragRef*)&signal->theData[0];
- ref->senderData = senderData;
- ref->transId1 = transid1;
- ref->transId2 = transid2;
- ref->errorCode = errorCode;
- sendSignal(signal->senderBlockRef(), GSN_SCAN_FRAGREF, signal,
- ScanFragRef::SignalLength, JBB);
-}//Dblqh::execSCAN_FRAGREQ()
-
-void Dblqh::continueAfterReceivingAllAiLab(Signal* signal)
-{
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
-
- if(scanptr.p->scanState == ScanRecord::IN_QUEUE){
- jam();
- return;
- }
-
- scanptr.p->scanState = ScanRecord::WAIT_ACC_SCAN;
- AccScanReq * req = (AccScanReq*)&signal->theData[0];
- req->senderData = scanptr.i;
- req->senderRef = cownref;
- req->tableId = tcConnectptr.p->tableref;
- req->fragmentNo = tcConnectptr.p->fragmentid;
- req->requestInfo = 0;
- AccScanReq::setLockMode(req->requestInfo, scanptr.p->scanLockMode);
- AccScanReq::setReadCommittedFlag(req->requestInfo, scanptr.p->readCommitted);
- AccScanReq::setDescendingFlag(req->requestInfo, scanptr.p->descending);
-
- if (refToBlock(tcConnectptr.p->clientBlockref) == BACKUP)
- {
- if (scanptr.p->lcpScan)
- {
- AccScanReq::setNoDiskScanFlag(req->requestInfo, 1);
- AccScanReq::setLcpScanFlag(req->requestInfo, 1);
- }
- else
- {
- /* If backup scan disktables in disk order */
- AccScanReq::setNoDiskScanFlag(req->requestInfo,
- !tcConnectptr.p->m_disk_table);
- AccScanReq::setLcpScanFlag(req->requestInfo, 0);
- }
- }
- else
- {
-#if BUG_27776_FIXED
- AccScanReq::setNoDiskScanFlag(req->requestInfo,
- !tcConnectptr.p->m_disk_table);
-#else
- AccScanReq::setNoDiskScanFlag(req->requestInfo, 1);
-#endif
- AccScanReq::setLcpScanFlag(req->requestInfo, 0);
- }
-
- req->transId1 = tcConnectptr.p->transid[0];
- req->transId2 = tcConnectptr.p->transid[1];
- req->savePointId = tcConnectptr.p->savePointId;
- sendSignal(scanptr.p->scanBlockref, GSN_ACC_SCANREQ, signal,
- AccScanReq::SignalLength, JBB);
-}//Dblqh::continueAfterReceivingAllAiLab()
-
-void Dblqh::scanAttrinfoLab(Signal* signal, Uint32* dataPtr, Uint32 length)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
- if (tcConnectptr.p->currTupAiLen < scanptr.p->scanAiLength) {
- jam();
- } else {
- jam();
- ndbrequire(tcConnectptr.p->currTupAiLen == scanptr.p->scanAiLength);
- continueAfterReceivingAllAiLab(signal);
- }//if
- return;
- }//if
- abort_scan(signal, scanptr.i, ZGET_ATTRINBUF_ERROR);
-}
-
-void Dblqh::abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode){
- jam();
- scanptr.i = scan_ptr_i;
- c_scanRecordPool.getPtr(scanptr);
-
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- finishScanrec(signal);
- releaseScanrec(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::IDLE;
- tcConnectptr.p->abortState = TcConnectionrec::ABORT_ACTIVE;
-
- if(errcode)
- {
- jam();
- ScanFragRef * ref = (ScanFragRef*)&signal->theData[0];
- ref->senderData = tcConnectptr.p->clientConnectrec;
- ref->transId1 = tcConnectptr.p->transid[0];
- ref->transId2 = tcConnectptr.p->transid[1];
- ref->errorCode = errcode;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal,
- ScanFragRef::SignalLength, JBB);
- }
- deleteTransidHash(signal);
- releaseOprec(signal);
- releaseTcrec(signal, tcConnectptr);
-}
-
-/*---------------------------------------------------------------------*/
-/* Send this 'I am alive' signal to TC when it is received from ACC */
-/* We include the scanPtr.i that comes from ACC in signalData[1], this */
-/* tells TC which fragment record to check for a timeout. */
-/*---------------------------------------------------------------------*/
-void Dblqh::execSCAN_HBREP(Signal* signal)
-{
- jamEntry();
- scanptr.i = signal->theData[0];
- c_scanRecordPool.getPtr(scanptr);
- switch(scanptr.p->scanType){
- case ScanRecord::SCAN:
- if (scanptr.p->scanTcWaiting == ZTRUE) {
- jam();
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- const Uint32 transid1 = signal->theData[1];
- const Uint32 transid2 = signal->theData[2];
- ndbrequire(transid1 == tcConnectptr.p->transid[0] &&
- transid2 == tcConnectptr.p->transid[1]);
-
- // Update counter on tcConnectPtr
- if (tcConnectptr.p->tcTimer != 0){
- tcConnectptr.p->tcTimer = cLqhTimeOutCount;
- } else {
- jam();
- //ndbout << "SCAN_HBREP when tcTimer was off" << endl;
- }
-
- signal->theData[0] = tcConnectptr.p->clientConnectrec;
- signal->theData[1] = tcConnectptr.p->transid[0];
- signal->theData[2] = tcConnectptr.p->transid[1];
- sendSignal(tcConnectptr.p->clientBlockref,
- GSN_SCAN_HBREP, signal, 3, JBB);
- }//if
- break;
- case ScanRecord::COPY:
- // ndbout << "Dblqh::execSCAN_HBREP Dropping SCAN_HBREP" << endl;
- break;
- default:
- ndbrequire(false);
- }
-}
-
-void Dblqh::accScanConfScanLab(Signal* signal)
-{
- AccScanConf * const accScanConf = (AccScanConf *)&signal->theData[0];
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- /* -----------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_ACC_SCAN
- * ----------------------------------------------------------------------- */
- if (accScanConf->flag == AccScanConf::ZEMPTY_FRAGMENT) {
- jam();
- /* ---------------------------------------------------------------------
- * THE FRAGMENT WAS EMPTY.
- * REPORT SUCCESSFUL COPYING.
- * --------------------------------------------------------------------- */
- tupScanCloseConfLab(signal);
- return;
- }//if
- scanptr.p->scanAccPtr = accScanConf->accPtr;
- if (scanptr.p->rangeScan) {
- jam();
- TuxBoundInfo* req = (TuxBoundInfo*)signal->getDataPtrSend();
- req->errorCode = RNIL;
- req->tuxScanPtrI = scanptr.p->scanAccPtr;
- Uint32 len = req->boundAiLength = copy_bounds(req->data, tcConnectptr.p);
- EXECUTE_DIRECT(DBTUX, GSN_TUX_BOUND_INFO, signal,
- TuxBoundInfo::SignalLength + len);
-
- jamEntry();
- if (req->errorCode != 0) {
- jam();
- /*
- * Cannot use STORED_PROCREF to abort since even the REF
- * returns a stored proc id. So record error and continue.
- * The scan is already Invalid in TUX and returns empty set.
- */
- tcConnectptr.p->errorCode = req->errorCode;
- }
- }
-
- scanptr.p->scanState = ScanRecord::WAIT_STORED_PROC_SCAN;
- if(scanptr.p->scanStoredProcId == RNIL)
- {
- jam();
- signal->theData[0] = tcConnectptr.p->tupConnectrec;
- signal->theData[1] = tcConnectptr.p->tableref;
- signal->theData[2] = scanptr.p->scanSchemaVersion;
- signal->theData[3] = ZSTORED_PROC_SCAN;
-
- signal->theData[4] = scanptr.p->scanAiLength;
- sendSignal(tcConnectptr.p->tcTupBlockref,
- GSN_STORED_PROCREQ, signal, 5, JBB);
-
- signal->theData[0] = tcConnectptr.p->tupConnectrec;
- AttrbufPtr regAttrinbufptr;
- Uint32 firstAttr = regAttrinbufptr.i = tcConnectptr.p->firstAttrinbuf;
- while (regAttrinbufptr.i != RNIL) {
- ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf);
- jam();
- Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN];
- ndbrequire(dataLen != 0);
- // first 3 words already set in STORED_PROCREQ
- MEMCOPY_NO_WORDS(&signal->theData[3],
- &regAttrinbufptr.p->attrbuf[0],
- dataLen);
- sendSignal(tcConnectptr.p->tcTupBlockref,
- GSN_ATTRINFO, signal, dataLen + 3, JBB);
- regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT];
- c_no_attrinbuf_recs++;
- }//while
-
- /**
- * Release attr info
- */
- if(firstAttr != RNIL)
- {
- regAttrinbufptr.p->attrbuf[ZINBUF_NEXT] = cfirstfreeAttrinbuf;
- cfirstfreeAttrinbuf = firstAttr;
- tcConnectptr.p->firstAttrinbuf = tcConnectptr.p->lastAttrinbuf = RNIL;
- }
- }
- else
- {
- jam();
- storedProcConfScanLab(signal);
- }
-}//Dblqh::accScanConfScanLab()
-
-#define print_buf(s,idx,len) {\
- printf(s); Uint32 t2=len; DatabufPtr t3; t3.i = idx; \
- while(t3.i != RNIL && t2-- > 0){\
- ptrCheckGuard(t3, cdatabufFileSize, databuf);\
- printf("%d ", t3.i); t3.i= t3.p->nextDatabuf;\
- } printf("\n"); }
-
-Uint32
-Dblqh::copy_bounds(Uint32 * dst, TcConnectionrec* tcPtrP)
-{
- /**
- * copy_bounds handles multiple bounds by
- * in the 16 upper bits of the first words (used to specify bound type)
- * setting the length of this specific bound
- *
- */
-
- DatabufPtr regDatabufptr;
- Uint32 left = 4 - tcPtrP->m_offset_current_keybuf; // left in buf
- Uint32 totalLen = tcPtrP->primKeyLen - 4;
- regDatabufptr.i = tcPtrP->firstTupkeybuf;
-
- ndbassert(tcPtrP->primKeyLen >= 4);
- ndbassert(tcPtrP->m_offset_current_keybuf < 4);
- ndbassert(!(totalLen == 0 && regDatabufptr.i != RNIL));
- ndbassert(!(totalLen != 0 && regDatabufptr.i == RNIL));
-
- if(totalLen)
- {
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- Uint32 sig0 = regDatabufptr.p->data[0];
- Uint32 sig1 = regDatabufptr.p->data[1];
- Uint32 sig2 = regDatabufptr.p->data[2];
- Uint32 sig3 = regDatabufptr.p->data[3];
-
- switch(left){
- case 4:
- * dst++ = sig0;
- case 3:
- * dst++ = sig1;
- case 2:
- * dst++ = sig2;
- case 1:
- * dst++ = sig3;
- }
-
- Uint32 first = (* (dst - left)); // First word in range
-
- // Length of this range
- Uint8 offset;
- const Uint32 len = (first >> 16) ? (first >> 16) : totalLen;
- tcPtrP->m_scan_curr_range_no = (first & 0xFFF0) >> 4;
- (* (dst - left)) = (first & 0xF); // Remove length & range no
-
- if(len < left)
- {
- offset = len;
- }
- else
- {
- Databuf * lastP;
- left = (len - left);
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
-
- while(left >= 4)
- {
- left -= 4;
- lastP = regDatabufptr.p;
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- sig0 = regDatabufptr.p->data[0];
- sig1 = regDatabufptr.p->data[1];
- sig2 = regDatabufptr.p->data[2];
- sig3 = regDatabufptr.p->data[3];
- regDatabufptr.i = regDatabufptr.p->nextDatabuf;
-
- * dst++ = sig0;
- * dst++ = sig1;
- * dst++ = sig2;
- * dst++ = sig3;
- }
-
- if(left > 0)
- {
- lastP = regDatabufptr.p;
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- sig0 = regDatabufptr.p->data[0];
- sig1 = regDatabufptr.p->data[1];
- sig2 = regDatabufptr.p->data[2];
- sig3 = regDatabufptr.p->data[3];
- * dst++ = sig0;
- * dst++ = sig1;
- * dst++ = sig2;
- * dst++ = sig3;
- }
- else
- {
- lastP = regDatabufptr.p;
- }
- offset = left & 3;
- lastP->nextDatabuf = cfirstfreeDatabuf;
- cfirstfreeDatabuf = tcPtrP->firstTupkeybuf;
- ndbassert(cfirstfreeDatabuf != RNIL);
- }
-
- if(len == totalLen && regDatabufptr.i != RNIL)
- {
- regDatabufptr.p->nextDatabuf = cfirstfreeDatabuf;
- cfirstfreeDatabuf = regDatabufptr.i;
- tcPtrP->lastTupkeybuf = regDatabufptr.i = RNIL;
- ndbassert(cfirstfreeDatabuf != RNIL);
- }
-
- tcPtrP->m_offset_current_keybuf = offset;
- tcPtrP->firstTupkeybuf = regDatabufptr.i;
- tcPtrP->primKeyLen = 4 + totalLen - len;
-
- return len;
- }
- return totalLen;
-}
-
-/* -------------------------------------------------------------------------
- * ENTER STORED_PROCCONF WITH
- * TC_CONNECTPTR,
- * TSTORED_PROC_ID
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_STORED_PROC_SCAN
- * ------------------------------------------------------------------------- */
-void Dblqh::storedProcConfScanLab(Signal* signal)
-{
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
- // STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- closeScanLab(signal);
- return;
- }//if
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_FIRST_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- jamLine(fragptr.p->fragStatus);
- ndbout_c("fragptr.p->fragStatus: %u",
- fragptr.p->fragStatus);
- ndbrequire(false);
- break;
- }//switch
- continueFirstScanAfterBlockedLab(signal);
-}//Dblqh::storedProcConfScanLab()
-
-void Dblqh::continueFirstScanAfterBlockedLab(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN;
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = RNIL;
- signal->theData[2] = NextScanReq::ZSCAN_NEXT;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
- return;
-}//Dblqh::continueFirstScanAfterBlockedLab()
-
-/* -------------------------------------------------------------------------
- * When executing a scan we must come up to the surface at times to make
- * sure we can quickly start local checkpoints.
- * ------------------------------------------------------------------------- */
-void Dblqh::execCHECK_LCP_STOP(Signal* signal)
-{
- jamEntry();
- scanptr.i = signal->theData[0];
- c_scanRecordPool.getPtr(scanptr);
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- if (signal->theData[1] == ZTRUE) {
- jam();
- signal->theData[0] = ZCHECK_LCP_STOP_BLOCKED;
- signal->theData[1] = scanptr.i;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
- signal->theData[0] = RNIL;
- return;
- }//if
- if (fragptr.p->fragStatus != Fragrecord::FSACTIVE) {
- ndbrequire(fragptr.p->fragStatus == Fragrecord::BLOCKED);
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_CHECK_STOPPED;
- signal->theData[0] = RNIL;
- }//if
-}//Dblqh::execCHECK_LCP_STOP()
-
-void Dblqh::checkLcpStopBlockedLab(Signal* signal)
-{
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- continueAfterCheckLcpStopBlocked(signal);
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_CHECK_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- }//switch
-}//Dblqh::checkLcpStopBlockedLab()
-
-void Dblqh::continueAfterCheckLcpStopBlocked(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = AccCheckScan::ZNOT_CHECK_LCP_STOP;
- EXECUTE_DIRECT(refToBlock(scanptr.p->scanBlockref), GSN_ACC_CHECK_SCAN,
- signal, 2);
-}//Dblqh::continueAfterCheckLcpStopBlocked()
-
-/* -------------------------------------------------------------------------
- * ENTER NEXT_SCANCONF
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_NEXT_SCAN
- * ------------------------------------------------------------------------- */
-void Dblqh::nextScanConfScanLab(Signal* signal)
-{
- NextScanConf * const nextScanConf = (NextScanConf *)&signal->theData[0];
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- if (nextScanConf->fragId == RNIL) {
- jam();
- /* ---------------------------------------------------------------------
- * THERE ARE NO MORE TUPLES TO FETCH. IF WE HAVE ANY
- * OPERATIONS STILL NEEDING A LOCK WE REPORT TO THE
- * APPLICATION AND CLOSE THE SCAN WHEN THE NEXT SCAN
- * REQUEST IS RECEIVED. IF WE DO NOT HAVE ANY NEED FOR
- * LOCKS WE CAN CLOSE THE SCAN IMMEDIATELY.
- * --------------------------------------------------------------------- */
- /*************************************************************
- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- ************************************************************ */
- if (!scanptr.p->scanLockHold)
- {
- jam();
- closeScanLab(signal);
- return;
- }
-
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- if ((scanptr.p->scanLockHold == ZTRUE) &&
- (scanptr.p->m_curr_batch_size_rows > 0)) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- jam();
- closeScanLab(signal);
- return;
- }//if
-
- if (scanptr.p->m_curr_batch_size_rows > 0) {
- jam();
-
- if((tcConnectptr.p->primKeyLen - 4) == 0)
- scanptr.p->scanCompletedStatus = ZTRUE;
-
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- return;
- }//if
- closeScanLab(signal);
- return;
- }//if
-
- // If accOperationPtr == RNIL no record was returned by ACC
- Uint32 accOpPtr = nextScanConf->accOperationPtr;
- if (accOpPtr == RNIL)
- {
- jam();
- /*************************************************************
- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- ************************************************************ */
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- if ((scanptr.p->scanLockHold == ZTRUE) &&
- (scanptr.p->m_curr_batch_size_rows > 0)) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- jam();
- closeScanLab(signal);
- return;
- }//if
-
- if (scanptr.p->m_curr_batch_size_rows > 0) {
- jam();
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- return;
- }//if
-
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(scanptr.p->scanBlockref,
- GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- }//if
- jam();
- set_acc_ptr_in_scan_record(scanptr.p,
- scanptr.p->m_curr_batch_size_rows,
- accOpPtr);
-
- jam();
- nextScanConfLoopLab(signal);
-}//Dblqh::nextScanConfScanLab()
-
-void Dblqh::nextScanConfLoopLab(Signal* signal)
-{
- /* ----------------------------------------------------------------------
- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- * ---------------------------------------------------------------------- */
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
- if ((scanptr.p->scanLockHold == ZTRUE) &&
- (scanptr.p->m_curr_batch_size_rows > 0)) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- closeScanLab(signal);
- return;
- }//if
-
- Fragrecord* fragPtrP= fragptr.p;
- if (scanptr.p->rangeScan) {
- jam();
- // for ordered index use primary table
- fragPtrP= c_fragment_pool.getPtr(fragPtrP->tableFragptr);
- }
-
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_TUPKEY;
- if(tcConnectptr.p->m_disk_table)
- {
- next_scanconf_load_diskpage(signal, scanptr, tcConnectptr,fragPtrP);
- }
- else
- {
- next_scanconf_tupkeyreq(signal, scanptr, tcConnectptr.p, fragPtrP, RNIL);
- }
-}
-
-void
-Dblqh::next_scanconf_load_diskpage(Signal* signal,
- ScanRecordPtr scanPtr,
- Ptr<TcConnectionrec> regTcPtr,
- Fragrecord* fragPtrP)
-{
- jam();
-
- int res;
- Uint32 local_key = scanPtr.p->m_row_id.ref();
-
- if((res= c_tup->load_diskpage_scan(signal,
- regTcPtr.p->tupConnectrec,
- fragPtrP->tupFragptr,
- local_key,
- 0)) > 0)
- {
- next_scanconf_tupkeyreq(signal, scanptr, regTcPtr.p, fragPtrP, res);
- }
- else if(unlikely(res != 0))
- {
- jam();
- TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
- ref->userRef= regTcPtr.i;
- ref->errorCode= ~0;
- execTUPKEYREF(signal);
- }
-}
-
-void
-Dblqh::next_scanconf_load_diskpage_callback(Signal* signal,
- Uint32 callbackData,
- Uint32 disk_page)
-{
- jamEntry();
-
- Ptr<TcConnectionrec> regTcPtr;
- regTcPtr.i= callbackData;
- ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
-
- ScanRecordPtr scanPtr;
- c_scanRecordPool.getPtr(scanPtr, regTcPtr.p->tcScanRec);
-
- if(disk_page > 0)
- {
- FragrecordPtr fragPtr;
- c_fragment_pool.getPtr(fragPtr, regTcPtr.p->fragmentptr);
-
- if (scanPtr.p->rangeScan) {
- jam();
- // for ordered index use primary table
- fragPtr.p = c_fragment_pool.getPtr(fragPtr.p->tableFragptr);
- }
-
- next_scanconf_tupkeyreq(signal, scanPtr, regTcPtr.p, fragPtr.p, disk_page);
- }
- else
- {
- TupKeyRef * ref = (TupKeyRef *)signal->getDataPtr();
- ref->userRef= callbackData;
- ref->errorCode= disk_page;
- execTUPKEYREF(signal);
- }
-}
-
-void
-Dblqh::next_scanconf_tupkeyreq(Signal* signal,
- Ptr<ScanRecord> scanPtr,
- TcConnectionrec * regTcPtr,
- Fragrecord* fragPtrP,
- Uint32 disk_page)
-{
- jam();
- Uint32 reqinfo = (scanPtr.p->scanLockHold == ZFALSE);
- reqinfo = reqinfo + (regTcPtr->operation << 6);
- reqinfo = reqinfo + (regTcPtr->opExec << 10);
-
- TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
-
- tupKeyReq->connectPtr = regTcPtr->tupConnectrec;
- tupKeyReq->request = reqinfo;
- tupKeyReq->keyRef1 = scanPtr.p->m_row_id.m_page_no;
- tupKeyReq->keyRef2 = scanPtr.p->m_row_id.m_page_idx;
- tupKeyReq->attrBufLen = 0;
- tupKeyReq->opRef = scanPtr.p->scanApiOpPtr;
- tupKeyReq->applRef = scanPtr.p->scanApiBlockref;
- tupKeyReq->storedProcedure = scanPtr.p->scanStoredProcId;
- tupKeyReq->transId1 = regTcPtr->transid[0];
- tupKeyReq->transId2 = regTcPtr->transid[1];
- tupKeyReq->fragPtr = fragPtrP->tupFragptr;
- tupKeyReq->primaryReplica = (regTcPtr->seqNoReplica == 0)?true:false;
- tupKeyReq->coordinatorTC = regTcPtr->tcBlockref;
- tupKeyReq->tcOpIndex = regTcPtr->tcOprec;
- tupKeyReq->savePointId = regTcPtr->savePointId;
- tupKeyReq->disk_page= disk_page;
- Uint32 blockNo = refToBlock(regTcPtr->tcTupBlockref);
- EXECUTE_DIRECT(blockNo, GSN_TUPKEYREQ, signal,
- TupKeyReq::SignalLength);
-}
-
-/* -------------------------------------------------------------------------
- * RECEPTION OF FURTHER KEY INFORMATION WHEN KEY SIZE > 16 BYTES.
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_SCAN_KEYINFO
- * ------------------------------------------------------------------------- */
-void
-Dblqh::keyinfoLab(const Uint32 * src, const Uint32 * end)
-{
- do {
- jam();
- seizeTupkeybuf(0);
- databufptr.p->data[0] = * src ++;
- databufptr.p->data[1] = * src ++;
- databufptr.p->data[2] = * src ++;
- databufptr.p->data[3] = * src ++;
- } while (src < end);
-}//Dblqh::keyinfoLab()
-
-Uint32
-Dblqh::readPrimaryKeys(ScanRecord *scanP, TcConnectionrec *tcConP, Uint32 *dst)
-{
- Uint32 tableId = tcConP->tableref;
- Uint32 fragId = tcConP->fragmentid;
- Uint32 fragPageId = scanP->m_row_id.m_page_no;
- Uint32 pageIndex = scanP->m_row_id.m_page_idx;
-
- if(scanP->rangeScan)
- {
- jam();
- // for ordered index use primary table
- FragrecordPtr tFragPtr;
- tFragPtr.i = fragptr.p->tableFragptr;
- c_fragment_pool.getPtr(tFragPtr);
- tableId = tFragPtr.p->tabRef;
- }
-
- int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, dst, false);
- jamEntry();
- if(0)
- ndbout_c("readPrimaryKeys(table: %d fragment: %d [ %d %d ] -> %d",
- tableId, fragId, fragPageId, pageIndex, ret);
- ndbassert(ret > 0);
-
- return ret;
-}
-
-/* -------------------------------------------------------------------------
- * ENTER TUPKEYCONF
- * -------------------------------------------------------------------------
- * PRECONDITION: TRANSACTION_STATE = SCAN_TUPKEY
- * ------------------------------------------------------------------------- */
-void Dblqh::scanTupkeyConfLab(Signal* signal)
-{
- const TupKeyConf * conf = (TupKeyConf *)signal->getDataPtr();
- UintR tdata4 = conf->readLength;
- UintR tdata5 = conf->lastRow;
-
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
-
- Uint32 rows = scanptr.p->m_curr_batch_size_rows;
- Uint32 accOpPtr= get_acc_ptr_from_scan_record(scanptr.p, rows, false);
- if (accOpPtr != (Uint32)-1)
- {
- c_acc->execACCKEY_ORD(signal, accOpPtr);
- jamEntry();
- }
- else
- {
- ndbassert(refToBlock(scanptr.p->scanBlockref) != DBACC);
- }
-
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- /* ---------------------------------------------------------------------
- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- * --------------------------------------------------------------------- */
- if ((scanptr.p->scanLockHold == ZTRUE) && rows)
- {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- jam();
- closeScanLab(signal);
- return;
- }//if
- if (scanptr.p->scanKeyinfoFlag) {
- jam();
- // Inform API about keyinfo len aswell
- tdata4 += sendKeyinfo20(signal, scanptr.p, tcConnectptr.p);
- }//if
- ndbrequire(scanptr.p->m_curr_batch_size_rows < MAX_PARALLEL_OP_PER_SCAN);
- scanptr.p->m_curr_batch_size_bytes+= tdata4;
- scanptr.p->m_curr_batch_size_rows = rows + 1;
- scanptr.p->m_last_row = tdata5;
- if (scanptr.p->check_scan_batch_completed() | tdata5){
- if (scanptr.p->scanLockHold == ZTRUE) {
- jam();
- scanptr.p->scanState = ScanRecord::WAIT_SCAN_NEXTREQ;
- sendScanFragConf(signal, ZFALSE);
- return;
- } else {
- jam();
- scanptr.p->scanReleaseCounter = rows + 1;
- scanReleaseLocksLab(signal);
- return;
- }
- } else {
- if (scanptr.p->scanLockHold == ZTRUE) {
- jam();
- scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT;
- } else {
- jam();
- scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT_COMMIT;
- }
- }
- scanNextLoopLab(signal);
-}//Dblqh::scanTupkeyConfLab()
-
-void Dblqh::scanNextLoopLab(Signal* signal)
-{
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- }//switch
- continueScanAfterBlockedLab(signal);
-}//Dblqh::scanNextLoopLab()
-
-void Dblqh::continueScanAfterBlockedLab(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- Uint32 accOpPtr;
- if (scanptr.p->scanFlag == NextScanReq::ZSCAN_NEXT_ABORT) {
- jam();
- scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT_COMMIT;
- accOpPtr= get_acc_ptr_from_scan_record(scanptr.p,
- scanptr.p->m_curr_batch_size_rows,
- false);
- scanptr.p->scan_acc_index--;
- } else if (scanptr.p->scanFlag == NextScanReq::ZSCAN_NEXT_COMMIT) {
- jam();
- accOpPtr= get_acc_ptr_from_scan_record(scanptr.p,
- scanptr.p->m_curr_batch_size_rows-1,
- false);
- } else {
- jam();
- accOpPtr = RNIL; // The value is not used in ACC
- }//if
- scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN;
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = accOpPtr;
- signal->theData[2] = scanptr.p->scanFlag;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
-}//Dblqh::continueScanAfterBlockedLab()
-
-/* -------------------------------------------------------------------------
- * ENTER TUPKEYREF WITH
- * TC_CONNECTPTR,
- * TERROR_CODE
- * -------------------------------------------------------------------------
- * PRECONDITION: TRANSACTION_STATE = SCAN_TUPKEY
- * ------------------------------------------------------------------------- */
-void Dblqh::scanTupkeyRefLab(Signal* signal)
-{
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
-
- Uint32 rows = scanptr.p->m_curr_batch_size_rows;
- Uint32 accOpPtr= get_acc_ptr_from_scan_record(scanptr.p, rows, false);
- if (accOpPtr != (Uint32)-1)
- {
- c_acc->execACCKEY_ORD(signal, accOpPtr);
- }
- else
- {
- ndbassert(refToBlock(scanptr.p->scanBlockref) != DBACC);
- }
-
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- /* ---------------------------------------------------------------------
- * STOP THE SCAN PROCESS IF THIS HAS BEEN REQUESTED.
- * --------------------------------------------------------------------- */
- if ((scanptr.p->scanLockHold == ZTRUE) && rows)
- {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- scanReleaseLocksLab(signal);
- return;
- }//if
- jam();
- closeScanLab(signal);
- return;
- }//if
- if ((terrorCode != ZSEARCH_CONDITION_FALSE) &&
- (terrorCode != ZNO_TUPLE_FOUND) &&
- (terrorCode >= ZUSER_ERROR_CODE_LIMIT)) {
- scanptr.p->scanErrorCounter++;
- tcConnectptr.p->errorCode = terrorCode;
-
- if (scanptr.p->scanLockHold == ZTRUE) {
- jam();
- scanptr.p->scanReleaseCounter = 1;
- } else {
- jam();
- scanptr.p->m_curr_batch_size_rows = rows + 1;
- scanptr.p->scanReleaseCounter = rows + 1;
- }//if
- /* --------------------------------------------------------------------
- * WE NEED TO RELEASE ALL LOCKS CURRENTLY
- * HELD BY THIS SCAN.
- * -------------------------------------------------------------------- */
- scanReleaseLocksLab(signal);
- return;
- }//if
- Uint32 time_passed= tcConnectptr.p->tcTimer - cLqhTimeOutCount;
- if (rows) {
- if (time_passed > 1) {
- /* -----------------------------------------------------------------------
- * WE NEED TO ENSURE THAT WE DO NOT SEARCH FOR THE NEXT TUPLE FOR A
- * LONG TIME WHILE WE KEEP A LOCK ON A FOUND TUPLE. WE RATHER REPORT
- * THE FOUND TUPLE IF FOUND TUPLES ARE RARE. If more than 10 ms passed we
- * send the found tuples to the API.
- * ----------------------------------------------------------------------- */
- scanptr.p->scanReleaseCounter = rows + 1;
- scanReleaseLocksLab(signal);
- return;
- }
- } else {
- if (time_passed > 10) {
- jam();
- signal->theData[0]= scanptr.i;
- signal->theData[1]= tcConnectptr.p->transid[0];
- signal->theData[2]= tcConnectptr.p->transid[1];
- execSCAN_HBREP(signal);
- }
- }
- scanptr.p->scanFlag = NextScanReq::ZSCAN_NEXT_ABORT;
- scanNextLoopLab(signal);
-}//Dblqh::scanTupkeyRefLab()
-
-/* -------------------------------------------------------------------------
- * THE SCAN HAS BEEN COMPLETED. EITHER BY REACHING THE END OR BY COMMAND
- * FROM THE APPLICATION OR BY SOME SORT OF ERROR CONDITION.
- * ------------------------------------------------------------------------- */
-void Dblqh::closeScanLab(Signal* signal)
-{
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_CLOSE_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- ndbrequire(false);
- }//switch
- continueCloseScanAfterBlockedLab(signal);
-}//Dblqh::closeScanLab()
-
-void Dblqh::continueCloseScanAfterBlockedLab(Signal* signal)
-{
- tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanState = ScanRecord::WAIT_CLOSE_SCAN;
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = RNIL;
- signal->theData[2] = NextScanReq::ZSCAN_CLOSE;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
-}//Dblqh::continueCloseScanAfterBlockedLab()
-
-/* -------------------------------------------------------------------------
- * ENTER NEXT_SCANCONF
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_CLOSE_SCAN
- * ------------------------------------------------------------------------- */
-void Dblqh::accScanCloseConfLab(Signal* signal)
-{
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-
- if((tcConnectptr.p->primKeyLen - 4) > 0 &&
- scanptr.p->scanCompletedStatus != ZTRUE)
- {
- jam();
- continueAfterReceivingAllAiLab(signal);
- return;
- }
-
- scanptr.p->scanState = ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN;
- signal->theData[0] = tcConnectptr.p->tupConnectrec;
- signal->theData[1] = tcConnectptr.p->tableref;
- signal->theData[2] = scanptr.p->scanSchemaVersion;
- signal->theData[3] = ZDELETE_STORED_PROC_ID;
- signal->theData[4] = scanptr.p->scanStoredProcId;
- sendSignal(tcConnectptr.p->tcTupBlockref,
- GSN_STORED_PROCREQ, signal, 5, JBB);
-}//Dblqh::accScanCloseConfLab()
-
-/* -------------------------------------------------------------------------
- * ENTER STORED_PROCCONF WITH
- * -------------------------------------------------------------------------
- * PRECONDITION: SCAN_STATE = WAIT_DELETE_STORED_PROC_ID_SCAN
- * ------------------------------------------------------------------------- */
-void Dblqh::tupScanCloseConfLab(Signal* signal)
-{
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- tcNodeFailptr.p->tcRecNow = tcConnectptr.i + 1;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else if (tcConnectptr.p->errorCode != 0) {
- jam();
- ScanFragRef * ref = (ScanFragRef*)&signal->theData[0];
- ref->senderData = tcConnectptr.p->clientConnectrec;
- ref->transId1 = tcConnectptr.p->transid[0];
- ref->transId2 = tcConnectptr.p->transid[1];
- ref->errorCode = tcConnectptr.p->errorCode;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGREF, signal,
- ScanFragRef::SignalLength, JBB);
- } else {
- jam();
- sendScanFragConf(signal, ZSCAN_FRAG_CLOSED);
- }//if
- finishScanrec(signal);
- releaseScanrec(signal);
- tcConnectptr.p->tcScanRec = RNIL;
- deleteTransidHash(signal);
- releaseOprec(signal);
- releaseTcrec(signal, tcConnectptr);
-}//Dblqh::tupScanCloseConfLab()
-
-/* =========================================================================
- * ======= INITIATE SCAN RECORD =======
- *
- * SUBROUTINE SHORT NAME = ISC
- * ========================================================================= */
-Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
-{
- const Uint32 reqinfo = scanFragReq->requestInfo;
- const Uint32 max_rows = scanFragReq->batch_size_rows;
- const Uint32 max_bytes = scanFragReq->batch_size_bytes;
- const Uint32 scanLockMode = ScanFragReq::getLockMode(reqinfo);
- const Uint32 scanLockHold = ScanFragReq::getHoldLockFlag(reqinfo);
- const Uint32 keyinfo = ScanFragReq::getKeyinfoFlag(reqinfo);
- const Uint32 readCommitted = ScanFragReq::getReadCommittedFlag(reqinfo);
- const Uint32 rangeScan = ScanFragReq::getRangeScanFlag(reqinfo);
- const Uint32 descending = ScanFragReq::getDescendingFlag(reqinfo);
- Uint32 tupScan = ScanFragReq::getTupScanFlag(reqinfo);
- const Uint32 attrLen = ScanFragReq::getAttrLen(reqinfo);
- const Uint32 scanPrio = ScanFragReq::getScanPrio(reqinfo);
-
- scanptr.p->scanKeyinfoFlag = keyinfo;
- scanptr.p->scanLockHold = scanLockHold;
- scanptr.p->scanCompletedStatus = ZFALSE;
- scanptr.p->scanType = ScanRecord::SCAN;
- scanptr.p->scanApiBlockref = scanFragReq->resultRef;
- scanptr.p->scanAiLength = attrLen;
- scanptr.p->scanTcrec = tcConnectptr.i;
- scanptr.p->scanSchemaVersion = scanFragReq->schemaVersion;
-
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
- scanptr.p->m_max_batch_size_rows = max_rows;
- scanptr.p->m_max_batch_size_bytes = max_bytes;
-
-#if 0
- if (! rangeScan)
- tupScan = 1;
-#endif
-
- if (! rangeScan && ! tupScan)
- scanptr.p->scanBlockref = tcConnectptr.p->tcAccBlockref;
- else if (! tupScan)
- scanptr.p->scanBlockref = tcConnectptr.p->tcTuxBlockref;
- else
- scanptr.p->scanBlockref = tcConnectptr.p->tcTupBlockref;
-
- scanptr.p->scanErrorCounter = 0;
- scanptr.p->scanLockMode = scanLockMode;
- scanptr.p->readCommitted = readCommitted;
- scanptr.p->rangeScan = rangeScan;
- scanptr.p->descending = descending;
- scanptr.p->tupScan = tupScan;
- scanptr.p->lcpScan = ScanFragReq::getLcpScanFlag(reqinfo);
- scanptr.p->scanState = ScanRecord::SCAN_FREE;
- scanptr.p->scanFlag = ZFALSE;
- scanptr.p->m_row_id.setNull();
- scanptr.p->scanTcWaiting = ZTRUE;
- scanptr.p->scanNumber = ~0;
- scanptr.p->scanApiOpPtr = scanFragReq->clientOpPtr;
- scanptr.p->m_last_row = 0;
- scanptr.p->scanStoredProcId = RNIL;
- scanptr.p->copyPtr = RNIL;
- if (max_rows == 0 || (max_bytes > 0 && max_rows > max_bytes)){
- jam();
- return ScanFragRef::ZWRONG_BATCH_SIZE;
- }
- if (!seize_acc_ptr_list(scanptr.p, max_rows)){
- jam();
- return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR;
- }
- /**
- * Used for scan take over
- */
- FragrecordPtr tFragPtr;
- tFragPtr.i = fragptr.p->tableFragptr;
- c_fragment_pool.getPtr(tFragPtr);
- scanptr.p->fragPtrI = fragptr.p->tableFragptr;
-
- /**
- * !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1) = 1-11
- * idx uses from MAX_PARALLEL_SCANS_PER_FRAG - MAX = 12-42)
- */
- tupScan = 0; // Make sure that close tup scan does not start acc scan incorrectly
- Uint32 start = (rangeScan || tupScan) ? MAX_PARALLEL_SCANS_PER_FRAG : 1 ;
- Uint32 stop = (rangeScan || tupScan) ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG :
- MAX_PARALLEL_SCANS_PER_FRAG - 1;
- stop += start;
- Uint32 free = tFragPtr.p->m_scanNumberMask.find(start);
-
- if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){
- jam();
-
- if(scanPrio == 0){
- jam();
- return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR;
- }
-
- /**
- * Put on queue
- */
- scanptr.p->scanState = ScanRecord::IN_QUEUE;
- LocalDLFifoList<ScanRecord> queue(c_scanRecordPool,
- fragptr.p->m_queuedScans);
- queue.add(scanptr);
- return ZOK;
- }
-
- scanptr.p->scanNumber = free;
- tFragPtr.p->m_scanNumberMask.clear(free);// Update mask
-
- LocalDLList<ScanRecord> active(c_scanRecordPool, fragptr.p->m_activeScans);
- active.add(scanptr);
- if(scanptr.p->scanKeyinfoFlag){
- jam();
-#if defined VM_TRACE || defined ERROR_INSERT
- ScanRecordPtr tmp;
- ndbrequire(!c_scanTakeOverHash.find(tmp, * scanptr.p));
-#endif
-#ifdef TRACE_SCAN_TAKEOVER
- ndbout_c("adding (%d %d) table: %d fragId: %d frag.i: %d tableFragptr: %d",
- scanptr.p->scanNumber, scanptr.p->fragPtrI,
- tabptr.i, scanFragReq->fragmentNoKeyLen & 0xFFFF,
- fragptr.i, fragptr.p->tableFragptr);
-#endif
- c_scanTakeOverHash.add(scanptr);
- }
- init_acc_ptr_list(scanptr.p);
- return ZOK;
-}
-
-/* =========================================================================
- * ======= INITIATE TC RECORD AT SCAN =======
- *
- * SUBROUTINE SHORT NAME = IST
- * ========================================================================= */
-void Dblqh::initScanTc(const ScanFragReq* req,
- Uint32 transid1,
- Uint32 transid2,
- Uint32 fragId,
- Uint32 nodeId)
-{
- tcConnectptr.p->transid[0] = transid1;
- tcConnectptr.p->transid[1] = transid2;
- tcConnectptr.p->tcScanRec = scanptr.i;
- tcConnectptr.p->tableref = tabptr.i;
- tcConnectptr.p->fragmentid = fragId;
- tcConnectptr.p->fragmentptr = fragptr.i;
- tcConnectptr.p->tcOprec = tcConnectptr.p->clientConnectrec;
- tcConnectptr.p->tcBlockref = tcConnectptr.p->clientBlockref;
- tcConnectptr.p->errorCode = 0;
- tcConnectptr.p->reclenAiLqhkey = 0;
- tcConnectptr.p->abortState = TcConnectionrec::ABORT_IDLE;
- tcConnectptr.p->nextReplica = nodeId;
- tcConnectptr.p->currTupAiLen = 0;
- tcConnectptr.p->opExec = 1;
- tcConnectptr.p->operation = ZREAD;
- tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
- tcConnectptr.p->commitAckMarker = RNIL;
- tcConnectptr.p->m_offset_current_keybuf = 0;
- tcConnectptr.p->m_scan_curr_range_no = 0;
- tcConnectptr.p->m_dealloc = 0;
- tcConnectptr.p->activeCreat = Fragrecord::AC_NORMAL;
- TablerecPtr tTablePtr;
- tTablePtr.i = tabptr.p->primaryTableId;
- ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
- tcConnectptr.p->m_disk_table = tTablePtr.p->m_disk_table &&
- (!req || !ScanFragReq::getNoDiskFlag(req->requestInfo));
-
- tabptr.p->usageCount++;
-}//Dblqh::initScanTc()
-
-/* =========================================================================
- * ======= FINISH SCAN RECORD =======
- *
- * REMOVE SCAN RECORD FROM PER FRAGMENT LIST.
- * ========================================================================= */
-void Dblqh::finishScanrec(Signal* signal)
-{
- release_acc_ptr_list(scanptr.p);
-
- LocalDLFifoList<ScanRecord> queue(c_scanRecordPool,
- fragptr.p->m_queuedScans);
-
- if(scanptr.p->scanState == ScanRecord::IN_QUEUE){
- jam();
- queue.release(scanptr);
- return;
- }
-
- if(scanptr.p->scanKeyinfoFlag){
- jam();
- ScanRecordPtr tmp;
-#ifdef TRACE_SCAN_TAKEOVER
- ndbout_c("removing (%d %d)", scanptr.p->scanNumber, scanptr.p->fragPtrI);
-#endif
- c_scanTakeOverHash.remove(tmp, * scanptr.p);
- ndbrequire(tmp.p == scanptr.p);
- }
-
- LocalDLList<ScanRecord> scans(c_scanRecordPool, fragptr.p->m_activeScans);
- scans.release(scanptr);
-
- FragrecordPtr tFragPtr;
- tFragPtr.i = scanptr.p->fragPtrI;
- c_fragment_pool.getPtr(tFragPtr);
-
- const Uint32 scanNumber = scanptr.p->scanNumber;
- ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber));
- ScanRecordPtr restart;
-
- /**
- * Start on of queued scans
- */
- if(scanNumber == NR_ScanNo || !queue.first(restart)){
- jam();
- tFragPtr.p->m_scanNumberMask.set(scanNumber);
- return;
- }
-
- if(ERROR_INSERTED(5034)){
- jam();
- tFragPtr.p->m_scanNumberMask.set(scanNumber);
- return;
- }
-
- ndbrequire(restart.p->scanState == ScanRecord::IN_QUEUE);
-
- ScanRecordPtr tmpScan = scanptr;
- TcConnectionrecPtr tmpTc = tcConnectptr;
-
- tcConnectptr.i = restart.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- restart.p->scanNumber = scanNumber;
-
- queue.remove(restart);
- scans.add(restart);
- if(restart.p->scanKeyinfoFlag){
- jam();
-#if defined VM_TRACE || defined ERROR_INSERT
- ScanRecordPtr tmp;
- ndbrequire(!c_scanTakeOverHash.find(tmp, * restart.p));
-#endif
- c_scanTakeOverHash.add(restart);
-#ifdef TRACE_SCAN_TAKEOVER
- ndbout_c("adding-r (%d %d)", restart.p->scanNumber, restart.p->fragPtrI);
-#endif
- }
-
- /**
- * This state is a bit weird, but that what set in initScanRec
- */
- restart.p->scanState = ScanRecord::SCAN_FREE;
- if(tcConnectptr.p->transactionState == TcConnectionrec::SCAN_STATE_USED)
- {
- scanptr = restart;
- continueAfterReceivingAllAiLab(signal);
- }
- else
- {
- ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_SCAN_AI);
- }
-
- scanptr = tmpScan;
- tcConnectptr = tmpTc;
-}//Dblqh::finishScanrec()
-
-/* =========================================================================
- * ======= RELEASE SCAN RECORD =======
- *
- * RELEASE A SCAN RECORD TO THE FREELIST.
- * ========================================================================= */
-void Dblqh::releaseScanrec(Signal* signal)
-{
- scanptr.p->scanState = ScanRecord::SCAN_FREE;
- scanptr.p->scanType = ScanRecord::ST_IDLE;
- scanptr.p->scanTcWaiting = ZFALSE;
- cbookedAccOps -= scanptr.p->m_max_batch_size_rows;
- cscanNoFreeRec++;
-}//Dblqh::releaseScanrec()
-
-/* ------------------------------------------------------------------------
- * ------- SEND KEYINFO20 TO API -------
- *
- * ------------------------------------------------------------------------ */
-Uint32 Dblqh::sendKeyinfo20(Signal* signal,
- ScanRecord * scanP,
- TcConnectionrec * tcConP)
-{
- ndbrequire(scanP->m_curr_batch_size_rows < MAX_PARALLEL_OP_PER_SCAN);
- KeyInfo20 * keyInfo = (KeyInfo20 *)&signal->theData[0];
-
- /**
- * Note that this code requires signal->theData to be big enough for
- * a entire key
- */
- const BlockReference ref = scanP->scanApiBlockref;
- const Uint32 scanOp = scanP->m_curr_batch_size_rows;
- const Uint32 nodeId = refToNode(ref);
- const bool connectedToNode = getNodeInfo(nodeId).m_connected;
-#ifdef NOT_USED
- 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));
-#endif
- const bool longable = true; // TODO is_api && !old_dest;
-
- Uint32 * dst = keyInfo->keyData;
- dst += nodeId == getOwnNodeId() ? 0 : KeyInfo20::DataLength;
-
- Uint32 keyLen = readPrimaryKeys(scanP, tcConP, dst);
- Uint32 fragId = tcConP->fragmentid;
- keyInfo->clientOpPtr = scanP->scanApiOpPtr;
- keyInfo->keyLen = keyLen;
- keyInfo->scanInfo_Node =
- KeyInfo20::setScanInfo(scanOp, scanP->scanNumber) + (fragId << 20);
- keyInfo->transId1 = tcConP->transid[0];
- keyInfo->transId2 = tcConP->transid[1];
-
- Uint32 * src = signal->theData+25;
- if(connectedToNode){
- jam();
-
- 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;
- }
-
- MEMCOPY_NO_WORDS(keyInfo->keyData, src, keyLen);
- sendSignal(ref, GSN_KEYINFO20, signal,
- KeyInfo20::HeaderLength+keyLen, JBB);
- return keyLen;
- }
-
- LinearSectionPtr ptr[3];
- ptr[0].p = src;
- ptr[0].sz = keyLen;
- sendSignal(ref, GSN_KEYINFO20, signal, KeyInfo20::HeaderLength,
- JBB, ptr, 1);
- return keyLen;
- }
-
- EXECUTE_DIRECT(refToBlock(ref), GSN_KEYINFO20, signal,
- KeyInfo20::HeaderLength + keyLen);
- jamEntry();
- return keyLen;
- }
-
- /**
- * 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();
-
- 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);
- src += KeyInfo20::DataLength - 1;
- keyLen -= KeyInfo20::DataLength - 1;
- }
-
- MEMCOPY_NO_WORDS(keyInfo->keyData, src, keyLen);
- keyInfo->keyData[keyLen] = ref;
- sendSignal(routeBlockref, GSN_KEYINFO20_R, signal,
- KeyInfo20::HeaderLength+keyLen+1, JBB);
- return keyLen;
- }
-
- 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 keyLen;
-}
-
-/* ------------------------------------------------------------------------
- * ------- SEND SCAN_FRAGCONF TO TC THAT CONTROLS THE SCAN -------
- *
- * ------------------------------------------------------------------------ */
-void Dblqh::sendScanFragConf(Signal* signal, Uint32 scanCompleted)
-{
- Uint32 completed_ops= scanptr.p->m_curr_batch_size_rows;
- Uint32 total_len= scanptr.p->m_curr_batch_size_bytes;
- scanptr.p->scanTcWaiting = ZFALSE;
-
- if(ERROR_INSERTED(5037)){
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
- ScanFragConf * conf = (ScanFragConf*)&signal->theData[0];
-#ifdef NOT_USED
- NodeId tc_node_id= refToNode(tcConnectptr.p->clientBlockref);
-#endif
- Uint32 trans_id1= tcConnectptr.p->transid[0];
- Uint32 trans_id2= tcConnectptr.p->transid[1];
-
- conf->senderData = tcConnectptr.p->clientConnectrec;
- conf->completedOps = completed_ops;
- conf->fragmentCompleted = scanCompleted;
- conf->transId1 = trans_id1;
- conf->transId2 = trans_id2;
- conf->total_len= total_len;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_SCAN_FRAGCONF,
- signal, ScanFragConf::SignalLength, JBB);
-
- if(!scanptr.p->scanLockHold)
- {
- jam();
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
- }
-}//Dblqh::sendScanFragConf()
-
-/* ######################################################################### */
-/* ####### NODE RECOVERY MODULE ####### */
-/* */
-/* ######################################################################### */
-/*---------------------------------------------------------------------------*/
-/* */
-/* THIS MODULE IS USED WHEN A NODE HAS FAILED. IT PERFORMS A COPY OF A */
-/* FRAGMENT TO A NEW REPLICA OF THE FRAGMENT. IT DOES ALSO SHUT DOWN ALL */
-/* CONNECTIONS TO THE FAILED NODE. */
-/*---------------------------------------------------------------------------*/
-Uint32
-Dblqh::calculateHash(Uint32 tableId, const Uint32* src)
-{
- jam();
- Uint64 Tmp[(MAX_KEY_SIZE_IN_WORDS*MAX_XFRM_MULTIPLY) >> 1];
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
- Uint32 keyLen = xfrm_key(tableId, src, (Uint32*)Tmp, sizeof(Tmp) >> 2,
- keyPartLen);
- ndbrequire(keyLen);
-
- return md5_hash(Tmp, keyLen);
-}//Dblqh::calculateHash()
-
-/**
- * PREPARE COPY FRAG REQ
- */
-void
-Dblqh::execPREPARE_COPY_FRAG_REQ(Signal* signal)
-{
- jamEntry();
- PrepareCopyFragReq req = *(PrepareCopyFragReq*)signal->getDataPtr();
-
- CRASH_INSERTION(5045);
-
- tabptr.i = req.tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- Uint32 max_page = RNIL;
-
- if (getOwnNodeId() != req.startingNodeId)
- {
- jam();
- /**
- * This is currently dead code...
- * but is provided so we can impl. a better scan+delete on
- * starting node wo/ having to change running node
- */
- ndbrequire(getOwnNodeId() == req.copyNodeId);
- c_tup->get_frag_info(req.tableId, req.fragId, &max_page);
-
- PrepareCopyFragConf* conf = (PrepareCopyFragConf*)signal->getDataPtrSend();
- conf->senderData = req.senderData;
- conf->senderRef = reference();
- conf->tableId = req.tableId;
- conf->fragId = req.fragId;
- conf->copyNodeId = req.copyNodeId;
- conf->startingNodeId = req.startingNodeId;
- conf->maxPageNo = max_page;
- sendSignal(req.senderRef, GSN_PREPARE_COPY_FRAG_CONF,
- signal, PrepareCopyFragConf::SignalLength, JBB);
-
- return;
- }
-
- if (! DictTabInfo::isOrderedIndex(tabptr.p->tableType))
- {
- jam();
- ndbrequire(getFragmentrec(signal, req.fragId));
-
- /**
- *
- */
- if (cstartType == NodeState::ST_SYSTEM_RESTART)
- {
- jam();
- signal->theData[0] = fragptr.p->tabRef;
- signal->theData[1] = fragptr.p->fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
- }
-
-
- /**
- *
- */
- fragptr.p->m_copy_started_state = Fragrecord::AC_IGNORED;
- fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
- fragptr.p->logFlag = Fragrecord::STATE_FALSE;
-
- c_tup->get_frag_info(req.tableId, req.fragId, &max_page);
- }
-
- PrepareCopyFragConf* conf = (PrepareCopyFragConf*)signal->getDataPtrSend();
- conf->senderData = req.senderData;
- conf->senderRef = reference();
- conf->tableId = req.tableId;
- conf->fragId = req.fragId;
- conf->copyNodeId = req.copyNodeId;
- conf->startingNodeId = req.startingNodeId;
- conf->maxPageNo = max_page;
- sendSignal(req.senderRef, GSN_PREPARE_COPY_FRAG_CONF,
- signal, PrepareCopyFragConf::SignalLength, JBB);
-}
-
-/* *************************************** */
-/* COPY_FRAGREQ: Start copying a fragment */
-/* *************************************** */
-void Dblqh::execCOPY_FRAGREQ(Signal* signal)
-{
- jamEntry();
- const CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
- tabptr.i = copyFragReq->tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- Uint32 i;
- const Uint32 fragId = copyFragReq->fragId;
- const Uint32 copyPtr = copyFragReq->userPtr;
- const Uint32 userRef = copyFragReq->userRef;
- const Uint32 nodeId = copyFragReq->nodeId;
- const Uint32 gci = copyFragReq->gci;
-
- ndbrequire(cnoActiveCopy < 3);
- ndbrequire(getFragmentrec(signal, fragId));
- ndbrequire(fragptr.p->copyFragState == ZIDLE);
- ndbrequire(cfirstfreeTcConrec != RNIL);
- ndbrequire(fragptr.p->m_scanNumberMask.get(NR_ScanNo));
-
- Uint32 key = fragptr.p->fragDistributionKey = copyFragReq->distributionKey;
-
- Uint32 checkversion = NDB_VERSION >= MAKE_VERSION(5,1,0) ?
- NDBD_UPDATE_FRAG_DIST_KEY_51 : NDBD_UPDATE_FRAG_DIST_KEY_50;
-
- Uint32 nodeCount = copyFragReq->nodeCount;
- NdbNodeBitmask nodemask;
- if (getNodeInfo(refToNode(userRef)).m_version >= checkversion)
- {
- ndbrequire(nodeCount <= MAX_REPLICAS);
- for (i = 0; i<nodeCount; i++)
- nodemask.set(copyFragReq->nodeList[i]);
- }
- Uint32 maxPage = copyFragReq->nodeList[nodeCount];
- Uint32 version = getNodeInfo(refToNode(userRef)).m_version;
- if (ndb_check_prep_copy_frag_version(version) < 2)
- {
- jam();
- maxPage = RNIL;
- }
-
- if (DictTabInfo::isOrderedIndex(tabptr.p->tableType)) {
- jam();
- /**
- * Ordered index doesn't need to be copied
- */
- CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
- conf->userPtr = copyPtr;
- conf->sendingNodeId = cownNodeid;
- conf->startingNodeId = nodeId;
- conf->tableId = tabptr.i;
- conf->fragId = fragId;
- sendSignal(userRef, GSN_COPY_FRAGCONF, signal,
- CopyFragConf::SignalLength, JBB);
- return;
- }//if
-
- LocalDLList<ScanRecord> scans(c_scanRecordPool, fragptr.p->m_activeScans);
- ndbrequire(scans.seize(scanptr));
-/* ------------------------------------------------------------------------- */
-// We keep track of how many operation records in ACC that has been booked.
-// Copy fragment has records always booked and thus need not book any. The
-// most operations in parallel use is the m_max_batch_size_rows.
-// This variable has to be set-up here since it is used by releaseScanrec
-// to unbook operation records in ACC.
-/* ------------------------------------------------------------------------- */
- scanptr.p->m_max_batch_size_rows = 0;
- scanptr.p->rangeScan = 0;
- scanptr.p->tupScan = 0;
- seizeTcrec();
- tcConnectptr.p->clientBlockref = userRef;
-
- /**
- * Remove implicit cast/usage of CopyFragReq
- */
- //initCopyrec(signal);
- scanptr.p->copyPtr = copyPtr;
- scanptr.p->scanType = ScanRecord::COPY;
- scanptr.p->scanNodeId = nodeId;
- scanptr.p->scanTcrec = tcConnectptr.i;
- scanptr.p->scanSchemaVersion = copyFragReq->schemaVersion;
- scanptr.p->scanCompletedStatus = ZFALSE;
- scanptr.p->scanErrorCounter = 0;
- scanptr.p->scanNumber = NR_ScanNo;
- scanptr.p->scanKeyinfoFlag = 0; // Don't put into hash
- scanptr.p->fragPtrI = fragptr.i;
- scanptr.p->scanApiOpPtr = tcConnectptr.i;
- scanptr.p->scanApiBlockref = reference();
- fragptr.p->m_scanNumberMask.clear(NR_ScanNo);
- scanptr.p->scanBlockref = DBTUP_REF;
- scanptr.p->scanLockHold = ZFALSE;
- scanptr.p->m_curr_batch_size_rows = 0;
- scanptr.p->m_curr_batch_size_bytes= 0;
-
- initScanTc(0,
- 0,
- (DBLQH << 20) + (cownNodeid << 8),
- fragId,
- copyFragReq->nodeId);
- cactiveCopy[cnoActiveCopy] = fragptr.i;
- cnoActiveCopy++;
-
- tcConnectptr.p->copyCountWords = 0;
- tcConnectptr.p->tcOprec = tcConnectptr.i;
- tcConnectptr.p->schemaVersion = scanptr.p->scanSchemaVersion;
- tcConnectptr.p->savePointId = gci;
- scanptr.p->scanState = ScanRecord::WAIT_ACC_COPY;
- AccScanReq * req = (AccScanReq*)&signal->theData[0];
- req->senderData = scanptr.i;
- req->senderRef = cownref;
- req->tableId = tabptr.i;
- req->fragmentNo = fragId;
- req->requestInfo = 0;
- AccScanReq::setLockMode(req->requestInfo, 0);
- AccScanReq::setReadCommittedFlag(req->requestInfo, 0);
- AccScanReq::setNRScanFlag(req->requestInfo, 1);
- AccScanReq::setNoDiskScanFlag(req->requestInfo, 1);
-
- req->transId1 = tcConnectptr.p->transid[0];
- req->transId2 = tcConnectptr.p->transid[1];
- req->savePointId = tcConnectptr.p->savePointId;
- req->maxPage = maxPage;
- sendSignal(scanptr.p->scanBlockref, GSN_ACC_SCANREQ, signal,
- AccScanReq::SignalLength + 1, JBB);
-
- if (! nodemask.isclear())
- {
- ndbrequire(nodemask.get(getOwnNodeId()));
- ndbrequire(nodemask.get(nodeId)); // cpy dest
- nodemask.clear(getOwnNodeId());
- nodemask.clear(nodeId);
-
- UpdateFragDistKeyOrd*
- ord = (UpdateFragDistKeyOrd*)signal->getDataPtrSend();
- ord->tableId = tabptr.i;
- ord->fragId = fragId;
- ord->fragDistributionKey = key;
- i = 0;
- while ((i = nodemask.find(i+1)) != NdbNodeBitmask::NotFound)
- {
- if (getNodeInfo(i).m_version >= checkversion)
- sendSignal(calcLqhBlockRef(i), GSN_UPDATE_FRAG_DIST_KEY_ORD,
- signal, UpdateFragDistKeyOrd::SignalLength, JBB);
- }
- }
- return;
-}//Dblqh::execCOPY_FRAGREQ()
-
-void
-Dblqh::execUPDATE_FRAG_DIST_KEY_ORD(Signal * signal)
-{
- jamEntry();
- UpdateFragDistKeyOrd* ord =(UpdateFragDistKeyOrd*)signal->getDataPtr();
-
- tabptr.i = ord->tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- ndbrequire(getFragmentrec(signal, ord->fragId));
- fragptr.p->fragDistributionKey = ord->fragDistributionKey;
-}
-
-void Dblqh::accScanConfCopyLab(Signal* signal)
-{
- AccScanConf * const accScanConf = (AccScanConf *)&signal->theData[0];
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
-/*--------------------------------------------------------------------------*/
-/* PRECONDITION: SCAN_STATE = WAIT_ACC_COPY */
-/*--------------------------------------------------------------------------*/
- if (accScanConf->flag == AccScanConf::ZEMPTY_FRAGMENT) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE FRAGMENT WAS EMPTY. */
-/* REPORT SUCCESSFUL COPYING. */
-/*---------------------------------------------------------------------------*/
- tupCopyCloseConfLab(signal);
- return;
- }//if
- scanptr.p->scanAccPtr = accScanConf->accPtr;
- scanptr.p->scanState = ScanRecord::WAIT_STORED_PROC_COPY;
- signal->theData[0] = tcConnectptr.p->tupConnectrec;
- signal->theData[1] = tcConnectptr.p->tableref;
- signal->theData[2] = scanptr.p->scanSchemaVersion;
- signal->theData[3] = ZSTORED_PROC_COPY;
-// theData[4] is not used in TUP with ZSTORED_PROC_COPY
- sendSignal(scanptr.p->scanBlockref, GSN_STORED_PROCREQ, signal, 5, JBB);
- return;
-}//Dblqh::accScanConfCopyLab()
-
-/*---------------------------------------------------------------------------*/
-/* ENTER STORED_PROCCONF WITH */
-/* TC_CONNECTPTR, */
-/* TSTORED_PROC_ID */
-/*---------------------------------------------------------------------------*/
-void Dblqh::storedProcConfCopyLab(Signal* signal)
-{
-/*---------------------------------------------------------------------------*/
-/* PRECONDITION: SCAN_STATE = WAIT_STORED_PROC_COPY */
-/*---------------------------------------------------------------------------*/
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE COPY PROCESS HAVE BEEN COMPLETED, MOST LIKELY DUE TO A NODE FAILURE.*/
-/*---------------------------------------------------------------------------*/
- closeCopyLab(signal);
- return;
- }//if
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN_COPY;
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::COPY_FIRST_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- continueFirstCopyAfterBlockedLab(signal);
- return;
-}//Dblqh::storedProcConfCopyLab()
-
-void Dblqh::continueFirstCopyAfterBlockedLab(Signal* signal)
-{
- /**
- * Start sending ROWID for all operations from now on
- */
- fragptr.p->m_copy_started_state = Fragrecord::AC_NR_COPY;
-
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
-
- if (false && fragptr.p->tabRef > 4)
- {
- ndbout_c("STOPPING COPY X = [ %d %d %d %d ]",
- refToBlock(scanptr.p->scanBlockref),
- scanptr.p->scanAccPtr, RNIL, NextScanReq::ZSCAN_NEXT);
-
- /**
- * RESTART: > DUMP 7020 332 X
- */
- return;
- }
-
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = RNIL;
- signal->theData[2] = NextScanReq::ZSCAN_NEXT;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
- return;
-}//Dblqh::continueFirstCopyAfterBlockedLab()
-
-/*---------------------------------------------------------------------------*/
-/* ENTER NEXT_SCANCONF WITH */
-/* SCANPTR, */
-/* TFRAGID, */
-/* TACC_OPPTR, */
-/* TLOCAL_KEY1, */
-/* TLOCAL_KEY2, */
-/* TKEY_LENGTH, */
-/* TKEY1, */
-/* TKEY2, */
-/* TKEY3, */
-/* TKEY4 */
-/*---------------------------------------------------------------------------*/
-/* PRECONDITION: SCAN_STATE = WAIT_NEXT_SCAN_COPY */
-/*---------------------------------------------------------------------------*/
-void Dblqh::nextScanConfCopyLab(Signal* signal)
-{
- NextScanConf * const nextScanConf = (NextScanConf *)&signal->theData[0];
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- if (nextScanConf->fragId == RNIL) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THERE ARE NO MORE TUPLES TO FETCH. WE NEED TO CLOSE */
-/* THE COPY IN ACC AND DELETE THE STORED PROCEDURE IN TUP */
-/*---------------------------------------------------------------------------*/
- if (tcConnectptr.p->copyCountWords == 0) {
- closeCopyLab(signal);
- return;
- }//if
-/*---------------------------------------------------------------------------*/
-// Wait until copying is completed also at the starting node before reporting
-// completion. Signal completion through scanCompletedStatus-flag.
-/*---------------------------------------------------------------------------*/
- scanptr.p->scanCompletedStatus = ZTRUE;
- scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY;
- if (ERROR_INSERTED(5043))
- {
- CLEAR_ERROR_INSERT_VALUE;
- tcConnectptr.p->copyCountWords = ~0;
- signal->theData[0] = 9999;
- sendSignal(numberToRef(CMVMI, scanptr.p->scanNodeId),
- GSN_NDB_TAMPER, signal, 1, JBA);
- }
- return;
- }//if
-
- TcConnectionrec * tcConP = tcConnectptr.p;
-
- tcConP->m_use_rowid = true;
- tcConP->m_row_id = scanptr.p->m_row_id;
-
- if (signal->getLength() == 7)
- {
- jam();
- ndbrequire(nextScanConf->accOperationPtr == RNIL);
- initCopyTc(signal, ZDELETE);
- set_acc_ptr_in_scan_record(scanptr.p, 0, RNIL);
- tcConP->gci = nextScanConf->gci;
-
- tcConP->primKeyLen = 0;
- tcConP->totSendlenAi = 0;
- tcConP->connectState = TcConnectionrec::COPY_CONNECTED;
-
-/*---------------------------------------------------------------------------*/
-// To avoid using up to many operation records in ACC we will increase the
-// constant to ensure that we never send more than 40 records at a time.
-// This is where the constant 56 comes from. For long records this constant
-// will not matter that much. The current maximum is 6000 words outstanding
-// (including a number of those 56 words not really sent). We also have to
-// ensure that there are never more simultaneous usage of these operation
-// records to ensure that node recovery does not fail because of simultaneous
-// scanning.
-/*---------------------------------------------------------------------------*/
- UintR TnoOfWords = 8;
- TnoOfWords = TnoOfWords + MAGIC_CONSTANT;
- TnoOfWords = TnoOfWords + (TnoOfWords >> 2);
-
- /*-----------------------------------------------------------------
- * NOTE for transid1!
- * Transid1 in the tcConnection record is used load regulate the
- * copy(node recovery) process.
- * The number of outstanding words are written in the transid1
- * variable. This will be sent to the starting node in the
- * LQHKEYREQ signal and when the answer is returned in the LQHKEYCONF
- * we can reduce the number of outstanding words and check to see
- * if more LQHKEYREQ signals should be sent.
- *
- * However efficient this method is rather unsafe in such way that
- * it overwrites the transid1 original data.
- *
- * Also see TR 587.
- *----------------------------------------------------------------*/
- tcConP->transid[0] = TnoOfWords; // Data overload, see note!
- packLqhkeyreqLab(signal);
- tcConP->copyCountWords += TnoOfWords;
- scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY;
- if (tcConP->copyCountWords < cmaxWordsAtNodeRec) {
- nextRecordCopy(signal);
- }
- return;
- }
- else
- {
- // If accOperationPtr == RNIL no record was returned by ACC
- if (nextScanConf->accOperationPtr == RNIL) {
- jam();
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = AccCheckScan::ZCHECK_LCP_STOP;
- sendSignal(scanptr.p->scanBlockref, GSN_ACC_CHECK_SCAN, signal, 2, JBB);
- return;
- }
-
- initCopyTc(signal, ZINSERT);
- set_acc_ptr_in_scan_record(scanptr.p, 0, nextScanConf->accOperationPtr);
-
- Fragrecord* fragPtrP= fragptr.p;
- scanptr.p->scanState = ScanRecord::WAIT_TUPKEY_COPY;
- tcConP->transactionState = TcConnectionrec::COPY_TUPKEY;
- if(tcConP->m_disk_table)
- {
- next_scanconf_load_diskpage(signal, scanptr, tcConnectptr,fragPtrP);
- }
- else
- {
- next_scanconf_tupkeyreq(signal, scanptr, tcConP, fragPtrP, RNIL);
- }
- }
-}//Dblqh::nextScanConfCopyLab()
-
-
-/*---------------------------------------------------------------------------*/
-/* USED IN COPYING OPERATION TO RECEIVE ATTRINFO FROM TUP. */
-/*---------------------------------------------------------------------------*/
-/* ************>> */
-/* TRANSID_AI > */
-/* ************>> */
-void Dblqh::execTRANSID_AI(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- Uint32 length = signal->length() - 3;
- ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::COPY_TUPKEY);
- Uint32 * src = &signal->theData[3];
- while(length > 22){
- if (saveTupattrbuf(signal, src, 22) == ZOK) {
- ;
- } else {
- jam();
- tcConnectptr.p->errorCode = ZGET_ATTRINBUF_ERROR;
- return;
- }//if
- src += 22;
- length -= 22;
- }
- if (saveTupattrbuf(signal, src, length) == ZOK) {
- return;
- }
- jam();
- tcConnectptr.p->errorCode = ZGET_ATTRINBUF_ERROR;
-}//Dblqh::execTRANSID_AI()
-
-/*--------------------------------------------------------------------------*/
-/* ENTER TUPKEYCONF WITH */
-/* TC_CONNECTPTR, */
-/* TDATA2, */
-/* TDATA3, */
-/* TDATA4, */
-/* TDATA5 */
-/*--------------------------------------------------------------------------*/
-/* PRECONDITION: TRANSACTION_STATE = COPY_TUPKEY */
-/*--------------------------------------------------------------------------*/
-void Dblqh::copyTupkeyConfLab(Signal* signal)
-{
- const TupKeyConf * const tupKeyConf = (TupKeyConf *)signal->getDataPtr();
-
- UintR readLength = tupKeyConf->readLength;
- Uint32 tableId = tcConnectptr.p->tableref;
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- ScanRecord* scanP = scanptr.p;
-
- Uint32 rows = scanP->m_curr_batch_size_rows;
- Uint32 accOpPtr= get_acc_ptr_from_scan_record(scanP, rows, false);
- ndbassert(accOpPtr != (Uint32)-1);
- c_acc->execACCKEY_ORD(signal, accOpPtr);
-
- if (tcConnectptr.p->errorCode != 0) {
- jam();
- closeCopyLab(signal);
- return;
- }//if
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE COPY PROCESS HAVE BEEN CLOSED. MOST LIKELY A NODE FAILURE. */
-/*---------------------------------------------------------------------------*/
- closeCopyLab(signal);
- return;
- }//if
- TcConnectionrec * tcConP = tcConnectptr.p;
- tcConnectptr.p->totSendlenAi = readLength;
- tcConnectptr.p->connectState = TcConnectionrec::COPY_CONNECTED;
-
- // Read primary keys (used to get here via scan keyinfo)
- Uint32* tmp = signal->getDataPtrSend()+24;
- Uint32 len= tcConnectptr.p->primKeyLen = readPrimaryKeys(scanP, tcConP, tmp);
-
- tcConP->gci = tmp[len];
- // Calculate hash (no need to linearies key)
- if (g_key_descriptor_pool.getPtr(tableId)->hasCharAttr)
- {
- tcConnectptr.p->hashValue = calculateHash(tableId, tmp);
- }
- else
- {
- tcConnectptr.p->hashValue = md5_hash((Uint64*)tmp, len);
- }
-
- // Move into databuffer to make packLqhkeyreqLab happy
- memcpy(tcConP->tupkeyData, tmp, 4*4);
- if(len > 4)
- keyinfoLab(tmp+4, tmp + len);
- LqhKeyReq::setKeyLen(tcConP->reqinfo, len);
-
-/*---------------------------------------------------------------------------*/
-// To avoid using up to many operation records in ACC we will increase the
-// constant to ensure that we never send more than 40 records at a time.
-// This is where the constant 56 comes from. For long records this constant
-// will not matter that much. The current maximum is 6000 words outstanding
-// (including a number of those 56 words not really sent). We also have to
-// ensure that there are never more simultaneous usage of these operation
-// records to ensure that node recovery does not fail because of simultaneous
-// scanning.
-/*---------------------------------------------------------------------------*/
- UintR TnoOfWords = readLength + len;
- TnoOfWords = TnoOfWords + MAGIC_CONSTANT;
- TnoOfWords = TnoOfWords + (TnoOfWords >> 2);
-
- /*-----------------------------------------------------------------
- * NOTE for transid1!
- * Transid1 in the tcConnection record is used load regulate the
- * copy(node recovery) process.
- * The number of outstanding words are written in the transid1
- * variable. This will be sent to the starting node in the
- * LQHKEYREQ signal and when the answer is returned in the LQHKEYCONF
- * we can reduce the number of outstanding words and check to see
- * if more LQHKEYREQ signals should be sent.
- *
- * However efficient this method is rather unsafe in such way that
- * it overwrites the transid1 original data.
- *
- * Also see TR 587.
- *----------------------------------------------------------------*/
- tcConnectptr.p->transid[0] = TnoOfWords; // Data overload, see note!
- packLqhkeyreqLab(signal);
- tcConnectptr.p->copyCountWords += TnoOfWords;
- scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY;
- if (tcConnectptr.p->copyCountWords < cmaxWordsAtNodeRec) {
- nextRecordCopy(signal);
- return;
- }//if
- return;
-}//Dblqh::copyTupkeyConfLab()
-
-/*---------------------------------------------------------------------------*/
-/* ENTER LQHKEYCONF */
-/*---------------------------------------------------------------------------*/
-/* PRECONDITION: CONNECT_STATE = COPY_CONNECTED */
-/*---------------------------------------------------------------------------*/
-void Dblqh::copyCompletedLab(Signal* signal)
-{
- const LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
-
- ndbrequire(tcConnectptr.p->transid[1] == lqhKeyConf->transId2);
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- if (tcConnectptr.p->copyCountWords >= cmaxWordsAtNodeRec) {
- tcConnectptr.p->copyCountWords -= lqhKeyConf->transId1; // Data overload, see note!
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
-/*---------------------------------------------------------------------------*/
-// Copy to complete, we will not start any new copying.
-/*---------------------------------------------------------------------------*/
- closeCopyLab(signal);
- return;
- }//if
- if (tcConnectptr.p->copyCountWords < cmaxWordsAtNodeRec) {
- jam();
- nextRecordCopy(signal);
- }//if
- return;
- }//if
- tcConnectptr.p->copyCountWords -= lqhKeyConf->transId1; // Data overload, see note!
- ndbrequire(tcConnectptr.p->copyCountWords <= cmaxWordsAtNodeRec);
- if (tcConnectptr.p->copyCountWords > 0) {
- jam();
- return;
- }//if
-/*---------------------------------------------------------------------------*/
-// No more outstanding copies. We will only start new ones from here if it was
-// stopped before and this only happens when copyCountWords is bigger than the
-// threshold value. Since this did not occur we must be waiting for completion.
-// Check that this is so. If not we crash to find out what is going on.
-/*---------------------------------------------------------------------------*/
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
- closeCopyLab(signal);
- return;
- }//if
-
- if (scanptr.p->scanState == ScanRecord::WAIT_LQHKEY_COPY &&
- scanptr.p->scanErrorCounter)
- {
- jam();
- closeCopyLab(signal);
- return;
- }
-
- if (scanptr.p->scanState == ScanRecord::WAIT_LQHKEY_COPY) {
- jam();
-/*---------------------------------------------------------------------------*/
-// Make sure that something is in progress. Otherwise we will simply stop
-// and nothing more will happen.
-/*---------------------------------------------------------------------------*/
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- return;
-}//Dblqh::copyCompletedLab()
-
-void Dblqh::nextRecordCopy(Signal* signal)
-{
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- if (scanptr.p->scanState != ScanRecord::WAIT_LQHKEY_COPY) {
- jam();
-/*---------------------------------------------------------------------------*/
-// Make sure that nothing is in progress. Otherwise we will have to simultaneous
-// scans on the same record and this will certainly lead to unexpected
-// behaviour.
-/*---------------------------------------------------------------------------*/
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN_COPY;
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::COPY_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- continueCopyAfterBlockedLab(signal);
- return;
-}//Dblqh::nextRecordCopy()
-
-void Dblqh::continueCopyAfterBlockedLab(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- tcConnectptr.p->errorCode = 0;
- Uint32 acc_op_ptr= get_acc_ptr_from_scan_record(scanptr.p, 0, false);
- if (acc_op_ptr != RNIL)
- {
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = acc_op_ptr;
- signal->theData[2] = NextScanReq::ZSCAN_NEXT_COMMIT;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
- }
- else
- {
- /**
- * No need to commit (unlock)
- */
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = RNIL;
- signal->theData[2] = NextScanReq::ZSCAN_NEXT;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
- }
- return;
-}//Dblqh::continueCopyAfterBlockedLab()
-
-void Dblqh::copyLqhKeyRefLab(Signal* signal)
-{
- ndbrequire(tcConnectptr.p->transid[1] == signal->theData[4]);
- Uint32 copyWords = signal->theData[3];
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanErrorCounter++;
- tcConnectptr.p->errorCode = terrorCode;
-
- LqhKeyConf* conf = (LqhKeyConf*)signal->getDataPtrSend();
- conf->transId1 = copyWords;
- conf->transId2 = tcConnectptr.p->transid[1];
- copyCompletedLab(signal);
-}//Dblqh::copyLqhKeyRefLab()
-
-void Dblqh::closeCopyLab(Signal* signal)
-{
- if (tcConnectptr.p->copyCountWords > 0) {
-/*---------------------------------------------------------------------------*/
-// We are still waiting for responses from the starting node.
-// Wait until all of those have arrived until we start the
-// close process.
-/*---------------------------------------------------------------------------*/
- scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY;
- jam();
- return;
- }//if
- tcConnectptr.p->transid[0] = 0;
- tcConnectptr.p->transid[1] = 0;
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
-
- /**
- * Stop sending ROWID for all operations from now on
- */
- fragptr.p->m_copy_started_state = Fragrecord::AC_NORMAL;
-
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- scanptr.p->scanState = ScanRecord::WAIT_CLOSE_COPY;
- switch (fragptr.p->fragStatus) {
- case Fragrecord::FSACTIVE:
- jam();
- break;
- case Fragrecord::BLOCKED:
- jam();
- linkFragQueue(signal);
- tcConnectptr.p->transactionState = TcConnectionrec::COPY_CLOSE_STOPPED;
- return;
- break;
- case Fragrecord::FREE:
- jam();
- case Fragrecord::ACTIVE_CREATION:
- jam();
- case Fragrecord::CRASH_RECOVERING:
- jam();
- case Fragrecord::DEFINED:
- jam();
- case Fragrecord::REMOVING:
- jam();
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- continueCloseCopyAfterBlockedLab(signal);
- return;
-}//Dblqh::closeCopyLab()
-
-void Dblqh::continueCloseCopyAfterBlockedLab(Signal* signal)
-{
- scanptr.i = tcConnectptr.p->tcScanRec;
- c_scanRecordPool.getPtr(scanptr);
- signal->theData[0] = scanptr.p->scanAccPtr;
- signal->theData[1] = RNIL;
- signal->theData[2] = NextScanReq::ZSCAN_CLOSE;
- sendSignal(scanptr.p->scanBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
- return;
-}//Dblqh::continueCloseCopyAfterBlockedLab()
-
-/*---------------------------------------------------------------------------*/
-/* ENTER NEXT_SCANCONF WITH */
-/* SCANPTR, */
-/* TFRAGID, */
-/* TACC_OPPTR, */
-/* TLOCAL_KEY1, */
-/* TLOCAL_KEY2, */
-/* TKEY_LENGTH, */
-/* TKEY1, */
-/* TKEY2, */
-/* TKEY3, */
-/* TKEY4 */
-/*---------------------------------------------------------------------------*/
-/* PRECONDITION: SCAN_STATE = WAIT_CLOSE_COPY */
-/*---------------------------------------------------------------------------*/
-void Dblqh::accCopyCloseConfLab(Signal* signal)
-{
- tcConnectptr.i = scanptr.p->scanTcrec;
- scanptr.p->scanState = ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- signal->theData[0] = tcConnectptr.p->tupConnectrec;
- signal->theData[1] = tcConnectptr.p->tableref;
- signal->theData[2] = scanptr.p->scanSchemaVersion;
- signal->theData[3] = ZDELETE_STORED_PROC_ID;
- signal->theData[4] = scanptr.p->scanStoredProcId;
- sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 5, JBB);
- return;
-}//Dblqh::accCopyCloseConfLab()
-
-/*---------------------------------------------------------------------------*/
-/* ENTER STORED_PROCCONF WITH */
-/* TC_CONNECTPTR, */
-/* TSTORED_PROC_ID */
-/*---------------------------------------------------------------------------*/
-/* PRECONDITION: SCAN_STATE = WAIT_DELETE_STORED_PROC_ID_COPY */
-/*---------------------------------------------------------------------------*/
-void Dblqh::tupCopyCloseConfLab(Signal* signal)
-{
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- fragptr.p->copyFragState = ZIDLE;
-
- if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
- jam();
- tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
- tcNodeFailptr.p->tcRecNow = tcConnectptr.i + 1;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
-
- CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
- ref->userPtr = scanptr.p->copyPtr;
- ref->sendingNodeId = cownNodeid;
- ref->startingNodeId = scanptr.p->scanNodeId;
- ref->tableId = fragptr.p->tabRef;
- ref->fragId = fragptr.p->fragId;
- ref->errorCode = ZNODE_FAILURE_ERROR;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGREF, signal,
- CopyFragRef::SignalLength, JBB);
- } else {
- if (scanptr.p->scanErrorCounter > 0) {
- jam();
- CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
- ref->userPtr = scanptr.p->copyPtr;
- ref->sendingNodeId = cownNodeid;
- ref->startingNodeId = scanptr.p->scanNodeId;
- ref->tableId = fragptr.p->tabRef;
- ref->fragId = fragptr.p->fragId;
- ref->errorCode = tcConnectptr.p->errorCode;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGREF, signal,
- CopyFragRef::SignalLength, JBB);
- } else {
- jam();
- CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
- conf->userPtr = scanptr.p->copyPtr;
- conf->sendingNodeId = cownNodeid;
- conf->startingNodeId = scanptr.p->scanNodeId;
- conf->tableId = tcConnectptr.p->tableref;
- conf->fragId = tcConnectptr.p->fragmentid;
- sendSignal(tcConnectptr.p->clientBlockref, GSN_COPY_FRAGCONF, signal,
- CopyFragConf::SignalLength, JBB);
- }//if
- }//if
- releaseActiveCopy(signal);
- tcConnectptr.p->tcScanRec = RNIL;
- finishScanrec(signal);
- releaseOprec(signal);
- releaseTcrec(signal, tcConnectptr);
- releaseScanrec(signal);
-}//Dblqh::tupCopyCloseConfLab()
-
-/*---------------------------------------------------------------------------*/
-/* A NODE FAILURE OCCURRED DURING THE COPY PROCESS. WE NEED TO CLOSE THE */
-/* COPY PROCESS SINCE A NODE FAILURE DURING THE COPY PROCESS WILL ALSO */
-/* FAIL THE NODE THAT IS TRYING TO START-UP. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::closeCopyRequestLab(Signal* signal)
-{
- scanptr.p->scanErrorCounter++;
- if (0) ndbout_c("closeCopyRequestLab: scanState: %d", scanptr.p->scanState);
- switch (scanptr.p->scanState) {
- case ScanRecord::WAIT_TUPKEY_COPY:
- case ScanRecord::WAIT_NEXT_SCAN_COPY:
- jam();
-/*---------------------------------------------------------------------------*/
-/* SET COMPLETION STATUS AND WAIT FOR OPPORTUNITY TO STOP THE SCAN. */
-// ALSO SET NO OF WORDS OUTSTANDING TO ZERO TO AVOID ETERNAL WAIT.
-/*---------------------------------------------------------------------------*/
- scanptr.p->scanCompletedStatus = ZTRUE;
- tcConnectptr.p->copyCountWords = 0;
- break;
- case ScanRecord::WAIT_ACC_COPY:
- case ScanRecord::WAIT_STORED_PROC_COPY:
- jam();
-/*---------------------------------------------------------------------------*/
-/* WE ARE CURRENTLY STARTING UP THE SCAN. SET COMPLETED STATUS AND WAIT FOR*/
-/* COMPLETION OF STARTUP. */
-/*---------------------------------------------------------------------------*/
- scanptr.p->scanCompletedStatus = ZTRUE;
- break;
- case ScanRecord::WAIT_CLOSE_COPY:
- case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
- jam();
-/*---------------------------------------------------------------------------*/
-/* CLOSE IS ALREADY ONGOING. WE NEED NOT DO ANYTHING. */
-/*---------------------------------------------------------------------------*/
- break;
- case ScanRecord::WAIT_LQHKEY_COPY:
- jam();
-/*---------------------------------------------------------------------------*/
-/* WE ARE WAITING FOR THE FAILED NODE. THE NODE WILL NEVER COME BACK. */
-// WE NEED TO START THE FAILURE HANDLING IMMEDIATELY.
-// ALSO SET NO OF WORDS OUTSTANDING TO ZERO TO AVOID ETERNAL WAIT.
-/*---------------------------------------------------------------------------*/
- tcConnectptr.p->copyCountWords = 0;
- closeCopyLab(signal);
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- return;
-}//Dblqh::closeCopyRequestLab()
-
-/* ****************************************************** */
-/* COPY_ACTIVEREQ: Change state of a fragment to ACTIVE. */
-/* ****************************************************** */
-void Dblqh::execCOPY_ACTIVEREQ(Signal* signal)
-{
- CRASH_INSERTION(5026);
-
- const CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
- jamEntry();
- Uint32 masterPtr = req->userPtr;
- BlockReference masterRef = req->userRef;
- tabptr.i = req->tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- Uint32 fragId = req->fragId;
- ndbrequire(getFragmentrec(signal, fragId));
-
- fragptr.p->fragDistributionKey = req->distributionKey;
-
- ndbrequire(cnoActiveCopy < 3);
- cactiveCopy[cnoActiveCopy] = fragptr.i;
- cnoActiveCopy++;
- fragptr.p->masterBlockref = masterRef;
- fragptr.p->masterPtr = masterPtr;
- if (fragptr.p->fragStatus == Fragrecord::FSACTIVE) {
- jam();
-/*------------------------------------------------------*/
-/* PROCESS HAVE ALREADY BEEN STARTED BY PREVIOUS */
-/* MASTER. WE HAVE ALREADY SET THE PROPER MASTER */
-/* BLOCK REFERENCE. */
-/*------------------------------------------------------*/
- if (fragptr.p->activeTcCounter == 0) {
- jam();
-/*------------------------------------------------------*/
-/* PROCESS WAS EVEN COMPLETED. */
-/*------------------------------------------------------*/
- sendCopyActiveConf(signal, tabptr.i);
- }//if
- return;
- }//if
-
- fragptr.p->fragStatus = Fragrecord::FSACTIVE;
- if (TRACENR_FLAG)
- TRACENR("tab: " << tabptr.i
- << " frag: " << fragId
- << " COPY ACTIVE" << endl);
-
- if (fragptr.p->lcpFlag == Fragrecord::LCP_STATE_TRUE) {
- jam();
- fragptr.p->logFlag = Fragrecord::STATE_TRUE;
- }//if
- fragptr.p->activeTcCounter = 1;
-/*------------------------------------------------------*/
-/* SET IT TO ONE TO ENSURE THAT IT IS NOT POSSIBLE*/
-/* TO DECREASE IT TO ZERO UNTIL WE HAVE COMPLETED */
-/* THE SCAN. */
-/*------------------------------------------------------*/
- signal->theData[0] = ZSCAN_TC_CONNECT;
- signal->theData[1] = 0;
- signal->theData[2] = tabptr.i;
- signal->theData[3] = fragId;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
-}//Dblqh::execCOPY_ACTIVEREQ()
-
-void Dblqh::scanTcConnectLab(Signal* signal, Uint32 tstartTcConnect, Uint32 fragId)
-{
- Uint32 tendTcConnect;
-
- ndbrequire(getFragmentrec(signal, fragId));
- if ((tstartTcConnect + 200) >= ctcConnectrecFileSize) {
- jam();
- tendTcConnect = ctcConnectrecFileSize - 1;
- } else {
- jam();
- tendTcConnect = tstartTcConnect + 200;
- }//if
- for (tcConnectptr.i = tstartTcConnect;
- tcConnectptr.i <= tendTcConnect;
- tcConnectptr.i++) {
- jam();
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- if (tcConnectptr.p->transactionState != TcConnectionrec::IDLE) {
- switch (tcConnectptr.p->logWriteState) {
- case TcConnectionrec::NOT_WRITTEN:
- jam();
- if (fragptr.i == tcConnectptr.p->fragmentptr) {
- jam();
- fragptr.p->activeTcCounter = fragptr.p->activeTcCounter + 1;
- tcConnectptr.p->logWriteState = TcConnectionrec::NOT_WRITTEN_WAIT;
- }//if
- break;
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- }//if
- }//for
- if (tendTcConnect < (ctcConnectrecFileSize - 1)) {
- jam();
- signal->theData[0] = ZSCAN_TC_CONNECT;
- signal->theData[1] = tendTcConnect + 1;
- signal->theData[2] = tabptr.i;
- signal->theData[3] = fragId;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- } else {
- jam();
-/*------------------------------------------------------*/
-/* THE SCAN HAVE BEEN COMPLETED. WE CHECK IF ALL */
-/* OPERATIONS HAVE ALREADY BEEN COMPLETED. */
-/*------------------------------------------------------*/
- ndbrequire(fragptr.p->activeTcCounter > 0);
- fragptr.p->activeTcCounter--;
- if (fragptr.p->activeTcCounter == 0) {
- jam();
-/*------------------------------------------------------*/
-/* SET START GLOBAL CHECKPOINT TO THE NEXT */
-/* CHECKPOINT WE HAVE NOT YET HEARD ANYTHING ABOUT*/
-/* THIS GCP WILL BE COMPLETELY COVERED BY THE LOG.*/
-/*------------------------------------------------------*/
- fragptr.p->startGci = cnewestGci + 1;
- sendCopyActiveConf(signal, tabptr.i);
- }//if
- }//if
- return;
-}//Dblqh::scanTcConnectLab()
-
-/*---------------------------------------------------------------------------*/
-/* A NEW MASTER IS REQUESTING THE STATE IN LQH OF THE COPY FRAGMENT PARTS. */
-/*---------------------------------------------------------------------------*/
-/* ***************>> */
-/* COPY_STATEREQ > */
-/* ***************>> */
-void Dblqh::execCOPY_STATEREQ(Signal* signal)
-{
- jamEntry();
- ndbrequire(0)
-#if 0
- Uint32* dataPtr = &signal->theData[2];
- BlockReference tmasterBlockref = signal->theData[0];
- Uint32 tnoCopy = 0;
- do {
- jam();
- arrGuard(tnoCopy, 4);
- fragptr.i = cactiveCopy[tnoCopy];
- if (fragptr.i == RNIL) {
- jam();
- break;
- }//if
- c_fragment_pool.getPtr(fragptr);
- if (fragptr.p->copyFragState != ZIDLE) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS FRAGMENT IS CURRENTLY ACTIVE IN COPYING THE FRAGMENT. */
-/*---------------------------------------------------------------------------*/
- scanptr.i = fragptr.p->fragScanRec[NR_ScanNo];
- c_scanRecordPool.getPtr(scanptr);
- if (scanptr.p->scanCompletedStatus == ZTRUE) {
- jam();
- dataPtr[3 + (tnoCopy << 2)] = ZCOPY_CLOSING;
- } else {
- jam();
- dataPtr[3 + (tnoCopy << 2)] = ZCOPY_ONGOING;
- }//if
- dataPtr[2 + (tnoCopy << 2)] = scanptr.p->scanSchemaVersion;
- scanptr.p->scanApiBlockref = tmasterBlockref;
- } else {
- ndbrequire(fragptr.p->activeTcCounter != 0);
-/*---------------------------------------------------------------------------*/
-/* COPY FRAGMENT IS COMPLETED AND WE ARE CURRENTLY GETTING THE STARTING */
-/* GCI OF THE NEW REPLICA OF THIS FRAGMENT. */
-/*---------------------------------------------------------------------------*/
- fragptr.p->masterBlockref = tmasterBlockref;
- dataPtr[3 + (tnoCopy << 2)] = ZCOPY_ACTIVATION;
- }//if
- dataPtr[tnoCopy << 2] = fragptr.p->tabRef;
- dataPtr[1 + (tnoCopy << 2)] = fragptr.p->fragId;
- tnoCopy++;
- } while (tnoCopy < cnoActiveCopy);
- signal->theData[0] = cownNodeid;
- signal->theData[1] = tnoCopy;
- sendSignal(tmasterBlockref, GSN_COPY_STATECONF, signal, 18, JBB);
-#endif
- return;
-}//Dblqh::execCOPY_STATEREQ()
-
-/* ========================================================================= */
-/* ======= INITIATE TC RECORD AT COPY FRAGMENT ======= */
-/* */
-/* SUBROUTINE SHORT NAME = ICT */
-/* ========================================================================= */
-void Dblqh::initCopyTc(Signal* signal, Operation_t op)
-{
- tcConnectptr.p->operation = ZREAD;
- tcConnectptr.p->apiVersionNo = 0;
- tcConnectptr.p->opExec = 0; /* NOT INTERPRETED MODE */
- tcConnectptr.p->schemaVersion = scanptr.p->scanSchemaVersion;
- Uint32 reqinfo = 0;
- LqhKeyReq::setDirtyFlag(reqinfo, 1);
- LqhKeyReq::setSimpleFlag(reqinfo, 1);
- LqhKeyReq::setOperation(reqinfo, op);
- LqhKeyReq::setGCIFlag(reqinfo, 1);
- LqhKeyReq::setNrCopyFlag(reqinfo, 1);
- /* AILen in LQHKEYREQ IS ZERO */
- tcConnectptr.p->reqinfo = reqinfo;
-/* ------------------------------------------------------------------------ */
-/* THE RECEIVING NODE WILL EXPECT THAT IT IS THE LAST NODE AND WILL */
-/* SEND COMPLETED AS THE RESPONSE SIGNAL SINCE DIRTY_OP BIT IS SET. */
-/* ------------------------------------------------------------------------ */
- tcConnectptr.p->nodeAfterNext[0] = ZNIL;
- tcConnectptr.p->nodeAfterNext[1] = ZNIL;
- tcConnectptr.p->tcBlockref = cownref;
- tcConnectptr.p->readlenAi = 0;
- tcConnectptr.p->storedProcId = ZNIL;
- tcConnectptr.p->opExec = 0;
- tcConnectptr.p->nextSeqNoReplica = 0;
- tcConnectptr.p->dirtyOp = ZFALSE;
- tcConnectptr.p->lastReplicaNo = 0;
- tcConnectptr.p->currTupAiLen = 0;
- tcConnectptr.p->tcTimer = cLqhTimeOutCount;
-}//Dblqh::initCopyTc()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEND COPY_ACTIVECONF TO MASTER DIH ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::sendCopyActiveConf(Signal* signal, Uint32 tableId)
-{
- releaseActiveCopy(signal);
- CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
- conf->userPtr = fragptr.p->masterPtr;
- conf->tableId = tableId;
- conf->fragId = fragptr.p->fragId;
- conf->startingNodeId = cownNodeid;
- conf->startGci = fragptr.p->startGci;
- sendSignal(fragptr.p->masterBlockref, GSN_COPY_ACTIVECONF, signal,
- CopyActiveConf::SignalLength, JBB);
-}//Dblqh::sendCopyActiveConf()
-
-/* ##########################################################################
- * ####### LOCAL CHECKPOINT MODULE #######
- *
- * ##########################################################################
- * --------------------------------------------------------------------------
- * THIS MODULE HANDLES THE EXECUTION AND CONTROL OF LOCAL CHECKPOINTS
- * IT CONTROLS THE LOCAL CHECKPOINTS IN TUP AND ACC. IT DOES ALSO INTERACT
- * WITH DIH TO CONTROL WHICH GLOBAL CHECKPOINTS THAT ARE RECOVERABLE
- * ------------------------------------------------------------------------- */
-void Dblqh::execEMPTY_LCP_REQ(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(5008);
- EmptyLcpReq * const emptyLcpOrd = (EmptyLcpReq*)&signal->theData[0];
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
-
- Uint32 nodeId = refToNode(emptyLcpOrd->senderRef);
-
- lcpPtr.p->m_EMPTY_LCP_REQ.set(nodeId);
- lcpPtr.p->reportEmpty = true;
-
- if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE){
- jam();
- bool ok = false;
- switch(clcpCompletedState){
- case LCP_IDLE:
- ok = true;
- sendEMPTY_LCP_CONF(signal, true);
- break;
- case LCP_RUNNING:
- ok = true;
- sendEMPTY_LCP_CONF(signal, false);
- break;
- case LCP_CLOSE_STARTED:
- jam();
- case ACC_LCP_CLOSE_COMPLETED:
- jam();
- case TUP_LCP_CLOSE_COMPLETED:
- jam();
- ok = true;
- break;
- }
- ndbrequire(ok);
-
- }//if
-
- return;
-}//Dblqh::execEMPTY_LCPREQ()
-
-#ifdef NDB_DEBUG_FULL
-static struct TraceLCP {
- void sendSignal(Uint32 ref, Uint32 gsn, Signal* signal,
- Uint32 len, Uint32 prio);
- void save(Signal*);
- void restore(SimulatedBlock&, Signal* sig);
- struct Sig {
- enum {
- Sig_save = 0,
- Sig_send = 1
- } type;
- SignalHeader header;
- Uint32 theData[25];
- };
- Vector<Sig> m_signals;
-} g_trace_lcp;
-template class Vector<TraceLCP::Sig>;
-#else
-#endif
-
-void Dblqh::execLCP_FRAG_ORD(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(5010);
- LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
-
- Uint32 lcpId = lcpFragOrd->lcpId;
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
-
- lcpPtr.p->lastFragmentFlag = lcpFragOrd->lastFragmentFlag;
- if (lcpFragOrd->lastFragmentFlag) {
- jam();
- if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
- jam();
- /* ----------------------------------------------------------
- * NOW THE COMPLETE LOCAL CHECKPOINT ROUND IS COMPLETED.
- * -------------------------------------------------------- */
- if (cnoOfFragsCheckpointed > 0) {
- jam();
- completeLcpRoundLab(signal, lcpId);
- } else {
- jam();
- sendLCP_COMPLETE_REP(signal, lcpId);
- }//if
- }
- return;
- }//if
- tabptr.i = lcpFragOrd->tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- ndbrequire(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
- tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE ||
- tabptr.p->tableStatus == Tablerec::TABLE_DEFINED);
-
- ndbrequire(getFragmentrec(signal, lcpFragOrd->fragmentId));
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- ndbrequire(!lcpPtr.p->lcpQueued);
-
- if (c_lcpId < lcpFragOrd->lcpId) {
- jam();
-
- lcpPtr.p->firstFragmentFlag= true;
-
- c_lcpId = lcpFragOrd->lcpId;
- ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_IDLE);
- setLogTail(signal, lcpFragOrd->keepGci);
- ndbrequire(clcpCompletedState == LCP_IDLE);
- clcpCompletedState = LCP_RUNNING;
- }
- cnoOfFragsCheckpointed++;
-
- if(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
- jam();
- LcpRecord::FragOrd fragOrd;
- fragOrd.fragPtrI = fragptr.i;
- fragOrd.lcpFragOrd = * lcpFragOrd;
- sendLCP_FRAG_REP(signal, fragOrd);
- return;
- }
-
- if (lcpPtr.p->lcpState != LcpRecord::LCP_IDLE) {
- ndbrequire(lcpPtr.p->lcpQueued == false);
- lcpPtr.p->lcpQueued = true;
- lcpPtr.p->queuedFragment.fragPtrI = fragptr.i;
- lcpPtr.p->queuedFragment.lcpFragOrd = * lcpFragOrd;
- return;
- }//if
-
- lcpPtr.p->currentFragment.fragPtrI = fragptr.i;
- lcpPtr.p->currentFragment.lcpFragOrd = * lcpFragOrd;
-
- sendLCP_FRAGIDREQ(signal);
-}//Dblqh::execLCP_FRAGORD()
-
-void Dblqh::execLCP_PREPARE_REF(Signal* signal)
-{
- jamEntry();
-
- LcpPrepareRef* ref= (LcpPrepareRef*)signal->getDataPtr();
-
- lcpPtr.i = ref->senderData;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_FRAGID);
-
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- c_fragment_pool.getPtr(fragptr);
-
- ndbrequire(ref->tableId == fragptr.p->tabRef);
- ndbrequire(ref->fragmentId == fragptr.p->fragId);
-
- tabptr.i = ref->tableId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- ndbrequire(lcpPtr.p->m_outstanding);
- lcpPtr.p->m_outstanding--;
-
- /**
- * Only BACKUP is allowed to ref LCP_PREPARE
- */
- ndbrequire(refToBlock(signal->getSendersBlockRef()) == BACKUP);
- lcpPtr.p->m_error = ref->errorCode;
-
- if (lcpPtr.p->m_outstanding == 0)
- {
- jam();
-
- if(lcpPtr.p->firstFragmentFlag)
- {
- jam();
- LcpFragOrd *ord= (LcpFragOrd*)signal->getDataPtrSend();
- lcpPtr.p->firstFragmentFlag= false;
- *ord = lcpPtr.p->currentFragment.lcpFragOrd;
- EXECUTE_DIRECT(PGMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
-
- /**
- * First fragment mean that last LCP is complete :-)
- */
- EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
- }
-
- lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
- contChkpNextFragLab(signal);
- }
-}
-
-/* --------------------------------------------------------------------------
- * PRECONDITION: LCP_PTR:LCP_STATE = WAIT_FRAGID
- * --------------------------------------------------------------------------
- * WE NOW HAVE THE LOCAL FRAGMENTS THAT THE LOCAL CHECKPOINT WILL USE.
- * -------------------------------------------------------------------------- */
-void Dblqh::execLCP_PREPARE_CONF(Signal* signal)
-{
- jamEntry();
-
- LcpPrepareConf* conf= (LcpPrepareConf*)signal->getDataPtr();
-
- lcpPtr.i = conf->senderData;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_FRAGID);
-
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- c_fragment_pool.getPtr(fragptr);
-
- if (refToBlock(signal->getSendersBlockRef()) != PGMAN)
- {
- ndbrequire(conf->tableId == fragptr.p->tabRef);
- ndbrequire(conf->fragmentId == fragptr.p->fragId);
- }
-
- ndbrequire(lcpPtr.p->m_outstanding);
- lcpPtr.p->m_outstanding--;
- if (lcpPtr.p->m_outstanding == 0)
- {
- jam();
-
- if(lcpPtr.p->firstFragmentFlag)
- {
- jam();
- LcpFragOrd *ord= (LcpFragOrd*)signal->getDataPtrSend();
- lcpPtr.p->firstFragmentFlag= false;
- *ord = lcpPtr.p->currentFragment.lcpFragOrd;
- EXECUTE_DIRECT(PGMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
-
- /**
- * First fragment mean that last LCP is complete :-)
- */
- EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
- }
-
- if (lcpPtr.p->m_error)
- {
- jam();
-
- lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
- contChkpNextFragLab(signal);
- return;
- }
-
- lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
- lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
-
- /* ----------------------------------------------------------------------
- * UPDATE THE MAX_GCI_IN_LCP AND MAX_GCI_COMPLETED_IN_LCP NOW BEFORE
- * ACTIVATING THE FRAGMENT AGAIN.
- * --------------------------------------------------------------------- */
- ndbrequire(lcpPtr.p->currentFragment.lcpFragOrd.lcpNo < MAX_LCP_STORED);
- fragptr.p->maxGciInLcp = fragptr.p->newestGci;
- fragptr.p->maxGciCompletedInLcp = cnewestCompletedGci;
-
- {
- LcpFragOrd *ord= (LcpFragOrd*)signal->getDataPtrSend();
- *ord = lcpPtr.p->currentFragment.lcpFragOrd;
- EXECUTE_DIRECT(LGMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
-
- *ord = lcpPtr.p->currentFragment.lcpFragOrd;
- EXECUTE_DIRECT(DBTUP, GSN_LCP_FRAG_ORD, signal, signal->length());
- jamEntry();
- }
-
- BackupFragmentReq* req= (BackupFragmentReq*)signal->getDataPtr();
- req->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- req->fragmentNo = 0;
- req->backupPtr = m_backup_ptr;
- req->backupId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
- req->count = 0;
-
-#ifdef NDB_DEBUG_FULL
- if(ERROR_INSERTED(5904))
- {
- g_trace_lcp.sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal,
- BackupFragmentReq::SignalLength, JBB);
- }
- else
-#endif
- {
- if (ERROR_INSERTED(5044) &&
- (fragptr.p->tabRef == c_error_insert_table_id) &&
- fragptr.p->fragId) // Not first frag
- {
- /**
- * Force CRASH_INSERTION in 10s
- */
- ndbout_c("table: %d frag: %d", fragptr.p->tabRef, fragptr.p->fragId);
- SET_ERROR_INSERT_VALUE(5027);
- sendSignalWithDelay(reference(), GSN_START_RECREQ, signal, 10000, 1);
- }
- else
- {
- sendSignal(BACKUP_REF, GSN_BACKUP_FRAGMENT_REQ, signal,
- BackupFragmentReq::SignalLength, JBB);
- }
- }
- }
-}
-
-void Dblqh::execBACKUP_FRAGMENT_REF(Signal* signal)
-{
- BackupFragmentRef *ref= (BackupFragmentRef*)signal->getDataPtr();
- char buf[100];
- BaseString::snprintf(buf,sizeof(buf),
- "Unable to store fragment during LCP. NDBFS Error: %u",
- ref->errorCode);
-
- progError(__LINE__,
- (ref->errorCode & FsRef::FS_ERR_BIT)?
- NDBD_EXIT_AFS_UNKNOWN
- : ref->errorCode,
- buf);
-}
-
-void Dblqh::execBACKUP_FRAGMENT_CONF(Signal* signal)
-{
- jamEntry();
- //BackupFragmentConf* conf= (BackupFragmentConf*)signal->getDataPtr();
-
- lcpPtr.i = 0;
- ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
- ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_START_CHKP);
- lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
-
- /* ------------------------------------------------------------------------
- * THE LOCAL CHECKPOINT HAS BEEN COMPLETED. IT IS NOW TIME TO START
- * A LOCAL CHECKPOINT ON THE NEXT FRAGMENT OR COMPLETE THIS LCP ROUND.
- * ------------------------------------------------------------------------
- * WE START BY SENDING LCP_REPORT TO DIH TO REPORT THE COMPLETED LCP.
- * TO CATER FOR NODE CRASHES WE SEND IT IN PARALLEL TO ALL NODES.
- * ----------------------------------------------------------------------- */
- fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
- c_fragment_pool.getPtr(fragptr);
-
- contChkpNextFragLab(signal);
- return;
-}//Dblqh::lcpCompletedLab()
-
-void
-Dblqh::sendLCP_FRAG_REP(Signal * signal,
- const LcpRecord::FragOrd & fragOrd) const {
-
- const Fragrecord* fragPtrP = c_fragment_pool.getConstPtr(fragOrd.fragPtrI);
-
- ndbrequire(fragOrd.lcpFragOrd.lcpNo < MAX_LCP_STORED);
- LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
- lcpReport->nodeId = cownNodeid;
- lcpReport->lcpId = fragOrd.lcpFragOrd.lcpId;
- lcpReport->lcpNo = fragOrd.lcpFragOrd.lcpNo;
- lcpReport->tableId = fragOrd.lcpFragOrd.tableId;
- lcpReport->fragId = fragOrd.lcpFragOrd.fragmentId;
- lcpReport->maxGciCompleted = fragPtrP->maxGciCompletedInLcp;
- lcpReport->maxGciStarted = fragPtrP->maxGciInLcp;
-
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- Uint32 nodeId = cnodeData[i];
- if(cnodeStatus[i] == ZNODE_UP){
- jam();
- BlockReference Tblockref = calcDihBlockRef(nodeId);
- sendSignal(Tblockref, GSN_LCP_FRAG_REP, signal,
- LcpFragRep::SignalLength, JBB);
- }//if
- }//for
-}
-
-void Dblqh::contChkpNextFragLab(Signal* signal)
-{
- /* ------------------------------------------------------------------------
- * UPDATE THE LATEST LOCAL CHECKPOINT COMPLETED ON FRAGMENT.
- * UPDATE THE LCP_ID OF THIS CHECKPOINT.
- * REMOVE THE LINK BETWEEN THE FRAGMENT RECORD AND THE LCP RECORD.
- * ----------------------------------------------------------------------- */
- if (fragptr.p->fragStatus == Fragrecord::BLOCKED) {
- jam();
- /**
- * LCP of fragment complete
- * but restarting of operations isn't
- */
- lcpPtr.p->lcpState = LcpRecord::LCP_BLOCKED_COMP;
- return;
- }//if
-
- /**
- * Send rep when fragment is done + unblocked
- */
- sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment);
-
- /* ------------------------------------------------------------------------
- * WE ALSO RELEASE THE LOCAL LCP RECORDS.
- * ----------------------------------------------------------------------- */
- if (lcpPtr.p->lcpQueued) {
- jam();
- /* ----------------------------------------------------------------------
- * Transfer the state from the queued to the active LCP.
- * --------------------------------------------------------------------- */
- lcpPtr.p->lcpQueued = false;
- lcpPtr.p->currentFragment = lcpPtr.p->queuedFragment;
-
- /* ----------------------------------------------------------------------
- * START THE QUEUED LOCAL CHECKPOINT.
- * --------------------------------------------------------------------- */
- sendLCP_FRAGIDREQ(signal);
- return;
- }//if
-
- lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
- if (lcpPtr.p->lastFragmentFlag){
- jam();
- /* ----------------------------------------------------------------------
- * NOW THE COMPLETE LOCAL CHECKPOINT ROUND IS COMPLETED.
- * --------------------------------------------------------------------- */
- completeLcpRoundLab(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
- return;
- }//if
-
- if (lcpPtr.p->reportEmpty) {
- jam();
- sendEMPTY_LCP_CONF(signal, false);
- }//if
- return;
-}//Dblqh::contChkpNextFragLab()
-
-void Dblqh::sendLCP_FRAGIDREQ(Signal* signal)
-{
- TablerecPtr tabPtr;
- tabPtr.i = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- ptrAss(tabPtr, tablerec);
- if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
- tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
- jam();
- /**
- * Fake that the fragment is done
- */
- contChkpNextFragLab(signal);
- return;
- }
-
- lcpPtr.p->m_error = 0;
- lcpPtr.p->m_outstanding = 1;
-
- ndbrequire(tabPtr.p->tableStatus == Tablerec::TABLE_DEFINED);
-
- lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_FRAGID;
- LcpPrepareReq* req= (LcpPrepareReq*)signal->getDataPtr();
- req->senderData = lcpPtr.i;
- req->senderRef = reference();
- req->lcpNo = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
- req->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- req->fragmentId = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
- req->lcpId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
- req->backupPtr = m_backup_ptr;
- req->backupId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
- sendSignal(BACKUP_REF, GSN_LCP_PREPARE_REQ, signal,
- LcpPrepareReq::SignalLength, JBB);
-
-}//Dblqh::sendLCP_FRAGIDREQ()
-
-void Dblqh::sendEMPTY_LCP_CONF(Signal* signal, bool idle)
-{
-
- EmptyLcpConf * const rep = (EmptyLcpConf*)&signal->theData[0];
- /* ----------------------------------------------------------------------
- * We have been requested to report when there are no more local
- * waiting to be started or ongoing. In this signal we also report
- * the last completed fragments state.
- * ---------------------------------------------------------------------- */
- rep->senderNodeId = getOwnNodeId();
- if(!idle){
- jam();
- rep->idle = 0 ;
- rep->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
- rep->fragmentId = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
- rep->lcpNo = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
- rep->lcpId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
- } else {
- jam();
- rep->idle = 1;
- rep->tableId = ~0;
- rep->fragmentId = ~0;
- rep->lcpNo = ~0;
- rep->lcpId = c_lcpId;
- }
-
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- Uint32 nodeId = cnodeData[i];
- if (lcpPtr.p->m_EMPTY_LCP_REQ.get(nodeId)) {
- jam();
-
- BlockReference blockref = calcDihBlockRef(nodeId);
- sendSignal(blockref, GSN_EMPTY_LCP_CONF, signal,
- EmptyLcpConf::SignalLength, JBB);
- }//if
- }//for
-
- lcpPtr.p->reportEmpty = false;
- lcpPtr.p->m_EMPTY_LCP_REQ.clear();
-}//Dblqh::sendEMPTY_LCPCONF()
-
-/* --------------------------------------------------------------------------
- * THE LOCAL CHECKPOINT ROUND IS NOW COMPLETED. SEND COMPLETED MESSAGE
- * TO THE MASTER DIH.
- * ------------------------------------------------------------------------- */
-void Dblqh::completeLcpRoundLab(Signal* signal, Uint32 lcpId)
-{
- clcpCompletedState = LCP_CLOSE_STARTED;
-
- EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
- req->senderData= lcpPtr.i;
- req->senderRef= reference();
- req->backupPtr= m_backup_ptr;
- req->backupId= lcpId;
- sendSignal(BACKUP_REF, GSN_END_LCP_REQ, signal,
- EndLcpReq::SignalLength, JBB);
-
- sendSignal(PGMAN_REF, GSN_END_LCP_REQ, signal,
- EndLcpReq::SignalLength, JBB);
-
- sendSignal(LGMAN_REF, GSN_END_LCP_REQ, signal,
- EndLcpReq::SignalLength, JBB);
-
- EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength);
- jamEntry();
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- lcpPtr.p->m_outstanding = 3;
- return;
-}//Dblqh::completeLcpRoundLab()
-
-void Dblqh::execEND_LCPCONF(Signal* signal)
-{
- jamEntry();
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
-
- ndbrequire(clcpCompletedState == LCP_CLOSE_STARTED);
- ndbrequire(lcpPtr.p->m_outstanding);
-
- lcpPtr.p->m_outstanding--;
- if(lcpPtr.p->m_outstanding == 0)
- {
- jam();
- clcpCompletedState = LCP_IDLE;
- sendLCP_COMPLETE_REP(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
- }
-}//Dblqh::execEND_LCPCONF()
-
-void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId)
-{
- cnoOfFragsCheckpointed = 0;
- ndbrequire((cnoOfNodes - 1) < (MAX_NDB_NODES - 1));
- /* ------------------------------------------------------------------------
- * WE SEND COMP_LCP_ROUND TO ALL NODES TO PREPARE FOR NODE CRASHES.
- * ----------------------------------------------------------------------- */
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- lcpPtr.p->lastFragmentFlag = false;
- lcpPtr.p->firstFragmentFlag = false;
-
- LcpCompleteRep* rep = (LcpCompleteRep*)signal->getDataPtrSend();
- rep->nodeId = getOwnNodeId();
- rep->lcpId = lcpId;
- rep->blockNo = DBLQH;
-
- for (Uint32 i = 0; i < cnoOfNodes; i++) {
- jam();
- Uint32 nodeId = cnodeData[i];
- if(cnodeStatus[i] == ZNODE_UP){
- jam();
-
- BlockReference blockref = calcDihBlockRef(nodeId);
- sendSignal(blockref, GSN_LCP_COMPLETE_REP, signal,
- LcpCompleteRep::SignalLength, JBB);
- }//if
- }//for
-
- if(lcpPtr.p->reportEmpty){
- jam();
- sendEMPTY_LCP_CONF(signal, true);
- }
-
- if (getNodeState().getNodeRestartInProgress() && cstartRecReq != 3)
- {
- jam();
- ndbrequire(cstartRecReq == 2);
- cstartRecReq = 3;
- }
- return;
-
-}//Dblqh::sendCOMP_LCP_ROUND()
-
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEND ACC_LCPREQ AND TUP_LCPREQ ------- */
-/* */
-/* INPUT: LCP_PTR LOCAL CHECKPOINT RECORD */
-/* FRAGPTR FRAGMENT RECORD */
-/* SUBROUTINE SHORT NAME = STL */
-/* ------------------------------------------------------------------------- */
-void Dblqh::sendStartLcp(Signal* signal)
-{
-}//Dblqh::sendStartLcp()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SET THE LOG TAIL IN THE LOG FILES ------- */
-/* */
-/*THIS SUBROUTINE HAVE BEEN BUGGY AND IS RATHER COMPLEX. IT IS IMPORTANT TO */
-/*REMEMBER THAT WE SEARCH FROM THE TAIL UNTIL WE REACH THE HEAD (CURRENT). */
-/*THE TAIL AND HEAD CAN BE ON THE SAME MBYTE. WE SEARCH UNTIL WE FIND A MBYTE*/
-/*THAT WE NEED TO KEEP. WE THEN SET THE TAIL TO BE THE PREVIOUS. IF WE DO */
-/*NOT FIND A MBYTE THAT WE NEED TO KEEP UNTIL WE REACH THE HEAD THEN WE USE */
-/*THE HEAD AS TAIL. FINALLY WE HAVE TO MOVE BACK THE TAIL TO ALSO INCLUDE */
-/*ALL PREPARE RECORDS. THIS MEANS THAT LONG-LIVED TRANSACTIONS ARE DANGEROUS */
-/*FOR SHORT LOGS. */
-/* ------------------------------------------------------------------------- */
-
-// this function has not been verified yet
-Uint32 Dblqh::remainingLogSize(const LogFileRecordPtr &sltCurrLogFilePtr,
- const LogPartRecordPtr &sltLogPartPtr)
-{
- Uint32 hf = sltCurrLogFilePtr.p->fileNo*clogFileSize+sltCurrLogFilePtr.p->currentMbyte;
- Uint32 tf = sltLogPartPtr.p->logTailFileNo*clogFileSize+sltLogPartPtr.p->logTailMbyte;
- Uint32 sz = sltLogPartPtr.p->noLogFiles*clogFileSize;
- if (tf > hf) hf += sz;
- return sz-(hf-tf);
-}
-
-void Dblqh::setLogTail(Signal* signal, Uint32 keepGci)
-{
- LogPartRecordPtr sltLogPartPtr;
- LogFileRecordPtr sltLogFilePtr;
-#if 0
- LogFileRecordPtr sltCurrLogFilePtr;
-#endif
- UintR tsltMbyte;
- UintR tsltStartMbyte;
- UintR tsltIndex;
- UintR tsltFlag;
-
- for (sltLogPartPtr.i = 0; sltLogPartPtr.i < 4; sltLogPartPtr.i++) {
- jam();
- ptrAss(sltLogPartPtr, logPartRecord);
- findLogfile(signal, sltLogPartPtr.p->logTailFileNo,
- sltLogPartPtr, &sltLogFilePtr);
-
-#if 0
- sltCurrLogFilePtr.i = sltLogPartPtr.p->currentLogfile;
- ptrCheckGuard(sltCurrLogFilePtr, clogFileFileSize, logFileRecord);
- infoEvent("setLogTail: Available log file %d size = %d[mbytes]+%d[words]", sltLogPartPtr.i,
- remainingLogSize(sltCurrLogFilePtr, sltLogPartPtr), sltCurrLogFilePtr.p->remainingWordsInMbyte);
-#endif
-
- tsltMbyte = sltLogPartPtr.p->logTailMbyte;
- tsltStartMbyte = tsltMbyte;
- tsltFlag = ZFALSE;
- if (sltLogFilePtr.i == sltLogPartPtr.p->currentLogfile) {
-/* ------------------------------------------------------------------------- */
-/*THE LOG AND THE TAIL IS ALREADY IN THE SAME FILE. */
-/* ------------------------------------------------------------------------- */
- if (sltLogFilePtr.p->currentMbyte >= sltLogPartPtr.p->logTailMbyte) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*THE CURRENT MBYTE IS AHEAD OF OR AT THE TAIL. THUS WE WILL ONLY LOOK FOR */
-/*THE TAIL UNTIL WE REACH THE CURRENT MBYTE WHICH IS IN THIS LOG FILE. */
-/*IF THE LOG TAIL IS AHEAD OF THE CURRENT MBYTE BUT IN THE SAME LOG FILE */
-/*THEN WE HAVE TO SEARCH THROUGH ALL FILES BEFORE WE COME TO THE CURRENT */
-/*MBYTE. WE ALWAYS STOP WHEN WE COME TO THE CURRENT MBYTE SINCE THE TAIL */
-/*CAN NEVER BE BEFORE THE HEAD. */
-/* ------------------------------------------------------------------------- */
- tsltFlag = ZTRUE;
- }//if
- }//if
-
-/* ------------------------------------------------------------------------- */
-/*NOW START SEARCHING FOR THE NEW TAIL, STARTING AT THE CURRENT TAIL AND */
-/*PROCEEDING UNTIL WE FIND A MBYTE WHICH IS NEEDED TO KEEP OR UNTIL WE REACH */
-/*CURRENT MBYTE (THE HEAD). */
-/* ------------------------------------------------------------------------- */
- SLT_LOOP:
- for (tsltIndex = tsltStartMbyte;
- tsltIndex <= clogFileSize - 1;
- tsltIndex++) {
- if (sltLogFilePtr.p->logMaxGciStarted[tsltIndex] >= keepGci) {
-/* ------------------------------------------------------------------------- */
-/*WE ARE NOT ALLOWED TO STEP THE LOG ANY FURTHER AHEAD */
-/*SET THE NEW LOG TAIL AND CONTINUE WITH NEXT LOG PART. */
-/*THIS MBYTE IS NOT TO BE INCLUDED SO WE NEED TO STEP BACK ONE MBYTE. */
-/* ------------------------------------------------------------------------- */
- if (tsltIndex != 0) {
- jam();
- tsltMbyte = tsltIndex - 1;
- } else {
- jam();
-/* ------------------------------------------------------------------------- */
-/*STEPPING BACK INCLUDES ALSO STEPPING BACK TO THE PREVIOUS LOG FILE. */
-/* ------------------------------------------------------------------------- */
- tsltMbyte = clogFileSize - 1;
- sltLogFilePtr.i = sltLogFilePtr.p->prevLogFile;
- ptrCheckGuard(sltLogFilePtr, clogFileFileSize, logFileRecord);
- }//if
- goto SLT_BREAK;
- } else {
- jam();
- if (tsltFlag == ZTRUE) {
-/* ------------------------------------------------------------------------- */
-/*WE ARE IN THE SAME FILE AS THE CURRENT MBYTE AND WE CAN REACH THE CURRENT */
-/*MBYTE BEFORE WE REACH A NEW TAIL. */
-/* ------------------------------------------------------------------------- */
- if (tsltIndex == sltLogFilePtr.p->currentMbyte) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*THE TAIL OF THE LOG IS ACTUALLY WITHIN THE CURRENT MBYTE. THUS WE SET THE */
-/*LOG TAIL TO BE THE CURRENT MBYTE. */
-/* ------------------------------------------------------------------------- */
- tsltMbyte = sltLogFilePtr.p->currentMbyte;
- goto SLT_BREAK;
- }//if
- }//if
- }//if
- }//for
- sltLogFilePtr.i = sltLogFilePtr.p->nextLogFile;
- ptrCheckGuard(sltLogFilePtr, clogFileFileSize, logFileRecord);
- if (sltLogFilePtr.i == sltLogPartPtr.p->currentLogfile) {
- jam();
- tsltFlag = ZTRUE;
- }//if
- tsltStartMbyte = 0;
- goto SLT_LOOP;
- SLT_BREAK:
- jam();
- {
- UintR ToldTailFileNo = sltLogPartPtr.p->logTailFileNo;
- UintR ToldTailMByte = sltLogPartPtr.p->logTailMbyte;
-
- arrGuard(tsltMbyte, clogFileSize);
- sltLogPartPtr.p->logTailFileNo =
- sltLogFilePtr.p->logLastPrepRef[tsltMbyte] >> 16;
-/* ------------------------------------------------------------------------- */
-/*SINCE LOG_MAX_GCI_STARTED ONLY KEEP TRACK OF COMMIT LOG RECORDS WE ALSO */
-/*HAVE TO STEP BACK THE TAIL SO THAT WE INCLUDE ALL PREPARE RECORDS */
-/*NEEDED FOR THOSE COMMIT RECORDS IN THIS MBYTE. THIS IS A RATHER */
-/*CONSERVATIVE APPROACH BUT IT WORKS. */
-/* ------------------------------------------------------------------------- */
- sltLogPartPtr.p->logTailMbyte =
- sltLogFilePtr.p->logLastPrepRef[tsltMbyte] & 65535;
- if ((ToldTailFileNo != sltLogPartPtr.p->logTailFileNo) ||
- (ToldTailMByte != sltLogPartPtr.p->logTailMbyte)) {
- jam();
- if (sltLogPartPtr.p->logPartState == LogPartRecord::TAIL_PROBLEM) {
- if (sltLogPartPtr.p->firstLogQueue == RNIL) {
- jam();
- sltLogPartPtr.p->logPartState = LogPartRecord::IDLE;
- } else {
- jam();
- sltLogPartPtr.p->logPartState = LogPartRecord::ACTIVE;
- }//if
- }//if
- }//if
- }
-#if 0
- infoEvent("setLogTail: Available log file %d size = %d[mbytes]+%d[words]", sltLogPartPtr.i,
- remainingLogSize(sltCurrLogFilePtr, sltLogPartPtr), sltCurrLogFilePtr.p->remainingWordsInMbyte);
-#endif
- }//for
-
-}//Dblqh::setLogTail()
-
-/* ######################################################################### */
-/* ####### GLOBAL CHECKPOINT MODULE ####### */
-/* */
-/* ######################################################################### */
-/*---------------------------------------------------------------------------*/
-/* THIS MODULE HELPS DIH IN DISCOVERING WHEN GLOBAL CHECKPOINTS ARE */
-/* RECOVERABLE. IT HANDLES THE REQUEST GCP_SAVEREQ THAT REQUESTS LQH TO */
-/* SAVE A PARTICULAR GLOBAL CHECKPOINT TO DISK AND RESPOND WHEN COMPLETED. */
-/*---------------------------------------------------------------------------*/
-/* *************** */
-/* GCP_SAVEREQ > */
-/* *************** */
-void Dblqh::execGCP_SAVEREQ(Signal* signal)
-{
- jamEntry();
- const GCPSaveReq * const saveReq = (GCPSaveReq *)&signal->theData[0];
-
- if (ERROR_INSERTED(5000)) {
- systemErrorLab(signal, __LINE__);
- }
-
- if (ERROR_INSERTED(5007)){
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_GCP_SAVEREQ, signal, 10000,
- signal->length());
- return;
- }
-
- const Uint32 dihBlockRef = saveReq->dihBlockRef;
- const Uint32 dihPtr = saveReq->dihPtr;
- const Uint32 gci = saveReq->gci;
-
- if(getNodeState().startLevel >= NodeState::SL_STOPPING_4){
- GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
- saveRef->dihPtr = dihPtr;
- saveRef->nodeId = getOwnNodeId();
- saveRef->gci = gci;
- saveRef->errorCode = GCPSaveRef::NodeShutdownInProgress;
- sendSignal(dihBlockRef, GSN_GCP_SAVEREF, signal,
- GCPSaveRef::SignalLength, JBB);
- return;
- }
-
- if (getNodeState().getNodeRestartInProgress() && cstartRecReq < 2)
- {
- GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
- saveRef->dihPtr = dihPtr;
- saveRef->nodeId = getOwnNodeId();
- saveRef->gci = gci;
- saveRef->errorCode = GCPSaveRef::NodeRestartInProgress;
- sendSignal(dihBlockRef, GSN_GCP_SAVEREF, signal,
- GCPSaveRef::SignalLength, JBB);
- return;
- }
-
- ndbrequire(gci >= cnewestCompletedGci);
-
- if (gci == cnewestCompletedGci) {
-/*---------------------------------------------------------------------------*/
-/* GLOBAL CHECKPOINT HAVE ALREADY BEEN HANDLED. REQUEST MUST HAVE BEEN SENT */
-/* FROM NEW MASTER DIH. */
-/*---------------------------------------------------------------------------*/
- if (ccurrentGcprec == RNIL) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS INDICATES THAT WE HAVE ALREADY SENT GCP_SAVECONF TO PREVIOUS MASTER. */
-/* WE SIMPLY SEND IT ALSO TO THE NEW MASTER. */
-/*---------------------------------------------------------------------------*/
- GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
- saveConf->dihPtr = dihPtr;
- saveConf->nodeId = getOwnNodeId();
- saveConf->gci = cnewestCompletedGci;
- sendSignal(dihBlockRef, GSN_GCP_SAVECONF, signal,
- GCPSaveConf::SignalLength, JBA);
- return;
- }
- jam();
-/*---------------------------------------------------------------------------*/
-/* WE HAVE NOT YET SENT THE RESPONSE TO THE OLD MASTER. WE WILL SET THE NEW */
-/* RECEIVER OF THE RESPONSE AND THEN EXIT SINCE THE PROCESS IS ALREADY */
-/* STARTED. */
-/*---------------------------------------------------------------------------*/
- gcpPtr.i = ccurrentGcprec;
- ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
- gcpPtr.p->gcpUserptr = dihPtr;
- gcpPtr.p->gcpBlockref = dihBlockRef;
- return;
- }//if
-
- ndbrequire(ccurrentGcprec == RNIL);
- cnewestCompletedGci = gci;
- if (gci > cnewestGci) {
- jam();
- cnewestGci = gci;
- }//if
-
- if(getNodeState().getNodeRestartInProgress() && cstartRecReq < 3)
- {
- GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
- saveRef->dihPtr = dihPtr;
- saveRef->nodeId = getOwnNodeId();
- saveRef->gci = gci;
- saveRef->errorCode = GCPSaveRef::NodeRestartInProgress;
- sendSignal(dihBlockRef, GSN_GCP_SAVEREF, signal,
- GCPSaveRef::SignalLength, JBB);
- return;
- }
-
- ccurrentGcprec = 0;
- gcpPtr.i = ccurrentGcprec;
- ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
-
- gcpPtr.p->gcpBlockref = dihBlockRef;
- gcpPtr.p->gcpUserptr = dihPtr;
- gcpPtr.p->gcpId = gci;
- bool tlogActive = false;
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState == LogPartRecord::ACTIVE) {
- jam();
- logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_TRUE;
- tlogActive = true;
- } else {
- jam();
- logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_FALSE;
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- writeCompletedGciLog(signal);
- }//if
- }//for
- if (tlogActive == true) {
- jam();
- return;
- }//if
- initGcpRecLab(signal);
- startTimeSupervision(signal);
- return;
-}//Dblqh::execGCP_SAVEREQ()
-
-/* ------------------------------------------------------------------------- */
-/* START TIME SUPERVISION OF THE LOG PARTS. */
-/* ------------------------------------------------------------------------- */
-void Dblqh::startTimeSupervision(Signal* signal)
-{
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
-/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-/* WE HAVE TO START CHECKING IF THE LOG IS TO BE WRITTEN EVEN IF PAGES ARE */
-/* FULL. INITIALISE THE VALUES OF WHERE WE ARE IN THE LOG CURRENTLY. */
-/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
- logPartPtr.p->logPartTimer = 0;
- logPartPtr.p->logTimer = 1;
- signal->theData[0] = ZTIME_SUPERVISION;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//for
-}//Dblqh::startTimeSupervision()
-
-/*---------------------------------------------------------------------------*/
-/* WE SET THE GLOBAL CHECKPOINT VARIABLES AFTER WRITING THE COMPLETED GCI LOG*/
-/* RECORD. THIS ENSURES THAT WE WILL ENCOUNTER THE COMPLETED GCI RECORD WHEN */
-/* WE EXECUTE THE FRAGMENT LOG. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::initGcpRecLab(Signal* signal)
-{
-/* ======================================================================== */
-/* ======= INITIATE GCP RECORD ======= */
-/* */
-/* SUBROUTINE SHORT NAME = IGR */
-/* ======================================================================== */
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
-/*--------------------------------------------------*/
-/* BY SETTING THE GCPREC = 0 WE START THE */
-/* CHECKING BY CHECK_GCP_COMPLETED. THIS */
-/* CHECKING MUST NOT BE STARTED UNTIL WE HAVE */
-/* INSERTED ALL COMPLETE GCI LOG RECORDS IN */
-/* ALL LOG PARTS. */
-/*--------------------------------------------------*/
- logPartPtr.p->gcprec = 0;
- gcpPtr.p->gcpLogPartState[logPartPtr.i] = ZWAIT_DISK;
- gcpPtr.p->gcpSyncReady[logPartPtr.i] = ZFALSE;
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- gcpPtr.p->gcpFilePtr[logPartPtr.i] = logFilePtr.i;
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- if (logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == ZPAGE_HEADER_SIZE) {
- jam();
-/*--------------------------------------------------*/
-/* SINCE THE CURRENT FILEPAGE POINTS AT THE */
-/* NEXT WORD TO BE WRITTEN WE HAVE TO ADJUST */
-/* FOR THIS BY DECREASING THE FILE PAGE BY ONE*/
-/* IF NO WORD HAS BEEN WRITTEN ON THE CURRENT */
-/* FILEPAGE. */
-/*--------------------------------------------------*/
- gcpPtr.p->gcpPageNo[logPartPtr.i] = logFilePtr.p->currentFilepage - 1;
- gcpPtr.p->gcpWordNo[logPartPtr.i] = ZPAGE_SIZE - 1;
- } else {
- jam();
- gcpPtr.p->gcpPageNo[logPartPtr.i] = logFilePtr.p->currentFilepage;
- gcpPtr.p->gcpWordNo[logPartPtr.i] =
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] - 1;
- }//if
- }//for
- return;
-}//Dblqh::initGcpRecLab()
-
-/* ========================================================================= */
-/* ==== CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED AFTER A COMPLETED===== */
-/* DISK WRITE. */
-/* */
-/* SUBROUTINE SHORT NAME = CGC */
-/* ========================================================================= */
-void Dblqh::checkGcpCompleted(Signal* signal,
- Uint32 tcgcPageWritten,
- Uint32 tcgcWordWritten)
-{
- UintR tcgcFlag;
- UintR tcgcJ;
-
- gcpPtr.i = logPartPtr.p->gcprec;
- if (gcpPtr.i != RNIL) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* IF THE GLOBAL CHECKPOINT IS NOT WAITING FOR COMPLETION THEN WE CAN QUIT */
-/* THE SEARCH IMMEDIATELY. */
-/* ------------------------------------------------------------------------- */
- ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
- if (gcpPtr.p->gcpFilePtr[logPartPtr.i] == logFilePtr.i) {
-/* ------------------------------------------------------------------------- */
-/* IF THE COMPLETED DISK OPERATION WAS ON ANOTHER FILE THAN THE ONE WE ARE */
-/* WAITING FOR, THEN WE CAN ALSO QUIT THE SEARCH IMMEDIATELY. */
-/* ------------------------------------------------------------------------- */
- if (tcgcPageWritten < gcpPtr.p->gcpPageNo[logPartPtr.i]) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* THIS LOG PART HAVE NOT YET WRITTEN THE GLOBAL CHECKPOINT TO DISK. */
-/* ------------------------------------------------------------------------- */
- return;
- } else {
- if (tcgcPageWritten == gcpPtr.p->gcpPageNo[logPartPtr.i]) {
- if (tcgcWordWritten < gcpPtr.p->gcpWordNo[logPartPtr.i]) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* THIS LOG PART HAVE NOT YET WRITTEN THE GLOBAL CHECKPOINT TO DISK. */
-/* ------------------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//if
-/* ------------------------------------------------------------------------- */
-/* THIS LOG PART HAVE WRITTEN THE GLOBAL CHECKPOINT TO DISK. */
-/* ------------------------------------------------------------------------- */
- logPartPtr.p->gcprec = RNIL;
- gcpPtr.p->gcpLogPartState[logPartPtr.i] = ZON_DISK;
- tcgcFlag = ZTRUE;
- for (tcgcJ = 0; tcgcJ <= 3; tcgcJ++) {
- jam();
- if (gcpPtr.p->gcpLogPartState[tcgcJ] != ZON_DISK) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*ALL LOG PARTS HAVE NOT SAVED THIS GLOBAL CHECKPOINT TO DISK YET. WAIT FOR */
-/*THEM TO COMPLETE. */
-/* ------------------------------------------------------------------------- */
- tcgcFlag = ZFALSE;
- }//if
- }//for
- if (tcgcFlag == ZTRUE) {
- jam();
-/* ------------------------------------------------------------------------- */
-/*WE HAVE FOUND A COMPLETED GLOBAL CHECKPOINT OPERATION. WE NOW NEED TO SEND */
-/*GCP_SAVECONF, REMOVE THE GCP RECORD FROM THE LIST OF WAITING GCP RECORDS */
-/*ON THIS LOG PART AND RELEASE THE GCP RECORD. */
-// After changing the log implementation we need to perform a FSSYNCREQ on all
-// log files where the last log word resided first before proceeding.
-/* ------------------------------------------------------------------------- */
- UintR Ti;
- for (Ti = 0; Ti < 4; Ti++) {
- LogFileRecordPtr loopLogFilePtr;
- loopLogFilePtr.i = gcpPtr.p->gcpFilePtr[Ti];
- ptrCheckGuard(loopLogFilePtr, clogFileFileSize, logFileRecord);
- if (loopLogFilePtr.p->logFileStatus == LogFileRecord::OPEN) {
- jam();
- signal->theData[0] = loopLogFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = gcpPtr.p->gcpFilePtr[Ti];
- sendSignal(NDBFS_REF, GSN_FSSYNCREQ, signal, 3, JBA);
- } else {
- ndbrequire((loopLogFilePtr.p->logFileStatus ==
- LogFileRecord::CLOSED) ||
- (loopLogFilePtr.p->logFileStatus ==
- LogFileRecord::CLOSING_WRITE_LOG) ||
- (loopLogFilePtr.p->logFileStatus ==
- LogFileRecord::OPENING_WRITE_LOG));
- signal->theData[0] = loopLogFilePtr.i;
- execFSSYNCCONF(signal);
- }//if
- }//for
- return;
- }//if
- }//if
- }//if
-}//Dblqh::checkGcpCompleted()
-
-void
-Dblqh::execFSSYNCCONF(Signal* signal)
-{
- GcpRecordPtr localGcpPtr;
- LogFileRecordPtr localLogFilePtr;
- LogPartRecordPtr localLogPartPtr;
- localLogFilePtr.i = signal->theData[0];
- ptrCheckGuard(localLogFilePtr, clogFileFileSize, logFileRecord);
- localLogPartPtr.i = localLogFilePtr.p->logPartRec;
- localGcpPtr.i = ccurrentGcprec;
- ptrCheckGuard(localGcpPtr, cgcprecFileSize, gcpRecord);
- localGcpPtr.p->gcpSyncReady[localLogPartPtr.i] = ZTRUE;
- UintR Ti;
- for (Ti = 0; Ti < 4; Ti++) {
- jam();
- if (localGcpPtr.p->gcpSyncReady[Ti] == ZFALSE) {
- jam();
- return;
- }//if
- }//for
- GCPSaveConf * const saveConf = (GCPSaveConf *)&signal->theData[0];
- saveConf->dihPtr = localGcpPtr.p->gcpUserptr;
- saveConf->nodeId = getOwnNodeId();
- saveConf->gci = localGcpPtr.p->gcpId;
- sendSignal(localGcpPtr.p->gcpBlockref, GSN_GCP_SAVECONF, signal,
- GCPSaveConf::SignalLength, JBA);
- ccurrentGcprec = RNIL;
-}//Dblqh::execFSSYNCCONF()
-
-
-/* ######################################################################### */
-/* ####### FILE HANDLING MODULE ####### */
-/* */
-/* ######################################################################### */
-/* THIS MODULE HANDLES RESPONSE MESSAGES FROM THE FILE SYSTEM */
-/* ######################################################################### */
-/* ######################################################################### */
-/* SIGNAL RECEPTION MODULE */
-/* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
-/* */
-/* THIS MODULE CHECKS THE STATE AND JUMPS TO THE PROPER PART OF THE FILE */
-/* HANDLING MODULE. */
-/* ######################################################################### */
-/* *************** */
-/* FSCLOSECONF > */
-/* *************** */
-void Dblqh::execFSCLOSECONF(Signal* signal)
-{
- jamEntry();
- logFilePtr.i = signal->theData[0];
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- switch (logFilePtr.p->logFileStatus) {
- case LogFileRecord::CLOSE_SR_INVALIDATE_PAGES:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
-
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
-
- exitFromInvalidate(signal);
- return;
- case LogFileRecord::CLOSING_INIT:
- jam();
- closingInitLab(signal);
- return;
- case LogFileRecord::CLOSING_SR:
- jam();
- closingSrLab(signal);
- return;
- case LogFileRecord::CLOSING_EXEC_SR:
- jam();
- closeExecSrLab(signal);
- return;
- case LogFileRecord::CLOSING_EXEC_SR_COMPLETED:
- jam();
- closeExecSrCompletedLab(signal);
- return;
- case LogFileRecord::CLOSING_WRITE_LOG:
- jam();
- closeWriteLogLab(signal);
- return;
- case LogFileRecord::CLOSING_EXEC_LOG:
- jam();
- closeExecLogLab(signal);
- return;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}//Dblqh::execFSCLOSECONF()
-
-
-/* ************>> */
-/* FSOPENCONF > */
-/* ************>> */
-void Dblqh::execFSOPENCONF(Signal* signal)
-{
- jamEntry();
- initFsopenconf(signal);
- switch (logFilePtr.p->logFileStatus) {
- case LogFileRecord::OPEN_SR_INVALIDATE_PAGES:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- readFileInInvalidate(signal, false);
- return;
- case LogFileRecord::OPENING_INIT:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openFileInitLab(signal);
- return;
- case LogFileRecord::OPEN_SR_FRONTPAGE:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrFrontpageLab(signal);
- return;
- case LogFileRecord::OPEN_SR_LAST_FILE:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrLastFileLab(signal);
- return;
- case LogFileRecord::OPEN_SR_NEXT_FILE:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrNextFileLab(signal);
- return;
- case LogFileRecord::OPEN_EXEC_SR_START:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openExecSrStartLab(signal);
- return;
- case LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openExecSrNewMbyteLab(signal);
- return;
- case LogFileRecord::OPEN_SR_FOURTH_PHASE:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrFourthPhaseLab(signal);
- return;
- case LogFileRecord::OPEN_SR_FOURTH_NEXT:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrFourthNextLab(signal);
- return;
- case LogFileRecord::OPEN_SR_FOURTH_ZERO:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openSrFourthZeroLab(signal);
- return;
- case LogFileRecord::OPENING_WRITE_LOG:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- return;
- case LogFileRecord::OPEN_EXEC_LOG:
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
- openExecLogLab(signal);
- return;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}//Dblqh::execFSOPENCONF()
-
-void
-Dblqh::execFSOPENREF(Signal* signal)
-{
- jamEntry();
- FsRef* ref = (FsRef*)signal->getDataPtr();
- Uint32 err = ref->errorCode;
- if (err == FsRef::fsErrInvalidFileSize)
- {
- char buf[256];
- BaseString::snprintf(buf, sizeof(buf),
- "Invalid file size for redo logfile, "
- " size only changable with --initial");
- progError(__LINE__,
- NDBD_EXIT_INVALID_CONFIG,
- buf);
- return;
- }
-
- SimulatedBlock::execFSOPENREF(signal);
-}
-
-/* ************>> */
-/* FSREADCONF > */
-/* ************>> */
-void Dblqh::execFSREADCONF(Signal* signal)
-{
- jamEntry();
- initFsrwconf(signal, false);
-
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::READ_SR_LAST_MBYTE:
- jam();
- releaseLfo(signal);
- readSrLastMbyteLab(signal);
- return;
- case LogFileOperationRecord::READ_SR_FRONTPAGE:
- jam();
- releaseLfo(signal);
- readSrFrontpageLab(signal);
- return;
- case LogFileOperationRecord::READ_SR_LAST_FILE:
- jam();
- releaseLfo(signal);
- readSrLastFileLab(signal);
- return;
- case LogFileOperationRecord::READ_SR_NEXT_FILE:
- jam();
- releaseLfo(signal);
- readSrNextFileLab(signal);
- return;
- case LogFileOperationRecord::READ_EXEC_SR:
- jam();
- readExecSrLab(signal);
- return;
- case LogFileOperationRecord::READ_EXEC_LOG:
- jam();
- readExecLogLab(signal);
- return;
- case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
- jam();
- invalidateLogAfterLastGCI(signal);
- return;
- case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
- jam();
- releaseLfo(signal);
- readSrFourthPhaseLab(signal);
- return;
- case LogFileOperationRecord::READ_SR_FOURTH_ZERO:
- jam();
- releaseLfo(signal);
- readSrFourthZeroLab(signal);
- return;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}//Dblqh::execFSREADCONF()
-
-/* ************>> */
-/* FSREADCONF > */
-/* ************>> */
-void Dblqh::execFSREADREF(Signal* signal)
-{
- jamEntry();
- lfoPtr.i = signal->theData[0];
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::READ_SR_LAST_MBYTE:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_FRONTPAGE:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_LAST_FILE:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_NEXT_FILE:
- jam();
- break;
- case LogFileOperationRecord::READ_EXEC_SR:
- jam();
- break;
- case LogFileOperationRecord::READ_EXEC_LOG:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_FOURTH_ZERO:
- jam();
- break;
- case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
- jam()
- break;
- default:
- jam();
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system read failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState);
- fsRefError(signal,__LINE__,msg);
- }
-}//Dblqh::execFSREADREF()
-
-/* *************** */
-/* FSWRITECONF > */
-/* *************** */
-void Dblqh::execFSWRITECONF(Signal* signal)
-{
- jamEntry();
- initFsrwconf(signal, true);
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
- jam();
- invalidateLogAfterLastGCI(signal);
- CRASH_INSERTION(5047);
- return;
- case LogFileOperationRecord::WRITE_PAGE_ZERO:
- jam();
- writePageZeroLab(signal);
- return;
- case LogFileOperationRecord::LAST_WRITE_IN_FILE:
- jam();
- lastWriteInFileLab(signal);
- return;
- case LogFileOperationRecord::INIT_WRITE_AT_END:
- jam();
- initWriteEndLab(signal);
- return;
- case LogFileOperationRecord::INIT_FIRST_PAGE:
- jam();
- initFirstPageLab(signal);
- return;
- case LogFileOperationRecord::WRITE_GCI_ZERO:
- jam();
- writeGciZeroLab(signal);
- return;
- case LogFileOperationRecord::WRITE_DIRTY:
- jam();
- writeDirtyLab(signal);
- return;
- case LogFileOperationRecord::WRITE_INIT_MBYTE:
- jam();
- writeInitMbyteLab(signal);
- return;
- case LogFileOperationRecord::ACTIVE_WRITE_LOG:
- jam();
- writeLogfileLab(signal);
- return;
- case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE:
- jam();
- firstPageWriteLab(signal);
- return;
- case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES_UPDATE_PAGE0:
- jam();
- // We are done...send completed signal and exit this phase.
- releaseLfo(signal);
- signal->theData[0] = ZSR_FOURTH_COMP;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}//Dblqh::execFSWRITECONF()
-
-/* ************>> */
-/* FSWRITEREF > */
-/* ************>> */
-void Dblqh::execFSWRITEREF(Signal* signal)
-{
- jamEntry();
- lfoPtr.i = signal->theData[0];
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- terrorCode = signal->theData[1];
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::WRITE_PAGE_ZERO:
- jam();
- break;
- case LogFileOperationRecord::LAST_WRITE_IN_FILE:
- jam();
- break;
- case LogFileOperationRecord::INIT_WRITE_AT_END:
- jam();
- break;
- case LogFileOperationRecord::INIT_FIRST_PAGE:
- jam();
- break;
- case LogFileOperationRecord::WRITE_GCI_ZERO:
- jam();
- break;
- case LogFileOperationRecord::WRITE_DIRTY:
- jam();
- break;
- case LogFileOperationRecord::WRITE_INIT_MBYTE:
- jam();
- break;
- case LogFileOperationRecord::ACTIVE_WRITE_LOG:
- jam();
- break;
- case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE:
- jam();
- break;
- case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
- jam();
- systemErrorLab(signal, __LINE__);
- default:
- jam();
- break;
- }//switch
- {
- char msg[100];
- sprintf(msg, "File system write failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState);
- fsRefError(signal,__LINE__,msg);
- }
-}//Dblqh::execFSWRITEREF()
-
-
-/* ========================================================================= */
-/* ======= INITIATE WHEN RECEIVING FSOPENCONF ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initFsopenconf(Signal* signal)
-{
- logFilePtr.i = signal->theData[0];
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logFilePtr.p->fileRef = signal->theData[1];
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.p->currentMbyte = 0;
- logFilePtr.p->filePosition = 0;
-}//Dblqh::initFsopenconf()
-
-/* ========================================================================= */
-/* ======= INITIATE WHEN RECEIVING FSREADCONF AND FSWRITECONF ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initFsrwconf(Signal* signal, bool write)
-{
- LogPageRecordPtr logP;
- Uint32 noPages, totPages;
- lfoPtr.i = signal->theData[0];
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- totPages= lfoPtr.p->noPagesRw;
- logFilePtr.i = lfoPtr.p->logFileRec;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logPagePtr.i = lfoPtr.p->firstLfoPage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logP= logPagePtr;
- noPages= 1;
- ndbassert(totPages > 0);
- for (;;)
- {
- logP.p->logPageWord[ZPOS_IN_WRITING]= 0;
- logP.p->logPageWord[ZPOS_IN_FREE_LIST]= 0;
- if (noPages == totPages)
- return;
- if (write)
- logP.i= logP.p->logPageWord[ZNEXT_PAGE];
- else
- logP.i= lfoPtr.p->logPageArray[noPages];
- ptrCheckGuard(logP, clogPageFileSize, logPageRecord);
- noPages++;
- }
-}//Dblqh::initFsrwconf()
-
-/* ######################################################################### */
-/* NORMAL OPERATION MODULE */
-/* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
-/* */
-/* THIS PART HANDLES THE NORMAL OPENING, CLOSING AND WRITING OF LOG FILES */
-/* DURING NORMAL OPERATION. */
-/* ######################################################################### */
-/*---------------------------------------------------------------------------*/
-/* THIS SIGNAL IS USED TO SUPERVISE THAT THE LOG RECORDS ARE NOT KEPT IN MAIN*/
-/* MEMORY FOR MORE THAN 1 SECOND TO ACHIEVE THE PROPER RELIABILITY. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::timeSup(Signal* signal)
-{
- LogPageRecordPtr origLogPagePtr;
- Uint32 wordWritten;
-
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- if (logPartPtr.p->logPartTimer != logPartPtr.p->logTimer) {
- jam();
-/*--------------------------------------------------------------------------*/
-/* THIS LOG PART HAS NOT WRITTEN TO DISK DURING THE LAST SECOND. */
-/*--------------------------------------------------------------------------*/
- switch (logPartPtr.p->logPartState) {
- case LogPartRecord::FILE_CHANGE_PROBLEM:
- jam();
-/*--------------------------------------------------------------------------*/
-/* THIS LOG PART HAS PROBLEMS IN CHANGING FILES MAKING IT IMPOSSIBLE */
-// TO WRITE TO THE FILE CURRENTLY. WE WILL COMEBACK LATER AND SEE IF
-// THE PROBLEM HAS BEEN FIXED.
-/*--------------------------------------------------------------------------*/
- case LogPartRecord::ACTIVE:
- jam();
-/*---------------------------------------------------------------------------*/
-/* AN OPERATION IS CURRENTLY ACTIVE IN WRITING THIS LOG PART. WE THUS CANNOT */
-/* WRITE ANYTHING TO DISK AT THIS MOMENT. WE WILL SEND A SIGNAL DELAYED FOR */
-/* 10 MS AND THEN TRY AGAIN. POSSIBLY THE LOG PART WILL HAVE BEEN WRITTEN */
-/* UNTIL THEN OR ELSE IT SHOULD BE FREE TO WRITE AGAIN. */
-/*---------------------------------------------------------------------------*/
- signal->theData[0] = ZTIME_SUPERVISION;
- signal->theData[1] = logPartPtr.i;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
- return;
- break;
- case LogPartRecord::IDLE:
- case LogPartRecord::TAIL_PROBLEM:
- jam();
-/*---------------------------------------------------------------------------*/
-/* IDLE AND NOT WRITTEN TO DISK IN A SECOND. ALSO WHEN WE HAVE A TAIL PROBLEM*/
-/* WE HAVE TO WRITE TO DISK AT TIMES. WE WILL FIRST CHECK WHETHER ANYTHING */
-/* AT ALL HAVE BEEN WRITTEN TO THE PAGES BEFORE WRITING TO DISK. */
-/*---------------------------------------------------------------------------*/
-/* WE HAVE TO WRITE TO DISK IN ALL CASES SINCE THERE COULD BE INFORMATION */
-/* STILL IN THE LOG THAT WAS GENERATED BEFORE THE PREVIOUS TIME SUPERVISION */
-/* BUT AFTER THE LAST DISK WRITE. THIS PREVIOUSLY STOPPED ALL DISK WRITES */
-/* WHEN NO MORE LOG WRITES WERE PERFORMED (THIS HAPPENED WHEN LOG GOT FULL */
-/* AND AFTER LOADING THE INITIAL RECORDS IN INITIAL START). */
-/*---------------------------------------------------------------------------*/
- if (((logFilePtr.p->currentFilepage + 1) & (ZPAGES_IN_MBYTE -1)) == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS IS THE LAST PAGE IN THIS MBYTE. WRITE NEXT LOG AND SWITCH TO NEXT */
-/* MBYTE. */
-/*---------------------------------------------------------------------------*/
- changeMbyte(signal);
- } else {
-/*---------------------------------------------------------------------------*/
-/* WRITE THE LOG PAGE TO DISK EVEN IF IT IS NOT FULL. KEEP PAGE AND WRITE A */
-/* COPY. THE ORIGINAL PAGE WILL BE WRITTEN AGAIN LATER ON. */
-/*---------------------------------------------------------------------------*/
- wordWritten = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] - 1;
- origLogPagePtr.i = logPagePtr.i;
- origLogPagePtr.p = logPagePtr.p;
- seizeLogpage(signal);
- MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[0],
- &origLogPagePtr.p->logPageWord[0],
- wordWritten + 1);
- ndbrequire(wordWritten < ZPAGE_SIZE);
- if (logFilePtr.p->noLogpagesInBuffer > 0) {
- jam();
- completedLogPage(signal, ZENFORCE_WRITE, __LINE__);
-/*---------------------------------------------------------------------------*/
-/*SINCE WE ARE ONLY WRITING PART OF THE LAST PAGE WE HAVE TO UPDATE THE WORD */
-/*WRITTEN TO REFLECT THE REAL LAST WORD WRITTEN. WE ALSO HAVE TO MOVE THE */
-/*FILE POSITION ONE STEP BACKWARDS SINCE WE ARE NOT WRITING THE LAST PAGE */
-/*COMPLETELY. IT WILL BE WRITTEN AGAIN. */
-/*---------------------------------------------------------------------------*/
- lfoPtr.p->lfoWordWritten = wordWritten;
- logFilePtr.p->filePosition = logFilePtr.p->filePosition - 1;
- } else {
- if (wordWritten == (ZPAGE_HEADER_SIZE - 1)) {
-/*---------------------------------------------------------------------------*/
-/*THIS IS POSSIBLE BUT VERY UNLIKELY. IF THE PAGE WAS COMPLETED AFTER THE LAST*/
-/*WRITE TO DISK THEN NO_LOG_PAGES_IN_BUFFER > 0 AND IF NOT WRITTEN SINCE LAST*/
-/*WRITE TO DISK THEN THE PREVIOUS PAGE MUST HAVE BEEN WRITTEN BY SOME */
-/*OPERATION AND THAT BECAME COMPLETELY FULL. IN ANY CASE WE NEED NOT WRITE AN*/
-/*EMPTY PAGE TO DISK. */
-/*---------------------------------------------------------------------------*/
- jam();
- releaseLogpage(signal);
- } else {
- jam();
- writeSinglePage(signal, logFilePtr.p->currentFilepage,
- wordWritten, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::ACTIVE_WRITE_LOG;
- }//if
- }//if
- }//if
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- }//if
- logPartPtr.p->logTimer++;
- return;
-}//Dblqh::timeSup()
-
-void Dblqh::writeLogfileLab(Signal* signal)
-{
-/*---------------------------------------------------------------------------*/
-/* CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED DUE TO THIS COMPLETED DISK */
-/* WRITE. */
-/*---------------------------------------------------------------------------*/
- switch (logFilePtr.p->fileChangeState) {
- case LogFileRecord::NOT_ONGOING:
- jam();
- checkGcpCompleted(signal,
- ((lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1),
- lfoPtr.p->lfoWordWritten);
- break;
-#if 0
- case LogFileRecord::BOTH_WRITES_ONGOING:
- jam();
- ndbout_c("not crashing!!");
- // Fall-through
-#endif
- case LogFileRecord::WRITE_PAGE_ZERO_ONGOING:
- case LogFileRecord::LAST_WRITE_ONGOING:
- jam();
- logFilePtr.p->lastPageWritten = (lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1;
- logFilePtr.p->lastWordWritten = lfoPtr.p->lfoWordWritten;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- releaseLfoPages(signal);
- releaseLfo(signal);
- return;
-}//Dblqh::writeLogfileLab()
-
-void Dblqh::closeWriteLogLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- return;
-}//Dblqh::closeWriteLogLab()
-
-/* ######################################################################### */
-/* FILE CHANGE MODULE */
-/* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
-/* */
-/*THIS PART OF THE FILE MODULE HANDLES WHEN WE ARE CHANGING LOG FILE DURING */
-/*NORMAL OPERATION. WE HAVE TO BE CAREFUL WHEN WE ARE CHANGING LOG FILE SO */
-/*THAT WE DO NOT COMPLICATE THE SYSTEM RESTART PROCESS TOO MUCH. */
-/*THE IDEA IS THAT WE START BY WRITING THE LAST WRITE IN THE OLD FILE AND WE */
-/*ALSO WRITE THE FIRST PAGE OF THE NEW FILE CONCURRENT WITH THAT. THIS FIRST */
-/*PAGE IN THE NEW FILE DO NOT CONTAIN ANY LOG RECORDS OTHER THAN A DESCRIPTOR*/
-/*CONTAINING INFORMATION ABOUT GCI'S NEEDED AT SYSTEM RESTART AND A NEXT LOG */
-/*RECORD. */
-/* */
-/*WHEN BOTH OF THOSE WRITES HAVE COMPLETED WE ALSO WRITE PAGE ZERO IN FILE */
-/*ZERO. THE ONLY INFORMATION WHICH IS INTERESTING HERE IS THE NEW FILE NUMBER*/
-/* */
-/*IF OPTIMISATIONS ARE NEEDED OF THE LOG HANDLING THEN IT IS POSSIBLE TO */
-/*AVOID WRITING THE FIRST PAGE OF THE NEW PAGE IMMEDIATELY. THIS COMPLICATES */
-/*THE SYSTEM RESTART AND ONE HAS TO TAKE SPECIAL CARE WITH FILE ZERO. IT IS */
-/*HOWEVER NO LARGE PROBLEM TO CHANGE INTO THIS SCENARIO. TO AVOID ALSO THE */
-/*WRITING OF PAGE ZERO IS ALSO POSSIBLE BUT COMPLICATES THE DESIGN EVEN */
-/*FURTHER. IT GETS FAIRLY COMPLEX TO FIND THE END OF THE LOG. SOME SORT OF */
-/*BINARY SEARCH IS HOWEVER MOST LIKELY A GOOD METHODOLOGY FOR THIS. */
-/* ######################################################################### */
-void Dblqh::firstPageWriteLab(Signal* signal)
-{
- releaseLfo(signal);
-/*---------------------------------------------------------------------------*/
-/* RELEASE PAGE ZERO IF THE FILE IS NOT FILE 0. */
-/*---------------------------------------------------------------------------*/
- Uint32 fileNo = logFilePtr.p->fileNo;
- if (fileNo != 0) {
- jam();
- releaseLogpage(signal);
- }//if
-/*---------------------------------------------------------------------------*/
-/* IF A NEW FILE HAS BEEN OPENED WE SHALL ALWAYS ALSO WRITE TO PAGE O IN */
-/* FILE 0. THE AIM IS TO MAKE RESTARTS EASIER BY SPECIFYING WHICH IS THE */
-/* LAST FILE WHERE LOGGING HAS STARTED. */
-/*---------------------------------------------------------------------------*/
-/* FIRST CHECK WHETHER THE LAST WRITE IN THE PREVIOUS FILE HAVE COMPLETED */
-/*---------------------------------------------------------------------------*/
- if (logFilePtr.p->fileChangeState == LogFileRecord::BOTH_WRITES_ONGOING) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE LAST WRITE WAS STILL ONGOING. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::LAST_WRITE_ONGOING;
- return;
- } else {
- jam();
- ndbrequire(logFilePtr.p->fileChangeState == LogFileRecord::FIRST_WRITE_ONGOING);
-/*---------------------------------------------------------------------------*/
-/* WRITE TO PAGE 0 IN IN FILE 0 NOW. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::WRITE_PAGE_ZERO_ONGOING;
- if (fileNo == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* IF THE NEW FILE WAS 0 THEN WE HAVE ALREADY WRITTEN PAGE ZERO IN FILE 0. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- return;
- } else {
- jam();
-/*---------------------------------------------------------------------------*/
-/* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE */
-/* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS */
-/* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE. */
-/* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE */
-/* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE */
-/* LOG PART. */
-/*---------------------------------------------------------------------------*/
- Uint32 currLogFile = logFilePtr.i;
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->logFileRec = currLogFile;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
- return;
- }//if
- }//if
-}//Dblqh::firstPageWriteLab()
-
-void Dblqh::lastWriteInFileLab(Signal* signal)
-{
- LogFileRecordPtr locLogFilePtr;
-/*---------------------------------------------------------------------------*/
-/* CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED DUE TO THIS COMPLETED DISK */
-/* WRITE. */
-/*---------------------------------------------------------------------------*/
- checkGcpCompleted(signal,
- ((lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1),
- (ZPAGE_SIZE - 1));
- releaseLfoPages(signal);
- releaseLfo(signal);
-/*---------------------------------------------------------------------------*/
-/* IF THE FILE IS NOT IN USE OR THE NEXT FILE TO BE USED WE WILL CLOSE IT. */
-/*---------------------------------------------------------------------------*/
- locLogFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.i != locLogFilePtr.i) {
- if (logFilePtr.i != locLogFilePtr.p->nextLogFile) {
- if (logFilePtr.p->fileNo != 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE FILE IS NOT FILE ZERO EITHER. WE WILL NOT CLOSE FILE ZERO SINCE WE */
-/* USE IT TO KEEP TRACK OF THE CURRENT LOG FILE BY WRITING PAGE ZERO IN */
-/* FILE ZERO. */
-/*---------------------------------------------------------------------------*/
-/* WE WILL CLOSE THE FILE. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_WRITE_LOG;
- closeFile(signal, logFilePtr, __LINE__);
- }//if
- }//if
- }//if
-/*---------------------------------------------------------------------------*/
-/* IF A NEW FILE HAS BEEN OPENED WE SHALL ALWAYS ALSO WRITE TO PAGE O IN */
-/* FILE 0. THE AIM IS TO MAKE RESTARTS EASIER BY SPECIFYING WHICH IS THE */
-/* LAST FILE WHERE LOGGING HAS STARTED. */
-/*---------------------------------------------------------------------------*/
-/* FIRST CHECK WHETHER THE FIRST WRITE IN THE NEW FILE HAVE COMPLETED */
-/* THIS STATE INFORMATION IS IN THE NEW LOG FILE AND THUS WE HAVE TO MOVE */
-/* THE LOG FILE POINTER TO THIS LOG FILE. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->fileChangeState == LogFileRecord::BOTH_WRITES_ONGOING) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE FIRST WRITE WAS STILL ONGOING. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::FIRST_WRITE_ONGOING;
- return;
- } else {
- ndbrequire(logFilePtr.p->fileChangeState == LogFileRecord::LAST_WRITE_ONGOING);
-/*---------------------------------------------------------------------------*/
-/* WRITE TO PAGE 0 IN IN FILE 0 NOW. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::WRITE_PAGE_ZERO_ONGOING;
- Uint32 fileNo = logFilePtr.p->fileNo;
- if (fileNo == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* IF THE NEW FILE WAS 0 THEN WE HAVE ALREADY WRITTEN PAGE ZERO IN FILE 0. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- return;
- } else {
- jam();
-/*---------------------------------------------------------------------------*/
-/* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE */
-/* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS */
-/* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE. */
-/* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE */
-/* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE */
-/* LOG PART. */
-/*---------------------------------------------------------------------------*/
- Uint32 currLogFile = logFilePtr.i;
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->logFileRec = currLogFile;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
- return;
- }//if
- }//if
-}//Dblqh::lastWriteInFileLab()
-
-void Dblqh::writePageZeroLab(Signal* signal)
-{
- if (logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM)
- {
- if (logPartPtr.p->firstLogQueue == RNIL)
- {
- jam();
- logPartPtr.p->logPartState = LogPartRecord::IDLE;
- }
- else
- {
- jam();
- logPartPtr.p->logPartState = LogPartRecord::ACTIVE;
- }
- }
-
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
-/*---------------------------------------------------------------------------*/
-/* IT COULD HAVE ARRIVED PAGE WRITES TO THE CURRENT FILE WHILE WE WERE */
-/* WAITING FOR THIS DISK WRITE TO COMPLETE. THEY COULD NOT CHECK FOR */
-/* COMPLETED GLOBAL CHECKPOINTS. THUS WE SHOULD DO THAT NOW INSTEAD. */
-/*---------------------------------------------------------------------------*/
- checkGcpCompleted(signal,
- logFilePtr.p->lastPageWritten,
- logFilePtr.p->lastWordWritten);
- releaseLfo(signal);
- return;
-}//Dblqh::writePageZeroLab()
-
-/* ######################################################################### */
-/* INITIAL START MODULE */
-/* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
-/* */
-/*THIS MODULE INITIALISES ALL THE LOG FILES THAT ARE NEEDED AT A SYSTEM */
-/*RESTART AND WHICH ARE USED DURING NORMAL OPERATIONS. IT CREATES THE FILES */
-/*AND SETS A PROPER SIZE OF THEM AND INITIALISES THE FIRST PAGE IN EACH FILE */
-/* ######################################################################### */
-void Dblqh::openFileInitLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_INIT;
- seizeLogpage(signal);
- writeSinglePage(signal, (clogFileSize * ZPAGES_IN_MBYTE) - 1,
- ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::INIT_WRITE_AT_END;
- return;
-}//Dblqh::openFileInitLab()
-
-void Dblqh::initWriteEndLab(Signal* signal)
-{
- releaseLfo(signal);
- initLogpage(signal);
- if (logFilePtr.p->fileNo == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* PAGE ZERO IN FILE ZERO MUST SET LOG LAP TO ONE SINCE IT HAS STARTED */
-/* WRITING TO THE LOG, ALSO GLOBAL CHECKPOINTS ARE SET TO ZERO. */
-/*---------------------------------------------------------------------------*/
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = 0;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] = 0;
- logFilePtr.p->logMaxGciStarted[0] = 0;
- logFilePtr.p->logMaxGciCompleted[0] = 0;
- }//if
-/*---------------------------------------------------------------------------*/
-/* REUSE CODE FOR INITIALISATION OF FIRST PAGE IN ALL LOG FILES. */
-/*---------------------------------------------------------------------------*/
- writeFileHeaderOpen(signal, ZINIT);
- return;
-}//Dblqh::initWriteEndLab()
-
-void Dblqh::initFirstPageLab(Signal* signal)
-{
- releaseLfo(signal);
- if (logFilePtr.p->fileNo == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* IN FILE ZERO WE WILL INSERT A PAGE ONE WHERE WE WILL INSERT A COMPLETED */
-/* GCI RECORD FOR GCI = 0. */
-/*---------------------------------------------------------------------------*/
- initLogpage(signal);
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE] = ZCOMPLETED_GCI_TYPE;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + 1] = 1;
- writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_GCI_ZERO;
- return;
- }//if
- logFilePtr.p->currentMbyte = 1;
- writeInitMbyte(signal);
- return;
-}//Dblqh::initFirstPageLab()
-
-void Dblqh::writeGciZeroLab(Signal* signal)
-{
- releaseLfo(signal);
- logFilePtr.p->currentMbyte = 1;
- writeInitMbyte(signal);
- return;
-}//Dblqh::writeGciZeroLab()
-
-void Dblqh::writeInitMbyteLab(Signal* signal)
-{
- releaseLfo(signal);
- logFilePtr.p->currentMbyte = logFilePtr.p->currentMbyte + 1;
- if (logFilePtr.p->currentMbyte == clogFileSize) {
- jam();
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_INIT;
- closeFile(signal, logFilePtr, __LINE__);
- return;
- }//if
- writeInitMbyte(signal);
- return;
-}//Dblqh::writeInitMbyteLab()
-
-void Dblqh::closingInitLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- if (logFilePtr.p->nextLogFile == logPartPtr.p->firstLogfile) {
- jam();
- checkInitCompletedLab(signal);
- return;
- } else {
- jam();
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- openLogfileInit(signal);
- }//if
- return;
-}//Dblqh::closingInitLab()
-
-void Dblqh::checkInitCompletedLab(Signal* signal)
-{
- logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
-/*---------------------------------------------------------------------------*/
-/* WE HAVE NOW INITIALISED ALL FILES IN THIS LOG PART. WE CAN NOW SET THE */
-/* THE LOG LAP TO ONE SINCE WE WILL START WITH LOG LAP ONE. LOG LAP = ZERO */
-/* MEANS THIS PART OF THE LOG IS NOT WRITTEN YET. */
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->logLap = 1;
- logPartPtr.i = 0;
-CHECK_LOG_PARTS_LOOP:
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS PART HAS STILL NOT COMPLETED. WAIT FOR THIS TO OCCUR. */
-/*---------------------------------------------------------------------------*/
- return;
- }//if
- if (logPartPtr.i == 3) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* ALL LOG PARTS ARE COMPLETED. NOW WE CAN CONTINUE WITH THE RESTART */
-/* PROCESSING. THE NEXT STEP IS TO PREPARE FOR EXECUTING OPERATIONS. THUS WE */
-/* NEED TO INITIALISE ALL NEEDED DATA AND TO OPEN FILE ZERO AND THE NEXT AND */
-/* TO SET THE CURRENT LOG PAGE TO BE PAGE 1 IN FILE ZERO. */
-/*---------------------------------------------------------------------------*/
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- signal->theData[0] = ZINIT_FOURTH;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//for
- return;
- } else {
- jam();
- logPartPtr.i = logPartPtr.i + 1;
- goto CHECK_LOG_PARTS_LOOP;
- }//if
-}//Dblqh::checkInitCompletedLab()
-
-/* ========================================================================= */
-/* ======= INITIATE LOG FILE OPERATION RECORD WHEN ALLOCATED ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initLfo(Signal* signal)
-{
- lfoPtr.p->firstLfoPage = RNIL;
- lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
- lfoPtr.p->logFileRec = logFilePtr.i;
- lfoPtr.p->noPagesRw = 0;
- lfoPtr.p->lfoPageNo = ZNIL;
-}//Dblqh::initLfo()
-
-/* ========================================================================= */
-/* ======= INITIATE LOG FILE WHEN ALLOCATED ======= */
-/* */
-/* INPUT: TFILE_NO NUMBER OF THE FILE INITIATED */
-/* LOG_PART_PTR NUMBER OF LOG PART */
-/* SUBROUTINE SHORT NAME = IL */
-/* ========================================================================= */
-void Dblqh::initLogfile(Signal* signal, Uint32 fileNo)
-{
- UintR tilTmp;
- UintR tilIndex;
-
- logFilePtr.p->currentFilepage = 0;
- logFilePtr.p->currentLogpage = RNIL;
- logFilePtr.p->fileName[0] = (UintR)-1;
- logFilePtr.p->fileName[1] = (UintR)-1; /* = H'FFFFFFFF = -1 */
- logFilePtr.p->fileName[2] = fileNo; /* Sfile_no */
- tilTmp = 1; /* VERSION 1 OF FILE NAME */
- tilTmp = (tilTmp << 8) + 1; /* FRAGMENT LOG => .FRAGLOG AS EXTENSION */
- tilTmp = (tilTmp << 8) + (8 + logPartPtr.i); /* DIRECTORY = D(8+Part)/DBLQH */
- tilTmp = (tilTmp << 8) + 255; /* IGNORE Pxx PART OF FILE NAME */
- logFilePtr.p->fileName[3] = tilTmp;
-/* ========================================================================= */
-/* FILE NAME BECOMES /D2/DBLQH/Tpart_no/Sfile_no.FRAGLOG */
-/* ========================================================================= */
- logFilePtr.p->fileNo = fileNo;
- logFilePtr.p->filePosition = 0;
- logFilePtr.p->firstLfo = RNIL;
- logFilePtr.p->lastLfo = RNIL;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logFilePtr.p->logPartRec = logPartPtr.i;
- logFilePtr.p->noLogpagesInBuffer = 0;
- logFilePtr.p->firstFilledPage = RNIL;
- logFilePtr.p->lastFilledPage = RNIL;
- logFilePtr.p->lastPageWritten = 0;
- logFilePtr.p->logPageZero = RNIL;
- logFilePtr.p->currentMbyte = 0;
- for (tilIndex = 0; tilIndex < clogFileSize; tilIndex++) {
- logFilePtr.p->logMaxGciCompleted[tilIndex] = (UintR)-1;
- logFilePtr.p->logMaxGciStarted[tilIndex] = (UintR)-1;
- logFilePtr.p->logLastPrepRef[tilIndex] = 0;
- }//for
-}//Dblqh::initLogfile()
-
-/* ========================================================================= */
-/* ======= INITIATE LOG PAGE WHEN ALLOCATED ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initLogpage(Signal* signal)
-{
- TcConnectionrecPtr ilpTcConnectptr;
-
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = logPartPtr.p->logLap;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] =
- logPartPtr.p->logPartNewestCompletedGCI;
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = cnewestGci;
- logPagePtr.p->logPageWord[ZPOS_VERSION] = NDB_VERSION;
- logPagePtr.p->logPageWord[ZPOS_NO_LOG_FILES] = logPartPtr.p->noLogFiles;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- ilpTcConnectptr.i = logPartPtr.p->firstLogTcrec;
- if (ilpTcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(ilpTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] =
- (ilpTcConnectptr.p->logStartFileNo << 16) +
- (ilpTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE);
- } else {
- jam();
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] =
- (logFilePtr.p->fileNo << 16) +
- (logFilePtr.p->currentFilepage >> ZTWOLOG_NO_PAGES_IN_MBYTE);
- }//if
-}//Dblqh::initLogpage()
-
-/* ------------------------------------------------------------------------- */
-/* ------- OPEN LOG FILE FOR READ AND WRITE ------- */
-/* */
-/* SUBROUTINE SHORT NAME = OFR */
-/* ------------------------------------------------------------------------- */
-void Dblqh::openFileRw(Signal* signal, LogFileRecordPtr olfLogFilePtr)
-{
- FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
- signal->theData[0] = cownref;
- signal->theData[1] = olfLogFilePtr.i;
- signal->theData[2] = olfLogFilePtr.p->fileName[0];
- signal->theData[3] = olfLogFilePtr.p->fileName[1];
- signal->theData[4] = olfLogFilePtr.p->fileName[2];
- signal->theData[5] = olfLogFilePtr.p->fileName[3];
- signal->theData[6] = FsOpenReq::OM_READWRITE | FsOpenReq::OM_AUTOSYNC | FsOpenReq::OM_CHECK_SIZE;
- if (c_o_direct)
- signal->theData[6] |= FsOpenReq::OM_DIRECT;
- req->auto_sync_size = MAX_REDO_PAGES_WITHOUT_SYNCH * sizeof(LogPageRecord);
- Uint64 sz = clogFileSize;
- sz *= 1024; sz *= 1024;
- req->file_size_hi = sz >> 32;
- req->file_size_lo = sz & 0xFFFFFFFF;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}//Dblqh::openFileRw()
-
-/* ------------------------------------------------------------------------- */
-/* ------- OPEN LOG FILE DURING INITIAL START ------- */
-/* */
-/* SUBROUTINE SHORT NAME = OLI */
-/* ------------------------------------------------------------------------- */
-void Dblqh::openLogfileInit(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::OPENING_INIT;
- FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
- signal->theData[0] = cownref;
- signal->theData[1] = logFilePtr.i;
- signal->theData[2] = logFilePtr.p->fileName[0];
- signal->theData[3] = logFilePtr.p->fileName[1];
- signal->theData[4] = logFilePtr.p->fileName[2];
- signal->theData[5] = logFilePtr.p->fileName[3];
- signal->theData[6] = FsOpenReq::OM_READWRITE | FsOpenReq::OM_TRUNCATE | FsOpenReq::OM_CREATE | FsOpenReq::OM_AUTOSYNC;
- if (c_o_direct)
- signal->theData[6] |= FsOpenReq::OM_DIRECT;
- req->auto_sync_size = MAX_REDO_PAGES_WITHOUT_SYNCH * sizeof(LogPageRecord);
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}//Dblqh::openLogfileInit()
-
-/* OPEN FOR READ/WRITE, DO CREATE AND DO TRUNCATE FILE */
-/* ------------------------------------------------------------------------- */
-/* ------- OPEN NEXT LOG FILE ------- */
-/* */
-/* SUBROUTINE SHORT NAME = ONL */
-/* ------------------------------------------------------------------------- */
-void Dblqh::openNextLogfile(Signal* signal)
-{
- LogFileRecordPtr onlLogFilePtr;
-
- if (logPartPtr.p->noLogFiles > 2) {
- jam();
-/* -------------------------------------------------- */
-/* IF ONLY 1 OR 2 LOG FILES EXIST THEN THEY ARE */
-/* ALWAYS OPEN AND THUS IT IS NOT NECESSARY TO */
-/* OPEN THEM NOW. */
-/* -------------------------------------------------- */
- onlLogFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(onlLogFilePtr, clogFileFileSize, logFileRecord);
- if (onlLogFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
- ndbrequire(onlLogFilePtr.p->fileNo == 0);
- return;
- }//if
- onlLogFilePtr.p->logFileStatus = LogFileRecord::OPENING_WRITE_LOG;
- FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
- signal->theData[0] = cownref;
- signal->theData[1] = onlLogFilePtr.i;
- signal->theData[2] = onlLogFilePtr.p->fileName[0];
- signal->theData[3] = onlLogFilePtr.p->fileName[1];
- signal->theData[4] = onlLogFilePtr.p->fileName[2];
- signal->theData[5] = onlLogFilePtr.p->fileName[3];
- signal->theData[6] = FsOpenReq::OM_READWRITE | FsOpenReq::OM_AUTOSYNC | FsOpenReq::OM_CHECK_SIZE;
- if (c_o_direct)
- signal->theData[6] |= FsOpenReq::OM_DIRECT;
- req->auto_sync_size = MAX_REDO_PAGES_WITHOUT_SYNCH * sizeof(LogPageRecord);
- Uint64 sz = clogFileSize;
- sz *= 1024; sz *= 1024;
- req->file_size_hi = sz >> 32;
- req->file_size_lo = sz & 0xFFFFFFFF;
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
- }//if
-}//Dblqh::openNextLogfile()
-
- /* OPEN FOR READ/WRITE, DON'T CREATE AND DON'T TRUNCATE FILE */
-/* ------------------------------------------------------------------------- */
-/* ------- RELEASE LFO RECORD ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::releaseLfo(Signal* signal)
-{
-#ifdef VM_TRACE
- // Check that lfo record isn't already in free list
- LogFileOperationRecordPtr TlfoPtr;
- TlfoPtr.i = cfirstfreeLfo;
- while (TlfoPtr.i != RNIL){
- ptrCheckGuard(TlfoPtr, clfoFileSize, logFileOperationRecord);
- ndbrequire(TlfoPtr.i != lfoPtr.i);
- TlfoPtr.i = TlfoPtr.p->nextLfo;
- }
-#endif
- lfoPtr.p->nextLfo = cfirstfreeLfo;
- lfoPtr.p->lfoTimer = 0;
- cfirstfreeLfo = lfoPtr.i;
- lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
-}//Dblqh::releaseLfo()
-
-/* ------------------------------------------------------------------------- */
-/* ------- RELEASE ALL LOG PAGES CONNECTED TO A LFO RECORD ------- */
-/* */
-/* SUBROUTINE SHORT NAME = RLP */
-/* ------------------------------------------------------------------------- */
-void Dblqh::releaseLfoPages(Signal* signal)
-{
- LogPageRecordPtr rlpLogPagePtr;
-
- logPagePtr.i = lfoPtr.p->firstLfoPage;
-RLP_LOOP:
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- rlpLogPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- releaseLogpage(signal);
- if (rlpLogPagePtr.i != RNIL) {
- jam();
- logPagePtr.i = rlpLogPagePtr.i;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- goto RLP_LOOP;
- }//if
- lfoPtr.p->firstLfoPage = RNIL;
-}//Dblqh::releaseLfoPages()
-
-/* ------------------------------------------------------------------------- */
-/* ------- RELEASE LOG PAGE ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::releaseLogpage(Signal* signal)
-{
-#ifdef VM_TRACE
- // Check that log page isn't already in free list
- ndbrequire(logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] == 0);
-#endif
-
- cnoOfLogPages++;
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = cfirstfreeLogPage;
- logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
- logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
- cfirstfreeLogPage = logPagePtr.i;
-}//Dblqh::releaseLogpage()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEIZE LFO RECORD ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::seizeLfo(Signal* signal)
-{
- lfoPtr.i = cfirstfreeLfo;
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- cfirstfreeLfo = lfoPtr.p->nextLfo;
- lfoPtr.p->nextLfo = RNIL;
- lfoPtr.p->lfoTimer = cLqhTimeOutCount;
-}//Dblqh::seizeLfo()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEIZE LOG FILE RECORD ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::seizeLogfile(Signal* signal)
-{
- logFilePtr.i = cfirstfreeLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
-/* ------------------------------------------------------------------------- */
-/*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_FILE_PTR = RNIL */
-/* ------------------------------------------------------------------------- */
- cfirstfreeLogFile = logFilePtr.p->nextLogFile;
- logFilePtr.p->nextLogFile = RNIL;
-}//Dblqh::seizeLogfile()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEIZE LOG PAGE RECORD ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::seizeLogpage(Signal* signal)
-{
- cnoOfLogPages--;
- logPagePtr.i = cfirstfreeLogPage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
-/* ------------------------------------------------------------------------- */
-/*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_PAGE_PTR = RNIL */
-/* ------------------------------------------------------------------------- */
- cfirstfreeLogPage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
- logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] = 0;
-}//Dblqh::seizeLogpage()
-
-/* ------------------------------------------------------------------------- */
-/* ------- WRITE FILE DESCRIPTOR INFORMATION ------- */
-/* */
-/* SUBROUTINE SHORT NAME: WFD */
-// Pointer handling:
-// logFilePtr in
-// logPartPtr in
-/* ------------------------------------------------------------------------- */
-void Dblqh::writeFileDescriptor(Signal* signal)
-{
- TcConnectionrecPtr wfdTcConnectptr;
- UintR twfdFileNo;
- UintR twfdMbyte;
-
-/* -------------------------------------------------- */
-/* START BY WRITING TO LOG FILE RECORD */
-/* -------------------------------------------------- */
- arrGuard(logFilePtr.p->currentMbyte, clogFileSize);
- logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] =
- logPartPtr.p->logPartNewestCompletedGCI;
- logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] = cnewestGci;
- wfdTcConnectptr.i = logPartPtr.p->firstLogTcrec;
- if (wfdTcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(wfdTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- twfdFileNo = wfdTcConnectptr.p->logStartFileNo;
- twfdMbyte = wfdTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- (twfdFileNo << 16) + twfdMbyte;
- } else {
- jam();
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- (logFilePtr.p->fileNo << 16) + logFilePtr.p->currentMbyte;
- }//if
-}//Dblqh::writeFileDescriptor()
-
-/* ------------------------------------------------------------------------- */
-/* ------- WRITE THE HEADER PAGE OF A NEW FILE ------- */
-/* */
-/* SUBROUTINE SHORT NAME: WMO */
-/* ------------------------------------------------------------------------- */
-void Dblqh::writeFileHeaderOpen(Signal* signal, Uint32 wmoType)
-{
- UintR twmoNoLogDescriptors;
-
-/* -------------------------------------------------- */
-/* WRITE HEADER INFORMATION IN THE NEW FILE. */
-/* -------------------------------------------------- */
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_LOG_TYPE] = ZFD_TYPE;
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] =
- logFilePtr.p->fileNo;
- if (logPartPtr.p->noLogFiles > cmaxLogFilesInPageZero) {
- jam();
- twmoNoLogDescriptors = cmaxLogFilesInPageZero;
- } else {
- jam();
- twmoNoLogDescriptors = logPartPtr.p->noLogFiles;
- }//if
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD] =
- twmoNoLogDescriptors;
-
- {
- Uint32 pos = ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE;
- LogFileRecordPtr filePtr = logFilePtr;
- for (Uint32 fd = 0; fd < twmoNoLogDescriptors; fd++)
- {
- jam();
- ptrCheckGuard(filePtr, clogFileFileSize, logFileRecord);
- for (Uint32 mb = 0; mb < clogFileSize; mb ++)
- {
- jam();
- Uint32 pos0 = pos + fd * (ZFD_MBYTE_SIZE * clogFileSize) + mb;
- Uint32 pos1 = pos0 + clogFileSize;
- Uint32 pos2 = pos1 + clogFileSize;
- arrGuard(pos0, ZPAGE_SIZE);
- arrGuard(pos1, ZPAGE_SIZE);
- arrGuard(pos2, ZPAGE_SIZE);
- logPagePtr.p->logPageWord[pos0] = filePtr.p->logMaxGciCompleted[mb];
- logPagePtr.p->logPageWord[pos1] = filePtr.p->logMaxGciStarted[mb];
- logPagePtr.p->logPageWord[pos2] = filePtr.p->logLastPrepRef[mb];
- }
- filePtr.i = filePtr.p->prevLogFile;
- }
- pos += (twmoNoLogDescriptors * ZFD_MBYTE_SIZE * clogFileSize);
- arrGuard(pos, ZPAGE_SIZE);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = pos;
- logPagePtr.p->logPageWord[pos] = ZNEXT_LOG_RECORD_TYPE;
- }
-
-/* ------------------------------------------------------- */
-/* THIS IS A SPECIAL WRITE OF THE FIRST PAGE IN THE */
-/* LOG FILE. THIS HAS SPECIAL SIGNIFANCE TO FIND */
-/* THE END OF THE LOG AT SYSTEM RESTART. */
-/* ------------------------------------------------------- */
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
- if (wmoType == ZINIT) {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::INIT_FIRST_PAGE;
- } else {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE;
- }//if
- logFilePtr.p->filePosition = 1;
- if (wmoType == ZNORMAL) {
- jam();
-/* -------------------------------------------------- */
-/* ALLOCATE A NEW PAGE SINCE THE CURRENT IS */
-/* WRITTEN. */
-/* -------------------------------------------------- */
- seizeLogpage(signal);
- initLogpage(signal);
- logFilePtr.p->currentLogpage = logPagePtr.i;
- logFilePtr.p->currentFilepage = logFilePtr.p->currentFilepage + 1;
- }//if
-}//Dblqh::writeFileHeaderOpen()
-
-/* -------------------------------------------------- */
-/* THE NEW FILE POSITION WILL ALWAYS BE 1 SINCE */
-/* WE JUST WROTE THE FIRST PAGE IN THE LOG FILE */
-/* -------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------- WRITE A MBYTE HEADER DURING INITIAL START ------- */
-/* */
-/* SUBROUTINE SHORT NAME: WIM */
-/* ------------------------------------------------------------------------- */
-void Dblqh::writeInitMbyte(Signal* signal)
-{
- initLogpage(signal);
- writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE,
- ZPAGE_SIZE - 1, __LINE__);
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_INIT_MBYTE;
-}//Dblqh::writeInitMbyte()
-
-/* ------------------------------------------------------------------------- */
-/* ------- WRITE A SINGLE PAGE INTO A FILE ------- */
-/* */
-/* INPUT: TWSP_PAGE_NO THE PAGE NUMBER WRITTEN */
-/* SUBROUTINE SHORT NAME: WSP */
-/* ------------------------------------------------------------------------- */
-void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo,
- Uint32 wordWritten, Uint32 place)
-{
- seizeLfo(signal);
- initLfo(signal);
- lfoPtr.p->firstLfoPage = logPagePtr.i;
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
-
- writeDbgInfoPageHeader(logPagePtr, place, pageNo, wordWritten);
- // Calculate checksum for page
- logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
-
- lfoPtr.p->lfoPageNo = pageNo;
- lfoPtr.p->lfoWordWritten = wordWritten;
- lfoPtr.p->noPagesRw = 1;
-/* -------------------------------------------------- */
-/* SET TIMER ON THIS LOG PART TO SIGNIFY THAT A */
-/* LOG RECORD HAS BEEN SENT AT THIS TIME. */
-/* -------------------------------------------------- */
- logPartPtr.p->logPartTimer = logPartPtr.p->logTimer;
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = 1; /* ONE PAGE WRITTEN */
- signal->theData[6] = logPagePtr.i;
- signal->theData[7] = pageNo;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("writeSingle 1 page at part: %u file: %u pos: %u",
- logPartPtr.i,
- logFilePtr.p->fileNo,
- pageNo);
-}//Dblqh::writeSinglePage()
-
-/* ##########################################################################
- * SYSTEM RESTART PHASE ONE MODULE
- * THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
- *
- * THIS MODULE CONTAINS THE CODE FOR THE FIRST PHASE OF THE SYSTEM RESTART.
- * THE AIM OF THIS PHASE IS TO FIND THE END OF THE LOG AND TO FIND
- * INFORMATION ABOUT WHERE GLOBAL CHECKPOINTS ARE COMPLETED AND STARTED
- * IN THE LOG. THIS INFORMATION IS NEEDED TO START PHASE THREE OF
- * THE SYSTEM RESTART.
- * ########################################################################## */
-/* --------------------------------------------------------------------------
- * A SYSTEM RESTART OR NODE RESTART IS ONGOING. WE HAVE NOW OPENED FILE 0
- * NOW WE NEED TO READ PAGE 0 TO FIND WHICH LOG FILE THAT WAS OPEN AT
- * CRASH TIME.
- * -------------------------------------------------------------------------- */
-void Dblqh::openSrFrontpageLab(Signal* signal)
-{
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FRONTPAGE;
- return;
-}//Dblqh::openSrFrontpageLab()
-
-/* -------------------------------------------------------------------------
- * WE HAVE NOW READ PAGE 0 IN FILE 0. CHECK THE LAST OPEN FILE. ACTUALLY THE
- * LAST OPEN FILE COULD BE THE NEXT AFTER THAT. CHECK THAT FIRST. WHEN THE
- * LAST WAS FOUND WE CAN FIND ALL THE NEEDED INFORMATION WHERE TO START AND
- * STOP READING THE LOG.
- * -------------------------------------------------------------------------- */
-void Dblqh::readSrFrontpageLab(Signal* signal)
-{
- Uint32 fileNo = logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO];
- if (fileNo == 0) {
- jam();
- /* ----------------------------------------------------------------------
- * FILE 0 WAS ALSO LAST FILE SO WE DO NOT NEED TO READ IT AGAIN.
- * ---------------------------------------------------------------------- */
- readSrLastFileLab(signal);
- return;
- }//if
- /* ------------------------------------------------------------------------
- * CLOSE FILE 0 SO THAT WE HAVE CLOSED ALL FILES WHEN STARTING TO READ
- * THE FRAGMENT LOG. ALSO RELEASE PAGE ZERO.
- * ------------------------------------------------------------------------ */
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr, __LINE__);
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_LAST_FILE;
- openFileRw(signal, locLogFilePtr);
- return;
-}//Dblqh::readSrFrontpageLab()
-
-void Dblqh::openSrLastFileLab(Signal* signal)
-{
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_FILE;
- return;
-}//Dblqh::openSrLastFileLab()
-
-void Dblqh::readSrLastFileLab(Signal* signal)
-{
- logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
- if (DEBUG_REDO)
- ndbout_c("readSrLastFileLab part: %u logExecState: %u logPartState: %u logLap: %u",
- logPartPtr.i,
- logPartPtr.p->logExecState,
- logPartPtr.p->logPartState,
- logPartPtr.p->logLap);
- if (logPartPtr.p->noLogFiles > cmaxLogFilesInPageZero) {
- jam();
- initGciInLogFileRec(signal, cmaxLogFilesInPageZero);
- } else {
- jam();
- initGciInLogFileRec(signal, logPartPtr.p->noLogFiles);
- }//if
- releaseLogpage(signal);
- /* ------------------------------------------------------------------------
- * NOW WE HAVE FOUND THE LAST LOG FILE. WE ALSO NEED TO FIND THE LAST
- * MBYTE THAT WAS LAST WRITTEN BEFORE THE SYSTEM CRASH.
- * ------------------------------------------------------------------------ */
- logPartPtr.p->lastLogfile = logFilePtr.i;
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
- logFilePtr.p->currentMbyte = 0;
- return;
-}//Dblqh::readSrLastFileLab()
-
-void Dblqh::readSrLastMbyteLab(Signal* signal)
-{
- if (logPartPtr.p->lastMbyte == ZNIL) {
- if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] < logPartPtr.p->logLap) {
- jam();
- logPartPtr.p->lastMbyte = logFilePtr.p->currentMbyte - 1;
- }//if
- }//if
- arrGuard(logFilePtr.p->currentMbyte, clogFileSize);
- logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED];
- logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED];
- logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] =
- logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF];
- releaseLogpage(signal);
- if (logFilePtr.p->currentMbyte < (clogFileSize - 1)) {
- jam();
- logFilePtr.p->currentMbyte++;
- readSinglePage(signal, ZPAGES_IN_MBYTE * logFilePtr.p->currentMbyte);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
- return;
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THE LOG WAS IN THE LAST MBYTE WHEN THE CRASH OCCURRED SINCE ALL
- * LOG LAPS ARE EQUAL TO THE CURRENT LOG LAP.
- * ---------------------------------------------------------------------- */
- if (logPartPtr.p->lastMbyte == ZNIL) {
- jam();
- logPartPtr.p->lastMbyte = clogFileSize - 1;
- }//if
- }//if
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr, __LINE__);
- if (logPartPtr.p->noLogFiles > cmaxLogFilesInPageZero) {
- Uint32 fileNo;
- if (logFilePtr.p->fileNo >= cmaxLogFilesInPageZero) {
- jam();
- fileNo = logFilePtr.p->fileNo - cmaxLogFilesInPageZero;
- } else {
- jam();
- fileNo =
- (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) -
- cmaxLogFilesInPageZero;
- }//if
- if (fileNo == 0) {
- jam();
- /* --------------------------------------------------------------------
- * AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE
- * MOMENT.
- * -------------------------------------------------------------------- */
- fileNo = 1;
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->noLogFiles - (cmaxLogFilesInPageZero - 1);
- } else {
- jam();
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->noLogFiles - cmaxLogFilesInPageZero;
- }//if
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
- openFileRw(signal, locLogFilePtr);
- return;
- }//if
- /* ------------------------------------------------------------------------
- * THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES.
- * WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED.
- * NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
- * ------------------------------------------------------------------------ */
- return;
-}//Dblqh::readSrLastMbyteLab()
-
-void Dblqh::openSrNextFileLab(Signal* signal)
-{
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_NEXT_FILE;
- return;
-}//Dblqh::openSrNextFileLab()
-
-void Dblqh::readSrNextFileLab(Signal* signal)
-{
- if (logPartPtr.p->srRemainingFiles > cmaxLogFilesInPageZero) {
- jam();
- initGciInLogFileRec(signal, cmaxLogFilesInPageZero);
- } else {
- jam();
- initGciInLogFileRec(signal, logPartPtr.p->srRemainingFiles);
- }//if
- releaseLogpage(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
- closeFile(signal, logFilePtr, __LINE__);
- if (logPartPtr.p->srRemainingFiles > cmaxLogFilesInPageZero) {
- Uint32 fileNo;
- if (logFilePtr.p->fileNo >= cmaxLogFilesInPageZero) {
- jam();
- fileNo = logFilePtr.p->fileNo - cmaxLogFilesInPageZero;
- } else {
- jam();
- fileNo =
- (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) -
- cmaxLogFilesInPageZero;
- }//if
- if (fileNo == 0) {
- jam();
- /* --------------------------------------------------------------------
- * AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE MOMENT.
- * -------------------------------------------------------------------- */
- fileNo = 1;
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->srRemainingFiles - (cmaxLogFilesInPageZero - 1);
- } else {
- jam();
- logPartPtr.p->srRemainingFiles =
- logPartPtr.p->srRemainingFiles - cmaxLogFilesInPageZero;
- }//if
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
- openFileRw(signal, locLogFilePtr);
- }//if
- /* ------------------------------------------------------------------------
- * THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES.
- * WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED.
- * NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
- * ------------------------------------------------------------------------ */
- return;
-}//Dblqh::readSrNextFileLab()
-
-void Dblqh::closingSrLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = logPartPtr.p->firstLogfile;
- do {
- jam();
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
- jam();
- /* --------------------------------------------------------------------
- * EXIT AND WAIT FOR REMAINING LOG FILES TO COMPLETE THEIR WORK.
- * -------------------------------------------------------------------- */
- return;
- }//if
- logFilePtr.i = logFilePtr.p->nextLogFile;
- } while (logFilePtr.i != logPartPtr.p->firstLogfile);
- /* ------------------------------------------------------------------------
- * ALL FILES IN THIS PART HAVE BEEN CLOSED. THIS INDICATES THAT THE FIRST
- * PHASE OF THE SYSTEM RESTART HAVE BEEN CONCLUDED FOR THIS LOG PART.
- * CHECK IF ALL OTHER LOG PARTS ARE ALSO COMPLETED.
- * ------------------------------------------------------------------------ */
- logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
- jam();
- /* --------------------------------------------------------------------
- * EXIT AND WAIT FOR THE REST OF THE LOG PARTS TO COMPLETE.
- * -------------------------------------------------------------------- */
- return;
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * THE FIRST PHASE HAVE BEEN COMPLETED.
- * ------------------------------------------------------------------------ */
- signal->theData[0] = ZSR_PHASE3_START;
- signal->theData[1] = ZSR_PHASE1_COMPLETED;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::closingSrLab()
-
-/* ##########################################################################
- * ####### SYSTEM RESTART PHASE TWO MODULE #######
- *
- * THIS MODULE HANDLES THE SYSTEM RESTART WHERE LQH CONTROLS TUP AND ACC TO
- * ENSURE THAT THEY HAVE KNOWLEDGE OF ALL FRAGMENTS AND HAVE DONE THE NEEDED
- * READING OF DATA FROM FILE AND EXECUTION OF LOCAL LOGS. THIS PROCESS
- * EXECUTES CONCURRENTLY WITH PHASE ONE OF THE SYSTEM RESTART. THIS PHASE
- * FINDS THE INFORMATION ABOUT THE FRAGMENT LOG NEEDED TO EXECUTE THE FRAGMENT
- * LOG.
- * WHEN TUP AND ACC HAVE PREPARED ALL FRAGMENTS THEN LQH ORDERS THOSE LQH'S
- * THAT ARE RESPONSIBLE TO EXECUTE THE FRAGMENT LOGS TO DO SO. IT IS POSSIBLE
- * THAT ANOTHER NODE EXECUTES THE LOG FOR A FRAGMENT RESIDING AT THIS NODE.
- * ########################################################################## */
-/* ***************>> */
-/* START_FRAGREQ > */
-/* ***************>> */
-void Dblqh::execSTART_FRAGREQ(Signal* signal)
-{
- const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
- jamEntry();
-
- tabptr.i = startFragReq->tableId;
- Uint32 fragId = startFragReq->fragId;
-
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if (!getFragmentrec(signal, fragId)) {
- startFragRefLab(signal);
- return;
- }//if
- tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
-
- Uint32 lcpNo = startFragReq->lcpNo;
- Uint32 noOfLogNodes = startFragReq->noOfLogNodes;
- Uint32 lcpId = startFragReq->lcpId;
-
- ndbrequire(noOfLogNodes <= 4);
- fragptr.p->fragStatus = Fragrecord::CRASH_RECOVERING;
- fragptr.p->srBlockref = startFragReq->userRef;
- fragptr.p->srUserptr = startFragReq->userPtr;
- fragptr.p->srChkpnr = lcpNo;
- if (lcpNo == (MAX_LCP_STORED - 1)) {
- jam();
- fragptr.p->lcpId[lcpNo] = lcpId;
- } else if (lcpNo < (MAX_LCP_STORED - 1)) {
- jam();
- fragptr.p->lcpId[lcpNo] = lcpId;
- } else {
- ndbrequire(lcpNo == ZNIL);
- jam();
- }//if
- fragptr.p->srNoLognodes = noOfLogNodes;
- fragptr.p->logFlag = Fragrecord::STATE_FALSE;
- fragptr.p->srStatus = Fragrecord::SS_IDLE;
-
- if (noOfLogNodes > 0) {
- jam();
- for (Uint32 i = 0; i < noOfLogNodes; i++) {
- jam();
- fragptr.p->srStartGci[i] = startFragReq->startGci[i];
- fragptr.p->srLastGci[i] = startFragReq->lastGci[i];
- fragptr.p->srLqhLognode[i] = startFragReq->lqhLogNode[i];
- }//for
- fragptr.p->newestGci = startFragReq->lastGci[noOfLogNodes - 1];
- } else {
- fragptr.p->newestGci = cnewestGci;
- }//if
-
- if (lcpNo == ZNIL)
- {
- jam();
- /**
- * THERE WAS NO LOCAL CHECKPOINT AVAILABLE FOR THIS FRAGMENT. WE DO
- * NOT NEED TO READ IN THE LOCAL FRAGMENT.
- */
- /**
- * Or this is not "first" fragment in table
- * RESTORE_LCP_REQ will currently restore all fragments
- */
- c_lcp_complete_fragments.add(fragptr);
-
- signal->theData[0] = tabptr.i;
- signal->theData[1] = fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
- c_tup->disk_restart_lcp_id(tabptr.i, fragId, RNIL);
- jamEntry();
- return;
- }
- else
- {
- jam();
- c_tup->disk_restart_lcp_id(tabptr.i, fragId, lcpId);
- jamEntry();
- }
-
- c_lcpId = (c_lcpId == 0 ? lcpId : c_lcpId);
- c_lcpId = (c_lcpId < lcpId ? c_lcpId : lcpId);
- c_lcp_waiting_fragments.add(fragptr);
- if(c_lcp_restoring_fragments.isEmpty())
- send_restore_lcp(signal);
-}//Dblqh::execSTART_FRAGREQ()
-
-void
-Dblqh::send_restore_lcp(Signal * signal)
-{
- c_lcp_waiting_fragments.first(fragptr);
- c_lcp_waiting_fragments.remove(fragptr);
- c_lcp_restoring_fragments.add(fragptr);
-
- RestoreLcpReq* req= (RestoreLcpReq*)signal->getDataPtrSend();
- req->senderData = fragptr.i;
- req->senderRef = reference();
- req->tableId = fragptr.p->tabRef;
- req->fragmentId = fragptr.p->fragId;
- req->lcpNo = fragptr.p->srChkpnr;
- req->lcpId = fragptr.p->lcpId[fragptr.p->srChkpnr];
-
- sendSignal(RESTORE_REF, GSN_RESTORE_LCP_REQ, signal,
- RestoreLcpReq::SignalLength, JBB);
-}
-
-void Dblqh::startFragRefLab(Signal* signal)
-{
- const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
- BlockReference userRef = startFragReq->userRef;
- Uint32 userPtr = startFragReq->userPtr;
- signal->theData[0] = userPtr;
- signal->theData[1] = terrorCode;
- signal->theData[2] = cownNodeid;
- sendSignal(userRef, GSN_START_FRAGREF, signal, 3, JBB);
- return;
-}//Dblqh::startFragRefLab()
-
-void Dblqh::execRESTORE_LCP_REF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
- return;
-}
-
-void Dblqh::execRESTORE_LCP_CONF(Signal* signal)
-{
- jamEntry();
- RestoreLcpConf* conf= (RestoreLcpConf*)signal->getDataPtr();
- fragptr.i = conf->senderData;
- c_fragment_pool.getPtr(fragptr);
-
- c_lcp_restoring_fragments.remove(fragptr);
- c_lcp_complete_fragments.add(fragptr);
-
- /**
- * Disable expand check in ACC
- * before running REDO
- */
- tabptr.i = fragptr.p->tabRef;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
-
- signal->theData[0] = fragptr.p->tabRef;
- signal->theData[1] = fragptr.p->fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
-
- if (!c_lcp_waiting_fragments.isEmpty())
- {
- send_restore_lcp(signal);
- return;
- }
-
- if (c_lcp_restoring_fragments.isEmpty() && cstartRecReq == 1)
- {
- jam();
- /* ----------------------------------------------------------------
- * WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS
- * NEEDS RESTART.
- * NOW IT IS TIME TO START EXECUTING THE UNDO LOG.
- * ----------------------------------------------------------------
- * WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START
- * EXECUTING THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE
- * FRAGMENT LOGS CAN BE EXECUTED.
- * ---------------------------------------------------------------- */
- csrExecUndoLogState = EULS_STARTED;
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- lcpPtr.p->m_outstanding = 1;
-
- signal->theData[0] = c_lcpId;
- sendSignal(LGMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
- return;
- }
-}
-
-/* ***************> */
-/* START_RECREQ > */
-/* ***************> */
-void Dblqh::execSTART_RECREQ(Signal* signal)
-{
- CRASH_INSERTION(5027);
-
- jamEntry();
- StartRecReq * const req = (StartRecReq*)&signal->theData[0];
- cmasterDihBlockref = req->senderRef;
-
- crestartOldestGci = req->keepGci;
- crestartNewestGci = req->lastCompletedGci;
- cnewestGci = req->newestGci;
-
- ndbrequire(req->receivingNodeId == cownNodeid);
-
- cnewestCompletedGci = cnewestGci;
- cstartRecReq = 1;
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
- }//for
- /* ------------------------------------------------------------------------
- * WE HAVE TO SET THE OLDEST AND THE NEWEST GLOBAL CHECKPOINT IDENTITY
- * THAT WILL SURVIVE THIS SYSTEM RESTART. THIS IS NEEDED SO THAT WE CAN
- * SET THE LOG HEAD AND LOG TAIL PROPERLY BEFORE STARTING THE SYSTEM AGAIN.
- * WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED
- * WITH A PROPER GCI.
- *------------------------------------------------------------------------ */
-
- if (c_lcp_restoring_fragments.isEmpty())
- {
- jam();
- csrExecUndoLogState = EULS_STARTED;
-
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- lcpPtr.p->m_outstanding = 1;
-
- signal->theData[0] = c_lcpId;
- sendSignal(LGMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
- }//if
-}//Dblqh::execSTART_RECREQ()
-
-/* ***************>> */
-/* START_RECCONF > */
-/* ***************>> */
-void Dblqh::execSTART_RECCONF(Signal* signal)
-{
- jamEntry();
- lcpPtr.i = 0;
- ptrAss(lcpPtr, lcpRecord);
- ndbrequire(csrExecUndoLogState == EULS_STARTED);
- ndbrequire(lcpPtr.p->m_outstanding);
-
- Uint32 sender= signal->theData[0];
-
- lcpPtr.p->m_outstanding--;
- if(lcpPtr.p->m_outstanding)
- {
- jam();
- return;
- }
-
- switch(refToBlock(sender)){
- case TSMAN:
- jam();
- break;
- case LGMAN:
- jam();
- lcpPtr.p->m_outstanding++;
- signal->theData[0] = c_lcpId;
- sendSignal(TSMAN_REF, GSN_START_RECREQ, signal, 1, JBB);
- return;
- break;
- default:
- ndbrequire(false);
- }
-
- jam();
- csrExecUndoLogState = EULS_COMPLETED;
-
- if(cstartType == NodeState::ST_INITIAL_NODE_RESTART)
- {
- jam();
- cstartRecReq = 2;
-
- StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
- conf->startingNodeId = getOwnNodeId();
- sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
- StartRecConf::SignalLength, JBB);
- return;
- }
-
- startExecSr(signal);
-}
-
-/* ***************> */
-/* START_RECREF > */
-/* ***************> */
-void Dblqh::execSTART_RECREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}//Dblqh::execSTART_RECREF()
-
-/* ***************>> */
-/* START_EXEC_SR > */
-/* ***************>> */
-void Dblqh::execSTART_EXEC_SR(Signal* signal)
-{
- jamEntry();
- fragptr.i = signal->theData[0];
- Uint32 next = RNIL;
-
- if (fragptr.i == RNIL)
- {
- jam();
- /* ----------------------------------------------------------------------
- * NO MORE FRAGMENTS TO START EXECUTING THE LOG ON.
- * SEND EXEC_SRREQ TO ALL LQH TO INDICATE THAT THIS NODE WILL
- * NOT REQUEST ANY MORE FRAGMENTS TO EXECUTE THE FRAGMENT LOG ON.
- * ----------------------------------------------------------------------
- * WE NEED TO SEND THOSE SIGNALS EVEN IF WE HAVE NOT REQUESTED
- * ANY FRAGMENTS PARTICIPATE IN THIS PHASE.
- * --------------------------------------------------------------------- */
- NodeReceiverGroup rg(DBLQH, m_sr_nodes);
- signal->theData[0] = cownNodeid;
- sendSignal(rg, GSN_EXEC_SRREQ, signal, 1, JBB);
- return;
- } else {
- jam();
- c_lcp_complete_fragments.getPtr(fragptr);
- next = fragptr.p->nextList;
-
- if (fragptr.p->srNoLognodes > csrPhasesCompleted)
- {
- jam();
- cnoOutstandingExecFragReq++;
-
- Uint32 index = csrPhasesCompleted;
- arrGuard(index, MAX_LOG_EXEC);
- BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]);
- fragptr.p->srStatus = Fragrecord::SS_STARTED;
-
- /* --------------------------------------------------------------------
- * SINCE WE CAN HAVE SEVERAL LQH NODES PER FRAGMENT WE CALCULATE
- * THE LQH POINTER IN SUCH A WAY THAT WE CAN DEDUCE WHICH OF THE
- * LQH NODES THAT HAS RESPONDED WHEN EXEC_FRAGCONF IS RECEIVED.
- * ------------------------------------------------------------------- */
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- execFragReq->userPtr = fragptr.i;
- execFragReq->userRef = cownref;
- execFragReq->tableId = fragptr.p->tabRef;
- execFragReq->fragId = fragptr.p->fragId;
- execFragReq->startGci = fragptr.p->srStartGci[index];
- execFragReq->lastGci = fragptr.p->srLastGci[index];
- sendSignal(ref, GSN_EXEC_FRAGREQ, signal,
- ExecFragReq::SignalLength, JBB);
-
- }
- signal->theData[0] = next;
- sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
- }//if
- return;
-}//Dblqh::execSTART_EXEC_SR()
-
-/* ***************> */
-/* EXEC_FRAGREQ > */
-/* ***************> */
-/* --------------------------------------------------------------------------
- * THIS SIGNAL IS USED TO REQUEST THAT A FRAGMENT PARTICIPATES IN EXECUTING
- * THE LOG IN THIS NODE.
- * ------------------------------------------------------------------------- */
-void Dblqh::execEXEC_FRAGREQ(Signal* signal)
-{
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- jamEntry();
- tabptr.i = execFragReq->tableId;
- Uint32 fragId = execFragReq->fragId;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- ndbrequire(getFragmentrec(signal, fragId));
-
- ndbrequire(fragptr.p->execSrNoReplicas < 4);
- fragptr.p->execSrBlockref[fragptr.p->execSrNoReplicas] = execFragReq->userRef;
- fragptr.p->execSrUserptr[fragptr.p->execSrNoReplicas] = execFragReq->userPtr;
- fragptr.p->execSrStartGci[fragptr.p->execSrNoReplicas] = execFragReq->startGci;
- fragptr.p->execSrLastGci[fragptr.p->execSrNoReplicas] = execFragReq->lastGci;
- fragptr.p->execSrStatus = Fragrecord::ACTIVE;
- fragptr.p->execSrNoReplicas++;
- cnoFragmentsExecSr++;
- return;
-}//Dblqh::execEXEC_FRAGREQ()
-
-void Dblqh::sendExecFragRefLab(Signal* signal)
-{
- ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
- BlockReference retRef = execFragReq->userRef;
- Uint32 retPtr = execFragReq->userPtr;
-
- signal->theData[0] = retPtr;
- signal->theData[1] = terrorCode;
- sendSignal(retRef, GSN_EXEC_FRAGREF, signal, 2, JBB);
- return;
-}//Dblqh::sendExecFragRefLab()
-
-/* ***************>> */
-/* EXEC_FRAGCONF > */
-/* ***************>> */
-void Dblqh::execEXEC_FRAGCONF(Signal* signal)
-{
- jamEntry();
- fragptr.i = signal->theData[0];
- c_fragment_pool.getPtr(fragptr);
- fragptr.p->srStatus = Fragrecord::SS_COMPLETED;
-
- ndbrequire(cnoOutstandingExecFragReq);
- cnoOutstandingExecFragReq--;
- if (fragptr.p->srNoLognodes == csrPhasesCompleted + 1)
- {
- jam();
-
- fragptr.p->logFlag = Fragrecord::STATE_TRUE;
- fragptr.p->fragStatus = Fragrecord::FSACTIVE;
-
- signal->theData[0] = fragptr.p->srUserptr;
- signal->theData[1] = cownNodeid;
- sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
- }
-
- return;
-}//Dblqh::execEXEC_FRAGCONF()
-
-/* ***************> */
-/* EXEC_FRAGREF > */
-/* ***************> */
-void Dblqh::execEXEC_FRAGREF(Signal* signal)
-{
- jamEntry();
- terrorCode = signal->theData[1];
- systemErrorLab(signal, __LINE__);
- return;
-}//Dblqh::execEXEC_FRAGREF()
-
-/* *************** */
-/* EXEC_SRCONF > */
-/* *************** */
-void Dblqh::execEXEC_SRCONF(Signal* signal)
-{
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- arrGuard(nodeId, MAX_NDB_NODES);
- m_sr_exec_sr_conf.set(nodeId);
-
- if (!m_sr_nodes.equal(m_sr_exec_sr_conf))
- {
- jam();
- /* ------------------------------------------------------------------
- * ALL NODES HAVE NOT REPORTED COMPLETION OF EXECUTING FRAGMENT
- * LOGS YET.
- * ----------------------------------------------------------------- */
- return;
- }
-
- /* ------------------------------------------------------------------------
- * CLEAR NODE SYSTEM RESTART EXECUTION STATE TO PREPARE FOR NEXT PHASE OF
- * LOG EXECUTION.
- * ----------------------------------------------------------------------- */
- m_sr_exec_sr_conf.clear();
-
- /* ------------------------------------------------------------------------
- * NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE
- * NEXT PHASE.
- * ----------------------------------------------------------------------- */
- ndbrequire(cnoOutstandingExecFragReq == 0);
-
- execSrCompletedLab(signal);
- return;
-}//Dblqh::execEXEC_SRCONF()
-
-void Dblqh::execSrCompletedLab(Signal* signal)
-{
- csrPhasesCompleted++;
- /* ------------------------------------------------------------------------
- * ALL FRAGMENTS WERE COMPLETED. THIS PHASE IS COMPLETED. IT IS NOW TIME TO
- * START THE NEXT PHASE.
- * ----------------------------------------------------------------------- */
- if (csrPhasesCompleted >= 4) {
- jam();
- /* ----------------------------------------------------------------------
- * THIS WAS THE LAST PHASE. WE HAVE NOW COMPLETED THE EXECUTION THE
- * FRAGMENT LOGS IN ALL NODES. BEFORE WE SEND START_RECCONF TO THE
- * MASTER DIH TO INDICATE A COMPLETED SYSTEM RESTART IT IS NECESSARY
- * TO FIND THE HEAD AND THE TAIL OF THE LOG WHEN NEW OPERATIONS START
- * TO COME AGAIN.
- *
- * THE FIRST STEP IS TO FIND THE HEAD AND TAIL MBYTE OF EACH LOG PART.
- * TO DO THIS WE REUSE THE CONTINUEB SIGNAL SR_LOG_LIMITS. THEN WE
- * HAVE TO FIND THE ACTUAL PAGE NUMBER AND PAGE INDEX WHERE TO
- * CONTINUE WRITING THE LOG AFTER THE SYSTEM RESTART.
- * --------------------------------------------------------------------- */
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
- logPartPtr.p->logLastGci = crestartNewestGci;
- logPartPtr.p->logStartGci = crestartOldestGci;
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
- if (logPartPtr.p->headFileNo == ZNIL) {
- jam();
- /* -----------------------------------------------------------------
- * IF WE HAVEN'T FOUND ANY HEAD OF THE LOG THEN WE ARE IN SERIOUS
- * PROBLEM. THIS SHOULD NOT OCCUR. IF IT OCCURS ANYWAY THEN WE
- * HAVE TO FIND A CURE FOR THIS PROBLEM.
- * ----------------------------------------------------------------- */
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logPartPtr.p->lastLogfile;
- signal->theData[3] = logPartPtr.p->lastMbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- }//for
- return;
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THERE ARE YET MORE PHASES TO RESTART.
- * WE MUST INITIALISE DATA FOR NEXT PHASE AND SEND START SIGNAL.
- * --------------------------------------------------------------------- */
- csrPhaseStarted = ZSR_PHASE1_COMPLETED; // Set correct state first...
- startExecSr(signal);
- }//if
- return;
-}//Dblqh::execSrCompletedLab()
-
-/* ************>> */
-/* EXEC_SRREQ > */
-/* ************>> */
-void Dblqh::execEXEC_SRREQ(Signal* signal)
-{
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- ndbrequire(nodeId < MAX_NDB_NODES);
- m_sr_exec_sr_req.set(nodeId);
- if (!m_sr_exec_sr_req.equal(m_sr_nodes))
- {
- jam();
- return;
- }
-
- /* ------------------------------------------------------------------------
- * CLEAR NODE SYSTEM RESTART STATE TO PREPARE FOR NEXT PHASE OF LOG
- * EXECUTION
- * ----------------------------------------------------------------------- */
- m_sr_exec_sr_req.clear();
-
- if (csrPhasesCompleted != 0) {
- /* ----------------------------------------------------------------------
- * THE FIRST PHASE MUST ALWAYS EXECUTE THE LOG.
- * --------------------------------------------------------------------- */
- if (cnoFragmentsExecSr == 0) {
- jam();
- /* --------------------------------------------------------------------
- * THERE WERE NO FRAGMENTS THAT NEEDED TO EXECUTE THE LOG IN THIS PHASE.
- * ------------------------------------------------------------------- */
- srPhase3Comp(signal);
- return;
- }//if
- }//if
- /* ------------------------------------------------------------------------
- * NOW ALL NODES HAVE SENT ALL EXEC_FRAGREQ. NOW WE CAN START EXECUTING THE
- * LOG FROM THE MINIMUM GCI NEEDED UNTIL THE MAXIMUM GCI NEEDED.
- *
- * WE MUST FIRST CHECK IF THE FIRST PHASE OF THE SYSTEM RESTART HAS BEEN
- * COMPLETED. THIS HANDLING IS PERFORMED IN THE FILE SYSTEM MODULE
- * ----------------------------------------------------------------------- */
- signal->theData[0] = ZSR_PHASE3_START;
- signal->theData[1] = ZSR_PHASE2_COMPLETED;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::execEXEC_SRREQ()
-
-/* ######################################################################### */
-/* SYSTEM RESTART PHASE THREE MODULE */
-/* THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING. */
-/* */
-/* THIS MODULE IS CONCERNED WITH EXECUTING THE FRAGMENT LOG. IT DOES ALSO */
-/* CONTAIN SIGNAL RECEPTIONS LQHKEYCONF AND LQHKEYREF SINCE LQHKEYREQ IS USED*/
-/* TO EXECUTE THE LOG RECORDS. */
-/* */
-/* BEFORE IT STARTS IT HAS BEEN DECIDED WHERE TO START AND WHERE TO STOP */
-/* READING THE FRAGMENT LOG BY USING THE INFORMATION ABOUT GCI DISCOVERED IN */
-/* PHASE ONE OF THE SYSTEM RESTART. */
-/* ######################################################################### */
-/*---------------------------------------------------------------------------*/
-/* PHASE THREE OF THE SYSTEM RESTART CAN NOW START. ONE OF THE PHASES HAVE */
-/* COMPLETED. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::srPhase3Start(Signal* signal)
-{
- UintR tsrPhaseStarted;
-
- jamEntry();
-
- tsrPhaseStarted = signal->theData[1];
- if (csrPhaseStarted == ZSR_NO_PHASE_STARTED) {
- jam();
- csrPhaseStarted = tsrPhaseStarted;
- return;
- }//if
- ndbrequire(csrPhaseStarted != tsrPhaseStarted);
- ndbrequire(csrPhaseStarted != ZSR_BOTH_PHASES_STARTED);
-
- csrPhaseStarted = ZSR_BOTH_PHASES_STARTED;
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_STARTED;
- logPartPtr.p->logStartGci = (UintR)-1;
- if (csrPhasesCompleted == 0) {
- jam();
- /* --------------------------------------------------------------------
- * THE FIRST PHASE WE MUST ENSURE THAT IT REACHES THE END OF THE LOG.
- * ------------------------------------------------------------------- */
- logPartPtr.p->logLastGci = crestartNewestGci;
- } else {
- jam();
- logPartPtr.p->logLastGci = 2;
- }//if
- }//for
-
- jam();
- c_lcp_complete_fragments.first(fragptr);
- signal->theData[0] = ZSR_GCI_LIMITS;
- signal->theData[1] = fragptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::srPhase3Start()
-
-/* --------------------------------------------------------------------------
- * WE NOW WE NEED TO FIND THE LIMITS WITHIN WHICH TO EXECUTE
- * THE FRAGMENT LOG
- * ------------------------------------------------------------------------- */
-void Dblqh::srGciLimits(Signal* signal)
-{
- jamEntry();
- fragptr.i = signal->theData[0];
- Uint32 loopCount = 0;
- logPartPtr.i = 0;
- ptrAss(logPartPtr, logPartRecord);
- while (fragptr.i != RNIL){
- jam();
- c_lcp_complete_fragments.getPtr(fragptr);
- ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
- for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
- jam();
- if (fragptr.p->execSrStartGci[i] < logPartPtr.p->logStartGci) {
- jam();
- logPartPtr.p->logStartGci = fragptr.p->execSrStartGci[i];
- }//if
- if (fragptr.p->execSrLastGci[i] > logPartPtr.p->logLastGci) {
- jam();
- logPartPtr.p->logLastGci = fragptr.p->execSrLastGci[i];
- }
- }
-
- loopCount++;
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSR_GCI_LIMITS;
- signal->theData[1] = fragptr.p->nextList;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- fragptr.i = fragptr.p->nextList;
- }//if
- }
-
- for(Uint32 i = 1; i<4; i++)
- {
- LogPartRecordPtr tmp;
- tmp.i = i;
- ptrAss(tmp, logPartRecord);
- tmp.p->logStartGci = logPartPtr.p->logStartGci;
- tmp.p->logLastGci = logPartPtr.p->logLastGci;
- }
-
- if (logPartPtr.p->logStartGci == (UintR)-1) {
- jam();
- /* --------------------------------------------------------------------
- * THERE WERE NO FRAGMENTS TO INSTALL WE WILL EXECUTE THE LOG AS
- * SHORT AS POSSIBLE TO REACH THE END OF THE LOG. THIS WE DO BY
- * STARTING AT THE STOP GCI.
- * ------------------------------------------------------------------- */
- logPartPtr.p->logStartGci = logPartPtr.p->logLastGci;
- }//if
-
- for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logPartPtr.p->lastLogfile;
- signal->theData[3] = logPartPtr.p->lastMbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- }//for
-}//Dblqh::srGciLimits()
-
-/* --------------------------------------------------------------------------
- * IT IS NOW TIME TO FIND WHERE TO START EXECUTING THE LOG.
- * THIS SIGNAL IS SENT FOR EACH LOG PART AND STARTS THE EXECUTION
- * OF THE LOG FOR THIS PART.
- *-------------------------------------------------------------------------- */
-void Dblqh::srLogLimits(Signal* signal)
-{
- Uint32 tlastPrepRef;
- Uint32 tmbyte;
-
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = signal->theData[1];
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- tmbyte = signal->theData[2];
- Uint32 loopCount = 0;
- /* ------------------------------------------------------------------------
- * WE ARE SEARCHING FOR THE START AND STOP MBYTE OF THE LOG THAT IS TO BE
- * EXECUTED.
- * ----------------------------------------------------------------------- */
- while(true) {
- ndbrequire(tmbyte < clogFileSize);
- if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) {
- if (logFilePtr.p->logMaxGciCompleted[tmbyte] <= logPartPtr.p->logLastGci) {
- jam();
- /* --------------------------------------------------------------------
- * WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST
- * MBYTE WHICH IS TO BE INCLUDED IN THE LOG EXECUTION. THE STOP GCI
- * HAS NOT BEEN COMPLETED BEFORE THIS MBYTE. THUS THIS MBYTE HAVE
- * TO BE EXECUTED.
- * ------------------------------------------------------------------- */
- logPartPtr.p->stopLogfile = logFilePtr.i;
- logPartPtr.p->stopMbyte = tmbyte;
- logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_START;
- }//if
- }//if
- /* ------------------------------------------------------------------------
- * WHEN WE HAVEN'T FOUND THE STOP MBYTE IT IS NOT NECESSARY TO LOOK FOR THE
- * START MBYTE. THE REASON IS THE FOLLOWING LOGIC CHAIN:
- * MAX_GCI_STARTED >= MAX_GCI_COMPLETED >= LAST_GCI >= START_GCI
- * THUS MAX_GCI_STARTED >= START_GCI. THUS MAX_GCI_STARTED < START_GCI CAN
- * NOT BE TRUE AS WE WILL CHECK OTHERWISE.
- * ----------------------------------------------------------------------- */
- if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_START) {
- if (logFilePtr.p->logMaxGciStarted[tmbyte] < logPartPtr.p->logStartGci) {
- jam();
- /* --------------------------------------------------------------------
- * WE HAVE NOW FOUND THE START OF THE EXECUTION OF THE LOG.
- * WE STILL HAVE TO MOVE IT BACKWARDS TO ALSO INCLUDE THE
- * PREPARE RECORDS WHICH WERE STARTED IN A PREVIOUS MBYTE.
- * ------------------------------------------------------------------- */
- tlastPrepRef = logFilePtr.p->logLastPrepRef[tmbyte];
- logPartPtr.p->startMbyte = tlastPrepRef & 65535;
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, tlastPrepRef >> 16, logPartPtr, &locLogFilePtr);
- logPartPtr.p->startLogfile = locLogFilePtr.i;
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG;
- }//if
- }//if
- if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG) {
- if (tmbyte == 0) {
- jam();
- tmbyte = clogFileSize - 1;
- logFilePtr.i = logFilePtr.p->prevLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- } else {
- jam();
- tmbyte--;
- }//if
- if (logPartPtr.p->lastLogfile == logFilePtr.i) {
- ndbrequire(logPartPtr.p->lastMbyte != tmbyte);
- }//if
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSR_LOG_LIMITS;
- signal->theData[1] = logPartPtr.i;
- signal->theData[2] = logFilePtr.i;
- signal->theData[3] = tmbyte;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }//if
- loopCount++;
- } else {
- jam();
- break;
- }//if
- }//while
-
- if (DEBUG_REDO)
- {
- LogFileRecordPtr tmp;
- tmp.i = logPartPtr.p->stopLogfile;
- ptrCheckGuard(tmp, clogFileFileSize, logFileRecord);
- ndbout_c("srLogLimits part: %u start file: %u mb: %u stop file: %u mb: %u",
- logPartPtr.i,
- tlastPrepRef >> 16,
- tlastPrepRef & 65535,
- tmp.p->fileNo,
- logPartPtr.p->stopMbyte);
- }
-
- /* ------------------------------------------------------------------------
- * WE HAVE NOW FOUND BOTH THE START AND THE STOP OF THE LOG. NOW START
- * EXECUTING THE LOG. THE FIRST ACTION IS TO OPEN THE LOG FILE WHERE TO
- * START EXECUTING THE LOG.
- * ----------------------------------------------------------------------- */
- if (logPartPtr.p->logPartState == LogPartRecord::SR_THIRD_PHASE_STARTED) {
- jam();
- logFilePtr.i = logPartPtr.p->startLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_START;
- openFileRw(signal, logFilePtr);
- } else {
- jam();
- ndbrequire(logPartPtr.p->logPartState == LogPartRecord::SR_FOURTH_PHASE_STARTED);
- /* --------------------------------------------------------------------
- * WE HAVE NOW FOUND THE TAIL MBYTE IN THE TAIL FILE.
- * SET THOSE PARAMETERS IN THE LOG PART.
- * WE HAVE ALSO FOUND THE HEAD MBYTE. WE STILL HAVE TO SEARCH
- * FOR THE PAGE NUMBER AND PAGE INDEX WHERE TO SET THE HEAD.
- * ------------------------------------------------------------------- */
- logFilePtr.i = logPartPtr.p->startLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->logTailFileNo = logFilePtr.p->fileNo;
- logPartPtr.p->logTailMbyte = logPartPtr.p->startMbyte;
- /* --------------------------------------------------------------------
- * THE HEAD WE ACTUALLY FOUND DURING EXECUTION OF LOG SO WE USE
- * THIS INFO HERE RATHER THAN THE MBYTE WE FOUND TO BE THE HEADER.
- * ------------------------------------------------------------------- */
- LogFileRecordPtr locLogFilePtr;
- findLogfile(signal, logPartPtr.p->headFileNo, logPartPtr, &locLogFilePtr);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
- openFileRw(signal, locLogFilePtr);
- }//if
- return;
-}//Dblqh::srLogLimits()
-
-void Dblqh::openExecSrStartLab(Signal* signal)
-{
- logPartPtr.p->currentLogfile = logFilePtr.i;
- logFilePtr.p->currentMbyte = logPartPtr.p->startMbyte;
- /* ------------------------------------------------------------------------
- * WE NEED A TC CONNECT RECORD TO HANDLE EXECUTION OF LOG RECORDS.
- * ------------------------------------------------------------------------ */
- seizeTcrec();
- logPartPtr.p->logTcConrec = tcConnectptr.i;
- /* ------------------------------------------------------------------------
- * THE FIRST LOG RECORD TO EXECUTE IS ALWAYS AT A NEW MBYTE.
- * SET THE NUMBER OF PAGES IN THE MAIN MEMORY BUFFER TO ZERO AS AN INITIAL
- * VALUE. THIS VALUE WILL BE UPDATED AND ENSURED THAT IT RELEASES PAGES IN
- * THE SUBROUTINE READ_EXEC_SR.
- * ----------------------------------------------------------------------- */
- logPartPtr.p->mmBufferSize = 0;
- readExecSrNewMbyte(signal);
- return;
-}//Dblqh::openExecSrStartLab()
-
-/* ---------------------------------------------------------------------------
- * WE WILL ALWAYS ENSURE THAT WE HAVE AT LEAST 16 KBYTE OF LOG PAGES WHEN WE
- * START READING A LOG RECORD. THE ONLY EXCEPTION IS WHEN WE COME CLOSE TO A
- * MBYTE BOUNDARY. SINCE WE KNOW THAT LOG RECORDS ARE NEVER WRITTEN ACROSS A
- * MBYTE BOUNDARY THIS IS NOT A PROBLEM.
- *
- * WE START BY READING 64 KBYTE BEFORE STARTING TO EXECUTE THE LOG RECORDS.
- * WHEN WE COME BELOW 64 KBYTE WE READ ANOTHER SET OF LOG PAGES. WHEN WE
- * GO BELOW 16 KBYTE WE WAIT UNTIL THE READ PAGES HAVE ENTERED THE BLOCK.
- * ------------------------------------------------------------------------- */
-/* --------------------------------------------------------------------------
- * NEW PAGES FROM LOG FILE DURING EXECUTION OF LOG HAS ARRIVED.
- * ------------------------------------------------------------------------- */
-void Dblqh::readExecSrLab(Signal* signal)
-{
- buildLinkedLogPageList(signal);
- /* ------------------------------------------------------------------------
- * WE NEED TO SET THE CURRENT PAGE INDEX OF THE FIRST PAGE SINCE IT CAN BE
- * USED IMMEDIATELY WITHOUT ANY OTHER INITIALISATION. THE REST OF THE PAGES
- * WILL BE INITIALISED BY READ_LOGWORD.
- * ----------------------------------------------------------------------- */
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- if (logPartPtr.p->logExecState ==
- LogPartRecord::LES_WAIT_READ_EXEC_SR_NEW_MBYTE) {
- jam();
- /* ----------------------------------------------------------------------
- * THIS IS THE FIRST READ DURING THE EXECUTION OF THIS MBYTE. SET THE
- * NEW CURRENT LOG PAGE TO THE FIRST OF THESE PAGES. CHANGE
- * LOG_EXEC_STATE TO ENSURE THAT WE START EXECUTION OF THE LOG.
- * --------------------------------------------------------------------- */
- logFilePtr.p->currentFilepage = logFilePtr.p->currentMbyte *
- ZPAGES_IN_MBYTE;
- logPartPtr.p->prevFilepage = logFilePtr.p->currentFilepage;
- logFilePtr.p->currentLogpage = lfoPtr.p->firstLfoPage;
- logPartPtr.p->prevLogpage = logFilePtr.p->currentLogpage;
- }//if
- moveToPageRef(signal);
- releaseLfo(signal);
- /* ------------------------------------------------------------------------
- * NOW WE HAVE COMPLETED THE RECEPTION OF THESE PAGES.
- * NOW CHECK IF WE NEED TO READ MORE PAGES.
- * ----------------------------------------------------------------------- */
- checkReadExecSr(signal);
- if (logPartPtr.p->logExecState == LogPartRecord::LES_EXEC_LOG) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- return;
-}//Dblqh::readExecSrLab()
-
-void Dblqh::openExecSrNewMbyteLab(Signal* signal)
-{
- readExecSrNewMbyte(signal);
- return;
-}//Dblqh::openExecSrNewMbyteLab()
-
-void Dblqh::closeExecSrLab(Signal* signal)
-{
- LogFileRecordPtr locLogFilePtr;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- logPartPtr.i = logFilePtr.p->logPartRec;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- locLogFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE;
- openFileRw(signal, locLogFilePtr);
- return;
-}//Dblqh::closeExecSrLab()
-
-void Dblqh::writeDirtyLab(Signal* signal)
-{
- releaseLfo(signal);
- signal->theData[0] = logPartPtr.i;
- execSr(signal);
- return;
-}//Dblqh::writeDirtyLab()
-
-/* --------------------------------------------------------------------------
- * EXECUTE A LOG RECORD WITHIN THE CURRENT MBYTE.
- * ------------------------------------------------------------------------- */
-void Dblqh::execSr(Signal* signal)
-{
- LogFileRecordPtr nextLogFilePtr;
- LogPageRecordPtr tmpLogPagePtr;
- Uint32 logWord;
- Uint32 line;
- const char * crash_msg = 0;
-
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
-
- do {
- jam();
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logPartPtr.p->prevLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- if (logPagePtr.p->logPageWord[ZPOS_DIRTY] == ZDIRTY) {
- jam();
- switch (logPartPtr.p->logExecState) {
- case LogPartRecord::LES_EXEC_LOG_COMPLETED:
- case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
- case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
- jam();
- /* ------------------------------------------------------------------
- * IN THIS WE HAVE COMPLETED EXECUTION OF THE CURRENT LOG PAGE
- * AND CAN WRITE IT TO DISK SINCE IT IS DIRTY.
- * ----------------------------------------------------------------- */
- writeDirty(signal, __LINE__);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG:
- jam();
- /* --------------------------------------------------------------------
- * IN THIS CASE WE ONLY WRITE THE PAGE TO DISK IF WE HAVE COMPLETED
- * EXECUTION OF LOG RECORDS BELONGING TO THIS LOG PAGE.
- * ------------------------------------------------------------------- */
- if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
- jam();
- writeDirty(signal, __LINE__);
- return;
- }//if
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- }//if
- if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
- jam();
- logPartPtr.p->prevLogpage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logPartPtr.p->prevFilepage++;
- continue;
- }//if
- switch (logPartPtr.p->logExecState) {
- case LogPartRecord::LES_EXEC_LOG_COMPLETED:
- jam();
- releaseMmPages(signal);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR_COMPLETED;
- closeFile(signal, logFilePtr, __LINE__);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
- jam();
- logFilePtr.p->currentMbyte++;
- readExecSrNewMbyte(signal);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
- jam();
- nextLogFilePtr.i = logFilePtr.p->nextLogFile;
- logPartPtr.p->currentLogfile = nextLogFilePtr.i;
- ptrCheckGuard(nextLogFilePtr, clogFileFileSize, logFileRecord);
- nextLogFilePtr.p->currentMbyte = 0;
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR;
- closeFile(signal, logFilePtr, __LINE__);
- return;
- break;
- case LogPartRecord::LES_EXEC_LOG:
- jam();
- /*empty*/;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPartPtr.p->savePageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- if (logPartPtr.p->execSrPagesRead < ZMIN_READ_BUFFER_SIZE) {
- /* --------------------------------------------------------------------
- * THERE WERE LESS THAN 16 KBYTE OF LOG PAGES REMAINING. WE WAIT UNTIL
- * THE NEXT 64 KBYTE ARRIVES UNTIL WE CONTINUE AGAIN.
- * ------------------------------------------------------------------- */
- if ((logPartPtr.p->execSrPagesRead +
- logPartPtr.p->execSrPagesExecuted) < ZPAGES_IN_MBYTE) {
- jam();
- /* ------------------------------------------------------------------
- * WE ONLY STOP AND WAIT IF THERE MORE PAGES TO READ. IF IT IS NOT
- * THEN IT IS THE END OF THE MBYTE AND WE WILL CONTINUE. IT IS NO
- * RISK THAT A LOG RECORD WE FIND WILL NOT BE READ AT THIS TIME
- * SINCE THE LOG RECORDS NEVER SPAN OVER A MBYTE BOUNDARY.
- * ----------------------------------------------------------------- */
- readExecSr(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_WAIT_READ_EXEC_SR;
- return;
- }//if
- }//if
- logWord = readLogword(signal);
- switch (logWord) {
-/* ========================================================================= */
-/* ========================================================================= */
- case ZPREP_OP_TYPE:
- {
- logWord = readLogword(signal);
- stepAhead(signal, logWord - 2);
- break;
- }
-/* ========================================================================= */
-/* ========================================================================= */
- case ZINVALID_COMMIT_TYPE:
- jam();
- stepAhead(signal, ZCOMMIT_LOG_SIZE - 1);
- break;
-/* ========================================================================= */
-/* ========================================================================= */
- case ZCOMMIT_TYPE:
- {
- CommitLogRecord commitLogRecord;
- jam();
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- readCommitLog(signal, &commitLogRecord);
- if (tcConnectptr.p->gci > crestartNewestGci) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS LOG RECORD MUST BE IGNORED. IT IS PART OF A GLOBAL CHECKPOINT WHICH */
-/* WILL BE INVALIDATED BY THE SYSTEM RESTART. IF NOT INVALIDATED IT MIGHT BE */
-/* EXECUTED IN A FUTURE SYSTEM RESTART. */
-/*---------------------------------------------------------------------------*/
- tmpLogPagePtr.i = logPartPtr.p->prevLogpage;
- ptrCheckGuard(tmpLogPagePtr, clogPageFileSize, logPageRecord);
- arrGuard(logPartPtr.p->savePageIndex, ZPAGE_SIZE);
- tmpLogPagePtr.p->logPageWord[logPartPtr.p->savePageIndex] =
- ZINVALID_COMMIT_TYPE;
- tmpLogPagePtr.p->logPageWord[ZPOS_DIRTY] = ZDIRTY;
- } else {
- jam();
-/*---------------------------------------------------------------------------*/
-/* CHECK IF I AM SUPPOSED TO EXECUTE THIS LOG RECORD. IF I AM THEN SAVE PAGE */
-/* INDEX IN CURRENT LOG PAGE SINCE IT WILL BE OVERWRITTEN WHEN EXECUTING THE */
-/* LOG RECORD. */
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->execSrExecuteIndex = 0;
- Uint32 result = checkIfExecLog(signal);
- if (result == ZOK) {
- jam();
-//*---------------------------------------------------------------------------*/
-/* IN A NODE RESTART WE WILL NEVER END UP HERE SINCE NO FRAGMENTS HAVE BEEN */
-/* DEFINED YET. THUS NO EXTRA CHECKING FOR NODE RESTART IS NECESSARY. */
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->savePageIndex =
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- tcConnectptr.p->fragmentptr = fragptr.i;
- findPageRef(signal, &commitLogRecord);
- logPartPtr.p->execSrLogPageIndex = commitLogRecord.startPageIndex;
- if (logPagePtr.i != RNIL) {
- jam();
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = commitLogRecord.startPageIndex;
- logPartPtr.p->execSrLogPage = logPagePtr.i;
- execLogRecord(signal);
- return;
- }//if
- logPartPtr.p->execSrStartPageNo = commitLogRecord.startPageNo;
- logPartPtr.p->execSrStopPageNo = commitLogRecord.stopPageNo;
- findLogfile(signal, commitLogRecord.fileNo, logPartPtr, &logFilePtr);
- logPartPtr.p->execSrExecLogFile = logFilePtr.i;
- if (logFilePtr.i == logPartPtr.p->currentLogfile) {
- jam();
- readExecLog(signal);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
- return;
- } else {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THE FILE IS CURRENTLY NOT OPEN. WE MUST OPEN IT BEFORE WE CAN READ FROM */
-/* THE FILE. */
-/*---------------------------------------------------------------------------*/
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_LOG;
- openFileRw(signal, logFilePtr);
- return;
- }//if
- }//if
- }//if
- break;
- }
-/* ========================================================================= */
-/* ========================================================================= */
- case ZABORT_TYPE:
- jam();
- stepAhead(signal, ZABORT_LOG_SIZE - 1);
- break;
-/* ========================================================================= */
-/* ========================================================================= */
- case ZFD_TYPE:
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS IS THE FIRST ITEM WE ENCOUNTER IN A NEW FILE. AT THIS MOMENT WE SHALL*/
-/* SIMPLY BYPASS IT. IT HAS NO SIGNIFANCE WHEN EXECUTING THE LOG. IT HAS ITS */
-/* SIGNIFANCE WHEN FINDING THE START END THE END OF THE LOG. */
-/* WE HARDCODE THE PAGE INDEX SINCE THIS SHOULD NEVER BE FOUND AT ANY OTHER */
-/* PLACE THAN IN THE FIRST PAGE OF A NEW FILE IN THE FIRST POSITION AFTER THE*/
-/* HEADER. */
-/*---------------------------------------------------------------------------*/
- if (unlikely(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] !=
- (ZPAGE_HEADER_SIZE + ZPOS_NO_FD)))
- {
- line = __LINE__;
- logWord = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- crash_msg = "ZFD_TYPE at incorrect position!";
- goto crash;
- }
- {
- Uint32 noFdDescriptors =
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- (ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
- (noFdDescriptors * ZFD_MBYTE_SIZE * clogFileSize);
- }
- break;
-/* ========================================================================= */
-/* ========================================================================= */
- case ZNEXT_LOG_RECORD_TYPE:
- jam();
- stepAhead(signal, ZPAGE_SIZE - logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]);
- break;
-/* ========================================================================= */
-/* ========================================================================= */
- case ZNEXT_MBYTE_TYPE:
-/*---------------------------------------------------------------------------*/
-/* WE WILL SKIP A PART OF THE LOG FILE. ACTUALLY THE NEXT POINTER IS TO */
-/* A NEW MBYTE. THEREFORE WE WILL START UP A NEW MBYTE. THIS NEW MBYTE IS */
-/* HOWEVER ONLY STARTED IF IT IS NOT AFTER THE STOP MBYTE. */
-/* IF WE HAVE REACHED THE END OF THE STOP MBYTE THEN THE EXECUTION OF THE LOG*/
-/* IS COMPLETED. */
-/*---------------------------------------------------------------------------*/
- if (logPartPtr.p->currentLogfile == logPartPtr.p->stopLogfile) {
- if (logFilePtr.p->currentMbyte == logPartPtr.p->stopMbyte) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* THIS WAS THE LAST MBYTE TO EXECUTE IN THIS LOG PART. WE SHOULD HAVE FOUND */
-/* A COMPLETED GCI RECORD OF THE LAST GCI BEFORE THIS. FOR SOME REASON THIS */
-/* RECORD WAS NOT AVAILABLE ON THE LOG. CRASH THE SYSTEM, A VERY SERIOUS */
-/* ERROR WHICH WE MUST REALLY WORK HARD TO AVOID. */
-/*---------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------*/
-/* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
-/*---------------------------------------------------------------------------*/
- line = __LINE__;
- logWord = ZNEXT_MBYTE_TYPE;
- crash_msg = "end of log wo/ having found last GCI";
- goto crash;
- }//if
- }//if
-/*---------------------------------------------------------------------------*/
-/* START EXECUTION OF A NEW MBYTE IN THE LOG. */
-/*---------------------------------------------------------------------------*/
- if (logFilePtr.p->currentMbyte < (clogFileSize - 1)) {
- jam();
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_MBYTE;
- } else {
- ndbrequire(logFilePtr.p->currentMbyte == (clogFileSize - 1));
- jam();
-/*---------------------------------------------------------------------------*/
-/* WE HAVE TO CHANGE FILE. CLOSE THIS ONE AND THEN OPEN THE NEXT. */
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_FILE;
- }//if
- break;
-/* ========================================================================= */
-/* ========================================================================= */
- case ZCOMPLETED_GCI_TYPE:
- jam();
- logWord = readLogword(signal);
- if (DEBUG_REDO)
- ndbout_c("found gci: %u part: %u file: %u page: %u",
- logWord,
- logPartPtr.i,
- logFilePtr.p->fileNo,
- logFilePtr.p->currentFilepage);
- if (logWord == logPartPtr.p->logLastGci) {
- jam();
-/*---------------------------------------------------------------------------*/
-/* IF IT IS THE LAST GCI TO LIVE AFTER SYSTEM RESTART THEN WE RECORD THE NEXT*/
-/* WORD AS THE NEW HEADER OF THE LOG FILE. OTHERWISE WE SIMPLY IGNORE THIS */
-/* LOG RECORD. */
-/*---------------------------------------------------------------------------*/
- if (csrPhasesCompleted == 0) {
- jam();
-/*---------------------------------------------------------------------------*/
-/*WE ONLY RECORD THE HEAD OF THE LOG IN THE FIRST LOG ROUND OF LOG EXECUTION.*/
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->headFileNo = logFilePtr.p->fileNo;
- logPartPtr.p->headPageNo = logFilePtr.p->currentFilepage;
- logPartPtr.p->headPageIndex =
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
- if (DEBUG_REDO)
- ndbout_c("execSr part: %u logLap: %u",
- logPartPtr.i, logPartPtr.p->logLap);
- }//if
-/*---------------------------------------------------------------------------*/
-/* THERE IS NO NEED OF EXECUTING PAST THIS LINE SINCE THERE WILL ONLY BE LOG */
-/* RECORDS THAT WILL BE OF NO INTEREST. THUS CLOSE THE FILE AND START THE */
-/* NEXT PHASE OF THE SYSTEM RESTART. */
-/*---------------------------------------------------------------------------*/
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_COMPLETED;
- }//if
- break;
- default:
- jam();
-/* ========================================================================= */
-/* ========================================================================= */
-/*---------------------------------------------------------------------------*/
-/* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
-/*---------------------------------------------------------------------------*/
- line = __LINE__;
- crash_msg = "Invalid logword";
- goto crash;
- break;
- }//switch
-/*---------------------------------------------------------------------------*/
-// We continue to execute log records until we find a proper one to execute or
-// that we reach a new page.
-/*---------------------------------------------------------------------------*/
- } while (1);
- return;
-
-crash:
- signal->theData[0] = RNIL;
- signal->theData[1] = logPartPtr.i;
- Uint32 tmp = logFilePtr.p->fileName[3];
- tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
- signal->theData[2] = tmp;
- signal->theData[3] = logFilePtr.p->fileNo;
- signal->theData[4] = logFilePtr.p->currentMbyte;
- signal->theData[5] = logFilePtr.p->currentFilepage;
- signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- signal->theData[7] = logWord;
- signal->theData[8] = line;
-
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Error while reading REDO log. from %d\n"
- "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d : %s",
- signal->theData[8],
- signal->theData[2],
- signal->theData[3],
- signal->theData[4],
- signal->theData[5],
- signal->theData[6],
- signal->theData[7],
- crash_msg ? crash_msg : "");
-
- progError(__LINE__, NDBD_EXIT_SR_REDOLOG, buf);
-}//Dblqh::execSr()
-
-/*---------------------------------------------------------------------------*/
-/* THIS SIGNAL IS ONLY RECEIVED TO BE CAPTURED IN THE SIGNAL LOG. IT IS */
-/* ALSO USED TO CRASH THE SYSTEM AFTER SENDING A SIGNAL TO THE LOG. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::execDEBUG_SIG(Signal* signal)
-{
-/*
-2.5 TEMPORARY VARIABLES
------------------------
-*/
- jamEntry();
- //logPagePtr.i = signal->theData[0];
- //tdebug = logPagePtr.p->logPageWord[0];
-
- char buf[100];
- BaseString::snprintf(buf, 100,
- "Error while reading REDO log. from %d\n"
- "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d",
- signal->theData[8],
- signal->theData[2], signal->theData[3], signal->theData[4],
- signal->theData[5], signal->theData[6], signal->theData[7]);
-
- progError(__LINE__, NDBD_EXIT_SR_REDOLOG, buf);
-
- return;
-}//Dblqh::execDEBUG_SIG()
-
-/*---------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------*/
-void Dblqh::closeExecLogLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logFilePtr.p->logPartRec;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::closeExecLogLab()
-
-void Dblqh::openExecLogLab(Signal* signal)
-{
- readExecLog(signal);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
- return;
-}//Dblqh::openExecLogLab()
-
-void Dblqh::readExecLogLab(Signal* signal)
-{
- buildLinkedLogPageList(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOGREC_FROM_FILE;
- logPartPtr.p->execSrLfoRec = lfoPtr.i;
- logPartPtr.p->execSrLogPage = logPagePtr.i;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- logPartPtr.p->execSrLogPageIndex;
- execLogRecord(signal);
- return;
-}//Dblqh::readExecLogLab()
-
-/*---------------------------------------------------------------------------*/
-/* THIS CODE IS USED TO EXECUTE A LOG RECORD WHEN IT'S DATA HAVE BEEN LOCATED*/
-/* AND TRANSFERRED INTO MEMORY. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::execLogRecord(Signal* signal)
-{
- jamEntry();
-
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- tcConnectptr.p->m_log_part_ptr_i = fragptr.p->m_log_part_ptr_i;
-
- // Read a log record and prepare it for execution
- readLogHeader(signal);
- readKey(signal);
- readAttrinfo(signal);
- initReqinfoExecSr(signal);
- arrGuard(logPartPtr.p->execSrExecuteIndex, 4);
- BlockReference ref = fragptr.p->execSrBlockref[logPartPtr.p->execSrExecuteIndex];
- tcConnectptr.p->nextReplica = refToNode(ref);
- tcConnectptr.p->connectState = TcConnectionrec::LOG_CONNECTED;
- tcConnectptr.p->tcOprec = tcConnectptr.i;
- packLqhkeyreqLab(signal);
- return;
-}//Dblqh::execLogRecord()
-
-//----------------------------------------------------------------------------
-// This function invalidates log pages after the last GCI record in a
-// system/node restart. This is to ensure that the end of the log is
-// consistent. This function is executed last in start phase 3.
-// RT 450. EDTJAMO.
-//----------------------------------------------------------------------------
-void Dblqh::invalidateLogAfterLastGCI(Signal* signal) {
-
- jam();
- if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG_INVALIDATE) {
- jam();
- systemError(signal, __LINE__);
- }
-
- if (logFilePtr.p->fileNo != logPartPtr.p->invalidateFileNo) {
- jam();
- systemError(signal, __LINE__);
- }
-
- switch (lfoPtr.p->lfoState) {
- case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
- jam();
- // Check if this page must be invalidated.
- // If the log lap number on a page after the head of the tail is the same
- // as the actual log lap number we must invalidate this page. Otherwise it
- // could be impossible to find the end of the log in a later system/node
- // restart.
- if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] == logPartPtr.p->logLap)
- {
- // This page must be invalidated.
- // We search for end
- // read next
- releaseLfo(signal);
- releaseLogpage(signal);
- readFileInInvalidate(signal, true);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
- return;
- }
-
- /**
- * We found the "last" page to invalidate...
- * Invalidate backwards until head...
- */
-
- // Fall through...
- case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
- jam();
-
- releaseLfo(signal);
- releaseLogpage(signal);
-
- // Step backwards...
- logPartPtr.p->invalidatePageNo--;
-
- if (logPartPtr.p->invalidatePageNo == 0)
- {
- jam();
-
- if (logFilePtr.p->fileNo == 0)
- {
- /**
- * We're wrapping in the log...
- * update logLap
- */
- logPartPtr.p->logLap--;
- ndbrequire(logPartPtr.p->logLap); // Should always be > 0
- if (DEBUG_REDO)
- ndbout_c("invalidateLogAfterLastGCI part: %u wrap from file 0 -> logLap: %u",
- logPartPtr.i, logPartPtr.p->logLap);
- }
-
- /**
- * Move to prev file
- */
- logFilePtr.i = logFilePtr.p->prevLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
- logPartPtr.p->invalidatePageNo = clogFileSize * ZPAGES_IN_MBYTE - 1;
- }
-
- if (logPartPtr.p->invalidateFileNo == logPartPtr.p->headFileNo &&
- logPartPtr.p->invalidatePageNo == logPartPtr.p->headPageNo)
- {
- /**
- * Done...
- */
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
-
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
-
- // Close files if necessary. Current file and the next file should be
- // left open.
- exitFromInvalidate(signal);
- return;
- }
-
- seizeLogpage(signal);
-
- /**
- * Make page really empty
- */
- bzero(logPagePtr.p, sizeof(LogPageRecord));
- writeSinglePage(signal, logPartPtr.p->invalidatePageNo,
- ZPAGE_SIZE - 1, __LINE__);
-
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
- return;
- default:
- jam();
- systemError(signal, __LINE__);
- return;
- break;
- }
-}//Dblqh::invalidateLogAfterLastGCI
-
-void Dblqh::readFileInInvalidate(Signal* signal, bool stepNext)
-{
- jam();
-
- if (stepNext)
- {
- logPartPtr.p->invalidatePageNo++;
- if (logPartPtr.p->invalidatePageNo == (clogFileSize * ZPAGES_IN_MBYTE))
- {
- // We continue in the next file.
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
- // Page 0 is used for file descriptors.
- logPartPtr.p->invalidatePageNo = 1;
-
- if (logFilePtr.p->fileNo == 0)
- {
- /**
- * We're wrapping in the log...
- * update logLap
- */
- logPartPtr.p->logLap++;
- if (DEBUG_REDO)
- ndbout_c("readFileInInvalidate part: %u wrap to file 0 -> logLap: %u",
- logPartPtr.i, logPartPtr.p->logLap);
- }
- if (logFilePtr.p->logFileStatus != LogFileRecord::OPEN)
- {
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_INVALIDATE_PAGES;
- openFileRw(signal, logFilePtr);
- return;
- }
- }
- }
-
- // Contact NDBFS. Real time break.
- readSinglePage(signal, logPartPtr.p->invalidatePageNo);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
-}
-
-void Dblqh::exitFromInvalidate(Signal* signal) {
- jam();
-
-loop:
- logFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
-
- if (logFilePtr.i == logPartPtr.p->currentLogfile)
- {
- jam();
- goto done;
- }
-
- if (logFilePtr.p->fileNo == 0)
- {
- jam();
- /**
- * Logfile 0 shoult *not* be closed
- */
- goto loop;
- }
-
- if (logFilePtr.p->logFileStatus == LogFileRecord::CLOSED)
- {
- jam();
- goto done;
- }
-
- jam();
- ndbrequire(logFilePtr.p->logFileStatus == LogFileRecord::OPEN);
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSE_SR_INVALIDATE_PAGES;
- closeFile(signal, logFilePtr, __LINE__);
- return;
-
-done:
- if (DEBUG_REDO)
- ndbout_c("exitFromInvalidate part: %u head file: %u page: %u",
- logPartPtr.i,
- logPartPtr.p->headFileNo,
- logPartPtr.p->headPageNo);
-
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] =
- logPartPtr.p->headFileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
-
- lfoPtr.p->logFileRec = logFilePtr.i;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES_UPDATE_PAGE0;
- return;
-}
-
-/*---------------------------------------------------------------------------*/
-/* THE EXECUTION OF A LOG RECORD IS COMPLETED. RELEASE PAGES IF THEY WERE */
-/* READ FROM DISK FOR THIS PARTICULAR OPERATION. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::completedLab(Signal* signal)
-{
- Uint32 result = returnExecLog(signal);
-/*---------------------------------------------------------------------------*/
-/* ENTER COMPLETED WITH */
-/* LQH_CONNECTPTR */
-/*---------------------------------------------------------------------------*/
- if (result == ZOK) {
- jam();
- execLogRecord(signal);
- return;
- } else if (result == ZNOT_OK) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- /*empty*/;
- }//if
-/*---------------------------------------------------------------------------*/
-/* WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE PROCEEDING IN */
-/* RARE CASES. */
-/*---------------------------------------------------------------------------*/
- return;
-}//Dblqh::completedLab()
-
-/*---------------------------------------------------------------------------*/
-/* EXECUTION OF LOG RECORD WAS NOT SUCCESSFUL. CHECK IF IT IS OK ANYWAY, */
-/* THEN EXECUTE THE NEXT LOG RECORD. */
-/*---------------------------------------------------------------------------*/
-void Dblqh::logLqhkeyrefLab(Signal* signal)
-{
- Uint32 result = returnExecLog(signal);
- switch (tcConnectptr.p->operation) {
- case ZUPDATE:
- case ZDELETE:
- jam();
- if (unlikely(terrorCode != ZNO_TUPLE_FOUND))
- goto error;
- break;
- case ZINSERT:
- jam();
- if (unlikely(terrorCode != ZTUPLE_ALREADY_EXIST && terrorCode != 899))
- goto error;
-
- break;
- default:
- goto error;
- }
-
- if (result == ZOK) {
- jam();
- execLogRecord(signal);
- return;
- } else if (result == ZNOT_OK) {
- jam();
- signal->theData[0] = ZEXEC_SR;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- } else {
- jam();
- /*empty*/;
- }//if
- /* ------------------------------------------------------------------------
- * WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE
- * PROCEEDING IN RARE CASES.
- * ----------------------------------------------------------------------- */
- return;
-error:
- BaseString tmp;
- tmp.appfmt("You have found a bug!"
- " Failed op (%s) during REDO table: %d fragment: %d err: %d",
- tcConnectptr.p->operation == ZINSERT ? "INSERT" :
- tcConnectptr.p->operation == ZUPDATE ? "UPDATE" :
- tcConnectptr.p->operation == ZDELETE ? "DELETE" :
- tcConnectptr.p->operation == ZWRITE ? "WRITE" : "<unknown>",
- tcConnectptr.p->tableref,
- tcConnectptr.p->fragmentid,
- terrorCode);
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR,
- tmp.c_str());
-}//Dblqh::logLqhkeyrefLab()
-
-void Dblqh::closeExecSrCompletedLab(Signal* signal)
-{
- logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
- signal->theData[0] = logFilePtr.p->logPartRec;
- execLogComp(signal);
- return;
-}//Dblqh::closeExecSrCompletedLab()
-
-/* --------------------------------------------------------------------------
- * ONE OF THE LOG PARTS HAVE COMPLETED EXECUTING THE LOG. CHECK IF ALL LOG
- * PARTS ARE COMPLETED. IF SO START SENDING EXEC_FRAGCONF AND EXEC_SRCONF.
- * ------------------------------------------------------------------------- */
-void Dblqh::execLogComp(Signal* signal)
-{
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_COMPLETED;
- /* ------------------------------------------------------------------------
- * WE MUST RELEASE THE TC CONNECT RECORD HERE SO THAT IT CAN BE REUSED.
- * ----------------------------------------------------------------------- */
- tcConnectptr.i = logPartPtr.p->logTcConrec;
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- releaseTcrecLog(signal, tcConnectptr);
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_COMPLETED) {
- if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_STARTED) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- } else {
- jam();
- /* ------------------------------------------------------------------
- * THIS LOG PART WAS NOT COMPLETED YET. EXIT AND WAIT FOR IT
- * TO COMPLETE
- * ----------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * ALL LOG PARTS HAVE COMPLETED THE EXECUTION OF THE LOG. WE CAN NOW START
- * SENDING THE EXEC_FRAGCONF SIGNALS TO ALL INVOLVED FRAGMENTS.
- * ----------------------------------------------------------------------- */
- jam();
- c_lcp_complete_fragments.first(fragptr);
- signal->theData[0] = ZSEND_EXEC_CONF;
- signal->theData[1] = fragptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//Dblqh::execLogComp()
-
-/* --------------------------------------------------------------------------
- * GO THROUGH THE FRAGMENT RECORDS TO DEDUCE TO WHICH SHALL BE SENT
- * EXEC_FRAGCONF AFTER COMPLETING THE EXECUTION OF THE LOG.
- * ------------------------------------------------------------------------- */
-void Dblqh::sendExecConf(Signal* signal)
-{
- jamEntry();
- fragptr.i = signal->theData[0];
- Uint32 loopCount = 0;
- while (fragptr.i != RNIL) {
- c_lcp_complete_fragments.getPtr(fragptr);
- Uint32 next = fragptr.p->nextList;
- if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
- jam();
- ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
- for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
- jam();
- signal->theData[0] = fragptr.p->execSrUserptr[i];
- sendSignal(fragptr.p->execSrBlockref[i], GSN_EXEC_FRAGCONF,
- signal, 1, JBB);
- }//for
- fragptr.p->execSrNoReplicas = 0;
- }//if
- loopCount++;
- if (loopCount > 20) {
- jam();
- signal->theData[0] = ZSEND_EXEC_CONF;
- signal->theData[1] = next;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- } else {
- jam();
- fragptr.i = next;
- }//if
- }//while
- /* ----------------------------------------------------------------------
- * WE HAVE NOW SENT ALL EXEC_FRAGCONF. NOW IT IS TIME TO SEND
- * EXEC_SRCONF TO ALL NODES.
- * --------------------------------------------------------------------- */
- srPhase3Comp(signal);
-}//Dblqh::sendExecConf()
-
-/* --------------------------------------------------------------------------
- * PHASE 3 HAS NOW COMPLETED. INFORM ALL OTHER NODES OF THIS EVENT.
- * ------------------------------------------------------------------------- */
-void Dblqh::srPhase3Comp(Signal* signal)
-{
- jamEntry();
-
- signal->theData[0] = cownNodeid;
- NodeReceiverGroup rg(DBLQH, m_sr_nodes);
- sendSignal(rg, GSN_EXEC_SRCONF, signal, 1, JBB);
- return;
-}//Dblqh::srPhase3Comp()
-
-/* ##########################################################################
- * SYSTEM RESTART PHASE FOUR MODULE
- * THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
- *
- * THIS MODULE SETS UP THE HEAD AND TAIL POINTERS OF THE LOG PARTS IN THE
- * FRAGMENT LOG. WHEN IT IS COMPLETED IT REPORTS TO THE MASTER DIH THAT
- * IT HAS COMPLETED THE PART OF THE SYSTEM RESTART WHERE THE DATABASE IS
- * LOADED.
- * IT ALSO OPENS THE CURRENT LOG FILE AND THE NEXT AND SETS UP THE FIRST
- * LOG PAGE WHERE NEW LOG DATA IS TO BE INSERTED WHEN THE SYSTEM STARTS
- * AGAIN.
- *
- * THIS PART IS ACTUALLY EXECUTED FOR ALL RESTART TYPES.
- * ######################################################################### */
-void Dblqh::initFourth(Signal* signal)
-{
- LogFileRecordPtr locLogFilePtr;
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- crestartNewestGci = 1;
- crestartOldestGci = 1;
- /* ------------------------------------------------------------------------
- * INITIALISE LOG PART AND LOG FILES AS NEEDED.
- * ----------------------------------------------------------------------- */
- logPartPtr.p->headFileNo = 0;
- logPartPtr.p->headPageNo = 1;
- logPartPtr.p->headPageIndex = ZPAGE_HEADER_SIZE + 2;
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
- logPartPtr.p->logTailFileNo = 0;
- logPartPtr.p->logTailMbyte = 0;
- locLogFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
- openFileRw(signal, locLogFilePtr);
- return;
-}//Dblqh::initFourth()
-
-void Dblqh::openSrFourthPhaseLab(Signal* signal)
-{
- /* ------------------------------------------------------------------------
- * WE HAVE NOW OPENED THE HEAD LOG FILE WE WILL NOW START READING IT
- * FROM THE HEAD MBYTE TO FIND THE NEW HEAD OF THE LOG.
- * ----------------------------------------------------------------------- */
- readSinglePage(signal, logPartPtr.p->headPageNo);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_PHASE;
- return;
-}//Dblqh::openSrFourthPhaseLab()
-
-void Dblqh::readSrFourthPhaseLab(Signal* signal)
-{
- if(c_diskless){
- jam();
- logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
- }
-
- /* ------------------------------------------------------------------------
- * INITIALISE ALL LOG PART INFO AND LOG FILE INFO THAT IS NEEDED TO
- * START UP THE SYSTEM.
- * ------------------------------------------------------------------------
- * INITIALISE THE NEWEST GLOBAL CHECKPOINT IDENTITY AND THE NEWEST
- * COMPLETED GLOBAL CHECKPOINT IDENITY AS THE NEWEST THAT WAS RESTARTED.
- * ------------------------------------------------------------------------
- * INITIALISE THE HEAD PAGE INDEX IN THIS PAGE.
- * ASSIGN IT AS THE CURRENT LOGPAGE.
- * ASSIGN THE FILE AS THE CURRENT LOG FILE.
- * ASSIGN THE CURRENT FILE NUMBER FROM THE CURRENT LOG FILE AND THE NEXT
- * FILE NUMBER FROM THE NEXT LOG FILE.
- * ASSIGN THE CURRENT FILEPAGE FROM HEAD PAGE NUMBER.
- * ASSIGN THE CURRENT MBYTE BY DIVIDING PAGE NUMBER BY 128.
- * INITIALISE LOG LAP TO BE THE LOG LAP AS FOUND IN THE HEAD PAGE.
- * WE HAVE TO CALCULATE THE NUMBER OF REMAINING WORDS IN THIS MBYTE.
- * ----------------------------------------------------------------------- */
- cnewestGci = crestartNewestGci;
- cnewestCompletedGci = crestartNewestGci;
- logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
- logPartPtr.p->currentLogfile = logFilePtr.i;
- logFilePtr.p->filePosition = logPartPtr.p->headPageNo;
- logFilePtr.p->currentMbyte =
- logPartPtr.p->headPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
- logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
- logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
- logFilePtr.p->currentFilepage = logPartPtr.p->headPageNo;
- logFilePtr.p->currentLogpage = logPagePtr.i;
-
- initLogpage(signal);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPartPtr.p->headPageIndex;
- logFilePtr.p->remainingWordsInMbyte =
- ((
- ((logFilePtr.p->currentMbyte + 1) * ZPAGES_IN_MBYTE) -
- logFilePtr.p->currentFilepage) *
- (ZPAGE_SIZE - ZPAGE_HEADER_SIZE)) -
- (logPartPtr.p->headPageIndex - ZPAGE_HEADER_SIZE);
- /* ------------------------------------------------------------------------
- * THE NEXT STEP IS TO OPEN THE NEXT LOG FILE (IF THERE IS ONE).
- * ----------------------------------------------------------------------- */
- if (logFilePtr.p->nextLogFile != logFilePtr.i) {
- LogFileRecordPtr locLogFilePtr;
- jam();
- locLogFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_NEXT;
- openFileRw(signal, locLogFilePtr);
- } else {
- jam();
- /* ----------------------------------------------------------------------
- * THIS CAN ONLY OCCUR IF WE HAVE ONLY ONE LOG FILE. THIS LOG FILE MUST
- * BE LOG FILE ZERO AND THAT IS THE FILE WE CURRENTLY HAVE READ.
- * THUS WE CAN CONTINUE IMMEDIATELY TO READ PAGE ZERO IN FILE ZERO.
- * --------------------------------------------------------------------- */
- openSrFourthZeroSkipInitLab(signal);
- return;
- }//if
- return;
-}//Dblqh::readSrFourthPhaseLab()
-
-void Dblqh::openSrFourthNextLab(Signal* signal)
-{
- /* ------------------------------------------------------------------------
- * WE MUST ALSO HAVE FILE 0 OPEN ALL THE TIME.
- * ----------------------------------------------------------------------- */
- logFilePtr.i = logPartPtr.p->firstLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- if (logFilePtr.p->logFileStatus == LogFileRecord::OPEN) {
- jam();
- openSrFourthZeroSkipInitLab(signal);
- return;
- } else {
- jam();
- logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_ZERO;
- openFileRw(signal, logFilePtr);
- }//if
- return;
-}//Dblqh::openSrFourthNextLab()
-
-void Dblqh::openSrFourthZeroLab(Signal* signal)
-{
- openSrFourthZeroSkipInitLab(signal);
- return;
-}//Dblqh::openSrFourthZeroLab()
-
-void Dblqh::openSrFourthZeroSkipInitLab(Signal* signal)
-{
- if (logFilePtr.i == logPartPtr.p->currentLogfile) {
- if (logFilePtr.p->currentFilepage == 0) {
- jam();
- /* -------------------------------------------------------------------
- * THE HEADER PAGE IN THE LOG IS PAGE ZERO IN FILE ZERO.
- * THIS SHOULD NEVER OCCUR.
- * ------------------------------------------------------------------- */
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- }//if
- readSinglePage(signal, 0);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_ZERO;
- return;
-}//Dblqh::openSrFourthZeroSkipInitLab()
-
-void Dblqh::readSrFourthZeroLab(Signal* signal)
-{
- logFilePtr.p->logPageZero = logPagePtr.i;
- // --------------------------------------------------------------------
- // This is moved to invalidateLogAfterLastGCI(), RT453.
- // signal->theData[0] = ZSR_FOURTH_COMP;
- // signal->theData[1] = logPartPtr.i;
- // sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- // --------------------------------------------------------------------
-
- // Need to invalidate log pages after the head of the log. RT 453. EDTJAMO.
- // Set the start of the invalidation.
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPartPtr.p->invalidateFileNo = logPartPtr.p->headFileNo;
- logPartPtr.p->invalidatePageNo = logPartPtr.p->headPageNo;
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_INVALIDATE;
-
- readFileInInvalidate(signal, true);
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
- return;
-}//Dblqh::readSrFourthZeroLab()
-
-/* --------------------------------------------------------------------------
- * ONE OF THE LOG PARTS HAVE COMPLETED PHASE FOUR OF THE SYSTEM RESTART.
- * CHECK IF ALL LOG PARTS ARE COMPLETED. IF SO SEND START_RECCONF
- * ------------------------------------------------------------------------- */
-void Dblqh::srFourthComp(Signal* signal)
-{
- jamEntry();
- logPartPtr.i = signal->theData[0];
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_COMPLETED;
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- jam();
- ptrAss(logPartPtr, logPartRecord);
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FOURTH_PHASE_COMPLETED) {
- if (logPartPtr.p->logPartState != LogPartRecord::SR_FOURTH_PHASE_STARTED) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- } else {
- jam();
- /* ------------------------------------------------------------------
- * THIS LOG PART WAS NOT COMPLETED YET.
- * EXIT AND WAIT FOR IT TO COMPLETE
- * ----------------------------------------------------------------- */
- return;
- }//if
- }//if
- }//for
- /* ------------------------------------------------------------------------
- * ALL LOG PARTS HAVE COMPLETED PHASE FOUR OF THE SYSTEM RESTART.
- * WE CAN NOW SEND START_RECCONF TO THE MASTER DIH IF IT WAS A
- * SYSTEM RESTART. OTHERWISE WE WILL CONTINUE WITH AN INITIAL START.
- * SET LOG PART STATE TO IDLE TO
- * INDICATE THAT NOTHING IS GOING ON IN THE LOG PART.
- * ----------------------------------------------------------------------- */
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->logPartState = LogPartRecord::IDLE;
- }//for
-
- if ((cstartType == NodeState::ST_INITIAL_START) ||
- (cstartType == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
-
- ndbrequire(cinitialStartOngoing == ZTRUE);
- cinitialStartOngoing = ZFALSE;
-
- checkStartCompletedLab(signal);
- return;
- } else if ((cstartType == NodeState::ST_NODE_RESTART) ||
- (cstartType == NodeState::ST_SYSTEM_RESTART)) {
- jam();
-
- if(cstartType == NodeState::ST_SYSTEM_RESTART)
- {
- jam();
- if (c_lcp_complete_fragments.first(fragptr))
- {
- jam();
- signal->theData[0] = ZENABLE_EXPAND_CHECK;
- signal->theData[1] = fragptr.i;
- sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
- }
- cstartRecReq = 2;
- StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
- conf->startingNodeId = getOwnNodeId();
- sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
- StartRecConf::SignalLength, JBB);
- } else {
- ndbrequire(false);
- }//if
- return;
-}//Dblqh::srFourthComp()
-
-/* ######################################################################### */
-/* ####### ERROR MODULE ####### */
-/* */
-/* ######################################################################### */
-
-/*---------------------------------------------------------------------------*/
-/* AN ERROR OCCURRED THAT WE WILL NOT TREAT AS SYSTEM ERROR. MOST OFTEN THIS */
-/* WAS CAUSED BY AN ERRONEUS SIGNAL SENT BY ANOTHER NODE. WE DO NOT WISH TO */
-/* CRASH BECAUSE OF FAULTS IN OTHER NODES. THUS WE ONLY REPORT A WARNING. */
-/* THIS IS CURRENTLY NOT IMPLEMENTED AND FOR THE MOMENT WE GENERATE A SYSTEM */
-/* ERROR SINCE WE WANT TO FIND FAULTS AS QUICKLY AS POSSIBLE IN A TEST PHASE.*/
-/* IN A LATER PHASE WE WILL CHANGE THIS TO BE A WARNING MESSAGE INSTEAD. */
-/*---------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------*/
-/* THIS TYPE OF ERROR SHOULD NOT GENERATE A SYSTEM ERROR IN A PRODUCT */
-/* RELEASE. THIS IS A TEMPORARY SOLUTION DURING TEST PHASE TO QUICKLY */
-/* FIND ERRORS. NORMALLY THIS SHOULD GENERATE A WARNING MESSAGE ONTO */
-/* SOME ERROR LOGGER. THIS WILL LATER BE IMPLEMENTED BY SOME SIGNAL. */
-/*---------------------------------------------------------------------------*/
-/* ------ SYSTEM ERROR SITUATIONS ------- */
-/* IN SITUATIONS WHERE THE STATE IS ERRONEOUS OR IF THE ERROR OCCURS IN */
-/* THE COMMIT, COMPLETE OR ABORT PHASE, WE PERFORM A CRASH OF THE AXE VM*/
-/*---------------------------------------------------------------------------*/
-
-void Dblqh::systemErrorLab(Signal* signal, int line)
-{
- systemError(signal, line);
- progError(line, NDBD_EXIT_NDBREQUIRE);
-/*************************************************************************>*/
-/* WE WANT TO INVOKE AN IMMEDIATE ERROR HERE SO WE GET THAT BY */
-/* INSERTING A CERTAIN POINTER OUT OF RANGE. */
-/*************************************************************************>*/
-}//Dblqh::systemErrorLab()
-
-/* ------- ERROR SITUATIONS ------- */
-
-void Dblqh::aiStateErrorCheckLab(Signal* signal, Uint32* dataPtr, Uint32 length)
-{
- ndbrequire(tcConnectptr.p->abortState != TcConnectionrec::ABORT_IDLE);
- if (tcConnectptr.p->transactionState != TcConnectionrec::IDLE) {
- jam();
-/*************************************************************************>*/
-/* TRANSACTION ABORT IS ONGOING. IT CAN STILL BE A PART OF AN */
-/* OPERATION THAT SHOULD CONTINUE SINCE THE TUPLE HAS NOT ARRIVED */
-/* YET. THIS IS POSSIBLE IF ACTIVE CREATION OF THE FRAGMENT IS */
-/* ONGOING. */
-/*************************************************************************>*/
- if (tcConnectptr.p->activeCreat == Fragrecord::AC_IGNORED) {
- jam();
-/*************************************************************************>*/
-/* ONGOING ABORTS DURING ACTIVE CREATION MUST SAVE THE ATTRIBUTE INFO*/
-/* SO THAT IT CAN BE SENT TO THE NEXT NODE IN THE COMMIT CHAIN. THIS */
-/* IS NEEDED SINCE ALL ABORTS DURING CREATION OF A FRAGMENT ARE NOT */
-/* REALLY ERRORS. A MISSING TUPLE TO BE UPDATED SIMPLY MEANS THAT */
-/* IT HASN'T BEEN TRANSFERRED TO THE NEW REPLICA YET. */
-/*************************************************************************>*/
-/*************************************************************************>*/
-/* AFTER THIS ERROR THE ABORT MUST BE COMPLETED. TO ENSURE THIS SET */
-/* ACTIVE CREATION TO FALSE. THIS WILL ENSURE THAT THE ABORT IS */
-/* COMPLETED. */
-/*************************************************************************>*/
- if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
- jam();
- if (tcConnectptr.p->transactionState ==
- TcConnectionrec::WAIT_AI_AFTER_ABORT) {
- if (tcConnectptr.p->currTupAiLen == tcConnectptr.p->totReclenAi) {
- jam();
-/*************************************************************************>*/
-/* WE WERE WAITING FOR MORE ATTRIBUTE INFO AFTER A SUCCESSFUL ABORT */
-/* IN ACTIVE CREATION STATE. THE TRANSACTION SHOULD CONTINUE AS IF */
-/* IT WAS COMMITTED. NOW ALL INFO HAS ARRIVED AND WE CAN CONTINUE */
-/* WITH NORMAL PROCESSING AS IF THE TRANSACTION WAS PREPARED. */
-/* SINCE THE FRAGMENT IS UNDER CREATION WE KNOW THAT LOGGING IS */
-/* DISABLED. WE STILL HAVE TO CATER FOR DIRTY OPERATION OR NOT. */
-/*************************************************************************>*/
- tcConnectptr.p->abortState = TcConnectionrec::ABORT_IDLE;
- rwConcludedAiLab(signal);
- return;
- } else {
- ndbrequire(tcConnectptr.p->currTupAiLen < tcConnectptr.p->totReclenAi);
- jam();
- return; /* STILL WAITING FOR MORE ATTRIBUTE INFO */
- }//if
- }//if
- } else {
- jam();
-/*************************************************************************>*/
-/* AFTER THIS ERROR THE ABORT MUST BE COMPLETED. TO ENSURE THIS SET */
-/* ACTIVE CREATION TO ABORT. THIS WILL ENSURE THAT THE ABORT IS */
-/* COMPLETED AND THAT THE ERROR CODE IS PROPERLY SET */
-/*************************************************************************>*/
- tcConnectptr.p->errorCode = terrorCode;
- tcConnectptr.p->activeCreat = Fragrecord::AC_NORMAL;
- if (tcConnectptr.p->transactionState ==
- TcConnectionrec::WAIT_AI_AFTER_ABORT) {
- jam();
-/*************************************************************************>*/
-/* ABORT IS ALREADY COMPLETED. WE NEED TO RESTART IT FROM WHERE IT */
-/* WAS INTERRUPTED. */
-/*************************************************************************>*/
- continueAbortLab(signal);
- return;
- } else {
- jam();
- return;
-/*************************************************************************>*/
-// Abort is ongoing. It will complete since we set the activeCreat = ZFALSE
-/*************************************************************************>*/
- }//if
- }//if
- }//if
- }//if
-/*************************************************************************>*/
-/* TRANSACTION HAVE BEEN ABORTED. THUS IGNORE ALL SIGNALS BELONGING TO IT. */
-/*************************************************************************>*/
- return;
-}//Dblqh::aiStateErrorCheckLab()
-
-void Dblqh::takeOverErrorLab(Signal* signal)
-{
- terrorCode = ZTAKE_OVER_ERROR;
- abortErrorLab(signal);
- return;
-}//Dblqh::takeOverErrorLab()
-
-/* ##########################################################################
- * TEST MODULE
- * ######################################################################### */
-#ifdef VM_TRACE
-void Dblqh::execTESTSIG(Signal* signal)
-{
- jamEntry();
- Uint32 userpointer = signal->theData[0];
- BlockReference userblockref = signal->theData[1];
- Uint32 testcase = signal->theData[2];
-
- signal->theData[0] = userpointer;
- signal->theData[1] = cownref;
- signal->theData[2] = testcase;
- sendSignal(userblockref, GSN_TESTSIG, signal, 25, JBB);
- return;
-}//Dblqh::execTESTSIG()
-
-/* *************** */
-/* MEMCHECKREQ > */
-/* *************** */
-/* ************************************************************************>>
- * THIS SIGNAL IS PURELY FOR TESTING PURPOSES. IT CHECKS THE FREE LIST
- * AND REPORTS THE NUMBER OF FREE RECORDS.
- * THIS CAN BE DONE TO ENSURE THAT NO RECORDS HAS BEEN LOST
- * ************************************************************************> */
-void Dblqh::execMEMCHECKREQ(Signal* signal)
-{
- Uint32* dataPtr = &signal->theData[0];
- jamEntry();
- BlockReference userblockref = signal->theData[0];
- Uint32 index = 0;
- for (Uint32 i = 0; i < 7; i++)
- dataPtr[i] = 0;
- addfragptr.i = cfirstfreeAddfragrec;
- while (addfragptr.i != RNIL) {
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- addfragptr.i = addfragptr.p->nextAddfragrec;
- dataPtr[index]++;
- }//while
- index++;
- attrinbufptr.i = cfirstfreeAttrinbuf;
- while (attrinbufptr.i != RNIL) {
- ptrCheckGuard(attrinbufptr, cattrinbufFileSize, attrbuf);
- attrinbufptr.i = attrinbufptr.p->attrbuf[ZINBUF_NEXT];
- dataPtr[index]++;
- }//while
- index++;
- databufptr.i = cfirstfreeDatabuf;
- while (databufptr.i != RNIL) {
- ptrCheckGuard(databufptr, cdatabufFileSize, databuf);
- databufptr.i = databufptr.p->nextDatabuf;
- dataPtr[index]++;
- }//while
- index++;
- for (tabptr.i = 0;
- tabptr.i < ctabrecFileSize;
- tabptr.i++) {
- ptrAss(tabptr, tablerec);
- if (tabptr.p->tableStatus == Tablerec::NOT_DEFINED) {
- dataPtr[index]++;
- }//if
- }//for
- index++;
- tcConnectptr.i = cfirstfreeTcConrec;
- while (tcConnectptr.i != RNIL) {
- ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- tcConnectptr.i = tcConnectptr.p->nextTcConnectrec;
- dataPtr[index]++;
- }//while
- sendSignal(userblockref, GSN_MEMCHECKCONF, signal, 10, JBB);
- return;
-}//Dblqh::execMEMCHECKREQ()
-
-#endif
-
-/* ************************************************************************* */
-/* ************************* STATEMENT BLOCKS ****************************** */
-/* ************************************************************************* */
-/* ========================================================================= */
-/* ====== BUILD LINKED LIST OF LOG PAGES AFTER RECEIVING FSREADCONF ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::buildLinkedLogPageList(Signal* signal)
-{
- LogPageRecordPtr bllLogPagePtr;
-
- arrGuard(lfoPtr.p->noPagesRw - 1, 16);
- arrGuard(lfoPtr.p->noPagesRw, 16);
- for (UintR tbllIndex = 0; tbllIndex < lfoPtr.p->noPagesRw; tbllIndex++) {
- jam();
- /* ----------------------------------------------------------------------
- * BUILD LINKED LIST BUT ALSO ENSURE THAT PAGE IS NOT SEEN AS DIRTY
- * INITIALLY.
- * --------------------------------------------------------------------- */
- bllLogPagePtr.i = lfoPtr.p->logPageArray[tbllIndex];
- ptrCheckGuard(bllLogPagePtr, clogPageFileSize, logPageRecord);
-
-// #if VM_TRACE
-// // Check logPage checksum before modifying it
-// Uint32 calcCheckSum = calcPageCheckSum(bllLogPagePtr);
-// Uint32 checkSum = bllLogPagePtr.p->logPageWord[ZPOS_CHECKSUM];
-// if (checkSum != calcCheckSum) {
-// ndbout << "Redolog: Checksum failure." << endl;
-// progError(__LINE__, NDBD_EXIT_NDBREQUIRE, "Redolog: Checksum failure.");
-// }
-// #endif
-
- bllLogPagePtr.p->logPageWord[ZNEXT_PAGE] =
- lfoPtr.p->logPageArray[tbllIndex + 1];
- bllLogPagePtr.p->logPageWord[ZPOS_DIRTY] = ZNOT_DIRTY;
- }//for
- bllLogPagePtr.i = lfoPtr.p->logPageArray[lfoPtr.p->noPagesRw - 1];
- ptrCheckGuard(bllLogPagePtr, clogPageFileSize, logPageRecord);
- bllLogPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
-}//Dblqh::buildLinkedLogPageList()
-
-/* =========================================================================
- * ======= CHANGE TO NEXT MBYTE IN LOG =======
- *
- * ========================================================================= */
-void Dblqh::changeMbyte(Signal* signal)
-{
- writeNextLog(signal);
- writeFileDescriptor(signal);
-}//Dblqh::changeMbyte()
-
-/* ========================================================================= */
-/* ====== CHECK IF THIS COMMIT LOG RECORD IS TO BE EXECUTED ======= */
-/* */
-/* SUBROUTINE SHORT NAME = CEL */
-/* ========================================================================= */
-Uint32 Dblqh::checkIfExecLog(Signal* signal)
-{
- tabptr.i = tcConnectptr.p->tableref;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- if (getFragmentrec(signal, tcConnectptr.p->fragmentid) &&
- (table_version_major(tabptr.p->schemaVersion) == table_version_major(tcConnectptr.p->schemaVersion))) {
- if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
- if (fragptr.p->execSrNoReplicas > logPartPtr.p->execSrExecuteIndex) {
- ndbrequire((fragptr.p->execSrNoReplicas - 1) < 4);
- for (Uint32 i = logPartPtr.p->execSrExecuteIndex;
- i < fragptr.p->execSrNoReplicas;
- i++) {
- jam();
- if (tcConnectptr.p->gci >= fragptr.p->execSrStartGci[i]) {
- if (tcConnectptr.p->gci <= fragptr.p->execSrLastGci[i]) {
- jam();
- logPartPtr.p->execSrExecuteIndex = i;
- return ZOK;
- }//if
- }//if
- }//for
- }//if
- }//if
- }//if
- return ZNOT_OK;
-}//Dblqh::checkIfExecLog()
-
-/* ========================================================================= */
-/* == CHECK IF THERE IS LESS THAN 192 KBYTE IN THE BUFFER PLUS INCOMING === */
-/* READS ALREADY STARTED. IF SO IS THE CASE THEN START ANOTHER READ IF */
-/* THERE ARE MORE PAGES IN THIS MBYTE. */
-/* */
-/* ========================================================================= */
-void Dblqh::checkReadExecSr(Signal* signal)
-{
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG;
- logPartPtr.p->execSrPagesRead = logPartPtr.p->execSrPagesRead + 8;
- logPartPtr.p->execSrPagesReading = logPartPtr.p->execSrPagesReading - 8;
- if ((logPartPtr.p->execSrPagesRead + logPartPtr.p->execSrPagesReading) <
- ZREAD_AHEAD_SIZE) {
- jam();
- /* ----------------------------------------------------------------------
- * WE HAVE LESS THAN 64 KBYTE OF LOG PAGES REMAINING IN MEMORY OR ON
- * ITS WAY TO MAIN MEMORY. READ IN 8 MORE PAGES.
- * --------------------------------------------------------------------- */
- if ((logPartPtr.p->execSrPagesRead + logPartPtr.p->execSrPagesExecuted) <
- ZPAGES_IN_MBYTE) {
- jam();
- /* --------------------------------------------------------------------
- * THERE ARE MORE PAGES TO READ IN THIS MBYTE. READ THOSE FIRST
- * IF >= ZPAGES_IN_MBYTE THEN THERE ARE NO MORE PAGES TO READ. THUS
- * WE PROCEED WITH EXECUTION OF THE LOG.
- * ------------------------------------------------------------------- */
- readExecSr(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_WAIT_READ_EXEC_SR;
- }//if
- }//if
-}//Dblqh::checkReadExecSr()
-
-/* ========================================================================= */
-/* ==== CHECK IF START OF NEW FRAGMENT IS COMPLETED AND WE CAN ======= */
-/* ==== GET THE START GCI ======= */
-/* */
-/* SUBROUTINE SHORT NAME = CTC */
-/* ========================================================================= */
-void Dblqh::checkScanTcCompleted(Signal* signal)
-{
- tcConnectptr.p->logWriteState = TcConnectionrec::NOT_STARTED;
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- fragptr.p->activeTcCounter = fragptr.p->activeTcCounter - 1;
- if (fragptr.p->activeTcCounter == 0) {
- jam();
- fragptr.p->startGci = cnewestGci + 1;
- tabptr.i = tcConnectptr.p->tableref;
- ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
- sendCopyActiveConf(signal, tcConnectptr.p->tableref);
- }//if
-}//Dblqh::checkScanTcCompleted()
-
-/* ------------------------------------------------------------------------- */
-/* ------ CLOSE A FILE DURING EXECUTION OF FRAGMENT LOG ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::closeFile(Signal* signal,
- LogFileRecordPtr clfLogFilePtr, Uint32 line)
-{
- signal->theData[0] = clfLogFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = clfLogFilePtr.i;
- signal->theData[3] = ZCLOSE_NO_DELETE;
- signal->theData[4] = line;
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 5, JBA);
-}//Dblqh::closeFile()
-
-
-/* ---------------------------------------------------------------- */
-/* ---------------- A LOG PAGE HAVE BEEN COMPLETED ---------------- */
-/* */
-/* SUBROUTINE SHORT NAME = CLP */
-// Input Pointers:
-// logFilePtr
-// logPagePtr
-// logPartPtr
-// Defines lfoPtr
-/* ---------------------------------------------------------------- */
-void Dblqh::completedLogPage(Signal* signal, Uint32 clpType, Uint32 place)
-{
- LogPageRecordPtr clpLogPagePtr;
- LogPageRecordPtr wlpLogPagePtr;
- UintR twlpNoPages;
- UintR twlpType;
-
- if (logFilePtr.p->firstFilledPage == RNIL) {
- jam();
- logFilePtr.p->firstFilledPage = logPagePtr.i;
- } else {
- jam();
- clpLogPagePtr.i = logFilePtr.p->lastFilledPage;
- ptrCheckGuard(clpLogPagePtr, clogPageFileSize, logPageRecord);
- clpLogPagePtr.p->logPageWord[ZNEXT_PAGE] = logPagePtr.i;
- }//if
- logFilePtr.p->lastFilledPage = logPagePtr.i;
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
- logFilePtr.p->noLogpagesInBuffer = logFilePtr.p->noLogpagesInBuffer + 1;
- if (logFilePtr.p->noLogpagesInBuffer != ZMAX_PAGES_WRITTEN) {
- if (clpType != ZLAST_WRITE_IN_FILE) {
- if (clpType != ZENFORCE_WRITE) {
- jam();
- return;
- }//if
- }//if
- }//if
- twlpType = clpType;
-/* ------------------------------------------------------------------------- */
-/* ------ WRITE A SET OF LOG PAGES TO DISK ------- */
-/* */
-/* SUBROUTINE SHORT NAME: WLP */
-/* ------------------------------------------------------------------------- */
- seizeLfo(signal);
- initLfo(signal);
- Uint32* dataPtr = &signal->theData[6];
- twlpNoPages = 0;
- wlpLogPagePtr.i = logFilePtr.p->firstFilledPage;
- do {
- dataPtr[twlpNoPages] = wlpLogPagePtr.i;
- twlpNoPages++;
- ptrCheckGuard(wlpLogPagePtr, clogPageFileSize, logPageRecord);
-
- writeDbgInfoPageHeader(wlpLogPagePtr, place,
- logFilePtr.p->filePosition + twlpNoPages - 1,
- ZPAGE_SIZE);
- // Calculate checksum for page
- wlpLogPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(wlpLogPagePtr);
- wlpLogPagePtr.i = wlpLogPagePtr.p->logPageWord[ZNEXT_PAGE];
- } while (wlpLogPagePtr.i != RNIL);
- ndbrequire(twlpNoPages < 9);
- dataPtr[twlpNoPages] = logFilePtr.p->filePosition;
-/* -------------------------------------------------- */
-/* SET TIMER ON THIS LOG PART TO SIGNIFY THAT A */
-/* LOG RECORD HAS BEEN SENT AT THIS TIME. */
-/* -------------------------------------------------- */
- logPartPtr.p->logPartTimer = logPartPtr.p->logTimer;
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- if (twlpType == ZLAST_WRITE_IN_FILE) {
- jam();
- signal->theData[3] = ZLIST_OF_MEM_PAGES_SYNCH;
- } else {
- jam();
- signal->theData[3] = ZLIST_OF_MEM_PAGES;
- }//if
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = twlpNoPages;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 15, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("writing %d pages at part: %u file: %u pos: %u",
- twlpNoPages,
- logPartPtr.i,
- logFilePtr.p->fileNo,
- logFilePtr.p->filePosition);
-
- if (twlpType == ZNORMAL) {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::ACTIVE_WRITE_LOG;
- } else if (twlpType == ZLAST_WRITE_IN_FILE) {
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::LAST_WRITE_IN_FILE;
- } else {
- ndbrequire(twlpType == ZENFORCE_WRITE);
- jam();
- lfoPtr.p->lfoState = LogFileOperationRecord::ACTIVE_WRITE_LOG;
- }//if
- /* ----------------------------------------------------------------------- */
- /* ------ MOVE PAGES FROM LOG FILE TO LFO RECORD ------- */
- /* */
- /* ----------------------------------------------------------------------- */
- /* -------------------------------------------------- */
- /* MOVE PAGES TO LFO RECORD AND REMOVE THEM */
- /* FROM LOG FILE RECORD. */
- /* -------------------------------------------------- */
- lfoPtr.p->firstLfoPage = logFilePtr.p->firstFilledPage;
- logFilePtr.p->firstFilledPage = RNIL;
- logFilePtr.p->lastFilledPage = RNIL;
- logFilePtr.p->noLogpagesInBuffer = 0;
-
- lfoPtr.p->noPagesRw = twlpNoPages;
- lfoPtr.p->lfoPageNo = logFilePtr.p->filePosition;
- lfoPtr.p->lfoWordWritten = ZPAGE_SIZE - 1;
- logFilePtr.p->filePosition += twlpNoPages;
-}//Dblqh::completedLogPage()
-
-/* ---------------------------------------------------------------- */
-/* ---------------- DELETE FRAGMENT RECORD ------------------------ */
-/* */
-/* SUBROUTINE SHORT NAME = DFR */
-/* ---------------------------------------------------------------- */
-void Dblqh::deleteFragrec(Uint32 fragId)
-{
- Uint32 indexFound= RNIL;
- fragptr.i = RNIL;
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragid[i] == fragId) {
- fragptr.i = tabptr.p->fragrec[i];
- indexFound = i;
- break;
- }//if
- }//for
- if (fragptr.i != RNIL) {
- jam();
- c_fragment_pool.getPtr(fragptr);
- tabptr.p->fragid[indexFound] = ZNIL;
- tabptr.p->fragrec[indexFound] = RNIL;
- fragptr.p->fragStatus = Fragrecord::FREE;
- c_fragment_pool.release(fragptr);
- }//if
-}//Dblqh::deleteFragrec()
-
-/* ------------------------------------------------------------------------- */
-/* ------- FIND LOG FILE RECORD GIVEN FILE NUMBER ------- */
-/* */
-/* INPUT: TFLF_FILE_NO THE FILE NUMBER */
-/* FLF_LOG_PART_PTR THE LOG PART RECORD */
-/* OUTPUT: FLF_LOG_FILE_PTR THE FOUND LOG FILE RECORD */
-/* SUBROUTINE SHORT NAME = FLF */
-/* ------------------------------------------------------------------------- */
-void Dblqh::findLogfile(Signal* signal,
- Uint32 fileNo,
- LogPartRecordPtr flfLogPartPtr,
- LogFileRecordPtr* parLogFilePtr)
-{
- LogFileRecordPtr locLogFilePtr;
- locLogFilePtr.i = flfLogPartPtr.p->firstLogfile;
- Uint32 loopCount = 0;
- while (true) {
- ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
- if (locLogFilePtr.p->fileNo == fileNo) {
- jam();
- ndbrequire(loopCount == fileNo);
- parLogFilePtr->i = locLogFilePtr.i;
- parLogFilePtr->p = locLogFilePtr.p;
- return;
- }//if
- locLogFilePtr.i = locLogFilePtr.p->nextLogFile;
- loopCount++;
- if (loopCount >= flfLogPartPtr.p->noLogFiles &&
- getNodeState().startLevel != NodeState::SL_STARTED)
- {
- goto error;
- }
- ndbrequire(loopCount < flfLogPartPtr.p->noLogFiles);
- }//while
-
-error:
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Unable to restart, failed while reading redo."
- " Likely invalid change of configuration");
- progError(__LINE__,
- NDBD_EXIT_INVALID_CONFIG,
- buf);
-}//Dblqh::findLogfile()
-
-/* ------------------------------------------------------------------------- */
-/* ------ FIND PAGE REFERENCE IN MEMORY BUFFER AT LOG EXECUTION ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::findPageRef(Signal* signal, CommitLogRecord* commitLogRecord)
-{
- UintR tfprIndex;
-
- logPagePtr.i = RNIL;
- if (ERROR_INSERTED(5020)) {
- // Force system to read page from disk
- return;
- }
- pageRefPtr.i = logPartPtr.p->lastPageRef;
- do {
- ptrCheckGuard(pageRefPtr, cpageRefFileSize, pageRefRecord);
- if (commitLogRecord->fileNo == pageRefPtr.p->prFileNo) {
- if (commitLogRecord->startPageNo >= pageRefPtr.p->prPageNo) {
- if (commitLogRecord->startPageNo < (Uint16) (pageRefPtr.p->prPageNo + 8)) {
- jam();
- tfprIndex = commitLogRecord->startPageNo - pageRefPtr.p->prPageNo;
- logPagePtr.i = pageRefPtr.p->pageRef[tfprIndex];
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- return;
- }//if
- }//if
- }//if
- pageRefPtr.i = pageRefPtr.p->prPrev;
- } while (pageRefPtr.i != RNIL);
-}//Dblqh::findPageRef()
-
-/* ------------------------------------------------------------------------- */
-/* ------ GET FIRST OPERATION QUEUED FOR LOGGING ------- */
-/* */
-/* SUBROUTINE SHORT NAME = GFL */
-/* ------------------------------------------------------------------------- */
-void Dblqh::getFirstInLogQueue(Signal* signal)
-{
- TcConnectionrecPtr gflTcConnectptr;
-/* -------------------------------------------------- */
-/* GET THE FIRST FROM THE LOG QUEUE AND REMOVE */
-/* IT FROM THE QUEUE. */
-/* -------------------------------------------------- */
- gflTcConnectptr.i = logPartPtr.p->firstLogQueue;
- ptrCheckGuard(gflTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- logPartPtr.p->firstLogQueue = gflTcConnectptr.p->nextTcLogQueue;
- if (logPartPtr.p->firstLogQueue == RNIL) {
- jam();
- logPartPtr.p->lastLogQueue = RNIL;
- }//if
-}//Dblqh::getFirstInLogQueue()
-
-/* ---------------------------------------------------------------- */
-/* ---------------- GET FRAGMENT RECORD --------------------------- */
-/* INPUT: TFRAGID FRAGMENT ID LOOKING FOR */
-/* TABPTR TABLE ID */
-/* SUBROUTINE SHORT NAME = GFR */
-/* ---------------------------------------------------------------- */
-bool Dblqh::getFragmentrec(Signal* signal, Uint32 fragId)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragid[i] == fragId) {
- fragptr.i = tabptr.p->fragrec[i];
- c_fragment_pool.getPtr(fragptr);
- return true;
- }//if
- }//for
- return false;
-}//Dblqh::getFragmentrec()
-
-/* ========================================================================= */
-/* ====== INITIATE FRAGMENT RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseAddfragrec(Signal* signal)
-{
- if (caddfragrecFileSize != 0) {
- for (addfragptr.i = 0; addfragptr.i < caddfragrecFileSize; addfragptr.i++) {
- ptrAss(addfragptr, addFragRecord);
- addfragptr.p->addfragStatus = AddFragRecord::FREE;
- addfragptr.p->nextAddfragrec = addfragptr.i + 1;
- }//for
- addfragptr.i = caddfragrecFileSize - 1;
- ptrAss(addfragptr, addFragRecord);
- addfragptr.p->nextAddfragrec = RNIL;
- cfirstfreeAddfragrec = 0;
- } else {
- jam();
- cfirstfreeAddfragrec = RNIL;
- }//if
-}//Dblqh::initialiseAddfragrec()
-
-/* ========================================================================= */
-/* ====== INITIATE ATTRIBUTE IN AND OUT DATA BUFFER ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseAttrbuf(Signal* signal)
-{
- if (cattrinbufFileSize != 0) {
- for (attrinbufptr.i = 0;
- attrinbufptr.i < cattrinbufFileSize;
- attrinbufptr.i++) {
- refresh_watch_dog();
- ptrAss(attrinbufptr, attrbuf);
- attrinbufptr.p->attrbuf[ZINBUF_NEXT] = attrinbufptr.i + 1;
- }//for
- /* NEXT ATTRINBUF */
- attrinbufptr.i = cattrinbufFileSize - 1;
- ptrAss(attrinbufptr, attrbuf);
- attrinbufptr.p->attrbuf[ZINBUF_NEXT] = RNIL; /* NEXT ATTRINBUF */
- cfirstfreeAttrinbuf = 0;
- } else {
- jam();
- cfirstfreeAttrinbuf = RNIL;
- }//if
-}//Dblqh::initialiseAttrbuf()
-
-/* ========================================================================= */
-/* ====== INITIATE DATA BUFFER ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseDatabuf(Signal* signal)
-{
- if (cdatabufFileSize != 0) {
- for (databufptr.i = 0; databufptr.i < cdatabufFileSize; databufptr.i++) {
- refresh_watch_dog();
- ptrAss(databufptr, databuf);
- databufptr.p->nextDatabuf = databufptr.i + 1;
- }//for
- databufptr.i = cdatabufFileSize - 1;
- ptrAss(databufptr, databuf);
- databufptr.p->nextDatabuf = RNIL;
- cfirstfreeDatabuf = 0;
- } else {
- jam();
- cfirstfreeDatabuf = RNIL;
- }//if
-}//Dblqh::initialiseDatabuf()
-
-/* ========================================================================= */
-/* ====== INITIATE FRAGMENT RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseFragrec(Signal* signal)
-{
-
- SLList<Fragrecord> tmp(c_fragment_pool);
- while(tmp.seize(fragptr))
- {
- refresh_watch_dog();
- new (fragptr.p) Fragrecord();
- fragptr.p->fragStatus = Fragrecord::FREE;
- fragptr.p->execSrStatus = Fragrecord::IDLE;
- fragptr.p->srStatus = Fragrecord::SS_IDLE;
- }
- tmp.release();
-}//Dblqh::initialiseFragrec()
-
-/* ========================================================================= */
-/* ====== INITIATE FRAGMENT RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseGcprec(Signal* signal)
-{
- UintR tigpIndex;
-
- if (cgcprecFileSize != 0) {
- for (gcpPtr.i = 0; gcpPtr.i < cgcprecFileSize; gcpPtr.i++) {
- ptrAss(gcpPtr, gcpRecord);
- for (tigpIndex = 0; tigpIndex <= 3; tigpIndex++) {
- gcpPtr.p->gcpLogPartState[tigpIndex] = ZIDLE;
- gcpPtr.p->gcpSyncReady[tigpIndex] = ZFALSE;
- }//for
- }//for
- }//if
-}//Dblqh::initialiseGcprec()
-
-/* ========================================================================= */
-/* ====== INITIATE LCP RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseLcpRec(Signal* signal)
-{
- if (clcpFileSize != 0) {
- for (lcpPtr.i = 0; lcpPtr.i < clcpFileSize; lcpPtr.i++) {
- ptrAss(lcpPtr, lcpRecord);
- lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
- lcpPtr.p->lcpQueued = false;
- lcpPtr.p->reportEmpty = false;
- lcpPtr.p->firstFragmentFlag = false;
- lcpPtr.p->lastFragmentFlag = false;
- }//for
- }//if
-}//Dblqh::initialiseLcpRec()
-
-/* ========================================================================= */
-/* ====== INITIATE LOG FILE OPERATION RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseLfo(Signal* signal)
-{
- if (clfoFileSize != 0) {
- for (lfoPtr.i = 0; lfoPtr.i < clfoFileSize; lfoPtr.i++) {
- ptrAss(lfoPtr, logFileOperationRecord);
- lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
- lfoPtr.p->lfoTimer = 0;
- lfoPtr.p->nextLfo = lfoPtr.i + 1;
- }//for
- lfoPtr.i = clfoFileSize - 1;
- ptrAss(lfoPtr, logFileOperationRecord);
- lfoPtr.p->nextLfo = RNIL;
- cfirstfreeLfo = 0;
- } else {
- jam();
- cfirstfreeLfo = RNIL;
- }//if
-}//Dblqh::initialiseLfo()
-
-/* ========================================================================= */
-/* ====== INITIATE LOG FILE RECORD ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseLogFile(Signal* signal)
-{
- if (clogFileFileSize != 0) {
- for (logFilePtr.i = 0; logFilePtr.i < clogFileFileSize; logFilePtr.i++) {
- ptrAss(logFilePtr, logFileRecord);
- logFilePtr.p->nextLogFile = logFilePtr.i + 1;
- logFilePtr.p->logFileStatus = LogFileRecord::LFS_IDLE;
-
- logFilePtr.p->logLastPrepRef = new Uint32[clogFileSize];
- logFilePtr.p->logMaxGciCompleted = new Uint32[clogFileSize];
- logFilePtr.p->logMaxGciStarted = new Uint32[clogFileSize];
-
- if (logFilePtr.p->logLastPrepRef == 0 ||
- logFilePtr.p->logMaxGciCompleted == 0 ||
- logFilePtr.p->logMaxGciStarted == 0)
- {
- char buf[256];
- BaseString::snprintf(buf, sizeof(buf),
- "Failed to alloc mbyte(%u) arrays for logfile %u",
- clogFileSize, logFilePtr.i);
- progError(__LINE__, NDBD_EXIT_MEMALLOC, buf);
- }
-
- }//for
- logFilePtr.i = clogFileFileSize - 1;
- ptrAss(logFilePtr, logFileRecord);
- logFilePtr.p->nextLogFile = RNIL;
- cfirstfreeLogFile = 0;
- } else {
- jam();
- cfirstfreeLogFile = RNIL;
- }//if
-}//Dblqh::initialiseLogFile()
-
-/* ========================================================================= */
-/* ====== INITIATE LOG PAGES ======= */
-/* */
-/* ========================================================================= */
-void Dblqh::initialiseLogPage(Signal* signal)
-{
- if (clogPageFileSize != 0) {
- for (logPagePtr.i = 0; logPagePtr.i < clogPageFileSize; logPagePtr.i++) {
- refresh_watch_dog();
- ptrAss(logPagePtr, logPageRecord);
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = logPagePtr.i + 1;
- logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
- logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
- }//for
- logPagePtr.i = clogPageFileSize - 1;
- ptrAss(logPagePtr, logPageRecord);
- logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
- cfirstfreeLogPage = 0;
- } else {
- jam();
- cfirstfreeLogPage = RNIL;
- }//if
- cnoOfLogPages = clogPageFileSize;
-}//Dblqh::initialiseLogPage()
-
-/* =========================================================================
- * ====== INITIATE LOG PART RECORD =======
- *
- * ========================================================================= */
-void Dblqh::initialiseLogPart(Signal* signal)
-{
- for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
- ptrAss(logPartPtr, logPartRecord);
- logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_FALSE;
- logPartPtr.p->LogLqhKeyReqSent = ZFALSE;
- logPartPtr.p->logPartNewestCompletedGCI = (UintR)-1;
- }//for
-}//Dblqh::initialiseLogPart()
-
-void Dblqh::initialisePageRef(Signal* signal)
-{
- if (cpageRefFileSize != 0) {
- for (pageRefPtr.i = 0;
- pageRefPtr.i < cpageRefFileSize;
- pageRefPtr.i++) {
- ptrAss(pageRefPtr, pageRefRecord);
- pageRefPtr.p->prNext = pageRefPtr.i + 1;
- }//for
- pageRefPtr.i = cpageRefFileSize - 1;
- ptrAss(pageRefPtr, pageRefRecord);
- pageRefPtr.p->prNext = RNIL;
- cfirstfreePageRef = 0;
- } else {
- jam();
- cfirstfreePageRef = RNIL;
- }//if
-}//Dblqh::initialisePageRef()
-
-/* ==========================================================================
- * ======= INITIATE RECORDS =======
- *
- * TAKES CARE OF INITIATION OF ALL RECORDS IN THIS BLOCK.
- * ========================================================================= */
-void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data,
- Uint32 retRef, Uint32 retData)
-{
- Uint32 i;
- switch (data) {
- case 0:
- jam();
- m_sr_nodes.clear();
- m_sr_exec_sr_req.clear();
- m_sr_exec_sr_conf.clear();
- for (i = 0; i < 1024; i++) {
- ctransidHash[i] = RNIL;
- }//for
- for (i = 0; i < 4; i++) {
- cactiveCopy[i] = RNIL;
- }//for
- cnoActiveCopy = 0;
- ccurrentGcprec = RNIL;
- caddNodeState = ZFALSE;
- cstartRecReq = 0;
- cnewestGci = 0;
- cnewestCompletedGci = 0;
- crestartOldestGci = 0;
- crestartNewestGci = 0;
- csrPhaseStarted = ZSR_NO_PHASE_STARTED;
- csrPhasesCompleted = 0;
- cmasterDihBlockref = 0;
- cnoFragmentsExecSr = 0;
- clcpCompletedState = LCP_IDLE;
- csrExecUndoLogState = EULS_IDLE;
- c_lcpId = 0;
- cnoOfFragsCheckpointed = 0;
- break;
- case 1:
- jam();
- initialiseAddfragrec(signal);
- break;
- case 2:
- jam();
- initialiseAttrbuf(signal);
- break;
- case 3:
- jam();
- initialiseDatabuf(signal);
- break;
- case 4:
- jam();
- initialiseFragrec(signal);
- break;
- case 5:
- jam();
- initialiseGcprec(signal);
- initialiseLcpRec(signal);
- break;
- case 6:
- jam();
- initialiseLogPage(signal);
- break;
- case 7:
- jam();
- initialiseLfo(signal);
- break;
- case 8:
- jam();
- initialiseLogFile(signal);
- initialiseLogPart(signal);
- break;
- case 9:
- jam();
- initialisePageRef(signal);
- break;
- case 10:
- jam();
- initialiseScanrec(signal);
- break;
- case 11:
- jam();
- initialiseTabrec(signal);
- break;
- case 12:
- jam();
- initialiseTcNodeFailRec(signal);
- initialiseTcrec(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
-
- signal->theData[0] = ZINITIALISE_RECORDS;
- signal->theData[1] = data + 1;
- signal->theData[2] = 0;
- signal->theData[3] = retRef;
- signal->theData[4] = retData;
- sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 5, JBB);
-
- return;
-}//Dblqh::initialiseRecordsLab()
-
-/* ==========================================================================
- * ======= INITIATE TC CONNECTION RECORD =======
- *
- * ========================================================================= */
-void Dblqh::initialiseScanrec(Signal* signal)
-{
- ndbrequire(cscanrecFileSize > 1);
- DLList<ScanRecord> tmp(c_scanRecordPool);
- while (tmp.seize(scanptr)){
- //new (scanptr.p) ScanRecord();
- refresh_watch_dog();
- scanptr.p->scanType = ScanRecord::ST_IDLE;
- scanptr.p->scanState = ScanRecord::SCAN_FREE;
- scanptr.p->scanTcWaiting = ZFALSE;
- scanptr.p->nextHash = RNIL;
- scanptr.p->prevHash = RNIL;
- scanptr.p->scan_acc_index= 0;
- scanptr.p->scan_acc_attr_recs= 0;
- }
- tmp.release();
-}//Dblqh::initialiseScanrec()
-
-/* ==========================================================================
- * ======= INITIATE TABLE RECORD =======
- *
- * ========================================================================= */
-void Dblqh::initialiseTabrec(Signal* signal)
-{
- if (ctabrecFileSize != 0) {
- for (tabptr.i = 0; tabptr.i < ctabrecFileSize; tabptr.i++) {
- refresh_watch_dog();
- ptrAss(tabptr, tablerec);
- tabptr.p->tableStatus = Tablerec::NOT_DEFINED;
- tabptr.p->usageCount = 0;
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- tabptr.p->fragid[i] = ZNIL;
- tabptr.p->fragrec[i] = RNIL;
- }//for
- }//for
- }//if
-}//Dblqh::initialiseTabrec()
-
-/* ==========================================================================
- * ======= INITIATE TC CONNECTION RECORD =======
- *
- * ========================================================================= */
-void Dblqh::initialiseTcrec(Signal* signal)
-{
- if (ctcConnectrecFileSize != 0) {
- for (tcConnectptr.i = 0;
- tcConnectptr.i < ctcConnectrecFileSize;
- tcConnectptr.i++) {
- refresh_watch_dog();
- ptrAss(tcConnectptr, tcConnectionrec);
- tcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED;
- tcConnectptr.p->tcScanRec = RNIL;
- tcConnectptr.p->logWriteState = TcConnectionrec::NOT_STARTED;
- tcConnectptr.p->firstAttrinbuf = RNIL;
- tcConnectptr.p->lastAttrinbuf = RNIL;
- tcConnectptr.p->firstTupkeybuf = RNIL;
- tcConnectptr.p->lastTupkeybuf = RNIL;
- tcConnectptr.p->tcTimer = 0;
- tcConnectptr.p->nextTcConnectrec = tcConnectptr.i + 1;
- }//for
- tcConnectptr.i = ctcConnectrecFileSize - 1;
- ptrAss(tcConnectptr, tcConnectionrec);
- tcConnectptr.p->nextTcConnectrec = RNIL;
- cfirstfreeTcConrec = 0;
- } else {
- jam();
- cfirstfreeTcConrec = RNIL;
- }//if
-}//Dblqh::initialiseTcrec()
-
-/* ==========================================================================
- * ======= INITIATE TC CONNECTION RECORD =======
- *
- * ========================================================================= */
-void Dblqh::initialiseTcNodeFailRec(Signal* signal)
-{
- if (ctcNodeFailrecFileSize != 0) {
- for (tcNodeFailptr.i = 0;
- tcNodeFailptr.i < ctcNodeFailrecFileSize;
- tcNodeFailptr.i++) {
- ptrAss(tcNodeFailptr, tcNodeFailRecord);
- tcNodeFailptr.p->tcFailStatus = TcNodeFailRecord::TC_STATE_FALSE;
- }//for
- }//if
-}//Dblqh::initialiseTcNodeFailRec()
-
-/* ==========================================================================
- * ======= INITIATE FRAGMENT RECORD =======
- *
- * SUBROUTINE SHORT NAME = IF
- * ========================================================================= */
-void Dblqh::initFragrec(Signal* signal,
- Uint32 tableId,
- Uint32 fragId,
- Uint32 copyType)
-{
- new (fragptr.p) Fragrecord();
- fragptr.p->m_scanNumberMask.set(); // All is free
- fragptr.p->accBlockref = caccBlockref;
- fragptr.p->firstWaitQueue = RNIL;
- fragptr.p->lastWaitQueue = RNIL;
- fragptr.p->fragStatus = Fragrecord::DEFINED;
- fragptr.p->fragCopy = copyType;
- fragptr.p->tupBlockref = ctupBlockref;
- fragptr.p->tuxBlockref = ctuxBlockref;
- fragptr.p->logFlag = Fragrecord::STATE_TRUE;
- fragptr.p->lcpFlag = Fragrecord::LCP_STATE_TRUE;
- for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
- fragptr.p->lcpId[i] = 0;
- }//for
- fragptr.p->maxGciCompletedInLcp = 0;
- fragptr.p->maxGciInLcp = 0;
- fragptr.p->copyFragState = ZIDLE;
- fragptr.p->newestGci = cnewestGci;
- fragptr.p->tabRef = tableId;
- fragptr.p->fragId = fragId;
- fragptr.p->srStatus = Fragrecord::SS_IDLE;
- fragptr.p->execSrStatus = Fragrecord::IDLE;
- fragptr.p->execSrNoReplicas = 0;
- fragptr.p->fragDistributionKey = 0;
- fragptr.p->activeTcCounter = 0;
- fragptr.p->tableFragptr = RNIL;
-}//Dblqh::initFragrec()
-
-/* ==========================================================================
- * ======= INITIATE FRAGMENT RECORD FOR SYSTEM RESTART =======
- *
- * SUBROUTINE SHORT NAME = IFS
- * ========================================================================= */
-
-/* ==========================================================================
- * ======= INITIATE INFORMATION ABOUT GLOBAL CHECKPOINTS =======
- * IN LOG FILE RECORDS
- *
- * INPUT: LOG_FILE_PTR CURRENT LOG FILE
- * TNO_FD_DESCRIPTORS THE NUMBER OF FILE DESCRIPTORS
- * TO READ FROM THE LOG PAGE
- * LOG_PAGE_PTR PAGE ZERO IN LOG FILE
- * SUBROUTINE SHORT NAME = IGL
- * ========================================================================= */
-void Dblqh::initGciInLogFileRec(Signal* signal, Uint32 noFdDescriptors)
-{
- LogFileRecordPtr filePtr = logFilePtr;
- Uint32 pos = ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE;
- for (Uint32 fd = 0; fd < noFdDescriptors; fd++)
- {
- jam();
- for (Uint32 mb = 0; mb < clogFileSize; mb++)
- {
- jam();
- Uint32 pos0 = pos + fd * (ZFD_MBYTE_SIZE * clogFileSize) + mb;
- Uint32 pos1 = pos0 + clogFileSize;
- Uint32 pos2 = pos1 + clogFileSize;
- arrGuard(pos0, ZPAGE_SIZE);
- arrGuard(pos1, ZPAGE_SIZE);
- arrGuard(pos2, ZPAGE_SIZE);
- filePtr.p->logMaxGciCompleted[mb] = logPagePtr.p->logPageWord[pos0];
- filePtr.p->logMaxGciStarted[mb] = logPagePtr.p->logPageWord[pos1];
- filePtr.p->logLastPrepRef[mb] = logPagePtr.p->logPageWord[pos2];
- }
- if (fd + 1 < noFdDescriptors)
- {
- jam();
- filePtr.i = filePtr.p->prevLogFile;
- ptrCheckGuard(filePtr, clogFileFileSize, logFileRecord);
- }
- }
-}//Dblqh::initGciInLogFileRec()
-
-/* ==========================================================================
- * ======= INITIATE LCP RECORD WHEN USED FOR SYSTEM RESTART =======
- *
- * SUBROUTINE SHORT NAME = ILS
- * ========================================================================= */
-void Dblqh::initLcpSr(Signal* signal,
- Uint32 lcpNo,
- Uint32 lcpId,
- Uint32 tableId,
- Uint32 fragId,
- Uint32 fragPtr)
-{
- lcpPtr.p->lcpQueued = false;
- lcpPtr.p->currentFragment.fragPtrI = fragPtr;
- lcpPtr.p->currentFragment.lcpFragOrd.lcpNo = lcpNo;
- lcpPtr.p->currentFragment.lcpFragOrd.lcpId = lcpId;
- lcpPtr.p->currentFragment.lcpFragOrd.tableId = tableId;
- lcpPtr.p->currentFragment.lcpFragOrd.fragmentId = fragId;
- lcpPtr.p->lcpState = LcpRecord::LCP_SR_WAIT_FRAGID;
-}//Dblqh::initLcpSr()
-
-/* ==========================================================================
- * ======= INITIATE LOG PART =======
- *
- * ========================================================================= */
-void Dblqh::initLogpart(Signal* signal)
-{
- logPartPtr.p->execSrLogPage = RNIL;
- logPartPtr.p->execSrLogPageIndex = ZNIL;
- logPartPtr.p->execSrExecuteIndex = 0;
- logPartPtr.p->noLogFiles = cnoLogFiles;
- logPartPtr.p->logLap = 0;
- logPartPtr.p->logTailFileNo = 0;
- logPartPtr.p->logTailMbyte = 0;
- logPartPtr.p->lastMbyte = ZNIL;
- logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE;
- logPartPtr.p->logExecState = LogPartRecord::LES_IDLE;
- logPartPtr.p->firstLogTcrec = RNIL;
- logPartPtr.p->lastLogTcrec = RNIL;
- logPartPtr.p->firstLogQueue = RNIL;
- logPartPtr.p->lastLogQueue = RNIL;
- logPartPtr.p->gcprec = RNIL;
- logPartPtr.p->firstPageRef = RNIL;
- logPartPtr.p->lastPageRef = RNIL;
- logPartPtr.p->headFileNo = ZNIL;
- logPartPtr.p->headPageNo = ZNIL;
- logPartPtr.p->headPageIndex = ZNIL;
-}//Dblqh::initLogpart()
-
-/* ==========================================================================
- * ======= INITIATE LOG POINTERS =======
- *
- * ========================================================================= */
-void Dblqh::initLogPointers(Signal* signal)
-{
- logPartPtr.i = tcConnectptr.p->m_log_part_ptr_i;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- logFilePtr.i = logPartPtr.p->currentLogfile;
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
-}//Dblqh::initLogPointers()
-
-/* ------------------------------------------------------------------------- */
-/* ------- INIT REQUEST INFO BEFORE EXECUTING A LOG RECORD ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::initReqinfoExecSr(Signal* signal)
-{
- UintR Treqinfo = 0;
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- LqhKeyReq::setKeyLen(Treqinfo, regTcPtr->primKeyLen);
-/* ------------------------------------------------------------------------- */
-/* NUMBER OF BACKUPS AND STANDBYS ARE ZERO AND NEED NOT BE SET. */
-/* REPLICA TYPE IS CLEARED BY SEND_LQHKEYREQ. */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* SET LAST REPLICA NUMBER TO ZERO (BIT 10-11) */
-/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* SET DIRTY FLAG */
-/* ------------------------------------------------------------------------- */
- LqhKeyReq::setDirtyFlag(Treqinfo, 1);
-/* ------------------------------------------------------------------------- */
-/* SET SIMPLE TRANSACTION */
-/* ------------------------------------------------------------------------- */
- LqhKeyReq::setSimpleFlag(Treqinfo, 1);
- LqhKeyReq::setGCIFlag(Treqinfo, 1);
-/* ------------------------------------------------------------------------- */
-/* SET OPERATION TYPE AND LOCK MODE (NEVER READ OPERATION OR SCAN IN LOG) */
-/* ------------------------------------------------------------------------- */
- LqhKeyReq::setOperation(Treqinfo, regTcPtr->operation);
- regTcPtr->reqinfo = Treqinfo;
-/* ------------------------------------------------------------------------ */
-/* NO OF BACKUP IS SET TO ONE AND NUMBER OF STANDBY NODES IS SET TO ZERO. */
-/* THUS THE RECEIVING NODE WILL EXPECT THAT IT IS THE LAST NODE AND WILL */
-/* SEND COMPLETED AS THE RESPONSE SIGNAL SINCE DIRTY_OP BIT IS SET. */
-/* ------------------------------------------------------------------------ */
-/* ------------------------------------------------------------------------- */
-/* SET REPLICA TYPE TO PRIMARY AND NUMBER OF REPLICA TO ONE */
-/* ------------------------------------------------------------------------- */
- regTcPtr->lastReplicaNo = 0;
- regTcPtr->apiVersionNo = 0;
- regTcPtr->nextSeqNoReplica = 0;
- regTcPtr->opExec = 0;
- regTcPtr->storedProcId = ZNIL;
- regTcPtr->readlenAi = 0;
- regTcPtr->nodeAfterNext[0] = ZNIL;
- regTcPtr->nodeAfterNext[1] = ZNIL;
- regTcPtr->dirtyOp = ZFALSE;
- regTcPtr->tcBlockref = cownref;
-}//Dblqh::initReqinfoExecSr()
-
-/* --------------------------------------------------------------------------
- * ------- INSERT FRAGMENT -------
- *
- * ------------------------------------------------------------------------- */
-bool Dblqh::insertFragrec(Signal* signal, Uint32 fragId)
-{
- terrorCode = ZOK;
- if(c_fragment_pool.seize(fragptr) == false)
- {
- terrorCode = ZNO_FREE_FRAGMENTREC;
- return false;
- }
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabptr.p->fragid[i] == ZNIL) {
- jam();
- tabptr.p->fragid[i] = fragId;
- tabptr.p->fragrec[i] = fragptr.i;
- return true;
- }//if
- }//for
- c_fragment_pool.release(fragptr);
- terrorCode = ZTOO_MANY_FRAGMENTS;
- return false;
-}//Dblqh::insertFragrec()
-
-/* --------------------------------------------------------------------------
- * ------- LINK OPERATION IN ACTIVE LIST ON FRAGMENT -------
- *
- * SUBROUTINE SHORT NAME: LFQ
-// Input Pointers:
-// tcConnectptr
-// fragptr
-* ------------------------------------------------------------------------- */
-void Dblqh::linkFragQueue(Signal* signal)
-{
- TcConnectionrecPtr lfqTcConnectptr;
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- Fragrecord * const regFragPtr = fragptr.p;
- Uint32 tcIndex = tcConnectptr.i;
-
- lfqTcConnectptr.i = regFragPtr->lastWaitQueue;
- regTcPtr->nextTc = RNIL;
- regFragPtr->lastWaitQueue = tcIndex;
- regTcPtr->prevTc = lfqTcConnectptr.i;
- ndbrequire(regTcPtr->listState == TcConnectionrec::NOT_IN_LIST);
- regTcPtr->listState = TcConnectionrec::WAIT_QUEUE_LIST;
- if (lfqTcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(lfqTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- lfqTcConnectptr.p->nextTc = tcIndex;
- } else {
- regFragPtr->firstWaitQueue = tcIndex;
- }//if
- return;
-}//Dblqh::linkFragQueue()
-
-/* -------------------------------------------------------------------------
- * ------- LINK OPERATION INTO WAITING FOR LOGGING -------
- *
- * SUBROUTINE SHORT NAME = LWL
-// Input Pointers:
-// tcConnectptr
-// logPartPtr
- * ------------------------------------------------------------------------- */
-void Dblqh::linkWaitLog(Signal* signal, LogPartRecordPtr regLogPartPtr)
-{
- TcConnectionrecPtr lwlTcConnectptr;
-
-/* -------------------------------------------------- */
-/* LINK ACTIVE OPERATION INTO QUEUE WAITING FOR */
-/* ACCESS TO THE LOG PART. */
-/* -------------------------------------------------- */
- lwlTcConnectptr.i = regLogPartPtr.p->lastLogQueue;
- if (lwlTcConnectptr.i == RNIL) {
- jam();
- regLogPartPtr.p->firstLogQueue = tcConnectptr.i;
- } else {
- jam();
- ptrCheckGuard(lwlTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- lwlTcConnectptr.p->nextTcLogQueue = tcConnectptr.i;
- }//if
- regLogPartPtr.p->lastLogQueue = tcConnectptr.i;
- tcConnectptr.p->nextTcLogQueue = RNIL;
- if (regLogPartPtr.p->LogLqhKeyReqSent == ZFALSE) {
- jam();
- regLogPartPtr.p->LogLqhKeyReqSent = ZTRUE;
- signal->theData[0] = ZLOG_LQHKEYREQ;
- signal->theData[1] = regLogPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
-}//Dblqh::linkWaitLog()
-
-/* --------------------------------------------------------------------------
- * ------- START THE NEXT OPERATION ON THIS LOG PART IF ANY -------
- * ------- OPERATIONS ARE QUEUED. -------
- *
- * SUBROUTINE SHORT NAME = LNS
-// Input Pointers:
-// tcConnectptr
-// logPartPtr
- * ------------------------------------------------------------------------- */
-void Dblqh::logNextStart(Signal* signal)
-{
- LogPartRecordPtr lnsLogPartPtr;
- UintR tlnsStillWaiting;
- LogPartRecord * const regLogPartPtr = logPartPtr.p;
-
- if ((regLogPartPtr->firstLogQueue == RNIL) &&
- (regLogPartPtr->logPartState == LogPartRecord::ACTIVE) &&
- (regLogPartPtr->waitWriteGciLog != LogPartRecord::WWGL_TRUE)) {
-// --------------------------------------------------------------------------
-// Optimised route for the common case
-// --------------------------------------------------------------------------
- regLogPartPtr->logPartState = LogPartRecord::IDLE;
- return;
- }//if
- if (regLogPartPtr->firstLogQueue != RNIL) {
- jam();
- if (regLogPartPtr->LogLqhKeyReqSent == ZFALSE) {
- jam();
- regLogPartPtr->LogLqhKeyReqSent = ZTRUE;
- signal->theData[0] = ZLOG_LQHKEYREQ;
- signal->theData[1] = logPartPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
- } else {
- if (regLogPartPtr->logPartState == LogPartRecord::ACTIVE) {
- jam();
- regLogPartPtr->logPartState = LogPartRecord::IDLE;
- } else {
- jam();
- }//if
- }//if
- if (regLogPartPtr->waitWriteGciLog != LogPartRecord::WWGL_TRUE) {
- jam();
- return;
- } else {
- jam();
-/* --------------------------------------------------------------------------
- * A COMPLETE GCI LOG RECORD IS WAITING TO BE WRITTEN. WE GIVE THIS HIGHEST
- * PRIORITY AND WRITE IT IMMEDIATELY. AFTER WRITING IT WE CHECK IF ANY MORE
- * LOG PARTS ARE WAITING. IF NOT WE SEND A SIGNAL THAT INITIALISES THE GCP
- * RECORD TO WAIT UNTIL ALL COMPLETE GCI LOG RECORDS HAVE REACHED TO DISK.
- * -------------------------------------------------------------------------- */
- writeCompletedGciLog(signal);
- logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_FALSE;
- tlnsStillWaiting = ZFALSE;
- for (lnsLogPartPtr.i = 0; lnsLogPartPtr.i < 4; lnsLogPartPtr.i++) {
- jam();
- ptrAss(lnsLogPartPtr, logPartRecord);
- if (lnsLogPartPtr.p->waitWriteGciLog == LogPartRecord::WWGL_TRUE) {
- jam();
- tlnsStillWaiting = ZTRUE;
- }//if
- }//for
- if (tlnsStillWaiting == ZFALSE) {
- jam();
- signal->theData[0] = ZINIT_GCP_REC;
- sendSignal(cownref, GSN_CONTINUEB, signal, 1, JBB);
- }//if
- }//if
-}//Dblqh::logNextStart()
-
-/* --------------------------------------------------------------------------
- * ------- MOVE PAGES FROM LFO RECORD TO PAGE REFERENCE RECORD -------
- * WILL ALWAYS MOVE 8 PAGES TO A PAGE REFERENCE RECORD.
- *
- * SUBROUTINE SHORT NAME = MPR
- * ------------------------------------------------------------------------- */
-void Dblqh::moveToPageRef(Signal* signal)
-{
- LogPageRecordPtr mprLogPagePtr;
- PageRefRecordPtr mprPageRefPtr;
- UintR tmprIndex;
-
-/* --------------------------------------------------------------------------
- * ------- INSERT PAGE REFERENCE RECORD -------
- *
- * INPUT: LFO_PTR LOG FILE OPERATION RECORD
- * LOG_PART_PTR LOG PART RECORD
- * PAGE_REF_PTR THE PAGE REFERENCE RECORD TO BE INSERTED.
- * ------------------------------------------------------------------------- */
- PageRefRecordPtr iprPageRefPtr;
-
- if ((logPartPtr.p->mmBufferSize + 8) >= ZMAX_MM_BUFFER_SIZE) {
- jam();
- pageRefPtr.i = logPartPtr.p->firstPageRef;
- ptrCheckGuard(pageRefPtr, cpageRefFileSize, pageRefRecord);
- releasePrPages(signal);
- removePageRef(signal);
- } else {
- jam();
- logPartPtr.p->mmBufferSize = logPartPtr.p->mmBufferSize + 8;
- }//if
- seizePageRef(signal);
- if (logPartPtr.p->firstPageRef == RNIL) {
- jam();
- logPartPtr.p->firstPageRef = pageRefPtr.i;
- } else {
- jam();
- iprPageRefPtr.i = logPartPtr.p->lastPageRef;
- ptrCheckGuard(iprPageRefPtr, cpageRefFileSize, pageRefRecord);
- iprPageRefPtr.p->prNext = pageRefPtr.i;
- }//if
- pageRefPtr.p->prPrev = logPartPtr.p->lastPageRef;
- logPartPtr.p->lastPageRef = pageRefPtr.i;
-
- pageRefPtr.p->prFileNo = logFilePtr.p->fileNo;
- pageRefPtr.p->prPageNo = lfoPtr.p->lfoPageNo;
- tmprIndex = 0;
- mprLogPagePtr.i = lfoPtr.p->firstLfoPage;
-MPR_LOOP:
- arrGuard(tmprIndex, 8);
- pageRefPtr.p->pageRef[tmprIndex] = mprLogPagePtr.i;
- tmprIndex = tmprIndex + 1;
- ptrCheckGuard(mprLogPagePtr, clogPageFileSize, logPageRecord);
- mprLogPagePtr.i = mprLogPagePtr.p->logPageWord[ZNEXT_PAGE];
- if (mprLogPagePtr.i != RNIL) {
- jam();
- goto MPR_LOOP;
- }//if
- mprPageRefPtr.i = pageRefPtr.p->prPrev;
- if (mprPageRefPtr.i != RNIL) {
- jam();
- ptrCheckGuard(mprPageRefPtr, cpageRefFileSize, pageRefRecord);
- mprLogPagePtr.i = mprPageRefPtr.p->pageRef[7];
- ptrCheckGuard(mprLogPagePtr, clogPageFileSize, logPageRecord);
- mprLogPagePtr.p->logPageWord[ZNEXT_PAGE] = pageRefPtr.p->pageRef[0];
- }//if
-}//Dblqh::moveToPageRef()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ THE ATTRINFO FROM THE LOG ------- */
-/* */
-/* SUBROUTINE SHORT NAME = RA */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readAttrinfo(Signal* signal)
-{
- Uint32 remainingLen = tcConnectptr.p->totSendlenAi;
- if (remainingLen == 0) {
- jam();
- tcConnectptr.p->reclenAiLqhkey = 0;
- return;
- }//if
- Uint32 dataLen = remainingLen;
- if (remainingLen > 5)
- dataLen = 5;
- readLogData(signal, dataLen, &tcConnectptr.p->firstAttrinfo[0]);
- tcConnectptr.p->reclenAiLqhkey = dataLen;
- remainingLen -= dataLen;
- while (remainingLen > 0) {
- jam();
- dataLen = remainingLen;
- if (remainingLen > 22)
- dataLen = 22;
- seizeAttrinbuf(signal);
- readLogData(signal, dataLen, &attrinbufptr.p->attrbuf[0]);
- attrinbufptr.p->attrbuf[ZINBUF_DATA_LEN] = dataLen;
- remainingLen -= dataLen;
- }//while
-}//Dblqh::readAttrinfo()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ COMMIT LOG ------- */
-/* */
-/* SUBROUTINE SHORT NAME = RCL */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readCommitLog(Signal* signal, CommitLogRecord* commitLogRecord)
-{
- Uint32 trclPageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- if ((trclPageIndex + (ZCOMMIT_LOG_SIZE - 1)) < ZPAGE_SIZE) {
- jam();
- tcConnectptr.p->tableref = logPagePtr.p->logPageWord[trclPageIndex + 0];
- tcConnectptr.p->schemaVersion = logPagePtr.p->logPageWord[trclPageIndex + 1];
- tcConnectptr.p->fragmentid = logPagePtr.p->logPageWord[trclPageIndex + 2];
- commitLogRecord->fileNo = logPagePtr.p->logPageWord[trclPageIndex + 3];
- commitLogRecord->startPageNo = logPagePtr.p->logPageWord[trclPageIndex + 4];
- commitLogRecord->startPageIndex = logPagePtr.p->logPageWord[trclPageIndex + 5];
- commitLogRecord->stopPageNo = logPagePtr.p->logPageWord[trclPageIndex + 6];
- tcConnectptr.p->gci = logPagePtr.p->logPageWord[trclPageIndex + 7];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- (trclPageIndex + ZCOMMIT_LOG_SIZE) - 1;
- } else {
- jam();
- tcConnectptr.p->tableref = readLogword(signal);
- tcConnectptr.p->schemaVersion = readLogword(signal);
- tcConnectptr.p->fragmentid = readLogword(signal);
- commitLogRecord->fileNo = readLogword(signal);
- commitLogRecord->startPageNo = readLogword(signal);
- commitLogRecord->startPageIndex = readLogword(signal);
- commitLogRecord->stopPageNo = readLogword(signal);
- tcConnectptr.p->gci = readLogword(signal);
- }//if
- tcConnectptr.p->transid[0] = logPartPtr.i + 65536;
- tcConnectptr.p->transid[1] = (DBLQH << 20) + (cownNodeid << 8);
-}//Dblqh::readCommitLog()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ LOG PAGES FROM DISK IN ORDER TO EXECUTE A LOG ------- */
-/* RECORD WHICH WAS NOT FOUND IN MAIN MEMORY. */
-/* */
-/* SUBROUTINE SHORT NAME = REL */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readExecLog(Signal* signal)
-{
- UintR trelIndex;
- UintR trelI;
-
- seizeLfo(signal);
- initLfo(signal);
- trelI = logPartPtr.p->execSrStopPageNo - logPartPtr.p->execSrStartPageNo;
- arrGuard(trelI + 1, 16);
- lfoPtr.p->logPageArray[trelI + 1] = logPartPtr.p->execSrStartPageNo;
- for (trelIndex = logPartPtr.p->execSrStopPageNo; (trelIndex >= logPartPtr.p->execSrStartPageNo) &&
- (UintR)~trelIndex; trelIndex--) {
- jam();
- seizeLogpage(signal);
- arrGuard(trelI, 16);
- lfoPtr.p->logPageArray[trelI] = logPagePtr.i;
- trelI--;
- }//for
- lfoPtr.p->lfoPageNo = logPartPtr.p->execSrStartPageNo;
- lfoPtr.p->noPagesRw = (logPartPtr.p->execSrStopPageNo -
- logPartPtr.p->execSrStartPageNo) + 1;
- lfoPtr.p->firstLfoPage = lfoPtr.p->logPageArray[0];
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_MEM_PAGES; // edtjamo TR509 //ZLIST_OF_PAIRS;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = lfoPtr.p->noPagesRw;
- signal->theData[6] = lfoPtr.p->logPageArray[0];
- signal->theData[7] = lfoPtr.p->logPageArray[1];
- signal->theData[8] = lfoPtr.p->logPageArray[2];
- signal->theData[9] = lfoPtr.p->logPageArray[3];
- signal->theData[10] = lfoPtr.p->logPageArray[4];
- signal->theData[11] = lfoPtr.p->logPageArray[5];
- signal->theData[12] = lfoPtr.p->logPageArray[6];
- signal->theData[13] = lfoPtr.p->logPageArray[7];
- signal->theData[14] = lfoPtr.p->logPageArray[8];
- signal->theData[15] = lfoPtr.p->logPageArray[9];
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 16, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("readExecLog %u page at part: %u file: %u pos: %u",
- lfoPtr.p->noPagesRw,
- logPartPtr.i,
- logFilePtr.p->fileNo,
- logPartPtr.p->execSrStartPageNo);
-
-}//Dblqh::readExecLog()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ 64 KBYTES WHEN EXECUTING THE FRAGMENT LOG ------- */
-/* */
-/* SUBROUTINE SHORT NAME = RES */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readExecSrNewMbyte(Signal* signal)
-{
- logFilePtr.p->currentFilepage = logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE;
- logFilePtr.p->filePosition = logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE;
- logPartPtr.p->execSrPagesRead = 0;
- logPartPtr.p->execSrPagesReading = 0;
- logPartPtr.p->execSrPagesExecuted = 0;
- readExecSr(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_WAIT_READ_EXEC_SR_NEW_MBYTE;
-}//Dblqh::readExecSrNewMbyte()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ 64 KBYTES WHEN EXECUTING THE FRAGMENT LOG ------- */
-/* */
-/* SUBROUTINE SHORT NAME = RES */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readExecSr(Signal* signal)
-{
- UintR tresPageid;
- UintR tresIndex;
-
- tresPageid = logFilePtr.p->filePosition;
- seizeLfo(signal);
- initLfo(signal);
- for (tresIndex = 7; (UintR)~tresIndex; tresIndex--) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* GO BACKWARDS SINCE WE INSERT AT THE BEGINNING AND WE WANT THAT FIRST PAGE */
-/* SHALL BE FIRST AND LAST PAGE LAST. */
-/* ------------------------------------------------------------------------- */
- seizeLogpage(signal);
- lfoPtr.p->logPageArray[tresIndex] = logPagePtr.i;
- }//for
- lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_SR;
- lfoPtr.p->lfoPageNo = tresPageid;
- logFilePtr.p->filePosition = logFilePtr.p->filePosition + 8;
- logPartPtr.p->execSrPagesReading = logPartPtr.p->execSrPagesReading + 8;
- lfoPtr.p->noPagesRw = 8;
- lfoPtr.p->firstLfoPage = lfoPtr.p->logPageArray[0];
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_MEM_PAGES;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = 8;
- signal->theData[6] = lfoPtr.p->logPageArray[0];
- signal->theData[7] = lfoPtr.p->logPageArray[1];
- signal->theData[8] = lfoPtr.p->logPageArray[2];
- signal->theData[9] = lfoPtr.p->logPageArray[3];
- signal->theData[10] = lfoPtr.p->logPageArray[4];
- signal->theData[11] = lfoPtr.p->logPageArray[5];
- signal->theData[12] = lfoPtr.p->logPageArray[6];
- signal->theData[13] = lfoPtr.p->logPageArray[7];
- signal->theData[14] = tresPageid;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 15, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("readExecSr %u page at part: %u file: %u pos: %u",
- 8,
- logPartPtr.i,
- logFilePtr.p->fileNo,
- tresPageid);
-
-}//Dblqh::readExecSr()
-
-/* ------------------------------------------------------------------------- */
-/* ------------ READ THE PRIMARY KEY FROM THE LOG ---------------- */
-/* */
-/* SUBROUTINE SHORT NAME = RK */
-/* --------------------------------------------------------------------------*/
-void Dblqh::readKey(Signal* signal)
-{
- Uint32 remainingLen = tcConnectptr.p->primKeyLen;
- ndbrequire(remainingLen != 0);
- Uint32 dataLen = remainingLen;
- if (remainingLen > 4)
- dataLen = 4;
- readLogData(signal, dataLen, &tcConnectptr.p->tupkeyData[0]);
- remainingLen -= dataLen;
- while (remainingLen > 0) {
- jam();
- seizeTupkeybuf(signal);
- dataLen = remainingLen;
- if (dataLen > 4)
- dataLen = 4;
- readLogData(signal, dataLen, &databufptr.p->data[0]);
- remainingLen -= dataLen;
- }//while
-}//Dblqh::readKey()
-
-/* ------------------------------------------------------------------------- */
-/* ------------ READ A NUMBER OF WORDS FROM LOG INTO CDATA ---------------- */
-/* */
-/* SUBROUTINE SHORT NAME = RLD */
-/* --------------------------------------------------------------------------*/
-void Dblqh::readLogData(Signal* signal, Uint32 noOfWords, Uint32* dataPtr)
-{
- ndbrequire(noOfWords < 32);
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- if ((logPos + noOfWords) >= ZPAGE_SIZE) {
- for (Uint32 i = 0; i < noOfWords; i++)
- dataPtr[i] = readLogwordExec(signal);
- } else {
- MEMCOPY_NO_WORDS(dataPtr, &logPagePtr.p->logPageWord[logPos], noOfWords);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + noOfWords;
- }//if
-}//Dblqh::readLogData()
-
-/* ------------------------------------------------------------------------- */
-/* ------------ READ THE LOG HEADER OF A PREPARE LOG HEADER ---------------- */
-/* */
-/* SUBROUTINE SHORT NAME = RLH */
-/* --------------------------------------------------------------------------*/
-void Dblqh::readLogHeader(Signal* signal)
-{
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- if ((logPos + ZLOG_HEAD_SIZE) < ZPAGE_SIZE) {
- jam();
- tcConnectptr.p->hashValue = logPagePtr.p->logPageWord[logPos + 2];
- tcConnectptr.p->operation = logPagePtr.p->logPageWord[logPos + 3];
- tcConnectptr.p->totSendlenAi = logPagePtr.p->logPageWord[logPos + 4];
- tcConnectptr.p->primKeyLen = logPagePtr.p->logPageWord[logPos + 5];
- tcConnectptr.p->m_row_id.m_page_no = logPagePtr.p->logPageWord[logPos + 6];
- tcConnectptr.p->m_row_id.m_page_idx = logPagePtr.p->logPageWord[logPos+ 7];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + ZLOG_HEAD_SIZE;
- } else {
- jam();
- readLogwordExec(signal); /* IGNORE PREPARE LOG RECORD TYPE */
- readLogwordExec(signal); /* IGNORE LOG RECORD SIZE */
- tcConnectptr.p->hashValue = readLogwordExec(signal);
- tcConnectptr.p->operation = readLogwordExec(signal);
- tcConnectptr.p->totSendlenAi = readLogwordExec(signal);
- tcConnectptr.p->primKeyLen = readLogwordExec(signal);
- tcConnectptr.p->m_row_id.m_page_no = readLogwordExec(signal);
- tcConnectptr.p->m_row_id.m_page_idx = readLogwordExec(signal);
- }//if
-
- tcConnectptr.p->m_use_rowid = (tcConnectptr.p->operation == ZINSERT);
-}//Dblqh::readLogHeader()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ A WORD FROM THE LOG ------- */
-/* */
-/* OUTPUT: TLOG_WORD */
-/* SUBROUTINE SHORT NAME = RLW */
-/* ------------------------------------------------------------------------- */
-Uint32 Dblqh::readLogword(Signal* signal)
-{
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- ndbrequire(logPos < ZPAGE_SIZE);
- Uint32 logWord = logPagePtr.p->logPageWord[logPos];
- logPos++;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
- if (logPos >= ZPAGE_SIZE) {
- jam();
- logPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- logFilePtr.p->currentLogpage = logPagePtr.i;
- logFilePtr.p->currentFilepage++;
- logPartPtr.p->execSrPagesRead--;
- logPartPtr.p->execSrPagesExecuted++;
- }//if
- return logWord;
-}//Dblqh::readLogword()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ A WORD FROM THE LOG WHEN EXECUTING A LOG RECORD ------- */
-/* */
-/* OUTPUT: TLOG_WORD */
-/* SUBROUTINE SHORT NAME = RWE */
-/* ------------------------------------------------------------------------- */
-Uint32 Dblqh::readLogwordExec(Signal* signal)
-{
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- ndbrequire(logPos < ZPAGE_SIZE);
- Uint32 logWord = logPagePtr.p->logPageWord[logPos];
- logPos++;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos;
- if (logPos >= ZPAGE_SIZE) {
- jam();
- logPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- if (logPagePtr.i != RNIL){
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- } else {
- // Reading word at the last pos in the last page
- // Don't step forward to next page!
- jam();
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]++;
- }
- }//if
- return logWord;
-}//Dblqh::readLogwordExec()
-
-/* ------------------------------------------------------------------------- */
-/* ------- READ A SINGLE PAGE FROM THE LOG ------- */
-/* */
-/* INPUT: TRSP_PAGE_NO */
-/* SUBROUTINE SHORT NAME = RSP */
-/* ------------------------------------------------------------------------- */
-void Dblqh::readSinglePage(Signal* signal, Uint32 pageNo)
-{
- seizeLfo(signal);
- initLfo(signal);
- seizeLogpage(signal);
- lfoPtr.p->firstLfoPage = logPagePtr.i;
- lfoPtr.p->lfoPageNo = pageNo;
- lfoPtr.p->noPagesRw = 1;
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = 1;
- signal->theData[6] = logPagePtr.i;
- signal->theData[7] = pageNo;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("readSinglePage 1 page at part: %u file: %u pos: %u",
- logPartPtr.i,
- logFilePtr.p->fileNo,
- pageNo);
-
-}//Dblqh::readSinglePage()
-
-/* --------------------------------------------------------------------------
- * ------- REMOVE COPY FRAGMENT FROM ACTIVE COPY LIST -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseActiveCopy(Signal* signal)
-{
- /* MUST BE 8 BIT */
- UintR tracFlag;
- UintR tracIndex;
-
- tracFlag = ZFALSE;
- for (tracIndex = 0; tracIndex < 4; tracIndex++) {
- if (tracFlag == ZFALSE) {
- jam();
- if (cactiveCopy[tracIndex] == fragptr.i) {
- jam();
- tracFlag = ZTRUE;
- }//if
- } else {
- if (tracIndex < 3) {
- jam();
- cactiveCopy[tracIndex - 1] = cactiveCopy[tracIndex];
- } else {
- jam();
- cactiveCopy[3] = RNIL;
- }//if
- }//if
- }//for
- ndbrequire(tracFlag == ZTRUE);
- cnoActiveCopy--;
-}//Dblqh::releaseActiveCopy()
-
-
-/* --------------------------------------------------------------------------
- * ------- RELEASE ADD FRAGMENT RECORD -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseAddfragrec(Signal* signal)
-{
- addfragptr.p->addfragStatus = AddFragRecord::FREE;
- addfragptr.p->nextAddfragrec = cfirstfreeAddfragrec;
- cfirstfreeAddfragrec = addfragptr.i;
-}//Dblqh::releaseAddfragrec()
-
-/* --------------------------------------------------------------------------
- * ------- RELEASE A PAGE REFERENCE RECORD. -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releasePageRef(Signal* signal)
-{
- pageRefPtr.p->prNext = cfirstfreePageRef;
- cfirstfreePageRef = pageRefPtr.i;
-}//Dblqh::releasePageRef()
-
-/* --------------------------------------------------------------------------
- * --- RELEASE ALL PAGES IN THE MM BUFFER AFTER EXECUTING THE LOG ON IT. ----
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseMmPages(Signal* signal)
-{
-RMP_LOOP:
- jam();
- pageRefPtr.i = logPartPtr.p->firstPageRef;
- if (pageRefPtr.i != RNIL) {
- jam();
- ptrCheckGuard(pageRefPtr, cpageRefFileSize, pageRefRecord);
- releasePrPages(signal);
- removePageRef(signal);
- goto RMP_LOOP;
- }//if
-}//Dblqh::releaseMmPages()
-
-/* --------------------------------------------------------------------------
- * ------- RELEASE A SET OF PAGES AFTER EXECUTING THE LOG ON IT. -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::releasePrPages(Signal* signal)
-{
- UintR trppIndex;
-
- for (trppIndex = 0; trppIndex <= 7; trppIndex++) {
- jam();
- logPagePtr.i = pageRefPtr.p->pageRef[trppIndex];
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- releaseLogpage(signal);
- }//for
-}//Dblqh::releasePrPages()
-
-/* --------------------------------------------------------------------------
- * ------- RELEASE OPERATION FROM WAIT QUEUE LIST ON FRAGMENT -------
- *
- * SUBROUTINE SHORT NAME : RWA
- * ------------------------------------------------------------------------- */
-void Dblqh::releaseWaitQueue(Signal* signal)
-{
- TcConnectionrecPtr rwaTcNextConnectptr;
- TcConnectionrecPtr rwaTcPrevConnectptr;
-
- fragptr.i = tcConnectptr.p->fragmentptr;
- c_fragment_pool.getPtr(fragptr);
- rwaTcPrevConnectptr.i = tcConnectptr.p->prevTc;
- rwaTcNextConnectptr.i = tcConnectptr.p->nextTc;
- if (tcConnectptr.p->listState != TcConnectionrec::WAIT_QUEUE_LIST) {
- jam();
- systemError(signal, __LINE__);
- }//if
- tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
- if (rwaTcNextConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rwaTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rwaTcNextConnectptr.p->prevTc = rwaTcPrevConnectptr.i;
- } else {
- jam();
- fragptr.p->lastWaitQueue = rwaTcPrevConnectptr.i;
- }//if
- if (rwaTcPrevConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rwaTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rwaTcPrevConnectptr.p->nextTc = rwaTcNextConnectptr.i;
- } else {
- jam();
- fragptr.p->firstWaitQueue = rwaTcNextConnectptr.i;
- }//if
-}//Dblqh::releaseWaitQueue()
-
-/* --------------------------------------------------------------------------
- * ------- REMOVE OPERATION RECORD FROM LIST ON LOG PART OF NOT -------
- * COMPLETED OPERATIONS IN THE LOG.
- *
- * SUBROUTINE SHORT NAME = RLO
- * ------------------------------------------------------------------------- */
-void Dblqh::removeLogTcrec(Signal* signal)
-{
- TcConnectionrecPtr rloTcNextConnectptr;
- TcConnectionrecPtr rloTcPrevConnectptr;
- rloTcPrevConnectptr.i = tcConnectptr.p->prevLogTcrec;
- rloTcNextConnectptr.i = tcConnectptr.p->nextLogTcrec;
- if (rloTcNextConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rloTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rloTcNextConnectptr.p->prevLogTcrec = rloTcPrevConnectptr.i;
- } else {
- jam();
- logPartPtr.p->lastLogTcrec = rloTcPrevConnectptr.i;
- }//if
- if (rloTcPrevConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rloTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rloTcPrevConnectptr.p->nextLogTcrec = rloTcNextConnectptr.i;
- } else {
- jam();
- logPartPtr.p->firstLogTcrec = rloTcNextConnectptr.i;
- }//if
-}//Dblqh::removeLogTcrec()
-
-/* --------------------------------------------------------------------------
- * ------- REMOVE PAGE REFERENCE RECORD FROM LIST IN THIS LOG PART -------
- *
- * SUBROUTINE SHORT NAME = RPR
- * ------------------------------------------------------------------------- */
-void Dblqh::removePageRef(Signal* signal)
-{
- PageRefRecordPtr rprPageRefPtr;
-
- pageRefPtr.i = logPartPtr.p->firstPageRef;
- if (pageRefPtr.i != RNIL) {
- jam();
- ptrCheckGuard(pageRefPtr, cpageRefFileSize, pageRefRecord);
- if (pageRefPtr.p->prNext == RNIL) {
- jam();
- logPartPtr.p->lastPageRef = RNIL;
- logPartPtr.p->firstPageRef = RNIL;
- } else {
- jam();
- logPartPtr.p->firstPageRef = pageRefPtr.p->prNext;
- rprPageRefPtr.i = pageRefPtr.p->prNext;
- ptrCheckGuard(rprPageRefPtr, cpageRefFileSize, pageRefRecord);
- rprPageRefPtr.p->prPrev = RNIL;
- }//if
- releasePageRef(signal);
- }//if
-}//Dblqh::removePageRef()
-
-/* ------------------------------------------------------------------------- */
-/* ------- RETURN FROM EXECUTION OF LOG ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-Uint32 Dblqh::returnExecLog(Signal* signal)
-{
- tcConnectptr.p->connectState = TcConnectionrec::CONNECTED;
- initLogPointers(signal);
- logPartPtr.p->execSrExecuteIndex++;
- Uint32 result = checkIfExecLog(signal);
- if (result == ZOK) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* THIS LOG RECORD WILL BE EXECUTED AGAIN TOWARDS ANOTHER NODE. */
-/* ------------------------------------------------------------------------- */
- logPagePtr.i = logPartPtr.p->execSrLogPage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] =
- logPartPtr.p->execSrLogPageIndex;
- } else {
- jam();
-/* ------------------------------------------------------------------------- */
-/* NO MORE EXECUTION OF THIS LOG RECORD. */
-/* ------------------------------------------------------------------------- */
- if (logPartPtr.p->logExecState ==
- LogPartRecord::LES_EXEC_LOGREC_FROM_FILE) {
- jam();
-/* ------------------------------------------------------------------------- */
-/* THE LOG RECORD WAS READ FROM DISK. RELEASE ITS PAGES IMMEDIATELY. */
-/* ------------------------------------------------------------------------- */
- lfoPtr.i = logPartPtr.p->execSrLfoRec;
- ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
- releaseLfoPages(signal);
- releaseLfo(signal);
- logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG;
- if (logPartPtr.p->execSrExecLogFile != logPartPtr.p->currentLogfile) {
- jam();
- LogFileRecordPtr clfLogFilePtr;
- clfLogFilePtr.i = logPartPtr.p->execSrExecLogFile;
- ptrCheckGuard(clfLogFilePtr, clogFileFileSize, logFileRecord);
- clfLogFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_LOG;
- closeFile(signal, clfLogFilePtr, __LINE__);
- result = ZCLOSE_FILE;
- }//if
- }//if
- logPartPtr.p->execSrExecuteIndex = 0;
- logPartPtr.p->execSrLogPage = RNIL;
- logPartPtr.p->execSrLogPageIndex = ZNIL;
- logPagePtr.i = logFilePtr.p->currentLogpage;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPartPtr.p->savePageIndex;
- }//if
- return result;
-}//Dblqh::returnExecLog()
-
-/* --------------------------------------------------------------------------
- * ------- SEIZE ADD FRAGMENT RECORD ------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::seizeAddfragrec(Signal* signal)
-{
- addfragptr.i = cfirstfreeAddfragrec;
- ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
- cfirstfreeAddfragrec = addfragptr.p->nextAddfragrec;
-}//Dblqh::seizeAddfragrec()
-
-/* --------------------------------------------------------------------------
- * ------- SEIZE FRAGMENT RECORD -------
- *
- * ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* ------- SEIZE A PAGE REFERENCE RECORD. ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dblqh::seizePageRef(Signal* signal)
-{
- pageRefPtr.i = cfirstfreePageRef;
- ptrCheckGuard(pageRefPtr, cpageRefFileSize, pageRefRecord);
- cfirstfreePageRef = pageRefPtr.p->prNext;
- pageRefPtr.p->prNext = RNIL;
-}//Dblqh::seizePageRef()
-
-/* --------------------------------------------------------------------------
- * ------- SEND ABORTED -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::sendAborted(Signal* signal)
-{
- UintR TlastInd;
- if (tcConnectptr.p->nextReplica == ZNIL) {
- TlastInd = ZTRUE;
- } else {
- TlastInd = ZFALSE;
- }//if
- signal->theData[0] = tcConnectptr.p->tcOprec;
- signal->theData[1] = tcConnectptr.p->transid[0];
- signal->theData[2] = tcConnectptr.p->transid[1];
- signal->theData[3] = cownNodeid;
- signal->theData[4] = TlastInd;
- sendSignal(tcConnectptr.p->tcBlockref, GSN_ABORTED, signal, 5, JBB);
- return;
-}//Dblqh::sendAborted()
-
-/* --------------------------------------------------------------------------
- * ------- SEND LQH_TRANSCONF -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::sendLqhTransconf(Signal* signal, LqhTransConf::OperationStatus stat)
-{
- tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
- ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
-
- Uint32 reqInfo = 0;
- LqhTransConf::setReplicaType(reqInfo, tcConnectptr.p->replicaType);
- LqhTransConf::setReplicaNo(reqInfo, tcConnectptr.p->seqNoReplica);
- LqhTransConf::setLastReplicaNo(reqInfo, tcConnectptr.p->lastReplicaNo);
- LqhTransConf::setSimpleFlag(reqInfo, tcConnectptr.p->opSimple);
- LqhTransConf::setDirtyFlag(reqInfo, tcConnectptr.p->dirtyOp);
- LqhTransConf::setOperation(reqInfo, tcConnectptr.p->operation);
-
- LqhTransConf * const lqhTransConf = (LqhTransConf *)&signal->theData[0];
- lqhTransConf->tcRef = tcNodeFailptr.p->newTcRef;
- lqhTransConf->lqhNodeId = cownNodeid;
- lqhTransConf->operationStatus = stat;
- lqhTransConf->lqhConnectPtr = tcConnectptr.i;
- lqhTransConf->transId1 = tcConnectptr.p->transid[0];
- lqhTransConf->transId2 = tcConnectptr.p->transid[1];
- lqhTransConf->oldTcOpRec = tcConnectptr.p->tcOprec;
- lqhTransConf->requestInfo = reqInfo;
- lqhTransConf->gci = tcConnectptr.p->gci;
- lqhTransConf->nextNodeId1 = tcConnectptr.p->nextReplica;
- lqhTransConf->nextNodeId2 = tcConnectptr.p->nodeAfterNext[0];
- lqhTransConf->nextNodeId3 = tcConnectptr.p->nodeAfterNext[1];
- lqhTransConf->apiRef = tcConnectptr.p->applRef;
- lqhTransConf->apiOpRec = tcConnectptr.p->applOprec;
- lqhTransConf->tableId = tcConnectptr.p->tableref;
- sendSignal(tcNodeFailptr.p->newTcBlockref, GSN_LQH_TRANSCONF,
- signal, LqhTransConf::SignalLength, JBB);
- tcNodeFailptr.p->tcRecNow = tcConnectptr.i + 1;
- signal->theData[0] = ZLQH_TRANS_NEXT;
- signal->theData[1] = tcNodeFailptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
-}//Dblqh::sendLqhTransconf()
-
-/* --------------------------------------------------------------------------
- * ------- START ANOTHER PHASE OF LOG EXECUTION -------
- * RESET THE VARIABLES NEEDED BY THIS PROCESS AND SEND THE START SIGNAL
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::startExecSr(Signal* signal)
-{
- cnoFragmentsExecSr = 0;
- cnoOutstandingExecFragReq = 0;
- c_lcp_complete_fragments.first(fragptr);
- signal->theData[0] = fragptr.i;
- sendSignal(cownref, GSN_START_EXEC_SR, signal, 1, JBB);
-}//Dblqh::startExecSr()
-
-/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
- * ¤¤¤¤¤¤¤ LOG MODULE ¤¤¤¤¤¤¤
- * ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */
-/* --------------------------------------------------------------------------
- * ------- STEP FORWARD IN FRAGMENT LOG DURING LOG EXECUTION -------
- *
- * ------------------------------------------------------------------------- */
-void Dblqh::stepAhead(Signal* signal, Uint32 stepAheadWords)
-{
- UintR tsaPos;
-
- tsaPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- while ((stepAheadWords + tsaPos) >= ZPAGE_SIZE) {
- jam();
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_SIZE;
- stepAheadWords = stepAheadWords - (ZPAGE_SIZE - tsaPos);
- logFilePtr.p->currentLogpage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
- logFilePtr.p->currentFilepage++;
- ptrCheckGuardErr(logPagePtr, clogPageFileSize, logPageRecord,
- NDBD_EXIT_SR_REDOLOG);
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
- logPartPtr.p->execSrPagesRead--;
- logPartPtr.p->execSrPagesExecuted++;
- tsaPos = ZPAGE_HEADER_SIZE;
- }//while
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = stepAheadWords + tsaPos;
-}//Dblqh::stepAhead()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A ABORT LOG RECORD -------
- *
- * SUBROUTINE SHORT NAME: WAL
- * ------------------------------------------------------------------------- */
-void Dblqh::writeAbortLog(Signal* signal)
-{
- if ((ZABORT_LOG_SIZE + ZNEXT_LOG_SIZE) >
- logFilePtr.p->remainingWordsInMbyte) {
- jam();
- changeMbyte(signal);
- }//if
- logFilePtr.p->remainingWordsInMbyte =
- logFilePtr.p->remainingWordsInMbyte - ZABORT_LOG_SIZE;
- writeLogWord(signal, ZABORT_TYPE);
- writeLogWord(signal, tcConnectptr.p->transid[0]);
- writeLogWord(signal, tcConnectptr.p->transid[1]);
-}//Dblqh::writeAbortLog()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A COMMIT LOG RECORD -------
- *
- * SUBROUTINE SHORT NAME: WCL
- * ------------------------------------------------------------------------- */
-void Dblqh::writeCommitLog(Signal* signal, LogPartRecordPtr regLogPartPtr)
-{
- LogFileRecordPtr regLogFilePtr;
- LogPageRecordPtr regLogPagePtr;
- TcConnectionrec * const regTcPtr = tcConnectptr.p;
- regLogFilePtr.i = regLogPartPtr.p->currentLogfile;
- ptrCheckGuard(regLogFilePtr, clogFileFileSize, logFileRecord);
- regLogPagePtr.i = regLogFilePtr.p->currentLogpage;
- Uint32 twclTmp = regLogFilePtr.p->remainingWordsInMbyte;
- ptrCheckGuard(regLogPagePtr, clogPageFileSize, logPageRecord);
- logPartPtr = regLogPartPtr;
- logFilePtr = regLogFilePtr;
- logPagePtr = regLogPagePtr;
- if ((ZCOMMIT_LOG_SIZE + ZNEXT_LOG_SIZE) > twclTmp) {
- jam();
- changeMbyte(signal);
- twclTmp = logFilePtr.p->remainingWordsInMbyte;
- }//if
-
- Uint32 twclLogPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- Uint32 tableId = regTcPtr->tableref;
- Uint32 schemaVersion = regTcPtr->schemaVersion;
- Uint32 fragId = regTcPtr->fragmentid;
- Uint32 fileNo = regTcPtr->logStartFileNo;
- Uint32 startPageNo = regTcPtr->logStartPageNo;
- Uint32 pageIndex = regTcPtr->logStartPageIndex;
- Uint32 stopPageNo = regTcPtr->logStopPageNo;
- Uint32 gci = regTcPtr->gci;
- logFilePtr.p->remainingWordsInMbyte = twclTmp - ZCOMMIT_LOG_SIZE;
-
- if ((twclLogPos + ZCOMMIT_LOG_SIZE) >= ZPAGE_SIZE) {
- writeLogWord(signal, ZCOMMIT_TYPE);
- writeLogWord(signal, tableId);
- writeLogWord(signal, schemaVersion);
- writeLogWord(signal, fragId);
- writeLogWord(signal, fileNo);
- writeLogWord(signal, startPageNo);
- writeLogWord(signal, pageIndex);
- writeLogWord(signal, stopPageNo);
- writeLogWord(signal, gci);
- } else {
- Uint32* dataPtr = &logPagePtr.p->logPageWord[twclLogPos];
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = twclLogPos + ZCOMMIT_LOG_SIZE;
- dataPtr[0] = ZCOMMIT_TYPE;
- dataPtr[1] = tableId;
- dataPtr[2] = schemaVersion;
- dataPtr[3] = fragId;
- dataPtr[4] = fileNo;
- dataPtr[5] = startPageNo;
- dataPtr[6] = pageIndex;
- dataPtr[7] = stopPageNo;
- dataPtr[8] = gci;
- }//if
- TcConnectionrecPtr rloTcNextConnectptr;
- TcConnectionrecPtr rloTcPrevConnectptr;
- rloTcPrevConnectptr.i = regTcPtr->prevLogTcrec;
- rloTcNextConnectptr.i = regTcPtr->nextLogTcrec;
- if (rloTcNextConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rloTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rloTcNextConnectptr.p->prevLogTcrec = rloTcPrevConnectptr.i;
- } else {
- regLogPartPtr.p->lastLogTcrec = rloTcPrevConnectptr.i;
- }//if
- if (rloTcPrevConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(rloTcPrevConnectptr, ctcConnectrecFileSize, tcConnectionrec);
- rloTcPrevConnectptr.p->nextLogTcrec = rloTcNextConnectptr.i;
- } else {
- regLogPartPtr.p->firstLogTcrec = rloTcNextConnectptr.i;
- }//if
-}//Dblqh::writeCommitLog()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A COMPLETED GCI LOG RECORD -------
- *
- * SUBROUTINE SHORT NAME: WCG
-// Input Pointers:
-// logFilePtr
-// logPartPtr
- * ------------------------------------------------------------------------- */
-void Dblqh::writeCompletedGciLog(Signal* signal)
-{
- if ((ZCOMPLETED_GCI_LOG_SIZE + ZNEXT_LOG_SIZE) >
- logFilePtr.p->remainingWordsInMbyte) {
- jam();
- changeMbyte(signal);
- }//if
-
- logFilePtr.p->remainingWordsInMbyte =
- logFilePtr.p->remainingWordsInMbyte - ZCOMPLETED_GCI_LOG_SIZE;
-
- if (DEBUG_REDO)
- ndbout_c("writeCompletedGciLog gci: %u part: %u file: %u page: %u",
- cnewestCompletedGci,
- logPartPtr.i,
- logFilePtr.p->fileNo,
- logFilePtr.p->currentFilepage);
-
- writeLogWord(signal, ZCOMPLETED_GCI_TYPE);
- writeLogWord(signal, cnewestCompletedGci);
- logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
-}//Dblqh::writeCompletedGciLog()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A DIRTY PAGE DURING LOG EXECUTION -------
- *
- * SUBROUTINE SHORT NAME: WD
- * ------------------------------------------------------------------------- */
-void Dblqh::writeDirty(Signal* signal, Uint32 place)
-{
- logPagePtr.p->logPageWord[ZPOS_DIRTY] = ZNOT_DIRTY;
-
- ndbassert(logPartPtr.p->prevFilepage ==
- logPagePtr.p->logPageWord[ZPOS_PAGE_NO]);
- writeDbgInfoPageHeader(logPagePtr, place, logPartPtr.p->prevFilepage,
- ZPAGE_SIZE);
- // Calculate checksum for page
- logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
-
- seizeLfo(signal);
- initLfo(signal);
- lfoPtr.p->lfoPageNo = logPartPtr.p->prevFilepage;
- lfoPtr.p->noPagesRw = 1;
- lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_DIRTY;
- lfoPtr.p->firstLfoPage = logPagePtr.i;
- signal->theData[0] = logFilePtr.p->fileRef;
- signal->theData[1] = cownref;
- signal->theData[2] = lfoPtr.i;
- signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
- signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
- signal->theData[5] = 1;
- signal->theData[6] = logPagePtr.i;
- signal->theData[7] = logPartPtr.p->prevFilepage;
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
-
- if (DEBUG_REDO)
- ndbout_c("writeDirty 1 page at part: %u file: %u pos: %u",
- logPartPtr.i,
- logFilePtr.p->fileNo,
- logPartPtr.p->prevFilepage);
-
-}//Dblqh::writeDirty()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A WORD INTO THE LOG, CHECK FOR NEW PAGE -------
- *
- * SUBROUTINE SHORT NAME: WLW
- * ------------------------------------------------------------------------- */
-void Dblqh::writeLogWord(Signal* signal, Uint32 data)
-{
- Uint32 logPos = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- ndbrequire(logPos < ZPAGE_SIZE);
- logPagePtr.p->logPageWord[logPos] = data;
- logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + 1;
- if ((logPos + 1) == ZPAGE_SIZE) {
- jam();
- completedLogPage(signal, ZNORMAL, __LINE__);
- seizeLogpage(signal);
- initLogpage(signal);
- logFilePtr.p->currentLogpage = logPagePtr.i;
- logFilePtr.p->currentFilepage++;
- }//if
-}//Dblqh::writeLogWord()
-
-/* --------------------------------------------------------------------------
- * ------- WRITE A NEXT LOG RECORD AND CHANGE TO NEXT MBYTE -------
- *
- * SUBROUTINE SHORT NAME: WNL
-// Input Pointers:
-// logFilePtr(Redefines)
-// logPagePtr (Redefines)
-// logPartPtr
- * ------------------------------------------------------------------------- */
-void Dblqh::writeNextLog(Signal* signal)
-{
- LogFileRecordPtr wnlNextLogFilePtr;
- UintR twnlNextFileNo;
- UintR twnlNewMbyte;
- UintR twnlRemWords;
- UintR twnlNextMbyte;
-
-/* -------------------------------------------------- */
-/* CALCULATE THE NEW NUMBER OF REMAINING WORDS */
-/* AS 128*2036 WHERE 128 * 8 KBYTE = 1 MBYTE */
-/* AND 2036 IS THE NUMBER OF WORDS IN A PAGE */
-/* THAT IS USED FOR LOG INFORMATION. */
-/* -------------------------------------------------- */
- twnlRemWords = ZPAGE_SIZE - ZPAGE_HEADER_SIZE;
- twnlRemWords = twnlRemWords * ZPAGES_IN_MBYTE;
- wnlNextLogFilePtr.i = logFilePtr.p->nextLogFile;
- ptrCheckGuard(wnlNextLogFilePtr, clogFileFileSize, logFileRecord);
-/* -------------------------------------------------- */
-/* WRITE THE NEXT LOG RECORD. */
-/* -------------------------------------------------- */
- ndbrequire(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] < ZPAGE_SIZE);
- logPagePtr.p->logPageWord[logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]] =
- ZNEXT_MBYTE_TYPE;
- if (logFilePtr.p->currentMbyte == (clogFileSize - 1)) {
- jam();
-/* -------------------------------------------------- */
-/* CALCULATE THE NEW REMAINING WORDS WHEN */
-/* CHANGING LOG FILE IS PERFORMED */
-/* -------------------------------------------------- */
- twnlRemWords = twnlRemWords - (ZPAGE_SIZE - ZPAGE_HEADER_SIZE);
-/* -------------------------------------------------- */
-/* ENSURE THAT THE LOG PAGES ARE WRITTEN AFTER */
-/* WE HAVE CHANGED MBYTE. */
-/* -------------------------------------------------- */
-/* ENSURE LAST PAGE IN PREVIOUS MBYTE IS */
-/* WRITTEN AND THAT THE STATE OF THE WRITE IS */
-/* PROPERLY SET. */
-/* -------------------------------------------------- */
-/* WE HAVE TO CHANGE LOG FILE */
-/* -------------------------------------------------- */
- completedLogPage(signal, ZLAST_WRITE_IN_FILE, __LINE__);
- if (wnlNextLogFilePtr.p->fileNo == 0) {
- jam();
-/* -------------------------------------------------- */
-/* WE HAVE FINALISED A LOG LAP, START FROM LOG */
-/* FILE 0 AGAIN */
-/* -------------------------------------------------- */
- logPartPtr.p->logLap++;
- }//if
- logPartPtr.p->currentLogfile = wnlNextLogFilePtr.i;
- logFilePtr.i = wnlNextLogFilePtr.i;
- logFilePtr.p = wnlNextLogFilePtr.p;
- twnlNewMbyte = 0;
- } else {
- jam();
-/* -------------------------------------------------- */
-/* INCREMENT THE CURRENT MBYTE */
-/* SET PAGE INDEX TO PAGE HEADER SIZE */
-/* -------------------------------------------------- */
- completedLogPage(signal, ZENFORCE_WRITE, __LINE__);
- twnlNewMbyte = logFilePtr.p->currentMbyte + 1;
- }//if
-/* -------------------------------------------------- */
-/* CHANGE TO NEW LOG FILE IF NECESSARY */
-/* UPDATE THE FILE POSITION TO THE NEW MBYTE */
-/* FOUND IN PAGE PART OF TNEXT_LOG_PTR */
-/* ALLOCATE AND INITIATE A NEW PAGE SINCE WE */
-/* HAVE SENT THE PREVIOUS PAGE TO DISK. */
-/* SET THE NEW NUMBER OF REMAINING WORDS IN THE */
-/* NEW MBYTE ALLOCATED. */
-/* -------------------------------------------------- */
- logFilePtr.p->currentMbyte = twnlNewMbyte;
- logFilePtr.p->filePosition = twnlNewMbyte * ZPAGES_IN_MBYTE;
- logFilePtr.p->currentFilepage = twnlNewMbyte * ZPAGES_IN_MBYTE;
- logFilePtr.p->remainingWordsInMbyte = twnlRemWords;
- seizeLogpage(signal);
- if (logFilePtr.p->currentMbyte == 0) {
- jam();
- logFilePtr.p->lastPageWritten = 0;
- if (logFilePtr.p->fileNo == 0) {
- jam();
- releaseLogpage(signal);
- logPagePtr.i = logFilePtr.p->logPageZero;
- ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
- }//if
- }//if
- initLogpage(signal);
- logFilePtr.p->currentLogpage = logPagePtr.i;
- if (logFilePtr.p->currentMbyte == 0) {
- jam();
-/* -------------------------------------------------- */
-/* THIS IS A NEW FILE, WRITE THE FILE DESCRIPTOR*/
-/* ALSO OPEN THE NEXT LOG FILE TO ENSURE THAT */
-/* THIS FILE IS OPEN WHEN ITS TURN COMES. */
-/* -------------------------------------------------- */
- writeFileHeaderOpen(signal, ZNORMAL);
- openNextLogfile(signal);
- logFilePtr.p->fileChangeState = LogFileRecord::BOTH_WRITES_ONGOING;
- }//if
- if (logFilePtr.p->fileNo == logPartPtr.p->logTailFileNo) {
- if (logFilePtr.p->currentMbyte == logPartPtr.p->logTailMbyte) {
- jam();
-/* -------------------------------------------------- */
-/* THE HEAD AND TAIL HAS MET. THIS SHOULD NEVER */
-/* OCCUR. CAN HAPPEN IF THE LOCAL CHECKPOINTS */
-/* TAKE FAR TOO LONG TIME. SO TIMING PROBLEMS */
-/* CAN INVOKE THIS SYSTEM CRASH. HOWEVER ONLY */
-/* VERY SERIOUS TIMING PROBLEMS. */
-/* -------------------------------------------------- */
- systemError(signal, __LINE__);
- }//if
- }//if
- if (logFilePtr.p->currentMbyte == (clogFileSize - 1)) {
- jam();
- twnlNextMbyte = 0;
- if (logFilePtr.p->fileChangeState != LogFileRecord::NOT_ONGOING) {
- jam();
- logPartPtr.p->logPartState = LogPartRecord::FILE_CHANGE_PROBLEM;
- }//if
- twnlNextFileNo = wnlNextLogFilePtr.p->fileNo;
- } else {
- jam();
- twnlNextMbyte = logFilePtr.p->currentMbyte + 1;
- twnlNextFileNo = logFilePtr.p->fileNo;
- }//if
- if (twnlNextFileNo == logPartPtr.p->logTailFileNo) {
- if (logPartPtr.p->logTailMbyte == twnlNextMbyte) {
- jam();
-/* -------------------------------------------------- */
-/* THE NEXT MBYTE WILL BE THE TAIL. WE MUST */
-/* STOP LOGGING NEW OPERATIONS. THIS OPERATION */
-/* ALLOWED TO PASS. ALSO COMMIT, NEXT, COMPLETED*/
-/* GCI, ABORT AND FRAGMENT SPLIT IS ALLOWED. */
-/* OPERATIONS ARE ALLOWED AGAIN WHEN THE TAIL */
-/* IS MOVED FORWARD AS A RESULT OF A START_LCP */
-/* _ROUND SIGNAL ARRIVING FROM DBDIH. */
-/* -------------------------------------------------- */
- logPartPtr.p->logPartState = LogPartRecord::TAIL_PROBLEM;
- }//if
- }//if
-}//Dblqh::writeNextLog()
-
-void
-Dblqh::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
- DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
- Uint32 arg= dumpState->args[0];
- if(dumpState->args[0] == DumpStateOrd::CommitAckMarkersSize){
- infoEvent("LQH: m_commitAckMarkerPool: %d free size: %d",
- m_commitAckMarkerPool.getNoOfFree(),
- m_commitAckMarkerPool.getSize());
- }
- if(dumpState->args[0] == DumpStateOrd::CommitAckMarkersDump){
- infoEvent("LQH: m_commitAckMarkerPool: %d free size: %d",
- m_commitAckMarkerPool.getNoOfFree(),
- m_commitAckMarkerPool.getSize());
-
- CommitAckMarkerIterator iter;
- for(m_commitAckMarkerHash.first(iter); iter.curr.i != RNIL;
- m_commitAckMarkerHash.next(iter)){
- infoEvent("CommitAckMarker: i = %d (0x%x, 0x%x)"
- " ApiRef: 0x%x apiOprec: 0x%x TcNodeId: %d",
- iter.curr.i,
- iter.curr.p->transid1,
- iter.curr.p->transid2,
- iter.curr.p->apiRef,
- iter.curr.p->apiOprec,
- iter.curr.p->tcNodeId);
- }
- }
-
- // Dump info about number of log pages
- if(dumpState->args[0] == DumpStateOrd::LqhDumpNoLogPages){
- infoEvent("LQH: Log pages : %d Free: %d",
- clogPageFileSize,
- cnoOfLogPages);
- }
-
- // Dump all defined tables that LQH knowns about
- if(dumpState->args[0] == DumpStateOrd::LqhDumpAllDefinedTabs){
- for(Uint32 i = 0; i<ctabrecFileSize; i++){
- TablerecPtr tabPtr;
- tabPtr.i = i;
- ptrAss(tabPtr, tablerec);
- if(tabPtr.p->tableStatus != Tablerec::NOT_DEFINED){
- infoEvent("Table %d Status: %d Usage: %d",
- i, tabPtr.p->tableStatus, tabPtr.p->usageCount);
-
- for (Uint32 j = 0; j<MAX_FRAG_PER_NODE; j++)
- {
- FragrecordPtr fragPtr;
- if ((fragPtr.i = tabPtr.p->fragrec[j]) != RNIL)
- {
- c_fragment_pool.getPtr(fragPtr);
- infoEvent(" frag: %d distKey: %u",
- tabPtr.p->fragid[j],
- fragPtr.p->fragDistributionKey);
- }
- }
- }
- }
- return;
- }
-
- // Dump all ScanRecords
- if (dumpState->args[0] == DumpStateOrd::LqhDumpAllScanRec){
- Uint32 recordNo = 0;
- if (signal->length() == 1)
- infoEvent("LQH: Dump all ScanRecords - size: %d",
- cscanrecFileSize);
- else if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- dumpState->args[0] = DumpStateOrd::LqhDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
-
- if (recordNo < cscanrecFileSize-1){
- dumpState->args[0] = DumpStateOrd::LqhDumpAllScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- return;
- }
-
- // Dump all active ScanRecords
- if (dumpState->args[0] == DumpStateOrd::LqhDumpAllActiveScanRec){
- Uint32 recordNo = 0;
- if (signal->length() == 1)
- infoEvent("LQH: Dump active ScanRecord - size: %d",
- cscanrecFileSize);
- else if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- ScanRecordPtr sp;
- sp.i = recordNo;
- c_scanRecordPool.getPtr(scanptr);
- if (sp.p->scanState != ScanRecord::SCAN_FREE){
- dumpState->args[0] = DumpStateOrd::LqhDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
- }
-
- if (recordNo < cscanrecFileSize-1){
- dumpState->args[0] = DumpStateOrd::LqhDumpAllActiveScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- return;
- }
-
- if(dumpState->args[0] == DumpStateOrd::LqhDumpOneScanRec){
- Uint32 recordNo = RNIL;
- if (signal->length() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= cscanrecFileSize)
- return;
-
- ScanRecordPtr sp;
- sp.i = recordNo;
- c_scanRecordPool.getPtr(sp);
- infoEvent("Dblqh::ScanRecord[%d]: state=%d, type=%d, "
- "complStatus=%d, scanNodeId=%d",
- sp.i,
- sp.p->scanState,
- sp.p->scanType,
- sp.p->scanCompletedStatus,
- sp.p->scanNodeId);
- infoEvent(" apiBref=0x%x, scanAccPtr=%d",
- sp.p->scanApiBlockref,
- sp.p->scanAccPtr);
- infoEvent(" copyptr=%d, ailen=%d, complOps=%d, concurrOps=%d",
- sp.p->copyPtr,
- sp.p->scanAiLength,
- sp.p->m_curr_batch_size_rows,
- sp.p->m_max_batch_size_rows);
- infoEvent(" errCnt=%d, schV=%d",
- sp.p->scanErrorCounter,
- sp.p->scanSchemaVersion);
- infoEvent(" stpid=%d, flag=%d, lhold=%d, lmode=%d, num=%d",
- sp.p->scanStoredProcId,
- sp.p->scanFlag,
- sp.p->scanLockHold,
- sp.p->scanLockMode,
- sp.p->scanNumber);
- infoEvent(" relCount=%d, TCwait=%d, TCRec=%d, KIflag=%d",
- sp.p->scanReleaseCounter,
- sp.p->scanTcWaiting,
- sp.p->scanTcrec,
- sp.p->scanKeyinfoFlag);
- return;
- }
- if(dumpState->args[0] == DumpStateOrd::LqhDumpLcpState){
-
- infoEvent("== LQH LCP STATE ==");
- infoEvent(" clcpCompletedState=%d, c_lcpId=%d, cnoOfFragsCheckpointed=%d",
- clcpCompletedState,
- c_lcpId,
- cnoOfFragsCheckpointed);
-
- LcpRecordPtr TlcpPtr;
- // Print information about the current local checkpoint
- TlcpPtr.i = 0;
- ptrAss(TlcpPtr, lcpRecord);
- infoEvent(" lcpState=%d lastFragmentFlag=%d",
- TlcpPtr.p->lcpState, TlcpPtr.p->lastFragmentFlag);
- infoEvent("currentFragment.fragPtrI=%d",
- TlcpPtr.p->currentFragment.fragPtrI);
- infoEvent("currentFragment.lcpFragOrd.tableId=%d",
- TlcpPtr.p->currentFragment.lcpFragOrd.tableId);
- infoEvent(" lcpQueued=%d reportEmpty=%d",
- TlcpPtr.p->lcpQueued,
- TlcpPtr.p->reportEmpty);
- char buf[8*_NDB_NODE_BITMASK_SIZE+1];
- infoEvent(" m_EMPTY_LCP_REQ=%d",
- TlcpPtr.p->m_EMPTY_LCP_REQ.getText(buf));
-
- return;
- }
-
-#ifdef ERROR_INSERT
-#ifdef NDB_DEBUG_FULL
- if(dumpState->args[0] == DumpStateOrd::LCPContinue){
- switch(cerrorInsert){
- case 5904:
- CLEAR_ERROR_INSERT_VALUE;
- g_trace_lcp.restore(*globalData.getBlock(BACKUP), signal);
- return;
- default:
- return;
- }
- }
-#endif
-#endif
-
- if(arg == 2304 || arg == 2305)
- {
- jam();
- Uint32 i;
- GcpRecordPtr gcp; gcp.i = RNIL;
- for(i = 0; i<4; i++)
- {
- logPartPtr.i = i;
- ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
- ndbout_c("LP %d state: %d WW_Gci: %d gcprec: %d flq: %d currfile: %d tailFileNo: %d logTailMbyte: %d",
- i,
- logPartPtr.p->logPartState,
- logPartPtr.p->waitWriteGciLog,
- logPartPtr.p->gcprec,
- logPartPtr.p->firstLogQueue,
- logPartPtr.p->currentLogfile,
- logPartPtr.p->logTailFileNo,
- logPartPtr.p->logTailMbyte);
-
- if(gcp.i == RNIL && logPartPtr.p->gcprec != RNIL)
- gcp.i = logPartPtr.p->gcprec;
-
- LogFileRecordPtr logFilePtr;
- Uint32 first= logFilePtr.i= logPartPtr.p->firstLogfile;
- do
- {
- ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
- ndbout_c(" file %d(%d) FileChangeState: %d logFileStatus: %d currentMbyte: %d currentFilepage %d",
- logFilePtr.p->fileNo,
- logFilePtr.i,
- logFilePtr.p->fileChangeState,
- logFilePtr.p->logFileStatus,
- logFilePtr.p->currentMbyte,
- logFilePtr.p->currentFilepage);
- logFilePtr.i = logFilePtr.p->nextLogFile;
- } while(logFilePtr.i != first);
- }
-
- if(gcp.i != RNIL)
- {
- ptrCheckGuard(gcp, cgcprecFileSize, gcpRecord);
- for(i = 0; i<4; i++)
- {
- ndbout_c(" GCP %d file: %d state: %d sync: %d page: %d word: %d",
- i, gcp.p->gcpFilePtr[i], gcp.p->gcpLogPartState[i],
- gcp.p->gcpSyncReady[i],
- gcp.p->gcpPageNo[i],
- gcp.p->gcpWordNo[i]);
- }
- }
-
- if(arg== 2305)
- {
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR,
- "Please report this as a bug. "
- "Provide as much info as possible, expecially all the "
- "ndb_*_out.log files, Thanks. "
- "Shutting down node due to failed handling of GCP_SAVEREQ");
-
- }
- }
-
- if (dumpState->args[0] == DumpStateOrd::LqhErrorInsert5042 && (signal->getLength() >= 2))
- {
- c_error_insert_table_id = dumpState->args[1];
- if (signal->getLength() == 2)
- {
- SET_ERROR_INSERT_VALUE(5042);
- }
- else
- {
- SET_ERROR_INSERT_VALUE(dumpState->args[2]);
- }
- }
-
- TcConnectionrec *regTcConnectionrec = tcConnectionrec;
- Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
- if(arg == 2306)
- {
- for(Uint32 i = 0; i<1024; i++)
- {
- TcConnectionrecPtr tcRec;
- tcRec.i = ctransidHash[i];
- while(tcRec.i != RNIL)
- {
- ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
- ndbout << "TcConnectionrec " << tcRec.i;
- signal->theData[0] = 2307;
- signal->theData[1] = tcRec.i;
- execDUMP_STATE_ORD(signal);
- tcRec.i = tcRec.p->nextHashRec;
- }
- }
- }
-
- if(arg == 2307 || arg == 2308)
- {
- TcConnectionrecPtr tcRec;
- tcRec.i = signal->theData[1];
- ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
-
- ndbout << " transactionState = " << tcRec.p->transactionState<<endl;
- ndbout << " operation = " << tcRec.p->operation<<endl;
- ndbout << " tcNodeFailrec = " << tcRec.p->tcNodeFailrec
- << " seqNoReplica = " << tcRec.p->seqNoReplica
- << endl;
- ndbout << " replicaType = " << tcRec.p->replicaType
- << " reclenAiLqhkey = " << tcRec.p->reclenAiLqhkey
- << " opExec = " << tcRec.p->opExec
- << endl;
- ndbout << " opSimple = " << tcRec.p->opSimple
- << " nextSeqNoReplica = " << tcRec.p->nextSeqNoReplica
- << " lockType = " << tcRec.p->lockType
- << endl;
- ndbout << " lastReplicaNo = " << tcRec.p->lastReplicaNo
- << " indTakeOver = " << tcRec.p->indTakeOver
- << " dirtyOp = " << tcRec.p->dirtyOp
- << endl;
- ndbout << " activeCreat = " << tcRec.p->activeCreat
- << " tcBlockref = " << hex << tcRec.p->tcBlockref
- << " reqBlockref = " << hex << tcRec.p->reqBlockref
- << " primKeyLen = " << tcRec.p->primKeyLen
- << " nrcopyflag = " << LqhKeyReq::getNrCopyFlag(tcRec.p->reqinfo)
- << endl;
- ndbout << " nextReplica = " << tcRec.p->nextReplica
- << " tcBlockref = " << hex << tcRec.p->tcBlockref
- << " reqBlockref = " << hex << tcRec.p->reqBlockref
- << " primKeyLen = " << tcRec.p->primKeyLen
- << endl;
- ndbout << " logStopPageNo = " << tcRec.p->logStopPageNo
- << " logStartPageNo = " << tcRec.p->logStartPageNo
- << " logStartPageIndex = " << tcRec.p->logStartPageIndex
- << endl;
- ndbout << " errorCode = " << tcRec.p->errorCode
- << " clientBlockref = " << hex << tcRec.p->clientBlockref
- << " applRef = " << hex << tcRec.p->applRef
- << " totSendlenAi = " << tcRec.p->totSendlenAi
- << endl;
- ndbout << " totReclenAi = " << tcRec.p->totReclenAi
- << " tcScanRec = " << tcRec.p->tcScanRec
- << " tcScanInfo = " << tcRec.p->tcScanInfo
- << " tcOprec = " << hex << tcRec.p->tcOprec
- << endl;
- ndbout << " tableref = " << tcRec.p->tableref
- << " simpleTcConnect = " << tcRec.p->simpleTcConnect
- << " storedProcId = " << tcRec.p->storedProcId
- << " schemaVersion = " << tcRec.p->schemaVersion
- << endl;
- ndbout << " reqinfo = " << tcRec.p->reqinfo
- << " reqRef = " << tcRec.p->reqRef
- << " readlenAi = " << tcRec.p->readlenAi
- << " prevTc = " << tcRec.p->prevTc
- << endl;
- ndbout << " prevLogTcrec = " << tcRec.p->prevLogTcrec
- << " prevHashRec = " << tcRec.p->prevHashRec
- << " nodeAfterNext0 = " << tcRec.p->nodeAfterNext[0]
- << " nodeAfterNext1 = " << tcRec.p->nodeAfterNext[1]
- << endl;
- ndbout << " nextTcConnectrec = " << tcRec.p->nextTcConnectrec
- << " nextTc = " << tcRec.p->nextTc
- << " nextTcLogQueue = " << tcRec.p->nextTcLogQueue
- << " nextLogTcrec = " << tcRec.p->nextLogTcrec
- << endl;
- ndbout << " nextHashRec = " << tcRec.p->nextHashRec
- << " logWriteState = " << tcRec.p->logWriteState
- << " logStartFileNo = " << tcRec.p->logStartFileNo
- << " listState = " << tcRec.p->listState
- << endl;
- ndbout << " lastAttrinbuf = " << tcRec.p->lastAttrinbuf
- << " lastTupkeybuf = " << tcRec.p->lastTupkeybuf
- << " hashValue = " << tcRec.p->hashValue
- << endl;
- ndbout << " gci = " << tcRec.p->gci
- << " fragmentptr = " << tcRec.p->fragmentptr
- << " fragmentid = " << tcRec.p->fragmentid
- << " firstTupkeybuf = " << tcRec.p->firstTupkeybuf
- << endl;
- ndbout << " firstAttrinbuf = " << tcRec.p->firstAttrinbuf
- << " currTupAiLen = " << tcRec.p->currTupAiLen
- << " currReclenAi = " << tcRec.p->currReclenAi
- << endl;
- ndbout << " tcTimer = " << tcRec.p->tcTimer
- << " clientConnectrec = " << tcRec.p->clientConnectrec
- << " applOprec = " << hex << tcRec.p->applOprec
- << " abortState = " << tcRec.p->abortState
- << endl;
- ndbout << " transid0 = " << hex << tcRec.p->transid[0]
- << " transid1 = " << hex << tcRec.p->transid[1]
- << " tupkeyData0 = " << tcRec.p->tupkeyData[0]
- << " tupkeyData1 = " << tcRec.p->tupkeyData[1]
- << endl;
- ndbout << " tupkeyData2 = " << tcRec.p->tupkeyData[2]
- << " tupkeyData3 = " << tcRec.p->tupkeyData[3]
- << " m_nr_delete.m_cnt = " << tcRec.p->m_nr_delete.m_cnt
- << endl;
- switch (tcRec.p->transactionState) {
-
- case TcConnectionrec::SCAN_STATE_USED:
- if (tcRec.p->tcScanRec < cscanrecFileSize){
- ScanRecordPtr TscanPtr;
- c_scanRecordPool.getPtr(TscanPtr, tcRec.p->tcScanRec);
- ndbout << " scanState = " << TscanPtr.p->scanState << endl;
- //TscanPtr.p->scanLocalref[2];
- ndbout << " copyPtr="<<TscanPtr.p->copyPtr
- << " scanAccPtr="<<TscanPtr.p->scanAccPtr
- << " scanAiLength="<<TscanPtr.p->scanAiLength
- << endl;
- ndbout << " m_curr_batch_size_rows="<<
- TscanPtr.p->m_curr_batch_size_rows
- << " m_max_batch_size_rows="<<
- TscanPtr.p->m_max_batch_size_rows
- << " scanErrorCounter="<<TscanPtr.p->scanErrorCounter
- << endl;
- ndbout << " scanSchemaVersion="<<TscanPtr.p->scanSchemaVersion
- << " scanStoredProcId="<<TscanPtr.p->scanStoredProcId
- << " scanTcrec="<<TscanPtr.p->scanTcrec
- << endl;
- ndbout << " scanType="<<TscanPtr.p->scanType
- << " scanApiBlockref="<<TscanPtr.p->scanApiBlockref
- << " scanNodeId="<<TscanPtr.p->scanNodeId
- << " scanCompletedStatus="<<TscanPtr.p->scanCompletedStatus
- << endl;
- ndbout << " scanFlag="<<TscanPtr.p->scanFlag
- << " scanLockHold="<<TscanPtr.p->scanLockHold
- << " scanLockMode="<<TscanPtr.p->scanLockMode
- << " scanNumber="<<TscanPtr.p->scanNumber
- << endl;
- ndbout << " scanReleaseCounter="<<TscanPtr.p->scanReleaseCounter
- << " scanTcWaiting="<<TscanPtr.p->scanTcWaiting
- << " scanKeyinfoFlag="<<TscanPtr.p->scanKeyinfoFlag
- << endl;
- } else{
- ndbout << "No connected scan record found" << endl;
- }
- break;
- default:
- break;
- }
- ndbrequire(arg != 2308);
- }
-
-#ifdef ERROR_INSERT
- if (arg == 5712 || arg == 5713)
- {
- if (arg == 5712)
- {
- traceopout = &ndbout;
- }
- else if (arg == 5713)
- {
- traceopout = tracenrout;
- }
- SET_ERROR_INSERT_VALUE(arg);
- }
-#endif
-
-}//Dblqh::execDUMP_STATE_ORD()
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* ---------------------- TRIGGER HANDLING ------------------------ */
-/* ---------------------------------------------------------------- */
-/* */
-/* All trigger signals from TRIX are forwarded top TUP */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-// Trigger signals
-void
-Dblqh::execCREATE_TRIG_REQ(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBTUP_REF, GSN_CREATE_TRIG_REQ, signal,
- CreateTrigReq::SignalLength, JBB);
-}
-
-void
-Dblqh::execCREATE_TRIG_CONF(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBDICT_REF, GSN_CREATE_TRIG_CONF, signal,
- CreateTrigConf::SignalLength, JBB);
-}
-
-void
-Dblqh::execCREATE_TRIG_REF(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBDICT_REF, GSN_CREATE_TRIG_REF, signal,
- CreateTrigRef::SignalLength, JBB);
-}
-
-void
-Dblqh::execDROP_TRIG_REQ(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ, signal,
- DropTrigReq::SignalLength, JBB);
-}
-
-void
-Dblqh::execDROP_TRIG_CONF(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBDICT_REF, GSN_DROP_TRIG_CONF, signal,
- DropTrigConf::SignalLength, JBB);
-}
-
-void
-Dblqh::execDROP_TRIG_REF(Signal* signal)
-{
- jamEntry();
-
- sendSignal(DBDICT_REF, GSN_DROP_TRIG_REF, signal,
- DropTrigRef::SignalLength, JBB);
-}
-
-Uint32 Dblqh::calcPageCheckSum(LogPageRecordPtr logP){
- Uint32 checkSum = 37;
-#ifdef VM_TRACE
- for (Uint32 i = (ZPOS_CHECKSUM+1); i<ZPAGE_SIZE; i++)
- checkSum = logP.p->logPageWord[i] ^ checkSum;
-#endif
- return checkSum;
- }
-
-#ifdef NDB_DEBUG_FULL
-#ifdef ERROR_INSERT
-void
-TraceLCP::sendSignal(Uint32 ref, Uint32 gsn, Signal* signal,
- Uint32 len, Uint32 prio)
-{
- Sig s;
- s.type = Sig::Sig_send;
- s.header = signal->header;
- s.header.theVerId_signalNumber = gsn;
- s.header.theReceiversBlockNumber = ref;
- s.header.theLength = len;
- memcpy(s.theData, signal->theData, 4 * len);
- m_signals.push_back(s);
- assert(signal->getNoOfSections() == 0);
-}
-
-void
-TraceLCP::save(Signal* signal){
- Sig s;
- s.type = Sig::Sig_save;
- s.header = signal->header;
- memcpy(s.theData, signal->theData, 4 * signal->getLength());
- m_signals.push_back(s);
- assert(signal->getNoOfSections() == 0);
-}
-
-void
-TraceLCP::restore(SimulatedBlock& lqh, Signal* sig){
- Uint32 cnt = m_signals.size();
- for(Uint32 i = 0; i<cnt; i++){
- sig->header = m_signals[i].header;
- memcpy(sig->theData, m_signals[i].theData, 4 * sig->getLength());
- switch(m_signals[i].type){
- case Sig::Sig_send:
- lqh.sendSignal(sig->header.theReceiversBlockNumber,
- sig->header.theVerId_signalNumber,
- sig,
- sig->header.theLength,
- JBB);
- break;
- case Sig::Sig_save:
- lqh.executeFunction(sig->header.theVerId_signalNumber, sig);
- break;
- }
- }
- m_signals.clear();
-}
-#endif
-#endif
-
-void Dblqh::writeDbgInfoPageHeader(LogPageRecordPtr logP, Uint32 place,
- Uint32 pageNo, Uint32 wordWritten)
-{
- logP.p->logPageWord[ZPOS_LOG_TIMER]= logPartPtr.p->logTimer;
- logP.p->logPageWord[ZPOS_PREV_PAGE_NO]= logP.p->logPageWord[ZPOS_PAGE_NO];
- logP.p->logPageWord[ZPOS_PAGE_I]= logP.i;
- logP.p->logPageWord[ZPOS_PLACE_WRITTEN_FROM]= place;
- logP.p->logPageWord[ZPOS_PAGE_NO]= pageNo;
- logP.p->logPageWord[ZPOS_PAGE_FILE_NO]= logFilePtr.p->fileNo;
- logP.p->logPageWord[ZPOS_WORD_WRITTEN]= wordWritten;
- logP.p->logPageWord[ZPOS_IN_WRITING]= 1;
-}
-
-#if defined ERROR_INSERT
-void
-Dblqh::TRACE_OP_DUMP(const Dblqh::TcConnectionrec* regTcPtr, const char * pos)
-{
- (* traceopout)
- << "[ " << hex << regTcPtr->transid[0]
- << " " << hex << regTcPtr->transid[1] << " ] " << dec
- << pos
- << " " << (Operation_t)regTcPtr->operation
- << " " << regTcPtr->tableref
- << "(" << regTcPtr->fragmentid << ")"
- << "(" << (regTcPtr->seqNoReplica == 0 ? "P" : "B") << ")" ;
-
- {
- (* traceopout) << "key=[" << hex;
- Uint32 i;
- for(i = 0; i<regTcPtr->primKeyLen && i < 4; i++){
- (* traceopout) << hex << regTcPtr->tupkeyData[i] << " ";
- }
-
- DatabufPtr regDatabufptr;
- regDatabufptr.i = regTcPtr->firstTupkeybuf;
- while(i < regTcPtr->primKeyLen)
- {
- ptrCheckGuard(regDatabufptr, cdatabufFileSize, databuf);
- for(Uint32 j = 0; j<4 && i<regTcPtr->primKeyLen; j++, i++)
- (* traceopout) << hex << regDatabufptr.p->data[j] << " ";
- }
- (* traceopout) << "] ";
- }
-
- if (regTcPtr->m_use_rowid)
- (* traceopout) << " " << regTcPtr->m_row_id;
- (* traceopout) << endl;
-}
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Makefile.am b/storage/ndb/src/kernel/blocks/dblqh/Makefile.am
deleted file mode 100644
index 31612b5c25e..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_PROGRAMS = ndbd_redo_log_reader
-
-ndbd_redo_log_reader_SOURCES = redoLogReader/records.cpp \
- redoLogReader/reader.cpp
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-ndbd_redo_log_reader_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/reader.cpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/reader.cpp
deleted file mode 100644
index ea483527c15..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/reader.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//----------------------------------------------------------------
-// REDOLOGFILEREADER
-// Reads a redo log file and checks it for errors and/or prints
-// the file in a human readable format.
-//
-// Usage: redoLogFileReader <file> [-noprint] [-nocheck]
-// [-mbyte <0-15>] [-mbyteHeaders] [-pageHeaders]
-//
-//----------------------------------------------------------------
-
-
-#include <ndb_global.h>
-
-#include "records.hpp"
-
-#define RETURN_ERROR 1
-#define RETURN_OK 0
-
-#define FROM_BEGINNING 0
-
-void usage(const char * prg);
-Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords);
-void readArguments(int argc, const char** argv);
-void doExit();
-
-FILE * f= 0;
-char fileName[256];
-bool theDumpFlag = false;
-bool thePrintFlag = true;
-bool theCheckFlag = true;
-bool onlyPageHeaders = false;
-bool onlyMbyteHeaders = false;
-bool onlyFileDesc = false;
-bool firstLap = true;
-Uint32 startAtMbyte = 0;
-Uint32 startAtPage = 0;
-Uint32 startAtPageIndex = 0;
-Uint32 *redoLogPage;
-
-NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read a redo log file", 16384) {
- int wordIndex = 0;
- int oldWordIndex = 0;
- Uint32 recordType = 1234567890;
-
- PageHeader *thePageHeader;
- CompletedGCIRecord *cGCIrecord;
- PrepareOperationRecord *poRecord;
- NextLogRecord *nlRecord;
- FileDescriptor *fdRecord;
- CommitTransactionRecord *ctRecord;
- InvalidCommitTransactionRecord *ictRecord;
- NextMbyteRecord *nmRecord;
- AbortTransactionRecord *atRecord;
-
- readArguments(argc, argv);
-
- f = fopen(fileName, "rb");
- if(!f){
- perror("Error: open file");
- exit(RETURN_ERROR);
- }
-
- Uint32 tmpFileOffset = startAtMbyte * PAGESIZE * NO_PAGES_IN_MBYTE * sizeof(Uint32);
- if (fseek(f, tmpFileOffset, FROM_BEGINNING)) {
- perror("Error: Move in file");
- exit(RETURN_ERROR);
- }
-
- redoLogPage = new Uint32[PAGESIZE*NO_PAGES_IN_MBYTE];
- Uint32 words_from_previous_page = 0;
-
- // Loop for every mbyte.
- bool lastPage = false;
- for (Uint32 j = startAtMbyte; j < NO_MBYTE_IN_FILE && !lastPage; j++) {
-
- readFromFile(f, redoLogPage, PAGESIZE*NO_PAGES_IN_MBYTE);
-
- words_from_previous_page = 0;
-
- // Loop for every page.
- for (int i = 0; i < NO_PAGES_IN_MBYTE; i++) {
- wordIndex = 0;
- thePageHeader = (PageHeader *) &redoLogPage[i*PAGESIZE];
- // Print out mbyte number, page number and page index.
- ndbout << j << ":" << i << ":" << wordIndex << endl
- << " " << j*32 + i << ":" << wordIndex << " ";
- if (thePrintFlag) ndbout << (*thePageHeader);
- if (theCheckFlag) {
- if(!thePageHeader->check()) {
- ndbout << "Error in thePageHeader->check()" << endl;
- doExit();
- }
-
- Uint32 checkSum = 37;
- for (int ps = 1; ps < PAGESIZE; ps++)
- checkSum = redoLogPage[i*PAGESIZE+ps] ^ checkSum;
-
- if (checkSum != redoLogPage[i*PAGESIZE]){
- ndbout << "WRONG CHECKSUM: checksum = " << redoLogPage[i*PAGESIZE]
- << " expected = " << checkSum << endl;
- doExit();
- }
- else
- ndbout << "expected checksum: " << checkSum << endl;
-
- }
-
- lastPage = i != 0 && thePageHeader->lastPage();
- Uint32 lastWord = thePageHeader->lastWord();
-
- if (onlyMbyteHeaders) {
- // Show only the first page header in every mbyte of the file.
- break;
- }
-
- if (onlyPageHeaders) {
- // Show only page headers. Continue with the next page in this for loop.
- continue;
- }
-
-
- wordIndex = thePageHeader->getLogRecordSize() - words_from_previous_page;
- Uint32 *redoLogPagePos = redoLogPage + i*PAGESIZE;
- if (words_from_previous_page)
- {
- memmove(redoLogPagePos + wordIndex ,
- redoLogPagePos - words_from_previous_page,
- words_from_previous_page*4);
- }
-
- do {
- if (words_from_previous_page)
- {
- // Print out mbyte number, page number and word index.
- ndbout << j << ":" << i-1 << ":" << PAGESIZE-words_from_previous_page << endl
- << j << ":" << i << ":" << wordIndex+words_from_previous_page << endl
- << " " << j*32 + i-1 << ":" << PAGESIZE-words_from_previous_page << " ";
- words_from_previous_page = 0;
- }
- else
- {
- // Print out mbyte number, page number and word index.
- ndbout << j << ":" << i << ":" << wordIndex << endl
- << " " << j*32 + i << ":" << wordIndex << " ";
- }
- redoLogPagePos = redoLogPage + i*PAGESIZE + wordIndex;
- oldWordIndex = wordIndex;
- recordType = *redoLogPagePos;
- switch(recordType) {
- case ZFD_TYPE:
- fdRecord = (FileDescriptor *) redoLogPagePos;
- if (thePrintFlag) ndbout << (*fdRecord);
- if (theCheckFlag) {
- if(!fdRecord->check()) {
- ndbout << "Error in fdRecord->check()" << endl;
- doExit();
- }
- }
- if (onlyFileDesc) {
- delete [] redoLogPage;
- exit(RETURN_OK);
- }
- wordIndex += fdRecord->getLogRecordSize();
- break;
-
- case ZNEXT_LOG_RECORD_TYPE:
- nlRecord = (NextLogRecord *) redoLogPagePos;
- wordIndex += nlRecord->getLogRecordSize(wordIndex);
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*nlRecord);
- if (theCheckFlag) {
- if(!nlRecord->check()) {
- ndbout << "Error in nlRecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZCOMPLETED_GCI_TYPE:
- cGCIrecord = (CompletedGCIRecord *) redoLogPagePos;
- wordIndex += cGCIrecord->getLogRecordSize();
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*cGCIrecord);
- if (theCheckFlag) {
- if(!cGCIrecord->check()) {
- ndbout << "Error in cGCIrecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZPREP_OP_TYPE:
- poRecord = (PrepareOperationRecord *) redoLogPagePos;
- wordIndex += poRecord->getLogRecordSize(PAGESIZE-wordIndex);
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*poRecord);
- if (theCheckFlag) {
- if(!poRecord->check()) {
- ndbout << "Error in poRecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZCOMMIT_TYPE:
- ctRecord = (CommitTransactionRecord *) redoLogPagePos;
- wordIndex += ctRecord->getLogRecordSize();
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*ctRecord);
- if (theCheckFlag) {
- if(!ctRecord->check()) {
- ndbout << "Error in ctRecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZINVALID_COMMIT_TYPE:
- ictRecord = (InvalidCommitTransactionRecord *) redoLogPagePos;
- wordIndex += ictRecord->getLogRecordSize();
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*ictRecord);
- if (theCheckFlag) {
- if(!ictRecord->check()) {
- ndbout << "Error in ictRecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZNEXT_MBYTE_TYPE:
- nmRecord = (NextMbyteRecord *) redoLogPagePos;
- if (thePrintFlag) ndbout << (*nmRecord);
- i = NO_PAGES_IN_MBYTE;
- break;
-
- case ZABORT_TYPE:
- atRecord = (AbortTransactionRecord *) redoLogPagePos;
- wordIndex += atRecord->getLogRecordSize();
- if (wordIndex <= PAGESIZE) {
- if (thePrintFlag) ndbout << (*atRecord);
- if (theCheckFlag) {
- if(!atRecord->check()) {
- ndbout << "Error in atRecord->check()" << endl;
- doExit();
- }
- }
- }
- break;
-
- case ZNEW_PREP_OP_TYPE:
- case ZFRAG_SPLIT_TYPE:
- ndbout << endl << "Record type = " << recordType << " not implemented." << endl;
- doExit();
-
- default:
- ndbout << " ------ERROR: UNKNOWN RECORD TYPE------" << endl;
-
- // Print out remaining data in this page
- for (int k = wordIndex; k < PAGESIZE; k++){
- Uint32 unknown = redoLogPage[i*PAGESIZE + k];
- ndbout_c("%-30d%-12u%-12x", k, unknown, unknown);
- }
-
- doExit();
- }
- } while(wordIndex < lastWord && i < NO_PAGES_IN_MBYTE);
-
-
- if (lastPage)
- {
- if (theDumpFlag)
- {
- ndbout << " ------PAGE END: DUMPING REST OF PAGE------" << endl;
- for (int k = wordIndex > PAGESIZE ? oldWordIndex : wordIndex;
- k < PAGESIZE; k++)
- {
- Uint32 word = redoLogPage[i*PAGESIZE + k];
- ndbout_c("%-30d%-12u%-12x", k, word, word);
- }
- }
- break;
- }
- if (wordIndex > PAGESIZE) {
- words_from_previous_page = PAGESIZE - oldWordIndex;
- ndbout << " ----------- Record continues on next page -----------" << endl;
- } else {
- wordIndex = 0;
- words_from_previous_page = 0;
- }
- ndbout << endl;
- }//for
- ndbout << endl;
- if (startAtMbyte != 0) {
- break;
- }
- }//for
- fclose(f);
- delete [] redoLogPage;
- exit(RETURN_OK);
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords) {
- Uint32 noOfReadWords;
- if ( !(noOfReadWords = fread(toPtr, sizeof(Uint32), sizeInWords, f)) ) {
- ndbout << "Error reading file" << endl;
- doExit();
- }
-
- return noOfReadWords;
-}
-
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-
-void usage(const char * prg){
- ndbout << endl << "Usage: " << endl << prg
- << " <Binary log file> [-noprint] [-nocheck] [-mbyte <0-15>] "
- << "[-mbyteheaders] [-pageheaders] [-filedescriptors] [-page <0-31>] "
- << "[-pageindex <12-8191>]"
- << endl << endl;
-
-}
-void readArguments(int argc, const char** argv)
-{
- if(argc < 2 || argc > 9){
- usage(argv[0]);
- doExit();
- }
-
- strcpy(fileName, argv[1]);
- argc--;
-
- int i = 2;
- while (argc > 1)
- {
- if (strcmp(argv[i], "-noprint") == 0) {
- thePrintFlag = false;
- } else if (strcmp(argv[i], "-dump") == 0) {
- theDumpFlag = true;
- } else if (strcmp(argv[i], "-nocheck") == 0) {
- theCheckFlag = false;
- } else if (strcmp(argv[i], "-mbyteheaders") == 0) {
- onlyMbyteHeaders = true;
- } else if (strcmp(argv[i], "-pageheaders") == 0) {
- onlyPageHeaders = true;
- } else if (strcmp(argv[i], "-filedescriptors") == 0) {
- onlyFileDesc = true;
- } else if (strcmp(argv[i], "-mbyte") == 0) {
- startAtMbyte = atoi(argv[i+1]);
- if (startAtMbyte > 15) {
- usage(argv[0]);
- doExit();
- }
- argc--;
- i++;
- } else if (strcmp(argv[i], "-page") == 0) {
- startAtPage = atoi(argv[i+1]);
- if (startAtPage > 31) {
- usage(argv[0]);
- doExit();
- }
- argc--;
- i++;
- } else if (strcmp(argv[i], "-pageindex") == 0) {
- startAtPageIndex = atoi(argv[i+1]);
- if (startAtPageIndex > 8191 || startAtPageIndex < 12) {
- usage(argv[0]);
- doExit();
- }
- argc--;
- i++;
- } else {
- usage(argv[0]);
- doExit();
- }
- argc--;
- i++;
- }
-
-}
-
-void doExit() {
- ndbout << "Error in redoLogReader(). Exiting!" << endl;
- if (f) fclose(f);
- delete [] redoLogPage;
- exit(RETURN_ERROR);
-}
diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp
deleted file mode 100644
index 6431b4ba9b6..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "records.hpp"
-
-void printOut(const char *string, Uint32 value) {
- ndbout_c("%-30s%-12u%-12x", string, value, value);
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool AbortTransactionRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 AbortTransactionRecord::getLogRecordSize() {
- return ABORTTRANSACTIONRECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const AbortTransactionRecord& atr) {
- no << "----------ABORT TRANSACTION RECORD-------------" << endl << endl;
- printOut("Record type:", atr.m_recordType);
- printOut("TransactionId1:", atr.m_transactionId1);
- printOut("TransactionId2:", atr.m_transactionId2);
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool NextMbyteRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 NextMbyteRecord::getLogRecordSize() {
- return NEXTMBYTERECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const NextMbyteRecord& nmr) {
- no << "----------NEXT MBYTE RECORD--------------------" << endl << endl;
- printOut("Record type:", nmr.m_recordType);
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool CommitTransactionRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 CommitTransactionRecord::getLogRecordSize() {
- return COMMITTRANSACTIONRECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const CommitTransactionRecord& ctr) {
- no << "----------COMMIT TRANSACTION RECORD------------" << endl << endl;
- printOut("Record type:", ctr.m_recordType);
- printOut("TableId", ctr.m_tableId);
- printOut("SchemaVersion:", ctr.m_schemaVersion);
- printOut("FfragmentId", ctr.m_fragmentId);
- printOut("File no. of Prep. Op.", ctr.m_fileNumberOfPrepareOperation);
- printOut("Start page no. of Prep. Op.", ctr.m_startPageNumberOfPrepareOperation);
- printOut("Start page index of Prep. Op.", ctr.m_startPageIndexOfPrepareOperation);
- printOut("Stop page no. of Prep. Op.", ctr.m_stopPageNumberOfPrepareOperation);
- printOut("GlobalCheckpoint", ctr.m_globalCheckpoint);
-
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool InvalidCommitTransactionRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 InvalidCommitTransactionRecord::getLogRecordSize() {
- return COMMITTRANSACTIONRECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const InvalidCommitTransactionRecord& ictr) {
- no << "------INVALID COMMIT TRANSACTION RECORD--------" << endl << endl;
- printOut("Record type:", ictr.m_recordType);
- printOut("TableId", ictr.m_tableId);
- printOut("FfragmentId", ictr.m_fragmentId);
- printOut("File no. of Prep. Op.", ictr.m_fileNumberOfPrepareOperation);
- printOut("Start page no. of Prep. Op.", ictr.m_startPageNumberOfPrepareOperation);
- printOut("Start page index of Prep. Op.", ictr.m_startPageIndexOfPrepareOperation);
- printOut("Stop page no. of Prep. Op.", ictr.m_stopPageNumberOfPrepareOperation);
- printOut("GlobalCheckpoint", ictr.m_globalCheckpoint);
-
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool PrepareOperationRecord::check() {
- // Not fully implemented.
- if (m_operationType == 3 && m_attributeLength != 0)
- return false;
-
- if (m_logRecordSize != (m_attributeLength + m_keyLength + 8))
- return false;
-
- return true;
-}
-
-Uint32 PrepareOperationRecord::getLogRecordSize(Uint32 wordsRead) {
- if (wordsRead < 2)
- return 2; // make sure we read more
- return m_logRecordSize;
-}
-
-NdbOut& operator<<(NdbOut& no, const PrepareOperationRecord& por) {
- no << "-----------PREPARE OPERATION RECORD------------" << endl << endl;
- printOut("Record type:", por.m_recordType);
- printOut("logRecordSize:", por.m_logRecordSize);
- printOut("hashValue:", por.m_hashValue);
- switch (por.m_operationType) {
- case 0:
- ndbout_c("%-30s%-12u%-6s", "operationType:",
- por.m_operationType, "read");
- break;
- case 1:
- ndbout_c("%-30s%-12u%-6s", "operationType:",
- por.m_operationType, "update");
- break;
- case 2:
- ndbout_c("%-30s%-12u%-6s", "operationType:",
- por.m_operationType, "insert");
- break;
- case 3:
- ndbout_c("%-30s%-12u%-6s", "operationType:",
- por.m_operationType, "delete");
- break;
- default:
- printOut("operationType:", por.m_operationType);
- }
- printOut("page_no: ", por.m_page_no);
- printOut("page_idx: ", por.m_page_idx);
- printOut("attributeLength:", por.m_attributeLength);
- printOut("keyLength:", por.m_keyLength);
-
-#if 1
- // Print keydata
- Uint32* p = (Uint32*)&por.m_keyInfo;
- for(Uint32 i=0; i < por.m_keyLength; i++){
- printOut("keydata:", *p);
- p++;
- }
-
- // Print attrdata
- for(Uint32 i=0; i < por.m_attributeLength; i++){
- printOut("attrdata:", *p);
- p++;
- }
-#endif
-
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool CompletedGCIRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 CompletedGCIRecord::getLogRecordSize() {
- return COMPLETEDGCIRECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const CompletedGCIRecord& cGCIr) {
- no << "-----------COMPLETED GCI RECORD----------------" << endl << endl;
- printOut("Record type:", cGCIr.m_recordType);
- printOut("Completed GCI:", cGCIr.m_theCompletedGCI);
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-bool NextLogRecord::check() {
- // Not implemented yet.
- return true;
-}
-
-Uint32 NextLogRecord::getLogRecordSize(Uint32 pageIndex) {
- return PAGESIZE - pageIndex;
-}
-
-NdbOut& operator<<(NdbOut& no, const NextLogRecord& nl) {
- no << "-----------NEXT LOG RECORD --------------------" << endl << endl;
- printOut("Record type:", nl.m_recordType);
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-Uint32 PageHeader::getLogRecordSize() {
- return PAGEHEADERSIZE;
-}
-
-bool PageHeader::check() {
- // Not implemented yet.
- return true;
-}
-
-bool PageHeader::lastPage()
-{
- return m_next_page == 0xffffff00;
-}
-
-Uint32 PageHeader::lastWord()
-{
- return m_current_page_index;
-}
-
-
-NdbOut& operator<<(NdbOut& no, const PageHeader& ph) {
- no << "------------PAGE HEADER------------------------" << endl << endl;
- ndbout_c("%-30s%-12s%-12s\n", "", "Decimal", "Hex");
- printOut("Checksum:", ph.m_checksum);
- printOut("Laps since initial start:", ph.m_lap);
- printOut("Max gci completed:", ph.m_max_gci_completed);
- printOut("Max gci started:", ph.m_max_gci_started);
- printOut("Ptr to next page:", ph.m_next_page);
- printOut("Ptr to previous page:", ph.m_previous_page);
- printOut("Ndb version:", ph.m_ndb_version);
- printOut("Number of log files:", ph.m_number_of_logfiles);
- printOut("Current page index:", ph.m_current_page_index);
- printOut("Oldest prepare op. file No.:", ph.m_old_prepare_file_number);
- printOut("Oldest prepare op. page ref.:", ph.m_old_prepare_page_reference);
- printOut("Dirty flag:", ph.m_dirty_flag);
- printOut("Write Timer:", ph.m_log_timer);
- printOut("Page i-val:", ph.m_page_i_value);
- printOut("Place written:", ph.m_place_written_from);
- printOut("Page No in File:", ph.m_page_no);
- printOut("File No:", ph.m_file_no);
- printOut("Word Written:", ph.m_word_written);
- printOut("In Writing (should be 1)", ph.m_in_writing_flag);
- printOut("Prev Page No (can be garbage)", ph.m_prev_page_no);
- printOut("In Free List (should be 0):", ph.m_in_free_list);
- no << endl;
- return no;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-Uint32 FileDescriptor::getLogRecordSize() {
- return FILEDESCRIPTORHEADERSIZE
- + m_fdHeader.m_noOfDescriptors * FILEDESCRIPTORRECORDSIZE;
-}
-
-NdbOut& operator<<(NdbOut& no, const FileDescriptor& fd) {
- no << "-------FILE DESCRIPTOR HEADER------------------" << endl << endl;
- printOut("Record type:", fd.m_fdHeader.m_recordType);
- printOut("Number of file descriptors:", fd.m_fdHeader.m_noOfDescriptors);
- printOut("File number:", fd.m_fdHeader.m_fileNo);
- ndbout << endl;
- for(Uint32 i = 0; i < fd.m_fdHeader.m_noOfDescriptors; i++) {
- fd.printARecord(i);
- }
- return no;
-}
-
-void FileDescriptor::printARecord( Uint32 recordIndex ) const {
- ndbout << "------------------FILE DESCRIPTOR " << recordIndex
- <<" ---------------------" << endl << endl;
- ndbout_c("%-30s%-12s%-12s\n", "", "Decimal", "Hex");
-
- for(int i = 1; i <= NO_MBYTE_IN_FILE; i++) {
- ndbout_c("%s%2d%s%-12u%-12x", "Max GCI completed, mbyte ", i, ": ",
- m_fdRecord[recordIndex].m_maxGciCompleted[i-1],
- m_fdRecord[recordIndex].m_maxGciCompleted[i-1]);
- }
- for(int i = 1; i <= NO_MBYTE_IN_FILE; i++) {
- ndbout_c("%s%2d%s%-12u%-12x", "Max GCI started, mbyte ", i, ": ",
- m_fdRecord[recordIndex].m_maxGciStarted[i-1],
- m_fdRecord[recordIndex].m_maxGciStarted[i-1]);
- }
- for(int i = 1; i <= NO_MBYTE_IN_FILE; i++) {
- ndbout_c("%s%2d%s%-12u%-12x", "Last prepared ref, mbyte ", i, ": ",
- m_fdRecord[recordIndex].m_lastPreparedReference[i-1],
- m_fdRecord[recordIndex].m_lastPreparedReference[i-1]);
- }
- ndbout << endl;
-}
-
-bool FileDescriptor::check() {
- // Not implemented yet.
- return true;
-}
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp
deleted file mode 100644
index abdb57e8646..00000000000
--- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-#include <ndb_types.h>
-
-#define ZNEW_PREP_OP_TYPE 0
-#define ZPREP_OP_TYPE 1
-#define ZCOMMIT_TYPE 2
-#define ZABORT_TYPE 3
-#define ZFD_TYPE 4
-#define ZFRAG_SPLIT_TYPE 5
-#define ZNEXT_LOG_RECORD_TYPE 6
-#define ZNEXT_MBYTE_TYPE 7
-#define ZCOMPLETED_GCI_TYPE 8
-#define ZINVALID_COMMIT_TYPE 9
-
-#define MAX_FILE_DESCRIPTORS 40
-#define NO_MBYTE_IN_FILE 16
-
-#define PAGESIZE 8192
-#define NO_PAGES_IN_MBYTE 32
-#define NO_MBYTE_IN_FILE 16
-
-#define COMMITTRANSACTIONRECORDSIZE 9
-#define COMPLETEDGCIRECORDSIZE 2
-#define PAGEHEADERSIZE 32
-#define FILEDESCRIPTORHEADERSIZE 3
-#define FILEDESCRIPTORRECORDSIZE 48
-#define NEXTMBYTERECORDSIZE 1
-#define ABORTTRANSACTIONRECORDSIZE 3
-
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class AbortTransactionRecord {
- friend NdbOut& operator<<(NdbOut&, const AbortTransactionRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- Uint32 m_recordType;
- Uint32 m_transactionId1;
- Uint32 m_transactionId2;
-};
-
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class NextMbyteRecord {
- friend NdbOut& operator<<(NdbOut&, const NextMbyteRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- Uint32 m_recordType;
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-
-class PrepareOperationRecord {
- friend NdbOut& operator<<(NdbOut&, const PrepareOperationRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize(Uint32 wordsRead);
-
-protected:
- Uint32 m_recordType;
- Uint32 m_logRecordSize;
- Uint32 m_hashValue;
- Uint32 m_operationType; // 0 READ, 1 UPDATE, 2 INSERT, 3 DELETE
- Uint32 m_attributeLength;
- Uint32 m_keyLength;
- Uint32 m_page_no;
- Uint32 m_page_idx;
- Uint32 *m_keyInfo; // In this order
- Uint32 *m_attrInfo;// In this order
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class CompletedGCIRecord {
- friend NdbOut& operator<<(NdbOut&, const CompletedGCIRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- Uint32 m_recordType;
- Uint32 m_theCompletedGCI;
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class NextLogRecord {
- friend NdbOut& operator<<(NdbOut&, const NextLogRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize(Uint32);
-protected:
- Uint32 m_recordType;
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class PageHeader {
- friend NdbOut& operator<<(NdbOut&, const PageHeader&);
-public:
- bool check();
- Uint32 getLogRecordSize();
- bool lastPage();
- Uint32 lastWord();
-protected:
- Uint32 m_checksum;
- Uint32 m_lap;
- Uint32 m_max_gci_completed;
- Uint32 m_max_gci_started;
- Uint32 m_next_page;
- Uint32 m_previous_page;
- Uint32 m_ndb_version;
- Uint32 m_number_of_logfiles;
- Uint32 m_current_page_index;
- Uint32 m_old_prepare_file_number;
- Uint32 m_old_prepare_page_reference;
- Uint32 m_dirty_flag;
-/* Debug info Start */
- Uint32 m_log_timer;
- Uint32 m_page_i_value;
- Uint32 m_place_written_from;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_word_written;
- Uint32 m_in_writing_flag;
- Uint32 m_prev_page_no;
- Uint32 m_in_free_list;
-/* Debug info End */
-};
-
-//----------------------------------------------------------------
-// File descriptor.
-//----------------------------------------------------------------
-
-class FileDescriptorHeader {
-public:
- Uint32 m_recordType;
- Uint32 m_noOfDescriptors;
- Uint32 m_fileNo;
-};
-
-class FileDescriptorRecord {
-public:
- Uint32 m_maxGciCompleted[16];
- Uint32 m_maxGciStarted[16];
- Uint32 m_lastPreparedReference[16];
-};
-
-class FileDescriptor {
- friend NdbOut& operator<<(NdbOut&, const FileDescriptor&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- void printARecord( Uint32 ) const;
- FileDescriptorHeader m_fdHeader;
- FileDescriptorRecord m_fdRecord[1];
-};
-
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class CommitTransactionRecord {
- friend NdbOut& operator<<(NdbOut&, const CommitTransactionRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- Uint32 m_recordType;
- Uint32 m_tableId;
- Uint32 m_schemaVersion;
- Uint32 m_fragmentId;
- Uint32 m_fileNumberOfPrepareOperation;
- Uint32 m_startPageNumberOfPrepareOperation;
- Uint32 m_startPageIndexOfPrepareOperation;
- Uint32 m_stopPageNumberOfPrepareOperation;
- Uint32 m_globalCheckpoint;
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-class InvalidCommitTransactionRecord {
- friend NdbOut& operator<<(NdbOut&, const InvalidCommitTransactionRecord&);
-public:
- bool check();
- Uint32 getLogRecordSize();
-protected:
- Uint32 m_recordType;
- Uint32 m_tableId;
- Uint32 m_fragmentId;
- Uint32 m_fileNumberOfPrepareOperation;
- Uint32 m_startPageNumberOfPrepareOperation;
- Uint32 m_startPageIndexOfPrepareOperation;
- Uint32 m_stopPageNumberOfPrepareOperation;
- Uint32 m_globalCheckpoint;
-};
-
-//----------------------------------------------------------------
-//
-//----------------------------------------------------------------
-
-struct NextLogRec {
-
-};
-
-struct NewPrepareOperation {
-
-};
-
-struct FragmentSplit {
-
-};
diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
deleted file mode 100644
index 90338cb58cd..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ /dev/null
@@ -1,1978 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBTC_H
-#define DBTC_H
-
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include <DLHashTable.hpp>
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <DLFifoList.hpp>
-#include <DataBuffer.hpp>
-#include <Bitmask.hpp>
-#include <AttributeList.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/LqhTransConf.hpp>
-#include <signaldata/LqhKey.hpp>
-#include <signaldata/TrigAttrInfo.hpp>
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/TransIdAI.hpp>
-#include <signaldata/EventReport.hpp>
-#include <trigger_definitions.h>
-#include <SignalCounter.hpp>
-
-#ifdef DBTC_C
-/*
- * 2.2 LOCAL SYMBOLS
- * -----------------
- */
-#define Z8NIL 255
-#define ZAPI_CONNECT_FILESIZE 20
-#define ZATTRBUF_FILESIZE 4000
-#define ZCLOSED 2
-#define ZCOMMITING 0 /* VALUE FOR TRANSTATUS */
-#define ZCOMMIT_SETUP 2
-#define ZCONTINUE_ABORT_080 4
-#define ZDATABUF_FILESIZE 4000
-#define ZGCP_FILESIZE 10
-#define ZINBUF_DATA_LEN 24 /* POSITION OF 'DATA LENGHT'-VARIABLE. */
-#define ZINBUF_NEXT 27 /* POSITION OF 'NEXT'-VARIABLE. */
-#define ZINBUF_PREV 26 /* POSITION OF 'PREVIOUS'-VARIABLE. */
-#define ZINTSPH1 1
-#define ZINTSPH2 2
-#define ZINTSPH3 3
-#define ZINTSPH6 6
-#define ZLASTPHASE 255
-#define ZMAX_DATA_IN_LQHKEYREQ 12
-#define ZNODEBUF_FILESIZE 2000
-#define ZNR_OF_SEIZE 10
-#define ZSCANREC_FILE_SIZE 100
-#define ZSCAN_FRAGREC_FILE_SIZE 400
-#define ZSCAN_OPREC_FILE_SIZE 400
-#define ZSEND_ATTRINFO 0
-#define ZSPH1 1
-#define ZTABREC_FILESIZE 16
-#define ZTAKE_OVER_ACTIVE 1
-#define ZTAKE_OVER_IDLE 0
-#define ZTC_CONNECT_FILESIZE 200
-#define ZTCOPCONF_SIZE 6
-
-// ----------------------------------------
-// Error Codes for Scan
-// ----------------------------------------
-#define ZNO_CONCURRENCY_ERROR 242
-#define ZTOO_HIGH_CONCURRENCY_ERROR 244
-#define ZNO_SCANREC_ERROR 245
-#define ZNO_FRAGMENT_ERROR 246
-#define ZSCAN_AI_LEN_ERROR 269
-#define ZSCAN_LQH_ERROR 270
-#define ZSCAN_FRAG_LQH_ERROR 274
-
-#define ZSCANTIME_OUT_ERROR 296
-#define ZSCANTIME_OUT_ERROR2 297
-
-// ----------------------------------------
-// Error Codes for transactions
-// ----------------------------------------
-#define ZSTATE_ERROR 202
-#define ZLENGTH_ERROR 207 // Also Scan
-#define ZERO_KEYLEN_ERROR 208
-#define ZSIGNAL_ERROR 209
-#define ZGET_ATTRBUF_ERROR 217 // Also Scan
-#define ZGET_DATAREC_ERROR 218
-#define ZMORE_AI_IN_TCKEYREQ_ERROR 220
-#define ZCOMMITINPROGRESS 230
-#define ZROLLBACKNOTALLOWED 232
-#define ZNO_FREE_TC_CONNECTION 233 // Also Scan
-#define ZABORTINPROGRESS 237
-#define ZPREPAREINPROGRESS 238
-#define ZWRONG_SCHEMA_VERSION_ERROR 241 // Also Scan
-#define ZSCAN_NODE_ERROR 250
-#define ZTRANS_STATUS_ERROR 253
-#define ZTIME_OUT_ERROR 266
-#define ZSIMPLE_READ_WITHOUT_AI 271
-#define ZNO_AI_WITH_UPDATE 272
-#define ZSEIZE_API_COPY_ERROR 275
-#define ZSCANINPROGRESS 276
-#define ZABORT_ERROR 277
-#define ZCOMMIT_TYPE_ERROR 278
-
-#define ZNO_FREE_TC_MARKER 279
-#define ZNODE_SHUTDOWN_IN_PROGRESS 280
-#define ZCLUSTER_SHUTDOWN_IN_PROGRESS 281
-#define ZWRONG_STATE 282
-#define ZCLUSTER_IN_SINGLEUSER_MODE 299
-
-#define ZDROP_TABLE_IN_PROGRESS 283
-#define ZNO_SUCH_TABLE 284
-#define ZUNKNOWN_TABLE_ERROR 285
-#define ZNODEFAIL_BEFORE_COMMIT 286
-#define ZINDEX_CORRUPT_ERROR 287
-
-// ----------------------------------------
-// Seize error
-// ----------------------------------------
-#define ZNO_FREE_API_CONNECTION 219
-#define ZSYSTEM_NOT_STARTED_ERROR 203
-
-// ----------------------------------------
-// Release errors
-// ----------------------------------------
-#define ZINVALID_CONNECTION 229
-
-
-#define ZNOT_FOUND 626
-#define ZALREADYEXIST 630
-#define ZNOTUNIQUE 893
-
-#define ZINVALID_KEY 290
-#endif
-
-class Dbtc: public SimulatedBlock {
-public:
- enum ConnectionState {
- CS_CONNECTED = 0,
- CS_DISCONNECTED = 1,
- CS_STARTED = 2,
- CS_RECEIVING = 3,
- CS_PREPARED = 4,
- CS_START_PREPARING = 5,
- CS_REC_PREPARING = 6,
- CS_RESTART = 7,
- CS_ABORTING = 8,
- CS_COMPLETING = 9,
- CS_COMPLETE_SENT = 10,
- CS_PREPARE_TO_COMMIT = 11,
- CS_COMMIT_SENT = 12,
- CS_START_COMMITTING = 13,
- CS_COMMITTING = 14,
- CS_REC_COMMITTING = 15,
- CS_WAIT_ABORT_CONF = 16,
- CS_WAIT_COMPLETE_CONF = 17,
- CS_WAIT_COMMIT_CONF = 18,
- CS_FAIL_ABORTING = 19,
- CS_FAIL_ABORTED = 20,
- CS_FAIL_PREPARED = 21,
- CS_FAIL_COMMITTING = 22,
- CS_FAIL_COMMITTED = 23,
- CS_FAIL_COMPLETED = 24,
- CS_START_SCAN = 25
- };
-
- enum OperationState {
- OS_CONNECTING_DICT = 0,
- OS_CONNECTED = 1,
- OS_OPERATING = 2,
- OS_PREPARED = 3,
- OS_COMMITTING = 4,
- OS_COMMITTED = 5,
- OS_COMPLETING = 6,
- OS_COMPLETED = 7,
- OS_RESTART = 8,
- OS_ABORTING = 9,
- OS_ABORT_SENT = 10,
- OS_TAKE_OVER = 11,
- OS_WAIT_DIH = 12,
- OS_WAIT_KEYINFO = 13,
- OS_WAIT_ATTR = 14,
- OS_WAIT_COMMIT_CONF = 15,
- OS_WAIT_ABORT_CONF = 16,
- OS_WAIT_COMPLETE_CONF = 17,
- OS_WAIT_SCAN = 18
- };
-
- enum AbortState {
- AS_IDLE = 0,
- AS_ACTIVE = 1
- };
-
- enum HostState {
- HS_ALIVE = 0,
- HS_DEAD = 1
- };
-
- enum LqhTransState {
- LTS_IDLE = 0,
- LTS_ACTIVE = 1
- };
-
- enum FailState {
- FS_IDLE = 0,
- FS_LISTENING = 1,
- FS_COMPLETING = 2
- };
-
- enum SystemStartState {
- SSS_TRUE = 0,
- SSS_FALSE = 1
- };
-
- enum TimeOutCheckState {
- TOCS_TRUE = 0,
- TOCS_FALSE = 1
- };
-
- enum ReturnSignal {
- RS_NO_RETURN = 0,
- RS_TCKEYCONF = 1,
- RS_TC_COMMITCONF = 3,
- RS_TCROLLBACKCONF = 4,
- RS_TCROLLBACKREP = 5
- };
-
- enum IndexOperationState {
- IOS_NOOP = 0,
- IOS_INDEX_ACCESS = 1,
- IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF = 2,
- IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3,
- IOS_INDEX_OPERATION = 4
- };
-
- enum IndexState {
- IS_BUILDING = 0, // build in progress, start state at create
- IS_ONLINE = 1 // ready to use
- };
-
-
- /**--------------------------------------------------------------------------
- * LOCAL SYMBOLS PER 'SYMBOL-VALUED' VARIABLE
- *
- *
- * NSYMB ZAPI_CONNECT_FILESIZE = 20
- * NSYMB ZTC_CONNECT_FILESIZE = 200
- * NSYMB ZHOST_FILESIZE = 16
- * NSYMB ZDATABUF_FILESIZE = 4000
- * NSYMB ZATTRBUF_FILESIZE = 4000
- * NSYMB ZGCP_FILESIZE = 10
- *
- *
- * ABORTED CODES
- * TPHASE NSYMB ZSPH1 = 1
- * NSYMB ZLASTPHASE = 255
- *
- *
- * LQH_TRANS
- * NSYMB ZTRANS_ABORTED = 1
- * NSYMB ZTRANS_PREPARED = 2
- * NSYMB ZTRANS_COMMITTED = 3
- * NSYMB ZCOMPLETED_LQH_TRANS = 4
- * NSYMB ZTRANS_COMPLETED = 5
- *
- *
- * TAKE OVER
- * NSYMB ZTAKE_OVER_IDLE = 0
- * NSYMB ZTAKE_OVER_ACTIVE = 1
- *
- * ATTRBUF (ATTRBUF_RECORD)
- * NSYMB ZINBUF_DATA_LEN = 24
- * NSYMB ZINBUF_NEXTFREE = 25 (NOT USED )
- * NSYMB ZINBUF_PREV = 26
- * NSYMB ZINBUF_NEXT = 27
- -------------------------------------------------------------------------*/
- /*
- 2.3 RECORDS AND FILESIZES
- -------------------------
- */
- /* **************************************************************** */
- /* ---------------------------------------------------------------- */
- /* ------------------- TRIGGER AND INDEX DATA --------------------- */
- /* ---------------------------------------------------------------- */
- /* **************************************************************** */
- /* ********* DEFINED TRIGGER DATA ********* */
- /* THIS RECORD FORMS LISTS OF ACTIVE */
- /* TRIGGERS FOR EACH TABLE. */
- /* THE RECORDS ARE MANAGED BY A TRIGGER */
- /* POOL WHERE A TRIGGER RECORD IS SEIZED */
- /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
- /* WHEN THE TRIGGER IS DEACTIVATED. */
- /* **************************************** */
- struct TcDefinedTriggerData {
- TcDefinedTriggerData() {}
- /**
- * Trigger id, used to identify the trigger
- */
- UintR triggerId;
-
- /**
- * Trigger type, defines what the trigger is used for
- */
- TriggerType::Value triggerType;
-
- /**
- * Trigger type, defines what the trigger is used for
- */
- TriggerEvent::Value triggerEvent;
-
- /**
- * Attribute mask, defines what attributes are to be monitored
- * Can be seen as a compact representation of SQL column name list
- */
- Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
-
- /**
- * Index id, only used by secondary_index triggers. This is same as
- * index table id in DICT.
- **/
- Uint32 indexId;
-
- /**
- * Prev pointer (used in list)
- */
- Uint32 prevList;
-
- inline void print(NdbOut & s) const {
- s << "[DefinedTriggerData = " << triggerId << "]";
- }
- };
- typedef Ptr<TcDefinedTriggerData> DefinedTriggerPtr;
-
- /**
- * Pool of trigger data record
- */
- ArrayPool<TcDefinedTriggerData> c_theDefinedTriggerPool;
-
- /**
- * The list of active triggers
- */
- DLList<TcDefinedTriggerData> c_theDefinedTriggers;
-
- typedef DataBuffer<11> AttributeBuffer;
-
- AttributeBuffer::DataBufferPool c_theAttributeBufferPool;
-
- UintR c_transactionBufferSpace;
-
-
- /* ********** FIRED TRIGGER DATA ********** */
- /* THIS RECORD FORMS LISTS OF FIRED */
- /* TRIGGERS FOR A TRANSACTION. */
- /* THE RECORDS ARE MANAGED BY A TRIGGER */
- /* POOL WHERE A TRIGGER RECORD IS SEIZED */
- /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
- /* WHEN THE TRIGGER IS DEACTIVATED. */
- /* **************************************** */
- struct TcFiredTriggerData {
- TcFiredTriggerData() {}
-
- /**
- * Trigger id, used to identify the trigger
- **/
- Uint32 triggerId;
-
- /**
- * The operation that fired the trigger
- */
- Uint32 fireingOperation;
-
- /**
- * The fragment id of the firing operation. This will be appended
- * to the Primary Key such that the record can be found even in the
- * case of user defined partitioning.
- */
- Uint32 fragId;
-
- /**
- * Used for scrapping in case of node failure
- */
- Uint32 nodeId;
-
- /**
- * Trigger attribute info, primary key value(s)
- */
- AttributeBuffer::Head keyValues;
-
- /**
- * Trigger attribute info, attribute value(s) before operation
- */
- AttributeBuffer::Head beforeValues;
-
- /**
- * Trigger attribute info, attribute value(s) after operation
- */
- AttributeBuffer::Head afterValues;
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- Uint32 nextHash;
- };
-
- /**
- * Prev pointer (used in list)
- */
- union {
- Uint32 prevList;
- Uint32 prevHash;
- };
-
- inline void print(NdbOut & s) const {
- s << "[FiredTriggerData = " << triggerId << "]";
- }
-
- inline Uint32 hashValue() const {
- return fireingOperation ^ nodeId;
- }
-
- inline bool equal(const TcFiredTriggerData & rec) const {
- return fireingOperation == rec.fireingOperation && nodeId == rec.nodeId;
- }
- };
- typedef Ptr<TcFiredTriggerData> FiredTriggerPtr;
-
- /**
- * Pool of trigger data record
- */
- ArrayPool<TcFiredTriggerData> c_theFiredTriggerPool;
- DLHashTable<TcFiredTriggerData> c_firedTriggerHash;
- AttributeBuffer::DataBufferPool c_theTriggerAttrInfoPool;
-
- Uint32 c_maxNumberOfDefinedTriggers;
- Uint32 c_maxNumberOfFiredTriggers;
-
- struct AttrInfoRecord {
- /**
- * Pre-allocated AttrInfo signal
- */
- AttrInfo attrInfo;
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- /**
- * Prev pointer (used in list)
- */
- Uint32 prevList;
- };
-
-
- /* ************* INDEX DATA *************** */
- /* THIS RECORD FORMS LISTS OF ACTIVE */
- /* INDEX FOR EACH TABLE. */
- /* THE RECORDS ARE MANAGED BY A INDEX */
- /* POOL WHERE AN INDEX RECORD IS SEIZED */
- /* WHEN AN INDEX IS CREATED AND RELEASED */
- /* WHEN THE INDEX IS DROPPED. */
- /* **************************************** */
- struct TcIndexData {
- /**
- * IndexState
- */
- IndexState indexState;
-
- /**
- * Index id, same as index table id in DICT
- */
- Uint32 indexId;
-
- /**
- * Index attribute list. Only the length is used in v21x.
- */
- AttributeList attributeList;
-
- /**
- * Primary table id, the primary table to be indexed
- */
- Uint32 primaryTableId;
-
- /**
- * Primary key position in secondary table
- */
- Uint32 primaryKeyPos;
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- /**
- * Prev pointer (used in list)
- */
- Uint32 prevList;
- };
-
- typedef Ptr<TcIndexData> TcIndexDataPtr;
-
- /**
- * Pool of index data record
- */
- ArrayPool<TcIndexData> c_theIndexPool;
-
- /**
- * The list of defined indexes
- */
- DLList<TcIndexData> c_theIndexes;
- UintR c_maxNumberOfIndexes;
-
- struct TcIndexOperation {
- TcIndexOperation(AttributeBuffer::DataBufferPool & abp) :
- indexOpState(IOS_NOOP),
- expectedKeyInfo(0),
- keyInfo(abp),
- expectedAttrInfo(0),
- attrInfo(abp),
- expectedTransIdAI(0),
- transIdAI(abp),
- indexReadTcConnect(RNIL)
- {}
-
- ~TcIndexOperation()
- {
- }
-
- // Index data
- Uint32 indexOpId;
- IndexOperationState indexOpState; // Used to mark on-going TcKeyReq
- Uint32 expectedKeyInfo;
- AttributeBuffer keyInfo; // For accumulating IndxKeyInfo
- Uint32 expectedAttrInfo;
- AttributeBuffer attrInfo; // For accumulating IndxAttrInfo
- Uint32 expectedTransIdAI;
- AttributeBuffer transIdAI; // For accumulating TransId_AI
-
- TcKeyReq tcIndxReq;
- UintR connectionIndex;
- UintR indexReadTcConnect; //
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- /**
- * Prev pointer (used in list)
- */
- Uint32 prevList;
- };
-
- typedef Ptr<TcIndexOperation> TcIndexOperationPtr;
-
- /**
- * Pool of index data record
- */
- ArrayPool<TcIndexOperation> c_theIndexOperationPool;
-
- UintR c_maxNumberOfIndexOperations;
-
- /************************** API CONNECT RECORD ***********************
- * The API connect record contains the connection record to which the
- * application connects.
- *
- * The application can send one operation at a time. It can send a
- * new operation immediately after sending the previous operation.
- * Thereby several operations can be active in one transaction within TC.
- * This is achieved by using the API connect record.
- * Each active operation is handled by the TC connect record.
- * As soon as the TC connect record has sent the
- * request to the LQH it is ready to receive new operations.
- * The LQH connect record takes care of waiting for an operation to
- * complete.
- * When an operation has completed on the LQH connect record,
- * a new operation can be started on this LQH connect record.
- *******************************************************************
- *
- * API CONNECT RECORD ALIGNED TO BE 256 BYTES
- ********************************************************************/
-
- /*******************************************************************>*/
- // We break out the API Timer for optimisation on scanning rather than
- // on fast access.
- /*******************************************************************>*/
- inline void setApiConTimer(Uint32 apiConPtrI, Uint32 value, Uint32 line){
- c_apiConTimer[apiConPtrI] = value;
- c_apiConTimer_line[apiConPtrI] = line;
- }
-
- inline Uint32 getApiConTimer(Uint32 apiConPtrI) const {
- return c_apiConTimer[apiConPtrI];
- }
- UintR* c_apiConTimer;
- UintR* c_apiConTimer_line;
-
- struct ApiConnectRecord {
- ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
- ArrayPool<TcIndexOperation> & seizedIndexOpPool):
- theFiredTriggers(firedTriggerPool),
- isIndexOp(false),
- theSeizedIndexOperations(seizedIndexOpPool)
- {}
-
- //---------------------------------------------------
- // First 16 byte cache line. Hot variables.
- //---------------------------------------------------
- ConnectionState apiConnectstate;
- UintR transid[2];
- UintR firstTcConnect;
- NdbNodeBitmask m_transaction_nodes;
-
- //---------------------------------------------------
- // Second 16 byte cache line. Hot variables.
- //---------------------------------------------------
- UintR lqhkeyconfrec;
- UintR cachePtr;
- UintR currSavePointId;
- UintR counter;
-
- //---------------------------------------------------
- // Third 16 byte cache line. First and second cache
- // line plus this will be enough for copy API records.
- // Variables used in late phases.
- //---------------------------------------------------
- UintR nextGcpConnect;
- UintR prevGcpConnect;
- UintR gcpPointer;
- UintR ndbapiConnect;
-
- //---------------------------------------------------
- // Fourth 16 byte cache line. Only used in late phases.
- // Plus 4 bytes of error handling.
- //---------------------------------------------------
- UintR nextApiConnect;
- BlockReference ndbapiBlockref;
- UintR apiCopyRecord;
- UintR globalcheckpointid;
-
- //---------------------------------------------------
- // Second 64 byte cache line starts. First 16 byte
- // cache line in this one. Variables primarily used
- // in early phase.
- //---------------------------------------------------
- UintR lastTcConnect;
- UintR lqhkeyreqrec;
- AbortState abortState;
- Uint32 buddyPtr;
- Uint8 m_exec_flag;
- Uint8 unused2;
- Uint8 takeOverRec;
- Uint8 currentReplicaNo;
-
- //---------------------------------------------------
- // Error Handling variables. If cache line 32 bytes
- // ensures that cache line is still only read in
- // early phases.
- //---------------------------------------------------
- union {
- UintR apiScanRec;
- UintR commitAckMarker;
- };
- UintR currentTcConnect;
- BlockReference tcBlockref;
- Uint16 returncode;
- Uint16 takeOverInd;
-
- //---------------------------------------------------
- // Second 64 byte cache line. Third 16 byte cache line
- // in this one. Variables primarily used in early phase
- // and checked in late phase.
- // Fourth cache line is the tcSendArray that is used
- // when two and three operations are responded to in
- // parallel. The first two entries in tcSendArray is
- // part of the third cache line.
- //---------------------------------------------------
- //---------------------------------------------------
- // timeOutCounter is used waiting for ABORTCONF, COMMITCONF
- // and COMPLETECONF
- //---------------------------------------------------
- UintR failureNr;
- Uint8 tckeyrec; // Ändrad från R
- Uint8 tcindxrec;
- Uint8 apiFailState; // Ändrad från R
- Uint8 singleUserMode;
- ReturnSignal returnsignal;
- Uint8 timeOutCounter;
-
- UintR tcSendArray[6];
-
- // Trigger data
-
- /**
- * The list of fired triggers
- */
- DLFifoList<TcFiredTriggerData> theFiredTriggers;
-
- bool triggerPending; // Used to mark waiting for a CONTINUEB
-
- // Index data
-
- Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access
- bool indexOpReturn;
- UintR noIndexOp; // No outstanding index ops
-
- // Index op return context
- UintR indexOp;
- UintR clientData;
- Uint32 errorData;
- UintR attrInfoLen;
-
- UintR accumulatingIndexOp;
- UintR executingIndexOp;
- UintR tcIndxSendArray[6];
- DLList<TcIndexOperation> theSeizedIndexOperations;
- };
-
- typedef Ptr<ApiConnectRecord> ApiConnectRecordPtr;
-
-
- /************************** TC CONNECT RECORD ************************/
- /* *******************************************************************/
- /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
- /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
- /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
- /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
- /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
- /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
- /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
- /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
- /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
- /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
- /* EXECUTED WITH THE TC CONNECT RECORD. */
- /*******************************************************************>*/
- /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
- /*******************************************************************>*/
- struct TcConnectRecord {
- //---------------------------------------------------
- // First 16 byte cache line. Those variables are only
- // used in error cases.
- //---------------------------------------------------
- UintR tcOprec; /* TC OPREC of operation being taken over */
- Uint16 failData[4]; /* Failed nodes when taking over an operation */
- UintR nextTcFailHash;
-
- //---------------------------------------------------
- // Second 16 byte cache line. Those variables are used
- // from LQHKEYCONF to sending COMMIT and COMPLETED.
- //---------------------------------------------------
- UintR lastLqhCon; /* Connect record in last replicas Lqh record */
- Uint16 lastLqhNodeId; /* Node id of last replicas Lqh */
- Uint16 m_execAbortOption;/* TcKeyReq::ExecuteAbortOption */
- UintR commitAckMarker; /* CommitMarker I value */
-
- //---------------------------------------------------
- // Third 16 byte cache line. The hottest variables.
- //---------------------------------------------------
- OperationState tcConnectstate; /* THE STATE OF THE CONNECT*/
- UintR apiConnect; /* POINTER TO API CONNECT RECORD */
- UintR nextTcConnect; /* NEXT TC RECORD*/
- Uint8 dirtyOp;
- Uint8 opSimple;
- Uint8 lastReplicaNo; /* NUMBER OF THE LAST REPLICA IN THE OPERATION */
- Uint8 noOfNodes; /* TOTAL NUMBER OF NODES IN OPERATION */
- Uint8 operation; /* OPERATION TYPE */
- /* 0 = READ REQUEST */
- /* 1 = UPDATE REQUEST */
- /* 2 = INSERT REQUEST */
- /* 3 = DELETE REQUEST */
-
- //---------------------------------------------------
- // Fourth 16 byte cache line. The mildly hot variables.
- // tcNodedata expands 4 Bytes into the next cache line
- // with indexes almost never used.
- //---------------------------------------------------
- UintR clientData; /* SENDERS OPERATION POINTER */
- UintR dihConnectptr; /* CONNECTION TO DIH BLOCK ON THIS NODE */
- UintR prevTcConnect; /* DOUBLY LINKED LIST OF TC CONNECT RECORDS*/
- UintR savePointId;
-
- Uint16 tcNodedata[4];
-
- // Trigger data
- FiredTriggerPtr accumulatingTriggerData;
- UintR noFiredTriggers;
- UintR noReceivedTriggers;
- UintR triggerExecutionCount;
- UintR triggeringOperation;
- UintR savedState[LqhKeyConf::SignalLength];
-
- // Index data
- Uint8 isIndexOp; // Used to mark on-going TcKeyReq as index table access
- UintR indexOp;
- UintR currentIndexId;
- UintR attrInfoLen;
- };
-
- friend struct TcConnectRecord;
-
- typedef Ptr<TcConnectRecord> TcConnectRecordPtr;
-
- // ********************** CACHE RECORD **************************************
- //---------------------------------------------------------------------------
- // This record is used between reception of TCKEYREQ and sending of LQHKEYREQ
- // It is separatedso as to improve the cache hit rate and also to minimise
- // the necessary memory storage in NDB Cluster.
- //---------------------------------------------------------------------------
-
- struct CacheRecord {
- //---------------------------------------------------
- // First 16 byte cache line. Variables used by
- // ATTRINFO processing.
- //---------------------------------------------------
- UintR firstAttrbuf; /* POINTER TO LINKED LIST OF ATTRIBUTE BUFFERS */
- UintR lastAttrbuf; /* POINTER TO LINKED LIST OF ATTRIBUTE BUFFERS */
- UintR currReclenAi;
- Uint16 attrlength; /* ATTRIBUTE INFORMATION LENGTH */
- Uint16 save1;
-
- //---------------------------------------------------
- // Second 16 byte cache line. Variables initiated by
- // TCKEYREQ and used in LQHKEYREQ.
- //---------------------------------------------------
- UintR attrinfo15[4];
-
- //---------------------------------------------------
- // Third 16 byte cache line. Variables initiated by
- // TCKEYREQ and used in LQHKEYREQ.
- //---------------------------------------------------
- UintR attrinfo0;
- UintR schemaVersion;/* SCHEMA VERSION USED IN TRANSACTION */
- UintR tableref; /* POINTER TO THE TABLE IN WHICH THE FRAGMENT EXISTS*/
- Uint16 apiVersionNo;
- Uint16 keylen; /* KEY LENGTH SENT BY REQUEST SIGNAL */
-
- //---------------------------------------------------
- // Fourth 16 byte cache line. Variables initiated by
- // TCKEYREQ and used in LQHKEYREQ.
- //---------------------------------------------------
- UintR keydata[4]; /* RECEIVES FIRST 16 BYTES OF TUPLE KEY */
-
- //---------------------------------------------------
- // First 16 byte cache line in second 64 byte cache
- // line. Diverse use.
- //---------------------------------------------------
- UintR fragmentid; /* THE COMPUTED FRAGMENT ID */
- UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */
-
- Uint8 distributionKeyIndicator;
- Uint8 m_special_hash; // collation or distribution key
- Uint8 m_no_disk_flag;
- Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */
-
- Uint8 fragmentDistributionKey; /* DIH generation no */
-
- /**
- * EXECUTION MODE OF OPERATION
- * 0 = NORMAL EXECUTION, 1 = INTERPRETED EXECUTION
- */
- Uint8 opExec;
-
- Uint8 unused;
- Uint8 unused1;
-
- //---------------------------------------------------
- // Second 16 byte cache line in second 64 byte cache
- // line. Diverse use.
- //---------------------------------------------------
- UintR distributionKey;
- UintR nextCacheRec;
- UintR unused3;
- Uint32 scanInfo;
-
- //---------------------------------------------------
- // Third 16 byte cache line in second 64
- // byte cache line. Diverse use.
- //---------------------------------------------------
- Uint32 unused4;
- Uint32 scanTakeOverInd;
- UintR firstKeybuf; /* POINTER THE LINKED LIST OF KEY BUFFERS */
- UintR lastKeybuf; /* VARIABLE POINTING TO THE LAST KEY BUFFER */
-
- //---------------------------------------------------
- // Fourth 16 byte cache line in second 64
- // byte cache line. Not used currently.
- //---------------------------------------------------
- UintR packedCacheVar[4];
- };
-
- typedef Ptr<CacheRecord> CacheRecordPtr;
-
- /* ************************ HOST RECORD ********************************** */
- /********************************************************/
- /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
- /* SYSTEM */
- /********************************************************/
- /* THIS RECORD IS ALIGNED TO BE 128 BYTES. */
- /********************************************************/
- struct HostRecord {
- HostState hostStatus;
- LqhTransState lqhTransStatus;
- bool inPackedList;
- UintR noOfPackedWordsLqh;
- UintR packedWordsLqh[26];
- UintR noOfWordsTCKEYCONF;
- UintR packedWordsTCKEYCONF[30];
- UintR noOfWordsTCINDXCONF;
- UintR packedWordsTCINDXCONF[30];
- BlockReference hostLqhBlockRef;
-
- enum NodeFailBits
- {
- NF_TAKEOVER = 0x1,
- NF_CHECK_SCAN = 0x2,
- NF_CHECK_TRANSACTION = 0x4,
- NF_CHECK_DROP_TAB = 0x8,
- NF_NODE_FAIL_BITS = 0xF // All bits...
- };
- Uint32 m_nf_bits;
- NdbNodeBitmask m_lqh_trans_conf;
- }; /* p2c: size = 128 bytes */
-
- typedef Ptr<HostRecord> HostRecordPtr;
-
- /* *********** TABLE RECORD ********************************************* */
-
- /********************************************************/
- /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
- /* ALL TABLES IN THE SYSTEM. */
- /********************************************************/
- struct TableRecord {
- TableRecord() {}
- Uint32 currentSchemaVersion;
- Uint16 m_flags;
- Uint8 tableType;
- Uint8 singleUserMode;
-
- enum {
- TR_ENABLED = 1 << 0,
- TR_DROPPING = 1 << 1,
- TR_STORED_TABLE = 1 << 2
- };
- Uint8 get_enabled() const { return (m_flags & TR_ENABLED) != 0; }
- Uint8 get_dropping() const { return (m_flags & TR_DROPPING) != 0; }
- Uint8 get_storedTable() const { return (m_flags & TR_STORED_TABLE) != 0; }
- void set_enabled(Uint8 f) { f ? m_flags |= (Uint16)TR_ENABLED : m_flags &= ~(Uint16)TR_ENABLED; }
- void set_dropping(Uint8 f) { f ? m_flags |= (Uint16)TR_DROPPING : m_flags &= ~(Uint16)TR_DROPPING; }
- void set_storedTable(Uint8 f) { f ? m_flags |= (Uint16)TR_STORED_TABLE : m_flags &= ~(Uint16)TR_STORED_TABLE; }
-
- Uint8 noOfKeyAttr;
- Uint8 hasCharAttr;
- Uint8 noOfDistrKeys;
- Uint8 hasVarKeys;
-
- bool checkTable(Uint32 schemaVersion) const {
- return get_enabled() && !get_dropping() &&
- (table_version_major(schemaVersion) == table_version_major(currentSchemaVersion));
- }
-
- Uint32 getErrorCode(Uint32 schemaVersion) const;
-
- struct DropTable {
- Uint32 senderRef;
- Uint32 senderData;
- SignalCounter waitDropTabCount;
- } dropTable;
- };
- 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(){
- stopFragTimer();
- lqhBlockref = 0;
- scanFragState = IDLE;
- scanRec = RNIL;
- }
- /**
- * 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 value of fragmentCompleted in the last received SCAN_FRAGCONF
- Uint8 m_scan_frag_conf_status;
-
- 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.
- * THE PROCESS HAS THREE STEPS IT GOES THROUGH.
- * 1) THE INITIAL STATES WHEN RECEIVING DATA FOR THE SCAN.
- * - WAIT_SCAN_TAB_INFO
- * - WAIT_AI
- * - WAIT_FRAGMENT_COUNT
- * 2) THE EXECUTION STATES WHEN THE SCAN IS PERFORMED.
- * - SCAN_NEXT_ORDERED
- * - DELIVERED
- * - QUEUED_DELIVERED
- * 3) THE CLOSING STATE WHEN THE SCAN PROCESS IS CLOSING UP
- * EVERYTHING.
- * - CLOSING_SCAN
- * INITIAL START WHEN SCAN_TABREQ RECEIVED
- * -> WAIT_SCAN_TAB_INFO (IF ANY SCAN_TABINFO TO BE RECEIVED)
- * -> WAIT_AI (IF NO SCAN_TAB_INFO BUT ATTRINFO IS RECEIVED)
- * -> WAIT_FRAGMENT_COUNT (IF NEITHER SCAN_TABINFO OR ATTRINFO
- * RECEIVED)
- *
- * WAIT_SCAN_TAB_INFO TRANSITIONS:
- * -> WAIT_SCAN_TABINFO (WHEN MORE SCAN_TABINFO RECEIVED)
- * -> WAIT_AI (WHEN ATTRINFO RECEIVED AFTER RECEIVING ALL
- * SCAN_TABINFO)
- * -> WAIT_FRAGMENT_COUNT (WHEN NO ATTRINFO RECEIVED AFTER
- * RECEIVING ALL SCAN_TABINFO )
- * WAIT_AI TRANSITIONS:
- * -> WAIT_AI (WHEN MORE ATTRINFO RECEIVED)
- * -> WAIT_FRAGMENT_COUNT (WHEN ALL ATTRINFO RECEIVED)
- *
- * WAIT_FRAGMENT_COUNT TRANSITIONS:
- * -> SCAN_NEXT_ORDERED
- *
- * SCAN_NEXT_ORDERED TRANSITIONS:
- * -> DELIVERED (WHEN FIRST SCAN_FRAGCONF ARRIVES WITH OPERATIONS
- * TO REPORT IN IT)
- * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME
- * ERROR)
- *
- * DELIVERED TRANSITIONS:
- * -> SCAN_NEXT_ORDERED (IF SCAN_NEXTREQ ARRIVES BEFORE ANY NEW
- * OPERATIONS TO REPORT ARRIVES)
- * -> QUEUED_DELIVERED (IF NEW OPERATION TO REPORT ARRIVES BEFORE
- * SCAN_NEXTREQ)
- * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY SOME
- * ERROR)
- *
- * QUEUED_DELIVERED TRANSITIONS:
- * -> DELIVERED (WHEN SCAN_NEXTREQ ARRIVES AND QUEUED OPERATIONS
- * TO REPORT ARE SENT TO THE APPLICATION)
- * -> CLOSING_SCAN (WHEN SCAN IS CLOSED BY SCAN_NEXTREQ OR BY
- * SOME ERROR)
- */
- enum ScanState {
- IDLE = 0,
- WAIT_SCAN_TAB_INFO = 1,
- WAIT_AI = 2,
- WAIT_FRAGMENT_COUNT = 3,
- RUNNING = 4,
- CLOSING_SCAN = 5
- };
-
- // State of this scan
- ScanState scanState;
-
- 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
-
- // 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
- union { Uint32 scanAiLength; Uint32 m_booked_fragments_count; };
-
- Uint32 scanKeyLen;
-
- // Reference to ApiConnectRecord
- Uint32 scanApiRec;
-
- // Reference to TcConnectRecord
- Uint32 scanTcrec;
-
- // Number of scan frag processes that belong to this scan
- Uint32 scanParallel;
-
- // 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
- // Number of operations in first batch
- // Max number of bytes per batch
- union {
- Uint16 first_batch_size_rows;
- Uint16 batch_size_rows;
- };
- Uint32 batch_byte_size;
-
- Uint32 scanRequestInfo; // ScanFrag format
-
- // Close is ordered
- bool m_close_scan_req;
- };
- typedef Ptr<ScanRecord> ScanRecordPtr;
-
- /* **********************************************************************$ */
- /* ******$ DATA BUFFER ******$ */
- /* */
- /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */
- /* **********************************************************************$ */
- struct DatabufRecord {
- UintR data[4];
- /* 4 * 1 WORD = 4 WORD */
- UintR nextDatabuf;
- }; /* p2c: size = 20 bytes */
-
- typedef Ptr<DatabufRecord> DatabufRecordPtr;
-
- /* **********************************************************************$ */
- /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */
- /*
- * CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR.
- * INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY.
- * SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS:
- * DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY
- * ZINBUF_DATA_LEN.
- * NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY
- * PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV
- * (NOT USED YET).
- * NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT. */
- /* ******************************************************************** */
- struct AttrbufRecord {
- UintR attrbuf[32];
- }; /* p2c: size = 128 bytes */
-
- typedef Ptr<AttrbufRecord> AttrbufRecordPtr;
-
- /*************************************************************************>*/
- /* GLOBAL CHECKPOINT INFORMATION RECORD */
- /* */
- /* THIS RECORD IS USED TO STORE THE GLOBALCHECKPOINT NUMBER AND A
- * COUNTER DURING THE COMPLETION PHASE OF THE TRANSACTION */
- /*************************************************************************>*/
- /* */
- /* GCP RECORD ALIGNED TO BE 32 BYTES */
- /*************************************************************************>*/
- struct GcpRecord {
- UintR gcpUnused1[2]; /* p2c: Not used */
- UintR firstApiConnect;
- UintR lastApiConnect;
- UintR gcpId;
- UintR nextGcp;
- UintR gcpUnused2; /* p2c: Not used */
- Uint16 gcpNomoretransRec;
- }; /* p2c: size = 32 bytes */
-
- typedef Ptr<GcpRecord> GcpRecordPtr;
-
- /*************************************************************************>*/
- /* TC_FAIL_RECORD */
- /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED
- * TC NODE. */
- /*************************************************************************>*/
- struct TcFailRecord {
- Uint16 queueList[MAX_NDB_NODES];
- Uint8 takeOverProcState[MAX_NDB_NODES];
- UintR completedTakeOver;
- UintR currentHashIndexTakeOver;
- FailState failStatus;
- Uint16 queueIndex;
- Uint16 takeOverNode;
- }; /* p2c: size = 64 bytes */
-
- typedef Ptr<TcFailRecord> TcFailRecordPtr;
-
-public:
- Dbtc(Block_context&);
- virtual ~Dbtc();
-
-private:
- BLOCK_DEFINES(Dbtc);
-
- // Transit signals
- void execPACKED_SIGNAL(Signal* signal);
- void execABORTED(Signal* signal);
- void execATTRINFO(Signal* signal);
- void execCONTINUEB(Signal* signal);
- void execKEYINFO(Signal* signal);
- void execSCAN_NEXTREQ(Signal* signal);
- void execSCAN_PROCREQ(Signal* signal);
- void execSCAN_PROCCONF(Signal* signal);
- void execTAKE_OVERTCREQ(Signal* signal);
- void execTAKE_OVERTCCONF(Signal* signal);
- void execLQHKEYREF(Signal* signal);
- void execTRANSID_AI_R(Signal* signal);
- void execKEYINFO20_R(Signal* signal);
- void execROUTE_ORD(Signal* signal);
- // Received signals
- void execDUMP_STATE_ORD(Signal* signal);
- void execSEND_PACKED(Signal* signal);
- void execCOMPLETED(Signal* signal);
- void execCOMMITTED(Signal* signal);
- void execDIGETNODESREF(Signal* signal);
- void execDIGETPRIMCONF(Signal* signal);
- void execDIGETPRIMREF(Signal* signal);
- void execDISEIZECONF(Signal* signal);
- void execDIVERIFYCONF(Signal* signal);
- void execDI_FCOUNTCONF(Signal* signal);
- void execDI_FCOUNTREF(Signal* signal);
- void execGCP_NOMORETRANS(Signal* signal);
- void execLQHKEYCONF(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execREAD_NODESREF(Signal* signal);
- void execSTTOR(Signal* signal);
- void execTC_COMMITREQ(Signal* signal);
- void execTC_CLOPSIZEREQ(Signal* signal);
- void execTCGETOPSIZEREQ(Signal* signal);
- void execTCKEYREQ(Signal* signal);
- void execTCRELEASEREQ(Signal* signal);
- void execTCSEIZEREQ(Signal* signal);
- void execTCROLLBACKREQ(Signal* signal);
- void execTC_HBREP(Signal* signal);
- void execTC_SCHVERREQ(Signal* signal);
- void execSCAN_TABREQ(Signal* signal);
- void execSCAN_TABINFO(Signal* signal);
- void execSCAN_FRAGCONF(Signal* signal);
- void execSCAN_FRAGREF(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execLQH_TRANSCONF(Signal* signal);
- void execCOMPLETECONF(Signal* signal);
- void execCOMMITCONF(Signal* signal);
- void execABORTCONF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
- void execTIME_SIGNAL(Signal* signal);
- void execAPI_FAILREQ(Signal* signal);
- void execSCAN_HBREP(Signal* signal);
-
- void execABORT_ALL_REQ(Signal* signal);
-
- void execCREATE_TRIG_REQ(Signal* signal);
- void execDROP_TRIG_REQ(Signal* signal);
- void execFIRE_TRIG_ORD(Signal* signal);
- void execTRIG_ATTRINFO(Signal* signal);
- void execCREATE_INDX_REQ(Signal* signal);
- void execDROP_INDX_REQ(Signal* signal);
- void execTCINDXREQ(Signal* signal);
- void execINDXKEYINFO(Signal* signal);
- void execINDXATTRINFO(Signal* signal);
- void execALTER_INDX_REQ(Signal* signal);
-
- // Index table lookup
- void execTCKEYCONF(Signal* signal);
- void execTCKEYREF(Signal* signal);
- void execTRANSID_AI(Signal* signal);
- void execTCROLLBACKREP(Signal* signal);
-
- 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);
- void set_timeout_value(Uint32 timeOut);
- void set_appl_timeout_value(Uint32 timeOut);
- void set_no_parallel_takeover(Uint32);
- void updateBuddyTimer(ApiConnectRecordPtr);
-
- // Statement blocks
- void updatePackedList(Signal* signal, HostRecord* ahostptr,
- Uint16 ahostIndex);
- void clearTcNodeData(Signal* signal,
- UintR TLastLqhIndicator,
- UintR Tstart);
- void errorReport(Signal* signal, int place);
- void warningReport(Signal* signal, int place);
- void printState(Signal* signal, int place);
- int seizeTcRecord(Signal* signal);
- int seizeCacheRecord(Signal* signal);
- void TCKEY_abort(Signal* signal, int place);
- void copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR copyLen);
- void reportNodeFailed(Signal* signal, Uint32 nodeId);
- void sendPackedTCKEYCONF(Signal* signal,
- HostRecord * ahostptr,
- UintR hostId);
- void sendPackedTCINDXCONF(Signal* signal,
- HostRecord * ahostptr,
- UintR hostId);
- void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
- void sendCommitLqh(Signal* signal,
- TcConnectRecord * const regTcPtr);
- void sendCompleteLqh(Signal* signal,
- TcConnectRecord * const regTcPtr);
- void sendTCKEY_FAILREF(Signal* signal, const ApiConnectRecord *);
- void sendTCKEY_FAILCONF(Signal* signal, ApiConnectRecord *);
- void checkStartTimeout(Signal* signal);
- void checkStartFragTimeout(Signal* signal);
- void timeOutFoundFragLab(Signal* signal, Uint32 TscanConPtr);
- void timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr);
- int releaseAndAbort(Signal* signal);
- void findApiConnectFail(Signal* signal);
- void findTcConnectFail(Signal* signal);
- void initApiConnectFail(Signal* signal);
- void initTcConnectFail(Signal* signal);
- void initTcFail(Signal* signal);
- void releaseTakeOver(Signal* signal);
- void setupFailData(Signal* signal);
- void updateApiStateFail(Signal* signal);
- void updateTcStateFail(Signal* signal);
- void handleApiFailState(Signal* signal, UintR anApiConnectptr);
- void handleFailedApiNode(Signal* signal,
- UintR aFailedNode,
- UintR anApiConnectPtr);
- void handleScanStop(Signal* signal, UintR aFailedNode);
- void initScanTcrec(Signal* signal);
- void initScanrec(ScanRecordPtr, const class ScanTabReq*,
- const UintR scanParallel,
- const UintR noOprecPerFrag);
- void initScanfragrec(Signal* signal);
- void releaseScanResources(ScanRecordPtr, bool not_started = false);
- ScanRecordPtr seizeScanrec(Signal* signal);
- void sendScanFragReq(Signal*, ScanRecord*, ScanFragRec*);
- void sendScanTabConf(Signal* signal, ScanRecordPtr);
- void close_scan_req(Signal*, ScanRecordPtr, bool received_req);
- void close_scan_req_send_conf(Signal*, ScanRecordPtr);
-
- void checkGcp(Signal* signal);
- void commitGciHandling(Signal* signal, UintR Tgci);
- void copyApi(Signal* signal);
- void DIVER_node_fail_handling(Signal* signal, UintR Tgci);
- void gcpTcfinished(Signal* signal);
- void handleGcp(Signal* signal);
- void hash(Signal* signal);
- bool handle_special_hash(Uint32 dstHash[4],
- Uint32* src, Uint32 srcLen,
- Uint32 tabPtrI, bool distr);
-
- void initApiConnect(Signal* signal);
- void initApiConnectRec(Signal* signal,
- ApiConnectRecord * const regApiPtr,
- bool releaseIndexOperations = false);
- void initattrbuf(Signal* signal);
- void initdatabuf(Signal* signal);
- void initgcp(Signal* signal);
- void inithost(Signal* signal);
- void initialiseScanrec(Signal* signal);
- void initialiseScanFragrec(Signal* signal);
- void initialiseScanOprec(Signal* signal);
- void initTable(Signal* signal);
- void initialiseTcConnect(Signal* signal);
- void linkApiToGcp(Signal* signal);
- void linkGciInGcilist(Signal* signal);
- void linkKeybuf(Signal* signal);
- void linkTcInConnectionlist(Signal* signal);
- void releaseAbortResources(Signal* signal);
- void releaseApiCon(Signal* signal, UintR aApiConnectPtr);
- void releaseApiConCopy(Signal* signal);
- void releaseApiConnectFail(Signal* signal);
- void releaseAttrinfo();
- void releaseGcp(Signal* signal);
- void releaseKeys();
- void releaseDirtyRead(Signal*, ApiConnectRecordPtr, TcConnectRecord*);
- void releaseDirtyWrite(Signal* signal);
- void releaseTcCon();
- void releaseTcConnectFail(Signal* signal);
- void releaseTransResources(Signal* signal);
- void saveAttrbuf(Signal* signal);
- void seizeApiConnect(Signal* signal);
- void seizeApiConnectCopy(Signal* signal);
- void seizeApiConnectFail(Signal* signal);
- void seizeDatabuf(Signal* signal);
- void seizeGcp(Signal* signal);
- void seizeTcConnect(Signal* signal);
- void seizeTcConnectFail(Signal* signal);
- void sendApiCommit(Signal* signal);
- void sendAttrinfo(Signal* signal,
- UintR TattrinfoPtr,
- AttrbufRecord * const regAttrPtr,
- UintR TBref);
- void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr);
- void sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len);
- void sendlqhkeyreq(Signal* signal, BlockReference TBRef);
- void sendSystemError(Signal* signal, int line);
- void sendtckeyconf(Signal* signal, UintR TcommitFlag);
- void sendTcIndxConf(Signal* signal, UintR TcommitFlag);
- void unlinkApiConnect(Signal* signal);
- void unlinkGcp(Signal* signal);
- void unlinkReadyTcCon(Signal* signal);
- void handleFailedOperation(Signal* signal,
- const LqhKeyRef * const lqhKeyRef,
- bool gotLqhKeyRef);
- void markOperationAborted(ApiConnectRecord * const regApiPtr,
- TcConnectRecord * const regTcPtr);
- void clearCommitAckMarker(ApiConnectRecord * const regApiPtr,
- TcConnectRecord * const regTcPtr);
- // Trigger and index handling
- int saveINDXKEYINFO(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len);
- bool receivedAllINDXKEYINFO(TcIndexOperation* indexOp);
- int saveINDXATTRINFO(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len);
- bool receivedAllINDXATTRINFO(TcIndexOperation* indexOp);
- bool saveTRANSID_AI(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len);
- bool receivedAllTRANSID_AI(TcIndexOperation* indexOp);
- void readIndexTable(Signal* signal,
- ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp);
- void executeIndexOperation(Signal* signal,
- ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp);
- bool seizeIndexOperation(ApiConnectRecord* regApiPtr,
- TcIndexOperationPtr& indexOpPtr);
- void releaseIndexOperation(ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp);
- void releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr);
- void setupIndexOpReturn(ApiConnectRecord* regApiPtr,
- TcConnectRecord* regTcPtr);
-
- void saveTriggeringOpState(Signal* signal,
- TcConnectRecord* trigOp);
- void restoreTriggeringOpState(Signal* signal,
- TcConnectRecord* trigOp);
- void continueTriggeringOp(Signal* signal,
- TcConnectRecord* trigOp);
-
- void scheduleFiredTrigger(ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr);
- void executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr);
- void executeTrigger(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr);
- void executeIndexTrigger(Signal* signal,
- TcDefinedTriggerData* definedTriggerData,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr);
- void insertIntoIndexTable(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr,
- TcIndexData* indexData,
- bool holdOperation = false);
- void deleteFromIndexTable(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr,
- TcIndexData* indexData,
- bool holdOperation = false);
- void releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers);
- // Generated statement blocks
- void warningHandlerLab(Signal* signal, int line);
- void systemErrorLab(Signal* signal, int line);
- void sendSignalErrorRefuseLab(Signal* signal);
- void scanTabRefLab(Signal* signal, Uint32 errCode);
- void diFcountReqLab(Signal* signal, ScanRecordPtr);
- void signalErrorRefuseLab(Signal* signal);
- void abort080Lab(Signal* signal);
- void packKeyData000Lab(Signal* signal, BlockReference TBRef, Uint32 len);
- void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode,
- bool not_started = false);
- void sendAbortedAfterTimeout(Signal* signal, int Tcheck);
- void abort010Lab(Signal* signal);
- void abort015Lab(Signal* signal);
- void packLqhkeyreq(Signal* signal, BlockReference TBRef);
- void packLqhkeyreq040Lab(Signal* signal,
- UintR anAttrBufIndex,
- BlockReference TBRef);
- void packLqhkeyreq040Lab(Signal* signal);
- void returnFromQueuedDeliveryLab(Signal* signal);
- void startTakeOverLab(Signal* signal);
- void toCompleteHandlingLab(Signal* signal);
- void toCommitHandlingLab(Signal* signal);
- void toAbortHandlingLab(Signal* signal);
- void abortErrorLab(Signal* signal);
- void nodeTakeOverCompletedLab(Signal* signal);
- void ndbsttorry010Lab(Signal* signal);
- void commit020Lab(Signal* signal);
- void complete010Lab(Signal* signal);
- void releaseAtErrorLab(Signal* signal);
- void seizeDatabuferrorLab(Signal* signal);
- void scanAttrinfoLab(Signal* signal, UintR Tlen);
- void seizeAttrbuferrorLab(Signal* signal);
- void attrinfoDihReceivedLab(Signal* signal);
- void aiErrorLab(Signal* signal);
- void attrinfo020Lab(Signal* signal);
- void scanReleaseResourcesLab(Signal* signal);
- void scanCompletedLab(Signal* signal);
- void scanError(Signal* signal, ScanRecordPtr, Uint32 errorCode);
- void diverify010Lab(Signal* signal);
- void intstartphase2x010Lab(Signal* signal);
- void intstartphase3x010Lab(Signal* signal);
- void sttorryLab(Signal* signal);
- void abortBeginErrorLab(Signal* signal);
- void tabStateErrorLab(Signal* signal);
- void wrongSchemaVersionErrorLab(Signal* signal);
- void noFreeConnectionErrorLab(Signal* signal);
- void tckeyreq050Lab(Signal* signal);
- void timeOutFoundLab(Signal* signal, UintR anAdd, Uint32 errCode);
- void completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd);
- void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd);
- void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd);
- void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr);
- void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32);
- void tckeyreq020Lab(Signal* signal);
- void intstartphase2x020Lab(Signal* signal);
- void intstartphase1x010Lab(Signal* signal);
- void startphase1x010Lab(Signal* signal);
-
- void lqhKeyConf_checkTransactionState(Signal * signal,
- Ptr<ApiConnectRecord> regApiPtr);
-
- void checkDropTab(Signal* signal);
-
- void checkScanActiveInFailedLqh(Signal* signal,
- Uint32 scanPtrI,
- Uint32 failedNodeId);
- void checkScanFragList(Signal*, Uint32 failedNodeId, ScanRecord * scanP,
- LocalDLList<ScanFragRec>::Head&);
-
- void nodeFailCheckTransactions(Signal*,Uint32 transPtrI,Uint32 failedNodeId);
- void checkNodeFailComplete(Signal* signal, Uint32 failedNodeId, Uint32 bit);
-
- // Initialisation
- void initData();
- void initRecords();
-
- // Transit signals
-
-
- ApiConnectRecord *apiConnectRecord;
- ApiConnectRecordPtr apiConnectptr;
- UintR capiConnectFilesize;
-
- TcConnectRecord *tcConnectRecord;
- TcConnectRecordPtr tcConnectptr;
- UintR ctcConnectFilesize;
-
- CacheRecord *cacheRecord;
- CacheRecordPtr cachePtr;
- UintR ccacheFilesize;
-
- AttrbufRecord *attrbufRecord;
- AttrbufRecordPtr attrbufptr;
- UintR cattrbufFilesize;
-
- HostRecord *hostRecord;
- HostRecordPtr hostptr;
- UintR chostFilesize;
- NdbNodeBitmask c_alive_nodes;
-
- GcpRecord *gcpRecord;
- GcpRecordPtr gcpPtr;
- UintR cgcpFilesize;
-
- TableRecord *tableRecord;
- UintR ctabrecFilesize;
-
- UintR thashValue;
- UintR tdistrHashValue;
-
- UintR ttransid_ptr;
- UintR cfailure_nr;
- UintR coperationsize;
- UintR ctcTimer;
- UintR cDbHbInterval;
-
- ApiConnectRecordPtr tmpApiConnectptr;
- UintR tcheckGcpId;
-
- struct TransCounters {
- TransCounters() {}
- enum { Off, Timer, Started } c_trans_status;
- UintR cattrinfoCount;
- UintR ctransCount;
- UintR ccommitCount;
- UintR creadCount;
- UintR csimpleReadCount;
- UintR cwriteCount;
- UintR cabortCount;
- UintR cconcurrentOp;
- Uint32 c_scan_count;
- Uint32 c_range_scan_count;
- void reset () {
- cattrinfoCount = ctransCount = ccommitCount = creadCount =
- csimpleReadCount = cwriteCount = cabortCount =
- c_scan_count = c_range_scan_count = 0;
- }
- Uint32 report(Signal* signal){
- signal->theData[0] = NDB_LE_TransReportCounters;
- signal->theData[1] = ctransCount;
- signal->theData[2] = ccommitCount;
- signal->theData[3] = creadCount;
- signal->theData[4] = csimpleReadCount;
- signal->theData[5] = cwriteCount;
- signal->theData[6] = cattrinfoCount;
- signal->theData[7] = cconcurrentOp;
- signal->theData[8] = cabortCount;
- signal->theData[9] = c_scan_count;
- signal->theData[10] = c_range_scan_count;
- return 11;
- }
- } c_counters;
-
- Uint16 cownNodeid;
- Uint16 terrorCode;
-
- UintR cfirstfreeAttrbuf;
- UintR cfirstfreeTcConnect;
- UintR cfirstfreeApiConnectCopy;
- UintR cfirstfreeCacheRec;
-
- UintR cfirstgcp;
- UintR clastgcp;
- UintR cfirstfreeGcp;
- UintR cfirstfreeScanrec;
-
- TableRecordPtr tabptr;
- UintR cfirstfreeApiConnectFail;
- UintR cfirstfreeApiConnect;
-
- UintR cfirstfreeDatabuf;
- BlockReference cdihblockref;
- BlockReference cownref; /* OWN BLOCK REFERENCE */
-
- ApiConnectRecordPtr timeOutptr;
-
- ScanRecord *scanRecord;
- UintR cscanrecFileSize;
-
- UnsafeArrayPool<ScanFragRec> c_scan_frag_pool;
- ScanFragRecPtr scanFragptr;
-
- UintR cscanFragrecFileSize;
- UintR cdatabufFilesize;
-
- BlockReference cdictblockref;
- BlockReference cerrorBlockref;
- BlockReference clqhblockref;
- BlockReference cndbcntrblockref;
-
- Uint16 csignalKey;
- Uint16 csystemnodes;
- Uint16 cnodes[4];
- NodeId cmasterNodeId;
- UintR cnoParallelTakeOver;
- TimeOutCheckState ctimeOutCheckFragActive;
-
- UintR ctimeOutCheckFragCounter;
- UintR ctimeOutCheckCounter;
- UintR ctimeOutValue;
- UintR ctimeOutCheckDelay;
- Uint32 ctimeOutCheckHeartbeat;
- Uint32 ctimeOutCheckLastHeartbeat;
- Uint32 ctimeOutMissedHeartbeats;
- Uint32 c_appl_timeout_value;
-
- SystemStartState csystemStart;
- TimeOutCheckState ctimeOutCheckActive;
-
- BlockReference capiFailRef;
- UintR cpackedListIndex;
- Uint16 cpackedList[MAX_NODES];
- UintR capiConnectClosing[MAX_NODES];
- UintR con_lineNodes;
-
- DatabufRecord *databufRecord;
- DatabufRecordPtr databufptr;
- DatabufRecordPtr tmpDatabufptr;
-
- UintR treqinfo;
- UintR ttransid1;
- UintR ttransid2;
-
- UintR tabortInd;
-
- NodeId tnodeid;
- BlockReference tblockref;
-
- LqhTransConf::OperationStatus ttransStatus;
- UintR ttcOprec;
- NodeId tfailedNodeId;
- Uint8 tcurrentReplicaNo;
- Uint8 tpad1;
-
- UintR tgci;
- UintR tapplRef;
- UintR tapplOprec;
-
- UintR tindex;
- UintR tmaxData;
- UintR tmp;
-
- UintR tnodes;
- BlockReference tusersblkref;
- UintR tuserpointer;
- UintR tloadCode;
-
- UintR tconfig1;
- UintR tconfig2;
-
- UintR cdata[32];
- UintR ctransidFailHash[512];
- UintR ctcConnectFailHash[1024];
-
- /**
- * Commit Ack handling
- */
-public:
- struct CommitAckMarker {
- CommitAckMarker() {}
- Uint32 transid1;
- Uint32 transid2;
- union { Uint32 nextPool; Uint32 nextHash; };
- Uint32 prevHash;
- Uint32 apiConnectPtr;
- Uint16 apiNodeId;
- Uint16 noOfLqhs;
- Uint16 lqhNodeId[MAX_REPLICAS];
-
- inline bool equal(const CommitAckMarker & p) const {
- return ((p.transid1 == transid1) && (p.transid2 == transid2));
- }
-
- inline Uint32 hashValue() const {
- return transid1;
- }
- };
-private:
- typedef Ptr<CommitAckMarker> CommitAckMarkerPtr;
- typedef DLHashTable<CommitAckMarker>::Iterator CommitAckMarkerIterator;
-
- ArrayPool<CommitAckMarker> m_commitAckMarkerPool;
- DLHashTable<CommitAckMarker> m_commitAckMarkerHash;
-
- void execTC_COMMIT_ACK(Signal* signal);
- void sendRemoveMarkers(Signal*, const CommitAckMarker *);
- void sendRemoveMarker(Signal* signal,
- NodeId nodeId,
- Uint32 transid1,
- Uint32 transid2);
- void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
-
- bool getAllowStartTransaction(Uint32 nodeId, Uint32 table_single_user_mode) const {
- if (unlikely(getNodeState().getSingleUserMode()))
- {
- if (getNodeState().getSingleUserApi() == nodeId || table_single_user_mode)
- return true;
- else
- return false;
- }
- return getNodeState().startLevel < NodeState::SL_STOPPING_2;
- }
-
- void checkAbortAllTimeout(Signal* signal, Uint32 sleepTime);
- struct AbortAllRecord {
- AbortAllRecord(){ clientRef = 0; }
- Uint32 clientData;
- BlockReference clientRef;
-
- Uint32 oldTimeOutValue;
- };
- AbortAllRecord c_abortRec;
-
- /************************** API CONNECT RECORD ***********************/
- /* *******************************************************************/
- /* THE API CONNECT RECORD CONTAINS THE CONNECTION RECORD TO WHICH THE*/
- /* APPLICATION CONNECTS. THE APPLICATION CAN SEND ONE OPERATION AT A */
- /* TIME. IT CAN SEND A NEW OPERATION IMMEDIATELY AFTER SENDING THE */
- /* PREVIOUS OPERATION. THEREBY SEVERAL OPERATIONS CAN BE ACTIVE IN */
- /* ONE TRANSACTION WITHIN TC. THIS IS ACHIEVED BY USING THE API */
- /* CONNECT RECORD. EACH ACTIVE OPERATION IS HANDLED BY THE TC */
- /* CONNECT RECORD. AS SOON AS THE TC CONNECT RECORD HAS SENT THE */
- /* REQUEST TO THE LQH IT IS READY TO RECEIVE NEW OPERATIONS. THE */
- /* LQH CONNECT RECORD TAKES CARE OF WAITING FOR AN OPERATION TO */
- /* COMPLETE. WHEN AN OPERATION HAS COMPLETED ON THE LQH CONNECT */
- /* RECORD A NEW OPERATION CAN BE STARTED ON THIS LQH CONNECT RECORD. */
- /*******************************************************************>*/
- /* */
- /* API CONNECT RECORD ALIGNED TO BE 256 BYTES */
- /*******************************************************************>*/
- /************************** TC CONNECT RECORD ************************/
- /* *******************************************************************/
- /* TC CONNECT RECORD KEEPS ALL INFORMATION TO CARRY OUT A TRANSACTION*/
- /* THE TRANSACTION CONTROLLER ESTABLISHES CONNECTIONS TO DIFFERENT */
- /* BLOCKS TO CARRY OUT THE TRANSACTION. THERE CAN BE SEVERAL RECORDS */
- /* PER ACTIVE TRANSACTION. THE TC CONNECT RECORD COOPERATES WITH THE */
- /* API CONNECT RECORD FOR COMMUNICATION WITH THE API AND WITH THE */
- /* LQH CONNECT RECORD FOR COMMUNICATION WITH THE LQH'S INVOLVED IN */
- /* THE TRANSACTION. TC CONNECT RECORD IS PERMANENTLY CONNECTED TO A */
- /* RECORD IN DICT AND ONE IN DIH. IT CONTAINS A LIST OF ACTIVE LQH */
- /* CONNECT RECORDS AND A LIST OF STARTED BUT NOT ACTIVE LQH CONNECT */
- /* RECORDS. IT DOES ALSO CONTAIN A LIST OF ALL OPERATIONS THAT ARE */
- /* EXECUTED WITH THE TC CONNECT RECORD. */
- /*******************************************************************>*/
- /* TC_CONNECT RECORD ALIGNED TO BE 128 BYTES */
- /*******************************************************************>*/
- UintR cfirstfreeTcConnectFail;
-
- /* POINTER FOR THE LQH RECORD*/
- /* ************************ HOST RECORD ********************************* */
- /********************************************************/
- /* THIS RECORD CONTAINS ALIVE-STATUS ON ALL NODES IN THE*/
- /* SYSTEM */
- /********************************************************/
- /* THIS RECORD IS ALIGNED TO BE 8 BYTES. */
- /********************************************************/
- /* ************************ TABLE RECORD ******************************** */
- /********************************************************/
- /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */
- /* ALL TABLES IN THE SYSTEM. */
- /********************************************************/
- /*-------------------------------------------------------------------------*/
- /* THE TC CONNECTION USED BY THIS SCAN. */
- /*-------------------------------------------------------------------------*/
- /*-------------------------------------------------------------------------*/
- /* LENGTH READ FOR A PARTICULAR SCANNED OPERATION. */
- /*-------------------------------------------------------------------------*/
- /*-------------------------------------------------------------------------*/
- /* REFERENCE TO THE SCAN RECORD FOR THIS SCAN PROCESS. */
- /*-------------------------------------------------------------------------*/
- /* *********************************************************************** */
- /* ******$ DATA BUFFER ******$ */
- /* */
- /* THIS BUFFER IS USED AS A GENERAL DATA STORAGE. */
- /* *********************************************************************** */
- /* *********************************************************************** */
- /* ******$ ATTRIBUTE INFORMATION RECORD ******$ */
- /*
- CAN CONTAIN ONE (1) ATTRINFO SIGNAL. ONE SIGNAL CONTAINS 24 ATTR.
- INFO WORDS. BUT 32 ELEMENTS ARE USED TO MAKE PLEX HAPPY.
- SOME OF THE ELEMENTS ARE USED TO THE FOLLOWING THINGS:
- DATA LENGHT IN THIS RECORD IS STORED IN THE ELEMENT INDEXED BY
- ZINBUF_DATA_LEN.
- NEXT FREE ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY
- PREVIOUS ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_PREV
- (NOT USED YET).
- NEXT ATTRBUF IS POINTED OUT BY THE ELEMENT INDEXED BY ZINBUF_NEXT.
- */
- /* ********************************************************************** */
- /**************************************************************************/
- /* GLOBAL CHECKPOINT INFORMATION RECORD */
- /* */
- /* THIS RECORD IS USED TO STORE THE GCP NUMBER AND A COUNTER */
- /* DURING THE COMPLETION PHASE OF THE TRANSACTION */
- /**************************************************************************/
- /* */
- /* GCP RECORD ALIGNED TO BE 32 BYTES */
- /**************************************************************************/
- /**************************************************************************/
- /* TC_FAIL_RECORD */
- /* THIS RECORD IS USED WHEN HANDLING TAKE OVER OF ANOTHER FAILED TC NODE.*/
- /**************************************************************************/
- TcFailRecord *tcFailRecord;
- TcFailRecordPtr tcNodeFailptr;
- /**************************************************************************/
- // Temporary variables that are not allowed to use for storage between
- // signals. They
- // can only be used in a signal to transfer values between subroutines.
- // In the long run
- // those variables should be removed and exchanged for stack
- // variable communication.
- /**************************************************************************/
-
- Uint32 c_gcp_ref;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
deleted file mode 100644
index 22a1d7edb36..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTC_C
-#include "Dbtc.hpp"
-#include <pc.hpp>
-#include <ndb_limits.h>
-#include <Properties.hpp>
-#include <Configuration.hpp>
-
-#define DEBUG(x) { ndbout << "TC::" << x << endl; }
-
-
-void Dbtc::initData()
-{
- cattrbufFilesize = ZATTRBUF_FILESIZE;
- capiConnectFilesize = ZAPI_CONNECT_FILESIZE;
- ccacheFilesize = ZAPI_CONNECT_FILESIZE;
- chostFilesize = MAX_NODES;
- cdatabufFilesize = ZDATABUF_FILESIZE;
- cgcpFilesize = ZGCP_FILESIZE;
- cscanrecFileSize = ZSCANREC_FILE_SIZE;
- cscanFragrecFileSize = ZSCAN_FRAGREC_FILE_SIZE;
- ctabrecFilesize = ZTABREC_FILESIZE;
- ctcConnectFilesize = ZTC_CONNECT_FILESIZE;
- cdihblockref = DBDIH_REF;
- cdictblockref = DBDICT_REF;
- clqhblockref = DBLQH_REF;
- cerrorBlockref = NDBCNTR_REF;
-
- // Records with constant sizes
- tcFailRecord = (TcFailRecord*)allocRecord("TcFailRecord",
- sizeof(TcFailRecord), 1);
-
- // Variables
- ctcTimer = 0;
-
- // Trigger and index pools
- c_theDefinedTriggerPool.setSize(c_maxNumberOfDefinedTriggers);
- c_theFiredTriggerPool.setSize(c_maxNumberOfFiredTriggers);
- c_theIndexPool.setSize(c_maxNumberOfIndexes);
- c_theIndexOperationPool.setSize(c_maxNumberOfIndexOperations);
- c_theAttributeBufferPool.setSize(c_transactionBufferSpace);
- c_firedTriggerHash.setSize((c_maxNumberOfFiredTriggers+10)/10);
-}//Dbtc::initData()
-
-void Dbtc::initRecords()
-{
- void *p;
- // Records with dynamic sizes
- cacheRecord = (CacheRecord*)allocRecord("CacheRecord",
- sizeof(CacheRecord),
- ccacheFilesize);
-
- apiConnectRecord = (ApiConnectRecord*)allocRecord("ApiConnectRecord",
- sizeof(ApiConnectRecord),
- capiConnectFilesize);
-
- for(unsigned i = 0; i<capiConnectFilesize; i++) {
- p = &apiConnectRecord[i];
- new (p) ApiConnectRecord(c_theFiredTriggerPool,
- c_theIndexOperationPool);
- }
- // Init all fired triggers
- DLFifoList<TcFiredTriggerData> triggers(c_theFiredTriggerPool);
- FiredTriggerPtr tptr;
- while(triggers.seize(tptr) == true) {
- p= tptr.p;
- new (p) TcFiredTriggerData();
- }
- triggers.release();
-
- /*
- // Init all index records
- ArrayList<TcIndexData> indexes(c_theIndexPool);
- TcIndexDataPtr iptr;
- while(indexes.seize(iptr) == true) {
- new (iptr.p) TcIndexData(c_theAttrInfoListPool);
- }
- indexes.release();
- */
-
- // Init all index operation records
- SLList<TcIndexOperation> indexOps(c_theIndexOperationPool);
- TcIndexOperationPtr ioptr;
- while(indexOps.seize(ioptr) == true) {
- p= ioptr.p;
- new (p) TcIndexOperation(c_theAttributeBufferPool);
- }
- indexOps.release();
-
- c_apiConTimer = (UintR*)allocRecord("ApiConTimer",
- sizeof(UintR),
- capiConnectFilesize);
-
- c_apiConTimer_line = (UintR*)allocRecord("ApiConTimer_line",
- sizeof(UintR),
- capiConnectFilesize);
-
- tcConnectRecord = (TcConnectRecord*)allocRecord("TcConnectRecord",
- sizeof(TcConnectRecord),
- ctcConnectFilesize);
-
- m_commitAckMarkerPool.setSize(capiConnectFilesize);
- m_commitAckMarkerHash.setSize(512);
-
- hostRecord = (HostRecord*)allocRecord("HostRecord",
- sizeof(HostRecord),
- chostFilesize);
-
- tableRecord = (TableRecord*)allocRecord("TableRecord",
- sizeof(TableRecord),
- ctabrecFilesize);
-
- scanRecord = (ScanRecord*)allocRecord("ScanRecord",
- sizeof(ScanRecord),
- cscanrecFileSize);
-
-
- 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);
-
- attrbufRecord = (AttrbufRecord*)allocRecord("AttrbufRecord",
- sizeof(AttrbufRecord),
- cattrbufFilesize);
-
- gcpRecord = (GcpRecord*)allocRecord("GcpRecord",
- sizeof(GcpRecord),
- cgcpFilesize);
-
-}//Dbtc::initRecords()
-
-Dbtc::Dbtc(Block_context& ctx):
- SimulatedBlock(DBTC, ctx),
- c_theDefinedTriggers(c_theDefinedTriggerPool),
- c_firedTriggerHash(c_theFiredTriggerPool),
- c_maxNumberOfDefinedTriggers(0),
- c_maxNumberOfFiredTriggers(0),
- c_theIndexes(c_theIndexPool),
- c_maxNumberOfIndexes(0),
- c_maxNumberOfIndexOperations(0),
- m_commitAckMarkerHash(m_commitAckMarkerPool)
-{
- BLOCK_CONSTRUCTOR(Dbtc);
-
- const ndb_mgm_configuration_iterator * p =
- ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint32 transactionBufferMemory = 0;
- Uint32 maxNoOfIndexes = 0, maxNoOfConcurrentIndexOperations = 0;
- Uint32 maxNoOfTriggers = 0, maxNoOfFiredTriggers = 0;
-
- ndb_mgm_get_int_parameter(p, CFG_DB_TRANS_BUFFER_MEM,
- &transactionBufferMemory);
- ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE,
- &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;
- c_maxNumberOfIndexOperations = maxNoOfConcurrentIndexOperations;
- c_maxNumberOfDefinedTriggers = maxNoOfTriggers;
- c_maxNumberOfFiredTriggers = maxNoOfFiredTriggers;
-
- // Transit signals
- addRecSignal(GSN_PACKED_SIGNAL, &Dbtc::execPACKED_SIGNAL);
- addRecSignal(GSN_ABORTED, &Dbtc::execABORTED);
- addRecSignal(GSN_ATTRINFO, &Dbtc::execATTRINFO);
- addRecSignal(GSN_CONTINUEB, &Dbtc::execCONTINUEB);
- addRecSignal(GSN_KEYINFO, &Dbtc::execKEYINFO);
- addRecSignal(GSN_SCAN_NEXTREQ, &Dbtc::execSCAN_NEXTREQ);
- addRecSignal(GSN_TAKE_OVERTCREQ, &Dbtc::execTAKE_OVERTCREQ);
- addRecSignal(GSN_TAKE_OVERTCCONF, &Dbtc::execTAKE_OVERTCCONF);
- addRecSignal(GSN_LQHKEYREF, &Dbtc::execLQHKEYREF);
-
- // Received signals
-
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbtc::execDUMP_STATE_ORD);
- addRecSignal(GSN_SEND_PACKED, &Dbtc::execSEND_PACKED);
- addRecSignal(GSN_SCAN_HBREP, &Dbtc::execSCAN_HBREP);
- addRecSignal(GSN_COMPLETED, &Dbtc::execCOMPLETED);
- addRecSignal(GSN_COMMITTED, &Dbtc::execCOMMITTED);
- addRecSignal(GSN_DIGETPRIMCONF, &Dbtc::execDIGETPRIMCONF);
- addRecSignal(GSN_DIGETPRIMREF, &Dbtc::execDIGETPRIMREF);
- addRecSignal(GSN_DISEIZECONF, &Dbtc::execDISEIZECONF);
- addRecSignal(GSN_DIVERIFYCONF, &Dbtc::execDIVERIFYCONF);
- addRecSignal(GSN_DI_FCOUNTCONF, &Dbtc::execDI_FCOUNTCONF);
- addRecSignal(GSN_DI_FCOUNTREF, &Dbtc::execDI_FCOUNTREF);
- addRecSignal(GSN_GCP_NOMORETRANS, &Dbtc::execGCP_NOMORETRANS);
- addRecSignal(GSN_LQHKEYCONF, &Dbtc::execLQHKEYCONF);
- addRecSignal(GSN_NDB_STTOR, &Dbtc::execNDB_STTOR);
- addRecSignal(GSN_READ_NODESCONF, &Dbtc::execREAD_NODESCONF);
- addRecSignal(GSN_READ_NODESREF, &Dbtc::execREAD_NODESREF);
- addRecSignal(GSN_STTOR, &Dbtc::execSTTOR);
- addRecSignal(GSN_TC_COMMITREQ, &Dbtc::execTC_COMMITREQ);
- addRecSignal(GSN_TC_CLOPSIZEREQ, &Dbtc::execTC_CLOPSIZEREQ);
- addRecSignal(GSN_TCGETOPSIZEREQ, &Dbtc::execTCGETOPSIZEREQ);
- addRecSignal(GSN_TCKEYREQ, &Dbtc::execTCKEYREQ);
- addRecSignal(GSN_TCRELEASEREQ, &Dbtc::execTCRELEASEREQ);
- addRecSignal(GSN_TCSEIZEREQ, &Dbtc::execTCSEIZEREQ);
- addRecSignal(GSN_TCROLLBACKREQ, &Dbtc::execTCROLLBACKREQ);
- addRecSignal(GSN_TC_HBREP, &Dbtc::execTC_HBREP);
- addRecSignal(GSN_TC_SCHVERREQ, &Dbtc::execTC_SCHVERREQ);
- addRecSignal(GSN_SCAN_TABREQ, &Dbtc::execSCAN_TABREQ);
- addRecSignal(GSN_SCAN_FRAGCONF, &Dbtc::execSCAN_FRAGCONF);
- addRecSignal(GSN_SCAN_FRAGREF, &Dbtc::execSCAN_FRAGREF);
- 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);
- addRecSignal(GSN_ABORTCONF, &Dbtc::execABORTCONF);
- addRecSignal(GSN_NODE_FAILREP, &Dbtc::execNODE_FAILREP);
- addRecSignal(GSN_INCL_NODEREQ, &Dbtc::execINCL_NODEREQ);
- addRecSignal(GSN_TIME_SIGNAL, &Dbtc::execTIME_SIGNAL);
- addRecSignal(GSN_API_FAILREQ, &Dbtc::execAPI_FAILREQ);
-
- addRecSignal(GSN_TC_COMMIT_ACK, &Dbtc::execTC_COMMIT_ACK);
- addRecSignal(GSN_ABORT_ALL_REQ, &Dbtc::execABORT_ALL_REQ);
-
- addRecSignal(GSN_CREATE_TRIG_REQ, &Dbtc::execCREATE_TRIG_REQ);
- addRecSignal(GSN_DROP_TRIG_REQ, &Dbtc::execDROP_TRIG_REQ);
- addRecSignal(GSN_FIRE_TRIG_ORD, &Dbtc::execFIRE_TRIG_ORD);
- addRecSignal(GSN_TRIG_ATTRINFO, &Dbtc::execTRIG_ATTRINFO);
-
- addRecSignal(GSN_CREATE_INDX_REQ, &Dbtc::execCREATE_INDX_REQ);
- addRecSignal(GSN_DROP_INDX_REQ, &Dbtc::execDROP_INDX_REQ);
- addRecSignal(GSN_TCINDXREQ, &Dbtc::execTCINDXREQ);
- addRecSignal(GSN_INDXKEYINFO, &Dbtc::execINDXKEYINFO);
- addRecSignal(GSN_INDXATTRINFO, &Dbtc::execINDXATTRINFO);
- addRecSignal(GSN_ALTER_INDX_REQ, &Dbtc::execALTER_INDX_REQ);
-
- addRecSignal(GSN_TRANSID_AI_R, &Dbtc::execTRANSID_AI_R);
- addRecSignal(GSN_KEYINFO20_R, &Dbtc::execKEYINFO20_R);
-
- // Index table lookup
- addRecSignal(GSN_TCKEYCONF, &Dbtc::execTCKEYCONF);
- addRecSignal(GSN_TCKEYREF, &Dbtc::execTCKEYREF);
- addRecSignal(GSN_TRANSID_AI, &Dbtc::execTRANSID_AI);
- addRecSignal(GSN_TCROLLBACKREP, &Dbtc::execTCROLLBACKREP);
-
- //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);
- addRecSignal(GSN_ROUTE_ORD, &Dbtc::execROUTE_ORD);
-
- cacheRecord = 0;
- apiConnectRecord = 0;
- tcConnectRecord = 0;
- hostRecord = 0;
- tableRecord = 0;
- scanRecord = 0;
- databufRecord = 0;
- attrbufRecord = 0;
- gcpRecord = 0;
- tcFailRecord = 0;
- c_apiConTimer = 0;
- c_apiConTimer_line = 0;
-
-#ifdef VM_TRACE
- {
- void* tmp[] = { &apiConnectptr,
- &tcConnectptr,
- &cachePtr,
- &attrbufptr,
- &hostptr,
- &gcpPtr,
- &tmpApiConnectptr,
- &timeOutptr,
- &scanFragptr,
- &databufptr,
- &tmpDatabufptr };
- init_globals_list(tmp, sizeof(tmp)/sizeof(tmp[0]));
- }
-#endif
- cacheRecord = 0;
- apiConnectRecord = 0;
- tcConnectRecord = 0;
- hostRecord = 0;
- tableRecord = 0;
- scanRecord = 0;
- databufRecord = 0;
- attrbufRecord = 0;
- gcpRecord = 0;
- tcFailRecord = 0;
- c_apiConTimer = 0;
- c_apiConTimer_line = 0;
-}//Dbtc::Dbtc()
-
-Dbtc::~Dbtc()
-{
- // Records with dynamic sizes
- deallocRecord((void **)&cacheRecord, "CacheRecord",
- sizeof(CacheRecord),
- ccacheFilesize);
-
- deallocRecord((void **)&apiConnectRecord, "ApiConnectRecord",
- sizeof(ApiConnectRecord),
- capiConnectFilesize);
-
- deallocRecord((void **)&tcConnectRecord, "TcConnectRecord",
- sizeof(TcConnectRecord),
- ctcConnectFilesize);
-
- deallocRecord((void **)&hostRecord, "HostRecord",
- sizeof(HostRecord),
- chostFilesize);
-
- deallocRecord((void **)&tableRecord, "TableRecord",
- sizeof(TableRecord),
- ctabrecFilesize);
-
- deallocRecord((void **)&scanRecord, "ScanRecord",
- sizeof(ScanRecord),
- cscanrecFileSize);
-
- deallocRecord((void **)&databufRecord, "DatabufRecord",
- sizeof(DatabufRecord),
- cdatabufFilesize);
-
- deallocRecord((void **)&attrbufRecord, "AttrbufRecord",
- sizeof(AttrbufRecord),
- cattrbufFilesize);
-
- deallocRecord((void **)&gcpRecord, "GcpRecord",
- sizeof(GcpRecord),
- cgcpFilesize);
-
- deallocRecord((void **)&tcFailRecord, "TcFailRecord",
- sizeof(TcFailRecord), 1);
-
- deallocRecord((void **)&c_apiConTimer, "ApiConTimer",
- sizeof(UintR),
- capiConnectFilesize);
-
- deallocRecord((void **)&c_apiConTimer_line, "ApiConTimer",
- sizeof(UintR),
- capiConnectFilesize);
-}//Dbtc::~Dbtc()
-
-BLOCK_FUNCTIONS(Dbtc)
-
diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
deleted file mode 100644
index f4b0e07854c..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ /dev/null
@@ -1,13612 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTC_C
-
-#include "Dbtc.hpp"
-#include "md5_hash.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <my_sys.h>
-#include <ndb_rand.h>
-
-#include <signaldata/EventReport.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/TcKeyConf.hpp>
-#include <signaldata/TcKeyRef.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/TransIdAI.hpp>
-#include <signaldata/TcRollbackRep.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/LqhKey.hpp>
-#include <signaldata/TcCommit.hpp>
-#include <signaldata/TcContinueB.hpp>
-#include <signaldata/TcKeyFailConf.hpp>
-#include <signaldata/AbortAll.hpp>
-#include <signaldata/DihFragCount.hpp>
-#include <signaldata/ScanFrag.hpp>
-#include <signaldata/ScanTab.hpp>
-#include <signaldata/PrepDropTab.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/FireTrigOrd.hpp>
-#include <signaldata/TrigAttrInfo.hpp>
-#include <signaldata/CreateIndx.hpp>
-#include <signaldata/DropIndx.hpp>
-#include <signaldata/AlterIndx.hpp>
-#include <signaldata/ScanTab.hpp>
-#include <signaldata/SystemError.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/DisconnectRep.hpp>
-#include <signaldata/TcHbRep.hpp>
-
-#include <signaldata/PrepDropTab.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/IndxKeyInfo.hpp>
-#include <signaldata/IndxAttrInfo.hpp>
-#include <signaldata/PackedSignal.hpp>
-#include <AttributeHeader.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <AttributeDescriptor.hpp>
-#include <SectionReader.hpp>
-#include <KeyDescriptor.hpp>
-
-#include <NdbOut.hpp>
-#include <DebuggerNames.hpp>
-
-#include <signaldata/RouteOrd.hpp>
-
-// Use DEBUG to print messages that should be
-// seen only when we debug the product
-#ifdef VM_TRACE
-#define DEBUG(x) ndbout << "DBTC: "<< x << endl;
-#else
-#define DEBUG(x)
-#endif
-
-#define INTERNAL_TRIGGER_TCKEYREQ_JBA 0
-
-#ifdef VM_TRACE
-NdbOut &
-operator<<(NdbOut& out, Dbtc::ConnectionState state){
- switch(state){
- case Dbtc::CS_CONNECTED: out << "CS_CONNECTED"; break;
- case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break;
- case Dbtc::CS_STARTED: out << "CS_STARTED"; break;
- case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break;
- case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break;
- case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break;
- case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break;
- case Dbtc::CS_RESTART: out << "CS_RESTART"; break;
- case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break;
- case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break;
- case Dbtc::CS_COMPLETE_SENT: out << "CS_COMPLETE_SENT"; break;
- case Dbtc::CS_PREPARE_TO_COMMIT: out << "CS_PREPARE_TO_COMMIT"; break;
- case Dbtc::CS_COMMIT_SENT: out << "CS_COMMIT_SENT"; break;
- case Dbtc::CS_START_COMMITTING: out << "CS_START_COMMITTING"; break;
- case Dbtc::CS_COMMITTING: out << "CS_COMMITTING"; break;
- case Dbtc::CS_REC_COMMITTING: out << "CS_REC_COMMITTING"; break;
- case Dbtc::CS_WAIT_ABORT_CONF: out << "CS_WAIT_ABORT_CONF"; break;
- case Dbtc::CS_WAIT_COMPLETE_CONF: out << "CS_WAIT_COMPLETE_CONF"; break;
- case Dbtc::CS_WAIT_COMMIT_CONF: out << "CS_WAIT_COMMIT_CONF"; break;
- case Dbtc::CS_FAIL_ABORTING: out << "CS_FAIL_ABORTING"; break;
- case Dbtc::CS_FAIL_ABORTED: out << "CS_FAIL_ABORTED"; break;
- case Dbtc::CS_FAIL_PREPARED: out << "CS_FAIL_PREPARED"; break;
- case Dbtc::CS_FAIL_COMMITTING: out << "CS_FAIL_COMMITTING"; break;
- case Dbtc::CS_FAIL_COMMITTED: out << "CS_FAIL_COMMITTED"; break;
- case Dbtc::CS_FAIL_COMPLETED: out << "CS_FAIL_COMPLETED"; break;
- case Dbtc::CS_START_SCAN: out << "CS_START_SCAN"; break;
- default:
- out << "Unknown: " << (int)state; break;
- }
- return out;
-}
-NdbOut &
-operator<<(NdbOut& out, Dbtc::OperationState state){
- out << (int)state;
- return out;
-}
-NdbOut &
-operator<<(NdbOut& out, Dbtc::AbortState state){
- out << (int)state;
- return out;
-}
-NdbOut &
-operator<<(NdbOut& out, Dbtc::ReturnSignal state){
- out << (int)state;
- return out;
-}
-NdbOut &
-operator<<(NdbOut& out, Dbtc::ScanRecord::ScanState state){
- out << (int)state;
- return out;
-}
-NdbOut &
-operator<<(NdbOut& out, Dbtc::ScanFragRec::ScanFragState state){
- out << (int)state;
- return out;
-}
-#endif
-
-void
-Dbtc::updateBuddyTimer(ApiConnectRecordPtr apiPtr)
-{
- if (apiPtr.p->buddyPtr != RNIL) {
- jam();
- ApiConnectRecordPtr buddyApiPtr;
- buddyApiPtr.i = apiPtr.p->buddyPtr;
- ptrCheckGuard(buddyApiPtr, capiConnectFilesize, apiConnectRecord);
- if (getApiConTimer(buddyApiPtr.i) != 0) {
- if ((apiPtr.p->transid[0] == buddyApiPtr.p->transid[0]) &&
- (apiPtr.p->transid[1] == buddyApiPtr.p->transid[1])) {
- jam();
- setApiConTimer(buddyApiPtr.i, ctcTimer, __LINE__);
- } else {
- jam();
- // Not a buddy anymore since not the same transid
- apiPtr.p->buddyPtr = RNIL;
- }//if
- }//if
- }//if
-}
-
-void Dbtc::execCONTINUEB(Signal* signal)
-{
- UintR tcase;
-
- jamEntry();
- 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();
- ndbrequire(false);
- return;
- case TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER:
- jam();
- tcNodeFailptr.i = Tdata0;
- ptrCheckGuard(tcNodeFailptr, 1, tcFailRecord);
- completeTransAtTakeOverLab(signal, Tdata1);
- return;
- case TcContinueB::ZCONTINUE_TIME_OUT_CONTROL:
- jam();
- timeOutLoopStartLab(signal, Tdata0);
- return;
- case TcContinueB::ZNODE_TAKE_OVER_COMPLETED:
- jam();
- tnodeid = Tdata0;
- tcNodeFailptr.i = 0;
- ptrAss(tcNodeFailptr, tcFailRecord);
- nodeTakeOverCompletedLab(signal);
- return;
- case TcContinueB::ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal, Tdata0, Tdata2, signal->theData[4]);
- return;
- case TcContinueB::ZSEND_COMMIT_LOOP:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- tcConnectptr.i = Tdata1;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- commit020Lab(signal);
- return;
- case TcContinueB::ZSEND_COMPLETE_LOOP:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- tcConnectptr.i = Tdata1;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- complete010Lab(signal);
- return;
- case TcContinueB::ZHANDLE_FAILED_API_NODE:
- jam();
- handleFailedApiNode(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::ZTRANS_EVENT_REP:
- jam();
- /* -------------------------------------------------------------------- */
- // Report information about transaction activity once per second.
- /* -------------------------------------------------------------------- */
- if (c_counters.c_trans_status == TransCounters::Timer){
- Uint32 len = c_counters.report(signal);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, len, JBB);
-
- c_counters.reset();
- signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1);
- }
- return;
- case TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL:
- jam();
- timeOutLoopStartFragLab(signal, Tdata0);
- return;
- case TcContinueB::ZABORT_BREAK:
- jam();
- tcConnectptr.i = Tdata0;
- apiConnectptr.i = Tdata1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->counter--;
- abort015Lab(signal);
- return;
- case TcContinueB::ZABORT_TIMEOUT_BREAK:
- jam();
- tcConnectptr.i = Tdata0;
- apiConnectptr.i = Tdata1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->counter--;
- sendAbortedAfterTimeout(signal, 1);
- return;
- case TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS:
- jam();
- removeMarkerForFailedAPI(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::ZWAIT_ABORT_ALL:
- jam();
- checkAbortAllTimeout(signal, Tdata0);
- return;
- case TcContinueB::ZCHECK_SCAN_ACTIVE_FAILED_LQH:
- jam();
- checkScanActiveInFailedLqh(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::ZNF_CHECK_TRANSACTIONS:
- jam();
- nodeFailCheckTransactions(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:
- jam();
- checkWaitDropTabFailedLqh(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::TRIGGER_PENDING:
- jam();
- ApiConnectRecordPtr transPtr;
- transPtr.i = Tdata0;
- ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
- transPtr.p->triggerPending = false;
- executeTriggers(signal, &transPtr);
- return;
- case TcContinueB::DelayTCKEYCONF:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- sendtckeyconf(signal, Tdata1);
- return;
- default:
- ndbrequire(false);
- }//switch
-}
-
-void Dbtc::execDIGETNODESREF(Signal* signal)
-{
- jamEntry();
- terrorCode = signal->theData[1];
- releaseAtErrorLab(signal);
-}
-
-void Dbtc::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
- tblockref = signal->theData[0];
- hostptr.i = signal->theData[1];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- hostptr.p->hostStatus = HS_ALIVE;
- c_alive_nodes.set(hostptr.i);
-
- signal->theData[0] = hostptr.i;
- signal->theData[1] = cownref;
-
- if (ERROR_INSERTED(8039))
- {
- CLEAR_ERROR_INSERT_VALUE;
- Uint32 save = signal->theData[0];
- signal->theData[0] = 9999;
- sendSignal(numberToRef(CMVMI, hostptr.i),
- GSN_NDB_TAMPER, signal, 1, JBB);
- signal->theData[0] = save;
- sendSignalWithDelay(tblockref, GSN_INCL_NODECONF, signal, 5000, 2);
- return;
- }
-
- sendSignal(tblockref, GSN_INCL_NODECONF, signal, 2, JBB);
-}
-
-void Dbtc::execREAD_NODESREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}
-
-void Dbtc::execTC_SCHVERREQ(Signal* signal)
-{
- jamEntry();
- if (! assembleFragments(signal)) {
- jam();
- return;
- }
- tabptr.i = signal->theData[0];
- ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord);
- tabptr.p->currentSchemaVersion = signal->theData[1];
- tabptr.p->m_flags = 0;
- tabptr.p->set_storedTable((bool)signal->theData[2]);
- BlockReference retRef = signal->theData[3];
- tabptr.p->tableType = (Uint8)signal->theData[4];
- BlockReference retPtr = signal->theData[5];
- Uint32 noOfKeyAttr = signal->theData[6];
- tabptr.p->singleUserMode = (Uint8)signal->theData[7];
- ndbrequire(noOfKeyAttr <= MAX_ATTRIBUTES_IN_INDEX);
-
- const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tabptr.i);
- ndbrequire(noOfKeyAttr == desc->noOfKeyAttr);
-
- ndbrequire(tabptr.p->get_enabled() == false);
- tabptr.p->set_enabled(true);
- tabptr.p->set_dropping(false);
- tabptr.p->noOfKeyAttr = desc->noOfKeyAttr;
- tabptr.p->hasCharAttr = desc->hasCharAttr;
- tabptr.p->noOfDistrKeys = desc->noOfDistrKeys;
- tabptr.p->hasVarKeys = desc->noOfVarKeys > 0;
- signal->theData[0] = tabptr.i;
- signal->theData[1] = retPtr;
- sendSignal(retRef, GSN_TC_SCHVERCONF, signal, 2, JBB);
-}//Dbtc::execTC_SCHVERREQ()
-
-void
-Dbtc::execPREP_DROP_TAB_REQ(Signal* signal)
-{
- jamEntry();
-
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
-
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- if(!tabPtr.p->get_enabled()){
- jam();
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = PrepDropTabRef::NoSuchTable;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
-
- if(tabPtr.p->get_dropping()){
- jam();
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = PrepDropTabRef::DropInProgress;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->set_dropping(true);
- tabPtr.p->dropTable.senderRef = senderRef;
- tabPtr.p->dropTable.senderData = senderData;
-
- {
- WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
- req->tableId = tabPtr.i;
- req->senderRef = reference();
-
- HostRecordPtr hostPtr;
- tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor();
- for (hostPtr.i = 1; hostPtr.i < MAX_NDB_NODES; hostPtr.i++) {
- jam();
- ptrAss(hostPtr, hostRecord);
- if (hostPtr.p->hostStatus == HS_ALIVE) {
- jam();
- tabPtr.p->dropTable.waitDropTabCount.setWaitingFor(hostPtr.i);
- sendSignal(calcLqhBlockRef(hostPtr.i), GSN_WAIT_DROP_TAB_REQ,
- signal, WaitDropTabReq::SignalLength, JBB);
- }//for
- }//if
-
- ndbrequire(tabPtr.p->dropTable.waitDropTabCount.done() != true);
- }
-}
-
-void
-Dbtc::execWAIT_DROP_TAB_CONF(Signal* signal)
-{
- jamEntry();
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
-
- TableRecordPtr tabPtr;
- tabPtr.i = conf->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- ndbrequire(tabPtr.p->get_dropping() == true);
- Uint32 nodeId = refToNode(conf->senderRef);
- tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
-
- 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::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->get_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)
-{
-
- TableRecordPtr tabPtr;
- tabPtr.i = tableId;
-
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
- conf->tableId = tableId;
-
- const Uint32 RT_BREAK = 16;
- for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabrecFilesize; i++, tabPtr.i++){
- jam();
- ptrAss(tabPtr, tableRecord);
- if(tabPtr.p->get_enabled() && tabPtr.p->get_dropping()){
- if(tabPtr.p->dropTable.waitDropTabCount.isWaitingFor(nodeId)){
- jam();
- conf->senderRef = calcLqhBlockRef(nodeId);
- execWAIT_DROP_TAB_CONF(signal);
- tabPtr.i++;
- break;
- }
- }
- }
-
- if(tabPtr.i == ctabrecFilesize){
- /**
- * Finished
- */
- jam();
- checkNodeFailComplete(signal, nodeId, HostRecord::NF_CHECK_DROP_TAB);
- return;
- }
-
- signal->theData[0] = TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void
-Dbtc::execDROP_TAB_REQ(Signal* signal)
-{
- jamEntry();
-
- DropTabReq* req = (DropTabReq*)signal->getDataPtr();
-
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
-
- if(!tabPtr.p->get_enabled() && rt == DropTabReq::OnlineDropTab){
- jam();
- DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = DropTabRef::NoSuchTable;
- sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
- DropTabRef::SignalLength, JBB);
- return;
- }
-
- if(!tabPtr.p->get_dropping() && rt == DropTabReq::OnlineDropTab){
- jam();
- DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = DropTabRef::DropWoPrep;
- sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
- DropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->set_enabled(false);
- tabPtr.p->set_dropping(false);
-
- DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(senderRef, GSN_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
-}
-
-void Dbtc::execALTER_TAB_REQ(Signal * signal)
-{
- AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- const Uint32 gci = req->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) req->requestType;
-
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
- tabPtr.p->currentSchemaVersion = tableVersion;
-
- // Request handled successfully
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
-}
-
-/* ***************************************************************************/
-/* START / RESTART */
-/* ***************************************************************************/
-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();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- initData();
-
- 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;
- cscanFragrecFileSize = localScan;
-
- initRecords();
- initialiseRecordsLab(signal, 0, ref, senderData);
-
- Uint32 val = 3000;
- ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val);
- set_timeout_value(val);
-
- val = 1500;
- ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &val);
- cDbHbInterval = (val < 10) ? 10 : 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)
-{
- Uint16 tphase;
-
- jamEntry();
- /* START CASE */
- tphase = signal->theData[1];
- csignalKey = signal->theData[6];
- switch (tphase) {
- case ZSPH1:
- jam();
- startphase1x010Lab(signal);
- return;
- default:
- jam();
- sttorryLab(signal); /* START PHASE 255 */
- return;
- }//switch
-}//Dbtc::execSTTOR()
-
-void Dbtc::sttorryLab(Signal* signal)
-{
- signal->theData[0] = csignalKey;
- signal->theData[1] = 3; /* BLOCK CATEGORY */
- signal->theData[2] = 2; /* SIGNAL VERSION NUMBER */
- signal->theData[3] = ZSPH1;
- signal->theData[4] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
-}//Dbtc::sttorryLab()
-
-/* ***************************************************************************/
-/* INTERNAL START / RESTART */
-/*****************************************************************************/
-void Dbtc::execNDB_STTOR(Signal* signal)
-{
- Uint16 tndbstartphase;
- Uint16 tstarttype;
-
- jamEntry();
- tusersblkref = signal->theData[0];
- tnodeid = signal->theData[1];
- tndbstartphase = signal->theData[2]; /* START PHASE */
- tstarttype = signal->theData[3]; /* START TYPE */
- switch (tndbstartphase) {
- case ZINTSPH1:
- jam();
- intstartphase1x010Lab(signal);
- return;
- case ZINTSPH2:
- jam();
- intstartphase2x010Lab(signal);
- return;
- case ZINTSPH3:
- jam();
- intstartphase3x010Lab(signal); /* SEIZE CONNECT RECORD IN EACH LQH*/
-// Start transaction event reporting.
- c_counters.c_trans_status = TransCounters::Timer;
- c_counters.reset();
- signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
- return;
- case ZINTSPH6:
- jam();
- csystemStart = SSS_TRUE;
- break;
- default:
- jam();
- break;
- }//switch
- ndbsttorry010Lab(signal);
- return;
-}//Dbtc::execNDB_STTOR()
-
-void Dbtc::ndbsttorry010Lab(Signal* signal)
-{
- signal->theData[0] = cownref;
- sendSignal(cndbcntrblockref, GSN_NDB_STTORRY, signal, 1, JBB);
-}//Dbtc::ndbsttorry010Lab()
-
-void
-Dbtc::set_timeout_value(Uint32 timeOut)
-{
- timeOut = timeOut / 10;
- if (timeOut < 2) {
- jam();
- timeOut = 100;
- }//if
- ctimeOutValue = timeOut;
-}
-
-void
-Dbtc::set_appl_timeout_value(Uint32 timeOut)
-{
- if (timeOut)
- {
- timeOut /= 10;
- if (timeOut < ctimeOutValue) {
- jam();
- c_appl_timeout_value = ctimeOutValue;
- }//if
- }
- c_appl_timeout_value = timeOut;
-}
-
-void
-Dbtc::set_no_parallel_takeover(Uint32 noParallelTakeOver)
-{
- if (noParallelTakeOver == 0) {
- jam();
- noParallelTakeOver = 1;
- } else if (noParallelTakeOver > MAX_NDB_NODES) {
- jam();
- noParallelTakeOver = MAX_NDB_NODES;
- }//if
- cnoParallelTakeOver = noParallelTakeOver;
-}
-
-/* ***************************************************************************/
-/* S T A R T P H A S E 1 X */
-/* INITIALISE BLOCKREF AND BLOCKNUMBERS */
-/* ***************************************************************************/
-void Dbtc::startphase1x010Lab(Signal* signal)
-{
- csystemStart = SSS_FALSE;
- ctimeOutCheckCounter = 0;
- ctimeOutCheckFragCounter = 0;
- ctimeOutMissedHeartbeats = 0;
- ctimeOutCheckHeartbeat = 0;
- ctimeOutCheckLastHeartbeat = 0;
- ctimeOutCheckActive = TOCS_FALSE;
- ctimeOutCheckFragActive = TOCS_FALSE;
- sttorryLab(signal);
-}//Dbtc::startphase1x010Lab()
-
-/*****************************************************************************/
-/* I N T S T A R T P H A S E 1 X */
-/* INITIALISE ALL RECORDS. */
-/*****************************************************************************/
-void Dbtc::intstartphase1x010Lab(Signal* signal)
-{
- cownNodeid = tnodeid;
- cownref = calcTcBlockRef(cownNodeid);
- clqhblockref = calcLqhBlockRef(cownNodeid);
- cdihblockref = calcDihBlockRef(cownNodeid);
- cdictblockref = calcDictBlockRef(cownNodeid);
- cndbcntrblockref = calcNdbCntrBlockRef(cownNodeid);
- cerrorBlockref = calcNdbCntrBlockRef(cownNodeid);
- coperationsize = 0;
- cfailure_nr = 0;
- ndbsttorry010Lab(signal);
-}//Dbtc::intstartphase1x010Lab()
-
-/*****************************************************************************/
-/* I N T S T A R T P H A S E 2 X */
-/* SET-UP LOCAL CONNECTIONS. */
-/*****************************************************************************/
-void Dbtc::intstartphase2x010Lab(Signal* signal)
-{
- tcConnectptr.i = cfirstfreeTcConnect;
- intstartphase2x020Lab(signal);
-}//Dbtc::intstartphase2x010Lab()
-
-void Dbtc::intstartphase2x020Lab(Signal* signal)
-{
- if (tcConnectptr.i == RNIL) {
- jam();
- ndbsttorry010Lab(signal);
- return;
- }//if
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcConnectptr.p->tcConnectstate = OS_CONNECTING_DICT;
-/* ****************** */
-/* DISEIZEREQ < */
-/* ****************** */
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- sendSignal(cdihblockref, GSN_DISEIZEREQ, signal, 2, JBB);
-}//Dbtc::intstartphase2x020Lab()
-
-void Dbtc::execDISEIZECONF(Signal* signal)
-{
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcConnectptr.p->dihConnectptr = signal->theData[1];
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- intstartphase2x020Lab(signal);
-}//Dbtc::execDISEIZECONF()
-
-/*****************************************************************************/
-/* I N T S T A R T P H A S E 3 X */
-/* PREPARE DISTRIBUTED CONNECTIONS */
-/*****************************************************************************/
-void Dbtc::intstartphase3x010Lab(Signal* signal)
-{
- signal->theData[0] = cownref;
- sendSignal(cndbcntrblockref, GSN_READ_NODESREQ, signal, 1, JBB);
-}//Dbtc::intstartphase3x010Lab()
-
-void Dbtc::execREAD_NODESCONF(Signal* signal)
-{
- UintR guard0;
-
- jamEntry();
-
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
-
- csystemnodes = readNodes->noOfNodes;
- cmasterNodeId = readNodes->masterNodeId;
-
- con_lineNodes = 0;
- arrGuard(csystemnodes, MAX_NDB_NODES);
- guard0 = csystemnodes - 1;
- arrGuard(guard0, MAX_NDB_NODES); // Check not zero nodes
-
- for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if (NodeBitmask::get(readNodes->allNodes, i)) {
- hostptr.i = i;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
-
- if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
- jam();
- hostptr.p->hostStatus = HS_DEAD;
- } else {
- jam();
- con_lineNodes++;
- hostptr.p->hostStatus = HS_ALIVE;
- c_alive_nodes.set(i);
- }//if
- }//if
- }//for
- ndbsttorry010Lab(signal);
-}//Dbtc::execREAD_NODESCONF()
-
-/*****************************************************************************/
-/* A P I _ F A I L R E Q */
-// An API node has failed for some reason. We need to disconnect all API
-// connections to the API node. This also includes
-/*****************************************************************************/
-void Dbtc::execAPI_FAILREQ(Signal* signal)
-{
- /***************************************************************************
- * Set the block reference to return API_FAILCONF to. Set the number of api
- * connects currently closing to one to indicate that we are still in the
- * process of going through the api connect records. Thus checking for zero
- * can only be true after all api connect records have been checked.
- **************************************************************************/
- jamEntry();
- capiFailRef = signal->theData[1];
- arrGuard(signal->theData[0], MAX_NODES);
- capiConnectClosing[signal->theData[0]] = 1;
- handleFailedApiNode(signal, signal->theData[0], (UintR)0);
-}
-
-void
-Dbtc::handleFailedApiNode(Signal* signal,
- UintR TapiFailedNode,
- UintR TapiConnectPtr)
-{
- UintR TloopCount = 0;
- arrGuard(TapiFailedNode, MAX_NODES);
- apiConnectptr.i = TapiConnectPtr;
- do {
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- const UintR TapiNode = refToNode(apiConnectptr.p->ndbapiBlockref);
- if (TapiNode == TapiFailedNode) {
-#ifdef VM_TRACE
- if (apiConnectptr.p->apiFailState != ZFALSE) {
- ndbout << "Error in previous API fail handling discovered" << endl
- << " apiConnectptr.i = " << apiConnectptr.i << endl
- << " apiConnectstate = " << apiConnectptr.p->apiConnectstate
- << endl
- << " ndbapiBlockref = " << hex
- << apiConnectptr.p->ndbapiBlockref << endl
- << " apiNode = " << refToNode(apiConnectptr.p->ndbapiBlockref)
- << endl;
- if (apiConnectptr.p->lastTcConnect != RNIL){
- jam();
- tcConnectptr.i = apiConnectptr.p->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- ndbout << " tcConnectptr.i = " << tcConnectptr.i << endl
- << " tcConnectstate = " << tcConnectptr.p->tcConnectstate
- << endl;
- }
- }//if
-#endif
-
- apiConnectptr.p->returnsignal = RS_NO_RETURN;
- /***********************************************************************/
- // The connected node is the failed node.
- /**********************************************************************/
- switch(apiConnectptr.p->apiConnectstate) {
- case CS_DISCONNECTED:
- /*********************************************************************/
- // These states do not need any special handling.
- // Simply continue with the next.
- /*********************************************************************/
- jam();
- break;
- case CS_ABORTING:
- /*********************************************************************/
- // This could actually mean that the API connection is already
- // ready to release if the abortState is IDLE.
- /*********************************************************************/
- if (apiConnectptr.p->abortState == AS_IDLE) {
- jam();
- releaseApiCon(signal, apiConnectptr.i);
- } else {
- jam();
- capiConnectClosing[TapiFailedNode]++;
- apiConnectptr.p->apiFailState = ZTRUE;
- }//if
- break;
- case CS_WAIT_ABORT_CONF:
- case CS_WAIT_COMMIT_CONF:
- case CS_START_COMMITTING:
- case CS_PREPARE_TO_COMMIT:
- case CS_COMMITTING:
- case CS_COMMIT_SENT:
- /*********************************************************************/
- // These states indicate that an abort process or commit process is
- // already ongoing. We will set a state in the api record indicating
- // that the API node has failed.
- // Also we will increase the number of outstanding api records to
- // wait for before we can respond with API_FAILCONF.
- /*********************************************************************/
- jam();
- capiConnectClosing[TapiFailedNode]++;
- apiConnectptr.p->apiFailState = ZTRUE;
- break;
- case CS_START_SCAN:
- /*********************************************************************/
- // The api record was performing a scan operation. We need to check
- // on the scan state. Since completing a scan process might involve
- // sending several signals we will increase the loop count by 64.
- /*********************************************************************/
- jam();
-
- apiConnectptr.p->apiFailState = ZTRUE;
- capiConnectClosing[TapiFailedNode]++;
-
- ScanRecordPtr scanPtr;
- scanPtr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
- close_scan_req(signal, scanPtr, true);
-
- TloopCount += 64;
- break;
- case CS_CONNECTED:
- case CS_REC_COMMITTING:
- case CS_RECEIVING:
- case CS_STARTED:
- /*********************************************************************/
- // The api record was in the process of performing a transaction but
- // had not yet sent all information.
- // We need to initiate an ABORT since the API will not provide any
- // more information.
- // Since the abort can send many signals we will insert a real-time
- // break after checking this record.
- /*********************************************************************/
- jam();
- apiConnectptr.p->apiFailState = ZTRUE;
- capiConnectClosing[TapiFailedNode]++;
- abort010Lab(signal);
- TloopCount = 256;
- break;
- case CS_PREPARED:
- jam();
- case CS_REC_PREPARING:
- jam();
- case CS_START_PREPARING:
- jam();
- /*********************************************************************/
- // Not implemented yet.
- /*********************************************************************/
- systemErrorLab(signal, __LINE__);
- break;
- case CS_RESTART:
- jam();
- case CS_COMPLETING:
- jam();
- case CS_COMPLETE_SENT:
- jam();
- case CS_WAIT_COMPLETE_CONF:
- jam();
- case CS_FAIL_ABORTING:
- jam();
- case CS_FAIL_ABORTED:
- jam();
- case CS_FAIL_PREPARED:
- jam();
- case CS_FAIL_COMMITTING:
- jam();
- case CS_FAIL_COMMITTED:
- /*********************************************************************/
- // These states are only valid on copy and fail API connections.
- /*********************************************************************/
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
- } else {
- jam();
- }//if
- apiConnectptr.i++;
- if (apiConnectptr.i > ((capiConnectFilesize / 3) - 1)) {
- jam();
- /**
- * Finished with scanning connection record
- *
- * Now scan markers
- */
- removeMarkerForFailedAPI(signal, TapiFailedNode, 0);
- return;
- }//if
- } while (TloopCount++ < 256);
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE;
- signal->theData[1] = TapiFailedNode;
- signal->theData[2] = apiConnectptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
-}//Dbtc::handleFailedApiNode()
-
-void
-Dbtc::removeMarkerForFailedAPI(Signal* signal,
- Uint32 nodeId,
- Uint32 startBucket)
-{
- TcFailRecordPtr node_fail_ptr;
- node_fail_ptr.i = 0;
- ptrAss(node_fail_ptr, tcFailRecord);
- if(node_fail_ptr.p->failStatus != FS_IDLE) {
- jam();
- DEBUG("Restarting removeMarkerForFailedAPI");
- /**
- * TC take-over in progress
- * needs to restart as this
- * creates new markers
- */
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
- signal->theData[1] = nodeId;
- signal->theData[2] = 0;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 500, 3);
- return;
- }
-
- CommitAckMarkerIterator iter;
- m_commitAckMarkerHash.next(startBucket, iter);
-
- const Uint32 RT_BREAK = 256;
- for(Uint32 i = 0; i<RT_BREAK || iter.bucket == startBucket; i++){
- jam();
-
- if(iter.curr.i == RNIL){
- jam();
- /**
- * Done with iteration
- */
- capiConnectClosing[nodeId]--;
- if (capiConnectClosing[nodeId] == 0) {
- jam();
- /********************************************************************/
- // No outstanding ABORT or COMMIT's of this failed API node.
- // We can respond with API_FAILCONF
- /********************************************************************/
- signal->theData[0] = nodeId;
- signal->theData[1] = cownref;
- sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
- }
- return;
- }
-
- if(iter.curr.p->apiNodeId == nodeId){
- jam();
-
- /**
- * Check so that the record is not still in use
- *
- */
- ApiConnectRecordPtr apiConnectPtr;
- apiConnectPtr.i = iter.curr.p->apiConnectPtr;
- ptrCheckGuard(apiConnectPtr, capiConnectFilesize, apiConnectRecord);
- if(apiConnectPtr.p->commitAckMarker == iter.curr.i){
- jam();
- /**
- * The record is still active
- *
- * Don't remove it, but continueb instead
- */
- break;
- }
- sendRemoveMarkers(signal, iter.curr.p);
- m_commitAckMarkerHash.release(iter.curr);
-
- break;
- }
- m_commitAckMarkerHash.next(iter);
- }
-
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
- signal->theData[1] = nodeId;
- signal->theData[2] = iter.bucket;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void Dbtc::handleApiFailState(Signal* signal, UintR TapiConnectptr)
-{
- ApiConnectRecordPtr TlocalApiConnectptr;
- UintR TfailedApiNode;
-
- TlocalApiConnectptr.i = TapiConnectptr;
- ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
- TfailedApiNode = refToNode(TlocalApiConnectptr.p->ndbapiBlockref);
- arrGuard(TfailedApiNode, MAX_NODES);
- capiConnectClosing[TfailedApiNode]--;
- releaseApiCon(signal, TapiConnectptr);
- TlocalApiConnectptr.p->apiFailState = ZFALSE;
- if (capiConnectClosing[TfailedApiNode] == 0) {
- jam();
- signal->theData[0] = TfailedApiNode;
- signal->theData[1] = cownref;
- sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
- }//if
-}//Dbtc::handleApiFailState()
-
-/****************************************************************************
- * T C S E I Z E R E Q
- * THE APPLICATION SENDS A REQUEST TO SEIZE A CONNECT RECORD TO CARRY OUT A
- * TRANSACTION
- * TC BLOCK TAKE OUT A CONNECT RECORD FROM THE FREE LIST AND ESTABLISHES ALL
- * NECESSARY CONNECTION BEFORE REPLYING TO THE APPLICATION BLOCK
- ****************************************************************************/
-void Dbtc::execTCSEIZEREQ(Signal* signal)
-{
- UintR tapiPointer;
- BlockReference tapiBlockref; /* SENDER BLOCK REFERENCE*/
-
- jamEntry();
- tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
- tapiBlockref = signal->theData[1]; /* SENDERS BLOCK REFERENCE*/
-
- const NodeState::StartLevel sl =
- (NodeState::StartLevel)getNodeState().startLevel;
-
- const NodeId senderNodeId = refToNode(tapiBlockref);
- const bool local = senderNodeId == getOwnNodeId() || senderNodeId == 0;
-
- {
- {
- if (!(sl == NodeState::SL_STARTED ||
- (sl == NodeState::SL_STARTING && local == true))) {
- jam();
-
- Uint32 errCode = 0;
- if(!local)
- {
- switch(sl){
- case NodeState::SL_STARTING:
- errCode = ZSYSTEM_NOT_STARTED_ERROR;
- break;
- case NodeState::SL_STOPPING_1:
- case NodeState::SL_STOPPING_2:
- if (getNodeState().getSingleUserMode())
- break;
- case NodeState::SL_STOPPING_3:
- case NodeState::SL_STOPPING_4:
- if(getNodeState().stopping.systemShutdown)
- errCode = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
- else
- errCode = ZNODE_SHUTDOWN_IN_PROGRESS;
- break;
- case NodeState::SL_SINGLEUSER:
- break;
- default:
- errCode = ZWRONG_STATE;
- break;
- }
- if (errCode)
- {
- signal->theData[0] = tapiPointer;
- signal->theData[1] = errCode;
- sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
- return;
- }
- }//if (!(sl == SL_SINGLEUSER))
- } //if
- }
- }
-
- seizeApiConnect(signal);
- if (terrorCode == ZOK) {
- jam();
- apiConnectptr.p->ndbapiConnect = tapiPointer;
- apiConnectptr.p->ndbapiBlockref = tapiBlockref;
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.i;
- sendSignal(tapiBlockref, GSN_TCSEIZECONF, signal, 2, JBB);
- return;
- }
-
- signal->theData[0] = tapiPointer;
- signal->theData[1] = terrorCode;
- sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
-}//Dbtc::execTCSEIZEREQ()
-
-/****************************************************************************/
-/* T C R E L E A S E Q */
-/* REQUEST TO RELEASE A CONNECT RECORD */
-/****************************************************************************/
-void Dbtc::execTCRELEASEREQ(Signal* signal)
-{
- UintR tapiPointer;
- BlockReference tapiBlockref; /* SENDER BLOCK REFERENCE*/
-
- jamEntry();
- tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
- tapiBlockref = signal->theData[1];/* SENDERS BLOCK REFERENCE*/
- tuserpointer = signal->theData[2];
- if (tapiPointer >= capiConnectFilesize) {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 3, JBB);
- return;
- } else {
- jam();
- apiConnectptr.i = tapiPointer;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- if (apiConnectptr.p->apiConnectstate == CS_DISCONNECTED) {
- jam();
- signal->theData[0] = tuserpointer;
- sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB);
- } else {
- if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) {
- if (apiConnectptr.p->apiConnectstate == CS_CONNECTED ||
- (apiConnectptr.p->apiConnectstate == CS_ABORTING &&
- apiConnectptr.p->abortState == AS_IDLE) ||
- (apiConnectptr.p->apiConnectstate == CS_STARTED &&
- apiConnectptr.p->firstTcConnect == RNIL))
- {
- jam(); /* JUST REPLY OK */
- apiConnectptr.p->m_transaction_nodes.clear();
- releaseApiCon(signal, apiConnectptr.i);
- signal->theData[0] = tuserpointer;
- sendSignal(tapiBlockref,
- GSN_TCRELEASECONF, signal, 1, JBB);
- } else {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- signal->theData[3] = apiConnectptr.p->apiConnectstate;
- sendSignal(tapiBlockref,
- GSN_TCRELEASEREF, signal, 4, JBB);
- }
- } else {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- signal->theData[3] = tapiBlockref;
- signal->theData[4] = apiConnectptr.p->ndbapiBlockref;
- sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 5, JBB);
- }//if
- }//if
-}//Dbtc::execTCRELEASEREQ()
-
-/****************************************************************************/
-// Error Handling for TCKEYREQ messages
-/****************************************************************************/
-void Dbtc::signalErrorRefuseLab(Signal* signal)
-{
- ptrGuard(apiConnectptr);
- if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) {
- jam();
- apiConnectptr.p->abortState = AS_IDLE;
- apiConnectptr.p->apiConnectstate = CS_ABORTING;
- }//if
- sendSignalErrorRefuseLab(signal);
-}//Dbtc::signalErrorRefuseLab()
-
-void Dbtc::sendSignalErrorRefuseLab(Signal* signal)
-{
- ndbassert(false);
- 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];
- signal->theData[3] = ZSIGNAL_ERROR;
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP,
- signal, 4, JBB);
- }
-}//Dbtc::sendSignalErrorRefuseLab()
-
-void Dbtc::abortBeginErrorLab(Signal* signal)
-{
- apiConnectptr.p->transid[0] = signal->theData[ttransid_ptr];
- apiConnectptr.p->transid[1] = signal->theData[ttransid_ptr + 1];
- abortErrorLab(signal);
-}//Dbtc::abortBeginErrorLab()
-
-void Dbtc::printState(Signal* signal, int place)
-{
-#ifdef VM_TRACE // Change to if 0 to disable these printouts
- ndbout << "-- Dbtc::printState -- " << endl;
- ndbout << "Received from place = " << place
- << " apiConnectptr.i = " << apiConnectptr.i
- << " apiConnectstate = " << apiConnectptr.p->apiConnectstate << endl;
- ndbout << "ctcTimer = " << ctcTimer
- << " ndbapiBlockref = " << hex <<apiConnectptr.p->ndbapiBlockref
- << " Transid = " << apiConnectptr.p->transid[0]
- << " " << apiConnectptr.p->transid[1] << endl;
- ndbout << " apiTimer = " << getApiConTimer(apiConnectptr.i)
- << " counter = " << apiConnectptr.p->counter
- << " lqhkeyconfrec = " << apiConnectptr.p->lqhkeyconfrec
- << " lqhkeyreqrec = " << apiConnectptr.p->lqhkeyreqrec << endl;
- ndbout << "abortState = " << apiConnectptr.p->abortState
- << " apiScanRec = " << apiConnectptr.p->apiScanRec
- << " returncode = " << apiConnectptr.p->returncode << endl;
- ndbout << "tckeyrec = " << apiConnectptr.p->tckeyrec
- << " returnsignal = " << apiConnectptr.p->returnsignal
- << " apiFailState = " << apiConnectptr.p->apiFailState << endl;
- if (apiConnectptr.p->cachePtr != RNIL) {
- jam();
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = apiConnectptr.p->cachePtr;
- if (TcachePtr < TcacheFilesize) {
- jam();
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- ndbout << "currReclenAi = " << regCachePtr->currReclenAi
- << " attrlength = " << regCachePtr->attrlength
- << " tableref = " << regCachePtr->tableref
- << " keylen = " << regCachePtr->keylen << endl;
- } else {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- }//if
-#endif
- return;
-}//Dbtc::printState()
-
-void
-Dbtc::TCKEY_abort(Signal* signal, int place)
-{
- switch (place) {
- case 0:
- jam();
- terrorCode = ZSTATE_ERROR;
- apiConnectptr.p->firstTcConnect = RNIL;
- printState(signal, 4);
- abortBeginErrorLab(signal);
- return;
- case 1:
- jam();
- printState(signal, 3);
- sendSignalErrorRefuseLab(signal);
- return;
- case 2:{
- printState(signal, 6);
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
- const Uint32 t1 = tcKeyReq->transId1;
- const Uint32 t2 = tcKeyReq->transId2;
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- 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;
- }
- case 3:
- jam();
- printState(signal, 7);
- noFreeConnectionErrorLab(signal);
- return;
- case 4:
- jam();
- terrorCode = ZERO_KEYLEN_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 5:
- jam();
- terrorCode = ZNO_AI_WITH_UPDATE;
- releaseAtErrorLab(signal);
- return;
- case 6:
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
-
- case 7:
- jam();
- tabStateErrorLab(signal);
- return;
-
- case 8:
- jam();
- wrongSchemaVersionErrorLab(signal);
- return;
-
- case 9:
- jam();
- terrorCode = ZSTATE_ERROR;
- releaseAtErrorLab(signal);
- return;
-
- case 10:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 11:
- jam();
- terrorCode = ZMORE_AI_IN_TCKEYREQ_ERROR;
- releaseAtErrorLab(signal);
- return;
-
- case 12:
- jam();
- terrorCode = ZSIMPLE_READ_WITHOUT_AI;
- releaseAtErrorLab(signal);
- return;
-
- case 13:
- jam();
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_WAIT_KEYINFO:
- jam();
- printState(signal, 8);
- terrorCode = ZSTATE_ERROR;
- abortErrorLab(signal);
- return;
- default:
- jam();
- /********************************************************************/
- /* MISMATCH BETWEEN STATE ON API CONNECTION AND THIS */
- /* PARTICULAR TC CONNECT RECORD. THIS MUST BE CAUSED BY NDB */
- /* INTERNAL ERROR. */
- /********************************************************************/
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
- return;
-
- case 15:
- jam();
- terrorCode = ZSCAN_NODE_ERROR;
- releaseAtErrorLab(signal);
- return;
-
- case 16:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 17:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 18:
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
-
- case 19:
- jam();
- return;
-
- case 20:
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
-
- case 21:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 22:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 23:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 24:
- jam();
- seizeAttrbuferrorLab(signal);
- return;
-
- case 25:
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
-
- case 26:
- jam();
- return;
-
- case 27:
- systemErrorLab(signal, __LINE__);
- jam();
- return;
-
- case 28:
- jam();
- // NOT USED
- return;
-
- case 29:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 30:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 31:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 32:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 33:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 34:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 35:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 36:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 37:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 38:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 39:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 40:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 41:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 42:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 43:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 44:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 45:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 46:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 47:
- jam();
- terrorCode = apiConnectptr.p->returncode;
- releaseAtErrorLab(signal);
- return;
-
- case 48:
- jam();
- terrorCode = ZCOMMIT_TYPE_ERROR;
- releaseAtErrorLab(signal);
- return;
-
- case 49:
- jam();
- abortErrorLab(signal);
- return;
-
- case 50:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
-
- case 51:
- jam();
- abortErrorLab(signal);
- return;
-
- case 52:
- jam();
- abortErrorLab(signal);
- return;
-
- case 53:
- jam();
- abortErrorLab(signal);
- return;
-
- case 54:
- jam();
- abortErrorLab(signal);
- return;
-
- case 55:
- jam();
- printState(signal, 5);
- sendSignalErrorRefuseLab(signal);
- return;
-
- case 56:{
- jam();
- terrorCode = ZNO_FREE_TC_MARKER;
- abortErrorLab(signal);
- return;
- }
- case 57:{
- jam();
- /**
- * Initialize object before starting error handling
- */
- initApiConnectRec(signal, apiConnectptr.p, true);
-start_failure:
- switch(getNodeState().startLevel){
- case NodeState::SL_STOPPING_2:
- if (getNodeState().getSingleUserMode())
- {
- terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- break;
- }
- case NodeState::SL_STOPPING_3:
- case NodeState::SL_STOPPING_4:
- if(getNodeState().stopping.systemShutdown)
- terrorCode = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
- else
- terrorCode = ZNODE_SHUTDOWN_IN_PROGRESS;
- break;
- case NodeState::SL_SINGLEUSER:
- terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- break;
- case NodeState::SL_STOPPING_1:
- if (getNodeState().getSingleUserMode())
- {
- terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- break;
- }
- default:
- terrorCode = ZWRONG_STATE;
- break;
- }
- abortErrorLab(signal);
- return;
- }
-
- case 58:{
- jam();
- releaseAtErrorLab(signal);
- return;
- }
-
- case 59:{
- jam();
- terrorCode = ZABORTINPROGRESS;
- abortErrorLab(signal);
- return;
- }
-
- case 60:
- {
- jam();
- initApiConnectRec(signal, apiConnectptr.p, true);
- apiConnectptr.p->m_exec_flag = 1;
- goto start_failure;
- }
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}
-
-static
-inline
-bool
-compare_transid(Uint32* val0, Uint32* val1)
-{
- Uint32 tmp0 = val0[0] ^ val1[0];
- Uint32 tmp1 = val0[1] ^ val1[1];
- return (tmp0 | tmp1) == 0;
-}
-
-void Dbtc::execKEYINFO(Signal* signal)
-{
- jamEntry();
- apiConnectptr.i = signal->theData[0];
- tmaxData = 20;
- if (apiConnectptr.i >= capiConnectFilesize) {
- TCKEY_abort(signal, 18);
- return;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- ttransid_ptr = 1;
- if (compare_transid(apiConnectptr.p->transid, signal->theData+1) == false)
- {
- TCKEY_abort(signal, 19);
- return;
- }//if
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_RECEIVING:
- case CS_REC_COMMITTING:
- case CS_START_SCAN:
- jam();
- /*empty*/;
- break;
- /* OK */
- case CS_ABORTING:
- jam();
- return; /* IGNORE */
- case CS_CONNECTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. */
- /****************************************************************>*/
- printState(signal, 11);
- signalErrorRefuseLab(signal);
- return;
- case CS_STARTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED */
- /* WE ALSO NEED TO ABORT THIS TRANSACTION. */
- /****************************************************************>*/
- terrorCode = ZSIGNAL_ERROR;
- printState(signal, 2);
- abortErrorLab(signal);
- return;
- default:
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//switch
-
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = apiConnectptr.p->cachePtr;
- UintR TtcTimer = ctcTimer;
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- if (TcachePtr >= TcacheFilesize) {
- TCKEY_abort(signal, 42);
- return;
- }//if
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- cachePtr.i = TcachePtr;
- cachePtr.p = regCachePtr;
-
- tcConnectptr.i = apiConnectptr.p->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_WAIT_KEYINFO:
- jam();
- tckeyreq020Lab(signal);
- return;
- case OS_WAIT_SCAN:
- break;
- default:
- jam();
- terrorCode = ZSTATE_ERROR;
- abortErrorLab(signal);
- return;
- }//switch
-
- UintR TdataPos = 0;
- UintR TkeyLen = regCachePtr->keylen;
- UintR Tlen = regCachePtr->save1;
-
- do {
- if (cfirstfreeDatabuf == RNIL) {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- linkKeybuf(signal);
- arrGuard(TdataPos, 19);
- databufptr.p->data[0] = signal->theData[TdataPos + 3];
- databufptr.p->data[1] = signal->theData[TdataPos + 4];
- databufptr.p->data[2] = signal->theData[TdataPos + 5];
- databufptr.p->data[3] = signal->theData[TdataPos + 6];
- Tlen = Tlen + 4;
- TdataPos = TdataPos + 4;
- if (Tlen < TkeyLen) {
- jam();
- if (TdataPos >= tmaxData) {
- jam();
- /*----------------------------------------------------*/
- /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/
- /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/
- /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/
- /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/
- /*----------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = Tlen;
- return;
- }//if
- } else {
- jam();
- return;
- }//if
- } while (1);
- return;
-}//Dbtc::execKEYINFO()
-
-/*---------------------------------------------------------------------------*/
-/* */
-/* MORE THAN FOUR WORDS OF KEY DATA. WE NEED TO PACK THIS IN KEYINFO SIGNALS.*/
-/* WE WILL ALWAYS PACK 4 WORDS AT A TIME. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::packKeyData000Lab(Signal* signal,
- BlockReference TBRef,
- Uint32 totalLen)
-{
- CacheRecord * const regCachePtr = cachePtr.p;
-
- jam();
- Uint32 len = 0;
- databufptr.i = regCachePtr->firstKeybuf;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- Uint32 * dst = signal->theData+3;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
-
- do {
- jam();
- databufptr.i = databufptr.p->nextDatabuf;
- dst[len + 0] = databufptr.p->data[0];
- dst[len + 1] = databufptr.p->data[1];
- dst[len + 2] = databufptr.p->data[2];
- dst[len + 3] = databufptr.p->data[3];
- len += 4;
- if (totalLen <= 4) {
- jam();
- /*---------------------------------------------------------------------*/
- /* LAST PACK OF KEY DATA HAVE BEEN SENT */
- /*---------------------------------------------------------------------*/
- /* THERE WERE UNSENT INFORMATION, SEND IT. */
- /*---------------------------------------------------------------------*/
- sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB);
- return;
- } else if(len == KeyInfo::DataLength){
- jam();
- len = 0;
- sendSignal(TBRef, GSN_KEYINFO, signal, 3 + KeyInfo::DataLength, JBB);
- }
- totalLen -= 4;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
- } while (1);
-}//Dbtc::packKeyData000Lab()
-
-void Dbtc::tckeyreq020Lab(Signal* signal)
-{
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR TdataPos = 0;
- UintR TkeyLen = regCachePtr->keylen;
- UintR Tlen = regCachePtr->save1;
-
- do {
- if (cfirstfreeDatabuf == RNIL) {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- linkKeybuf(signal);
- arrGuard(TdataPos, 19);
- databufptr.p->data[0] = signal->theData[TdataPos + 3];
- databufptr.p->data[1] = signal->theData[TdataPos + 4];
- databufptr.p->data[2] = signal->theData[TdataPos + 5];
- databufptr.p->data[3] = signal->theData[TdataPos + 6];
- Tlen = Tlen + 4;
- TdataPos = TdataPos + 4;
- if (Tlen < TkeyLen) {
- jam();
- if (TdataPos >= tmaxData) {
- jam();
- /*----------------------------------------------------*/
- /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/
- /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/
- /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/
- /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/
- /*----------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = Tlen;
- tcConnectptr.p->tcConnectstate = OS_WAIT_KEYINFO;
- return;
- }//if
- } else {
- jam();
- tckeyreq050Lab(signal);
- return;
- }//if
- } while (1);
- return;
-}//Dbtc::tckeyreq020Lab()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SAVE ATTRIBUTE INFORMATION IN OPERATION RECORD ------- */
-/* ------------------------------------------------------------------------- */
-void Dbtc::saveAttrbuf(Signal* signal)
-{
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
- UintR TattrbufFilesize = cattrbufFilesize;
- UintR TTcfirstAttrbuf = regCachePtr->firstAttrbuf;
- UintR Tlen = signal->length() - 3;
- AttrbufRecord *localAttrbufRecord = attrbufRecord;
-
- AttrbufRecord * const regAttrPtr = &localAttrbufRecord[TfirstfreeAttrbuf];
- if (TfirstfreeAttrbuf >= TattrbufFilesize) {
- TCKEY_abort(signal, 21);
- return;
- }//if
- UintR Tnext = regAttrPtr->attrbuf[ZINBUF_NEXT];
- if (TTcfirstAttrbuf == RNIL) {
- jam();
- regCachePtr->firstAttrbuf = TfirstfreeAttrbuf;
- } else {
- AttrbufRecordPtr saAttrbufptr;
-
- saAttrbufptr.i = regCachePtr->lastAttrbuf;
- jam();
- if (saAttrbufptr.i >= TattrbufFilesize) {
- TCKEY_abort(signal, 22);
- return;
- }//if
- saAttrbufptr.p = &localAttrbufRecord[saAttrbufptr.i];
- saAttrbufptr.p->attrbuf[ZINBUF_NEXT] = TfirstfreeAttrbuf;
- }//if
-
- cfirstfreeAttrbuf = Tnext;
- regAttrPtr->attrbuf[ZINBUF_NEXT] = RNIL;
- regCachePtr->lastAttrbuf = TfirstfreeAttrbuf;
- regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = Tlen;
-
- UintR Tdata1 = signal->theData[3];
- UintR Tdata2 = signal->theData[4];
- UintR Tdata3 = signal->theData[5];
- UintR Tdata4 = signal->theData[6];
- UintR Tdata5 = signal->theData[7];
- UintR Tdata6 = signal->theData[8];
- UintR Tdata7 = signal->theData[9];
- UintR Tdata8 = signal->theData[10];
-
- regAttrPtr->attrbuf[0] = Tdata1;
- regAttrPtr->attrbuf[1] = Tdata2;
- regAttrPtr->attrbuf[2] = Tdata3;
- regAttrPtr->attrbuf[3] = Tdata4;
- regAttrPtr->attrbuf[4] = Tdata5;
- regAttrPtr->attrbuf[5] = Tdata6;
- regAttrPtr->attrbuf[6] = Tdata7;
- regAttrPtr->attrbuf[7] = Tdata8;
-
- if (Tlen > 8) {
-
- Tdata1 = signal->theData[11];
- Tdata2 = signal->theData[12];
- Tdata3 = signal->theData[13];
- Tdata4 = signal->theData[14];
- Tdata5 = signal->theData[15];
- Tdata6 = signal->theData[16];
- Tdata7 = signal->theData[17];
-
- regAttrPtr->attrbuf[8] = Tdata1;
- regAttrPtr->attrbuf[9] = Tdata2;
- regAttrPtr->attrbuf[10] = Tdata3;
- regAttrPtr->attrbuf[11] = Tdata4;
- regAttrPtr->attrbuf[12] = Tdata5;
- regAttrPtr->attrbuf[13] = Tdata6;
- regAttrPtr->attrbuf[14] = Tdata7;
- jam();
- if (Tlen > 15) {
-
- Tdata1 = signal->theData[18];
- Tdata2 = signal->theData[19];
- Tdata3 = signal->theData[20];
- Tdata4 = signal->theData[21];
- Tdata5 = signal->theData[22];
- Tdata6 = signal->theData[23];
- Tdata7 = signal->theData[24];
-
- jam();
- regAttrPtr->attrbuf[15] = Tdata1;
- regAttrPtr->attrbuf[16] = Tdata2;
- regAttrPtr->attrbuf[17] = Tdata3;
- regAttrPtr->attrbuf[18] = Tdata4;
- regAttrPtr->attrbuf[19] = Tdata5;
- regAttrPtr->attrbuf[20] = Tdata6;
- regAttrPtr->attrbuf[21] = Tdata7;
- }//if
- }//if
-}//Dbtc::saveAttrbuf()
-
-void Dbtc::execATTRINFO(Signal* signal)
-{
- UintR Tdata1 = signal->theData[0];
- UintR Tlength = signal->length();
- UintR TapiConnectFilesize = capiConnectFilesize;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- jamEntry();
- apiConnectptr.i = Tdata1;
- ttransid_ptr = 1;
- if (Tdata1 >= TapiConnectFilesize) {
- DEBUG("Drop ATTRINFO, wrong apiConnectptr");
- TCKEY_abort(signal, 18);
- return;
- }//if
-
- ApiConnectRecord * const regApiPtr = &localApiConnectRecord[Tdata1];
- apiConnectptr.p = regApiPtr;
-
- if (compare_transid(regApiPtr->transid, signal->theData+1) == false)
- {
- DEBUG("Drop ATTRINFO, wrong transid, lenght="<<Tlength
- << " transid("<<hex<<signal->theData[1]<<", "<<signal->theData[2]);
- TCKEY_abort(signal, 19);
- return;
- }//if
- if (Tlength < 4) {
- DEBUG("Drop ATTRINFO, wrong length = " << Tlength);
- TCKEY_abort(signal, 20);
- return;
- }
- Tlength -= 3;
- UintR TcompREC_COMMIT = (regApiPtr->apiConnectstate == CS_REC_COMMITTING);
- UintR TcompRECEIVING = (regApiPtr->apiConnectstate == CS_RECEIVING);
- UintR TcompBOTH = TcompREC_COMMIT | TcompRECEIVING;
-
- if (TcompBOTH) {
- jam();
- if (ERROR_INSERTED(8015)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- if (ERROR_INSERTED(8016)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = regApiPtr->cachePtr;
- UintR TtcTimer = ctcTimer;
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- if (TcachePtr >= TcacheFilesize) {
- TCKEY_abort(signal, 43);
- return;
- }//if
- UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
- UintR TcurrReclenAi = regCachePtr->currReclenAi;
- UintR TattrLen = regCachePtr->attrlength;
-
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- cachePtr.i = TcachePtr;
- cachePtr.p = regCachePtr;
- TcurrReclenAi = TcurrReclenAi + Tlength;
- regCachePtr->currReclenAi = TcurrReclenAi;
- int TattrlengthRemain = TattrLen - TcurrReclenAi;
-
- if (TfirstfreeAttrbuf == RNIL) {
- DEBUG("No more attrinfo buffers");
- TCKEY_abort(signal, 24);
- return;
- }//if
- saveAttrbuf(signal);
- if (TattrlengthRemain == 0) {
- /****************************************************************>*/
- /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS */
- /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
- /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
- /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER */
- /* OPERATIONS. */
- /****************************************************************>*/
- UintR TlastConnect = regApiPtr->lastTcConnect;
- if (TcompRECEIVING) {
- jam();
- regApiPtr->apiConnectstate = CS_STARTED;
- } else {
- jam();
- regApiPtr->apiConnectstate = CS_START_COMMITTING;
- }//if
- tcConnectptr.i = TlastConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- attrinfoDihReceivedLab(signal);
- } else if (TattrlengthRemain < 0) {
- jam();
- DEBUG("ATTRINFO wrong total length="<<Tlength
- <<", TattrlengthRemain="<<TattrlengthRemain
- <<", TattrLen="<<TattrLen
- <<", TcurrReclenAi="<<TcurrReclenAi);
- tcConnectptr.i = regApiPtr->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- aiErrorLab(signal);
- }//if
- return;
- } else if (regApiPtr->apiConnectstate == CS_START_SCAN) {
- jam();
- scanAttrinfoLab(signal, Tlength);
- return;
- } else {
- switch (regApiPtr->apiConnectstate) {
- case CS_ABORTING:
- jam();
- /* JUST IGNORE THE SIGNAL*/
- // DEBUG("Drop ATTRINFO, CS_ABORTING");
- return;
- case CS_CONNECTED:
- jam();
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL.*/
- // DEBUG("Drop ATTRINFO, CS_CONNECTED");
- return;
- case CS_STARTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED */
- /* WE ALSO NEED TO ABORT THIS TRANSACTION. */
- /****************************************************************>*/
- terrorCode = ZSIGNAL_ERROR;
- printState(signal, 1);
- abortErrorLab(signal);
- return;
- default:
- jam();
- /****************************************************************>*/
- /* SIGNAL RECEIVED IN AN UNEXPECTED STATE. WE IGNORE SIGNAL */
- /* SINCE WE DO NOT REALLY KNOW WHERE THE ERROR OCCURRED. */
- /****************************************************************>*/
- DEBUG("Drop ATTRINFO, illegal state="<<regApiPtr->apiConnectstate);
- printState(signal, 9);
- return;
- }//switch
- }//if
-}//Dbtc::execATTRINFO()
-
-/* *********************************************************************>> */
-/* */
-/* MODULE: HASH MODULE */
-/* DESCRIPTION: CONTAINS THE HASH VALUE CALCULATION */
-/* *********************************************************************> */
-void Dbtc::hash(Signal* signal)
-{
- DatabufRecordPtr locDatabufptr;
- UintR ti;
- UintR Tdata0;
- UintR Tdata1;
- UintR Tdata2;
- UintR Tdata3;
- UintR* Tdata32;
-
- CacheRecord * const regCachePtr = cachePtr.p;
- Tdata32 = signal->theData;
-
- Tdata0 = regCachePtr->keydata[0];
- Tdata1 = regCachePtr->keydata[1];
- Tdata2 = regCachePtr->keydata[2];
- Tdata3 = regCachePtr->keydata[3];
- Tdata32[0] = Tdata0;
- Tdata32[1] = Tdata1;
- Tdata32[2] = Tdata2;
- Tdata32[3] = Tdata3;
- if (regCachePtr->keylen > 4) {
- locDatabufptr.i = regCachePtr->firstKeybuf;
- ti = 4;
- while (locDatabufptr.i != RNIL) {
- ptrCheckGuard(locDatabufptr, cdatabufFilesize, databufRecord);
- Tdata0 = locDatabufptr.p->data[0];
- Tdata1 = locDatabufptr.p->data[1];
- Tdata2 = locDatabufptr.p->data[2];
- Tdata3 = locDatabufptr.p->data[3];
- Tdata32[ti ] = Tdata0;
- Tdata32[ti + 1] = Tdata1;
- Tdata32[ti + 2] = Tdata2;
- Tdata32[ti + 3] = Tdata3;
- locDatabufptr.i = locDatabufptr.p->nextDatabuf;
- ti += 4;
- }//while
- }//if
-
- UintR keylen = (UintR)regCachePtr->keylen;
- Uint32 distKey = regCachePtr->distributionKeyIndicator;
-
- Uint32 tmp[4];
- if(!regCachePtr->m_special_hash)
- {
- md5_hash(tmp, (Uint64*)&Tdata32[0], keylen);
- }
- else
- {
- handle_special_hash(tmp, Tdata32, keylen, regCachePtr->tableref, !distKey);
- }
-
- thashValue = tmp[0];
- if (distKey){
- jam();
- tdistrHashValue = regCachePtr->distributionKey;
- } else {
- jam();
- tdistrHashValue = tmp[1];
- }//if
-}//Dbtc::hash()
-
-bool
-Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen,
- Uint32 tabPtrI,
- bool distr)
-{
- Uint64 Tmp[MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
- const TableRecord* tabPtrP = &tableRecord[tabPtrI];
- const bool hasVarKeys = tabPtrP->hasVarKeys;
- const bool hasCharAttr = tabPtrP->hasCharAttr;
- const bool compute_distkey = distr && (tabPtrP->noOfDistrKeys > 0);
-
- Uint32 *dst = (Uint32*)Tmp;
- Uint32 dstPos = 0;
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
- Uint32 * keyPartLenPtr;
- if(hasCharAttr || (compute_distkey && hasVarKeys))
- {
- keyPartLenPtr = keyPartLen;
- dstPos = xfrm_key(tabPtrI, src, dst, sizeof(Tmp) >> 2, keyPartLenPtr);
- if (unlikely(dstPos == 0))
- {
- goto error;
- }
- }
- else
- {
- dst = src;
- dstPos = srcLen;
- keyPartLenPtr = 0;
- }
-
- md5_hash(dstHash, (Uint64*)dst, dstPos);
-
- if(compute_distkey)
- {
- jam();
-
- Uint32 tmp[4];
- Uint32 len = create_distr_key(tabPtrI, dst, keyPartLenPtr);
- md5_hash(tmp, (Uint64*)dst, len);
- dstHash[1] = tmp[1];
- }
- return true; // success
-
-error:
- terrorCode = ZINVALID_KEY;
- return false;
-}
-
-/*
-INIT_API_CONNECT_REC
----------------------------
-*/
-/* ========================================================================= */
-/* ======= INIT_API_CONNECT_REC ======= */
-/* */
-/* ========================================================================= */
-void Dbtc::initApiConnectRec(Signal* signal,
- ApiConnectRecord * const regApiPtr,
- bool releaseIndexOperations)
-{
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
- UintR TfailureNr = cfailure_nr;
- UintR TtransCount = c_counters.ctransCount;
- UintR Ttransid0 = tcKeyReq->transId1;
- UintR Ttransid1 = tcKeyReq->transId2;
-
- regApiPtr->m_exec_flag = 0;
- regApiPtr->returncode = 0;
- regApiPtr->returnsignal = RS_TCKEYCONF;
- ndbassert(regApiPtr->firstTcConnect == RNIL);
- regApiPtr->firstTcConnect = RNIL;
- regApiPtr->lastTcConnect = RNIL;
- regApiPtr->globalcheckpointid = 0;
- regApiPtr->lqhkeyconfrec = 0;
- regApiPtr->lqhkeyreqrec = 0;
- regApiPtr->tckeyrec = 0;
- regApiPtr->tcindxrec = 0;
- regApiPtr->failureNr = TfailureNr;
- regApiPtr->transid[0] = Ttransid0;
- regApiPtr->transid[1] = Ttransid1;
- regApiPtr->commitAckMarker = RNIL;
- regApiPtr->buddyPtr = RNIL;
- regApiPtr->currSavePointId = 0;
- regApiPtr->m_transaction_nodes.clear();
- regApiPtr->singleUserMode = 0;
- // Trigger data
- releaseFiredTriggerData(&regApiPtr->theFiredTriggers),
- // Index data
- regApiPtr->indexOpReturn = false;
- regApiPtr->noIndexOp = 0;
- if(releaseIndexOperations)
- releaseAllSeizedIndexOperations(regApiPtr);
-
- c_counters.ctransCount = TtransCount + 1;
-}//Dbtc::initApiConnectRec()
-
-int
-Dbtc::seizeTcRecord(Signal* signal)
-{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- UintR TfirstfreeTcConnect = cfirstfreeTcConnect;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- tcConnectptr.i = TfirstfreeTcConnect;
- if (TfirstfreeTcConnect >= TtcConnectFilesize) {
- int place = 3;
- if (TfirstfreeTcConnect != RNIL) {
- place = 10;
- }//if
- TCKEY_abort(signal, place);
- return 1;
- }//if
- //--------------------------------------------------------------------------
- // Optimised version of ptrAss(tcConnectptr, tcConnectRecord)
- //--------------------------------------------------------------------------
- TcConnectRecord * const regTcPtr =
- &localTcConnectRecord[TfirstfreeTcConnect];
-
- UintR TconcurrentOp = c_counters.cconcurrentOp;
- UintR TlastTcConnect = regApiPtr->lastTcConnect;
- UintR TtcConnectptrIndex = tcConnectptr.i;
- TcConnectRecordPtr tmpTcConnectptr;
-
- cfirstfreeTcConnect = regTcPtr->nextTcConnect;
- tcConnectptr.p = regTcPtr;
-
- c_counters.cconcurrentOp = TconcurrentOp + 1;
- regTcPtr->prevTcConnect = TlastTcConnect;
- regTcPtr->nextTcConnect = RNIL;
- regTcPtr->accumulatingTriggerData.i = RNIL;
- regTcPtr->accumulatingTriggerData.p = NULL;
- regTcPtr->noFiredTriggers = 0;
- regTcPtr->noReceivedTriggers = 0;
- regTcPtr->triggerExecutionCount = 0;
- regTcPtr->triggeringOperation = RNIL;
- regTcPtr->isIndexOp = false;
- regTcPtr->indexOp = RNIL;
- regTcPtr->currentIndexId = RNIL;
-
- regApiPtr->lastTcConnect = TtcConnectptrIndex;
-
- if (TlastTcConnect == RNIL) {
- jam();
- regApiPtr->firstTcConnect = TtcConnectptrIndex;
- } else {
- tmpTcConnectptr.i = TlastTcConnect;
- jam();
- ptrCheckGuard(tmpTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- tmpTcConnectptr.p->nextTcConnect = TtcConnectptrIndex;
- }//if
- return 0;
-}//Dbtc::seizeTcRecord()
-
-int
-Dbtc::seizeCacheRecord(Signal* signal)
-{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TfirstfreeCacheRec = cfirstfreeCacheRec;
- UintR TcacheFilesize = ccacheFilesize;
- CacheRecord *localCacheRecord = cacheRecord;
- if (TfirstfreeCacheRec >= TcacheFilesize) {
- TCKEY_abort(signal, 41);
- return 1;
- }//if
- CacheRecord * const regCachePtr = &localCacheRecord[TfirstfreeCacheRec];
-
- regApiPtr->cachePtr = TfirstfreeCacheRec;
- cfirstfreeCacheRec = regCachePtr->nextCacheRec;
- cachePtr.i = TfirstfreeCacheRec;
- cachePtr.p = regCachePtr;
-
-#ifdef VM_TRACE
- // This is a good place to check that resources have
- // been properly released from CacheRecord
- ndbrequire(regCachePtr->firstKeybuf == RNIL);
- ndbrequire(regCachePtr->lastKeybuf == RNIL);
-#endif
- regCachePtr->firstKeybuf = RNIL;
- regCachePtr->lastKeybuf = RNIL;
- regCachePtr->firstAttrbuf = RNIL;
- regCachePtr->lastAttrbuf = RNIL;
- regCachePtr->currReclenAi = 0;
- return 0;
-}//Dbtc::seizeCacheRecord()
-
-/*****************************************************************************/
-/* T C K E Y R E Q */
-/* AFTER HAVING ESTABLISHED THE CONNECT, THE APPLICATION BLOCK SENDS AN */
-/* OPERATION REQUEST TO TC. ALL NECESSARY INFORMATION TO CARRY OUT REQUEST */
-/* IS FURNISHED IN PARAMETERS. TC STORES THIS INFORMATION AND ENQUIRES */
-/* FROM DIH ABOUT THE NODES WHICH MAY HAVE THE REQUESTED DATA */
-/*****************************************************************************/
-void Dbtc::execTCKEYREQ(Signal* signal)
-{
- Uint32 sendersNodeId = refToNode(signal->getSendersBlockRef());
- UintR compare_transid1, compare_transid2;
- UintR titcLenAiInTckeyreq;
- UintR TkeyLength;
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtr();
- UintR Treqinfo;
-
- jamEntry();
- /*-------------------------------------------------------------------------
- * Common error routines are used for several signals, they need to know
- * where to find the transaction identifier in the signal.
- *-------------------------------------------------------------------------*/
- const UintR TapiIndex = tcKeyReq->apiConnectPtr;
- const UintR TapiMaxIndex = capiConnectFilesize;
- const UintR TtabIndex = tcKeyReq->tableId;
- const UintR TtabMaxIndex = ctabrecFilesize;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- ttransid_ptr = 6;
- apiConnectptr.i = TapiIndex;
- if (TapiIndex >= TapiMaxIndex) {
- TCKEY_abort(signal, 6);
- return;
- }//if
- if (TtabIndex >= TtabMaxIndex) {
- TCKEY_abort(signal, 7);
- return;
- }//if
-
- Treqinfo = tcKeyReq->requestInfo;
- //--------------------------------------------------------------------------
- // Optimised version of ptrAss(tabptr, tableRecord)
- // Optimised version of ptrAss(apiConnectptr, apiConnectRecord)
- //--------------------------------------------------------------------------
- ApiConnectRecord * const regApiPtr = &localApiConnectRecord[TapiIndex];
- apiConnectptr.p = regApiPtr;
-
- Uint32 TstartFlag = TcKeyReq::getStartFlag(Treqinfo);
- Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
-
- Uint8 isIndexOp = regApiPtr->isIndexOp;
- bool isIndexOpReturn = regApiPtr->indexOpReturn;
- regApiPtr->isIndexOp = false; // Reset marker
- regApiPtr->m_exec_flag |= TexecFlag;
- TableRecordPtr localTabptr;
- localTabptr.i = TtabIndex;
- localTabptr.p = &tableRecord[TtabIndex];
- switch (regApiPtr->apiConnectstate) {
- case CS_CONNECTED:{
- if (TstartFlag == 1 && getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == true){
- //---------------------------------------------------------------------
- // Initialise API connect record if transaction is started.
- //---------------------------------------------------------------------
- jam();
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else {
- if(getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == true){
- /*------------------------------------------------------------------
- * WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN
- * RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO
- * ENSURE PROPER OPERATION OF THE COMMON ABORT HANDLING.
- *-----------------------------------------------------------------*/
- TCKEY_abort(signal, 0);
- return;
- } else {
- /**
- * getAllowStartTransaction(sendersNodeId) == false
- */
- TCKEY_abort(signal, TexecFlag ? 60 : 57);
- return;
- }//if
- }
- }
- break;
- case CS_STARTED:
- if(TstartFlag == 1 && regApiPtr->firstTcConnect == RNIL)
- {
- /**
- * If last operation in last transaction was a simple/dirty read
- * it does not have to be committed or rollbacked hence,
- * the state will be CS_STARTED
- */
- jam();
- if (unlikely(getNodeState().getSingleUserMode()) &&
- getNodeState().getSingleUserApi() != sendersNodeId &&
- !localTabptr.p->singleUserMode)
- {
- TCKEY_abort(signal, TexecFlag ? 60 : 57);
- return;
- }
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else {
- //----------------------------------------------------------------------
- // Transaction is started already.
- // Check that the operation is on the same transaction.
- //-----------------------------------------------------------------------
- compare_transid1 = regApiPtr->transid[0] ^ tcKeyReq->transId1;
- compare_transid2 = regApiPtr->transid[1] ^ tcKeyReq->transId2;
- jam();
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- TCKEY_abort(signal, 1);
- return;
- }//if
- }
- break;
- case CS_ABORTING:
- if (regApiPtr->abortState == AS_IDLE) {
- if (TstartFlag == 1) {
- if(getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == false){
- TCKEY_abort(signal, TexecFlag ? 60 : 57);
- return;
- }
- //--------------------------------------------------------------------
- // Previous transaction had been aborted and the abort was completed.
- // It is then OK to start a new transaction again.
- //--------------------------------------------------------------------
- jam();
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else if(TexecFlag) {
- TCKEY_abort(signal, 59);
- return;
- } else {
- //--------------------------------------------------------------------
- // The current transaction was aborted successfully.
- // We will not do anything before we receive an operation
- // with a start indicator. We will ignore this signal.
- //--------------------------------------------------------------------
- jam();
- DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, ==AS_IDLE");
- return;
- }//if
- } else {
- //----------------------------------------------------------------------
- // Previous transaction is still aborting
- //----------------------------------------------------------------------
- jam();
- if (TstartFlag == 1) {
- //--------------------------------------------------------------------
- // If a new transaction tries to start while the old is
- // still aborting, we will report this to the starting API.
- //--------------------------------------------------------------------
- TCKEY_abort(signal, 2);
- return;
- } else if(TexecFlag) {
- TCKEY_abort(signal, 59);
- return;
- }
- //----------------------------------------------------------------------
- // Ignore signals without start indicator set when aborting transaction.
- //----------------------------------------------------------------------
- DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, !=AS_IDLE");
- return;
- }//if
- break;
- case CS_START_COMMITTING:
- jam();
- if(isIndexOpReturn || TcKeyReq::getExecutingTrigger(Treqinfo)){
- break;
- }
- default:
- jam();
- /*----------------------------------------------------------------------
- * IN THIS CASE THE NDBAPI IS AN UNTRUSTED ENTITY THAT HAS SENT A SIGNAL
- * WHEN IT WAS NOT EXPECTED TO.
- * WE MIGHT BE IN A PROCESS TO RECEIVE, PREPARE,
- * COMMIT OR COMPLETE AND OBVIOUSLY THIS IS NOT A DESIRED EVENT.
- * WE WILL ALWAYS COMPLETE THE ABORT HANDLING BEFORE WE ALLOW
- * ANYTHING TO HAPPEN ON THIS CONNECTION AGAIN.
- * THUS THERE IS NO ACTION FROM THE API THAT CAN SPEED UP THIS PROCESS.
- *---------------------------------------------------------------------*/
- TCKEY_abort(signal, 55);
- return;
- }//switch
-
- if (localTabptr.p->checkTable(tcKeyReq->tableSchemaVersion)) {
- ;
- } else {
- /*-----------------------------------------------------------------------*/
- /* THE API IS WORKING WITH AN OLD SCHEMA VERSION. IT NEEDS REPLACEMENT. */
- /* COULD ALSO BE THAT THE TABLE IS NOT DEFINED. */
- /*-----------------------------------------------------------------------*/
- TCKEY_abort(signal, 8);
- return;
- }//if
-
- //-------------------------------------------------------------------------
- // Error Insertion for testing purposes. Test to see what happens when no
- // more TC records available.
- //-------------------------------------------------------------------------
- if (ERROR_INSERTED(8032)) {
- TCKEY_abort(signal, 3);
- return;
- }//if
-
- if (seizeTcRecord(signal) != 0) {
- return;
- }//if
-
- if (seizeCacheRecord(signal) != 0) {
- return;
- }//if
-
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- CacheRecord * const regCachePtr = cachePtr.p;
-
- /*
- INIT_TC_CONNECT_REC
- -------------------------
- */
- /* ---------------------------------------------------------------------- */
- /* ------- INIT OPERATION RECORD WITH SIGNAL DATA AND RNILS ------- */
- /* */
- /* ---------------------------------------------------------------------- */
-
- UintR TapiVersionNo = TcKeyReq::getAPIVersion(tcKeyReq->attrLen);
- UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec;
- regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec + 1;
- regCachePtr->apiVersionNo = TapiVersionNo;
-
- UintR TapiConnectptrIndex = apiConnectptr.i;
- UintR TsenderData = tcKeyReq->senderData;
- UintR TattrLen = TcKeyReq::getAttrinfoLen(tcKeyReq->attrLen);
- UintR TattrinfoCount = c_counters.cattrinfoCount;
-
- regTcPtr->apiConnect = TapiConnectptrIndex;
- regTcPtr->clientData = TsenderData;
- regTcPtr->commitAckMarker = RNIL;
- regTcPtr->isIndexOp = isIndexOp;
- regTcPtr->indexOp = regApiPtr->executingIndexOp;
- regTcPtr->savePointId = regApiPtr->currSavePointId;
- regApiPtr->executingIndexOp = RNIL;
-
- regApiPtr->singleUserMode |= 1 << localTabptr.p->singleUserMode;
-
- if (TcKeyReq::getExecutingTrigger(Treqinfo)) {
- // Save the TcOperationPtr for fireing operation
- regTcPtr->triggeringOperation = TsenderData;
- }
-
- if (TexecFlag){
- Uint32 currSPId = regApiPtr->currSavePointId;
- regApiPtr->currSavePointId = ++currSPId;
- }
-
- regCachePtr->attrlength = TattrLen;
- c_counters.cattrinfoCount = TattrinfoCount + TattrLen;
-
- UintR TtabptrIndex = localTabptr.i;
- UintR TtableSchemaVersion = tcKeyReq->tableSchemaVersion;
- Uint8 TOperationType = TcKeyReq::getOperationType(Treqinfo);
- regCachePtr->tableref = TtabptrIndex;
- regCachePtr->schemaVersion = TtableSchemaVersion;
- regTcPtr->operation = TOperationType;
-
- Uint8 TSimpleFlag = TcKeyReq::getSimpleFlag(Treqinfo);
- Uint8 TDirtyFlag = TcKeyReq::getDirtyFlag(Treqinfo);
- Uint8 TInterpretedFlag = TcKeyReq::getInterpretedFlag(Treqinfo);
- Uint8 TDistrKeyFlag = TcKeyReq::getDistributionKeyFlag(Treqinfo);
- Uint8 TNoDiskFlag = TcKeyReq::getNoDiskFlag(Treqinfo);
- Uint8 TexecuteFlag = TexecFlag;
-
- regTcPtr->dirtyOp = TDirtyFlag;
- regTcPtr->opSimple = TSimpleFlag;
- regCachePtr->opExec = TInterpretedFlag;
- regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
- regCachePtr->m_no_disk_flag = TNoDiskFlag;
-
- //-------------------------------------------------------------
- // The next step is to read the upto three conditional words.
- //-------------------------------------------------------------
- Uint32 TkeyIndex;
- Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
- {
- Uint32 TDistrGHIndex = TcKeyReq::getScanIndFlag(Treqinfo);
- Uint32 TDistrKeyIndex = TDistrGHIndex;
-
- Uint32 TscanInfo = TcKeyReq::getTakeOverScanInfo(TOptionalDataPtr[0]);
-
- regCachePtr->scanTakeOverInd = TDistrGHIndex;
- regCachePtr->scanInfo = TscanInfo;
-
- regCachePtr->distributionKey = TOptionalDataPtr[TDistrKeyIndex];
-
- TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
- }
- Uint32* TkeyDataPtr = &TOptionalDataPtr[TkeyIndex];
-
- UintR Tdata1 = TkeyDataPtr[0];
- UintR Tdata2 = TkeyDataPtr[1];
- UintR Tdata3 = TkeyDataPtr[2];
- UintR Tdata4 = TkeyDataPtr[3];
- UintR Tdata5;
-
- regCachePtr->keydata[0] = Tdata1;
- regCachePtr->keydata[1] = Tdata2;
- regCachePtr->keydata[2] = Tdata3;
- regCachePtr->keydata[3] = Tdata4;
-
- TkeyLength = TcKeyReq::getKeyLength(Treqinfo);
- Uint32 TAIDataIndex;
- if (TkeyLength > 8) {
- TAIDataIndex = TkeyIndex + 8;
- } else {
- if (TkeyLength == 0) {
- TCKEY_abort(signal, 4);
- return;
- }//if
- TAIDataIndex = TkeyIndex + TkeyLength;
- }//if
- Uint32* TAIDataPtr = &TOptionalDataPtr[TAIDataIndex];
-
- titcLenAiInTckeyreq = TcKeyReq::getAIInTcKeyReq(Treqinfo);
- regCachePtr->keylen = TkeyLength;
- regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq;
- regCachePtr->currReclenAi = titcLenAiInTckeyreq;
- regCachePtr->m_special_hash =
- localTabptr.p->hasCharAttr | (localTabptr.p->noOfDistrKeys > 0);
- Tdata1 = TAIDataPtr[0];
- Tdata2 = TAIDataPtr[1];
- Tdata3 = TAIDataPtr[2];
- Tdata4 = TAIDataPtr[3];
- Tdata5 = TAIDataPtr[4];
-
- regCachePtr->attrinfo0 = Tdata1;
- regCachePtr->attrinfo15[0] = Tdata2;
- regCachePtr->attrinfo15[1] = Tdata3;
- regCachePtr->attrinfo15[2] = Tdata4;
- regCachePtr->attrinfo15[3] = Tdata5;
-
- if (TOperationType == ZREAD || TOperationType == ZREAD_EX) {
- Uint32 TreadCount = c_counters.creadCount;
- jam();
- c_counters.creadCount = TreadCount + 1;
- } else {
- if(regApiPtr->commitAckMarker == RNIL){
- jam();
- CommitAckMarkerPtr tmp;
- if(!m_commitAckMarkerHash.seize(tmp)){
- TCKEY_abort(signal, 56);
- return;
- } else {
- regTcPtr->commitAckMarker = tmp.i;
- regApiPtr->commitAckMarker = tmp.i;
- tmp.p->transid1 = tcKeyReq->transId1;
- tmp.p->transid2 = tcKeyReq->transId2;
- tmp.p->apiNodeId = refToNode(regApiPtr->ndbapiBlockref);
- tmp.p->apiConnectPtr = TapiIndex;
- tmp.p->noOfLqhs = 0;
-#if defined VM_TRACE || defined ERROR_INSERT
- {
- CommitAckMarkerPtr check;
- ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
- }
-#endif
- m_commitAckMarkerHash.add(tmp);
- }
- }
-
- UintR TwriteCount = c_counters.cwriteCount;
- UintR Toperationsize = coperationsize;
- /* --------------------------------------------------------------------
- * THIS IS A TEMPORARY TABLE, DON'T UPDATE coperationsize.
- * THIS VARIABLE CONTROLS THE INTERVAL BETWEEN LCP'S AND
- * TEMP TABLES DON'T PARTICIPATE.
- * -------------------------------------------------------------------- */
- if (localTabptr.p->get_storedTable()) {
- coperationsize = ((Toperationsize + TattrLen) + TkeyLength) + 17;
- }
- c_counters.cwriteCount = TwriteCount + 1;
- switch (TOperationType) {
- case ZUPDATE:
- case ZINSERT:
- case ZDELETE:
- case ZWRITE:
- jam();
- break;
- default:
- TCKEY_abort(signal, 9);
- return;
- }//switch
- }//if
-
- Uint32 TabortOption = TcKeyReq::getAbortOption(Treqinfo);
- regTcPtr->m_execAbortOption = TabortOption;
-
- /*-------------------------------------------------------------------------
- * Check error handling per operation
- * If CommitFlag is set state accordingly and check for early abort
- *------------------------------------------------------------------------*/
- if (TcKeyReq::getCommitFlag(Treqinfo) == 1) {
- ndbrequire(TexecuteFlag);
- regApiPtr->apiConnectstate = CS_REC_COMMITTING;
- } else {
- /* ---------------------------------------------------------------------
- * PREPARE TRANSACTION IS NOT IMPLEMENTED YET.
- * ---------------------------------------------------------------------
- * ELSIF (TREQINFO => 3) (*) 1 = 1 THEN
- * IF PREPARE TRANSACTION THEN
- * API_CONNECTPTR:API_CONNECTSTATE = REC_PREPARING
- * SET STATE TO PREPARING
- * --------------------------------------------------------------------- */
- if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
- jam();
- // Trigger execution at commit
- regApiPtr->apiConnectstate = CS_REC_COMMITTING;
- } else {
- jam();
- regApiPtr->apiConnectstate = CS_RECEIVING;
- }//if
- }//if
- if (TkeyLength <= 4) {
- tckeyreq050Lab(signal);
- return;
- } else {
- if (cfirstfreeDatabuf != RNIL) {
- jam();
- linkKeybuf(signal);
- Tdata1 = TkeyDataPtr[4];
- Tdata2 = TkeyDataPtr[5];
- Tdata3 = TkeyDataPtr[6];
- Tdata4 = TkeyDataPtr[7];
-
- DatabufRecord * const regDataPtr = databufptr.p;
- regDataPtr->data[0] = Tdata1;
- regDataPtr->data[1] = Tdata2;
- regDataPtr->data[2] = Tdata3;
- regDataPtr->data[3] = Tdata4;
- } else {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- if (TkeyLength <= 8) {
- jam();
- tckeyreq050Lab(signal);
- return;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * THE TCKEYREQ DIDN'T CONTAIN ALL KEY DATA,
- * SAVE STATE AND WAIT FOR KEYINFO
- * --------------------------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = 8;
- regTcPtr->tcConnectstate = OS_WAIT_KEYINFO;
- return;
- }//if
- }//if
- return;
-}//Dbtc::execTCKEYREQ()
-
-void Dbtc::tckeyreq050Lab(Signal* signal)
-{
- UintR tnoOfBackup;
- UintR tnoOfStandby;
- UintR tnodeinfo;
-
- terrorCode = 0;
-
- hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
-
- if (unlikely(terrorCode))
- {
- releaseAtErrorLab(signal);
- return;
- }
-
- CacheRecord * const regCachePtr = cachePtr.p;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-
- UintR TtcTimer = ctcTimer;
- UintR ThashValue = thashValue;
- UintR TdistrHashValue = tdistrHashValue;
- UintR TdihConnectptr = regTcPtr->dihConnectptr;
- UintR Ttableref = regCachePtr->tableref;
-
- TableRecordPtr localTabptr;
- localTabptr.i = Ttableref;
- localTabptr.p = &tableRecord[localTabptr.i];
- Uint32 schemaVersion = regCachePtr->schemaVersion;
- if(localTabptr.p->checkTable(schemaVersion)){
- ;
- } else {
- terrorCode = localTabptr.p->getErrorCode(schemaVersion);
- TCKEY_abort(signal, 58);
- return;
- }
-
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- regCachePtr->hashValue = ThashValue;
-
- signal->theData[0] = TdihConnectptr;
- signal->theData[1] = Ttableref;
- signal->theData[2] = TdistrHashValue;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- signal->theData[5] = 0;
- signal->theData[6] = 0;
-
- /*-------------------------------------------------------------*/
- /* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
- /* PROCEED IMMEDIATELY TO DIH. IN MULTI-THREADED VERSIONS WE */
- /* HAVE TO INSERT A MUTEX ON DIH TO ENSURE PROPER OPERATION. */
- /* SINCE THIS SIGNAL AND DIVERIFYREQ ARE THE ONLY SIGNALS SENT */
- /* TO DIH IN TRAFFIC IT SHOULD BE OK (3% OF THE EXECUTION TIME */
- /* IS SPENT IN DIH AND EVEN LESS IN REPLICATED NDB. */
- /*-------------------------------------------------------------*/
- EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
- UintR TerrorIndicator = signal->theData[0];
- jamEntry();
- if (TerrorIndicator != 0) {
- execDIGETNODESREF(signal);
- return;
- }
-
- if(ERROR_INSERTED(8050) && signal->theData[3] != getOwnNodeId())
- {
- ndbassert(false);
- signal->theData[1] = 626;
- execDIGETNODESREF(signal);
- return;
- }
-
- /****************>>*/
- /* DIGETNODESCONF >*/
- /* ***************>*/
-
- UintR Tdata1 = signal->theData[1];
- UintR Tdata2 = signal->theData[2];
- UintR Tdata3 = signal->theData[3];
- UintR Tdata4 = signal->theData[4];
- UintR Tdata5 = signal->theData[5];
- UintR Tdata6 = signal->theData[6];
-
- regCachePtr->fragmentid = Tdata1;
- tnodeinfo = Tdata2;
-
- regTcPtr->tcNodedata[0] = Tdata3;
- regTcPtr->tcNodedata[1] = Tdata4;
- regTcPtr->tcNodedata[2] = Tdata5;
- regTcPtr->tcNodedata[3] = Tdata6;
-
- Uint8 Toperation = regTcPtr->operation;
- Uint8 Tdirty = regTcPtr->dirtyOp;
- tnoOfBackup = tnodeinfo & 3;
- tnoOfStandby = (tnodeinfo >> 8) & 3;
-
- regCachePtr->fragmentDistributionKey = (tnodeinfo >> 16) & 255;
- if (Toperation == ZREAD || Toperation == ZREAD_EX) {
- if (Tdirty == 1) {
- jam();
- /*-------------------------------------------------------------*/
- /* A SIMPLE READ CAN SELECT ANY OF THE PRIMARY AND */
- /* BACKUP NODES TO READ. WE WILL TRY TO SELECT THIS */
- /* NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION */
- /* WITH SIMPLE READS. */
- /*-------------------------------------------------------------*/
- arrGuard(tnoOfBackup, MAX_REPLICAS);
- UintR Tindex;
- UintR TownNode = cownNodeid;
- for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) {
- UintR Tnode = regTcPtr->tcNodedata[Tindex];
- jam();
- if (Tnode == TownNode) {
- jam();
- regTcPtr->tcNodedata[0] = Tnode;
- }//if
- }//for
- if(ERROR_INSERTED(8048) || ERROR_INSERTED(8049))
- {
- for (Tindex = 0; Tindex <= tnoOfBackup; Tindex++)
- {
- UintR Tnode = regTcPtr->tcNodedata[Tindex];
- jam();
- if (Tnode != TownNode) {
- jam();
- regTcPtr->tcNodedata[0] = Tnode;
- ndbout_c("Choosing %d", Tnode);
- }//if
- }//for
- }
- }//if
- jam();
- regTcPtr->lastReplicaNo = 0;
- regTcPtr->noOfNodes = 1;
- } else {
- UintR TlastReplicaNo;
- jam();
- TlastReplicaNo = tnoOfBackup + tnoOfStandby;
- regTcPtr->lastReplicaNo = (Uint8)TlastReplicaNo;
- regTcPtr->noOfNodes = (Uint8)(TlastReplicaNo + 1);
- }//if
- if (regCachePtr->lenAiInTckeyreq == regCachePtr->attrlength) {
- /****************************************************************>*/
- /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS */
- /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
- /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
- /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER */
- /* OPERATIONS. WE KNOW THAT WE WILL WAIT FOR DICT NEXT. IT IS NOT */
- /* POSSIBLE FOR THE TC CONNECTION TO BE READY YET. */
- /****************************************************************>*/
- switch (regApiPtr->apiConnectstate) {
- case CS_RECEIVING:
- jam();
- regApiPtr->apiConnectstate = CS_STARTED;
- break;
- case CS_REC_COMMITTING:
- jam();
- regApiPtr->apiConnectstate = CS_START_COMMITTING;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
- attrinfoDihReceivedLab(signal);
- return;
- } else {
- if (regCachePtr->lenAiInTckeyreq < regCachePtr->attrlength) {
- TtcTimer = ctcTimer;
- jam();
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- regTcPtr->tcConnectstate = OS_WAIT_ATTR;
- return;
- } else {
- TCKEY_abort(signal, 11);
- return;
- }//if
- }//if
- return;
-}//Dbtc::tckeyreq050Lab()
-
-void Dbtc::attrinfoDihReceivedLab(Signal* signal)
-{
- CacheRecord * const regCachePtr = cachePtr.p;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- Uint16 Tnode = regTcPtr->tcNodedata[0];
-
- TableRecordPtr localTabptr;
- localTabptr.i = regCachePtr->tableref;
- localTabptr.p = &tableRecord[localTabptr.i];
-
- if(localTabptr.p->checkTable(regCachePtr->schemaVersion)){
- ;
- } else {
- terrorCode = localTabptr.p->getErrorCode(regCachePtr->schemaVersion);
- TCKEY_abort(signal, 58);
- return;
- }
- arrGuard(Tnode, MAX_NDB_NODES);
- packLqhkeyreq(signal, calcLqhBlockRef(Tnode));
-}//Dbtc::attrinfoDihReceivedLab()
-
-void Dbtc::packLqhkeyreq(Signal* signal,
- BlockReference TBRef)
-{
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR Tkeylen = regCachePtr->keylen;
- UintR TfirstAttrbuf = regCachePtr->firstAttrbuf;
- sendlqhkeyreq(signal, TBRef);
- if (Tkeylen > 4) {
- packKeyData000Lab(signal, TBRef, Tkeylen - 4);
- releaseKeys();
- }//if
- packLqhkeyreq040Lab(signal,
- TfirstAttrbuf,
- TBRef);
-}//Dbtc::packLqhkeyreq()
-
-void Dbtc::sendlqhkeyreq(Signal* signal,
- BlockReference TBRef)
-{
- UintR tslrAttrLen;
- UintR Tdata10;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- CacheRecord * const regCachePtr = cachePtr.p;
- Uint32 version = getNodeInfo(refToNode(TBRef)).m_version;
- UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(8002)) {
- systemErrorLab(signal, __LINE__);
- }//if
- if (ERROR_INSERTED(8007)) {
- if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8008)) {
- if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8009)) {
- if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8010)) {
- if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
- return;
- }//if
- }//if
-#endif
-
- tslrAttrLen = 0;
- LqhKeyReq::setAttrLen(tslrAttrLen, regCachePtr->attrlength);
- /* ---------------------------------------------------------------------- */
- // Bit16 == 0 since StoredProcedures are not yet supported.
- /* ---------------------------------------------------------------------- */
- LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->fragmentDistributionKey);
- LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
-
- Tdata10 = 0;
- sig0 = regTcPtr->opSimple;
- sig1 = regTcPtr->operation;
- sig2 = regTcPtr->dirtyOp;
- bool dirtyRead = (sig1 == ZREAD && sig2 == ZTRUE);
- LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
- LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
- if (unlikely(version < NDBD_ROWID_VERSION))
- {
- Uint32 op = regTcPtr->operation;
- Uint32 lock = (Operation_t) op == ZREAD_EX ? ZUPDATE : (Operation_t) op == ZWRITE ? ZINSERT : (Operation_t) op;
- LqhKeyReq::setLockType(Tdata10, lock);
- }
- /* ---------------------------------------------------------------------- */
- // Indicate Application Reference is present in bit 15
- /* ---------------------------------------------------------------------- */
- LqhKeyReq::setApplicationAddressFlag(Tdata10, 1);
- LqhKeyReq::setDirtyFlag(Tdata10, sig2);
- LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
- LqhKeyReq::setSimpleFlag(Tdata10, sig0);
- LqhKeyReq::setOperation(Tdata10, sig1);
- LqhKeyReq::setNoDiskFlag(Tdata10, regCachePtr->m_no_disk_flag);
-
- /* -----------------------------------------------------------------------
- * Sequential Number of first LQH = 0, bit 22-23
- * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
- * IT IS ALSO SENT IN LQHKEYREQ
- * ----------------------------------------------------------------------- */
- LqhKeyReq::setAIInLqhKeyReq(Tdata10, regCachePtr->lenAiInTckeyreq);
- /* -----------------------------------------------------------------------
- * Bit 27 == 0 since TC record is the same as the client record.
- * Bit 28 == 0 since readLenAi can only be set after reading in LQH.
- * ----------------------------------------------------------------------- */
- //LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
- Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- const Uint32 noOfLqhs = regTcPtr->noOfNodes;
- if(commitAckMarker != RNIL){
- jam();
- LqhKeyReq::setMarkerFlag(Tdata10, 1);
-
- CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
-
- /**
- * Populate LQH array
- */
- tmp->noOfLqhs = noOfLqhs;
- for(Uint32 i = 0; i<noOfLqhs; i++){
- tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
- }
- }
-
- /* ************************************************************> */
- /* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT */
- /* IS SENT TO A PRIMARY NODE. */
- /* ************************************************************> */
-
- LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtrSend();
-
- sig0 = tcConnectptr.i;
- sig2 = regCachePtr->hashValue;
- sig4 = cownref;
- sig5 = regTcPtr->savePointId;
-
- lqhKeyReq->clientConnectPtr = sig0;
- lqhKeyReq->attrLen = tslrAttrLen;
- lqhKeyReq->hashValue = sig2;
- lqhKeyReq->requestInfo = Tdata10;
- lqhKeyReq->tcBlockref = sig4;
- lqhKeyReq->savePointId = sig5;
-
- sig0 = regCachePtr->tableref + ((regCachePtr->schemaVersion << 16) & 0xFFFF0000);
- sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16);
- sig2 = regApiPtr->transid[0];
- sig3 = regApiPtr->transid[1];
- sig4 = (regTcPtr->isIndexOp == 2) ? reference() : regApiPtr->ndbapiBlockref;
- sig5 = regTcPtr->clientData;
- sig6 = regCachePtr->scanInfo;
-
- if (! dirtyRead)
- {
- regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[0]);
- regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[1]);
- regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[2]);
- regApiPtr->m_transaction_nodes.set(regTcPtr->tcNodedata[3]);
- }
-
- lqhKeyReq->tableSchemaVersion = sig0;
- lqhKeyReq->fragmentData = sig1;
- lqhKeyReq->transId1 = sig2;
- lqhKeyReq->transId2 = sig3;
- lqhKeyReq->scanInfo = sig6;
-
- lqhKeyReq->variableData[0] = sig4;
- lqhKeyReq->variableData[1] = sig5;
-
- UintR nextPos = 2;
-
- if (regTcPtr->lastReplicaNo > 1) {
- sig0 = (UintR)regTcPtr->tcNodedata[2] +
- (UintR)(regTcPtr->tcNodedata[3] << 16);
- lqhKeyReq->variableData[nextPos] = sig0;
- nextPos++;
- }//if
-
- sig0 = regCachePtr->keydata[0];
- sig1 = regCachePtr->keydata[1];
- sig2 = regCachePtr->keydata[2];
- sig3 = regCachePtr->keydata[3];
- UintR Tkeylen = regCachePtr->keylen;
-
- lqhKeyReq->variableData[nextPos + 0] = sig0;
- lqhKeyReq->variableData[nextPos + 1] = sig1;
- lqhKeyReq->variableData[nextPos + 2] = sig2;
- lqhKeyReq->variableData[nextPos + 3] = sig3;
-
- if (Tkeylen < 4) {
- nextPos += Tkeylen;
- } else {
- nextPos += 4;
- }//if
-
- sig0 = regCachePtr->attrinfo0;
- sig1 = regCachePtr->attrinfo15[0];
- sig2 = regCachePtr->attrinfo15[1];
- sig3 = regCachePtr->attrinfo15[2];
- sig4 = regCachePtr->attrinfo15[3];
- UintR TlenAi = regCachePtr->lenAiInTckeyreq;
-
- lqhKeyReq->variableData[nextPos + 0] = sig0;
- lqhKeyReq->variableData[nextPos + 1] = sig1;
- lqhKeyReq->variableData[nextPos + 2] = sig2;
- lqhKeyReq->variableData[nextPos + 3] = sig3;
- lqhKeyReq->variableData[nextPos + 4] = sig4;
-
- nextPos += TlenAi;
-
- // Reset trigger count
- regTcPtr->accumulatingTriggerData.i = RNIL;
- regTcPtr->accumulatingTriggerData.p = NULL;
- regTcPtr->noFiredTriggers = 0;
- regTcPtr->triggerExecutionCount = 0;
-
- sendSignal(TBRef, GSN_LQHKEYREQ, signal,
- nextPos + LqhKeyReq::FixedSignalLength, JBB);
-}//Dbtc::sendlqhkeyreq()
-
-void Dbtc::packLqhkeyreq040Lab(Signal* signal,
- UintR anAttrBufIndex,
- BlockReference TBRef)
-{
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
-#ifdef ERROR_INSERT
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- if (ERROR_INSERTED(8009)) {
- if (regApiPtr->apiConnectstate == CS_STARTED) {
- attrbufptr.i = RNIL;
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8010)) {
- if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
- attrbufptr.i = RNIL;
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
-#endif
-
- UintR TattrbufFilesize = cattrbufFilesize;
- AttrbufRecord *localAttrbufRecord = attrbufRecord;
- while (1) {
- if (anAttrBufIndex == RNIL) {
- UintR TtcTimer = ctcTimer;
- UintR Tread = (regTcPtr->operation == ZREAD);
- UintR Tdirty = (regTcPtr->dirtyOp == ZTRUE);
- UintR Tboth = Tread & Tdirty;
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- jam();
- /*--------------------------------------------------------------------
- * WE HAVE SENT ALL THE SIGNALS OF THIS OPERATION. SET STATE AND EXIT.
- *---------------------------------------------------------------------*/
- releaseAttrinfo();
- if (Tboth) {
- jam();
- releaseDirtyRead(signal, apiConnectptr, tcConnectptr.p);
- return;
- }//if
- regTcPtr->tcConnectstate = OS_OPERATING;
- return;
- }//if
- if (anAttrBufIndex < TattrbufFilesize) {
- AttrbufRecord * const regAttrPtr = &localAttrbufRecord[anAttrBufIndex];
- anAttrBufIndex = regAttrPtr->attrbuf[ZINBUF_NEXT];
- sendAttrinfo(signal,
- tcConnectptr.i,
- regAttrPtr,
- TBRef);
- } else {
- TCKEY_abort(signal, 17);
- return;
- }//if
- }//while
-}//Dbtc::packLqhkeyreq040Lab()
-
-/* ========================================================================= */
-/* ------- RELEASE ALL ATTRINFO RECORDS IN AN OPERATION RECORD ------- */
-/* ========================================================================= */
-void Dbtc::releaseAttrinfo()
-{
- UintR Tmp;
- AttrbufRecordPtr Tattrbufptr;
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR TattrbufFilesize = cattrbufFilesize;
- UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
- Tattrbufptr.i = regCachePtr->firstAttrbuf;
- AttrbufRecord *localAttrbufRecord = attrbufRecord;
-
- while (Tattrbufptr.i < TattrbufFilesize) {
- Tattrbufptr.p = &localAttrbufRecord[Tattrbufptr.i];
- Tmp = Tattrbufptr.p->attrbuf[ZINBUF_NEXT];
- Tattrbufptr.p->attrbuf[ZINBUF_NEXT] = TfirstfreeAttrbuf;
- TfirstfreeAttrbuf = Tattrbufptr.i;
- Tattrbufptr.i = Tmp;
- jam();
- }//while
- if (Tattrbufptr.i == RNIL) {
-//---------------------------------------------------
-// Now we will release the cache record at the same
-// time as releasing the attrinfo records.
-//---------------------------------------------------
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TfirstfreeCacheRec = cfirstfreeCacheRec;
- UintR TCacheIndex = cachePtr.i;
- cfirstfreeAttrbuf = TfirstfreeAttrbuf;
- regCachePtr->nextCacheRec = TfirstfreeCacheRec;
- cfirstfreeCacheRec = TCacheIndex;
- regApiPtr->cachePtr = RNIL;
- return;
- }//if
- systemErrorLab(0, __LINE__);
- return;
-}//Dbtc::releaseAttrinfo()
-
-/* ========================================================================= */
-/* ------- RELEASE ALL RECORDS CONNECTED TO A DIRTY OPERATION ------- */
-/* ========================================================================= */
-void Dbtc::releaseDirtyRead(Signal* signal,
- ApiConnectRecordPtr regApiPtr,
- TcConnectRecord* regTcPtr)
-{
- Uint32 Ttckeyrec = regApiPtr.p->tckeyrec;
- Uint32 TclientData = regTcPtr->clientData;
- Uint32 Tnode = regTcPtr->tcNodedata[0];
- Uint32 Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec;
- Uint32 TsimpleReadCount = c_counters.csimpleReadCount;
- ConnectionState state = regApiPtr.p->apiConnectstate;
-
- regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData;
- regApiPtr.p->tcSendArray[Ttckeyrec + 1] = TcKeyConf::DirtyReadBit | Tnode;
- regApiPtr.p->tckeyrec = Ttckeyrec + 2;
-
- unlinkReadyTcCon(signal);
- releaseTcCon();
-
- /**
- * No LQHKEYCONF in Simple/Dirty read
- * Therefore decrese no LQHKEYCONF(REF) we are waiting for
- */
- c_counters.csimpleReadCount = TsimpleReadCount + 1;
- regApiPtr.p->lqhkeyreqrec = --Tlqhkeyreqrec;
-
- if(Tlqhkeyreqrec == 0)
- {
- /**
- * Special case of lqhKeyConf_checkTransactionState:
- * - commit with zero operations: handle only for simple read
- */
- sendtckeyconf(signal, state == CS_START_COMMITTING);
- regApiPtr.p->apiConnectstate =
- (state == CS_START_COMMITTING ? CS_CONNECTED : state);
- setApiConTimer(regApiPtr.i, 0, __LINE__);
-
- return;
- }
-
- /**
- * Emulate LQHKEYCONF
- */
- lqhKeyConf_checkTransactionState(signal, regApiPtr);
-}//Dbtc::releaseDirtyRead()
-
-/* ------------------------------------------------------------------------- */
-/* ------- CHECK IF ALL TC CONNECTIONS ARE COMPLETED ------- */
-/* ------------------------------------------------------------------------- */
-void Dbtc::unlinkReadyTcCon(Signal* signal)
-{
- TcConnectRecordPtr urtTcConnectptr;
-
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- if (regTcPtr->prevTcConnect != RNIL) {
- jam();
- urtTcConnectptr.i = regTcPtr->prevTcConnect;
- ptrCheckGuard(urtTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- urtTcConnectptr.p->nextTcConnect = regTcPtr->nextTcConnect;
- } else {
- jam();
- regApiPtr->firstTcConnect = regTcPtr->nextTcConnect;
- }//if
- if (regTcPtr->nextTcConnect != RNIL) {
- jam();
- urtTcConnectptr.i = regTcPtr->nextTcConnect;
- ptrCheckGuard(urtTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- urtTcConnectptr.p->prevTcConnect = regTcPtr->prevTcConnect;
- } else {
- jam();
- regApiPtr->lastTcConnect = tcConnectptr.p->prevTcConnect;
- }//if
-}//Dbtc::unlinkReadyTcCon()
-
-void Dbtc::releaseTcCon()
-{
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- UintR TfirstfreeTcConnect = cfirstfreeTcConnect;
- UintR TconcurrentOp = c_counters.cconcurrentOp;
- UintR TtcConnectptrIndex = tcConnectptr.i;
-
- regTcPtr->tcConnectstate = OS_CONNECTED;
- regTcPtr->nextTcConnect = TfirstfreeTcConnect;
- regTcPtr->apiConnect = RNIL;
- regTcPtr->isIndexOp = false;
- regTcPtr->indexOp = RNIL;
- cfirstfreeTcConnect = TtcConnectptrIndex;
- c_counters.cconcurrentOp = TconcurrentOp - 1;
-}//Dbtc::releaseTcCon()
-
-void Dbtc::execPACKED_SIGNAL(Signal* signal)
-{
- LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
-
- UintR Ti;
- UintR Tstep = 0;
- UintR Tlength;
- UintR TpackedData[28];
- UintR Tdata1, Tdata2, Tdata3, Tdata4;
-
- jamEntry();
- Tlength = signal->length();
- if (Tlength > 25) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- Uint32* TpackDataPtr;
- for (Ti = 0; Ti < Tlength; Ti += 4) {
- Uint32* TsigDataPtr = &signal->theData[Ti];
- Tdata1 = TsigDataPtr[0];
- Tdata2 = TsigDataPtr[1];
- Tdata3 = TsigDataPtr[2];
- Tdata4 = TsigDataPtr[3];
-
- TpackDataPtr = &TpackedData[Ti];
- TpackDataPtr[0] = Tdata1;
- TpackDataPtr[1] = Tdata2;
- TpackDataPtr[2] = Tdata3;
- TpackDataPtr[3] = Tdata4;
- }//for
- while (Tlength > Tstep) {
-
- TpackDataPtr = &TpackedData[Tstep];
- Tdata1 = TpackDataPtr[0];
- Tdata2 = TpackDataPtr[1];
- Tdata3 = TpackDataPtr[2];
-
- lqhKeyConf->connectPtr = Tdata1 & 0x0FFFFFFF;
- lqhKeyConf->opPtr = Tdata2;
- lqhKeyConf->userRef = Tdata3;
-
- switch (Tdata1 >> 28) {
- case ZCOMMITTED:
- signal->header.theLength = 3;
- execCOMMITTED(signal);
- Tstep += 3;
- break;
- case ZCOMPLETED:
- signal->header.theLength = 3;
- execCOMPLETED(signal);
- Tstep += 3;
- break;
- case ZLQHKEYCONF:
- jam();
- Tdata1 = TpackDataPtr[3];
- Tdata2 = TpackDataPtr[4];
- Tdata3 = TpackDataPtr[5];
- Tdata4 = TpackDataPtr[6];
-
- lqhKeyConf->readLen = Tdata1;
- lqhKeyConf->transId1 = Tdata2;
- lqhKeyConf->transId2 = Tdata3;
- lqhKeyConf->noFiredTriggers = Tdata4;
- signal->header.theLength = LqhKeyConf::SignalLength;
- execLQHKEYCONF(signal);
- Tstep += LqhKeyConf::SignalLength;
- break;
- default:
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
- }//while
- return;
-}//Dbtc::execPACKED_SIGNAL()
-
-void Dbtc::execLQHKEYCONF(Signal* signal)
-{
- const LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
- UintR compare_transid1, compare_transid2;
- BlockReference tlastLqhBlockref;
- UintR tlastLqhConnect;
- UintR treadlenAi;
- UintR TtcConnectptrIndex;
- UintR TtcConnectFilesize = ctcConnectFilesize;
-
- tlastLqhConnect = lqhKeyConf->connectPtr;
- TtcConnectptrIndex = lqhKeyConf->opPtr;
- tlastLqhBlockref = lqhKeyConf->userRef;
- treadlenAi = lqhKeyConf->readLen;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
- /*------------------------------------------------------------------------
- * NUMBER OF EXTERNAL TRIGGERS FIRED IN DATA[6]
- * OPERATION IS NOW COMPLETED. CHECK FOR CORRECT OPERATION POINTER
- * TO ENSURE NO CRASHES BECAUSE OF ERRONEUS NODES. CHECK STATE OF
- * OPERATION. THEN SET OPERATION STATE AND RETRIEVE ALL POINTERS
- * OF THIS OPERATION. PUT COMPLETED OPERATION IN LIST OF COMPLETED
- * OPERATIONS ON THE LQH CONNECT RECORD.
- *------------------------------------------------------------------------
- * THIS SIGNAL ALWAYS ARRIVE BEFORE THE ABORTED SIGNAL ARRIVES SINCE IT USES
- * THE SAME PATH BACK TO TC AS THE ABORTED SIGNAL DO. WE DO HOWEVER HAVE A
- * PROBLEM WHEN WE ENCOUNTER A TIME-OUT WAITING FOR THE ABORTED SIGNAL.
- * THEN THIS SIGNAL MIGHT ARRIVE WHEN THE TC CONNECT RECORD HAVE BEEN REUSED
- * BY OTHER TRANSACTION THUS WE CHECK THE TRANSACTION ID OF THE SIGNAL
- * BEFORE ACCEPTING THIS SIGNAL.
- * Due to packing of LQHKEYCONF the ABORTED signal can now arrive before
- * this.
- * This is more reason to ignore the signal if not all states are correct.
- *------------------------------------------------------------------------*/
- if (TtcConnectptrIndex >= TtcConnectFilesize) {
- TCKEY_abort(signal, 25);
- return;
- }//if
- TcConnectRecord* const regTcPtr = &localTcConnectRecord[TtcConnectptrIndex];
- OperationState TtcConnectstate = regTcPtr->tcConnectstate;
- tcConnectptr.i = TtcConnectptrIndex;
- tcConnectptr.p = regTcPtr;
- if (TtcConnectstate != OS_OPERATING) {
- warningReport(signal, 23);
- return;
- }//if
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- UintR TapiConnectptrIndex = regTcPtr->apiConnect;
- UintR TapiConnectFilesize = capiConnectFilesize;
- UintR Ttrans1 = lqhKeyConf->transId1;
- UintR Ttrans2 = lqhKeyConf->transId2;
- Uint32 noFired = lqhKeyConf->noFiredTriggers;
-
- if (TapiConnectptrIndex >= TapiConnectFilesize) {
- TCKEY_abort(signal, 29);
- return;
- }//if
- Ptr<ApiConnectRecord> regApiPtr;
- regApiPtr.i = TapiConnectptrIndex;
- regApiPtr.p = &localApiConnectRecord[TapiConnectptrIndex];
- apiConnectptr.i = TapiConnectptrIndex;
- apiConnectptr.p = regApiPtr.p;
- compare_transid1 = regApiPtr.p->transid[0] ^ Ttrans1;
- compare_transid2 = regApiPtr.p->transid[1] ^ Ttrans2;
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 24);
- return;
- }//if
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(8029)) {
- systemErrorLab(signal, __LINE__);
- }//if
- if (ERROR_INSERTED(8003)) {
- if (regApiPtr.p->apiConnectstate == CS_STARTED) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8004)) {
- if (regApiPtr.p->apiConnectstate == CS_RECEIVING) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8005)) {
- if (regApiPtr.p->apiConnectstate == CS_REC_COMMITTING) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8006)) {
- if (regApiPtr.p->apiConnectstate == CS_START_COMMITTING) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8023)) {
- SET_ERROR_INSERT_VALUE(8024);
- return;
- }//if
-#endif
- UintR TtcTimer = ctcTimer;
- regTcPtr->lastLqhCon = tlastLqhConnect;
- regTcPtr->lastLqhNodeId = refToNode(tlastLqhBlockref);
- regTcPtr->noFiredTriggers = noFired;
-
- UintR Ttckeyrec = (UintR)regApiPtr.p->tckeyrec;
- UintR TclientData = regTcPtr->clientData;
- UintR TdirtyOp = regTcPtr->dirtyOp;
- Uint32 TopSimple = regTcPtr->opSimple;
- Uint32 Toperation = regTcPtr->operation;
- ConnectionState TapiConnectstate = regApiPtr.p->apiConnectstate;
- if (Ttckeyrec > (ZTCOPCONF_SIZE - 2)) {
- TCKEY_abort(signal, 30);
- return;
- }
- if (TapiConnectstate == CS_ABORTING) {
- warningReport(signal, 27);
- return;
- }//if
-
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
-
- if (regTcPtr->isIndexOp) {
- jam();
- // This was an internal TCKEYREQ
- // will be returned unpacked
- regTcPtr->attrInfoLen = treadlenAi;
- } else {
- if (noFired == 0 && regTcPtr->triggeringOperation == RNIL) {
- jam();
- /*
- * Skip counting triggering operations the first round
- * since they will enter execLQHKEYCONF a second time
- * Skip counting internally generated TcKeyReq
- */
- regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData;
- regApiPtr.p->tcSendArray[Ttckeyrec + 1] = treadlenAi;
- regApiPtr.p->tckeyrec = Ttckeyrec + 2;
- }//if
- }//if
- if (TdirtyOp == ZTRUE)
- {
- UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec;
- jam();
- releaseDirtyWrite(signal);
- regApiPtr.p->lqhkeyreqrec = Tlqhkeyreqrec - 1;
- }
- else if (Toperation == ZREAD && TopSimple)
- {
- UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec;
- jam();
- unlinkReadyTcCon(signal);
- releaseTcCon();
- regApiPtr.p->lqhkeyreqrec = Tlqhkeyreqrec - 1;
- }
- else
- {
- jam();
- if (noFired == 0) {
- jam();
- // No triggers to execute
- UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec;
- regApiPtr.p->lqhkeyconfrec = Tlqhkeyconfrec + 1;
- regTcPtr->tcConnectstate = OS_PREPARED;
- }
- }//if
-
- /**
- * And now decide what to do next
- */
- if (regTcPtr->triggeringOperation != RNIL) {
- jam();
- // This operation was created by a trigger execting operation
- // Restart it if we have executed all it's triggers
- TcConnectRecordPtr opPtr;
-
- opPtr.i = regTcPtr->triggeringOperation;
- ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
- opPtr.p->triggerExecutionCount--;
- if (opPtr.p->triggerExecutionCount == 0) {
- /*
- We have completed current trigger execution
- Continue triggering operation
- */
- jam();
- continueTriggeringOp(signal, opPtr.p);
- }
- } else if (noFired == 0) {
- // This operation did not fire any triggers, finish operation
- jam();
- if (regTcPtr->isIndexOp) {
- jam();
- setupIndexOpReturn(regApiPtr.p, regTcPtr);
- }
- lqhKeyConf_checkTransactionState(signal, regApiPtr);
- } else {
- // We have fired triggers
- jam();
- saveTriggeringOpState(signal, regTcPtr);
- if (regTcPtr->noReceivedTriggers == noFired)
- {
- // We have received all data
- jam();
- executeTriggers(signal, &regApiPtr);
- }
- // else wait for more trigger data
- }
-}//Dbtc::execLQHKEYCONF()
-
-void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr,
- TcConnectRecord* regTcPtr)
-{
- regApiPtr->indexOpReturn = true;
- regApiPtr->indexOp = regTcPtr->indexOp;
- regApiPtr->clientData = regTcPtr->clientData;
- regApiPtr->attrInfoLen = regTcPtr->attrInfoLen;
-}
-
-/**
- * lqhKeyConf_checkTransactionState
- *
- * This functions checks state variables, and
- * decides if it should wait for more LQHKEYCONF signals
- * or if it should start commiting
- */
-void
-Dbtc::lqhKeyConf_checkTransactionState(Signal * signal,
- Ptr<ApiConnectRecord> regApiPtr)
-{
-/*---------------------------------------------------------------*/
-/* IF THE COMMIT FLAG IS SET IN SIGNAL TCKEYREQ THEN DBTC HAS TO */
-/* SEND TCKEYCONF FOR ALL OPERATIONS EXCEPT THE LAST ONE. WHEN */
-/* THE TRANSACTION THEN IS COMMITTED TCKEYCONF IS SENT FOR THE */
-/* WHOLE TRANSACTION */
-/* IF THE COMMIT FLAG IS NOT RECECIVED DBTC WILL SEND TCKEYCONF */
-/* FOR ALL OPERATIONS, AND THEN WAIT FOR THE API TO CONCLUDE THE */
-/* TRANSACTION */
-/*---------------------------------------------------------------*/
- ConnectionState TapiConnectstate = regApiPtr.p->apiConnectstate;
- UintR Tlqhkeyconfrec = regApiPtr.p->lqhkeyconfrec;
- UintR Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec;
- int TnoOfOutStanding = Tlqhkeyreqrec - Tlqhkeyconfrec;
-
- switch (TapiConnectstate) {
- case CS_START_COMMITTING:
- if (TnoOfOutStanding == 0) {
- jam();
- diverify010Lab(signal);
- return;
- } else if (TnoOfOutStanding > 0) {
- if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- } else if (regApiPtr.p->indexOpReturn) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- }//if
- jam();
- return;
- } else {
- TCKEY_abort(signal, 44);
- return;
- }//if
- return;
- case CS_STARTED:
- case CS_RECEIVING:
- if (TnoOfOutStanding == 0) {
- jam();
- sendtckeyconf(signal, 2);
- return;
- } else {
- if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- } else if (regApiPtr.p->indexOpReturn) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- }//if
- jam();
- }//if
- return;
- case CS_REC_COMMITTING:
- if (TnoOfOutStanding > 0) {
- if (regApiPtr.p->tckeyrec == ZTCOPCONF_SIZE) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- } else if (regApiPtr.p->indexOpReturn) {
- jam();
- sendtckeyconf(signal, 0);
- return;
- }//if
- jam();
- return;
- }//if
- TCKEY_abort(signal, 45);
- return;
- case CS_CONNECTED:
- jam();
-/*---------------------------------------------------------------*/
-/* WE HAVE CONCLUDED THE TRANSACTION SINCE IT WAS ONLY */
-/* CONSISTING OF DIRTY WRITES AND ALL OF THOSE WERE */
-/* COMPLETED. ENSURE TCKEYREC IS ZERO TO PREVENT ERRORS. */
-/*---------------------------------------------------------------*/
- regApiPtr.p->tckeyrec = 0;
- return;
- default:
- TCKEY_abort(signal, 46);
- return;
- }//switch
-}//Dbtc::lqhKeyConf_checkTransactionState()
-
-void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag)
-{
- if(ERROR_INSERTED(8049)){
- CLEAR_ERROR_INSERT_VALUE;
- signal->theData[0] = TcContinueB::DelayTCKEYCONF;
- signal->theData[1] = apiConnectptr.i;
- signal->theData[2] = TcommitFlag;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 3000, 3);
- return;
- }
-
- HostRecordPtr localHostptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- const UintR TopWords = (UintR)regApiPtr->tckeyrec;
- localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
- const Uint32 type = getNodeInfo(localHostptr.i).m_type;
- const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
- const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
- const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL) ? 0 : 1;
- ptrAss(localHostptr, hostRecord);
- UintR TcurrLen = localHostptr.p->noOfWordsTCKEYCONF;
- UintR confInfo = 0;
- TcKeyConf::setCommitFlag(confInfo, TcommitFlag == 1);
- TcKeyConf::setMarkerFlag(confInfo, Tmarker);
- const UintR TpacketLen = 6 + TopWords;
- regApiPtr->tckeyrec = 0;
-
- if (regApiPtr->indexOpReturn) {
- jam();
- // Return internally generated TCKEY
- TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
- TcKeyConf::setNoOfOperations(confInfo, 1);
- tcKeyConf->apiConnectPtr = regApiPtr->indexOp;
- tcKeyConf->gci = regApiPtr->globalcheckpointid;
- tcKeyConf->confInfo = confInfo;
- tcKeyConf->transId1 = regApiPtr->transid[0];
- tcKeyConf->transId2 = regApiPtr->transid[1];
- tcKeyConf->operations[0].apiOperationPtr = regApiPtr->clientData;
- tcKeyConf->operations[0].attrInfoLen = regApiPtr->attrInfoLen;
- Uint32 sigLen = TcKeyConf::StaticLength + TcKeyConf::OperationLength;
- EXECUTE_DIRECT(DBTC, GSN_TCKEYCONF, signal, sigLen);
- regApiPtr->indexOpReturn = false;
- if (TopWords == 0) {
- jam();
- return; // No queued TcKeyConf
- }//if
- }//if
- if(TcommitFlag){
- jam();
- regApiPtr->m_exec_flag = 0;
- }
- TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1));
- if ((TpacketLen > 25) || !is_api){
- TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
-
- jam();
- tcKeyConf->apiConnectPtr = regApiPtr->ndbapiConnect;
- tcKeyConf->gci = regApiPtr->globalcheckpointid;;
- tcKeyConf->confInfo = confInfo;
- tcKeyConf->transId1 = regApiPtr->transid[0];
- tcKeyConf->transId2 = regApiPtr->transid[1];
- copyFromToLen(&regApiPtr->tcSendArray[0],
- (UintR*)&tcKeyConf->operations,
- (UintR)ZTCOPCONF_SIZE);
- sendSignal(regApiPtr->ndbapiBlockref,
- GSN_TCKEYCONF, signal, (TpacketLen - 1), JBB);
- return;
- } else if (((TcurrLen + TpacketLen) > 25) && (TcurrLen > 0)) {
- jam();
- sendPackedTCKEYCONF(signal, localHostptr.p, localHostptr.i);
- TcurrLen = 0;
- } else {
- jam();
- updatePackedList(signal, localHostptr.p, localHostptr.i);
- }//if
- // -------------------------------------------------------------------------
- // The header contains the block reference of receiver plus the real signal
- // length - 3, since we have the real signal length plus one additional word
- // for the header we have to do - 4.
- // -------------------------------------------------------------------------
- UintR Tpack0 = (TblockNum << 16) + (TpacketLen - 4);
- UintR Tpack1 = regApiPtr->ndbapiConnect;
- UintR Tpack2 = regApiPtr->globalcheckpointid;
- UintR Tpack3 = confInfo;
- UintR Tpack4 = regApiPtr->transid[0];
- UintR Tpack5 = regApiPtr->transid[1];
-
- localHostptr.p->noOfWordsTCKEYCONF = TcurrLen + TpacketLen;
-
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 0] = Tpack0;
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 1] = Tpack1;
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 2] = Tpack2;
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 3] = Tpack3;
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 4] = Tpack4;
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 5] = Tpack5;
-
- UintR Ti;
- for (Ti = 6; Ti < TpacketLen; Ti++) {
- localHostptr.p->packedWordsTCKEYCONF[TcurrLen + Ti] =
- regApiPtr->tcSendArray[Ti - 6];
- }//for
-}//Dbtc::sendtckeyconf()
-
-void Dbtc::copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR Tlen)
-{
- UintR Tindex = 0;
- UintR Ti;
- while (Tlen >= 4) {
- UintR Tdata0 = sourceBuffer[Tindex + 0];
- UintR Tdata1 = sourceBuffer[Tindex + 1];
- UintR Tdata2 = sourceBuffer[Tindex + 2];
- UintR Tdata3 = sourceBuffer[Tindex + 3];
- Tlen -= 4;
- destBuffer[Tindex + 0] = Tdata0;
- destBuffer[Tindex + 1] = Tdata1;
- destBuffer[Tindex + 2] = Tdata2;
- destBuffer[Tindex + 3] = Tdata3;
- Tindex += 4;
- }//while
- for (Ti = 0; Ti < Tlen; Ti++, Tindex++) {
- destBuffer[Tindex] = sourceBuffer[Tindex];
- }//for
-}//Dbtc::copyFromToLen()
-
-void Dbtc::execSEND_PACKED(Signal* signal)
-{
- HostRecordPtr Thostptr;
- HostRecord *localHostRecord = hostRecord;
- UintR i;
- UintR TpackedListIndex = cpackedListIndex;
- jamEntry();
- for (i = 0; i < TpackedListIndex; i++) {
- Thostptr.i = cpackedList[i];
- ptrAss(Thostptr, localHostRecord);
- arrGuard(Thostptr.i - 1, MAX_NODES - 1);
- UintR TnoOfPackedWordsLqh = Thostptr.p->noOfPackedWordsLqh;
- UintR TnoOfWordsTCKEYCONF = Thostptr.p->noOfWordsTCKEYCONF;
- UintR TnoOfWordsTCINDXCONF = Thostptr.p->noOfWordsTCINDXCONF;
- jam();
- if (TnoOfPackedWordsLqh > 0) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- }//if
- if (TnoOfWordsTCKEYCONF > 0) {
- jam();
- sendPackedTCKEYCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
- }//if
- if (TnoOfWordsTCINDXCONF > 0) {
- jam();
- sendPackedTCINDXCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
- }//if
- Thostptr.p->inPackedList = false;
- }//for
- cpackedListIndex = 0;
- return;
-}//Dbtc::execSEND_PACKED()
-
-void
-Dbtc::updatePackedList(Signal* signal, HostRecord* ahostptr, Uint16 ahostIndex)
-{
- if (ahostptr->inPackedList == false) {
- UintR TpackedListIndex = cpackedListIndex;
- jam();
- ahostptr->inPackedList = true;
- cpackedList[TpackedListIndex] = ahostIndex;
- cpackedListIndex = TpackedListIndex + 1;
- }//if
-}//Dbtc::updatePackedList()
-
-void Dbtc::sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr)
-{
- UintR Tj;
- UintR TnoOfWords = ahostptr->noOfPackedWordsLqh;
- for (Tj = 0; Tj < TnoOfWords; Tj += 4) {
- UintR sig0 = ahostptr->packedWordsLqh[Tj + 0];
- UintR sig1 = ahostptr->packedWordsLqh[Tj + 1];
- UintR sig2 = ahostptr->packedWordsLqh[Tj + 2];
- UintR sig3 = ahostptr->packedWordsLqh[Tj + 3];
- signal->theData[Tj + 0] = sig0;
- signal->theData[Tj + 1] = sig1;
- signal->theData[Tj + 2] = sig2;
- signal->theData[Tj + 3] = sig3;
- }//for
- ahostptr->noOfPackedWordsLqh = 0;
- sendSignal(ahostptr->hostLqhBlockRef,
- GSN_PACKED_SIGNAL,
- signal,
- TnoOfWords,
- JBB);
-}//Dbtc::sendPackedSignalLqh()
-
-void Dbtc::sendPackedTCKEYCONF(Signal* signal,
- HostRecord * ahostptr,
- UintR hostId)
-{
- UintR Tj;
- UintR TnoOfWords = ahostptr->noOfWordsTCKEYCONF;
- BlockReference TBref = numberToRef(API_PACKED, hostId);
- for (Tj = 0; Tj < ahostptr->noOfWordsTCKEYCONF; Tj += 4) {
- UintR sig0 = ahostptr->packedWordsTCKEYCONF[Tj + 0];
- UintR sig1 = ahostptr->packedWordsTCKEYCONF[Tj + 1];
- UintR sig2 = ahostptr->packedWordsTCKEYCONF[Tj + 2];
- UintR sig3 = ahostptr->packedWordsTCKEYCONF[Tj + 3];
- signal->theData[Tj + 0] = sig0;
- signal->theData[Tj + 1] = sig1;
- signal->theData[Tj + 2] = sig2;
- signal->theData[Tj + 3] = sig3;
- }//for
- ahostptr->noOfWordsTCKEYCONF = 0;
- sendSignal(TBref, GSN_TCKEYCONF, signal, TnoOfWords, JBB);
-}//Dbtc::sendPackedTCKEYCONF()
-
-void Dbtc::sendPackedTCINDXCONF(Signal* signal,
- HostRecord * ahostptr,
- UintR hostId)
-{
- UintR Tj;
- UintR TnoOfWords = ahostptr->noOfWordsTCINDXCONF;
- BlockReference TBref = numberToRef(API_PACKED, hostId);
- for (Tj = 0; Tj < ahostptr->noOfWordsTCINDXCONF; Tj += 4) {
- UintR sig0 = ahostptr->packedWordsTCINDXCONF[Tj + 0];
- UintR sig1 = ahostptr->packedWordsTCINDXCONF[Tj + 1];
- UintR sig2 = ahostptr->packedWordsTCINDXCONF[Tj + 2];
- UintR sig3 = ahostptr->packedWordsTCINDXCONF[Tj + 3];
- signal->theData[Tj + 0] = sig0;
- signal->theData[Tj + 1] = sig1;
- signal->theData[Tj + 2] = sig2;
- signal->theData[Tj + 3] = sig3;
- }//for
- ahostptr->noOfWordsTCINDXCONF = 0;
- sendSignal(TBref, GSN_TCINDXCONF, signal, TnoOfWords, JBB);
-}//Dbtc::sendPackedTCINDXCONF()
-
-/*
-4.3.11 DIVERIFY
----------------
-*/
-/*****************************************************************************/
-/* D I V E R I F Y */
-/* */
-/*****************************************************************************/
-void Dbtc::diverify010Lab(Signal* signal)
-{
- UintR TfirstfreeApiConnectCopy = cfirstfreeApiConnectCopy;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- signal->theData[0] = apiConnectptr.i;
- if (ERROR_INSERTED(8022)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
-
- if (regApiPtr->lqhkeyreqrec)
- {
- if (TfirstfreeApiConnectCopy != RNIL) {
- seizeApiConnectCopy(signal);
- regApiPtr->apiConnectstate = CS_PREPARE_TO_COMMIT;
- /*-----------------------------------------------------------------------
- * WE COME HERE ONLY IF THE TRANSACTION IS PREPARED ON ALL TC CONNECTIONS
- * THUS WE CAN START THE COMMIT PHASE BY SENDING DIVERIFY ON ALL TC
- * CONNECTIONS AND THEN WHEN ALL DIVERIFYCONF HAVE BEEN RECEIVED THE
- * COMMIT MESSAGE CAN BE SENT TO ALL INVOLVED PARTS.
- *---------------------------------------------------------------------*/
- EXECUTE_DIRECT(DBDIH, GSN_DIVERIFYREQ, signal, 1);
- if (signal->theData[2] == 0) {
- execDIVERIFYCONF(signal);
- }
- return;
- } else {
- /*-----------------------------------------------------------------------
- * There were no free copy connections available. We must abort the
- * transaction since otherwise we will have a problem with the report
- * to the application.
- * This should more or less not happen but if it happens we do
- * not want to crash and we do not want to create code to handle it
- * properly since it is difficult to test it and will be complex to
- * handle a problem more or less not occurring.
- *---------------------------------------------------------------------*/
- terrorCode = ZSEIZE_API_COPY_ERROR;
- abortErrorLab(signal);
- return;
- }
- }
- else
- {
- jam();
- sendtckeyconf(signal, 1);
- regApiPtr->apiConnectstate = CS_CONNECTED;
- regApiPtr->m_transaction_nodes.clear();
- setApiConTimer(apiConnectptr.i, 0,__LINE__);
- }
-}//Dbtc::diverify010Lab()
-
-/* ------------------------------------------------------------------------- */
-/* ------- SEIZE_API_CONNECT ------- */
-/* SEIZE CONNECT RECORD FOR A REQUEST */
-/* ------------------------------------------------------------------------- */
-void Dbtc::seizeApiConnectCopy(Signal* signal)
-{
- ApiConnectRecordPtr locApiConnectptr;
-
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- UintR TapiConnectFilesize = capiConnectFilesize;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-
- locApiConnectptr.i = cfirstfreeApiConnectCopy;
- ptrCheckGuard(locApiConnectptr, TapiConnectFilesize, localApiConnectRecord);
- cfirstfreeApiConnectCopy = locApiConnectptr.p->nextApiConnect;
- locApiConnectptr.p->nextApiConnect = RNIL;
- regApiPtr->apiCopyRecord = locApiConnectptr.i;
- regApiPtr->triggerPending = false;
- regApiPtr->isIndexOp = false;
-}//Dbtc::seizeApiConnectCopy()
-
-void Dbtc::execDIVERIFYCONF(Signal* signal)
-{
- UintR TapiConnectptrIndex = signal->theData[0];
- UintR TapiConnectFilesize = capiConnectFilesize;
- UintR Tgci = signal->theData[1];
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- jamEntry();
- if (ERROR_INSERTED(8017)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- if (TapiConnectptrIndex >= TapiConnectFilesize) {
- TCKEY_abort(signal, 31);
- return;
- }//if
- ApiConnectRecord * const regApiPtr =
- &localApiConnectRecord[TapiConnectptrIndex];
- ConnectionState TapiConnectstate = regApiPtr->apiConnectstate;
- UintR TApifailureNr = regApiPtr->failureNr;
- UintR Tfailure_nr = cfailure_nr;
- apiConnectptr.i = TapiConnectptrIndex;
- apiConnectptr.p = regApiPtr;
- if (TapiConnectstate != CS_PREPARE_TO_COMMIT) {
- TCKEY_abort(signal, 32);
- return;
- }//if
- /*--------------------------------------------------------------------------
- * THIS IS THE COMMIT POINT. IF WE ARRIVE HERE THE TRANSACTION IS COMMITTED
- * UNLESS EVERYTHING CRASHES BEFORE WE HAVE BEEN ABLE TO REPORT THE COMMIT
- * DECISION. THERE IS NO TURNING BACK FROM THIS DECISION FROM HERE ON.
- * WE WILL INSERT THE TRANSACTION INTO ITS PROPER QUEUE OF
- * TRANSACTIONS FOR ITS GLOBAL CHECKPOINT.
- *-------------------------------------------------------------------------*/
- if (TApifailureNr != Tfailure_nr) {
- DIVER_node_fail_handling(signal, Tgci);
- return;
- }//if
- commitGciHandling(signal, Tgci);
-
- /**************************************************************************
- * C O M M I T
- * THE TRANSACTION HAVE NOW BEEN VERIFIED AND NOW THE COMMIT PHASE CAN START
- **************************************************************************/
-
- UintR TtcConnectptrIndex = regApiPtr->firstTcConnect;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
- regApiPtr->counter = regApiPtr->lqhkeyconfrec;
- regApiPtr->apiConnectstate = CS_COMMITTING;
- if (TtcConnectptrIndex >= TtcConnectFilesize) {
- TCKEY_abort(signal, 33);
- return;
- }//if
- TcConnectRecord* const regTcPtr = &localTcConnectRecord[TtcConnectptrIndex];
- tcConnectptr.i = TtcConnectptrIndex;
- tcConnectptr.p = regTcPtr;
- commit020Lab(signal);
-}//Dbtc::execDIVERIFYCONF()
-
-/*--------------------------------------------------------------------------*/
-/* COMMIT_GCI_HANDLING */
-/* SET UP GLOBAL CHECKPOINT DATA STRUCTURE AT THE COMMIT POINT. */
-/*--------------------------------------------------------------------------*/
-void Dbtc::commitGciHandling(Signal* signal, UintR Tgci)
-{
- GcpRecordPtr localGcpPointer;
-
- UintR TgcpFilesize = cgcpFilesize;
- UintR Tfirstgcp = cfirstgcp;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- GcpRecord *localGcpRecord = gcpRecord;
-
- regApiPtr->globalcheckpointid = Tgci;
- if (Tfirstgcp != RNIL) {
- /* IF THIS GLOBAL CHECKPOINT ALREADY EXISTS */
- localGcpPointer.i = Tfirstgcp;
- ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
- do {
- if (regApiPtr->globalcheckpointid == localGcpPointer.p->gcpId) {
- jam();
- gcpPtr.i = localGcpPointer.i;
- gcpPtr.p = localGcpPointer.p;
- linkApiToGcp(signal);
- return;
- } else {
- localGcpPointer.i = localGcpPointer.p->nextGcp;
- jam();
- if (localGcpPointer.i != RNIL) {
- jam();
- ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
- continue;
- }//if
- }//if
- seizeGcp(signal);
- linkApiToGcp(signal);
- return;
- } while (1);
- } else {
- jam();
- seizeGcp(signal);
- linkApiToGcp(signal);
- }//if
-}//Dbtc::commitGciHandling()
-
-/* --------------------------------------------------------------------------*/
-/* -LINK AN API CONNECT RECORD IN STATE PREPARED INTO THE LIST WITH GLOBAL - */
-/* CHECKPOINTS. WHEN THE TRANSACTION I COMPLETED THE API CONNECT RECORD IS */
-/* LINKED OUT OF THE LIST. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::linkApiToGcp(Signal* signal)
-{
- ApiConnectRecordPtr localApiConnectptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- GcpRecord * const regGcpPtr = gcpPtr.p;
- UintR TapiConnectptrIndex = apiConnectptr.i;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- regApiPtr->nextGcpConnect = RNIL;
- if (regGcpPtr->firstApiConnect == RNIL) {
- regGcpPtr->firstApiConnect = TapiConnectptrIndex;
- jam();
- } else {
- UintR TapiConnectFilesize = capiConnectFilesize;
- localApiConnectptr.i = regGcpPtr->lastApiConnect;
- jam();
- ptrCheckGuard(localApiConnectptr,
- TapiConnectFilesize, localApiConnectRecord);
- localApiConnectptr.p->nextGcpConnect = TapiConnectptrIndex;
- }//if
- UintR TlastApiConnect = regGcpPtr->lastApiConnect;
- regApiPtr->gcpPointer = gcpPtr.i;
- regApiPtr->prevGcpConnect = TlastApiConnect;
- regGcpPtr->lastApiConnect = TapiConnectptrIndex;
-}//Dbtc::linkApiToGcp()
-
-void Dbtc::seizeGcp(Signal* signal)
-{
- GcpRecordPtr tmpGcpPointer;
- GcpRecordPtr localGcpPointer;
-
- UintR Tfirstgcp = cfirstgcp;
- UintR Tglobalcheckpointid = apiConnectptr.p->globalcheckpointid;
- UintR TgcpFilesize = cgcpFilesize;
- GcpRecord *localGcpRecord = gcpRecord;
-
- localGcpPointer.i = cfirstfreeGcp;
- ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
- UintR TfirstfreeGcp = localGcpPointer.p->nextGcp;
- localGcpPointer.p->gcpId = Tglobalcheckpointid;
- localGcpPointer.p->nextGcp = RNIL;
- localGcpPointer.p->firstApiConnect = RNIL;
- localGcpPointer.p->lastApiConnect = RNIL;
- localGcpPointer.p->gcpNomoretransRec = ZFALSE;
- cfirstfreeGcp = TfirstfreeGcp;
-
- if (Tfirstgcp == RNIL) {
- jam();
- cfirstgcp = localGcpPointer.i;
- } else {
- tmpGcpPointer.i = clastgcp;
- jam();
- ptrCheckGuard(tmpGcpPointer, TgcpFilesize, localGcpRecord);
- tmpGcpPointer.p->nextGcp = localGcpPointer.i;
- }//if
- clastgcp = localGcpPointer.i;
- gcpPtr = localGcpPointer;
-}//Dbtc::seizeGcp()
-
-/*---------------------------------------------------------------------------*/
-// Send COMMIT messages to all LQH operations involved in the transaction.
-/*---------------------------------------------------------------------------*/
-void Dbtc::commit020Lab(Signal* signal)
-{
- TcConnectRecordPtr localTcConnectptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
- localTcConnectptr.p = tcConnectptr.p;
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- UintR Tcount = 0;
- do {
- /*-----------------------------------------------------------------------
- * WE ARE NOW READY TO RELEASE ALL OPERATIONS ON THE LQH
- *-----------------------------------------------------------------------*/
- /* *********< */
- /* COMMIT < */
- /* *********< */
- localTcConnectptr.i = localTcConnectptr.p->nextTcConnect;
- localTcConnectptr.p->tcConnectstate = OS_COMMITTING;
- sendCommitLqh(signal, localTcConnectptr.p);
-
- if (localTcConnectptr.i != RNIL) {
- Tcount = Tcount + 1;
- if (Tcount < 16 && !ERROR_INSERTED(8057)) {
- ptrCheckGuard(localTcConnectptr,
- TtcConnectFilesize, localTcConnectRecord);
- jam();
- continue;
- } else {
- jam();
- if (ERROR_INSERTED(8014)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- signal->theData[0] = TcContinueB::ZSEND_COMMIT_LOOP;
- signal->theData[1] = apiConnectptr.i;
- signal->theData[2] = localTcConnectptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }//if
- } else {
- jam();
- if (ERROR_INSERTED(8057))
- CLEAR_ERROR_INSERT_VALUE;
-
- regApiPtr->apiConnectstate = CS_COMMIT_SENT;
- return;
- }//if
- } while (1);
-}//Dbtc::commit020Lab()
-
-void Dbtc::sendCommitLqh(Signal* signal,
- TcConnectRecord * const regTcPtr)
-{
- HostRecordPtr Thostptr;
- UintR ThostFilesize = chostFilesize;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- Thostptr.i = regTcPtr->lastLqhNodeId;
- ptrCheckGuard(Thostptr, ThostFilesize, hostRecord);
- if (Thostptr.p->noOfPackedWordsLqh > 21) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
- UintR Tindex = Thostptr.p->noOfPackedWordsLqh;
- UintR* TDataPtr = &Thostptr.p->packedWordsLqh[Tindex];
- UintR Tdata1 = regTcPtr->lastLqhCon;
- UintR Tdata2 = regApiPtr->globalcheckpointid;
- UintR Tdata3 = regApiPtr->transid[0];
- UintR Tdata4 = regApiPtr->transid[1];
-
- TDataPtr[0] = Tdata1 | (ZCOMMIT << 28);
- TDataPtr[1] = Tdata2;
- TDataPtr[2] = Tdata3;
- TDataPtr[3] = Tdata4;
- Thostptr.p->noOfPackedWordsLqh = Tindex + 4;
-}//Dbtc::sendCommitLqh()
-
-void
-Dbtc::DIVER_node_fail_handling(Signal* signal, UintR Tgci)
-{
- /*------------------------------------------------------------------------
- * AT LEAST ONE NODE HAS FAILED DURING THE TRANSACTION. WE NEED TO CHECK IF
- * THIS IS SO SERIOUS THAT WE NEED TO ABORT THE TRANSACTION. IN BOTH THE
- * ABORT AND THE COMMIT CASES WE NEED TO SET-UP THE DATA FOR THE
- * ABORT/COMMIT/COMPLETE HANDLING AS ALSO USED BY TAKE OVER FUNCTIONALITY.
- *------------------------------------------------------------------------*/
- tabortInd = ZFALSE;
- setupFailData(signal);
- if (false && tabortInd == ZFALSE) {
- jam();
- commitGciHandling(signal, Tgci);
- toCommitHandlingLab(signal);
- } else {
- jam();
- apiConnectptr.p->returnsignal = RS_TCROLLBACKREP;
- apiConnectptr.p->returncode = ZNODEFAIL_BEFORE_COMMIT;
- toAbortHandlingLab(signal);
- }//if
- return;
-}//Dbtc::DIVER_node_fail_handling()
-
-
-/* ------------------------------------------------------------------------- */
-/* ------- ENTER COMMITTED ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dbtc::execCOMMITTED(Signal* signal)
-{
- TcConnectRecordPtr localTcConnectptr;
- ApiConnectRecordPtr localApiConnectptr;
-
- UintR TtcConnectFilesize = ctcConnectFilesize;
- UintR TapiConnectFilesize = capiConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(8018)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- if (ERROR_INSERTED(8030)) {
- systemErrorLab(signal, __LINE__);
- }//if
- if (ERROR_INSERTED(8025)) {
- SET_ERROR_INSERT_VALUE(8026);
- return;
- }//if
- if (ERROR_INSERTED(8041)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMMITTED, signal, 2000, 3);
- return;
- }//if
- if (ERROR_INSERTED(8042)) {
- SET_ERROR_INSERT_VALUE(8046);
- sendSignalWithDelay(cownref, GSN_COMMITTED, signal, 2000, 4);
- return;
- }//if
-#endif
- localTcConnectptr.i = signal->theData[0];
- jamEntry();
- ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- localApiConnectptr.i = localTcConnectptr.p->apiConnect;
- if (localTcConnectptr.p->tcConnectstate != OS_COMMITTING) {
- warningReport(signal, 4);
- return;
- }//if
- ptrCheckGuard(localApiConnectptr, TapiConnectFilesize,
- localApiConnectRecord);
- UintR Tcounter = localApiConnectptr.p->counter - 1;
- ConnectionState TapiConnectstate = localApiConnectptr.p->apiConnectstate;
- UintR Tdata1 = localApiConnectptr.p->transid[0] - signal->theData[1];
- UintR Tdata2 = localApiConnectptr.p->transid[1] - signal->theData[2];
- Tdata1 = Tdata1 | Tdata2;
- bool TcheckCondition =
- (TapiConnectstate != CS_COMMIT_SENT) || (Tcounter != 0);
-
- setApiConTimer(localApiConnectptr.i, ctcTimer, __LINE__);
- localApiConnectptr.p->counter = Tcounter;
- localTcConnectptr.p->tcConnectstate = OS_COMMITTED;
- if (Tdata1 != 0) {
- warningReport(signal, 5);
- return;
- }//if
- if (TcheckCondition) {
- jam();
- /*-------------------------------------------------------*/
- // We have not sent all COMMIT requests yet. We could be
- // in the state that all sent are COMMITTED but we are
- // still waiting for a CONTINUEB to send the rest of the
- // COMMIT requests.
- /*-------------------------------------------------------*/
- return;
- }//if
- if (ERROR_INSERTED(8020)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- /*-------------------------------------------------------*/
- /* THE ENTIRE TRANSACTION IS NOW COMMITED */
- /* NOW WE NEED TO SEND THE RESPONSE TO THE APPLICATION. */
- /* THE APPLICATION CAN THEN REUSE THE API CONNECTION AND */
- /* THEREFORE WE NEED TO MOVE THE API CONNECTION TO A */
- /* NEW API CONNECT RECORD. */
- /*-------------------------------------------------------*/
-
- apiConnectptr = localApiConnectptr;
- sendApiCommit(signal);
-
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- localTcConnectptr.i = regApiPtr->firstTcConnect;
- UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec;
- ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- regApiPtr->counter = Tlqhkeyconfrec;
-
- tcConnectptr = localTcConnectptr;
- complete010Lab(signal);
- return;
-
-}//Dbtc::execCOMMITTED()
-
-/*-------------------------------------------------------*/
-/* SEND_API_COMMIT */
-/* SEND COMMIT DECISION TO THE API. */
-/*-------------------------------------------------------*/
-void Dbtc::sendApiCommit(Signal* signal)
-{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-
- if (regApiPtr->returnsignal == RS_TCKEYCONF) {
- sendtckeyconf(signal, 1);
- } else if (regApiPtr->returnsignal == RS_TC_COMMITCONF) {
- jam();
- TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
- if(regApiPtr->commitAckMarker == RNIL){
- jam();
- commitConf->apiConnectPtr = regApiPtr->ndbapiConnect;
- } else {
- jam();
- commitConf->apiConnectPtr = regApiPtr->ndbapiConnect | 1;
- }
- commitConf->transId1 = regApiPtr->transid[0];
- commitConf->transId2 = regApiPtr->transid[1];
- commitConf->gci = regApiPtr->globalcheckpointid;
-
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal,
- TcCommitConf::SignalLength, JBB);
- } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
- jam();
- } else {
- TCKEY_abort(signal, 37);
- return;
- }//if
- UintR TapiConnectFilesize = capiConnectFilesize;
- UintR TcommitCount = c_counters.ccommitCount;
- UintR TapiIndex = apiConnectptr.i;
- UintR TnewApiIndex = regApiPtr->apiCopyRecord;
- UintR TapiFailState = regApiPtr->apiFailState;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- tmpApiConnectptr.p = apiConnectptr.p;
- tmpApiConnectptr.i = TapiIndex;
- c_counters.ccommitCount = TcommitCount + 1;
- apiConnectptr.i = TnewApiIndex;
- ptrCheckGuard(apiConnectptr, TapiConnectFilesize, localApiConnectRecord);
- copyApi(signal);
- if (TapiFailState != ZTRUE) {
- return;
- } else {
- jam();
- handleApiFailState(signal, tmpApiConnectptr.i);
- return;
- }//if
-}//Dbtc::sendApiCommit()
-
-/* ========================================================================= */
-/* ======= COPY_API ======= */
-/* COPY API RECORD ALSO RESET THE OLD API RECORD SO THAT IT */
-/* IS PREPARED TO RECEIVE A NEW TRANSACTION. */
-/*===========================================================================*/
-void Dbtc::copyApi(Signal* signal)
-{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
-
- UintR TndbapiConnect = regTmpApiPtr->ndbapiConnect;
- UintR TfirstTcConnect = regTmpApiPtr->firstTcConnect;
- UintR Ttransid1 = regTmpApiPtr->transid[0];
- UintR Ttransid2 = regTmpApiPtr->transid[1];
- UintR Tlqhkeyconfrec = regTmpApiPtr->lqhkeyconfrec;
- UintR TgcpPointer = regTmpApiPtr->gcpPointer;
- UintR TgcpFilesize = cgcpFilesize;
- UintR TcommitAckMarker = regTmpApiPtr->commitAckMarker;
- NdbNodeBitmask Tnodes = regTmpApiPtr->m_transaction_nodes;
- GcpRecord *localGcpRecord = gcpRecord;
-
- regApiPtr->ndbapiBlockref = regTmpApiPtr->ndbapiBlockref;
- regApiPtr->ndbapiConnect = TndbapiConnect;
- regApiPtr->firstTcConnect = TfirstTcConnect;
- regApiPtr->apiConnectstate = CS_COMPLETING;
- regApiPtr->transid[0] = Ttransid1;
- regApiPtr->transid[1] = Ttransid2;
- regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
- regApiPtr->commitAckMarker = TcommitAckMarker;
- regApiPtr->m_transaction_nodes = Tnodes;
- regApiPtr->singleUserMode = 0;
-
- gcpPtr.i = TgcpPointer;
- ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
- unlinkApiConnect(signal);
- linkApiToGcp(signal);
- setApiConTimer(tmpApiConnectptr.i, 0, __LINE__);
- regTmpApiPtr->apiConnectstate = CS_CONNECTED;
- regTmpApiPtr->commitAckMarker = RNIL;
- regTmpApiPtr->firstTcConnect = RNIL;
- regTmpApiPtr->lastTcConnect = RNIL;
- regTmpApiPtr->m_transaction_nodes.clear();
- regTmpApiPtr->singleUserMode = 0;
- releaseAllSeizedIndexOperations(regTmpApiPtr);
-}//Dbtc::copyApi()
-
-void Dbtc::unlinkApiConnect(Signal* signal)
-{
- ApiConnectRecordPtr localApiConnectptr;
- ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
- UintR TapiConnectFilesize = capiConnectFilesize;
- UintR TprevGcpConnect = regTmpApiPtr->prevGcpConnect;
- UintR TnextGcpConnect = regTmpApiPtr->nextGcpConnect;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
- if (TprevGcpConnect == RNIL) {
- gcpPtr.p->firstApiConnect = TnextGcpConnect;
- jam();
- } else {
- localApiConnectptr.i = TprevGcpConnect;
- jam();
- ptrCheckGuard(localApiConnectptr,
- TapiConnectFilesize, localApiConnectRecord);
- localApiConnectptr.p->nextGcpConnect = TnextGcpConnect;
- }//if
- if (TnextGcpConnect == RNIL) {
- gcpPtr.p->lastApiConnect = TprevGcpConnect;
- jam();
- } else {
- localApiConnectptr.i = TnextGcpConnect;
- jam();
- ptrCheckGuard(localApiConnectptr,
- TapiConnectFilesize, localApiConnectRecord);
- localApiConnectptr.p->prevGcpConnect = TprevGcpConnect;
- }//if
-}//Dbtc::unlinkApiConnect()
-
-void Dbtc::complete010Lab(Signal* signal)
-{
- TcConnectRecordPtr localTcConnectptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
- localTcConnectptr.p = tcConnectptr.p;
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- UintR TapiConnectptrIndex = apiConnectptr.i;
- UintR Tcount = 0;
- do {
- localTcConnectptr.p->apiConnect = TapiConnectptrIndex;
- localTcConnectptr.p->tcConnectstate = OS_COMPLETING;
-
- /* ************ */
- /* COMPLETE < */
- /* ************ */
- const Uint32 nextTcConnect = localTcConnectptr.p->nextTcConnect;
- sendCompleteLqh(signal, localTcConnectptr.p);
- localTcConnectptr.i = nextTcConnect;
- if (localTcConnectptr.i != RNIL) {
- Tcount++;
- if (Tcount < 16) {
- ptrCheckGuard(localTcConnectptr,
- TtcConnectFilesize, localTcConnectRecord);
- jam();
- continue;
- } else {
- jam();
- if (ERROR_INSERTED(8013)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- signal->theData[0] = TcContinueB::ZSEND_COMPLETE_LOOP;
- signal->theData[1] = apiConnectptr.i;
- signal->theData[2] = localTcConnectptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }//if
- } else {
- jam();
- regApiPtr->apiConnectstate = CS_COMPLETE_SENT;
- return;
- }//if
- } while (1);
-}//Dbtc::complete010Lab()
-
-void Dbtc::sendCompleteLqh(Signal* signal,
- TcConnectRecord * const regTcPtr)
-{
- HostRecordPtr Thostptr;
- UintR ThostFilesize = chostFilesize;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- Thostptr.i = regTcPtr->lastLqhNodeId;
- ptrCheckGuard(Thostptr, ThostFilesize, hostRecord);
- if (Thostptr.p->noOfPackedWordsLqh > 22) {
- jam();
- sendPackedSignalLqh(signal, Thostptr.p);
- } else {
- jam();
- updatePackedList(signal, Thostptr.p, Thostptr.i);
- }//if
-
- UintR Tindex = Thostptr.p->noOfPackedWordsLqh;
- UintR* TDataPtr = &Thostptr.p->packedWordsLqh[Tindex];
- UintR Tdata1 = regTcPtr->lastLqhCon | (ZCOMPLETE << 28);
- UintR Tdata2 = regApiPtr->transid[0];
- UintR Tdata3 = regApiPtr->transid[1];
-
- TDataPtr[0] = Tdata1;
- TDataPtr[1] = Tdata2;
- TDataPtr[2] = Tdata3;
- Thostptr.p->noOfPackedWordsLqh = Tindex + 3;
-}//Dbtc::sendCompleteLqh()
-
-void
-Dbtc::execTC_COMMIT_ACK(Signal* signal){
- jamEntry();
-
- CommitAckMarker key;
- key.transid1 = signal->theData[0];
- key.transid2 = signal->theData[1];
-
- CommitAckMarkerPtr removedMarker;
- m_commitAckMarkerHash.remove(removedMarker, key);
- if (removedMarker.i == RNIL) {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
- sendRemoveMarkers(signal, removedMarker.p);
- m_commitAckMarkerPool.release(removedMarker);
-}
-
-void
-Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker){
- jam();
- const Uint32 noOfLqhs = marker->noOfLqhs;
- const Uint32 transId1 = marker->transid1;
- const Uint32 transId2 = marker->transid2;
-
- for(Uint32 i = 0; i<noOfLqhs; i++){
- jam();
- const NodeId nodeId = marker->lqhNodeId[i];
- sendRemoveMarker(signal, nodeId, transId1, transId2);
- }
-}
-
-void
-Dbtc::sendRemoveMarker(Signal* signal,
- NodeId nodeId,
- Uint32 transid1,
- Uint32 transid2){
- /**
- * Seize host ptr
- */
- HostRecordPtr hostPtr;
- const UintR ThostFilesize = chostFilesize;
- hostPtr.i = nodeId;
- ptrCheckGuard(hostPtr, ThostFilesize, hostRecord);
-
- if (hostPtr.p->noOfPackedWordsLqh > (25 - 3)){
- jam();
- sendPackedSignalLqh(signal, hostPtr.p);
- } else {
- jam();
- updatePackedList(signal, hostPtr.p, hostPtr.i);
- }//if
-
- UintR numWord = hostPtr.p->noOfPackedWordsLqh;
- UintR* dataPtr = &hostPtr.p->packedWordsLqh[numWord];
-
- dataPtr[0] = (ZREMOVE_MARKER << 28);
- dataPtr[1] = transid1;
- dataPtr[2] = transid2;
- hostPtr.p->noOfPackedWordsLqh = numWord + 3;
-}
-
-void Dbtc::execCOMPLETED(Signal* signal)
-{
- TcConnectRecordPtr localTcConnectptr;
- ApiConnectRecordPtr localApiConnectptr;
-
- UintR TtcConnectFilesize = ctcConnectFilesize;
- UintR TapiConnectFilesize = capiConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(8031)) {
- systemErrorLab(signal, __LINE__);
- }//if
- if (ERROR_INSERTED(8019)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- if (ERROR_INSERTED(8027)) {
- SET_ERROR_INSERT_VALUE(8028);
- return;
- }//if
- if (ERROR_INSERTED(8043)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMPLETED, signal, 2000, 3);
- return;
- }//if
- if (ERROR_INSERTED(8044)) {
- SET_ERROR_INSERT_VALUE(8047);
- sendSignalWithDelay(cownref, GSN_COMPLETED, signal, 2000, 3);
- return;
- }//if
-#endif
- localTcConnectptr.i = signal->theData[0];
- jamEntry();
- ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- bool Tcond1 = (localTcConnectptr.p->tcConnectstate != OS_COMPLETING);
- localApiConnectptr.i = localTcConnectptr.p->apiConnect;
- if (Tcond1) {
- warningReport(signal, 6);
- return;
- }//if
- ptrCheckGuard(localApiConnectptr, TapiConnectFilesize,
- localApiConnectRecord);
- UintR Tdata1 = localApiConnectptr.p->transid[0] - signal->theData[1];
- UintR Tdata2 = localApiConnectptr.p->transid[1] - signal->theData[2];
- UintR Tcounter = localApiConnectptr.p->counter - 1;
- ConnectionState TapiConnectstate = localApiConnectptr.p->apiConnectstate;
- Tdata1 = Tdata1 | Tdata2;
- bool TcheckCondition =
- (TapiConnectstate != CS_COMPLETE_SENT) || (Tcounter != 0);
- if (Tdata1 != 0) {
- warningReport(signal, 7);
- return;
- }//if
- setApiConTimer(localApiConnectptr.i, ctcTimer, __LINE__);
- localApiConnectptr.p->counter = Tcounter;
- localTcConnectptr.p->tcConnectstate = OS_COMPLETED;
- localTcConnectptr.p->noOfNodes = 0; // == releaseNodes(signal)
- if (TcheckCondition) {
- jam();
- /*-------------------------------------------------------*/
- // We have not sent all COMPLETE requests yet. We could be
- // in the state that all sent are COMPLETED but we are
- // still waiting for a CONTINUEB to send the rest of the
- // COMPLETE requests.
- /*-------------------------------------------------------*/
- return;
- }//if
- if (ERROR_INSERTED(8021)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- apiConnectptr = localApiConnectptr;
- releaseTransResources(signal);
-}//Dbtc::execCOMPLETED()
-
-/*---------------------------------------------------------------------------*/
-/* RELEASE_TRANS_RESOURCES */
-/* RELEASE ALL RESOURCES THAT ARE CONNECTED TO THIS TRANSACTION. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::releaseTransResources(Signal* signal)
-{
- TcConnectRecordPtr localTcConnectptr;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- apiConnectptr.p->m_transaction_nodes.clear();
- localTcConnectptr.i = apiConnectptr.p->firstTcConnect;
- do {
- jam();
- ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- UintR rtrTcConnectptrIndex = localTcConnectptr.p->nextTcConnect;
- tcConnectptr.i = localTcConnectptr.i;
- tcConnectptr.p = localTcConnectptr.p;
- localTcConnectptr.i = rtrTcConnectptrIndex;
- releaseTcCon();
- } while (localTcConnectptr.i != RNIL);
- handleGcp(signal);
- releaseFiredTriggerData(&apiConnectptr.p->theFiredTriggers);
- releaseAllSeizedIndexOperations(apiConnectptr.p);
- releaseApiConCopy(signal);
-}//Dbtc::releaseTransResources()
-
-/* *********************************************************************>> */
-/* MODULE: HANDLE_GCP */
-/* DESCRIPTION: HANDLES GLOBAL CHECKPOINT HANDLING AT THE COMPLETION */
-/* OF THE COMMIT PHASE AND THE ABORT PHASE. WE MUST ENSURE THAT TC */
-/* SENDS GCP_TCFINISHED WHEN ALL TRANSACTIONS BELONGING TO A CERTAIN */
-/* GLOBAL CHECKPOINT HAVE COMPLETED. */
-/* *********************************************************************>> */
-void Dbtc::handleGcp(Signal* signal)
-{
- GcpRecord *localGcpRecord = gcpRecord;
- GcpRecordPtr localGcpPtr;
- UintR TapiConnectptrIndex = apiConnectptr.i;
- UintR TgcpFilesize = cgcpFilesize;
- localGcpPtr.i = apiConnectptr.p->gcpPointer;
- tmpApiConnectptr.i = TapiConnectptrIndex;
- tmpApiConnectptr.p = apiConnectptr.p;
- ptrCheckGuard(localGcpPtr, TgcpFilesize, localGcpRecord);
- gcpPtr.i = localGcpPtr.i;
- gcpPtr.p = localGcpPtr.p;
- unlinkApiConnect(signal);
- if (localGcpPtr.p->firstApiConnect == RNIL) {
- if (localGcpPtr.p->gcpNomoretransRec == ZTRUE) {
- jam();
- tcheckGcpId = localGcpPtr.p->gcpId;
- gcpTcfinished(signal);
- unlinkGcp(signal);
- }//if
- }//if
-}//Dbtc::handleGcp()
-
-void Dbtc::releaseApiConCopy(Signal* signal)
-{
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TfirstfreeApiConnectCopyOld = cfirstfreeApiConnectCopy;
- cfirstfreeApiConnectCopy = apiConnectptr.i;
- regApiPtr->nextApiConnect = TfirstfreeApiConnectCopyOld;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- regApiPtr->apiConnectstate = CS_RESTART;
-}//Dbtc::releaseApiConCopy()
-
-/* ========================================================================= */
-/* ------- RELEASE ALL RECORDS CONNECTED TO A DIRTY WRITE OPERATION ------- */
-/* ========================================================================= */
-void Dbtc::releaseDirtyWrite(Signal* signal)
-{
- unlinkReadyTcCon(signal);
- releaseTcCon();
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
- if (regApiPtr->firstTcConnect == RNIL) {
- jam();
- regApiPtr->apiConnectstate = CS_CONNECTED;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- sendtckeyconf(signal, 1);
- }//if
- }//if
-}//Dbtc::releaseDirtyWrite()
-
-/*****************************************************************************
- * L Q H K E Y R E F
- * WHEN LQHKEYREF IS RECEIVED DBTC WILL CHECK IF COMMIT FLAG WAS SENT FROM THE
- * APPLICATION. IF SO, THE WHOLE TRANSACTION WILL BE ROLLED BACK AND SIGNAL
- * TCROLLBACKREP WILL BE SENT TO THE API.
- *
- * OTHERWISE TC WILL CHECK THE ERRORCODE. IF THE ERRORCODE IS INDICATING THAT
- * THE "ROW IS NOT FOUND" FOR UPDATE/READ/DELETE OPERATIONS AND "ROW ALREADY
- * EXISTS" FOR INSERT OPERATIONS, DBTC WILL RELEASE THE OPERATION AND THEN
- * SEND RETURN SIGNAL TCKEYREF TO THE USER. THE USER THEN HAVE TO SEND
- * SIGNAL TC_COMMITREQ OR TC_ROLLBACKREQ TO CONCLUDE THE TRANSACTION.
- * IF ANY TCKEYREQ WITH COMMIT IS RECEIVED AND API_CONNECTSTATE EQUALS
- * "REC_LQHREFUSE",
- * THE OPERATION WILL BE TREATED AS AN OPERATION WITHOUT COMMIT. WHEN ANY
- * OTHER FAULTCODE IS RECEIVED THE WHOLE TRANSACTION MUST BE ROLLED BACK
- *****************************************************************************/
-void Dbtc::execLQHKEYREF(Signal* signal)
-{
- const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr();
- Uint32 indexId = 0;
- jamEntry();
-
- UintR compare_transid1, compare_transid2;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- /*-------------------------------------------------------------------------
- *
- * RELEASE NODE BUFFER(S) TO INDICATE THAT THIS OPERATION HAVE NO
- * TRANSACTION PARTS ACTIVE ANYMORE.
- * LQHKEYREF HAVE CLEARED ALL PARTS ON ITS PATH BACK TO TC.
- *-------------------------------------------------------------------------*/
- if (lqhKeyRef->connectPtr < TtcConnectFilesize) {
- /*-----------------------------------------------------------------------
- * WE HAVE TO CHECK THAT THE TRANSACTION IS STILL VALID. FIRST WE CHECK
- * THAT THE LQH IS STILL CONNECTED TO A TC, IF THIS HOLDS TRUE THEN THE
- * TC MUST BE CONNECTED TO AN API CONNECT RECORD.
- * WE MUST ENSURE THAT THE TRANSACTION ID OF THIS API CONNECT
- * RECORD IS STILL THE SAME AS THE ONE LQHKEYREF REFERS TO.
- * IF NOT SIMPLY EXIT AND FORGET THE SIGNAL SINCE THE TRANSACTION IS
- * ALREADY COMPLETED (ABORTED).
- *-----------------------------------------------------------------------*/
- tcConnectptr.i = lqhKeyRef->connectPtr;
- Uint32 errCode = terrorCode = lqhKeyRef->errorCode;
- ptrAss(tcConnectptr, tcConnectRecord);
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- if (regTcPtr->tcConnectstate == OS_OPERATING) {
- Uint32 save = apiConnectptr.i = regTcPtr->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1;
- compare_transid2 = regApiPtr->transid[1] ^ lqhKeyRef->transId2;
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 25);
- return;
- }//if
-
- const ConnectionState state = regApiPtr->apiConnectstate;
- const Uint32 triggeringOp = regTcPtr->triggeringOperation;
- if (triggeringOp != RNIL) {
- jam();
- // This operation was created by a trigger execting operation
- TcConnectRecordPtr opPtr;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
-
- const Uint32 currentIndexId = regTcPtr->currentIndexId;
- ndbassert(currentIndexId != 0); // Only index triggers so far
-
- opPtr.i = triggeringOp;
- ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
-
- // The operation executed an index trigger
- TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
- indexId = indexData->indexId;
- regApiPtr->errorData = indexId;
- const Uint32 opType = regTcPtr->operation;
- if (errCode == ZALREADYEXIST)
- errCode = terrorCode = ZNOTUNIQUE;
- else if (!(opType == ZDELETE && errCode == ZNOT_FOUND)) {
- jam();
- /**
- * "Normal path"
- */
- // fall-through
- } else {
- jam();
- /** ZDELETE && NOT_FOUND */
- if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){
- jam();
- /**
- * Ignore error
- */
- regApiPtr->lqhkeyconfrec++;
-
- unlinkReadyTcCon(signal);
- releaseTcCon();
-
- opPtr.p->triggerExecutionCount--;
- if (opPtr.p->triggerExecutionCount == 0) {
- /**
- * We have completed current trigger execution
- * Continue triggering operation
- */
- jam();
- continueTriggeringOp(signal, opPtr.p);
- }
- return;
- }
- }
- }
-
- Uint32 marker = regTcPtr->commitAckMarker;
- markOperationAborted(regApiPtr, regTcPtr);
-
- if(regApiPtr->apiConnectstate == CS_ABORTING){
- /**
- * We're already aborting' so don't send an "extra" TCKEYREF
- */
- jam();
- return;
- }
-
- const Uint32 abort = regTcPtr->m_execAbortOption;
- if (abort == TcKeyReq::AbortOnError || triggeringOp != RNIL) {
- /**
- * No error is allowed on this operation
- */
- TCKEY_abort(signal, 49);
- return;
- }//if
-
- if (marker != RNIL){
- /**
- * This was an insert/update/delete/write which failed
- * that contained the marker
- * Currently unsupported to place new marker
- */
- TCKEY_abort(signal, 49);
- return;
- }
-
- /* Only ref in certain situations */
- {
- const Uint32 opType = regTcPtr->operation;
- if ( (opType == ZDELETE && errCode != ZNOT_FOUND)
- || (opType == ZINSERT && errCode != ZALREADYEXIST)
- || (opType == ZUPDATE && errCode != ZNOT_FOUND)
- || (opType == ZWRITE && errCode != 839 && errCode != 840))
- {
- TCKEY_abort(signal, 49);
- return;
- }
- }
-
- /* *************** */
- /* TCKEYREF < */
- /* *************** */
- TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend();
- tcKeyRef->transId[0] = regApiPtr->transid[0];
- tcKeyRef->transId[1] = regApiPtr->transid[1];
- tcKeyRef->errorCode = terrorCode;
- bool isIndexOp = regTcPtr->isIndexOp;
- Uint32 indexOp = tcConnectptr.p->indexOp;
- Uint32 clientData = regTcPtr->clientData;
- unlinkReadyTcCon(signal); /* LINK TC CONNECT RECORD OUT OF */
- releaseTcCon(); /* RELEASE THE TC CONNECT RECORD */
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- if (isIndexOp) {
- jam();
- regApiPtr->lqhkeyreqrec--; // Compensate for extra during read
- tcKeyRef->connectPtr = indexOp;
- tcKeyRef->errorData = indexId;
- EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength);
- apiConnectptr.i = save;
- apiConnectptr.p = regApiPtr;
- } else {
- jam();
- tcKeyRef->connectPtr = clientData;
- tcKeyRef->errorData = indexId;
- sendSignal(regApiPtr->ndbapiBlockref,
- GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
- }//if
-
- /*---------------------------------------------------------------------
- * SINCE WE ARE NOT ABORTING WE NEED TO UPDATE THE COUNT OF HOW MANY
- * LQHKEYREQ THAT HAVE RETURNED.
- * IF NO MORE OUTSTANDING LQHKEYREQ'S THEN WE NEED TO
- * TCKEYCONF (IF THERE IS ANYTHING TO SEND).
- *---------------------------------------------------------------------*/
- regApiPtr->lqhkeyreqrec--;
- if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) {
- if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
- jam();
- diverify010Lab(signal);
- return;
- } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) {
- jam();
- sendtckeyconf(signal, 2);
- return;
- }
- }//if
- return;
-
- } else {
- warningReport(signal, 26);
- }//if
- } else {
- errorReport(signal, 6);
- }//if
- return;
-}//Dbtc::execLQHKEYREF()
-
-void Dbtc::clearCommitAckMarker(ApiConnectRecord * const regApiPtr,
- TcConnectRecord * const regTcPtr)
-{
- const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- if (regApiPtr->commitAckMarker == RNIL)
- ndbassert(commitAckMarker == RNIL);
- if (commitAckMarker != RNIL)
- ndbassert(regApiPtr->commitAckMarker != RNIL);
- if(commitAckMarker != RNIL){
- jam();
- m_commitAckMarkerHash.release(commitAckMarker);
- regTcPtr->commitAckMarker = RNIL;
- regApiPtr->commitAckMarker = RNIL;
- }
-}
-
-void Dbtc::markOperationAborted(ApiConnectRecord * const regApiPtr,
- TcConnectRecord * const regTcPtr)
-{
- /*------------------------------------------------------------------------
- * RELEASE NODES TO INDICATE THAT THE OPERATION IS ALREADY ABORTED IN THE
- * LQH'S ALSO SET STATE TO ABORTING TO INDICATE THE ABORT IS
- * ALREADY COMPLETED.
- *------------------------------------------------------------------------*/
- regTcPtr->noOfNodes = 0; // == releaseNodes(signal)
- regTcPtr->tcConnectstate = OS_ABORTING;
- clearCommitAckMarker(regApiPtr, regTcPtr);
-}
-
-/*--------------------------------------*/
-/* EXIT AND WAIT FOR SIGNAL TCOMMITREQ */
-/* OR TCROLLBACKREQ FROM THE USER TO */
-/* CONTINUE THE TRANSACTION */
-/*--------------------------------------*/
-void Dbtc::execTC_COMMITREQ(Signal* signal)
-{
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
- apiConnectptr.i = signal->theData[0];
- if (apiConnectptr.i < capiConnectFilesize) {
- ptrAss(apiConnectptr, apiConnectRecord);
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- jam();
- return;
- }//if
-
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-
- const Uint32 apiConnectPtr = regApiPtr->ndbapiConnect;
- const Uint32 apiBlockRef = regApiPtr->ndbapiBlockref;
- const Uint32 transId1 = regApiPtr->transid[0];
- const Uint32 transId2 = regApiPtr->transid[1];
- Uint32 errorCode = 0;
-
- regApiPtr->m_exec_flag = 1;
- switch (regApiPtr->apiConnectstate) {
- case CS_STARTED:
- tcConnectptr.i = regApiPtr->firstTcConnect;
- if (tcConnectptr.i != RNIL) {
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) {
- jam();
- /*******************************************************************/
- // The proper case where the application is waiting for commit or
- // abort order.
- // Start the commit order.
- /*******************************************************************/
- regApiPtr->returnsignal = RS_TC_COMMITCONF;
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- diverify010Lab(signal);
- return;
- } else {
- jam();
- /*******************************************************************/
- // The transaction is started but not all operations are completed.
- // It is not possible to commit the transaction in this state.
- // We will abort it instead.
- /*******************************************************************/
- regApiPtr->returnsignal = RS_NO_RETURN;
- errorCode = ZTRANS_STATUS_ERROR;
- abort010Lab(signal);
- }//if
- } else {
- jam();
- /**
- * No operations, accept commit
- */
- TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
- commitConf->apiConnectPtr = apiConnectPtr;
- commitConf->transId1 = transId1;
- commitConf->transId2 = transId2;
- commitConf->gci = 0;
- sendSignal(apiBlockRef, GSN_TC_COMMITCONF, signal,
- TcCommitConf::SignalLength, JBB);
-
- regApiPtr->returnsignal = RS_NO_RETURN;
- releaseAbortResources(signal);
- return;
- }//if
- break;
- case CS_RECEIVING:
- jam();
- /***********************************************************************/
- // A transaction is still receiving data. We cannot commit an unfinished
- // transaction. We will abort it instead.
- /***********************************************************************/
- regApiPtr->returnsignal = RS_NO_RETURN;
- errorCode = ZPREPAREINPROGRESS;
- abort010Lab(signal);
- break;
-
- case CS_START_COMMITTING:
- case CS_COMMITTING:
- case CS_COMMIT_SENT:
- case CS_COMPLETING:
- case CS_COMPLETE_SENT:
- case CS_REC_COMMITTING:
- case CS_PREPARE_TO_COMMIT:
- jam();
- /***********************************************************************/
- // The transaction is already performing a commit but it is not concluded
- // yet.
- /***********************************************************************/
- errorCode = ZCOMMITINPROGRESS;
- break;
- case CS_ABORTING:
- jam();
- errorCode = regApiPtr->returncode ?
- regApiPtr->returncode : ZABORTINPROGRESS;
- break;
- case CS_START_SCAN:
- jam();
- /***********************************************************************/
- // The transaction is a scan. Scans cannot commit
- /***********************************************************************/
- errorCode = ZSCANINPROGRESS;
- break;
- case CS_PREPARED:
- jam();
- return;
- case CS_START_PREPARING:
- jam();
- return;
- case CS_REC_PREPARING:
- jam();
- return;
- break;
- default:
- warningHandlerLab(signal, __LINE__);
- return;
- }//switch
- TcCommitRef * const commitRef = (TcCommitRef*)&signal->theData[0];
- commitRef->apiConnectPtr = apiConnectPtr;
- commitRef->transId1 = transId1;
- commitRef->transId2 = transId2;
- commitRef->errorCode = errorCode;
- sendSignal(apiBlockRef, GSN_TC_COMMITREF, signal,
- TcCommitRef::SignalLength, JBB);
- return;
- } else /** apiConnectptr.i < capiConnectFilesize */ {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }
-}//Dbtc::execTC_COMMITREQ()
-
-/**
- * TCROLLBACKREQ
- *
- * Format is:
- *
- * thedata[0] = apiconnectptr
- * thedata[1] = transid[0]
- * thedata[2] = transid[1]
- * OPTIONAL thedata[3] = flags
- *
- * Flags:
- * 0x1 = potentiallyBad data from API (try not to assert)
- */
-void Dbtc::execTCROLLBACKREQ(Signal* signal)
-{
- bool potentiallyBad= false;
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
-
- if(unlikely((signal->getLength() >= 4) && (signal->theData[3] & 0x1)))
- {
- ndbout_c("Trying to roll back potentially bad txn\n");
- potentiallyBad= true;
- }
-
- apiConnectptr.i = signal->theData[0];
- if (apiConnectptr.i >= capiConnectFilesize) {
- goto TC_ROLL_warning;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- jam();
- return;
- }//if
-
- apiConnectptr.p->m_exec_flag = 1;
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_STARTED:
- case CS_RECEIVING:
- jam();
- apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
- abort010Lab(signal);
- return;
- case CS_CONNECTED:
- jam();
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKCONF,
- signal, 3, JBB);
- break;
- case CS_START_SCAN:
- case CS_PREPARE_TO_COMMIT:
- case CS_COMMITTING:
- case CS_COMMIT_SENT:
- case CS_COMPLETING:
- case CS_COMPLETE_SENT:
- case CS_WAIT_COMMIT_CONF:
- case CS_WAIT_COMPLETE_CONF:
- case CS_RESTART:
- case CS_DISCONNECTED:
- case CS_START_COMMITTING:
- case CS_REC_COMMITTING:
- jam();
- /* ***************< */
- /* TC_ROLLBACKREF < */
- /* ***************< */
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- signal->theData[3] = ZROLLBACKNOTALLOWED;
- signal->theData[4] = apiConnectptr.p->apiConnectstate;
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREF,
- signal, 5, JBB);
- break;
- /* SEND A REFUSAL SIGNAL*/
- case CS_ABORTING:
- jam();
- if (apiConnectptr.p->abortState == AS_IDLE) {
- jam();
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKCONF,
- signal, 3, JBB);
- } else {
- jam();
- apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
- }//if
- break;
- case CS_WAIT_ABORT_CONF:
- jam();
- apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
- break;
- case CS_START_PREPARING:
- jam();
- case CS_PREPARED:
- jam();
- case CS_REC_PREPARING:
- jam();
- default:
- goto TC_ROLL_system_error;
- break;
- }//switch
- return;
-
-TC_ROLL_warning:
- jam();
- if(likely(potentiallyBad==false))
- warningHandlerLab(signal, __LINE__);
- return;
-
-TC_ROLL_system_error:
- jam();
- if(likely(potentiallyBad==false))
- systemErrorLab(signal, __LINE__);
- return;
-}//Dbtc::execTCROLLBACKREQ()
-
-void Dbtc::execTC_HBREP(Signal* signal)
-{
- const TcHbRep * const tcHbRep =
- (TcHbRep *)signal->getDataPtr();
-
- jamEntry();
- apiConnectptr.i = tcHbRep->apiConnectPtr;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
-
- if (apiConnectptr.p->transid[0] == tcHbRep->transId1 &&
- apiConnectptr.p->transid[1] == tcHbRep->transId2){
-
- if (getApiConTimer(apiConnectptr.i) != 0){
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- } else {
- DEBUG("TCHBREP received when timer was off apiConnectptr.i="
- << apiConnectptr.i);
- }
- }
-}//Dbtc::execTCHBREP()
-
-/*
-4.3.15 ABORT
------------
-*/
-/*****************************************************************************/
-/* A B O R T */
-/* */
-/*****************************************************************************/
-void Dbtc::warningReport(Signal* signal, int place)
-{
- switch (place) {
- case 0:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "ABORTED to not active TC record" << endl;
-#endif
- break;
- case 1:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "ABORTED to TC record active with new transaction" << endl;
-#endif
- break;
- case 2:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "ABORTED to active TC record not expecting ABORTED" << endl;
-#endif
- break;
- case 3:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "ABORTED to TC rec active with trans but wrong node" << endl;
- ndbout << "This is ok when aborting in node failure situations" << endl;
-#endif
- break;
- case 4:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITTED in wrong state in Dbtc" << endl;
-#endif
- break;
- case 5:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITTED with wrong transid in Dbtc" << endl;
-#endif
- break;
- case 6:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETED in wrong state in Dbtc" << endl;
-#endif
- break;
- case 7:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETED with wrong transid in Dbtc" << endl;
-#endif
- break;
- case 8:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITCONF with tc-rec in wrong state in Dbtc" << endl;
-#endif
- break;
- case 9:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITCONF with api-rec in wrong state in Dbtc" <<endl;
-#endif
- break;
- case 10:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITCONF with wrong transid in Dbtc" << endl;
-#endif
- break;
- case 11:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMMITCONF from wrong nodeid in Dbtc" << endl;
-#endif
- break;
- case 12:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETECONF, tc-rec in wrong state in Dbtc" << endl;
-#endif
- break;
- case 13:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETECONF, api-rec in wrong state in Dbtc" << endl;
-#endif
- break;
- case 14:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETECONF with wrong transid in Dbtc" << endl;
-#endif
- break;
- case 15:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received COMPLETECONF from wrong nodeid in Dbtc" << endl;
-#endif
- break;
- case 16:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received ABORTCONF, tc-rec in wrong state in Dbtc" << endl;
-#endif
- break;
- case 17:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received ABORTCONF, api-rec in wrong state in Dbtc" << endl;
-#endif
- break;
- case 18:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received ABORTCONF with wrong transid in Dbtc" << endl;
-#endif
- break;
- case 19:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received ABORTCONF from wrong nodeid in Dbtc" << endl;
-#endif
- break;
- case 20:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Time-out waiting for ABORTCONF in Dbtc" << endl;
-#endif
- break;
- case 21:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Time-out waiting for COMMITCONF in Dbtc" << endl;
-#endif
- break;
- case 22:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Time-out waiting for COMPLETECONF in Dbtc" << endl;
-#endif
- break;
- case 23:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received LQHKEYCONF in wrong tc-state in Dbtc" << endl;
-#endif
- break;
- case 24:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received LQHKEYREF to wrong transid in Dbtc" << endl;
-#endif
- break;
- case 25:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received LQHKEYREF in wrong state in Dbtc" << endl;
-#endif
- break;
- case 26:
- jam();
-#ifdef ABORT_TRACE
- ndbout << "Received LQHKEYCONF to wrong transid in Dbtc" << endl;
-#endif
- break;
- case 27:
- jam();
- // printState(signal, 27);
-#ifdef ABORT_TRACE
- ndbout << "Received LQHKEYCONF in wrong api-state in Dbtc" << endl;
-#endif
- break;
- default:
- jam();
- break;
- }//switch
- return;
-}//Dbtc::warningReport()
-
-void Dbtc::errorReport(Signal* signal, int place)
-{
- switch (place) {
- case 0:
- jam();
- break;
- case 1:
- jam();
- break;
- case 2:
- jam();
- break;
- case 3:
- jam();
- break;
- case 4:
- jam();
- break;
- case 5:
- jam();
- break;
- case 6:
- jam();
- break;
- default:
- jam();
- break;
- }//switch
- systemErrorLab(signal, __LINE__);
- return;
-}//Dbtc::errorReport()
-
-/* ------------------------------------------------------------------------- */
-/* ------- ENTER ABORTED ------- */
-/* */
-/*-------------------------------------------------------------------------- */
-void Dbtc::execABORTED(Signal* signal)
-{
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- UintR Tnodeid = signal->theData[3];
- UintR TlastLqhInd = signal->theData[4];
-
- if (ERROR_INSERTED(8040)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_ABORTED, signal, 2000, 5);
- return;
- }//if
- /*------------------------------------------------------------------------
- * ONE PARTICIPANT IN THE TRANSACTION HAS REPORTED THAT IT IS ABORTED.
- *------------------------------------------------------------------------*/
- if (tcConnectptr.i >= ctcConnectFilesize) {
- errorReport(signal, 0);
- return;
- }//if
- /*-------------------------------------------------------------------------
- * WE HAVE TO CHECK THAT THIS IS NOT AN OLD SIGNAL BELONGING TO A
- * TRANSACTION ALREADY ABORTED. THIS CAN HAPPEN WHEN TIME-OUT OCCURS
- * IN TC WAITING FOR ABORTED.
- *-------------------------------------------------------------------------*/
- ptrAss(tcConnectptr, tcConnectRecord);
- if (tcConnectptr.p->tcConnectstate != OS_ABORT_SENT) {
- warningReport(signal, 2);
- return;
- /*-----------------------------------------------------------------------*/
- // ABORTED reported on an operation not expecting ABORT.
- /*-----------------------------------------------------------------------*/
- }//if
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- if (apiConnectptr.i >= capiConnectFilesize) {
- warningReport(signal, 0);
- return;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 1);
- return;
- }//if
- if (ERROR_INSERTED(8024)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
-
- /**
- * Release marker
- */
- clearCommitAckMarker(apiConnectptr.p, tcConnectptr.p);
-
- Uint32 i;
- Uint32 Tfound = 0;
- for (i = 0; i < tcConnectptr.p->noOfNodes; i++) {
- jam();
- if (tcConnectptr.p->tcNodedata[i] == Tnodeid) {
- /*---------------------------------------------------------------------
- * We have received ABORTED from one of the participants in this
- * operation in this aborted transaction.
- * Record all nodes that have completed abort.
- * If last indicator is set it means that no more replica has
- * heard of the operation and are thus also aborted.
- *---------------------------------------------------------------------*/
- jam();
- Tfound = 1;
- clearTcNodeData(signal, TlastLqhInd, i);
- }//if
- }//for
- if (Tfound == 0) {
- warningReport(signal, 3);
- return;
- }
- for (i = 0; i < tcConnectptr.p->noOfNodes; i++) {
- if (tcConnectptr.p->tcNodedata[i] != 0) {
- /*--------------------------------------------------------------------
- * There are still outstanding ABORTED's to wait for.
- *--------------------------------------------------------------------*/
- jam();
- return;
- }//if
- }//for
- tcConnectptr.p->noOfNodes = 0;
- tcConnectptr.p->tcConnectstate = OS_ABORTING;
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- apiConnectptr.p->counter--;
- if (apiConnectptr.p->counter > 0) {
- jam();
- /*----------------------------------------------------------------------
- * WE ARE STILL WAITING FOR MORE PARTICIPANTS TO SEND ABORTED.
- *----------------------------------------------------------------------*/
- return;
- }//if
- /*------------------------------------------------------------------------*/
- /* */
- /* WE HAVE NOW COMPLETED THE ABORT PROCESS. WE HAVE RECEIVED ABORTED */
- /* FROM ALL PARTICIPANTS IN THE TRANSACTION. WE CAN NOW RELEASE ALL */
- /* RESOURCES CONNECTED TO THE TRANSACTION AND SEND THE ABORT RESPONSE */
- /*------------------------------------------------------------------------*/
- releaseAbortResources(signal);
-}//Dbtc::execABORTED()
-
-void Dbtc::clearTcNodeData(Signal* signal,
- UintR TLastLqhIndicator,
- UintR Tstart)
-{
- UintR Ti;
- if (TLastLqhIndicator == ZTRUE) {
- for (Ti = Tstart ; Ti < tcConnectptr.p->noOfNodes; Ti++) {
- jam();
- tcConnectptr.p->tcNodedata[Ti] = 0;
- }//for
- } else {
- jam();
- tcConnectptr.p->tcNodedata[Tstart] = 0;
- }//for
-}//clearTcNodeData()
-
-void Dbtc::abortErrorLab(Signal* signal)
-{
- ptrGuard(apiConnectptr);
- ApiConnectRecord * transP = apiConnectptr.p;
- if (transP->apiConnectstate == CS_ABORTING && transP->abortState != AS_IDLE){
- jam();
- return;
- }
- transP->returnsignal = RS_TCROLLBACKREP;
- if(transP->returncode == 0){
- jam();
- transP->returncode = terrorCode;
- }
- abort010Lab(signal);
-}//Dbtc::abortErrorLab()
-
-void Dbtc::abort010Lab(Signal* signal)
-{
- ApiConnectRecord * transP = apiConnectptr.p;
- if (transP->apiConnectstate == CS_ABORTING && transP->abortState != AS_IDLE){
- jam();
- return;
- }
- transP->apiConnectstate = CS_ABORTING;
- /*------------------------------------------------------------------------*/
- /* AN ABORT DECISION HAS BEEN TAKEN FOR SOME REASON. WE NEED TO ABORT */
- /* ALL PARTICIPANTS IN THE TRANSACTION. */
- /*------------------------------------------------------------------------*/
- transP->abortState = AS_ACTIVE;
- transP->counter = 0;
-
- if (transP->firstTcConnect == RNIL) {
- jam();
- /*--------------------------------------------------------------------*/
- /* WE HAVE NO PARTICIPANTS IN THE TRANSACTION. */
- /*--------------------------------------------------------------------*/
- releaseAbortResources(signal);
- return;
- }//if
- tcConnectptr.i = transP->firstTcConnect;
- abort015Lab(signal);
-}//Dbtc::abort010Lab()
-
-/*--------------------------------------------------------------------------*/
-/* */
-/* WE WILL ABORT ONE NODE PER OPERATION AT A TIME. THIS IS TO KEEP */
-/* ERROR HANDLING OF THIS PROCESS FAIRLY SIMPLE AND TRACTABLE. */
-/* EVEN IF NO NODE OF THIS PARTICULAR NODE NUMBER NEEDS ABORTION WE */
-/* MUST ENSURE THAT ALL NODES ARE CHECKED. THUS A FAULTY NODE DOES */
-/* NOT MEAN THAT ALL NODES IN AN OPERATION IS ABORTED. FOR THIS REASON*/
-/* WE SET THE TCONTINUE_ABORT TO TRUE WHEN A FAULTY NODE IS DETECTED. */
-/*--------------------------------------------------------------------------*/
-void Dbtc::abort015Lab(Signal* signal)
-{
- Uint32 TloopCount = 0;
-ABORT020:
- jam();
- TloopCount++;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_WAIT_DIH:
- case OS_WAIT_KEYINFO:
- case OS_WAIT_ATTR:
- jam();
- /*----------------------------------------------------------------------*/
- /* WE ARE STILL WAITING FOR MORE KEYINFO/ATTRINFO. WE HAVE NOT CONTACTED*/
- /* ANY LQH YET AND SO WE CAN SIMPLY SET STATE TO ABORTING. */
- /*----------------------------------------------------------------------*/
- tcConnectptr.p->noOfNodes = 0; // == releaseAbort(signal)
- tcConnectptr.p->tcConnectstate = OS_ABORTING;
- break;
- case OS_CONNECTED:
- jam();
- /*-----------------------------------------------------------------------
- * WE ARE STILL IN THE INITIAL PHASE OF THIS OPERATION.
- * NEED NOT BOTHER ABOUT ANY LQH ABORTS.
- *-----------------------------------------------------------------------*/
- tcConnectptr.p->noOfNodes = 0; // == releaseAbort(signal)
- tcConnectptr.p->tcConnectstate = OS_ABORTING;
- break;
- case OS_PREPARED:
- jam();
- case OS_OPERATING:
- jam();
- /*----------------------------------------------------------------------
- * WE HAVE SENT LQHKEYREQ AND ARE IN SOME STATE OF EITHER STILL
- * SENDING THE OPERATION, WAITING FOR REPLIES, WAITING FOR MORE
- * ATTRINFO OR OPERATION IS PREPARED. WE NEED TO ABORT ALL LQH'S.
- *----------------------------------------------------------------------*/
- releaseAndAbort(signal);
- tcConnectptr.p->tcConnectstate = OS_ABORT_SENT;
- TloopCount += 127;
- break;
- case OS_ABORTING:
- jam();
- break;
- case OS_ABORT_SENT:
- jam();
- DEBUG("ABORT_SENT state in abort015Lab(), not expected");
- systemErrorLab(signal, __LINE__);
- return;
- default:
- jam();
- DEBUG("tcConnectstate = " << tcConnectptr.p->tcConnectstate);
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-
- if (tcConnectptr.p->nextTcConnect != RNIL) {
- jam();
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- if (TloopCount < 1024) {
- goto ABORT020;
- } else {
- jam();
- /*---------------------------------------------------------------------
- * Reset timer to avoid time-out in real-time break.
- * Increase counter to ensure that we don't think that all ABORTED have
- * been received before all have been sent.
- *---------------------------------------------------------------------*/
- apiConnectptr.p->counter++;
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- signal->theData[0] = TcContinueB::ZABORT_BREAK;
- signal->theData[1] = tcConnectptr.i;
- signal->theData[2] = apiConnectptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }//if
- }//if
- if (apiConnectptr.p->counter > 0) {
- jam();
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- return;
- }//if
- /*-----------------------------------------------------------------------
- * WE HAVE NOW COMPLETED THE ABORT PROCESS. WE HAVE RECEIVED ABORTED
- * FROM ALL PARTICIPANTS IN THE TRANSACTION. WE CAN NOW RELEASE ALL
- * RESOURCES CONNECTED TO THE TRANSACTION AND SEND THE ABORT RESPONSE
- *------------------------------------------------------------------------*/
- releaseAbortResources(signal);
-}//Dbtc::abort015Lab()
-
-/*--------------------------------------------------------------------------*/
-/* RELEASE KEY AND ATTRINFO OBJECTS AND SEND ABORT TO THE LQH BLOCK. */
-/*--------------------------------------------------------------------------*/
-int Dbtc::releaseAndAbort(Signal* signal)
-{
- HostRecordPtr localHostptr;
- UintR TnoLoops = tcConnectptr.p->noOfNodes;
-
- apiConnectptr.p->counter++;
- bool prevAlive = false;
- for (Uint32 Ti = 0; Ti < TnoLoops ; Ti++) {
- localHostptr.i = tcConnectptr.p->tcNodedata[Ti];
- ptrCheckGuard(localHostptr, chostFilesize, hostRecord);
- if (localHostptr.p->hostStatus == HS_ALIVE) {
- jam();
- if (prevAlive) {
- // if previous is alive, its LQH forwards abort to this node
- jam();
- continue;
- }
- /* ************< */
- /* ABORT < */
- /* ************< */
- tblockref = calcLqhBlockRef(localHostptr.i);
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = apiConnectptr.p->transid[0];
- signal->theData[3] = apiConnectptr.p->transid[1];
- sendSignal(tblockref, GSN_ABORT, signal, 4, JBB);
- prevAlive = true;
- } else {
- jam();
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- signal->theData[3] = localHostptr.i;
- signal->theData[4] = ZFALSE;
- sendSignal(cownref, GSN_ABORTED, signal, 5, JBB);
- prevAlive = false;
- }//if
- }//for
- return 1;
-}//Dbtc::releaseAndAbort()
-
-/* ------------------------------------------------------------------------- */
-/* ------- ENTER TIME_SIGNAL ------- */
-/* */
-/* ------------------------------------------------------------------------- */
-void Dbtc::execTIME_SIGNAL(Signal* signal)
-{
-
- jamEntry();
- ctcTimer++;
- if (csystemStart != SSS_TRUE) {
- jam();
- return;
- }//if
- checkStartTimeout(signal);
- checkStartFragTimeout(signal);
-}//Dbtc::execTIME_SIGNAL()
-
-/*------------------------------------------------*/
-/* Start timeout handling if not already going on */
-/*------------------------------------------------*/
-void Dbtc::checkStartTimeout(Signal* signal)
-{
- ctimeOutCheckCounter++;
- if (ctimeOutCheckActive == TOCS_TRUE) {
- jam();
- // Check heartbeat of timeout loop
- if(ctimeOutCheckHeartbeat > ctimeOutCheckLastHeartbeat){
- jam();
- ctimeOutMissedHeartbeats = 0;
- }else{
- jam();
- ctimeOutMissedHeartbeats++;
- if (ctimeOutMissedHeartbeats > 100){
- jam();
- systemErrorLab(signal, __LINE__);
- }
- }
- ctimeOutCheckLastHeartbeat = ctimeOutCheckHeartbeat;
- return;
- }//if
- if (ctimeOutCheckCounter < ctimeOutCheckDelay) {
- jam();
- /*------------------------------------------------------------------*/
- /* */
- /* NO TIME-OUT CHECKED THIS TIME. WAIT MORE. */
- /*------------------------------------------------------------------*/
- return;
- }//if
- ctimeOutCheckActive = TOCS_TRUE;
- ctimeOutCheckCounter = 0;
- timeOutLoopStartLab(signal, 0); // 0 is first api connect record
- return;
-}//Dbtc::execTIME_SIGNAL()
-
-/*----------------------------------------------------------------*/
-/* Start fragment (scan) timeout handling if not already going on */
-/*----------------------------------------------------------------*/
-void Dbtc::checkStartFragTimeout(Signal* signal)
-{
- ctimeOutCheckFragCounter++;
- if (ctimeOutCheckFragActive == TOCS_TRUE) {
- jam();
- return;
- }//if
- if (ctimeOutCheckFragCounter < ctimeOutCheckDelay) {
- jam();
- /*------------------------------------------------------------------*/
- /* NO TIME-OUT CHECKED THIS TIME. WAIT MORE. */
- /*------------------------------------------------------------------*/
- return;
- }//if
-
- // Go through the fragment records and look for timeout in a scan.
- ctimeOutCheckFragActive = TOCS_TRUE;
- ctimeOutCheckFragCounter = 0;
- timeOutLoopStartFragLab(signal, 0); // 0 means first scan record
-}//checkStartFragTimeout()
-
-/*------------------------------------------------------------------*/
-/* IT IS NOW TIME TO CHECK WHETHER ANY TRANSACTIONS HAVE */
-/* BEEN DELAYED FOR SO LONG THAT WE ARE FORCED TO PERFORM */
-/* SOME ACTION, EITHER ABORT OR RESEND OR REMOVE A NODE FROM */
-/* THE WAITING PART OF A PROTOCOL. */
-/*
-The algorithm used here is to check 1024 transactions at a time before
-doing a real-time break.
-To avoid aborting both transactions in a deadlock detected by time-out
-we insert a random extra time-out of upto 630 ms by using the lowest
-six bits of the api connect reference.
-We spread it out from 0 to 630 ms if base time-out is larger than 3 sec,
-we spread it out from 0 to 70 ms if base time-out is smaller than 300 msec,
-and otherwise we spread it out 310 ms.
-*/
-/*------------------------------------------------------------------*/
-void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr)
-{
- Uint32 end_ptr, time_passed, time_out_value, mask_value;
- Uint32 old_mask_value= 0;
- const Uint32 api_con_sz= capiConnectFilesize;
- const Uint32 tc_timer= ctcTimer;
- const Uint32 time_out_param= ctimeOutValue;
- const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
-
- ctimeOutCheckHeartbeat = tc_timer;
-
- if (api_con_ptr + 1024 < api_con_sz) {
- jam();
- end_ptr= api_con_ptr + 1024;
- } else {
- jam();
- end_ptr= api_con_sz;
- }
- if (time_out_param > 300) {
- jam();
- mask_value= 63;
- } else if (time_out_param < 30) {
- jam();
- mask_value= 7;
- } else {
- jam();
- mask_value= 31;
- }
- if (time_out_param != old_time_out_param &&
- getNodeState().getSingleUserMode())
- {
- // abort during single user mode, use old_mask_value as flag
- // and calculate value to be used for connections with allowed api
- if (old_time_out_param > 300) {
- jam();
- old_mask_value= 63;
- } else if (old_time_out_param < 30) {
- jam();
- old_mask_value= 7;
- } else {
- jam();
- old_mask_value= 31;
- }
- }
- for ( ; api_con_ptr < end_ptr; api_con_ptr++) {
- Uint32 api_timer= getApiConTimer(api_con_ptr);
- jam();
- if (api_timer != 0) {
- Uint32 error= ZTIME_OUT_ERROR;
- time_out_value= time_out_param + (ndb_rand() & mask_value);
- if (unlikely(old_mask_value)) // abort during single user mode
- {
- apiConnectptr.i = api_con_ptr;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- if ((getNodeState().getSingleUserApi() ==
- refToNode(apiConnectptr.p->ndbapiBlockref)) ||
- !(apiConnectptr.p->singleUserMode & (1 << NDB_SUM_LOCKED)))
- {
- // api allowed during single user, use original timeout
- time_out_value=
- old_time_out_param + (api_con_ptr & old_mask_value);
- }
- else
- {
- error= ZCLUSTER_IN_SINGLEUSER_MODE;
- }
- }
- time_passed= tc_timer - api_timer;
- if (time_passed > time_out_value)
- {
- jam();
- timeOutFoundLab(signal, api_con_ptr, error);
- api_con_ptr++;
- break;
- }
- }
- }
- if (api_con_ptr == api_con_sz) {
- jam();
- /*------------------------------------------------------------------*/
- /* */
- /* WE HAVE NOW CHECKED ALL TRANSACTIONS FOR TIME-OUT AND ALSO */
- /* STARTED TIME-OUT HANDLING OF THOSE WE FOUND. WE ARE NOW */
- /* READY AND CAN WAIT FOR THE NEXT TIME-OUT CHECK. */
- /*------------------------------------------------------------------*/
- ctimeOutCheckActive = TOCS_FALSE;
- } else {
- jam();
- sendContinueTimeOutControl(signal, api_con_ptr);
- }
- return;
-}//Dbtc::timeOutLoopStartLab()
-
-void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
-{
- apiConnectptr.i = TapiConPtr;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- /*------------------------------------------------------------------*/
- /* */
- /* THIS TRANSACTION HAVE EXPERIENCED A TIME-OUT AND WE NEED TO*/
- /* FIND OUT WHAT WE NEED TO DO BASED ON THE STATE INFORMATION.*/
- /*------------------------------------------------------------------*/
- DEBUG("[ H'" << hex << apiConnectptr.p->transid[0]
- << " H'" << apiConnectptr.p->transid[1] << "] " << dec
- << "Time-out in state = " << apiConnectptr.p->apiConnectstate
- << " apiConnectptr.i = " << apiConnectptr.i
- << " - exec: " << apiConnectptr.p->m_exec_flag
- << " - place: " << c_apiConTimer_line[apiConnectptr.i]
- << " code: " << errCode);
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_STARTED:
- if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec &&
- errCode != ZCLUSTER_IN_SINGLEUSER_MODE){
- jam();
- /*
- We are waiting for application to continue the transaction. In this
- particular state we will use the application timeout parameter rather
- than the shorter Deadlock detection timeout.
- */
- if (c_appl_timeout_value == 0 ||
- (ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) {
- jam();
- return;
- }//if
- }
- apiConnectptr.p->returnsignal = RS_TCROLLBACKREP;
- apiConnectptr.p->returncode = errCode;
- abort010Lab(signal);
- return;
- case CS_RECEIVING:
- case CS_REC_COMMITTING:
- case CS_START_COMMITTING:
- jam();
- /*------------------------------------------------------------------*/
- /* WE ARE STILL IN THE PREPARE PHASE AND THE TRANSACTION HAS */
- /* NOT YET REACHED ITS COMMIT POINT. THUS IT IS NOW OK TO */
- /* START ABORTING THE TRANSACTION. ALSO START CHECKING THE */
- /* REMAINING TRANSACTIONS. */
- /*------------------------------------------------------------------*/
- terrorCode = errCode;
- abortErrorLab(signal);
- return;
- case CS_COMMITTING:
- jam();
- /*------------------------------------------------------------------*/
- // We are simply waiting for a signal in the job buffer. Only extreme
- // conditions should get us here. We ignore it.
- /*------------------------------------------------------------------*/
- case CS_COMPLETING:
- jam();
- /*------------------------------------------------------------------*/
- // We are simply waiting for a signal in the job buffer. Only extreme
- // conditions should get us here. We ignore it.
- /*------------------------------------------------------------------*/
- case CS_PREPARE_TO_COMMIT:
- {
- jam();
- /*------------------------------------------------------------------*/
- /* WE ARE WAITING FOR DIH TO COMMIT THE TRANSACTION. WE SIMPLY*/
- /* KEEP WAITING SINCE THERE IS NO BETTER IDEA ON WHAT TO DO. */
- /* IF IT IS BLOCKED THEN NO TRANSACTION WILL PASS THIS GATE. */
- // To ensure against strange bugs we crash the system if we have passed
- // time-out period by a factor of 10 and it is also at least 5 seconds.
- /*------------------------------------------------------------------*/
- Uint32 time_passed = ctcTimer - getApiConTimer(apiConnectptr.i);
- if (time_passed > 500 &&
- time_passed > (5 * cDbHbInterval) &&
- time_passed > (10 * ctimeOutValue))
- {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- break;
- }
- case CS_COMMIT_SENT:
- jam();
- /*------------------------------------------------------------------*/
- /* WE HAVE SENT COMMIT TO A NUMBER OF NODES. WE ARE CURRENTLY */
- /* WAITING FOR THEIR REPLY. WITH NODE RECOVERY SUPPORTED WE */
- /* WILL CHECK FOR CRASHED NODES AND RESEND THE COMMIT SIGNAL */
- /* TO THOSE NODES THAT HAVE MISSED THE COMMIT SIGNAL DUE TO */
- /* A NODE FAILURE. */
- /*------------------------------------------------------------------*/
- tabortInd = ZCOMMIT_SETUP;
- setupFailData(signal);
- toCommitHandlingLab(signal);
- return;
- case CS_COMPLETE_SENT:
- jam();
- /*--------------------------------------------------------------------*/
- /* WE HAVE SENT COMPLETE TO A NUMBER OF NODES. WE ARE CURRENTLY */
- /* WAITING FOR THEIR REPLY. WITH NODE RECOVERY SUPPORTED WE */
- /* WILL CHECK FOR CRASHED NODES AND RESEND THE COMPLETE SIGNAL */
- /* TO THOSE NODES THAT HAVE MISSED THE COMPLETE SIGNAL DUE TO */
- /* A NODE FAILURE. */
- /*--------------------------------------------------------------------*/
- tabortInd = ZCOMMIT_SETUP;
- setupFailData(signal);
- toCompleteHandlingLab(signal);
- return;
- case CS_ABORTING:
- jam();
- /*------------------------------------------------------------------*/
- /* TIME-OUT DURING ABORT. WE NEED TO SEND ABORTED FOR ALL */
- /* NODES THAT HAVE FAILED BEFORE SENDING ABORTED. */
- /*------------------------------------------------------------------*/
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- sendAbortedAfterTimeout(signal, 0);
- break;
- case CS_START_SCAN:{
- jam();
-
- /*
- We are waiting for application to continue the transaction. In this
- particular state we will use the application timeout parameter rather
- than the shorter Deadlock detection timeout.
- */
- if (c_appl_timeout_value == 0 ||
- (ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) {
- jam();
- return;
- }//if
-
- ScanRecordPtr scanPtr;
- scanPtr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
- scanError(signal, scanPtr, ZSCANTIME_OUT_ERROR);
- break;
- }
- case CS_WAIT_ABORT_CONF:
- jam();
- tcConnectptr.i = apiConnectptr.p->currentTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- /*------------------------------------------------------------------*/
- // Time-out waiting for ABORTCONF. We will resend the ABORTREQ just in
- // case.
- /*------------------------------------------------------------------*/
- warningReport(signal, 20);
- apiConnectptr.p->timeOutCounter++;
- if (apiConnectptr.p->timeOutCounter > 3) {
- /*------------------------------------------------------------------*/
- // 100 time-outs are not acceptable. We will shoot down the node
- // not responding.
- /*------------------------------------------------------------------*/
- reportNodeFailed(signal, hostptr.i);
- }//if
- apiConnectptr.p->currentReplicaNo++;
- }//if
- tcurrentReplicaNo = (Uint8)Z8NIL;
- toAbortHandlingLab(signal);
- return;
- case CS_WAIT_COMMIT_CONF:
- jam();
- CRASH_INSERTION(8053);
- tcConnectptr.i = apiConnectptr.p->currentTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- /*------------------------------------------------------------------*/
- // Time-out waiting for COMMITCONF. We will resend the COMMITREQ just in
- // case.
- /*------------------------------------------------------------------*/
- warningReport(signal, 21);
- apiConnectptr.p->timeOutCounter++;
- if (apiConnectptr.p->timeOutCounter > 3) {
- /*------------------------------------------------------------------*/
- // 100 time-outs are not acceptable. We will shoot down the node
- // not responding.
- /*------------------------------------------------------------------*/
- reportNodeFailed(signal, hostptr.i);
- }//if
- apiConnectptr.p->currentReplicaNo++;
- }//if
- tcurrentReplicaNo = (Uint8)Z8NIL;
- toCommitHandlingLab(signal);
- return;
- case CS_WAIT_COMPLETE_CONF:
- jam();
- tcConnectptr.i = apiConnectptr.p->currentTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- /*------------------------------------------------------------------*/
- // Time-out waiting for COMPLETECONF. We will resend the COMPLETEREQ
- // just in case.
- /*------------------------------------------------------------------*/
- warningReport(signal, 22);
- apiConnectptr.p->timeOutCounter++;
- if (apiConnectptr.p->timeOutCounter > 100) {
- /*------------------------------------------------------------------*/
- // 100 time-outs are not acceptable. We will shoot down the node
- // not responding.
- /*------------------------------------------------------------------*/
- reportNodeFailed(signal, hostptr.i);
- }//if
- apiConnectptr.p->currentReplicaNo++;
- }//if
- tcurrentReplicaNo = (Uint8)Z8NIL;
- toCompleteHandlingLab(signal);
- return;
- case CS_FAIL_PREPARED:
- jam();
- case CS_FAIL_COMMITTING:
- jam();
- case CS_FAIL_COMMITTED:
- jam();
- case CS_REC_PREPARING:
- jam();
- case CS_START_PREPARING:
- jam();
- case CS_PREPARED:
- jam();
- case CS_RESTART:
- jam();
- case CS_FAIL_ABORTED:
- jam();
- case CS_DISCONNECTED:
- jam();
- default:
- jam();
- /*------------------------------------------------------------------*/
- /* AN IMPOSSIBLE STATE IS SET. CRASH THE SYSTEM. */
- /*------------------------------------------------------------------*/
- DEBUG("State = " << apiConnectptr.p->apiConnectstate);
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
- return;
-}//Dbtc::timeOutFoundLab()
-
-void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck)
-{
- ApiConnectRecord * transP = apiConnectptr.p;
- if(transP->abortState == AS_IDLE){
- jam();
- warningEvent("TC: %d: %d state=%d abort==IDLE place: %d fop=%d t: %d",
- __LINE__,
- apiConnectptr.i,
- transP->apiConnectstate,
- c_apiConTimer_line[apiConnectptr.i],
- transP->firstTcConnect,
- c_apiConTimer[apiConnectptr.i]
- );
- ndbout_c("TC: %d: %d state=%d abort==IDLE place: %d fop=%d t: %d",
- __LINE__,
- apiConnectptr.i,
- transP->apiConnectstate,
- c_apiConTimer_line[apiConnectptr.i],
- transP->firstTcConnect,
- c_apiConTimer[apiConnectptr.i]
- );
- ndbrequire(false);
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- return;
- }
-
- bool found = false;
- OperationState tmp[16];
-
- Uint32 TloopCount = 0;
- do {
- jam();
- if (tcConnectptr.i == RNIL) {
- jam();
-
-#ifdef VM_TRACE
- ndbout_c("found: %d Tcheck: %d apiConnectptr.p->counter: %d",
- found, Tcheck, apiConnectptr.p->counter);
-#endif
- if (found || apiConnectptr.p->counter)
- {
- jam();
- /**
- * We sent atleast one ABORT/ABORTED
- * or ZABORT_TIMEOUT_BREAK is in job buffer
- * wait for reception...
- */
- return;
- }
-
- if (Tcheck == 1)
- {
- jam();
- releaseAbortResources(signal);
- return;
- }
-
- if (Tcheck == 0)
- {
- jam();
- /*------------------------------------------------------------------
- * All nodes had already reported ABORTED for all tcConnect records.
- * Crash since it is an error situation that we then received a
- * time-out.
- *------------------------------------------------------------------*/
- char buf[96]; buf[0] = 0;
- char buf2[96];
- BaseString::snprintf(buf, sizeof(buf), "TC %d: %d counter: %d ops:",
- __LINE__, apiConnectptr.i,
- apiConnectptr.p->counter);
- for(Uint32 i = 0; i<TloopCount; i++)
- {
- BaseString::snprintf(buf2, sizeof(buf2), "%s %d", buf, tmp[i]);
- BaseString::snprintf(buf, sizeof(buf), buf2);
- }
- warningEvent(buf);
- ndbout_c(buf);
- ndbrequire(false);
- releaseAbortResources(signal);
- return;
- }
-
- return;
- }//if
- TloopCount++;
- if (TloopCount >= 1024) {
- jam();
- /*------------------------------------------------------------------*/
- // Insert a real-time break for large transactions to avoid blowing
- // away the job buffer.
- /*------------------------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- apiConnectptr.p->counter++;
- signal->theData[0] = TcContinueB::ZABORT_TIMEOUT_BREAK;
- signal->theData[1] = tcConnectptr.i;
- signal->theData[2] = apiConnectptr.i;
- if (ERROR_INSERTED(8050))
- {
- ndbout_c("sending ZABORT_TIMEOUT_BREAK delayed (%d %d)",
- Tcheck, apiConnectptr.p->counter);
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 2000, 3);
- }
- else
- {
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- }
- return;
- }//if
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- if(TloopCount < 16){
- jam();
- tmp[TloopCount-1] = tcConnectptr.p->tcConnectstate;
- }
-
- if (tcConnectptr.p->tcConnectstate == OS_ABORT_SENT) {
- jam();
- /*------------------------------------------------------------------*/
- // We have sent an ABORT signal to this node but not yet received any
- // reply. We have to send an ABORTED signal on our own in some cases.
- // If the node is declared as up and running and still do not respond
- // in time to the ABORT signal we will declare it as dead.
- /*------------------------------------------------------------------*/
- UintR Ti = 0;
- arrGuard(tcConnectptr.p->noOfNodes, MAX_REPLICAS+1);
- for (Ti = 0; Ti < tcConnectptr.p->noOfNodes; Ti++) {
- jam();
- if (tcConnectptr.p->tcNodedata[Ti] != 0) {
- TloopCount += 31;
- found = true;
- hostptr.i = tcConnectptr.p->tcNodedata[Ti];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- jam();
- /*---------------------------------------------------------------
- * A backup replica has not sent ABORTED.
- * Could be that a node before him has crashed.
- * Send an ABORT signal specifically to this node.
- * We will not send to any more nodes after this
- * to avoid race problems.
- * To also ensure that we use this message also as a heartbeat
- * we will move this node to the primary replica seat.
- * The primary replica and any failed node after it will
- * be removed from the node list. Update also number of nodes.
- * Finally break the loop to ensure we don't mess
- * things up by executing another loop.
- * We also update the timer to ensure we don't get time-out
- * too early.
- *--------------------------------------------------------------*/
- BlockReference TBRef = calcLqhBlockRef(hostptr.i);
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = apiConnectptr.p->transid[0];
- signal->theData[3] = apiConnectptr.p->transid[1];
- sendSignal(TBRef, GSN_ABORT, signal, 4, JBB);
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- break;
- } else {
- jam();
- /*--------------------------------------------------------------
- * The node we are waiting for is dead. We will send ABORTED to
- * ourselves vicarious for the failed node.
- *--------------------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- signal->theData[3] = hostptr.i;
- signal->theData[4] = ZFALSE;
- sendSignal(cownref, GSN_ABORTED, signal, 5, JBB);
- }//if
- }//if
- }//for
- }//if
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- } while (1);
-}//Dbtc::sendAbortedAfterTimeout()
-
-void Dbtc::reportNodeFailed(Signal* signal, Uint32 nodeId)
-{
- DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
- rep->nodeId = nodeId;
- rep->err = DisconnectRep::TcReportNodeFailed;
- sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
- DisconnectRep::SignalLength, JBB);
-}//Dbtc::reportNodeFailed()
-
-/*-------------------------------------------------*/
-/* Timeout-loop for scanned fragments. */
-/*-------------------------------------------------*/
-void Dbtc::timeOutLoopStartFragLab(Signal* signal, Uint32 TscanConPtr)
-{
- ScanFragRecPtr timeOutPtr[8];
- UintR tfragTimer[8];
- UintR texpiredTime[8];
- UintR TloopCount = 0;
- Uint32 TtcTimer = ctcTimer;
-
- while ((TscanConPtr + 8) < cscanFragrecFileSize) {
- jam();
- timeOutPtr[0].i = TscanConPtr + 0;
- timeOutPtr[1].i = TscanConPtr + 1;
- timeOutPtr[2].i = TscanConPtr + 2;
- timeOutPtr[3].i = TscanConPtr + 3;
- timeOutPtr[4].i = TscanConPtr + 4;
- timeOutPtr[5].i = TscanConPtr + 5;
- timeOutPtr[6].i = TscanConPtr + 6;
- timeOutPtr[7].i = TscanConPtr + 7;
-
- 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;
- tfragTimer[2] = timeOutPtr[2].p->scanFragTimer;
- tfragTimer[3] = timeOutPtr[3].p->scanFragTimer;
- tfragTimer[4] = timeOutPtr[4].p->scanFragTimer;
- tfragTimer[5] = timeOutPtr[5].p->scanFragTimer;
- tfragTimer[6] = timeOutPtr[6].p->scanFragTimer;
- tfragTimer[7] = timeOutPtr[7].p->scanFragTimer;
-
- texpiredTime[0] = TtcTimer - tfragTimer[0];
- texpiredTime[1] = TtcTimer - tfragTimer[1];
- texpiredTime[2] = TtcTimer - tfragTimer[2];
- texpiredTime[3] = TtcTimer - tfragTimer[3];
- texpiredTime[4] = TtcTimer - tfragTimer[4];
- texpiredTime[5] = TtcTimer - tfragTimer[5];
- texpiredTime[6] = TtcTimer - tfragTimer[6];
- texpiredTime[7] = TtcTimer - tfragTimer[7];
-
- for (Uint32 Ti = 0; Ti < 8; Ti++) {
- jam();
- if (tfragTimer[Ti] != 0) {
-
- if (texpiredTime[Ti] > ctimeOutValue) {
- jam();
- DEBUG("Fragment timeout found:"<<
- " ctimeOutValue=" <<ctimeOutValue
- <<", texpiredTime="<<texpiredTime[Ti]<<endl
- <<" tfragTimer="<<tfragTimer[Ti]
- <<", ctcTimer="<<ctcTimer);
- timeOutFoundFragLab(signal, TscanConPtr + Ti);
- return;
- }//if
- }//if
- }//for
- TscanConPtr += 8;
- /*----------------------------------------------------------------*/
- /* We split the process up checking 1024 fragmentrecords at a time*/
- /* to maintain real time behaviour. */
- /*----------------------------------------------------------------*/
- if (TloopCount++ > 128 ) {
- jam();
- signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL;
- signal->theData[1] = TscanConPtr;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }//if
- }//while
- for ( ; TscanConPtr < cscanFragrecFileSize; TscanConPtr++){
- jam();
- timeOutPtr[0].i = TscanConPtr;
- c_scan_frag_pool.getPtrForce(timeOutPtr[0]);
- if (timeOutPtr[0].p->scanFragTimer != 0) {
- texpiredTime[0] = ctcTimer - timeOutPtr[0].p->scanFragTimer;
- if (texpiredTime[0] > ctimeOutValue) {
- jam();
- DEBUG("Fragment timeout found:"<<
- " ctimeOutValue=" <<ctimeOutValue
- <<", texpiredTime="<<texpiredTime[0]<<endl
- <<" tfragTimer="<<tfragTimer[0]
- <<", ctcTimer="<<ctcTimer);
- timeOutFoundFragLab(signal, TscanConPtr);
- return;
- }//if
- }//if
- }//for
- ctimeOutCheckFragActive = TOCS_FALSE;
-
- return;
-}//timeOutLoopStartFragLab()
-
-/*--------------------------------------------------------------------------*/
-/*Handle the heartbeat signal from LQH in a scan process */
-// (Set timer on fragrec.)
-/*--------------------------------------------------------------------------*/
-void Dbtc::execSCAN_HBREP(Signal* signal)
-{
- jamEntry();
-
- scanFragptr.i = signal->theData[0];
- c_scan_frag_pool.getPtr(scanFragptr);
- switch (scanFragptr.p->scanFragState){
- case ScanFragRec::LQH_ACTIVE:
- break;
- default:
- DEBUG("execSCAN_HBREP: scanFragState="<<scanFragptr.p->scanFragState);
- systemErrorLab(signal, __LINE__);
- break;
- }
-
- ScanRecordPtr scanptr;
- scanptr.i = scanFragptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- apiConnectptr.i = scanptr.p->scanApiRec;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
-
- if (!(apiConnectptr.p->transid[0] == signal->theData[1] &&
- apiConnectptr.p->transid[1] == signal->theData[2])){
- jam();
- /**
- * Send signal back to sender so that the crash occurs there
- */
- // Save original transid
- signal->theData[3] = signal->theData[0];
- signal->theData[4] = signal->theData[1];
- // Set transid to illegal values
- signal->theData[1] = RNIL;
- signal->theData[2] = RNIL;
-
- sendSignal(signal->senderBlockRef(), GSN_SCAN_HBREP, signal, 5, JBA);
- DEBUG("SCAN_HBREP with wrong transid("
- <<signal->theData[3]<<", "<<signal->theData[4]<<")");
- return;
- }//if
-
- // Update timer on ScanFragRec
- if (scanFragptr.p->scanFragTimer != 0){
- updateBuddyTimer(apiConnectptr);
- scanFragptr.p->startFragTimer(ctcTimer);
- } else {
- ndbassert(false);
- DEBUG("SCAN_HBREP when scanFragTimer was turned off");
- }
-}//execSCAN_HBREP()
-
-/*--------------------------------------------------------------------------*/
-/* Timeout has occured on a fragment which means a scan has timed out. */
-/* If this is true we have an error in LQH/ACC. */
-/*--------------------------------------------------------------------------*/
-void Dbtc::timeOutFoundFragLab(Signal* signal, UintR TscanConPtr)
-{
- ScanFragRecPtr ptr;
- c_scan_frag_pool.getPtr(ptr, TscanConPtr);
- DEBUG(TscanConPtr << " timeOutFoundFragLab: scanFragState = "<< ptr.p->scanFragState);
-
- const Uint32 time_out_param= ctimeOutValue;
- const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
-
- if (unlikely(time_out_param != old_time_out_param &&
- getNodeState().getSingleUserMode()))
- {
- jam();
- ScanRecordPtr scanptr;
- scanptr.i = ptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- ApiConnectRecordPtr TlocalApiConnectptr;
- TlocalApiConnectptr.i = scanptr.p->scanApiRec;
- ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
-
- if (refToNode(TlocalApiConnectptr.p->ndbapiBlockref) ==
- getNodeState().getSingleUserApi())
- {
- jam();
- Uint32 val = ctcTimer - ptr.p->scanFragTimer;
- if (val <= old_time_out_param)
- {
- jam();
- goto next;
- }
- }
- }
-
- /*-------------------------------------------------------------------------*/
- // The scan fragment has expired its timeout. Check its state to decide
- // what to do.
- /*-------------------------------------------------------------------------*/
- switch (ptr.p->scanFragState) {
- case ScanFragRec::WAIT_GET_PRIMCONF:
- jam();
- ndbrequire(false);
- break;
- case ScanFragRec::LQH_ACTIVE:{
- jam();
-
- /**
- * The LQH expired it's timeout, try to close it
- */
- Uint32 nodeId = refToNode(ptr.p->lqhBlockref);
- Uint32 connectCount = getNodeInfo(nodeId).m_connectCount;
- ScanRecordPtr scanptr;
- scanptr.i = ptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- if(connectCount != ptr.p->m_connectCount){
- jam();
- /**
- * The node has died
- */
- ptr.p->scanFragState = ScanFragRec::COMPLETED;
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(ptr);
- ptr.p->stopFragTimer();
- }
-
- scanError(signal, scanptr, ZSCAN_FRAG_LQH_ERROR);
- break;
- }
- case ScanFragRec::DELIVERED:
- jam();
- case ScanFragRec::IDLE:
- jam();
- case ScanFragRec::QUEUED_FOR_DELIVERY:
- jam();
- /*-----------------------------------------------------------------------
- * Should never occur. We will simply report set the timer to zero and
- * continue. In a debug version we should crash here but not in a release
- * version. In a release version we will simply set the time-out to zero.
- *-----------------------------------------------------------------------*/
-#ifdef VM_TRACE
- systemErrorLab(signal, __LINE__);
-#endif
- scanFragptr.p->stopFragTimer();
- break;
- default:
- jam();
- /*-----------------------------------------------------------------------
- * Non-existent state. Crash.
- *-----------------------------------------------------------------------*/
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
-
-next:
- signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL;
- signal->theData[1] = TscanConPtr + 1;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- return;
-}//timeOutFoundFragLab()
-
-
-/*
- 4.3.16 GCP_NOMORETRANS
- ----------------------
-*/
-/*****************************************************************************
- * G C P _ N O M O R E T R A N S
- *
- * WHEN DBTC RECEIVES SIGNAL GCP_NOMORETRANS A CHECK IS DONE TO FIND OUT IF
- * THERE ARE ANY GLOBAL CHECKPOINTS GOING ON - CFIRSTGCP /= RNIL. DBTC THEN
- * SEARCHES THE GCP_RECORD FILE TO FIND OUT IF THERE ARE ANY TRANSACTIONS NOT
- * CONCLUDED WITH THIS SPECIFIC CHECKPOINT - GCP_PTR:GCP_ID = TCHECK_GCP_ID.
- * FOR EACH TRANSACTION WHERE API_CONNECTSTATE EQUALS PREPARED, COMMITTING,
- * COMMITTED OR COMPLETING SIGNAL CONTINUEB IS SENT WITH A DELAY OF 100 MS,
- * THE COUNTER GCP_PTR:OUTSTANDINGAPI IS INCREASED. WHEN CONTINUEB IS RECEIVED
- * THE COUNTER IS DECREASED AND A CHECK IS DONE TO FIND OUT IF ALL
- * TRANSACTIONS ARE CONCLUDED. IF SO, SIGNAL GCP_TCFINISHED IS SENT.
- *****************************************************************************/
-void Dbtc::execGCP_NOMORETRANS(Signal* signal)
-{
- jamEntry();
- c_gcp_ref = signal->theData[0];
- tcheckGcpId = signal->theData[1];
- if (cfirstgcp != RNIL) {
- jam();
- /* A GLOBAL CHECKPOINT IS GOING ON */
- gcpPtr.i = cfirstgcp; /* SET POINTER TO FIRST GCP IN QUEUE*/
- ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
- if (gcpPtr.p->gcpId == tcheckGcpId) {
- jam();
- if (gcpPtr.p->firstApiConnect != RNIL) {
- jam();
- gcpPtr.p->gcpNomoretransRec = ZTRUE;
- } else {
- jam();
- gcpTcfinished(signal);
- unlinkGcp(signal);
- }//if
- } else {
- jam();
- /*------------------------------------------------------------*/
- /* IF IT IS NOT THE FIRST THEN THERE SHOULD BE NO */
- /* RECORD FOR THIS GLOBAL CHECKPOINT. WE ALWAYS REMOVE */
- /* THE GLOBAL CHECKPOINTS IN ORDER. */
- /*------------------------------------------------------------*/
- gcpTcfinished(signal);
- }//if
- } else {
- jam();
- gcpTcfinished(signal);
- }//if
- return;
-}//Dbtc::execGCP_NOMORETRANS()
-
-/*****************************************************************************/
-/* */
-/* TAKE OVER MODULE */
-/* */
-/*****************************************************************************/
-/* */
-/* THIS PART OF TC TAKES OVER THE COMMIT/ABORT OF TRANSACTIONS WHERE THE */
-/* NODE ACTING AS TC HAVE FAILED. IT STARTS BY QUERYING ALL NODES ABOUT */
-/* ANY OPERATIONS PARTICIPATING IN A TRANSACTION WHERE THE TC NODE HAVE */
-/* FAILED. */
-/* */
-/* AFTER RECEIVING INFORMATION FROM ALL NODES ABOUT OPERATION STATUS THIS */
-/* CODE WILL ENSURE THAT ALL AFFECTED TRANSACTIONS ARE PROPERLY ABORTED OR*/
-/* COMMITTED. THE ORIGINATING APPLICATION NODE WILL ALSO BE CONTACTED. */
-/* IF THE ORIGINATING APPLICATION ALSO FAILED THEN THERE IS CURRENTLY NO */
-/* WAY TO FIND OUT WHETHER A TRANSACTION WAS PERFORMED OR NOT. */
-/*****************************************************************************/
-void Dbtc::execNODE_FAILREP(Signal* signal)
-{
- jamEntry();
-
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- cfailure_nr = nodeFail->failNo;
- const Uint32 tnoOfNodes = nodeFail->noOfNodes;
- const Uint32 tnewMasterId = nodeFail->masterNodeId;
-
- arrGuard(tnoOfNodes, MAX_NDB_NODES);
- Uint32 i;
- int index = 0;
- for (i = 1; i< MAX_NDB_NODES; i++)
- {
- if(NodeBitmask::get(nodeFail->theNodes, i))
- {
- cdata[index] = i;
- index++;
- }//if
- }//for
-
- cmasterNodeId = tnewMasterId;
-
- tcNodeFailptr.i = 0;
- ptrAss(tcNodeFailptr, tcFailRecord);
- for (i = 0; i < tnoOfNodes; i++)
- {
- jam();
- hostptr.i = cdata[i];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
-
- /*------------------------------------------------------------*/
- /* SET STATUS OF THE FAILED NODE TO DEAD SINCE IT HAS */
- /* FAILED. */
- /*------------------------------------------------------------*/
- hostptr.p->hostStatus = HS_DEAD;
- hostptr.p->m_nf_bits = HostRecord::NF_NODE_FAIL_BITS;
- c_alive_nodes.clear(hostptr.i);
-
- if (tcNodeFailptr.p->failStatus == FS_LISTENING)
- {
- jam();
- /*------------------------------------------------------------*/
- /* THE CURRENT TAKE OVER CAN BE AFFECTED BY THIS NODE */
- /* FAILURE. */
- /*------------------------------------------------------------*/
- if (hostptr.p->lqhTransStatus == LTS_ACTIVE)
- {
- jam();
- /*------------------------------------------------------------*/
- /* WE WERE WAITING FOR THE FAILED NODE IN THE TAKE OVER */
- /* PROTOCOL FOR TC. */
- /*------------------------------------------------------------*/
- signal->theData[0] = TcContinueB::ZNODE_TAKE_OVER_COMPLETED;
- signal->theData[1] = hostptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
- }//if
- }//if
-
- if (getOwnNodeId() != tnewMasterId)
- {
- jam();
- /**
- * Only master does takeover currently
- */
- hostptr.p->m_nf_bits &= ~HostRecord::NF_TAKEOVER;
- }
- else
- {
- jam();
- signal->theData[0] = hostptr.i;
- sendSignal(cownref, GSN_TAKE_OVERTCREQ, signal, 1, JBB);
- }
-
- checkScanActiveInFailedLqh(signal, 0, hostptr.i);
- checkWaitDropTabFailedLqh(signal, hostptr.i, 0); // nodeid, tableid
- nodeFailCheckTransactions(signal, 0, hostptr.i);
- }
-}//Dbtc::execNODE_FAILREP()
-
-void
-Dbtc::checkNodeFailComplete(Signal* signal,
- Uint32 failedNodeId,
- Uint32 bit)
-{
- hostptr.i = failedNodeId;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- hostptr.p->m_nf_bits &= ~bit;
- if (hostptr.p->m_nf_bits == 0)
- {
- NFCompleteRep * const nfRep = (NFCompleteRep *)&signal->theData[0];
- nfRep->blockNo = DBTC;
- nfRep->nodeId = cownNodeid;
- nfRep->failedNodeId = hostptr.i;
- sendSignal(cdihblockref, GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBB);
- }
-}
-
-void Dbtc::checkScanActiveInFailedLqh(Signal* signal,
- Uint32 scanPtrI,
- Uint32 failedNodeId){
-
- ScanRecordPtr scanptr;
- for (scanptr.i = scanPtrI; scanptr.i < cscanrecFileSize; scanptr.i++) {
- jam();
- ptrAss(scanptr, scanRecord);
- bool found = false;
- if (scanptr.p->scanState != ScanRecord::IDLE){
- jam();
- ScanFragRecPtr ptr;
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- for(run.first(ptr); !ptr.isNull(); ){
- jam();
- ScanFragRecPtr curr = ptr;
- run.next(ptr);
- if (curr.p->scanFragState == ScanFragRec::LQH_ACTIVE &&
- refToNode(curr.p->lqhBlockref) == failedNodeId){
- jam();
-
- run.release(curr);
- curr.p->scanFragState = ScanFragRec::COMPLETED;
- curr.p->stopFragTimer();
- found = true;
- }
- }
-
- ScanFragList deliv(c_scan_frag_pool, scanptr.p->m_delivered_scan_frags);
- for(deliv.first(ptr); !ptr.isNull(); deliv.next(ptr))
- {
- jam();
- if (refToNode(ptr.p->lqhBlockref) == failedNodeId)
- {
- jam();
- found = true;
- break;
- }
- }
- }
- if(found){
- jam();
- scanError(signal, scanptr, ZSCAN_LQH_ERROR);
- }
-
- // Send CONTINUEB to continue later
- signal->theData[0] = TcContinueB::ZCHECK_SCAN_ACTIVE_FAILED_LQH;
- signal->theData[1] = scanptr.i + 1; // Check next scanptr
- signal->theData[2] = failedNodeId;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }//for
-
- checkNodeFailComplete(signal, failedNodeId, HostRecord::NF_CHECK_SCAN);
-}
-
-void
-Dbtc::nodeFailCheckTransactions(Signal* signal,
- Uint32 transPtrI,
- Uint32 failedNodeId)
-{
- jam();
- Ptr<ApiConnectRecord> transPtr;
- Uint32 TtcTimer = ctcTimer;
- Uint32 TapplTimeout = c_appl_timeout_value;
- for (transPtr.i = transPtrI; transPtr.i < capiConnectFilesize; transPtr.i++)
- {
- ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
- if (transPtr.p->m_transaction_nodes.get(failedNodeId))
- {
- jam();
-
- // Force timeout regardless of state
- c_appl_timeout_value = 1;
- setApiConTimer(transPtr.i, TtcTimer - 2, __LINE__);
- timeOutFoundLab(signal, transPtr.i, ZNODEFAIL_BEFORE_COMMIT);
- c_appl_timeout_value = TapplTimeout;
- }
-
- // Send CONTINUEB to continue later
- signal->theData[0] = TcContinueB::ZNF_CHECK_TRANSACTIONS;
- signal->theData[1] = transPtr.i + 1; // Check next
- signal->theData[2] = failedNodeId;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
-
- checkNodeFailComplete(signal, failedNodeId,
- HostRecord::NF_CHECK_TRANSACTION);
-}
-
-
-void
-Dbtc::checkScanFragList(Signal* signal,
- Uint32 failedNodeId,
- ScanRecord * scanP,
- ScanFragList::Head & head){
-
- DEBUG("checkScanActiveInFailedLqh: scanFragError");
-}
-
-void Dbtc::execTAKE_OVERTCCONF(Signal* signal)
-{
- jamEntry();
- tfailedNodeId = signal->theData[0];
- hostptr.i = tfailedNodeId;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
-
- if (signal->getSendersBlockRef() != reference())
- {
- jam();
- return;
- }
-
- checkNodeFailComplete(signal, hostptr.i, HostRecord::NF_TAKEOVER);
-}//Dbtc::execTAKE_OVERTCCONF()
-
-void Dbtc::execTAKE_OVERTCREQ(Signal* signal)
-{
- jamEntry();
- tfailedNodeId = signal->theData[0];
- tcNodeFailptr.i = 0;
- ptrAss(tcNodeFailptr, tcFailRecord);
- if (tcNodeFailptr.p->failStatus != FS_IDLE) {
- jam();
- /*------------------------------------------------------------*/
- /* WE CAN CURRENTLY ONLY HANDLE ONE TAKE OVER AT A TIME */
- /*------------------------------------------------------------*/
- /* IF MORE THAN ONE TAKE OVER IS REQUESTED WE WILL */
- /* QUEUE THE TAKE OVER AND START IT AS SOON AS THE */
- /* PREVIOUS ARE COMPLETED. */
- /*------------------------------------------------------------*/
- arrGuard(tcNodeFailptr.p->queueIndex, MAX_NDB_NODES);
- tcNodeFailptr.p->queueList[tcNodeFailptr.p->queueIndex] = tfailedNodeId;
- tcNodeFailptr.p->queueIndex = tcNodeFailptr.p->queueIndex + 1;
- return;
- }//if
- startTakeOverLab(signal);
-}//Dbtc::execTAKE_OVERTCREQ()
-
-/*------------------------------------------------------------*/
-/* INITIALISE THE HASH TABLES FOR STORING TRANSACTIONS */
-/* AND OPERATIONS DURING TC TAKE OVER. */
-/*------------------------------------------------------------*/
-void Dbtc::startTakeOverLab(Signal* signal)
-{
- for (tindex = 0; tindex <= 511; tindex++) {
- ctransidFailHash[tindex] = RNIL;
- }//for
- for (tindex = 0; tindex <= 1023; tindex++) {
- ctcConnectFailHash[tindex] = RNIL;
- }//for
- tcNodeFailptr.p->failStatus = FS_LISTENING;
- tcNodeFailptr.p->takeOverNode = tfailedNodeId;
- for (hostptr.i = 1; hostptr.i < MAX_NDB_NODES; hostptr.i++) {
- jam();
- ptrAss(hostptr, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- jam();
- tblockref = calcLqhBlockRef(hostptr.i);
- hostptr.p->lqhTransStatus = LTS_ACTIVE;
- signal->theData[0] = tcNodeFailptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = tfailedNodeId;
- sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
- }//if
- }//for
-}//Dbtc::startTakeOverLab()
-
-/*------------------------------------------------------------*/
-/* A REPORT OF AN OPERATION WHERE TC FAILED HAS ARRIVED.*/
-/*------------------------------------------------------------*/
-void Dbtc::execLQH_TRANSCONF(Signal* signal)
-{
- jamEntry();
- LqhTransConf * const lqhTransConf = (LqhTransConf *)&signal->theData[0];
-
- tcNodeFailptr.i = lqhTransConf->tcRef;
- ptrCheckGuard(tcNodeFailptr, 1, tcFailRecord);
- tnodeid = lqhTransConf->lqhNodeId;
- ttransStatus = (LqhTransConf::OperationStatus)lqhTransConf->operationStatus;
- ttransid1 = lqhTransConf->transId1;
- ttransid2 = lqhTransConf->transId2;
- ttcOprec = lqhTransConf->oldTcOpRec;
- treqinfo = lqhTransConf->requestInfo;
- tgci = lqhTransConf->gci;
- cnodes[0] = lqhTransConf->nextNodeId1;
- cnodes[1] = lqhTransConf->nextNodeId2;
- cnodes[2] = lqhTransConf->nextNodeId3;
- const Uint32 ref = tapplRef = lqhTransConf->apiRef;
- tapplOprec = lqhTransConf->apiOpRec;
- const Uint32 tableId = lqhTransConf->tableId;
-
- if (ttransStatus == LqhTransConf::LastTransConf){
- jam();
- /*------------------------------------------------------------*/
- /* A NODE HAS REPORTED COMPLETION OF TAKE OVER REPORTING*/
- /*------------------------------------------------------------*/
- nodeTakeOverCompletedLab(signal);
- return;
- }//if
- if (ttransStatus == LqhTransConf::Marker){
- jam();
- treqinfo = 0;
- LqhTransConf::setMarkerFlag(treqinfo, 1);
- } else {
- TableRecordPtr tabPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
- switch((DictTabInfo::TableType)tabPtr.p->tableType){
- case DictTabInfo::SystemTable:
- case DictTabInfo::UserTable:
- break;
- default:
- tapplRef = 0;
- tapplOprec = 0;
- }
- }
-
- findApiConnectFail(signal);
-
- if(apiConnectptr.p->ndbapiBlockref == 0 && tapplRef != 0){
- apiConnectptr.p->ndbapiBlockref = ref;
- apiConnectptr.p->ndbapiConnect = tapplOprec;
- }
-
- if (ttransStatus != LqhTransConf::Marker){
- jam();
- findTcConnectFail(signal);
- }
-}//Dbtc::execLQH_TRANSCONF()
-
-/*------------------------------------------------------------*/
-/* A NODE HAS REPORTED COMPLETION OF TAKE OVER REPORTING*/
-/*------------------------------------------------------------*/
-void Dbtc::nodeTakeOverCompletedLab(Signal* signal)
-{
- Uint32 guard0;
-
- hostptr.i = tnodeid;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- hostptr.p->lqhTransStatus = LTS_IDLE;
- for (hostptr.i = 1; hostptr.i < MAX_NDB_NODES; hostptr.i++) {
- jam();
- ptrAss(hostptr, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- if (hostptr.p->lqhTransStatus == LTS_ACTIVE) {
- jam();
- /*------------------------------------------------------------*/
- /* NOT ALL NODES ARE COMPLETED WITH REPORTING IN THE */
- /* TAKE OVER. */
- /*------------------------------------------------------------*/
- return;
- }//if
- }//if
- }//for
- /*------------------------------------------------------------*/
- /* ALL NODES HAVE REPORTED ON THE STATUS OF THE VARIOUS */
- /* OPERATIONS THAT WAS CONTROLLED BY THE FAILED TC. WE */
- /* ARE NOW IN A POSITION TO COMPLETE ALL OF THOSE */
- /* TRANSACTIONS EITHER IN A SUCCESSFUL WAY OR IN AN */
- /* UNSUCCESSFUL WAY. WE WILL ALSO REPORT THIS CONCLUSION*/
- /* TO THE APPLICATION IF THAT IS STILL ALIVE. */
- /*------------------------------------------------------------*/
- tcNodeFailptr.p->currentHashIndexTakeOver = 0;
- tcNodeFailptr.p->completedTakeOver = 0;
- tcNodeFailptr.p->failStatus = FS_COMPLETING;
- guard0 = cnoParallelTakeOver - 1;
- /*------------------------------------------------------------*/
- /* WE WILL COMPLETE THE TRANSACTIONS BY STARTING A */
- /* NUMBER OF PARALLEL ACTIVITIES. EACH ACTIVITY WILL */
- /* COMPLETE ONE TRANSACTION AT A TIME AND IN THAT */
- /* TRANSACTION IT WILL COMPLETE ONE OPERATION AT A TIME.*/
- /* WHEN ALL ACTIVITIES ARE COMPLETED THEN THE TAKE OVER */
- /* IS COMPLETED. */
- /*------------------------------------------------------------*/
- arrGuard(guard0, MAX_NDB_NODES);
- for (tindex = 0; tindex <= guard0; tindex++) {
- jam();
- tcNodeFailptr.p->takeOverProcState[tindex] = ZTAKE_OVER_ACTIVE;
- signal->theData[0] = TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER;
- signal->theData[1] = tcNodeFailptr.i;
- signal->theData[2] = tindex;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- }//for
-}//Dbtc::nodeTakeOverCompletedLab()
-
-/*------------------------------------------------------------*/
-/* COMPLETE A NEW TRANSACTION FROM THE HASH TABLE OF */
-/* TRANSACTIONS TO COMPLETE. */
-/*------------------------------------------------------------*/
-void Dbtc::completeTransAtTakeOverLab(Signal* signal, UintR TtakeOverInd)
-{
- jam();
- while (tcNodeFailptr.p->currentHashIndexTakeOver < 512){
- jam();
- apiConnectptr.i =
- ctransidFailHash[tcNodeFailptr.p->currentHashIndexTakeOver];
- if (apiConnectptr.i != RNIL) {
- jam();
- /*------------------------------------------------------------*/
- /* WE HAVE FOUND A TRANSACTION THAT NEEDS TO BE */
- /* COMPLETED. REMOVE IT FROM THE HASH TABLE SUCH THAT */
- /* NOT ANOTHER ACTIVITY ALSO TRIES TO COMPLETE THIS */
- /* TRANSACTION. */
- /*------------------------------------------------------------*/
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- ctransidFailHash[tcNodeFailptr.p->currentHashIndexTakeOver] =
- apiConnectptr.p->nextApiConnect;
-
- completeTransAtTakeOverDoOne(signal, TtakeOverInd);
- // One transaction taken care of, return from this function
- // and wait for the next CONTINUEB to continue processing
- break;
-
- } else {
- if (tcNodeFailptr.p->currentHashIndexTakeOver < 511){
- jam();
- tcNodeFailptr.p->currentHashIndexTakeOver++;
- } else {
- jam();
- completeTransAtTakeOverDoLast(signal, TtakeOverInd);
- tcNodeFailptr.p->currentHashIndexTakeOver++;
- }//if
- }//if
- }//while
-}//Dbtc::completeTransAtTakeOverLab()
-
-
-
-
-void Dbtc::completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd)
-{
- Uint32 guard0;
- /*------------------------------------------------------------*/
- /* THERE ARE NO MORE TRANSACTIONS TO COMPLETE. THIS */
- /* ACTIVITY IS COMPLETED. */
- /*------------------------------------------------------------*/
- arrGuard(TtakeOverInd, MAX_NDB_NODES);
- if (tcNodeFailptr.p->takeOverProcState[TtakeOverInd] != ZTAKE_OVER_ACTIVE) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- tcNodeFailptr.p->takeOverProcState[TtakeOverInd] = ZTAKE_OVER_IDLE;
- tcNodeFailptr.p->completedTakeOver++;
-
- if (tcNodeFailptr.p->completedTakeOver == cnoParallelTakeOver) {
- jam();
- /*------------------------------------------------------------*/
- /* WE WERE THE LAST ACTIVITY THAT WAS COMPLETED. WE NEED*/
- /* TO REPORT THE COMPLETION OF THE TAKE OVER TO ALL */
- /* NODES THAT ARE ALIVE. */
- /*------------------------------------------------------------*/
- NodeReceiverGroup rg(DBTC, c_alive_nodes);
- signal->theData[0] = tcNodeFailptr.p->takeOverNode;
- sendSignal(rg, GSN_TAKE_OVERTCCONF, signal, 1, JBB);
-
- if (tcNodeFailptr.p->queueIndex > 0) {
- jam();
- /*------------------------------------------------------------*/
- /* THERE ARE MORE NODES TO TAKE OVER. WE NEED TO START */
- /* THE TAKE OVER. */
- /*------------------------------------------------------------*/
- tfailedNodeId = tcNodeFailptr.p->queueList[0];
- guard0 = tcNodeFailptr.p->queueIndex - 1;
- arrGuard(guard0 + 1, MAX_NDB_NODES);
- for (tindex = 0; tindex <= guard0; tindex++) {
- jam();
- tcNodeFailptr.p->queueList[tindex] =
- tcNodeFailptr.p->queueList[tindex + 1];
- }//for
- tcNodeFailptr.p->queueIndex--;
- startTakeOverLab(signal);
- return;
- } else {
- jam();
- tcNodeFailptr.p->failStatus = FS_IDLE;
- }//if
- }//if
- return;
-}//Dbtc::completeTransAtTakeOverDoLast()
-
-void Dbtc::completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd)
-{
- apiConnectptr.p->takeOverRec = (Uint8)tcNodeFailptr.i;
- apiConnectptr.p->takeOverInd = TtakeOverInd;
-
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_FAIL_COMMITTED:
- jam();
- /*------------------------------------------------------------*/
- /* ALL PARTS OF THE TRANSACTIONS REPORTED COMMITTED. WE */
- /* HAVE THUS COMPLETED THE COMMIT PHASE. WE CAN REPORT */
- /* COMMITTED TO THE APPLICATION AND CONTINUE WITH THE */
- /* COMPLETE PHASE. */
- /*------------------------------------------------------------*/
- sendTCKEY_FAILCONF(signal, apiConnectptr.p);
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- toCompleteHandlingLab(signal);
- return;
- case CS_FAIL_COMMITTING:
- jam();
- /*------------------------------------------------------------*/
- /* AT LEAST ONE PART WAS ONLY PREPARED AND AT LEAST ONE */
- /* PART WAS COMMITTED. COMPLETE THE COMMIT PHASE FIRST. */
- /* THEN CONTINUE AS AFTER COMMITTED. */
- /*------------------------------------------------------------*/
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- toCommitHandlingLab(signal);
- return;
- case CS_FAIL_ABORTING:
- case CS_FAIL_PREPARED:
- jam();
- /*------------------------------------------------------------*/
- /* WE WILL ABORT THE TRANSACTION IF IT IS IN A PREPARED */
- /* STATE IN THIS VERSION. IN LATER VERSIONS WE WILL */
- /* HAVE TO ADD CODE FOR HANDLING OF PREPARED-TO-COMMIT */
- /* TRANSACTIONS. THESE ARE NOT ALLOWED TO ABORT UNTIL WE*/
- /* HAVE HEARD FROM THE TRANSACTION COORDINATOR. */
- /* */
- /* IT IS POSSIBLE TO COMMIT TRANSACTIONS THAT ARE */
- /* PREPARED ACTUALLY. WE WILL LEAVE THIS PROBLEM UNTIL */
- /* LATER VERSIONS. */
- /*------------------------------------------------------------*/
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- toAbortHandlingLab(signal);
- return;
- case CS_FAIL_ABORTED:
- jam();
- sendTCKEY_FAILREF(signal, apiConnectptr.p);
-
- signal->theData[0] = TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER;
- signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
- signal->theData[2] = apiConnectptr.p->takeOverInd;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- releaseTakeOver(signal);
- break;
- case CS_FAIL_COMPLETED:
- jam();
- sendTCKEY_FAILCONF(signal, apiConnectptr.p);
-
- signal->theData[0] = TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER;
- signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
- signal->theData[2] = apiConnectptr.p->takeOverInd;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- releaseApiConnectFail(signal);
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
-}//Dbtc::completeTransAtTakeOverDoOne()
-
-void
-Dbtc::sendTCKEY_FAILREF(Signal* signal, const ApiConnectRecord * regApiPtr){
- jam();
-
- const Uint32 ref = regApiPtr->ndbapiBlockref;
- if(ref != 0){
- signal->theData[0] = regApiPtr->ndbapiConnect;
- signal->theData[1] = regApiPtr->transid[0];
- signal->theData[2] = regApiPtr->transid[1];
-
- sendSignal(ref, GSN_TCKEY_FAILREF, signal, 3, JBB);
- }
-}
-
-void
-Dbtc::sendTCKEY_FAILCONF(Signal* signal, ApiConnectRecord * regApiPtr){
- jam();
- TcKeyFailConf * const failConf = (TcKeyFailConf *)&signal->theData[0];
-
- const Uint32 ref = regApiPtr->ndbapiBlockref;
- const Uint32 marker = regApiPtr->commitAckMarker;
- if(ref != 0){
- failConf->apiConnectPtr = regApiPtr->ndbapiConnect | (marker != RNIL);
- failConf->transId1 = regApiPtr->transid[0];
- failConf->transId2 = regApiPtr->transid[1];
-
- sendSignal(regApiPtr->ndbapiBlockref,
- GSN_TCKEY_FAILCONF, signal, TcKeyFailConf::SignalLength, JBB);
- }
- regApiPtr->commitAckMarker = RNIL;
-}
-
-/*------------------------------------------------------------*/
-/* THIS PART HANDLES THE ABORT PHASE IN THE CASE OF A */
-/* NODE FAILURE BEFORE THE COMMIT DECISION. */
-/*------------------------------------------------------------*/
-/* ABORT REQUEST SUCCESSFULLY COMPLETED ON TNODEID */
-/*------------------------------------------------------------*/
-void Dbtc::execABORTCONF(Signal* signal)
-{
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- tnodeid = signal->theData[2];
- if (ERROR_INSERTED(8045)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_ABORTCONF, signal, 2000, 5);
- return;
- }//if
- if (tcConnectptr.i >= ctcConnectFilesize) {
- errorReport(signal, 5);
- return;
- }//if
- ptrAss(tcConnectptr, tcConnectRecord);
- if (tcConnectptr.p->tcConnectstate != OS_WAIT_ABORT_CONF) {
- warningReport(signal, 16);
- return;
- }//if
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- if (apiConnectptr.p->apiConnectstate != CS_WAIT_ABORT_CONF) {
- warningReport(signal, 17);
- return;
- }//if
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[3];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[4];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 18);
- return;
- }//if
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
- tnodeid) {
- warningReport(signal, 19);
- return;
- }//if
- tcurrentReplicaNo = (Uint8)Z8NIL;
- tcConnectptr.p->tcConnectstate = OS_ABORTING;
- toAbortHandlingLab(signal);
-}//Dbtc::execABORTCONF()
-
-void Dbtc::toAbortHandlingLab(Signal* signal)
-{
- do {
- if (tcurrentReplicaNo != (Uint8)Z8NIL) {
- jam();
- arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
- const LqhTransConf::OperationStatus stat =
- (LqhTransConf::OperationStatus)
- tcConnectptr.p->failData[tcurrentReplicaNo];
- switch(stat){
- case LqhTransConf::InvalidStatus:
- case LqhTransConf::Aborted:
- jam();
- /*empty*/;
- break;
- case LqhTransConf::Prepared:
- jam();
- hostptr.i = tcConnectptr.p->tcNodedata[tcurrentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- jam();
- tblockref = calcLqhBlockRef(hostptr.i);
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- tcConnectptr.p->tcConnectstate = OS_WAIT_ABORT_CONF;
- apiConnectptr.p->apiConnectstate = CS_WAIT_ABORT_CONF;
- apiConnectptr.p->timeOutCounter = 0;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = apiConnectptr.p->transid[0];
- signal->theData[3] = apiConnectptr.p->transid[1];
- signal->theData[4] = apiConnectptr.p->tcBlockref;
- signal->theData[5] = tcConnectptr.p->tcOprec;
- sendSignal(tblockref, GSN_ABORTREQ, signal, 6, JBB);
- return;
- }//if
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//switch
- }//if
- if (apiConnectptr.p->currentReplicaNo > 0) {
- jam();
- /*------------------------------------------------------------*/
- /* THERE IS STILL ANOTHER REPLICA THAT NEEDS TO BE */
- /* ABORTED. */
- /*------------------------------------------------------------*/
- apiConnectptr.p->currentReplicaNo--;
- tcurrentReplicaNo = apiConnectptr.p->currentReplicaNo;
- } else {
- /*------------------------------------------------------------*/
- /* THE LAST REPLICA IN THIS OPERATION HAVE COMMITTED. */
- /*------------------------------------------------------------*/
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- if (tcConnectptr.i == RNIL) {
- /*------------------------------------------------------------*/
- /* WE HAVE COMPLETED THE ABORT PHASE. WE CAN NOW REPORT */
- /* THE ABORT STATUS TO THE APPLICATION AND CONTINUE */
- /* WITH THE NEXT TRANSACTION. */
- /*------------------------------------------------------------*/
- if (apiConnectptr.p->takeOverRec != (Uint8)Z8NIL) {
- jam();
- sendTCKEY_FAILREF(signal, apiConnectptr.p);
- const Uint32 marker = apiConnectptr.p->commitAckMarker;
- if(marker != RNIL){
- jam();
-
- CommitAckMarkerPtr tmp;
- tmp.i = marker;
- tmp.p = m_commitAckMarkerHash.getPtr(tmp.i);
-
- m_commitAckMarkerHash.release(tmp);
- apiConnectptr.p->commitAckMarker = RNIL;
- }
-
- /*------------------------------------------------------------*/
- /* WE HAVE COMPLETED THIS TRANSACTION NOW AND CAN */
- /* CONTINUE THE PROCESS WITH THE NEXT TRANSACTION. */
- /*------------------------------------------------------------*/
- signal->theData[0] = TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER;
- signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
- signal->theData[2] = apiConnectptr.p->takeOverInd;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- releaseTakeOver(signal);
- } else {
- jam();
- releaseAbortResources(signal);
- }//if
- return;
- }//if
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- }//if
- } while (1);
-}//Dbtc::toAbortHandlingLab()
-
-/*------------------------------------------------------------*/
-/* THIS PART HANDLES THE COMMIT PHASE IN THE CASE OF A */
-/* NODE FAILURE IN THE MIDDLE OF THE COMMIT PHASE. */
-/*------------------------------------------------------------*/
-/* COMMIT REQUEST SUCCESSFULLY COMPLETED ON TNODEID */
-/*------------------------------------------------------------*/
-void Dbtc::execCOMMITCONF(Signal* signal)
-{
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- tnodeid = signal->theData[1];
- if (ERROR_INSERTED(8046)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMMITCONF, signal, 2000, 4);
- return;
- }//if
- if (tcConnectptr.i >= ctcConnectFilesize) {
- errorReport(signal, 4);
- return;
- }//if
- ptrAss(tcConnectptr, tcConnectRecord);
- if (tcConnectptr.p->tcConnectstate != OS_WAIT_COMMIT_CONF) {
- warningReport(signal, 8);
- return;
- }//if
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- if (apiConnectptr.p->apiConnectstate != CS_WAIT_COMMIT_CONF) {
- warningReport(signal, 9);
- return;
- }//if
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[2];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[3];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 10);
- return;
- }//if
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
- tnodeid) {
- warningReport(signal, 11);
- return;
- }//if
- if (ERROR_INSERTED(8026)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- tcurrentReplicaNo = (Uint8)Z8NIL;
- tcConnectptr.p->tcConnectstate = OS_COMMITTED;
- toCommitHandlingLab(signal);
-}//Dbtc::execCOMMITCONF()
-
-void Dbtc::toCommitHandlingLab(Signal* signal)
-{
- do {
- if (tcurrentReplicaNo != (Uint8)Z8NIL) {
- jam();
- arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
- switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
- case LqhTransConf::InvalidStatus:
- jam();
- /*empty*/;
- break;
- case LqhTransConf::Committed:
- jam();
- /*empty*/;
- break;
- case LqhTransConf::Prepared:
- jam();
- /*------------------------------------------------------------*/
- /* THE NODE WAS PREPARED AND IS WAITING FOR ABORT OR */
- /* COMMIT REQUEST FROM TC. */
- /*------------------------------------------------------------*/
- hostptr.i = tcConnectptr.p->tcNodedata[tcurrentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- jam();
- tblockref = calcLqhBlockRef(hostptr.i);
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- apiConnectptr.p->apiConnectstate = CS_WAIT_COMMIT_CONF;
- apiConnectptr.p->timeOutCounter = 0;
- tcConnectptr.p->tcConnectstate = OS_WAIT_COMMIT_CONF;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = apiConnectptr.p->globalcheckpointid;
- signal->theData[3] = apiConnectptr.p->transid[0];
- signal->theData[4] = apiConnectptr.p->transid[1];
- signal->theData[5] = apiConnectptr.p->tcBlockref;
- signal->theData[6] = tcConnectptr.p->tcOprec;
- sendSignal(tblockref, GSN_COMMITREQ, signal, 7, JBB);
- return;
- }//if
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- }//if
- if (apiConnectptr.p->currentReplicaNo > 0) {
- jam();
- /*------------------------------------------------------------*/
- /* THERE IS STILL ANOTHER REPLICA THAT NEEDS TO BE */
- /* COMMITTED. */
- /*------------------------------------------------------------*/
- apiConnectptr.p->currentReplicaNo--;
- tcurrentReplicaNo = apiConnectptr.p->currentReplicaNo;
- } else {
- /*------------------------------------------------------------*/
- /* THE LAST REPLICA IN THIS OPERATION HAVE COMMITTED. */
- /*------------------------------------------------------------*/
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- if (tcConnectptr.i == RNIL) {
- /*------------------------------------------------------------*/
- /* WE HAVE COMPLETED THE COMMIT PHASE. WE CAN NOW REPORT*/
- /* THE COMMIT STATUS TO THE APPLICATION AND CONTINUE */
- /* WITH THE COMPLETE PHASE. */
- /*------------------------------------------------------------*/
- if (apiConnectptr.p->takeOverRec != (Uint8)Z8NIL) {
- jam();
- sendTCKEY_FAILCONF(signal, apiConnectptr.p);
- } else {
- jam();
- sendApiCommit(signal);
- }//if
- apiConnectptr.p->currentTcConnect = apiConnectptr.p->firstTcConnect;
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- apiConnectptr.p->currentReplicaNo = tcurrentReplicaNo;
- toCompleteHandlingLab(signal);
- return;
- }//if
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- }//if
- } while (1);
-}//Dbtc::toCommitHandlingLab()
-
-/*------------------------------------------------------------*/
-/* COMMON PART TO HANDLE COMPLETE PHASE WHEN ANY NODE */
-/* HAVE FAILED. */
-/*------------------------------------------------------------*/
-/* THE NODE WITH TNODEID HAVE COMPLETED THE OPERATION */
-/*------------------------------------------------------------*/
-void Dbtc::execCOMPLETECONF(Signal* signal)
-{
- UintR compare_transid1, compare_transid2;
-
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- tnodeid = signal->theData[1];
- if (ERROR_INSERTED(8047)) {
- CLEAR_ERROR_INSERT_VALUE;
- sendSignalWithDelay(cownref, GSN_COMPLETECONF, signal, 2000, 4);
- return;
- }//if
- if (tcConnectptr.i >= ctcConnectFilesize) {
- errorReport(signal, 3);
- return;
- }//if
- ptrAss(tcConnectptr, tcConnectRecord);
- if (tcConnectptr.p->tcConnectstate != OS_WAIT_COMPLETE_CONF) {
- warningReport(signal, 12);
- return;
- }//if
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- if (apiConnectptr.p->apiConnectstate != CS_WAIT_COMPLETE_CONF) {
- warningReport(signal, 13);
- return;
- }//if
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[2];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[3];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- warningReport(signal, 14);
- return;
- }//if
- arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
- if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
- tnodeid) {
- warningReport(signal, 15);
- return;
- }//if
- if (ERROR_INSERTED(8028)) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- tcConnectptr.p->tcConnectstate = OS_COMPLETED;
- tcurrentReplicaNo = (Uint8)Z8NIL;
- toCompleteHandlingLab(signal);
-}//Dbtc::execCOMPLETECONF()
-
-void Dbtc::toCompleteHandlingLab(Signal* signal)
-{
- do {
- if (tcurrentReplicaNo != (Uint8)Z8NIL) {
- jam();
- arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
- switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
- case LqhTransConf::InvalidStatus:
- jam();
- /*empty*/;
- break;
- default:
- jam();
- /*------------------------------------------------------------*/
- /* THIS NODE DID NOT REPORT ANYTHING FOR THIS OPERATION */
- /* IT MUST HAVE FAILED. */
- /*------------------------------------------------------------*/
- /*------------------------------------------------------------*/
- /* SEND COMPLETEREQ TO THE NEXT REPLICA. */
- /*------------------------------------------------------------*/
- hostptr.i = tcConnectptr.p->tcNodedata[tcurrentReplicaNo];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus == HS_ALIVE) {
- jam();
- tblockref = calcLqhBlockRef(hostptr.i);
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- tcConnectptr.p->tcConnectstate = OS_WAIT_COMPLETE_CONF;
- apiConnectptr.p->apiConnectstate = CS_WAIT_COMPLETE_CONF;
- apiConnectptr.p->timeOutCounter = 0;
- tcConnectptr.p->apiConnect = apiConnectptr.i;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- signal->theData[2] = apiConnectptr.p->transid[0];
- signal->theData[3] = apiConnectptr.p->transid[1];
- signal->theData[4] = apiConnectptr.p->tcBlockref;
- signal->theData[5] = tcConnectptr.p->tcOprec;
- sendSignal(tblockref, GSN_COMPLETEREQ, signal, 6, JBB);
- return;
- }//if
- break;
- }//switch
- }//if
- if (apiConnectptr.p->currentReplicaNo != 0) {
- jam();
- /*------------------------------------------------------------*/
- /* THERE ARE STILL MORE REPLICAS IN THIS OPERATION. WE */
- /* NEED TO CONTINUE WITH THOSE REPLICAS. */
- /*------------------------------------------------------------*/
- apiConnectptr.p->currentReplicaNo--;
- tcurrentReplicaNo = apiConnectptr.p->currentReplicaNo;
- } else {
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- if (tcConnectptr.i == RNIL) {
- /*------------------------------------------------------------*/
- /* WE HAVE COMPLETED THIS TRANSACTION NOW AND CAN */
- /* CONTINUE THE PROCESS WITH THE NEXT TRANSACTION. */
- /*------------------------------------------------------------*/
- if (apiConnectptr.p->takeOverRec != (Uint8)Z8NIL) {
- jam();
- signal->theData[0] = TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER;
- signal->theData[1] = (UintR)apiConnectptr.p->takeOverRec;
- signal->theData[2] = apiConnectptr.p->takeOverInd;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- releaseTakeOver(signal);
- } else {
- jam();
- releaseTransResources(signal);
- }//if
- return;
- }//if
- /*------------------------------------------------------------*/
- /* WE HAVE COMPLETED AN OPERATION AND THERE ARE MORE TO */
- /* COMPLETE. TAKE THE NEXT OPERATION AND START WITH THE */
- /* FIRST REPLICA SINCE IT IS THE COMPLETE PHASE. */
- /*------------------------------------------------------------*/
- apiConnectptr.p->currentTcConnect = tcConnectptr.i;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
- apiConnectptr.p->currentReplicaNo = tcurrentReplicaNo;
- }//if
- } while (1);
-}//Dbtc::toCompleteHandlingLab()
-
-/*------------------------------------------------------------*/
-/* */
-/* FIND THE API CONNECT RECORD FOR THIS TRANSACTION */
-/* DURING TAKE OVER FROM A FAILED TC. IF NONE EXISTS */
-/* YET THEN SEIZE A NEW API CONNECT RECORD AND LINK IT */
-/* INTO THE HASH TABLE. */
-/*------------------------------------------------------------*/
-void Dbtc::findApiConnectFail(Signal* signal)
-{
- ApiConnectRecordPtr fafPrevApiConnectptr;
- ApiConnectRecordPtr fafNextApiConnectptr;
- UintR tfafHashNumber;
-
- tfafHashNumber = ttransid1 & 511;
- fafPrevApiConnectptr.i = RNIL;
- ptrNull(fafPrevApiConnectptr);
- arrGuard(tfafHashNumber, 512);
- fafNextApiConnectptr.i = ctransidFailHash[tfafHashNumber];
- ptrCheck(fafNextApiConnectptr, capiConnectFilesize, apiConnectRecord);
-FAF_LOOP:
- jam();
- if (fafNextApiConnectptr.i == RNIL) {
- jam();
- if (cfirstfreeApiConnectFail == RNIL) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- seizeApiConnectFail(signal);
- if (fafPrevApiConnectptr.i == RNIL) {
- jam();
- ctransidFailHash[tfafHashNumber] = apiConnectptr.i;
- } else {
- jam();
- ptrGuard(fafPrevApiConnectptr);
- fafPrevApiConnectptr.p->nextApiConnect = apiConnectptr.i;
- }//if
- apiConnectptr.p->nextApiConnect = RNIL;
- initApiConnectFail(signal);
- } else {
- jam();
- fafPrevApiConnectptr.i = fafNextApiConnectptr.i;
- fafPrevApiConnectptr.p = fafNextApiConnectptr.p;
- apiConnectptr.i = fafNextApiConnectptr.i;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- fafNextApiConnectptr.i = apiConnectptr.p->nextApiConnect;
- ptrCheck(fafNextApiConnectptr, capiConnectFilesize, apiConnectRecord);
- if ((apiConnectptr.p->transid[1] != ttransid2) ||
- (apiConnectptr.p->transid[0] != ttransid1)) {
- goto FAF_LOOP;
- }//if
- updateApiStateFail(signal);
- }//if
-}//Dbtc::findApiConnectFail()
-
-/*----------------------------------------------------------*/
-/* FIND THE TC CONNECT AND IF NOT FOUND ALLOCATE A NEW */
-/*----------------------------------------------------------*/
-void Dbtc::findTcConnectFail(Signal* signal)
-{
- UintR tftfHashNumber;
-
- tftfHashNumber = (ttransid1 ^ ttcOprec) & 1023;
- tcConnectptr.i = ctcConnectFailHash[tftfHashNumber];
- do {
- if (tcConnectptr.i == RNIL) {
- jam();
- if (cfirstfreeTcConnectFail == RNIL) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
- seizeTcConnectFail(signal);
- linkTcInConnectionlist(signal);
- tcConnectptr.p->nextTcFailHash = ctcConnectFailHash[tftfHashNumber];
- ctcConnectFailHash[tftfHashNumber] = tcConnectptr.i;
- initTcConnectFail(signal);
- return;
- } else {
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- if (tcConnectptr.p->tcOprec != ttcOprec) {
- jam(); /* FRAGMENTID = TC_OPREC HERE, LOOP ANOTHER TURN */
- tcConnectptr.i = tcConnectptr.p->nextTcFailHash;
- } else {
- updateTcStateFail(signal);
- return;
- }//if
- }//if
- } while (1);
-}//Dbtc::findTcConnectFail()
-
-/*----------------------------------------------------------*/
-/* INITIALISE AN API CONNECT FAIL RECORD */
-/*----------------------------------------------------------*/
-void Dbtc::initApiConnectFail(Signal* signal)
-{
- apiConnectptr.p->transid[0] = ttransid1;
- apiConnectptr.p->transid[1] = ttransid2;
- apiConnectptr.p->firstTcConnect = RNIL;
- apiConnectptr.p->currSavePointId = 0;
- apiConnectptr.p->lastTcConnect = RNIL;
- tblockref = calcTcBlockRef(tcNodeFailptr.p->takeOverNode);
-
- apiConnectptr.p->tcBlockref = tblockref;
- apiConnectptr.p->ndbapiBlockref = 0;
- apiConnectptr.p->ndbapiConnect = 0;
- apiConnectptr.p->buddyPtr = RNIL;
- apiConnectptr.p->m_transaction_nodes.clear();
- apiConnectptr.p->singleUserMode = 0;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- switch(ttransStatus){
- case LqhTransConf::Committed:
- jam();
- apiConnectptr.p->globalcheckpointid = tgci;
- apiConnectptr.p->apiConnectstate = CS_FAIL_COMMITTED;
- break;
- case LqhTransConf::Prepared:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_PREPARED;
- break;
- case LqhTransConf::Aborted:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_ABORTED;
- break;
- case LqhTransConf::Marker:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_COMPLETED;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- apiConnectptr.p->commitAckMarker = RNIL;
- if(LqhTransConf::getMarkerFlag(treqinfo)){
- jam();
- CommitAckMarkerPtr tmp;
- m_commitAckMarkerHash.seize(tmp);
-
- ndbrequire(tmp.i != RNIL);
-
- apiConnectptr.p->commitAckMarker = tmp.i;
- tmp.p->transid1 = ttransid1;
- tmp.p->transid2 = ttransid2;
- tmp.p->apiNodeId = refToNode(tapplRef);
- tmp.p->noOfLqhs = 1;
- tmp.p->lqhNodeId[0] = tnodeid;
- tmp.p->apiConnectPtr = apiConnectptr.i;
-
-#if defined VM_TRACE || defined ERROR_INSERT
- {
- CommitAckMarkerPtr check;
- ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
- }
-#endif
- m_commitAckMarkerHash.add(tmp);
- }
-}//Dbtc::initApiConnectFail()
-
-/*------------------------------------------------------------*/
-/* INITIALISE AT TC CONNECT AT TAKE OVER WHEN ALLOCATING*/
-/* THE TC CONNECT RECORD. */
-/*------------------------------------------------------------*/
-void Dbtc::initTcConnectFail(Signal* signal)
-{
- tcConnectptr.p->apiConnect = apiConnectptr.i;
- tcConnectptr.p->tcOprec = ttcOprec;
- Uint32 treplicaNo = LqhTransConf::getReplicaNo(treqinfo);
- for (Uint32 i = 0; i < MAX_REPLICAS; i++) {
- tcConnectptr.p->failData[i] = LqhTransConf::InvalidStatus;
- }//for
- tcConnectptr.p->tcNodedata[treplicaNo] = tnodeid;
- tcConnectptr.p->failData[treplicaNo] = ttransStatus;
- tcConnectptr.p->lastReplicaNo = LqhTransConf::getLastReplicaNo(treqinfo);
- tcConnectptr.p->dirtyOp = LqhTransConf::getDirtyFlag(treqinfo);
-
-}//Dbtc::initTcConnectFail()
-
-/*----------------------------------------------------------*/
-/* INITIALISE TC NODE FAIL RECORD. */
-/*----------------------------------------------------------*/
-void Dbtc::initTcFail(Signal* signal)
-{
- tcNodeFailptr.i = 0;
- ptrAss(tcNodeFailptr, tcFailRecord);
- tcNodeFailptr.p->queueIndex = 0;
- tcNodeFailptr.p->failStatus = FS_IDLE;
-}//Dbtc::initTcFail()
-
-/*----------------------------------------------------------*/
-/* RELEASE_TAKE_OVER */
-/*----------------------------------------------------------*/
-void Dbtc::releaseTakeOver(Signal* signal)
-{
- TcConnectRecordPtr rtoNextTcConnectptr;
-
- rtoNextTcConnectptr.i = apiConnectptr.p->firstTcConnect;
- do {
- jam();
- tcConnectptr.i = rtoNextTcConnectptr.i;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- rtoNextTcConnectptr.i = tcConnectptr.p->nextTcConnect;
- releaseTcConnectFail(signal);
- } while (rtoNextTcConnectptr.i != RNIL);
- releaseApiConnectFail(signal);
-}//Dbtc::releaseTakeOver()
-
-/*---------------------------------------------------------------------------*/
-/* SETUP_FAIL_DATA */
-/* SETUP DATA TO REUSE TAKE OVER CODE FOR HANDLING ABORT/COMMIT IN NODE */
-/* FAILURE SITUATIONS. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::setupFailData(Signal* signal)
-{
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- do {
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_PREPARED:
- case OS_COMMITTING:
- jam();
- arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
- for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
- jam();
- /*-------------------------------------------------------------------
- * KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH.
- * IN THIS CASE ALL LQH'S ARE PREPARED AND WAITING FOR
- * COMMIT/ABORT DECISION.
- *------------------------------------------------------------------*/
- tcConnectptr.p->failData[tindex] = LqhTransConf::Prepared;
- }//for
- break;
- case OS_COMMITTED:
- case OS_COMPLETING:
- jam();
- arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
- for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
- jam();
- /*-------------------------------------------------------------------
- * KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH.
- * IN THIS CASE ALL LQH'S ARE COMMITTED AND WAITING FOR
- * COMPLETE MESSAGE.
- *------------------------------------------------------------------*/
- tcConnectptr.p->failData[tindex] = LqhTransConf::Committed;
- }//for
- break;
- case OS_COMPLETED:
- jam();
- arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
- for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
- jam();
- /*-------------------------------------------------------------------
- * KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH.
- * IN THIS CASE ALL LQH'S ARE COMPLETED.
- *-------------------------------------------------------------------*/
- tcConnectptr.p->failData[tindex] = LqhTransConf::InvalidStatus;
- }//for
- break;
- default:
- jam();
- sendSystemError(signal, __LINE__);
- break;
- }//switch
- if (tabortInd != ZCOMMIT_SETUP) {
- jam();
- for (UintR Ti = 0; Ti <= tcConnectptr.p->lastReplicaNo; Ti++) {
- hostptr.i = tcConnectptr.p->tcNodedata[Ti];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- if (hostptr.p->hostStatus != HS_ALIVE) {
- jam();
- /*-----------------------------------------------------------------
- * FAILURE OF ANY INVOLVED NODE ALWAYS INVOKES AN ABORT DECISION.
- *-----------------------------------------------------------------*/
- tabortInd = ZTRUE;
- }//if
- }//for
- }//if
- tcConnectptr.p->tcConnectstate = OS_TAKE_OVER;
- tcConnectptr.p->tcOprec = tcConnectptr.i;
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- } while (tcConnectptr.i != RNIL);
- apiConnectptr.p->tcBlockref = cownref;
- apiConnectptr.p->currentTcConnect = apiConnectptr.p->firstTcConnect;
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->currentReplicaNo = tcConnectptr.p->lastReplicaNo;
- tcurrentReplicaNo = tcConnectptr.p->lastReplicaNo;
-}//Dbtc::setupFailData()
-
-/*----------------------------------------------------------*/
-/* UPDATE THE STATE OF THE API CONNECT FOR THIS PART. */
-/*----------------------------------------------------------*/
-void Dbtc::updateApiStateFail(Signal* signal)
-{
- if(LqhTransConf::getMarkerFlag(treqinfo)){
- jam();
- const Uint32 marker = apiConnectptr.p->commitAckMarker;
- if(marker == RNIL){
- jam();
-
- CommitAckMarkerPtr tmp;
- m_commitAckMarkerHash.seize(tmp);
- ndbrequire(tmp.i != RNIL);
-
- apiConnectptr.p->commitAckMarker = tmp.i;
- tmp.p->transid1 = ttransid1;
- tmp.p->transid2 = ttransid2;
- tmp.p->apiNodeId = refToNode(tapplRef);
- tmp.p->noOfLqhs = 1;
- tmp.p->lqhNodeId[0] = tnodeid;
- tmp.p->apiConnectPtr = apiConnectptr.i;
-#if defined VM_TRACE || defined ERROR_INSERT
- {
- CommitAckMarkerPtr check;
- ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
- }
-#endif
- m_commitAckMarkerHash.add(tmp);
- } else {
- jam();
-
- CommitAckMarkerPtr tmp;
- tmp.i = marker;
- tmp.p = m_commitAckMarkerHash.getPtr(marker);
-
- const Uint32 noOfLqhs = tmp.p->noOfLqhs;
- ndbrequire(noOfLqhs < MAX_REPLICAS);
- tmp.p->lqhNodeId[noOfLqhs] = tnodeid;
- tmp.p->noOfLqhs = (noOfLqhs + 1);
- }
- }
-
- switch (ttransStatus) {
- case LqhTransConf::Committed:
- jam();
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_FAIL_COMMITTING:
- case CS_FAIL_COMMITTED:
- jam();
- ndbrequire(tgci == apiConnectptr.p->globalcheckpointid);
- break;
- case CS_FAIL_PREPARED:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_COMMITTING;
- apiConnectptr.p->globalcheckpointid = tgci;
- break;
- case CS_FAIL_COMPLETED:
- jam();
- apiConnectptr.p->globalcheckpointid = tgci;
- apiConnectptr.p->apiConnectstate = CS_FAIL_COMMITTED;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
- break;
- case LqhTransConf::Prepared:
- jam();
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_FAIL_COMMITTED:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_COMMITTING;
- break;
- case CS_FAIL_ABORTED:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_ABORTING;
- break;
- case CS_FAIL_COMMITTING:
- case CS_FAIL_PREPARED:
- case CS_FAIL_ABORTING:
- jam();
- /*empty*/;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
- break;
- case LqhTransConf::Aborted:
- jam();
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_FAIL_COMMITTING:
- case CS_FAIL_COMMITTED:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- case CS_FAIL_PREPARED:
- jam();
- apiConnectptr.p->apiConnectstate = CS_FAIL_ABORTING;
- break;
- case CS_FAIL_ABORTING:
- case CS_FAIL_ABORTED:
- jam();
- /*empty*/;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
- break;
- case LqhTransConf::Marker:
- jam();
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
-}//Dbtc::updateApiStateFail()
-
-/*------------------------------------------------------------*/
-/* UPDATE_TC_STATE_FAIL */
-/* */
-/* WE NEED TO UPDATE THE STATUS OF TC_CONNECT RECORD AND*/
-/* WE ALSO NEED TO CHECK THAT THERE IS CONSISTENCY */
-/* BETWEEN THE DIFFERENT REPLICAS. */
-/*------------------------------------------------------------*/
-void Dbtc::updateTcStateFail(Signal* signal)
-{
- const Uint8 treplicaNo = LqhTransConf::getReplicaNo(treqinfo);
- const Uint8 tlastReplicaNo = LqhTransConf::getLastReplicaNo(treqinfo);
- const Uint8 tdirtyOp = LqhTransConf::getDirtyFlag(treqinfo);
-
- TcConnectRecord * regTcPtr = tcConnectptr.p;
-
- ndbrequire(regTcPtr->apiConnect == apiConnectptr.i);
- ndbrequire(regTcPtr->failData[treplicaNo] == LqhTransConf::InvalidStatus);
- ndbrequire(regTcPtr->lastReplicaNo == tlastReplicaNo);
- ndbrequire(regTcPtr->dirtyOp == tdirtyOp);
-
- regTcPtr->tcNodedata[treplicaNo] = tnodeid;
- regTcPtr->failData[treplicaNo] = ttransStatus;
-}//Dbtc::updateTcStateFail()
-
-void Dbtc::execTCGETOPSIZEREQ(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(8000);
-
- UintR Tuserpointer = signal->theData[0]; /* DBDIH POINTER */
- BlockReference Tusersblkref = signal->theData[1];/* DBDIH BLOCK REFERENCE */
- signal->theData[0] = Tuserpointer;
- signal->theData[1] = coperationsize;
- sendSignal(Tusersblkref, GSN_TCGETOPSIZECONF, signal, 2, JBB);
-}//Dbtc::execTCGETOPSIZEREQ()
-
-void Dbtc::execTC_CLOPSIZEREQ(Signal* signal)
-{
- jamEntry();
- CRASH_INSERTION(8001);
-
- tuserpointer = signal->theData[0];
- tusersblkref = signal->theData[1];
- /* DBDIH BLOCK REFERENCE */
- coperationsize = 0;
- signal->theData[0] = tuserpointer;
- sendSignal(tusersblkref, GSN_TC_CLOPSIZECONF, signal, 1, JBB);
-}//Dbtc::execTC_CLOPSIZEREQ()
-
-/* ######################################################################### */
-/* ####### ERROR MODULE ####### */
-/* ######################################################################### */
-void Dbtc::tabStateErrorLab(Signal* signal)
-{
- terrorCode = ZSTATE_ERROR;
- releaseAtErrorLab(signal);
-}//Dbtc::tabStateErrorLab()
-
-void Dbtc::wrongSchemaVersionErrorLab(Signal* signal)
-{
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
-
- TableRecordPtr tabPtr;
- tabPtr.i = tcKeyReq->tableId;
- const Uint32 schemVer = tcKeyReq->tableSchemaVersion;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- terrorCode = tabPtr.p->getErrorCode(schemVer);
-
- abortErrorLab(signal);
-}//Dbtc::wrongSchemaVersionErrorLab()
-
-void Dbtc::noFreeConnectionErrorLab(Signal* signal)
-{
- terrorCode = ZNO_FREE_TC_CONNECTION;
- abortErrorLab(signal); /* RECORD. OTHERWISE GOTO ERRORHANDLING */
-}//Dbtc::noFreeConnectionErrorLab()
-
-void Dbtc::aiErrorLab(Signal* signal)
-{
- terrorCode = ZLENGTH_ERROR;
- abortErrorLab(signal);
-}//Dbtc::aiErrorLab()
-
-void Dbtc::seizeAttrbuferrorLab(Signal* signal)
-{
- terrorCode = ZGET_ATTRBUF_ERROR;
- abortErrorLab(signal);
-}//Dbtc::seizeAttrbuferrorLab()
-
-void Dbtc::seizeDatabuferrorLab(Signal* signal)
-{
- terrorCode = ZGET_DATAREC_ERROR;
- releaseAtErrorLab(signal);
-}//Dbtc::seizeDatabuferrorLab()
-
-void Dbtc::releaseAtErrorLab(Signal* signal)
-{
- ptrGuard(tcConnectptr);
- tcConnectptr.p->tcConnectstate = OS_ABORTING;
- /*-------------------------------------------------------------------------*
- * A FAILURE OF THIS OPERATION HAS OCCURRED. THIS FAILURE WAS EITHER A
- * FAULTY PARAMETER OR A RESOURCE THAT WAS NOT AVAILABLE.
- * WE WILL ABORT THE ENTIRE TRANSACTION SINCE THIS IS THE SAFEST PATH
- * TO HANDLE THIS PROBLEM.
- * SINCE WE HAVE NOT YET CONTACTED ANY LQH WE SET NUMBER OF NODES TO ZERO
- * WE ALSO SET THE STATE TO ABORTING TO INDICATE THAT WE ARE NOT EXPECTING
- * ANY SIGNALS.
- *-------------------------------------------------------------------------*/
- tcConnectptr.p->noOfNodes = 0;
- abortErrorLab(signal);
-}//Dbtc::releaseAtErrorLab()
-
-void Dbtc::warningHandlerLab(Signal* signal, int line)
-{
- ndbassert(false);
-}//Dbtc::warningHandlerLab()
-
-void Dbtc::systemErrorLab(Signal* signal, int line)
-{
- progError(line, NDBD_EXIT_NDBREQUIRE);
-}//Dbtc::systemErrorLab()
-
-
-/* ######################################################################### *
- * ####### SCAN MODULE ####### *
- * ######################################################################### *
-
- The application orders a scan of a table. We divide the scan into a scan on
- each fragment. The scan uses the primary replicas since the scan might be
- used for an update in a separate transaction.
-
- Scans are always done as a separate transaction. Locks from the scan
- can be overtaken by another transaction. Scans can never lock the entire
- table. Locks are released immediately after the read has been verified
- by the application. There is not even an option to leave the locks.
- The reason is that this would hurt real-time behaviour too much.
-
- -# The first step in handling a scan of a table is to receive all signals
- defining the scan. If failures occur during this step we release all
- resource and reply with SCAN_TABREF providing the error code.
- If system load is too high, the request will not be allowed.
-
- -# The second step retrieves the number of fragments that exist in the
- table. It also ensures that the table actually exist. After this,
- the scan is ready to be parallelised. The idea is that the receiving
- process (hereafter called delivery process) will start up a number
- of scan processes. Each of these scan processes will
- independently scan one fragment at a time. The delivery
- process object is the scan record and the scan process object is
- the scan fragment record plus the scan operation record.
-
- -# The third step is thus performed in parallel. In the third step each
- scan process retrieves the primary replica of the fragment it will
- scan. Then it starts the scan as soon as the load on that node permits.
-
- The LQH returns either when it retrieved the maximum number of tuples or
- when it has retrived at least one tuple and is hindered by a lock to
- retrieve the next tuple. This is to ensure that a scan process never
- can be involved in a deadlock situation.
-
- When the scan process receives a number of tuples to report to the
- application it checks the state of the delivery process. Only one delivery
- at a time is handled by the application. Thus if the delivery process
- has already sent a number of tuples to the application this set of tuples
- are queued.
-
- When the application requests the next set of tuples it is immediately
- delivered if any are queued, otherwise it waits for the next scan
- process that is ready to deliver.
-
-
- ERROR HANDLING
-
- As already mentioned it is rather easy to handle errors before the scan
- processes have started. In this case it is enough to release the resources
- and send SCAN_TAB_REF.
-
- If an error occurs in any of the scan processes then we have to stop all
- scan processes. We do however only stop the delivery process and ask
- the api to order us to close the scan. The reason is that we can easily
- enter into difficult timing problems since the application and this
- block is out of synch we will thus always start by report the error to
- the application and wait for a close request. This error report uses the
- SCAN_TABREF signal with a special error code that the api must check for.
-
-
- CLOSING AN ACTIVE SCAN
-
- The application can close a scan for several reasons before it is completed.
- One reason was mentioned above where an error in a scan process led to a
- request to close the scan. Another reason could simply be that the
- application found what it looked for and is thus not interested in the
- rest of the scan.
-
- IT COULD ALSO BE DEPENDENT ON INTERNAL ERRORS IN THE API.
-
- When a close scan request is received, all scan processes are stopped and all
- resources belonging to those scan processes are released. Stopping the scan
- processes most often includes communication with an LQH where the local scan
- is controlled. Finally all resources belonging to the scan is released and
- the SCAN_TABCONF is sent with an indication of that the scan is closed.
-
-
- CLOSING A COMPLETED SCAN
-
- When all scan processes are completed then a report is sent to the
- application which indicates that no more tuples can be fetched.
- The application will send a close scan and the same action as when
- closing an active scan is performed.
- In this case it will of course not find any active scan processes.
- It will even find all scan processes already released.
-
- The reason for requiring the api to close the scan is the same as above.
- It is to avoid any timing problems due to that the api and this block
- is out of synch.
-
- * ######################################################################## */
-void Dbtc::execSCAN_TABREQ(Signal* signal)
-{
- const ScanTabReq * const scanTabReq = (ScanTabReq *)&signal->theData[0];
- const Uint32 ri = scanTabReq->requestInfo;
- const Uint32 aiLength = (scanTabReq->attrLenKeyLen & 0xFFFF);
- const Uint32 keyLen = scanTabReq->attrLenKeyLen >> 16;
- const Uint32 schemaVersion = scanTabReq->tableSchemaVersion;
- const Uint32 transid1 = scanTabReq->transId1;
- const Uint32 transid2 = scanTabReq->transId2;
- const Uint32 tmpXX = scanTabReq->buddyConPtr;
- const Uint32 buddyPtr = (tmpXX == 0xFFFFFFFF ? RNIL : tmpXX);
- Uint32 currSavePointId = 0;
-
- Uint32 scanConcurrency = scanTabReq->getParallelism(ri);
- Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(ri);
- Uint32 scanParallel = scanConcurrency;
- Uint32 errCode;
- ScanRecordPtr scanptr;
-
- jamEntry();
-
- SegmentedSectionPtr api_op_ptr;
- signal->getSection(api_op_ptr, 0);
- copy(&cdata[0], api_op_ptr);
- releaseSections(signal);
-
- apiConnectptr.i = scanTabReq->apiConnectPtr;
- tabptr.i = scanTabReq->tableId;
-
- if (apiConnectptr.i >= capiConnectFilesize)
- {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
-
- ptrAss(apiConnectptr, apiConnectRecord);
- ApiConnectRecord * transP = apiConnectptr.p;
-
- if (transP->apiConnectstate != CS_CONNECTED) {
- jam();
- // could be left over from TCKEYREQ rollback
- if (transP->apiConnectstate == CS_ABORTING &&
- transP->abortState == AS_IDLE) {
- jam();
- } else if(transP->apiConnectstate == CS_STARTED &&
- transP->firstTcConnect == RNIL){
- jam();
- // left over from simple/dirty read
- } else {
- jam();
- jamLine(transP->apiConnectstate);
- errCode = ZSTATE_ERROR;
- goto SCAN_TAB_error_no_state_change;
- }
- }
-
- if(tabptr.i >= ctabrecFilesize)
- {
- errCode = ZUNKNOWN_TABLE_ERROR;
- goto SCAN_TAB_error;
- }
-
- ptrAss(tabptr, tableRecord);
- if ((aiLength == 0) ||
- (!tabptr.p->checkTable(schemaVersion)) ||
- (scanConcurrency == 0) ||
- (cfirstfreeTcConnect == RNIL) ||
- (cfirstfreeScanrec == RNIL)) {
- goto SCAN_error_check;
- }
- if (buddyPtr != RNIL) {
- jam();
- ApiConnectRecordPtr buddyApiPtr;
- buddyApiPtr.i = buddyPtr;
- ptrCheckGuard(buddyApiPtr, capiConnectFilesize, apiConnectRecord);
- if ((transid1 == buddyApiPtr.p->transid[0]) &&
- (transid2 == buddyApiPtr.p->transid[1])) {
- jam();
-
- if (buddyApiPtr.p->apiConnectstate == CS_ABORTING) {
- // transaction has been aborted
- jam();
- errCode = buddyApiPtr.p->returncode;
- goto SCAN_TAB_error;
- }//if
- currSavePointId = buddyApiPtr.p->currSavePointId;
- buddyApiPtr.p->currSavePointId++;
- }
- }
-
- if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
- getNodeState().getSingleUserApi() !=
- refToNode(apiConnectptr.p->ndbapiBlockref))
- {
- errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- goto SCAN_TAB_error;
- }
-
- seizeTcConnect(signal);
- tcConnectptr.p->apiConnect = apiConnectptr.i;
- tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN;
- apiConnectptr.p->lastTcConnect = tcConnectptr.i;
-
- seizeCacheRecord(signal);
- cachePtr.p->keylen = keyLen;
- cachePtr.p->save1 = 0;
- cachePtr.p->distributionKey = scanTabReq->distributionKey;
- cachePtr.p->distributionKeyIndicator= ScanTabReq::getDistributionKeyFlag(ri);
- scanptr = seizeScanrec(signal);
-
- ndbrequire(transP->apiScanRec == RNIL);
- ndbrequire(scanptr.p->scanApiRec == RNIL);
-
- initScanrec(scanptr, scanTabReq, scanParallel, noOprecPerFrag);
-
- transP->apiScanRec = scanptr.i;
- transP->returncode = 0;
- transP->transid[0] = transid1;
- transP->transid[1] = transid2;
- transP->buddyPtr = buddyPtr;
-
- // The scan is started
- transP->apiConnectstate = CS_START_SCAN;
- transP->currSavePointId = currSavePointId;
-
- /**********************************************************
- * We start the timer on scanRec to be able to discover a
- * timeout in the API the API now is in charge!
- ***********************************************************/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- updateBuddyTimer(apiConnectptr);
-
- /***********************************************************
- * 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;
-
- if (ERROR_INSERTED(8038))
- {
- /**
- * Force API_FAILREQ
- */
- DisconnectRep * const rep = (DisconnectRep *)signal->getDataPtrSend();
- rep->nodeId = refToNode(apiConnectptr.p->ndbapiBlockref);
- rep->err = 8038;
-
- EXECUTE_DIRECT(CMVMI, GSN_DISCONNECT_REP, signal, 2);
- CLEAR_ERROR_INSERT_VALUE;
- }
-
- return;
-
- SCAN_error_check:
- if (aiLength == 0) {
- jam()
- errCode = ZSCAN_AI_LEN_ERROR;
- goto SCAN_TAB_error;
- }//if
- if (!tabptr.p->checkTable(schemaVersion)){
- jam();
- errCode = tabptr.p->getErrorCode(schemaVersion);
- goto SCAN_TAB_error;
- }//if
- if (scanConcurrency == 0) {
- jam();
- errCode = ZNO_CONCURRENCY_ERROR;
- goto SCAN_TAB_error;
- }//if
- if (cfirstfreeTcConnect == RNIL) {
- jam();
- errCode = ZNO_FREE_TC_CONNECTION;
- goto SCAN_TAB_error;
- }//if
- ndbrequire(cfirstfreeScanrec == RNIL);
- jam();
- errCode = ZNO_SCANREC_ERROR;
- goto SCAN_TAB_error;
-
-SCAN_TAB_error:
- jam();
- /**
- * Prepare for up coming ATTRINFO/KEYINFO
- */
- transP->apiConnectstate = CS_ABORTING;
- transP->abortState = AS_IDLE;
- transP->transid[0] = transid1;
- transP->transid[1] = transid2;
-
-SCAN_TAB_error_no_state_change:
-
- ScanTabRef * ref = (ScanTabRef*)&signal->theData[0];
- ref->apiConnectPtr = transP->ndbapiConnect;
- ref->transId1 = transid1;
- ref->transId2 = transid2;
- ref->errorCode = errCode;
- ref->closeNeeded = 0;
- sendSignal(transP->ndbapiBlockref, GSN_SCAN_TABREF,
- signal, ScanTabRef::SignalLength, JBB);
- return;
-}//Dbtc::execSCAN_TABREQ()
-
-void Dbtc::initScanrec(ScanRecordPtr scanptr,
- const ScanTabReq * scanTabReq,
- UintR scanParallel,
- UintR noOprecPerFrag)
-{
- const UintR ri = scanTabReq->requestInfo;
- scanptr.p->scanTcrec = tcConnectptr.i;
- scanptr.p->scanApiRec = apiConnectptr.i;
- scanptr.p->scanAiLength = scanTabReq->attrLenKeyLen & 0xFFFF;
- scanptr.p->scanKeyLen = scanTabReq->attrLenKeyLen >> 16;
- scanptr.p->scanTableref = tabptr.i;
- scanptr.p->scanSchemaVersion = scanTabReq->tableSchemaVersion;
- scanptr.p->scanParallel = scanParallel;
- scanptr.p->first_batch_size_rows = scanTabReq->first_batch_size;
- scanptr.p->batch_byte_size = scanTabReq->batch_byte_size;
- scanptr.p->batch_size_rows = noOprecPerFrag;
-
- Uint32 tmp = 0;
- ScanFragReq::setLockMode(tmp, ScanTabReq::getLockMode(ri));
- ScanFragReq::setHoldLockFlag(tmp, ScanTabReq::getHoldLockFlag(ri));
- ScanFragReq::setKeyinfoFlag(tmp, ScanTabReq::getKeyinfoFlag(ri));
- ScanFragReq::setReadCommittedFlag(tmp,ScanTabReq::getReadCommittedFlag(ri));
- ScanFragReq::setRangeScanFlag(tmp, ScanTabReq::getRangeScanFlag(ri));
- ScanFragReq::setDescendingFlag(tmp, ScanTabReq::getDescendingFlag(ri));
- ScanFragReq::setTupScanFlag(tmp, ScanTabReq::getTupScanFlag(ri));
- ScanFragReq::setAttrLen(tmp, scanTabReq->attrLenKeyLen & 0xFFFF);
- ScanFragReq::setNoDiskFlag(tmp, ScanTabReq::getNoDiskFlag(ri));
-
- scanptr.p->scanRequestInfo = tmp;
- scanptr.p->scanStoredProcId = scanTabReq->storedProcId;
- 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->scanFragState = ScanFragRec::IDLE;
- ptr.p->scanRec = scanptr.i;
- ptr.p->scanFragId = 0;
- ptr.p->m_apiPtr = cdata[i];
- }//for
-
- (* (ScanTabReq::getRangeScanFlag(ri) ?
- &c_counters.c_range_scan_count :
- &c_counters.c_scan_count))++;
-}//Dbtc::initScanrec()
-
-void Dbtc::scanTabRefLab(Signal* signal, Uint32 errCode)
-{
- 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 = errCode;
- ref->closeNeeded = 0;
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_SCAN_TABREF,
- signal, ScanTabRef::SignalLength, JBB);
-}//Dbtc::scanTabRefLab()
-
-/*---------------------------------------------------------------------------*/
-/* */
-/* RECEPTION OF ATTRINFO FOR SCAN TABLE REQUEST. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::scanAttrinfoLab(Signal* signal, UintR Tlen)
-{
- ScanRecordPtr scanptr;
- scanptr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- cachePtr.i = apiConnectptr.p->cachePtr;
- ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord);
- CacheRecord * const regCachePtr = cachePtr.p;
- ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_AI);
-
- regCachePtr->currReclenAi = regCachePtr->currReclenAi + Tlen;
- if (regCachePtr->currReclenAi < scanptr.p->scanAiLength) {
- if (cfirstfreeAttrbuf == RNIL) {
- goto scanAttrinfo_attrbuf_error;
- }//if
- saveAttrbuf(signal);
- } else {
- if (regCachePtr->currReclenAi > scanptr.p->scanAiLength) {
- goto scanAttrinfo_len_error;
- } else {
- /* CURR_RECLEN_AI = SCAN_AI_LENGTH */
- if (cfirstfreeAttrbuf == RNIL) {
- goto scanAttrinfo_attrbuf2_error;
- }//if
- saveAttrbuf(signal);
- /**************************************************
- * WE HAVE NOW RECEIVED ALL INFORMATION CONCERNING
- * THIS SCAN. WE ARE READY TO START THE ACTUAL
- * EXECUTION OF THE SCAN QUERY
- **************************************************/
- diFcountReqLab(signal, scanptr);
- return;
- }//if
- }//if
- return;
-
-scanAttrinfo_attrbuf_error:
- jam();
- abortScanLab(signal, scanptr, ZGET_ATTRBUF_ERROR, true);
- return;
-
-scanAttrinfo_attrbuf2_error:
- jam();
- abortScanLab(signal, scanptr, ZGET_ATTRBUF_ERROR, true);
- return;
-
-scanAttrinfo_len_error:
- jam();
- abortScanLab(signal, scanptr, ZLENGTH_ERROR, true);
- return;
-}//Dbtc::scanAttrinfoLab()
-
-void Dbtc::diFcountReqLab(Signal* signal, ScanRecordPtr scanptr)
-{
- /**
- * Check so that the table is not being dropped
- */
- TableRecordPtr tabPtr;
- tabPtr.i = scanptr.p->scanTableref;
- tabPtr.p = &tableRecord[tabPtr.i];
- if (tabPtr.p->checkTable(scanptr.p->scanSchemaVersion)){
- ;
- } else {
- abortScanLab(signal, scanptr,
- tabPtr.p->getErrorCode(scanptr.p->scanSchemaVersion),
- true);
- return;
- }
-
- scanptr.p->scanNextFragId = 0;
- scanptr.p->m_booked_fragments_count= 0;
- scanptr.p->scanState = ScanRecord::WAIT_FRAGMENT_COUNT;
-
- if(!cachePtr.p->distributionKeyIndicator)
- {
- jam();
- /*************************************************
- * THE FIRST STEP TO RECEIVE IS SUCCESSFULLY COMPLETED.
- * WE MUST FIRST GET THE NUMBER OF FRAGMENTS IN THE TABLE.
- ***************************************************/
- DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtrSend();
- req->m_connectionData = tcConnectptr.p->dihConnectptr;
- req->m_tableRef = scanptr.p->scanTableref;
- sendSignal(cdihblockref, GSN_DI_FCOUNTREQ, signal,
- DihFragCountReq::SignalLength, JBB);
- }
- else
- {
- signal->theData[0] = tcConnectptr.p->dihConnectptr;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = cachePtr.p->distributionKey;
- EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
- UintR TerrorIndicator = signal->theData[0];
- jamEntry();
- if (TerrorIndicator != 0) {
- DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
- ref->m_connectionData = tcConnectptr.i;
- ref->m_error = signal->theData[1];
- execDI_FCOUNTREF(signal);
- return;
- }
-
- UintR Tdata1 = signal->theData[1];
- scanptr.p->scanNextFragId = Tdata1;
- DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
- conf->m_connectionData = tcConnectptr.i;
- conf->m_fragmentCount = 1; // Frag count
- execDI_FCOUNTCONF(signal);
- }
- return;
-}//Dbtc::diFcountReqLab()
-
-/********************************************************************
- * execDI_FCOUNTCONF
- *
- * WE HAVE ASKED DIH ABOUT THE NUMBER OF FRAGMENTS IN THIS TABLE.
- * WE WILL NOW START A NUMBER OF PARALLEL SCAN PROCESSES. EACH OF
- * THESE WILL SCAN ONE FRAGMENT AT A TIME. THEY WILL CONTINUE THIS
- * UNTIL THERE ARE NO MORE FRAGMENTS TO SCAN OR UNTIL THE APPLICATION
- * CLOSES THE SCAN.
- ********************************************************************/
-void Dbtc::execDI_FCOUNTCONF(Signal* signal)
-{
- jamEntry();
- DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
- tcConnectptr.i = conf->m_connectionData;
- Uint32 tfragCount = conf->m_fragmentCount;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- ScanRecordPtr scanptr;
- scanptr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_FRAGMENT_COUNT);
- if (apiConnectptr.p->apiFailState == ZTRUE) {
- jam();
- releaseScanResources(scanptr, true);
- handleApiFailState(signal, apiConnectptr.i);
- return;
- }//if
- if (tfragCount == 0) {
- jam();
- abortScanLab(signal, scanptr, ZNO_FRAGMENT_ERROR, true);
- return;
- }//if
-
- /**
- * Check so that the table is not being dropped
- */
- TableRecordPtr tabPtr;
- tabPtr.i = scanptr.p->scanTableref;
- tabPtr.p = &tableRecord[tabPtr.i];
- if (tabPtr.p->checkTable(scanptr.p->scanSchemaVersion)){
- ;
- } else {
- abortScanLab(signal, scanptr,
- tabPtr.p->getErrorCode(scanptr.p->scanSchemaVersion),
- true);
- return;
- }
-
- scanptr.p->scanParallel = tfragCount;
- scanptr.p->scanNoFrag = tfragCount;
- scanptr.p->scanState = ScanRecord::RUNNING;
-
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- updateBuddyTimer(apiConnectptr);
-
- ScanFragRecPtr ptr;
- ScanFragList list(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
- for (list.first(ptr); !ptr.isNull() && tfragCount;
- list.next(ptr), tfragCount--){
- jam();
-
- ptr.p->lqhBlockref = 0;
- 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
-
- ScanFragList queued(c_scan_frag_pool, scanptr.p->m_queued_scan_frags);
- for (; !ptr.isNull();)
- {
- ptr.p->m_ops = 0;
- ptr.p->m_totalLen = 0;
- ptr.p->m_scan_frag_conf_status = 1;
- ptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY;
- ptr.p->stopFragTimer();
-
- ScanFragRecPtr tmp = ptr;
- list.next(ptr);
- list.remove(tmp);
- queued.add(tmp);
- scanptr.p->m_queued_count++;
- }
-}//Dbtc::execDI_FCOUNTCONF()
-
-/******************************************************
- * execDI_FCOUNTREF
- ******************************************************/
-void Dbtc::execDI_FCOUNTREF(Signal* signal)
-{
- jamEntry();
- DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
- tcConnectptr.i = ref->m_connectionData;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- const Uint32 errCode = ref->m_error;
- apiConnectptr.i = tcConnectptr.p->apiConnect;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- ScanRecordPtr scanptr;
- scanptr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- ndbrequire(scanptr.p->scanState == ScanRecord::WAIT_FRAGMENT_COUNT);
- if (apiConnectptr.p->apiFailState == ZTRUE) {
- jam();
- releaseScanResources(scanptr, true);
- handleApiFailState(signal, apiConnectptr.i);
- return;
- }//if
- abortScanLab(signal, scanptr, errCode, true);
-}//Dbtc::execDI_FCOUNTREF()
-
-void Dbtc::abortScanLab(Signal* signal, ScanRecordPtr scanptr, Uint32 errCode,
- bool not_started)
-{
- scanTabRefLab(signal, errCode);
- releaseScanResources(scanptr, not_started);
-}//Dbtc::abortScanLab()
-
-void Dbtc::releaseScanResources(ScanRecordPtr scanPtr,
- bool not_started)
-{
- if (apiConnectptr.p->cachePtr != RNIL) {
- cachePtr.i = apiConnectptr.p->cachePtr;
- ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord);
- releaseKeys();
- releaseAttrinfo();
- }//if
- tcConnectptr.i = scanPtr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- releaseTcCon();
-
- if (not_started)
- {
- jam();
- ScanFragList run(c_scan_frag_pool, scanPtr.p->m_running_scan_frags);
- ScanFragList queue(c_scan_frag_pool, scanPtr.p->m_queued_scan_frags);
- run.release();
- queue.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());
-
- ndbassert(scanPtr.p->scanApiRec == apiConnectptr.i);
- ndbassert(apiConnectptr.p->apiScanRec == scanPtr.i);
-
- // link into free list
- scanPtr.p->nextScan = cfirstfreeScanrec;
- scanPtr.p->scanState = ScanRecord::IDLE;
- scanPtr.p->scanTcrec = RNIL;
- scanPtr.p->scanApiRec = RNIL;
- cfirstfreeScanrec = scanPtr.i;
-
- apiConnectptr.p->apiScanRec = RNIL;
- apiConnectptr.p->apiConnectstate = CS_CONNECTED;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
-}//Dbtc::releaseScanResources()
-
-
-/****************************************************************
- * execDIGETPRIMCONF
- *
- * WE HAVE RECEIVED THE PRIMARY NODE OF THIS FRAGMENT.
- * WE ARE NOW READY TO ASK FOR PERMISSION TO LOAD THIS
- * SPECIFIC NODE WITH A SCAN OPERATION.
- ****************************************************************/
-void Dbtc::execDIGETPRIMCONF(Signal* signal)
-{
- jamEntry();
- // tcConnectptr.i in theData[0] is not used
- scanFragptr.i = signal->theData[1];
- 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();
-
- ScanRecordPtr scanptr;
- scanptr.i = scanFragptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- /**
- * This must be false as select count(*) otherwise
- * can "pass" committing on backup fragments and
- * get incorrect row count
- */
- if(false && ScanFragReq::getReadCommittedFlag(scanptr.p->scanRequestInfo))
- {
- jam();
- Uint32 max = 3+signal->theData[6];
- Uint32 nodeid = getOwnNodeId();
- for(Uint32 i = 3; i<max; i++)
- if(signal->theData[i] == nodeid)
- {
- jam();
- tnodeid = nodeid;
- break;
- }
- }
-
- {
- /**
- * Check table
- */
- TableRecordPtr tabPtr;
- tabPtr.i = scanptr.p->scanTableref;
- ptrAss(tabPtr, tableRecord);
- Uint32 schemaVersion = scanptr.p->scanSchemaVersion;
- if(tabPtr.p->checkTable(schemaVersion) == false){
- jam();
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(scanFragptr);
- scanError(signal, scanptr, tabPtr.p->getErrorCode(schemaVersion));
- return;
- }
- }
-
- tcConnectptr.i = scanptr.p->scanTcrec;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.i = scanptr.p->scanApiRec;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- cachePtr.i = apiConnectptr.p->cachePtr;
- ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord);
- switch (scanptr.p->scanState) {
- case ScanRecord::CLOSING_SCAN:
- jam();
- updateBuddyTimer(apiConnectptr);
- {
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(scanFragptr);
- }
- close_scan_req_send_conf(signal, scanptr);
- return;
- default:
- jam();
- /*empty*/;
- break;
- }//switch
- Uint32 ref = calcLqhBlockRef(tnodeid);
- scanFragptr.p->lqhBlockref = ref;
- scanFragptr.p->m_connectCount = getNodeInfo(tnodeid).m_connectCount;
- sendScanFragReq(signal, scanptr.p, scanFragptr.p);
- if(ERROR_INSERTED(8035))
- globalTransporterRegistry.performSend();
- attrbufptr.i = cachePtr.p->firstAttrbuf;
- while (attrbufptr.i != RNIL) {
- jam();
- ptrCheckGuard(attrbufptr, cattrbufFilesize, attrbufRecord);
- sendAttrinfo(signal,
- scanFragptr.i,
- attrbufptr.p,
- ref);
- attrbufptr.i = attrbufptr.p->attrbuf[ZINBUF_NEXT];
- if(ERROR_INSERTED(8035))
- globalTransporterRegistry.performSend();
- }//while
- scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
- scanFragptr.p->startFragTimer(ctcTimer);
- updateBuddyTimer(apiConnectptr);
- /*********************************************
- * WE HAVE NOW STARTED A FRAGMENT SCAN. NOW
- * WAIT FOR THE FIRST SCANNED RECORDS
- *********************************************/
-}//Dbtc::execDIGETPRIMCONF
-
-/***************************************************
- * execDIGETPRIMREF
- *
- * WE ARE NOW FORCED TO STOP THE SCAN. THIS ERROR
- * IS NOT RECOVERABLE SINCE THERE IS A PROBLEM WITH
- * FINDING A PRIMARY REPLICA OF A CERTAIN FRAGMENT.
- ***************************************************/
-void Dbtc::execDIGETPRIMREF(Signal* signal)
-{
- jamEntry();
- // tcConnectptr.i in theData[0] is not used.
- scanFragptr.i = signal->theData[1];
- const Uint32 errCode = signal->theData[2];
- c_scan_frag_pool.getPtr(scanFragptr);
- ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::WAIT_GET_PRIMCONF);
-
- ScanRecordPtr scanptr;
- scanptr.i = scanFragptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(scanFragptr);
-
- scanError(signal, scanptr, errCode);
-}//Dbtc::execDIGETPRIMREF()
-
-/**
- * Dbtc::execSCAN_FRAGREF
- * Our attempt to scan a fragment was refused
- * set error code and close all other fragment
- * scan's belonging to this scan
- */
-void Dbtc::execSCAN_FRAGREF(Signal* signal)
-{
- const ScanFragRef * const ref = (ScanFragRef *)&signal->theData[0];
-
- jamEntry();
- const Uint32 errCode = ref->errorCode;
-
- scanFragptr.i = ref->senderData;
- c_scan_frag_pool.getPtr(scanFragptr);
-
- ScanRecordPtr scanptr;
- scanptr.i = scanFragptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- apiConnectptr.i = scanptr.p->scanApiRec;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
-
- Uint32 transid1 = apiConnectptr.p->transid[0] ^ ref->transId1;
- Uint32 transid2 = apiConnectptr.p->transid[1] ^ ref->transId2;
- transid1 = transid1 | transid2;
- if (transid1 != 0) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
-
- /**
- * Set errorcode, close connection to this lqh fragment,
- * stop fragment timer and call scanFragError to start
- * close of the other fragment scans
- */
- ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::LQH_ACTIVE);
- {
- scanFragptr.p->scanFragState = ScanFragRec::COMPLETED;
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(scanFragptr);
- scanFragptr.p->stopFragTimer();
- }
- scanError(signal, scanptr, errCode);
-}//Dbtc::execSCAN_FRAGREF()
-
-/**
- * Dbtc::scanError
- *
- * Called when an error occurs during
- */
-void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode)
-{
- jam();
- ScanRecord* scanP = scanptr.p;
-
- DEBUG("scanError, errorCode = "<< errorCode <<
- ", scanState = " << scanptr.p->scanState);
-
- apiConnectptr.i = scanP->scanApiRec;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- ndbrequire(apiConnectptr.p->apiScanRec == scanptr.i);
-
- if(scanP->scanState == ScanRecord::CLOSING_SCAN){
- jam();
- close_scan_req_send_conf(signal, scanptr);
- return;
- }
-
- ndbrequire(scanP->scanState == ScanRecord::RUNNING);
-
- /**
- * Close scan wo/ having received an order to do so
- */
- close_scan_req(signal, scanptr, false);
-
- const bool apiFail = (apiConnectptr.p->apiFailState == ZTRUE);
- if(apiFail){
- jam();
- return;
- }
-
- 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 = errorCode;
- ref->closeNeeded = 1;
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_SCAN_TABREF,
- signal, ScanTabRef::SignalLength, JBB);
-}//Dbtc::scanError()
-
-/************************************************************
- * execSCAN_FRAGCONF
- *
- * A NUMBER OF OPERATIONS HAVE BEEN COMPLETED IN THIS
- * FRAGMENT. TAKE CARE OF AND ISSUE FURTHER ACTIONS.
- ************************************************************/
-void Dbtc::execSCAN_FRAGCONF(Signal* signal)
-{
- Uint32 transid1, transid2, total_len;
- jamEntry();
-
- const ScanFragConf * const conf = (ScanFragConf*)&signal->theData[0];
- const Uint32 noCompletedOps = conf->completedOps;
- const Uint32 status = conf->fragmentCompleted;
-
- scanFragptr.i = conf->senderData;
- c_scan_frag_pool.getPtr(scanFragptr);
-
- ScanRecordPtr scanptr;
- scanptr.i = scanFragptr.p->scanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
-
- apiConnectptr.i = scanptr.p->scanApiRec;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
-
- transid1 = apiConnectptr.p->transid[0] ^ conf->transId1;
- transid2 = apiConnectptr.p->transid[1] ^ conf->transId2;
- total_len= conf->total_len;
- transid1 = transid1 | transid2;
- if (transid1 != 0) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
-
- ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::LQH_ACTIVE);
-
- if(scanptr.p->scanState == ScanRecord::CLOSING_SCAN){
- jam();
- if(status == 0){
- /**
- * We have started closing = we sent a close -> ignore this
- */
- return;
- } else {
- jam();
- ScanFragList run(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
-
- run.release(scanFragptr);
- scanFragptr.p->stopFragTimer();
- scanFragptr.p->scanFragState = ScanFragRec::COMPLETED;
- }
- close_scan_req_send_conf(signal, scanptr);
- return;
- }
-
- if(noCompletedOps == 0 && status != 0 &&
- scanptr.p->scanNextFragId+scanptr.p->m_booked_fragments_count < scanptr.p->scanNoFrag){
- /**
- * Start on next fragment
- */
- scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF;
- scanFragptr.p->startFragTimer(ctcTimer);
-
- 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 totalLen = 0;
- for(Uint32 i = 0; i<noCompletedOps; i++){
- Uint32 tmp = conf->opReturnDataLen[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.p->m_scan_frag_conf_status = status;
- scanFragptr.p->m_ops = noCompletedOps;
- scanFragptr.p->m_totalLen = total_len;
- scanFragptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY;
- scanFragptr.p->stopFragTimer();
-
- if(scanptr.p->m_queued_count > /** Min */ 0){
- jam();
- sendScanTabConf(signal, scanptr);
- }
-}//Dbtc::execSCAN_FRAGCONF()
-
-/****************************************************************************
- * execSCAN_NEXTREQ
- *
- * THE APPLICATION HAVE PROCESSED THE TUPLES TRANSFERRED AND IS NOW READY FOR
- * MORE. THIS SIGNAL IS ALSO USED TO CLOSE THE SCAN.
- ****************************************************************************/
-void Dbtc::execSCAN_NEXTREQ(Signal* signal)
-{
- const ScanNextReq * const req = (ScanNextReq *)&signal->theData[0];
- const UintR transid1 = req->transId1;
- const UintR transid2 = req->transId2;
- const UintR stopScan = req->stopScan;
-
- jamEntry();
-
- apiConnectptr.i = req->apiConnectPtr;
- if (apiConnectptr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
-
- /**
- * Check transid
- */
- const UintR ctransid1 = apiConnectptr.p->transid[0] ^ transid1;
- const UintR ctransid2 = apiConnectptr.p->transid[1] ^ transid2;
- if ((ctransid1 | ctransid2) != 0){
- ScanTabRef * ref = (ScanTabRef*)&signal->theData[0];
- ref->apiConnectPtr = apiConnectptr.p->ndbapiConnect;
- ref->transId1 = transid1;
- ref->transId2 = transid2;
- ref->errorCode = ZSTATE_ERROR;
- ref->closeNeeded = 0;
- sendSignal(signal->senderBlockRef(), GSN_SCAN_TABREF,
- signal, ScanTabRef::SignalLength, JBB);
- DEBUG("Wrong transid");
- return;
- }
-
- /**
- * Check state of API connection
- */
- if (apiConnectptr.p->apiConnectstate != CS_START_SCAN) {
- jam();
- if (apiConnectptr.p->apiConnectstate == CS_CONNECTED) {
- jam();
- /*********************************************************************
- * The application sends a SCAN_NEXTREQ after experiencing a time-out.
- * We will send a SCAN_TABREF to indicate a time-out occurred.
- *********************************************************************/
- DEBUG("scanTabRefLab: ZSCANTIME_OUT_ERROR2");
- ndbout_c("apiConnectptr(%d) -> abort", apiConnectptr.i);
- ndbrequire(false); //B2 indication of strange things going on
- scanTabRefLab(signal, ZSCANTIME_OUT_ERROR2);
- return;
- }
- DEBUG("scanTabRefLab: ZSTATE_ERROR");
- DEBUG(" apiConnectstate="<<apiConnectptr.p->apiConnectstate);
- ndbrequire(false); //B2 indication of strange things going on
- scanTabRefLab(signal, ZSTATE_ERROR);
- return;
- }//if
-
- /*******************************************************
- * START THE ACTUAL LOGIC OF SCAN_NEXTREQ.
- ********************************************************/
- // Stop the timer that is used to check for timeout in the API
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- ScanRecordPtr scanptr;
- scanptr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- ScanRecord* scanP = scanptr.p;
-
- const Uint32 len = signal->getLength() - 4;
-
- if (stopScan == ZTRUE) {
- jam();
- /*********************************************************************
- * APPLICATION IS CLOSING THE SCAN.
- **********************************************************************/
- close_scan_req(signal, scanptr, true);
- return;
- }//if
-
- if (scanptr.p->scanState == ScanRecord::CLOSING_SCAN){
- jam();
- /**
- * The scan is closing (typically due to error)
- * but the API hasn't understood it yet
- *
- * Wait for API close request
- */
- return;
- }
-
- // Copy op ptrs so I dont overwrite them when sending...
- memcpy(signal->getDataPtrSend()+25, signal->getDataPtr()+4, 4 * len);
-
- ScanFragNextReq tmp;
- tmp.closeFlag = ZFALSE;
- tmp.transId1 = apiConnectptr.p->transid[0];
- tmp.transId2 = apiConnectptr.p->transid[1];
- tmp.batch_size_rows = scanP->batch_size_rows;
- tmp.batch_size_bytes = scanP->batch_byte_size;
-
- 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();
- scanFragptr.i = signal->theData[i+25];
- c_scan_frag_pool.getPtr(scanFragptr);
- ndbrequire(scanFragptr.p->scanFragState == ScanFragRec::DELIVERED);
-
- scanFragptr.p->startFragTimer(ctcTimer);
- scanFragptr.p->m_ops = 0;
-
- if(scanFragptr.p->m_scan_frag_conf_status)
- {
- /**
- * last scan was complete
- */
- jam();
- ndbrequire(scanptr.p->scanNextFragId < scanptr.p->scanNoFrag);
- jam();
- ndbassert(scanptr.p->m_booked_fragments_count);
- scanptr.p->m_booked_fragments_count--;
- scanFragptr.p->scanFragState = ScanFragRec::WAIT_GET_PRIMCONF;
-
- 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);
- }
- else
- {
- jam();
- scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
- ScanFragNextReq * req = (ScanFragNextReq*)signal->getDataPtrSend();
- * req = tmp;
- req->senderData = scanFragptr.i;
- sendSignal(scanFragptr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- }
- delivered.remove(scanFragptr);
- running.add(scanFragptr);
- }//for
-
-}//Dbtc::execSCAN_NEXTREQ()
-
-void
-Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){
-
- ScanRecord* scanP = scanPtr.p;
- ndbrequire(scanPtr.p->scanState != ScanRecord::IDLE);
- ScanRecord::ScanState old = scanPtr.p->scanState;
- scanPtr.p->scanState = ScanRecord::CLOSING_SCAN;
- scanPtr.p->m_close_scan_req = req_received;
-
- if (old == ScanRecord::WAIT_FRAGMENT_COUNT)
- {
- jam();
- scanPtr.p->scanState = old;
- return; // Will continue on execDI_FCOUNTCONF
- }
-
- /**
- * Queue : Action
- * ============= : =================
- * completed : -
- * running : close -> LQH
- * delivered w/ : close -> LQH
- * delivered wo/ : move to completed
- * queued w/ : close -> LQH
- * queued wo/ : move to completed
- */
-
- 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 delivered(c_scan_frag_pool, scanP->m_delivered_scan_frags);
- ScanFragList queued(c_scan_frag_pool, scanP->m_queued_scan_frags);
-
- // Close running
- for(running.first(ptr); !ptr.isNull(); ){
- ScanFragRecPtr curr = ptr; // Remove while iterating...
- running.next(ptr);
-
- switch(curr.p->scanFragState){
- case ScanFragRec::IDLE:
- jam(); // real early abort
- ndbrequire(old == ScanRecord::WAIT_AI);
- running.release(curr);
- continue;
- case ScanFragRec::WAIT_GET_PRIMCONF:
- jam();
- continue;
- case ScanFragRec::LQH_ACTIVE:
- jam();
- break;
- default:
- jamLine(curr.p->scanFragState);
- ndbrequire(false);
- }
-
- curr.p->startFragTimer(ctcTimer);
- curr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
- nextReq->senderData = curr.i;
- sendSignal(curr.p->lqhBlockref, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- }
-
- // Close delivered
- 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 && curr.p->m_scan_frag_conf_status == 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);
-
- } else {
- jam();
- c_scan_frag_pool.release(curr);
- curr.p->scanFragState = ScanFragRec::COMPLETED;
- curr.p->stopFragTimer();
- }
- }//for
-
- /**
- * All queued with data should be closed
- */
- 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);
- } else {
- jam();
- c_scan_frag_pool.release(curr);
- curr.p->scanFragState = ScanFragRec::COMPLETED;
- curr.p->stopFragTimer();
- }
- }
- }
- close_scan_req_send_conf(signal, scanPtr);
-}
-
-void
-Dbtc::close_scan_req_send_conf(Signal* signal, ScanRecordPtr scanPtr){
-
- jam();
-
- ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty());
- ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty());
- //ndbrequire(scanPtr.p->m_running_scan_frags.isEmpty());
-
-#if 0
- {
- ScanFragList comp(c_scan_frag_pool, scanPtr.p->m_completed_scan_frags);
- ScanFragRecPtr ptr;
- for(comp.first(ptr); !ptr.isNull(); comp.next(ptr)){
- ndbrequire(ptr.p->scanFragTimer == 0);
- ndbrequire(ptr.p->scanFragState == ScanFragRec::COMPLETED);
- }
- }
-#endif
-
- if(!scanPtr.p->m_running_scan_frags.isEmpty()){
- jam();
- return;
- }
-
- const bool apiFail = (apiConnectptr.p->apiFailState == ZTRUE);
-
- if(!scanPtr.p->m_close_scan_req){
- jam();
- /**
- * The API hasn't order closing yet
- */
- return;
- }
-
- Uint32 ref = apiConnectptr.p->ndbapiBlockref;
- if(!apiFail && ref){
- jam();
- 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);
- }
-}
-
-Dbtc::ScanRecordPtr
-Dbtc::seizeScanrec(Signal* signal) {
- ScanRecordPtr scanptr;
- scanptr.i = cfirstfreeScanrec;
- ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
- cfirstfreeScanrec = scanptr.p->nextScan;
- scanptr.p->nextScan = RNIL;
- ndbrequire(scanptr.p->scanState == ScanRecord::IDLE);
- return scanptr;
-}//Dbtc::seizeScanrec()
-
-void Dbtc::sendScanFragReq(Signal* signal,
- ScanRecord* scanP,
- ScanFragRec* scanFragP)
-{
- ScanFragReq * const req = (ScanFragReq *)&signal->theData[0];
- Uint32 requestInfo = scanP->scanRequestInfo;
- ScanFragReq::setScanPrio(requestInfo, 1);
- apiConnectptr.i = scanP->scanApiRec;
- req->tableId = scanP->scanTableref;
- req->schemaVersion = scanP->scanSchemaVersion;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- req->senderData = scanFragptr.i;
- req->requestInfo = requestInfo;
- req->fragmentNoKeyLen = scanFragP->scanFragId | (scanP->scanKeyLen << 16);
- req->resultRef = apiConnectptr.p->ndbapiBlockref;
- req->savePointId = apiConnectptr.p->currSavePointId;
- req->transId1 = apiConnectptr.p->transid[0];
- req->transId2 = apiConnectptr.p->transid[1];
- req->clientOpPtr = scanFragP->m_apiPtr;
- req->batch_size_rows= scanP->batch_size_rows;
- req->batch_size_bytes= scanP->batch_byte_size;
- sendSignal(scanFragP->lqhBlockref, GSN_SCAN_FRAGREQ, signal,
- ScanFragReq::SignalLength, JBB);
- if(scanP->scanKeyLen > 0)
- {
- tcConnectptr.i = scanFragptr.i;
- packKeyData000Lab(signal, scanFragP->lqhBlockref, scanP->scanKeyLen);
- }
- updateBuddyTimer(apiConnectptr);
- scanFragP->startFragTimer(ctcTimer);
-}//Dbtc::sendScanFragReq()
-
-
-void Dbtc::sendScanTabConf(Signal* signal, ScanRecordPtr scanPtr) {
- jam();
- Uint32* ops = signal->getDataPtrSend()+4;
- Uint32 op_count = scanPtr.p->m_queued_count;
- if(4 + 3 * op_count > 25){
- jam();
- ops += 21;
- }
-
- int left = scanPtr.p->scanNoFrag - scanPtr.p->scanNextFragId;
- Uint32 booked = scanPtr.p->m_booked_fragments_count;
-
- ScanTabConf * conf = (ScanTabConf*)&signal->theData[0];
- conf->apiConnectPtr = apiConnectptr.p->ndbapiConnect;
- conf->requestInfo = op_count;
- conf->transId1 = apiConnectptr.p->transid[0];
- conf->transId2 = apiConnectptr.p->transid[1];
- ScanFragRecPtr ptr;
- {
- ScanFragList queued(c_scan_frag_pool, scanPtr.p->m_queued_scan_frags);
- ScanFragList delivered(c_scan_frag_pool,scanPtr.p->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);
-
- bool done = curr.p->m_scan_frag_conf_status && (left <= (int)booked);
- if(curr.p->m_scan_frag_conf_status)
- booked++;
-
- * ops++ = curr.p->m_apiPtr;
- * ops++ = done ? RNIL : curr.i;
- * ops++ = (curr.p->m_totalLen << 10) + curr.p->m_ops;
-
- queued.remove(curr);
- if(!done){
- delivered.add(curr);
- curr.p->scanFragState = ScanFragRec::DELIVERED;
- curr.p->stopFragTimer();
- } else {
- c_scan_frag_pool.release(curr);
- curr.p->scanFragState = ScanFragRec::COMPLETED;
- curr.p->stopFragTimer();
- }
- }
- }
-
- scanPtr.p->m_booked_fragments_count = booked;
- if(scanPtr.p->m_delivered_scan_frags.isEmpty() &&
- scanPtr.p->m_running_scan_frags.isEmpty())
- {
- conf->requestInfo = op_count | ScanTabConf::EndOfData;
- releaseScanResources(scanPtr);
- }
- else
- {
- if (scanPtr.p->m_running_scan_frags.isEmpty())
- {
- jam();
- /**
- * All scan frags delivered...waiting for API
- */
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- }
- }
-
- 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()
-
-
-void Dbtc::gcpTcfinished(Signal* signal)
-{
- signal->theData[0] = c_gcp_ref;
- signal->theData[1] = tcheckGcpId;
- sendSignal(cdihblockref, GSN_GCP_TCFINISHED, signal, 2, JBB);
-}//Dbtc::gcpTcfinished()
-
-void Dbtc::initApiConnect(Signal* signal)
-{
- Uint32 tiacTmp;
- Uint32 guard4;
-
- tiacTmp = capiConnectFilesize / 3;
- ndbrequire(tiacTmp > 0);
- guard4 = tiacTmp + 1;
- for (cachePtr.i = 0; cachePtr.i < guard4; cachePtr.i++) {
- refresh_watch_dog();
- ptrAss(cachePtr, cacheRecord);
- cachePtr.p->firstAttrbuf = RNIL;
- cachePtr.p->lastAttrbuf = RNIL;
- cachePtr.p->firstKeybuf = RNIL;
- cachePtr.p->lastKeybuf = RNIL;
- cachePtr.p->nextCacheRec = cachePtr.i + 1;
- }//for
- cachePtr.i = tiacTmp;
- ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord);
- cachePtr.p->nextCacheRec = RNIL;
- cfirstfreeCacheRec = 0;
-
- guard4 = tiacTmp - 1;
- for (apiConnectptr.i = 0; apiConnectptr.i <= guard4; apiConnectptr.i++) {
- refresh_watch_dog();
- jam();
- ptrAss(apiConnectptr, apiConnectRecord);
- apiConnectptr.p->apiConnectstate = CS_DISCONNECTED;
- apiConnectptr.p->apiFailState = ZFALSE;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- apiConnectptr.p->takeOverRec = (Uint8)Z8NIL;
- apiConnectptr.p->cachePtr = RNIL;
- apiConnectptr.p->nextApiConnect = apiConnectptr.i + 1;
- apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref
- apiConnectptr.p->commitAckMarker = RNIL;
- apiConnectptr.p->firstTcConnect = RNIL;
- apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
- apiConnectptr.p->accumulatingIndexOp = RNIL;
- apiConnectptr.p->executingIndexOp = RNIL;
- apiConnectptr.p->buddyPtr = RNIL;
- apiConnectptr.p->currSavePointId = 0;
- apiConnectptr.p->m_transaction_nodes.clear();
- apiConnectptr.p->singleUserMode = 0;
- }//for
- apiConnectptr.i = tiacTmp - 1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->nextApiConnect = RNIL;
- cfirstfreeApiConnect = 0;
- guard4 = (2 * tiacTmp) - 1;
- for (apiConnectptr.i = tiacTmp; apiConnectptr.i <= guard4; apiConnectptr.i++)
- {
- refresh_watch_dog();
- jam();
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->apiConnectstate = CS_RESTART;
- apiConnectptr.p->apiFailState = ZFALSE;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- apiConnectptr.p->takeOverRec = (Uint8)Z8NIL;
- apiConnectptr.p->cachePtr = RNIL;
- apiConnectptr.p->nextApiConnect = apiConnectptr.i + 1;
- apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref
- apiConnectptr.p->commitAckMarker = RNIL;
- apiConnectptr.p->firstTcConnect = RNIL;
- apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
- apiConnectptr.p->accumulatingIndexOp = RNIL;
- apiConnectptr.p->executingIndexOp = RNIL;
- apiConnectptr.p->buddyPtr = RNIL;
- apiConnectptr.p->currSavePointId = 0;
- apiConnectptr.p->m_transaction_nodes.clear();
- apiConnectptr.p->singleUserMode = 0;
- }//for
- apiConnectptr.i = (2 * tiacTmp) - 1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->nextApiConnect = RNIL;
- cfirstfreeApiConnectCopy = tiacTmp;
- guard4 = (3 * tiacTmp) - 1;
- for (apiConnectptr.i = 2 * tiacTmp; apiConnectptr.i <= guard4;
- apiConnectptr.i++) {
- refresh_watch_dog();
- jam();
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- apiConnectptr.p->apiFailState = ZFALSE;
- apiConnectptr.p->apiConnectstate = CS_RESTART;
- apiConnectptr.p->takeOverRec = (Uint8)Z8NIL;
- apiConnectptr.p->cachePtr = RNIL;
- apiConnectptr.p->nextApiConnect = apiConnectptr.i + 1;
- apiConnectptr.p->ndbapiBlockref = 0xFFFFFFFF; // Invalid ref
- apiConnectptr.p->commitAckMarker = RNIL;
- apiConnectptr.p->firstTcConnect = RNIL;
- apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
- apiConnectptr.p->accumulatingIndexOp = RNIL;
- apiConnectptr.p->executingIndexOp = RNIL;
- apiConnectptr.p->buddyPtr = RNIL;
- apiConnectptr.p->currSavePointId = 0;
- apiConnectptr.p->m_transaction_nodes.clear();
- apiConnectptr.p->singleUserMode = 0;
- }//for
- apiConnectptr.i = (3 * tiacTmp) - 1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->nextApiConnect = RNIL;
- cfirstfreeApiConnectFail = 2 * tiacTmp;
-}//Dbtc::initApiConnect()
-
-void Dbtc::initattrbuf(Signal* signal)
-{
- ndbrequire(cattrbufFilesize > 0);
- for (attrbufptr.i = 0; attrbufptr.i < cattrbufFilesize; attrbufptr.i++) {
- refresh_watch_dog();
- jam();
- ptrAss(attrbufptr, attrbufRecord);
- attrbufptr.p->attrbuf[ZINBUF_NEXT] = attrbufptr.i + 1; /* NEXT ATTRBUF */
- }//for
- attrbufptr.i = cattrbufFilesize - 1;
- ptrAss(attrbufptr, attrbufRecord);
- attrbufptr.p->attrbuf[ZINBUF_NEXT] = RNIL; /* NEXT ATTRBUF */
- cfirstfreeAttrbuf = 0;
-}//Dbtc::initattrbuf()
-
-void Dbtc::initdatabuf(Signal* signal)
-{
- ndbrequire(cdatabufFilesize > 0);
- for (databufptr.i = 0; databufptr.i < cdatabufFilesize; databufptr.i++) {
- refresh_watch_dog();
- ptrAss(databufptr, databufRecord);
- databufptr.p->nextDatabuf = databufptr.i + 1;
- }//for
- databufptr.i = cdatabufFilesize - 1;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
- databufptr.p->nextDatabuf = RNIL;
- cfirstfreeDatabuf = 0;
-}//Dbtc::initdatabuf()
-
-void Dbtc::initgcp(Signal* signal)
-{
- ndbrequire(cgcpFilesize > 0);
- for (gcpPtr.i = 0; gcpPtr.i < cgcpFilesize; gcpPtr.i++) {
- ptrAss(gcpPtr, gcpRecord);
- gcpPtr.p->nextGcp = gcpPtr.i + 1;
- }//for
- gcpPtr.i = cgcpFilesize - 1;
- ptrCheckGuard(gcpPtr, cgcpFilesize, gcpRecord);
- gcpPtr.p->nextGcp = RNIL;
- cfirstfreeGcp = 0;
- cfirstgcp = RNIL;
- clastgcp = RNIL;
-}//Dbtc::initgcp()
-
-void Dbtc::inithost(Signal* signal)
-{
- cpackedListIndex = 0;
- ndbrequire(chostFilesize > 0);
- for (hostptr.i = 0; hostptr.i < chostFilesize; hostptr.i++) {
- jam();
- ptrAss(hostptr, hostRecord);
- hostptr.p->hostStatus = HS_DEAD;
- hostptr.p->inPackedList = false;
- hostptr.p->lqhTransStatus = LTS_IDLE;
- hostptr.p->noOfWordsTCKEYCONF = 0;
- hostptr.p->noOfWordsTCINDXCONF = 0;
- hostptr.p->noOfPackedWordsLqh = 0;
- hostptr.p->hostLqhBlockRef = calcLqhBlockRef(hostptr.i);
- hostptr.p->m_nf_bits = 0;
- }//for
- c_alive_nodes.clear();
-}//Dbtc::inithost()
-
-void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0,
- Uint32 retRef, Uint32 retData)
-{
- switch (Tdata0) {
- case 0:
- jam();
- initApiConnect(signal);
- break;
- case 1:
- jam();
- initattrbuf(signal);
- break;
- case 2:
- jam();
- initdatabuf(signal);
- break;
- case 3:
- jam();
- initgcp(signal);
- break;
- case 4:
- jam();
- inithost(signal);
- break;
- case 5:
- jam();
- // UNUSED Free to initialise something
- break;
- case 6:
- jam();
- initTable(signal);
- break;
- case 7:
- jam();
- initialiseScanrec(signal);
- break;
- case 8:
- jam();
- initialiseScanOprec(signal);
- break;
- case 9:
- jam();
- initialiseScanFragrec(signal);
- break;
- case 10:
- jam();
- initialiseTcConnect(signal);
- break;
- case 11:
- jam();
- initTcFail(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:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
-
- 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)
-{
- ScanRecordPtr scanptr;
- ndbrequire(cscanrecFileSize > 0);
- for (scanptr.i = 0; scanptr.i < cscanrecFileSize; scanptr.i++) {
- refresh_watch_dog();
- jam();
- ptrAss(scanptr, scanRecord);
- new (scanptr.p) ScanRecord();
- scanptr.p->scanState = ScanRecord::IDLE;
- scanptr.p->scanApiRec = RNIL;
- scanptr.p->nextScan = scanptr.i + 1;
- }//for
- scanptr.i = cscanrecFileSize - 1;
- ptrAss(scanptr, scanRecord);
- scanptr.p->nextScan = RNIL;
- cfirstfreeScanrec = 0;
-}//Dbtc::initialiseScanrec()
-
-void Dbtc::initialiseScanFragrec(Signal* signal)
-{
-}//Dbtc::initialiseScanFragrec()
-
-void Dbtc::initialiseScanOprec(Signal* signal)
-{
-}//Dbtc::initialiseScanOprec()
-
-void Dbtc::initTable(Signal* signal)
-{
-
- ndbrequire(ctabrecFilesize > 0);
- for (tabptr.i = 0; tabptr.i < ctabrecFilesize; tabptr.i++) {
- refresh_watch_dog();
- ptrAss(tabptr, tableRecord);
- tabptr.p->currentSchemaVersion = 0;
- tabptr.p->m_flags = 0;
- tabptr.p->set_storedTable(true);
- tabptr.p->tableType = 0;
- tabptr.p->set_enabled(false);
- tabptr.p->set_dropping(false);
- tabptr.p->noOfKeyAttr = 0;
- tabptr.p->hasCharAttr = 0;
- tabptr.p->noOfDistrKeys = 0;
- tabptr.p->hasVarKeys = 0;
- }//for
-}//Dbtc::initTable()
-
-void Dbtc::initialiseTcConnect(Signal* signal)
-{
- ndbrequire(ctcConnectFilesize >= 2);
-
- // Place half of tcConnectptr's in cfirstfreeTcConnectFail list
- Uint32 titcTmp = ctcConnectFilesize / 2;
- for (tcConnectptr.i = 0; tcConnectptr.i < titcTmp; tcConnectptr.i++) {
- refresh_watch_dog();
- jam();
- ptrAss(tcConnectptr, tcConnectRecord);
- tcConnectptr.p->tcConnectstate = OS_RESTART;
- tcConnectptr.p->apiConnect = RNIL;
- tcConnectptr.p->noOfNodes = 0;
- tcConnectptr.p->nextTcConnect = tcConnectptr.i + 1;
- }//for
- tcConnectptr.i = titcTmp - 1;
- ptrAss(tcConnectptr, tcConnectRecord);
- tcConnectptr.p->nextTcConnect = RNIL;
- cfirstfreeTcConnectFail = 0;
-
- // Place other half in cfirstfreeTcConnect list
- for (tcConnectptr.i = titcTmp; tcConnectptr.i < ctcConnectFilesize;
- tcConnectptr.i++) {
- refresh_watch_dog();
- jam();
- ptrAss(tcConnectptr, tcConnectRecord);
- tcConnectptr.p->tcConnectstate = OS_RESTART;
- tcConnectptr.p->apiConnect = RNIL;
- tcConnectptr.p->noOfNodes = 0;
- tcConnectptr.p->nextTcConnect = tcConnectptr.i + 1;
- }//for
- tcConnectptr.i = ctcConnectFilesize - 1;
- ptrAss(tcConnectptr, tcConnectRecord);
- tcConnectptr.p->nextTcConnect = RNIL;
- cfirstfreeTcConnect = titcTmp;
- c_counters.cconcurrentOp = 0;
-}//Dbtc::initialiseTcConnect()
-
-/* ------------------------------------------------------------------------- */
-/* ---- LINK A GLOBAL CHECKPOINT RECORD INTO THE LIST WITH TRANSACTIONS */
-/* WAITING FOR COMPLETION. */
-/* ------------------------------------------------------------------------- */
-void Dbtc::linkGciInGcilist(Signal* signal)
-{
- GcpRecordPtr tmpGcpPointer;
- if (cfirstgcp == RNIL) {
- jam();
- cfirstgcp = gcpPtr.i;
- } else {
- jam();
- tmpGcpPointer.i = clastgcp;
- ptrCheckGuard(tmpGcpPointer, cgcpFilesize, gcpRecord);
- tmpGcpPointer.p->nextGcp = gcpPtr.i;
- }//if
- clastgcp = gcpPtr.i;
-}//Dbtc::linkGciInGcilist()
-
-/* ------------------------------------------------------------------------- */
-/* ------- LINK SECONDARY KEY BUFFER IN OPERATION RECORD ------- */
-/* ------------------------------------------------------------------------- */
-void Dbtc::linkKeybuf(Signal* signal)
-{
- seizeDatabuf(signal);
- tmpDatabufptr.i = cachePtr.p->lastKeybuf;
- cachePtr.p->lastKeybuf = databufptr.i;
- if (tmpDatabufptr.i == RNIL) {
- jam();
- cachePtr.p->firstKeybuf = databufptr.i;
- } else {
- jam();
- ptrCheckGuard(tmpDatabufptr, cdatabufFilesize, databufRecord);
- tmpDatabufptr.p->nextDatabuf = databufptr.i;
- }//if
-}//Dbtc::linkKeybuf()
-
-/* ------------------------------------------------------------------------- */
-/* ------- LINK A TC CONNECT RECORD INTO THE API LIST OF TC CONNECTIONS --- */
-/* ------------------------------------------------------------------------- */
-void Dbtc::linkTcInConnectionlist(Signal* signal)
-{
- /* POINTER FOR THE CONNECT_RECORD */
- TcConnectRecordPtr ltcTcConnectptr;
-
- tcConnectptr.p->nextTcConnect = RNIL;
- ltcTcConnectptr.i = apiConnectptr.p->lastTcConnect;
- ptrCheck(ltcTcConnectptr, ctcConnectFilesize, tcConnectRecord);
- apiConnectptr.p->lastTcConnect = tcConnectptr.i;
- if (ltcTcConnectptr.i == RNIL) {
- jam();
- apiConnectptr.p->firstTcConnect = tcConnectptr.i;
- } else {
- jam();
- ptrGuard(ltcTcConnectptr);
- ltcTcConnectptr.p->nextTcConnect = tcConnectptr.i;
- }//if
-}//Dbtc::linkTcInConnectionlist()
-
-/*---------------------------------------------------------------------------*/
-/* RELEASE_ABORT_RESOURCES */
-/* THIS CODE RELEASES ALL RESOURCES AFTER AN ABORT OF A TRANSACTION AND ALSO */
-/* SENDS THE ABORT DECISION TO THE APPLICATION. */
-/*---------------------------------------------------------------------------*/
-void Dbtc::releaseAbortResources(Signal* signal)
-{
- TcConnectRecordPtr rarTcConnectptr;
-
- c_counters.cabortCount++;
- if (apiConnectptr.p->cachePtr != RNIL) {
- cachePtr.i = apiConnectptr.p->cachePtr;
- ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord);
- releaseAttrinfo();
- releaseKeys();
- }//if
- tcConnectptr.i = apiConnectptr.p->firstTcConnect;
- while (tcConnectptr.i != RNIL) {
- jam();
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- // Clear any markers that were set in CS_RECEIVING state
- clearCommitAckMarker(apiConnectptr.p, tcConnectptr.p);
- rarTcConnectptr.i = tcConnectptr.p->nextTcConnect;
- releaseTcCon();
- tcConnectptr.i = rarTcConnectptr.i;
- }//while
- apiConnectptr.p->firstTcConnect = RNIL;
- apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->m_transaction_nodes.clear();
- apiConnectptr.p->singleUserMode = 0;
-
- // MASV let state be CS_ABORTING until all
- // signals in the "air" have been received. Reset to CS_CONNECTED
- // will be done when a TCKEYREQ with start flag is recieved
- // or releaseApiCon is called
- // apiConnectptr.p->apiConnectstate = CS_CONNECTED;
- apiConnectptr.p->apiConnectstate = CS_ABORTING;
- apiConnectptr.p->abortState = AS_IDLE;
- releaseAllSeizedIndexOperations(apiConnectptr.p);
- if(apiConnectptr.p->m_exec_flag || apiConnectptr.p->apiFailState == ZTRUE){
- jam();
- bool ok = false;
- Uint32 blockRef = apiConnectptr.p->ndbapiBlockref;
- ReturnSignal ret = apiConnectptr.p->returnsignal;
- apiConnectptr.p->returnsignal = RS_NO_RETURN;
- apiConnectptr.p->m_exec_flag = 0;
- switch(ret){
- case RS_TCROLLBACKCONF:
- jam();
- ok = true;
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- sendSignal(blockRef, GSN_TCROLLBACKCONF, signal, 3, JBB);
- break;
- case RS_TCROLLBACKREP:{
- jam();
- ok = true;
- TcRollbackRep * const tcRollbackRep =
- (TcRollbackRep *) signal->getDataPtr();
-
- tcRollbackRep->connectPtr = apiConnectptr.p->ndbapiConnect;
- tcRollbackRep->transId[0] = apiConnectptr.p->transid[0];
- tcRollbackRep->transId[1] = apiConnectptr.p->transid[1];
- tcRollbackRep->returnCode = apiConnectptr.p->returncode;
- tcRollbackRep->errorData = apiConnectptr.p->errorData;
- sendSignal(blockRef, GSN_TCROLLBACKREP, signal,
- TcRollbackRep::SignalLength, JBB);
- }
- break;
- case RS_NO_RETURN:
- jam();
- ok = true;
- break;
- case RS_TCKEYCONF:
- case RS_TC_COMMITCONF:
- break;
- }
- if(!ok){
- jam();
- ndbout_c("returnsignal = %d", apiConnectptr.p->returnsignal);
- sendSystemError(signal, __LINE__);
- }//if
-
- }
- setApiConTimer(apiConnectptr.i, 0,
- 100000+c_apiConTimer_line[apiConnectptr.i]);
- if (apiConnectptr.p->apiFailState == ZTRUE) {
- jam();
- handleApiFailState(signal, apiConnectptr.i);
- return;
- }//if
-}//Dbtc::releaseAbortResources()
-
-void Dbtc::releaseApiCon(Signal* signal, UintR TapiConnectPtr)
-{
- ApiConnectRecordPtr TlocalApiConnectptr;
-
- TlocalApiConnectptr.i = TapiConnectPtr;
- ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
- TlocalApiConnectptr.p->nextApiConnect = cfirstfreeApiConnect;
- cfirstfreeApiConnect = TlocalApiConnectptr.i;
- setApiConTimer(TlocalApiConnectptr.i, 0, __LINE__);
- TlocalApiConnectptr.p->apiConnectstate = CS_DISCONNECTED;
- ndbassert(TlocalApiConnectptr.p->m_transaction_nodes.isclear());
- ndbassert(TlocalApiConnectptr.p->apiScanRec == RNIL);
- TlocalApiConnectptr.p->ndbapiBlockref = 0;
-}//Dbtc::releaseApiCon()
-
-void Dbtc::releaseApiConnectFail(Signal* signal)
-{
- apiConnectptr.p->apiConnectstate = CS_RESTART;
- apiConnectptr.p->takeOverRec = (Uint8)Z8NIL;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- apiConnectptr.p->nextApiConnect = cfirstfreeApiConnectFail;
- cfirstfreeApiConnectFail = apiConnectptr.i;
-}//Dbtc::releaseApiConnectFail()
-
-void Dbtc::releaseGcp(Signal* signal)
-{
- ptrGuard(gcpPtr);
- gcpPtr.p->nextGcp = cfirstfreeGcp;
- cfirstfreeGcp = gcpPtr.i;
-}//Dbtc::releaseGcp()
-
-void Dbtc::releaseKeys()
-{
- UintR Tmp;
- databufptr.i = cachePtr.p->firstKeybuf;
- while (databufptr.i != RNIL) {
- jam();
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
- Tmp = databufptr.p->nextDatabuf;
- databufptr.p->nextDatabuf = cfirstfreeDatabuf;
- cfirstfreeDatabuf = databufptr.i;
- databufptr.i = Tmp;
- }//while
- cachePtr.p->firstKeybuf = RNIL;
- cachePtr.p->lastKeybuf = RNIL;
-}//Dbtc::releaseKeys()
-
-void Dbtc::releaseTcConnectFail(Signal* signal)
-{
- ptrGuard(tcConnectptr);
- tcConnectptr.p->nextTcConnect = cfirstfreeTcConnectFail;
- cfirstfreeTcConnectFail = tcConnectptr.i;
-}//Dbtc::releaseTcConnectFail()
-
-void Dbtc::seizeApiConnect(Signal* signal)
-{
- if (cfirstfreeApiConnect != RNIL) {
- jam();
- terrorCode = ZOK;
- apiConnectptr.i = cfirstfreeApiConnect; /* ASSIGN A FREE RECORD FROM */
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- cfirstfreeApiConnect = apiConnectptr.p->nextApiConnect;
- apiConnectptr.p->nextApiConnect = RNIL;
- setApiConTimer(apiConnectptr.i, 0, __LINE__);
- apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
- } else {
- jam();
- terrorCode = ZNO_FREE_API_CONNECTION;
- }//if
-}//Dbtc::seizeApiConnect()
-
-void Dbtc::seizeApiConnectFail(Signal* signal)
-{
- apiConnectptr.i = cfirstfreeApiConnectFail;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- cfirstfreeApiConnectFail = apiConnectptr.p->nextApiConnect;
-}//Dbtc::seizeApiConnectFail()
-
-void Dbtc::seizeDatabuf(Signal* signal)
-{
- databufptr.i = cfirstfreeDatabuf;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
- cfirstfreeDatabuf = databufptr.p->nextDatabuf;
- databufptr.p->nextDatabuf = RNIL;
-}//Dbtc::seizeDatabuf()
-
-void Dbtc::seizeTcConnect(Signal* signal)
-{
- tcConnectptr.i = cfirstfreeTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- cfirstfreeTcConnect = tcConnectptr.p->nextTcConnect;
- c_counters.cconcurrentOp++;
- tcConnectptr.p->isIndexOp = false;
-}//Dbtc::seizeTcConnect()
-
-void Dbtc::seizeTcConnectFail(Signal* signal)
-{
- tcConnectptr.i = cfirstfreeTcConnectFail;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- cfirstfreeTcConnectFail = tcConnectptr.p->nextTcConnect;
-}//Dbtc::seizeTcConnectFail()
-
-void Dbtc::sendAttrinfo(Signal* signal,
- UintR TattrinfoPtr,
- AttrbufRecord * const regAttrPtr,
- UintR TBref)
-{
- UintR TdataPos;
- UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6, sig7;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- TdataPos = regAttrPtr->attrbuf[ZINBUF_DATA_LEN];
- sig0 = TattrinfoPtr;
- sig1 = regApiPtr->transid[0];
- sig2 = regApiPtr->transid[1];
-
- signal->theData[0] = sig0;
- signal->theData[1] = sig1;
- signal->theData[2] = sig2;
-
- sig0 = regAttrPtr->attrbuf[0];
- sig1 = regAttrPtr->attrbuf[1];
- sig2 = regAttrPtr->attrbuf[2];
- sig3 = regAttrPtr->attrbuf[3];
- sig4 = regAttrPtr->attrbuf[4];
- sig5 = regAttrPtr->attrbuf[5];
- sig6 = regAttrPtr->attrbuf[6];
- sig7 = regAttrPtr->attrbuf[7];
-
- signal->theData[3] = sig0;
- signal->theData[4] = sig1;
- signal->theData[5] = sig2;
- signal->theData[6] = sig3;
- signal->theData[7] = sig4;
- signal->theData[8] = sig5;
- signal->theData[9] = sig6;
- signal->theData[10] = sig7;
-
- if (TdataPos > 8) {
- sig0 = regAttrPtr->attrbuf[8];
- sig1 = regAttrPtr->attrbuf[9];
- sig2 = regAttrPtr->attrbuf[10];
- sig3 = regAttrPtr->attrbuf[11];
- sig4 = regAttrPtr->attrbuf[12];
- sig5 = regAttrPtr->attrbuf[13];
- sig6 = regAttrPtr->attrbuf[14];
-
- jam();
- signal->theData[11] = sig0;
- signal->theData[12] = sig1;
- signal->theData[13] = sig2;
- signal->theData[14] = sig3;
- signal->theData[15] = sig4;
- signal->theData[16] = sig5;
- signal->theData[17] = sig6;
-
- if (TdataPos > 15) {
-
- sig0 = regAttrPtr->attrbuf[15];
- sig1 = regAttrPtr->attrbuf[16];
- sig2 = regAttrPtr->attrbuf[17];
- sig3 = regAttrPtr->attrbuf[18];
- sig4 = regAttrPtr->attrbuf[19];
- sig5 = regAttrPtr->attrbuf[20];
- sig6 = regAttrPtr->attrbuf[21];
-
- jam();
- signal->theData[18] = sig0;
- signal->theData[19] = sig1;
- signal->theData[20] = sig2;
- signal->theData[21] = sig3;
- signal->theData[22] = sig4;
- signal->theData[23] = sig5;
- signal->theData[24] = sig6;
- }//if
- }//if
- sendSignal(TBref, GSN_ATTRINFO, signal, TdataPos + 3, JBB);
-}//Dbtc::sendAttrinfo()
-
-void Dbtc::sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr)
-{
- signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_CONTROL;
- signal->theData[1] = TapiConPtr;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
-}//Dbtc::sendContinueTimeOutControl()
-
-void Dbtc::sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len)
-{
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- signal->theData[3] = cdata[0];
- signal->theData[4] = cdata[1];
- signal->theData[5] = cdata[2];
- signal->theData[6] = cdata[3];
- signal->theData[7] = cdata[4];
- signal->theData[8] = cdata[5];
- signal->theData[9] = cdata[6];
- signal->theData[10] = cdata[7];
- signal->theData[11] = cdata[8];
- signal->theData[12] = cdata[9];
- signal->theData[13] = cdata[10];
- signal->theData[14] = cdata[11];
- signal->theData[15] = cdata[12];
- signal->theData[16] = cdata[13];
- signal->theData[17] = cdata[14];
- signal->theData[18] = cdata[15];
- signal->theData[19] = cdata[16];
- signal->theData[20] = cdata[17];
- signal->theData[21] = cdata[18];
- signal->theData[22] = cdata[19];
- sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB);
-}//Dbtc::sendKeyinfo()
-
-void Dbtc::sendSystemError(Signal* signal, int line)
-{
- progError(line, NDBD_EXIT_NDBREQUIRE);
-}//Dbtc::sendSystemError()
-
-/* ========================================================================= */
-/* ------- LINK ACTUAL GCP OUT OF LIST ------- */
-/* ------------------------------------------------------------------------- */
-void Dbtc::unlinkGcp(Signal* signal)
-{
- if (cfirstgcp == gcpPtr.i) {
- jam();
- cfirstgcp = gcpPtr.p->nextGcp;
- if (gcpPtr.i == clastgcp) {
- jam();
- clastgcp = RNIL;
- }//if
- } else {
- jam();
- /* --------------------------------------------------------------------
- * WE ARE TRYING TO REMOVE A GLOBAL CHECKPOINT WHICH WAS NOT THE OLDEST.
- * THIS IS A SYSTEM ERROR.
- * ------------------------------------------------------------------- */
- sendSystemError(signal, __LINE__);
- }//if
- gcpPtr.p->nextGcp = cfirstfreeGcp;
- cfirstfreeGcp = gcpPtr.i;
-}//Dbtc::unlinkGcp()
-
-void
-Dbtc::execDUMP_STATE_ORD(Signal* signal)
-{
- DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
- if(signal->theData[0] == DumpStateOrd::CommitAckMarkersSize){
- infoEvent("TC: m_commitAckMarkerPool: %d free size: %d",
- m_commitAckMarkerPool.getNoOfFree(),
- m_commitAckMarkerPool.getSize());
- }
- if(signal->theData[0] == DumpStateOrd::CommitAckMarkersDump){
- infoEvent("TC: m_commitAckMarkerPool: %d free size: %d",
- m_commitAckMarkerPool.getNoOfFree(),
- m_commitAckMarkerPool.getSize());
-
- CommitAckMarkerIterator iter;
- for(m_commitAckMarkerHash.first(iter); iter.curr.i != RNIL;
- m_commitAckMarkerHash.next(iter)){
- infoEvent("CommitAckMarker: i = %d (0x%x, 0x%x)"
- " Api: %d Lghs(%d): %d %d %d %d bucket = %d",
- iter.curr.i,
- iter.curr.p->transid1,
- iter.curr.p->transid2,
- iter.curr.p->apiNodeId,
- iter.curr.p->noOfLqhs,
- iter.curr.p->lqhNodeId[0],
- iter.curr.p->lqhNodeId[1],
- iter.curr.p->lqhNodeId[2],
- iter.curr.p->lqhNodeId[3],
- iter.bucket);
- }
- }
- // Dump all ScanFragRecs
- if (dumpState->args[0] == DumpStateOrd::TcDumpAllScanFragRec){
- Uint32 recordNo = 0;
- if (signal->getLength() == 1)
- infoEvent("TC: Dump all ScanFragRec - size: %d",
- cscanFragrecFileSize);
- else if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- dumpState->args[0] = DumpStateOrd::TcDumpOneScanFragRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
-
- if (recordNo < cscanFragrecFileSize-1){
- dumpState->args[0] = DumpStateOrd::TcDumpAllScanFragRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- }
-
- // Dump one ScanFragRec
- if (dumpState->args[0] == DumpStateOrd::TcDumpOneScanFragRec){
- Uint32 recordNo = RNIL;
- if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= cscanFragrecFileSize)
- return;
-
- ScanFragRecPtr sfp;
- sfp.i = recordNo;
- c_scan_frag_pool.getPtr(sfp);
- infoEvent("Dbtc::ScanFragRec[%d]: state=%d fragid=%d",
- sfp.i,
- sfp.p->scanFragState,
- sfp.p->scanFragId);
- infoEvent(" nodeid=%d, timer=%d",
- refToNode(sfp.p->lqhBlockref),
- sfp.p->scanFragTimer);
- }
-
- // Dump all ScanRecords
- if (dumpState->args[0] == DumpStateOrd::TcDumpAllScanRec){
- Uint32 recordNo = 0;
- if (signal->getLength() == 1)
- infoEvent("TC: Dump all ScanRecord - size: %d",
- cscanrecFileSize);
- else if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- dumpState->args[0] = DumpStateOrd::TcDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
-
- if (recordNo < cscanrecFileSize-1){
- dumpState->args[0] = DumpStateOrd::TcDumpAllScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- }
-
- // Dump all active ScanRecords
- if (dumpState->args[0] == DumpStateOrd::TcDumpAllActiveScanRec){
- Uint32 recordNo = 0;
- if (signal->getLength() == 1)
- infoEvent("TC: Dump active ScanRecord - size: %d",
- cscanrecFileSize);
- else if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- ScanRecordPtr sp;
- sp.i = recordNo;
- ptrAss(sp, scanRecord);
- if (sp.p->scanState != ScanRecord::IDLE){
- dumpState->args[0] = DumpStateOrd::TcDumpOneScanRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
- }
-
- if (recordNo < cscanrecFileSize-1){
- dumpState->args[0] = DumpStateOrd::TcDumpAllActiveScanRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- }
-
- // Dump one ScanRecord
- // and associated ScanFragRec and ApiConnectRecord
- if (dumpState->args[0] == DumpStateOrd::TcDumpOneScanRec){
- Uint32 recordNo = RNIL;
- if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= cscanrecFileSize)
- return;
-
- ScanRecordPtr sp;
- sp.i = recordNo;
- ptrAss(sp, scanRecord);
- infoEvent("Dbtc::ScanRecord[%d]: state=%d"
- "nextfrag=%d, nofrag=%d",
- sp.i,
- sp.p->scanState,
- sp.p->scanNextFragId,
- sp.p->scanNoFrag);
- infoEvent(" ailen=%d, para=%d, receivedop=%d, noOprePperFrag=%d",
- sp.p->scanAiLength,
- sp.p->scanParallel,
- sp.p->scanReceivedOperations,
- sp.p->batch_size_rows);
- infoEvent(" schv=%d, tab=%d, sproc=%d",
- sp.p->scanSchemaVersion,
- sp.p->scanTableref,
- sp.p->scanStoredProcId);
- infoEvent(" apiRec=%d, next=%d",
- sp.p->scanApiRec, sp.p->nextScan);
-
- if (sp.p->scanState != ScanRecord::IDLE){
- // Request dump of ScanFragRec
- 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);
-
- // Request dump of ApiConnectRecord
- dumpState->args[0] = DumpStateOrd::TcDumpOneApiConnectRec;
- dumpState->args[1] = sp.p->scanApiRec;
- execDUMP_STATE_ORD(signal);
- }
-
- }
-
- // Dump all ApiConnectRecord(s)
- if (dumpState->args[0] == DumpStateOrd::TcDumpAllApiConnectRec){
- Uint32 recordNo = 0;
- if (signal->getLength() == 1)
- infoEvent("TC: Dump all ApiConnectRecord - size: %d",
- capiConnectFilesize);
- else if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- dumpState->args[0] = DumpStateOrd::TcDumpOneApiConnectRec;
- dumpState->args[1] = recordNo;
- execDUMP_STATE_ORD(signal);
-
- if (recordNo < capiConnectFilesize-1){
- dumpState->args[0] = DumpStateOrd::TcDumpAllApiConnectRec;
- dumpState->args[1] = recordNo+1;
- sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
- }
- }
-
- // Dump one ApiConnectRecord
- if (dumpState->args[0] == DumpStateOrd::TcDumpOneApiConnectRec){
- Uint32 recordNo = RNIL;
- if (signal->getLength() == 2)
- recordNo = dumpState->args[1];
- else
- return;
-
- if (recordNo >= capiConnectFilesize)
- return;
-
- ApiConnectRecordPtr ap;
- ap.i = recordNo;
- ptrAss(ap, apiConnectRecord);
- infoEvent("Dbtc::ApiConnectRecord[%d]: state=%d, abortState=%d, "
- "apiFailState=%d",
- ap.i,
- ap.p->apiConnectstate,
- ap.p->abortState,
- ap.p->apiFailState);
- infoEvent(" transid(0x%x, 0x%x), apiBref=0x%x, scanRec=%d",
- ap.p->transid[0],
- ap.p->transid[1],
- ap.p->ndbapiBlockref,
- ap.p->apiScanRec);
- infoEvent(" ctcTimer=%d, apiTimer=%d, counter=%d, retcode=%d, "
- "retsig=%d",
- ctcTimer, getApiConTimer(ap.i),
- ap.p->counter,
- ap.p->returncode,
- ap.p->returnsignal);
- infoEvent(" lqhkeyconfrec=%d, lqhkeyreqrec=%d, "
- "tckeyrec=%d",
- ap.p->lqhkeyconfrec,
- ap.p->lqhkeyreqrec,
- ap.p->tckeyrec);
- infoEvent(" next=%d ",
- ap.p->nextApiConnect);
- }
-
- if (dumpState->args[0] == DumpStateOrd::TcSetTransactionTimeout){
- jam();
- if(signal->getLength() > 1){
- set_timeout_value(signal->theData[1]);
- }
- }
-
- if (dumpState->args[0] == DumpStateOrd::TcSetApplTransactionTimeout){
- jam();
- if(signal->getLength() > 1){
- set_appl_timeout_value(signal->theData[1]);
- }
- }
-
- if (dumpState->args[0] == DumpStateOrd::StartTcTimer){
- c_counters.c_trans_status = TransCounters::Started;
- c_counters.reset();
- }
-
- if (dumpState->args[0] == DumpStateOrd::StopTcTimer){
- c_counters.c_trans_status = TransCounters::Off;
- Uint32 len = c_counters.report(signal);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, len, JBB);
- c_counters.reset();
- }
-
- if (dumpState->args[0] == DumpStateOrd::StartPeriodicTcTimer){
- c_counters.c_trans_status = TransCounters::Timer;
- c_counters.reset();
- signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1);
- }
-
- if (dumpState->args[0] == DumpStateOrd::TcStartDumpIndexOpCount)
- {
- static int frequency = 1;
- if (signal->getLength() > 1)
- frequency = signal->theData[1];
- else
- if (refToBlock(signal->getSendersBlockRef()) != DBTC)
- frequency = 1;
-
- if (frequency)
- {
- dumpState->args[0] = DumpStateOrd::TcDumpIndexOpCount;
- execDUMP_STATE_ORD(signal);
- dumpState->args[0] = DumpStateOrd::TcStartDumpIndexOpCount;
-
- Uint32 delay = 1000 * (frequency > 25 ? 25 : frequency);
- sendSignalWithDelay(cownref, GSN_DUMP_STATE_ORD, signal, delay, 1);
- }
- }
-
- if (dumpState->args[0] == DumpStateOrd::TcDumpIndexOpCount)
- {
- infoEvent("IndexOpCount: pool: %d free: %d",
- c_theIndexOperationPool.getSize(),
- c_theIndexOperationPool.getNoOfFree());
- }
-
- if (dumpState->args[0] == 2514)
- {
- if (signal->getLength() == 2)
- {
- dumpState->args[0] = DumpStateOrd::TcDumpOneApiConnectRec;
- execDUMP_STATE_ORD(signal);
- }
-
- NodeReceiverGroup rg(CMVMI, c_alive_nodes);
- dumpState->args[0] = 15;
- sendSignal(rg, GSN_DUMP_STATE_ORD, signal, 1, JBB);
-
- signal->theData[0] = 2515;
- sendSignalWithDelay(cownref, GSN_DUMP_STATE_ORD, signal, 1000, 1);
- return;
- }
-
- if (dumpState->args[0] == 2515)
- {
- NdbNodeBitmask mask = c_alive_nodes;
- mask.clear(getOwnNodeId());
- NodeReceiverGroup rg(NDBCNTR, mask);
-
- sendSignal(rg, GSN_SYSTEM_ERROR, signal, 1, JBB);
- sendSignalWithDelay(cownref, GSN_SYSTEM_ERROR, signal, 300, 1);
- return;
- }
-}//Dbtc::execDUMP_STATE_ORD()
-
-void Dbtc::execABORT_ALL_REQ(Signal* signal)
-{
- jamEntry();
- AbortAllReq * req = (AbortAllReq*)&signal->theData[0];
- AbortAllRef * ref = (AbortAllRef*)&signal->theData[0];
-
- const Uint32 senderData = req->senderData;
- const BlockReference senderRef = req->senderRef;
-
- if(getAllowStartTransaction(refToNode(senderRef), 0) == true && !getNodeState().getSingleUserMode()){
- jam();
-
- ref->senderData = senderData;
- ref->errorCode = AbortAllRef::InvalidState;
- sendSignal(senderRef, GSN_ABORT_ALL_REF, signal,
- AbortAllRef::SignalLength, JBB);
- return;
- }
-
- if(c_abortRec.clientRef != 0){
- jam();
-
- ref->senderData = senderData;
- ref->errorCode = AbortAllRef::AbortAlreadyInProgress;
- sendSignal(senderRef, GSN_ABORT_ALL_REF, signal,
- AbortAllRef::SignalLength, JBB);
- return;
- }
-
- if(refToNode(senderRef) != getOwnNodeId()){
- jam();
-
- ref->senderData = senderData;
- ref->errorCode = AbortAllRef::FunctionNotImplemented;
- sendSignal(senderRef, GSN_ABORT_ALL_REF, signal,
- AbortAllRef::SignalLength, JBB);
- return;
- }
-
- c_abortRec.clientRef = senderRef;
- c_abortRec.clientData = senderData;
- c_abortRec.oldTimeOutValue = ctimeOutValue;
-
- ctimeOutValue = 0;
- const Uint32 sleepTime = (2 * 10 * ctimeOutCheckDelay + 199) / 200;
-
- checkAbortAllTimeout(signal, (sleepTime == 0 ? 1 : sleepTime));
-}
-
-void Dbtc::checkAbortAllTimeout(Signal* signal, Uint32 sleepTime)
-{
-
- ndbrequire(c_abortRec.clientRef != 0);
-
- if(sleepTime > 0){
- jam();
-
- sleepTime -= 1;
- signal->theData[0] = TcContinueB::ZWAIT_ABORT_ALL;
- signal->theData[1] = sleepTime;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 200, 2);
- return;
- }
-
- AbortAllConf * conf = (AbortAllConf*)&signal->theData[0];
- conf->senderData = c_abortRec.clientData;
- sendSignal(c_abortRec.clientRef, GSN_ABORT_ALL_CONF, signal,
- AbortAllConf::SignalLength, JBB);
-
- ctimeOutValue = c_abortRec.oldTimeOutValue;
- c_abortRec.clientRef = 0;
-}
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* ------------------ TRIGGER AND INDEX HANDLING ------------------ */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-void Dbtc::execCREATE_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- CreateTrigReq * const createTrigReq =
- (CreateTrigReq *)&signal->theData[0];
- TcDefinedTriggerData* triggerData;
- DefinedTriggerPtr triggerPtr;
- BlockReference sender = signal->senderBlockRef();
-
- releaseSections(signal);
-
- triggerPtr.i = createTrigReq->getTriggerId();
- if (ERROR_INSERTED(8033) ||
- !c_theDefinedTriggers.seizeId(triggerPtr,
- createTrigReq->getTriggerId())) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- // Failed to allocate trigger record
- CreateTrigRef * const createTrigRef =
- (CreateTrigRef *)&signal->theData[0];
-
- createTrigRef->setConnectionPtr(createTrigReq->getConnectionPtr());
- createTrigRef->setErrorCode(CreateTrigRef::TooManyTriggers);
- sendSignal(sender, GSN_CREATE_TRIG_REF,
- signal, CreateTrigRef::SignalLength, JBB);
- return;
- }
-
- triggerData = triggerPtr.p;
- triggerData->triggerId = createTrigReq->getTriggerId();
- triggerData->triggerType = createTrigReq->getTriggerType();
- triggerData->triggerEvent = createTrigReq->getTriggerEvent();
- triggerData->attributeMask = createTrigReq->getAttributeMask();
- if (triggerData->triggerType == TriggerType::SECONDARY_INDEX)
- triggerData->indexId = createTrigReq->getIndexId();
- CreateTrigConf * const createTrigConf =
- (CreateTrigConf *)&signal->theData[0];
-
- createTrigConf->setConnectionPtr(createTrigReq->getConnectionPtr());
- sendSignal(sender, GSN_CREATE_TRIG_CONF,
- signal, CreateTrigConf::SignalLength, JBB);
-}
-
-
-void Dbtc::execDROP_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- DropTrigReq * const dropTrigReq = (DropTrigReq *)&signal->theData[0];
- BlockReference sender = signal->senderBlockRef();
-
- if (ERROR_INSERTED(8035) ||
- (c_theDefinedTriggers.getPtr(dropTrigReq->getTriggerId())) == NULL) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- // Failed to find find trigger record
- DropTrigRef * const dropTrigRef = (DropTrigRef *)&signal->theData[0];
-
- dropTrigRef->setConnectionPtr(dropTrigReq->getConnectionPtr());
- dropTrigRef->setErrorCode(DropTrigRef::TriggerNotFound);
- sendSignal(sender, GSN_DROP_TRIG_REF,
- signal, DropTrigRef::SignalLength, JBB);
- return;
- }
-
- // Release trigger record
- c_theDefinedTriggers.release(dropTrigReq->getTriggerId());
-
- DropTrigConf * const dropTrigConf = (DropTrigConf *)&signal->theData[0];
-
- dropTrigConf->setConnectionPtr(dropTrigReq->getConnectionPtr());
- sendSignal(sender, GSN_DROP_TRIG_CONF,
- signal, DropTrigConf::SignalLength, JBB);
-}
-
-void Dbtc::execCREATE_INDX_REQ(Signal* signal)
-{
- jamEntry();
- CreateIndxReq * const createIndxReq =
- (CreateIndxReq *)signal->getDataPtr();
- TcIndexData* indexData;
- TcIndexDataPtr indexPtr;
- BlockReference sender = signal->senderBlockRef();
-
- if (ERROR_INSERTED(8034) ||
- !c_theIndexes.seizeId(indexPtr, createIndxReq->getIndexId())) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- // Failed to allocate index record
- CreateIndxRef * const createIndxRef =
- (CreateIndxRef *)&signal->theData[0];
-
- createIndxRef->setConnectionPtr(createIndxReq->getConnectionPtr());
- createIndxRef->setErrorCode(CreateIndxRef::TooManyIndexes);
- releaseSections(signal);
- sendSignal(sender, GSN_CREATE_INDX_REF,
- signal, CreateIndxRef::SignalLength, JBB);
- return;
- }
- indexData = indexPtr.p;
- // Indexes always start in state IS_BUILDING
- // Will become IS_ONLINE in execALTER_INDX_REQ
- indexData->indexState = IS_BUILDING;
- indexData->indexId = indexPtr.i;
- indexData->primaryTableId = createIndxReq->getTableId();
-
- // So far need only attribute count
- SegmentedSectionPtr ssPtr;
- signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
- SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
- r0.reset(); // undo implicit first()
- if (!r0.getWord(&indexData->attributeList.sz) ||
- !r0.getWords(indexData->attributeList.id, indexData->attributeList.sz)) {
- ndbrequire(false);
- }
- indexData->primaryKeyPos = indexData->attributeList.sz;
-
- releaseSections(signal);
-
- CreateIndxConf * const createIndxConf =
- (CreateIndxConf *)&signal->theData[0];
-
- createIndxConf->setConnectionPtr(createIndxReq->getConnectionPtr());
- createIndxConf->setTableId(createIndxReq->getTableId());
- createIndxConf->setIndexId(createIndxReq->getIndexId());
- sendSignal(sender, GSN_CREATE_INDX_CONF,
- signal, CreateIndxConf::SignalLength, JBB);
-}
-
-void Dbtc::execALTER_INDX_REQ(Signal* signal)
-{
- jamEntry();
- AlterIndxReq * const alterIndxReq = (AlterIndxReq *)signal->getDataPtr();
- TcIndexData* indexData;
- //BlockReference sender = signal->senderBlockRef();
- BlockReference sender = (BlockReference) alterIndxReq->getUserRef();
- Uint32 connectionPtr = alterIndxReq->getConnectionPtr();
- AlterIndxReq::RequestType requestType = alterIndxReq->getRequestType();
- Uint32 tableId = alterIndxReq->getTableId();
- Uint32 indexId = alterIndxReq->getIndexId();
- bool online = (alterIndxReq->getOnline() == 1) ? true : false;
-
- if ((indexData = c_theIndexes.getPtr(indexId)) == NULL) {
- jam();
- // Failed to find index record
- AlterIndxRef * const alterIndxRef =
- (AlterIndxRef *)signal->getDataPtrSend();
-
- alterIndxRef->setUserRef(reference());
- alterIndxRef->setConnectionPtr(connectionPtr);
- alterIndxRef->setRequestType(requestType);
- alterIndxRef->setTableId(tableId);
- alterIndxRef->setIndexId(indexId);
- alterIndxRef->setErrorCode(AlterIndxRef::IndexNotFound);
- alterIndxRef->setErrorLine(__LINE__);
- alterIndxRef->setErrorNode(getOwnNodeId());
- sendSignal(sender, GSN_ALTER_INDX_REF,
- signal, AlterIndxRef::SignalLength, JBB);
- return;
- }
- // Found index record, alter it's state
- if (online) {
- jam();
- indexData->indexState = IS_ONLINE;
- } else {
- jam();
- indexData->indexState = IS_BUILDING;
- }//if
- AlterIndxConf * const alterIndxConf =
- (AlterIndxConf *)signal->getDataPtrSend();
-
- alterIndxConf->setUserRef(reference());
- alterIndxConf->setConnectionPtr(connectionPtr);
- alterIndxConf->setRequestType(requestType);
- alterIndxConf->setTableId(tableId);
- alterIndxConf->setIndexId(indexId);
- sendSignal(sender, GSN_ALTER_INDX_CONF,
- signal, AlterIndxConf::SignalLength, JBB);
-}
-
-void Dbtc::execFIRE_TRIG_ORD(Signal* signal)
-{
- jamEntry();
- FireTrigOrd * const fireOrd = (FireTrigOrd *)signal->getDataPtr();
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- ApiConnectRecordPtr transPtr;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- TcConnectRecordPtr opPtr;
- /**
- * TODO
- * Check transid,
- * Fix overload i.e invalid word count
- */
- TcFiredTriggerData key;
- key.fireingOperation = fireOrd->getConnectionPtr();
- key.nodeId = refToNode(signal->getSendersBlockRef());
- FiredTriggerPtr trigPtr;
- if(c_firedTriggerHash.find(trigPtr, key)){
-
- c_firedTriggerHash.remove(trigPtr);
-
- trigPtr.p->fragId= fireOrd->fragId;
- bool ok = trigPtr.p->keyValues.getSize() == fireOrd->m_noPrimKeyWords;
- ok &= trigPtr.p->afterValues.getSize() == fireOrd->m_noAfterValueWords;
- ok &= trigPtr.p->beforeValues.getSize() == fireOrd->m_noBeforeValueWords;
- if(ok){
- opPtr.i = key.fireingOperation;
- ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
- transPtr.i = opPtr.p->apiConnect;
- transPtr.p = &localApiConnectRecord[transPtr.i];
-
- opPtr.p->noReceivedTriggers++;
- opPtr.p->triggerExecutionCount++;
-
- // Insert fired trigger in execution queue
- transPtr.p->theFiredTriggers.add(trigPtr);
- if (opPtr.p->noReceivedTriggers == opPtr.p->noFiredTriggers) {
- executeTriggers(signal, &transPtr);
- }
- return;
- }
- jam();
- c_theFiredTriggerPool.release(trigPtr);
- }
- jam();
- /**
- * Failed to find record or invalid word counts
- */
- ndbrequire(false);
-}
-
-void Dbtc::execTRIG_ATTRINFO(Signal* signal)
-{
- jamEntry();
- TrigAttrInfo * const trigAttrInfo = (TrigAttrInfo *)signal->getDataPtr();
- Uint32 attrInfoLength = signal->getLength() - TrigAttrInfo::StaticLength;
- const Uint32 *src = trigAttrInfo->getData();
- FiredTriggerPtr firedTrigPtr;
-
- TcFiredTriggerData key;
- key.fireingOperation = trigAttrInfo->getConnectionPtr();
- key.nodeId = refToNode(signal->getSendersBlockRef());
- if(!c_firedTriggerHash.find(firedTrigPtr, key)){
- jam();
- if(!c_firedTriggerHash.seize(firedTrigPtr)){
- jam();
- /**
- * Will be handled when FIRE_TRIG_ORD arrives
- */
- ndbout_c("op: %d node: %d failed to seize",
- key.fireingOperation, key.nodeId);
- return;
- }
- ndbrequire(firedTrigPtr.p->keyValues.getSize() == 0 &&
- firedTrigPtr.p->beforeValues.getSize() == 0 &&
- firedTrigPtr.p->afterValues.getSize() == 0);
-
- firedTrigPtr.p->nodeId = refToNode(signal->getSendersBlockRef());
- firedTrigPtr.p->fireingOperation = key.fireingOperation;
- firedTrigPtr.p->triggerId = trigAttrInfo->getTriggerId();
- c_firedTriggerHash.add(firedTrigPtr);
- }
-
- AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool;
- switch (trigAttrInfo->getAttrInfoType()) {
- case(TrigAttrInfo::PRIMARY_KEY):
- jam();
- {
- LocalDataBuffer<11> buf(pool, firedTrigPtr.p->keyValues);
- buf.append(src, attrInfoLength);
- }
- break;
- case(TrigAttrInfo::BEFORE_VALUES):
- jam();
- {
- LocalDataBuffer<11> buf(pool, firedTrigPtr.p->beforeValues);
- buf.append(src, attrInfoLength);
- }
- break;
- case(TrigAttrInfo::AFTER_VALUES):
- jam();
- {
- LocalDataBuffer<11> buf(pool, firedTrigPtr.p->afterValues);
- buf.append(src, attrInfoLength);
- }
- break;
- default:
- ndbrequire(false);
- }
-}
-
-void Dbtc::execDROP_INDX_REQ(Signal* signal)
-{
- jamEntry();
- DropIndxReq * const dropIndxReq = (DropIndxReq *)signal->getDataPtr();
- TcIndexData* indexData;
- BlockReference sender = signal->senderBlockRef();
-
- if (ERROR_INSERTED(8036) ||
- (indexData = c_theIndexes.getPtr(dropIndxReq->getIndexId())) == NULL) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- // Failed to find index record
- DropIndxRef * const dropIndxRef =
- (DropIndxRef *)signal->getDataPtrSend();
-
- dropIndxRef->setConnectionPtr(dropIndxReq->getConnectionPtr());
- dropIndxRef->setErrorCode(DropIndxRef::IndexNotFound);
- sendSignal(sender, GSN_DROP_INDX_REF,
- signal, DropIndxRef::SignalLength, JBB);
- return;
- }
- // Release index record
- c_theIndexes.release(dropIndxReq->getIndexId());
-
- DropIndxConf * const dropIndxConf =
- (DropIndxConf *)signal->getDataPtrSend();
-
- dropIndxConf->setConnectionPtr(dropIndxReq->getConnectionPtr());
- sendSignal(sender, GSN_DROP_INDX_CONF,
- signal, DropIndxConf::SignalLength, JBB);
-}
-
-void Dbtc::execTCINDXREQ(Signal* signal)
-{
- jamEntry();
-
- TcKeyReq * const tcIndxReq = (TcKeyReq *)signal->getDataPtr();
- const UintR TapiIndex = tcIndxReq->apiConnectPtr;
- Uint32 tcIndxRequestInfo = tcIndxReq->requestInfo;
- Uint32 startFlag = tcIndxReq->getStartFlag(tcIndxRequestInfo);
- Uint32 * dataPtr = &tcIndxReq->scanInfo;
- Uint32 indexBufSize = 8; // Maximum for index in TCINDXREQ
- Uint32 attrBufSize = 5; // Maximum for attrInfo in TCINDXREQ
- ApiConnectRecordPtr transPtr;
- transPtr.i = TapiIndex;
- if (transPtr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
- ptrAss(transPtr, apiConnectRecord);
- ApiConnectRecord * const regApiPtr = transPtr.p;
- // Seize index operation
- TcIndexOperationPtr indexOpPtr;
- if ((startFlag == 1) &&
- (regApiPtr->apiConnectstate == CS_CONNECTED ||
- (regApiPtr->apiConnectstate == CS_STARTED &&
- regApiPtr->firstTcConnect == RNIL)) ||
- (regApiPtr->apiConnectstate == CS_ABORTING &&
- regApiPtr->abortState == AS_IDLE)) {
- jam();
- // This is a newly started transaction, clean-up
- releaseAllSeizedIndexOperations(regApiPtr);
-
- regApiPtr->apiConnectstate = CS_STARTED;
- regApiPtr->transid[0] = tcIndxReq->transId1;
- regApiPtr->transid[1] = tcIndxReq->transId2;
- }//if
-
- if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
- getNodeState().getSingleUserApi() !=
- refToNode(regApiPtr->ndbapiBlockref))
- {
- terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
- apiConnectptr = transPtr;
- abortErrorLab(signal);
- return;
- }
-
- if (ERROR_INSERTED(8036) || !seizeIndexOperation(regApiPtr, indexOpPtr)) {
- jam();
- // Failed to allocate index operation
- terrorCode = 288;
- regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
- apiConnectptr = transPtr;
- abortErrorLab(signal);
- return;
- }
- TcIndexOperation* indexOp = indexOpPtr.p;
- indexOp->indexOpId = indexOpPtr.i;
-
- // Save original signal
- indexOp->tcIndxReq = *tcIndxReq;
- indexOp->connectionIndex = TapiIndex;
- regApiPtr->accumulatingIndexOp = indexOp->indexOpId;
-
- // If operation is readTupleExclusive or updateTuple then read index
- // table with exclusive lock
- Uint32 indexLength = TcKeyReq::getKeyLength(tcIndxRequestInfo);
- Uint32 attrLength = TcKeyReq::getAttrinfoLen(tcIndxReq->attrLen);
- indexOp->expectedKeyInfo = indexLength;
- Uint32 includedIndexLength = MIN(indexLength, indexBufSize);
- indexOp->expectedAttrInfo = attrLength;
- Uint32 includedAttrLength = MIN(attrLength, attrBufSize);
-
- int ret;
- if ((ret = saveINDXKEYINFO(signal,
- indexOp,
- dataPtr,
- includedIndexLength)) == 0)
- {
- jam();
- // We have received all we need
- readIndexTable(signal, regApiPtr, indexOp);
- return;
- }
- else if (ret == -1)
- {
- jam();
- return;
- }
-
- dataPtr += includedIndexLength;
- if (saveINDXATTRINFO(signal,
- indexOp,
- dataPtr,
- includedAttrLength) == 0) {
- jam();
- // We have received all we need
- readIndexTable(signal, regApiPtr, indexOp);
- return;
- }
-}
-
-
-void Dbtc::sendTcIndxConf(Signal* signal, UintR TcommitFlag)
-{
- HostRecordPtr localHostptr;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- const UintR TopWords = (UintR)regApiPtr->tcindxrec;
- localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
- const Uint32 type = getNodeInfo(localHostptr.i).m_type;
- const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
- const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
- const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL ? 0 : 1);
- ptrAss(localHostptr, hostRecord);
- UintR TcurrLen = localHostptr.p->noOfWordsTCINDXCONF;
- UintR confInfo = 0;
- TcIndxConf::setNoOfOperations(confInfo, (TopWords >> 1));
- TcIndxConf::setCommitFlag(confInfo, TcommitFlag == 1);
- TcIndxConf::setMarkerFlag(confInfo, Tmarker);
- const UintR TpacketLen = 6 + TopWords;
- regApiPtr->tcindxrec = 0;
-
- if(TcommitFlag || (regApiPtr->lqhkeyreqrec == regApiPtr->lqhkeyconfrec)){
- jam();
- regApiPtr->m_exec_flag = 0;
- }
-
- if ((TpacketLen > 25) || !is_api){
- TcIndxConf * const tcIndxConf = (TcIndxConf *)signal->getDataPtrSend();
-
- jam();
- tcIndxConf->apiConnectPtr = regApiPtr->ndbapiConnect;
- tcIndxConf->gci = regApiPtr->globalcheckpointid;;
- tcIndxConf->confInfo = confInfo;
- tcIndxConf->transId1 = regApiPtr->transid[0];
- tcIndxConf->transId2 = regApiPtr->transid[1];
- copyFromToLen(&regApiPtr->tcIndxSendArray[0],
- (UintR*)&tcIndxConf->operations,
- (UintR)ZTCOPCONF_SIZE);
- sendSignal(regApiPtr->ndbapiBlockref,
- GSN_TCINDXCONF, signal, (TpacketLen - 1), JBB);
- return;
- } else if (((TcurrLen + TpacketLen) > 25) && (TcurrLen > 0)) {
- jam();
- sendPackedTCINDXCONF(signal, localHostptr.p, localHostptr.i);
- TcurrLen = 0;
- } else {
- jam();
- updatePackedList(signal, localHostptr.p, localHostptr.i);
- }//if
-// -------------------------------------------------------------------------
-// The header contains the block reference of receiver plus the real signal
-// length - 3, since we have the real signal length plus one additional word
-// for the header we have to do - 4.
-// -------------------------------------------------------------------------
- UintR Tpack0 = (TblockNum << 16) + (TpacketLen - 4);
- UintR Tpack1 = regApiPtr->ndbapiConnect;
- UintR Tpack2 = regApiPtr->globalcheckpointid;
- UintR Tpack3 = confInfo;
- UintR Tpack4 = regApiPtr->transid[0];
- UintR Tpack5 = regApiPtr->transid[1];
-
- localHostptr.p->noOfWordsTCINDXCONF = TcurrLen + TpacketLen;
-
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 0] = Tpack0;
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 1] = Tpack1;
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 2] = Tpack2;
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 3] = Tpack3;
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 4] = Tpack4;
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 5] = Tpack5;
-
- UintR Ti;
- for (Ti = 6; Ti < TpacketLen; Ti++) {
- localHostptr.p->packedWordsTCINDXCONF[TcurrLen + Ti] =
- regApiPtr->tcIndxSendArray[Ti - 6];
- }//for
-}//Dbtc::sendTcIndxConf()
-
-void Dbtc::execINDXKEYINFO(Signal* signal)
-{
- jamEntry();
- Uint32 keyInfoLength = signal->getLength() - IndxKeyInfo::HeaderLength;
- IndxKeyInfo * const indxKeyInfo = (IndxKeyInfo *)signal->getDataPtr();
- const Uint32 *src = indxKeyInfo->getData();
- const UintR TconnectIndex = indxKeyInfo->connectPtr;
- ApiConnectRecordPtr transPtr;
- transPtr.i = TconnectIndex;
- if (transPtr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
- ptrAss(transPtr, apiConnectRecord);
- ApiConnectRecord * const regApiPtr = transPtr.p;
- TcIndexOperationPtr indexOpPtr;
- TcIndexOperation* indexOp;
-
- if (compare_transid(regApiPtr->transid, indxKeyInfo->transId) == false)
- {
- TCKEY_abort(signal, 19);
- return;
- }
-
- if (regApiPtr->apiConnectstate == CS_ABORTING)
- {
- jam();
- return;
- }
-
- if((indexOpPtr.i = regApiPtr->accumulatingIndexOp) != RNIL)
- {
- indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- if (saveINDXKEYINFO(signal,
- indexOp,
- src,
- keyInfoLength) == 0) {
- jam();
- // We have received all we need
- readIndexTable(signal, regApiPtr, indexOp);
- }
- }
-}
-
-void Dbtc::execINDXATTRINFO(Signal* signal)
-{
- jamEntry();
- Uint32 attrInfoLength = signal->getLength() - IndxAttrInfo::HeaderLength;
- IndxAttrInfo * const indxAttrInfo = (IndxAttrInfo *)signal->getDataPtr();
- const Uint32 *src = indxAttrInfo->getData();
- const UintR TconnectIndex = indxAttrInfo->connectPtr;
- ApiConnectRecordPtr transPtr;
- transPtr.i = TconnectIndex;
- if (transPtr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal, __LINE__);
- return;
- }//if
- ptrAss(transPtr, apiConnectRecord);
- ApiConnectRecord * const regApiPtr = transPtr.p;
- TcIndexOperationPtr indexOpPtr;
- TcIndexOperation* indexOp;
-
- if (compare_transid(regApiPtr->transid, indxAttrInfo->transId) == false)
- {
- TCKEY_abort(signal, 19);
- return;
- }
-
- if (regApiPtr->apiConnectstate == CS_ABORTING)
- {
- jam();
- return;
- }
-
- if((indexOpPtr.i = regApiPtr->accumulatingIndexOp) != RNIL)
- {
- indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- if (saveINDXATTRINFO(signal,
- indexOp,
- src,
- attrInfoLength) == 0) {
- jam();
- // We have received all we need
- readIndexTable(signal, regApiPtr, indexOp);
- return;
- }
- return;
- }
-}
-
-/**
- * Save signal INDXKEYINFO
- * Return true if we have received all needed data
- */
-int
-Dbtc::saveINDXKEYINFO(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len)
-{
- if (ERROR_INSERTED(8052) || !indexOp->keyInfo.append(src, len)) {
- jam();
- // Failed to seize keyInfo, abort transaction
-#ifdef VM_TRACE
- ndbout_c("Dbtc::saveINDXKEYINFO: Failed to seize keyinfo\n");
-#endif
- // Abort transaction
- apiConnectptr.i = indexOp->connectionIndex;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- releaseIndexOperation(apiConnectptr.p, indexOp);
- terrorCode = 289;
- if(TcKeyReq::getExecuteFlag(indexOp->tcIndxReq.requestInfo))
- apiConnectptr.p->m_exec_flag= 1;
- abortErrorLab(signal);
- return -1;
- }
- if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
- jam();
- return 0;
- }
- return 1;
-}
-
-bool Dbtc::receivedAllINDXKEYINFO(TcIndexOperation* indexOp)
-{
- return (indexOp->keyInfo.getSize() == indexOp->expectedKeyInfo);
-}
-
-/**
- * Save signal INDXATTRINFO
- * Return true if we have received all needed data
- */
-int
-Dbtc::saveINDXATTRINFO(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len)
-{
- if (ERROR_INSERTED(8051) || !indexOp->attrInfo.append(src, len)) {
- jam();
-#ifdef VM_TRACE
- ndbout_c("Dbtc::saveINDXATTRINFO: Failed to seize attrInfo\n");
-#endif
- apiConnectptr.i = indexOp->connectionIndex;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- releaseIndexOperation(apiConnectptr.p, indexOp);
- terrorCode = 289;
- if(TcKeyReq::getExecuteFlag(indexOp->tcIndxReq.requestInfo))
- apiConnectptr.p->m_exec_flag= 1;
- abortErrorLab(signal);
- return -1;
- }
- if (receivedAllINDXKEYINFO(indexOp) && receivedAllINDXATTRINFO(indexOp)) {
- jam();
- return 0;
- }
- return 1;
-}
-
-bool Dbtc::receivedAllINDXATTRINFO(TcIndexOperation* indexOp)
-{
- return (indexOp->attrInfo.getSize() == indexOp->expectedAttrInfo);
-}
-
-bool Dbtc::saveTRANSID_AI(Signal* signal,
- TcIndexOperation* indexOp,
- const Uint32 *src,
- Uint32 len)
-{
- Uint32 currentTransIdAILength = indexOp->transIdAI.getSize();
-
- if (currentTransIdAILength == 0) {
- jam();
- // Read first AttributeHeader to get expected size
- // of the single key attribute expected
- AttributeHeader* head = (AttributeHeader *) src;
- indexOp->expectedTransIdAI = head->getHeaderSize() + head->getDataSize();
- }
- if (!indexOp->transIdAI.append(src, len)) {
- jam();
-#ifdef VM_TRACE
- ndbout_c("Dbtc::saveTRANSID_AI: Failed to seize transIdAI\n");
-#endif
- apiConnectptr.i = indexOp->connectionIndex;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- releaseIndexOperation(apiConnectptr.p, indexOp);
- terrorCode = 4000;
- abortErrorLab(signal);
- return false;
- }
- return true;
-}
-
-bool Dbtc::receivedAllTRANSID_AI(TcIndexOperation* indexOp)
-{
- return (indexOp->transIdAI.getSize() == indexOp->expectedTransIdAI);
-}
-
-/**
- * Receive signal TCINDXCONF
- * This can be either the return of reading an index table
- * or performing an index operation
- */
-void Dbtc::execTCKEYCONF(Signal* signal)
-{
- TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtr();
- TcIndexOperationPtr indexOpPtr;
-
- jamEntry();
- indexOpPtr.i = tcKeyConf->apiConnectPtr;
- TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- Uint32 confInfo = tcKeyConf->confInfo;
-
- /**
- * Check on TCKEYCONF wheater the the transaction was committed
- */
- Uint32 Tcommit = TcKeyConf::getCommitFlag(confInfo);
-
- indexOpPtr.p = indexOp;
- if (!indexOp) {
- jam();
- // Missing index operation
- return;
- }
- const UintR TconnectIndex = indexOp->connectionIndex;
- ApiConnectRecord * const regApiPtr = &apiConnectRecord[TconnectIndex];
- apiConnectptr.p = regApiPtr;
- apiConnectptr.i = TconnectIndex;
- switch(indexOp->indexOpState) {
- case(IOS_NOOP): {
- jam();
- // Should never happen, abort
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
- case(IOS_INDEX_ACCESS): {
- jam();
- // Wait for TRANSID_AI
- indexOp->indexOpState = IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI;
- break;
- }
- case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): {
- jam();
- // Double TCKEYCONF, should never happen, abort
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
- case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {
- jam();
- // Continue with index operation
- executeIndexOperation(signal, regApiPtr, indexOp);
- break;
- }
- case(IOS_INDEX_OPERATION): {
- // We are done, send TCINDXCONF
- jam();
- Uint32 Ttcindxrec = regApiPtr->tcindxrec;
- // Copy reply from TcKeyConf
-
- ndbassert(regApiPtr->noIndexOp);
- regApiPtr->noIndexOp--; // Decrease count
- regApiPtr->tcIndxSendArray[Ttcindxrec] = indexOp->tcIndxReq.senderData;
- regApiPtr->tcIndxSendArray[Ttcindxrec + 1] =
- tcKeyConf->operations[0].attrInfoLen;
- regApiPtr->tcindxrec = Ttcindxrec + 2;
- if (regApiPtr->noIndexOp == 0) {
- jam();
- sendTcIndxConf(signal, Tcommit);
- } else if (regApiPtr->tcindxrec == ZTCOPCONF_SIZE) {
- jam();
- sendTcIndxConf(signal, 0);
- }
- releaseIndexOperation(regApiPtr, indexOp);
- break;
- }
- }
-}
-
-void Dbtc::execTCKEYREF(Signal* signal)
-{
- TcKeyRef * const tcKeyRef = (TcKeyRef *)signal->getDataPtr();
- TcIndexOperationPtr indexOpPtr;
-
- jamEntry();
- indexOpPtr.i = tcKeyRef->connectPtr;
- TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- indexOpPtr.p = indexOp;
- if (!indexOp) {
- jam();
- // Missing index operation
- return;
- }
- const UintR TconnectIndex = indexOp->connectionIndex;
- ApiConnectRecord * const regApiPtr = &apiConnectRecord[TconnectIndex];
-
- switch(indexOp->indexOpState) {
- case(IOS_NOOP): {
- jam();
- // Should never happen, abort
- break;
- }
- case(IOS_INDEX_ACCESS):
- case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI):
- case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {
- jam();
- /**
- * Increase count as it will be decreased below...
- * (and the code is written to handle failing lookup on "real" table
- * not lookup on index table)
- */
- regApiPtr->noIndexOp++;
- // else continue
- }
- case(IOS_INDEX_OPERATION): {
- // Send TCINDXREF
-
- jam();
- TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- ndbassert(regApiPtr->noIndexOp);
- regApiPtr->noIndexOp--; // Decrease count
- tcIndxRef->connectPtr = tcIndxReq->senderData;
- tcIndxRef->transId[0] = tcKeyRef->transId[0];
- tcIndxRef->transId[1] = tcKeyRef->transId[1];
- tcIndxRef->errorCode = tcKeyRef->errorCode;
- tcIndxRef->errorData = 0;
-
- releaseIndexOperation(regApiPtr, indexOp);
-
- sendSignal(regApiPtr->ndbapiBlockref,
- GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB);
- return;
- }
- }
-}
-
-void Dbtc::execTRANSID_AI_R(Signal* signal){
- TransIdAI * const transIdAI = (TransIdAI *)signal->getDataPtr();
- Uint32 sigLen = signal->length();
- Uint32 dataLen = sigLen - TransIdAI::HeaderLength - 1;
- Uint32 recBlockref = transIdAI->attrData[dataLen];
-
- jamEntry();
-
- /**
- * Forward signal to final destination
- * Truncate last word since that was used to hold the final dest.
- */
- sendSignal(recBlockref, GSN_TRANSID_AI,
- signal, sigLen - 1, JBB);
-}
-
-void Dbtc::execKEYINFO20_R(Signal* signal){
- KeyInfo20 * const keyInfo = (KeyInfo20 *)signal->getDataPtr();
- Uint32 sigLen = signal->length();
- Uint32 dataLen = sigLen - KeyInfo20::HeaderLength - 1;
- Uint32 recBlockref = keyInfo->keyData[dataLen];
-
- jamEntry();
-
- /**
- * Forward signal to final destination
- * Truncate last word since that was used to hold the final dest.
- */
- sendSignal(recBlockref, GSN_KEYINFO20,
- signal, sigLen - 1, JBB);
-}
-
-
-void Dbtc::execTRANSID_AI(Signal* signal)
-{
- TransIdAI * const transIdAI = (TransIdAI *)signal->getDataPtr();
-
- jamEntry();
- TcIndexOperationPtr indexOpPtr;
- indexOpPtr.i = transIdAI->connectPtr;
- TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- indexOpPtr.p = indexOp;
- if (!indexOp) {
- jam();
- // Missing index operation
- }
- const UintR TconnectIndex = indexOp->connectionIndex;
- // ApiConnectRecord * const regApiPtr = &apiConnectRecord[TconnectIndex];
- ApiConnectRecordPtr transPtr;
-
- transPtr.i = TconnectIndex;
- ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
- ApiConnectRecord * const regApiPtr = transPtr.p;
-
- // Acccumulate attribute data
- if (!saveTRANSID_AI(signal,
- indexOp,
- transIdAI->getData(),
- signal->getLength() - TransIdAI::HeaderLength)) {
- jam();
- // Failed to allocate space for TransIdAI
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4000;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
-
- switch(indexOp->indexOpState) {
- case(IOS_NOOP): {
- jam();
- // Should never happen, abort
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- break;
- }
- case(IOS_INDEX_ACCESS): {
- jam();
- // Check if all TRANSID_AI have been received
- if (receivedAllTRANSID_AI(indexOp)) {
- jam();
- // Wait for TRANSID_AI
- indexOp->indexOpState = IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF;
- }
- break;
- }
- case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {
- jam();
-#ifdef VM_TRACE
- ndbout_c("Dbtc::execTRANSID_AI: Too many TRANSID_AI, ignore for now\n");
-#endif
- /*
- // Too many TRANSID_AI
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndexRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- */
- break;
- }
- case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): {
- jam();
- // Check if all TRANSID_AI have been received
- if (receivedAllTRANSID_AI(indexOp)) {
- jam();
- // Continue with index operation
- executeIndexOperation(signal, regApiPtr, indexOp);
- }
- // else continue waiting for more TRANSID_AI
- break;
- }
- case(IOS_INDEX_OPERATION): {
- // Should never receive TRANSID_AI in this state!!
- jam();
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = regApiPtr->errorData;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
- }
-}
-
-void Dbtc::execTCROLLBACKREP(Signal* signal)
-{
- TcRollbackRep* tcRollbackRep = (TcRollbackRep *)signal->getDataPtr();
- jamEntry();
- TcIndexOperationPtr indexOpPtr;
- indexOpPtr.i = tcRollbackRep->connectPtr;
- TcIndexOperation* indexOp = c_theIndexOperationPool.getPtr(indexOpPtr.i);
- indexOpPtr.p = indexOp;
- tcRollbackRep = (TcRollbackRep *)signal->getDataPtrSend();
- tcRollbackRep->connectPtr = indexOp->tcIndxReq.senderData;
- sendSignal(apiConnectptr.p->ndbapiBlockref,
- GSN_TCROLLBACKREP, signal, TcRollbackRep::SignalLength, JBB);
-}
-
-/**
- * Read index table with the index attributes as PK
- */
-void Dbtc::readIndexTable(Signal* signal,
- ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp)
-{
- Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
- Uint32 dataPos = 0;
- TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
- Uint32 * dataPtr = &tcKeyReq->scanInfo;
- Uint32 tcKeyLength = TcKeyReq::StaticLength;
- Uint32 tcKeyRequestInfo = indexOp->tcIndxReq.requestInfo;
- AttributeBuffer::DataBufferIterator keyIter;
- Uint32 keyLength = TcKeyReq::getKeyLength(tcKeyRequestInfo);
- TcIndexData* indexData;
- Uint32 transId1 = indexOp->tcIndxReq.transId1;
- Uint32 transId2 = indexOp->tcIndxReq.transId2;
-
- const Operation_t opType =
- (Operation_t)TcKeyReq::getOperationType(tcKeyRequestInfo);
-
- // Find index table
- if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.tableId)) == NULL) {
- jam();
- // Failed to find index record
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4000;
- // tcIndxRef->errorData = ??; Where to find indexId
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
- tcKeyReq->transId1 = transId1;
- tcKeyReq->transId2 = transId2;
- tcKeyReq->tableId = indexData->indexId;
- tcKeyLength += MIN(keyLength, keyBufSize);
- tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.tableSchemaVersion;
- TcKeyReq::setOperationType(tcKeyRequestInfo,
- opType == ZREAD ? ZREAD : ZREAD_EX);
- TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo
- TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0);
- tcKeyReq->senderData = indexOp->indexOpId;
- indexOp->indexOpState = IOS_INDEX_ACCESS;
- regApiPtr->executingIndexOp = regApiPtr->accumulatingIndexOp;
- regApiPtr->accumulatingIndexOp = RNIL;
- regApiPtr->isIndexOp = 2;
-
- if (ERROR_INSERTED(8037))
- {
- ndbout_c("shifting index version");
- tcKeyReq->tableSchemaVersion = ~(Uint32)indexOp->tcIndxReq.tableSchemaVersion;
- }
-
- Uint32 remainingKey = indexOp->keyInfo.getSize();
- bool moreKeyData = indexOp->keyInfo.first(keyIter);
- // *********** KEYINFO in TCKEYREQ ***********
- while((dataPos < keyBufSize) &&
- (remainingKey-- != 0)) {
- *dataPtr++ = *keyIter.data;
- dataPos++;
- moreKeyData = indexOp->keyInfo.next(keyIter);
- }
- // *********** ATTRINFO in TCKEYREQ ***********
- tcKeyReq->attrLen = 1; // Primary key is stored as one attribute
- AttributeHeader::init(dataPtr, indexData->primaryKeyPos, 0);
- tcKeyLength++;
- tcKeyReq->requestInfo = tcKeyRequestInfo;
-
- ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0);
- ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0);
- EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- goto err;
- }
-
- // *********** KEYINFO ***********
- if (moreKeyData) {
- jam();
- // Send KEYINFO sequence
- KeyInfo * const keyInfo = (KeyInfo *)signal->getDataPtrSend();
-
- keyInfo->connectPtr = indexOp->tcIndxReq.apiConnectPtr;
- keyInfo->transId[0] = transId1;
- keyInfo->transId[1] = transId2;
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- while(remainingKey-- != 0) {// If we have not read complete key
- *dataPtr++ = *keyIter.data;
- dataPos++;
- if (dataPos == KeyInfo::DataLength) {
- // Flush KEYINFO
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- goto err;
- }
- dataPos = 0;
- dataPtr = (Uint32 *) &keyInfo->keyData;
- }
- moreKeyData = indexOp->keyInfo.next(keyIter);
- }
- if (dataPos != 0) {
- // Flush last KEYINFO
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos);
- jamEntry();
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- goto err;
- }
- }
- }
-
- /**
- * "Fool" TC not to start commiting transaction since it always will
- * have one outstanding lqhkeyreq
- * This is later decreased when the index read is complete
- */
- regApiPtr->lqhkeyreqrec++;
-
- /**
- * Remember ptr to index read operation
- * (used to set correct save point id on index operation later)
- */
- indexOp->indexReadTcConnect = regApiPtr->lastTcConnect;
-
-done:
- return;
-
-err:
- jam();
- goto done;
-}
-
-/**
- * Execute the index operation with the result from
- * the index table read as PK
- */
-void Dbtc::executeIndexOperation(Signal* signal,
- ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp) {
-
- Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
- Uint32 attrBufSize = 5;
- Uint32 dataPos = 0;
- TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
- TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
- /*
- Data points to distrGroupHashValue since scanInfo is used to send
- fragment id of receiving fragment
- */
- Uint32 * dataPtr = &tcKeyReq->distrGroupHashValue;
- Uint32 tcKeyLength = TcKeyReq::StaticLength;
- Uint32 tcKeyRequestInfo = tcIndxReq->requestInfo;
- TcIndexData* indexData;
- AttributeBuffer::DataBufferIterator attrIter;
- AttributeBuffer::DataBufferIterator aiIter;
- bool moreKeyData = indexOp->transIdAI.first(aiIter);
-
- // Find index table
- if ((indexData = c_theIndexes.getPtr(tcIndxReq->tableId)) == NULL) {
- jam();
- // Failed to find index record
- TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
- tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
- tcIndxRef->transId[0] = regApiPtr->transid[0];
- tcIndxRef->transId[1] = regApiPtr->transid[1];
- tcIndxRef->errorCode = 4349;
- tcIndxRef->errorData = 0;
- sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
- TcKeyRef::SignalLength, JBB);
- return;
- }
- // Find schema version of primary table
- TableRecordPtr tabPtr;
- tabPtr.i = indexData->primaryTableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- tcKeyReq->apiConnectPtr = tcIndxReq->apiConnectPtr;
- tcKeyReq->attrLen = tcIndxReq->attrLen;
- tcKeyReq->tableId = indexData->primaryTableId;
- tcKeyReq->tableSchemaVersion = tabPtr.p->currentSchemaVersion;
- tcKeyReq->transId1 = regApiPtr->transid[0];
- tcKeyReq->transId2 = regApiPtr->transid[1];
- tcKeyReq->senderData = tcIndxReq->senderData; // Needed for TRANSID_AI to API
- indexOp->indexOpState = IOS_INDEX_OPERATION;
- regApiPtr->isIndexOp = 1;
- regApiPtr->executingIndexOp = indexOp->indexOpId;;
- regApiPtr->noIndexOp++; // Increase count
-
- /*
- Filter out AttributeHeader:s since this should not be in key.
- Also filter out fragment id from primary key and handle that
- separately by setting it as Distribution Key and set indicator.
- */
-
- AttributeHeader* attrHeader = (AttributeHeader *) aiIter.data;
-
- Uint32 headerSize = attrHeader->getHeaderSize();
- Uint32 keySize = attrHeader->getDataSize() - 1;
- TcKeyReq::setKeyLength(tcKeyRequestInfo, keySize);
- // Skip header
- if (headerSize == 1) {
- jam();
- moreKeyData = indexOp->transIdAI.next(aiIter);
- } else {
- jam();
- moreKeyData = indexOp->transIdAI.next(aiIter, headerSize - 1);
- }//if
- tcKeyReq->scanInfo = *aiIter.data; //Fragment Id
- moreKeyData = indexOp->transIdAI.next(aiIter);
- TcKeyReq::setDistributionKeyFlag(tcKeyRequestInfo, 1U);
- while(// If we have not read complete key
- (keySize != 0) &&
- (dataPos < keyBufSize)) {
- *dataPtr++ = *aiIter.data;
- dataPos++;
- keySize--;
- moreKeyData = indexOp->transIdAI.next(aiIter);
- }
- tcKeyLength += dataPos;
-
- Uint32 attributesLength = indexOp->attrInfo.getSize();
- if (attributesLength <= attrBufSize) {
- jam();
- // ATTRINFO fits in TCKEYREQ
- // Pack ATTRINFO IN TCKEYREQ
- TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, indexOp->attrInfo.getSize());
- // Insert IndxAttrInfo
- for(bool moreAttrData = indexOp->attrInfo.first(attrIter);
- moreAttrData;
- moreAttrData = indexOp->attrInfo.next(attrIter)) {
- *dataPtr++ = *attrIter.data;
- }
- tcKeyLength += attributesLength;
- } else {
- jam();
- // No ATTRINFO in TCKEYREQ
- TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 0);
- }
-
- TcKeyReq::setCommitFlag(tcKeyRequestInfo, 0);
- TcKeyReq::setExecuteFlag(tcKeyRequestInfo, 0);
- TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0);
- tcKeyReq->requestInfo = tcKeyRequestInfo;
-
- ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0);
- ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0);
-
- /**
- * Decrease lqhkeyreqrec to compensate for addition
- * during read of index table
- * I.e. let TC start committing when other operations has completed
- */
- regApiPtr->lqhkeyreqrec--;
-
- /**
- * Fix savepoint id -
- * fix so that index operation has the same savepoint id
- * as the read of the index table (TCINDXREQ)
- */
- TcConnectRecordPtr tmp;
- tmp.i = indexOp->indexReadTcConnect;
- ptrCheckGuard(tmp, ctcConnectFilesize, tcConnectRecord);
- const Uint32 currSavePointId = regApiPtr->currSavePointId;
- regApiPtr->currSavePointId = tmp.p->savePointId;
- EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- regApiPtr->currSavePointId = currSavePointId;
-
- // *********** KEYINFO ***********
- if (moreKeyData) {
- jam();
- // Send KEYINFO sequence
- KeyInfo * const keyInfo = (KeyInfo *)signal->getDataPtrSend();
-
- keyInfo->connectPtr = indexOp->tcIndxReq.apiConnectPtr;
- keyInfo->transId[0] = regApiPtr->transid[0];
- keyInfo->transId[1] = regApiPtr->transid[1];
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- // Pack any part of a key attribute that did no fit TCKEYREQ
- while(keySize-- != 0) {// If we have not read complete key
- *dataPtr++ = *aiIter.data;
- dataPos++;
- if (dataPos == KeyInfo::DataLength) {
- // Flush KEYINFO
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPos = 0;
- dataPtr = (Uint32 *) &keyInfo->keyData;
- }
- moreKeyData = indexOp->transIdAI.next(aiIter);
- }
- if (dataPos != 0) {
- // Flush last KEYINFO
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
- }
- }
-
- // *********** ATTRINFO ***********
- if (attributesLength > attrBufSize) {
- jam();
- // No ATTRINFO in TcKeyReq
- TcKeyReq::setAIInTcKeyReq(tcKeyReq->requestInfo, 0);
- // Send ATTRINFO sequence
- AttrInfo * const attrInfo = (AttrInfo *)signal->getDataPtrSend();
- Uint32 attrInfoPos = 0;
-
- attrInfo->connectPtr = indexOp->tcIndxReq.apiConnectPtr;
- attrInfo->transId[0] = regApiPtr->transid[0];
- attrInfo->transId[1] = regApiPtr->transid[1];
- dataPtr = (Uint32 *) &attrInfo->attrData;
-
-
- // Insert attribute values (insert key values of primary table)
- for(bool moreAttrData = indexOp->attrInfo.first(attrIter);
- moreAttrData;
- moreAttrData = indexOp->attrInfo.next(attrIter)) {
- *dataPtr++ = *attrIter.data;
- attrInfoPos++;
- if (attrInfoPos == AttrInfo::DataLength) {
- // Flush ATTRINFO
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- attrInfoPos = 0;
- dataPtr = (Uint32 *) &attrInfo->attrData;
- }
- }
- if (attrInfoPos != 0) {
- // Send last ATTRINFO
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + attrInfoPos);
- jamEntry();
- }
- }
-}
-
-bool Dbtc::seizeIndexOperation(ApiConnectRecord* regApiPtr,
- TcIndexOperationPtr& indexOpPtr)
-{
- if (regApiPtr->theSeizedIndexOperations.seize(indexOpPtr))
- {
- ndbassert(indexOpPtr.p->expectedKeyInfo == 0);
- ndbassert(indexOpPtr.p->keyInfo.getSize() == 0);
- ndbassert(indexOpPtr.p->expectedAttrInfo == 0);
- ndbassert(indexOpPtr.p->attrInfo.getSize() == 0);
- ndbassert(indexOpPtr.p->expectedTransIdAI == 0);
- ndbassert(indexOpPtr.p->transIdAI.getSize() == 0);
- return true;
- }
-
- return false;
-}
-
-void Dbtc::releaseIndexOperation(ApiConnectRecord* regApiPtr,
- TcIndexOperation* indexOp)
-{
- indexOp->indexOpState = IOS_NOOP;
- indexOp->expectedKeyInfo = 0;
- indexOp->keyInfo.release();
- indexOp->expectedAttrInfo = 0;
- indexOp->attrInfo.release();
- indexOp->expectedTransIdAI = 0;
- indexOp->transIdAI.release();
- regApiPtr->theSeizedIndexOperations.release(indexOp->indexOpId);
-}
-
-void Dbtc::releaseAllSeizedIndexOperations(ApiConnectRecord* regApiPtr)
-{
- TcIndexOperationPtr seizedIndexOpPtr;
-
- regApiPtr->theSeizedIndexOperations.first(seizedIndexOpPtr);
- while(seizedIndexOpPtr.i != RNIL) {
- jam();
- TcIndexOperation* indexOp = seizedIndexOpPtr.p;
-
- indexOp->indexOpState = IOS_NOOP;
- indexOp->expectedKeyInfo = 0;
- indexOp->keyInfo.release();
- indexOp->expectedAttrInfo = 0;
- indexOp->attrInfo.release();
- indexOp->expectedTransIdAI = 0;
- indexOp->transIdAI.release();
- regApiPtr->theSeizedIndexOperations.next(seizedIndexOpPtr);
- }
- regApiPtr->theSeizedIndexOperations.release();
-}
-
-void Dbtc::saveTriggeringOpState(Signal* signal, TcConnectRecord* trigOp)
-{
- LqhKeyConf * lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
- copyFromToLen((UintR*)lqhKeyConf,
- &trigOp->savedState[0],
- LqhKeyConf::SignalLength);
-}
-
-void Dbtc::continueTriggeringOp(Signal* signal, TcConnectRecord* trigOp)
-{
- LqhKeyConf * lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
- copyFromToLen(&trigOp->savedState[0],
- (UintR*)lqhKeyConf,
- LqhKeyConf::SignalLength);
-
- lqhKeyConf->noFiredTriggers = 0;
- trigOp->noReceivedTriggers = 0;
-
- // All triggers executed successfully, continue operation
- execLQHKEYCONF(signal);
-}
-
-void Dbtc::scheduleFiredTrigger(ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr)
-{
- // Set initial values for trigger fireing operation
- opPtr->p->triggerExecutionCount++;
-
- // Insert fired trigger in execution queue
- transPtr->p->theFiredTriggers.add(opPtr->p->accumulatingTriggerData);
- opPtr->p->accumulatingTriggerData.i = RNIL;
- opPtr->p->accumulatingTriggerData.p = NULL;
-}
-
-void Dbtc::executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr)
-{
- ApiConnectRecord* regApiPtr = transPtr->p;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- TcConnectRecordPtr opPtr;
- FiredTriggerPtr trigPtr;
-
- if (!regApiPtr->theFiredTriggers.isEmpty()) {
- jam();
- if ((regApiPtr->apiConnectstate == CS_STARTED) ||
- (regApiPtr->apiConnectstate == CS_START_COMMITTING)) {
- jam();
- regApiPtr->theFiredTriggers.first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- // Execute all ready triggers in parallel
- opPtr.i = trigPtr.p->fireingOperation;
- ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
- FiredTriggerPtr nextTrigPtr = trigPtr;
- regApiPtr->theFiredTriggers.next(nextTrigPtr);
- if (opPtr.p->noReceivedTriggers == opPtr.p->noFiredTriggers) {
- jam();
- // Fireing operation is ready to have a trigger executing
- executeTrigger(signal, trigPtr.p, transPtr, &opPtr);
- // Should allow for interleaving here by sending a CONTINUEB and
- // return
- // Release trigger records
- AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool;
- LocalDataBuffer<11> tmp1(pool, trigPtr.p->keyValues);
- tmp1.release();
- LocalDataBuffer<11> tmp2(pool, trigPtr.p->beforeValues);
- tmp2.release();
- LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
- tmp3.release();
- regApiPtr->theFiredTriggers.release(trigPtr);
- }
- trigPtr = nextTrigPtr;
- }
- return;
- // No more triggers, continue transaction after last executed trigger has
- // reurned (in execLQHKEYCONF or execLQHKEYREF)
- } else {
- // Wait until transaction is ready to execute a trigger
- jam();
- if (!regApiPtr->triggerPending) {
- jam();
- regApiPtr->triggerPending = true;
- signal->theData[0] = TcContinueB::TRIGGER_PENDING;
- signal->theData[1] = transPtr->i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
- // else
- // We are already waiting for a pending trigger (CONTINUEB)
- }
- }
-}
-
-void Dbtc::executeTrigger(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr)
-{
- TcDefinedTriggerData* definedTriggerData;
-
- if ((definedTriggerData =
- c_theDefinedTriggers.getPtr(firedTriggerData->triggerId))
- != NULL) {
- switch(definedTriggerData->triggerType) {
- case(TriggerType::SECONDARY_INDEX):
- jam();
- executeIndexTrigger(signal, definedTriggerData, firedTriggerData,
- transPtr, opPtr);
- break;
- default:
- ndbrequire(false);
- }
- }
-}
-
-void Dbtc::executeIndexTrigger(Signal* signal,
- TcDefinedTriggerData* definedTriggerData,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr)
-{
- TcIndexData* indexData;
-
- indexData = c_theIndexes.getPtr(definedTriggerData->indexId);
- ndbassert(indexData != NULL);
-
- switch (definedTriggerData->triggerEvent) {
- case(TriggerEvent::TE_INSERT): {
- jam();
- insertIntoIndexTable(signal, firedTriggerData, transPtr, opPtr, indexData);
- break;
- }
- case(TriggerEvent::TE_DELETE): {
- jam();
- deleteFromIndexTable(signal, firedTriggerData, transPtr, opPtr, indexData);
- break;
- }
- case(TriggerEvent::TE_UPDATE): {
- jam();
- deleteFromIndexTable(signal, firedTriggerData, transPtr, opPtr,
- indexData, true); // Hold the triggering operation
- insertIntoIndexTable(signal, firedTriggerData, transPtr, opPtr, indexData);
- break;
- }
- default:
- ndbrequire(false);
- }
-}
-
-void Dbtc::releaseFiredTriggerData(DLFifoList<TcFiredTriggerData>* triggers)
-{
- FiredTriggerPtr trigPtr;
-
- triggers->first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- // Release trigger records
-
- AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool;
- LocalDataBuffer<11> tmp1(pool, trigPtr.p->keyValues);
- tmp1.release();
- LocalDataBuffer<11> tmp2(pool, trigPtr.p->beforeValues);
- tmp2.release();
- LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
- tmp3.release();
-
- triggers->next(trigPtr);
- }
- triggers->release();
-}
-
-void Dbtc::insertIntoIndexTable(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr,
- TcIndexData* indexData,
- bool holdOperation)
-{
- ApiConnectRecord* regApiPtr = transPtr->p;
- TcConnectRecord* opRecord = opPtr->p;
- TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
- Uint32 tcKeyRequestInfo = 0;
- Uint32 tcKeyLength = TcKeyReq::StaticLength;
- TableRecordPtr indexTabPtr;
- AttributeBuffer::DataBufferIterator iter;
- Uint32 attrId = 0;
- Uint32 keyLength = 0;
- Uint32 totalPrimaryKeyLength = 1; // fragment length
- Uint32 hops;
-
- indexTabPtr.i = indexData->indexId;
- ptrCheckGuard(indexTabPtr, ctabrecFilesize, tableRecord);
- tcKeyReq->apiConnectPtr = transPtr->i;
- tcKeyReq->senderData = opPtr->i;
- if (holdOperation) {
- jam();
- opRecord->triggerExecutionCount++;
- }//if
- // Calculate key length and renumber attribute id:s
- AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool;
- LocalDataBuffer<11> afterValues(pool, firedTriggerData->afterValues);
- bool skipNull = false;
- for(bool moreKeyAttrs = afterValues.first(iter); moreKeyAttrs; attrId++) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- // Filter out NULL valued attributes
- if (attrHeader->isNULL()) {
- skipNull = true;
- break;
- }
- attrHeader->setAttributeId(attrId);
- keyLength += attrHeader->getDataSize();
- hops = attrHeader->getHeaderSize() + attrHeader->getDataSize();
- moreKeyAttrs = afterValues.next(iter, hops);
- }
- if (skipNull) {
- jam();
- opRecord->triggerExecutionCount--;
- if (opRecord->triggerExecutionCount == 0) {
- /*
- We have completed current trigger execution
- Continue triggering operation
- */
- jam();
- continueTriggeringOp(signal, opRecord);
- }//if
- return;
- }//if
-
- // Calculate total length of primary key to be stored in index table
- LocalDataBuffer<11> keyValues(pool, firedTriggerData->keyValues);
- for(bool moreAttrData = keyValues.first(iter); moreAttrData; ) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- totalPrimaryKeyLength += attrHeader->getDataSize();
- hops = attrHeader->getHeaderSize() + attrHeader->getDataSize();
- moreAttrData = keyValues.next(iter, hops);
- }
- AttributeHeader pkAttrHeader(attrId, totalPrimaryKeyLength << 2);
- Uint32 attributesLength = afterValues.getSize() +
- pkAttrHeader.getHeaderSize() + pkAttrHeader.getDataSize();
-
- TcKeyReq::setKeyLength(tcKeyRequestInfo, keyLength);
- tcKeyReq->attrLen = attributesLength;
- tcKeyReq->tableId = indexData->indexId;
- TcKeyReq::setOperationType(tcKeyRequestInfo, ZINSERT);
- TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, true);
- tcKeyReq->tableSchemaVersion = indexTabPtr.p->currentSchemaVersion;
- tcKeyReq->transId1 = regApiPtr->transid[0];
- tcKeyReq->transId2 = regApiPtr->transid[1];
- Uint32 * dataPtr = &tcKeyReq->scanInfo;
- // Write first part of key in TCKEYREQ
- Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
- Uint32 attrBufSize = 5; // Maximum for key in TCKEYREQ
- Uint32 dataPos = 0;
- // Filter out AttributeHeader:s since this should no be in key
- bool moreKeyData = afterValues.first(iter);
- Uint32 headerSize = 0, keyAttrSize = 0, dataSize = 0, headAndData = 0;
-
- while (moreKeyData && (dataPos < keyBufSize)) {
- /*
- * If we have not read complete key
- * and it fits in the signal
- */
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- keyAttrSize = attrHeader->getDataSize();
- headAndData = headerSize + attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreKeyData = afterValues.next(iter);
- } else {
- jam();
- moreKeyData = afterValues.next(iter, headerSize - 1);
- }//if
- while((keyAttrSize != 0) && (dataPos < keyBufSize)) {
- // If we have not read complete key
- jam();
- *dataPtr++ = *iter.data;
- dataPos++;
- keyAttrSize--;
- moreKeyData = afterValues.next(iter);
- }
- if (keyAttrSize != 0) {
- jam();
- break;
- }//if
- }
-
- tcKeyLength += dataPos;
- /*
- Size of attrinfo is unique index attributes one by one, header for each
- of them (all contained in the afterValues data structure), plus a header,
- the primary key (compacted) and the fragment id before the primary key
- */
- if (attributesLength <= attrBufSize) {
- jam();
- // ATTRINFO fits in TCKEYREQ
- // Pack ATTRINFO IN TCKEYREQ as one attribute
- TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, attributesLength);
- bool moreAttrData;
- // Insert primary key attributes (insert after values of primary table)
- for(moreAttrData = afterValues.first(iter);
- moreAttrData;
- moreAttrData = afterValues.next(iter)) {
- *dataPtr++ = *iter.data;
- }
- // Insert attribute values (insert key values of primary table)
- // as one attribute
- pkAttrHeader.insertHeader(dataPtr);
- dataPtr += pkAttrHeader.getHeaderSize();
- /*
- Insert fragment id before primary key as part of reference to tuple
- */
- *dataPtr++ = firedTriggerData->fragId;
- moreAttrData = keyValues.first(iter);
- while(moreAttrData) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- dataSize = attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreAttrData = keyValues.next(iter);
- } else {
- jam();
- moreAttrData = keyValues.next(iter, headerSize - 1);
- }//if
- // Copy attribute data
- while(dataSize-- != 0) {
- *dataPtr++ = *iter.data;
- moreAttrData = keyValues.next(iter);
- }
- }
- tcKeyLength += attributesLength;
- } else {
- jam();
- // No ATTRINFO in TCKEYREQ
- TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 0);
- }
- tcKeyReq->requestInfo = tcKeyRequestInfo;
-
- /**
- * Fix savepoint id -
- * fix so that insert has same savepoint id as triggering operation
- */
- const Uint32 currSavePointId = regApiPtr->currSavePointId;
- regApiPtr->currSavePointId = opRecord->savePointId;
- EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- regApiPtr->currSavePointId = currSavePointId;
- tcConnectptr.p->currentIndexId = indexData->indexId;
-
- // *********** KEYINFO ***********
- if (moreKeyData) {
- jam();
- // Send KEYINFO sequence
- KeyInfo * const keyInfo = (KeyInfo *)signal->getDataPtrSend();
-
- keyInfo->connectPtr = transPtr->i;
- keyInfo->transId[0] = regApiPtr->transid[0];
- keyInfo->transId[1] = regApiPtr->transid[1];
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- // Pack any part of a key attribute that did no fit TCKEYREQ
- while((keyAttrSize != 0) && (dataPos < KeyInfo::DataLength)) {
- // If we have not read complete key
- *dataPtr++ = *iter.data;
- dataPos++;
- keyAttrSize--;
- if (dataPos == KeyInfo::DataLength) {
- jam();
- // Flush KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- }
- moreKeyData = afterValues.next(iter);
- }
-
- while(moreKeyData) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- keyAttrSize = attrHeader->getDataSize();
- headAndData = headerSize + attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreKeyData = afterValues.next(iter);
- } else {
- jam();
- moreKeyData = afterValues.next(iter, headerSize - 1);
- }//if
- while (keyAttrSize-- != 0) {
- *dataPtr++ = *iter.data;
- dataPos++;
- if (dataPos == KeyInfo::DataLength) {
- jam();
- // Flush KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
-#endif
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- }
- moreKeyData = afterValues.next(iter);
- }
- }
- if (dataPos != 0) {
- jam();
- // Flush last KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
- }
- }
-
- // *********** ATTRINFO ***********
- if (attributesLength > attrBufSize) {
- jam();
- // No ATTRINFO in TcKeyReq
- TcKeyReq::setAIInTcKeyReq(tcKeyReq->requestInfo, 0);
- // Send ATTRINFO sequence
- AttrInfo * const attrInfo = (AttrInfo *)signal->getDataPtrSend();
- Uint32 attrInfoPos = 0;
-
- attrInfo->connectPtr = transPtr->i;
- attrInfo->transId[0] = regApiPtr->transid[0];
- attrInfo->transId[1] = regApiPtr->transid[1];
- dataPtr = (Uint32 *) &attrInfo->attrData;
-
- bool moreAttrData;
- // Insert primary key attributes (insert after values of primary table)
- for(moreAttrData = afterValues.first(iter);
- moreAttrData;
- moreAttrData = afterValues.next(iter)) {
- *dataPtr++ = *iter.data;
- attrInfoPos++;
- if (attrInfoPos == AttrInfo::DataLength) {
- jam();
- // Flush ATTRINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &attrInfo->attrData;
- attrInfoPos = 0;
- }
- }
- // Insert attribute values (insert key values of primary table)
- // as one attribute
- pkAttrHeader.insertHeader(dataPtr);
- dataPtr += pkAttrHeader.getHeaderSize();
- attrInfoPos += pkAttrHeader.getHeaderSize();
- /*
- Add fragment id before primary key
- TODO: This code really needs to be made into a long signal
- to remove this messy code.
- */
- if (attrInfoPos == AttrInfo::DataLength)
- {
- jam();
- // Flush ATTRINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength);
- jamEntry();
-#endif
- dataPtr = (Uint32 *) &attrInfo->attrData;
- attrInfoPos = 0;
- }
- attrInfoPos++;
- *dataPtr++ = firedTriggerData->fragId;
-
- moreAttrData = keyValues.first(iter);
- while(moreAttrData) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- dataSize = attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreAttrData = keyValues.next(iter);
- } else {
- jam();
- moreAttrData = keyValues.next(iter, headerSize - 1);
- }//if
- while(dataSize-- != 0) { // If we have not read complete key
- if (attrInfoPos == AttrInfo::DataLength) {
- jam();
- // Flush ATTRINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + AttrInfo::DataLength);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &attrInfo->attrData;
- attrInfoPos = 0;
- }
- *dataPtr++ = *iter.data;
- attrInfoPos++;
- moreAttrData = keyValues.next(iter);
- }
- }
- if (attrInfoPos != 0) {
- jam();
- // Flush last ATTRINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + attrInfoPos, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + attrInfoPos);
- jamEntry();
-#endif
- }
- }
-}
-
-void Dbtc::deleteFromIndexTable(Signal* signal,
- TcFiredTriggerData* firedTriggerData,
- ApiConnectRecordPtr* transPtr,
- TcConnectRecordPtr* opPtr,
- TcIndexData* indexData,
- bool holdOperation)
-{
- ApiConnectRecord* regApiPtr = transPtr->p;
- TcConnectRecord* opRecord = opPtr->p;
- TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
- Uint32 tcKeyRequestInfo = 0;
- Uint32 tcKeyLength = 12; // Static length
- TableRecordPtr indexTabPtr;
- AttributeBuffer::DataBufferIterator iter;
- Uint32 attrId = 0;
- Uint32 keyLength = 0;
- Uint32 hops;
-
- indexTabPtr.i = indexData->indexId;
- ptrCheckGuard(indexTabPtr, ctabrecFilesize, tableRecord);
- tcKeyReq->apiConnectPtr = transPtr->i;
- tcKeyReq->senderData = opPtr->i;
- if (holdOperation) {
- jam();
- opRecord->triggerExecutionCount++;
- }//if
- // Calculate key length and renumber attribute id:s
- AttributeBuffer::DataBufferPool & pool = c_theAttributeBufferPool;
- LocalDataBuffer<11> beforeValues(pool, firedTriggerData->beforeValues);
- bool skipNull = false;
- for(bool moreKeyAttrs = beforeValues.first(iter);
- (moreKeyAttrs);
- attrId++) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- // Filter out NULL valued attributes
- if (attrHeader->isNULL()) {
- skipNull = true;
- break;
- }
- attrHeader->setAttributeId(attrId);
- keyLength += attrHeader->getDataSize();
- hops = attrHeader->getHeaderSize() + attrHeader->getDataSize();
- moreKeyAttrs = beforeValues.next(iter, hops);
- }
-
- if (skipNull) {
- jam();
- opRecord->triggerExecutionCount--;
- if (opRecord->triggerExecutionCount == 0) {
- /*
- We have completed current trigger execution
- Continue triggering operation
- */
- jam();
- continueTriggeringOp(signal, opRecord);
- }//if
- return;
- }//if
-
- TcKeyReq::setKeyLength(tcKeyRequestInfo, keyLength);
- tcKeyReq->attrLen = 0;
- tcKeyReq->tableId = indexData->indexId;
- TcKeyReq::setOperationType(tcKeyRequestInfo, ZDELETE);
- TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, true);
- tcKeyReq->tableSchemaVersion = indexTabPtr.p->currentSchemaVersion;
- tcKeyReq->transId1 = regApiPtr->transid[0];
- tcKeyReq->transId2 = regApiPtr->transid[1];
- Uint32 * dataPtr = &tcKeyReq->scanInfo;
- // Write first part of key in TCKEYREQ
- Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
- Uint32 dataPos = 0;
- // Filter out AttributeHeader:s since this should no be in key
- bool moreKeyData = beforeValues.first(iter);
- Uint32 headerSize = 0, keyAttrSize = 0, headAndData = 0;
-
- while (moreKeyData &&
- (dataPos < keyBufSize)) {
- /*
- If we have not read complete key
- and it fits in the signal
- */
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- keyAttrSize = attrHeader->getDataSize();
- headAndData = headerSize + attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreKeyData = beforeValues.next(iter);
- } else {
- jam();
- moreKeyData = beforeValues.next(iter, headerSize - 1);
- }//if
- while((keyAttrSize != 0) &&
- (dataPos < keyBufSize)) {
- // If we have not read complete key
- jam();
- *dataPtr++ = *iter.data;
- dataPos++;
- keyAttrSize--;
- moreKeyData = beforeValues.next(iter);
- }
- if (keyAttrSize != 0) {
- jam();
- break;
- }//if
- }
-
- tcKeyLength += dataPos;
- tcKeyReq->requestInfo = tcKeyRequestInfo;
-
- /**
- * Fix savepoint id -
- * fix so that delete has same savepoint id as triggering operation
- */
- const Uint32 currSavePointId = regApiPtr->currSavePointId;
- regApiPtr->currSavePointId = opRecord->savePointId;
- EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
- jamEntry();
-
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- regApiPtr->currSavePointId = currSavePointId;
- tcConnectptr.p->currentIndexId = indexData->indexId;
-
- // *********** KEYINFO ***********
- if (moreKeyData) {
- jam();
- // Send KEYINFO sequence
- KeyInfo * const keyInfo = (KeyInfo *)signal->getDataPtrSend();
-
- keyInfo->connectPtr = transPtr->i;
- keyInfo->transId[0] = regApiPtr->transid[0];
- keyInfo->transId[1] = regApiPtr->transid[1];
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- // Pack any part of a key attribute that did no fit TCKEYREQ
- while((keyAttrSize != 0) &&
- (dataPos < KeyInfo::DataLength)) {
- // If we have not read complete key
- *dataPtr++ = *iter.data;
- dataPos++;
- keyAttrSize--;
- if (dataPos == KeyInfo::DataLength) {
- jam();
- // Flush KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- }
- moreKeyData = beforeValues.next(iter);
- }
-
- while(moreKeyData) {
- jam();
- AttributeHeader* attrHeader = (AttributeHeader *) iter.data;
-
- headerSize = attrHeader->getHeaderSize();
- keyAttrSize = attrHeader->getDataSize();
- headAndData = headerSize + attrHeader->getDataSize();
- // Skip header
- if (headerSize == 1) {
- jam();
- moreKeyData = beforeValues.next(iter);
- } else {
- jam();
- moreKeyData = beforeValues.next(iter,
- headerSize - 1);
- }//if
- while (keyAttrSize-- != 0) {
- *dataPtr++ = *iter.data;
- dataPos++;
- if (dataPos == KeyInfo::DataLength) {
- jam();
- // Flush KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + KeyInfo::DataLength);
- jamEntry();
-#endif
- if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
- {
- jam();
- return;
- }
-
- dataPtr = (Uint32 *) &keyInfo->keyData;
- dataPos = 0;
- }
- moreKeyData = beforeValues.next(iter);
- }
- }
- if (dataPos != 0) {
- jam();
- // Flush last KEYINFO
-#if INTERNAL_TRIGGER_TCKEYREQ_JBA
- sendSignal(reference(), GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos, JBA);
-#else
- EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + dataPos);
- jamEntry();
-#endif
- }
- }
-}
-
-Uint32
-Dbtc::TableRecord::getErrorCode(Uint32 schemaVersion) const {
- if(!get_enabled())
- return ZNO_SUCH_TABLE;
- if(get_dropping())
- return ZDROP_TABLE_IN_PROGRESS;
- if(table_version_major(schemaVersion) != table_version_major(currentSchemaVersion))
- return ZWRONG_SCHEMA_VERSION_ERROR;
- ErrorReporter::handleAssert("Dbtc::TableRecord::getErrorCode",
- __FILE__, __LINE__);
- return 0;
-}
-
-void
-Dbtc::execROUTE_ORD(Signal* signal)
-{
- jamEntry();
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- RouteOrd* ord = (RouteOrd*)signal->getDataPtr();
- Uint32 dstRef = ord->dstRef;
- Uint32 srcRef = ord->srcRef;
- Uint32 gsn = ord->gsn;
-
- if (likely(getNodeInfo(refToNode(dstRef)).m_connected))
- {
- jam();
- Uint32 secCount = signal->getNoOfSections();
- SegmentedSectionPtr ptr[3];
- ndbrequire(secCount >= 1 && secCount <= 3);
-
- jamLine(secCount);
- for (Uint32 i = 0; i<secCount; i++)
- signal->getSection(ptr[i], i);
-
- /**
- * Put section 0 in signal->theData
- */
- ndbrequire(ptr[0].sz <= 25);
- copy(signal->theData, ptr[0]);
-
- signal->header.m_noOfSections = 0;
-
- /**
- * Shift rest of sections
- */
- for(Uint32 i = 1; i<secCount; i++)
- {
- signal->setSection(ptr[i], i - 1);
- }
-
- sendSignal(dstRef, gsn, signal, ptr[0].sz, JBB);
-
- signal->header.m_noOfSections = 0;
- signal->setSection(ptr[0], 0);
- releaseSections(signal);
- return ;
- }
-
- warningEvent("Unable to route GSN: %d from %x to %x",
- gsn, srcRef, dstRef);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp b/storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp
deleted file mode 100644
index 12be23851c8..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ATTRIBUTE_OFFSET_HPP
-#define ATTRIBUTE_OFFSET_HPP
-
-class AttributeOffset {
- friend class Dbtup;
-
-private:
- static void setOffset(Uint32 & desc, Uint32 offset);
- static void setCharsetPos(Uint32 & desc, Uint32 offset);
- static void setNullFlagPos(Uint32 & desc, Uint32 offset);
-
- static Uint32 getOffset(const Uint32 &);
- static bool getCharsetFlag(const Uint32 &);
- static Uint32 getCharsetPos(const Uint32 &);
- static Uint32 getNullFlagPos(const Uint32 &);
- static Uint32 getNullFlagOffset(const Uint32 &);
- static Uint32 getNullFlagBitOffset(const Uint32 &);
-
- Uint32 m_data;
-
- friend class NdbOut& operator<<(class NdbOut&, const AttributeOffset&);
-};
-
-/**
- * Allow for 4096 attributes, all nullable, and for 128 different
- * character sets.
- *
- * a = Attribute offset - 11 bits 0-10 ( addr word in 8 kb )
- * c = Has charset flag 1 bits 11-11
- * s = Charset pointer position - 7 bits 12-18 ( in table descriptor )
- * f = Null flag offset in word - 5 bits 20-24 ( address 32 bits )
- * w = Null word offset - 7 bits 25-32 ( f+w addr 4096 attrs )
- *
- * 1111111111222222222233
- * 01234567890123456789012345678901
- * aaaaaaaaaaacsssssss fffffwwwwwww
- */
-
-#define AO_ATTRIBUTE_OFFSET_SHIFT 0
-#define AO_ATTRIBUTE_OFFSET_MASK 0x7ff
-
-#define AO_CHARSET_FLAG_SHIFT 11
-#define AO_CHARSET_POS_SHIFT 12
-#define AO_CHARSET_POS_MASK 127
-
-#define AO_NULL_FLAG_POS_MASK 0xfff // f+w
-#define AO_NULL_FLAG_POS_SHIFT 20
-
-#define AO_NULL_FLAG_WORD_MASK 31 // f
-#define AO_NULL_FLAG_OFFSET_SHIFT 5
-
-inline
-void
-AttributeOffset::setOffset(Uint32 & desc, Uint32 offset){
- ASSERT_MAX(offset, AO_ATTRIBUTE_OFFSET_MASK, "AttributeOffset::setOffset");
- desc &= ~(Uint32)(AO_ATTRIBUTE_OFFSET_MASK << AO_ATTRIBUTE_OFFSET_SHIFT);
- desc |= (offset << AO_ATTRIBUTE_OFFSET_SHIFT);
-}
-
-inline
-void
-AttributeOffset::setCharsetPos(Uint32 & desc, Uint32 offset) {
- ASSERT_MAX(offset, AO_CHARSET_POS_MASK, "AttributeOffset::setCharsetPos");
- desc |= (1 << AO_CHARSET_FLAG_SHIFT);
- desc |= (offset << AO_CHARSET_POS_SHIFT);
-}
-
-inline
-void
-AttributeOffset::setNullFlagPos(Uint32 & desc, Uint32 pos){
- ASSERT_MAX(pos, AO_NULL_FLAG_POS_MASK, "AttributeOffset::setNullFlagPos");
- desc |= (pos << AO_NULL_FLAG_POS_SHIFT);
-}
-
-inline
-Uint32
-AttributeOffset::getOffset(const Uint32 & desc)
-{
- return (desc >> AO_ATTRIBUTE_OFFSET_SHIFT) & AO_ATTRIBUTE_OFFSET_MASK;
-}
-
-inline
-bool
-AttributeOffset::getCharsetFlag(const Uint32 & desc)
-{
- return (desc >> AO_CHARSET_FLAG_SHIFT) & 1;
-}
-
-inline
-Uint32
-AttributeOffset::getCharsetPos(const Uint32 & desc)
-{
- return (desc >> AO_CHARSET_POS_SHIFT) & AO_CHARSET_POS_MASK;
-}
-
-inline
-Uint32
-AttributeOffset::getNullFlagPos(const Uint32 & desc)
-{
- return ((desc >> AO_NULL_FLAG_POS_SHIFT) & AO_NULL_FLAG_POS_MASK);
-}
-
-inline
-Uint32
-AttributeOffset::getNullFlagOffset(const Uint32 & desc)
-{
- return (getNullFlagPos(desc) >> AO_NULL_FLAG_OFFSET_SHIFT);
-}
-
-inline
-Uint32
-AttributeOffset::getNullFlagBitOffset(const Uint32 & desc)
-{
- return (getNullFlagPos(desc) & AO_NULL_FLAG_WORD_MASK);
-}
-
-class NdbOut&
-operator<<(class NdbOut&, const AttributeOffset&);
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
deleted file mode 100644
index a963fe9b708..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ /dev/null
@@ -1,3070 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBTUP_H
-#define DBTUP_H
-
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include <ndb_limits.h>
-#include <trigger_definitions.h>
-#include <AttributeHeader.hpp>
-#include <Bitmask.hpp>
-#include <signaldata/TupKey.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/TrigAttrInfo.hpp>
-#include <signaldata/BuildIndx.hpp>
-#include "Undo_buffer.hpp"
-#include "tuppage.hpp"
-#include <../pgman.hpp>
-#include <../tsman.hpp>
-
-// jams
-#undef jam
-#undef jamEntry
-#ifdef DBTUP_BUFFER_CPP
-#define jam() jamLine(10000 + __LINE__)
-#define jamEntry() jamEntryLine(10000 + __LINE__)
-#endif
-#ifdef DBTUP_ROUTINES_CPP
-#define jam() jamLine(15000 + __LINE__)
-#define jamEntry() jamEntryLine(15000 + __LINE__)
-#endif
-#ifdef DBTUP_COMMIT_CPP
-#define jam() jamLine(20000 + __LINE__)
-#define jamEntry() jamEntryLine(20000 + __LINE__)
-#endif
-#ifdef DBTUP_FIXALLOC_CPP
-#define jam() jamLine(25000 + __LINE__)
-#define jamEntry() jamEntryLine(25000 + __LINE__)
-#endif
-#ifdef DBTUP_TRIGGER_CPP
-#define jam() jamLine(30000 + __LINE__)
-#define jamEntry() jamEntryLine(30000 + __LINE__)
-#endif
-#ifdef DBTUP_ABORT_CPP
-#define jam() jamLine(35000 + __LINE__)
-#define jamEntry() jamEntryLine(35000 + __LINE__)
-#endif
-#ifdef DBTUP_PAGE_MAP_CPP
-#define jam() jamLine(40000 + __LINE__)
-#define jamEntry() jamEntryLine(40000 + __LINE__)
-#endif
-#ifdef DBTUP_PAG_MAN_CPP
-#define jam() jamLine(45000 + __LINE__)
-#define jamEntry() jamEntryLine(45000 + __LINE__)
-#endif
-#ifdef DBTUP_STORE_PROC_DEF_CPP
-#define jam() jamLine(50000 + __LINE__)
-#define jamEntry() jamEntryLine(50000 + __LINE__)
-#endif
-#ifdef DBTUP_META_CPP
-#define jam() jamLine(55000 + __LINE__)
-#define jamEntry() jamEntryLine(55000 + __LINE__)
-#endif
-#ifdef DBTUP_TAB_DES_MAN_CPP
-#define jam() jamLine(60000 + __LINE__)
-#define jamEntry() jamEntryLine(60000 + __LINE__)
-#endif
-#ifdef DBTUP_GEN_CPP
-#define jam() jamLine(65000 + __LINE__)
-#define jamEntry() jamEntryLine(65000 + __LINE__)
-#endif
-#ifdef DBTUP_INDEX_CPP
-#define jam() jamLine(70000 + __LINE__)
-#define jamEntry() jamEntryLine(70000 + __LINE__)
-#endif
-#ifdef DBTUP_DEBUG_CPP
-#define jam() jamLine(75000 + __LINE__)
-#define jamEntry() jamEntryLine(75000 + __LINE__)
-#endif
-#ifdef DBTUP_VAR_ALLOC_CPP
-#define jam() jamLine(80000 + __LINE__)
-#define jamEntry() jamEntryLine(80000 + __LINE__)
-#endif
-#ifdef DBTUP_SCAN_CPP
-#define jam() jamLine(85000 + __LINE__)
-#define jamEntry() jamEntryLine(85000 + __LINE__)
-#endif
-#ifdef DBTUP_DISK_ALLOC_CPP
-#define jam() jamLine(90000 + __LINE__)
-#define jamEntry() jamEntryLine(90000 + __LINE__)
-#endif
-#ifndef jam
-#define jam() jamLine(__LINE__)
-#define jamEntry() jamEntryLine(__LINE__)
-#endif
-
-#ifdef VM_TRACE
-inline const char* dbgmask(const Bitmask<MAXNROFATTRIBUTESINWORDS>& bm) {
- static int i=0; static char buf[5][200];
- bm.getText(buf[i%5]); return buf[i++%5]; }
-inline const char* dbgmask(const Uint32 bm[2]) {
- static int i=0; static char buf[5][200];
- sprintf(buf[i%5],"%08x%08x",bm[1],bm[0]); return buf[i++%5]; }
-#endif
-
-#define ZWORDS_ON_PAGE 8192 /* NUMBER OF WORDS ON A PAGE. */
-#define ZATTRBUF_SIZE 32 /* SIZE OF ATTRIBUTE RECORD BUFFER */
-#define ZMIN_PAGE_LIMIT_TUPKEYREQ 5
-#define ZTUP_VERSION_BITS 15
-#define ZTUP_VERSION_MASK ((1 << ZTUP_VERSION_BITS) - 1)
-#define MAX_FREE_LIST 4
-
-inline Uint32* ALIGN_WORD(void * ptr)
-{
- return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
-}
-
-inline const Uint32* ALIGN_WORD(const void* ptr)
-{
- return (Uint32*)(((UintPtr(ptr) + 3) >> 2) << 2);
-}
-
-#ifdef DBTUP_C
-//------------------------------------------------------------------
-// Jam Handling:
-//
-// When DBTUP reports lines through jam in the trace files it has to
-// be interpreted. 4024 means as an example line 24 in DbtupCommit.cpp
-// Thus 4000 is added to the line number beacuse it is located in the
-// file DbtupCommit.cpp. The following is the exhaustive list of the
-// added value in the various files. ndbrequire, ptrCheckGuard still
-// only reports the line number in the file it currently is located in.
-//
-// DbtupExecQuery.cpp 0
-// DbtupBuffer.cpp 10000
-// DbtupRoutines.cpp 15000
-// DbtupCommit.cpp 20000
-// DbtupFixAlloc.cpp 25000
-// DbtupTrigger.cpp 30000
-// DbtupAbort.cpp 35000
-// DbtupPageMap.cpp 40000
-// DbtupPagMan.cpp 45000
-// DbtupStoredProcDef.cpp 50000
-// DbtupMeta.cpp 55000
-// DbtupTabDesMan.cpp 60000
-// DbtupGen.cpp 65000
-// DbtupIndex.cpp 70000
-// DbtupDebug.cpp 75000
-// DbtupVarAlloc.cpp 80000
-// DbtupScan.cpp 85000
-// DbtupDiskAlloc.cpp 90000
-//------------------------------------------------------------------
-
-/*
-2.2 LOCAL SYMBOLS
------------------
-*/
-/* ---------------------------------------------------------------- */
-/* S I Z E O F R E C O R D S */
-/* ---------------------------------------------------------------- */
-#define ZNO_OF_ATTRBUFREC 10000 /* SIZE OF ATTRIBUTE INFO FILE */
-#define ZNO_OF_CONCURRENT_OPEN_OP 40 /* NUMBER OF CONCURRENT OPENS */
-#define ZNO_OF_CONCURRENT_WRITE_OP 80 /* NUMBER OF CONCURRENT DISK WRITES*/
-#define ZNO_OF_FRAGOPREC 20 /* NUMBER OF CONCURRENT ADD FRAG. */
-#define TOT_PAGE_RECORD_SPACE 262144 /* SIZE OF PAGE RECORD FILE. */
-#define ZNO_OF_PAGE TOT_PAGE_RECORD_SPACE/ZWORDS_ON_PAGE
-#define ZNO_OF_PAGE_RANGE_REC 128 /* SIZE OF PAGE RANGE FILE */
-// Trigger constants
-#define ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE 16
-
-/* ---------------------------------------------------------------- */
-/* A ATTRIBUTE MAY BE NULL, DYNAMIC OR NORMAL. A NORMAL ATTRIBUTE */
-/* IS A ATTRIBUTE THAT IS NOT NULL OR DYNAMIC. A NULL ATTRIBUTE */
-/* MAY HAVE NO VALUE. A DYNAMIC ATTRIBUTE IS A NULL ATTRIBUTE THAT */
-/* DOES NOT HAVE TO BE A MEMBER OF EVERY TUPLE I A CERTAIN TABLE. */
-/* ---------------------------------------------------------------- */
-/**
- * #defines moved into include/kernel/Interpreter.hpp
- */
-#define ZINSERT_DELETE 0
-#define ZUPDATE_ALL 8
-/* ---------------------------------------------------------------- */
-/* THE MINIMUM SIZE OF AN 'EMPTY' TUPLE HEADER IN R-WORDS */
-/* ---------------------------------------------------------------- */
- /* THE TUPLE HEADER FIELD 'SIZE OF NULL ATTR. FIELD' SPECIFYES */
- /* THE SIZE OF THE TUPLE HEADER FIELD 'NULL ATTR. FIELD'. */
- /* THE TUPLE HEADER FIELD 'TYPE' SPECIFYES THE TYPE OF THE TUPLE */
- /* HEADER. */
- /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
- /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */
- /* IT MAY ALSO CONTAIN SHORT ATTRIBUTES AND */
- /* POINTERS TO LONG ATTRIBUTE HEADERS. */
- /* TUPLE ATTRIBUTE INDEX CLUSTERS, ATTRIBUTE */
- /* CLUSTERS AND A DYNAMIC ATTRIBUTE HEADER. */
-
- /* DATA STRUCTURE TYPES */
- /* WHEN ATTRIBUTE INFO IS SENT WITH A ATTRINFO-SIGNAL THE */
- /* VARIABLE TYPE IS SPECIFYED. THIS MUST BE DONE TO BE ABLE TO */
- /* NOW HOW MUCH DATA OF A ATTRIBUTE TO READ FROM ATTRINFO. */
-
- /* WHEN A REQUEST CAN NOT BE EXECUTED BECAUSE OF A ERROR THE */
- /* ERROR MUST BE IDENTIFYED BY MEANS OF A ERROR CODE AND SENT TO */
- /* THE REQUESTER. */
-#define ZGET_OPREC_ERROR 804 // TUP_SEIZEREF
-
-#define ZEXIST_FRAG_ERROR 816 // Add fragment
-#define ZFULL_FRAGRECORD_ERROR 817 // Add fragment
-#define ZNO_FREE_PAGE_RANGE_ERROR 818 // Add fragment
-#define ZNOFREE_FRAGOP_ERROR 830 // Add fragment
-#define ZTOO_LARGE_TUPLE_ERROR 851 // Add fragment
-#define ZNO_FREE_TAB_ENTRY_ERROR 852 // Add fragment
-#define ZNO_PAGES_ALLOCATED_ERROR 881 // Add fragment
-
-#define ZGET_REALPID_ERROR 809
-#define ZNOT_IMPLEMENTED_ERROR 812
-#define ZSEIZE_ATTRINBUFREC_ERROR 805
-#define ZTOO_MUCH_ATTRINFO_ERROR 823
-#define ZMEM_NOTABDESCR_ERROR 826
-#define ZMEM_NOMEM_ERROR 827
-#define ZAI_INCONSISTENCY_ERROR 829
-#define ZNO_ILLEGAL_NULL_ATTR 839
-#define ZNOT_NULL_ATTR 840
-#define ZNO_INSTRUCTION_ERROR 871
-#define ZOUTSIDE_OF_PROGRAM_ERROR 876
-#define ZSTORED_PROC_ID_ERROR 877
-#define ZREGISTER_INIT_ERROR 878
-#define ZATTRIBUTE_ID_ERROR 879
-#define ZTRY_TO_READ_TOO_MUCH_ERROR 880
-#define ZTOTAL_LEN_ERROR 882
-#define ZATTR_INTERPRETER_ERROR 883
-#define ZSTACK_OVERFLOW_ERROR 884
-#define ZSTACK_UNDERFLOW_ERROR 885
-#define ZTOO_MANY_INSTRUCTIONS_ERROR 886
-#define ZTRY_TO_UPDATE_ERROR 888
-#define ZCALL_ERROR 890
-#define ZTEMPORARY_RESOURCE_FAILURE 891
-#define ZUNSUPPORTED_BRANCH 892
-
-#define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan
-#define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
-
-#define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
-#define ZVAR_SIZED_NOT_SUPPORTED 894
-#define ZINCONSISTENT_NULL_ATTRIBUTE_COUNT 895
-#define ZTUPLE_CORRUPTED_ERROR 896
-#define ZTRY_UPDATE_PRIMARY_KEY 897
-#define ZMUST_BE_ABORTED_ERROR 898
-#define ZTUPLE_DELETED_ERROR 626
-#define ZINSERT_ERROR 630
-
-#define ZINVALID_CHAR_FORMAT 744
-#define ZROWID_ALLOCATED 899
-
- /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */
-
-#define ZFREE_COMMON 1 /* PAGE STATE, PAGE IN COMMON AREA */
-#define ZEMPTY_MM 2 /* PAGE STATE, PAGE IN EMPTY LIST */
-#define ZTH_MM_FREE 3 /* PAGE STATE, TUPLE HEADER PAGE WITH FREE AREA */
-#define ZTH_MM_FULL 4 /* PAGE STATE, TUPLE HEADER PAGE WHICH IS FULL */
-
-#define ZTD_HEADER 0 /* HEADER POSITION */
-#define ZTD_DATASIZE 1 /* SIZE OF THE DATA IN THIS CHUNK */
-#define ZTD_SIZE 2 /* TOTAL SIZE OF TABLE DESCRIPTOR */
-
- /* TRAILER POSITIONS FROM END OF TABLE DESCRIPTOR RECORD */
-#define ZTD_TR_SIZE 1 /* SIZE DESCRIPTOR POS FROM END+1 */
-#define ZTD_TR_TYPE 2
-#define ZTD_TRAILER_SIZE 2 /* TOTAL SIZE OF TABLE TRAILER */
-#define ZAD_SIZE 2 /* TOTAL SIZE OF ATTR DESCRIPTOR */
-#define ZAD_LOG_SIZE 1 /* TWO LOG OF TOTAL SIZE OF ATTR DESCRIPTOR */
-
- /* CONSTANTS USED TO HANDLE TABLE DESCRIPTOR AS A FREELIST */
-#define ZTD_FL_HEADER 0 /* HEADER POSITION */
-#define ZTD_FL_SIZE 1 /* TOTAL SIZE OF THIS FREELIST ENTRY */
-#define ZTD_FL_PREV 2 /* PREVIOUS RECORD IN FREELIST */
-#define ZTD_FL_NEXT 3 /* NEXT RECORD IN FREELIST */
-#define ZTD_FREE_SIZE 16 /* SIZE NEEDED TO HOLD ONE FL ENTRY */
-
- /* CONSTANTS USED IN LSB OF TABLE DESCRIPTOR HEADER DESCRIBING USAGE */
-#define ZTD_TYPE_FREE 0 /* RECORD LINKED INTO FREELIST */
-#define ZTD_TYPE_NORMAL 1 /* RECORD USED AS TABLE DESCRIPTOR */
- /* ATTRIBUTE OPERATION CONSTANTS */
-#define ZLEAF 1
-#define ZNON_LEAF 2
-
- /* ATTRINBUFREC VARIABLE POSITIONS. */
-#define ZBUF_PREV 29 /* POSITION OF 'PREV'-VARIABLE (USED BY INTERPRETED EXEC) */
-#define ZBUF_DATA_LEN 30 /* POSITION OF 'DATA LENGTH'-VARIABLE. */
-#define ZBUF_NEXT 31 /* POSITION OF 'NEXT'-VARIABLE. */
-#define ZSAVE_BUF_NEXT 28
-#define ZSAVE_BUF_DATA_LEN 27
-
- /* RETURN POINTS. */
- /* RESTART PHASES */
-#define ZSTARTPHASE1 1
-#define ZSTARTPHASE2 2
-#define ZSTARTPHASE3 3
-#define ZSTARTPHASE4 4
-#define ZSTARTPHASE6 6
-
-#define ZADDFRAG 0
-
-//------------------------------------------------------------
-// TUP_CONTINUEB codes
-//------------------------------------------------------------
-#define ZINITIALISE_RECORDS 6
-#define ZREL_FRAG 7
-#define ZREPORT_MEMORY_USAGE 8
-#define ZBUILD_INDEX 9
-#define ZTUP_SCAN 10
-#define ZFREE_EXTENT 11
-#define ZUNMAP_PAGES 12
-#define ZFREE_VAR_PAGES 13
-
-#define ZSCAN_PROCEDURE 0
-#define ZCOPY_PROCEDURE 2
-#define ZSTORED_PROCEDURE_DELETE 3
-#define ZSTORED_PROCEDURE_FREE 0xffff
-#define ZMIN_PAGE_LIMIT_TUP_COMMITREQ 2
-
-#define ZSKIP_TUX_TRIGGERS 0x1 // flag for TUP_ABORTREQ
-
-#endif
-
-class Dbtup: public SimulatedBlock {
-friend class Suma;
-public:
-struct KeyReqStruct;
-friend struct KeyReqStruct; // CC
-typedef bool (Dbtup::* ReadFunction)(Uint32*,
- KeyReqStruct*,
- AttributeHeader*,
- Uint32);
-typedef bool (Dbtup::* UpdateFunction)(Uint32*,
- KeyReqStruct*,
- Uint32);
-private:
-
- typedef Tup_fixsize_page Fix_page;
- typedef Tup_varsize_page Var_page;
-
-public:
- class Dblqh *c_lqh;
- Tsman* c_tsman;
- Lgman* c_lgman;
- Page_cache_client m_pgman;
-
-// State values
-enum ChangeMaskState {
- DELETE_CHANGES = 0,
- SET_ALL_MASK = 1,
- USE_SAVED_CHANGE_MASK = 2,
- RECALCULATE_CHANGE_MASK = 3
-};
-
-enum TransState {
- TRANS_IDLE = 0,
- TRANS_STARTED = 1,
- TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO = 2,
- TRANS_ERROR_WAIT_STORED_PROCREQ = 3,
- TRANS_ERROR_WAIT_TUPKEYREQ = 4,
- TRANS_TOO_MUCH_AI = 5,
- TRANS_DISCONNECTED = 6
-};
-
-enum TupleState {
- TUPLE_PREPARED = 1,
- TUPLE_ALREADY_ABORTED = 2,
- TUPLE_TO_BE_COMMITTED = 3
-};
-
-enum State {
- NOT_INITIALIZED = 0,
- IDLE = 17,
- ACTIVE = 18,
- SYSTEM_RESTART = 19,
- DEFINED = 34,
- NOT_DEFINED = 37,
- NORMAL_PAGE = 40,
- DEFINING = 65,
- DROPPING = 68
-};
-
-// Records
-/* ************** ATTRIBUTE INFO BUFFER RECORD ****************** */
-/* THIS RECORD IS USED AS A BUFFER FOR INCOMING AND OUTGOING DATA */
-/* ************************************************************** */
-struct Attrbufrec {
- Uint32 attrbuf[ZATTRBUF_SIZE];
-}; /* p2c: size = 128 bytes */
-
-typedef Ptr<Attrbufrec> AttrbufrecPtr;
-
-
-
-struct Fragoperrec {
- Uint64 minRows;
- Uint64 maxRows;
- Uint32 nextFragoprec;
- Uint32 lqhPtrFrag;
- Uint32 fragidFrag;
- Uint32 tableidFrag;
- Uint32 fragPointer;
- Uint32 attributeCount;
- Uint32 charsetIndex;
- Uint32 m_null_bits[2];
- Uint32 m_fix_attributes_size[2]; // In words
- Uint32 m_var_attributes_size[2]; // In bytes
- BlockReference lqhBlockrefFrag;
- bool inUse;
- bool definingFragment;
-};
-typedef Ptr<Fragoperrec> FragoperrecPtr;
-
-
- typedef Tup_page Page;
- typedef Ptr<Page> PagePtr;
-
- // Scan position
- struct ScanPos {
- enum Get {
- Get_undef = 0,
- Get_next_page,
- Get_page,
- Get_next_page_mm,
- Get_page_mm,
- Get_next_page_dd,
- Get_page_dd,
- Get_next_tuple,
- Get_tuple,
- Get_next_tuple_fs,
- Get_tuple_fs
- };
- Get m_get; // entry point in scanNext
- Local_key m_key; // scan position pointer MM or DD
- Page* m_page; // scanned MM or DD (cache) page
- Local_key m_key_mm; // MM local key returned
- Uint32 m_realpid_mm; // MM real page id
- Uint32 m_extent_info_ptr_i;
- };
-
- // Scan Lock
- struct ScanLock {
- Uint32 m_accLockOp;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<ScanLock> ScanLockPtr;
- ArrayPool<ScanLock> c_scanLockPool;
-
- // Tup scan, similar to Tux scan. Later some of this could
- // be moved to common superclass.
- struct ScanOp {
- ScanOp() :
- m_state(Undef),
- m_bits(0),
- m_userPtr(RNIL),
- m_userRef(RNIL),
- m_tableId(RNIL),
- m_fragId(~(Uint32)0),
- m_fragPtrI(RNIL),
- m_transId1(0),
- m_transId2(0),
- m_savePointId(0),
- m_accLockOp(RNIL)
- {}
-
- enum State {
- Undef = 0,
- First = 1, // before first entry
- Current = 2, // at current before locking
- Blocked = 3, // at current waiting for ACC lock
- Locked = 4, // at current and locked or no lock needed
- Next = 5, // looking for next extry
- Last = 6, // after last entry
- Aborting = 7, // lock wait at scan close
- Invalid = 9 // cannot return REF to LQH currently
- };
- Uint16 m_state;
-
- enum Bits {
- SCAN_DD = 0x01, // scan disk pages
- SCAN_VS = 0x02, // page format is var size
- SCAN_LCP = 0x04, // LCP mem page scan
- SCAN_LOCK_SH = 0x10, // lock mode shared
- SCAN_LOCK_EX = 0x20, // lock mode exclusive
- SCAN_LOCK_WAIT = 0x40, // lock wait
- // any lock mode
- SCAN_LOCK = SCAN_LOCK_SH | SCAN_LOCK_EX,
- SCAN_NR = 0x80 // Node recovery scan
- };
- Uint16 m_bits;
-
- Uint32 m_userPtr; // scanptr.i in LQH
- Uint32 m_userRef;
- Uint32 m_tableId;
- Uint32 m_fragId;
- Uint32 m_fragPtrI;
- Uint32 m_transId1;
- Uint32 m_transId2;
- union {
- Uint32 m_savePointId;
- Uint32 m_scanGCI;
- };
- Uint32 m_endPage;
- // lock waited for or obtained and not yet passed to LQH
- Uint32 m_accLockOp;
-
- ScanPos m_scanPos;
-
- DLFifoList<ScanLock>::Head m_accLockOps;
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<ScanOp> ScanOpPtr;
- ArrayPool<ScanOp> c_scanOpPool;
-
- void scanReply(Signal*, ScanOpPtr scanPtr);
- void scanFirst(Signal*, ScanOpPtr scanPtr);
- bool scanNext(Signal*, ScanOpPtr scanPtr);
- void scanCont(Signal*, ScanOpPtr scanPtr);
- void disk_page_tup_scan_callback(Signal*, Uint32 scanPtrI, Uint32 page_i);
- void scanClose(Signal*, ScanOpPtr scanPtr);
- void addAccLockOp(ScanOp& scan, Uint32 accLockOp);
- void removeAccLockOp(ScanOp& scan, Uint32 accLockOp);
- void releaseScanOp(ScanOpPtr& scanPtr);
-
- // for md5 of key (could maybe reuse existing temp buffer)
- Uint64 c_dataBuffer[ZWORDS_ON_PAGE/2 + 1];
-
- struct Page_request
- {
- Local_key m_key;
- Uint32 m_frag_ptr_i;
- Uint32 m_extent_info_ptr;
- Uint16 m_estimated_free_space; // in bytes/records
- Uint16 m_list_index; // in Disk_alloc_info.m_page_requests
- Uint16 m_ref_count; // Waiters for page
- Uint16 m_uncommitted_used_space;
- Uint32 nextList;
- Uint32 prevList;
- Uint32 m_magic;
- }; // 32 bytes
-
- typedef RecordPool<Page_request, WOPool> Page_request_pool;
- typedef DLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
- typedef LocalDLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
-
- STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
- STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
- STATIC_CONST( EXTENT_SEARCH_MATRIX_SIZE = 20 );
-
- struct Extent_list_t
- {
- Uint32 nextList;
- };
-
- struct Extent_info : public Extent_list_t
- {
- Uint32 m_magic;
- Uint32 m_first_page_no;
- Local_key m_key;
- Uint32 m_free_space;
- Uint32 m_free_matrix_pos;
- Uint16 m_free_page_count[EXTENT_SEARCH_MATRIX_COLS];
- union {
- Uint32 nextList;
- Uint32 nextPool;
- };
- Uint32 prevList;
- Uint32 nextHash, prevHash;
-
- Uint32 hashValue() const {
- return (m_key.m_file_no << 16) ^ m_key.m_page_idx;
- }
-
- Extent_info() {}
- bool equal(const Extent_info & rec) const {
- return m_key.m_file_no == rec.m_key.m_file_no &&
- m_key.m_page_idx == rec.m_key.m_page_idx;
- }
- }; // 40 bytes
-
- typedef RecordPool<Extent_info, RWPool> Extent_info_pool;
- typedef DLListImpl<Extent_info_pool, Extent_info> Extent_info_list;
- typedef LocalDLListImpl<Extent_info_pool, Extent_info> Local_extent_info_list;
- typedef DLHashTableImpl<Extent_info_pool, Extent_info> Extent_info_hash;
- typedef SLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Fragment_extent_list;
- typedef LocalSLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Local_fragment_extent_list;
- struct Tablerec;
- struct Disk_alloc_info
- {
- Disk_alloc_info() {}
- Disk_alloc_info(const Tablerec* tabPtrP,
- Uint32 extent_size_in_pages);
- Uint32 m_extent_size;
-
- /**
- * Disk allocation
- *
- * 1) Allocate space on pages that already are dirty
- * (4 free lists for different requests)
- * 2) Allocate space on pages waiting to maped that will be dirty
- * (4 free lists for different requests)
- * 3) Check if "current" extent can accommodate request
- * If so, allocate page from there
- * Else put "current" into free matrix
- * 4) Search free matrix for extent with greatest amount of free space
- * while still accommodating current request
- * (20 free lists for different requests)
- */
-
- /**
- * Free list of pages in different size
- * that are dirty
- */
- DLList<Page>::Head m_dirty_pages[MAX_FREE_LIST]; // In real page id's
-
- /**
- * Requests (for update) that have sufficient space left after request
- * these are currently being "mapped"
- */
- Page_request_list::Head m_page_requests[MAX_FREE_LIST];
-
- DLList<Page>::Head m_unmap_pages;
-
- /**
- * Current extent
- */
- Uint32 m_curr_extent_info_ptr_i;
-
- /**
- *
- */
- STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
- Extent_info_list::Head m_free_extents[SZ];
- Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
- Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
-
- Uint32 find_extent(Uint32 sz) const;
- Uint32 calc_extent_pos(const Extent_info*) const;
-
- /**
- * Compute minimum free space on page given bits
- */
- Uint32 calc_page_free_space(Uint32 bits) const {
- return m_page_free_bits_map[bits];
- }
-
- /**
- * Compute page free bits, given free space
- */
- Uint32 calc_page_free_bits(Uint32 free) const {
- for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_COLS-1; i++)
- if(free >= m_page_free_bits_map[i])
- return i;
- return EXTENT_SEARCH_MATRIX_COLS - 1;
- }
-
- Fragment_extent_list::Head m_extent_list;
- };
-
- void dump_disk_alloc(Disk_alloc_info&);
-
-struct Fragrecord {
- Uint32 nextStartRange;
- Uint32 currentPageRange;
- Uint32 rootPageRange;
- Uint32 noOfPages;
- Uint32 noOfVarPages;
- Uint32 noOfPagesToGrow;
-
- DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
- DLFifoList<Page>::Head thFreeFirst; // pages with atleast 1 free record
- SLList<Page>::Head m_empty_pages; // Empty pages not in logical/physical map
-
- Uint32 m_lcp_scan_op;
- Uint32 m_lcp_keep_list;
-
- State fragStatus;
- Uint32 fragTableId;
- Uint32 fragmentId;
- Uint32 nextfreefrag;
- DLList<Page>::Head free_var_page_array[MAX_FREE_LIST];
-
- DLList<ScanOp>::Head m_scanList;
-
- enum { UC_LCP = 1, UC_CREATE = 2, UC_SET_LCP = 3 };
- Uint32 m_restore_lcp_id;
- Uint32 m_undo_complete;
- Uint32 m_tablespace_id;
- Uint32 m_logfile_group_id;
- Disk_alloc_info m_disk_alloc_info;
- Uint32 m_var_page_chunks;
-};
-typedef Ptr<Fragrecord> FragrecordPtr;
-
-
-struct Operationrec {
- /*
- * To handle Attrinfo signals and buffer them up we need to
- * a simple list with first and last and we also need to keep track
- * of how much we received for security check.
- * Will most likely disappear with introduction of long signals.
- * These variables are used before TUPKEYREQ is received and not
- * thereafter and is disposed with after calling copyAttrinfo
- * which is called before putting the operation into its lists.
- * Thus we can use union declarations for these variables.
- */
-
- /*
- * Used by scans to find the Attrinfo buffers.
- * This is only until returning from copyAttrinfo and
- * can thus reuse the same memory as needed by the
- * active operation list variables.
- */
-
- /*
- * Doubly linked list with anchor on tuple.
- * This is to handle multiple updates on the same tuple
- * by the same transaction.
- */
- union {
- Uint32 prevActiveOp;
- Uint32 storedProcedureId; //Used until copyAttrinfo
- };
- union {
- Uint32 nextActiveOp;
- Uint32 currentAttrinbufLen; //Used until copyAttrinfo
- };
-
- Operationrec() {}
- bool is_first_operation() const { return prevActiveOp == RNIL;}
- bool is_last_operation() const { return nextActiveOp == RNIL;}
-
- Uint32 m_undo_buffer_space; // In words
- union {
- Uint32 firstAttrinbufrec; //Used until copyAttrinfo
- };
- Uint32 m_any_value;
- union {
- Uint32 lastAttrinbufrec; //Used until copyAttrinfo
- Uint32 nextPool;
- };
- Uint32 attrinbufLen; //only used during STORED_PROCDEF phase
- Uint32 storedProcPtr; //only used during STORED_PROCDEF phase
-
- /*
- * From fragment i-value we can find fragment and table record
- */
- Uint32 fragmentPtr;
-
- /*
- * We need references to both the original tuple and the copy tuple.
- * We keep the page's real i-value and its index and from there we
- * can find out about the fragment page id and the page offset.
- */
- Local_key m_tuple_location;
- Local_key m_copy_tuple_location;
-
- /*
- * We keep the record linked to the operation record in LQH.
- * This is needed due to writing of REDO log must be performed
- * in correct order, which is the same order as the writes
- * occurred. LQH can receive the records in different order.
- */
- Uint32 userpointer;
-
- /*
- * When responding to queries in the same transaction they will see
- * a result from the save point id the query was started. Again
- * functionality for multi-updates of the same record in one
- * transaction.
- */
- union {
- Uint32 savepointId;
- Uint32 m_commit_disk_callback_page;
- };
-
- /*
- * We use 64 bits to save change mask for the most common cases.
- */
- Uint32 saved_change_mask[2];
-
- /*
- * State variables on connection.
- * State variable on tuple after multi-updates
- * Is operation undo logged or not
- * Is operation in fragment list
- * Is operation in multi-update list
- * Operation type (READ, UPDATE, etc)
- * Is record primary replica
- * Is delete or insert performed
- */
- struct OpBitFields {
- unsigned int trans_state : 3;
- unsigned int tuple_state : 2;
- unsigned int in_active_list : 1;
-
- unsigned int op_type : 3;
- unsigned int delete_insert_flag : 1;
- unsigned int primary_replica : 1;
- unsigned int change_mask_state : 2;
- unsigned int m_disk_preallocated : 1;
- unsigned int m_load_diskpage_on_commit : 1;
- unsigned int m_wait_log_buffer : 1;
- };
- union {
- OpBitFields op_struct;
- Uint16 op_bit_fields;
- };
-
- /*
- * TUX needs to know the tuple version of the tuple since it
- * keeps an entry for both the committed and all versions in
- * a transaction currently. So each update will create a new
- * version even if in the same transaction.
- */
- Uint16 tupVersion;
-};
-typedef Ptr<Operationrec> OperationrecPtr;
-
- /* ****************************** PAGE RANGE RECORD ************************** */
- /* PAGE RANGES AND BASE PAGE ID. EACH RANGE HAS A CORRESPONDING BASE PAGE ID */
- /* THAT IS USED TO CALCULATE REAL PAGE ID FROM A FRAGMENT PAGE ID AND A TABLE */
- /* REFERENCE. */
- /* THE PAGE RANGES ARE ORGANISED IN A B-TREE FASHION WHERE THE VARIABLE TYPE */
- /* SPECIFIES IF A LEAF NODE HAS BEEN REACHED. IF A LEAF NODE HAS BEEN REACHED */
- /* THEN BASE_PAGE_ID IS THE BASE_PAGE_ID OF THE SET OF PAGES THAT WAS */
- /* ALLOCATED IN THAT RANGE. OTHERWISE BASE_PAGE_ID IS THE POINTER TO THE NEXT */
- /* PAGE_RANGE RECORD. */
- /* *************************************************************************** */
-struct PageRange {
- Uint32 startRange[4]; /* START OF RANGE */
- Uint32 endRange[4]; /* END OF THIS RANGE */
- Uint32 basePageId[4]; /* BASE PAGE ID. */
-/*---- VARIABLE BASE_PAGE_ID2 (4) 8 DS NEEDED WHEN SUPPORTING 40 BIT PAGE ID -------*/
- Uint8 type[4]; /* TYPE OF BASE PAGE ID */
- Uint32 nextFree; /* NEXT FREE PAGE RANGE RECORD */
- Uint32 parentPtr; /* THE PARENT TO THE PAGE RANGE REC IN THE B-TREE */
- Uint8 currentIndexPos;
-};
-typedef Ptr<PageRange> PageRangePtr;
-
-
- /* ************* TRIGGER DATA ************* */
- /* THIS RECORD FORMS LISTS OF ACTIVE */
- /* TRIGGERS FOR EACH TABLE. */
- /* THE RECORDS ARE MANAGED BY A TRIGGER */
- /* POOL wHERE A TRIGGER RECORD IS SEIZED */
- /* WHEN A TRIGGER IS ACTIVATED AND RELEASED */
- /* WHEN THE TRIGGER IS DEACTIVATED. */
- /* **************************************** */
-struct TupTriggerData {
- TupTriggerData() {}
-
- /**
- * Trigger id, used by DICT/TRIX to identify the trigger
- *
- * trigger Ids are unique per block for SUBSCRIPTION triggers.
- * This is so that BACKUP can use TUP triggers directly and delete them
- * properly.
- */
- Uint32 triggerId;
-
- /**
- * Index id is needed for ordered index.
- */
- Uint32 indexId;
-
- /**
- * Trigger type etc, defines what the trigger is used for
- */
- TriggerType::Value triggerType;
- TriggerActionTime::Value triggerActionTime;
- TriggerEvent::Value triggerEvent;
- /**
- * Receiver block
- */
- Uint32 m_receiverBlock;
-
- /**
- * Monitor all replicas, i.e. trigger will fire on all nodes where tuples
- * are stored
- */
- bool monitorReplicas;
-
- /**
- * Monitor all attributes, the trigger monitors all changes to attributes
- * in the table
- */
- bool monitorAllAttributes;
-
- /**
- * Send only changed attributes at trigger firing time.
- */
- bool sendOnlyChangedAttributes;
-
- /**
- * Send also before values at trigger firing time.
- */
- bool sendBeforeValues;
-
- /**
- * Attribute mask, defines what attributes are to be monitored
- * Can be seen as a compact representation of SQL column name list
- */
- Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
-
- /**
- * Next ptr (used in pool/list)
- */
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
-
- /**
- * Prev pointer (used in list)
- */
- Uint32 prevList;
-
- inline void print(NdbOut & s) const { s << "[TriggerData = " << triggerId << "]"; };
-};
-
-typedef Ptr<TupTriggerData> TriggerPtr;
-
-/**
- * Pool of trigger data record
- */
-ArrayPool<TupTriggerData> c_triggerPool;
-
- /* ************ TABLE RECORD ************ */
- /* THIS RECORD FORMS A LIST OF TABLE */
- /* REFERENCE INFORMATION. ONE RECORD */
- /* PER TABLE REFERENCE. */
- /* ************************************** */
- STATIC_CONST( MM = 0 );
- STATIC_CONST( DD = 1 );
-
- struct Tablerec {
- Tablerec(ArrayPool<TupTriggerData> & triggerPool) :
- afterInsertTriggers(triggerPool),
- afterDeleteTriggers(triggerPool),
- afterUpdateTriggers(triggerPool),
- subscriptionInsertTriggers(triggerPool),
- subscriptionDeleteTriggers(triggerPool),
- subscriptionUpdateTriggers(triggerPool),
- constraintUpdateTriggers(triggerPool),
- tuxCustomTriggers(triggerPool)
- {}
-
- Bitmask<MAXNROFATTRIBUTESINWORDS> notNullAttributeMask;
- Bitmask<MAXNROFATTRIBUTESINWORDS> blobAttributeMask;
-
- ReadFunction* readFunctionArray;
- UpdateFunction* updateFunctionArray;
- CHARSET_INFO** charsetArray;
-
- Uint32 readKeyArray;
- Uint32 tabDescriptor;
- Uint32 m_real_order_descriptor;
-
- enum Bits
- {
- TR_Checksum = 0x1, // Need to be 1
- TR_RowGCI = 0x2,
- TR_ForceVarPart = 0x4
- };
- Uint16 m_bits;
- Uint16 total_rec_size; // Max total size for entire tuple in words
-
- /**
- * Aggregates
- */
- Uint16 m_no_of_attributes;
- Uint16 m_no_of_disk_attributes;
- Uint16 noOfKeyAttr;
- Uint16 noOfCharsets;
-
- bool need_expand() const {
- return m_no_of_attributes > m_attributes[MM].m_no_of_fixsize;
- }
-
- bool need_expand(bool disk) const {
- return m_attributes[MM].m_no_of_varsize > 0 ||
- (disk && m_no_of_disk_attributes > 0);
- }
-
- bool need_shrink() const {
- return
- m_attributes[MM].m_no_of_varsize > 0 ||
- m_attributes[DD].m_no_of_varsize > 0;
- }
-
- bool need_shrink(bool disk) const {
- return
- m_attributes[MM].m_no_of_varsize > 0 ||
- (disk && m_attributes[DD].m_no_of_varsize > 0);
- }
-
- /**
- * Descriptors for MM and DD part
- */
- struct Tuple_offsets {
- Uint8 m_null_words;
- Uint8 m_null_offset;
- Uint16 m_disk_ref_offset; // In words relative m_data
- Uint16 m_fix_header_size; // For fix size tuples= total rec size(part)
- Uint16 m_max_var_offset; // In bytes relative m_var_data.m_data_ptr
- } m_offsets[2];
-
- Uint32 get_check_offset(Uint32 mm) const {
- return m_offsets[mm].m_fix_header_size;
- }
-
- struct {
- Uint16 m_no_of_fixsize;
- Uint16 m_no_of_varsize;
- } m_attributes[2];
-
- // Lists of trigger data for active triggers
- DLList<TupTriggerData> afterInsertTriggers;
- DLList<TupTriggerData> afterDeleteTriggers;
- DLList<TupTriggerData> afterUpdateTriggers;
- DLList<TupTriggerData> subscriptionInsertTriggers;
- DLList<TupTriggerData> subscriptionDeleteTriggers;
- DLList<TupTriggerData> subscriptionUpdateTriggers;
- DLList<TupTriggerData> constraintUpdateTriggers;
-
- // List of ordered indexes
- DLList<TupTriggerData> tuxCustomTriggers;
-
- Uint32 fragid[MAX_FRAG_PER_NODE];
- Uint32 fragrec[MAX_FRAG_PER_NODE];
-
- struct {
- Uint32 tabUserPtr;
- Uint32 tabUserRef;
- Uint32 m_lcpno;
- Uint32 m_fragPtrI;
- } m_dropTable;
- State tableStatus;
- };
-
- struct Disk_undo
- {
- enum
- {
- UNDO_ALLOC = File_formats::Undofile::UNDO_TUP_ALLOC
- ,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
- ,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
- ,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE
- ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
- ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT
- ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT
- };
-
- struct Alloc
- {
- Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
- Uint32 m_page_no;
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
-
- struct Update
- {
- Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
- Uint32 m_page_no;
- Uint32 m_gci;
- Uint32 m_data[1];
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
-
- struct Free
- {
- Uint32 m_file_no_page_idx; // 16 bit file_no, 16 bit page_idx
- Uint32 m_page_no;
- Uint32 m_gci;
- Uint32 m_data[1];
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
-
- struct Create
- {
- Uint32 m_table;
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
-
- struct Drop
- {
- Uint32 m_table;
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
-
- struct AllocExtent
- {
- Uint32 m_table;
- Uint32 m_fragment;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_type_length;
- };
-
- struct FreeExtent
- {
- Uint32 m_table;
- Uint32 m_fragment;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_type_length;
- };
- };
-
- Extent_info_pool c_extent_pool;
- Extent_info_hash c_extent_hash;
- Page_request_pool c_page_request_pool;
-
- typedef Ptr<Tablerec> TablerecPtr;
-
- struct storedProc {
- Uint32 storedLinkFirst;
- Uint32 storedLinkLast;
- Uint32 storedCounter;
- Uint32 nextPool;
- Uint16 storedCode;
- Uint16 storedProcLength;
-};
-
-typedef Ptr<storedProc> StoredProcPtr;
-
-ArrayPool<storedProc> c_storedProcPool;
-
-/* **************************** TABLE_DESCRIPTOR RECORD ******************************** */
-/* THIS VARIABLE IS USED TO STORE TABLE DESCRIPTIONS. A TABLE DESCRIPTION IS STORED AS A */
-/* CONTIGUOS ARRAY IN THIS VARIABLE. WHEN A NEW TABLE IS ADDED A CHUNK IS ALLOCATED IN */
-/* THIS RECORD. WHEN ATTRIBUTES ARE ADDED TO THE TABLE, A NEW CHUNK OF PROPER SIZE IS */
-/* ALLOCATED AND ALL DATA IS COPIED TO THIS NEW CHUNK AND THEN THE OLD CHUNK IS PUT IN */
-/* THE FREE LIST. EACH TABLE IS DESCRIBED BY A NUMBER OF TABLE DESCRIPTIVE ATTRIBUTES */
-/* AND A NUMBER OF ATTRIBUTE DESCRIPTORS AS SHOWN IN FIGURE BELOW */
-/* */
-/* WHEN ALLOCATING A TABLE DESCRIPTOR THE SIZE IS ALWAYS A MULTIPLE OF 16 WORDS. */
-/* */
-/* ---------------------------------------------- */
-/* | TRAILER USED FOR ALLOC/DEALLOC | */
-/* ---------------------------------------------- */
-/* | TABLE DESCRIPTIVE ATTRIBUTES | */
-/* ---------------------------------------------- */
-/* | ATTRIBUTE DESCRIPTION 1 | */
-/* ---------------------------------------------- */
-/* | ATTRIBUTE DESCRIPTION 2 | */
-/* ---------------------------------------------- */
-/* | | */
-/* | | */
-/* | | */
-/* ---------------------------------------------- */
-/* | ATTRIBUTE DESCRIPTION N | */
-/* ---------------------------------------------- */
-/* */
-/* THE TABLE DESCRIPTIVE ATTRIBUTES CONTAINS THE FOLLOWING ATTRIBUTES: */
-/* */
-/* ---------------------------------------------- */
-/* | HEADER (TYPE OF INFO) | */
-/* ---------------------------------------------- */
-/* | SIZE OF WHOLE CHUNK (INCL. TRAILER) | */
-/* ---------------------------------------------- */
-/* | TABLE IDENTITY | */
-/* ---------------------------------------------- */
-/* | FRAGMENT IDENTITY | */
-/* ---------------------------------------------- */
-/* | NUMBER OF ATTRIBUTES | */
-/* ---------------------------------------------- */
-/* | SIZE OF FIXED ATTRIBUTES | */
-/* ---------------------------------------------- */
-/* | NUMBER OF NULL FIELDS | */
-/* ---------------------------------------------- */
-/* | NOT USED | */
-/* ---------------------------------------------- */
-/* */
-/* THESE ATTRIBUTES ARE ALL ONE R-VARIABLE IN THE RECORD. */
-/* NORMALLY ONLY ONE TABLE DESCRIPTOR IS USED. DURING SCHEMA CHANGES THERE COULD */
-/* HOWEVER EXIST MORE THAN ONE TABLE DESCRIPTION SINCE THE SCHEMA CHANGE OF VARIOUS */
-/* FRAGMENTS ARE NOT SYNCHRONISED. THIS MEANS THAT ALTHOUGH THE SCHEMA HAS CHANGED */
-/* IN ALL FRAGMENTS, BUT THE FRAGMENTS HAVE NOT REMOVED THE ATTRIBUTES IN THE SAME */
-/* TIME-FRAME. THEREBY SOME ATTRIBUTE INFORMATION MIGHT DIFFER BETWEEN FRAGMENTS. */
-/* EXAMPLES OF ATTRIBUTES THAT MIGHT DIFFER ARE SIZE OF FIXED ATTRIBUTES, NUMBER OF */
-/* ATTRIBUTES, FIELD START WORD, START BIT. */
-/* */
-/* AN ATTRIBUTE DESCRIPTION CONTAINS THE FOLLOWING ATTRIBUTES: */
-/* */
-/* ---------------------------------------------- */
-/* | Field Type, 4 bits (LSB Bits) | */
-/* ---------------------------------------------- */
-/* | Attribute Size, 4 bits | */
-/* ---------------------------------------------- */
-/* | NULL indicator 1 bit | */
-/* ---------------------------------------------- */
-/* | Indicator if TUP stores attr. 1 bit | */
-/* ---------------------------------------------- */
-/* | Not used 6 bits | */
-/* ---------------------------------------------- */
-/* | No. of elements in fixed array 16 bits | */
-/* ---------------------------------------------- */
-/* ---------------------------------------------- */
-/* | Field Start Word, 21 bits (LSB Bits) | */
-/* ---------------------------------------------- */
-/* | NULL Bit, 11 bits | */
-/* ---------------------------------------------- */
-/* */
-/* THE ATTRIBUTE SIZE CAN BE 1,2,4,8,16,32,64 AND 128 BITS. */
-/* */
-/* THE UNUSED PARTS OF THE RECORDS ARE PUT IN A LINKED LIST OF FREE PARTS. EACH OF */
-/* THOSE FREE PARTS HAVE THREE RECORDS ASSIGNED AS SHOWN IN THIS STRUCTURE */
-/* ALL FREE PARTS ARE SET INTO A CHUNK LIST WHERE EACH CHUNK IS AT LEAST 16 WORDS */
-/* */
-/* ---------------------------------------------- */
-/* | HEADER = RNIL | */
-/* ---------------------------------------------- */
-/* | SIZE OF FREE AREA | */
-/* ---------------------------------------------- */
-/* | POINTER TO PREVIOUS FREE AREA | */
-/* ---------------------------------------------- */
-/* | POINTER TO NEXT FREE AREA | */
-/* ---------------------------------------------- */
-/* */
-/* IF THE POINTER TO THE NEXT AREA IS RNIL THEN THIS IS THE LAST FREE AREA. */
-/* */
-/*****************************************************************************************/
-struct TableDescriptor {
- Uint32 tabDescr;
-};
-typedef Ptr<TableDescriptor> TableDescriptorPtr;
-
-struct HostBuffer {
- bool inPackedList;
- Uint32 packetLenTA;
- Uint32 noOfPacketsTA;
- Uint32 packetBufferTA[30];
-};
-typedef Ptr<HostBuffer> HostBufferPtr;
-
- /*
- * Build index operation record.
- */
- struct BuildIndexRec {
- // request cannot use signal class due to extra members
- Uint32 m_request[BuildIndxReq::SignalLength];
- Uint8 m_build_vs; // varsize pages
- Uint32 m_indexId; // the index
- Uint32 m_fragNo; // fragment number under Tablerec
- Uint32 m_pageId; // logical fragment page id
- Uint32 m_tupleNo; // tuple number on page
- Uint32 m_buildRef; // Where to send tuples
- BuildIndxRef::ErrorCode m_errorCode;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<BuildIndexRec> BuildIndexPtr;
- ArrayPool<BuildIndexRec> c_buildIndexPool;
- DLList<BuildIndexRec> c_buildIndexList;
- Uint32 c_noOfBuildIndexRec;
-
- /**
- * Reference to variable part when a tuple is chained
- */
- struct Var_part_ref
- {
-#ifdef NDB_32BIT_VAR_REF
- /*
- In versions prior to ndb 6.1.6, 6.2.1 and mysql 5.1.17
- Running this code limits DataMemory to 16G, also online
- upgrade not possible between versions
- */
- Uint32 m_ref;
- STATIC_CONST( SZ32 = 1 );
-
- void copyout(Local_key* dst) const {
- dst->m_page_no = m_ref >> MAX_TUPLES_BITS;
- dst->m_page_idx = m_ref & MAX_TUPLES_PER_PAGE;
- }
-
- void assign(const Local_key* src) {
- m_ref = (src->m_page_no << MAX_TUPLES_BITS) | src->m_page_idx;
- }
-#else
- Uint32 m_page_no;
- Uint32 m_page_idx;
- STATIC_CONST( SZ32 = 2 );
-
- void copyout(Local_key* dst) const {
- dst->m_page_no = m_page_no;
- dst->m_page_idx = m_page_idx;
- }
-
- void assign(const Local_key* src) {
- m_page_no = src->m_page_no;
- m_page_idx = src->m_page_idx;
- }
-#endif
- };
-
- struct Disk_part_ref
- {
- STATIC_CONST( SZ32 = 2 );
- };
-
- struct Tuple_header
- {
- union {
- /**
- * List of prepared operations for this tuple.
- * Points to most recent/last operation, ie. to walk the list must follow
- * regOperPtr->prevActiveOp links.
- */
- Uint32 m_operation_ptr_i; // OperationPtrI
- Uint32 m_base_record_ref; // For disk tuple, ref to MM tuple
- };
- Uint32 m_header_bits; // Header word
- union {
- Uint32 m_checksum;
- Uint32 m_data[1];
- Uint32 m_null_bits[1];
- };
-
- STATIC_CONST( HeaderSize = 2 );
-
- /**
- * header bits
- */
- STATIC_CONST( TUP_VERSION_MASK = 0xFFFF );
- STATIC_CONST( CHAINED_ROW = 0x00010000 ); // Is var part on different page
- STATIC_CONST( DISK_PART = 0x00020000 ); // Is there a disk part
- STATIC_CONST( DISK_ALLOC = 0x00040000 ); // Is disk part allocated
- STATIC_CONST( DISK_INLINE = 0x00080000 ); // Is disk inline
- STATIC_CONST( ALLOC = 0x00100000 ); // Is record allocated now
- STATIC_CONST( MM_SHRINK = 0x00200000 ); // Has MM part shrunk
- STATIC_CONST( MM_GROWN = 0x00400000 ); // Has MM part grown
- STATIC_CONST( FREED = 0x00800000 ); // Is freed
- STATIC_CONST( LCP_SKIP = 0x01000000 ); // Should not be returned in LCP
- STATIC_CONST( LCP_KEEP = 0x02000000 ); // Should be returned in LCP
- STATIC_CONST( FREE = 0x02800000 ); // Is free
-
- Tuple_header() {}
- Uint32 get_tuple_version() const {
- return m_header_bits & TUP_VERSION_MASK;
- }
- void set_tuple_version(Uint32 version) {
- m_header_bits=
- (m_header_bits & ~(Uint32)TUP_VERSION_MASK) |
- (version & TUP_VERSION_MASK);
- }
-
- Uint32* get_null_bits(const Tablerec* tabPtrP) {
- return m_null_bits+tabPtrP->m_offsets[MM].m_null_offset;
- }
-
- Uint32* get_null_bits(const Tablerec* tabPtrP, Uint32 mm) {
- return m_null_bits+tabPtrP->m_offsets[mm].m_null_offset;
- }
-
- Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) {
- return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
- }
-
- const Var_part_ref* get_var_part_ref_ptr(const Tablerec* tabPtrP) const {
- return (Var_part_ref*)(get_disk_ref_ptr(tabPtrP) + Disk_part_ref::SZ32);
- }
-
- Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) {
- return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
- Tuple_header::HeaderSize;
- }
-
- const Uint32* get_end_of_fix_part_ptr(const Tablerec* tabPtrP) const {
- return m_data + tabPtrP->m_offsets[MM].m_fix_header_size -
- Tuple_header::HeaderSize;
- }
-
- Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) {
- return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
- }
-
- const Uint32* get_disk_ref_ptr(const Tablerec* tabPtrP) const {
- return m_data + tabPtrP->m_offsets[MM].m_disk_ref_offset;
- }
-
- Uint32 *get_mm_gci(const Tablerec* tabPtrP){
- assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
- return m_data + (tabPtrP->m_bits & Tablerec::TR_Checksum);
- }
-
- Uint32 *get_dd_gci(const Tablerec* tabPtrP, Uint32 mm){
- assert(tabPtrP->m_bits & Tablerec::TR_RowGCI);
- return m_data;
- }
- };
-
-struct KeyReqStruct {
-/**
- * These variables are used as temporary storage during execution of the
- * TUPKEYREQ signal.
- * The first set of variables defines a number of variables needed for
- * the fix part of the tuple.
- *
- * The second part defines a number of commonly used meta data variables.
- *
- * The third set of variables defines a set of variables needed for the
- * variable part.
- *
- * The fourth part is variables needed only for updates and inserts.
- *
- * The fifth part is a long array of real lengths which is is put last
- * for cache memory reasons. This is part of the variable part and
- * contains the real allocated lengths whereas the tuple contains
- * the length of attribute stored.
- */
- Tuple_header *m_tuple_ptr;
-
- Uint32 check_offset[2];
-
- TableDescriptor *attr_descr;
- Uint32 max_read;
- Uint32 out_buf_index;
- Uint32 in_buf_index;
- Uint32 in_buf_len;
- Uint32 attr_descriptor;
- bool xfrm_flag;
-
- struct Var_data {
- char *m_data_ptr;
- Uint16 *m_offset_array_ptr;
- Uint16 m_var_len_offset;
- Uint16 m_max_var_offset;
- } m_var_data[2];
-
- Tuple_header *m_disk_ptr;
- PagePtr m_page_ptr;
- PagePtr m_varpart_page_ptr; // could be same as m_page_ptr_p
- PagePtr m_disk_page_ptr; //
- Local_key m_row_id;
-
- bool dirty_op;
- bool interpreted_exec;
- bool last_row;
- bool m_use_rowid;
-
- Signal* signal;
- Uint32 no_fired_triggers;
- Uint32 frag_page_id;
- Uint32 hash_value;
- Uint32 gci;
- Uint32 log_size;
- Uint32 read_length;
- Uint32 attrinfo_len;
- Uint32 tc_operation_ptr;
- Uint32 trans_id1;
- Uint32 trans_id2;
- Uint32 TC_index;
- // next 2 apply only to attrids >= 64 (zero otherwise)
- Uint32 max_attr_id_updated;
- Uint32 no_changed_attrs;
- BlockReference TC_ref;
- BlockReference rec_blockref;
- bool change_mask_calculated;
- /*
- * A bit mask where a bit set means that the update or insert
- * was updating this record.
- */
- Bitmask<MAXNROFATTRIBUTESINWORDS> changeMask;
- Uint16 var_pos_array[2*MAX_ATTRIBUTES_IN_TABLE + 1];
- OperationrecPtr prevOpPtr;
-};
-
- friend class Undo_buffer;
- Undo_buffer c_undo_buffer;
-
-/*
- No longer used:
- Implemented by shift instructions in subroutines instead
-
-struct TupHeadInfo {
- struct BitPart {
- unsigned int disk_indicator : 1;
- unsigned int var_part_loc_ind : 1;
- unsigned int initialised : 1;
- unsigned int not_used_yet : 5;
- unsigned int no_var_sized : 8;
- unsigned int tuple_version : 16;
- };
- union {
- Uint32 all;
- BitPart bit_part;
- };
-};
-*/
-
-// updateAttributes module
- Uint32 terrorCode;
-
-public:
- Dbtup(Block_context&, Pgman*);
- virtual ~Dbtup();
-
- /*
- * TUX uses logical tuple address when talking to ACC and LQH.
- */
- void tuxGetTupAddr(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32& tupAddr);
-
- /*
- * TUX index in TUP has single Uint32 array attribute which stores an
- * index node. TUX reads and writes the node directly via pointer.
- */
- int tuxAllocNode(Signal* signal, Uint32 fragPtrI, Uint32& pageId, Uint32& pageOffset, Uint32*& node);
- void tuxFreeNode(Signal* signal, Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* node);
- void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node);
-
- /*
- * TUX reads primary table attributes for index keys. Tuple is
- * specified by location of original tuple and version number. Input
- * is attribute ids in AttributeHeader format. Output is attribute
- * data with headers. Uses readAttributes with xfrm option set.
- * Returns number of words or negative (-terrorCode) on error.
- */
- int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut);
-
- /*
- * TUX reads primary key without headers into an array of words. Used
- * for md5 summing and when returning keyinfo. Returns number of
- * words or negative (-terrorCode) on error.
- */
- int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag);
-
- /*
- * ACC reads primary key without headers into an array of words. At
- * this point in ACC deconstruction, ACC still uses logical references
- * to fragment and tuple.
- */
- int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag);
-
- /*
- * TUX checks if tuple is visible to scan.
- */
- bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savepointId);
-
- int load_diskpage(Signal*, Uint32 opRec, Uint32 fragPtrI,
- Uint32 local_key, Uint32 flags);
-
- int load_diskpage_scan(Signal*, Uint32 opRec, Uint32 fragPtrI,
- Uint32 local_key, Uint32 flags);
-
- int alloc_page(Tablerec*, Fragrecord*, PagePtr*,Uint32 page_no);
-
- void start_restore_lcp(Uint32 tableId, Uint32 fragmentId);
- void complete_restore_lcp(Uint32 tableId, Uint32 fragmentId);
-
- int nr_read_pk(Uint32 fragPtr, const Local_key*, Uint32* dataOut, bool&copy);
- int nr_update_gci(Uint32 fragPtr, const Local_key*, Uint32 gci);
- int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
-
- void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
- void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
-
- bool get_frag_info(Uint32 tableId, Uint32 fragId, Uint32* maxPage);
-private:
- BLOCK_DEFINES(Dbtup);
-
- // Transit signals
- void execDEBUG_SIG(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- // Received signals
- void execLCP_FRAG_ORD(Signal*signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execSEND_PACKED(Signal* signal);
- void execSTTOR(Signal* signal);
- void execTUP_LCPREQ(Signal* signal);
- void execEND_LCPREQ(Signal* signal);
- void execSTART_RECREQ(Signal* signal);
- void execMEMCHECKREQ(Signal* signal);
- void execTUPSEIZEREQ(Signal* signal);
- void execTUPRELEASEREQ(Signal* signal);
- void execSTORED_PROCREQ(Signal* signal);
- void execTUPFRAGREQ(Signal* signal);
- void execTUP_ADD_ATTRREQ(Signal* signal);
- void execTUP_COMMITREQ(Signal* signal);
- void execTUP_ABORTREQ(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDROP_TAB_REQ(Signal* signal);
- void execALTER_TAB_REQ(Signal* signal);
- void execTUP_DEALLOCREQ(Signal* signal);
- void execTUP_WRITELOG_REQ(Signal* signal);
-
- // Ordered index related
- void execBUILDINDXREQ(Signal* signal);
- void buildIndex(Signal* signal, Uint32 buildPtrI);
- void buildIndexReply(Signal* signal, const BuildIndexRec* buildRec);
-
- // Tup scan
- void execACC_SCANREQ(Signal* signal);
- void execNEXT_SCANREQ(Signal* signal);
- void execACC_CHECK_SCAN(Signal* signal);
- void execACCKEYCONF(Signal* signal);
- void execACCKEYREF(Signal* signal);
- void execACC_ABORTCONF(Signal* signal);
-
-
- // Drop table
- void execFSREMOVEREF(Signal*);
- void execFSREMOVECONF(Signal*);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-// Methods to handle execution of TUPKEYREQ + ATTRINFO.
-//
-// Module Execution Manager
-//
-// The TUPKEYREQ signal is central to this block. This signal is used
-// by everybody that needs to read data residing in DBTUP. The data is
-// read using an interpreter approach.
-//
-// Operations only needing to read execute a simplified version of the
-// interpreter where the only instruction is read Attribute to send.
-// Operations only needing to update the record (insert or update)
-// execute a simplified version of the interpreter where the only
-// instruction is write Attribute.
-//
-// Currently TUPKEYREQ is used in the following situations.
-// 1) Normal transaction execution. Can be any of the types described
-// below.
-// 2) Execution of fragment redo log during system restart.
-// In this situation there will only be normal updates, inserts
-// and deletes performed.
-// 3) A special type of normal transaction execution is to write the
-// records arriving from the primary replica in the node restart
-// processing. This will always be normal write operations which
-// are translated to inserts or updates before arriving to TUP.
-// 4) Scan processing. The scan processing will use normal reads or
-// interpreted reads in their execution. There will be one TUPKEYREQ
-// signal for each record processed.
-// 5) Copy fragment processing. This is a special type of scan used in the
-// primary replica at system restart. It reads the entire reads and
-// converts those to writes to the starting node. In this special case
-// LQH acts as an API node and receives also the ATTRINFO sent in the
-// TRANSID_AI signals.
-//
-// Signal Diagram:
-//
-// In Signals:
-// -----------
-//
-// Logically there is one request TUPKEYREQ which requests to read/write data
-// of one tuple in the database. Since the definition of what to read and write
-// can be bigger than the maximum signal size we segment the signal. The definition
-// of what to read/write/interpreted program is sent before the TUPKEYREQ signal.
-//
-// ---> ATTRINFO
-// ...
-// ---> ATTRINFO
-// ---> TUPKEYREQ
-// The number of ATTRINFO signals can be anything between 0 and upwards.
-// The total size of the ATTRINFO is not allowed to be more than 16384 words.
-// There is always one and only one TUPKEYREQ.
-//
-// Response Signals (successful case):
-//
-// Simple/Dirty Read Operation
-// ---------------------------
-//
-// <---- TRANSID_AI (to API)
-// ...
-// <---- TRANSID_AI (to API)
-// <---- READCONF (to API)
-// <---- TUPKEYCONF (to LQH)
-// There is always exactly one READCONF25 sent last. The number of
-// TRANSID_AI is dependent on how much that was read. The maximum size
-// of the ATTRINFO sent back is 16384 words. The signals are sent
-// directly to the application with an address provided by the
-// TUPKEYREQ signal.
-// A positive response signal is also sent to LQH.
-//
-// Normal Read Operation
-// ---------------------
-//
-// <---- TRANSID_AI (to API)
-// ...
-// <---- TRANSID_AI (to API)
-// <---- TUPKEYCONF (to LQH)
-// The number of TRANSID_AI is dependent on how much that was read.
-// The maximum size of the ATTRINFO sent back is 16384 words. The
-// signals are sent directly to the application with an address
-// provided by the TUPKEYREQ signal.
-// A positive response signal is also sent to LQH.
-//
-// Normal update/insert/delete operation
-// -------------------------------------
-//
-// <---- TUPKEYCONF
-// After successful updating of the tuple LQH is informed of this.
-//
-// Delete with read
-// ----------------
-//
-// Will behave as a normal read although it also prepares the
-// deletion of the tuple.
-//
-// Interpreted Update
-// ------------------
-//
-// <---- TRANSID_AI (to API)
-// ...
-// <---- TRANSID_AI (to API)
-// <---- TUP_ATTRINFO (to LQH)
-// ...
-// <---- TUP_ATTRINFO (to LQH)
-// <---- TUPKEYCONF (to LQH)
-//
-// The interpreted Update contains five sections:
-// The first section performs read Attribute operations
-// that send results back to the API.
-//
-// The second section executes the interpreted program
-// where data from attributes can be updated and it
-// can also read attribute values into the registers.
-//
-// The third section performs unconditional updates of
-// attributes.
-//
-// The fourth section can read the attributes to be sent to the
-// API after updating the record.
-//
-// The fifth section contains subroutines used by the interpreter
-// in the second section.
-//
-// All types of interpreted programs contains the same five sections.
-// The only difference is that only interpreted updates can update
-// attributes. Interpreted inserts are not allowed.
-//
-// Interpreted Updates have to send back the information about the
-// attributes they have updated. This information will be shipped to
-// the log and also to any other replicas. Thus interpreted updates
-// are only performed in the primary replica. The fragment redo log
-// in LQH will contain information so that normal update/inserts/deletes
-// can be performed using TUPKEYREQ.
-//
-// Interpreted Read
-// ----------------
-//
-// From a signalling point of view the Interpreted Read behaves as
-// as a Normal Read. The interpreted Read is often used by Scan's.
-//
-// Interpreted Delete
-// ------------------
-//
-// <---- TUPKEYCONF
-// After successful prepartion to delete the tuple LQH is informed
-// of this.
-//
-// Interpreted Delete with Read
-// ----------------------------
-//
-// From a signalling point of view an interpreted delete with read
-// behaves as a normal read.
-//
-// Continuation after successful case:
-//
-// After a read of any kind the operation record is ready to be used
-// again by a new operation.
-//
-// Any updates, inserts or deletes waits for either of two messages.
-// A commit specifying that the operation is to be performed for real
-// or an abort specifying that the operation is to be rolled back and
-// the record to be restored in its original format.
-//
-// This is handled by the module Transaction Manager.
-//
-// Response Signals (unsuccessful case):
-//
-// <---- TUPKEYREF (to LQH)
-// A signal is sent back to LQH informing about the unsuccessful
-// operation. In this case TUP waits for an abort signal to arrive
-// before the operation record is ready for the next operation.
-// This is handled by the Transaction Manager.
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-
-// *****************************************************************
-// Signal Reception methods.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void execTUPKEYREQ(Signal* signal);
- void disk_page_load_callback(Signal*, Uint32 op, Uint32 page);
- void disk_page_load_scan_callback(Signal*, Uint32 op, Uint32 page);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void execATTRINFO(Signal* signal);
-public:
- void receive_attrinfo(Signal*, Uint32 op, const Uint32* data, Uint32 len);
-private:
-
-// Trigger signals
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void execCREATE_TRIG_REQ(Signal* signal);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void execDROP_TRIG_REQ(Signal* signal);
-
-// *****************************************************************
-// Support methods for ATTRINFO.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void handleATTRINFOforTUPKEYREQ(Signal* signal,
- const Uint32* data,
- Uint32 length,
- Operationrec * regOperPtr);
-
-// *****************************************************************
-// Setting up the environment for reads, inserts, updates and deletes.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int handleReadReq(Signal* signal,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int handleUpdateReq(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct,
- bool disk);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int handleInsertReq(Signal* signal,
- Ptr<Operationrec> regOperPtr,
- Ptr<Fragrecord>,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int handleDeleteReq(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct,
- bool disk);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int updateStartLab(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct);
-
-// *****************************************************************
-// Interpreter Handling methods.
-// *****************************************************************
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int interpreterStartLab(Signal* signal,
- KeyReqStruct *req_struct);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int interpreterNextLab(Signal* signal,
- KeyReqStruct *req_struct,
- Uint32* logMemory,
- Uint32* mainProgram,
- Uint32 TmainProgLen,
- Uint32* subroutineProg,
- Uint32 TsubroutineLen,
- Uint32 * tmpArea,
- Uint32 tmpAreaSz);
-
-// *****************************************************************
-// Signal Sending methods.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void sendReadAttrinfo(Signal* signal,
- KeyReqStruct *req_struct,
- Uint32 TnoOfData,
- const Operationrec * regOperPtr);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void sendLogAttrinfo(Signal* signal,
- Uint32 TlogSize,
- Operationrec * regOperPtr);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void sendTUPKEYCONF(Signal* signal,
- KeyReqStruct *req_struct,
- Operationrec * regOperPtr);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-// *****************************************************************
-// The methods that perform the actual read and update of attributes
-// in the tuple.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int readAttributes(KeyReqStruct* req_struct,
- const Uint32* inBuffer,
- Uint32 inBufLen,
- Uint32* outBuffer,
- Uint32 TmaxRead,
- bool xfrmFlag);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int updateAttributes(KeyReqStruct *req_struct,
- Uint32* inBuffer,
- Uint32 inBufLen);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHOneWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHTwoWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHManyWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHOneWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHOneWordNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHTwoWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHTwoWordNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHManyWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readFixedSizeTHZeroWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readVarSizeNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateVarSizeNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readVarSizeNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateVarSizeNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readDynFixedSize(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateDynFixedSize(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool readDynVarSize(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool updateDynVarSize(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2);
-
- bool readCharNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
- bool readCharNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
- bool readBitsNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
- bool updateBitsNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
- bool readBitsNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
- bool updateBitsNotNULL(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
-
- bool updateFixedNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
- bool updateFixedNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
-
- bool updateVarNULLable(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
- bool updateVarNotNull(Uint32* inBuffer, KeyReqStruct *req_struct, Uint32);
-
-
- bool readDiskFixedSizeNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
-
- bool readDiskFixedSizeNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2);
- bool readDiskVarSizeNULLable(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
- bool readDiskVarSizeNotNULL(Uint32* outBuffer, KeyReqStruct *req_struct, AttributeHeader*, Uint32);
-
- bool updateDiskFixedSizeNULLable(Uint32*, KeyReqStruct*, Uint32);
- bool updateDiskFixedSizeNotNULL(Uint32*, KeyReqStruct*, Uint32);
-
- bool updateDiskVarSizeNULLable(Uint32*, KeyReqStruct *, Uint32);
- bool updateDiskVarSizeNotNULL(Uint32*, KeyReqStruct *, Uint32);
-
- bool readDiskBitsNULLable(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
- bool readDiskBitsNotNULL(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
- bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
- bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
-
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2);
- bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2);
- Uint32 read_pseudo(Uint32 attrId,
- KeyReqStruct *req_struct,
- Uint32* outBuffer);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void setUpQueryRoutines(Tablerec* regTabPtr);
-
-// *****************************************************************
-// Service methods.
-// *****************************************************************
- TransState get_trans_state(Operationrec * const);
- void set_trans_state(Operationrec * const, TransState);
- TupleState get_tuple_state(Operationrec * const);
- void set_tuple_state(Operationrec * const, TupleState);
- Uint32 get_frag_page_id(Uint32 real_page_id);
- Uint32 get_fix_page_offset(Uint32 page_index, Uint32 tuple_size);
-
- Uint32 decr_tup_version(Uint32 tuple_version);
- void set_change_mask_state(Operationrec * const, ChangeMaskState);
- ChangeMaskState get_change_mask_state(Operationrec * const);
- void update_change_mask_info(KeyReqStruct * const, Operationrec * const);
- void set_change_mask_info(KeyReqStruct * const, Operationrec * const);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void copyAttrinfo(Operationrec * regOperPtr, Uint32* inBuffer);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void initOpConnection(Operationrec* regOperPtr);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void initOperationrec(Signal* signal);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int initStoredOperationrec(Operationrec* regOperPtr,
- KeyReqStruct* req_struct,
- Uint32 storedId);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- bool insertActiveOpList(OperationrecPtr, KeyReqStruct* req_struct);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen);
-
-//------------------------------------------------------------------
-// Trigger handling routines
-//------------------------------------------------------------------
- DLList<TupTriggerData>*
- findTriggerList(Tablerec* table,
- TriggerType::Value ttype,
- TriggerActionTime::Value ttime,
- TriggerEvent::Value tevent);
-
- bool createTrigger(Tablerec* table, const CreateTrigReq* req);
-
- Uint32 dropTrigger(Tablerec* table,
- const DropTrigReq* req,
- BlockNumber sender);
-
- void
- checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* tablePtr,
- bool disk);
-
- void
- checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* tablePtr,
- bool disk);
-
- void
- checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* tablePtr,
- bool disk);
-
-#if 0
- void checkDeferredTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Tablerec* regTablePtr);
-#endif
- void checkDetachedTriggers(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTablePtr,
- bool disk);
-
- void fireImmediateTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* regOperPtr,
- bool disk);
-
- void fireDeferredTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* regOperPtr);
-
- void fireDetachedTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* regOperPtr,
- bool disk);
-
- void executeTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* regOperPtr,
- bool disk);
-
- void executeTrigger(KeyReqStruct *req_struct,
- TupTriggerData* trigPtr,
- Operationrec* regOperPtr,
- bool disk);
-
- bool readTriggerInfo(TupTriggerData* trigPtr,
- Operationrec* regOperPtr,
- KeyReqStruct * req_struct,
- Fragrecord* regFragPtr,
- Uint32* keyBuffer,
- Uint32& noPrimKey,
- Uint32* afterBuffer,
- Uint32& noAfterWords,
- Uint32* beforeBuffer,
- Uint32& noBeforeWords,
- bool disk);
-
- void sendTrigAttrInfo(Signal* signal,
- Uint32* data,
- Uint32 dataLen,
- bool executeDirect,
- BlockReference receiverReference);
-
- Uint32 setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask,
- Uint32 noOfAttributes,
- Uint32* inBuffer);
-
- void sendFireTrigOrd(Signal* signal,
- KeyReqStruct *req_struct,
- Operationrec * regOperPtr,
- TupTriggerData* trigPtr,
- Uint32 fragmentId,
- Uint32 noPrimKeySignals,
- Uint32 noBeforeSignals,
- Uint32 noAfterSignals);
-
- bool primaryKey(Tablerec* const, Uint32);
-
- // these set terrorCode and return non-zero on error
-
- int executeTuxInsertTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- int executeTuxUpdateTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- int executeTuxDeleteTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- int addTuxEntries(Signal* signal,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr);
-
- // these crash the node on error
-
- void executeTuxCommitTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- void executeTuxAbortTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- void removeTuxEntries(Signal* signal,
- Tablerec* regTabPtr);
-
-// *****************************************************************
-// Error Handling routines.
-// *****************************************************************
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- int TUPKEY_abort(Signal* signal, int error_type);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
- void tupkeyErrorLab(Signal* signal);
- void do_tup_abortreq(Signal*, Uint32 flags);
-
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-// Methods to handle execution of TUP_COMMITREQ + TUP_ABORTREQ.
-//
-// Module Transaction Manager
-//
-// The Transaction Manager module is responsible for the commit
-// and abort of operations started by the Execution Manager.
-//
-// Commit Operation:
-// ----------------
-//
-// Failures in commit processing is not allowed since that would
-// leave the database in an unreliable state. Thus the only way
-// to handle failures in commit processing is to crash the node.
-//
-// TUP_COMMITREQ can only be received in the wait state after a
-// successful TUPKEYREQ which was not a read operation.
-//
-// Commit of Delete:
-// -----------------
-//
-// This will actually perform the deletion of the record unless
-// other operations also are connected to the record. In this case
-// we will set the delete state on the record that becomes the ownerd
-// of the record.
-//
-// Commit of Update:
-// ----------------
-//
-// We will release the copy record where the original record was kept.
-// Also here we will take special care if more operations are updating
-// the record simultaneously.
-//
-// Commit of Insert:
-// -----------------
-//
-// Will simply reset the state of the operation record.
-//
-// Signal Diagram:
-// ---> TUP_COMMITREQ (from LQH)
-// <---- TUP_COMMITCONF (to LQH)
-//
-//
-// Abort Operation:
-// ----------------
-//
-// Signal Diagram:
-// ---> TUP_ABORTREQ (from LQH)
-// <---- TUP_ABORTCONF (to LQH)
-//
-// Failures in abort processing is not allowed since that would
-// leave the database in an unreliable state. Thus the only way
-// to handle failures in abort processing is to crash the node.
-//
-// Abort messages can arrive at any time. It can arrive even before
-// anything at all have arrived of the operation. It can arrive after
-// receiving a number of ATTRINFO but before TUPKEYREQ has been received.
-// It must arrive after that we sent TUPKEYREF in response to TUPKEYREQ
-// and finally it can arrive after successfully performing the TUPKEYREQ
-// in all cases including the read case.
-//------------------------------------------------------------------
-//------------------------------------------------------------------
-
-#if 0
- void checkPages(Fragrecord* regFragPtr);
-#endif
- Uint32 convert_byte_to_word_size(Uint32 byte_size)
- {
- return ((byte_size + 3) >> 2);
- }
- Uint32 convert_bit_to_word_size(Uint32 bit_size)
- {
- return ((bit_size + 31) >> 5);
- }
-
- void prepare_initial_insert(KeyReqStruct*, Operationrec*, Tablerec*);
- void fix_disk_insert_no_mem_insert(KeyReqStruct*, Operationrec*, Tablerec*);
- void setup_fixed_part(KeyReqStruct* req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr);
-
- void send_TUPKEYREF(Signal* signal,
- Operationrec* regOperPtr);
- void early_tupkey_error(Signal* signal);
-
- void printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit);
-
- bool checkUpdateOfPrimaryKey(KeyReqStruct *req_struct,
- Uint32* updateBuffer,
- Tablerec* regTabPtr);
-
- void setNullBits(Uint32*, Tablerec* regTabPtr);
- bool checkNullAttributes(KeyReqStruct * const, Tablerec* const);
- bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
- bool setup_read(KeyReqStruct* req_struct,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- bool disk);
-
- Uint32 calculateChecksum(Tuple_header*, Tablerec* regTabPtr);
- void setChecksum(Tuple_header*, Tablerec* regTabPtr);
-
- void complexTrigger(Signal* signal,
- KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- void setTupleStatesSetOpType(Operationrec* regOperPtr,
- KeyReqStruct *req_struct,
- Page* pagePtr,
- Uint32& opType,
- OperationrecPtr& firstOpPtr);
-
- void findBeforeValueOperation(OperationrecPtr& befOpPtr,
- OperationrecPtr firstOpPtr);
-
- void calculateChangeMask(Page* PagePtr,
- Tablerec* regTabPtr,
- KeyReqStruct * req_struct);
-
- void updateGcpId(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr);
-
- void setTupleStateOnPreviousOps(Uint32 prevOpIndex);
- void copyMem(Signal* signal, Uint32 sourceIndex, Uint32 destIndex);
-
- void freeAllAttrBuffers(Operationrec* const regOperPtr);
- void freeAttrinbufrec(Uint32 anAttrBufRec);
- void removeActiveOpList(Operationrec* const regOperPtr, Tuple_header*);
-
- void updatePackedList(Signal* signal, Uint16 ahostIndex);
-
- void setUpDescriptorReferences(Uint32 descriptorReference,
- Tablerec* regTabPtr,
- const Uint32* offset);
- void setUpKeyArray(Tablerec* regTabPtr);
- bool addfragtotab(Tablerec* regTabPtr, Uint32 fragId, Uint32 fragIndex);
- void deleteFragTab(Tablerec* regTabPtr, Uint32 fragId);
- void abortAddFragOp(Signal* signal);
- void releaseTabDescr(Tablerec* regTabPtr);
- void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* regTabPtr);
-
- void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32);
- void initializeAttrbufrec();
- void initializeCheckpointInfoRec();
- void initializeDiskBufferSegmentRecord();
- void initializeFragoperrec();
- void initializeFragrecord();
- void initializeHostBuffer();
- void initializeLocalLogInfo();
- void initializeOperationrec();
- void initializePendingFileOpenInfoRecord();
- void initializeRestartInfoRec();
- void initializeTablerec();
- void initializeTabDescr();
- void initializeUndoPage();
-
- void initTab(Tablerec* regTabPtr);
-
- void startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2);
-
- void fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr);
- void fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr);
- void fragrefuse2Lab(Signal* signal, FragoperrecPtr fragOperPtr, FragrecordPtr regFragPtr);
- void fragrefuse3Lab(Signal* signal,
- FragoperrecPtr fragOperPtr,
- FragrecordPtr regFragPtr,
- Tablerec* regTabPtr,
- Uint32 fragId);
- void fragrefuse4Lab(Signal* signal,
- FragoperrecPtr fragOperPtr,
- FragrecordPtr regFragPtr,
- Tablerec* regTabPtr,
- Uint32 fragId);
- void addattrrefuseLab(Signal* signal,
- FragrecordPtr regFragPtr,
- FragoperrecPtr fragOperPtr,
- Tablerec* regTabPtr,
- Uint32 fragId);
-
-
- void releaseFragment(Signal* signal, Uint32 tableId, Uint32);
- void drop_fragment_free_var_pages(Signal*);
- void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
- void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
- void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
- void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
- void drop_fragment_fsremove(Signal*, TablerecPtr, FragrecordPtr);
- void drop_fragment_fsremove_done(Signal*, TablerecPtr, FragrecordPtr);
-
- // Initialisation
- void initData();
- void initRecords();
-
- void deleteScanProcedure(Signal* signal, Operationrec* regOperPtr);
- void copyProcedure(Signal* signal,
- TablerecPtr regTabPtr,
- Operationrec* regOperPtr);
- void scanProcedure(Signal* signal,
- Operationrec* regOperPtr,
- Uint32 lenAttrInfo);
- void storedSeizeAttrinbufrecErrorLab(Signal* signal,
- Operationrec* regOperPtr,
- Uint32 errorCode);
- bool storedProcedureAttrInfo(Signal* signal,
- Operationrec* regOperPtr,
- const Uint32* data,
- Uint32 length,
- bool copyProc);
-
-//-----------------------------------------------------------------------------
-// Table Descriptor Memory Manager
-//-----------------------------------------------------------------------------
-
-// Public methods
- Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset);
- Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset);
- void freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal = true);
- Uint32 getTabDescrWord(Uint32 index);
- void setTabDescrWord(Uint32 index, Uint32 word);
-
-// Private methods
- Uint32 sizeOfReadFunction();
- void removeTdArea(Uint32 tabDesRef, Uint32 list);
- void insertTdArea(Uint32 tabDesRef, Uint32 list);
- void itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
-#ifdef VM_TRACE
- void verifytabdes();
-#endif
-
- void seizeOpRec(OperationrecPtr& regOperPtr);
- void seizeFragrecord(FragrecordPtr& regFragPtr);
- void seizeFragoperrec(FragoperrecPtr& fragOperPtr);
- void releaseFragoperrec(FragoperrecPtr fragOperPtr);
- void releaseFragrec(FragrecordPtr);
-//----------------------------------------------------------------------------
-// Page Memory Manager
-//----------------------------------------------------------------------------
-
-// Public methods
- void allocConsPages(Uint32 noOfPagesToAllocate,
- Uint32& noOfPagesAllocated,
- Uint32& allocPageRef);
- void returnCommonArea(Uint32 retPageRef, Uint32 retNo);
- void initializePage();
-
-// Private methods
- void removeCommonArea(Uint32 remPageRef, Uint32 list);
- void insertCommonArea(Uint32 insPageRef, Uint32 list);
- void findFreeLeftNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
- void findFreeRightNeighbours(Uint32& allocPageRef, Uint32& noPagesAllocated, Uint32 noPagesToAllocate);
- Uint32 nextHigherTwoLog(Uint32 input);
-
-// Private data
- Uint32 cfreepageList[16];
-
-//------------------------------------------------------------------------------------------------------
-// Page Mapper, convert logical page id's to physical page id's
-// The page mapper also handles the pages allocated to the fragment.
-//------------------------------------------------------------------------------------------------------
-//
-// Public methods
- Uint32 getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId);
- Uint32 getNoOfPages(Fragrecord* regFragPtr);
- void initPageRangeSize(Uint32 size);
- bool insertPageRangeTab(Fragrecord* regFragPtr,
- Uint32 startPageId,
- Uint32 noPages);
- void releaseFragPages(Fragrecord* regFragPtr);
- void initFragRange(Fragrecord* regFragPtr);
- void initializePageRange();
- Uint32 getEmptyPage(Fragrecord* regFragPtr);
- Uint32 allocFragPages(Fragrecord* regFragPtr, Uint32 noOfPagesAllocated);
- Uint32 get_empty_var_page(Fragrecord* frag_ptr);
-
-// Private methods
- Uint32 leafPageRangeFull(Fragrecord* regFragPtr, PageRangePtr currPageRangePtr);
- void releasePagerange(PageRangePtr regPRPtr);
- void seizePagerange(PageRangePtr& regPageRangePtr);
- void errorHandler(Uint32 errorCode);
- void allocMoreFragPages(Fragrecord* regFragPtr);
-
-// Private data
- Uint32 cfirstfreerange;
- PageRange *pageRange;
- Uint32 c_noOfFreePageRanges;
- Uint32 cnoOfPageRangeRec;
-
-//---------------------------------------------------------------
-// Variable Allocator
-// Allocates and deallocates tuples of fixed size on a fragment.
-//---------------------------------------------------------------
-//
-// Public methods
-
- void init_list_sizes(void);
-
-// Private methods
-
- Uint32 get_alloc_page(Fragrecord* const, Uint32);
- void update_free_page_list(Fragrecord* const, Ptr<Page>);
-
-#if 0
- Uint32 calc_free_list(const Tablerec* regTabPtr, Uint32 sz) const {
- return regTabPtr->m_disk_alloc_info.calc_page_free_bits(sz);
- }
-#endif
-
- Uint32 calculate_free_list_impl(Uint32) const ;
- void remove_free_page(Fragrecord*, Var_page*, Uint32);
- void insert_free_page(Fragrecord*, Var_page*, Uint32);
-
-//---------------------------------------------------------------
-// Fixed Allocator
-// Allocates and deallocates tuples of fixed size on a fragment.
-//---------------------------------------------------------------
-//
-// Public methods
- Uint32* alloc_var_rec(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
- void free_var_rec(Fragrecord*, Tablerec*, Local_key*, Ptr<Page>);
- Uint32* alloc_var_part(Fragrecord*, Tablerec*, Uint32, Local_key*);
- int realloc_var_part(Fragrecord*, Tablerec*,
- PagePtr, Var_part_ref*, Uint32, Uint32);
-
- void validate_page(Tablerec*, Var_page* page);
-
- Uint32* alloc_fix_rec(Fragrecord*const, Tablerec*const, Local_key*,
- Uint32*);
- void free_fix_rec(Fragrecord*, Tablerec*, Local_key*, Fix_page*);
-
- Uint32* alloc_fix_rowid(Fragrecord*, Tablerec*, Local_key*, Uint32 *);
- Uint32* alloc_var_rowid(Fragrecord*, Tablerec*, Uint32, Local_key*, Uint32*);
-// Private methods
- void convertThPage(Fix_page* regPagePtr,
- Tablerec*,
- Uint32 mm);
-
- /**
- * Return offset
- */
- Uint32 alloc_tuple_from_page(Fragrecord* regFragPtr,
- Fix_page* regPagePtr);
-
-//---------------------------------------------------------------
-// Temporary variables used for storing commonly used variables
-// in certain modules
-//---------------------------------------------------------------
-
- Uint32 c_lcp_scan_op;
- FragrecordPtr fragptr;
- OperationrecPtr operPtr;
- TablerecPtr tabptr;
-
-// readAttributes and updateAttributes module
-//------------------------------------------------------------------------------------------------------
-// Common stored variables. Variables that have a valid value always.
-//------------------------------------------------------------------------------------------------------
- Attrbufrec *attrbufrec;
- Uint32 cfirstfreeAttrbufrec;
- Uint32 cnoOfAttrbufrec;
- Uint32 cnoFreeAttrbufrec;
-
- Fragoperrec *fragoperrec;
- Uint32 cfirstfreeFragopr;
- Uint32 cnoOfFragoprec;
-
- Fragrecord *fragrecord;
- Uint32 cfirstfreefrag;
- Uint32 cnoOfFragrec;
-
- HostBuffer *hostBuffer;
-
- ArrayPool<Operationrec> c_operation_pool;
-
- ArrayPool<Page> c_page_pool;
- Uint32 cnoOfAllocatedPages;
- Uint32 m_max_allocate_pages;
-
- /* read ahead in pages during disk order scan */
- Uint32 m_max_page_read_ahead;
-
- Tablerec *tablerec;
- Uint32 cnoOfTablerec;
-
- TableDescriptor *tableDescriptor;
- Uint32 cnoOfTabDescrRec;
-
- Uint32 cdata[32];
- Uint32 cdataPages[16];
- Uint32 cpackedListIndex;
- Uint32 cpackedList[MAX_NODES];
- Uint32 cfreeTdList[16];
- Uint32 clastBitMask;
- Uint32 clblPageCounter;
- Uint32 clblPagesPerTick;
- Uint32 clblPagesPerTickAfterSr;
- BlockReference clqhBlockref;
- Uint32 clqhUserpointer;
- Uint32 cminusOne;
- BlockReference cndbcntrRef;
- BlockReference cownref;
- Uint32 cownNodeId;
- Uint32 czero;
-
- // A little bit bigger to cover overwrites in copy algorithms (16384 real size).
-#define ZATTR_BUFFER_SIZE 16384
- Uint32 clogMemBuffer[ZATTR_BUFFER_SIZE + 16];
- Uint32 coutBuffer[ZATTR_BUFFER_SIZE + 16];
- Uint32 cinBuffer[ZATTR_BUFFER_SIZE + 16];
- Uint32 ctemp_page[ZWORDS_ON_PAGE];
- Uint32 ctemp_var_record[ZWORDS_ON_PAGE];
- Uint32 totNoOfPagesAllocated;
-
- // Trigger variables
- Uint32 c_maxTriggersPerTable;
- Uint32 c_memusage_report_frequency;
-
- Uint32 c_errorInsert4000TableId;
- Uint32 c_min_list_size[MAX_FREE_LIST + 1];
- Uint32 c_max_list_size[MAX_FREE_LIST + 1];
-
- void initGlobalTemporaryVars();
- void reportMemoryUsage(Signal* signal, int incDec);
-
-
-#ifdef VM_TRACE
- struct Th {
- Uint32 data[1];
- };
- friend class NdbOut& operator<<(NdbOut&, const Operationrec&);
- friend class NdbOut& operator<<(NdbOut&, const Th&);
-#endif
-
- void expand_tuple(KeyReqStruct*, Uint32 sizes[4], Tuple_header*org,
- const Tablerec*, bool disk);
- void shrink_tuple(KeyReqStruct*, Uint32 sizes[2], const Tablerec*,
- bool disk);
-
- Uint32* get_ptr(Var_part_ref);
- Uint32* get_ptr(PagePtr*, Var_part_ref);
- Uint32* get_ptr(PagePtr*, const Local_key*, const Tablerec*);
- Uint32* get_dd_ptr(PagePtr*, const Local_key*, const Tablerec*);
-
- /**
- * prealloc space from disk
- * key.m_file_no contains file no
- * key.m_page_no contains disk page
- * key.m_page_idx contains byte preallocated
- */
- int disk_page_prealloc(Signal*, Ptr<Fragrecord>, Local_key*, Uint32);
- void disk_page_prealloc_dirty_page(Disk_alloc_info&,
- Ptr<Page>, Uint32, Uint32);
- void disk_page_prealloc_transit_page(Disk_alloc_info&,
- Ptr<Page_request>, Uint32, Uint32);
-
- void disk_page_abort_prealloc(Signal*, Fragrecord*,Local_key*, Uint32);
- void disk_page_abort_prealloc_callback(Signal*, Uint32, Uint32);
- void disk_page_abort_prealloc_callback_1(Signal*, Fragrecord*,
- PagePtr, Uint32);
-
- void disk_page_prealloc_callback(Signal*, Uint32, Uint32);
- void disk_page_prealloc_initial_callback(Signal*, Uint32, Uint32);
- void disk_page_prealloc_callback_common(Signal*,
- Ptr<Page_request>,
- Ptr<Fragrecord>,
- Ptr<Page>);
-
- void disk_page_alloc(Signal*,
- Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
- void disk_page_free(Signal*,
- Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
-
- void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
-
- void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
-
- void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
- void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
-
- Uint64 disk_page_undo_alloc(Page*, const Local_key*,
- Uint32 sz, Uint32 gci, Uint32 logfile_group_id);
-
- Uint64 disk_page_undo_update(Page*, const Local_key*,
- const Uint32*, Uint32,
- Uint32 gci, Uint32 logfile_group_id);
-
- Uint64 disk_page_undo_free(Page*, const Local_key*,
- const Uint32*, Uint32 sz,
- Uint32 gci, Uint32 logfile_group_id);
-
- void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
- void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
-
- void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
- void drop_table_logsync_callback(Signal*, Uint32, Uint32);
-
- void disk_page_set_dirty(Ptr<Page>);
- void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
- void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
-
- /**
- * Disk restart code
- */
-public:
- int disk_page_load_hook(Uint32 page_id);
-
- void disk_page_unmap_callback(Uint32 when, Uint32 page, Uint32 dirty_count);
-
- int disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
- const Local_key* key, Uint32 pages);
- void disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
- const Local_key*, Uint32 bits);
- void disk_restart_undo(Signal* signal, Uint64 lsn,
- Uint32 type, const Uint32 * ptr, Uint32 len);
-
- struct Apply_undo
- {
- Uint32 m_type, m_len;
- const Uint32* m_ptr;
- Uint64 m_lsn;
- Ptr<Tablerec> m_table_ptr;
- Ptr<Fragrecord> m_fragment_ptr;
- Ptr<Page> m_page_ptr;
- Ptr<Extent_info> m_extent_ptr;
- Local_key m_key;
- };
-
- void disk_restart_lcp_id(Uint32 table, Uint32 frag, Uint32 lcpId);
-
-private:
- void disk_restart_undo_next(Signal*);
- void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag, Uint32 lcpId);
- void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
- void disk_restart_undo_alloc(Apply_undo*);
- void disk_restart_undo_update(Apply_undo*);
- void disk_restart_undo_free(Apply_undo*);
- void disk_restart_undo_page_bits(Signal*, Apply_undo*);
-
-#ifdef VM_TRACE
- void verify_page_lists(Disk_alloc_info&);
-#else
- void verify_page_lists(Disk_alloc_info&) {}
-#endif
-
- void findFirstOp(OperationrecPtr&);
- void commit_operation(Signal*, Uint32, Tuple_header*, PagePtr,
- Operationrec*, Fragrecord*, Tablerec*);
-
- void dealloc_tuple(Signal* signal, Uint32, Page*, Tuple_header*,
- Operationrec*, Fragrecord*, Tablerec*);
-
- int handle_size_change_after_update(KeyReqStruct* req_struct,
- Tuple_header* org,
- Operationrec*,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- Uint32 sizes[4]);
-
- /**
- * Setup all pointer on keyreqstruct to prepare for read
- * req_struct->m_tuple_ptr is set to tuple to read
- */
- void prepare_read(KeyReqStruct*, Tablerec* const, bool disk);
-};
-
-#if 0
-inline
-Uint32
-Dbtup::get_frag_page_id(Uint32 real_page_id)
-{
- PagePtr real_page_ptr;
- real_page_ptr.i= real_page_id;
- ptrCheckGuard(real_page_ptr, cnoOfPage, cpage);
- return real_page_ptr.p->frag_page_id;
-}
-#endif
-
-inline
-Dbtup::TransState
-Dbtup::get_trans_state(Operationrec * regOperPtr)
-{
- return (Dbtup::TransState)regOperPtr->op_struct.trans_state;
-}
-
-inline
-void
-Dbtup::set_trans_state(Operationrec* regOperPtr,
- Dbtup::TransState trans_state)
-{
- regOperPtr->op_struct.trans_state= (Uint32)trans_state;
-}
-
-inline
-Dbtup::TupleState
-Dbtup::get_tuple_state(Operationrec * regOperPtr)
-{
- return (Dbtup::TupleState)regOperPtr->op_struct.tuple_state;
-}
-
-inline
-void
-Dbtup::set_tuple_state(Operationrec* regOperPtr,
- Dbtup::TupleState tuple_state)
-{
- regOperPtr->op_struct.tuple_state= (Uint32)tuple_state;
-}
-
-
-inline
-Uint32
-Dbtup::decr_tup_version(Uint32 tup_version)
-{
- return (tup_version - 1) & ZTUP_VERSION_MASK;
-}
-
-inline
-Dbtup::ChangeMaskState
-Dbtup::get_change_mask_state(Operationrec * regOperPtr)
-{
- return (Dbtup::ChangeMaskState)regOperPtr->op_struct.change_mask_state;
-}
-
-inline
-void
-Dbtup::set_change_mask_state(Operationrec * regOperPtr,
- ChangeMaskState new_state)
-{
- regOperPtr->op_struct.change_mask_state= (Uint32)new_state;
-}
-
-inline
-void
-Dbtup::update_change_mask_info(KeyReqStruct * req_struct,
- Operationrec * regOperPtr)
-{
- if (req_struct->max_attr_id_updated == 0) {
- if (get_change_mask_state(regOperPtr) == USE_SAVED_CHANGE_MASK) {
- // add new changes
- regOperPtr->saved_change_mask[0] |= req_struct->changeMask.getWord(0);
- regOperPtr->saved_change_mask[1] |= req_struct->changeMask.getWord(1);
- }
- } else {
- if (req_struct->no_changed_attrs < 16) {
- set_change_mask_state(regOperPtr, RECALCULATE_CHANGE_MASK);
- } else {
- set_change_mask_state(regOperPtr, SET_ALL_MASK);
- }
- }
-}
-
-inline
-Uint32*
-Dbtup::get_ptr(Var_part_ref ref)
-{
- Ptr<Page> tmp;
- return get_ptr(&tmp, ref);
-}
-
-inline
-Uint32*
-Dbtup::get_ptr(Ptr<Page>* pagePtr, Var_part_ref ref)
-{
- PagePtr tmp;
- Local_key key;
- ref.copyout(&key);
- tmp.i = key.m_page_no;
-
- c_page_pool.getPtr(tmp);
- memcpy(pagePtr, &tmp, sizeof(tmp));
- return ((Var_page*)tmp.p)->get_ptr(key.m_page_idx);
-}
-
-inline
-Uint32*
-Dbtup::get_ptr(PagePtr* pagePtr,
- const Local_key* key, const Tablerec* regTabPtr)
-{
- PagePtr tmp;
- tmp.i= key->m_page_no;
- c_page_pool.getPtr(tmp);
- memcpy(pagePtr, &tmp, sizeof(tmp));
-
- return ((Fix_page*)tmp.p)->
- get_ptr(key->m_page_idx, regTabPtr->m_offsets[MM].m_fix_header_size);
-}
-
-inline
-Uint32*
-Dbtup::get_dd_ptr(PagePtr* pagePtr,
- const Local_key* key, const Tablerec* regTabPtr)
-{
- PagePtr tmp;
- tmp.i= key->m_page_no;
- tmp.p= (Page*)m_global_page_pool.getPtr(tmp.i);
- memcpy(pagePtr, &tmp, sizeof(tmp));
-
- if(regTabPtr->m_attributes[DD].m_no_of_varsize)
- return ((Var_page*)tmp.p)->get_ptr(key->m_page_idx);
- else
- return ((Fix_page*)tmp.p)->
- get_ptr(key->m_page_idx, regTabPtr->m_offsets[DD].m_fix_header_size);
-}
-
-NdbOut&
-operator<<(NdbOut&, const Dbtup::Tablerec&);
-
-inline
-bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
-{
- while (true) {
- if (savepointId > loopOpPtr.p->savepointId) {
- jam();
- return true;
- }
- loopOpPtr.i = loopOpPtr.p->prevActiveOp;
- if (loopOpPtr.i == RNIL) {
- break;
- }
- c_operation_pool.getPtr(loopOpPtr);
- }
- return false;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
deleted file mode 100644
index 7a000eb5042..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_ABORT_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-void Dbtup::freeAllAttrBuffers(Operationrec* const regOperPtr)
-{
- if (regOperPtr->storedProcedureId == RNIL) {
- jam();
- freeAttrinbufrec(regOperPtr->firstAttrinbufrec);
- } else {
- jam();
- StoredProcPtr storedPtr;
- c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId);
- ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
- storedPtr.p->storedCounter--;
- regOperPtr->storedProcedureId = ZNIL;
- }//if
- regOperPtr->firstAttrinbufrec = RNIL;
- regOperPtr->lastAttrinbufrec = RNIL;
- regOperPtr->m_any_value = 0;
-}//Dbtup::freeAllAttrBuffers()
-
-void Dbtup::freeAttrinbufrec(Uint32 anAttrBuf)
-{
- Uint32 Ttemp;
- AttrbufrecPtr localAttrBufPtr;
- Uint32 RnoFree = cnoFreeAttrbufrec;
- localAttrBufPtr.i = anAttrBuf;
- while (localAttrBufPtr.i != RNIL) {
- jam();
- ptrCheckGuard(localAttrBufPtr, cnoOfAttrbufrec, attrbufrec);
- Ttemp = localAttrBufPtr.p->attrbuf[ZBUF_NEXT];
- localAttrBufPtr.p->attrbuf[ZBUF_NEXT] = cfirstfreeAttrbufrec;
- cfirstfreeAttrbufrec = localAttrBufPtr.i;
- localAttrBufPtr.i = Ttemp;
- RnoFree++;
- }//if
- cnoFreeAttrbufrec = RnoFree;
-}//Dbtup::freeAttrinbufrec()
-
-/**
- * Abort abort this operation and all after (nextActiveOp's)
- */
-void Dbtup::execTUP_ABORTREQ(Signal* signal)
-{
- jamEntry();
- do_tup_abortreq(signal, 0);
-}
-
-void Dbtup::do_tup_abortreq(Signal* signal, Uint32 flags)
-{
- OperationrecPtr regOperPtr;
- FragrecordPtr regFragPtr;
- TablerecPtr regTabPtr;
-
- regOperPtr.i = signal->theData[0];
- c_operation_pool.getPtr(regOperPtr);
- TransState trans_state= get_trans_state(regOperPtr.p);
- ndbrequire((trans_state == TRANS_STARTED) ||
- (trans_state == TRANS_TOO_MUCH_AI) ||
- (trans_state == TRANS_ERROR_WAIT_TUPKEYREQ) ||
- (trans_state == TRANS_IDLE));
- if (regOperPtr.p->op_struct.op_type == ZREAD) {
- jam();
- freeAllAttrBuffers(regOperPtr.p);
- initOpConnection(regOperPtr.p);
- return;
- }//if
-
- regFragPtr.i = regOperPtr.p->fragmentPtr;
- ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
-
- regTabPtr.i = regFragPtr.p->fragTableId;
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-
- if (get_tuple_state(regOperPtr.p) == TUPLE_PREPARED)
- {
- jam();
- if (!regTabPtr.p->tuxCustomTriggers.isEmpty() &&
- (flags & ZSKIP_TUX_TRIGGERS) == 0)
- executeTuxAbortTriggers(signal,
- regOperPtr.p,
- regFragPtr.p,
- regTabPtr.p);
-
- OperationrecPtr loopOpPtr;
- loopOpPtr.i = regOperPtr.p->nextActiveOp;
- while (loopOpPtr.i != RNIL) {
- jam();
- c_operation_pool.getPtr(loopOpPtr);
- if (get_tuple_state(loopOpPtr.p) != TUPLE_ALREADY_ABORTED &&
- !regTabPtr.p->tuxCustomTriggers.isEmpty() &&
- (flags & ZSKIP_TUX_TRIGGERS) == 0) {
- jam();
- executeTuxAbortTriggers(signal,
- loopOpPtr.p,
- regFragPtr.p,
- regTabPtr.p);
- }
- set_tuple_state(loopOpPtr.p, TUPLE_ALREADY_ABORTED);
- loopOpPtr.i = loopOpPtr.p->nextActiveOp;
- }
- }
-
- PagePtr page;
- Tuple_header *tuple_ptr= (Tuple_header*)
- get_ptr(&page, &regOperPtr.p->m_tuple_location, regTabPtr.p);
-
- Uint32 bits= tuple_ptr->m_header_bits;
- if(regOperPtr.p->op_struct.op_type != ZDELETE)
- {
- Tuple_header *copy= (Tuple_header*)
- c_undo_buffer.get_ptr(&regOperPtr.p->m_copy_tuple_location);
-
- if(regOperPtr.p->op_struct.m_disk_preallocated)
- {
- jam();
- Local_key key;
- memcpy(&key, copy->get_disk_ref_ptr(regTabPtr.p), sizeof(key));
- disk_page_abort_prealloc(signal, regFragPtr.p, &key, key.m_page_idx);
- }
-
-
- Uint32 copy_bits= copy->m_header_bits;
- if(! (bits & Tuple_header::ALLOC))
- {
- if(copy_bits & Tuple_header::MM_GROWN)
- {
- if (0) ndbout_c("abort grow");
- Ptr<Page> vpage;
- Uint32 idx= regOperPtr.p->m_tuple_location.m_page_idx;
- Uint32 mm_vars= regTabPtr.p->m_attributes[MM].m_no_of_varsize;
- Uint32 *var_part;
-
- ndbassert(tuple_ptr->m_header_bits & Tuple_header::CHAINED_ROW);
-
- Var_part_ref *ref = tuple_ptr->get_var_part_ref_ptr(regTabPtr.p);
-
- Local_key tmp;
- ref->copyout(&tmp);
-
- idx= tmp.m_page_idx;
- var_part= get_ptr(&vpage, *ref);
- Var_page* pageP = (Var_page*)vpage.p;
- Uint32 len= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
- Uint32 sz = ((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
- ndbassert(sz <= len);
- pageP->shrink_entry(idx, sz);
- update_free_page_list(regFragPtr.p, vpage);
- }
- else if(bits & Tuple_header::MM_SHRINK)
- {
- if (0) ndbout_c("abort shrink");
- }
- }
- else if (regOperPtr.p->is_first_operation() &&
- regOperPtr.p->is_last_operation())
- {
- /**
- * Aborting last operation that performed ALLOC
- */
- tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
- tuple_ptr->m_header_bits |= Tuple_header::FREED;
- }
- }
- else if (regOperPtr.p->is_first_operation() &&
- regOperPtr.p->is_last_operation())
- {
- if (bits & Tuple_header::ALLOC)
- {
- tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
- tuple_ptr->m_header_bits |= Tuple_header::FREED;
- }
- }
-
- if(regOperPtr.p->is_first_operation() && regOperPtr.p->is_last_operation())
- {
- if (regOperPtr.p->m_undo_buffer_space)
- c_lgman->free_log_space(regFragPtr.p->m_logfile_group_id,
- regOperPtr.p->m_undo_buffer_space);
- }
-
- removeActiveOpList(regOperPtr.p, tuple_ptr);
- initOpConnection(regOperPtr.p);
-}
-
-/* **************************************************************** */
-/* ********************** TRANSACTION ERROR MODULE **************** */
-/* **************************************************************** */
-int Dbtup::TUPKEY_abort(Signal* signal, int error_type)
-{
- switch(error_type) {
- case 1:
-//tmupdate_alloc_error:
- terrorCode= ZMEM_NOMEM_ERROR;
- jam();
- break;
-
- case 15:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 16:
- jam();
- terrorCode = ZTRY_TO_UPDATE_ERROR;
- break;
-
- case 17:
- jam();
- terrorCode = ZNO_ILLEGAL_NULL_ATTR;
- break;
-
- case 19:
- jam();
- terrorCode = ZTRY_TO_UPDATE_ERROR;
- break;
-
- case 20:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 22:
- jam();
- terrorCode = ZTOTAL_LEN_ERROR;
- break;
-
- case 23:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 24:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 26:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 27:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 28:
- jam();
- terrorCode = ZREGISTER_INIT_ERROR;
- break;
-
- case 29:
- jam();
- break;
-
- case 30:
- jam();
- terrorCode = ZCALL_ERROR;
- break;
-
- case 31:
- jam();
- terrorCode = ZSTACK_OVERFLOW_ERROR;
- break;
-
- case 32:
- jam();
- terrorCode = ZSTACK_UNDERFLOW_ERROR;
- break;
-
- case 33:
- jam();
- terrorCode = ZNO_INSTRUCTION_ERROR;
- break;
-
- case 34:
- jam();
- terrorCode = ZOUTSIDE_OF_PROGRAM_ERROR;
- break;
-
- case 35:
- jam();
- terrorCode = ZTOO_MANY_INSTRUCTIONS_ERROR;
- break;
-
- case 38:
- jam();
- terrorCode = ZTEMPORARY_RESOURCE_FAILURE;
- break;
-
- case 39:
- if (get_trans_state(operPtr.p) == TRANS_TOO_MUCH_AI) {
- jam();
- terrorCode = ZTOO_MUCH_ATTRINFO_ERROR;
- } else if (get_trans_state(operPtr.p) == TRANS_ERROR_WAIT_TUPKEYREQ) {
- jam();
- terrorCode = ZSEIZE_ATTRINBUFREC_ERROR;
- } else {
- ndbrequire(false);
- }//if
- break;
- case 40:
- jam();
- terrorCode = ZUNSUPPORTED_BRANCH;
- break;
- default:
- ndbrequire(false);
- break;
- }//switch
- tupkeyErrorLab(signal);
- return -1;
-}
-
-void Dbtup::early_tupkey_error(Signal* signal)
-{
- Operationrec * const regOperPtr = operPtr.p;
- ndbrequire(!regOperPtr->op_struct.in_active_list);
- set_trans_state(regOperPtr, TRANS_IDLE);
- set_tuple_state(regOperPtr, TUPLE_PREPARED);
- initOpConnection(regOperPtr);
- send_TUPKEYREF(signal, regOperPtr);
-}
-
-void Dbtup::tupkeyErrorLab(Signal* signal)
-{
- Operationrec * const regOperPtr = operPtr.p;
- set_trans_state(regOperPtr, TRANS_IDLE);
- set_tuple_state(regOperPtr, TUPLE_PREPARED);
-
- FragrecordPtr fragPtr;
- fragPtr.i= regOperPtr->fragmentPtr;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- TablerecPtr tabPtr;
- tabPtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- if (regOperPtr->m_undo_buffer_space &&
- (regOperPtr->is_first_operation() && regOperPtr->is_last_operation()))
- {
- c_lgman->free_log_space(fragPtr.p->m_logfile_group_id,
- regOperPtr->m_undo_buffer_space);
- }
-
- Uint32 *ptr = 0;
- if (!regOperPtr->m_tuple_location.isNull())
- {
- PagePtr tmp;
- ptr= get_ptr(&tmp, &regOperPtr->m_tuple_location, tabPtr.p);
- }
-
-
- removeActiveOpList(regOperPtr, (Tuple_header*)ptr);
- initOpConnection(regOperPtr);
- send_TUPKEYREF(signal, regOperPtr);
-}
-
-void Dbtup::send_TUPKEYREF(Signal* signal,
- Operationrec* const regOperPtr)
-{
- TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtrSend();
- tupKeyRef->userRef = regOperPtr->userpointer;
- tupKeyRef->errorCode = terrorCode;
- sendSignal(DBLQH_REF, GSN_TUPKEYREF, signal,
- TupKeyRef::SignalLength, JBB);
-}
-
-/**
- * Unlink one operation from the m_operation_ptr_i list in the tuple.
- */
-void Dbtup::removeActiveOpList(Operationrec* const regOperPtr,
- Tuple_header *tuple_ptr)
-{
- OperationrecPtr raoOperPtr;
-
- if(!regOperPtr->m_copy_tuple_location.isNull())
- {
- jam();
- c_undo_buffer.free_copy_tuple(&regOperPtr->m_copy_tuple_location);
- }
-
- if (regOperPtr->op_struct.in_active_list) {
- regOperPtr->op_struct.in_active_list= false;
- if (regOperPtr->nextActiveOp != RNIL) {
- jam();
- raoOperPtr.i= regOperPtr->nextActiveOp;
- c_operation_pool.getPtr(raoOperPtr);
- raoOperPtr.p->prevActiveOp= regOperPtr->prevActiveOp;
- } else {
- jam();
- tuple_ptr->m_operation_ptr_i = regOperPtr->prevActiveOp;
- }
- if (regOperPtr->prevActiveOp != RNIL) {
- jam();
- raoOperPtr.i= regOperPtr->prevActiveOp;
- c_operation_pool.getPtr(raoOperPtr);
- raoOperPtr.p->nextActiveOp= regOperPtr->nextActiveOp;
- }
- regOperPtr->prevActiveOp= RNIL;
- regOperPtr->nextActiveOp= RNIL;
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp
deleted file mode 100644
index 2f8151acca1..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_BUFFER_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <signaldata/TransIdAI.hpp>
-
-void Dbtup::execSEND_PACKED(Signal* signal)
-{
- Uint16 hostId;
- Uint32 i;
- Uint32 TpackedListIndex= cpackedListIndex;
- jamEntry();
- for (i= 0; i < TpackedListIndex; i++) {
- jam();
- hostId= cpackedList[i];
- ndbrequire((hostId - 1) < (MAX_NODES - 1)); // Also check not zero
- Uint32 TpacketTA= hostBuffer[hostId].noOfPacketsTA;
- if (TpacketTA != 0) {
- jam();
- BlockReference TBref= numberToRef(API_PACKED, hostId);
- Uint32 TpacketLen= hostBuffer[hostId].packetLenTA;
- MEMCOPY_NO_WORDS(&signal->theData[0],
- &hostBuffer[hostId].packetBufferTA[0],
- TpacketLen);
- sendSignal(TBref, GSN_TRANSID_AI, signal, TpacketLen, JBB);
- hostBuffer[hostId].noOfPacketsTA= 0;
- hostBuffer[hostId].packetLenTA= 0;
- }
- hostBuffer[hostId].inPackedList= false;
- }//for
- cpackedListIndex= 0;
-}
-
-void Dbtup::bufferTRANSID_AI(Signal* signal, BlockReference aRef,
- Uint32 Tlen)
-{
- if (Tlen == 3)
- return;
-
- 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;
- Uint32 sig0= signal->theData[0];
- Uint32 sig1= signal->theData[1];
- Uint32 sig2= signal->theData[2];
-
- 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.
-// ----------------------------------------------------------------
- jam();
- updatePackedList(signal, hostId);
- } else if (false && 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].packetBufferTA[0] >> 16),
- hostId);
- MEMCOPY_NO_WORDS(&signal->theData[0],
- &hostBuffer[hostId].packetBufferTA[1],
- TpacketLen - 1);
- sendSignal(TnewRef, GSN_TRANSID_AI, 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].packetBufferTA[0],
- TpacketLen);
- sendSignal(TBref, GSN_TRANSID_AI, signal, TpacketLen, JBB);
- TpacketLen= 0;
- TnoOfPackets= 0;
- }
-// ----------------------------------------------------------------
-// Copy the signal into the buffer
-// ----------------------------------------------------------------
- hostBuffer[hostId].packetBufferTA[TpacketLen + 0]= Theader;
- hostBuffer[hostId].packetBufferTA[TpacketLen + 1]= sig0;
- hostBuffer[hostId].packetBufferTA[TpacketLen + 2]= sig1;
- hostBuffer[hostId].packetBufferTA[TpacketLen + 3]= sig2;
- hostBuffer[hostId].noOfPacketsTA= TnoOfPackets + 1;
- hostBuffer[hostId].packetLenTA= Tlen + TpacketLen + 1;
- MEMCOPY_NO_WORDS(&hostBuffer[hostId].packetBufferTA[TpacketLen + 4],
- &signal->theData[25],
- Tlen - 3);
-}
-
-void Dbtup::updatePackedList(Signal* signal, Uint16 hostId)
-{
- if (hostBuffer[hostId].inPackedList == false) {
- Uint32 TpackedListIndex= cpackedListIndex;
- jam();
- hostBuffer[hostId].inPackedList= true;
- cpackedList[TpackedListIndex]= hostId;
- cpackedListIndex= TpackedListIndex + 1;
- }
-}
-
-/* ---------------------------------------------------------------- */
-/* ----------------------- SEND READ ATTRINFO --------------------- */
-/* ---------------------------------------------------------------- */
-void Dbtup::sendReadAttrinfo(Signal* signal,
- KeyReqStruct *req_struct,
- Uint32 ToutBufIndex,
- const Operationrec *regOperPtr)
-{
- if(ToutBufIndex == 0)
- return;
-
- const BlockReference recBlockref= req_struct->rec_blockref;
- 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::MGM);
- bool old_dest= (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0));
- Uint32 TpacketLen= hostBuffer[nodeId].packetLenTA;
- Uint32 TpacketTA= hostBuffer[nodeId].noOfPacketsTA;
-
- if (ERROR_INSERTED(4006) && (nodeId != getOwnNodeId())){
- // Use error insert to turn routing on
- jam();
- connectedToNode= false;
- }
-
- Uint32 sig0= req_struct->tc_operation_ptr;
- Uint32 sig1= req_struct->trans_id1;
- Uint32 sig2= req_struct->trans_id2;
-
- TransIdAI * transIdAI= (TransIdAI *)signal->getDataPtrSend();
- transIdAI->connectPtr= sig0;
- transIdAI->transId[0]= sig1;
- transIdAI->transId[1]= sig2;
-
- if (connectedToNode){
- /**
- * Own node -> execute direct
- */
- if(nodeId != getOwnNodeId()){
- jam();
-
- /**
- * Send long sig
- */
- if (ToutBufIndex >= 22 && is_api && !old_dest) {
- jam();
- /**
- * Flush buffer so that order is maintained
- */
- if (TpacketTA != 0) {
- jam();
- BlockReference TBref = numberToRef(API_PACKED, nodeId);
- MEMCOPY_NO_WORDS(&signal->theData[0],
- &hostBuffer[nodeId].packetBufferTA[0],
- TpacketLen);
- sendSignal(TBref, GSN_TRANSID_AI, signal, TpacketLen, JBB);
- hostBuffer[nodeId].noOfPacketsTA = 0;
- hostBuffer[nodeId].packetLenTA = 0;
- transIdAI->connectPtr = sig0;
- transIdAI->transId[0] = sig1;
- transIdAI->transId[1] = sig2;
- }//if
- LinearSectionPtr ptr[3];
- ptr[0].p= &signal->theData[25];
- ptr[0].sz= ToutBufIndex;
- sendSignal(recBlockref, GSN_TRANSID_AI, signal, 3, JBB, ptr, 1);
- return;
- }
-
- /**
- * short sig + api -> buffer
- */
-#ifndef NDB_NO_DROPPED_SIGNAL
- if (ToutBufIndex < 22 && is_api){
- jam();
- bufferTRANSID_AI(signal, recBlockref, 3+ToutBufIndex);
- return;
- }
-#endif
-
- /**
- * rest -> old send sig
- */
- Uint32 * src= signal->theData+25;
- if (ToutBufIndex >= 22){
- do {
- jam();
- 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){
- jam();
- 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);
- jamEntry();
- return;
- }
-
- /**
- * 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= req_struct->TC_ref;
-
- if (true){ // TODO is_api && !old_dest){
- jam();
- 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;
- }
-
- /**
- * 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) {
- jam();
- 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;
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
deleted file mode 100644
index d65ebf26eee..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_COMMIT_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <signaldata/TupCommit.hpp>
-#include "../dblqh/Dblqh.hpp"
-
-void Dbtup::execTUP_DEALLOCREQ(Signal* signal)
-{
- TablerecPtr regTabPtr;
- FragrecordPtr regFragPtr;
- Uint32 frag_page_id, frag_id;
-
- jamEntry();
-
- frag_id= signal->theData[0];
- regTabPtr.i= signal->theData[1];
- frag_page_id= signal->theData[2];
- Uint32 page_index= signal->theData[3];
-
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-
- getFragmentrec(regFragPtr, frag_id, regTabPtr.p);
- ndbassert(regFragPtr.p != NULL);
-
- if (! (((frag_page_id << MAX_TUPLES_BITS) + page_index) == ~ (Uint32) 0))
- {
- Local_key tmp;
- tmp.m_page_no= getRealpid(regFragPtr.p, frag_page_id);
- tmp.m_page_idx= page_index;
-
- PagePtr pagePtr;
- Tuple_header* ptr= (Tuple_header*)get_ptr(&pagePtr, &tmp, regTabPtr.p);
-
- ndbassert(ptr->m_header_bits & Tuple_header::FREE);
-
- if (ptr->m_header_bits & Tuple_header::LCP_KEEP)
- {
- ndbassert(! (ptr->m_header_bits & Tuple_header::FREED));
- ptr->m_header_bits |= Tuple_header::FREED;
- return;
- }
-
- if (regTabPtr.p->m_attributes[MM].m_no_of_varsize)
- {
- jam();
- free_var_rec(regFragPtr.p, regTabPtr.p, &tmp, pagePtr);
- } else {
- free_fix_rec(regFragPtr.p, regTabPtr.p, &tmp, (Fix_page*)pagePtr.p);
- }
- }
-}
-
-void Dbtup::execTUP_WRITELOG_REQ(Signal* signal)
-{
- jamEntry();
- OperationrecPtr loopOpPtr;
- loopOpPtr.i= signal->theData[0];
- Uint32 gci= signal->theData[1];
- c_operation_pool.getPtr(loopOpPtr);
- while (loopOpPtr.p->prevActiveOp != RNIL) {
- jam();
- loopOpPtr.i= loopOpPtr.p->prevActiveOp;
- c_operation_pool.getPtr(loopOpPtr);
- }
- do {
- ndbrequire(get_trans_state(loopOpPtr.p) == TRANS_STARTED);
- signal->theData[0]= loopOpPtr.p->userpointer;
- signal->theData[1]= gci;
- if (loopOpPtr.p->nextActiveOp == RNIL) {
- jam();
- EXECUTE_DIRECT(DBLQH, GSN_LQH_WRITELOG_REQ, signal, 2);
- return;
- }
- jam();
- EXECUTE_DIRECT(DBLQH, GSN_LQH_WRITELOG_REQ, signal, 2);
- jamEntry();
- loopOpPtr.i= loopOpPtr.p->nextActiveOp;
- c_operation_pool.getPtr(loopOpPtr);
- } while (true);
-}
-
-/* ---------------------------------------------------------------- */
-/* INITIALIZATION OF ONE CONNECTION RECORD TO PREPARE FOR NEXT OP. */
-/* ---------------------------------------------------------------- */
-void Dbtup::initOpConnection(Operationrec* regOperPtr)
-{
- set_tuple_state(regOperPtr, TUPLE_ALREADY_ABORTED);
- set_trans_state(regOperPtr, TRANS_IDLE);
- regOperPtr->currentAttrinbufLen= 0;
- regOperPtr->op_struct.op_type= ZREAD;
- regOperPtr->op_struct.m_disk_preallocated= 0;
- regOperPtr->op_struct.m_load_diskpage_on_commit= 0;
- regOperPtr->op_struct.m_wait_log_buffer= 0;
- regOperPtr->op_struct.in_active_list = false;
- regOperPtr->m_undo_buffer_space= 0;
-}
-
-static
-inline
-bool
-operator>(const Local_key& key1, const Local_key& key2)
-{
- return key1.m_page_no > key2.m_page_no ||
- (key1.m_page_no == key2.m_page_no && key1.m_page_idx > key2.m_page_idx);
-}
-
-void
-Dbtup::dealloc_tuple(Signal* signal,
- Uint32 gci,
- Page* page,
- Tuple_header* ptr,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op;
- Uint32 lcp_keep_list = regFragPtr->m_lcp_keep_list;
-
- Uint32 bits = ptr->m_header_bits;
- Uint32 extra_bits = Tuple_header::FREED;
- if (bits & Tuple_header::DISK_PART)
- {
- jam();
- Local_key disk;
- memcpy(&disk, ptr->get_disk_ref_ptr(regTabPtr), sizeof(disk));
- PagePtr tmpptr;
- tmpptr.i = m_pgman.m_ptr.i;
- tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
- disk_page_free(signal, regTabPtr, regFragPtr,
- &disk, tmpptr, gci);
- }
-
- if (! (bits & (Tuple_header::LCP_SKIP | Tuple_header::ALLOC)) &&
- lcpScan_ptr_i != RNIL)
- {
- jam();
- ScanOpPtr scanOp;
- c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i);
- Local_key rowid = regOperPtr->m_tuple_location;
- Local_key scanpos = scanOp.p->m_scanPos.m_key;
- rowid.m_page_no = page->frag_page_id;
- if (rowid > scanpos)
- {
- jam();
- extra_bits = Tuple_header::LCP_KEEP; // Note REMOVE FREE
- ptr->m_operation_ptr_i = lcp_keep_list;
- regFragPtr->m_lcp_keep_list = rowid.ref();
- }
- }
-
- ptr->m_header_bits = bits | extra_bits;
-
- if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
- {
- jam();
- * ptr->get_mm_gci(regTabPtr) = gci;
- }
-}
-
-void
-Dbtup::commit_operation(Signal* signal,
- Uint32 gci,
- Tuple_header* tuple_ptr,
- PagePtr pagePtr,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- ndbassert(regOperPtr->op_struct.op_type != ZDELETE);
-
- Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op;
- Uint32 save= tuple_ptr->m_operation_ptr_i;
- Uint32 bits= tuple_ptr->m_header_bits;
-
- Tuple_header *disk_ptr= 0;
- Tuple_header *copy= (Tuple_header*)
- c_undo_buffer.get_ptr(&regOperPtr->m_copy_tuple_location);
-
- Uint32 copy_bits= copy->m_header_bits;
-
- Uint32 fixsize= regTabPtr->m_offsets[MM].m_fix_header_size;
- Uint32 mm_vars= regTabPtr->m_attributes[MM].m_no_of_varsize;
- if(mm_vars == 0)
- {
- jam();
- memcpy(tuple_ptr, copy, 4*fixsize);
- disk_ptr= (Tuple_header*)(((Uint32*)copy)+fixsize);
- }
- else
- {
- jam();
- /**
- * Var_part_ref is only stored in *allocated* tuple
- * so memcpy from copy, will over write it...
- * hence subtle copyout/assign...
- */
- Local_key tmp;
- Var_part_ref *ref= tuple_ptr->get_var_part_ref_ptr(regTabPtr);
- ref->copyout(&tmp);
-
- memcpy(tuple_ptr, copy, 4*fixsize);
- ref->assign(&tmp);
-
- PagePtr vpagePtr;
- Uint32 *dst= get_ptr(&vpagePtr, *ref);
- Var_page* vpagePtrP = (Var_page*)vpagePtr.p;
- Uint32 *src= copy->get_end_of_fix_part_ptr(regTabPtr);
- Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)src)[mm_vars]);
- ndbassert(4*vpagePtrP->get_entry_len(tmp.m_page_idx) >= sz);
- memcpy(dst, src, sz);
-
- copy_bits |= Tuple_header::CHAINED_ROW;
-
- if(copy_bits & Tuple_header::MM_SHRINK)
- {
- jam();
- vpagePtrP->shrink_entry(tmp.m_page_idx, (sz + 3) >> 2);
- update_free_page_list(regFragPtr, vpagePtr);
- }
-
- disk_ptr = (Tuple_header*)(((Uint32*)copy)+fixsize+((sz + 3) >> 2));
- }
-
- if (regTabPtr->m_no_of_disk_attributes &&
- (copy_bits & Tuple_header::DISK_INLINE))
- {
- jam();
- Local_key key;
- memcpy(&key, copy->get_disk_ref_ptr(regTabPtr), sizeof(Local_key));
- Uint32 logfile_group_id= regFragPtr->m_logfile_group_id;
-
- PagePtr diskPagePtr = *(PagePtr*)&m_pgman.m_ptr;
- ndbassert(diskPagePtr.p->m_page_no == key.m_page_no);
- ndbassert(diskPagePtr.p->m_file_no == key.m_file_no);
- Uint32 sz, *dst;
- if(copy_bits & Tuple_header::DISK_ALLOC)
- {
- jam();
- disk_page_alloc(signal, regTabPtr, regFragPtr, &key, diskPagePtr, gci);
- }
-
- if(regTabPtr->m_attributes[DD].m_no_of_varsize == 0)
- {
- jam();
- sz= regTabPtr->m_offsets[DD].m_fix_header_size;
- dst= ((Fix_page*)diskPagePtr.p)->get_ptr(key.m_page_idx, sz);
- }
- else
- {
- jam();
- dst= ((Var_page*)diskPagePtr.p)->get_ptr(key.m_page_idx);
- sz= ((Var_page*)diskPagePtr.p)->get_entry_len(key.m_page_idx);
- }
-
- if(! (copy_bits & Tuple_header::DISK_ALLOC))
- {
- jam();
- disk_page_undo_update(diskPagePtr.p,
- &key, dst, sz, gci, logfile_group_id);
- }
-
- memcpy(dst, disk_ptr, 4*sz);
- memcpy(tuple_ptr->get_disk_ref_ptr(regTabPtr), &key, sizeof(Local_key));
-
- ndbassert(! (disk_ptr->m_header_bits & Tuple_header::FREE));
- copy_bits |= Tuple_header::DISK_PART;
- }
-
- if(lcpScan_ptr_i != RNIL && (bits & Tuple_header::ALLOC))
- {
- jam();
- ScanOpPtr scanOp;
- c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i);
- Local_key rowid = regOperPtr->m_tuple_location;
- Local_key scanpos = scanOp.p->m_scanPos.m_key;
- rowid.m_page_no = pagePtr.p->frag_page_id;
- if(rowid > scanpos)
- {
- jam();
- copy_bits |= Tuple_header::LCP_SKIP;
- }
- }
-
- Uint32 clear=
- Tuple_header::ALLOC | Tuple_header::FREE |
- Tuple_header::DISK_ALLOC | Tuple_header::DISK_INLINE |
- Tuple_header::MM_SHRINK | Tuple_header::MM_GROWN;
- copy_bits &= ~(Uint32)clear;
-
- tuple_ptr->m_header_bits= copy_bits;
- tuple_ptr->m_operation_ptr_i= save;
-
- if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
- {
- jam();
- * tuple_ptr->get_mm_gci(regTabPtr) = gci;
- }
-
- if (regTabPtr->m_bits & Tablerec::TR_Checksum) {
- jam();
- setChecksum(tuple_ptr, regTabPtr);
- }
-}
-
-void
-Dbtup::disk_page_commit_callback(Signal* signal,
- Uint32 opPtrI, Uint32 page_id)
-{
- Uint32 hash_value;
- Uint32 gci;
- OperationrecPtr regOperPtr;
-
- jamEntry();
-
- c_operation_pool.getPtr(regOperPtr, opPtrI);
- c_lqh->get_op_info(regOperPtr.p->userpointer, &hash_value, &gci);
-
- TupCommitReq * const tupCommitReq= (TupCommitReq *)signal->getDataPtr();
-
- tupCommitReq->opPtr= opPtrI;
- tupCommitReq->hashValue= hash_value;
- tupCommitReq->gci= gci;
- tupCommitReq->diskpage = page_id;
-
- regOperPtr.p->op_struct.m_load_diskpage_on_commit= 0;
- regOperPtr.p->m_commit_disk_callback_page= page_id;
- m_global_page_pool.getPtr(m_pgman.m_ptr, page_id);
-
- {
- PagePtr tmp;
- tmp.i = m_pgman.m_ptr.i;
- tmp.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
- disk_page_set_dirty(tmp);
- }
-
- execTUP_COMMITREQ(signal);
- if(signal->theData[0] == 0)
- {
- jam();
- c_lqh->tupcommit_conf_callback(signal, regOperPtr.p->userpointer);
- }
-}
-
-void
-Dbtup::disk_page_log_buffer_callback(Signal* signal,
- Uint32 opPtrI,
- Uint32 unused)
-{
- Uint32 hash_value;
- Uint32 gci;
- OperationrecPtr regOperPtr;
-
- jamEntry();
-
- c_operation_pool.getPtr(regOperPtr, opPtrI);
- c_lqh->get_op_info(regOperPtr.p->userpointer, &hash_value, &gci);
- Uint32 page= regOperPtr.p->m_commit_disk_callback_page;
-
- TupCommitReq * const tupCommitReq= (TupCommitReq *)signal->getDataPtr();
-
- tupCommitReq->opPtr= opPtrI;
- tupCommitReq->hashValue= hash_value;
- tupCommitReq->gci= gci;
- tupCommitReq->diskpage = page;
-
- ndbassert(regOperPtr.p->op_struct.m_load_diskpage_on_commit == 0);
- regOperPtr.p->op_struct.m_wait_log_buffer= 0;
- m_global_page_pool.getPtr(m_pgman.m_ptr, page);
-
- execTUP_COMMITREQ(signal);
- ndbassert(signal->theData[0] == 0);
-
- c_lqh->tupcommit_conf_callback(signal, regOperPtr.p->userpointer);
-}
-
-/**
- * Move to the first operation performed on this tuple
- */
-void
-Dbtup::findFirstOp(OperationrecPtr & firstPtr)
-{
- jam();
- printf("Detect out-of-order commit(%u) -> ", firstPtr.i);
- ndbassert(!firstPtr.p->is_first_operation());
- while(firstPtr.p->prevActiveOp != RNIL)
- {
- firstPtr.i = firstPtr.p->prevActiveOp;
- c_operation_pool.getPtr(firstPtr);
- }
- ndbout_c("%u", firstPtr.i);
-}
-
-/* ----------------------------------------------------------------- */
-/* --------------- COMMIT THIS PART OF A TRANSACTION --------------- */
-/* ----------------------------------------------------------------- */
-void Dbtup::execTUP_COMMITREQ(Signal* signal)
-{
- FragrecordPtr regFragPtr;
- OperationrecPtr regOperPtr;
- TablerecPtr regTabPtr;
- KeyReqStruct req_struct;
- TransState trans_state;
- Uint32 no_of_fragrec, no_of_tablerec;
-
- TupCommitReq * const tupCommitReq= (TupCommitReq *)signal->getDataPtr();
-
- regOperPtr.i= tupCommitReq->opPtr;
- Uint32 hash_value= tupCommitReq->hashValue;
- Uint32 gci = tupCommitReq->gci;
-
- jamEntry();
-
- c_operation_pool.getPtr(regOperPtr);
-
- regFragPtr.i= regOperPtr.p->fragmentPtr;
- trans_state= get_trans_state(regOperPtr.p);
-
- no_of_fragrec= cnoOfFragrec;
-
- ndbrequire(trans_state == TRANS_STARTED);
- ptrCheckGuard(regFragPtr, no_of_fragrec, fragrecord);
-
- no_of_tablerec= cnoOfTablerec;
- regTabPtr.i= regFragPtr.p->fragTableId;
- hash_value= tupCommitReq->hashValue;
- gci= tupCommitReq->gci;
-
- req_struct.signal= signal;
- req_struct.hash_value= hash_value;
- req_struct.gci= gci;
- regOperPtr.p->m_commit_disk_callback_page = tupCommitReq->diskpage;
-
-#ifdef VM_TRACE
- if (tupCommitReq->diskpage == RNIL)
- {
- m_pgman.m_ptr.i = RNIL;
- m_pgman.m_ptr.p = 0;
- req_struct.m_disk_page_ptr.i = RNIL;
- req_struct.m_disk_page_ptr.p = 0;
- }
-#endif
-
- ptrCheckGuard(regTabPtr, no_of_tablerec, tablerec);
-
- PagePtr page;
- Tuple_header* tuple_ptr= (Tuple_header*)
- get_ptr(&page, &regOperPtr.p->m_tuple_location, regTabPtr.p);
-
- /**
- * NOTE: This has to be run before potential time-slice when
- * waiting for disk, as otherwise the "other-ops" in a multi-op
- * commit might run while we're waiting for disk
- *
- */
- if (!regTabPtr.p->tuxCustomTriggers.isEmpty())
- {
- if(get_tuple_state(regOperPtr.p) == TUPLE_PREPARED)
- {
- jam();
-
- OperationrecPtr loopPtr = regOperPtr;
- if (unlikely(!regOperPtr.p->is_first_operation()))
- {
- findFirstOp(loopPtr);
- }
-
- /**
- * Execute all tux triggers at first commit
- * since previous tuple is otherwise removed...
- */
- jam();
- goto first;
- while(loopPtr.i != RNIL)
- {
- c_operation_pool.getPtr(loopPtr);
- first:
- executeTuxCommitTriggers(signal,
- loopPtr.p,
- regFragPtr.p,
- regTabPtr.p);
- set_tuple_state(loopPtr.p, TUPLE_TO_BE_COMMITTED);
- loopPtr.i = loopPtr.p->nextActiveOp;
- }
- }
- }
-
- bool get_page = false;
- if(regOperPtr.p->op_struct.m_load_diskpage_on_commit)
- {
- jam();
- Page_cache_client::Request req;
-
- /**
- * Only last op on tuple needs "real" commit,
- * hence only this one should have m_load_diskpage_on_commit
- */
- ndbassert(tuple_ptr->m_operation_ptr_i == regOperPtr.i);
-
- /**
- * Check for page
- */
- if(!regOperPtr.p->m_copy_tuple_location.isNull())
- {
- jam();
- Tuple_header* tmp= (Tuple_header*)
- c_undo_buffer.get_ptr(&regOperPtr.p->m_copy_tuple_location);
-
- memcpy(&req.m_page,
- tmp->get_disk_ref_ptr(regTabPtr.p), sizeof(Local_key));
-
- if (unlikely(regOperPtr.p->op_struct.op_type == ZDELETE &&
- tmp->m_header_bits & Tuple_header::DISK_ALLOC))
- {
- jam();
- /**
- * Insert+Delete
- */
- regOperPtr.p->op_struct.m_load_diskpage_on_commit = 0;
- regOperPtr.p->op_struct.m_wait_log_buffer = 0;
- disk_page_abort_prealloc(signal, regFragPtr.p,
- &req.m_page, req.m_page.m_page_idx);
-
- c_lgman->free_log_space(regFragPtr.p->m_logfile_group_id,
- regOperPtr.p->m_undo_buffer_space);
- goto skip_disk;
- if (0) ndbout_c("insert+delete");
- jamEntry();
- goto skip_disk;
- }
- }
- else
- {
- jam();
- // initial delete
- ndbassert(regOperPtr.p->op_struct.op_type == ZDELETE);
- memcpy(&req.m_page,
- tuple_ptr->get_disk_ref_ptr(regTabPtr.p), sizeof(Local_key));
-
- ndbassert(tuple_ptr->m_header_bits & Tuple_header::DISK_PART);
- }
- req.m_callback.m_callbackData= regOperPtr.i;
- req.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_commit_callback);
-
- /*
- * Consider commit to be correlated. Otherwise pk op + commit makes
- * the page hot. XXX move to TUP which knows better.
- */
- int flags= regOperPtr.p->op_struct.op_type |
- Page_cache_client::COMMIT_REQ | Page_cache_client::CORR_REQ;
- int res= m_pgman.get_page(signal, req, flags);
- switch(res){
- case 0:
- /**
- * Timeslice
- */
- jam();
- signal->theData[0] = 1;
- return;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- default:
- jam();
- }
- get_page = true;
-
- {
- PagePtr tmpptr;
- tmpptr.i = m_pgman.m_ptr.i;
- tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
- disk_page_set_dirty(tmpptr);
- }
-
- regOperPtr.p->m_commit_disk_callback_page= res;
- regOperPtr.p->op_struct.m_load_diskpage_on_commit= 0;
- }
-
- if(regOperPtr.p->op_struct.m_wait_log_buffer)
- {
- jam();
- /**
- * Only last op on tuple needs "real" commit,
- * hence only this one should have m_wait_log_buffer
- */
- ndbassert(tuple_ptr->m_operation_ptr_i == regOperPtr.i);
-
- Callback cb;
- cb.m_callbackData= regOperPtr.i;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_log_buffer_callback);
- Uint32 sz= regOperPtr.p->m_undo_buffer_space;
-
- Logfile_client lgman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
- int res= lgman.get_log_buffer(signal, sz, &cb);
- jamEntry();
- switch(res){
- case 0:
- jam();
- signal->theData[0] = 1;
- return;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- default:
- jam();
- }
- }
-
- assert(tuple_ptr);
-skip_disk:
- req_struct.m_tuple_ptr = tuple_ptr;
-
- Uint32 nextOp = regOperPtr.p->nextActiveOp;
- Uint32 prevOp = regOperPtr.p->prevActiveOp;
- /**
- * The trigger code (which is shared between detached/imediate)
- * check op-list to check were to read before values from
- * detached triggers should always read from original tuple value
- * from before transaction start, not from any intermediate update
- *
- * Setting the op-list has this effect
- */
- regOperPtr.p->nextActiveOp = RNIL;
- regOperPtr.p->prevActiveOp = RNIL;
- if(tuple_ptr->m_operation_ptr_i == regOperPtr.i)
- {
- jam();
- /**
- * Perform "real" commit
- */
- Uint32 disk = regOperPtr.p->m_commit_disk_callback_page;
- set_change_mask_info(&req_struct, regOperPtr.p);
- checkDetachedTriggers(&req_struct, regOperPtr.p, regTabPtr.p,
- disk != RNIL);
-
- tuple_ptr->m_operation_ptr_i = RNIL;
-
- if(regOperPtr.p->op_struct.op_type != ZDELETE)
- {
- jam();
- commit_operation(signal, gci, tuple_ptr, page,
- regOperPtr.p, regFragPtr.p, regTabPtr.p);
- }
- else
- {
- jam();
- if (get_page)
- ndbassert(tuple_ptr->m_header_bits & Tuple_header::DISK_PART);
- dealloc_tuple(signal, gci, page.p, tuple_ptr,
- regOperPtr.p, regFragPtr.p, regTabPtr.p);
- }
- }
-
- if (nextOp != RNIL)
- {
- c_operation_pool.getPtr(nextOp)->prevActiveOp = prevOp;
- }
-
- if (prevOp != RNIL)
- {
- c_operation_pool.getPtr(prevOp)->nextActiveOp = nextOp;
- }
-
- if(!regOperPtr.p->m_copy_tuple_location.isNull())
- {
- jam();
- c_undo_buffer.free_copy_tuple(&regOperPtr.p->m_copy_tuple_location);
- }
-
- initOpConnection(regOperPtr.p);
- signal->theData[0] = 0;
-}
-
-void
-Dbtup::set_change_mask_info(KeyReqStruct * const req_struct,
- Operationrec * const regOperPtr)
-{
- ChangeMaskState state = get_change_mask_state(regOperPtr);
- if (state == USE_SAVED_CHANGE_MASK) {
- jam();
- req_struct->changeMask.setWord(0, regOperPtr->saved_change_mask[0]);
- req_struct->changeMask.setWord(1, regOperPtr->saved_change_mask[1]);
- } else if (state == RECALCULATE_CHANGE_MASK) {
- jam();
- // Recompute change mask, for now set all bits
- req_struct->changeMask.set();
- } else if (state == SET_ALL_MASK) {
- jam();
- req_struct->changeMask.set();
- } else {
- jam();
- ndbrequire(state == DELETE_CHANGES);
- req_struct->changeMask.set();
- }
-}
-
-void
-Dbtup::calculateChangeMask(Page* const pagePtr,
- Tablerec* const regTabPtr,
- KeyReqStruct * const req_struct)
-{
- OperationrecPtr loopOpPtr;
- Uint32 saved_word1= 0;
- Uint32 saved_word2= 0;
- loopOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
- do {
- c_operation_pool.getPtr(loopOpPtr);
- ndbrequire(loopOpPtr.p->op_struct.op_type == ZUPDATE);
- ChangeMaskState change_mask= get_change_mask_state(loopOpPtr.p);
- if (change_mask == USE_SAVED_CHANGE_MASK) {
- jam();
- saved_word1|= loopOpPtr.p->saved_change_mask[0];
- saved_word2|= loopOpPtr.p->saved_change_mask[1];
- } else if (change_mask == RECALCULATE_CHANGE_MASK) {
- jam();
- //Recompute change mask, for now set all bits
- req_struct->changeMask.set();
- return;
- } else {
- ndbrequire(change_mask == SET_ALL_MASK);
- jam();
- req_struct->changeMask.set();
- return;
- }
- loopOpPtr.i= loopOpPtr.p->prevActiveOp;
- } while (loopOpPtr.i != RNIL);
- req_struct->changeMask.setWord(0, saved_word1);
- req_struct->changeMask.setWord(1, saved_word2);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp
deleted file mode 100644
index 7d88587cb35..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_DEBUG_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/EventReport.hpp>
-#include <Vector.hpp>
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* ------------------------ DEBUG MODULE -------------------------- */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-void Dbtup::execDEBUG_SIG(Signal* signal)
-{
- PagePtr regPagePtr;
- jamEntry();
- regPagePtr.i = signal->theData[0];
- c_page_pool.getPtr(regPagePtr);
-}//Dbtup::execDEBUG_SIG()
-
-#ifdef TEST_MR
-#include <time.h>
-
-void startTimer(struct timespec *tp)
-{
- clock_gettime(CLOCK_REALTIME, tp);
-}//startTimer()
-
-int stopTimer(struct timespec *tp)
-{
- double timer_count;
- struct timespec theStopTime;
- clock_gettime(CLOCK_REALTIME, &theStopTime);
- timer_count = (double)(1000000*((double)theStopTime.tv_sec - (double)tp->tv_sec)) +
- (double)((double)((double)theStopTime.tv_nsec - (double)tp->tv_nsec)/(double)1000);
- return (int)timer_count;
-}//stopTimer()
-
-#endif // end TEST_MR
-
-struct Chunk {
- Uint32 pageId;
- Uint32 pageCount;
-};
-
-void
-Dbtup::reportMemoryUsage(Signal* signal, int incDec){
- signal->theData[0] = NDB_LE_MemoryUsage;
- signal->theData[1] = incDec;
- signal->theData[2] = sizeof(Page);
- signal->theData[3] = cnoOfAllocatedPages;
- signal->theData[4] = c_page_pool.getSize();
- signal->theData[5] = DBTUP;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
-}
-
-#ifdef VM_TRACE
-extern Uint32 fc_left, fc_right, fc_remove;
-#endif
-
-void
-Dbtup::execDUMP_STATE_ORD(Signal* signal)
-{
- Uint32 type = signal->theData[0];
- if(type == DumpStateOrd::DumpPageMemory && signal->getLength() == 1){
- reportMemoryUsage(signal, 0);
- return;
- }
- DumpStateOrd * const dumpState = (DumpStateOrd *)&signal->theData[0];
-
-#if 0
- if (type == 100) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 2;
- req->secondaryTableId = RNIL;
- req->userPtr = 2;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 101) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 4;
- req->secondaryTableId = 5;
- req->userPtr = 4;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 102) {
- RelTabMemReq * const req = (RelTabMemReq *)signal->getDataPtrSend();
- req->primaryTableId = 6;
- req->secondaryTableId = 8;
- req->userPtr = 6;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_REL_TABMEMREQ, signal,
- RelTabMemReq::SignalLength, JBB);
- return;
- }//if
- if (type == 103) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 2;
- req->secondaryTableId = RNIL;
- req->userPtr = 2;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
- if (type == 104) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 4;
- req->secondaryTableId = 5;
- req->userPtr = 4;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
- if (type == 105) {
- DropTabFileReq * const req = (DropTabFileReq *)signal->getDataPtrSend();
- req->primaryTableId = 6;
- req->secondaryTableId = 8;
- req->userPtr = 6;
- req->userRef = DBDICT_REF;
- sendSignal(cownref, GSN_DROP_TABFILEREQ, signal,
- DropTabFileReq::SignalLength, JBB);
- return;
- }//if
-#endif
-#ifdef ERROR_INSERT
- if (type == DumpStateOrd::EnableUndoDelayDataWrite) {
- ndbout << "Dbtup:: delay write of datapages for table = "
- << dumpState->args[1]<< endl;
- c_errorInsert4000TableId = dumpState->args[1];
- SET_ERROR_INSERT_VALUE(4000);
- return;
- }//if
-#endif
-#if defined VM_TRACE
- if (type == 1211 || type == 1212 || type == 1213){
- Uint32 seed = time(0);
- if (signal->getLength() > 1)
- seed = signal->theData[1];
- ndbout_c("Startar modul test av Page Manager (seed: 0x%x)", seed);
- srand(seed);
-
- Vector<Chunk> chunks;
- const Uint32 LOOPS = 1000;
- Uint32 sum_req = 0;
- Uint32 sum_conf = 0;
- Uint32 sum_loop = 0;
- Uint32 max_loop = 0;
- for(Uint32 i = 0; i<LOOPS; i++){
-
- // Case
- Uint32 c = (rand() % 3);
- const Uint32 free = c_page_pool.getSize() - cnoOfAllocatedPages;
-
- Uint32 alloc = 0;
- if(free <= 1){
- c = 0;
- alloc = 1;
- } else
- alloc = 1 + (rand() % (free - 1));
-
- if(chunks.size() == 0 && c == 0){
- c = 1 + rand() % 2;
- }
-
- if (type == 1211)
- ndbout_c("loop=%d case=%d free=%d alloc=%d", i, c, free, alloc);
-
- if (type == 1213)
- {
- c = 1;
- alloc = 2 + (sum_conf >> 3) + (sum_conf >> 4);
- }
- switch(c){
- case 0:{ // Release
- const int ch = rand() % chunks.size();
- Chunk chunk = chunks[ch];
- chunks.erase(ch);
- returnCommonArea(chunk.pageId, chunk.pageCount);
- }
- break;
- case 2: { // Seize(n) - fail
- alloc += free;
- // Fall through
- sum_req += free;
- goto doalloc;
- }
- case 1: { // Seize(n) (success)
- sum_req += alloc;
- doalloc:
- Chunk chunk;
- allocConsPages(alloc, chunk.pageCount, chunk.pageId);
- ndbrequire(chunk.pageCount <= alloc);
- if(chunk.pageCount != 0){
- chunks.push_back(chunk);
- if(chunk.pageCount != alloc) {
- if (type == 1211)
- ndbout_c(" Tried to allocate %d - only allocated %d - free: %d",
- alloc, chunk.pageCount, free);
- }
- } else {
- ndbout_c(" Failed to alloc %d pages with %d pages free",
- alloc, free);
- }
-
- sum_conf += chunk.pageCount;
- Uint32 tot = fc_left + fc_right + fc_remove;
- sum_loop += tot;
- if (tot > max_loop)
- max_loop = tot;
-
- for(Uint32 i = 0; i<chunk.pageCount; i++){
- PagePtr pagePtr;
- pagePtr.i = chunk.pageId + i;
- c_page_pool.getPtr(pagePtr);
- pagePtr.p->page_state = ~ZFREE_COMMON;
- }
-
- if(alloc == 1 && free > 0)
- ndbrequire(chunk.pageCount == alloc);
- }
- break;
- }
- }
- while(chunks.size() > 0){
- Chunk chunk = chunks.back();
- returnCommonArea(chunk.pageId, chunk.pageCount);
- chunks.erase(chunks.size() - 1);
- }
-
- ndbout_c("Got %u%% of requested allocs, loops : %u 100*avg: %u max: %u",
- (100 * sum_conf) / sum_req, sum_loop, 100*sum_loop / LOOPS,
- max_loop);
- }
-#endif
-}//Dbtup::execDUMP_STATE_ORD()
-
-/* ---------------------------------------------------------------- */
-/* --------- MEMORY CHECK ----------------------- */
-/* ---------------------------------------------------------------- */
-void Dbtup::execMEMCHECKREQ(Signal* signal)
-{
- TablerecPtr regTabPtr;
- regTabPtr.i = 2;
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
- if(tablerec && regTabPtr.p->tableStatus == DEFINED)
- validate_page(regTabPtr.p, 0);
-
-#if 0
- const Dbtup::Tablerec& tab = *tup->tabptr.p;
-
- PagePtr regPagePtr;
- Uint32* data = &signal->theData[0];
-
- jamEntry();
- BlockReference blockref = signal->theData[0];
- Uint32 i;
- for (i = 0; i < 25; i++) {
- jam();
- data[i] = 0;
- }//for
- for (i = 0; i < 16; i++) {
- regPagePtr.i = cfreepageList[i];
- jam();
- while (regPagePtr.i != RNIL) {
- jam();
- ptrCheckGuard(regPagePtr, cnoOfPage, cpage);
- regPagePtr.i = regPagePtr.p->next_page;
- data[0]++;
- }//while
- }//for
- sendSignal(blockref, GSN_MEMCHECKCONF, signal, 25, JBB);
-#endif
-}//Dbtup::memCheck()
-
-// ------------------------------------------------------------------------
-// Help function to be used when debugging. Prints out a tuple page.
-// printLimit is the number of bytes that is printed out from the page. A
-// page is of size 32768 bytes as of March 2003.
-// ------------------------------------------------------------------------
-void Dbtup::printoutTuplePage(Uint32 fragid, Uint32 pageid, Uint32 printLimit)
-{
- PagePtr tmpPageP;
- FragrecordPtr tmpFragP;
- TablerecPtr tmpTableP;
-
- c_page_pool.getPtr(tmpPageP, pageid);
-
- tmpFragP.i = fragid;
- ptrCheckGuard(tmpFragP, cnoOfFragrec, fragrecord);
-
- tmpTableP.i = tmpFragP.p->fragTableId;
- ptrCheckGuard(tmpTableP, cnoOfTablerec, tablerec);
-
- ndbout << "Fragid: " << fragid << " Pageid: " << pageid << endl
- << "----------------------------------------" << endl;
-
- ndbout << "PageHead : ";
- ndbout << endl;
-}//Dbtup::printoutTuplePage
-
-#ifdef VM_TRACE
-NdbOut&
-operator<<(NdbOut& out, const Dbtup::Operationrec& op)
-{
- out << "[Operationrec " << hex << &op;
- // table
- out << " [fragmentPtr " << hex << op.fragmentPtr << "]";
- // type
- out << " [op_type " << dec << op.op_struct.op_type << "]";
- out << " [delete_insert_flag " << dec;
- out << op.op_struct.delete_insert_flag << "]";
- // state
- out << " [tuple_state " << dec << op.op_struct.tuple_state << "]";
- out << " [trans_state " << dec << op.op_struct.trans_state << "]";
- out << " [in_active_list " << dec << op.op_struct.in_active_list << "]";
- // links
- out << " [prevActiveOp " << hex << op.prevActiveOp << "]";
- out << " [nextActiveOp " << hex << op.nextActiveOp << "]";
- // tuples
- out << " [tupVersion " << hex << op.tupVersion << "]";
- out << " [m_tuple_location " << op.m_tuple_location << "]";
- out << " [m_copy_tuple_location " << op.m_copy_tuple_location << "]";
- out << "]";
- return out;
-}
-
-// uses global tabptr
-NdbOut&
-operator<<(NdbOut& out, const Dbtup::Th& th)
-{
- // ugly
- Dbtup* tup = (Dbtup*)globalData.getBlock(DBTUP);
- const Dbtup::Tablerec& tab = *tup->tabptr.p;
- unsigned i = 0;
- out << "[Th " << hex << &th;
- out << " [op " << hex << th.data[i++] << "]";
- out << " [version " << hex << (Uint16)th.data[i++] << "]";
- if (tab.m_bits & Dbtup::Tablerec::TR_Checksum)
- out << " [checksum " << hex << th.data[i++] << "]";
- out << " [nullbits";
- for (unsigned j = 0; j < tab.m_offsets[Dbtup::MM].m_null_words; j++)
- out << " " << hex << th.data[i++];
- out << "]";
- out << " [data";
- while (i < tab.m_offsets[Dbtup::MM].m_fix_header_size)
- out << " " << hex << th.data[i++];
- out << "]";
- out << "]";
- return out;
-}
-#endif
-
-#ifdef VM_TRACE
-template class Vector<Chunk>;
-#endif
-// uses global tabptr
-
-NdbOut&
-operator<<(NdbOut& out, const Local_key & key)
-{
- out << "[ m_page_no: " << dec << key.m_page_no
- << " m_file_no: " << dec << key.m_file_no
- << " m_page_idx: " << dec << key.m_page_idx << "]";
- return out;
-}
-
-static
-NdbOut&
-operator<<(NdbOut& out, const Dbtup::Tablerec::Tuple_offsets& off)
-{
- out << "[ null_words: " << (Uint32)off.m_null_words
- << " null off: " << (Uint32)off.m_null_offset
- << " disk_off: " << off.m_disk_ref_offset
- << " fixheadsz: " << off.m_fix_header_size
- << " max_var_off: " << off.m_max_var_offset
- << " ]";
-
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtup::Tablerec& tab)
-{
- out << "[ total_rec_size: " << tab.total_rec_size
- << " checksum: " << !!(tab.m_bits & Dbtup::Tablerec::TR_Checksum)
- << " attr: " << tab.m_no_of_attributes
- << " disk: " << tab.m_no_of_disk_attributes
- << " mm: " << tab.m_offsets[Dbtup::MM]
- << " [ fix: " << tab.m_attributes[Dbtup::MM].m_no_of_fixsize
- << " var: " << tab.m_attributes[Dbtup::MM].m_no_of_varsize << "]"
-
- << " dd: " << tab.m_offsets[Dbtup::DD]
- << " [ fix: " << tab.m_attributes[Dbtup::DD].m_no_of_fixsize
- << " var: " << tab.m_attributes[Dbtup::DD].m_no_of_varsize << "]"
- << " ]" << endl;
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const AttributeDescriptor& off)
-{
- Uint32 word;
- memcpy(&word, &off, 4);
- return out;
-}
-
-#include "AttributeOffset.hpp"
-
-NdbOut&
-operator<<(NdbOut& out, const AttributeOffset& off)
-{
- Uint32 word;
- memcpy(&word, &off, 4);
- out << "[ offset: " << AttributeOffset::getOffset(word)
- << " nullpos: " << AttributeOffset::getNullFlagPos(word);
- if(AttributeOffset::getCharsetFlag(word))
- out << " charset: %d" << AttributeOffset::getCharsetPos(word);
- out << " ]";
- return out;
-}
-
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
deleted file mode 100644
index e426213162a..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
+++ /dev/null
@@ -1,1893 +0,0 @@
-/* Copyright (c) 2004-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_DISK_ALLOC_CPP
-#include "Dbtup.hpp"
-
-static bool f_undo_done = true;
-
-static
-NdbOut&
-operator<<(NdbOut& out, const Ptr<Dbtup::Page> & ptr)
-{
- out << "[ Page: ptr.i: " << ptr.i
- << " [ m_file_no: " << ptr.p->m_file_no
- << " m_page_no: " << ptr.p->m_page_no << "]"
- << " list_index: " << ptr.p->list_index
- << " free_space: " << ptr.p->free_space
- << " uncommitted_used_space: " << ptr.p->uncommitted_used_space
- << " ]";
- return out;
-}
-
-static
-NdbOut&
-operator<<(NdbOut& out, const Ptr<Dbtup::Page_request> & ptr)
-{
- out << "[ Page_request: ptr.i: " << ptr.i
- << " " << ptr.p->m_key
- << " m_estimated_free_space: " << ptr.p->m_estimated_free_space
- << " m_list_index: " << ptr.p->m_list_index
- << " m_frag_ptr_i: " << ptr.p->m_frag_ptr_i
- << " m_extent_info_ptr: " << ptr.p->m_extent_info_ptr
- << " m_ref_count: " << ptr.p->m_ref_count
- << " m_uncommitted_used_space: " << ptr.p->m_uncommitted_used_space
- << " ]";
-
- return out;
-}
-
-static
-NdbOut&
-operator<<(NdbOut& out, const Ptr<Dbtup::Extent_info> & ptr)
-{
- out << "[ Extent_info: ptr.i " << ptr.i
- << " " << ptr.p->m_key
- << " m_first_page_no: " << ptr.p->m_first_page_no
- << " m_free_space: " << ptr.p->m_free_space
- << " m_free_matrix_pos: " << ptr.p->m_free_matrix_pos
- << " m_free_page_count: [";
-
- for(Uint32 i = 0; i<Dbtup::EXTENT_SEARCH_MATRIX_COLS; i++)
- out << " " << ptr.p->m_free_page_count[i];
- out << " ] ]";
-
- return out;
-}
-
-#if NOT_YET_FREE_EXTENT
-static
-inline
-bool
-check_free(const Dbtup::Extent_info* extP)
-{
- Uint32 res = 0;
- for (Uint32 i = 1; i<MAX_FREE_LIST; i++)
- res += extP->m_free_page_count[i];
- return res;
-}
-#error "Code for deallocting extents when they get empty"
-#error "This code is not yet complete"
-#endif
-
-#if NOT_YET_UNDO_ALLOC_EXTENT
-#error "This is needed for deallocting extents when they get empty"
-#error "This code is not complete yet"
-#endif
-
-void
-Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc)
-{
- ndbout_c("dirty pages");
- for(Uint32 i = 0; i<MAX_FREE_LIST; i++)
- {
- printf(" %d : ", i);
- PagePtr ptr;
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> list(*pool, alloc.m_dirty_pages[i]);
- for(list.first(ptr); !ptr.isNull(); list.next(ptr))
- {
- ndbout << ptr << " ";
- }
- ndbout_c(" ");
- }
- ndbout_c("page requests");
- for(Uint32 i = 0; i<MAX_FREE_LIST; i++)
- {
- printf(" %d : ", i);
- Ptr<Page_request> ptr;
- Local_page_request_list list(c_page_request_pool,
- alloc.m_page_requests[i]);
- for(list.first(ptr); !ptr.isNull(); list.next(ptr))
- {
- ndbout << ptr << " ";
- }
- ndbout_c(" ");
- }
-
- ndbout_c("Extent matrix");
- for(Uint32 i = 0; i<alloc.SZ; i++)
- {
- printf(" %d : ", i);
- Ptr<Extent_info> ptr;
- Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[i]);
- for(list.first(ptr); !ptr.isNull(); list.next(ptr))
- {
- ndbout << ptr << " ";
- }
- ndbout_c(" ");
- }
-
- if (alloc.m_curr_extent_info_ptr_i != RNIL)
- {
- Ptr<Extent_info> ptr;
- c_extent_pool.getPtr(ptr, alloc.m_curr_extent_info_ptr_i);
- ndbout << "current extent: " << ptr << endl;
- }
-}
-
-#if defined VM_TRACE || true
-#define ddassert(x) do { if(unlikely(!(x))) { dump_disk_alloc(alloc); ndbrequire(false); } } while(0)
-#else
-#define ddassert(x)
-#endif
-
-Dbtup::Disk_alloc_info::Disk_alloc_info(const Tablerec* tabPtrP,
- Uint32 extent_size)
-{
- m_extent_size = extent_size;
- m_curr_extent_info_ptr_i = RNIL;
- if (tabPtrP->m_no_of_disk_attributes == 0)
- return;
-
- Uint32 min_size= 4*tabPtrP->m_offsets[DD].m_fix_header_size;
-
- if (tabPtrP->m_attributes[DD].m_no_of_varsize == 0)
- {
- Uint32 recs_per_page= (4*Tup_fixsize_page::DATA_WORDS)/min_size;
- m_page_free_bits_map[0] = recs_per_page; // 100% free
- m_page_free_bits_map[1] = 1;
- m_page_free_bits_map[2] = 0;
- m_page_free_bits_map[3] = 0;
-
- Uint32 max= recs_per_page * extent_size;
- for(Uint32 i = 0; i<EXTENT_SEARCH_MATRIX_ROWS; i++)
- {
- m_total_extent_free_space_thresholds[i] =
- (EXTENT_SEARCH_MATRIX_ROWS - i - 1)*max/EXTENT_SEARCH_MATRIX_ROWS;
- }
- }
- else
- {
- abort();
- }
-}
-
-Uint32
-Dbtup::Disk_alloc_info::find_extent(Uint32 sz) const
-{
- /**
- * Find an extent with sufficient space for sz
- * Find the biggest available (with most free space)
- * Return position in matrix
- */
- Uint32 col = calc_page_free_bits(sz);
- Uint32 mask= EXTENT_SEARCH_MATRIX_COLS - 1;
- for(Uint32 i= 0; i<EXTENT_SEARCH_MATRIX_SIZE; i++)
- {
- // Check that it can cater for request
- if (!m_free_extents[i].isEmpty())
- {
- return i;
- }
-
- if ((i & mask) >= col)
- {
- i = (i & ~mask) + mask;
- }
- }
-
- return RNIL;
-}
-
-Uint32
-Dbtup::Disk_alloc_info::calc_extent_pos(const Extent_info* extP) const
-{
- Uint32 free= extP->m_free_space;
- Uint32 mask= EXTENT_SEARCH_MATRIX_COLS - 1;
-
- Uint32 col= 0, row=0;
-
- /**
- * Find correct row based on total free space
- * if zero (or very small free space) put
- * absolutly last
- */
- {
- const Uint32 *arr= m_total_extent_free_space_thresholds;
- for(; free < * arr++; row++)
- assert(row < EXTENT_SEARCH_MATRIX_ROWS);
- }
-
- /**
- * Find correct col based on largest available chunk
- */
- {
- const Uint16 *arr= extP->m_free_page_count;
- for(; col < EXTENT_SEARCH_MATRIX_COLS && * arr++ == 0; col++);
- }
-
- /**
- * NOTE
- *
- * If free space on extent is small or zero,
- * col will be = EXTENT_SEARCH_MATRIX_COLS
- * row will be = EXTENT_SEARCH_MATRIX_ROWS
- * in that case pos will be col * row = max pos
- * (as fixed by + 1 in declaration)
- */
- Uint32 pos= (row * (mask + 1)) + (col & mask);
-
- assert(pos < EXTENT_SEARCH_MATRIX_SIZE);
- return pos;
-}
-
-void
-Dbtup::update_extent_pos(Disk_alloc_info& alloc,
- Ptr<Extent_info> extentPtr)
-{
-#ifdef VM_TRACE
- Uint32 min_free = 0;
- for(Uint32 i = 0; i<MAX_FREE_LIST; i++)
- {
- Uint32 sum = alloc.calc_page_free_space(i);
- min_free += sum * extentPtr.p->m_free_page_count[i];
- }
- ddassert(extentPtr.p->m_free_space >= min_free);
-#endif
-
- Uint32 old = extentPtr.p->m_free_matrix_pos;
- if (old != RNIL)
- {
- Uint32 pos = alloc.calc_extent_pos(extentPtr.p);
- if (old != pos)
- {
- jam();
- Local_extent_info_list old_list(c_extent_pool, alloc.m_free_extents[old]);
- Local_extent_info_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
- old_list.remove(extentPtr);
- new_list.add(extentPtr);
- extentPtr.p->m_free_matrix_pos= pos;
- }
- }
- else
- {
- ddassert(alloc.m_curr_extent_info_ptr_i == extentPtr.i);
- }
-}
-
-void
-Dbtup::restart_setup_page(Disk_alloc_info& alloc, PagePtr pagePtr)
-{
- jam();
- /**
- * Link to extent, clear uncommitted_used_space
- */
- pagePtr.p->uncommitted_used_space = 0;
- pagePtr.p->m_restart_seq = globalData.m_restart_seq;
-
- Extent_info key;
- key.m_key.m_file_no = pagePtr.p->m_file_no;
- key.m_key.m_page_idx = pagePtr.p->m_extent_no;
- Ptr<Extent_info> extentPtr;
- ndbrequire(c_extent_hash.find(extentPtr, key));
- pagePtr.p->m_extent_info_ptr = extentPtr.i;
-
- Uint32 idx = pagePtr.p->list_index & ~0x8000;
- Uint32 estimated = alloc.calc_page_free_space(idx);
- Uint32 real_free = pagePtr.p->free_space;
-
- ddassert(real_free >= estimated);
- if (real_free != estimated)
- {
- jam();
- extentPtr.p->m_free_space += (real_free - estimated);
- update_extent_pos(alloc, extentPtr);
- }
-
-#ifdef VM_TRACE
- {
- Local_key page;
- page.m_file_no = pagePtr.p->m_file_no;
- page.m_page_no = pagePtr.p->m_page_no;
-
- Tablespace_client tsman(0, c_tsman,
- 0, 0, 0);
- unsigned uncommitted, committed;
- uncommitted = committed = ~(unsigned)0;
- (void) tsman.get_page_free_bits(&page, &uncommitted, &committed);
- jamEntry();
-
- idx = alloc.calc_page_free_bits(real_free);
- ddassert(idx == committed);
- }
-#endif
-}
-
-/**
- * - Page free bits -
- * 0 = 00 - free - 100% free
- * 1 = 01 - atleast 70% free, 70= pct_free + 2 * (100 - pct_free) / 3
- * 2 = 10 - atleast 40% free, 40= pct_free + (100 - pct_free) / 3
- * 3 = 11 - full - less than pct_free% free, pct_free=10%
- *
- */
-
-#define DBG_DISK 0
-
-int
-Dbtup::disk_page_prealloc(Signal* signal,
- Ptr<Fragrecord> fragPtr,
- Local_key* key, Uint32 sz)
-{
- int err;
- Uint32 i, ptrI;
- Ptr<Page_request> req;
- Fragrecord* fragPtrP = fragPtr.p;
- Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
- Uint32 idx= alloc.calc_page_free_bits(sz);
- Tablespace_client tsman(signal, c_tsman,
- fragPtrP->fragTableId,
- fragPtrP->fragmentId,
- fragPtrP->m_tablespace_id);
-
- if (DBG_DISK)
- ndbout << "disk_page_prealloc";
-
- /**
- * 1) search current dirty pages
- */
- for(i= 0; i <= idx; i++)
- {
- if (!alloc.m_dirty_pages[i].isEmpty())
- {
- ptrI= alloc.m_dirty_pages[i].firstItem;
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, ptrI);
-
- PagePtr tmp;
- tmp.i = gpage.i;
- tmp.p = reinterpret_cast<Page*>(gpage.p);
- disk_page_prealloc_dirty_page(alloc, tmp, i, sz);
- key->m_page_no= tmp.p->m_page_no;
- key->m_file_no= tmp.p->m_file_no;
- if (DBG_DISK)
- ndbout << " found dirty page " << *key << endl;
- jam();
- return 0; // Page in memory
- }
- }
-
- /**
- * Search outanding page requests
- * callback does not need to access page request again
- * as it's not the first request to this page
- */
- for(i= 0; i <= idx; i++)
- {
- if (!alloc.m_page_requests[i].isEmpty())
- {
- ptrI= alloc.m_page_requests[i].firstItem;
- Ptr<Page_request> req;
- c_page_request_pool.getPtr(req, ptrI);
-
- disk_page_prealloc_transit_page(alloc, req, i, sz);
- * key = req.p->m_key;
- if (DBG_DISK)
- ndbout << " found transit page " << *key << endl;
- jam();
- return 0;
- }
- }
-
- /**
- * We need to request a page...
- */
- if (!c_page_request_pool.seize(req))
- {
- jam();
- err= 1;
- //XXX set error code
- ndbout_c("no free request");
- return -err;
- }
-
- req.p->m_ref_count= 1;
- req.p->m_frag_ptr_i= fragPtr.i;
- req.p->m_uncommitted_used_space= sz;
-
- int pageBits; // received
- Ptr<Extent_info> ext;
- const Uint32 bits= alloc.calc_page_free_bits(sz); // required
- bool found= false;
-
- /**
- * Do we have a current extent
- */
- if ((ext.i= alloc.m_curr_extent_info_ptr_i) != RNIL)
- {
- jam();
- c_extent_pool.getPtr(ext);
- if ((pageBits= tsman.alloc_page_from_extent(&ext.p->m_key, bits)) >= 0)
- {
- jamEntry();
- found= true;
- }
- else
- {
- jamEntry();
- /**
- * The current extent is not in a free list
- * and since it couldn't accomadate the request
- * we put it on the free list
- */
- alloc.m_curr_extent_info_ptr_i = RNIL;
- Uint32 pos= alloc.calc_extent_pos(ext.p);
- ext.p->m_free_matrix_pos = pos;
- Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[pos]);
- list.add(ext);
- }
- }
-
- if (!found)
- {
- Uint32 pos;
- if ((pos= alloc.find_extent(sz)) != RNIL)
- {
- jam();
- Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[pos]);
- list.first(ext);
- list.remove(ext);
- }
- else
- {
- jam();
- /**
- * We need to alloc an extent
- */
-#if NOT_YET_UNDO_ALLOC_EXTENT
- Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id;
-
- err = c_lgman->alloc_log_space(logfile_group_id,
- sizeof(Disk_undo::AllocExtent)>>2);
- jamEntry();
- if(unlikely(err))
- {
- return -err;
- }
-#endif
-
- if (!c_extent_pool.seize(ext))
- {
- jam();
- //XXX
- err= 2;
-#if NOT_YET_UNDO_ALLOC_EXTENT
- c_lgman->free_log_space(logfile_group_id,
- sizeof(Disk_undo::AllocExtent)>>2);
-#endif
- c_page_request_pool.release(req);
- ndbout_c("no free extent info");
- return -err;
- }
-
- if ((err= tsman.alloc_extent(&ext.p->m_key)) < 0)
- {
- jamEntry();
-#if NOT_YET_UNDO_ALLOC_EXTENT
- c_lgman->free_log_space(logfile_group_id,
- sizeof(Disk_undo::AllocExtent)>>2);
-#endif
- c_extent_pool.release(ext);
- c_page_request_pool.release(req);
- return err;
- }
-
- int pages= err;
-#if NOT_YET_UNDO_ALLOC_EXTENT
- {
- /**
- * Do something here
- */
- {
- Callback cb;
- cb.m_callbackData= ext.i;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_alloc_extent_log_buffer_callback);
- Uint32 sz= sizeof(Disk_undo::AllocExtent)>>2;
-
- Logfile_client lgman(this, c_lgman, logfile_group_id);
- int res= lgman.get_log_buffer(signal, sz, &cb);
- switch(res){
- case 0:
- break;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- default:
- execute(signal, cb, res);
- }
- }
- }
-#endif
-
- ndbout << "allocated " << pages << " pages: " << ext.p->m_key << endl;
- ext.p->m_first_page_no = ext.p->m_key.m_page_no;
- bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count));
- ext.p->m_free_space= alloc.m_page_free_bits_map[0] * pages;
- ext.p->m_free_page_count[0]= pages; // All pages are "free"-est
- c_extent_hash.add(ext);
-
- Local_fragment_extent_list list1(c_extent_pool, alloc.m_extent_list);
- list1.add(ext);
- }
-
- alloc.m_curr_extent_info_ptr_i= ext.i;
- ext.p->m_free_matrix_pos= RNIL;
- pageBits= tsman.alloc_page_from_extent(&ext.p->m_key, bits);
- jamEntry();
- ddassert(pageBits >= 0);
- }
-
- /**
- * We have a page from an extent
- */
- *key= req.p->m_key= ext.p->m_key;
-
- if (DBG_DISK)
- ndbout << " allocated page " << *key << endl;
-
- /**
- * We don't know exact free space of page
- * but we know what page free bits it has.
- * compute free space based on them
- */
- Uint32 size= alloc.calc_page_free_space((Uint32)pageBits);
-
- ddassert(size >= sz);
- Uint32 new_size = size - sz; // Subtract alloc rec
- req.p->m_estimated_free_space= new_size; // Store on page request
-
- Uint32 newPageBits= alloc.calc_page_free_bits(new_size);
- if (newPageBits != (Uint32)pageBits)
- {
- jam();
- ddassert(ext.p->m_free_page_count[pageBits] > 0);
- ext.p->m_free_page_count[pageBits]--;
- ext.p->m_free_page_count[newPageBits]++;
- }
- ddassert(ext.p->m_free_space >= sz);
- ext.p->m_free_space -= sz;
-
- // And put page request in correct free list
- idx= alloc.calc_page_free_bits(new_size);
- {
- Local_page_request_list list(c_page_request_pool,
- alloc.m_page_requests[idx]);
-
- list.add(req);
- }
- req.p->m_list_index= idx;
- req.p->m_extent_info_ptr= ext.i;
-
- Page_cache_client::Request preq;
- preq.m_page = *key;
- preq.m_callback.m_callbackData= req.i;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_prealloc_callback);
-
- int flags= Page_cache_client::ALLOC_REQ;
- if (pageBits == 0)
- {
- jam();
- //XXX empty page -> fast to map
- flags |= Page_cache_client::EMPTY_PAGE;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_prealloc_initial_callback);
- }
-
- int res= m_pgman.get_page(signal, preq, flags);
- jamEntry();
- switch(res)
- {
- case 0:
- jam();
- break;
- case -1:
- ndbassert(false);
- break;
- default:
- jam();
- execute(signal, preq.m_callback, res); // run callback
- }
-
- return res;
-}
-
-void
-Dbtup::disk_page_prealloc_dirty_page(Disk_alloc_info & alloc,
- PagePtr pagePtr,
- Uint32 old_idx, Uint32 sz)
-{
- jam();
- ddassert(pagePtr.p->list_index == old_idx);
-
- Uint32 free= pagePtr.p->free_space;
- Uint32 used= pagePtr.p->uncommitted_used_space + sz;
- Uint32 ext= pagePtr.p->m_extent_info_ptr;
-
- ddassert(free >= used);
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, ext);
-
- Uint32 new_idx= alloc.calc_page_free_bits(free - used);
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
-
- if (old_idx != new_idx)
- {
- jam();
- LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
- LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
- old_list.remove(pagePtr);
- new_list.add(pagePtr);
-
- ddassert(extentPtr.p->m_free_page_count[old_idx]);
- extentPtr.p->m_free_page_count[old_idx]--;
- extentPtr.p->m_free_page_count[new_idx]++;
- pagePtr.p->list_index= new_idx;
- }
-
- pagePtr.p->uncommitted_used_space = used;
- ddassert(extentPtr.p->m_free_space >= sz);
- extentPtr.p->m_free_space -= sz;
- update_extent_pos(alloc, extentPtr);
-}
-
-
-void
-Dbtup::disk_page_prealloc_transit_page(Disk_alloc_info& alloc,
- Ptr<Page_request> req,
- Uint32 old_idx, Uint32 sz)
-{
- jam();
- ddassert(req.p->m_list_index == old_idx);
-
- Uint32 free= req.p->m_estimated_free_space;
- Uint32 used= req.p->m_uncommitted_used_space + sz;
- Uint32 ext= req.p->m_extent_info_ptr;
-
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, ext);
-
- ddassert(free >= sz);
- Uint32 new_idx= alloc.calc_page_free_bits(free - sz);
-
- if (old_idx != new_idx)
- {
- jam();
- Page_request_list::Head *lists = alloc.m_page_requests;
- Local_page_request_list old_list(c_page_request_pool, lists[old_idx]);
- Local_page_request_list new_list(c_page_request_pool, lists[new_idx]);
- old_list.remove(req);
- new_list.add(req);
-
- ddassert(extentPtr.p->m_free_page_count[old_idx]);
- extentPtr.p->m_free_page_count[old_idx]--;
- extentPtr.p->m_free_page_count[new_idx]++;
- req.p->m_list_index= new_idx;
- }
-
- req.p->m_uncommitted_used_space = used;
- req.p->m_estimated_free_space = free - sz;
- ddassert(extentPtr.p->m_free_space >= sz);
- extentPtr.p->m_free_space -= sz;
- update_extent_pos(alloc, extentPtr);
-}
-
-
-void
-Dbtup::disk_page_prealloc_callback(Signal* signal,
- Uint32 page_request, Uint32 page_id)
-{
- jamEntry();
- //ndbout_c("disk_alloc_page_callback id: %d", page_id);
-
- Ptr<Page_request> req;
- c_page_request_pool.getPtr(req, page_request);
-
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
-
- Ptr<Fragrecord> fragPtr;
- fragPtr.i= req.p->m_frag_ptr_i;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- if (unlikely(pagePtr.p->m_restart_seq != globalData.m_restart_seq))
- {
- restart_setup_page(fragPtr.p->m_disk_alloc_info, pagePtr);
- }
-
- disk_page_prealloc_callback_common(signal, req, fragPtr, pagePtr);
-}
-
-void
-Dbtup::disk_page_prealloc_initial_callback(Signal*signal,
- Uint32 page_request,
- Uint32 page_id)
-{
- jamEntry();
- //ndbout_c("disk_alloc_page_callback_initial id: %d", page_id);
- /**
- * 1) lookup page request
- * 2) lookup page
- * 3) lookup table
- * 4) init page (according to page type)
- * 5) call ordinary callback
- */
- Ptr<Page_request> req;
- c_page_request_pool.getPtr(req, page_request);
-
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- Ptr<Fragrecord> fragPtr;
- fragPtr.i= req.p->m_frag_ptr_i;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- Ptr<Tablerec> tabPtr;
- tabPtr.i = fragPtr.p->fragTableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, req.p->m_extent_info_ptr);
-
- pagePtr.p->m_page_no= req.p->m_key.m_page_no;
- pagePtr.p->m_file_no= req.p->m_key.m_file_no;
- pagePtr.p->m_table_id= fragPtr.p->fragTableId;
- pagePtr.p->m_fragment_id = fragPtr.p->fragmentId;
- pagePtr.p->m_extent_no = extentPtr.p->m_key.m_page_idx; // logical extent no
- pagePtr.p->m_extent_info_ptr= req.p->m_extent_info_ptr;
- pagePtr.p->m_restart_seq = globalData.m_restart_seq;
- pagePtr.p->list_index = 0x8000;
- pagePtr.p->uncommitted_used_space = 0;
- pagePtr.p->nextList = pagePtr.p->prevList = RNIL;
-
- if (tabPtr.p->m_attributes[DD].m_no_of_varsize == 0)
- {
- convertThPage((Fix_page*)pagePtr.p, tabPtr.p, DD);
- }
- else
- {
- abort();
- }
- disk_page_prealloc_callback_common(signal, req, fragPtr, pagePtr);
-}
-
-void
-Dbtup::disk_page_prealloc_callback_common(Signal* signal,
- Ptr<Page_request> req,
- Ptr<Fragrecord> fragPtr,
- PagePtr pagePtr)
-{
- /**
- * 1) remove page request from Disk_alloc_info.m_page_requests
- * 2) Add page to Disk_alloc_info.m_dirty_pages
- * 3) register callback in pgman (unmap callback)
- * 4) inform pgman about current users
- */
- Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
- ddassert((pagePtr.p->list_index & 0x8000) == 0x8000);
- ddassert(pagePtr.p->m_extent_info_ptr == req.p->m_extent_info_ptr);
- ddassert(pagePtr.p->m_page_no == req.p->m_key.m_page_no);
- ddassert(pagePtr.p->m_file_no == req.p->m_key.m_file_no);
-
- Uint32 old_idx = req.p->m_list_index;
- Uint32 free= req.p->m_estimated_free_space;
- Uint32 ext = req.p->m_extent_info_ptr;
- Uint32 used= req.p->m_uncommitted_used_space;
- Uint32 real_free = pagePtr.p->free_space;
- Uint32 real_used = used + pagePtr.p->uncommitted_used_space;
-
- ddassert(real_free >= free);
- ddassert(real_free >= real_used);
- ddassert(alloc.calc_page_free_bits(free) == old_idx);
- Uint32 new_idx= alloc.calc_page_free_bits(real_free - real_used);
-
- /**
- * Add to dirty pages
- */
- ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> list(* cheat_pool, alloc.m_dirty_pages[new_idx]);
- list.add(pagePtr);
- pagePtr.p->uncommitted_used_space = real_used;
- pagePtr.p->list_index = new_idx;
-
- if (old_idx != new_idx || free != real_free)
- {
- jam();
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, ext);
-
- extentPtr.p->m_free_space += (real_free - free);
-
- if (old_idx != new_idx)
- {
- jam();
- ddassert(extentPtr.p->m_free_page_count[old_idx]);
- extentPtr.p->m_free_page_count[old_idx]--;
- extentPtr.p->m_free_page_count[new_idx]++;
- }
-
- update_extent_pos(alloc, extentPtr);
- }
-
- {
- Local_page_request_list list(c_page_request_pool,
- alloc.m_page_requests[old_idx]);
- list.release(req);
- }
-}
-
-void
-Dbtup::disk_page_set_dirty(PagePtr pagePtr)
-{
- jam();
- Uint32 idx = pagePtr.p->list_index;
- if ((idx & 0x8000) == 0)
- {
- jam();
- /**
- * Already in dirty list
- */
- return ;
- }
-
- Local_key key;
- key.m_page_no = pagePtr.p->m_page_no;
- key.m_file_no = pagePtr.p->m_file_no;
-
- pagePtr.p->nextList = pagePtr.p->prevList = RNIL;
-
- if (DBG_DISK)
- ndbout << " disk_page_set_dirty " << key << endl;
-
- Ptr<Tablerec> tabPtr;
- tabPtr.i= pagePtr.p->m_table_id;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- Ptr<Fragrecord> fragPtr;
- getFragmentrec(fragPtr, pagePtr.p->m_fragment_id, tabPtr.p);
-
- Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
-
- Uint32 free = pagePtr.p->free_space;
- Uint32 used = pagePtr.p->uncommitted_used_space;
- if (unlikely(pagePtr.p->m_restart_seq != globalData.m_restart_seq))
- {
- restart_setup_page(alloc, pagePtr);
- idx = alloc.calc_page_free_bits(free);
- used = 0;
- }
- else
- {
- idx &= ~0x8000;
- ddassert(idx == alloc.calc_page_free_bits(free - used));
- }
-
- ddassert(free >= used);
-
- Tablespace_client tsman(0, c_tsman,
- fragPtr.p->fragTableId,
- fragPtr.p->fragmentId,
- fragPtr.p->m_tablespace_id);
-
- pagePtr.p->list_index = idx;
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> list(*pool, alloc.m_dirty_pages[idx]);
- list.add(pagePtr);
-
- // Make sure no one will allocate it...
- tsman.unmap_page(&key, MAX_FREE_LIST - 1);
- jamEntry();
-}
-
-void
-Dbtup::disk_page_unmap_callback(Uint32 when,
- Uint32 page_id, Uint32 dirty_count)
-{
- jamEntry();
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- Uint32 type = pagePtr.p->m_page_header.m_page_type;
- if (unlikely((type != File_formats::PT_Tup_fixsize_page &&
- type != File_formats::PT_Tup_varsize_page) ||
- f_undo_done == false))
- {
- jam();
- return ;
- }
-
- Uint32 idx = pagePtr.p->list_index;
-
- Ptr<Tablerec> tabPtr;
- tabPtr.i= pagePtr.p->m_table_id;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- Ptr<Fragrecord> fragPtr;
- getFragmentrec(fragPtr, pagePtr.p->m_fragment_id, tabPtr.p);
-
- Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
-
- if (when == 0)
- {
- /**
- * Before pageout
- */
- jam();
-
- if (DBG_DISK)
- {
- Local_key key;
- key.m_page_no = pagePtr.p->m_page_no;
- key.m_file_no = pagePtr.p->m_file_no;
- ndbout << "disk_page_unmap_callback(before) " << key
- << " cnt: " << dirty_count << " " << (idx & ~0x8000) << endl;
- }
-
- ndbassert((idx & 0x8000) == 0);
-
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> list(*pool, alloc.m_dirty_pages[idx]);
- LocalDLList<Page> list2(*pool, alloc.m_unmap_pages);
- list.remove(pagePtr);
- list2.add(pagePtr);
-
- if (dirty_count == 0)
- {
- jam();
- pagePtr.p->list_index = idx | 0x8000;
-
- Local_key key;
- key.m_page_no = pagePtr.p->m_page_no;
- key.m_file_no = pagePtr.p->m_file_no;
-
- Uint32 free = pagePtr.p->free_space;
- Uint32 used = pagePtr.p->uncommitted_used_space;
- ddassert(free >= used);
- ddassert(alloc.calc_page_free_bits(free - used) == idx);
-
- Tablespace_client tsman(0, c_tsman,
- fragPtr.p->fragTableId,
- fragPtr.p->fragmentId,
- fragPtr.p->m_tablespace_id);
-
- tsman.unmap_page(&key, idx);
- jamEntry();
- }
- }
- else if (when == 1)
- {
- /**
- * After page out
- */
- jam();
-
- Local_key key;
- key.m_page_no = pagePtr.p->m_page_no;
- key.m_file_no = pagePtr.p->m_file_no;
- Uint32 real_free = pagePtr.p->free_space;
-
- if (DBG_DISK)
- {
- ndbout << "disk_page_unmap_callback(after) " << key
- << " cnt: " << dirty_count << " " << (idx & ~0x8000) << endl;
- }
-
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> list(*pool, alloc.m_unmap_pages);
- list.remove(pagePtr);
-
- Tablespace_client tsman(0, c_tsman,
- fragPtr.p->fragTableId,
- fragPtr.p->fragmentId,
- fragPtr.p->m_tablespace_id);
-
- if (DBG_DISK && alloc.calc_page_free_bits(real_free) != (idx & ~0x8000))
- {
- ndbout << key
- << " calc: " << alloc.calc_page_free_bits(real_free)
- << " idx: " << (idx & ~0x8000)
- << endl;
- }
- tsman.update_page_free_bits(&key, alloc.calc_page_free_bits(real_free));
- jamEntry();
- }
-}
-
-void
-Dbtup::disk_page_alloc(Signal* signal,
- Tablerec* tabPtrP, Fragrecord* fragPtrP,
- Local_key* key, PagePtr pagePtr, Uint32 gci)
-{
- jam();
- Uint32 logfile_group_id= fragPtrP->m_logfile_group_id;
- Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
-
- Uint64 lsn;
- if (tabPtrP->m_attributes[DD].m_no_of_varsize == 0)
- {
- ddassert(pagePtr.p->uncommitted_used_space > 0);
- pagePtr.p->uncommitted_used_space--;
- key->m_page_idx= ((Fix_page*)pagePtr.p)->alloc_record();
- lsn= disk_page_undo_alloc(pagePtr.p, key, 1, gci, logfile_group_id);
- }
- else
- {
- Uint32 sz= key->m_page_idx;
- ddassert(pagePtr.p->uncommitted_used_space >= sz);
- pagePtr.p->uncommitted_used_space -= sz;
- key->m_page_idx= ((Var_page*)pagePtr.p)->
- alloc_record(sz, (Var_page*)ctemp_page, 0);
-
- lsn= disk_page_undo_alloc(pagePtr.p, key, sz, gci, logfile_group_id);
- }
-}
-
-void
-Dbtup::disk_page_free(Signal *signal,
- Tablerec *tabPtrP, Fragrecord * fragPtrP,
- Local_key* key, PagePtr pagePtr, Uint32 gci)
-{
- jam();
- if (DBG_DISK)
- ndbout << " disk_page_free " << *key << endl;
-
- Uint32 page_idx= key->m_page_idx;
- Uint32 logfile_group_id= fragPtrP->m_logfile_group_id;
- Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
- Uint32 old_free= pagePtr.p->free_space;
-
- Uint32 sz;
- Uint64 lsn;
- if (tabPtrP->m_attributes[DD].m_no_of_varsize == 0)
- {
- sz = 1;
- const Uint32 *src= ((Fix_page*)pagePtr.p)->get_ptr(page_idx, 0);
- ndbassert(* (src + 1) != Tup_fixsize_page::FREE_RECORD);
- lsn= disk_page_undo_free(pagePtr.p, key,
- src, tabPtrP->m_offsets[DD].m_fix_header_size,
- gci, logfile_group_id);
-
- ((Fix_page*)pagePtr.p)->free_record(page_idx);
- }
- else
- {
- const Uint32 *src= ((Var_page*)pagePtr.p)->get_ptr(page_idx);
- sz= ((Var_page*)pagePtr.p)->get_entry_len(page_idx);
- lsn= disk_page_undo_free(pagePtr.p, key,
- src, sz,
- gci, logfile_group_id);
-
- ((Var_page*)pagePtr.p)->free_record(page_idx, 0);
- }
-
- Uint32 new_free = pagePtr.p->free_space;
-
- Uint32 ext = pagePtr.p->m_extent_info_ptr;
- Uint32 used = pagePtr.p->uncommitted_used_space;
- Uint32 old_idx = pagePtr.p->list_index;
- ddassert(old_free >= used);
- ddassert(new_free >= used);
- ddassert(new_free >= old_free);
- ddassert((old_idx & 0x8000) == 0);
-
- Uint32 new_idx = alloc.calc_page_free_bits(new_free - used);
- ddassert(alloc.calc_page_free_bits(old_free - used) == old_idx);
-
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, ext);
-
- if (old_idx != new_idx)
- {
- jam();
- ddassert(extentPtr.p->m_free_page_count[old_idx]);
- extentPtr.p->m_free_page_count[old_idx]--;
- extentPtr.p->m_free_page_count[new_idx]++;
-
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
- LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
- old_list.remove(pagePtr);
- new_list.add(pagePtr);
- pagePtr.p->list_index = new_idx;
- }
-
- extentPtr.p->m_free_space += sz;
- update_extent_pos(alloc, extentPtr);
-#if NOT_YET_FREE_EXTENT
- if (check_free(extentPtr.p) == 0)
- {
- ndbout_c("free: extent is free");
- }
-#endif
-}
-
-void
-Dbtup::disk_page_abort_prealloc(Signal *signal, Fragrecord* fragPtrP,
- Local_key* key, Uint32 sz)
-{
- jam();
- Page_cache_client::Request req;
- req.m_callback.m_callbackData= sz;
- req.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_abort_prealloc_callback);
-
- int flags= Page_cache_client::DIRTY_REQ;
- memcpy(&req.m_page, key, sizeof(Local_key));
-
- int res= m_pgman.get_page(signal, req, flags);
- jamEntry();
- switch(res)
- {
- case 0:
- jam();
- break;
- case -1:
- ndbrequire(false);
- break;
- default:
- jam();
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, (Uint32)res);
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- disk_page_abort_prealloc_callback_1(signal, fragPtrP, pagePtr, sz);
- }
-}
-
-void
-Dbtup::disk_page_abort_prealloc_callback(Signal* signal,
- Uint32 sz, Uint32 page_id)
-{
- //ndbout_c("disk_alloc_page_callback id: %d", page_id);
- jamEntry();
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
-
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- Ptr<Tablerec> tabPtr;
- tabPtr.i= pagePtr.p->m_table_id;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- Ptr<Fragrecord> fragPtr;
- getFragmentrec(fragPtr, pagePtr.p->m_fragment_id, tabPtr.p);
-
- disk_page_abort_prealloc_callback_1(signal, fragPtr.p, pagePtr, sz);
-}
-
-void
-Dbtup::disk_page_abort_prealloc_callback_1(Signal* signal,
- Fragrecord* fragPtrP,
- PagePtr pagePtr,
- Uint32 sz)
-{
- jam();
- disk_page_set_dirty(pagePtr);
-
- Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
- Uint32 page_idx = pagePtr.p->list_index;
- Uint32 used = pagePtr.p->uncommitted_used_space;
- Uint32 free = pagePtr.p->free_space;
- Uint32 ext = pagePtr.p->m_extent_info_ptr;
-
- Uint32 old_idx = page_idx & 0x7FFF;
- ddassert(free >= used);
- ddassert(used >= sz);
- ddassert(alloc.calc_page_free_bits(free - used) == old_idx);
- Uint32 new_idx = alloc.calc_page_free_bits(free - used + sz);
-
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, ext);
- if (old_idx != new_idx)
- {
- jam();
- ddassert(extentPtr.p->m_free_page_count[old_idx]);
- extentPtr.p->m_free_page_count[old_idx]--;
- extentPtr.p->m_free_page_count[new_idx]++;
-
- if (old_idx == page_idx)
- {
- jam();
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
- LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
- old_list.remove(pagePtr);
- new_list.add(pagePtr);
- pagePtr.p->list_index = new_idx;
- }
- else
- {
- jam();
- pagePtr.p->list_index = new_idx | 0x8000;
- }
- }
-
- pagePtr.p->uncommitted_used_space = used - sz;
-
- extentPtr.p->m_free_space += sz;
- update_extent_pos(alloc, extentPtr);
-#if NOT_YET_FREE_EXTENT
- if (check_free(extentPtr.p) == 0)
- {
- ndbout_c("abort: extent is free");
- }
-#endif
-}
-
-#if NOT_YET_UNDO_ALLOC_EXTENT
-void
-Dbtup::disk_page_alloc_extent_log_buffer_callback(Signal* signal,
- Uint32 extentPtrI,
- Uint32 unused)
-{
- Ptr<Extent_info> extentPtr;
- c_extent_pool.getPtr(extentPtr, extentPtrI);
-
- Local_key key = extentPtr.p->m_key;
- Tablespace_client2 tsman(signal, c_tsman, &key);
-
- Ptr<Tablerec> tabPtr;
- tabPtr.i= tsman.m_table_id;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- Ptr<Fragrecord> fragPtr;
- getFragmentrec(fragPtr, tsman.m_fragment_id, tabPtr.p);
-
- Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
-
- Disk_undo::AllocExtent alloc;
- alloc.m_table = tabPtr.i;
- alloc.m_fragment = tsman.m_fragment_id;
- alloc.m_page_no = key.m_page_no;
- alloc.m_file_no = key.m_file_no;
- alloc.m_type_length = (Disk_undo::UNDO_ALLOC_EXTENT<<16)|(sizeof(alloc)>> 2);
-
- Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } };
-
- Uint64 lsn= lgman.add_entry(c, 1);
-
- tsman.update_lsn(&key, lsn);
- jamEntry();
-}
-#endif
-
-Uint64
-Dbtup::disk_page_undo_alloc(Page* page, const Local_key* key,
- Uint32 sz, Uint32 gci, Uint32 logfile_group_id)
-{
- jam();
- Logfile_client lgman(this, c_lgman, logfile_group_id);
-
- Disk_undo::Alloc alloc;
- alloc.m_type_length= (Disk_undo::UNDO_ALLOC << 16) | (sizeof(alloc) >> 2);
- alloc.m_page_no = key->m_page_no;
- alloc.m_file_no_page_idx= key->m_file_no << 16 | key->m_page_idx;
-
- Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } };
-
- Uint64 lsn= lgman.add_entry(c, 1);
- m_pgman.update_lsn(* key, lsn);
- jamEntry();
-
- return lsn;
-}
-
-Uint64
-Dbtup::disk_page_undo_update(Page* page, const Local_key* key,
- const Uint32* src, Uint32 sz,
- Uint32 gci, Uint32 logfile_group_id)
-{
- jam();
- Logfile_client lgman(this, c_lgman, logfile_group_id);
-
- Disk_undo::Update update;
- update.m_page_no = key->m_page_no;
- update.m_file_no_page_idx= key->m_file_no << 16 | key->m_page_idx;
- update.m_gci= gci;
-
- update.m_type_length=
- (Disk_undo::UNDO_UPDATE << 16) | (sz + (sizeof(update) >> 2) - 1);
-
- Logfile_client::Change c[3] = {
- { &update, 3 },
- { src, sz },
- { &update.m_type_length, 1 }
- };
-
- ndbassert(4*(3 + sz + 1) == (sizeof(update) + 4*sz - 4));
-
- Uint64 lsn= lgman.add_entry(c, 3);
- m_pgman.update_lsn(* key, lsn);
- jamEntry();
-
- return lsn;
-}
-
-Uint64
-Dbtup::disk_page_undo_free(Page* page, const Local_key* key,
- const Uint32* src, Uint32 sz,
- Uint32 gci, Uint32 logfile_group_id)
-{
- jam();
- Logfile_client lgman(this, c_lgman, logfile_group_id);
-
- Disk_undo::Free free;
- free.m_page_no = key->m_page_no;
- free.m_file_no_page_idx= key->m_file_no << 16 | key->m_page_idx;
- free.m_gci= gci;
-
- free.m_type_length=
- (Disk_undo::UNDO_FREE << 16) | (sz + (sizeof(free) >> 2) - 1);
-
- Logfile_client::Change c[3] = {
- { &free, 3 },
- { src, sz },
- { &free.m_type_length, 1 }
- };
-
- ndbassert(4*(3 + sz + 1) == (sizeof(free) + 4*sz - 4));
-
- Uint64 lsn= lgman.add_entry(c, 3);
- m_pgman.update_lsn(* key, lsn);
- jamEntry();
-
- return lsn;
-}
-
-#include <signaldata/LgmanContinueB.hpp>
-
-static Dbtup::Apply_undo f_undo;
-
-#define DBG_UNDO 0
-
-void
-Dbtup::disk_restart_undo(Signal* signal, Uint64 lsn,
- Uint32 type, const Uint32 * ptr, Uint32 len)
-{
- f_undo_done = false;
- f_undo.m_lsn= lsn;
- f_undo.m_ptr= ptr;
- f_undo.m_len= len;
- f_undo.m_type = type;
-
- Page_cache_client::Request preq;
- switch(f_undo.m_type){
- case File_formats::Undofile::UNDO_LCP_FIRST:
- case File_formats::Undofile::UNDO_LCP:
- {
- jam();
- ndbrequire(len == 3);
- Uint32 lcp = ptr[0];
- Uint32 tableId = ptr[1] >> 16;
- Uint32 fragId = ptr[1] & 0xFFFF;
- disk_restart_undo_lcp(tableId, fragId, Fragrecord::UC_LCP, lcp);
- disk_restart_undo_next(signal);
-
- if (DBG_UNDO)
- {
- ndbout_c("UNDO LCP %u (%u, %u)", lcp, tableId, fragId);
- }
- return;
- }
- case File_formats::Undofile::UNDO_TUP_ALLOC:
- {
- jam();
- Disk_undo::Alloc* rec= (Disk_undo::Alloc*)ptr;
- preq.m_page.m_page_no = rec->m_page_no;
- preq.m_page.m_file_no = rec->m_file_no_page_idx >> 16;
- preq.m_page.m_page_idx = rec->m_file_no_page_idx & 0xFFFF;
- break;
- }
- case File_formats::Undofile::UNDO_TUP_UPDATE:
- {
- jam();
- Disk_undo::Update* rec= (Disk_undo::Update*)ptr;
- preq.m_page.m_page_no = rec->m_page_no;
- preq.m_page.m_file_no = rec->m_file_no_page_idx >> 16;
- preq.m_page.m_page_idx = rec->m_file_no_page_idx & 0xFFFF;
- break;
- }
- case File_formats::Undofile::UNDO_TUP_FREE:
- {
- jam();
- Disk_undo::Free* rec= (Disk_undo::Free*)ptr;
- preq.m_page.m_page_no = rec->m_page_no;
- preq.m_page.m_file_no = rec->m_file_no_page_idx >> 16;
- preq.m_page.m_page_idx = rec->m_file_no_page_idx & 0xFFFF;
- break;
- }
- case File_formats::Undofile::UNDO_TUP_CREATE:
- /**
- *
- */
- {
- jam();
- Disk_undo::Create* rec= (Disk_undo::Create*)ptr;
- Ptr<Tablerec> tabPtr;
- tabPtr.i= rec->m_table;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- for(Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++)
- if (tabPtr.p->fragrec[i] != RNIL)
- disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i],
- Fragrecord::UC_CREATE, 0);
- disk_restart_undo_next(signal);
-
- if (DBG_UNDO)
- {
- ndbout_c("UNDO CREATE (%u)", tabPtr.i);
- }
- return;
- }
- case File_formats::Undofile::UNDO_TUP_DROP:
- {
- jam();
- Disk_undo::Drop* rec = (Disk_undo::Drop*)ptr;
- Ptr<Tablerec> tabPtr;
- tabPtr.i= rec->m_table;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- for(Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++)
- if (tabPtr.p->fragrec[i] != RNIL)
- disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i],
- Fragrecord::UC_CREATE, 0);
- disk_restart_undo_next(signal);
-
- if (DBG_UNDO)
- {
- ndbout_c("UNDO DROP (%u)", tabPtr.i);
- }
- return;
- }
- case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
- jam();
- case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
- jam();
- disk_restart_undo_next(signal);
- return;
-
- case File_formats::Undofile::UNDO_END:
- jam();
- f_undo_done = true;
- return;
- default:
- ndbrequire(false);
- }
-
- f_undo.m_key = preq.m_page;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_restart_undo_callback);
-
- int flags = 0;
- int res= m_pgman.get_page(signal, preq, flags);
- jamEntry();
- switch(res)
- {
- case 0:
- break; // Wait for callback
- case -1:
- ndbrequire(false);
- break;
- default:
- execute(signal, preq.m_callback, res); // run callback
- }
-}
-
-void
-Dbtup::disk_restart_undo_next(Signal* signal)
-{
- signal->theData[0] = LgmanContinueB::EXECUTE_UNDO_RECORD;
- sendSignal(LGMAN_REF, GSN_CONTINUEB, signal, 1, JBB);
-}
-
-void
-Dbtup::disk_restart_lcp_id(Uint32 tableId, Uint32 fragId, Uint32 lcpId)
-{
- jamEntry();
-
- if (lcpId == RNIL)
- {
- disk_restart_undo_lcp(tableId, fragId, Fragrecord::UC_CREATE, 0);
- if (DBG_UNDO)
- {
- ndbout_c("mark_no_lcp (%u, %u)", tableId, fragId);
- }
- }
- else
- {
- disk_restart_undo_lcp(tableId, fragId, Fragrecord::UC_SET_LCP, lcpId);
- if (DBG_UNDO)
- {
- ndbout_c("mark_no_lcp (%u, %u)", tableId, fragId);
- }
-
- }
-}
-
-void
-Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId, Uint32 flag,
- Uint32 lcpId)
-{
- Ptr<Tablerec> tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- if (tabPtr.p->tableStatus == DEFINED)
- {
- jam();
- FragrecordPtr fragPtr;
- getFragmentrec(fragPtr, fragId, tabPtr.p);
- if (!fragPtr.isNull())
- {
- jam();
- switch(flag){
- case Fragrecord::UC_CREATE:
- jam();
- fragPtr.p->m_undo_complete |= flag;
- return;
- case Fragrecord::UC_LCP:
- jam();
- if (fragPtr.p->m_undo_complete == 0 &&
- fragPtr.p->m_restore_lcp_id == lcpId)
- {
- jam();
- fragPtr.p->m_undo_complete |= flag;
- if (DBG_UNDO)
- ndbout_c("table: %u fragment: %u lcp: %u -> done",
- tableId, fragId, lcpId);
- }
- return;
- case Fragrecord::UC_SET_LCP:
- {
- jam();
- if (DBG_UNDO)
- ndbout_c("table: %u fragment: %u restore to lcp: %u",
- tableId, fragId, lcpId);
- ndbrequire(fragPtr.p->m_undo_complete == 0);
- ndbrequire(fragPtr.p->m_restore_lcp_id == RNIL);
- fragPtr.p->m_restore_lcp_id = lcpId;
- return;
- }
- }
- jamLine(flag);
- ndbrequire(false);
- }
- }
-}
-
-void
-Dbtup::disk_restart_undo_callback(Signal* signal,
- Uint32 id,
- Uint32 page_id)
-{
- jamEntry();
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
- PagePtr pagePtr;
- pagePtr.i = gpage.i;
- pagePtr.p = reinterpret_cast<Page*>(gpage.p);
-
- Apply_undo* undo = &f_undo;
-
- bool update = false;
- if (! (pagePtr.p->list_index & 0x8000) ||
- pagePtr.p->nextList != RNIL ||
- pagePtr.p->prevList != RNIL)
- {
- jam();
- update = true;
- pagePtr.p->list_index |= 0x8000;
- pagePtr.p->nextList = pagePtr.p->prevList = RNIL;
- }
-
- Uint32 tableId= pagePtr.p->m_table_id;
- Uint32 fragId = pagePtr.p->m_fragment_id;
-
- if (tableId >= cnoOfTablerec)
- {
- jam();
- if (DBG_UNDO)
- ndbout_c("UNDO table> %u", tableId);
- disk_restart_undo_next(signal);
- return;
- }
- undo->m_table_ptr.i = tableId;
- ptrCheckGuard(undo->m_table_ptr, cnoOfTablerec, tablerec);
-
- if (undo->m_table_ptr.p->tableStatus != DEFINED)
- {
- jam();
- if (DBG_UNDO)
- ndbout_c("UNDO !defined (%u) ", tableId);
- disk_restart_undo_next(signal);
- return;
- }
-
- getFragmentrec(undo->m_fragment_ptr, fragId, undo->m_table_ptr.p);
- if(undo->m_fragment_ptr.isNull())
- {
- jam();
- if (DBG_UNDO)
- ndbout_c("UNDO fragment null %u/%u", tableId, fragId);
- disk_restart_undo_next(signal);
- return;
- }
-
- if (undo->m_fragment_ptr.p->m_undo_complete)
- {
- jam();
- if (DBG_UNDO)
- ndbout_c("UNDO undo complete %u/%u", tableId, fragId);
- disk_restart_undo_next(signal);
- return;
- }
-
- Local_key key = undo->m_key;
-// key.m_page_no = pagePtr.p->m_page_no;
-// key.m_file_no = pagePtr.p->m_file_no;
-
- Uint64 lsn = 0;
- lsn += pagePtr.p->m_page_header.m_page_lsn_hi; lsn <<= 32;
- lsn += pagePtr.p->m_page_header.m_page_lsn_lo;
-
- undo->m_page_ptr = pagePtr;
-
- if (undo->m_lsn <= lsn)
- {
- jam();
- if (DBG_UNDO)
- {
- ndbout << "apply: " << undo->m_lsn << "(" << lsn << " )"
- << key << " type: " << undo->m_type << endl;
- }
-
- update = true;
- if (DBG_UNDO)
- ndbout_c("applying %lld", undo->m_lsn);
- /**
- * Apply undo record
- */
- switch(undo->m_type){
- case File_formats::Undofile::UNDO_TUP_ALLOC:
- jam();
- disk_restart_undo_alloc(undo);
- break;
- case File_formats::Undofile::UNDO_TUP_UPDATE:
- jam();
- disk_restart_undo_update(undo);
- break;
- case File_formats::Undofile::UNDO_TUP_FREE:
- jam();
- disk_restart_undo_free(undo);
- break;
- default:
- ndbrequire(false);
- }
-
- if (DBG_UNDO)
- ndbout << "disk_restart_undo: " << undo->m_type << " "
- << undo->m_key << endl;
-
- lsn = undo->m_lsn - 1; // make sure undo isn't run again...
-
- m_pgman.update_lsn(undo->m_key, lsn);
- jamEntry();
-
- disk_restart_undo_page_bits(signal, undo);
- }
- else if (DBG_UNDO)
- {
- jam();
- ndbout << "ignore: " << undo->m_lsn << "(" << lsn << " )"
- << key << " type: " << undo->m_type
- << " tab: " << tableId << endl;
- }
-
- disk_restart_undo_next(signal);
-}
-
-void
-Dbtup::disk_restart_undo_alloc(Apply_undo* undo)
-{
- ndbassert(undo->m_page_ptr.p->m_file_no == undo->m_key.m_file_no);
- ndbassert(undo->m_page_ptr.p->m_page_no == undo->m_key.m_page_no);
- if (undo->m_table_ptr.p->m_attributes[DD].m_no_of_varsize == 0)
- {
- ((Fix_page*)undo->m_page_ptr.p)->free_record(undo->m_key.m_page_idx);
- }
- else
- ((Var_page*)undo->m_page_ptr.p)->free_record(undo->m_key.m_page_idx, 0);
-}
-
-void
-Dbtup::disk_restart_undo_update(Apply_undo* undo)
-{
- Uint32* ptr;
- Uint32 len= undo->m_len - 4;
- if (undo->m_table_ptr.p->m_attributes[DD].m_no_of_varsize == 0)
- {
- ptr= ((Fix_page*)undo->m_page_ptr.p)->get_ptr(undo->m_key.m_page_idx, len);
- ndbrequire(len == undo->m_table_ptr.p->m_offsets[DD].m_fix_header_size);
- }
- else
- {
- ptr= ((Var_page*)undo->m_page_ptr.p)->get_ptr(undo->m_key.m_page_idx);
- abort();
- }
-
- const Disk_undo::Update *update = (const Disk_undo::Update*)undo->m_ptr;
- const Uint32* src= update->m_data;
- memcpy(ptr, src, 4 * len);
-}
-
-void
-Dbtup::disk_restart_undo_free(Apply_undo* undo)
-{
- Uint32* ptr, idx = undo->m_key.m_page_idx;
- Uint32 len= undo->m_len - 4;
- if (undo->m_table_ptr.p->m_attributes[DD].m_no_of_varsize == 0)
- {
- ndbrequire(len == undo->m_table_ptr.p->m_offsets[DD].m_fix_header_size);
- idx= ((Fix_page*)undo->m_page_ptr.p)->alloc_record(idx);
- ptr= ((Fix_page*)undo->m_page_ptr.p)->get_ptr(idx, len);
- }
- else
- {
- abort();
- }
-
- ndbrequire(idx == undo->m_key.m_page_idx);
- const Disk_undo::Free *free = (const Disk_undo::Free*)undo->m_ptr;
- const Uint32* src= free->m_data;
- memcpy(ptr, src, 4 * len);
-}
-
-void
-Dbtup::disk_restart_undo_page_bits(Signal* signal, Apply_undo* undo)
-{
- Fragrecord* fragPtrP = undo->m_fragment_ptr.p;
- Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
-
- /**
- * Set alloc.m_curr_extent_info_ptr_i to
- * current this extent (and move old extend into free matrix)
- */
- Page* pageP = undo->m_page_ptr.p;
- Uint32 free = pageP->free_space;
- Uint32 new_bits = alloc.calc_page_free_bits(free);
- pageP->list_index = 0x8000 | new_bits;
-
- Tablespace_client tsman(signal, c_tsman,
- fragPtrP->fragTableId,
- fragPtrP->fragmentId,
- fragPtrP->m_tablespace_id);
-
- tsman.restart_undo_page_free_bits(&undo->m_key, new_bits);
- jamEntry();
-}
-
-int
-Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
- const Local_key* key, Uint32 pages)
-{
- TablerecPtr tabPtr;
- FragrecordPtr fragPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- if (tabPtr.p->tableStatus == DEFINED)
- {
- getFragmentrec(fragPtr, fragId, tabPtr.p);
- if (fragPtr.p->m_undo_complete & Fragrecord::UC_CREATE)
- {
- jam();
- return -1;
- }
-
- if (!fragPtr.isNull())
- {
- Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
-
- Ptr<Extent_info> ext;
- ndbrequire(c_extent_pool.seize(ext));
-
- ndbout << "allocated " << pages << " pages: " << *key << endl;
-
- ext.p->m_key = *key;
- ext.p->m_first_page_no = ext.p->m_key.m_page_no;
- ext.p->m_free_space= 0;
- bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count));
-
- if (alloc.m_curr_extent_info_ptr_i != RNIL)
- {
- jam();
- Ptr<Extent_info> old;
- c_extent_pool.getPtr(old, alloc.m_curr_extent_info_ptr_i);
- ndbassert(old.p->m_free_matrix_pos == RNIL);
- Uint32 pos= alloc.calc_extent_pos(old.p);
- Local_extent_info_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
- new_list.add(old);
- old.p->m_free_matrix_pos= pos;
- }
-
- alloc.m_curr_extent_info_ptr_i = ext.i;
- ext.p->m_free_matrix_pos = RNIL;
- c_extent_hash.add(ext);
-
- Local_fragment_extent_list list1(c_extent_pool, alloc.m_extent_list);
- list1.add(ext);
- return 0;
- }
- }
-
- return -1;
-}
-
-void
-Dbtup::disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
- const Local_key*, Uint32 bits)
-{
- jam();
- TablerecPtr tabPtr;
- FragrecordPtr fragPtr;
- tabPtr.i = tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- getFragmentrec(fragPtr, fragId, tabPtr.p);
- Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
-
- Ptr<Extent_info> ext;
- c_extent_pool.getPtr(ext, alloc.m_curr_extent_info_ptr_i);
-
- Uint32 size= alloc.calc_page_free_space(bits);
-
- ext.p->m_free_space += size;
- ext.p->m_free_page_count[bits]++;
- ndbassert(ext.p->m_free_matrix_pos == RNIL);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
deleted file mode 100644
index d7d7f20bbc7..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ /dev/null
@@ -1,3205 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#include <Dblqh.hpp>
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <AttributeHeader.hpp>
-#include <Interpreter.hpp>
-#include <signaldata/TupKey.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <NdbSqlUtil.hpp>
-
-/* ----------------------------------------------------------------- */
-/* ----------- INIT_STORED_OPERATIONREC -------------- */
-/* ----------------------------------------------------------------- */
-int Dbtup::initStoredOperationrec(Operationrec* regOperPtr,
- KeyReqStruct* req_struct,
- Uint32 storedId)
-{
- jam();
- StoredProcPtr storedPtr;
- c_storedProcPool.getPtr(storedPtr, storedId);
- if (storedPtr.i != RNIL) {
- if (storedPtr.p->storedCode == ZSCAN_PROCEDURE) {
- storedPtr.p->storedCounter++;
- regOperPtr->firstAttrinbufrec= storedPtr.p->storedLinkFirst;
- regOperPtr->lastAttrinbufrec= storedPtr.p->storedLinkLast;
- regOperPtr->currentAttrinbufLen= storedPtr.p->storedProcLength;
- req_struct->attrinfo_len= storedPtr.p->storedProcLength;
- return ZOK;
- }
- }
- terrorCode= ZSTORED_PROC_ID_ERROR;
- return terrorCode;
-}
-
-void Dbtup::copyAttrinfo(Operationrec * regOperPtr,
- Uint32* inBuffer)
-{
- AttrbufrecPtr copyAttrBufPtr;
- Uint32 RnoOfAttrBufrec= cnoOfAttrbufrec;
- int RbufLen;
- Uint32 RinBufIndex= 0;
- Uint32 Rnext;
- Uint32 Rfirst;
- Uint32 TstoredProcedure= (regOperPtr->storedProcedureId != ZNIL);
- Uint32 RnoFree= cnoFreeAttrbufrec;
-
-//-------------------------------------------------------------------------
-// As a prelude to the execution of the TUPKEYREQ we will copy the program
-// into the inBuffer to enable easy execution without any complex jumping
-// between the buffers. In particular this will make the interpreter less
-// complex. Hopefully it does also improve performance.
-//-------------------------------------------------------------------------
- copyAttrBufPtr.i= regOperPtr->firstAttrinbufrec;
- while (copyAttrBufPtr.i != RNIL) {
- jam();
- ndbrequire(copyAttrBufPtr.i < RnoOfAttrBufrec);
- ptrAss(copyAttrBufPtr, attrbufrec);
- RbufLen = copyAttrBufPtr.p->attrbuf[ZBUF_DATA_LEN];
- Rnext = copyAttrBufPtr.p->attrbuf[ZBUF_NEXT];
- Rfirst = cfirstfreeAttrbufrec;
- /*
- * ATTRINFO comes from 2 mutually exclusive places:
- * 1) TUPKEYREQ (also interpreted part)
- * 2) STORED_PROCREQ before scan start
- * Assert here that both have a check for overflow.
- * The "<" instead of "<=" is intentional.
- */
- ndbrequire(RinBufIndex + RbufLen < ZATTR_BUFFER_SIZE);
- MEMCOPY_NO_WORDS(&inBuffer[RinBufIndex],
- &copyAttrBufPtr.p->attrbuf[0],
- RbufLen);
- RinBufIndex += RbufLen;
- if (!TstoredProcedure) {
- copyAttrBufPtr.p->attrbuf[ZBUF_NEXT]= Rfirst;
- cfirstfreeAttrbufrec= copyAttrBufPtr.i;
- RnoFree++;
- }
- copyAttrBufPtr.i= Rnext;
- }
- cnoFreeAttrbufrec= RnoFree;
- if (TstoredProcedure) {
- jam();
- StoredProcPtr storedPtr;
- c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId);
- ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
- storedPtr.p->storedCounter--;
- }
- // Release the ATTRINFO buffers
- regOperPtr->storedProcedureId= RNIL;
- regOperPtr->firstAttrinbufrec= RNIL;
- regOperPtr->lastAttrinbufrec= RNIL;
- regOperPtr->m_any_value= 0;
-}
-
-void Dbtup::handleATTRINFOforTUPKEYREQ(Signal* signal,
- const Uint32 *data,
- Uint32 len,
- Operationrec * regOperPtr)
-{
- while(len)
- {
- Uint32 length = len > AttrInfo::DataLength ? AttrInfo::DataLength : len;
-
- AttrbufrecPtr TAttrinbufptr;
- TAttrinbufptr.i= cfirstfreeAttrbufrec;
- if ((cfirstfreeAttrbufrec < cnoOfAttrbufrec) &&
- (cnoFreeAttrbufrec > MIN_ATTRBUF)) {
- ptrAss(TAttrinbufptr, attrbufrec);
- MEMCOPY_NO_WORDS(&TAttrinbufptr.p->attrbuf[0],
- data,
- length);
- Uint32 RnoFree= cnoFreeAttrbufrec;
- Uint32 Rnext= TAttrinbufptr.p->attrbuf[ZBUF_NEXT];
- TAttrinbufptr.p->attrbuf[ZBUF_DATA_LEN]= length;
- TAttrinbufptr.p->attrbuf[ZBUF_NEXT]= RNIL;
-
- AttrbufrecPtr locAttrinbufptr;
- Uint32 RnewLen= regOperPtr->currentAttrinbufLen;
-
- locAttrinbufptr.i= regOperPtr->lastAttrinbufrec;
- cfirstfreeAttrbufrec= Rnext;
- cnoFreeAttrbufrec= RnoFree - 1;
- RnewLen += length;
- regOperPtr->lastAttrinbufrec= TAttrinbufptr.i;
- regOperPtr->currentAttrinbufLen= RnewLen;
- if (locAttrinbufptr.i == RNIL) {
- regOperPtr->firstAttrinbufrec= TAttrinbufptr.i;
- } else {
- jam();
- ptrCheckGuard(locAttrinbufptr, cnoOfAttrbufrec, attrbufrec);
- locAttrinbufptr.p->attrbuf[ZBUF_NEXT]= TAttrinbufptr.i;
- }
- if (RnewLen < ZATTR_BUFFER_SIZE) {
- } else {
- jam();
- set_trans_state(regOperPtr, TRANS_TOO_MUCH_AI);
- return;
- }
- } else if (cnoFreeAttrbufrec <= MIN_ATTRBUF) {
- jam();
- set_trans_state(regOperPtr, TRANS_ERROR_WAIT_TUPKEYREQ);
- } else {
- ndbrequire(false);
- }
-
- len -= length;
- data += length;
- }
-}
-
-void Dbtup::execATTRINFO(Signal* signal)
-{
- Uint32 Rsig0= signal->theData[0];
- Uint32 Rlen= signal->length();
- jamEntry();
-
- receive_attrinfo(signal, Rsig0, signal->theData+3, Rlen-3);
-}
-
-void
-Dbtup::receive_attrinfo(Signal* signal, Uint32 op,
- const Uint32* data, Uint32 Rlen)
-{
- OperationrecPtr regOpPtr;
- regOpPtr.i= op;
- c_operation_pool.getPtr(regOpPtr, op);
- TransState trans_state= get_trans_state(regOpPtr.p);
- if (trans_state == TRANS_IDLE) {
- handleATTRINFOforTUPKEYREQ(signal, data, Rlen, regOpPtr.p);
- return;
- } else if (trans_state == TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO) {
- storedProcedureAttrInfo(signal, regOpPtr.p, data, Rlen, false);
- return;
- }
- switch (trans_state) {
- case TRANS_ERROR_WAIT_STORED_PROCREQ:
- jam();
- case TRANS_TOO_MUCH_AI:
- jam();
- case TRANS_ERROR_WAIT_TUPKEYREQ:
- jam();
- return; /* IGNORE ATTRINFO IN THOSE STATES, WAITING FOR ABORT SIGNAL */
- case TRANS_DISCONNECTED:
- jam();
- case TRANS_STARTED:
- jam();
- default:
- ndbrequire(false);
- }
-}
-
-void
-Dbtup::setChecksum(Tuple_header* tuple_ptr,
- Tablerec* regTabPtr)
-{
- tuple_ptr->m_checksum= 0;
- tuple_ptr->m_checksum= calculateChecksum(tuple_ptr, regTabPtr);
-}
-
-Uint32
-Dbtup::calculateChecksum(Tuple_header* tuple_ptr,
- Tablerec* regTabPtr)
-{
- Uint32 checksum;
- Uint32 i, rec_size, *tuple_header;
- rec_size= regTabPtr->m_offsets[MM].m_fix_header_size;
- tuple_header= tuple_ptr->m_data;
- checksum= 0;
- // includes tupVersion
- //printf("%p - ", tuple_ptr);
-
- for (i= 0; i < rec_size-Tuple_header::HeaderSize; i++) {
- checksum ^= tuple_header[i];
- //printf("%.8x ", tuple_header[i]);
- }
-
- //printf("-> %.8x\n", checksum);
-
-#if 0
- if (var_sized) {
- /*
- if (! req_struct->fix_var_together) {
- jam();
- checksum ^= tuple_header[rec_size];
- }
- */
- jam();
- var_data_part= req_struct->var_data_start;
- vsize_words= calculate_total_var_size(req_struct->var_len_array,
- regTabPtr->no_var_attr);
- ndbassert(req_struct->var_data_end >= &var_data_part[vsize_words]);
- for (i= 0; i < vsize_words; i++) {
- checksum ^= var_data_part[i];
- }
- }
-#endif
- return checksum;
-}
-
-/* ----------------------------------------------------------------- */
-/* ----------- INSERT_ACTIVE_OP_LIST -------------- */
-/* ----------------------------------------------------------------- */
-bool
-Dbtup::insertActiveOpList(OperationrecPtr regOperPtr,
- KeyReqStruct* req_struct)
-{
- OperationrecPtr prevOpPtr;
- ndbrequire(!regOperPtr.p->op_struct.in_active_list);
- regOperPtr.p->op_struct.in_active_list= true;
- req_struct->prevOpPtr.i=
- prevOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
- regOperPtr.p->prevActiveOp= prevOpPtr.i;
- regOperPtr.p->nextActiveOp= RNIL;
- regOperPtr.p->m_undo_buffer_space= 0;
- req_struct->m_tuple_ptr->m_operation_ptr_i= regOperPtr.i;
- if (prevOpPtr.i == RNIL) {
- set_change_mask_state(regOperPtr.p, USE_SAVED_CHANGE_MASK);
- regOperPtr.p->saved_change_mask[0] = 0;
- regOperPtr.p->saved_change_mask[1] = 0;
- return true;
- } else {
- req_struct->prevOpPtr.p= prevOpPtr.p= c_operation_pool.getPtr(prevOpPtr.i);
- prevOpPtr.p->nextActiveOp= regOperPtr.i;
-
- regOperPtr.p->op_struct.m_wait_log_buffer=
- prevOpPtr.p->op_struct.m_wait_log_buffer;
- regOperPtr.p->op_struct.m_load_diskpage_on_commit=
- prevOpPtr.p->op_struct.m_load_diskpage_on_commit;
- regOperPtr.p->m_undo_buffer_space= prevOpPtr.p->m_undo_buffer_space;
- // start with prev mask (matters only for UPD o UPD)
- set_change_mask_state(regOperPtr.p, get_change_mask_state(prevOpPtr.p));
- regOperPtr.p->saved_change_mask[0] = prevOpPtr.p->saved_change_mask[0];
- regOperPtr.p->saved_change_mask[1] = prevOpPtr.p->saved_change_mask[1];
-
- regOperPtr.p->m_any_value = prevOpPtr.p->m_any_value;
-
- prevOpPtr.p->op_struct.m_wait_log_buffer= 0;
- prevOpPtr.p->op_struct.m_load_diskpage_on_commit= 0;
-
- if(prevOpPtr.p->op_struct.tuple_state == TUPLE_PREPARED)
- {
- Uint32 op= regOperPtr.p->op_struct.op_type;
- Uint32 prevOp= prevOpPtr.p->op_struct.op_type;
- if (prevOp == ZDELETE)
- {
- if(op == ZINSERT)
- {
- // mark both
- prevOpPtr.p->op_struct.delete_insert_flag= true;
- regOperPtr.p->op_struct.delete_insert_flag= true;
- return true;
- } else {
- terrorCode= ZTUPLE_DELETED_ERROR;
- return false;
- }
- }
- else if(op == ZINSERT && prevOp != ZDELETE)
- {
- terrorCode= ZINSERT_ERROR;
- return false;
- }
- return true;
- }
- else
- {
- terrorCode= ZMUST_BE_ABORTED_ERROR;
- return false;
- }
- }
-}
-
-bool
-Dbtup::setup_read(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- bool disk)
-{
- OperationrecPtr currOpPtr;
- currOpPtr.i= req_struct->m_tuple_ptr->m_operation_ptr_i;
- if (currOpPtr.i == RNIL)
- {
- if (regTabPtr->need_expand(disk))
- prepare_read(req_struct, regTabPtr, disk);
- return true;
- }
-
- do {
- Uint32 savepointId= regOperPtr->savepointId;
- bool dirty= req_struct->dirty_op;
-
- c_operation_pool.getPtr(currOpPtr);
- bool sameTrans= c_lqh->is_same_trans(currOpPtr.p->userpointer,
- req_struct->trans_id1,
- req_struct->trans_id2);
- /**
- * Read committed in same trans reads latest copy
- */
- if(dirty && !sameTrans)
- {
- savepointId= 0;
- }
- else if(sameTrans)
- {
- // Use savepoint even in read committed mode
- dirty= false;
- }
-
- bool found= find_savepoint(currOpPtr, savepointId);
-
- Uint32 currOp= currOpPtr.p->op_struct.op_type;
-
- if((found && currOp == ZDELETE) ||
- ((dirty || !found) && currOp == ZINSERT))
- {
- terrorCode= ZTUPLE_DELETED_ERROR;
- break;
- }
-
- if(dirty || !found)
- {
-
- }
- else
- {
- req_struct->m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&currOpPtr.p->m_copy_tuple_location);
- }
-
- if (regTabPtr->need_expand(disk))
- prepare_read(req_struct, regTabPtr, disk);
-
-#if 0
- ndbout_c("reading copy");
- Uint32 *var_ptr = fixed_ptr+regTabPtr->var_offset;
- req_struct->m_tuple_ptr= fixed_ptr;
- req_struct->fix_var_together= true;
- req_struct->var_len_array= (Uint16*)var_ptr;
- req_struct->var_data_start= var_ptr+regTabPtr->var_array_wsize;
- Uint32 var_sz32= init_var_pos_array((Uint16*)var_ptr,
- req_struct->var_pos_array,
- regTabPtr->no_var_attr);
- req_struct->var_data_end= var_ptr+regTabPtr->var_array_wsize + var_sz32;
-#endif
- return true;
- } while(0);
-
- return false;
-}
-
-int
-Dbtup::load_diskpage(Signal* signal,
- Uint32 opRec, Uint32 fragPtrI,
- Uint32 local_key, Uint32 flags)
-{
- c_operation_pool.getPtr(operPtr, opRec);
- fragptr.i= fragPtrI;
- ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
-
- Operationrec * regOperPtr= operPtr.p;
- Fragrecord * regFragPtr= fragptr.p;
-
- tabptr.i = regFragPtr->fragTableId;
- ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
- Tablerec* regTabPtr = tabptr.p;
-
- if(local_key == ~(Uint32)0)
- {
- jam();
- regOperPtr->op_struct.m_wait_log_buffer= 1;
- regOperPtr->op_struct.m_load_diskpage_on_commit= 1;
- return 1;
- }
-
- jam();
- Uint32 page_idx= local_key & MAX_TUPLES_PER_PAGE;
- Uint32 frag_page_id= local_key >> MAX_TUPLES_BITS;
- regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
- frag_page_id);
- regOperPtr->m_tuple_location.m_page_idx= page_idx;
-
- PagePtr page_ptr;
- Uint32* tmp= get_ptr(&page_ptr, &regOperPtr->m_tuple_location, regTabPtr);
- Tuple_header* ptr= (Tuple_header*)tmp;
-
- int res= 1;
- if(ptr->m_header_bits & Tuple_header::DISK_PART)
- {
- Page_cache_client::Request req;
- memcpy(&req.m_page, ptr->get_disk_ref_ptr(regTabPtr), sizeof(Local_key));
- req.m_callback.m_callbackData= opRec;
- req.m_callback.m_callbackFunction=
- safe_cast(&Dbtup::disk_page_load_callback);
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(4022))
- {
- flags |= Page_cache_client::DELAY_REQ;
- req.m_delay_until_time = NdbTick_CurrentMillisecond()+(Uint64)3000;
- }
-#endif
-
- if((res= m_pgman.get_page(signal, req, flags)) > 0)
- {
- //ndbout_c("in cache");
- // In cache
- }
- else if(res == 0)
- {
- //ndbout_c("waiting for callback");
- // set state
- }
- else
- {
- // Error
- }
- }
-
- switch(flags & 7)
- {
- case ZREAD:
- case ZREAD_EX:
- break;
- case ZDELETE:
- case ZUPDATE:
- case ZINSERT:
- case ZWRITE:
- regOperPtr->op_struct.m_wait_log_buffer= 1;
- regOperPtr->op_struct.m_load_diskpage_on_commit= 1;
- }
- return res;
-}
-
-void
-Dbtup::disk_page_load_callback(Signal* signal, Uint32 opRec, Uint32 page_id)
-{
- c_operation_pool.getPtr(operPtr, opRec);
- c_lqh->acckeyconf_load_diskpage_callback(signal,
- operPtr.p->userpointer, page_id);
-}
-
-int
-Dbtup::load_diskpage_scan(Signal* signal,
- Uint32 opRec, Uint32 fragPtrI,
- Uint32 local_key, Uint32 flags)
-{
- c_operation_pool.getPtr(operPtr, opRec);
- fragptr.i= fragPtrI;
- ptrCheckGuard(fragptr, cnoOfFragrec, fragrecord);
-
- Operationrec * regOperPtr= operPtr.p;
- Fragrecord * regFragPtr= fragptr.p;
-
- tabptr.i = regFragPtr->fragTableId;
- ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
- Tablerec* regTabPtr = tabptr.p;
-
- jam();
- Uint32 page_idx= local_key & MAX_TUPLES_PER_PAGE;
- Uint32 frag_page_id= local_key >> MAX_TUPLES_BITS;
- regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
- frag_page_id);
- regOperPtr->m_tuple_location.m_page_idx= page_idx;
- regOperPtr->op_struct.m_load_diskpage_on_commit= 0;
-
- PagePtr page_ptr;
- Uint32* tmp= get_ptr(&page_ptr, &regOperPtr->m_tuple_location, regTabPtr);
- Tuple_header* ptr= (Tuple_header*)tmp;
-
- int res= 1;
- if(ptr->m_header_bits & Tuple_header::DISK_PART)
- {
- Page_cache_client::Request req;
- memcpy(&req.m_page, ptr->get_disk_ref_ptr(regTabPtr), sizeof(Local_key));
- req.m_callback.m_callbackData= opRec;
- req.m_callback.m_callbackFunction=
- safe_cast(&Dbtup::disk_page_load_scan_callback);
-
- if((res= m_pgman.get_page(signal, req, flags)) > 0)
- {
- // ndbout_c("in cache");
- // In cache
- }
- else if(res == 0)
- {
- //ndbout_c("waiting for callback");
- // set state
- }
- else
- {
- // Error
- }
- }
- return res;
-}
-
-void
-Dbtup::disk_page_load_scan_callback(Signal* signal,
- Uint32 opRec, Uint32 page_id)
-{
- c_operation_pool.getPtr(operPtr, opRec);
- c_lqh->next_scanconf_load_diskpage_callback(signal,
- operPtr.p->userpointer, page_id);
-}
-
-void Dbtup::execTUPKEYREQ(Signal* signal)
-{
- TupKeyReq * tupKeyReq= (TupKeyReq *)signal->getDataPtr();
- KeyReqStruct req_struct;
- Uint32 sig1, sig2, sig3, sig4;
-
- Uint32 RoperPtr= tupKeyReq->connectPtr;
- Uint32 Rfragptr= tupKeyReq->fragPtr;
-
- Uint32 RnoOfFragrec= cnoOfFragrec;
- Uint32 RnoOfTablerec= cnoOfTablerec;
-
- jamEntry();
- fragptr.i= Rfragptr;
-
- ndbrequire(Rfragptr < RnoOfFragrec);
-
- c_operation_pool.getPtr(operPtr, RoperPtr);
- ptrAss(fragptr, fragrecord);
-
- Uint32 TrequestInfo= tupKeyReq->request;
-
- Operationrec * regOperPtr= operPtr.p;
- Fragrecord * regFragPtr= fragptr.p;
-
- tabptr.i = regFragPtr->fragTableId;
- ptrCheckGuard(tabptr, RnoOfTablerec, tablerec);
- Tablerec* regTabPtr = tabptr.p;
-
- req_struct.signal= signal;
- req_struct.dirty_op= TrequestInfo & 1;
- req_struct.interpreted_exec= (TrequestInfo >> 10) & 1;
- req_struct.no_fired_triggers= 0;
- req_struct.read_length= 0;
- req_struct.max_attr_id_updated= 0;
- req_struct.no_changed_attrs= 0;
- req_struct.last_row= false;
- req_struct.changeMask.clear();
-
- if (unlikely(get_trans_state(regOperPtr) != TRANS_IDLE))
- {
- TUPKEY_abort(signal, 39);
- return;
- }
-
- /* ----------------------------------------------------------------- */
- // Operation is ZREAD when we arrive here so no need to worry about the
- // abort process.
- /* ----------------------------------------------------------------- */
- /* ----------- INITIATE THE OPERATION RECORD -------------- */
- /* ----------------------------------------------------------------- */
- Uint32 Rstoredid= tupKeyReq->storedProcedure;
-
- regOperPtr->fragmentPtr= Rfragptr;
- regOperPtr->op_struct.op_type= (TrequestInfo >> 6) & 0xf;
- regOperPtr->op_struct.delete_insert_flag = false;
- regOperPtr->storedProcedureId= Rstoredid;
-
- regOperPtr->m_copy_tuple_location.setNull();
- regOperPtr->tupVersion= ZNIL;
-
- sig1= tupKeyReq->savePointId;
- sig2= tupKeyReq->primaryReplica;
- sig3= tupKeyReq->keyRef2;
-
- regOperPtr->savepointId= sig1;
- regOperPtr->op_struct.primary_replica= sig2;
- Uint32 pageidx = regOperPtr->m_tuple_location.m_page_idx= sig3;
-
- sig1= tupKeyReq->opRef;
- sig2= tupKeyReq->tcOpIndex;
- sig3= tupKeyReq->coordinatorTC;
- sig4= tupKeyReq->keyRef1;
-
- req_struct.tc_operation_ptr= sig1;
- req_struct.TC_index= sig2;
- req_struct.TC_ref= sig3;
- Uint32 pageid = req_struct.frag_page_id= sig4;
- req_struct.m_use_rowid = (TrequestInfo >> 11) & 1;
-
- sig1= tupKeyReq->attrBufLen;
- sig2= tupKeyReq->applRef;
- sig3= tupKeyReq->transId1;
- sig4= tupKeyReq->transId2;
-
- Uint32 disk_page= tupKeyReq->disk_page;
-
- req_struct.log_size= sig1;
- req_struct.attrinfo_len= sig1;
- req_struct.rec_blockref= sig2;
- req_struct.trans_id1= sig3;
- req_struct.trans_id2= sig4;
- req_struct.m_disk_page_ptr.i= disk_page;
-
- sig1 = tupKeyReq->m_row_id_page_no;
- sig2 = tupKeyReq->m_row_id_page_idx;
-
- req_struct.m_row_id.m_page_no = sig1;
- req_struct.m_row_id.m_page_idx = sig2;
-
- Uint32 Roptype = regOperPtr->op_struct.op_type;
-
- if (Rstoredid != ZNIL) {
- ndbrequire(initStoredOperationrec(regOperPtr,
- &req_struct,
- Rstoredid) == ZOK);
- }
-
- copyAttrinfo(regOperPtr, &cinBuffer[0]);
-
- Uint32 localkey = (pageid << MAX_TUPLES_BITS) + pageidx;
- if (Roptype == ZINSERT && localkey == ~ (Uint32) 0)
- {
- // No tuple allocatated yet
- goto do_insert;
- }
-
- /**
- * Get pointer to tuple
- */
- regOperPtr->m_tuple_location.m_page_no= getRealpid(regFragPtr,
- req_struct.frag_page_id);
-
- setup_fixed_part(&req_struct, regOperPtr, regTabPtr);
-
- /**
- * Check operation
- */
- if (Roptype == ZREAD) {
- jam();
-
- if (setup_read(&req_struct, regOperPtr, regFragPtr, regTabPtr,
- disk_page != RNIL))
- {
- if(handleReadReq(signal, regOperPtr, regTabPtr, &req_struct) != -1)
- {
- req_struct.log_size= 0;
- sendTUPKEYCONF(signal, &req_struct, regOperPtr);
- /* ---------------------------------------------------------------- */
- // Read Operations need not to be taken out of any lists.
- // We also do not need to wait for commit since there is no changes
- // to commit. Thus we
- // prepare the operation record already now for the next operation.
- // Write operations have set the state to STARTED above indicating
- // that they are waiting for the Commit or Abort decision.
- /* ---------------------------------------------------------------- */
- set_trans_state(regOperPtr, TRANS_IDLE);
- regOperPtr->currentAttrinbufLen= 0;
- }
- return;
- }
- tupkeyErrorLab(signal);
- return;
- }
-
- if(insertActiveOpList(operPtr, &req_struct))
- {
- if(Roptype == ZINSERT)
- {
- jam();
- do_insert:
- if (handleInsertReq(signal, operPtr,
- fragptr, regTabPtr, &req_struct) == -1)
- {
- return;
- }
- if (!regTabPtr->tuxCustomTriggers.isEmpty())
- {
- jam();
- if (executeTuxInsertTriggers(signal,
- regOperPtr,
- regFragPtr,
- regTabPtr) != 0) {
- jam();
- /*
- * TUP insert succeeded but add of TUX entries failed. All
- * TUX changes have been rolled back at this point.
- *
- * We will abort via tupkeyErrorLab() as usual. This routine
- * however resets the operation to ZREAD. The TUP_ABORTREQ
- * arriving later cannot then undo the insert.
- *
- * Therefore we call TUP_ABORTREQ already now. Diskdata etc
- * should be in memory and timeslicing cannot occur. We must
- * skip TUX abort triggers since TUX is already aborted.
- */
- signal->theData[0] = operPtr.i;
- do_tup_abortreq(signal, ZSKIP_TUX_TRIGGERS);
- tupkeyErrorLab(signal);
- return;
- }
- }
- checkImmediateTriggersAfterInsert(&req_struct,
- regOperPtr,
- regTabPtr,
- disk_page != RNIL);
- set_change_mask_state(regOperPtr, SET_ALL_MASK);
- sendTUPKEYCONF(signal, &req_struct, regOperPtr);
- return;
- }
-
- if (Roptype == ZUPDATE) {
- jam();
- if (handleUpdateReq(signal, regOperPtr,
- regFragPtr, regTabPtr, &req_struct, disk_page != RNIL) == -1) {
- return;
- }
- // If update operation is done on primary,
- // check any after op triggers
- terrorCode= 0;
- if (!regTabPtr->tuxCustomTriggers.isEmpty()) {
- jam();
- if (executeTuxUpdateTriggers(signal,
- regOperPtr,
- regFragPtr,
- regTabPtr) != 0) {
- jam();
- /*
- * See insert case.
- */
- signal->theData[0] = operPtr.i;
- do_tup_abortreq(signal, ZSKIP_TUX_TRIGGERS);
- tupkeyErrorLab(signal);
- return;
- }
- }
- checkImmediateTriggersAfterUpdate(&req_struct,
- regOperPtr,
- regTabPtr,
- disk_page != RNIL);
- // XXX use terrorCode for now since all methods are void
- if (terrorCode != 0)
- {
- tupkeyErrorLab(signal);
- return;
- }
- update_change_mask_info(&req_struct, regOperPtr);
- sendTUPKEYCONF(signal, &req_struct, regOperPtr);
- return;
- }
- else if(Roptype == ZDELETE)
- {
- jam();
- req_struct.log_size= 0;
- if (handleDeleteReq(signal, regOperPtr,
- regFragPtr, regTabPtr,
- &req_struct,
- disk_page != RNIL) == -1) {
- return;
- }
- /*
- * TUX doesn't need to check for triggers at delete since entries in
- * the index are kept until commit time.
- */
-
- /*
- * Secondary index triggers fire on the primary after a delete.
- */
- checkImmediateTriggersAfterDelete(&req_struct,
- regOperPtr,
- regTabPtr,
- disk_page != RNIL);
- set_change_mask_state(regOperPtr, DELETE_CHANGES);
- sendTUPKEYCONF(signal, &req_struct, regOperPtr);
- return;
- }
- else
- {
- ndbrequire(false); // Invalid op type
- }
- }
-
- tupkeyErrorLab(signal);
- }
-
-void
-Dbtup::setup_fixed_part(KeyReqStruct* req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr)
-{
- PagePtr page_ptr;
- Uint32* ptr= get_ptr(&page_ptr, &regOperPtr->m_tuple_location, regTabPtr);
- req_struct->m_page_ptr = page_ptr;
- req_struct->m_tuple_ptr = (Tuple_header*)ptr;
-
- ndbassert(regOperPtr->op_struct.op_type == ZINSERT || (! (req_struct->m_tuple_ptr->m_header_bits & Tuple_header::FREE)));
-
- req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
- req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
-
- Uint32 num_attr= regTabPtr->m_no_of_attributes;
- Uint32 descr_start= regTabPtr->tabDescriptor;
- TableDescriptor *tab_descr= &tableDescriptor[descr_start];
- ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
- req_struct->attr_descr= tab_descr;
-}
-
- /* ---------------------------------------------------------------- */
- /* ------------------------ CONFIRM REQUEST ----------------------- */
- /* ---------------------------------------------------------------- */
- void Dbtup::sendTUPKEYCONF(Signal* signal,
- KeyReqStruct *req_struct,
- Operationrec * regOperPtr)
-{
- TupKeyConf * tupKeyConf= (TupKeyConf *)signal->getDataPtrSend();
-
- Uint32 Rcreate_rowid = req_struct->m_use_rowid;
- Uint32 RuserPointer= regOperPtr->userpointer;
- Uint32 RnoFiredTriggers= req_struct->no_fired_triggers;
- Uint32 log_size= req_struct->log_size;
- Uint32 read_length= req_struct->read_length;
- Uint32 last_row= req_struct->last_row;
-
- set_trans_state(regOperPtr, TRANS_STARTED);
- set_tuple_state(regOperPtr, TUPLE_PREPARED);
- tupKeyConf->userPtr= RuserPointer;
- tupKeyConf->readLength= read_length;
- tupKeyConf->writeLength= log_size;
- tupKeyConf->noFiredTriggers= RnoFiredTriggers;
- tupKeyConf->lastRow= last_row;
- tupKeyConf->rowid = Rcreate_rowid;
-
- EXECUTE_DIRECT(DBLQH, GSN_TUPKEYCONF, signal,
- TupKeyConf::SignalLength);
-
-}
-
-
-#define MAX_READ (sizeof(signal->theData) > MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : sizeof(signal->theData))
-
-/* ---------------------------------------------------------------- */
-/* ----------------------------- READ ---------------------------- */
-/* ---------------------------------------------------------------- */
-int Dbtup::handleReadReq(Signal* signal,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct)
-{
- Uint32 *dst;
- Uint32 dstLen, start_index;
- const BlockReference sendBref= req_struct->rec_blockref;
- if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
- (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0)) {
- jam();
- ndbout_c("here2");
- terrorCode= ZTUPLE_CORRUPTED_ERROR;
- tupkeyErrorLab(signal);
- return -1;
- }
-
- const Uint32 node = refToNode(sendBref);
- if(node != 0 && node != getOwnNodeId()) {
- start_index= 25;
- } else {
- jam();
- /**
- * execute direct
- */
- start_index= 3;
- }
- dst= &signal->theData[start_index];
- dstLen= (MAX_READ / 4) - start_index;
- if (!req_struct->interpreted_exec) {
- jam();
- int ret = readAttributes(req_struct,
- &cinBuffer[0],
- req_struct->attrinfo_len,
- dst,
- dstLen,
- false);
- if (likely(ret != -1)) {
-/* ------------------------------------------------------------------------- */
-// We have read all data into coutBuffer. Now send it to the API.
-/* ------------------------------------------------------------------------- */
- jam();
- Uint32 TnoOfDataRead= (Uint32) ret;
- req_struct->read_length= TnoOfDataRead;
- sendReadAttrinfo(signal, req_struct, TnoOfDataRead, regOperPtr);
- return 0;
- }
- } else {
- jam();
- if (likely(interpreterStartLab(signal, req_struct) != -1)) {
- return 0;
- }
- return -1;
- }
-
- jam();
- tupkeyErrorLab(signal);
- return -1;
-}
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------- UPDATE ---------------------------- */
-/* ---------------------------------------------------------------- */
-int Dbtup::handleUpdateReq(Signal* signal,
- Operationrec* operPtrP,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct* req_struct,
- bool disk)
-{
- Uint32 *dst;
- Tuple_header *base= req_struct->m_tuple_ptr, *org;
- if ((dst= c_undo_buffer.alloc_copy_tuple(&operPtrP->m_copy_tuple_location,
- regTabPtr->total_rec_size)) == 0)
- {
- terrorCode= ZMEM_NOMEM_ERROR;
- goto error;
- }
-
- Uint32 tup_version;
- if(operPtrP->is_first_operation())
- {
- org= req_struct->m_tuple_ptr;
- tup_version= org->get_tuple_version();
- }
- else
- {
- Operationrec* prevOp= req_struct->prevOpPtr.p;
- tup_version= prevOp->tupVersion;
- org= (Tuple_header*)c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
- }
-
- /**
- * Check consistency before update/delete
- */
- req_struct->m_tuple_ptr= org;
- if ((regTabPtr->m_bits & Tablerec::TR_Checksum) &&
- (calculateChecksum(req_struct->m_tuple_ptr, regTabPtr) != 0))
- {
- terrorCode= ZTUPLE_CORRUPTED_ERROR;
- goto error;
- }
-
- req_struct->m_tuple_ptr= (Tuple_header*)dst;
-
- union {
- Uint32 sizes[4];
- Uint64 cmp[2];
- };
-
- disk = disk || (org->m_header_bits & Tuple_header::DISK_INLINE);
- if (regTabPtr->need_expand(disk))
- {
- expand_tuple(req_struct, sizes, org, regTabPtr, disk);
- if(disk && operPtrP->m_undo_buffer_space == 0)
- {
- operPtrP->op_struct.m_wait_log_buffer = 1;
- operPtrP->op_struct.m_load_diskpage_on_commit = 1;
- Uint32 sz= operPtrP->m_undo_buffer_space=
- (sizeof(Dbtup::Disk_undo::Update) >> 2) + sizes[DD] - 1;
-
- terrorCode= c_lgman->alloc_log_space(regFragPtr->m_logfile_group_id,
- sz);
- if(unlikely(terrorCode))
- {
- operPtrP->m_undo_buffer_space= 0;
- goto error;
- }
- }
- }
- else
- {
- memcpy(dst, org, 4*regTabPtr->m_offsets[MM].m_fix_header_size);
- }
-
- tup_version= (tup_version + 1) & ZTUP_VERSION_MASK;
- operPtrP->tupVersion= tup_version;
-
- if (!req_struct->interpreted_exec) {
- jam();
- int retValue = updateAttributes(req_struct,
- &cinBuffer[0],
- req_struct->attrinfo_len);
- if (unlikely(retValue == -1))
- goto error;
- } else {
- jam();
- if (unlikely(interpreterStartLab(signal, req_struct) == -1))
- return -1;
- }
-
- if (regTabPtr->need_shrink())
- {
- shrink_tuple(req_struct, sizes+2, regTabPtr, disk);
- if (cmp[0] != cmp[1] && handle_size_change_after_update(req_struct,
- base,
- operPtrP,
- regFragPtr,
- regTabPtr,
- sizes)) {
- goto error;
- }
- }
-
- req_struct->m_tuple_ptr->set_tuple_version(tup_version);
- if (regTabPtr->m_bits & Tablerec::TR_Checksum) {
- jam();
- setChecksum(req_struct->m_tuple_ptr, regTabPtr);
- }
- return 0;
-
-error:
- tupkeyErrorLab(signal);
- return -1;
-}
-
-/* ---------------------------------------------------------------- */
-/* ----------------------------- INSERT --------------------------- */
-/* ---------------------------------------------------------------- */
-void
-Dbtup::prepare_initial_insert(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr)
-{
- Uint32 disk_undo = regTabPtr->m_no_of_disk_attributes ?
- sizeof(Dbtup::Disk_undo::Alloc) >> 2 : 0;
- regOperPtr->nextActiveOp= RNIL;
- regOperPtr->prevActiveOp= RNIL;
- regOperPtr->op_struct.in_active_list= true;
- regOperPtr->m_undo_buffer_space= disk_undo;
-
- req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
- req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
-
- Uint32 num_attr= regTabPtr->m_no_of_attributes;
- Uint32 descr_start= regTabPtr->tabDescriptor;
- Uint32 order_desc= regTabPtr->m_real_order_descriptor;
- TableDescriptor *tab_descr= &tableDescriptor[descr_start];
- ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
- req_struct->attr_descr= tab_descr;
- Uint16* order= (Uint16*)&tableDescriptor[order_desc];
-
- const Uint32 cnt1= regTabPtr->m_attributes[MM].m_no_of_varsize;
- const Uint32 cnt2= regTabPtr->m_attributes[DD].m_no_of_varsize;
- Uint32 *ptr= req_struct->m_tuple_ptr->get_end_of_fix_part_ptr(regTabPtr);
- Var_part_ref* ref = req_struct->m_tuple_ptr->get_var_part_ref_ptr(regTabPtr);
-
- if (regTabPtr->m_bits & Tablerec::TR_ForceVarPart)
- {
- ref->m_page_no = RNIL;
- ref->m_page_idx = Tup_varsize_page::END_OF_FREE_LIST;
- }
-
- if(cnt1)
- {
- KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
- dst->m_data_ptr= (char*)(((Uint16*)ptr)+cnt1+1);
- dst->m_offset_array_ptr= req_struct->var_pos_array;
- dst->m_var_len_offset= cnt1;
- dst->m_max_var_offset= regTabPtr->m_offsets[MM].m_max_var_offset;
- // Disk part is 32-bit aligned
- ptr= ALIGN_WORD(dst->m_data_ptr+regTabPtr->m_offsets[MM].m_max_var_offset);
- order += regTabPtr->m_attributes[MM].m_no_of_fixsize;
- Uint32 pos= 0;
- Uint16 *pos_ptr = req_struct->var_pos_array;
- Uint16 *len_ptr = pos_ptr + cnt1;
- for(Uint32 i= 0; i<cnt1; i++)
- {
- * pos_ptr++ = pos;
- * len_ptr++ = pos;
- pos += AttributeDescriptor::getSizeInBytes(tab_descr[*order++].tabDescr);
- }
- }
-
- req_struct->m_disk_ptr= (Tuple_header*)ptr;
-
- ndbrequire(cnt2 == 0);
-
- // Set all null bits
- memset(req_struct->m_tuple_ptr->m_null_bits+
- regTabPtr->m_offsets[MM].m_null_offset, 0xFF,
- 4*regTabPtr->m_offsets[MM].m_null_words);
- memset(req_struct->m_disk_ptr->m_null_bits+
- regTabPtr->m_offsets[DD].m_null_offset, 0xFF,
- 4*regTabPtr->m_offsets[DD].m_null_words);
- req_struct->m_tuple_ptr->m_header_bits=
- disk_undo ? (Tuple_header::DISK_ALLOC | Tuple_header::DISK_INLINE) : 0;
-}
-
-int Dbtup::handleInsertReq(Signal* signal,
- Ptr<Operationrec> regOperPtr,
- Ptr<Fragrecord> fragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct *req_struct)
-{
- Uint32 tup_version = 1;
- Fragrecord* regFragPtr = fragPtr.p;
- Uint32 *dst, *ptr= 0;
- Tuple_header *base= req_struct->m_tuple_ptr, *org= base;
- Tuple_header *tuple_ptr;
-
- bool disk = regTabPtr->m_no_of_disk_attributes > 0;
- bool mem_insert = regOperPtr.p->is_first_operation();
- bool disk_insert = mem_insert && disk;
- bool varsize = regTabPtr->m_attributes[MM].m_no_of_varsize;
- bool rowid = req_struct->m_use_rowid;
- Uint32 real_page_id = regOperPtr.p->m_tuple_location.m_page_no;
- Uint32 frag_page_id = req_struct->frag_page_id;
-
- union {
- Uint32 sizes[4];
- Uint64 cmp[2];
- };
-
- if (ERROR_INSERTED(4014))
- {
- dst = 0;
- goto undo_buffer_error;
- }
-
- dst= c_undo_buffer.alloc_copy_tuple(&regOperPtr.p->m_copy_tuple_location,
- regTabPtr->total_rec_size);
- if (unlikely(dst == 0))
- {
- goto undo_buffer_error;
- }
- tuple_ptr= req_struct->m_tuple_ptr= (Tuple_header*)dst;
-
- if(mem_insert)
- {
- jam();
- prepare_initial_insert(req_struct, regOperPtr.p, regTabPtr);
- }
- else
- {
- Operationrec* prevOp= req_struct->prevOpPtr.p;
- ndbassert(prevOp->op_struct.op_type == ZDELETE);
- tup_version= prevOp->tupVersion + 1;
-
- if(!prevOp->is_first_operation())
- org= (Tuple_header*)c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
- if (regTabPtr->need_expand())
- {
- expand_tuple(req_struct, sizes, org, regTabPtr, !disk_insert);
- memset(req_struct->m_disk_ptr->m_null_bits+
- regTabPtr->m_offsets[DD].m_null_offset, 0xFF,
- 4*regTabPtr->m_offsets[DD].m_null_words);
- }
- else
- {
- memcpy(dst, org, 4*regTabPtr->m_offsets[MM].m_fix_header_size);
- }
- memset(tuple_ptr->m_null_bits+
- regTabPtr->m_offsets[MM].m_null_offset, 0xFF,
- 4*regTabPtr->m_offsets[MM].m_null_words);
- }
-
- if (disk_insert)
- {
- int res;
-
- if (ERROR_INSERTED(4015))
- {
- terrorCode = 1501;
- goto log_space_error;
- }
-
- res= c_lgman->alloc_log_space(regFragPtr->m_logfile_group_id,
- regOperPtr.p->m_undo_buffer_space);
- if(unlikely(res))
- {
- terrorCode= res;
- goto log_space_error;
- }
- }
-
- regOperPtr.p->tupVersion= tup_version & ZTUP_VERSION_MASK;
- tuple_ptr->set_tuple_version(tup_version);
-
- if (ERROR_INSERTED(4016))
- {
- terrorCode = ZAI_INCONSISTENCY_ERROR;
- goto update_error;
- }
-
- if(unlikely(updateAttributes(req_struct, &cinBuffer[0],
- req_struct->attrinfo_len) == -1))
- {
- goto update_error;
- }
-
- if (ERROR_INSERTED(4017))
- {
- goto null_check_error;
- }
- if (unlikely(checkNullAttributes(req_struct, regTabPtr) == false))
- {
- goto null_check_error;
- }
-
- if (regTabPtr->need_shrink())
- {
- shrink_tuple(req_struct, sizes+2, regTabPtr, true);
- }
-
- if (ERROR_INSERTED(4025))
- {
- goto mem_error;
- }
-
- if (ERROR_INSERTED(4026))
- {
- CLEAR_ERROR_INSERT_VALUE;
- goto mem_error;
- }
-
- if (ERROR_INSERTED(4027) && (rand() % 100) > 25)
- {
- goto mem_error;
- }
-
- if (ERROR_INSERTED(4028) && (rand() % 100) > 25)
- {
- CLEAR_ERROR_INSERT_VALUE;
- goto mem_error;
- }
-
- /**
- * Alloc memory
- */
- if(mem_insert)
- {
- if (!rowid)
- {
- if (ERROR_INSERTED(4018))
- {
- goto mem_error;
- }
-
- if (!varsize)
- {
- jam();
- ptr= alloc_fix_rec(regFragPtr,
- regTabPtr,
- &regOperPtr.p->m_tuple_location,
- &frag_page_id);
- }
- else
- {
- jam();
- regOperPtr.p->m_tuple_location.m_file_no= sizes[2+MM];
- ptr= alloc_var_rec(regFragPtr, regTabPtr,
- sizes[2+MM],
- &regOperPtr.p->m_tuple_location,
- &frag_page_id);
- }
- if (unlikely(ptr == 0))
- {
- goto mem_error;
- }
- req_struct->m_use_rowid = true;
- }
- else
- {
- regOperPtr.p->m_tuple_location = req_struct->m_row_id;
- if (ERROR_INSERTED(4019))
- {
- terrorCode = ZROWID_ALLOCATED;
- goto alloc_rowid_error;
- }
-
- if (!varsize)
- {
- jam();
- ptr= alloc_fix_rowid(regFragPtr,
- regTabPtr,
- &regOperPtr.p->m_tuple_location,
- &frag_page_id);
- }
- else
- {
- jam();
- regOperPtr.p->m_tuple_location.m_file_no= sizes[2+MM];
- ptr= alloc_var_rowid(regFragPtr, regTabPtr,
- sizes[2+MM],
- &regOperPtr.p->m_tuple_location,
- &frag_page_id);
- }
- if (unlikely(ptr == 0))
- {
- jam();
- goto alloc_rowid_error;
- }
- }
- real_page_id = regOperPtr.p->m_tuple_location.m_page_no;
- regOperPtr.p->m_tuple_location.m_page_no= frag_page_id;
- c_lqh->accminupdate(signal,
- regOperPtr.p->userpointer,
- &regOperPtr.p->m_tuple_location);
-
- base = (Tuple_header*)ptr;
- base->m_operation_ptr_i= regOperPtr.i;
- base->m_header_bits= Tuple_header::ALLOC |
- (varsize ? Tuple_header::CHAINED_ROW : 0);
- regOperPtr.p->m_tuple_location.m_page_no = real_page_id;
- }
- else
- {
- int ret;
- if (ERROR_INSERTED(4020))
- {
- goto size_change_error;
- }
-
- if (regTabPtr->need_shrink() && cmp[0] != cmp[1] &&
- unlikely(ret = handle_size_change_after_update(req_struct,
- base,
- regOperPtr.p,
- regFragPtr,
- regTabPtr,
- sizes)))
- {
- goto size_change_error;
- }
- req_struct->m_use_rowid = false;
- base->m_header_bits &= ~(Uint32)Tuple_header::FREE;
- }
-
- base->m_header_bits |= Tuple_header::ALLOC &
- (regOperPtr.p->is_first_operation() ? ~0 : 1);
-
- if (disk_insert)
- {
- Local_key tmp;
- Uint32 size= regTabPtr->m_attributes[DD].m_no_of_varsize == 0 ?
- 1 : sizes[2+DD];
-
- if (ERROR_INSERTED(4021))
- {
- terrorCode = 1601;
- goto disk_prealloc_error;
- }
-
- int ret= disk_page_prealloc(signal, fragPtr, &tmp, size);
- if (unlikely(ret < 0))
- {
- terrorCode = -ret;
- goto disk_prealloc_error;
- }
-
- regOperPtr.p->op_struct.m_disk_preallocated= 1;
- tmp.m_page_idx= size;
- memcpy(tuple_ptr->get_disk_ref_ptr(regTabPtr), &tmp, sizeof(tmp));
-
- /**
- * Set ref from disk to mm
- */
- Local_key ref = regOperPtr.p->m_tuple_location;
- ref.m_page_no = frag_page_id;
-
- Tuple_header* disk_ptr= req_struct->m_disk_ptr;
- disk_ptr->m_header_bits = 0;
- disk_ptr->m_base_record_ref= ref.ref();
- }
-
- if (regTabPtr->m_bits & Tablerec::TR_Checksum)
- {
- jam();
- setChecksum(req_struct->m_tuple_ptr, regTabPtr);
- }
- return 0;
-
-size_change_error:
- jam();
- terrorCode = ZMEM_NOMEM_ERROR;
- goto exit_error;
-
-undo_buffer_error:
- jam();
- terrorCode= ZMEM_NOMEM_ERROR;
- regOperPtr.p->m_undo_buffer_space = 0;
- if (mem_insert)
- regOperPtr.p->m_tuple_location.setNull();
- regOperPtr.p->m_copy_tuple_location.setNull();
- tupkeyErrorLab(signal);
- return -1;
-
-null_check_error:
- jam();
- terrorCode= ZNO_ILLEGAL_NULL_ATTR;
- goto update_error;
-
-mem_error:
- jam();
- terrorCode= ZMEM_NOMEM_ERROR;
- goto update_error;
-
-log_space_error:
- jam();
- regOperPtr.p->m_undo_buffer_space = 0;
-alloc_rowid_error:
- jam();
-update_error:
- jam();
- if (mem_insert)
- {
- regOperPtr.p->op_struct.in_active_list = false;
- regOperPtr.p->m_tuple_location.setNull();
- }
-exit_error:
- tupkeyErrorLab(signal);
- return -1;
-
-disk_prealloc_error:
- base->m_header_bits |= Tuple_header::FREED;
- goto exit_error;
-}
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------- DELETE ---------------------------- */
-/* ---------------------------------------------------------------- */
-int Dbtup::handleDeleteReq(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- KeyReqStruct *req_struct,
- bool disk)
-{
- // delete must set but not increment tupVersion
- if (!regOperPtr->is_first_operation())
- {
- Operationrec* prevOp= req_struct->prevOpPtr.p;
- regOperPtr->tupVersion= prevOp->tupVersion;
- // make copy since previous op is committed before this one
- const Uint32* org = c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location);
- Uint32* dst = c_undo_buffer.alloc_copy_tuple(
- &regOperPtr->m_copy_tuple_location, regTabPtr->total_rec_size);
- if (dst == 0) {
- terrorCode = ZMEM_NOMEM_ERROR;
- goto error;
- }
- memcpy(dst, org, regTabPtr->total_rec_size << 2);
- req_struct->m_tuple_ptr = (Tuple_header*)dst;
- }
- else
- {
- regOperPtr->tupVersion= req_struct->m_tuple_ptr->get_tuple_version();
- }
-
- if(disk && regOperPtr->m_undo_buffer_space == 0)
- {
- regOperPtr->op_struct.m_wait_log_buffer = 1;
- regOperPtr->op_struct.m_load_diskpage_on_commit = 1;
- Uint32 sz= regOperPtr->m_undo_buffer_space=
- (sizeof(Dbtup::Disk_undo::Free) >> 2) +
- regTabPtr->m_offsets[DD].m_fix_header_size - 1;
-
- terrorCode= c_lgman->alloc_log_space(regFragPtr->m_logfile_group_id,
- sz);
- if(unlikely(terrorCode))
- {
- regOperPtr->m_undo_buffer_space= 0;
- goto error;
- }
- }
- if (req_struct->attrinfo_len == 0)
- {
- return 0;
- }
-
- if (regTabPtr->need_expand(disk))
- {
- prepare_read(req_struct, regTabPtr, disk);
- }
-
- {
- Uint32 RlogSize;
- int ret= handleReadReq(signal, regOperPtr, regTabPtr, req_struct);
- if (ret == 0 && (RlogSize= req_struct->log_size))
- {
- jam();
- sendLogAttrinfo(signal, RlogSize, regOperPtr);
- }
- return ret;
- }
-
-error:
- tupkeyErrorLab(signal);
- return -1;
-}
-
-bool
-Dbtup::checkNullAttributes(KeyReqStruct * req_struct,
- Tablerec* regTabPtr)
-{
-// Implement checking of updating all not null attributes in an insert here.
- Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
- /*
- * The idea here is maybe that changeMask is not-null attributes
- * and must contain notNullAttributeMask. But:
- *
- * 1. changeMask has all bits set on insert
- * 2. not-null is checked in each UpdateFunction
- * 3. the code below does not work except trivially due to 1.
- *
- * XXX remove or fix
- */
- attributeMask.clear();
- attributeMask.bitOR(req_struct->changeMask);
- attributeMask.bitAND(regTabPtr->notNullAttributeMask);
- attributeMask.bitXOR(regTabPtr->notNullAttributeMask);
- if (!attributeMask.isclear()) {
- return false;
- }
- return true;
-}
-
-/* ---------------------------------------------------------------- */
-/* THIS IS THE START OF THE INTERPRETED EXECUTION OF UPDATES. WE */
-/* START BY LINKING ALL ATTRINFO'S IN A DOUBLY LINKED LIST (THEY ARE*/
-/* ALREADY IN A LINKED LIST). WE ALLOCATE A REGISTER MEMORY (EQUAL */
-/* TO AN ATTRINFO RECORD). THE INTERPRETER GOES THROUGH FOUR PHASES*/
-/* DURING THE FIRST PHASE IT IS ONLY ALLOWED TO READ ATTRIBUTES THAT*/
-/* ARE SENT TO THE CLIENT APPLICATION. DURING THE SECOND PHASE IT IS*/
-/* ALLOWED TO READ FROM ATTRIBUTES INTO REGISTERS, TO UPDATE */
-/* ATTRIBUTES BASED ON EITHER A CONSTANT VALUE OR A REGISTER VALUE, */
-/* A DIVERSE SET OF OPERATIONS ON REGISTERS ARE AVAILABLE AS WELL. */
-/* IT IS ALSO POSSIBLE TO PERFORM JUMPS WITHIN THE INSTRUCTIONS THAT*/
-/* BELONGS TO THE SECOND PHASE. ALSO SUBROUTINES CAN BE CALLED IN */
-/* THIS PHASE. THE THIRD PHASE IS TO AGAIN READ ATTRIBUTES AND */
-/* FINALLY THE FOURTH PHASE READS SELECTED REGISTERS AND SEND THEM */
-/* TO THE CLIENT APPLICATION. */
-/* THERE IS A FIFTH REGION WHICH CONTAINS SUBROUTINES CALLABLE FROM */
-/* THE INTERPRETER EXECUTION REGION. */
-/* THE FIRST FIVE WORDS WILL GIVE THE LENGTH OF THE FIVEE REGIONS */
-/* */
-/* THIS MEANS THAT FROM THE APPLICATIONS POINT OF VIEW THE DATABASE */
-/* CAN HANDLE SUBROUTINE CALLS WHERE THE CODE IS SENT IN THE REQUEST*/
-/* THE RETURN PARAMETERS ARE FIXED AND CAN EITHER BE GENERATED */
-/* BEFORE THE EXECUTION OF THE ROUTINE OR AFTER. */
-/* */
-/* IN LATER VERSIONS WE WILL ADD MORE THINGS LIKE THE POSSIBILITY */
-/* TO ALLOCATE MEMORY AND USE THIS AS LOCAL STORAGE. IT IS ALSO */
-/* IMAGINABLE TO HAVE SPECIAL ROUTINES THAT CAN PERFORM CERTAIN */
-/* OPERATIONS ON BLOB'S DEPENDENT ON WHAT THE BLOB REPRESENTS. */
-/* */
-/* */
-/* ----------------------------------------- */
-/* + INITIAL READ REGION + */
-/* ----------------------------------------- */
-/* + INTERPRETED EXECUTE REGION + */
-/* ----------------------------------------- */
-/* + FINAL UPDATE REGION + */
-/* ----------------------------------------- */
-/* + FINAL READ REGION + */
-/* ----------------------------------------- */
-/* + SUBROUTINE REGION + */
-/* ----------------------------------------- */
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-/* ----------------- INTERPRETED EXECUTION ----------------------- */
-/* ---------------------------------------------------------------- */
-int Dbtup::interpreterStartLab(Signal* signal,
- KeyReqStruct *req_struct)
-{
- Operationrec * const regOperPtr= operPtr.p;
- int TnoDataRW;
- Uint32 RtotalLen, start_index, dstLen;
- Uint32 *dst;
-
- Uint32 RinitReadLen= cinBuffer[0];
- Uint32 RexecRegionLen= cinBuffer[1];
- Uint32 RfinalUpdateLen= cinBuffer[2];
- Uint32 RfinalRLen= cinBuffer[3];
- Uint32 RsubLen= cinBuffer[4];
-
- Uint32 RattrinbufLen= req_struct->attrinfo_len;
- const BlockReference sendBref= req_struct->rec_blockref;
-
- const Uint32 node = refToNode(sendBref);
- if(node != 0 && node != getOwnNodeId()) {
- start_index= 25;
- } else {
- jam();
- /**
- * execute direct
- */
- start_index= 3;
- }
- dst= &signal->theData[start_index];
- dstLen= (MAX_READ / 4) - start_index;
-
- RtotalLen= RinitReadLen;
- RtotalLen += RexecRegionLen;
- RtotalLen += RfinalUpdateLen;
- RtotalLen += RfinalRLen;
- RtotalLen += RsubLen;
-
- Uint32 RattroutCounter= 0;
- Uint32 RinstructionCounter= 5;
- Uint32 RlogSize= 0;
- if (((RtotalLen + 5) == RattrinbufLen) &&
- (RattrinbufLen >= 5) &&
- (RattrinbufLen < ZATTR_BUFFER_SIZE)) {
- /* ---------------------------------------------------------------- */
- // We start by checking consistency. We must have the first five
- // words of the ATTRINFO to give us the length of the regions. The
- // size of these regions must be the same as the total ATTRINFO
- // length and finally the total length must be within the limits.
- /* ---------------------------------------------------------------- */
-
- if (RinitReadLen > 0) {
- jam();
- /* ---------------------------------------------------------------- */
- // The first step that can be taken in the interpreter is to read
- // data of the tuple before any updates have been applied.
- /* ---------------------------------------------------------------- */
- TnoDataRW= readAttributes(req_struct,
- &cinBuffer[5],
- RinitReadLen,
- &dst[0],
- dstLen,
- false);
- if (TnoDataRW != -1) {
- RattroutCounter= TnoDataRW;
- RinstructionCounter += RinitReadLen;
- } else {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- }
- if (RexecRegionLen > 0) {
- jam();
- /* ---------------------------------------------------------------- */
- // The next step is the actual interpreted execution. This executes
- // a register-based virtual machine which can read and write attributes
- // to and from registers.
- /* ---------------------------------------------------------------- */
- Uint32 RsubPC= RinstructionCounter + RfinalUpdateLen + RfinalRLen;
- TnoDataRW= interpreterNextLab(signal,
- req_struct,
- &clogMemBuffer[0],
- &cinBuffer[RinstructionCounter],
- RexecRegionLen,
- &cinBuffer[RsubPC],
- RsubLen,
- &coutBuffer[0],
- sizeof(coutBuffer) / 4);
- if (TnoDataRW != -1) {
- RinstructionCounter += RexecRegionLen;
- RlogSize= TnoDataRW;
- } else {
- jam();
- /**
- * TUPKEY REF is sent from within interpreter
- */
- return -1;
- }
- }
- if (RfinalUpdateLen > 0) {
- jam();
- /* ---------------------------------------------------------------- */
- // We can also apply a set of updates without any conditions as part
- // of the interpreted execution.
- /* ---------------------------------------------------------------- */
- if (regOperPtr->op_struct.op_type == ZUPDATE) {
- TnoDataRW= updateAttributes(req_struct,
- &cinBuffer[RinstructionCounter],
- RfinalUpdateLen);
- if (TnoDataRW != -1) {
- MEMCOPY_NO_WORDS(&clogMemBuffer[RlogSize],
- &cinBuffer[RinstructionCounter],
- RfinalUpdateLen);
- RinstructionCounter += RfinalUpdateLen;
- RlogSize += RfinalUpdateLen;
- } else {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- } else {
- return TUPKEY_abort(signal, 19);
- }
- }
- if (RfinalRLen > 0) {
- jam();
- /* ---------------------------------------------------------------- */
- // The final action is that we can also read the tuple after it has
- // been updated.
- /* ---------------------------------------------------------------- */
- TnoDataRW= readAttributes(req_struct,
- &cinBuffer[RinstructionCounter],
- RfinalRLen,
- &dst[RattroutCounter],
- (dstLen - RattroutCounter),
- false);
- if (TnoDataRW != -1) {
- RattroutCounter += TnoDataRW;
- } else {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- }
- req_struct->log_size= RlogSize;
- req_struct->read_length= RattroutCounter;
- sendReadAttrinfo(signal, req_struct, RattroutCounter, regOperPtr);
- if (RlogSize > 0) {
- sendLogAttrinfo(signal, RlogSize, regOperPtr);
- }
- return 0;
- } else {
- return TUPKEY_abort(signal, 22);
- }
-}
-
-/* ---------------------------------------------------------------- */
-/* WHEN EXECUTION IS INTERPRETED WE NEED TO SEND SOME ATTRINFO*/
-/* BACK TO LQH FOR LOGGING AND SENDING TO BACKUP AND STANDBY */
-/* NODES. */
-/* INPUT: LOG_ATTRINFOPTR WHERE TO FETCH DATA FROM */
-/* TLOG_START FIRST INDEX TO LOG */
-/* TLOG_END LAST INDEX + 1 TO LOG */
-/* ---------------------------------------------------------------- */
-void Dbtup::sendLogAttrinfo(Signal* signal,
- Uint32 TlogSize,
- Operationrec * const regOperPtr)
-
-{
- Uint32 TbufferIndex= 0;
- signal->theData[0]= regOperPtr->userpointer;
- while (TlogSize > 22) {
- MEMCOPY_NO_WORDS(&signal->theData[3],
- &clogMemBuffer[TbufferIndex],
- 22);
- EXECUTE_DIRECT(DBLQH, GSN_TUP_ATTRINFO, signal, 25);
- TbufferIndex += 22;
- TlogSize -= 22;
- }
- MEMCOPY_NO_WORDS(&signal->theData[3],
- &clogMemBuffer[TbufferIndex],
- TlogSize);
- EXECUTE_DIRECT(DBLQH, GSN_TUP_ATTRINFO, signal, 3 + TlogSize);
-}
-
-inline
-Uint32
-brancher(Uint32 TheInstruction, Uint32 TprogramCounter)
-{
- Uint32 TbranchDirection= TheInstruction >> 31;
- Uint32 TbranchLength= (TheInstruction >> 16) & 0x7fff;
- TprogramCounter--;
- if (TbranchDirection == 1) {
- jam();
- /* ---------------------------------------------------------------- */
- /* WE JUMP BACKWARDS. */
- /* ---------------------------------------------------------------- */
- return (TprogramCounter - TbranchLength);
- } else {
- jam();
- /* ---------------------------------------------------------------- */
- /* WE JUMP FORWARD. */
- /* ---------------------------------------------------------------- */
- return (TprogramCounter + TbranchLength);
- }
-}
-
-int Dbtup::interpreterNextLab(Signal* signal,
- KeyReqStruct* req_struct,
- Uint32* logMemory,
- Uint32* mainProgram,
- Uint32 TmainProgLen,
- Uint32* subroutineProg,
- Uint32 TsubroutineLen,
- Uint32 * tmpArea,
- Uint32 tmpAreaSz)
-{
- register Uint32* TcurrentProgram= mainProgram;
- register Uint32 TcurrentSize= TmainProgLen;
- register Uint32 RnoOfInstructions= 0;
- register Uint32 TprogramCounter= 0;
- register Uint32 theInstruction;
- register Uint32 theRegister;
- Uint32 TdataWritten= 0;
- Uint32 RstackPtr= 0;
- union {
- Uint32 TregMemBuffer[32];
- Uint64 align[16];
- };
- Uint32 TstackMemBuffer[32];
-
- /* ---------------------------------------------------------------- */
- // Initialise all 8 registers to contain the NULL value.
- // In this version we can handle 32 and 64 bit unsigned integers.
- // They are handled as 64 bit values. Thus the 32 most significant
- // bits are zeroed for 32 bit values.
- /* ---------------------------------------------------------------- */
- TregMemBuffer[0]= 0;
- TregMemBuffer[4]= 0;
- TregMemBuffer[8]= 0;
- TregMemBuffer[12]= 0;
- TregMemBuffer[16]= 0;
- TregMemBuffer[20]= 0;
- TregMemBuffer[24]= 0;
- TregMemBuffer[28]= 0;
- Uint32 tmpHabitant= ~0;
-
- while (RnoOfInstructions < 8000) {
- /* ---------------------------------------------------------------- */
- /* EXECUTE THE NEXT INTERPRETER INSTRUCTION. */
- /* ---------------------------------------------------------------- */
- RnoOfInstructions++;
- theInstruction= TcurrentProgram[TprogramCounter];
- theRegister= Interpreter::getReg1(theInstruction) << 2;
- if (TprogramCounter < TcurrentSize) {
- TprogramCounter++;
- switch (Interpreter::getOpCode(theInstruction)) {
- case Interpreter::READ_ATTR_INTO_REG:
- jam();
- /* ---------------------------------------------------------------- */
- // Read an attribute from the tuple into a register.
- // While reading an attribute we allow the attribute to be an array
- // as long as it fits in the 64 bits of the register.
- /* ---------------------------------------------------------------- */
- {
- Uint32 theAttrinfo= theInstruction;
- int TnoDataRW= readAttributes(req_struct,
- &theAttrinfo,
- (Uint32)1,
- &TregMemBuffer[theRegister],
- (Uint32)3,
- false);
- if (TnoDataRW == 2) {
- /* ------------------------------------------------------------- */
- // Two words read means that we get the instruction plus one 32
- // word read. Thus we set the register to be a 32 bit register.
- /* ------------------------------------------------------------- */
- TregMemBuffer[theRegister]= 0x50;
- // arithmetic conversion if big-endian
- * (Int64*)(TregMemBuffer+theRegister+2)= TregMemBuffer[theRegister+1];
- } else if (TnoDataRW == 3) {
- /* ------------------------------------------------------------- */
- // Three words read means that we get the instruction plus two
- // 32 words read. Thus we set the register to be a 64 bit register.
- /* ------------------------------------------------------------- */
- TregMemBuffer[theRegister]= 0x60;
- TregMemBuffer[theRegister+3]= TregMemBuffer[theRegister+2];
- TregMemBuffer[theRegister+2]= TregMemBuffer[theRegister+1];
- } else if (TnoDataRW == 1) {
- /* ------------------------------------------------------------- */
- // One word read means that we must have read a NULL value. We set
- // the register to indicate a NULL value.
- /* ------------------------------------------------------------- */
- TregMemBuffer[theRegister]= 0;
- TregMemBuffer[theRegister + 2]= 0;
- TregMemBuffer[theRegister + 3]= 0;
- } else if (TnoDataRW == -1) {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- } else {
- /* ------------------------------------------------------------- */
- // Any other return value from the read attribute here is not
- // allowed and will lead to a system crash.
- /* ------------------------------------------------------------- */
- ndbrequire(false);
- }
- break;
- }
-
- case Interpreter::WRITE_ATTR_FROM_REG:
- jam();
- {
- Uint32 TattrId= theInstruction >> 16;
- Uint32 TattrDescrIndex= tabptr.p->tabDescriptor +
- (TattrId << ZAD_LOG_SIZE);
- Uint32 TattrDesc1= tableDescriptor[TattrDescrIndex].tabDescr;
- Uint32 TregType= TregMemBuffer[theRegister];
-
- /* --------------------------------------------------------------- */
- // Calculate the number of words of this attribute.
- // We allow writes into arrays as long as they fit into the 64 bit
- // register size.
- /* --------------------------------------------------------------- */
- Uint32 TattrNoOfWords = AttributeDescriptor::getSizeInWords(TattrDesc1);
- Uint32 Toptype = operPtr.p->op_struct.op_type;
- Uint32 TdataForUpdate[3];
- Uint32 Tlen;
-
- AttributeHeader ah(TattrId, TattrNoOfWords << 2);
- TdataForUpdate[0]= ah.m_value;
- TdataForUpdate[1]= TregMemBuffer[theRegister + 2];
- TdataForUpdate[2]= TregMemBuffer[theRegister + 3];
- Tlen= TattrNoOfWords + 1;
- if (Toptype == ZUPDATE) {
- if (TattrNoOfWords <= 2) {
- if (TattrNoOfWords == 1) {
- // arithmetic conversion if big-endian
- TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2];
- TdataForUpdate[2] = 0;
- }
- if (TregType == 0) {
- /* --------------------------------------------------------- */
- // Write a NULL value into the attribute
- /* --------------------------------------------------------- */
- ah.setNULL();
- TdataForUpdate[0]= ah.m_value;
- Tlen= 1;
- }
- int TnoDataRW= updateAttributes(req_struct,
- &TdataForUpdate[0],
- Tlen);
- if (TnoDataRW != -1) {
- /* --------------------------------------------------------- */
- // Write the written data also into the log buffer so that it
- // will be logged.
- /* --------------------------------------------------------- */
- logMemory[TdataWritten + 0]= TdataForUpdate[0];
- logMemory[TdataWritten + 1]= TdataForUpdate[1];
- logMemory[TdataWritten + 2]= TdataForUpdate[2];
- TdataWritten += Tlen;
- } else {
- tupkeyErrorLab(signal);
- return -1;
- }
- } else {
- return TUPKEY_abort(signal, 15);
- }
- } else {
- return TUPKEY_abort(signal, 16);
- }
- break;
- }
-
- case Interpreter::LOAD_CONST_NULL:
- jam();
- TregMemBuffer[theRegister]= 0; /* NULL INDICATOR */
- break;
-
- case Interpreter::LOAD_CONST16:
- jam();
- TregMemBuffer[theRegister]= 0x50; /* 32 BIT UNSIGNED CONSTANT */
- * (Int64*)(TregMemBuffer+theRegister+2)= theInstruction >> 16;
- break;
-
- case Interpreter::LOAD_CONST32:
- jam();
- TregMemBuffer[theRegister]= 0x50; /* 32 BIT UNSIGNED CONSTANT */
- * (Int64*)(TregMemBuffer+theRegister+2)= *
- (TcurrentProgram+TprogramCounter);
- TprogramCounter++;
- break;
-
- case Interpreter::LOAD_CONST64:
- jam();
- TregMemBuffer[theRegister]= 0x60; /* 64 BIT UNSIGNED CONSTANT */
- TregMemBuffer[theRegister + 2 ]= * (TcurrentProgram +
- TprogramCounter++);
- TregMemBuffer[theRegister + 3 ]= * (TcurrentProgram +
- TprogramCounter++);
- break;
-
- case Interpreter::ADD_REG_REG:
- jam();
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
- Uint32 TdestRegister= Interpreter::getReg3(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
- if ((TleftType | TrightType) != 0) {
- Uint64 Tdest0= Tleft0 + Tright0;
- * (Int64*)(TregMemBuffer+TdestRegister+2)= Tdest0;
- TregMemBuffer[TdestRegister]= 0x60;
- } else {
- return TUPKEY_abort(signal, 20);
- }
- break;
- }
-
- case Interpreter::SUB_REG_REG:
- jam();
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
- Uint32 TdestRegister= Interpreter::getReg3(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
- if ((TleftType | TrightType) != 0) {
- Int64 Tdest0= Tleft0 - Tright0;
- * (Int64*)(TregMemBuffer+TdestRegister+2)= Tdest0;
- TregMemBuffer[TdestRegister]= 0x60;
- } else {
- return TUPKEY_abort(signal, 20);
- }
- break;
- }
-
- case Interpreter::BRANCH:
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- break;
-
- case Interpreter::BRANCH_REG_EQ_NULL:
- if (TregMemBuffer[theRegister] != 0) {
- jam();
- continue;
- } else {
- jam();
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- break;
-
- case Interpreter::BRANCH_REG_NE_NULL:
- if (TregMemBuffer[theRegister] == 0) {
- jam();
- continue;
- } else {
- jam();
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- break;
-
-
- case Interpreter::BRANCH_EQ_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Uint32 Tleft0= TregMemBuffer[theRegister + 2];
- Uint32 Tleft1= TregMemBuffer[theRegister + 3];
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Uint32 Tright0= TregMemBuffer[TrightRegister + 2];
- Uint32 Tright1= TregMemBuffer[TrightRegister + 3];
- if ((TrightType | TleftType) != 0) {
- jam();
- if ((Tleft0 == Tright0) && (Tleft1 == Tright1)) {
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 23);
- }
- break;
- }
-
- case Interpreter::BRANCH_NE_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Uint32 Tleft0= TregMemBuffer[theRegister + 2];
- Uint32 Tleft1= TregMemBuffer[theRegister + 3];
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Uint32 Tright0= TregMemBuffer[TrightRegister + 2];
- Uint32 Tright1= TregMemBuffer[TrightRegister + 3];
- if ((TrightType | TleftType) != 0) {
- jam();
- if ((Tleft0 != Tright0) || (Tleft1 != Tright1)) {
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 24);
- }
- break;
- }
-
- case Interpreter::BRANCH_LT_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
-
- if ((TrightType | TleftType) != 0) {
- jam();
- if (Tleft0 < Tright0) {
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 24);
- }
- break;
- }
-
- case Interpreter::BRANCH_LE_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
-
- if ((TrightType | TleftType) != 0) {
- jam();
- if (Tleft0 <= Tright0) {
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 26);
- }
- break;
- }
-
- case Interpreter::BRANCH_GT_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
-
- if ((TrightType | TleftType) != 0) {
- jam();
- if (Tleft0 > Tright0){
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 27);
- }
- break;
- }
-
- case Interpreter::BRANCH_GE_REG_REG:
- {
- Uint32 TrightRegister= Interpreter::getReg2(theInstruction) << 2;
-
- Uint32 TrightType= TregMemBuffer[TrightRegister];
- Int64 Tright0= * (Int64*)(TregMemBuffer + TrightRegister + 2);
-
- Uint32 TleftType= TregMemBuffer[theRegister];
- Int64 Tleft0= * (Int64*)(TregMemBuffer + theRegister + 2);
-
-
- if ((TrightType | TleftType) != 0) {
- jam();
- if (Tleft0 >= Tright0){
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- } else {
- return TUPKEY_abort(signal, 28);
- }
- break;
- }
-
- case Interpreter::BRANCH_ATTR_OP_ARG:{
- jam();
- Uint32 cond = Interpreter::getBinaryCondition(theInstruction);
- Uint32 ins2 = TcurrentProgram[TprogramCounter];
- Uint32 attrId = Interpreter::getBranchCol_AttrId(ins2) << 16;
- Uint32 argLen = Interpreter::getBranchCol_Len(ins2);
-
- if(tmpHabitant != attrId){
- Int32 TnoDataR = readAttributes(req_struct,
- &attrId, 1,
- tmpArea, tmpAreaSz,
- false);
-
- if (TnoDataR == -1) {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- tmpHabitant= attrId;
- }
-
- // get type
- attrId >>= 16;
- Uint32 TattrDescrIndex = tabptr.p->tabDescriptor +
- (attrId << ZAD_LOG_SIZE);
- Uint32 TattrDesc1 = tableDescriptor[TattrDescrIndex].tabDescr;
- Uint32 TattrDesc2 = tableDescriptor[TattrDescrIndex+1].tabDescr;
- Uint32 typeId = AttributeDescriptor::getType(TattrDesc1);
- const void * cs = 0;
- if(AttributeOffset::getCharsetFlag(TattrDesc2))
- {
- Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2);
- cs = (void*) tabptr.p->charsetArray[pos];
- }
- const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(typeId);
-
- // get data
- AttributeHeader ah(tmpArea[0]);
- const char* s1 = (char*)&tmpArea[1];
- const char* s2 = (char*)&TcurrentProgram[TprogramCounter+1];
- // fixed length in 5.0
- Uint32 attrLen = AttributeDescriptor::getSizeInBytes(TattrDesc1);
-
- bool r1_null = ah.isNULL();
- bool r2_null = argLen == 0;
- int res1;
- if (cond != Interpreter::LIKE &&
- cond != Interpreter::NOT_LIKE) {
- if (r1_null || r2_null) {
- // NULL==NULL and NULL<not-NULL
- res1 = r1_null && r2_null ? 0 : r1_null ? -1 : 1;
- } else {
- jam();
- if (unlikely(sqlType.m_cmp == 0))
- {
- return TUPKEY_abort(signal, 40);
- }
- res1 = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true);
- }
- } else {
- if (r1_null || r2_null) {
- // NULL like NULL is true (has no practical use)
- res1 = r1_null && r2_null ? 0 : -1;
- } else {
- jam();
- if (unlikely(sqlType.m_like == 0))
- {
- return TUPKEY_abort(signal, 40);
- }
- res1 = (*sqlType.m_like)(cs, s1, attrLen, s2, argLen);
- }
- }
-
- int res = 0;
- switch ((Interpreter::BinaryCondition)cond) {
- case Interpreter::EQ:
- res = (res1 == 0);
- break;
- case Interpreter::NE:
- res = (res1 != 0);
- break;
- // note the condition is backwards
- case Interpreter::LT:
- res = (res1 > 0);
- break;
- case Interpreter::LE:
- res = (res1 >= 0);
- break;
- case Interpreter::GT:
- res = (res1 < 0);
- break;
- case Interpreter::GE:
- res = (res1 <= 0);
- break;
- case Interpreter::LIKE:
- res = (res1 == 0);
- break;
- case Interpreter::NOT_LIKE:
- res = (res1 == 1);
- break;
- // XXX handle invalid value
- }
-#ifdef TRACE_INTERPRETER
- ndbout_c("cond=%u attr(%d)='%.*s'(%d) str='%.*s'(%d) res1=%d res=%d",
- cond, attrId >> 16,
- attrLen, s1, attrLen, argLen, s2, argLen, res1, res);
-#endif
- if (res)
- TprogramCounter = brancher(theInstruction, TprogramCounter);
- else
- {
- Uint32 tmp = ((argLen + 3) >> 2) + 1;
- TprogramCounter += tmp;
- }
- break;
- }
-
- case Interpreter::BRANCH_ATTR_EQ_NULL:{
- jam();
- Uint32 ins2= TcurrentProgram[TprogramCounter];
- Uint32 attrId= Interpreter::getBranchCol_AttrId(ins2) << 16;
-
- if (tmpHabitant != attrId){
- Int32 TnoDataR= readAttributes(req_struct,
- &attrId, 1,
- tmpArea, tmpAreaSz,
- false);
-
- if (TnoDataR == -1) {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- tmpHabitant= attrId;
- }
-
- AttributeHeader ah(tmpArea[0]);
- if (ah.isNULL()){
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- } else {
- TprogramCounter ++;
- }
- break;
- }
-
- case Interpreter::BRANCH_ATTR_NE_NULL:{
- jam();
- Uint32 ins2= TcurrentProgram[TprogramCounter];
- Uint32 attrId= Interpreter::getBranchCol_AttrId(ins2) << 16;
-
- if (tmpHabitant != attrId){
- Int32 TnoDataR= readAttributes(req_struct,
- &attrId, 1,
- tmpArea, tmpAreaSz,
- false);
-
- if (TnoDataR == -1) {
- jam();
- tupkeyErrorLab(signal);
- return -1;
- }
- tmpHabitant= attrId;
- }
-
- AttributeHeader ah(tmpArea[0]);
- if (ah.isNULL()){
- TprogramCounter ++;
- } else {
- TprogramCounter= brancher(theInstruction, TprogramCounter);
- }
- break;
- }
-
- case Interpreter::EXIT_OK:
- jam();
-#ifdef TRACE_INTERPRETER
- ndbout_c(" - exit_ok");
-#endif
- return TdataWritten;
-
- case Interpreter::EXIT_OK_LAST:
- jam();
-#ifdef TRACE_INTERPRETER
- ndbout_c(" - exit_ok_last");
-#endif
- req_struct->last_row= true;
- return TdataWritten;
-
- case Interpreter::EXIT_REFUSE:
- jam();
-#ifdef TRACE_INTERPRETER
- ndbout_c(" - exit_nok");
-#endif
- terrorCode= theInstruction >> 16;
- return TUPKEY_abort(signal, 29);
-
- case Interpreter::CALL:
- jam();
- RstackPtr++;
- if (RstackPtr < 32) {
- TstackMemBuffer[RstackPtr]= TprogramCounter + 1;
- TprogramCounter= theInstruction >> 16;
- if (TprogramCounter < TsubroutineLen) {
- TcurrentProgram= subroutineProg;
- TcurrentSize= TsubroutineLen;
- } else {
- return TUPKEY_abort(signal, 30);
- }
- } else {
- return TUPKEY_abort(signal, 31);
- }
- break;
-
- case Interpreter::RETURN:
- jam();
- if (RstackPtr > 0) {
- TprogramCounter= TstackMemBuffer[RstackPtr];
- RstackPtr--;
- if (RstackPtr == 0) {
- jam();
- /* ------------------------------------------------------------- */
- // We are back to the main program.
- /* ------------------------------------------------------------- */
- TcurrentProgram= mainProgram;
- TcurrentSize= TmainProgLen;
- }
- } else {
- return TUPKEY_abort(signal, 32);
- }
- break;
-
- default:
- return TUPKEY_abort(signal, 33);
- }
- } else {
- return TUPKEY_abort(signal, 34);
- }
- }
- return TUPKEY_abort(signal, 35);
-}
-
-/**
- * expand_var_part - copy packed variable attributes to fully expanded size
- *
- * dst: where to start writing attribute data
- * dst_off_ptr where to write attribute offsets
- * src pointer to packed attributes
- * tabDesc array of attribute descriptors (used for getting max size)
- * no_of_attr no of atributes to expand
- */
-Uint32*
-expand_var_part(Dbtup::KeyReqStruct::Var_data *dst,
- const Uint32* src,
- const Uint32 * tabDesc,
- const Uint16* order)
-{
- char* dst_ptr= dst->m_data_ptr;
- Uint32 no_attr= dst->m_var_len_offset;
- Uint16* dst_off_ptr= dst->m_offset_array_ptr;
- Uint16* dst_len_ptr= dst_off_ptr + no_attr;
- const Uint16* src_off_ptr= (const Uint16*)src;
- const char* src_ptr= (const char*)(src_off_ptr + no_attr + 1);
-
- Uint16 tmp= *src_off_ptr++, next_pos, len, max_len, dst_off= 0;
- for(Uint32 i = 0; i<no_attr; i++)
- {
- next_pos= *src_off_ptr++;
- len= next_pos - tmp;
-
- *dst_off_ptr++ = dst_off;
- *dst_len_ptr++ = dst_off + len;
- memcpy(dst_ptr, src_ptr, len);
- src_ptr += len;
-
- max_len= AttributeDescriptor::getSizeInBytes(tabDesc[* order++]);
- dst_ptr += max_len; // Max size
- dst_off += max_len;
-
- tmp= next_pos;
- }
-
- return ALIGN_WORD(dst_ptr);
-}
-
-void
-Dbtup::expand_tuple(KeyReqStruct* req_struct,
- Uint32 sizes[2],
- Tuple_header* src,
- const Tablerec* tabPtrP,
- bool disk)
-{
- Uint32 bits= src->m_header_bits;
- Tuple_header* ptr= req_struct->m_tuple_ptr;
-
- Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
- Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
- Uint32 fix_size= tabPtrP->m_offsets[MM].m_fix_header_size;
- Uint32 order_desc= tabPtrP->m_real_order_descriptor;
-
- Uint32 *dst_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
- const Uint32 *disk_ref= src->get_disk_ref_ptr(tabPtrP);
- const Uint32 *src_ptr= src->get_end_of_fix_part_ptr(tabPtrP);
- const Var_part_ref* var_ref = src->get_var_part_ref_ptr(tabPtrP);
- const Uint32 *desc= (Uint32*)req_struct->attr_descr;
- const Uint16 *order = (Uint16*)(&tableDescriptor[order_desc]);
- order += tabPtrP->m_attributes[MM].m_no_of_fixsize;
-
- if(mm_vars)
- {
-
- Uint32 step; // in bytes
- const Uint32 *src_data= src_ptr;
- KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
- if(bits & Tuple_header::CHAINED_ROW)
- {
- Ptr<Page> var_page;
- src_data= get_ptr(&var_page, *var_ref);
- step= 4;
- sizes[MM]= (2 + (mm_vars << 1) + ((Uint16*)src_data)[mm_vars] + 3) >> 2;
- req_struct->m_varpart_page_ptr = var_page;
- }
- else
- {
- step= (2 + (mm_vars << 1) + ((Uint16*)src_ptr)[mm_vars]);
- sizes[MM]= (step + 3) >> 2;
- req_struct->m_varpart_page_ptr = req_struct->m_page_ptr;
- }
- dst->m_data_ptr= (char*)(((Uint16*)dst_ptr)+mm_vars+1);
- dst->m_offset_array_ptr= req_struct->var_pos_array;
- dst->m_var_len_offset= mm_vars;
- dst->m_max_var_offset= tabPtrP->m_offsets[MM].m_max_var_offset;
-
- dst_ptr= expand_var_part(dst, src_data, desc, order);
- ndbassert(dst_ptr == ALIGN_WORD(dst->m_data_ptr + dst->m_max_var_offset));
- ndbassert((UintPtr(src_ptr) & 3) == 0);
- src_ptr = ALIGN_WORD(((char*)src_ptr)+step);
-
- sizes[MM] += fix_size;
- memcpy(ptr, src, 4*fix_size);
- }
- else
- {
- sizes[MM]= 1;
- memcpy(ptr, src, 4*fix_size);
- }
-
- src->m_header_bits= bits &
- ~(Uint32)(Tuple_header::MM_SHRINK | Tuple_header::MM_GROWN);
-
- sizes[DD]= 0;
- if(disk && dd_tot)
- {
- const Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
- order += mm_vars;
-
- if(bits & Tuple_header::DISK_INLINE)
- {
- // Only on copy tuple
- ndbassert((bits & Tuple_header::CHAINED_ROW) == 0);
- }
- else
- {
- Local_key key;
- memcpy(&key, disk_ref, sizeof(key));
- key.m_page_no= req_struct->m_disk_page_ptr.i;
- src_ptr= get_dd_ptr(&req_struct->m_disk_page_ptr, &key, tabPtrP);
- }
- bits |= Tuple_header::DISK_INLINE;
-
- // Fix diskpart
- req_struct->m_disk_ptr= (Tuple_header*)dst_ptr;
- memcpy(dst_ptr, src_ptr, 4*tabPtrP->m_offsets[DD].m_fix_header_size);
- sizes[DD] = tabPtrP->m_offsets[DD].m_fix_header_size;
-
- ndbassert(! (req_struct->m_disk_ptr->m_header_bits & Tuple_header::FREE));
-
- ndbrequire(dd_vars == 0);
- }
-
- ptr->m_header_bits= (bits & ~(Uint32)(Tuple_header::CHAINED_ROW));
-}
-
-void
-Dbtup::prepare_read(KeyReqStruct* req_struct,
- Tablerec* tabPtrP, bool disk)
-{
- Tuple_header* ptr= req_struct->m_tuple_ptr;
-
- Uint32 bits= ptr->m_header_bits;
- Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
- Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
-
- const Uint32 *src_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
- const Uint32 *disk_ref= ptr->get_disk_ref_ptr(tabPtrP);
- const Var_part_ref* var_ref = ptr->get_var_part_ref_ptr(tabPtrP);
- if(mm_vars)
- {
- const Uint32 *src_data= src_ptr;
- KeyReqStruct::Var_data* dst= &req_struct->m_var_data[MM];
- if(bits & Tuple_header::CHAINED_ROW)
- {
-#if VM_TRACE
-
-#endif
- src_data= get_ptr(* var_ref);
- }
- dst->m_data_ptr= (char*)(((Uint16*)src_data)+mm_vars+1);
- dst->m_offset_array_ptr= (Uint16*)src_data;
- dst->m_var_len_offset= 1;
- dst->m_max_var_offset= ((Uint16*)src_data)[mm_vars];
-
- // disk part start after varsize (aligned)
- src_ptr = ALIGN_WORD(dst->m_data_ptr + dst->m_max_var_offset);
- }
-
- if(disk && dd_tot)
- {
- const Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
-
- if(bits & Tuple_header::DISK_INLINE)
- {
- // Only on copy tuple
- ndbassert((bits & Tuple_header::CHAINED_ROW) == 0);
- }
- else
- {
- // XXX
- Local_key key;
- memcpy(&key, disk_ref, sizeof(key));
- key.m_page_no= req_struct->m_disk_page_ptr.i;
- src_ptr= get_dd_ptr(&req_struct->m_disk_page_ptr, &key, tabPtrP);
- }
- // Fix diskpart
- req_struct->m_disk_ptr= (Tuple_header*)src_ptr;
- ndbassert(! (req_struct->m_disk_ptr->m_header_bits & Tuple_header::FREE));
- ndbrequire(dd_vars == 0);
- }
-}
-
-void
-Dbtup::shrink_tuple(KeyReqStruct* req_struct, Uint32 sizes[2],
- const Tablerec* tabPtrP, bool disk)
-{
- ndbassert(tabPtrP->need_shrink());
- Tuple_header* ptr= req_struct->m_tuple_ptr;
-
- Uint16 dd_tot= tabPtrP->m_no_of_disk_attributes;
- Uint16 mm_vars= tabPtrP->m_attributes[MM].m_no_of_varsize;
- Uint16 dd_vars= tabPtrP->m_attributes[DD].m_no_of_varsize;
-
- Uint32 *dst_ptr= ptr->get_end_of_fix_part_ptr(tabPtrP);
- Uint16* src_off_ptr= req_struct->var_pos_array;
-
- sizes[MM] = 1;
- sizes[DD] = 0;
- if(mm_vars)
- {
- Uint16* dst_off_ptr= (Uint16*)dst_ptr;
- char* dst_data_ptr= (char*)(dst_off_ptr + mm_vars + 1);
- char* src_data_ptr= dst_data_ptr;
- Uint32 off= 0;
- for(Uint32 i= 0; i<mm_vars; i++)
- {
- const char* data_ptr= src_data_ptr + *src_off_ptr;
- Uint32 len= src_off_ptr[mm_vars] - *src_off_ptr;
- * dst_off_ptr++= off;
- memmove(dst_data_ptr, data_ptr, len);
- off += len;
- src_off_ptr++;
- dst_data_ptr += len;
- }
- *dst_off_ptr= off;
- ndbassert(dst_data_ptr <= ((char*)ptr) + 8192);
- ndbassert((UintPtr(ptr) & 3) == 0);
- sizes[MM]= (dst_data_ptr + 3 - ((char*)ptr)) >> 2;
-
- dst_ptr = ALIGN_WORD(dst_data_ptr);
- }
-
- if(disk && dd_tot)
- {
- Uint32 * src_ptr = (Uint32*)req_struct->m_disk_ptr;
- req_struct->m_disk_ptr = (Tuple_header*)dst_ptr;
- ndbrequire(dd_vars == 0);
- sizes[DD] = tabPtrP->m_offsets[DD].m_fix_header_size;
- memmove(dst_ptr, src_ptr, 4*tabPtrP->m_offsets[DD].m_fix_header_size);
- }
-}
-
-void
-Dbtup::validate_page(Tablerec* regTabPtr, Var_page* p)
-{
- Uint32 mm_vars= regTabPtr->m_attributes[MM].m_no_of_varsize;
- Uint32 fix_sz= regTabPtr->m_offsets[MM].m_fix_header_size +
- Tuple_header::HeaderSize;
-
- if(mm_vars == 0)
- return;
-
- for(Uint32 F= 0; F<MAX_FRAG_PER_NODE; F++)
- {
- FragrecordPtr fragPtr;
-
- if((fragPtr.i = regTabPtr->fragrec[F]) == RNIL)
- continue;
-
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- for(Uint32 P= 0; P<fragPtr.p->noOfPages; P++)
- {
- Uint32 real= getRealpid(fragPtr.p, P);
- Var_page* page= (Var_page*)c_page_pool.getPtr(real);
-
- for(Uint32 i=1; i<page->high_index; i++)
- {
- Uint32 idx= page->get_index_word(i);
- Uint32 len = (idx & Var_page::LEN_MASK) >> Var_page::LEN_SHIFT;
- if(!(idx & Var_page::FREE) && !(idx & Var_page::CHAIN))
- {
- Tuple_header *ptr= (Tuple_header*)page->get_ptr(i);
- Uint32 *part= ptr->get_end_of_fix_part_ptr(regTabPtr);
- if(ptr->m_header_bits & Tuple_header::CHAINED_ROW)
- {
- ndbassert(len == fix_sz + 1);
- Local_key tmp; tmp.assref(*part);
- Ptr<Page> tmpPage;
- part= get_ptr(&tmpPage, *(Var_part_ref*)part);
- len= ((Var_page*)tmpPage.p)->get_entry_len(tmp.m_page_idx);
- Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
- ndbassert(len >= ((sz + 3) >> 2));
- }
- else
- {
- Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
- ndbassert(len >= ((sz+3)>>2)+fix_sz);
- }
- if(ptr->m_operation_ptr_i != RNIL)
- {
- c_operation_pool.getPtr(ptr->m_operation_ptr_i);
- }
- }
- else if(!(idx & Var_page::FREE))
- {
- /**
- * Chain
- */
- Uint32 *part= page->get_ptr(i);
- Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
- ndbassert(len >= ((sz + 3) >> 2));
- }
- else
- {
-
- }
- }
- if(p == 0 && page->high_index > 1)
- page->reorg((Var_page*)ctemp_page);
- }
- }
-
- if(p == 0)
- {
- validate_page(regTabPtr, (Var_page*)1);
- }
-}
-
-int
-Dbtup::handle_size_change_after_update(KeyReqStruct* req_struct,
- Tuple_header* org,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- Uint32 sizes[4])
-{
- ndbrequire(sizes[1] == sizes[3]);
- //ndbout_c("%d %d %d %d", sizes[0], sizes[1], sizes[2], sizes[3]);
- if(0)
- printf("%p %d %d - handle_size_change_after_update ",
- req_struct->m_tuple_ptr,
- regOperPtr->m_tuple_location.m_page_no,
- regOperPtr->m_tuple_location.m_page_idx);
-
- Uint32 bits= org->m_header_bits;
- Uint32 copy_bits= req_struct->m_tuple_ptr->m_header_bits;
- Uint32 fix_sz = regTabPtr->m_offsets[MM].m_fix_header_size;
-
- if(sizes[MM] == sizes[2+MM])
- ;
- else if(sizes[MM] > sizes[2+MM])
- {
- if(0) ndbout_c("shrink");
- copy_bits |= Tuple_header::MM_SHRINK;
- }
- else
- {
- if(0) printf("grow - ");
- Ptr<Page> pagePtr = req_struct->m_varpart_page_ptr;
- Var_page* pageP= (Var_page*)pagePtr.p;
- Uint32 idx, alloc, needed;
- Var_part_ref *refptr = org->get_var_part_ref_ptr(regTabPtr);
- ndbassert(bits & Tuple_header::CHAINED_ROW);
-
- Local_key ref;
- refptr->copyout(&ref);
- idx= ref.m_page_idx;
- if (! (copy_bits & Tuple_header::CHAINED_ROW))
- {
- c_page_pool.getPtr(pagePtr, ref.m_page_no);
- pageP = (Var_page*)pagePtr.p;
- }
- alloc= pageP->get_entry_len(idx);
-#ifdef VM_TRACE
- if(!pageP->get_entry_chain(idx))
- ndbout << *pageP << endl;
-#endif
- ndbassert(pageP->get_entry_chain(idx));
- needed= sizes[2+MM] - fix_sz;
-
- if(needed <= alloc)
- {
- //ndbassert(!regOperPtr->is_first_operation());
- if (0) ndbout_c(" no grow");
- return 0;
- }
- copy_bits |= Tuple_header::MM_GROWN;
- if (unlikely(realloc_var_part(regFragPtr, regTabPtr, pagePtr,
- refptr, alloc, needed)))
- return -1;
-
- if (regTabPtr->m_bits & Tablerec::TR_Checksum)
- {
- jam();
- setChecksum(org, regTabPtr);
- }
- }
- req_struct->m_tuple_ptr->m_header_bits = copy_bits;
- return 0;
-}
-
-int
-Dbtup::nr_update_gci(Uint32 fragPtrI, const Local_key* key, Uint32 gci)
-{
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
- {
- Local_key tmp = *key;
- PagePtr page_ptr;
-
- int ret = alloc_page(tablePtr.p, fragPtr.p, &page_ptr, tmp.m_page_no);
-
- if (ret)
- return -1;
-
- Tuple_header* ptr = (Tuple_header*)
- ((Fix_page*)page_ptr.p)->get_ptr(tmp.m_page_idx, 0);
-
- ndbrequire(ptr->m_header_bits & Tuple_header::FREE);
- *ptr->get_mm_gci(tablePtr.p) = gci;
- }
- return 0;
-}
-
-int
-Dbtup::nr_read_pk(Uint32 fragPtrI,
- const Local_key* key, Uint32* dst, bool& copy)
-{
-
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- Local_key tmp = *key;
-
-
- PagePtr page_ptr;
- int ret = alloc_page(tablePtr.p, fragPtr.p, &page_ptr, tmp.m_page_no);
- if (ret)
- return -1;
-
- KeyReqStruct req_struct;
- Uint32* ptr= ((Fix_page*)page_ptr.p)->get_ptr(key->m_page_idx, 0);
-
- req_struct.m_page_ptr = page_ptr;
- req_struct.m_tuple_ptr = (Tuple_header*)ptr;
- Uint32 bits = req_struct.m_tuple_ptr->m_header_bits;
-
- ret = 0;
- copy = false;
- if (! (bits & Tuple_header::FREE))
- {
- if (bits & Tuple_header::ALLOC)
- {
- Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
- Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
- ndbassert(!opPtrP->m_copy_tuple_location.isNull());
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
- copy = true;
- }
- req_struct.check_offset[MM]= tablePtr.p->get_check_offset(MM);
- req_struct.check_offset[DD]= tablePtr.p->get_check_offset(DD);
-
- Uint32 num_attr= tablePtr.p->m_no_of_attributes;
- Uint32 descr_start= tablePtr.p->tabDescriptor;
- TableDescriptor *tab_descr= &tableDescriptor[descr_start];
- ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
- req_struct.attr_descr= tab_descr;
-
- if (tablePtr.p->need_expand())
- prepare_read(&req_struct, tablePtr.p, false);
-
- const Uint32* attrIds= &tableDescriptor[tablePtr.p->readKeyArray].tabDescr;
- const Uint32 numAttrs= tablePtr.p->noOfKeyAttr;
- // read pk attributes from original tuple
-
- // new globals
- tabptr= tablePtr;
- fragptr= fragPtr;
- operPtr.i= RNIL;
- operPtr.p= NULL;
-
- // do it
- ret = readAttributes(&req_struct,
- attrIds,
- numAttrs,
- dst,
- ZNIL, false);
-
- // done
- if (likely(ret != -1)) {
- // remove headers
- Uint32 n= 0;
- Uint32 i= 0;
- while (n < numAttrs) {
- const AttributeHeader ah(dst[i]);
- Uint32 size= ah.getDataSize();
- ndbrequire(size != 0);
- for (Uint32 j= 0; j < size; j++) {
- dst[i + j - n]= dst[i + j + 1];
- }
- n+= 1;
- i+= 1 + size;
- }
- ndbrequire((int)i == ret);
- ret -= numAttrs;
- } else {
- return terrorCode ? (-(int)terrorCode) : -1;
- }
- }
-
- if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
- {
- dst[ret] = *req_struct.m_tuple_ptr->get_mm_gci(tablePtr.p);
- }
- else
- {
- dst[ret] = 0;
- }
- return ret;
-}
-
-#include <signaldata/TuxMaint.hpp>
-
-int
-Dbtup::nr_delete(Signal* signal, Uint32 senderData,
- Uint32 fragPtrI, const Local_key* key, Uint32 gci)
-{
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- Local_key tmp = * key;
- tmp.m_page_no= getRealpid(fragPtr.p, tmp.m_page_no);
-
- PagePtr pagePtr;
- Tuple_header* ptr= (Tuple_header*)get_ptr(&pagePtr, &tmp, tablePtr.p);
-
- if (!tablePtr.p->tuxCustomTriggers.isEmpty())
- {
- jam();
- TuxMaintReq* req = (TuxMaintReq*)signal->getDataPtrSend();
- req->tableId = fragPtr.p->fragTableId;
- req->fragId = fragPtr.p->fragmentId;
- req->pageId = tmp.m_page_no;
- req->pageIndex = tmp.m_page_idx;
- req->tupVersion = ptr->get_tuple_version();
- req->opInfo = TuxMaintReq::OpRemove;
- removeTuxEntries(signal, tablePtr.p);
- }
-
- Local_key disk;
- memcpy(&disk, ptr->get_disk_ref_ptr(tablePtr.p), sizeof(disk));
-
- if (tablePtr.p->m_attributes[MM].m_no_of_varsize)
- {
- jam();
- free_var_rec(fragPtr.p, tablePtr.p, &tmp, pagePtr);
- } else {
- jam();
- free_fix_rec(fragPtr.p, tablePtr.p, &tmp, (Fix_page*)pagePtr.p);
- }
-
- if (tablePtr.p->m_no_of_disk_attributes)
- {
- jam();
-
- Uint32 sz = (sizeof(Dbtup::Disk_undo::Free) >> 2) +
- tablePtr.p->m_offsets[DD].m_fix_header_size - 1;
-
- int res = c_lgman->alloc_log_space(fragPtr.p->m_logfile_group_id, sz);
- ndbrequire(res == 0);
-
- /**
- * 1) alloc log buffer
- * 2) get page
- * 3) get log buffer
- * 4) delete tuple
- */
- Page_cache_client::Request preq;
- preq.m_page = disk;
- preq.m_callback.m_callbackData = senderData;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::nr_delete_page_callback);
- int flags = Page_cache_client::COMMIT_REQ;
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(4023) || ERROR_INSERTED(4024))
- {
- int rnd = rand() % 100;
- int slp = 0;
- if (ERROR_INSERTED(4024))
- {
- slp = 3000;
- }
- else if (rnd > 90)
- {
- slp = 3000;
- }
- else if (rnd > 70)
- {
- slp = 100;
- }
-
- ndbout_c("rnd: %d slp: %d", rnd, slp);
-
- if (slp)
- {
- flags |= Page_cache_client::DELAY_REQ;
- preq.m_delay_until_time = NdbTick_CurrentMillisecond()+(Uint64)slp;
- }
- }
-#endif
-
- res = m_pgman.get_page(signal, preq, flags);
- if (res == 0)
- {
- goto timeslice;
- }
- else if (unlikely(res == -1))
- {
- return -1;
- }
-
- PagePtr disk_page = *(PagePtr*)&m_pgman.m_ptr;
- disk_page_set_dirty(disk_page);
-
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::nr_delete_log_buffer_callback);
- Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
- res= lgman.get_log_buffer(signal, sz, &preq.m_callback);
- switch(res){
- case 0:
- signal->theData[2] = disk_page.i;
- goto timeslice;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- }
-
- if (0) ndbout << "DIRECT DISK DELETE: " << disk << endl;
- disk_page_free(signal, tablePtr.p, fragPtr.p,
- &disk, *(PagePtr*)&disk_page, gci);
- return 0;
- }
-
- return 0;
-
-timeslice:
- memcpy(signal->theData, &disk, sizeof(disk));
- return 1;
-}
-
-void
-Dbtup::nr_delete_page_callback(Signal* signal,
- Uint32 userpointer, Uint32 page_id)
-{
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, page_id);
- PagePtr pagePtr= *(PagePtr*)&gpage;
- disk_page_set_dirty(pagePtr);
- Dblqh::Nr_op_info op;
- op.m_ptr_i = userpointer;
- op.m_disk_ref.m_page_no = pagePtr.p->m_page_no;
- op.m_disk_ref.m_file_no = pagePtr.p->m_file_no;
- c_lqh->get_nr_op_info(&op, page_id);
-
- Ptr<Fragrecord> fragPtr;
- fragPtr.i= op.m_tup_frag_ptr_i;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- Ptr<Tablerec> tablePtr;
- tablePtr.i = fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- Uint32 sz = (sizeof(Dbtup::Disk_undo::Free) >> 2) +
- tablePtr.p->m_offsets[DD].m_fix_header_size - 1;
-
- Callback cb;
- cb.m_callbackData = userpointer;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::nr_delete_log_buffer_callback);
- Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
- int res= lgman.get_log_buffer(signal, sz, &cb);
- switch(res){
- case 0:
- return;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- }
-
- if (0) ndbout << "PAGE CALLBACK DISK DELETE: " << op.m_disk_ref << endl;
- disk_page_free(signal, tablePtr.p, fragPtr.p,
- &op.m_disk_ref, pagePtr, op.m_gci);
-
- c_lqh->nr_delete_complete(signal, &op);
- return;
-}
-
-void
-Dbtup::nr_delete_log_buffer_callback(Signal* signal,
- Uint32 userpointer,
- Uint32 unused)
-{
- Dblqh::Nr_op_info op;
- op.m_ptr_i = userpointer;
- c_lqh->get_nr_op_info(&op, RNIL);
-
- Ptr<Fragrecord> fragPtr;
- fragPtr.i= op.m_tup_frag_ptr_i;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- Ptr<Tablerec> tablePtr;
- tablePtr.i = fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- Ptr<GlobalPage> gpage;
- m_global_page_pool.getPtr(gpage, op.m_page_id);
- PagePtr pagePtr= *(PagePtr*)&gpage;
-
- /**
- * reset page no
- */
- if (0) ndbout << "LOGBUFFER CALLBACK DISK DELETE: " << op.m_disk_ref << endl;
-
- disk_page_free(signal, tablePtr.p, fragPtr.p,
- &op.m_disk_ref, pagePtr, op.m_gci);
-
- c_lqh->nr_delete_complete(signal, &op);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp
deleted file mode 100644
index 6822deb8b19..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_FIXALLOC_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-//
-// Fixed Allocator
-// This module is used to allocate and free fixed size tuples from the
-// set of pages attached to a fragment. The fixed size is preset per
-// fragment and their can only be one such value per fragment in the
-// current implementation.
-//
-// Public methods
-// bool
-// alloc_fix_rec(Fragrecord* const regFragPtr, # In
-// Tablerec* const regTabPtr, # In
-// Uint32 pageType, # In
-// Signal* signal, # In
-// Uint32& pageOffset, # Out
-// PagePtr& pagePtr) # In/Out
-// This method allocates a fixed size and the pagePtr is a reference
-// to the page and pageOffset is the offset in the page of the tuple.
-//
-// freeTh()
-// This method is used to free a tuple header in normal transaction
-// handling.
-//
-// getThAtPageSr()
-// This method is used to allocate a tuple on a set page as part of
-// undo log execution.
-//
-//
-// Private methods
-// getThAtPage()
-// This method gets a tuple from a page with free tuples.
-//
-// convertThPage()
-// Convert an empty page into a page of free tuples in a linked list.
-//
-// getEmptyPageTh()
-// A page recently taken from the set of empty pages on the fragment is
-// is made part of the set of free pages with fixed size tuples in the
-// fragment.
-//
-Uint32*
-Dbtup::alloc_fix_rec(Fragrecord* const regFragPtr,
- Tablerec* const regTabPtr,
- Local_key* key,
- Uint32 * out_frag_page_id)
-{
-/* ---------------------------------------------------------------- */
-/* EITHER NORMAL PAGE REQUESTED OR ALLOCATION FROM COPY PAGE */
-/* FAILED. TRY ALLOCATING FROM NORMAL PAGE. */
-/* ---------------------------------------------------------------- */
- PagePtr pagePtr;
- pagePtr.i = regFragPtr->thFreeFirst.firstItem;
- if (pagePtr.i == RNIL) {
-/* ---------------------------------------------------------------- */
-// No prepared tuple header page with free entries exists.
-/* ---------------------------------------------------------------- */
- pagePtr.i = getEmptyPage(regFragPtr);
- if (pagePtr.i != RNIL) {
- jam();
-/* ---------------------------------------------------------------- */
-// We found empty pages on the fragment. Allocate an empty page and
-// convert it into a tuple header page and put it in thFreeFirst-list.
-/* ---------------------------------------------------------------- */
- c_page_pool.getPtr(pagePtr);
-
- ndbassert(pagePtr.p->page_state == ZEMPTY_MM);
-
- convertThPage((Fix_page*)pagePtr.p, regTabPtr, MM);
-
- pagePtr.p->page_state = ZTH_MM_FREE;
-
- LocalDLFifoList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
- free_pages.addFirst(pagePtr);
- } else {
- jam();
-/* ---------------------------------------------------------------- */
-/* THERE ARE NO EMPTY PAGES. MEMORY CAN NOT BE ALLOCATED. */
-/* ---------------------------------------------------------------- */
- return 0;
- }
- } else {
- jam();
-/* ---------------------------------------------------------------- */
-/* THIS SHOULD BE THE COMMON PATH THROUGH THE CODE, FREE */
-/* COPY PAGE EXISTED. */
-/* ---------------------------------------------------------------- */
- c_page_pool.getPtr(pagePtr);
- }
-
- Uint32 page_offset= alloc_tuple_from_page(regFragPtr, (Fix_page*)pagePtr.p);
-
- *out_frag_page_id= pagePtr.p->frag_page_id;
- key->m_page_no = pagePtr.i;
- key->m_page_idx = page_offset;
- return pagePtr.p->m_data + page_offset;
-}
-
-void Dbtup::convertThPage(Fix_page* regPagePtr,
- Tablerec* regTabPtr,
- Uint32 mm)
-{
- Uint32 nextTuple = regTabPtr->m_offsets[mm].m_fix_header_size;
- /*
- ASSUMES AT LEAST ONE TUPLE HEADER FITS AND THEREFORE NO HANDLING
- OF ZERO AS EXTREME CASE
- */
- Uint32 cnt= 0;
- Uint32 pos= 0;
- Uint32 prev = 0xFFFF;
-#ifdef VM_TRACE
- memset(regPagePtr->m_data, 0xF1, 4*Fix_page::DATA_WORDS);
-#endif
- Uint32 gci_pos = 2;
- Uint32 gci_val = 0xF1F1F1F1;
- if (regTabPtr->m_bits & Tablerec::TR_RowGCI)
- {
- Tuple_header* ptr = 0;
- gci_pos = ptr->get_mm_gci(regTabPtr) - (Uint32*)ptr;
- gci_val = 0;
- }
- while (pos + nextTuple <= Fix_page::DATA_WORDS)
- {
- regPagePtr->m_data[pos] = (prev << 16) | (pos + nextTuple);
- regPagePtr->m_data[pos + 1] = Fix_page::FREE_RECORD;
- regPagePtr->m_data[pos + gci_pos] = gci_val;
- prev = pos;
- pos += nextTuple;
- cnt ++;
- }
-
- regPagePtr->m_data[prev] |= 0xFFFF;
- regPagePtr->next_free_index= 0;
- regPagePtr->free_space= cnt;
- regPagePtr->m_page_header.m_page_type = File_formats::PT_Tup_fixsize_page;
-}//Dbtup::convertThPage()
-
-Uint32
-Dbtup::alloc_tuple_from_page(Fragrecord* const regFragPtr,
- Fix_page* const regPagePtr)
-{
- ndbassert(regPagePtr->free_space);
- Uint32 idx= regPagePtr->alloc_record();
- if(regPagePtr->free_space == 0)
- {
- jam();
-/* ---------------------------------------------------------------- */
-/* THIS WAS THE LAST TUPLE HEADER IN THIS PAGE. REMOVE IT FROM*/
-/* THE TUPLE HEADER FREE LIST OR TH COPY FREE LIST. ALSO SET */
-/* A PROPER PAGE STATE. */
-/* */
-/* WE ALSO HAVE TO INSERT AN UNDO LOG ENTRY TO ENSURE PAGE */
-/* ARE MAINTAINED EVEN AFTER A SYSTEM CRASH. */
-/* ---------------------------------------------------------------- */
- ndbrequire(regPagePtr->page_state == ZTH_MM_FREE);
- LocalDLFifoList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
- free_pages.remove((Page*)regPagePtr);
- regPagePtr->page_state = ZTH_MM_FULL;
- }
-
- return idx;
-}//Dbtup::getThAtPage()
-
-
-void Dbtup::free_fix_rec(Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- Local_key* key,
- Fix_page* regPagePtr)
-{
- Uint32 free= regPagePtr->free_record(key->m_page_idx);
-
- if(free == 1)
- {
- jam();
- PagePtr pagePtr = { (Page*)regPagePtr, key->m_page_no };
- LocalDLFifoList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
- ndbrequire(regPagePtr->page_state == ZTH_MM_FULL);
- regPagePtr->page_state = ZTH_MM_FREE;
- free_pages.addLast(pagePtr);
- }
-}//Dbtup::freeTh()
-
-
-int
-Dbtup::alloc_page(Tablerec* tabPtrP, Fragrecord* fragPtrP,
- PagePtr * ret, Uint32 page_no)
-{
- Uint32 pages = fragPtrP->noOfPages;
-
- if (page_no >= pages)
- {
- Uint32 start = pages;
- while(page_no >= pages)
- pages += (pages >> 3) + (pages >> 4) + 2;
- allocFragPages(fragPtrP, pages - start);
- if (page_no >= (pages = fragPtrP->noOfPages))
- {
- terrorCode = ZMEM_NOMEM_ERROR;
- return 1;
- }
- }
-
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, getRealpid(fragPtrP, page_no));
-
- LocalDLList<Page> alloc_pages(c_page_pool, fragPtrP->emptyPrimPage);
- LocalDLFifoList<Page> free_pages(c_page_pool, fragPtrP->thFreeFirst);
- if (pagePtr.p->page_state == ZEMPTY_MM)
- {
- convertThPage((Fix_page*)pagePtr.p, tabPtrP, MM);
- pagePtr.p->page_state = ZTH_MM_FREE;
- alloc_pages.remove(pagePtr);
- free_pages.addFirst(pagePtr);
- }
-
- *ret = pagePtr;
- return 0;
-}
-
-Uint32*
-Dbtup::alloc_fix_rowid(Fragrecord* regFragPtr,
- Tablerec* regTabPtr,
- Local_key* key,
- Uint32 * out_frag_page_id)
-{
- Uint32 page_no = key->m_page_no;
- Uint32 idx= key->m_page_idx;
-
- PagePtr pagePtr;
- if (alloc_page(regTabPtr, regFragPtr, &pagePtr, page_no))
- {
- terrorCode = ZMEM_NOMEM_ERROR;
- return 0;
- }
-
- Uint32 state = pagePtr.p->page_state;
- LocalDLFifoList<Page> free_pages(c_page_pool, regFragPtr->thFreeFirst);
- switch(state){
- case ZTH_MM_FREE:
- if (((Fix_page*)pagePtr.p)->alloc_record(idx) != idx)
- {
- terrorCode = ZROWID_ALLOCATED;
- return 0;
- }
-
- if(pagePtr.p->free_space == 0)
- {
- jam();
- pagePtr.p->page_state = ZTH_MM_FULL;
- free_pages.remove(pagePtr);
- }
-
- *out_frag_page_id= page_no;
- key->m_page_no = pagePtr.i;
- key->m_page_idx = idx;
- return pagePtr.p->m_data + idx;
- case ZTH_MM_FULL:
- terrorCode = ZROWID_ALLOCATED;
- return 0;
- case ZEMPTY_MM:
- ndbrequire(false);
- }
- return 0; /* purify: deadcode */
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
deleted file mode 100644
index 262701b3d87..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_GEN_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <AttributeHeader.hpp>
-#include <Interpreter.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-#include <signaldata/TupCommit.hpp>
-#include <signaldata/TupKey.hpp>
-
-#include <signaldata/DropTab.hpp>
-#include <SLList.hpp>
-
-#define DEBUG(x) { ndbout << "TUP::" << x << endl; }
-
-void Dbtup::initData()
-{
- cnoOfAttrbufrec = ZNO_OF_ATTRBUFREC;
- cnoOfFragrec = MAX_FRAG_PER_NODE;
- cnoOfFragoprec = MAX_FRAG_PER_NODE;
- cnoOfPageRangeRec = ZNO_OF_PAGE_RANGE_REC;
- c_maxTriggersPerTable = ZDEFAULT_MAX_NO_TRIGGERS_PER_TABLE;
- c_noOfBuildIndexRec = 32;
-
- // Records with constant sizes
- init_list_sizes();
-}//Dbtup::initData()
-
-Dbtup::Dbtup(Block_context& ctx, Pgman* pgman)
- : SimulatedBlock(DBTUP, ctx),
- c_lqh(0),
- m_pgman(this, pgman),
- c_extent_hash(c_extent_pool),
- c_storedProcPool(),
- c_buildIndexList(c_buildIndexPool),
- c_undo_buffer(this)
-{
- BLOCK_CONSTRUCTOR(Dbtup);
-
- addRecSignal(GSN_DEBUG_SIG, &Dbtup::execDEBUG_SIG);
- addRecSignal(GSN_CONTINUEB, &Dbtup::execCONTINUEB);
- addRecSignal(GSN_LCP_FRAG_ORD, &Dbtup::execLCP_FRAG_ORD);
-
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbtup::execDUMP_STATE_ORD);
- addRecSignal(GSN_SEND_PACKED, &Dbtup::execSEND_PACKED);
- addRecSignal(GSN_ATTRINFO, &Dbtup::execATTRINFO);
- addRecSignal(GSN_STTOR, &Dbtup::execSTTOR);
- addRecSignal(GSN_MEMCHECKREQ, &Dbtup::execMEMCHECKREQ);
- addRecSignal(GSN_TUPKEYREQ, &Dbtup::execTUPKEYREQ);
- addRecSignal(GSN_TUPSEIZEREQ, &Dbtup::execTUPSEIZEREQ);
- addRecSignal(GSN_TUPRELEASEREQ, &Dbtup::execTUPRELEASEREQ);
- addRecSignal(GSN_STORED_PROCREQ, &Dbtup::execSTORED_PROCREQ);
- addRecSignal(GSN_TUPFRAGREQ, &Dbtup::execTUPFRAGREQ);
- addRecSignal(GSN_TUP_ADD_ATTRREQ, &Dbtup::execTUP_ADD_ATTRREQ);
- addRecSignal(GSN_TUP_COMMITREQ, &Dbtup::execTUP_COMMITREQ);
- addRecSignal(GSN_TUP_ABORTREQ, &Dbtup::execTUP_ABORTREQ);
- addRecSignal(GSN_NDB_STTOR, &Dbtup::execNDB_STTOR);
- addRecSignal(GSN_READ_CONFIG_REQ, &Dbtup::execREAD_CONFIG_REQ, true);
-
- // Trigger Signals
- addRecSignal(GSN_CREATE_TRIG_REQ, &Dbtup::execCREATE_TRIG_REQ);
- addRecSignal(GSN_DROP_TRIG_REQ, &Dbtup::execDROP_TRIG_REQ);
-
- addRecSignal(GSN_DROP_TAB_REQ, &Dbtup::execDROP_TAB_REQ);
-
- addRecSignal(GSN_TUP_DEALLOCREQ, &Dbtup::execTUP_DEALLOCREQ);
- addRecSignal(GSN_TUP_WRITELOG_REQ, &Dbtup::execTUP_WRITELOG_REQ);
-
- // Ordered index related
- addRecSignal(GSN_BUILDINDXREQ, &Dbtup::execBUILDINDXREQ);
-
- // Tup scan
- addRecSignal(GSN_ACC_SCANREQ, &Dbtup::execACC_SCANREQ);
- addRecSignal(GSN_NEXT_SCANREQ, &Dbtup::execNEXT_SCANREQ);
- addRecSignal(GSN_ACC_CHECK_SCAN, &Dbtup::execACC_CHECK_SCAN);
- addRecSignal(GSN_ACCKEYCONF, &Dbtup::execACCKEYCONF);
- addRecSignal(GSN_ACCKEYREF, &Dbtup::execACCKEYREF);
- addRecSignal(GSN_ACC_ABORTCONF, &Dbtup::execACC_ABORTCONF);
-
- // Drop table
- addRecSignal(GSN_FSREMOVEREF, &Dbtup::execFSREMOVEREF, true);
- addRecSignal(GSN_FSREMOVECONF, &Dbtup::execFSREMOVECONF, true);
-
- attrbufrec = 0;
- fragoperrec = 0;
- fragrecord = 0;
- hostBuffer = 0;
- pageRange = 0;
- tablerec = 0;
- tableDescriptor = 0;
- totNoOfPagesAllocated = 0;
- cnoOfAllocatedPages = 0;
-
- initData();
- CLEAR_ERROR_INSERT_VALUE;
-}//Dbtup::Dbtup()
-
-Dbtup::~Dbtup()
-{
- // Records with dynamic sizes
- deallocRecord((void **)&attrbufrec,"Attrbufrec",
- sizeof(Attrbufrec),
- cnoOfAttrbufrec);
-
- deallocRecord((void **)&fragoperrec,"Fragoperrec",
- sizeof(Fragoperrec),
- cnoOfFragoprec);
-
- deallocRecord((void **)&fragrecord,"Fragrecord",
- sizeof(Fragrecord),
- cnoOfFragrec);
-
- deallocRecord((void **)&hostBuffer,"HostBuffer",
- sizeof(HostBuffer),
- MAX_NODES);
-
- deallocRecord((void **)&pageRange,"PageRange",
- sizeof(PageRange),
- cnoOfPageRangeRec);
-
- deallocRecord((void **)&tablerec,"Tablerec",
- sizeof(Tablerec),
- cnoOfTablerec);
-
- deallocRecord((void **)&tableDescriptor, "TableDescriptor",
- sizeof(TableDescriptor),
- cnoOfTabDescrRec);
-
-}//Dbtup::~Dbtup()
-
-BLOCK_FUNCTIONS(Dbtup)
-
-void Dbtup::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- Uint32 actionType = signal->theData[0];
- Uint32 dataPtr = signal->theData[1];
- switch (actionType) {
- case ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal, dataPtr,
- signal->theData[2], signal->theData[3]);
- break;
- case ZREL_FRAG:
- jam();
- releaseFragment(signal, dataPtr, signal->theData[2]);
- break;
- case ZREPORT_MEMORY_USAGE:{
- jam();
- static int c_currentMemUsed = 0;
- Uint32 cnt = signal->theData[1];
- Uint32 tmp = c_page_pool.getSize();
- int now = tmp ? (cnoOfAllocatedPages * 100)/tmp : 0;
- const int thresholds[] = { 100, 90, 80, 0 };
-
- Uint32 i = 0;
- const Uint32 sz = sizeof(thresholds)/sizeof(thresholds[0]);
- for(i = 0; i<sz; i++){
- if(now >= thresholds[i]){
- now = thresholds[i];
- break;
- }
- }
-
- if(now != c_currentMemUsed ||
- (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency))
- {
- reportMemoryUsage(signal,
- now > c_currentMemUsed ? 1 :
- now < c_currentMemUsed ? -1 : 0);
- cnt = 0;
- c_currentMemUsed = now;
- }
- else
- {
- cnt++;
- }
- signal->theData[0] = ZREPORT_MEMORY_USAGE;
- signal->theData[1] = cnt;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
- return;
- }
- case ZBUILD_INDEX:
- jam();
- buildIndex(signal, dataPtr);
- break;
- case ZTUP_SCAN:
- jam();
- {
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, dataPtr);
- scanCont(signal, scanPtr);
- }
- return;
- case ZFREE_EXTENT:
- {
- jam();
-
- TablerecPtr tabPtr;
- tabPtr.i= dataPtr;
- FragrecordPtr fragPtr;
- fragPtr.i= signal->theData[2];
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- drop_fragment_free_extent(signal, tabPtr, fragPtr, signal->theData[3]);
- return;
- }
- case ZUNMAP_PAGES:
- {
- jam();
-
- TablerecPtr tabPtr;
- tabPtr.i= dataPtr;
- FragrecordPtr fragPtr;
- fragPtr.i= signal->theData[2];
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- drop_fragment_unmap_pages(signal, tabPtr, fragPtr, signal->theData[3]);
- return;
- }
- case ZFREE_VAR_PAGES:
- {
- jam();
- drop_fragment_free_var_pages(signal);
- return;
- }
- default:
- ndbrequire(false);
- break;
- }//switch
-}//Dbtup::execTUP_CONTINUEB()
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* ------------------- SYSTEM RESTART MODULE ---------------------- */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-void Dbtup::execSTTOR(Signal* signal)
-{
- jamEntry();
- Uint32 startPhase = signal->theData[1];
- Uint32 sigKey = signal->theData[6];
- switch (startPhase) {
- case ZSTARTPHASE1:
- jam();
- ndbrequire((c_lqh= (Dblqh*)globalData.getBlock(DBLQH)) != 0);
- ndbrequire((c_tsman= (Tsman*)globalData.getBlock(TSMAN)) != 0);
- ndbrequire((c_lgman= (Lgman*)globalData.getBlock(LGMAN)) != 0);
- cownref = calcTupBlockRef(0);
- break;
- default:
- jam();
- break;
- }//switch
- signal->theData[0] = sigKey;
- signal->theData[1] = 3;
- signal->theData[2] = 2;
- signal->theData[3] = ZSTARTPHASE1;
- signal->theData[4] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- return;
-}//Dbtup::execSTTOR()
-
-/************************************************************************************************/
-// SIZE_ALTREP INITIALIZE DATA STRUCTURES, FILES AND DS VARIABLES, GET READY FOR EXTERNAL
-// CONNECTIONS.
-/************************************************************************************************/
-void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
-{
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
- ndbrequire(req->noOfParameters == 0);
-
- jamEntry();
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec));
-
- Uint32 noOfTriggers= 0;
-
- Uint32 tmp= 0;
-
- if (ndb_mgm_get_int_parameter(p, CFG_DB_MAX_ALLOCATE, &tmp))
- tmp = 32 * 1024 * 1024;
- m_max_allocate_pages = (tmp + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE;
-
- tmp = 0;
- 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));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS,
- &noOfTriggers));
-
- cnoOfTabDescrRec = (cnoOfTabDescrRec & 0xFFFFFFF0) + 16;
-
- initRecords();
-
- c_storedProcPool.setSize(noOfStoredProc);
- c_buildIndexPool.setSize(c_noOfBuildIndexRec);
- c_triggerPool.setSize(noOfTriggers, false, true, true, CFG_DB_NO_TRIGGERS);
-
- c_extent_hash.setSize(1024); // 4k
-
- Pool_context pc;
- pc.m_block = this;
- c_page_request_pool.wo_pool_init(RT_DBTUP_PAGE_REQUEST, pc);
- c_extent_pool.init(RT_DBTUP_EXTENT_INFO, pc);
-
- Uint32 nScanOp; // use TUX config for now
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
- c_scanOpPool.setSize(nScanOp + 1);
- Uint32 nScanBatch;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch));
- c_scanLockPool.setSize(nScanOp * nScanBatch);
-
-
- /* read ahead for disk scan can not be more that disk page buffer */
- {
- Uint64 tmp = 64*1024*1024;
- ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &tmp);
- m_max_page_read_ahead = (tmp + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; // in pages
- // never read ahead more than 32 pages
- if (m_max_page_read_ahead > 32)
- m_max_page_read_ahead = 32;
- }
-
-
- ScanOpPtr lcp;
- ndbrequire(c_scanOpPool.seize(lcp));
- new (lcp.p) ScanOp();
- c_lcp_scan_op= lcp.i;
-
- czero = 0;
- cminusOne = czero - 1;
- clastBitMask = 1;
- clastBitMask = clastBitMask << 31;
-
- c_memusage_report_frequency = 0;
- ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY,
- &c_memusage_report_frequency);
-
- initialiseRecordsLab(signal, 0, ref, senderData);
-}//Dbtup::execSIZEALT_REP()
-
-void Dbtup::initRecords()
-{
- unsigned i;
- Uint32 tmp;
- Uint32 tmp1 = 0;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp));
-
- // Records with dynamic sizes
- Page* ptr =(Page*)allocRecord("Page", sizeof(Page), tmp, false, CFG_DB_DATA_MEM);
- c_page_pool.set(ptr, tmp);
-
- attrbufrec = (Attrbufrec*)allocRecord("Attrbufrec",
- sizeof(Attrbufrec),
- cnoOfAttrbufrec);
-
- fragoperrec = (Fragoperrec*)allocRecord("Fragoperrec",
- sizeof(Fragoperrec),
- cnoOfFragoprec);
-
- fragrecord = (Fragrecord*)allocRecord("Fragrecord",
- sizeof(Fragrecord),
- cnoOfFragrec);
-
- hostBuffer = (HostBuffer*)allocRecord("HostBuffer",
- sizeof(HostBuffer),
- MAX_NODES);
-
- tableDescriptor = (TableDescriptor*)allocRecord("TableDescriptor",
- sizeof(TableDescriptor),
- cnoOfTabDescrRec);
-
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &tmp));
- ndb_mgm_get_int_parameter(p, CFG_DB_NO_LOCAL_OPS, &tmp1);
- c_operation_pool.setSize(tmp, false, true, true,
- tmp1 == 0 ? CFG_DB_NO_OPS : CFG_DB_NO_LOCAL_OPS);
-
- pageRange = (PageRange*)allocRecord("PageRange",
- sizeof(PageRange),
- cnoOfPageRangeRec);
-
- tablerec = (Tablerec*)allocRecord("Tablerec",
- sizeof(Tablerec),
- cnoOfTablerec);
-
- for (i = 0; i<cnoOfTablerec; i++) {
- void * p = &tablerec[i];
- new (p) Tablerec(c_triggerPool);
- }
-}//Dbtup::initRecords()
-
-void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData,
- Uint32 retRef, Uint32 retData)
-{
- switch (switchData) {
- case 0:
- jam();
- initializeHostBuffer();
- break;
- case 1:
- jam();
- initializeOperationrec();
- break;
- case 2:
- jam();
- initializePage();
- break;
- case 3:
- jam();
- break;
- case 4:
- jam();
- initializeTablerec();
- break;
- case 5:
- jam();
- break;
- case 6:
- jam();
- initializeFragrecord();
- break;
- case 7:
- jam();
- initializeFragoperrec();
- break;
- case 8:
- jam();
- initializePageRange();
- break;
- case 9:
- jam();
- initializeTabDescr();
- break;
- case 10:
- jam();
- break;
- case 11:
- jam();
- break;
- case 12:
- jam();
- initializeAttrbufrec();
- break;
- case 13:
- jam();
- break;
- case 14:
- jam();
-
- {
- 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
- signal->theData[0] = ZINITIALISE_RECORDS;
- signal->theData[1] = switchData + 1;
- signal->theData[2] = retRef;
- signal->theData[3] = retData;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- return;
-}//Dbtup::initialiseRecordsLab()
-
-void Dbtup::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
- cndbcntrRef = signal->theData[0];
- Uint32 ownNodeId = signal->theData[1];
- Uint32 startPhase = signal->theData[2];
- switch (startPhase) {
- case ZSTARTPHASE1:
- jam();
- cownNodeId = ownNodeId;
- cownref = calcTupBlockRef(ownNodeId);
- break;
- case ZSTARTPHASE2:
- jam();
- break;
- case ZSTARTPHASE3:
- jam();
- startphase3Lab(signal, ~0, ~0);
- break;
- case ZSTARTPHASE4:
- jam();
- break;
- case ZSTARTPHASE6:
- jam();
-/*****************************************/
-/* NOW SET THE DISK WRITE SPEED TO */
-/* PAGES PER TICK AFTER SYSTEM */
-/* RESTART. */
-/*****************************************/
- signal->theData[0] = ZREPORT_MEMORY_USAGE;
- signal->theData[1] = 0;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
- break;
- default:
- jam();
- break;
- }//switch
- signal->theData[0] = cownref;
- sendSignal(cndbcntrRef, GSN_NDB_STTORRY, signal, 1, JBB);
-}//Dbtup::execNDB_STTOR()
-
-void Dbtup::startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2)
-{
-}//Dbtup::startphase3Lab()
-
-void Dbtup::initializeAttrbufrec()
-{
- AttrbufrecPtr attrBufPtr;
- for (attrBufPtr.i = 0;
- attrBufPtr.i < cnoOfAttrbufrec; attrBufPtr.i++) {
- refresh_watch_dog();
- ptrAss(attrBufPtr, attrbufrec);
- attrBufPtr.p->attrbuf[ZBUF_NEXT] = attrBufPtr.i + 1;
- }//for
- attrBufPtr.i = cnoOfAttrbufrec - 1;
- ptrAss(attrBufPtr, attrbufrec);
- attrBufPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
- cfirstfreeAttrbufrec = 0;
- cnoFreeAttrbufrec = cnoOfAttrbufrec;
-}//Dbtup::initializeAttrbufrec()
-
-void Dbtup::initializeFragoperrec()
-{
- FragoperrecPtr fragoperPtr;
- for (fragoperPtr.i = 0; fragoperPtr.i < cnoOfFragoprec; fragoperPtr.i++) {
- ptrAss(fragoperPtr, fragoperrec);
- fragoperPtr.p->nextFragoprec = fragoperPtr.i + 1;
- }//for
- fragoperPtr.i = cnoOfFragoprec - 1;
- ptrAss(fragoperPtr, fragoperrec);
- fragoperPtr.p->nextFragoprec = RNIL;
- cfirstfreeFragopr = 0;
-}//Dbtup::initializeFragoperrec()
-
-void Dbtup::initializeFragrecord()
-{
- FragrecordPtr regFragPtr;
- for (regFragPtr.i = 0; regFragPtr.i < cnoOfFragrec; regFragPtr.i++) {
- refresh_watch_dog();
- ptrAss(regFragPtr, fragrecord);
- new (regFragPtr.p) Fragrecord();
- regFragPtr.p->nextfreefrag = regFragPtr.i + 1;
- regFragPtr.p->fragStatus = IDLE;
- }//for
- regFragPtr.i = cnoOfFragrec - 1;
- ptrAss(regFragPtr, fragrecord);
- regFragPtr.p->nextfreefrag = RNIL;
- cfirstfreefrag = 0;
-}//Dbtup::initializeFragrecord()
-
-void Dbtup::initializeHostBuffer()
-{
- Uint32 hostId;
- cpackedListIndex = 0;
- for (hostId = 0; hostId < MAX_NODES; hostId++) {
- hostBuffer[hostId].inPackedList = false;
- hostBuffer[hostId].noOfPacketsTA = 0;
- hostBuffer[hostId].packetLenTA = 0;
- }//for
-}//Dbtup::initializeHostBuffer()
-
-
-void Dbtup::initializeOperationrec()
-{
- refresh_watch_dog();
-}//Dbtup::initializeOperationrec()
-
-void Dbtup::initializeTablerec()
-{
- TablerecPtr regTabPtr;
- for (regTabPtr.i = 0; regTabPtr.i < cnoOfTablerec; regTabPtr.i++) {
- jam();
- refresh_watch_dog();
- ptrAss(regTabPtr, tablerec);
- initTab(regTabPtr.p);
- }//for
-}//Dbtup::initializeTablerec()
-
-void
-Dbtup::initTab(Tablerec* const regTabPtr)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- regTabPtr->fragid[i] = RNIL;
- regTabPtr->fragrec[i] = RNIL;
- }//for
- regTabPtr->readFunctionArray = NULL;
- regTabPtr->updateFunctionArray = NULL;
- regTabPtr->charsetArray = NULL;
-
- regTabPtr->tabDescriptor = RNIL;
- regTabPtr->readKeyArray = RNIL;
-
- regTabPtr->m_bits = 0;
-
- regTabPtr->m_no_of_attributes = 0;
- regTabPtr->noOfKeyAttr = 0;
-
- regTabPtr->m_dropTable.tabUserPtr = RNIL;
- regTabPtr->m_dropTable.tabUserRef = 0;
- regTabPtr->tableStatus = NOT_DEFINED;
-
- // Clear trigger data
- if (!regTabPtr->afterInsertTriggers.isEmpty())
- regTabPtr->afterInsertTriggers.release();
- if (!regTabPtr->afterDeleteTriggers.isEmpty())
- regTabPtr->afterDeleteTriggers.release();
- if (!regTabPtr->afterUpdateTriggers.isEmpty())
- regTabPtr->afterUpdateTriggers.release();
- if (!regTabPtr->subscriptionInsertTriggers.isEmpty())
- regTabPtr->subscriptionInsertTriggers.release();
- if (!regTabPtr->subscriptionDeleteTriggers.isEmpty())
- regTabPtr->subscriptionDeleteTriggers.release();
- if (!regTabPtr->subscriptionUpdateTriggers.isEmpty())
- regTabPtr->subscriptionUpdateTriggers.release();
- if (!regTabPtr->constraintUpdateTriggers.isEmpty())
- regTabPtr->constraintUpdateTriggers.release();
- if (!regTabPtr->tuxCustomTriggers.isEmpty())
- regTabPtr->tuxCustomTriggers.release();
-}//Dbtup::initTab()
-
-void Dbtup::initializeTabDescr()
-{
- TableDescriptorPtr regTabDesPtr;
- for (Uint32 i = 0; i < 16; i++) {
- cfreeTdList[i] = RNIL;
- }//for
- for (regTabDesPtr.i = 0; regTabDesPtr.i < cnoOfTabDescrRec; regTabDesPtr.i++) {
- refresh_watch_dog();
- ptrAss(regTabDesPtr, tableDescriptor);
- regTabDesPtr.p->tabDescr = RNIL;
- }//for
- freeTabDescr(0, cnoOfTabDescrRec);
-}//Dbtup::initializeTabDescr()
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-/* --------------- CONNECT/DISCONNECT MODULE ---------------------- */
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-void Dbtup::execTUPSEIZEREQ(Signal* signal)
-{
- OperationrecPtr regOperPtr;
- jamEntry();
- Uint32 userPtr = signal->theData[0];
- BlockReference userRef = signal->theData[1];
- if (!c_operation_pool.seize(regOperPtr))
- {
- jam();
- signal->theData[0] = userPtr;
- signal->theData[1] = ZGET_OPREC_ERROR;
- sendSignal(userRef, GSN_TUPSEIZEREF, signal, 2, JBB);
- return;
- }//if
-
- new (regOperPtr.p) Operationrec();
- regOperPtr.p->firstAttrinbufrec = RNIL;
- regOperPtr.p->lastAttrinbufrec = RNIL;
- regOperPtr.p->m_any_value = 0;
- regOperPtr.p->op_struct.op_type = ZREAD;
- regOperPtr.p->op_struct.in_active_list = false;
- set_trans_state(regOperPtr.p, TRANS_DISCONNECTED);
- regOperPtr.p->storedProcedureId = ZNIL;
- regOperPtr.p->prevActiveOp = RNIL;
- regOperPtr.p->nextActiveOp = RNIL;
- regOperPtr.p->tupVersion = ZNIL;
- regOperPtr.p->op_struct.delete_insert_flag = false;
-
- initOpConnection(regOperPtr.p);
- regOperPtr.p->userpointer = userPtr;
- signal->theData[0] = regOperPtr.p->userpointer;
- signal->theData[1] = regOperPtr.i;
- sendSignal(userRef, GSN_TUPSEIZECONF, signal, 2, JBB);
- return;
-}//Dbtup::execTUPSEIZEREQ()
-
-#define printFragment(t){ for(Uint32 i = 0; i < MAX_FRAG_PER_NODE;i++){\
- ndbout_c("table = %d fragid[%d] = %d fragrec[%d] = %d", \
- t.i, t.p->fragid[i], i, t.p->fragrec[i]); }}
-
-void Dbtup::execTUPRELEASEREQ(Signal* signal)
-{
- OperationrecPtr regOperPtr;
- jamEntry();
- regOperPtr.i = signal->theData[0];
- c_operation_pool.getPtr(regOperPtr);
- set_trans_state(regOperPtr.p, TRANS_DISCONNECTED);
- c_operation_pool.release(regOperPtr);
-
- signal->theData[0] = regOperPtr.p->userpointer;
- sendSignal(DBLQH_REF, GSN_TUPRELEASECONF, signal, 1, JBB);
- return;
-}//Dbtup::execTUPRELEASEREQ()
-
-void Dbtup::releaseFragrec(FragrecordPtr regFragPtr)
-{
- regFragPtr.p->nextfreefrag = cfirstfreefrag;
- cfirstfreefrag = regFragPtr.i;
-}//Dbtup::releaseFragrec()
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
deleted file mode 100644
index 51235a30939..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_INDEX_CPP
-#include <Dblqh.hpp>
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <AttributeHeader.hpp>
-#include <signaldata/TuxMaint.hpp>
-
-// methods used by ordered index
-
-void
-Dbtup::tuxGetTupAddr(Uint32 fragPtrI,
- Uint32 pageId,
- Uint32 pageIndex,
- Uint32& tupAddr)
-{
- jamEntry();
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, pageId);
- Uint32 fragPageId= pagePtr.p->frag_page_id;
- tupAddr= (fragPageId << MAX_TUPLES_BITS) | pageIndex;
-}
-
-int
-Dbtup::tuxAllocNode(Signal* signal,
- Uint32 fragPtrI,
- Uint32& pageId,
- Uint32& pageOffset,
- Uint32*& node)
-{
- jamEntry();
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- terrorCode= 0;
-
- Local_key key;
- Uint32* ptr, frag_page_id;
- if ((ptr= alloc_fix_rec(fragPtr.p, tablePtr.p, &key, &frag_page_id)) == 0)
- {
- jam();
- terrorCode = ZMEM_NOMEM_ERROR; // caller sets error
- return terrorCode;
- }
- pageId= key.m_page_no;
- pageOffset= key.m_page_idx;
- Uint32 attrDescIndex= tablePtr.p->tabDescriptor + (0 << ZAD_LOG_SIZE);
- Uint32 attrDataOffset= AttributeOffset::getOffset(
- tableDescriptor[attrDescIndex + 1].tabDescr);
- node= ptr + attrDataOffset;
- return 0;
-}
-
-#if 0
-void
-Dbtup::tuxFreeNode(Signal* signal,
- Uint32 fragPtrI,
- Uint32 pageId,
- Uint32 pageOffset,
- Uint32* node)
-{
- jamEntry();
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- PagePtr pagePtr;
- pagePtr.i= pageId;
- ptrCheckGuard(pagePtr, cnoOfPage, cpage);
- Uint32 attrDescIndex= tablePtr.p->tabDescriptor + (0 << ZAD_LOG_SIZE);
- Uint32 attrDataOffset= AttributeOffset::getOffset(tableDescriptor[attrDescIndex + 1].tabDescr);
- ndbrequire(node == &pagePtr.p->pageWord[pageOffset] + attrDataOffset);
- freeTh(fragPtr.p, tablePtr.p, signal, pagePtr.p, pageOffset);
-}
-#endif
-
-void
-Dbtup::tuxGetNode(Uint32 fragPtrI,
- Uint32 pageId,
- Uint32 pageOffset,
- Uint32*& node)
-{
- jamEntry();
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, pageId);
- Uint32 attrDescIndex= tablePtr.p->tabDescriptor + (0 << ZAD_LOG_SIZE);
- Uint32 attrDataOffset= AttributeOffset::getOffset(
- tableDescriptor[attrDescIndex + 1].tabDescr);
- node= ((Fix_page*)pagePtr.p)->
- get_ptr(pageOffset, tablePtr.p->m_offsets[MM].m_fix_header_size) +
- attrDataOffset;
-}
-int
-Dbtup::tuxReadAttrs(Uint32 fragPtrI,
- Uint32 pageId,
- Uint32 pageIndex,
- Uint32 tupVersion,
- const Uint32* attrIds,
- Uint32 numAttrs,
- Uint32* dataOut)
-{
- jamEntry();
- // use own variables instead of globals
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- // search for tuple version if not original
-
- Operationrec tmpOp;
- KeyReqStruct req_struct;
- tmpOp.m_tuple_location.m_page_no= pageId;
- tmpOp.m_tuple_location.m_page_idx= pageIndex;
-
- setup_fixed_part(&req_struct, &tmpOp, tablePtr.p);
- Tuple_header *tuple_ptr= req_struct.m_tuple_ptr;
- if (tuple_ptr->get_tuple_version() != tupVersion)
- {
- jam();
- OperationrecPtr opPtr;
- opPtr.i= tuple_ptr->m_operation_ptr_i;
- Uint32 loopGuard= 0;
- while (opPtr.i != RNIL) {
- c_operation_pool.getPtr(opPtr);
- if (opPtr.p->tupVersion == tupVersion) {
- jam();
- if (!opPtr.p->m_copy_tuple_location.isNull()) {
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtr.p->m_copy_tuple_location);
- }
- break;
- }
- jam();
- opPtr.i= opPtr.p->prevActiveOp;
- ndbrequire(++loopGuard < (1 << ZTUP_VERSION_BITS));
- }
- }
- // read key attributes from found tuple version
- // save globals
- TablerecPtr tabptr_old= tabptr;
- FragrecordPtr fragptr_old= fragptr;
- OperationrecPtr operPtr_old= operPtr;
- // new globals
- tabptr= tablePtr;
- fragptr= fragPtr;
- operPtr.i= RNIL;
- operPtr.p= NULL;
- prepare_read(&req_struct, tablePtr.p, false);
-
- // do it
- int ret = readAttributes(&req_struct,
- attrIds,
- numAttrs,
- dataOut,
- ZNIL,
- true);
-
- // restore globals
- tabptr= tabptr_old;
- fragptr= fragptr_old;
- operPtr= operPtr_old;
- // done
- if (ret == -1) {
- ret = terrorCode ? (-(int)terrorCode) : -1;
- }
- return ret;
-}
-int
-Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag)
-{
- jamEntry();
- // use own variables instead of globals
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- Operationrec tmpOp;
- tmpOp.m_tuple_location.m_page_no= pageId;
- tmpOp.m_tuple_location.m_page_idx= pageIndex;
-
- KeyReqStruct req_struct;
-
- PagePtr page_ptr;
- Uint32* ptr= get_ptr(&page_ptr, &tmpOp.m_tuple_location, tablePtr.p);
- req_struct.m_page_ptr = page_ptr;
- req_struct.m_tuple_ptr = (Tuple_header*)ptr;
-
- int ret = 0;
- if (! (req_struct.m_tuple_ptr->m_header_bits & Tuple_header::FREE))
- {
- req_struct.check_offset[MM]= tablePtr.p->get_check_offset(MM);
- req_struct.check_offset[DD]= tablePtr.p->get_check_offset(DD);
-
- Uint32 num_attr= tablePtr.p->m_no_of_attributes;
- Uint32 descr_start= tablePtr.p->tabDescriptor;
- TableDescriptor *tab_descr= &tableDescriptor[descr_start];
- ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
- req_struct.attr_descr= tab_descr;
-
- if(req_struct.m_tuple_ptr->m_header_bits & Tuple_header::ALLOC)
- {
- Uint32 opPtrI= req_struct.m_tuple_ptr->m_operation_ptr_i;
- Operationrec* opPtrP= c_operation_pool.getPtr(opPtrI);
- ndbassert(!opPtrP->m_copy_tuple_location.isNull());
- req_struct.m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&opPtrP->m_copy_tuple_location);
- }
- prepare_read(&req_struct, tablePtr.p, false);
-
- const Uint32* attrIds= &tableDescriptor[tablePtr.p->readKeyArray].tabDescr;
- const Uint32 numAttrs= tablePtr.p->noOfKeyAttr;
- // read pk attributes from original tuple
-
- // save globals
- TablerecPtr tabptr_old= tabptr;
- FragrecordPtr fragptr_old= fragptr;
- OperationrecPtr operPtr_old= operPtr;
-
- // new globals
- tabptr= tablePtr;
- fragptr= fragPtr;
- operPtr.i= RNIL;
- operPtr.p= NULL;
-
- // do it
- ret = readAttributes(&req_struct,
- attrIds,
- numAttrs,
- dataOut,
- ZNIL,
- xfrmFlag);
- // restore globals
- tabptr= tabptr_old;
- fragptr= fragptr_old;
- operPtr= operPtr_old;
- // done
- if (ret != -1) {
- // remove headers
- Uint32 n= 0;
- Uint32 i= 0;
- while (n < numAttrs) {
- const AttributeHeader ah(dataOut[i]);
- Uint32 size= ah.getDataSize();
- ndbrequire(size != 0);
- for (Uint32 j= 0; j < size; j++) {
- dataOut[i + j - n]= dataOut[i + j + 1];
- }
- n+= 1;
- i+= 1 + size;
- }
- ndbrequire((int)i == ret);
- ret -= numAttrs;
- } else {
- ret= terrorCode ? (-(int)terrorCode) : -1;
- }
- }
- if (tablePtr.p->m_bits & Tablerec::TR_RowGCI)
- {
- dataOut[ret] = *req_struct.m_tuple_ptr->get_mm_gci(tablePtr.p);
- }
- else
- {
- dataOut[ret] = 0;
- }
- return ret;
-}
-
-int
-Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag)
-{
- jamEntry();
- // get table
- TablerecPtr tablePtr;
- tablePtr.i = tableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- // get fragment
- FragrecordPtr fragPtr;
- getFragmentrec(fragPtr, fragId, tablePtr.p);
- // get real page id and tuple offset
-
- Uint32 pageId = getRealpid(fragPtr.p, fragPageId);
- // use TUX routine - optimize later
- int ret = tuxReadPk(fragPtr.i, pageId, pageIndex, dataOut, xfrmFlag);
- return ret;
-}
-
-/*
- * TUX index contains all tuple versions. A scan in TUX has scanned
- * one of them and asks if it can be returned as scan result. This
- * depends on trans id, dirty read flag, and savepoint within trans.
- *
- * Previously this faked a ZREAD operation and used getPage().
- * In TUP getPage() is run after ACC locking, but TUX comes here
- * before ACC access. Instead of modifying getPage() it is more
- * clear to do the full check here.
- */
-bool
-Dbtup::tuxQueryTh(Uint32 fragPtrI,
- Uint32 pageId,
- Uint32 pageIndex,
- Uint32 tupVersion,
- Uint32 transId1,
- Uint32 transId2,
- bool dirty,
- Uint32 savepointId)
-{
- jamEntry();
- FragrecordPtr fragPtr;
- fragPtr.i= fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- TablerecPtr tablePtr;
- tablePtr.i= fragPtr.p->fragTableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- PagePtr pagePtr;
- pagePtr.i = pageId;
- c_page_pool.getPtr(pagePtr);
-
- KeyReqStruct req_struct;
-
- {
- Operationrec tmpOp;
- tmpOp.m_tuple_location.m_page_no = pageId;
- tmpOp.m_tuple_location.m_page_idx = pageIndex;
- setup_fixed_part(&req_struct, &tmpOp, tablePtr.p);
- }
-
- Tuple_header* tuple_ptr = req_struct.m_tuple_ptr;
-
- OperationrecPtr currOpPtr;
- currOpPtr.i = tuple_ptr->m_operation_ptr_i;
- if (currOpPtr.i == RNIL) {
- jam();
- // tuple has no operation, any scan can see it
- return true;
- }
- c_operation_pool.getPtr(currOpPtr);
-
- const bool sameTrans =
- c_lqh->is_same_trans(currOpPtr.p->userpointer, transId1, transId2);
-
- bool res = false;
- OperationrecPtr loopOpPtr = currOpPtr;
-
- if (!sameTrans) {
- jam();
- if (!dirty) {
- jam();
- if (currOpPtr.p->nextActiveOp == RNIL) {
- jam();
- // last op - TUX makes ACC lock request in same timeslice
- res = true;
- }
- }
- else {
- // loop to first op (returns false)
- find_savepoint(loopOpPtr, 0);
- const Uint32 op_type = loopOpPtr.p->op_struct.op_type;
-
- if (op_type != ZINSERT) {
- jam();
- // read committed version
- const Uint32 origVersion = tuple_ptr->get_tuple_version();
- if (origVersion == tupVersion) {
- jam();
- res = true;
- }
- }
- }
- }
- else {
- jam();
- // for own trans, ignore dirty flag
-
- if (find_savepoint(loopOpPtr, savepointId)) {
- jam();
- const Uint32 op_type = loopOpPtr.p->op_struct.op_type;
-
- if (op_type != ZDELETE) {
- jam();
- // check if this op has produced the scanned version
- Uint32 loopVersion = loopOpPtr.p->tupVersion;
- if (loopVersion == tupVersion) {
- jam();
- res = true;
- }
- }
- }
- }
-
- return res;
-}
-
-// ordered index build
-
-//#define TIME_MEASUREMENT
-#ifdef TIME_MEASUREMENT
- static Uint32 time_events;
- NDB_TICKS tot_time_passed;
- Uint32 number_events;
-#endif
-void
-Dbtup::execBUILDINDXREQ(Signal* signal)
-{
- jamEntry();
-#ifdef TIME_MEASUREMENT
- time_events= 0;
- tot_time_passed= 0;
- number_events= 1;
-#endif
- // get new operation
- BuildIndexPtr buildPtr;
- if (! c_buildIndexList.seize(buildPtr)) {
- jam();
- BuildIndexRec buildRec;
- memcpy(buildRec.m_request, signal->theData, sizeof(buildRec.m_request));
- buildRec.m_errorCode= BuildIndxRef::Busy;
- buildIndexReply(signal, &buildRec);
- return;
- }
- memcpy(buildPtr.p->m_request,
- signal->theData,
- sizeof(buildPtr.p->m_request));
- // check
- buildPtr.p->m_errorCode= BuildIndxRef::NoError;
- do {
- const BuildIndxReq* buildReq= (const BuildIndxReq*)buildPtr.p->m_request;
- if (buildReq->getTableId() >= cnoOfTablerec) {
- jam();
- buildPtr.p->m_errorCode= BuildIndxRef::InvalidPrimaryTable;
- break;
- }
- TablerecPtr tablePtr;
- tablePtr.i= buildReq->getTableId();
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- if (tablePtr.p->tableStatus != DEFINED) {
- jam();
- buildPtr.p->m_errorCode= BuildIndxRef::InvalidPrimaryTable;
- break;
- }
- // memory page format
- buildPtr.p->m_build_vs =
- tablePtr.p->m_attributes[MM].m_no_of_varsize > 0;
- if (DictTabInfo::isOrderedIndex(buildReq->getIndexType())) {
- jam();
- const DLList<TupTriggerData>& triggerList =
- tablePtr.p->tuxCustomTriggers;
-
- TriggerPtr triggerPtr;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != RNIL) {
- if (triggerPtr.p->indexId == buildReq->getIndexId()) {
- jam();
- break;
- }
- triggerList.next(triggerPtr);
- }
- if (triggerPtr.i == RNIL) {
- jam();
- // trigger was not created
- buildPtr.p->m_errorCode = BuildIndxRef::InternalError;
- break;
- }
- buildPtr.p->m_indexId = buildReq->getIndexId();
- buildPtr.p->m_buildRef = DBTUX;
- } else if(buildReq->getIndexId() == RNIL) {
- jam();
- // REBUILD of acc
- buildPtr.p->m_indexId = RNIL;
- buildPtr.p->m_buildRef = DBACC;
- } else {
- jam();
- buildPtr.p->m_errorCode = BuildIndxRef::InvalidIndexType;
- break;
- }
-
- // set to first tuple position
- const Uint32 firstTupleNo = 0;
- buildPtr.p->m_fragNo= 0;
- buildPtr.p->m_pageId= 0;
- buildPtr.p->m_tupleNo= firstTupleNo;
- // start build
- buildIndex(signal, buildPtr.i);
- return;
- } while (0);
- // check failed
- buildIndexReply(signal, buildPtr.p);
- c_buildIndexList.release(buildPtr);
-}
-
-void
-Dbtup::buildIndex(Signal* signal, Uint32 buildPtrI)
-{
- // get build record
- BuildIndexPtr buildPtr;
- buildPtr.i= buildPtrI;
- c_buildIndexList.getPtr(buildPtr);
- const BuildIndxReq* buildReq= (const BuildIndxReq*)buildPtr.p->m_request;
- // get table
- TablerecPtr tablePtr;
- tablePtr.i= buildReq->getTableId();
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- const Uint32 firstTupleNo = 0;
- const Uint32 tupheadsize = tablePtr.p->m_offsets[MM].m_fix_header_size;
-
-#ifdef TIME_MEASUREMENT
- MicroSecondTimer start;
- MicroSecondTimer stop;
- NDB_TICKS time_passed;
-#endif
- do {
- // get fragment
- FragrecordPtr fragPtr;
- if (buildPtr.p->m_fragNo == MAX_FRAG_PER_NODE) {
- jam();
- // build ready
- buildIndexReply(signal, buildPtr.p);
- c_buildIndexList.release(buildPtr);
- return;
- }
- ndbrequire(buildPtr.p->m_fragNo < MAX_FRAG_PER_NODE);
- fragPtr.i= tablePtr.p->fragrec[buildPtr.p->m_fragNo];
- if (fragPtr.i == RNIL) {
- jam();
- buildPtr.p->m_fragNo++;
- buildPtr.p->m_pageId= 0;
- buildPtr.p->m_tupleNo= firstTupleNo;
- break;
- }
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- // get page
- PagePtr pagePtr;
- if (buildPtr.p->m_pageId >= fragPtr.p->noOfPages) {
- jam();
- buildPtr.p->m_fragNo++;
- buildPtr.p->m_pageId= 0;
- buildPtr.p->m_tupleNo= firstTupleNo;
- break;
- }
- Uint32 realPageId= getRealpid(fragPtr.p, buildPtr.p->m_pageId);
- c_page_pool.getPtr(pagePtr, realPageId);
- Uint32 pageState= pagePtr.p->page_state;
- // skip empty page
- if (pageState == ZEMPTY_MM) {
- jam();
- buildPtr.p->m_pageId++;
- buildPtr.p->m_tupleNo= firstTupleNo;
- break;
- }
- // get tuple
- Uint32 pageIndex = ~0;
- const Tuple_header* tuple_ptr = 0;
- pageIndex = buildPtr.p->m_tupleNo * tupheadsize;
- if (pageIndex + tupheadsize > Fix_page::DATA_WORDS) {
- jam();
- buildPtr.p->m_pageId++;
- buildPtr.p->m_tupleNo= firstTupleNo;
- break;
- }
- tuple_ptr = (Tuple_header*)&pagePtr.p->m_data[pageIndex];
- // skip over free tuple
- if (tuple_ptr->m_header_bits & Tuple_header::FREE) {
- jam();
- buildPtr.p->m_tupleNo++;
- break;
- }
- Uint32 tupVersion= tuple_ptr->get_tuple_version();
- OperationrecPtr pageOperPtr;
- pageOperPtr.i= tuple_ptr->m_operation_ptr_i;
-#ifdef TIME_MEASUREMENT
- NdbTick_getMicroTimer(&start);
-#endif
- // add to index
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- req->errorCode = RNIL;
- req->tableId = tablePtr.i;
- req->indexId = buildPtr.p->m_indexId;
- req->fragId = tablePtr.p->fragid[buildPtr.p->m_fragNo];
- req->pageId = realPageId;
- req->tupVersion = tupVersion;
- req->opInfo = TuxMaintReq::OpAdd;
- req->tupFragPtrI = fragPtr.i;
- req->fragPageId = buildPtr.p->m_pageId;
- req->pageIndex = pageIndex;
-
- if (pageOperPtr.i == RNIL)
- {
- EXECUTE_DIRECT(buildPtr.p->m_buildRef, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength+2);
- }
- else
- {
- /*
- If there is an ongoing operation on the tuple then it is either a
- copy tuple or an original tuple with an ongoing transaction. In
- both cases realPageId and pageOffset refer to the original tuple.
- The tuple address stored in TUX will always be the original tuple
- but with the tuple version of the tuple we found.
-
- This is necessary to avoid having to update TUX at abort of
- update. If an update aborts then the copy tuple is copied to
- the original tuple. The build will however have found that
- tuple as a copy tuple. The original tuple is stable and is thus
- preferrable to store in TUX.
- */
- jam();
-
- /**
- * Since copy tuples now can't be found on real pages.
- * we will here build all copies of the tuple
- *
- * Note only "real" tupVersion's should be added
- * i.e delete's shouldnt be added
- * (unless it's the first op, when "original" should be added)
- */
- do
- {
- c_operation_pool.getPtr(pageOperPtr);
- if(pageOperPtr.p->op_struct.op_type != ZDELETE ||
- pageOperPtr.p->is_first_operation())
- {
- req->errorCode = RNIL;
- req->tupVersion= pageOperPtr.p->tupVersion;
- EXECUTE_DIRECT(buildPtr.p->m_buildRef, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength+2);
- }
- else
- {
- req->errorCode= 0;
- }
- pageOperPtr.i= pageOperPtr.p->prevActiveOp;
- } while(req->errorCode == 0 && pageOperPtr.i != RNIL);
- }
-
- jamEntry();
- if (req->errorCode != 0) {
- switch (req->errorCode) {
- case TuxMaintReq::NoMemError:
- jam();
- buildPtr.p->m_errorCode= BuildIndxRef::AllocationFailure;
- break;
- default:
- ndbrequire(false);
- break;
- }
- buildIndexReply(signal, buildPtr.p);
- c_buildIndexList.release(buildPtr);
- return;
- }
-#ifdef TIME_MEASUREMENT
- NdbTick_getMicroTimer(&stop);
- time_passed= NdbTick_getMicrosPassed(start, stop);
- if (time_passed < 1000) {
- time_events++;
- tot_time_passed += time_passed;
- if (time_events == number_events) {
- NDB_TICKS mean_time_passed= tot_time_passed /
- (NDB_TICKS)number_events;
- ndbout << "Number of events= " << number_events;
- ndbout << " Mean time passed= " << mean_time_passed << endl;
- number_events <<= 1;
- tot_time_passed= (NDB_TICKS)0;
- time_events= 0;
- }
- }
-#endif
- // next tuple
- buildPtr.p->m_tupleNo++;
- break;
- } while (0);
- signal->theData[0]= ZBUILD_INDEX;
- signal->theData[1]= buildPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Dbtup::buildIndexReply(Signal* signal, const BuildIndexRec* buildPtrP)
-{
- const BuildIndxReq* const buildReq=
- (const BuildIndxReq*)buildPtrP->m_request;
- // conf is subset of ref
- BuildIndxRef* rep= (BuildIndxRef*)signal->getDataPtr();
- rep->setUserRef(buildReq->getUserRef());
- rep->setConnectionPtr(buildReq->getConnectionPtr());
- rep->setRequestType(buildReq->getRequestType());
- rep->setTableId(buildReq->getTableId());
- rep->setIndexType(buildReq->getIndexType());
- rep->setIndexId(buildReq->getIndexId());
- // conf
- if (buildPtrP->m_errorCode == BuildIndxRef::NoError) {
- jam();
- sendSignal(rep->getUserRef(), GSN_BUILDINDXCONF,
- signal, BuildIndxConf::SignalLength, JBB);
- return;
- }
- // ref
- rep->setErrorCode(buildPtrP->m_errorCode);
- sendSignal(rep->getUserRef(), GSN_BUILDINDXREF,
- signal, BuildIndxRef::SignalLength, JBB);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
deleted file mode 100644
index dffc966f875..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
+++ /dev/null
@@ -1,1486 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_META_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <signaldata/TupFrag.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/CreateFilegroupImpl.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <my_sys.h>
-
-void Dbtup::execTUPFRAGREQ(Signal* signal)
-{
- jamEntry();
-
- TupFragReq* tupFragReq = (TupFragReq*)signal->getDataPtr();
- if (tupFragReq->userPtr == (Uint32)-1) {
- jam();
- abortAddFragOp(signal);
- return;
- }
-
- FragoperrecPtr fragOperPtr;
- FragrecordPtr regFragPtr;
- TablerecPtr regTabPtr;
-
- Uint32 userptr = tupFragReq->userPtr;
- Uint32 userblockref = tupFragReq->userRef;
- Uint32 reqinfo = tupFragReq->reqInfo;
- regTabPtr.i = tupFragReq->tableId;
- Uint32 noOfAttributes = tupFragReq->noOfAttr;
- Uint32 fragId = tupFragReq->fragId;
- /* Uint32 schemaVersion = tupFragReq->schemaVersion;*/
- Uint32 noOfKeyAttr = tupFragReq->noOfKeyAttr;
- Uint32 noOfCharsets = tupFragReq->noOfCharsets;
-
- Uint32 checksumIndicator = tupFragReq->checksumIndicator;
- Uint32 gcpIndicator = tupFragReq->globalCheckpointIdIndicator;
- Uint32 tablespace_id= tupFragReq->tablespaceid;
- Uint32 forceVarPart = tupFragReq->forceVarPartFlag;
-
- Uint64 maxRows =
- (((Uint64)tupFragReq->maxRowsHigh) << 32) + tupFragReq->maxRowsLow;
- Uint64 minRows =
- (((Uint64)tupFragReq->minRowsHigh) << 32) + tupFragReq->minRowsLow;
-
-#ifndef VM_TRACE
- // config mismatch - do not crash if release compiled
- if (regTabPtr.i >= cnoOfTablerec) {
- jam();
- tupFragReq->userPtr = userptr;
- tupFragReq->userRef = 800;
- sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
- return;
- }
-#endif
-
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
- if (cfirstfreeFragopr == RNIL) {
- jam();
- tupFragReq->userPtr = userptr;
- tupFragReq->userRef = ZNOFREE_FRAGOP_ERROR;
- sendSignal(userblockref, GSN_TUPFRAGREF, signal, 2, JBB);
- return;
- }
- seizeFragoperrec(fragOperPtr);
-
- fragOperPtr.p->nextFragoprec = RNIL;
- fragOperPtr.p->lqhBlockrefFrag = userblockref;
- fragOperPtr.p->lqhPtrFrag = userptr;
- fragOperPtr.p->fragidFrag = fragId;
- fragOperPtr.p->tableidFrag = regTabPtr.i;
- fragOperPtr.p->attributeCount = noOfAttributes;
-
- memset(fragOperPtr.p->m_null_bits, 0, sizeof(fragOperPtr.p->m_null_bits));
- memset(fragOperPtr.p->m_fix_attributes_size, 0,
- sizeof(fragOperPtr.p->m_fix_attributes_size));
- memset(fragOperPtr.p->m_var_attributes_size, 0,
- sizeof(fragOperPtr.p->m_var_attributes_size));
-
- fragOperPtr.p->charsetIndex = 0;
- fragOperPtr.p->minRows = minRows;
- fragOperPtr.p->maxRows = maxRows;
-
- ndbrequire(reqinfo == ZADDFRAG);
-
- getFragmentrec(regFragPtr, fragId, regTabPtr.p);
- if (regFragPtr.i != RNIL) {
- jam();
- terrorCode= ZEXIST_FRAG_ERROR;
- fragrefuse1Lab(signal, fragOperPtr);
- return;
- }
- if (cfirstfreefrag != RNIL) {
- jam();
- seizeFragrecord(regFragPtr);
- } else {
- jam();
- terrorCode= ZFULL_FRAGRECORD_ERROR;
- fragrefuse1Lab(signal, fragOperPtr);
- return;
- }
- initFragRange(regFragPtr.p);
- if (!addfragtotab(regTabPtr.p, fragId, regFragPtr.i)) {
- jam();
- terrorCode= ZNO_FREE_TAB_ENTRY_ERROR;
- fragrefuse2Lab(signal, fragOperPtr, regFragPtr);
- return;
- }
- if (cfirstfreerange == RNIL) {
- jam();
- terrorCode= ZNO_FREE_PAGE_RANGE_ERROR;
- fragrefuse3Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
- return;
- }
-
- regFragPtr.p->fragTableId= regTabPtr.i;
- regFragPtr.p->fragmentId= fragId;
- regFragPtr.p->m_tablespace_id= tablespace_id;
- regFragPtr.p->m_undo_complete= false;
- regFragPtr.p->m_lcp_scan_op = RNIL;
- regFragPtr.p->m_lcp_keep_list = RNIL;
- regFragPtr.p->m_var_page_chunks = RNIL;
- regFragPtr.p->m_restore_lcp_id = RNIL;
-
- if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId ||
- ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId) {
- jam();
- terrorCode = 1;
- fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
-
- if (regTabPtr.p->tableStatus == NOT_DEFINED) {
- jam();
-//-----------------------------------------------------------------------------
-// We are setting up references to the header of the tuple.
-// Active operation This word contains a reference to the operation active
-// on the tuple at the moment. RNIL means no one active at
-// all. Not optional.
-// Tuple version Uses only low 16 bits. Not optional.
-// Checksum The third header word is optional and contains a checksum
-// of the tuple header.
-// Null-bits A number of words to contain null bits for all
-// non-dynamic attributes. Each word contains upto 32 null
-// bits. Each time a new word is needed we allocate the
-// complete word. Zero nullable attributes means that there
-// is no word at all
-//-----------------------------------------------------------------------------
- fragOperPtr.p->definingFragment= true;
- regTabPtr.p->tableStatus= DEFINING;
- regTabPtr.p->m_bits = 0;
- regTabPtr.p->m_bits |= (checksumIndicator ? Tablerec::TR_Checksum : 0);
- regTabPtr.p->m_bits |= (gcpIndicator ? Tablerec::TR_RowGCI : 0);
- regTabPtr.p->m_bits |= (forceVarPart ? Tablerec::TR_ForceVarPart : 0);
-
- regTabPtr.p->m_offsets[MM].m_disk_ref_offset= 0;
- regTabPtr.p->m_offsets[MM].m_null_words= 0;
- regTabPtr.p->m_offsets[MM].m_fix_header_size= 0;
- regTabPtr.p->m_offsets[MM].m_max_var_offset= 0;
-
- regTabPtr.p->m_offsets[DD].m_disk_ref_offset= 0;
- regTabPtr.p->m_offsets[DD].m_null_words= 0;
- regTabPtr.p->m_offsets[DD].m_fix_header_size= 0;
- regTabPtr.p->m_offsets[DD].m_max_var_offset= 0;
-
- regTabPtr.p->m_attributes[MM].m_no_of_fixsize= 0;
- regTabPtr.p->m_attributes[MM].m_no_of_varsize= 0;
- regTabPtr.p->m_attributes[DD].m_no_of_fixsize= 0;
- regTabPtr.p->m_attributes[DD].m_no_of_varsize= 0;
-
- regTabPtr.p->noOfKeyAttr= noOfKeyAttr;
- regTabPtr.p->noOfCharsets= noOfCharsets;
- regTabPtr.p->m_no_of_attributes= noOfAttributes;
-
- regTabPtr.p->notNullAttributeMask.clear();
- regTabPtr.p->blobAttributeMask.clear();
-
- Uint32 offset[10];
- Uint32 tableDescriptorRef= allocTabDescr(regTabPtr.p, offset);
- if (tableDescriptorRef == RNIL) {
- jam();
- fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId);
- return;
- }
- setUpDescriptorReferences(tableDescriptorRef, regTabPtr.p, offset);
- } else {
- jam();
- fragOperPtr.p->definingFragment= false;
- }
- signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
- signal->theData[1]= fragOperPtr.i;
- signal->theData[2]= regFragPtr.i;
- signal->theData[3]= fragId;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUPFRAGCONF, signal, 4, JBB);
- return;
-}
-
-bool Dbtup::addfragtotab(Tablerec* const regTabPtr,
- Uint32 fragId,
- Uint32 fragIndex)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (regTabPtr->fragid[i] == RNIL) {
- jam();
- regTabPtr->fragid[i]= fragId;
- regTabPtr->fragrec[i]= fragIndex;
- return true;
- }
- }
- return false;
-}
-
-void Dbtup::getFragmentrec(FragrecordPtr& regFragPtr,
- Uint32 fragId,
- Tablerec* const regTabPtr)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (regTabPtr->fragid[i] == fragId) {
- jam();
- regFragPtr.i= regTabPtr->fragrec[i];
- ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
- return;
- }
- }
- regFragPtr.i= RNIL;
- ptrNull(regFragPtr);
-}
-
-void Dbtup::seizeFragrecord(FragrecordPtr& regFragPtr)
-{
- regFragPtr.i= cfirstfreefrag;
- ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
- cfirstfreefrag= regFragPtr.p->nextfreefrag;
- regFragPtr.p->nextfreefrag= RNIL;
-}
-
-void Dbtup::seizeFragoperrec(FragoperrecPtr& fragOperPtr)
-{
- fragOperPtr.i= cfirstfreeFragopr;
- ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
- cfirstfreeFragopr = fragOperPtr.p->nextFragoprec;
- fragOperPtr.p->nextFragoprec = RNIL;
- fragOperPtr.p->inUse = true;
-}//Dbtup::seizeFragoperrec()
-
-/* **************************************************************** */
-/* ************** TUP_ADD_ATTRREQ ****************** */
-/* **************************************************************** */
-void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
-{
- FragrecordPtr regFragPtr;
- FragoperrecPtr fragOperPtr;
- TablerecPtr regTabPtr;
-
- jamEntry();
- fragOperPtr.i= signal->theData[0];
- ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
- Uint32 attrId = signal->theData[2];
- Uint32 attrDescriptor = signal->theData[3];
- Uint32 extType = AttributeDescriptor::getType(attrDescriptor);
- // DICT sends charset number in upper half
- Uint32 csNumber = (signal->theData[4] >> 16);
-
- regTabPtr.i= fragOperPtr.p->tableidFrag;
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-
- Uint32 fragId= fragOperPtr.p->fragidFrag;
-
- getFragmentrec(regFragPtr, fragId, regTabPtr.p);
- ndbrequire(regFragPtr.i != RNIL);
-
- ndbrequire(fragOperPtr.p->attributeCount > 0);
- fragOperPtr.p->attributeCount--;
- const bool lastAttr = (fragOperPtr.p->attributeCount == 0);
-
- if (regTabPtr.p->tableStatus != DEFINING)
- {
- ndbrequire(regTabPtr.p->tableStatus == DEFINED);
- signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
- signal->theData[1] = lastAttr;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
- signal, 2, JBB);
-
- if(lastAttr)
- {
- jam();
- /**
- * Init Disk_alloc_info
- */
- CreateFilegroupImplReq rep;
- if(regTabPtr.p->m_no_of_disk_attributes)
- {
- Tablespace_client tsman(0, c_tsman, 0, 0,
- regFragPtr.p->m_tablespace_id);
- ndbrequire(tsman.get_tablespace_info(&rep) == 0);
- regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
- }
- else
- {
- jam();
- regFragPtr.p->m_logfile_group_id = RNIL;
- }
- new (&regFragPtr.p->m_disk_alloc_info)
- Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
- releaseFragoperrec(fragOperPtr);
- }
- return;
- }
-
- Uint32 firstTabDesIndex= regTabPtr.p->tabDescriptor + (attrId * ZAD_SIZE);
- setTabDescrWord(firstTabDesIndex, attrDescriptor);
- Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
-
- Uint32 attrDes2= 0;
- if (!AttributeDescriptor::getDynamic(attrDescriptor)) {
- jam();
- Uint32 pos= 0, null_pos;
- Uint32 bytes= AttributeDescriptor::getSizeInBytes(attrDescriptor);
- Uint32 words= (bytes + 3) / 4;
- Uint32 ind= AttributeDescriptor::getDiskBased(attrDescriptor);
- ndbrequire(ind <= 1);
- null_pos= fragOperPtr.p->m_null_bits[ind];
-
- if (AttributeDescriptor::getNullable(attrDescriptor))
- {
- jam();
- fragOperPtr.p->m_null_bits[ind]++;
- }
- else
- {
- regTabPtr.p->notNullAttributeMask.set(attrId);
- }
-
- if (extType == NDB_TYPE_BLOB || extType == NDB_TYPE_TEXT) {
- regTabPtr.p->blobAttributeMask.set(attrId);
- }
-
- switch (AttributeDescriptor::getArrayType(attrDescriptor)) {
- case NDB_ARRAYTYPE_FIXED:
- {
- jam();
- regTabPtr.p->m_attributes[ind].m_no_of_fixsize++;
- if(attrLen != 0)
- {
- jam();
- pos= fragOperPtr.p->m_fix_attributes_size[ind];
- fragOperPtr.p->m_fix_attributes_size[ind] += words;
- }
- else
- {
- jam();
- Uint32 bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
- fragOperPtr.p->m_null_bits[ind] += bitCount;
- }
- break;
- }
- default:
- {
- jam();
- fragOperPtr.p->m_var_attributes_size[ind] += bytes;
- pos= regTabPtr.p->m_attributes[ind].m_no_of_varsize++;
- break;
- }
- }//switch
-
- AttributeOffset::setOffset(attrDes2, pos);
- AttributeOffset::setNullFlagPos(attrDes2, null_pos);
- } else {
- ndbrequire(false);
- }
- if (csNumber != 0) {
- CHARSET_INFO* cs = all_charsets[csNumber];
- ndbrequire(cs != NULL);
- Uint32 i = 0;
- while (i < fragOperPtr.p->charsetIndex) {
- jam();
- if (regTabPtr.p->charsetArray[i] == cs)
- break;
- i++;
- }
- if (i == fragOperPtr.p->charsetIndex) {
- jam();
- fragOperPtr.p->charsetIndex++;
- }
- ndbrequire(i < regTabPtr.p->noOfCharsets);
- regTabPtr.p->charsetArray[i]= cs;
- AttributeOffset::setCharsetPos(attrDes2, i);
- }
- setTabDescrWord(firstTabDesIndex + 1, attrDes2);
-
- if (ERROR_INSERTED(4009) && regTabPtr.p->fragid[0] == fragId && attrId == 0||
- ERROR_INSERTED(4010) && regTabPtr.p->fragid[0] == fragId && lastAttr ||
- ERROR_INSERTED(4011) && regTabPtr.p->fragid[1] == fragId && attrId == 0||
- ERROR_INSERTED(4012) && regTabPtr.p->fragid[1] == fragId && lastAttr) {
- jam();
- terrorCode = 1;
- addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }
-
-/* **************************************************************** */
-/* ************** TUP_ADD_ATTCONF ****************** */
-/* **************************************************************** */
- if (! lastAttr) {
- jam();
- signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
- signal->theData[1] = lastAttr;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
- signal, 2, JBB);
- return;
- }
-
- ndbrequire(regTabPtr.p->tableStatus == DEFINING);
- regTabPtr.p->tableStatus= DEFINED;
- regFragPtr.p->fragStatus= ACTIVE;
-
-#define BTW(x) ((x+31) >> 5)
- regTabPtr.p->m_offsets[MM].m_null_words= BTW(fragOperPtr.p->m_null_bits[MM]);
- regTabPtr.p->m_offsets[DD].m_null_words= BTW(fragOperPtr.p->m_null_bits[DD]);
-
- /**
- * Fix offsets
- */
- Uint32 pos[2] = { 0, 0 };
- if (regTabPtr.p->m_bits & Tablerec::TR_Checksum)
- {
- pos[0]= 1;
- }
-
- if (regTabPtr.p->m_bits & Tablerec::TR_RowGCI)
- {
- pos[MM]++;
- pos[DD]++;
- }
-
- regTabPtr.p->m_no_of_disk_attributes=
- regTabPtr.p->m_attributes[DD].m_no_of_fixsize +
- regTabPtr.p->m_attributes[DD].m_no_of_varsize;
-
- if(regTabPtr.p->m_no_of_disk_attributes > 0)
- {
- regTabPtr.p->m_offsets[MM].m_disk_ref_offset= pos[MM];
- pos[MM] += Disk_part_ref::SZ32; // 8 bytes
- }
- else
- {
- /**
- * var part ref is stored at m_disk_ref_offset + Disk_part_ref::SZ32
- */
- regTabPtr.p->m_offsets[MM].m_disk_ref_offset= pos[MM]-Disk_part_ref::SZ32;
- }
-
- if (regTabPtr.p->m_attributes[MM].m_no_of_varsize)
- {
- pos[MM] += Var_part_ref::SZ32;
- regTabPtr.p->m_bits &= ~(Uint32)Tablerec::TR_ForceVarPart;
- }
- else if (regTabPtr.p->m_bits & Tablerec::TR_ForceVarPart)
- {
- pos[MM] += Var_part_ref::SZ32;
- }
-
- regTabPtr.p->m_offsets[MM].m_null_offset= pos[MM];
- regTabPtr.p->m_offsets[DD].m_null_offset= pos[DD];
-
- pos[MM]+= regTabPtr.p->m_offsets[MM].m_null_words;
- pos[DD]+= regTabPtr.p->m_offsets[DD].m_null_words;
-
- Uint32 *tabDesc = (Uint32*)(tableDescriptor+regTabPtr.p->tabDescriptor);
- for(Uint32 i= 0; i<regTabPtr.p->m_no_of_attributes; i++)
- {
- Uint32 ind= AttributeDescriptor::getDiskBased(* tabDesc);
- Uint32 arr= AttributeDescriptor::getArrayType(* tabDesc++);
-
- if(arr == NDB_ARRAYTYPE_FIXED)
- {
- Uint32 desc= * tabDesc;
- Uint32 off= AttributeOffset::getOffset(desc) + pos[ind];
- AttributeOffset::setOffset(desc, off);
- * tabDesc= desc;
- }
- tabDesc++;
- }
-
- regTabPtr.p->m_offsets[MM].m_fix_header_size=
- Tuple_header::HeaderSize +
- fragOperPtr.p->m_fix_attributes_size[MM] +
- pos[MM];
-
- regTabPtr.p->m_offsets[DD].m_fix_header_size=
- fragOperPtr.p->m_fix_attributes_size[DD] +
- pos[DD];
-
- if(regTabPtr.p->m_attributes[DD].m_no_of_varsize == 0 &&
- regTabPtr.p->m_attributes[DD].m_no_of_fixsize > 0)
- regTabPtr.p->m_offsets[DD].m_fix_header_size += Tuple_header::HeaderSize;
-
- regTabPtr.p->m_offsets[MM].m_max_var_offset=
- fragOperPtr.p->m_var_attributes_size[MM];
-
- regTabPtr.p->m_offsets[DD].m_max_var_offset=
- fragOperPtr.p->m_var_attributes_size[DD];
-
- regTabPtr.p->total_rec_size=
- pos[MM] + fragOperPtr.p->m_fix_attributes_size[MM] +
- pos[DD] + fragOperPtr.p->m_fix_attributes_size[DD] +
- ((fragOperPtr.p->m_var_attributes_size[MM] + 3) >> 2) +
- ((fragOperPtr.p->m_var_attributes_size[DD] + 3) >> 2) +
- (regTabPtr.p->m_attributes[MM].m_no_of_varsize ?
- (regTabPtr.p->m_attributes[MM].m_no_of_varsize + 2) >> 1 : 0) +
- (regTabPtr.p->m_attributes[DD].m_no_of_varsize ?
- (regTabPtr.p->m_attributes[DD].m_no_of_varsize + 2) >> 1 : 0) +
- Tuple_header::HeaderSize +
- (regTabPtr.p->m_no_of_disk_attributes ? Tuple_header::HeaderSize : 0);
-
- setUpQueryRoutines(regTabPtr.p);
- setUpKeyArray(regTabPtr.p);
-
-#if 0
- ndbout << *regTabPtr.p << endl;
- Uint32 idx= regTabPtr.p->tabDescriptor;
- for(Uint32 i = 0; i<regTabPtr.p->m_no_of_attributes; i++)
- {
- ndbout << i << ": " << endl;
- ndbout << *(AttributeDescriptor*)(tableDescriptor+idx) << endl;
- ndbout << *(AttributeOffset*)(tableDescriptor+idx+1) << endl;
- idx += 2;
- }
-#endif
-
- {
- Uint32 fix_tupheader = regTabPtr.p->m_offsets[MM].m_fix_header_size;
- ndbassert(fix_tupheader > 0);
- Uint32 noRowsPerPage = ZWORDS_ON_PAGE / fix_tupheader;
- Uint32 noAllocatedPages =
- (fragOperPtr.p->minRows + noRowsPerPage - 1 )/ noRowsPerPage;
- if (fragOperPtr.p->minRows == 0)
- noAllocatedPages = 2;
- else if (noAllocatedPages == 0)
- noAllocatedPages = 2;
- noAllocatedPages = allocFragPages(regFragPtr.p, noAllocatedPages);
-
- if (noAllocatedPages == 0) {
- jam();
- terrorCode = ZNO_PAGES_ALLOCATED_ERROR;
- addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
- return;
- }//if
- }
-
- CreateFilegroupImplReq rep;
- if(regTabPtr.p->m_no_of_disk_attributes)
- {
- jam();
- Tablespace_client tsman(0, c_tsman, 0, 0,
- regFragPtr.p->m_tablespace_id);
- ndbrequire(tsman.get_tablespace_info(&rep) == 0);
- regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
- }
- else
- {
- jam();
- regFragPtr.p->m_logfile_group_id = RNIL;
- }
-
- new (&regFragPtr.p->m_disk_alloc_info)
- Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
-
- if (regTabPtr.p->m_no_of_disk_attributes)
- {
- jam();
- if(!(getNodeState().startLevel == NodeState::SL_STARTING &&
- getNodeState().starting.startPhase <= 4))
- {
- Callback cb;
- jam();
-
- cb.m_callbackData= fragOperPtr.i;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::undo_createtable_callback);
- Uint32 sz= sizeof(Disk_undo::Create) >> 2;
-
- Logfile_client lgman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
- if((terrorCode =
- c_lgman->alloc_log_space(regFragPtr.p->m_logfile_group_id, sz)))
- {
- addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
- return;
- }
-
- int res= lgman.get_log_buffer(signal, sz, &cb);
- switch(res){
- case 0:
- jam();
- signal->theData[0] = 1;
- return;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- }
- execute(signal, cb, regFragPtr.p->m_logfile_group_id);
- return;
- }
- }
-
- signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
- signal->theData[1] = lastAttr;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
- signal, 2, JBB);
-
- releaseFragoperrec(fragOperPtr);
-
- return;
-}
-
-void
-Dbtup::undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused)
-{
- FragrecordPtr regFragPtr;
- FragoperrecPtr fragOperPtr;
- TablerecPtr regTabPtr;
-
- fragOperPtr.i= opPtrI;
- ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
-
- regTabPtr.i= fragOperPtr.p->tableidFrag;
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-
- getFragmentrec(regFragPtr, fragOperPtr.p->fragidFrag, regTabPtr.p);
- ndbrequire(regFragPtr.i != RNIL);
-
- Logfile_client lgman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
-
- Disk_undo::Create create;
- create.m_type_length= Disk_undo::UNDO_CREATE << 16 | (sizeof(create) >> 2);
- create.m_table = regTabPtr.i;
-
- Logfile_client::Change c[1] = {{ &create, sizeof(create) >> 2 } };
-
- Uint64 lsn= lgman.add_entry(c, 1);
-
- Logfile_client::Request req;
- req.m_callback.m_callbackData= fragOperPtr.i;
- req.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::undo_createtable_logsync_callback);
-
- int ret = lgman.sync_lsn(signal, lsn, &req, 0);
- switch(ret){
- case 0:
- return;
- case -1:
- warningEvent("Failed to sync log for create of table: %u", regTabPtr.i);
- default:
- execute(signal, req.m_callback, regFragPtr.p->m_logfile_group_id);
- }
-}
-
-void
-Dbtup::undo_createtable_logsync_callback(Signal* signal, Uint32 ptrI,
- Uint32 res)
-{
- jamEntry();
- FragoperrecPtr fragOperPtr;
- fragOperPtr.i= ptrI;
- ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
-
- signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
- signal->theData[1] = 1;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
- signal, 2, JBB);
-
- releaseFragoperrec(fragOperPtr);
-}
-
-/*
- * Descriptor has these parts:
- *
- * 0 readFunctionArray ( one for each attribute )
- * 1 updateFunctionArray ( ditto )
- * 2 charsetArray ( pointers to distinct CHARSET_INFO )
- * 3 readKeyArray ( attribute ids of keys )
- * 5 tabDescriptor ( attribute descriptors, each ZAD_SIZE )
- */
-void Dbtup::setUpDescriptorReferences(Uint32 descriptorReference,
- Tablerec* const regTabPtr,
- const Uint32* offset)
-{
- Uint32* desc= &tableDescriptor[descriptorReference].tabDescr;
- regTabPtr->readFunctionArray= (ReadFunction*)(desc + offset[0]);
- regTabPtr->updateFunctionArray= (UpdateFunction*)(desc + offset[1]);
- regTabPtr->charsetArray= (CHARSET_INFO**)(desc + offset[2]);
- regTabPtr->readKeyArray= descriptorReference + offset[3];
- regTabPtr->tabDescriptor= descriptorReference + offset[4];
- regTabPtr->m_real_order_descriptor = descriptorReference + offset[5];
-}
-
-Uint32
-Dbtup::sizeOfReadFunction()
-{
- ReadFunction* tmp= (ReadFunction*)&tableDescriptor[0];
- TableDescriptor* start= &tableDescriptor[0];
- TableDescriptor * end= (TableDescriptor*)(tmp + 1);
- return (Uint32)(end - start);
-}
-
-void Dbtup::setUpKeyArray(Tablerec* const regTabPtr)
-{
- ndbrequire((regTabPtr->readKeyArray + regTabPtr->noOfKeyAttr) <
- cnoOfTabDescrRec);
- Uint32* keyArray= &tableDescriptor[regTabPtr->readKeyArray].tabDescr;
- Uint32 countKeyAttr= 0;
- for (Uint32 i= 0; i < regTabPtr->m_no_of_attributes; i++) {
- jam();
- Uint32 refAttr= regTabPtr->tabDescriptor + (i * ZAD_SIZE);
- Uint32 attrDescriptor= getTabDescrWord(refAttr);
- if (AttributeDescriptor::getPrimaryKey(attrDescriptor)) {
- jam();
- AttributeHeader::init(&keyArray[countKeyAttr], i, 0);
- countKeyAttr++;
- }
- }
- ndbrequire(countKeyAttr == regTabPtr->noOfKeyAttr);
-
- /**
- * Setup real order array (16 bit per column)
- */
- const Uint32 off= regTabPtr->m_real_order_descriptor;
- const Uint32 sz= (regTabPtr->m_no_of_attributes + 1) >> 1;
- ndbrequire((off + sz) < cnoOfTabDescrRec);
-
- Uint32 cnt= 0;
- Uint16* order= (Uint16*)&tableDescriptor[off].tabDescr;
- for (Uint32 type = 0; type < 4; type++)
- {
- for (Uint32 i= 0; i < regTabPtr->m_no_of_attributes; i++)
- {
- jam();
- Uint32 refAttr= regTabPtr->tabDescriptor + (i * ZAD_SIZE);
- Uint32 desc = getTabDescrWord(refAttr);
- Uint32 t = 0;
-
- if (AttributeDescriptor::getArrayType(desc) != NDB_ARRAYTYPE_FIXED)
- {
- t += 1;
- }
- if (AttributeDescriptor::getDiskBased(desc))
- {
- t += 2;
- }
- ndbrequire(t < 4);
- if(t == type)
- {
- * order++ = i << ZAD_LOG_SIZE;
- cnt++;
- }
- }
- }
- ndbrequire(cnt == regTabPtr->m_no_of_attributes);
-}
-
-void Dbtup::addattrrefuseLab(Signal* signal,
- FragrecordPtr regFragPtr,
- FragoperrecPtr fragOperPtr,
- Tablerec* const regTabPtr,
- Uint32 fragId)
-{
- releaseFragPages(regFragPtr.p);
- deleteFragTab(regTabPtr, fragId);
- releaseFragrec(regFragPtr);
- releaseTabDescr(regTabPtr);
- initTab(regTabPtr);
-
- signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
- signal->theData[1]= terrorCode;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag,
- GSN_TUP_ADD_ATTRREF, signal, 2, JBB);
- releaseFragoperrec(fragOperPtr);
-}
-
-void Dbtup::fragrefuse4Lab(Signal* signal,
- FragoperrecPtr fragOperPtr,
- FragrecordPtr regFragPtr,
- Tablerec* const regTabPtr,
- Uint32 fragId)
-{
- releaseFragPages(regFragPtr.p);
- fragrefuse3Lab(signal, fragOperPtr, regFragPtr, regTabPtr, fragId);
- initTab(regTabPtr);
-}
-
-void Dbtup::fragrefuse3Lab(Signal* signal,
- FragoperrecPtr fragOperPtr,
- FragrecordPtr regFragPtr,
- Tablerec* const regTabPtr,
- Uint32 fragId)
-{
- fragrefuse2Lab(signal, fragOperPtr, regFragPtr);
- deleteFragTab(regTabPtr, fragId);
-}
-
-void Dbtup::fragrefuse2Lab(Signal* signal,
- FragoperrecPtr fragOperPtr,
- FragrecordPtr regFragPtr)
-{
- fragrefuse1Lab(signal, fragOperPtr);
- releaseFragrec(regFragPtr);
-}
-
-void Dbtup::fragrefuse1Lab(Signal* signal, FragoperrecPtr fragOperPtr)
-{
- fragrefuseLab(signal, fragOperPtr);
- releaseFragoperrec(fragOperPtr);
-}
-
-void Dbtup::fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr)
-{
- signal->theData[0]= fragOperPtr.p->lqhPtrFrag;
- signal->theData[1]= terrorCode;
- sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUPFRAGREF, signal, 2, JBB);
-}
-
-void Dbtup::releaseFragoperrec(FragoperrecPtr fragOperPtr)
-{
- fragOperPtr.p->inUse = false;
- fragOperPtr.p->nextFragoprec = cfirstfreeFragopr;
- cfirstfreeFragopr = fragOperPtr.i;
-}//Dbtup::releaseFragoperrec()
-
-void Dbtup::deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId)
-{
- for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (regTabPtr->fragid[i] == fragId) {
- jam();
- regTabPtr->fragid[i]= RNIL;
- regTabPtr->fragrec[i]= RNIL;
- return;
- }
- }
- ndbrequire(false);
-}
-
-/*
- * LQH aborts on-going create table operation. The table is later
- * dropped by DICT.
- */
-void Dbtup::abortAddFragOp(Signal* signal)
-{
- FragoperrecPtr fragOperPtr;
-
- fragOperPtr.i = signal->theData[1];
- ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
- ndbrequire(fragOperPtr.p->inUse);
- releaseFragoperrec(fragOperPtr);
-}
-
-void
-Dbtup::execDROP_TAB_REQ(Signal* signal)
-{
- jamEntry();
- if (ERROR_INSERTED(4013)) {
-#ifdef VM_TRACE
- verifytabdes();
-#endif
- }
- DropTabReq* req= (DropTabReq*)signal->getDataPtr();
-
- TablerecPtr tabPtr;
- tabPtr.i= req->tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- tabPtr.p->m_dropTable.tabUserRef = req->senderRef;
- tabPtr.p->m_dropTable.tabUserPtr = req->senderData;
- tabPtr.p->tableStatus = DROPPING;
-
- signal->theData[0]= ZREL_FRAG;
- signal->theData[1]= tabPtr.i;
- signal->theData[2]= RNIL;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void Dbtup::releaseTabDescr(Tablerec* const regTabPtr)
-{
- Uint32 descriptor= regTabPtr->readKeyArray;
- if (descriptor != RNIL) {
- jam();
- Uint32 offset[10];
- getTabDescrOffsets(regTabPtr, offset);
-
- regTabPtr->tabDescriptor= RNIL;
- regTabPtr->readKeyArray= RNIL;
- regTabPtr->readFunctionArray= NULL;
- regTabPtr->updateFunctionArray= NULL;
- regTabPtr->charsetArray= NULL;
-
- // move to start of descriptor
- descriptor -= offset[3];
- Uint32 retNo= getTabDescrWord(descriptor + ZTD_DATASIZE);
- ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL);
- ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE));
- ndbrequire(ZTD_TYPE_NORMAL ==
- getTabDescrWord((descriptor + retNo) - ZTD_TR_TYPE));
- freeTabDescr(descriptor, retNo);
- }
-}
-
-void Dbtup::releaseFragment(Signal* signal, Uint32 tableId,
- Uint32 logfile_group_id)
-{
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
- Uint32 fragIndex = RNIL;
- Uint32 fragId = RNIL;
- Uint32 i = 0;
- for (i = 0; i < MAX_FRAG_PER_NODE; i++) {
- jam();
- if (tabPtr.p->fragid[i] != RNIL) {
- jam();
- fragIndex= tabPtr.p->fragrec[i];
- fragId= tabPtr.p->fragid[i];
- break;
- }
- }
- if (fragIndex != RNIL) {
- jam();
-
- signal->theData[0] = ZUNMAP_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragIndex;
- signal->theData[3] = 0;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }
-
- if (logfile_group_id != RNIL)
- {
- Callback cb;
- cb.m_callbackData= tabPtr.i;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::drop_table_log_buffer_callback);
- Uint32 sz= sizeof(Disk_undo::Drop) >> 2;
- int r0 = c_lgman->alloc_log_space(logfile_group_id, sz);
- if (r0)
- {
- jam();
- warningEvent("Failed to alloc log space for drop table: %u",
- tabPtr.i);
- goto done;
- }
-
- Logfile_client lgman(this, c_lgman, logfile_group_id);
- int res= lgman.get_log_buffer(signal, sz, &cb);
- switch(res){
- case 0:
- jam();
- return;
- case -1:
- warningEvent("Failed to get log buffer for drop table: %u",
- tabPtr.i);
- c_lgman->free_log_space(logfile_group_id, sz);
- goto done;
- break;
- default:
- execute(signal, cb, logfile_group_id);
- return;
- }
- }
-
-done:
- drop_table_logsync_callback(signal, tabPtr.i, RNIL);
-}
-
-void
-Dbtup::drop_fragment_unmap_pages(Signal *signal,
- TablerecPtr tabPtr,
- FragrecordPtr fragPtr,
- Uint32 pos)
-{
- if (tabPtr.p->m_no_of_disk_attributes)
- {
- jam();
- Disk_alloc_info& alloc_info= fragPtr.p->m_disk_alloc_info;
-
- if (!alloc_info.m_unmap_pages.isEmpty())
- {
- jam();
- ndbout_c("waiting for unmape pages");
- signal->theData[0] = ZUNMAP_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- signal->theData[3] = pos;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }
- while(alloc_info.m_dirty_pages[pos].isEmpty() && pos < MAX_FREE_LIST)
- pos++;
-
- if (pos == MAX_FREE_LIST)
- {
- if(alloc_info.m_curr_extent_info_ptr_i != RNIL)
- {
- Local_extent_info_list
- list(c_extent_pool, alloc_info.m_free_extents[0]);
- Ptr<Extent_info> ext_ptr;
- c_extent_pool.getPtr(ext_ptr, alloc_info.m_curr_extent_info_ptr_i);
- list.add(ext_ptr);
- alloc_info.m_curr_extent_info_ptr_i= RNIL;
- }
-
- drop_fragment_free_extent(signal, tabPtr, fragPtr, 0);
- return;
- }
-
- Ptr<Page> pagePtr;
- ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
- {
- LocalDLList<Page> list(*pool, alloc_info.m_dirty_pages[pos]);
- list.first(pagePtr);
- list.remove(pagePtr);
- }
-
- Page_cache_client::Request req;
- req.m_page.m_page_no = pagePtr.p->m_page_no;
- req.m_page.m_file_no = pagePtr.p->m_file_no;
-
- req.m_callback.m_callbackData= pos;
- req.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::drop_fragment_unmap_page_callback);
-
- int flags= Page_cache_client::COMMIT_REQ;
- int res= m_pgman.get_page(signal, req, flags);
- switch(res)
- {
- case 0:
- case -1:
- break;
- default:
- ndbrequire((Uint32)res == pagePtr.i);
- drop_fragment_unmap_page_callback(signal, pos, res);
- }
- return;
- }
- drop_fragment_free_extent(signal, tabPtr, fragPtr, 0);
-}
-
-void
-Dbtup::drop_fragment_unmap_page_callback(Signal* signal,
- Uint32 pos, Uint32 page_id)
-{
- Ptr<GlobalPage> page;
- m_global_page_pool.getPtr(page, page_id);
-
- Local_key key;
- key.m_page_no = ((Page*)page.p)->m_page_no;
- key.m_file_no = ((Page*)page.p)->m_file_no;
-
- Uint32 fragId = ((Page*)page.p)->m_fragment_id;
- Uint32 tableId = ((Page*)page.p)->m_table_id;
- m_pgman.drop_page(key, page_id);
-
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- FragrecordPtr fragPtr;
- getFragmentrec(fragPtr, fragId, tabPtr.p);
-
- signal->theData[0] = ZUNMAP_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- signal->theData[3] = pos;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
-}
-
-void
-Dbtup::drop_fragment_free_extent(Signal *signal,
- TablerecPtr tabPtr,
- FragrecordPtr fragPtr,
- Uint32 pos)
-{
- if (tabPtr.p->m_no_of_disk_attributes)
- {
- Disk_alloc_info& alloc_info= fragPtr.p->m_disk_alloc_info;
- for(; pos<EXTENT_SEARCH_MATRIX_SIZE; pos++)
- {
- if(!alloc_info.m_free_extents[pos].isEmpty())
- {
- jam();
- Callback cb;
- cb.m_callbackData= fragPtr.i;
- cb.m_callbackFunction =
- safe_cast(&Dbtup::drop_fragment_free_extent_log_buffer_callback);
-#if NOT_YET_UNDO_FREE_EXTENT
- Uint32 sz= sizeof(Disk_undo::FreeExtent) >> 2;
- (void) c_lgman->alloc_log_space(fragPtr.p->m_logfile_group_id, sz);
-
- Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
-
- int res= lgman.get_log_buffer(signal, sz, &cb);
- switch(res){
- case 0:
- jam();
- return;
- case -1:
- ndbrequire("NOT YET IMPLEMENTED" == 0);
- break;
- default:
- execute(signal, cb, fragPtr.p->m_logfile_group_id);
- return;
- }
-#else
- execute(signal, cb, fragPtr.p->m_logfile_group_id);
- return;
-#endif
- }
- }
-
- ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
- for(pos= 0; pos<MAX_FREE_LIST; pos++)
- {
- ndbrequire(alloc_info.m_page_requests[pos].isEmpty());
- LocalDLList<Page> list(* cheat_pool, alloc_info.m_dirty_pages[pos]);
- list.remove();
- }
- }
-
- signal->theData[0] = ZFREE_VAR_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void
-Dbtup::drop_table_log_buffer_callback(Signal* signal, Uint32 tablePtrI,
- Uint32 logfile_group_id)
-{
- TablerecPtr tabPtr;
- tabPtr.i = tablePtrI;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- ndbrequire(tabPtr.p->m_no_of_disk_attributes);
-
- Disk_undo::Drop drop;
- drop.m_table = tabPtr.i;
- drop.m_type_length =
- (Disk_undo::UNDO_DROP << 16) | (sizeof(drop) >> 2);
- Logfile_client lgman(this, c_lgman, logfile_group_id);
-
- Logfile_client::Change c[1] = {{ &drop, sizeof(drop) >> 2 } };
- Uint64 lsn = lgman.add_entry(c, 1);
-
- Logfile_client::Request req;
- req.m_callback.m_callbackData= tablePtrI;
- req.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::drop_table_logsync_callback);
-
- int ret = lgman.sync_lsn(signal, lsn, &req, 0);
- switch(ret){
- case 0:
- return;
- case -1:
- warningEvent("Failed to syn log for drop of table: %u", tablePtrI);
- default:
- execute(signal, req.m_callback, logfile_group_id);
- }
-}
-
-void
-Dbtup::drop_table_logsync_callback(Signal* signal,
- Uint32 tabPtrI,
- Uint32 logfile_group_id)
-{
- TablerecPtr tabPtr;
- tabPtr.i = tabPtrI;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend();
- dropConf->senderRef= reference();
- dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr;
- dropConf->tableId= tabPtr.i;
- sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
-
- releaseTabDescr(tabPtr.p);
- initTab(tabPtr.p);
-}
-
-void
-Dbtup::drop_fragment_free_extent_log_buffer_callback(Signal* signal,
- Uint32 fragPtrI,
- Uint32 unused)
-{
- FragrecordPtr fragPtr;
- fragPtr.i = fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- TablerecPtr tabPtr;
- tabPtr.i = fragPtr.p->fragTableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- ndbrequire(tabPtr.p->m_no_of_disk_attributes);
- Disk_alloc_info& alloc_info= fragPtr.p->m_disk_alloc_info;
-
- for(Uint32 pos = 0; pos<EXTENT_SEARCH_MATRIX_SIZE; pos++)
- {
- if(!alloc_info.m_free_extents[pos].isEmpty())
- {
- jam();
- Local_extent_info_list
- list(c_extent_pool, alloc_info.m_free_extents[pos]);
- Ptr<Extent_info> ext_ptr;
- list.first(ext_ptr);
-
-#if NOT_YET_UNDO_FREE_EXTENT
-#error "This code is complete"
-#error "but not needed until we do dealloc of empty extents"
- Disk_undo::FreeExtent free;
- free.m_table = tabPtr.i;
- free.m_fragment = fragPtr.p->fragmentId;
- free.m_file_no = ext_ptr.p->m_key.m_file_no;
- free.m_page_no = ext_ptr.p->m_key.m_page_no;
- free.m_type_length =
- (Disk_undo::UNDO_FREE_EXTENT << 16) | (sizeof(free) >> 2);
- Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
-
- Logfile_client::Change c[1] = {{ &free, sizeof(free) >> 2 } };
- Uint64 lsn = lgman.add_entry(c, 1);
-#else
- Uint64 lsn = 0;
-#endif
-
- Tablespace_client tsman(signal, c_tsman, tabPtr.i,
- fragPtr.p->fragmentId,
- fragPtr.p->m_tablespace_id);
-
- tsman.free_extent(&ext_ptr.p->m_key, lsn);
- c_extent_hash.remove(ext_ptr);
- list.release(ext_ptr);
-
- signal->theData[0] = ZFREE_EXTENT;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- signal->theData[3] = pos;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
- return;
- }
- }
- ndbrequire(false);
-}
-
-void
-Dbtup::drop_fragment_free_var_pages(Signal* signal)
-{
- jam();
- Uint32 tableId = signal->theData[1];
- Uint32 fragPtrI = signal->theData[2];
-
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- FragrecordPtr fragPtr;
- fragPtr.i = fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- PagePtr pagePtr;
- if ((pagePtr.i = fragPtr.p->m_var_page_chunks) != RNIL)
- {
- c_page_pool.getPtr(pagePtr);
- Var_page* page = (Var_page*)pagePtr.p;
- fragPtr.p->m_var_page_chunks = page->next_chunk;
-
- Uint32 sz = page->chunk_size;
- returnCommonArea(pagePtr.i, sz);
-
- signal->theData[0] = ZFREE_VAR_PAGES;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
-
- /**
- * Remove LCP's for fragment
- */
- tabPtr.p->m_dropTable.m_lcpno = 0;
- tabPtr.p->m_dropTable.m_fragPtrI = fragPtr.i;
- drop_fragment_fsremove(signal, tabPtr, fragPtr);
-}
-
-void
-Dbtup::drop_fragment_fsremove_done(Signal* signal,
- TablerecPtr tabPtr,
- FragrecordPtr fragPtr)
-{
- /**
- * LCP's removed...
- * now continue with "next"
- */
- Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id ;
- releaseFragPages(fragPtr.p);
- Uint32 i;
- for(i= 0; i<MAX_FRAG_PER_NODE; i++)
- if(tabPtr.p->fragrec[i] == fragPtr.i)
- break;
-
- ndbrequire(i != MAX_FRAG_PER_NODE);
- tabPtr.p->fragid[i]= RNIL;
- tabPtr.p->fragrec[i]= RNIL;
- releaseFragrec(fragPtr);
-
- signal->theData[0]= ZREL_FRAG;
- signal->theData[1]= tabPtr.i;
- signal->theData[2]= logfile_group_id;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- return;
-}
-
-// Remove LCP
-
-void
-Dbtup::drop_fragment_fsremove(Signal* signal,
- TablerecPtr tabPtr,
- FragrecordPtr fragPtr)
-{
- FsRemoveReq* req = (FsRemoveReq*)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = tabPtr.i;
- req->directory = 0;
- req->ownDirectory = 0;
-
- Uint32 lcpno = tabPtr.p->m_dropTable.m_lcpno;
- Uint32 fragId = fragPtr.p->fragmentId;
- Uint32 tableId = fragPtr.p->fragTableId;
-
- FsOpenReq::setVersion(req->fileNumber, 5);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
- FsOpenReq::v5_setLcpNo(req->fileNumber, lcpno);
- FsOpenReq::v5_setTableId(req->fileNumber, tableId);
- FsOpenReq::v5_setFragmentId(req->fileNumber, fragId);
- sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
- FsRemoveReq::SignalLength, JBB);
-}
-
-void
-Dbtup::execFSREMOVEREF(Signal* signal)
-{
- jamEntry();
- FsRef* ref = (FsRef*)signal->getDataPtr();
- Uint32 userPointer = ref->userPointer;
- FsConf* conf = (FsConf*)signal->getDataPtrSend();
- conf->userPointer = userPointer;
- execFSREMOVECONF(signal);
-}
-
-void
-Dbtup::execFSREMOVECONF(Signal* signal)
-{
- jamEntry();
- FsConf* conf = (FsConf*)signal->getDataPtrSend();
-
- TablerecPtr tabPtr;
- FragrecordPtr fragPtr;
-
- tabPtr.i = conf->userPointer;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- ndbrequire(tabPtr.p->tableStatus == DROPPING);
-
- fragPtr.i = tabPtr.p->m_dropTable.m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- tabPtr.p->m_dropTable.m_lcpno++;
- if (tabPtr.p->m_dropTable.m_lcpno < 3)
- {
- jam();
- drop_fragment_fsremove(signal, tabPtr, fragPtr);
- }
- else
- {
- jam();
- drop_fragment_fsremove_done(signal, tabPtr, fragPtr);
- }
-}
-// End remove LCP
-
-void
-Dbtup::start_restore_lcp(Uint32 tableId, Uint32 fragId)
-{
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- tabPtr.p->m_dropTable.tabUserPtr= tabPtr.p->m_attributes[DD].m_no_of_fixsize;
- tabPtr.p->m_dropTable.tabUserRef= tabPtr.p->m_attributes[DD].m_no_of_varsize;
-
- Uint32 *tabDesc = (Uint32*)(tableDescriptor+tabPtr.p->tabDescriptor);
- for(Uint32 i= 0; i<tabPtr.p->m_no_of_attributes; i++)
- {
- Uint32 disk= AttributeDescriptor::getDiskBased(* tabDesc);
- Uint32 null= AttributeDescriptor::getNullable(* tabDesc);
-
- ndbrequire(tabPtr.p->notNullAttributeMask.get(i) != null);
- if(disk)
- tabPtr.p->notNullAttributeMask.clear(i);
- tabDesc += 2;
- }
-
- tabPtr.p->m_no_of_disk_attributes = 0;
- tabPtr.p->m_attributes[DD].m_no_of_fixsize = 0;
- tabPtr.p->m_attributes[DD].m_no_of_varsize = 0;
-}
-void
-Dbtup::complete_restore_lcp(Uint32 tableId, Uint32 fragId)
-{
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- tabPtr.p->m_attributes[DD].m_no_of_fixsize= tabPtr.p->m_dropTable.tabUserPtr;
- tabPtr.p->m_attributes[DD].m_no_of_varsize= tabPtr.p->m_dropTable.tabUserRef;
-
- tabPtr.p->m_no_of_disk_attributes =
- tabPtr.p->m_attributes[DD].m_no_of_fixsize +
- tabPtr.p->m_attributes[DD].m_no_of_varsize;
-
- Uint32 *tabDesc = (Uint32*)(tableDescriptor+tabPtr.p->tabDescriptor);
- for(Uint32 i= 0; i<tabPtr.p->m_no_of_attributes; i++)
- {
- Uint32 disk= AttributeDescriptor::getDiskBased(* tabDesc);
- Uint32 null= AttributeDescriptor::getNullable(* tabDesc);
-
- if(disk && !null)
- tabPtr.p->notNullAttributeMask.set(i);
-
- tabDesc += 2;
- }
-}
-
-bool
-Dbtup::get_frag_info(Uint32 tableId, Uint32 fragId, Uint32* maxPage)
-{
- jamEntry();
- TablerecPtr tabPtr;
- tabPtr.i= tableId;
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- FragrecordPtr fragPtr;
- getFragmentrec(fragPtr, fragId, tabPtr.p);
-
- if (maxPage)
- {
- * maxPage = fragPtr.p->noOfPages;
- }
-
- return true;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp
deleted file mode 100644
index 47447bc3755..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_PAG_MAN_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-/* ---------------------------------------------------------------- */
-// 4) Page Memory Manager (buddy algorithm)
-//
-// The following data structures in Dbtup is used by the Page Memory
-// Manager.
-//
-// cfreepageList[16]
-// Pages with a header
-//
-// The cfreepageList is 16 free lists. Free list 0 contains chunks of
-// pages with 2^0 (=1) pages in each chunk. Free list 1 chunks of 2^1
-// (=2) pages in each chunk and so forth upto free list 15 which
-// contains chunks of 2^15 (=32768) pages in each chunk.
-// The cfreepageList array contains the pointer to the first chunk
-// in each of those lists. The lists are doubly linked where the
-// first page in each chunk contains the next and previous references
-// in position ZPAGE_NEXT_CLUST_POS and ZPAGE_PREV_CLUST_POS in the
-// page header.
-// In addition the leading page and the last page in each chunk is marked
-// with a state (=ZFREE_COMMON) in position ZPAGE_STATE_POS in page
-// header. This state indicates that the page is the leading or last page
-// in a chunk of free pages. Furthermore the leading and last page is
-// also marked with a reference to the leading (=ZPAGE_FIRST_CLUST_POS)
-// and the last page (=ZPAGE_LAST_CLUST_POS) in the chunk.
-//
-// The aim of these data structures is to enable a free area handling of
-// free pages based on a buddy algorithm. When allocating pages it is
-// performed in chunks of pages and the algorithm tries to make the
-// chunks as large as possible.
-// This manager is invoked when fragments lack internal page space to
-// accomodate all the data they are requested to store. It is also
-// invoked when fragments deallocate page space back to the free area.
-//
-// The following routines are part of the external interface:
-// void
-// allocConsPages(Uint32 noOfPagesToAllocate, #In
-// Uint32& noOfPagesAllocated, #Out
-// Uint32& retPageRef) #Out
-// void
-// returnCommonArea(Uint32 retPageRef, #In
-// Uint32 retNoPages) #In
-//
-// allocConsPages tries to allocate noOfPagesToAllocate pages in one chunk.
-// If this fails it delivers a chunk as large as possible. It returns the
-// i-value of the first page in the chunk delivered, if zero pages returned
-// this i-value is undefined. It also returns the size of the chunk actually
-// delivered.
-//
-// returnCommonArea is used when somebody is returning pages to the free area.
-// It is used both from internal routines and external routines.
-//
-// The following routines are private routines used to support the
-// above external interface:
-// removeCommonArea()
-// insertCommonArea()
-// findFreeLeftNeighbours()
-// findFreeRightNeighbours()
-// Uint32
-// nextHigherTwoLog(Uint32 input)
-//
-// nextHigherTwoLog is a support routine which is a mathematical function with
-// an integer as input and an integer as output. It calculates the 2-log of
-// (input + 1). If the 2-log of (input + 1) is larger than 15 then the routine
-// will return 15. It is part of the external interface since it is also used
-// by other similar memory management algorithms.
-//
-// External dependencies:
-// None.
-//
-// Side Effects:
-// Apart from the above mentioned data structures there are no more
-// side effects other than through the subroutine parameters in the
-// external interface.
-//
-/* ---------------------------------------------------------------- */
-
-/* ---------------------------------------------------------------- */
-/* CALCULATE THE 2-LOG + 1 OF TMP AND PUT RESULT INTO TBITS */
-/* ---------------------------------------------------------------- */
-Uint32 Dbtup::nextHigherTwoLog(Uint32 input)
-{
- input = input | (input >> 8);
- input = input | (input >> 4);
- input = input | (input >> 2);
- input = input | (input >> 1);
- Uint32 output = (input & 0x5555) + ((input >> 1) & 0x5555);
- output = (output & 0x3333) + ((output >> 2) & 0x3333);
- output = output + (output >> 4);
- output = (output & 0xf) + ((output >> 8) & 0xf);
- return output;
-}//nextHigherTwoLog()
-
-void Dbtup::initializePage()
-{
- for (Uint32 i = 0; i < 16; i++) {
- cfreepageList[i] = RNIL;
- }//for
- PagePtr pagePtr;
- for (pagePtr.i = 0; pagePtr.i < c_page_pool.getSize(); pagePtr.i++) {
- jam();
- refresh_watch_dog();
- c_page_pool.getPtr(pagePtr);
- pagePtr.p->physical_page_id= RNIL;
- pagePtr.p->next_page = pagePtr.i + 1;
- pagePtr.p->first_cluster_page = RNIL;
- pagePtr.p->next_cluster_page = RNIL;
- pagePtr.p->last_cluster_page = RNIL;
- pagePtr.p->prev_page = RNIL;
- pagePtr.p->page_state = ZFREE_COMMON;
- }//for
- pagePtr.p->next_page = RNIL;
-
- /**
- * Page 0 cant be part of buddy as
- * it will scan left right when searching for bigger blocks,
- * if 0 is part of arrat, it can search to -1...which is not good
- */
- pagePtr.i = 0;
- c_page_pool.getPtr(pagePtr);
- pagePtr.p->page_state = ~ZFREE_COMMON;
-
- Uint32 tmp = 1;
- returnCommonArea(tmp, c_page_pool.getSize() - tmp);
- cnoOfAllocatedPages = tmp; // Is updated by returnCommonArea
-}//Dbtup::initializePage()
-
-#ifdef VM_TRACE
-Uint32 fc_left, fc_right, fc_remove;
-#endif
-
-void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate,
- Uint32& noOfPagesAllocated,
- Uint32& allocPageRef)
-{
-#ifdef VM_TRACE
- fc_left = fc_right = fc_remove = 0;
-#endif
- if (noOfPagesToAllocate == 0){
- jam();
- noOfPagesAllocated = 0;
- return;
- }//if
-
- Uint32 firstListToCheck = nextHigherTwoLog(noOfPagesToAllocate - 1);
- for (Uint32 i = firstListToCheck; i < 16; i++) {
- jam();
- if (cfreepageList[i] != RNIL) {
- jam();
-/* ---------------------------------------------------------------- */
-/* PROPER AMOUNT OF PAGES WERE FOUND. NOW SPLIT THE FOUND */
-/* AREA AND RETURN THE PART NOT NEEDED. */
-/* ---------------------------------------------------------------- */
- noOfPagesAllocated = noOfPagesToAllocate;
- allocPageRef = cfreepageList[i];
- removeCommonArea(allocPageRef, i);
- Uint32 retNo = (1 << i) - noOfPagesToAllocate;
- Uint32 retPageRef = allocPageRef + noOfPagesToAllocate;
- returnCommonArea(retPageRef, retNo);
- return;
- }//if
- }//for
-/* ---------------------------------------------------------------- */
-/* PROPER AMOUNT OF PAGES WERE NOT FOUND. FIND AS MUCH AS */
-/* POSSIBLE. */
-/* ---------------------------------------------------------------- */
- if (firstListToCheck)
- {
- jam();
- for (Uint32 j = firstListToCheck - 1; (Uint32)~j; j--) {
- jam();
- if (cfreepageList[j] != RNIL) {
- jam();
-/* ---------------------------------------------------------------- */
-/* SOME AREA WAS FOUND, ALLOCATE ALL OF IT. */
-/* ---------------------------------------------------------------- */
- allocPageRef = cfreepageList[j];
- removeCommonArea(allocPageRef, j);
- noOfPagesAllocated = 1 << j;
- findFreeLeftNeighbours(allocPageRef, noOfPagesAllocated,
- noOfPagesToAllocate);
- findFreeRightNeighbours(allocPageRef, noOfPagesAllocated,
- noOfPagesToAllocate);
-
- return;
- }//if
- }//for
- }
-/* ---------------------------------------------------------------- */
-/* NO FREE AREA AT ALL EXISTED. RETURN ZERO PAGES */
-/* ---------------------------------------------------------------- */
- noOfPagesAllocated = 0;
- return;
-}//allocConsPages()
-
-void Dbtup::returnCommonArea(Uint32 retPageRef, Uint32 retNo)
-{
- do {
- jam();
- if (retNo == 0) {
- jam();
- return;
- }//if
- Uint32 list = nextHigherTwoLog(retNo) - 1;
- retNo -= (1 << list);
- insertCommonArea(retPageRef, list);
- retPageRef += (1 << list);
- } while (1);
-}//Dbtup::returnCommonArea()
-
-void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef,
- Uint32& noPagesAllocated,
- Uint32 noOfPagesToAllocate)
-{
- PagePtr pageFirstPtr, pageLastPtr;
- Uint32 remainAllocate = noOfPagesToAllocate - noPagesAllocated;
- Uint32 loop = 0;
- while (allocPageRef > 0 &&
- ++loop < 16)
- {
- jam();
- pageLastPtr.i = allocPageRef - 1;
- c_page_pool.getPtr(pageLastPtr);
- if (pageLastPtr.p->page_state != ZFREE_COMMON) {
- jam();
- return;
- } else {
- jam();
- pageFirstPtr.i = pageLastPtr.p->first_cluster_page;
- ndbrequire(pageFirstPtr.i != RNIL);
- Uint32 list = nextHigherTwoLog(pageLastPtr.i - pageFirstPtr.i);
- removeCommonArea(pageFirstPtr.i, list);
- Uint32 listSize = 1 << list;
- if (listSize > remainAllocate) {
- jam();
- Uint32 retNo = listSize - remainAllocate;
- returnCommonArea(pageFirstPtr.i, retNo);
- allocPageRef = pageFirstPtr.i + retNo;
- noPagesAllocated = noOfPagesToAllocate;
- return;
- } else {
- jam();
- allocPageRef = pageFirstPtr.i;
- noPagesAllocated += listSize;
- remainAllocate -= listSize;
- }//if
- }//if
-#ifdef VM_TRACE
- fc_left++;
-#endif
- }//while
-}//Dbtup::findFreeLeftNeighbours()
-
-void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef,
- Uint32& noPagesAllocated,
- Uint32 noOfPagesToAllocate)
-{
- PagePtr pageFirstPtr, pageLastPtr;
- Uint32 remainAllocate = noOfPagesToAllocate - noPagesAllocated;
- if (remainAllocate == 0) {
- jam();
- return;
- }//if
- Uint32 loop = 0;
- while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize() &&
- ++loop < 16)
- {
- jam();
- pageFirstPtr.i = allocPageRef + noPagesAllocated;
- c_page_pool.getPtr(pageFirstPtr);
- if (pageFirstPtr.p->page_state != ZFREE_COMMON) {
- jam();
- return;
- } else {
- jam();
- pageLastPtr.i = pageFirstPtr.p->last_cluster_page;
- ndbrequire(pageLastPtr.i != RNIL);
- Uint32 list = nextHigherTwoLog(pageLastPtr.i - pageFirstPtr.i);
- removeCommonArea(pageFirstPtr.i, list);
- Uint32 listSize = 1 << list;
- if (listSize > remainAllocate) {
- jam();
- Uint32 retPageRef = pageFirstPtr.i + remainAllocate;
- Uint32 retNo = listSize - remainAllocate;
- returnCommonArea(retPageRef, retNo);
- noPagesAllocated += remainAllocate;
- return;
- } else {
- jam();
- noPagesAllocated += listSize;
- remainAllocate -= listSize;
- }//if
- }//if
-#ifdef VM_TRACE
- fc_right++;
-#endif
- }//while
-}//Dbtup::findFreeRightNeighbours()
-
-void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList)
-{
- cnoOfAllocatedPages -= (1 << insList);
- PagePtr pageLastPtr, pageInsPtr, pageHeadPtr;
-
- pageHeadPtr.i = cfreepageList[insList];
- c_page_pool.getPtr(pageInsPtr, insPageRef);
- ndbrequire(insList < 16);
- pageLastPtr.i = (pageInsPtr.i + (1 << insList)) - 1;
-
- pageInsPtr.p->page_state = ZFREE_COMMON;
- pageInsPtr.p->next_cluster_page = pageHeadPtr.i;
- pageInsPtr.p->prev_cluster_page = RNIL;
- pageInsPtr.p->last_cluster_page = pageLastPtr.i;
- cfreepageList[insList] = pageInsPtr.i;
-
- if (pageHeadPtr.i != RNIL)
- {
- jam();
- c_page_pool.getPtr(pageHeadPtr);
- pageHeadPtr.p->prev_cluster_page = pageInsPtr.i;
- }
-
- c_page_pool.getPtr(pageLastPtr);
- pageLastPtr.p->page_state = ZFREE_COMMON;
- pageLastPtr.p->first_cluster_page = pageInsPtr.i;
- pageLastPtr.p->next_page = RNIL;
-}//Dbtup::insertCommonArea()
-
-void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
-{
- cnoOfAllocatedPages += (1 << list);
- PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, remPagePtr;
-
- c_page_pool.getPtr(remPagePtr, remPageRef);
- ndbrequire(list < 16);
- if (cfreepageList[list] == remPagePtr.i) {
- jam();
- ndbassert(remPagePtr.p->prev_cluster_page == RNIL);
- cfreepageList[list] = remPagePtr.p->next_cluster_page;
- pageNextPtr.i = cfreepageList[list];
- if (pageNextPtr.i != RNIL) {
- jam();
- c_page_pool.getPtr(pageNextPtr);
- pageNextPtr.p->prev_cluster_page = RNIL;
- }//if
- } else {
- pagePrevPtr.i = remPagePtr.p->prev_cluster_page;
- pageNextPtr.i = remPagePtr.p->next_cluster_page;
- c_page_pool.getPtr(pagePrevPtr);
- pagePrevPtr.p->next_cluster_page = pageNextPtr.i;
- if (pageNextPtr.i != RNIL)
- {
- jam();
- c_page_pool.getPtr(pageNextPtr);
- pageNextPtr.p->prev_cluster_page = pagePrevPtr.i;
- }
- }//if
- remPagePtr.p->next_cluster_page= RNIL;
- remPagePtr.p->last_cluster_page= RNIL;
- remPagePtr.p->prev_cluster_page= RNIL;
- remPagePtr.p->page_state = ~ZFREE_COMMON;
-
- pageLastPtr.i = (remPagePtr.i + (1 << list)) - 1;
- c_page_pool.getPtr(pageLastPtr);
- pageLastPtr.p->first_cluster_page= RNIL;
- pageLastPtr.p->page_state = ~ZFREE_COMMON;
-
-}//Dbtup::removeCommonArea()
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
deleted file mode 100644
index bf079627990..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_PAGE_MAP_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-//
-// PageMap is a service used by Dbtup to map logical page id's to physical
-// page id's. The mapping is needs the fragment and the logical page id to
-// provide the physical id.
-//
-// This is a part of Dbtup which is the exclusive user of a certain set of
-// variables on the fragment record and it is the exclusive user of the
-// struct for page ranges.
-//
-//
-// The following methods operate on the data handled by the page map class.
-//
-// Public methods
-// insertPageRange(Uint32 startPageId, # In
-// Uint32 noPages) # In
-// Inserts a range of pages into the mapping structure.
-//
-// void releaseFragPages()
-// Releases all pages and their mappings belonging to a fragment.
-//
-// Uint32 allocFragPages(Uint32 tafpNoAllocRequested)
-// Allocate a set of pages to the fragment from the page manager
-//
-// Uint32 getEmptyPage()
-// Get an empty page from the pool of empty pages on the fragment.
-// It returns the physical page id of the empty page.
-// Returns RNIL if no empty page is available.
-//
-// Uint32 getRealpid(Uint32 logicalPageId)
-// Return the physical page id provided the logical page id
-//
-// void initializePageRange()
-// Initialise free list of page ranges and initialise the page raneg records.
-//
-// void initFragRange()
-// Initialise the fragment variables when allocating a fragment to a table.
-//
-// void initPageRangeSize(Uint32 size)
-// Initialise the number of page ranges.
-//
-// Uint32 getNoOfPages()
-// Get the number of pages on the fragment currently.
-//
-//
-// Private methods
-// Uint32 leafPageRangeFull(PageRangePtr currPageRangePtr)
-//
-// void errorHandler()
-// Method to crash NDB kernel in case of weird data set-up
-//
-// void allocMoreFragPages()
-// When no more empty pages are attached to the fragment and we need more
-// we allocate more pages from the page manager using this method.
-//
-// Private data
-// On the fragment record
-// currentPageRange # The current page range where to insert the next range
-// rootPageRange # The root of the page ranges owned
-// nextStartRange # The next page id to assign when expanding the
-// # page map
-// noOfPages # The number of pages in the fragment
-// emptyPrimPage # The first page of the empty pages in the fragment
-//
-// The full page range struct
-
-Uint32 Dbtup::getEmptyPage(Fragrecord* regFragPtr)
-{
- Uint32 pageId = regFragPtr->emptyPrimPage.firstItem;
- if (pageId == RNIL) {
- jam();
- allocMoreFragPages(regFragPtr);
- pageId = regFragPtr->emptyPrimPage.firstItem;
- if (pageId == RNIL) {
- jam();
- return RNIL;
- }//if
- }//if
- PagePtr pagePtr;
- LocalDLList<Page> alloc_pages(c_page_pool, regFragPtr->emptyPrimPage);
- alloc_pages.getPtr(pagePtr, pageId);
- alloc_pages.remove(pagePtr);
- return pageId;
-}//Dbtup::getEmptyPage()
-
-Uint32 Dbtup::getRealpid(Fragrecord* regFragPtr, Uint32 logicalPageId)
-{
- PageRangePtr grpPageRangePtr;
- Uint32 loopLimit;
- Uint32 loopCount = 0;
- Uint32 pageRangeLimit = cnoOfPageRangeRec;
- ndbassert(logicalPageId < getNoOfPages(regFragPtr));
- grpPageRangePtr.i = regFragPtr->rootPageRange;
- while (true) {
- ndbassert(loopCount++ < 100);
- ndbrequire(grpPageRangePtr.i < pageRangeLimit);
- ptrAss(grpPageRangePtr, pageRange);
- loopLimit = grpPageRangePtr.p->currentIndexPos;
- ndbrequire(loopLimit <= 3);
- for (Uint32 i = 0; i <= loopLimit; i++) {
- jam();
- if (grpPageRangePtr.p->startRange[i] <= logicalPageId) {
- if (grpPageRangePtr.p->endRange[i] >= logicalPageId) {
- if (grpPageRangePtr.p->type[i] == ZLEAF) {
- jam();
- Uint32 realPageId = (logicalPageId - grpPageRangePtr.p->startRange[i]) +
- grpPageRangePtr.p->basePageId[i];
- return realPageId;
- } else {
- ndbrequire(grpPageRangePtr.p->type[i] == ZNON_LEAF);
- grpPageRangePtr.i = grpPageRangePtr.p->basePageId[i];
- }//if
- }//if
- }//if
- }//for
- }//while
- return 0;
-}//Dbtup::getRealpid()
-
-Uint32 Dbtup::getNoOfPages(Fragrecord* const regFragPtr)
-{
- return regFragPtr->noOfPages;
-}//Dbtup::getNoOfPages()
-
-void Dbtup::initPageRangeSize(Uint32 size)
-{
- cnoOfPageRangeRec = size;
-}//Dbtup::initPageRangeSize()
-
-/* ---------------------------------------------------------------- */
-/* ----------------------- INSERT_PAGE_RANGE_TAB ------------------ */
-/* ---------------------------------------------------------------- */
-/* INSERT A PAGE RANGE INTO THE FRAGMENT */
-/* */
-/* NOTE: THE METHOD IS ATOMIC. EITHER THE ACTION IS */
-/* PERFORMED FULLY OR NO ACTION IS PERFORMED AT ALL. */
-/* TO SUPPORT THIS THE CODE HAS A CLEANUP PART AFTER */
-/* ERRORS. */
-/* ---------------------------------------------------------------- */
-bool Dbtup::insertPageRangeTab(Fragrecord* const regFragPtr,
- Uint32 startPageId,
- Uint32 noPages)
-{
- PageRangePtr currPageRangePtr;
- if (cfirstfreerange == RNIL) {
- jam();
- return false;
- }//if
- currPageRangePtr.i = regFragPtr->currentPageRange;
- if (currPageRangePtr.i == RNIL) {
- jam();
-/* ---------------------------------------------------------------- */
-/* THE FIRST PAGE RANGE IS HANDLED WITH SPECIAL CODE */
-/* ---------------------------------------------------------------- */
- seizePagerange(currPageRangePtr);
- regFragPtr->rootPageRange = currPageRangePtr.i;
- currPageRangePtr.p->currentIndexPos = 0;
- currPageRangePtr.p->parentPtr = RNIL;
- } else {
- jam();
- ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange);
- if (currPageRangePtr.p->currentIndexPos < 3) {
- jam();
-/* ---------------------------------------------------------------- */
-/* THE SIMPLE CASE WHEN IT IS ONLY NECESSARY TO FILL IN THE */
-/* NEXT EMPTY POSITION IN THE PAGE RANGE RECORD IS TREATED */
-/* BY COMMON CODE AT THE END OF THE SUBROUTINE. */
-/* ---------------------------------------------------------------- */
- currPageRangePtr.p->currentIndexPos++;
- } else {
- jam();
- ndbrequire(currPageRangePtr.p->currentIndexPos == 3);
- currPageRangePtr.i = leafPageRangeFull(regFragPtr, currPageRangePtr);
- if (currPageRangePtr.i == RNIL) {
- return false;
- }//if
- ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange);
- }//if
- }//if
- currPageRangePtr.p->startRange[currPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;
-/* ---------------------------------------------------------------- */
-/* NOW SET THE LEAF LEVEL PAGE RANGE RECORD PROPERLY */
-/* PAGE_RANGE_PTR REFERS TO LEAF RECORD WHEN ARRIVING HERE */
-/* ---------------------------------------------------------------- */
- currPageRangePtr.p->endRange[currPageRangePtr.p->currentIndexPos] =
- (regFragPtr->nextStartRange + noPages) - 1;
- currPageRangePtr.p->basePageId[currPageRangePtr.p->currentIndexPos] = startPageId;
- currPageRangePtr.p->type[currPageRangePtr.p->currentIndexPos] = ZLEAF;
-/* ---------------------------------------------------------------- */
-/* WE NEED TO UPDATE THE CURRENT PAGE RANGE IN CASE IT HAS */
-/* CHANGED. WE ALSO NEED TO UPDATE THE NEXT START RANGE */
-/* ---------------------------------------------------------------- */
- regFragPtr->currentPageRange = currPageRangePtr.i;
- regFragPtr->nextStartRange += noPages;
-/* ---------------------------------------------------------------- */
-/* WE NEED TO UPDATE THE END RANGE IN ALL PAGE RANGE RECORDS */
-/* UP TO THE ROOT. */
-/* ---------------------------------------------------------------- */
- PageRangePtr loopPageRangePtr;
- loopPageRangePtr = currPageRangePtr;
- while (true) {
- jam();
- loopPageRangePtr.i = loopPageRangePtr.p->parentPtr;
- if (loopPageRangePtr.i != RNIL) {
- jam();
- ptrCheckGuard(loopPageRangePtr, cnoOfPageRangeRec, pageRange);
- ndbrequire(loopPageRangePtr.p->currentIndexPos < 4);
- loopPageRangePtr.p->endRange[loopPageRangePtr.p->currentIndexPos] += noPages;
- } else {
- jam();
- break;
- }//if
- }//while
- regFragPtr->noOfPages += noPages;
- return true;
-}//Dbtup::insertPageRangeTab()
-
-
-void Dbtup::releaseFragPages(Fragrecord* regFragPtr)
-{
- if (regFragPtr->rootPageRange == RNIL) {
- jam();
- return;
- }//if
- PageRangePtr regPRPtr;
- regPRPtr.i = regFragPtr->rootPageRange;
- ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
- while (true) {
- jam();
- const Uint32 indexPos = regPRPtr.p->currentIndexPos;
- ndbrequire(indexPos < 4);
-
- const Uint32 basePageId = regPRPtr.p->basePageId[indexPos];
- regPRPtr.p->basePageId[indexPos] = RNIL;
- if (basePageId == RNIL) {
- jam();
- /**
- * Finished with indexPos continue with next
- */
- if (indexPos > 0) {
- jam();
- regPRPtr.p->currentIndexPos--;
- continue;
- }//if
-
- /* ---------------------------------------------------------------- */
- /* THE PAGE RANGE REC IS EMPTY. RELEASE IT. */
- /*----------------------------------------------------------------- */
- Uint32 parentPtr = regPRPtr.p->parentPtr;
- releasePagerange(regPRPtr);
-
- if (parentPtr != RNIL) {
- jam();
- regPRPtr.i = parentPtr;
- ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
- continue;
- }//if
-
- jam();
- ndbrequire(regPRPtr.i == regFragPtr->rootPageRange);
- initFragRange(regFragPtr);
- for (Uint32 i = 0; i<MAX_FREE_LIST; i++)
- {
- LocalDLList<Page> tmp(c_page_pool, regFragPtr->free_var_page_array[i]);
- tmp.remove();
- }
-
- {
- LocalDLList<Page> tmp(c_page_pool, regFragPtr->emptyPrimPage);
- tmp.remove();
- }
-
- {
- LocalDLFifoList<Page> tmp(c_page_pool, regFragPtr->thFreeFirst);
- tmp.remove();
- }
-
- {
- LocalSLList<Page> tmp(c_page_pool, regFragPtr->m_empty_pages);
- tmp.remove();
- }
-
- return;
- } else {
- if (regPRPtr.p->type[indexPos] == ZNON_LEAF) {
- jam();
- /* ---------------------------------------------------------------- */
- // A non-leaf node, we must release everything below it before we
- // release this node.
- /* ---------------------------------------------------------------- */
- regPRPtr.i = basePageId;
- ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
- } else {
- jam();
- ndbrequire(regPRPtr.p->type[indexPos] == ZLEAF);
- /* ---------------------------------------------------------------- */
- /* PAGE_RANGE_PTR /= RNIL AND THE CURRENT POS IS NOT A CHLED. */
- /*----------------------------------------------------------------- */
- const Uint32 start = regPRPtr.p->startRange[indexPos];
- const Uint32 stop = regPRPtr.p->endRange[indexPos];
- ndbrequire(stop >= start);
- const Uint32 retNo = (stop - start + 1);
- returnCommonArea(basePageId, retNo);
- }//if
- }//if
- }//while
-}//Dbtup::releaseFragPages()
-
-void Dbtup::initializePageRange()
-{
- PageRangePtr regPTRPtr;
- for (regPTRPtr.i = 0;
- regPTRPtr.i < cnoOfPageRangeRec; regPTRPtr.i++) {
- ptrAss(regPTRPtr, pageRange);
- regPTRPtr.p->nextFree = regPTRPtr.i + 1;
- }//for
- regPTRPtr.i = cnoOfPageRangeRec - 1;
- ptrAss(regPTRPtr, pageRange);
- regPTRPtr.p->nextFree = RNIL;
- cfirstfreerange = 0;
- c_noOfFreePageRanges = cnoOfPageRangeRec;
-}//Dbtup::initializePageRange()
-
-void Dbtup::initFragRange(Fragrecord* const regFragPtr)
-{
- regFragPtr->rootPageRange = RNIL;
- regFragPtr->currentPageRange = RNIL;
- regFragPtr->noOfPages = 0;
- regFragPtr->noOfVarPages = 0;
- regFragPtr->noOfPagesToGrow = 2;
- regFragPtr->nextStartRange = 0;
-}//initFragRange()
-
-Uint32 Dbtup::allocFragPages(Fragrecord* regFragPtr, Uint32 tafpNoAllocRequested)
-{
- Uint32 tafpPagesAllocated = 0;
- while (true) {
- Uint32 noOfPagesAllocated = 0;
- Uint32 noPagesToAllocate = tafpNoAllocRequested - tafpPagesAllocated;
- Uint32 retPageRef = RNIL;
- allocConsPages(noPagesToAllocate, noOfPagesAllocated, retPageRef);
- if (noOfPagesAllocated == 0) {
- jam();
- return tafpPagesAllocated;
- }//if
-/* ---------------------------------------------------------------- */
-/* IT IS NOW TIME TO PUT THE ALLOCATED AREA INTO THE PAGE */
-/* RANGE TABLE. */
-/* ---------------------------------------------------------------- */
- Uint32 startRange = regFragPtr->nextStartRange;
- if (!insertPageRangeTab(regFragPtr, retPageRef, noOfPagesAllocated)) {
- jam();
- returnCommonArea(retPageRef, noOfPagesAllocated);
- return tafpPagesAllocated;
- }//if
- tafpPagesAllocated += noOfPagesAllocated;
- Uint32 loopLimit = retPageRef + noOfPagesAllocated;
- PagePtr loopPagePtr;
-/* ---------------------------------------------------------------- */
-/* SINCE A NUMBER OF PAGES WERE ALLOCATED FROM COMMON AREA */
-/* WITH SUCCESS IT IS NOW TIME TO CHANGE THE STATE OF */
-/* THOSE PAGES TO EMPTY_MM AND LINK THEM INTO THE EMPTY */
-/* PAGE LIST OF THE FRAGMENT. */
-/* ---------------------------------------------------------------- */
- Uint32 prev = RNIL;
- for (loopPagePtr.i = retPageRef; loopPagePtr.i < loopLimit; loopPagePtr.i++) {
- jam();
- c_page_pool.getPtr(loopPagePtr);
- loopPagePtr.p->page_state = ZEMPTY_MM;
- loopPagePtr.p->frag_page_id = startRange +
- (loopPagePtr.i - retPageRef);
- loopPagePtr.p->physical_page_id = loopPagePtr.i;
- loopPagePtr.p->nextList = loopPagePtr.i + 1;
- loopPagePtr.p->prevList = prev;
- prev = loopPagePtr.i;
- }//for
- loopPagePtr.i--;
- ndbassert(loopPagePtr.p == c_page_pool.getPtr(loopPagePtr.i));
- loopPagePtr.p->nextList = RNIL;
-
- LocalDLList<Page> alloc(c_page_pool, regFragPtr->emptyPrimPage);
- if (noOfPagesAllocated > 1)
- {
- alloc.add(retPageRef, loopPagePtr);
- }
- else
- {
- alloc.add(loopPagePtr);
- }
-
-/* ---------------------------------------------------------------- */
-/* WAS ENOUGH PAGES ALLOCATED OR ARE MORE NEEDED. */
-/* ---------------------------------------------------------------- */
- if (tafpPagesAllocated < tafpNoAllocRequested) {
- jam();
- } else {
- ndbrequire(tafpPagesAllocated == tafpNoAllocRequested);
- jam();
- return tafpNoAllocRequested;
- }//if
- }//while
-}//Dbtup::allocFragPages()
-
-void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr)
-{
- Uint32 noAllocPages = regFragPtr->noOfPagesToGrow >> 3; // 12.5%
- noAllocPages += regFragPtr->noOfPagesToGrow >> 4; // 6.25%
- noAllocPages += 2;
-/* -----------------------------------------------------------------*/
-// We will grow by 18.75% plus two more additional pages to grow
-// a little bit quicker in the beginning.
-/* -----------------------------------------------------------------*/
-
- if (noAllocPages > m_max_allocate_pages)
- {
- noAllocPages = m_max_allocate_pages;
- }
- Uint32 allocated = allocFragPages(regFragPtr, noAllocPages);
- regFragPtr->noOfPagesToGrow += allocated;
-}//Dbtup::allocMoreFragPages()
-
-Uint32 Dbtup::leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr)
-{
-/* ---------------------------------------------------------------- */
-/* THE COMPLEX CASE WHEN THE LEAF NODE IS FULL. GO UP THE TREE*/
-/* TO FIND THE FIRST RECORD WITH A FREE ENTRY. ALLOCATE NEW */
-/* PAGE RANGE RECORDS THEN ALL THE WAY DOWN TO THE LEAF LEVEL */
-/* AGAIN. THE TREE SHOULD ALWAYS REMAIN BALANCED. */
-/* ---------------------------------------------------------------- */
- PageRangePtr parentPageRangePtr;
- PageRangePtr foundPageRangePtr;
- parentPageRangePtr = currPageRangePtr;
- Uint32 tiprNoLevels = 1;
- while (true) {
- jam();
- parentPageRangePtr.i = parentPageRangePtr.p->parentPtr;
- if (parentPageRangePtr.i == RNIL) {
- jam();
-/* ---------------------------------------------------------------- */
-/* WE HAVE REACHED THE ROOT. A NEW ROOT MUST BE ALLOCATED. */
-/* ---------------------------------------------------------------- */
- if (c_noOfFreePageRanges < tiprNoLevels) {
- jam();
- return RNIL;
- }//if
- PageRangePtr oldRootPRPtr;
- PageRangePtr newRootPRPtr;
- oldRootPRPtr.i = regFragPtr->rootPageRange;
- ptrCheckGuard(oldRootPRPtr, cnoOfPageRangeRec, pageRange);
- seizePagerange(newRootPRPtr);
- regFragPtr->rootPageRange = newRootPRPtr.i;
- oldRootPRPtr.p->parentPtr = newRootPRPtr.i;
-
- newRootPRPtr.p->basePageId[0] = oldRootPRPtr.i;
- newRootPRPtr.p->parentPtr = RNIL;
- newRootPRPtr.p->startRange[0] = 0;
- newRootPRPtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
- newRootPRPtr.p->type[0] = ZNON_LEAF;
- newRootPRPtr.p->startRange[1] = regFragPtr->nextStartRange;
- newRootPRPtr.p->endRange[1] = regFragPtr->nextStartRange - 1;
- newRootPRPtr.p->type[1] = ZNON_LEAF;
- newRootPRPtr.p->currentIndexPos = 1;
- foundPageRangePtr = newRootPRPtr;
- break;
- } else {
- jam();
- ptrCheckGuard(parentPageRangePtr, cnoOfPageRangeRec, pageRange);
- if (parentPageRangePtr.p->currentIndexPos < 3) {
- jam();
-
- if (c_noOfFreePageRanges < tiprNoLevels)
- {
- jam();
- return RNIL;
- }//if
-
-/* ---------------------------------------------------------------- */
-/* WE HAVE FOUND AN EMPTY ENTRY IN A PAGE RANGE RECORD. */
-/* ALLOCATE A NEW PAGE RANGE RECORD, FILL IN THE START RANGE, */
-/* ALLOCATE A NEW PAGE RANGE RECORD AND UPDATE THE POINTERS */
-/* ---------------------------------------------------------------- */
- parentPageRangePtr.p->currentIndexPos++;
- parentPageRangePtr.p->startRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;
- parentPageRangePtr.p->endRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange - 1;
- parentPageRangePtr.p->type[parentPageRangePtr.p->currentIndexPos] = ZNON_LEAF;
- foundPageRangePtr = parentPageRangePtr;
- break;
- } else {
- jam();
- ndbrequire(parentPageRangePtr.p->currentIndexPos == 3);
-/* ---------------------------------------------------------------- */
-/* THE PAGE RANGE RECORD WAS FULL. FIND THE PARENT RECORD */
-/* AND INCREASE THE NUMBER OF LEVELS WE HAVE TRAVERSED */
-/* GOING UP THE TREE. */
-/* ---------------------------------------------------------------- */
- tiprNoLevels++;
- }//if
- }//if
- }//while
-/* ---------------------------------------------------------------- */
-/* REMEMBER THE ERROR LEVEL IN CASE OF ALLOCATION ERRORS */
-/* ---------------------------------------------------------------- */
- PageRangePtr newPageRangePtr;
- PageRangePtr prevPageRangePtr;
- prevPageRangePtr = foundPageRangePtr;
- if (c_noOfFreePageRanges < tiprNoLevels) {
- jam();
- return RNIL;
- }//if
-/* ---------------------------------------------------------------- */
-/* NOW WE HAVE PERFORMED THE SEARCH UPWARDS AND FILLED IN THE */
-/* PROPER FIELDS IN THE PAGE RANGE RECORD WHERE SOME SPACE */
-/* WAS FOUND. THE NEXT STEP IS TO ALLOCATE PAGE RANGES SO */
-/* THAT WE KEEP THE B-TREE BALANCED. THE NEW PAGE RANGE */
-/* ARE ALSO PROPERLY UPDATED ON THE PATH TO THE LEAF LEVEL. */
-/* ---------------------------------------------------------------- */
- while (true) {
- jam();
- seizePagerange(newPageRangePtr);
- tiprNoLevels--;
- ndbrequire(prevPageRangePtr.p->currentIndexPos < 4);
- prevPageRangePtr.p->basePageId[prevPageRangePtr.p->currentIndexPos] = newPageRangePtr.i;
- newPageRangePtr.p->parentPtr = prevPageRangePtr.i;
- newPageRangePtr.p->currentIndexPos = 0;
- if (tiprNoLevels > 0) {
- jam();
- newPageRangePtr.p->startRange[0] = regFragPtr->nextStartRange;
- newPageRangePtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
- newPageRangePtr.p->type[0] = ZNON_LEAF;
- prevPageRangePtr = newPageRangePtr;
- } else {
- jam();
- break;
- }//if
- }//while
- return newPageRangePtr.i;
-}//Dbtup::leafPageRangeFull()
-
-void Dbtup::releasePagerange(PageRangePtr regPRPtr)
-{
- regPRPtr.p->nextFree = cfirstfreerange;
- cfirstfreerange = regPRPtr.i;
- c_noOfFreePageRanges++;
-}//Dbtup::releasePagerange()
-
-void Dbtup::seizePagerange(PageRangePtr& regPageRangePtr)
-{
- regPageRangePtr.i = cfirstfreerange;
- ptrCheckGuard(regPageRangePtr, cnoOfPageRangeRec, pageRange);
- cfirstfreerange = regPageRangePtr.p->nextFree;
- regPageRangePtr.p->nextFree = RNIL;
- regPageRangePtr.p->currentIndexPos = 0;
- regPageRangePtr.p->parentPtr = RNIL;
- for (Uint32 i = 0; i < 4; i++) {
- regPageRangePtr.p->startRange[i] = 1;
- regPageRangePtr.p->endRange[i] = 0;
- regPageRangePtr.p->type[i] = ZNON_LEAF;
- regPageRangePtr.p->basePageId[i] = (Uint32)-1;
- }//for
- c_noOfFreePageRanges--;
-}//Dbtup::seizePagerange()
-
-void Dbtup::errorHandler(Uint32 errorCode)
-{
- switch (errorCode) {
- case 0:
- jam();
- break;
- case 1:
- jam();
- break;
- case 2:
- jam();
- break;
- default:
- jam();
- }
- ndbrequire(false);
-}//Dbtup::errorHandler()
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
deleted file mode 100644
index 1a027315060..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
+++ /dev/null
@@ -1,1687 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_ROUTINES_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <AttributeHeader.hpp>
-
-void
-Dbtup::setUpQueryRoutines(Tablerec *regTabPtr)
-{
- Uint32 startDescriptor= regTabPtr->tabDescriptor;
- ndbrequire((startDescriptor + (regTabPtr->m_no_of_attributes << ZAD_LOG_SIZE))
- <= cnoOfTabDescrRec);
- for (Uint32 i= 0; i < regTabPtr->m_no_of_attributes; i++) {
- Uint32 attrDescrStart= startDescriptor + (i << ZAD_LOG_SIZE);
- Uint32 attrDescr= tableDescriptor[attrDescrStart].tabDescr;
- Uint32 attrOffset= tableDescriptor[attrDescrStart + 1].tabDescr;
- if (!AttributeDescriptor::getDynamic(attrDescr)) {
- if (AttributeDescriptor::getArrayType(attrDescr) == NDB_ARRAYTYPE_FIXED){
- if (!AttributeDescriptor::getNullable(attrDescr)) {
- if (AttributeDescriptor::getSize(attrDescr) == 0){
- jam();
- regTabPtr->readFunctionArray[i] = &Dbtup::readBitsNotNULL;
- regTabPtr->updateFunctionArray[i] = &Dbtup::updateBitsNotNULL;
- } else if (AttributeDescriptor::getSizeInBytes(attrDescr) == 4) {
- jam();
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readFixedSizeTHOneWordNotNULL;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateFixedSizeTHOneWordNotNULL;
- } else if (AttributeDescriptor::getSizeInBytes(attrDescr) == 8) {
- jam();
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readFixedSizeTHTwoWordNotNULL;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateFixedSizeTHTwoWordNotNULL;
- } else {
- jam();
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readFixedSizeTHManyWordNotNULL;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateFixedSizeTHManyWordNotNULL;
- }
- // replace functions for char attribute
- if (AttributeOffset::getCharsetFlag(attrOffset)) {
- jam();
- regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNotNULL;
- regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNotNULL;
- }
- } else {
- if (AttributeDescriptor::getSize(attrDescr) == 0){
- jam();
- regTabPtr->readFunctionArray[i] = &Dbtup::readBitsNULLable;
- regTabPtr->updateFunctionArray[i] = &Dbtup::updateBitsNULLable;
- } else if (AttributeDescriptor::getSizeInBytes(attrDescr) == 4){
- jam();
- regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHOneWordNULLable;
- regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable;
- } else if (AttributeDescriptor::getSizeInBytes(attrDescr) == 8) {
- jam();
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readFixedSizeTHTwoWordNULLable;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateFixedSizeTHManyWordNULLable;
- } else {
- jam();
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readFixedSizeTHManyWordNULLable;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateFixedSizeTHManyWordNULLable;
- }
- // replace functions for char attribute
- if (AttributeOffset::getCharsetFlag(attrOffset)) {
- jam();
- regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNULLable;
- regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable;
- }
- }
- } else {
- if (!AttributeDescriptor::getNullable(attrDescr)) {
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readVarSizeNotNULL;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateVarSizeNotNULL;
- } else {
- regTabPtr->readFunctionArray[i]=
- &Dbtup::readVarSizeNULLable;
- regTabPtr->updateFunctionArray[i]=
- &Dbtup::updateVarSizeNULLable;
- }
- }
- if(AttributeDescriptor::getDiskBased(attrDescr))
- {
- // array initializer crashes gcc-2.95.3
- ReadFunction r[6];
- {
- r[0] = &Dbtup::readDiskBitsNotNULL;
- r[1] = &Dbtup::readDiskBitsNULLable;
- r[2] = &Dbtup::readDiskFixedSizeNotNULL;
- r[3] = &Dbtup::readDiskFixedSizeNULLable;
- r[4] = &Dbtup::readDiskVarSizeNULLable;
- r[5] = &Dbtup::readDiskVarSizeNotNULL;
- }
- UpdateFunction u[6];
- {
- u[0] = &Dbtup::updateDiskBitsNotNULL;
- u[1] = &Dbtup::updateDiskBitsNULLable;
- u[2] = &Dbtup::updateDiskFixedSizeNotNULL;
- u[3] = &Dbtup::updateDiskFixedSizeNULLable;
- u[4] = &Dbtup::updateDiskVarSizeNULLable;
- u[5] = &Dbtup::updateDiskVarSizeNotNULL;
- }
- Uint32 a=
- AttributeDescriptor::getArrayType(attrDescr) == NDB_ARRAYTYPE_FIXED ? 2 : 4;
-
- if(AttributeDescriptor::getSize(attrDescr) == 0)
- a= 0;
-
- Uint32 b=
- AttributeDescriptor::getNullable(attrDescr)? 1 : 0;
- regTabPtr->readFunctionArray[i]= r[a+b];
- regTabPtr->updateFunctionArray[i]= u[a+b];
- }
- } else {
- if (AttributeDescriptor::getArrayType(attrDescr) == NDB_ARRAYTYPE_FIXED){
- jam();
- regTabPtr->readFunctionArray[i]= &Dbtup::readDynFixedSize;
- regTabPtr->updateFunctionArray[i]= &Dbtup::updateDynFixedSize;
- } else {
- regTabPtr->readFunctionArray[i]= &Dbtup::readDynVarSize;
- regTabPtr->updateFunctionArray[i]= &Dbtup::updateDynVarSize;
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------- */
-/* THIS ROUTINE IS USED TO READ A NUMBER OF ATTRIBUTES IN THE */
-/* DATABASE AND PLACE THE RESULT IN ATTRINFO RECORDS. */
-//
-// In addition to the parameters used in the call it also relies on the
-// following variables set-up properly.
-//
-// operPtr.p Operation record pointer
-// fragptr.p Fragment record pointer
-// tabptr.p Table record pointer
-
-// It requires the following fields in KeyReqStruct to be properly
-// filled in:
-// tuple_header Reference to the tuple
-// check_offset Record size
-// attr_descr Reference to the Table Descriptor for the table
-//
-// The read functions in addition expects that the following fields in
-// KeyReqStruct is set up:
-// out_buf_index Index for output buffer
-// max_read Size of output buffer
-// attr_descriptor Attribute Descriptor from where attribute size
-// can be read
-/* ---------------------------------------------------------------- */
-int Dbtup::readAttributes(KeyReqStruct *req_struct,
- const Uint32* inBuffer,
- Uint32 inBufLen,
- Uint32* outBuffer,
- Uint32 maxRead,
- bool xfrm_flag)
-{
- Uint32 attributeId, descr_index, tmpAttrBufIndex, inBufIndex;
- Uint32 attributeOffset;
- TableDescriptor* attr_descr;
- AttributeHeader* ahOut;
-
- Tablerec* const regTabPtr= tabptr.p;
- Uint32 numAttributes= regTabPtr->m_no_of_attributes;
-
- inBufIndex= 0;
- req_struct->out_buf_index= 0;
- req_struct->max_read= maxRead;
- req_struct->xfrm_flag= xfrm_flag;
- while (inBufIndex < inBufLen) {
- tmpAttrBufIndex= req_struct->out_buf_index;
- AttributeHeader ahIn(inBuffer[inBufIndex]);
- inBufIndex++;
- attributeId= ahIn.getAttributeId();
- descr_index= attributeId << ZAD_LOG_SIZE;
- jam();
-
- AttributeHeader::init(&outBuffer[tmpAttrBufIndex], attributeId, 0);
- ahOut= (AttributeHeader*)&outBuffer[tmpAttrBufIndex];
- req_struct->out_buf_index= tmpAttrBufIndex + 1;
- attr_descr= req_struct->attr_descr;
- if (attributeId < numAttributes) {
- attributeOffset= attr_descr[descr_index + 1].tabDescr;
- ReadFunction f= regTabPtr->readFunctionArray[attributeId];
- req_struct->attr_descriptor= attr_descr[descr_index].tabDescr;
- if ((this->*f)(outBuffer,
- req_struct,
- ahOut,
- attributeOffset)) {
- continue;
- } else {
- return -1;
- }
- } else if(attributeId & AttributeHeader::PSEUDO) {
- if (attributeId == AttributeHeader::ANY_VALUE)
- {
- jam();
- Uint32 RlogSize = req_struct->log_size;
- operPtr.p->m_any_value = inBuffer[inBufIndex];
- * (clogMemBuffer + RlogSize) = inBuffer[inBufIndex - 1];
- * (clogMemBuffer + RlogSize + 1) = inBuffer[inBufIndex];
- inBufIndex++;
- req_struct->out_buf_index = tmpAttrBufIndex;
- req_struct->log_size = RlogSize + 2;
- continue;
- }
- jam();
- Uint32 sz= read_pseudo(attributeId,
- req_struct,
- outBuffer+tmpAttrBufIndex+1);
- AttributeHeader::init(&outBuffer[tmpAttrBufIndex], attributeId, sz << 2);
- req_struct->out_buf_index= tmpAttrBufIndex + 1 + sz;
- } else {
- terrorCode = ZATTRIBUTE_ID_ERROR;
- return -1;
- }//if
- }//while
- return req_struct->out_buf_index;
-}
-
-bool
-Dbtup::readFixedSizeTHOneWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- Uint32 indexBuf= req_struct->out_buf_index;
- Uint32 readOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 const wordRead= tuple_header[readOffset];
- Uint32 newIndexBuf= indexBuf + 1;
- Uint32 maxRead= req_struct->max_read;
-
- ndbrequire(readOffset < req_struct->check_offset[MM]);
- if (newIndexBuf <= maxRead) {
- jam();
- outBuffer[indexBuf]= wordRead;
- ahOut->setDataSize(1);
- req_struct->out_buf_index= newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode= ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::readFixedSizeTHTwoWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- Uint32 indexBuf= req_struct->out_buf_index;
- Uint32 readOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 const wordReadFirst= tuple_header[readOffset];
- Uint32 const wordReadSecond= tuple_header[readOffset + 1];
- Uint32 newIndexBuf= indexBuf + 2;
- Uint32 maxRead= req_struct->max_read;
-
- ndbrequire(readOffset + 1 < req_struct->check_offset[MM]);
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setDataSize(2);
- outBuffer[indexBuf]= wordReadFirst;
- outBuffer[indexBuf + 1]= wordReadSecond;
- req_struct->out_buf_index= newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode= ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::readFixedSizeTHManyWordNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Uint32 attrDescriptor= req_struct->attr_descriptor;
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- Uint32 indexBuf= req_struct->out_buf_index;
- Uint32 readOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
- Uint32 maxRead= req_struct->max_read;
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
-
- ndbrequire((readOffset + attrNoOfWords - 1) < req_struct->check_offset[MM]);
- if (! charsetFlag || ! req_struct->xfrm_flag) {
- Uint32 newIndexBuf = indexBuf + attrNoOfWords;
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setByteSize(AttributeDescriptor::getSizeInBytes(attrDescriptor));
- MEMCOPY_NO_WORDS(&outBuffer[indexBuf],
- &tuple_header[readOffset],
- attrNoOfWords);
- req_struct->out_buf_index = newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- }//if
- } else {
- jam();
- Tablerec* regTabPtr = tabptr.p;
- Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor);
- uchar* dstPtr = (uchar*)&outBuffer[indexBuf];
- const uchar* srcPtr = (uchar*)&tuple_header[readOffset];
- Uint32 i = AttributeOffset::getCharsetPos(attrDes2);
- ndbrequire(i < regTabPtr->noOfCharsets);
- CHARSET_INFO* cs = regTabPtr->charsetArray[i];
- Uint32 typeId = AttributeDescriptor::getType(attrDescriptor);
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- Uint32 dstLen = xmul * (srcBytes - lb);
- Uint32 maxIndexBuf = indexBuf + (dstLen >> 2);
- if (maxIndexBuf <= maxRead && ok) {
- jam();
- int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
- ndbrequire(n != -1);
- int m = n;
- while ((m & 3) != 0) {
- dstPtr[m++] = 0;
- }
- ahOut->setByteSize(n);
- Uint32 newIndexBuf = indexBuf + (m >> 2);
- ndbrequire(newIndexBuf <= maxRead);
- req_struct->out_buf_index = newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- }
- }
- return false;
-}//Dbtup::readFixedSizeTHManyWordNotNULL()
-
-bool
-Dbtup::readFixedSizeTHOneWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readFixedSizeTHOneWordNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-bool
-Dbtup::readFixedSizeTHTwoWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readFixedSizeTHTwoWordNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-bool
-Dbtup::readFixedSizeTHManyWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readFixedSizeTHManyWordNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-bool
-Dbtup::readFixedSizeTHZeroWordNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- jam();
- if (nullFlagCheck(req_struct, attrDes2)) {
- jam();
- ahOut->setNULL();
- }
- return true;
-}
-
-bool
-Dbtup::nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-
- return BitmaskImpl::get(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
-}
-
-bool
-Dbtup::disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
-
- return BitmaskImpl::get(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
-}
-
-bool
-Dbtup::readVarSizeNotNULL(Uint32* out_buffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ah_out,
- Uint32 attr_des2)
-{
- Uint32 attr_descriptor, index_buf, var_index;
- Uint32 vsize_in_bytes, vsize_in_words, new_index, max_var_size;
- Uint32 var_attr_pos, max_read;
-
- Uint32 idx= req_struct->m_var_data[MM].m_var_len_offset;
- var_index= AttributeOffset::getOffset(attr_des2);
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attr_des2);
- var_attr_pos= req_struct->m_var_data[MM].m_offset_array_ptr[var_index];
- vsize_in_bytes= req_struct->m_var_data[MM].m_offset_array_ptr[var_index+idx] - var_attr_pos;
- attr_descriptor= req_struct->attr_descriptor;
- index_buf= req_struct->out_buf_index;
- max_var_size= AttributeDescriptor::getSizeInWords(attr_descriptor);
- max_read= req_struct->max_read;
- vsize_in_words= convert_byte_to_word_size(vsize_in_bytes);
- new_index= index_buf + vsize_in_words;
-
- ndbrequire(vsize_in_words <= max_var_size);
- if (! charsetFlag || ! req_struct->xfrm_flag)
- {
- if (new_index <= max_read) {
- jam();
- ah_out->setByteSize(vsize_in_bytes);
- out_buffer[index_buf + (vsize_in_bytes >> 2)] = 0;
- memcpy(out_buffer+index_buf,
- req_struct->m_var_data[MM].m_data_ptr+var_attr_pos,
- vsize_in_bytes);
- req_struct->out_buf_index= new_index;
- return true;
- }
- }
- else
- {
- jam();
- Tablerec* regTabPtr = tabptr.p;
- Uint32 maxBytes = AttributeDescriptor::getSizeInBytes(attr_descriptor);
- Uint32 srcBytes = vsize_in_bytes;
- uchar* dstPtr = (uchar*)(out_buffer+index_buf);
- const uchar* srcPtr = (uchar*)(req_struct->m_var_data[MM].m_data_ptr+var_attr_pos);
- Uint32 i = AttributeOffset::getCharsetPos(attr_des2);
- ndbrequire(i < regTabPtr->noOfCharsets);
- CHARSET_INFO* cs = regTabPtr->charsetArray[i];
- Uint32 typeId = AttributeDescriptor::getType(attr_descriptor);
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- // see comment in DbtcMain.cpp
- Uint32 dstLen = xmul * (maxBytes - lb);
- Uint32 maxIndexBuf = index_buf + (dstLen >> 2);
- if (maxIndexBuf <= max_read && ok) {
- jam();
- int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
- ndbrequire(n != -1);
- int m = n;
- while ((m & 3) != 0) {
- dstPtr[m++] = 0;
- }
- ah_out->setByteSize(n);
- Uint32 newIndexBuf = index_buf + (m >> 2);
- ndbrequire(newIndexBuf <= max_read);
- req_struct->out_buf_index = newIndexBuf;
- return true;
- }
- }
- jam();
- terrorCode= ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
-}
-
-bool
-Dbtup::readVarSizeNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readVarSizeNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-bool
-Dbtup::readDynFixedSize(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- jam();
- terrorCode= ZVAR_SIZED_NOT_SUPPORTED;
- return false;
-}
-
-bool
-Dbtup::readDynVarSize(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- jam();
- terrorCode= ZVAR_SIZED_NOT_SUPPORTED;
- return false;
-}//Dbtup::readDynBigVarSize()
-
-bool
-Dbtup::readDiskFixedSizeNotNULL(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Uint32 attrDescriptor= req_struct->attr_descriptor;
- Uint32 *tuple_header= req_struct->m_disk_ptr->m_data;
- Uint32 indexBuf= req_struct->out_buf_index;
- Uint32 readOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
- Uint32 maxRead= req_struct->max_read;
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
-
- ndbrequire((readOffset + attrNoOfWords - 1) < req_struct->check_offset[DD]);
- if (! charsetFlag || ! req_struct->xfrm_flag) {
- Uint32 newIndexBuf = indexBuf + attrNoOfWords;
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setByteSize(AttributeDescriptor::getSizeInBytes(attrDescriptor));
- MEMCOPY_NO_WORDS(&outBuffer[indexBuf],
- &tuple_header[readOffset],
- attrNoOfWords);
- req_struct->out_buf_index = newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- }//if
- } else {
- jam();
- Tablerec* regTabPtr = tabptr.p;
- Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor);
- uchar* dstPtr = (uchar*)&outBuffer[indexBuf];
- const uchar* srcPtr = (uchar*)&tuple_header[readOffset];
- Uint32 i = AttributeOffset::getCharsetPos(attrDes2);
- ndbrequire(i < regTabPtr->noOfCharsets);
- CHARSET_INFO* cs = regTabPtr->charsetArray[i];
- Uint32 typeId = AttributeDescriptor::getType(attrDescriptor);
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- Uint32 dstLen = xmul * (srcBytes - lb);
- Uint32 maxIndexBuf = indexBuf + (dstLen >> 2);
- if (maxIndexBuf <= maxRead && ok) {
- jam();
- int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
- ndbrequire(n != -1);
- int m = n;
- while ((m & 3) != 0) {
- dstPtr[m++] = 0;
- }
- ahOut->setByteSize(n);
- Uint32 newIndexBuf = indexBuf + (m >> 2);
- ndbrequire(newIndexBuf <= maxRead);
- req_struct->out_buf_index = newIndexBuf;
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- }
- }
- return false;
-}
-
-bool
-Dbtup::readDiskFixedSizeNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!disk_nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readDiskFixedSizeNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-bool
-Dbtup::readDiskVarSizeNotNULL(Uint32* out_buffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ah_out,
- Uint32 attr_des2)
-{
- Uint32 attr_descriptor, index_buf, var_index;
- Uint32 vsize_in_bytes, vsize_in_words, new_index, max_var_size;
- Uint32 var_attr_pos, max_read;
-
- Uint32 idx= req_struct->m_var_data[DD].m_var_len_offset;
- var_index= AttributeOffset::getOffset(attr_des2);
- var_attr_pos= req_struct->m_var_data[DD].m_offset_array_ptr[var_index];
- vsize_in_bytes= req_struct->m_var_data[DD].m_offset_array_ptr[var_index+idx] - var_attr_pos;
- attr_descriptor= req_struct->attr_descriptor;
- index_buf= req_struct->out_buf_index;
- max_var_size= AttributeDescriptor::getSizeInWords(attr_descriptor);
- max_read= req_struct->max_read;
- vsize_in_words= convert_byte_to_word_size(vsize_in_bytes);
- new_index= index_buf + vsize_in_words;
-
- ndbrequire(vsize_in_words <= max_var_size);
- if (new_index <= max_read) {
- jam();
- ah_out->setByteSize(vsize_in_bytes);
- memcpy(out_buffer+index_buf,
- req_struct->m_var_data[DD].m_data_ptr+var_attr_pos,
- vsize_in_bytes);
- req_struct->out_buf_index= new_index;
- return true;
- } else {
- jam();
- terrorCode= ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::readDiskVarSizeNULLable(Uint32* outBuffer,
- KeyReqStruct *req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- if (!disk_nullFlagCheck(req_struct, attrDes2)) {
- jam();
- return readDiskVarSizeNotNULL(outBuffer,
- req_struct,
- ahOut,
- attrDes2);
- } else {
- jam();
- ahOut->setNULL();
- return true;
- }
-}
-
-
-/* ---------------------------------------------------------------------- */
-/* THIS ROUTINE IS USED TO UPDATE A NUMBER OF ATTRIBUTES. IT IS */
-/* USED BY THE INSERT ROUTINE, THE UPDATE ROUTINE AND IT CAN BE */
-/* CALLED SEVERAL TIMES FROM THE INTERPRETER. */
-// In addition to the parameters used in the call it also relies on the
-// following variables set-up properly.
-//
-// operPtr.p Operation record pointer
-// tabptr.p Table record pointer
-/* ---------------------------------------------------------------------- */
-int Dbtup::updateAttributes(KeyReqStruct *req_struct,
- Uint32* inBuffer,
- Uint32 inBufLen)
-{
- Tablerec* const regTabPtr= tabptr.p;
- Operationrec* const regOperPtr= operPtr.p;
- Uint32 numAttributes= regTabPtr->m_no_of_attributes;
- TableDescriptor *attr_descr= req_struct->attr_descr;
-
- Uint32 inBufIndex= 0;
- req_struct->in_buf_index= 0;
- req_struct->in_buf_len= inBufLen;
-
- while (inBufIndex < inBufLen) {
- AttributeHeader ahIn(inBuffer[inBufIndex]);
- Uint32 attributeId= ahIn.getAttributeId();
- Uint32 attrDescriptorIndex= attributeId << ZAD_LOG_SIZE;
- if (likely(attributeId < numAttributes)) {
- Uint32 attrDescriptor= attr_descr[attrDescriptorIndex].tabDescr;
- Uint32 attributeOffset= attr_descr[attrDescriptorIndex + 1].tabDescr;
- if ((AttributeDescriptor::getPrimaryKey(attrDescriptor)) &&
- (regOperPtr->op_struct.op_type != ZINSERT)) {
- if (checkUpdateOfPrimaryKey(req_struct,
- &inBuffer[inBufIndex],
- regTabPtr)) {
- jam();
- terrorCode= ZTRY_UPDATE_PRIMARY_KEY;
- return -1;
- }
- }
- UpdateFunction f= regTabPtr->updateFunctionArray[attributeId];
- jam();
- req_struct->attr_descriptor= attrDescriptor;
- req_struct->changeMask.set(attributeId);
- if (attributeId >= 64) {
- if (req_struct->max_attr_id_updated < attributeId) {
- Uint32 no_changed_attrs= req_struct->no_changed_attrs;
- req_struct->max_attr_id_updated= attributeId;
- req_struct->no_changed_attrs= no_changed_attrs + 1;
- }
- }
- if ((this->*f)(inBuffer,
- req_struct,
- attributeOffset)) {
- inBufIndex= req_struct->in_buf_index;
- continue;
- } else {
- jam();
- return -1;
- }
- }
- else if(attributeId == AttributeHeader::DISK_REF)
- {
- jam();
- Uint32 sz= ahIn.getDataSize();
- ndbrequire(sz == 2);
- req_struct->m_tuple_ptr->m_header_bits |= Tuple_header::DISK_PART;
- memcpy(req_struct->m_tuple_ptr->get_disk_ref_ptr(regTabPtr),
- inBuffer+inBufIndex+1, sz << 2);
- inBufIndex += 1 + sz;
- req_struct->in_buf_index = inBufIndex;
- }
- else if(attributeId == AttributeHeader::ANY_VALUE)
- {
- jam();
- Uint32 sz= ahIn.getDataSize();
- ndbrequire(sz == 1);
- regOperPtr->m_any_value = * (inBuffer + inBufIndex + 1);
- inBufIndex += 1 + sz;
- req_struct->in_buf_index = inBufIndex;
- }
- else
- {
- jam();
- terrorCode= ZATTRIBUTE_ID_ERROR;
- return -1;
- }
- }
- return 0;
-}
-
-bool
-Dbtup::checkUpdateOfPrimaryKey(KeyReqStruct* req_struct,
- Uint32* updateBuffer,
- Tablerec* const regTabPtr)
-{
- Uint32 keyReadBuffer[MAX_KEY_SIZE_IN_WORDS];
- TableDescriptor* attr_descr = req_struct->attr_descr;
- AttributeHeader ahIn(*updateBuffer);
- Uint32 attributeId = ahIn.getAttributeId();
- Uint32 attrDescriptorIndex = attributeId << ZAD_LOG_SIZE;
- Uint32 attrDescriptor = attr_descr[attrDescriptorIndex].tabDescr;
- Uint32 attributeOffset = attr_descr[attrDescriptorIndex + 1].tabDescr;
-
- Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset);
- if (charsetFlag) {
- Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset);
- CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex];
- Uint32 srcPos = 0;
- Uint32 dstPos = 0;
- xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos,
- &xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY);
- ahIn.setDataSize(dstPos);
- xfrmBuffer[0] = ahIn.m_value;
- updateBuffer = xfrmBuffer;
- }
-
- ReadFunction f = regTabPtr->readFunctionArray[attributeId];
-
- AttributeHeader attributeHeader(attributeId, 0);
- req_struct->out_buf_index = 0;
- req_struct->max_read = MAX_KEY_SIZE_IN_WORDS;
- req_struct->attr_descriptor = attrDescriptor;
-
- bool tmp = req_struct->xfrm_flag;
- req_struct->xfrm_flag = true;
- ndbrequire((this->*f)(&keyReadBuffer[0],
- req_struct,
- &attributeHeader,
- attributeOffset));
- req_struct->xfrm_flag = tmp;
-
- ndbrequire(req_struct->out_buf_index == attributeHeader.getDataSize());
- if (ahIn.getDataSize() != attributeHeader.getDataSize()) {
- jam();
- return true;
- }
- if (memcmp(&keyReadBuffer[0],
- &updateBuffer[1],
- req_struct->out_buf_index << 2) != 0) {
- jam();
- return true;
- }
- return false;
-}
-
-bool
-Dbtup::updateFixedSizeTHOneWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Uint32 indexBuf= req_struct->in_buf_index;
- Uint32 inBufLen= req_struct->in_buf_len;
- Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 newIndex= indexBuf + 2;
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- ndbrequire(updateOffset < req_struct->check_offset[MM]);
-
- if (newIndex <= inBufLen) {
- Uint32 updateWord= inBuffer[indexBuf + 1];
- if (!nullIndicator) {
- jam();
- req_struct->in_buf_index= newIndex;
- tuple_header[updateOffset]= updateWord;
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- return true;
-}
-
-bool
-Dbtup::updateFixedSizeTHTwoWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Uint32 indexBuf= req_struct->in_buf_index;
- Uint32 inBufLen= req_struct->in_buf_len;
- Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 newIndex= indexBuf + 3;
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- ndbrequire((updateOffset + 1) < req_struct->check_offset[MM]);
-
- if (newIndex <= inBufLen) {
- Uint32 updateWord1= inBuffer[indexBuf + 1];
- Uint32 updateWord2= inBuffer[indexBuf + 2];
- if (!nullIndicator) {
- jam();
- req_struct->in_buf_index= newIndex;
- tuple_header[updateOffset]= updateWord1;
- tuple_header[updateOffset + 1]= updateWord2;
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Uint32 attrDescriptor= req_struct->attr_descriptor;
- Uint32 indexBuf= req_struct->in_buf_index;
- Uint32 inBufLen= req_struct->in_buf_len;
- Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
-
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 noOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 newIndex= indexBuf + noOfWords + 1;
- Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
- ndbrequire((updateOffset + noOfWords - 1) < req_struct->check_offset[MM]);
-
- if (newIndex <= inBufLen) {
- if (!nullIndicator) {
- jam();
- if (charsetFlag) {
- jam();
- Tablerec* regTabPtr = tabptr.p;
- Uint32 typeId = AttributeDescriptor::getType(attrDescriptor);
- Uint32 bytes = AttributeDescriptor::getSizeInBytes(attrDescriptor);
- Uint32 i = AttributeOffset::getCharsetPos(attrDes2);
- ndbrequire(i < regTabPtr->noOfCharsets);
- // not const in MySQL
- CHARSET_INFO* cs = regTabPtr->charsetArray[i];
- int not_used;
- const char* ssrc = (const char*)&inBuffer[indexBuf + 1];
- Uint32 lb, len;
- if (! NdbSqlUtil::get_var_length(typeId, ssrc, bytes, lb, len)) {
- jam();
- terrorCode = ZINVALID_CHAR_FORMAT;
- return false;
- }
- // fast fix bug#7340
- if (typeId != NDB_TYPE_TEXT &&
- (*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL, &not_used) != len) {
- jam();
- terrorCode = ZINVALID_CHAR_FORMAT;
- return false;
- }
- }
- req_struct->in_buf_index= newIndex;
- MEMCOPY_NO_WORDS(&tuple_header[updateOffset],
- &inBuffer[indexBuf + 1],
- noOfWords);
-
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::updateFixedSizeTHManyWordNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-
- if (!nullIndicator) {
- jam();
- BitmaskImpl::clear(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
- return updateFixedSizeTHManyWordNotNULL(inBuffer,
- req_struct,
- attrDes2);
- } else {
- Uint32 newIndex= req_struct->in_buf_index + 1;
- if (newIndex <= req_struct->in_buf_len) {
- BitmaskImpl::set(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
- jam();
- req_struct->in_buf_index= newIndex;
- return true;
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- }
-}
-
-bool
-Dbtup::updateVarSizeNotNULL(Uint32* in_buffer,
- KeyReqStruct *req_struct,
- Uint32 attr_des2)
-{
- Uint32 attr_descriptor, index_buf, in_buf_len, var_index, null_ind;
- Uint32 vsize_in_words, new_index, max_var_size;
- Uint32 var_attr_pos;
- char *var_data_start;
- Uint16 *vpos_array;
-
- attr_descriptor= req_struct->attr_descriptor;
- index_buf= req_struct->in_buf_index;
- in_buf_len= req_struct->in_buf_len;
- var_index= AttributeOffset::getOffset(attr_des2);
- AttributeHeader ahIn(in_buffer[index_buf]);
- null_ind= ahIn.isNULL();
- Uint32 size_in_bytes = ahIn.getByteSize();
- vsize_in_words= (size_in_bytes + 3) >> 2;
- max_var_size= AttributeDescriptor::getSizeInBytes(attr_descriptor);
- new_index= index_buf + vsize_in_words + 1;
- vpos_array= req_struct->m_var_data[MM].m_offset_array_ptr;
- Uint32 idx= req_struct->m_var_data[MM].m_var_len_offset;
- Uint32 check_offset= req_struct->m_var_data[MM].m_max_var_offset;
-
- if (new_index <= in_buf_len && vsize_in_words <= max_var_size) {
- if (!null_ind) {
- jam();
- var_attr_pos= vpos_array[var_index];
- var_data_start= req_struct->m_var_data[MM].m_data_ptr;
- vpos_array[var_index+idx]= var_attr_pos+size_in_bytes;
- req_struct->in_buf_index= new_index;
-
- ndbrequire(var_attr_pos+size_in_bytes <= check_offset);
- memcpy(var_data_start+var_attr_pos, &in_buffer[index_buf + 1],
- size_in_bytes);
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- return false;
-}
-
-bool
-Dbtup::updateVarSizeNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
- Uint32 idx= req_struct->m_var_data[MM].m_var_len_offset;
-
- if (!nullIndicator) {
- jam();
- BitmaskImpl::clear(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
- return updateVarSizeNotNULL(inBuffer,
- req_struct,
- attrDes2);
- } else {
- Uint32 newIndex= req_struct->in_buf_index + 1;
- Uint32 var_index= AttributeOffset::getOffset(attrDes2);
- Uint32 var_pos= req_struct->var_pos_array[var_index];
- if (newIndex <= req_struct->in_buf_len) {
- jam();
- BitmaskImpl::set(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
- req_struct->var_pos_array[var_index+idx]= var_pos;
- req_struct->in_buf_index= newIndex;
- return true;
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- }
-}
-
-bool
-Dbtup::updateDynFixedSize(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- jam();
- terrorCode= ZVAR_SIZED_NOT_SUPPORTED;
- return false;
-}
-
-bool
-Dbtup::updateDynVarSize(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- jam();
- terrorCode= ZVAR_SIZED_NOT_SUPPORTED;
- return false;
-}
-
-Uint32
-Dbtup::read_pseudo(Uint32 attrId,
- KeyReqStruct *req_struct,
- Uint32* outBuffer)
-{
- Uint32 tmp[sizeof(SignalHeader)+25];
- Signal * signal = (Signal*)&tmp;
- switch(attrId){
- case AttributeHeader::FRAGMENT:
- * outBuffer = fragptr.p->fragmentId;
- return 1;
- case AttributeHeader::FRAGMENT_FIXED_MEMORY:
- {
- Uint64 tmp= fragptr.p->noOfPages;
- tmp*= 32768;
- memcpy(outBuffer,&tmp,8);
- }
- return 2;
- case AttributeHeader::FRAGMENT_VARSIZED_MEMORY:
- {
- Uint64 tmp= fragptr.p->noOfVarPages;
- tmp*= 32768;
- memcpy(outBuffer,&tmp,8);
- }
- return 2;
- case AttributeHeader::ROW_SIZE:
- * outBuffer = tabptr.p->m_offsets[MM].m_fix_header_size << 2;
- return 1;
- case AttributeHeader::ROW_COUNT:
- case AttributeHeader::COMMIT_COUNT:
- signal->theData[0] = operPtr.p->userpointer;
- signal->theData[1] = attrId;
-
- EXECUTE_DIRECT(DBLQH, GSN_READ_PSEUDO_REQ, signal, 2);
- outBuffer[0] = signal->theData[0];
- outBuffer[1] = signal->theData[1];
- return 2;
- case AttributeHeader::RANGE_NO:
- signal->theData[0] = operPtr.p->userpointer;
- signal->theData[1] = attrId;
-
- EXECUTE_DIRECT(DBLQH, GSN_READ_PSEUDO_REQ, signal, 2);
- outBuffer[0] = signal->theData[0];
- return 1;
- case AttributeHeader::DISK_REF:
- {
- Uint32 *ref= req_struct->m_tuple_ptr->get_disk_ref_ptr(tabptr.p);
- outBuffer[0] = ref[0];
- outBuffer[1] = ref[1];
- return 2;
- }
- case AttributeHeader::RECORDS_IN_RANGE:
- signal->theData[0] = operPtr.p->userpointer;
- signal->theData[1] = attrId;
-
- EXECUTE_DIRECT(DBLQH, GSN_READ_PSEUDO_REQ, signal, 2);
- outBuffer[0] = signal->theData[0];
- outBuffer[1] = signal->theData[1];
- outBuffer[2] = signal->theData[2];
- outBuffer[3] = signal->theData[3];
- return 4;
- case AttributeHeader::ROWID:
- outBuffer[0] = req_struct->frag_page_id;
- outBuffer[1] = operPtr.p->m_tuple_location.m_page_idx;
- return 2;
- case AttributeHeader::ROW_GCI:
- if (tabptr.p->m_bits & Tablerec::TR_RowGCI)
- {
- Uint64 tmp = * req_struct->m_tuple_ptr->get_mm_gci(tabptr.p);
- memcpy(outBuffer, &tmp, sizeof(tmp));
- return 2;
- }
- return 0;
- case AttributeHeader::COPY_ROWID:
- outBuffer[0] = operPtr.p->m_copy_tuple_location.m_page_no;
- outBuffer[1] = operPtr.p->m_copy_tuple_location.m_page_idx;
- return 2;
- default:
- return 0;
- }
-}
-
-bool
-Dbtup::readBitsNotNULL(Uint32* outBuffer,
- KeyReqStruct* req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 indexBuf = req_struct->out_buf_index;
- Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
- Uint32 maxRead = req_struct->max_read;
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setDataSize((bitCount + 31) >> 5);
- req_struct->out_buf_index = newIndexBuf;
-
- BitmaskImpl::getField(regTabPtr->m_offsets[MM].m_null_words, bits, pos,
- bitCount, outBuffer+indexBuf);
-
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }//if
-}
-
-bool
-Dbtup::readBitsNULLable(Uint32* outBuffer,
- KeyReqStruct* req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
-
- Uint32 indexBuf = req_struct->out_buf_index;
- Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
- Uint32 maxRead = req_struct->max_read;
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-
- if(BitmaskImpl::get(regTabPtr->m_offsets[MM].m_null_words, bits, pos))
- {
- jam();
- ahOut->setNULL();
- return true;
- }
-
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setDataSize((bitCount + 31) >> 5);
- req_struct->out_buf_index = newIndexBuf;
- BitmaskImpl::getField(regTabPtr->m_offsets[MM].m_null_words, bits, pos+1,
- bitCount, outBuffer+indexBuf);
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }//if
-}
-
-bool
-Dbtup::updateBitsNotNULL(Uint32* inBuffer,
- KeyReqStruct* req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 indexBuf = req_struct->in_buf_index;
- Uint32 inBufLen = req_struct->in_buf_len;
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator = ahIn.isNULL();
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-
- if (newIndex <= inBufLen) {
- if (!nullIndicator) {
- BitmaskImpl::setField(regTabPtr->m_offsets[MM].m_null_words, bits, pos,
- bitCount, inBuffer+indexBuf+1);
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- jam();
- terrorCode = ZNOT_NULL_ATTR;
- return false;
- }//if
- } else {
- jam();
- terrorCode = ZAI_INCONSISTENCY_ERROR;
- return false;
- }//if
- return true;
-}
-
-bool
-Dbtup::updateBitsNULLable(Uint32* inBuffer,
- KeyReqStruct* req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 indexBuf = req_struct->in_buf_index;
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator = ahIn.isNULL();
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-
- if (!nullIndicator) {
- BitmaskImpl::clear(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
- BitmaskImpl::setField(regTabPtr->m_offsets[MM].m_null_words, bits, pos+1,
- bitCount, inBuffer+indexBuf+1);
-
- Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- Uint32 newIndex = indexBuf + 1;
- if (newIndex <= req_struct->in_buf_len)
- {
- jam();
- BitmaskImpl::set(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
-
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- jam();
- terrorCode = ZAI_INCONSISTENCY_ERROR;
- return false;
- }//if
- }//if
-}
-
-bool
-Dbtup::updateDiskFixedSizeNotNULL(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Uint32 attrDescriptor= req_struct->attr_descriptor;
- Uint32 indexBuf= req_struct->in_buf_index;
- Uint32 inBufLen= req_struct->in_buf_len;
- Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
- Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
-
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 noOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 newIndex= indexBuf + noOfWords + 1;
- Uint32 *tuple_header= req_struct->m_disk_ptr->m_data;
- ndbrequire((updateOffset + noOfWords - 1) < req_struct->check_offset[DD]);
-
- if (newIndex <= inBufLen) {
- if (!nullIndicator) {
- jam();
- if (charsetFlag) {
- jam();
- Tablerec* regTabPtr = tabptr.p;
- Uint32 typeId = AttributeDescriptor::getType(attrDescriptor);
- Uint32 bytes = AttributeDescriptor::getSizeInBytes(attrDescriptor);
- Uint32 i = AttributeOffset::getCharsetPos(attrDes2);
- ndbrequire(i < regTabPtr->noOfCharsets);
- // not const in MySQL
- CHARSET_INFO* cs = regTabPtr->charsetArray[i];
- int not_used;
- const char* ssrc = (const char*)&inBuffer[indexBuf + 1];
- Uint32 lb, len;
- if (! NdbSqlUtil::get_var_length(typeId, ssrc, bytes, lb, len)) {
- jam();
- terrorCode = ZINVALID_CHAR_FORMAT;
- return false;
- }
- // fast fix bug#7340
- if (typeId != NDB_TYPE_TEXT &&
- (*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL, &not_used) != len) {
- jam();
- terrorCode = ZINVALID_CHAR_FORMAT;
- return false;
- }
- }
- req_struct->in_buf_index= newIndex;
- MEMCOPY_NO_WORDS(&tuple_header[updateOffset],
- &inBuffer[indexBuf + 1],
- noOfWords);
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
-}
-
-bool
-Dbtup::updateDiskFixedSizeNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-
- if (!nullIndicator) {
- jam();
- BitmaskImpl::clear(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
- return updateDiskFixedSizeNotNULL(inBuffer,
- req_struct,
- attrDes2);
- } else {
- Uint32 newIndex= req_struct->in_buf_index + 1;
- if (newIndex <= req_struct->in_buf_len) {
- BitmaskImpl::set(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
- jam();
- req_struct->in_buf_index= newIndex;
- return true;
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- }
-}
-
-bool
-Dbtup::updateDiskVarSizeNotNULL(Uint32* in_buffer,
- KeyReqStruct *req_struct,
- Uint32 attr_des2)
-{
- Uint32 attr_descriptor, index_buf, in_buf_len, var_index, null_ind;
- Uint32 vsize_in_words, new_index, max_var_size;
- Uint32 var_attr_pos;
- char *var_data_start;
- Uint16 *vpos_array;
-
- attr_descriptor= req_struct->attr_descriptor;
- index_buf= req_struct->in_buf_index;
- in_buf_len= req_struct->in_buf_len;
- var_index= AttributeOffset::getOffset(attr_des2);
- AttributeHeader ahIn(in_buffer[index_buf]);
- null_ind= ahIn.isNULL();
- Uint32 size_in_bytes = ahIn.getByteSize();
- vsize_in_words= (size_in_bytes + 3) >> 2;
- max_var_size= AttributeDescriptor::getSizeInBytes(attr_descriptor);
- new_index= index_buf + vsize_in_words + 1;
- vpos_array= req_struct->m_var_data[DD].m_offset_array_ptr;
- Uint32 idx= req_struct->m_var_data[DD].m_var_len_offset;
- Uint32 check_offset= req_struct->m_var_data[DD].m_max_var_offset;
-
- if (new_index <= in_buf_len && vsize_in_words <= max_var_size) {
- if (!null_ind) {
- jam();
- var_attr_pos= vpos_array[var_index];
- var_data_start= req_struct->m_var_data[DD].m_data_ptr;
- vpos_array[var_index+idx]= var_attr_pos+size_in_bytes;
- req_struct->in_buf_index= new_index;
-
- ndbrequire(var_attr_pos+size_in_bytes <= check_offset);
- memcpy(var_data_start+var_attr_pos, &in_buffer[index_buf + 1],
- size_in_bytes);
- return true;
- } else {
- jam();
- terrorCode= ZNOT_NULL_ATTR;
- return false;
- }
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- return false;
-}
-
-bool
-Dbtup::updateDiskVarSizeNULLable(Uint32* inBuffer,
- KeyReqStruct *req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr= tabptr.p;
- AttributeHeader ahIn(inBuffer[req_struct->in_buf_index]);
- Uint32 nullIndicator= ahIn.isNULL();
- Uint32 pos= AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
- Uint32 idx= req_struct->m_var_data[DD].m_var_len_offset;
-
- if (!nullIndicator) {
- jam();
- BitmaskImpl::clear(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
- return updateDiskVarSizeNotNULL(inBuffer,
- req_struct,
- attrDes2);
- } else {
- Uint32 newIndex= req_struct->in_buf_index + 1;
- Uint32 var_index= AttributeOffset::getOffset(attrDes2);
- Uint32 var_pos= req_struct->var_pos_array[var_index];
- if (newIndex <= req_struct->in_buf_len) {
- jam();
- BitmaskImpl::set(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
- req_struct->var_pos_array[var_index+idx]= var_pos;
- req_struct->in_buf_index= newIndex;
- return true;
- } else {
- jam();
- terrorCode= ZAI_INCONSISTENCY_ERROR;
- return false;
- }
- }
-}
-
-bool
-Dbtup::readDiskBitsNotNULL(Uint32* outBuffer,
- KeyReqStruct* req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 indexBuf = req_struct->out_buf_index;
- Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
- Uint32 maxRead = req_struct->max_read;
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setDataSize((bitCount + 31) >> 5);
- req_struct->out_buf_index = newIndexBuf;
-
- BitmaskImpl::getField(regTabPtr->m_offsets[DD].m_null_words, bits, pos,
- bitCount, outBuffer+indexBuf);
-
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }//if
-}
-
-bool
-Dbtup::readDiskBitsNULLable(Uint32* outBuffer,
- KeyReqStruct* req_struct,
- AttributeHeader* ahOut,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
-
- Uint32 indexBuf = req_struct->out_buf_index;
- Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
- Uint32 maxRead = req_struct->max_read;
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-
- if(BitmaskImpl::get(regTabPtr->m_offsets[DD].m_null_words, bits, pos))
- {
- jam();
- ahOut->setNULL();
- return true;
- }
-
- if (newIndexBuf <= maxRead) {
- jam();
- ahOut->setDataSize((bitCount + 31) >> 5);
- req_struct->out_buf_index = newIndexBuf;
- BitmaskImpl::getField(regTabPtr->m_offsets[DD].m_null_words, bits, pos+1,
- bitCount, outBuffer+indexBuf);
- return true;
- } else {
- jam();
- terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR;
- return false;
- }//if
-}
-
-bool
-Dbtup::updateDiskBitsNotNULL(Uint32* inBuffer,
- KeyReqStruct* req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 indexBuf = req_struct->in_buf_index;
- Uint32 inBufLen = req_struct->in_buf_len;
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator = ahIn.isNULL();
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-
- if (newIndex <= inBufLen) {
- if (!nullIndicator) {
- BitmaskImpl::setField(regTabPtr->m_offsets[DD].m_null_words, bits, pos,
- bitCount, inBuffer+indexBuf+1);
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- jam();
- terrorCode = ZNOT_NULL_ATTR;
- return false;
- }//if
- } else {
- jam();
- terrorCode = ZAI_INCONSISTENCY_ERROR;
- return false;
- }//if
- return true;
-}
-
-bool
-Dbtup::updateDiskBitsNULLable(Uint32* inBuffer,
- KeyReqStruct* req_struct,
- Uint32 attrDes2)
-{
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 indexBuf = req_struct->in_buf_index;
- AttributeHeader ahIn(inBuffer[indexBuf]);
- Uint32 nullIndicator = ahIn.isNULL();
- Uint32 pos = AttributeOffset::getNullFlagPos(attrDes2);
- Uint32 bitCount =
- AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
- Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-
- if (!nullIndicator) {
- BitmaskImpl::clear(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
- BitmaskImpl::setField(regTabPtr->m_offsets[DD].m_null_words, bits, pos+1,
- bitCount, inBuffer+indexBuf+1);
-
- Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- Uint32 newIndex = indexBuf + 1;
- if (newIndex <= req_struct->in_buf_len)
- {
- jam();
- BitmaskImpl::set(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
-
- req_struct->in_buf_index = newIndex;
- return true;
- } else {
- jam();
- terrorCode = ZAI_INCONSISTENCY_ERROR;
- return false;
- }//if
- }//if
-}
-
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
deleted file mode 100644
index 572be897a13..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
+++ /dev/null
@@ -1,1209 +0,0 @@
-/* Copyright (c) 2003, 2005-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_SCAN_CPP
-#include "Dbtup.hpp"
-#include <signaldata/AccScan.hpp>
-#include <signaldata/NextScan.hpp>
-#include <signaldata/AccLock.hpp>
-#include <md5_hash.hpp>
-
-#undef jam
-#undef jamEntry
-#define jam() { jamLine(32000 + __LINE__); }
-#define jamEntry() { jamEntryLine(32000 + __LINE__); }
-
-#ifdef VM_TRACE
-#define dbg(x) globalSignalLoggers.log x
-#else
-#define dbg(x)
-#endif
-
-void
-Dbtup::execACC_SCANREQ(Signal* signal)
-{
- jamEntry();
- const AccScanReq reqCopy = *(const AccScanReq*)signal->getDataPtr();
- const AccScanReq* const req = &reqCopy;
- ScanOpPtr scanPtr;
- scanPtr.i = RNIL;
- do {
- // find table and fragment
- TablerecPtr tablePtr;
- tablePtr.i = req->tableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- FragrecordPtr fragPtr;
- Uint32 fragId = req->fragmentNo;
- fragPtr.i = RNIL;
- getFragmentrec(fragPtr, fragId, tablePtr.p);
- ndbrequire(fragPtr.i != RNIL);
- Fragrecord& frag = *fragPtr.p;
- // flags
- Uint32 bits = 0;
-
-
- if (AccScanReq::getLcpScanFlag(req->requestInfo))
- {
- jam();
- bits |= ScanOp::SCAN_LCP;
- c_scanOpPool.getPtr(scanPtr, c_lcp_scan_op);
- }
- else
- {
- // seize from pool and link to per-fragment list
- LocalDLList<ScanOp> list(c_scanOpPool, frag.m_scanList);
- if (! list.seize(scanPtr)) {
- jam();
- break;
- }
- }
-
- if (!AccScanReq::getNoDiskScanFlag(req->requestInfo)
- && tablePtr.p->m_no_of_disk_attributes)
- {
- bits |= ScanOp::SCAN_DD;
- }
-
- bool mm = (bits & ScanOp::SCAN_DD);
- if (tablePtr.p->m_attributes[mm].m_no_of_varsize > 0) {
- bits |= ScanOp::SCAN_VS;
-
- // disk pages have fixed page format
- ndbrequire(! (bits & ScanOp::SCAN_DD));
- }
- if (! AccScanReq::getReadCommittedFlag(req->requestInfo)) {
- if (AccScanReq::getLockMode(req->requestInfo) == 0)
- bits |= ScanOp::SCAN_LOCK_SH;
- else
- bits |= ScanOp::SCAN_LOCK_EX;
- }
-
- if (AccScanReq::getNRScanFlag(req->requestInfo))
- {
- jam();
- bits |= ScanOp::SCAN_NR;
- scanPtr.p->m_endPage = req->maxPage;
- if (req->maxPage != RNIL && req->maxPage > frag.noOfPages)
- {
- ndbout_c("%u %u endPage: %u (noOfPages: %u)",
- tablePtr.i, fragId,
- req->maxPage, fragPtr.p->noOfPages);
- }
- }
- else
- {
- jam();
- scanPtr.p->m_endPage = RNIL;
- }
-
- if (AccScanReq::getLcpScanFlag(req->requestInfo))
- {
- jam();
- ndbrequire((bits & ScanOp::SCAN_DD) == 0);
- ndbrequire((bits & ScanOp::SCAN_LOCK) == 0);
- }
-
- // set up scan op
- new (scanPtr.p) ScanOp();
- ScanOp& scan = *scanPtr.p;
- scan.m_state = ScanOp::First;
- scan.m_bits = bits;
- scan.m_userPtr = req->senderData;
- scan.m_userRef = req->senderRef;
- scan.m_tableId = tablePtr.i;
- scan.m_fragId = frag.fragmentId;
- scan.m_fragPtrI = fragPtr.i;
- scan.m_transId1 = req->transId1;
- scan.m_transId2 = req->transId2;
- scan.m_savePointId = req->savePointId;
-
- // conf
- AccScanConf* const conf = (AccScanConf*)signal->getDataPtrSend();
- conf->scanPtr = req->senderData;
- conf->accPtr = scanPtr.i;
- conf->flag = AccScanConf::ZNOT_EMPTY_FRAGMENT;
- sendSignal(req->senderRef, GSN_ACC_SCANCONF,
- signal, AccScanConf::SignalLength, JBB);
- return;
- } while (0);
- if (scanPtr.i != RNIL) {
- jam();
- releaseScanOp(scanPtr);
- }
- // LQH does not handle REF
- signal->theData[0] = 0x313;
- sendSignal(req->senderRef, GSN_ACC_SCANREF, signal, 1, JBB);
-}
-
-void
-Dbtup::execNEXT_SCANREQ(Signal* signal)
-{
- jamEntry();
- const NextScanReq reqCopy = *(const NextScanReq*)signal->getDataPtr();
- const NextScanReq* const req = &reqCopy;
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, req->accPtr);
- ScanOp& scan = *scanPtr.p;
- switch (req->scanFlag) {
- case NextScanReq::ZSCAN_NEXT:
- jam();
- break;
- case NextScanReq::ZSCAN_NEXT_COMMIT:
- jam();
- case NextScanReq::ZSCAN_COMMIT:
- jam();
- if ((scan.m_bits & ScanOp::SCAN_LOCK) != 0) {
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Unlock;
- lockReq->accOpPtr = req->accOperationPtr;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ,
- signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- removeAccLockOp(scan, req->accOperationPtr);
- }
- if (req->scanFlag == NextScanReq::ZSCAN_COMMIT) {
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- unsigned signalLength = 1;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return;
- }
- break;
- case NextScanReq::ZSCAN_CLOSE:
- jam();
- if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
- jam();
- ndbrequire(scan.m_accLockOp != RNIL);
- // use ACC_ABORTCONF to flush out any reply in job buffer
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::AbortWithConf;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ,
- signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_state = ScanOp::Aborting;
- return;
- }
- if (scan.m_state == ScanOp::Locked) {
- jam();
- ndbrequire(scan.m_accLockOp != RNIL);
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ,
- signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- }
- scan.m_state = ScanOp::Aborting;
- scanClose(signal, scanPtr);
- return;
- case NextScanReq::ZSCAN_NEXT_ABORT:
- jam();
- default:
- jam();
- ndbrequire(false);
- break;
- }
- // start looking for next scan result
- AccCheckScan* checkReq = (AccCheckScan*)signal->getDataPtrSend();
- checkReq->accPtr = scanPtr.i;
- checkReq->checkLcpStop = AccCheckScan::ZNOT_CHECK_LCP_STOP;
- EXECUTE_DIRECT(DBTUP, GSN_ACC_CHECK_SCAN, signal, AccCheckScan::SignalLength);
- jamEntry();
-}
-
-void
-Dbtup::execACC_CHECK_SCAN(Signal* signal)
-{
- jamEntry();
- const AccCheckScan reqCopy = *(const AccCheckScan*)signal->getDataPtr();
- const AccCheckScan* const req = &reqCopy;
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, req->accPtr);
- ScanOp& scan = *scanPtr.p;
- // fragment
- FragrecordPtr fragPtr;
- fragPtr.i = scan.m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- Fragrecord& frag = *fragPtr.p;
- if (req->checkLcpStop == AccCheckScan::ZCHECK_LCP_STOP) {
- jam();
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return;
- }
- if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
- jam();
- // LQH asks if we are waiting for lock and we tell it to ask again
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = RNIL; // no tuple returned
- conf->fragId = frag.fragmentId;
- unsigned signalLength = 3;
- // if TC has ordered scan close, it will be detected here
- sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return; // stop
- }
- if (scan.m_state == ScanOp::First) {
- jam();
- scanFirst(signal, scanPtr);
- }
- if (scan.m_state == ScanOp::Next) {
- jam();
- bool immediate = scanNext(signal, scanPtr);
- if (! immediate) {
- jam();
- // time-slicing via TUP or PGMAN
- return;
- }
- }
- scanReply(signal, scanPtr);
-}
-
-void
-Dbtup::scanReply(Signal* signal, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- FragrecordPtr fragPtr;
- fragPtr.i = scan.m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- Fragrecord& frag = *fragPtr.p;
- // for reading tuple key in Current state
- Uint32* pkData = (Uint32*)c_dataBuffer;
- unsigned pkSize = 0;
- if (scan.m_state == ScanOp::Current) {
- // found an entry to return
- jam();
- ndbrequire(scan.m_accLockOp == RNIL);
- if (scan.m_bits & ScanOp::SCAN_LOCK) {
- jam();
- // read tuple key - use TUX routine
- const ScanPos& pos = scan.m_scanPos;
- const Local_key& key_mm = pos.m_key_mm;
- int ret = tuxReadPk(fragPtr.i, pos.m_realpid_mm, key_mm.m_page_idx,
- pkData, true);
- ndbrequire(ret > 0);
- pkSize = ret;
- dbg((DBTUP, "PK size=%d data=%08x", pkSize, pkData[0]));
- // get read lock or exclusive lock
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = (scan.m_bits & ScanOp::SCAN_LOCK_SH) ?
- AccLockReq::LockShared : AccLockReq::LockExclusive;
- lockReq->accOpPtr = RNIL;
- lockReq->userPtr = scanPtr.i;
- lockReq->userRef = reference();
- lockReq->tableId = scan.m_tableId;
- lockReq->fragId = frag.fragmentId;
- lockReq->fragPtrI = RNIL; // no cached frag ptr yet
- lockReq->hashValue = md5_hash((Uint64*)pkData, pkSize);
- lockReq->tupAddr = key_mm.ref();
- lockReq->transId1 = scan.m_transId1;
- lockReq->transId2 = scan.m_transId2;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ,
- signal, AccLockReq::LockSignalLength);
- jamEntry();
- switch (lockReq->returnCode) {
- case AccLockReq::Success:
- jam();
- scan.m_state = ScanOp::Locked;
- scan.m_accLockOp = lockReq->accOpPtr;
- break;
- case AccLockReq::IsBlocked:
- jam();
- // normal lock wait
- scan.m_state = ScanOp::Blocked;
- scan.m_bits |= ScanOp::SCAN_LOCK_WAIT;
- scan.m_accLockOp = lockReq->accOpPtr;
- // LQH will wake us up
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return;
- break;
- case AccLockReq::Refused:
- jam();
- // we cannot see deleted tuple (assert only)
- ndbassert(false);
- // skip it
- scan.m_state = ScanOp::Next;
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return;
- break;
- case AccLockReq::NoFreeOp:
- jam();
- // max ops should depend on max scans (assert only)
- ndbassert(false);
- // stay in Current state
- scan.m_state = ScanOp::Current;
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return;
- break;
- default:
- ndbrequire(false);
- break;
- }
- } else {
- scan.m_state = ScanOp::Locked;
- }
- }
-
- if (scan.m_state == ScanOp::Locked) {
- // we have lock or do not need one
- jam();
- // conf signal
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- // the lock is passed to LQH
- Uint32 accLockOp = scan.m_accLockOp;
- if (accLockOp != RNIL) {
- scan.m_accLockOp = RNIL;
- // remember it until LQH unlocks it
- addAccLockOp(scan, accLockOp);
- } else {
- ndbrequire(! (scan.m_bits & ScanOp::SCAN_LOCK));
- // operation RNIL in LQH would signal no tuple returned
- accLockOp = (Uint32)-1;
- }
- const ScanPos& pos = scan.m_scanPos;
- conf->accOperationPtr = accLockOp;
- conf->fragId = frag.fragmentId;
- conf->localKey[0] = pos.m_key_mm.ref();
- conf->localKey[1] = 0;
- conf->localKeyLength = 1;
- unsigned signalLength = 6;
- if (scan.m_bits & ScanOp::SCAN_LOCK) {
- sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- } else {
- Uint32 blockNo = refToBlock(scan.m_userRef);
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, signalLength);
- jamEntry();
- }
- // next time look for next entry
- scan.m_state = ScanOp::Next;
- return;
- }
- if (scan.m_state == ScanOp::Last ||
- scan.m_state == ScanOp::Invalid) {
- jam();
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = RNIL;
- conf->fragId = RNIL;
- unsigned signalLength = 3;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return;
- }
- ndbrequire(false);
-}
-
-/*
- * Lock succeeded (after delay) in ACC. If the lock is for current
- * entry, set state to Locked. If the lock is for an entry we were
- * moved away from, simply unlock it. Finally, if we are closing the
- * scan, do nothing since we have already sent an abort request.
- */
-void
-Dbtup::execACCKEYCONF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
- ndbrequire(scan.m_bits & ScanOp::SCAN_LOCK_WAIT && scan.m_accLockOp != RNIL);
- scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
- if (scan.m_state == ScanOp::Blocked) {
- // the lock wait was for current entry
- jam();
- scan.m_state = ScanOp::Locked;
- // LQH has the ball
- return;
- }
- if (scan.m_state != ScanOp::Aborting) {
- // we were moved, release lock
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- // LQH has the ball
- return;
- }
- // lose the lock
- scan.m_accLockOp = RNIL;
- // continue at ACC_ABORTCONF
-}
-
-/*
- * Lock failed (after delay) in ACC. Probably means somebody ahead of
- * us in lock queue deleted the tuple.
- */
-void
-Dbtup::execACCKEYREF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
- ndbrequire(scan.m_bits & ScanOp::SCAN_LOCK_WAIT && scan.m_accLockOp != RNIL);
- scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
- if (scan.m_state != ScanOp::Aborting) {
- jam();
- // release the operation
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- // scan position should already have been moved (assert only)
- if (scan.m_state == ScanOp::Blocked) {
- jam();
- //ndbassert(false);
- if (scan.m_bits & ScanOp::SCAN_NR)
- {
- jam();
- scan.m_state = ScanOp::Next;
- scan.m_scanPos.m_get = ScanPos::Get_tuple;
- ndbout_c("Ignoring scan.m_state == ScanOp::Blocked, refetch");
- }
- else
- {
- jam();
- scan.m_state = ScanOp::Next;
- ndbout_c("Ignoring scan.m_state == ScanOp::Blocked");
- }
- }
- // LQH has the ball
- return;
- }
- // lose the lock
- scan.m_accLockOp = RNIL;
- // continue at ACC_ABORTCONF
-}
-
-/*
- * Received when scan is closing. This signal arrives after any
- * ACCKEYCON or ACCKEYREF which may have been in job buffer.
- */
-void
-Dbtup::execACC_ABORTCONF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
- ndbrequire(scan.m_state == ScanOp::Aborting);
- // most likely we are still in lock wait
- if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
- jam();
- scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
- scan.m_accLockOp = RNIL;
- }
- scanClose(signal, scanPtr);
-}
-
-void
-Dbtup::scanFirst(Signal*, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- ScanPos& pos = scan.m_scanPos;
- Local_key& key = pos.m_key;
- const Uint32 bits = scan.m_bits;
- // fragment
- FragrecordPtr fragPtr;
- fragPtr.i = scan.m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- Fragrecord& frag = *fragPtr.p;
- // in the future should not pre-allocate pages
- if (frag.noOfPages == 0 && ((bits & ScanOp::SCAN_NR) == 0)) {
- jam();
- scan.m_state = ScanOp::Last;
- return;
- }
- if (! (bits & ScanOp::SCAN_DD)) {
- key.m_file_no = ZNIL;
- key.m_page_no = 0;
- pos.m_get = ScanPos::Get_page_mm;
- // for MM scan real page id is cached for efficiency
- pos.m_realpid_mm = RNIL;
- } else {
- Disk_alloc_info& alloc = frag.m_disk_alloc_info;
- // for now must check disk part explicitly
- if (alloc.m_extent_list.firstItem == RNIL) {
- jam();
- scan.m_state = ScanOp::Last;
- return;
- }
- pos.m_extent_info_ptr_i = alloc.m_extent_list.firstItem;
- Extent_info* ext = c_extent_pool.getPtr(pos.m_extent_info_ptr_i);
- key.m_file_no = ext->m_key.m_file_no;
- key.m_page_no = ext->m_first_page_no;
- pos.m_get = ScanPos::Get_page_dd;
- }
- key.m_page_idx = 0;
- // let scanNext() do the work
- scan.m_state = ScanOp::Next;
-}
-
-bool
-Dbtup::scanNext(Signal* signal, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- ScanPos& pos = scan.m_scanPos;
- Local_key& key = pos.m_key;
- const Uint32 bits = scan.m_bits;
- // table
- TablerecPtr tablePtr;
- tablePtr.i = scan.m_tableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- Tablerec& table = *tablePtr.p;
- // fragment
- FragrecordPtr fragPtr;
- fragPtr.i = scan.m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- Fragrecord& frag = *fragPtr.p;
- // tuple found
- Tuple_header* th = 0;
- Uint32 thbits = 0;
- Uint32 loop_count = 0;
- Uint32 scanGCI = scanPtr.p->m_scanGCI;
- Uint32 foundGCI;
-
- const bool mm = (bits & ScanOp::SCAN_DD);
- const bool lcp = (bits & ScanOp::SCAN_LCP);
-
- Uint32 lcp_list = fragPtr.p->m_lcp_keep_list;
- Uint32 size = table.m_offsets[mm].m_fix_header_size;
-
- if (lcp && lcp_list != RNIL)
- goto found_lcp_keep;
-
- switch(pos.m_get){
- case ScanPos::Get_next_tuple:
- case ScanPos::Get_next_tuple_fs:
- jam();
- key.m_page_idx += size;
- // fall through
- case ScanPos::Get_tuple:
- case ScanPos::Get_tuple_fs:
- jam();
- /**
- * We need to refetch page after timeslice
- */
- pos.m_get = ScanPos::Get_page;
- break;
- default:
- break;
- }
-
- while (true) {
- switch (pos.m_get) {
- case ScanPos::Get_next_page:
- // move to next page
- jam();
- {
- if (! (bits & ScanOp::SCAN_DD))
- pos.m_get = ScanPos::Get_next_page_mm;
- else
- pos.m_get = ScanPos::Get_next_page_dd;
- }
- continue;
- case ScanPos::Get_page:
- // get real page
- jam();
- {
- if (! (bits & ScanOp::SCAN_DD))
- pos.m_get = ScanPos::Get_page_mm;
- else
- pos.m_get = ScanPos::Get_page_dd;
- }
- continue;
- case ScanPos::Get_next_page_mm:
- // move to next logical TUP page
- jam();
- {
- key.m_page_no++;
- if (key.m_page_no >= frag.noOfPages) {
- jam();
-
- if ((bits & ScanOp::SCAN_NR) && (scan.m_endPage != RNIL))
- {
- jam();
- if (key.m_page_no < scan.m_endPage)
- {
- jam();
- ndbout_c("scanning page %u", key.m_page_no);
- goto cont;
- }
- }
- // no more pages, scan ends
- pos.m_get = ScanPos::Get_undef;
- scan.m_state = ScanOp::Last;
- return true;
- }
- cont:
- key.m_page_idx = 0;
- pos.m_get = ScanPos::Get_page_mm;
- // clear cached value
- pos.m_realpid_mm = RNIL;
- }
- /*FALLTHRU*/
- case ScanPos::Get_page_mm:
- // get TUP real page
- jam();
- {
- if (pos.m_realpid_mm == RNIL) {
- jam();
- if (key.m_page_no < frag.noOfPages)
- pos.m_realpid_mm = getRealpid(fragPtr.p, key.m_page_no);
- else
- {
- ndbassert(bits & ScanOp::SCAN_NR);
- goto nopage;
- }
- }
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, pos.m_realpid_mm);
-
- if (pagePtr.p->page_state == ZEMPTY_MM) {
- // skip empty page
- jam();
- if (! (bits & ScanOp::SCAN_NR))
- {
- pos.m_get = ScanPos::Get_next_page_mm;
- break; // incr loop count
- }
- else
- {
- jam();
- pos.m_realpid_mm = RNIL;
- }
- }
- nopage:
- pos.m_page = pagePtr.p;
- pos.m_get = ScanPos::Get_tuple;
- }
- continue;
- case ScanPos::Get_next_page_dd:
- // move to next disk page
- jam();
- {
- Disk_alloc_info& alloc = frag.m_disk_alloc_info;
- Local_fragment_extent_list list(c_extent_pool, alloc.m_extent_list);
- Ptr<Extent_info> ext_ptr;
- c_extent_pool.getPtr(ext_ptr, pos.m_extent_info_ptr_i);
- Extent_info* ext = ext_ptr.p;
- key.m_page_no++;
- if (key.m_page_no >= ext->m_first_page_no + alloc.m_extent_size) {
- // no more pages in this extent
- jam();
- if (! list.next(ext_ptr)) {
- // no more extents, scan ends
- jam();
- pos.m_get = ScanPos::Get_undef;
- scan.m_state = ScanOp::Last;
- return true;
- } else {
- // move to next extent
- jam();
- pos.m_extent_info_ptr_i = ext_ptr.i;
- ext = c_extent_pool.getPtr(pos.m_extent_info_ptr_i);
- key.m_file_no = ext->m_key.m_file_no;
- key.m_page_no = ext->m_first_page_no;
- }
- }
- key.m_page_idx = 0;
- pos.m_get = ScanPos::Get_page_dd;
- /*
- read ahead for scan in disk order
- do read ahead every 8:th page
- */
- if ((bits & ScanOp::SCAN_DD) &&
- (((key.m_page_no - ext->m_first_page_no) & 7) == 0))
- {
- jam();
- // initialize PGMAN request
- Page_cache_client::Request preq;
- preq.m_page = pos.m_key;
- preq.m_callback = TheNULLCallback;
-
- // set maximum read ahead
- Uint32 read_ahead = m_max_page_read_ahead;
-
- while (true)
- {
- // prepare page read ahead in current extent
- Uint32 page_no = preq.m_page.m_page_no;
- Uint32 page_no_limit = page_no + read_ahead;
- Uint32 limit = ext->m_first_page_no + alloc.m_extent_size;
- if (page_no_limit > limit)
- {
- jam();
- // read ahead crosses extent, set limit for this extent
- read_ahead = page_no_limit - limit;
- page_no_limit = limit;
- // and make sure we only read one extra extent next time around
- if (read_ahead > alloc.m_extent_size)
- read_ahead = alloc.m_extent_size;
- }
- else
- {
- jam();
- read_ahead = 0; // no more to read ahead after this
- }
- // do read ahead pages for this extent
- while (page_no < page_no_limit)
- {
- // page request to PGMAN
- jam();
- preq.m_page.m_page_no = page_no;
- int flags = 0;
- // ignore result
- m_pgman.get_page(signal, preq, flags);
- jamEntry();
- page_no++;
- }
- if (!read_ahead || !list.next(ext_ptr))
- {
- // no more extents after this or read ahead done
- jam();
- break;
- }
- // move to next extent and initialize PGMAN request accordingly
- Extent_info* ext = c_extent_pool.getPtr(ext_ptr.i);
- preq.m_page.m_file_no = ext->m_key.m_file_no;
- preq.m_page.m_page_no = ext->m_first_page_no;
- }
- } // if ScanOp::SCAN_DD read ahead
- }
- /*FALLTHRU*/
- case ScanPos::Get_page_dd:
- // get global page in PGMAN cache
- jam();
- {
- // check if page is un-allocated or empty
- if (likely(! (bits & ScanOp::SCAN_NR)))
- {
- Tablespace_client tsman(signal, c_tsman,
- frag.fragTableId,
- frag.fragmentId,
- frag.m_tablespace_id);
- unsigned uncommitted, committed;
- uncommitted = committed = ~(unsigned)0;
- int ret = tsman.get_page_free_bits(&key, &uncommitted, &committed);
- ndbrequire(ret == 0);
- if (committed == 0 && uncommitted == 0) {
- // skip empty page
- jam();
- pos.m_get = ScanPos::Get_next_page_dd;
- break; // incr loop count
- }
- }
- // page request to PGMAN
- Page_cache_client::Request preq;
- preq.m_page = pos.m_key;
- preq.m_callback.m_callbackData = scanPtr.i;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::disk_page_tup_scan_callback);
- int flags = 0;
- int res = m_pgman.get_page(signal, preq, flags);
- jamEntry();
- if (res == 0) {
- jam();
- // request queued
- pos.m_get = ScanPos::Get_tuple;
- return false;
- }
- ndbrequire(res > 0);
- pos.m_page = (Page*)m_pgman.m_ptr.p;
- }
- pos.m_get = ScanPos::Get_tuple;
- continue;
- // get tuple
- // move to next tuple
- case ScanPos::Get_next_tuple:
- case ScanPos::Get_next_tuple_fs:
- // move to next fixed size tuple
- jam();
- {
- key.m_page_idx += size;
- pos.m_get = ScanPos::Get_tuple_fs;
- }
- /*FALLTHRU*/
- case ScanPos::Get_tuple:
- case ScanPos::Get_tuple_fs:
- // get fixed size tuple
- jam();
- {
- Fix_page* page = (Fix_page*)pos.m_page;
- if (key.m_page_idx + size <= Fix_page::DATA_WORDS)
- {
- pos.m_get = ScanPos::Get_next_tuple_fs;
- th = (Tuple_header*)&page->m_data[key.m_page_idx];
-
- if (likely(! (bits & ScanOp::SCAN_NR)))
- {
- jam();
- thbits = th->m_header_bits;
- if (! (thbits & Tuple_header::FREE))
- {
- goto found_tuple;
- }
- }
- else
- {
- if (pos.m_realpid_mm == RNIL)
- {
- jam();
- foundGCI = 0;
- goto found_deleted_rowid;
- }
- thbits = th->m_header_bits;
- if ((foundGCI = *th->get_mm_gci(tablePtr.p)) > scanGCI ||
- foundGCI == 0)
- {
- if (! (thbits & Tuple_header::FREE))
- {
- jam();
- goto found_tuple;
- }
- else
- {
- goto found_deleted_rowid;
- }
- }
- else if (thbits != Fix_page::FREE_RECORD &&
- th->m_operation_ptr_i != RNIL)
- {
- jam();
- goto found_tuple; // Locked tuple...
- // skip free tuple
- }
- }
- } else {
- jam();
- // no more tuples on this page
- pos.m_get = ScanPos::Get_next_page;
- }
- }
- break; // incr loop count
- found_tuple:
- // found possible tuple to return
- jam();
- {
- // caller has already set pos.m_get to next tuple
- if (! (bits & ScanOp::SCAN_LCP && thbits & Tuple_header::LCP_SKIP)) {
- Local_key& key_mm = pos.m_key_mm;
- if (! (bits & ScanOp::SCAN_DD)) {
- key_mm = pos.m_key;
- // real page id is already set
- } else {
- key_mm.assref(th->m_base_record_ref);
- // recompute for each disk tuple
- pos.m_realpid_mm = getRealpid(fragPtr.p, key_mm.m_page_no);
- }
- // TUPKEYREQ handles savepoint stuff
- scan.m_state = ScanOp::Current;
- return true;
- } else {
- jam();
- // clear it so that it will show up in next LCP
- th->m_header_bits = thbits & ~(Uint32)Tuple_header::LCP_SKIP;
- if (tablePtr.p->m_bits & Tablerec::TR_Checksum) {
- jam();
- setChecksum(th, tablePtr.p);
- }
- }
- }
- break;
- found_deleted_rowid:
- jam();
- {
- ndbassert(bits & ScanOp::SCAN_NR);
- Local_key& key_mm = pos.m_key_mm;
- if (! (bits & ScanOp::SCAN_DD)) {
- key_mm = pos.m_key;
- // caller has already set pos.m_get to next tuple
- // real page id is already set
- } else {
- key_mm.assref(th->m_base_record_ref);
- // recompute for each disk tuple
- pos.m_realpid_mm = getRealpid(fragPtr.p, key_mm.m_page_no);
-
- Fix_page *mmpage = (Fix_page*)c_page_pool.getPtr(pos.m_realpid_mm);
- th = (Tuple_header*)(mmpage->m_data + key_mm.m_page_idx);
- if ((foundGCI = *th->get_mm_gci(tablePtr.p)) > scanGCI ||
- foundGCI == 0)
- {
- if (! (thbits & Tuple_header::FREE))
- break;
- }
- }
-
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = RNIL;
- conf->fragId = frag.fragmentId;
- conf->localKey[0] = pos.m_key_mm.ref();
- conf->localKey[1] = 0;
- conf->localKeyLength = 1;
- conf->gci = foundGCI;
- Uint32 blockNo = refToBlock(scan.m_userRef);
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 7);
- jamEntry();
-
- // TUPKEYREQ handles savepoint stuff
- loop_count = 32;
- scan.m_state = ScanOp::Next;
- return false;
- }
- break; // incr loop count
- default:
- ndbrequire(false);
- break;
- }
- if (++loop_count >= 32)
- break;
- }
- // TODO: at drop table we have to flush and terminate these
- jam();
- signal->theData[0] = ZTUP_SCAN;
- signal->theData[1] = scanPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return false;
-
-found_lcp_keep:
- Local_key tmp;
- tmp.assref(lcp_list);
- tmp.m_page_no = getRealpid(fragPtr.p, tmp.m_page_no);
-
- Ptr<Page> pagePtr;
- c_page_pool.getPtr(pagePtr, tmp.m_page_no);
- Tuple_header* ptr = (Tuple_header*)
- ((Fix_page*)pagePtr.p)->get_ptr(tmp.m_page_idx, 0);
- Uint32 headerbits = ptr->m_header_bits;
- ndbrequire(headerbits & Tuple_header::LCP_KEEP);
-
- Uint32 next = ptr->m_operation_ptr_i;
- ptr->m_operation_ptr_i = RNIL;
- ptr->m_header_bits = headerbits & ~(Uint32)Tuple_header::FREE;
-
- if (tablePtr.p->m_bits & Tablerec::TR_Checksum) {
- jam();
- setChecksum(ptr, tablePtr.p);
- }
-
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = (Uint32)-1;
- conf->fragId = frag.fragmentId;
- conf->localKey[0] = lcp_list;
- conf->localKey[1] = 0;
- conf->localKeyLength = 1;
- conf->gci = 0;
- Uint32 blockNo = refToBlock(scan.m_userRef);
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 7);
-
- fragPtr.p->m_lcp_keep_list = next;
- ptr->m_header_bits |= Tuple_header::FREED; // RESTORE free flag
- if (headerbits & Tuple_header::FREED)
- {
- if (tablePtr.p->m_attributes[MM].m_no_of_varsize)
- {
- jam();
- free_var_rec(fragPtr.p, tablePtr.p, &tmp, pagePtr);
- } else {
- jam();
- free_fix_rec(fragPtr.p, tablePtr.p, &tmp, (Fix_page*)pagePtr.p);
- }
- }
- return false;
-}
-
-void
-Dbtup::scanCont(Signal* signal, ScanOpPtr scanPtr)
-{
- bool immediate = scanNext(signal, scanPtr);
- if (! immediate) {
- jam();
- // time-slicing again
- return;
- }
- scanReply(signal, scanPtr);
-}
-
-void
-Dbtup::disk_page_tup_scan_callback(Signal* signal, Uint32 scanPtrI, Uint32 page_i)
-{
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, scanPtrI);
- ScanOp& scan = *scanPtr.p;
- ScanPos& pos = scan.m_scanPos;
- // get cache page
- Ptr<GlobalPage> gptr;
- m_global_page_pool.getPtr(gptr, page_i);
- pos.m_page = (Page*)gptr.p;
- // continue
- scanCont(signal, scanPtr);
-}
-
-void
-Dbtup::scanClose(Signal* signal, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- ndbrequire(! (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) && scan.m_accLockOp == RNIL);
- // unlock all not unlocked by LQH
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
- while (list.first(lockPtr)) {
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = lockPtr.p->m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- list.release(lockPtr);
- }
- // send conf
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scanPtr.p->m_userPtr;
- conf->accOperationPtr = RNIL;
- conf->fragId = RNIL;
- unsigned signalLength = 3;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- releaseScanOp(scanPtr);
-}
-
-void
-Dbtup::addAccLockOp(ScanOp& scan, Uint32 accLockOp)
-{
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
-#ifdef VM_TRACE
- list.first(lockPtr);
- while (lockPtr.i != RNIL) {
- ndbrequire(lockPtr.p->m_accLockOp != accLockOp);
- list.next(lockPtr);
- }
-#endif
- bool ok = list.seize(lockPtr);
- ndbrequire(ok);
- lockPtr.p->m_accLockOp = accLockOp;
-}
-
-void
-Dbtup::removeAccLockOp(ScanOp& scan, Uint32 accLockOp)
-{
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
- list.first(lockPtr);
- while (lockPtr.i != RNIL) {
- if (lockPtr.p->m_accLockOp == accLockOp) {
- jam();
- break;
- }
- list.next(lockPtr);
- }
- ndbrequire(lockPtr.i != RNIL);
- list.release(lockPtr);
-}
-
-void
-Dbtup::releaseScanOp(ScanOpPtr& scanPtr)
-{
- FragrecordPtr fragPtr;
- fragPtr.i = scanPtr.p->m_fragPtrI;
- ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
-
- if(scanPtr.p->m_bits & ScanOp::SCAN_LCP)
- {
- jam();
- fragPtr.p->m_lcp_scan_op = RNIL;
- scanPtr.p->m_fragPtrI = RNIL;
- }
- else
- {
- jam();
- LocalDLList<ScanOp> list(c_scanOpPool, fragPtr.p->m_scanList);
- list.release(scanPtr);
- }
-}
-
-void
-Dbtup::execLCP_FRAG_ORD(Signal* signal)
-{
- LcpFragOrd* req= (LcpFragOrd*)signal->getDataPtr();
-
- TablerecPtr tablePtr;
- tablePtr.i = req->tableId;
- ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
-
- if (tablePtr.p->m_no_of_disk_attributes)
- {
- jam();
- FragrecordPtr fragPtr;
- Uint32 fragId = req->fragmentId;
- fragPtr.i = RNIL;
- getFragmentrec(fragPtr, fragId, tablePtr.p);
- ndbrequire(fragPtr.i != RNIL);
- Fragrecord& frag = *fragPtr.p;
-
- ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL);
- frag.m_lcp_scan_op = c_lcp_scan_op;
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, frag.m_lcp_scan_op);
- ndbrequire(scanPtr.p->m_fragPtrI == RNIL);
- scanPtr.p->m_fragPtrI = fragPtr.i;
-
- scanFirst(signal, scanPtr);
- scanPtr.p->m_state = ScanOp::First;
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
deleted file mode 100644
index 63f73593ff7..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Copyright (c) 2003, 2005, 2007, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_STORE_PROC_DEF_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-/* ------------ADD/DROP STORED PROCEDURE MODULE ------------------- */
-/* ---------------------------------------------------------------- */
-/* ---------------------------------------------------------------- */
-void Dbtup::execSTORED_PROCREQ(Signal* signal)
-{
- OperationrecPtr regOperPtr;
- TablerecPtr regTabPtr;
- jamEntry();
- regOperPtr.i = signal->theData[0];
- c_operation_pool.getPtr(regOperPtr);
- regTabPtr.i = signal->theData[1];
- ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
-
- Uint32 requestInfo = signal->theData[3];
- TransState trans_state= get_trans_state(regOperPtr.p);
- ndbrequire(trans_state == TRANS_IDLE ||
- ((trans_state == TRANS_ERROR_WAIT_STORED_PROCREQ) &&
- (requestInfo == ZSTORED_PROCEDURE_DELETE)));
- ndbrequire(regTabPtr.p->tableStatus == DEFINED);
- switch (requestInfo) {
- case ZSCAN_PROCEDURE:
- jam();
- scanProcedure(signal,
- regOperPtr.p,
- signal->theData[4]);
- break;
- case ZCOPY_PROCEDURE:
- jam();
- copyProcedure(signal, regTabPtr, regOperPtr.p);
- break;
- case ZSTORED_PROCEDURE_DELETE:
- jam();
- deleteScanProcedure(signal, regOperPtr.p);
- break;
- default:
- ndbrequire(false);
- }//switch
-}//Dbtup::execSTORED_PROCREQ()
-
-void Dbtup::deleteScanProcedure(Signal* signal,
- Operationrec* regOperPtr)
-{
- StoredProcPtr storedPtr;
- Uint32 storedProcId = signal->theData[4];
- c_storedProcPool.getPtr(storedPtr, storedProcId);
- ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
- ndbrequire(storedPtr.p->storedCounter == 0);
- Uint32 firstAttrinbuf = storedPtr.p->storedLinkFirst;
- storedPtr.p->storedCode = ZSTORED_PROCEDURE_FREE;
- storedPtr.p->storedLinkFirst = RNIL;
- storedPtr.p->storedLinkLast = RNIL;
- storedPtr.p->storedProcLength = 0;
- c_storedProcPool.release(storedPtr);
- freeAttrinbufrec(firstAttrinbuf);
- regOperPtr->currentAttrinbufLen = 0;
- set_trans_state(regOperPtr, TRANS_IDLE);
- signal->theData[0] = regOperPtr->userpointer;
- signal->theData[1] = storedProcId;
- sendSignal(DBLQH_REF, GSN_STORED_PROCCONF, signal, 2, JBB);
-}//Dbtup::deleteScanProcedure()
-
-void Dbtup::scanProcedure(Signal* signal,
- Operationrec* regOperPtr,
- Uint32 lenAttrInfo)
-{
-//--------------------------------------------------------
-// We introduce the maxCheck so that there is always one
-// stored procedure entry free for copy procedures. Thus
-// no amount of scanning can cause problems for the node
-// recovery functionality.
-//--------------------------------------------------------
- StoredProcPtr storedPtr;
- c_storedProcPool.seize(storedPtr);
- ndbrequire(storedPtr.i != RNIL);
- storedPtr.p->storedCode = ZSCAN_PROCEDURE;
- storedPtr.p->storedCounter = 0;
- storedPtr.p->storedProcLength = lenAttrInfo;
- storedPtr.p->storedLinkFirst = RNIL;
- storedPtr.p->storedLinkLast = RNIL;
- set_trans_state(regOperPtr, TRANS_WAIT_STORED_PROCEDURE_ATTR_INFO);
- regOperPtr->attrinbufLen = lenAttrInfo;
- regOperPtr->currentAttrinbufLen = 0;
- regOperPtr->storedProcPtr = storedPtr.i;
- if (lenAttrInfo >= ZATTR_BUFFER_SIZE) { // yes ">="
- jam();
- // send REF and change state to ignore the ATTRINFO to come
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_TOO_MUCH_ATTRINFO_ERROR);
- }
-}//Dbtup::scanProcedure()
-
-void Dbtup::copyProcedure(Signal* signal,
- TablerecPtr regTabPtr,
- Operationrec* regOperPtr)
-{
- Uint32 TnoOfAttributes = regTabPtr.p->m_no_of_attributes;
- scanProcedure(signal,
- regOperPtr,
- TnoOfAttributes);
-
- Uint32 length = 0;
- for (Uint32 Ti = 0; Ti < TnoOfAttributes; Ti++) {
- AttributeHeader::init(&signal->theData[length + 1], Ti, 0);
- length++;
- if (length == 24) {
- jam();
- ndbrequire(storedProcedureAttrInfo(signal, regOperPtr,
- signal->theData+1, length, true));
- length = 0;
- }//if
- }//for
- if (length != 0) {
- jam();
- ndbrequire(storedProcedureAttrInfo(signal, regOperPtr,
- signal->theData+1, length, true));
- }//if
- ndbrequire(regOperPtr->currentAttrinbufLen == 0);
-}//Dbtup::copyProcedure()
-
-bool Dbtup::storedProcedureAttrInfo(Signal* signal,
- Operationrec* regOperPtr,
- const Uint32 *data,
- Uint32 length,
- bool copyProcedure)
-{
- AttrbufrecPtr regAttrPtr;
- Uint32 RnoFree = cnoFreeAttrbufrec;
- if (ERROR_INSERTED(4004) && !copyProcedure) {
- CLEAR_ERROR_INSERT_VALUE;
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
- return false;
- }//if
- regOperPtr->currentAttrinbufLen += length;
- ndbrequire(regOperPtr->currentAttrinbufLen <= regOperPtr->attrinbufLen);
- if ((RnoFree > MIN_ATTRBUF) ||
- (copyProcedure)) {
- jam();
- regAttrPtr.i = cfirstfreeAttrbufrec;
- ptrCheckGuard(regAttrPtr, cnoOfAttrbufrec, attrbufrec);
- regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = 0;
- cfirstfreeAttrbufrec = regAttrPtr.p->attrbuf[ZBUF_NEXT];
- cnoFreeAttrbufrec = RnoFree - 1;
- regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
- } else {
- jam();
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
- return false;
- }//if
- if (regOperPtr->firstAttrinbufrec == RNIL) {
- jam();
- regOperPtr->firstAttrinbufrec = regAttrPtr.i;
- }//if
- regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
- if (regOperPtr->lastAttrinbufrec != RNIL) {
- AttrbufrecPtr tempAttrinbufptr;
- jam();
- tempAttrinbufptr.i = regOperPtr->lastAttrinbufrec;
- ptrCheckGuard(tempAttrinbufptr, cnoOfAttrbufrec, attrbufrec);
- tempAttrinbufptr.p->attrbuf[ZBUF_NEXT] = regAttrPtr.i;
- }//if
- regOperPtr->lastAttrinbufrec = regAttrPtr.i;
-
- regAttrPtr.p->attrbuf[ZBUF_DATA_LEN] = length;
- MEMCOPY_NO_WORDS(&regAttrPtr.p->attrbuf[0],
- data,
- length);
-
- if (regOperPtr->currentAttrinbufLen < regOperPtr->attrinbufLen) {
- jam();
- return true;
- }//if
- if (ERROR_INSERTED(4005) && !copyProcedure) {
- CLEAR_ERROR_INSERT_VALUE;
- storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
- return false;
- }//if
-
- StoredProcPtr storedPtr;
- c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcPtr);
- ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
-
- regOperPtr->currentAttrinbufLen = 0;
- storedPtr.p->storedLinkFirst = regOperPtr->firstAttrinbufrec;
- storedPtr.p->storedLinkLast = regOperPtr->lastAttrinbufrec;
- regOperPtr->firstAttrinbufrec = RNIL;
- regOperPtr->lastAttrinbufrec = RNIL;
- regOperPtr->m_any_value = 0;
- set_trans_state(regOperPtr, TRANS_IDLE);
- signal->theData[0] = regOperPtr->userpointer;
- signal->theData[1] = storedPtr.i;
- sendSignal(DBLQH_REF, GSN_STORED_PROCCONF, signal, 2, JBB);
- return true;
-}//Dbtup::storedProcedureAttrInfo()
-
-void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
- Operationrec* regOperPtr,
- Uint32 errorCode)
-{
- StoredProcPtr storedPtr;
- c_storedProcPool.getPtr(storedPtr, regOperPtr->storedProcPtr);
- ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
-
- storedPtr.p->storedLinkFirst = regOperPtr->firstAttrinbufrec;
- regOperPtr->firstAttrinbufrec = RNIL;
- regOperPtr->lastAttrinbufrec = RNIL;
- regOperPtr->m_any_value = 0;
- set_trans_state(regOperPtr, TRANS_ERROR_WAIT_STORED_PROCREQ);
- signal->theData[0] = regOperPtr->userpointer;
- signal->theData[1] = errorCode;
- signal->theData[2] = regOperPtr->storedProcPtr;
- sendSignal(DBLQH_REF, GSN_STORED_PROCREF, signal, 3, JBB);
-}//Dbtup::storedSeizeAttrinbufrecErrorLab()
-
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
deleted file mode 100644
index 71a19c1840e..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_TAB_DES_MAN_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-
-/*
- * TABLE DESCRIPTOR MEMORY MANAGER
- *
- * Each table has a descriptor which is a contiguous array of words.
- * The descriptor is allocated from a global array using a buddy
- * algorithm. Free lists exist for each power of 2 words. Freeing
- * a piece first merges with free right and left neighbours and then
- * divides itself up into free list chunks.
- */
-
-Uint32
-Dbtup::getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset)
-{
- // belongs to configure.in
- unsigned sizeOfPointer = sizeof(CHARSET_INFO*);
- ndbrequire((sizeOfPointer & 0x3) == 0);
- sizeOfPointer = (sizeOfPointer >> 2);
- // do in layout order and return offsets (see DbtupMeta.cpp)
- Uint32 allocSize = 0;
- // magically aligned to 8 bytes
- offset[0] = allocSize += ZTD_SIZE;
- offset[1] = allocSize += regTabPtr->m_no_of_attributes* sizeOfReadFunction();
- offset[2] = allocSize += regTabPtr->m_no_of_attributes* sizeOfReadFunction();
- offset[3] = allocSize += regTabPtr->noOfCharsets * sizeOfPointer;
- offset[4] = allocSize += regTabPtr->noOfKeyAttr;
- offset[5] = allocSize += regTabPtr->m_no_of_attributes * ZAD_SIZE;
- offset[6] = allocSize += (regTabPtr->m_no_of_attributes + 1) >> 1; // real order
- allocSize += ZTD_TRAILER_SIZE;
- // return number of words
- return allocSize;
-}
-
-Uint32 Dbtup::allocTabDescr(const Tablerec* regTabPtr, Uint32* offset)
-{
- Uint32 reference = RNIL;
- Uint32 allocSize = getTabDescrOffsets(regTabPtr, offset);
-/* ---------------------------------------------------------------- */
-/* ALWAYS ALLOCATE A MULTIPLE OF 16 WORDS */
-/* ---------------------------------------------------------------- */
- allocSize = (((allocSize - 1) >> 4) + 1) << 4;
- Uint32 list = nextHigherTwoLog(allocSize - 1); /* CALCULATE WHICH LIST IT BELONGS TO */
- for (Uint32 i = list; i < 16; i++) {
- jam();
- if (cfreeTdList[i] != RNIL) {
- jam();
- reference = cfreeTdList[i];
- removeTdArea(reference, i); /* REMOVE THE AREA FROM THE FREELIST */
- Uint32 retNo = (1 << i) - allocSize; /* CALCULATE THE DIFFERENCE */
- if (retNo >= ZTD_FREE_SIZE) {
- jam();
- // return unused words, of course without attempting left merge
- Uint32 retRef = reference + allocSize;
- freeTabDescr(retRef, retNo, false);
- } else {
- jam();
- allocSize = 1 << i;
- }//if
- break;
- }//if
- }//for
- if (reference == RNIL) {
- jam();
- terrorCode = ZMEM_NOTABDESCR_ERROR;
- return RNIL;
- } else {
- jam();
- setTabDescrWord((reference + allocSize) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
- setTabDescrWord(reference + ZTD_DATASIZE, allocSize);
-
- /* INITIALIZE THE TRAILER RECORD WITH TYPE AND SIZE */
- /* THE TRAILER IS USED TO SIMPLIFY MERGE OF FREE AREAS */
-
- setTabDescrWord(reference + ZTD_HEADER, ZTD_TYPE_NORMAL);
- setTabDescrWord((reference + allocSize) - ZTD_TR_SIZE, allocSize);
- return reference;
- }//if
-}//Dbtup::allocTabDescr()
-
-void Dbtup::freeTabDescr(Uint32 retRef, Uint32 retNo, bool normal)
-{
- itdaMergeTabDescr(retRef, retNo, normal); /* MERGE WITH POSSIBLE NEIGHBOURS */
- while (retNo >= ZTD_FREE_SIZE) {
- jam();
- Uint32 list = nextHigherTwoLog(retNo);
- list--; /* RETURN TO NEXT LOWER LIST */
- Uint32 sizeOfChunk = 1 << list;
- insertTdArea(retRef, list);
- retRef += sizeOfChunk;
- retNo -= sizeOfChunk;
- }//while
- ndbassert(retNo == 0);
-}//Dbtup::freeTabDescr()
-
-Uint32
-Dbtup::getTabDescrWord(Uint32 index)
-{
- ndbrequire(index < cnoOfTabDescrRec);
- return tableDescriptor[index].tabDescr;
-}//Dbtup::getTabDescrWord()
-
-void
-Dbtup::setTabDescrWord(Uint32 index, Uint32 word)
-{
- ndbrequire(index < cnoOfTabDescrRec);
- tableDescriptor[index].tabDescr = word;
-}//Dbtup::setTabDescrWord()
-
-void Dbtup::insertTdArea(Uint32 tabDesRef, Uint32 list)
-{
- ndbrequire(list < 16);
- setTabDescrWord(tabDesRef + ZTD_FL_HEADER, ZTD_TYPE_FREE);
- setTabDescrWord(tabDesRef + ZTD_FL_NEXT, cfreeTdList[list]);
- if (cfreeTdList[list] != RNIL) {
- jam(); /* PREVIOUSLY EMPTY SLOT */
- setTabDescrWord(cfreeTdList[list] + ZTD_FL_PREV, tabDesRef);
- }//if
- cfreeTdList[list] = tabDesRef; /* RELINK THE LIST */
-
- setTabDescrWord(tabDesRef + ZTD_FL_PREV, RNIL);
- setTabDescrWord(tabDesRef + ZTD_FL_SIZE, 1 << list);
- setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_FREE);
- setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_SIZE, 1 << list);
-}//Dbtup::insertTdArea()
-
-/*
- * Merge to-be-removed chunk (which need not be initialized with header
- * and trailer) with left and right buddies. The start point retRef
- * moves to left and the size retNo increases to match the new chunk.
- */
-void Dbtup::itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal)
-{
- // merge right
- while ((retRef + retNo) < cnoOfTabDescrRec) {
- jam();
- Uint32 tabDesRef = retRef + retNo;
- Uint32 headerWord = getTabDescrWord(tabDesRef + ZTD_FL_HEADER);
- if (headerWord == ZTD_TYPE_FREE) {
- jam();
- Uint32 sizeOfMergedPart = getTabDescrWord(tabDesRef + ZTD_FL_SIZE);
-
- retNo += sizeOfMergedPart;
- Uint32 list = nextHigherTwoLog(sizeOfMergedPart - 1);
- removeTdArea(tabDesRef, list);
- } else {
- jam();
- break;
- }
- }
- // merge left
- const bool mergeLeft = normal;
- while (mergeLeft && retRef > 0) {
- jam();
- Uint32 trailerWord = getTabDescrWord(retRef - ZTD_TR_TYPE);
- if (trailerWord == ZTD_TYPE_FREE) {
- jam();
- Uint32 sizeOfMergedPart = getTabDescrWord(retRef - ZTD_TR_SIZE);
- ndbrequire(retRef >= sizeOfMergedPart);
- retRef -= sizeOfMergedPart;
- retNo += sizeOfMergedPart;
- Uint32 list = nextHigherTwoLog(sizeOfMergedPart - 1);
- removeTdArea(retRef, list);
- } else {
- jam();
- break;
- }
- }
- ndbrequire((retRef + retNo) <= cnoOfTabDescrRec);
-}//Dbtup::itdaMergeTabDescr()
-
-/* ---------------------------------------------------------------- */
-/* ------------------------ REMOVE_TD_AREA ------------------------ */
-/* ---------------------------------------------------------------- */
-/* */
-/* THIS ROUTINE REMOVES A TD CHUNK FROM THE POOL OF TD RECORDS */
-/* */
-/* INPUT: TLIST LIST TO USE */
-/* TAB_DESCR_PTR POINTS TO THE CHUNK TO BE REMOVED */
-/* */
-/* SHORTNAME: RMTA */
-/* -----------------------------------------------------------------*/
-void Dbtup::removeTdArea(Uint32 tabDesRef, Uint32 list)
-{
- ndbrequire(list < 16);
- Uint32 tabDescrNextPtr = getTabDescrWord(tabDesRef + ZTD_FL_NEXT);
- Uint32 tabDescrPrevPtr = getTabDescrWord(tabDesRef + ZTD_FL_PREV);
-
- setTabDescrWord(tabDesRef + ZTD_HEADER, ZTD_TYPE_NORMAL);
- setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
-
- if (tabDesRef == cfreeTdList[list]) {
- jam();
- cfreeTdList[list] = tabDescrNextPtr; /* RELINK THE LIST */
- }//if
- if (tabDescrNextPtr != RNIL) {
- jam();
- setTabDescrWord(tabDescrNextPtr + ZTD_FL_PREV, tabDescrPrevPtr);
- }//if
- if (tabDescrPrevPtr != RNIL) {
- jam();
- setTabDescrWord(tabDescrPrevPtr + ZTD_FL_NEXT, tabDescrNextPtr);
- }//if
-}//Dbtup::removeTdArea()
-
-#ifdef VM_TRACE
-void
-Dbtup::verifytabdes()
-{
- struct WordType {
- short fl; // free list 0-15
- short ti; // table id
- WordType() : fl(-1), ti(-1) {}
- };
- WordType* wt = new WordType [cnoOfTabDescrRec];
- uint free_frags = 0;
- // free lists
- {
- for (uint i = 0; i < 16; i++) {
- Uint32 desc2 = RNIL;
- Uint32 desc = cfreeTdList[i];
- while (desc != RNIL) {
- const Uint32 size = (1 << i);
- ndbrequire(size >= ZTD_FREE_SIZE);
- ndbrequire(desc + size <= cnoOfTabDescrRec);
- { Uint32 index = desc + ZTD_FL_HEADER;
- ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_FREE);
- }
- { Uint32 index = desc + ZTD_FL_SIZE;
- ndbrequire(tableDescriptor[index].tabDescr == size);
- }
- { Uint32 index = desc + size - ZTD_TR_TYPE;
- ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_FREE);
- }
- { Uint32 index = desc + size - ZTD_TR_SIZE;
- ndbrequire(tableDescriptor[index].tabDescr == size);
- }
- { Uint32 index = desc + ZTD_FL_PREV;
- ndbrequire(tableDescriptor[index].tabDescr == desc2);
- }
- for (uint j = 0; j < size; j++) {
- ndbrequire(wt[desc + j].fl == -1);
- wt[desc + j].fl = i;
- }
- desc2 = desc;
- desc = tableDescriptor[desc + ZTD_FL_NEXT].tabDescr;
- free_frags++;
- }
- }
- }
- // tables
- {
- for (uint i = 0; i < cnoOfTablerec; i++) {
- TablerecPtr ptr;
- ptr.i = i;
- ptrAss(ptr, tablerec);
- if (ptr.p->tableStatus == DEFINED) {
- Uint32 offset[10];
- const Uint32 alloc = getTabDescrOffsets(ptr.p, offset);
- const Uint32 desc = ptr.p->readKeyArray - offset[3];
- Uint32 size = alloc;
- if (size % ZTD_FREE_SIZE != 0)
- size += ZTD_FREE_SIZE - size % ZTD_FREE_SIZE;
- ndbrequire(desc + size <= cnoOfTabDescrRec);
- { Uint32 index = desc + ZTD_FL_HEADER;
- ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_NORMAL);
- }
- { Uint32 index = desc + ZTD_FL_SIZE;
- ndbrequire(tableDescriptor[index].tabDescr == size);
- }
- { Uint32 index = desc + size - ZTD_TR_TYPE;
- ndbrequire(tableDescriptor[index].tabDescr == ZTD_TYPE_NORMAL);
- }
- { Uint32 index = desc + size - ZTD_TR_SIZE;
- ndbrequire(tableDescriptor[index].tabDescr == size);
- }
- for (uint j = 0; j < size; j++) {
- ndbrequire(wt[desc + j].ti == -1);
- wt[desc + j].ti = i;
- }
- }
- }
- }
- // all words
- {
- for (uint i = 0; i < cnoOfTabDescrRec; i++) {
- bool is_fl = wt[i].fl != -1;
- bool is_ti = wt[i].ti != -1;
- ndbrequire(is_fl != is_ti);
- }
- }
- delete [] wt;
- ndbout << "verifytabdes: frags=" << free_frags << endl;
-}
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
deleted file mode 100644
index f202959b4da..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
+++ /dev/null
@@ -1,1291 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define DBTUP_C
-#define DBTUP_TRIGGER_CPP
-#include "Dbtup.hpp"
-#include <RefConvert.hpp>
-#include <ndb_limits.h>
-#include <pc.hpp>
-#include <AttributeDescriptor.hpp>
-#include "AttributeOffset.hpp"
-#include <AttributeHeader.hpp>
-#include <signaldata/FireTrigOrd.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/TuxMaint.hpp>
-
-/* **************************************************************** */
-/* ---------------------------------------------------------------- */
-/* ----------------------- TRIGGER HANDLING ----------------------- */
-/* ---------------------------------------------------------------- */
-/* **************************************************************** */
-
-DLList<Dbtup::TupTriggerData>*
-Dbtup::findTriggerList(Tablerec* table,
- TriggerType::Value ttype,
- TriggerActionTime::Value ttime,
- TriggerEvent::Value tevent)
-{
- DLList<TupTriggerData>* tlist = NULL;
- switch (ttype) {
- case TriggerType::SUBSCRIPTION:
- case TriggerType::SUBSCRIPTION_BEFORE:
- switch (tevent) {
- case TriggerEvent::TE_INSERT:
- jam();
- if (ttime == TriggerActionTime::TA_DETACHED)
- tlist = &table->subscriptionInsertTriggers;
- break;
- case TriggerEvent::TE_UPDATE:
- jam();
- if (ttime == TriggerActionTime::TA_DETACHED)
- tlist = &table->subscriptionUpdateTriggers;
- break;
- case TriggerEvent::TE_DELETE:
- jam();
- if (ttime == TriggerActionTime::TA_DETACHED)
- tlist = &table->subscriptionDeleteTriggers;
- break;
- default:
- break;
- }
- break;
- case TriggerType::SECONDARY_INDEX:
- switch (tevent) {
- case TriggerEvent::TE_INSERT:
- jam();
- if (ttime == TriggerActionTime::TA_AFTER)
- tlist = &table->afterInsertTriggers;
- break;
- case TriggerEvent::TE_UPDATE:
- jam();
- if (ttime == TriggerActionTime::TA_AFTER)
- tlist = &table->afterUpdateTriggers;
- break;
- case TriggerEvent::TE_DELETE:
- jam();
- if (ttime == TriggerActionTime::TA_AFTER)
- tlist = &table->afterDeleteTriggers;
- break;
- default:
- break;
- }
- break;
- case TriggerType::ORDERED_INDEX:
- switch (tevent) {
- case TriggerEvent::TE_CUSTOM:
- jam();
- if (ttime == TriggerActionTime::TA_CUSTOM)
- tlist = &table->tuxCustomTriggers;
- break;
- default:
- break;
- }
- break;
- case TriggerType::READ_ONLY_CONSTRAINT:
- switch (tevent) {
- case TriggerEvent::TE_UPDATE:
- jam();
- if (ttime == TriggerActionTime::TA_AFTER)
- tlist = &table->constraintUpdateTriggers;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- return tlist;
-}
-
-// Trigger signals
-void
-Dbtup::execCREATE_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- BlockReference senderRef = signal->getSendersBlockRef();
- const CreateTrigReq reqCopy = *(const CreateTrigReq*)signal->getDataPtr();
- const CreateTrigReq* const req = &reqCopy;
- CreateTrigRef::ErrorCode error= CreateTrigRef::NoError;
-
- // Find table
- TablerecPtr tabPtr;
- tabPtr.i = req->getTableId();
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- if (tabPtr.p->tableStatus != DEFINED )
- {
- jam();
- error= CreateTrigRef::InvalidTable;
- }
- // Create trigger and associate it with the table
- else if (createTrigger(tabPtr.p, req))
- {
- jam();
- // Send conf
- CreateTrigConf* const conf = (CreateTrigConf*)signal->getDataPtrSend();
- conf->setUserRef(reference());
- conf->setConnectionPtr(req->getConnectionPtr());
- conf->setRequestType(req->getRequestType());
- conf->setTableId(req->getTableId());
- conf->setIndexId(req->getIndexId());
- conf->setTriggerId(req->getTriggerId());
- conf->setTriggerInfo(req->getTriggerInfo());
- sendSignal(senderRef, GSN_CREATE_TRIG_CONF,
- signal, CreateTrigConf::SignalLength, JBB);
- return;
- }
- else
- {
- jam();
- error= CreateTrigRef::TooManyTriggers;
- }
- ndbassert(error != CreateTrigRef::NoError);
- // Send ref
- CreateTrigRef* const ref = (CreateTrigRef*)signal->getDataPtrSend();
- ref->setUserRef(reference());
- ref->setConnectionPtr(req->getConnectionPtr());
- ref->setRequestType(req->getRequestType());
- ref->setTableId(req->getTableId());
- ref->setIndexId(req->getIndexId());
- ref->setTriggerId(req->getTriggerId());
- ref->setTriggerInfo(req->getTriggerInfo());
- ref->setErrorCode(error);
- sendSignal(senderRef, GSN_CREATE_TRIG_REF,
- signal, CreateTrigRef::SignalLength, JBB);
-}//Dbtup::execCREATE_TRIG_REQ()
-
-void
-Dbtup::execDROP_TRIG_REQ(Signal* signal)
-{
- jamEntry();
- BlockReference senderRef = signal->getSendersBlockRef();
- const DropTrigReq reqCopy = *(const DropTrigReq*)signal->getDataPtr();
- const DropTrigReq* const req = &reqCopy;
-
- // Find table
- TablerecPtr tabPtr;
- tabPtr.i = req->getTableId();
- ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
-
- // Drop trigger
- Uint32 r = dropTrigger(tabPtr.p, req, refToBlock(senderRef));
- if (r == 0){
- // Send conf
- DropTrigConf* const conf = (DropTrigConf*)signal->getDataPtrSend();
- conf->setUserRef(senderRef);
- conf->setConnectionPtr(req->getConnectionPtr());
- conf->setRequestType(req->getRequestType());
- conf->setTableId(req->getTableId());
- conf->setIndexId(req->getIndexId());
- conf->setTriggerId(req->getTriggerId());
- sendSignal(senderRef, GSN_DROP_TRIG_CONF,
- signal, DropTrigConf::SignalLength, JBB);
- } else {
- // Send ref
- DropTrigRef* const ref = (DropTrigRef*)signal->getDataPtrSend();
- ref->setUserRef(senderRef);
- ref->setConnectionPtr(req->getConnectionPtr());
- ref->setRequestType(req->getRequestType());
- ref->setTableId(req->getTableId());
- ref->setIndexId(req->getIndexId());
- ref->setTriggerId(req->getTriggerId());
- ref->setErrorCode((DropTrigRef::ErrorCode)r);
- ref->setErrorLine(__LINE__);
- ref->setErrorNode(refToNode(reference()));
- sendSignal(senderRef, GSN_DROP_TRIG_REF,
- signal, DropTrigRef::SignalLength, JBB);
- }
-}//Dbtup::DROP_TRIG_REQ()
-
-/* ---------------------------------------------------------------- */
-/* ------------------------- createTrigger ------------------------ */
-/* */
-/* Creates a new trigger record by fetching one from the trigger */
-/* pool and associates it with the given table. */
-/* Trigger type can be one of secondary_index, subscription, */
-/* constraint(NYI), foreign_key(NYI), schema_upgrade(NYI), */
-/* api_trigger(NYI) or sql_trigger(NYI). */
-/* Note that this method only checks for total number of allowed */
-/* triggers. Checking the number of allowed triggers per table is */
-/* done by TRIX. */
-/* */
-/* ---------------------------------------------------------------- */
-bool
-Dbtup::createTrigger(Tablerec* table, const CreateTrigReq* req)
-{
- if (ERROR_INSERTED(4003)) {
- CLEAR_ERROR_INSERT_VALUE;
- return false;
- }
- TriggerType::Value ttype = req->getTriggerType();
- TriggerActionTime::Value ttime = req->getTriggerActionTime();
- TriggerEvent::Value tevent = req->getTriggerEvent();
-
- DLList<TupTriggerData>* tlist = findTriggerList(table, ttype, ttime, tevent);
- ndbrequire(tlist != NULL);
-
- TriggerPtr tptr;
- if (!tlist->seize(tptr))
- return false;
-
- // Set trigger id
- tptr.p->triggerId = req->getTriggerId();
-
- // ndbout_c("Create TupTrigger %u = %u %u %u %u", tptr.p->triggerId, table, ttype, ttime, tevent);
-
- // Set index id
- tptr.p->indexId = req->getIndexId();
-
- // Set trigger type etc
- tptr.p->triggerType = ttype;
- tptr.p->triggerActionTime = ttime;
- tptr.p->triggerEvent = tevent;
-
- tptr.p->sendBeforeValues = true;
- if ((tptr.p->triggerType == TriggerType::SUBSCRIPTION) &&
- ((tptr.p->triggerEvent == TriggerEvent::TE_UPDATE) ||
- (tptr.p->triggerEvent == TriggerEvent::TE_DELETE))) {
- jam();
- tptr.p->sendBeforeValues = false;
- }
- /*
- tptr.p->sendOnlyChangedAttributes = false;
- if (((tptr.p->triggerType == TriggerType::SUBSCRIPTION) ||
- (tptr.p->triggerType == TriggerType::SUBSCRIPTION_BEFORE)) &&
- (tptr.p->triggerEvent == TriggerEvent::TE_UPDATE)) {
- jam();
- tptr.p->sendOnlyChangedAttributes = true;
- }
- */
- tptr.p->sendOnlyChangedAttributes = !req->getReportAllMonitoredAttributes();
- // Set monitor all
- tptr.p->monitorAllAttributes = req->getMonitorAllAttributes();
- tptr.p->monitorReplicas = req->getMonitorReplicas();
- tptr.p->m_receiverBlock = refToBlock(req->getReceiverRef());
-
- tptr.p->attributeMask.clear();
- if (tptr.p->monitorAllAttributes) {
- jam();
- for(Uint32 i = 0; i < table->m_no_of_attributes; i++) {
- if (!primaryKey(table, i)) {
- jam();
- tptr.p->attributeMask.set(i);
- }
- }
- } else {
- // Set attribute mask
- jam();
- tptr.p->attributeMask = req->getAttributeMask();
- }
- return true;
-}//Dbtup::createTrigger()
-
-bool
-Dbtup::primaryKey(Tablerec* const regTabPtr, Uint32 attrId)
-{
- Uint32 attrDescriptorStart = regTabPtr->tabDescriptor;
- Uint32 attrDescriptor = getTabDescrWord(attrDescriptorStart +
- (attrId * ZAD_SIZE));
- return (bool)AttributeDescriptor::getPrimaryKey(attrDescriptor);
-}//Dbtup::primaryKey()
-
-/* ---------------------------------------------------------------- */
-/* -------------------------- dropTrigger ------------------------- */
-/* */
-/* Deletes a trigger record by disassociating it with the given */
-/* table and returning it to the trigger pool. */
-/* Trigger type can be one of secondary_index, subscription, */
-/* constraint(NYI), foreign_key(NYI), schema_upgrade(NYI), */
-/* api_trigger(NYI) or sql_trigger(NYI). */
-/* */
-/* ---------------------------------------------------------------- */
-Uint32
-Dbtup::dropTrigger(Tablerec* table, const DropTrigReq* req, BlockNumber sender)
-{
- if (ERROR_INSERTED(4004)) {
- CLEAR_ERROR_INSERT_VALUE;
- return 9999;
- }
- Uint32 triggerId = req->getTriggerId();
-
- TriggerType::Value ttype = req->getTriggerType();
- TriggerActionTime::Value ttime = req->getTriggerActionTime();
- TriggerEvent::Value tevent = req->getTriggerEvent();
-
- // ndbout_c("Drop TupTrigger %u = %u %u %u %u by %u", triggerId, table, ttype, ttime, tevent, sender);
-
- DLList<TupTriggerData>* tlist = findTriggerList(table, ttype, ttime, tevent);
- ndbrequire(tlist != NULL);
-
- Ptr<TupTriggerData> ptr;
- for (tlist->first(ptr); !ptr.isNull(); tlist->next(ptr)) {
- jam();
- if (ptr.p->triggerId == triggerId) {
- if(ttype==TriggerType::SUBSCRIPTION && sender != ptr.p->m_receiverBlock)
- {
- /**
- * You can only drop your own triggers for subscription triggers.
- * Trigger IDs are private for each block.
- *
- * SUMA encodes information in the triggerId
- *
- * Backup doesn't really care about the Ids though.
- */
- jam();
- continue;
- }
- jam();
- tlist->release(ptr.i);
- return 0;
- }
- }
- return DropTrigRef::TriggerNotFound;
-}//Dbtup::dropTrigger()
-
-/* ---------------------------------------------------------------- */
-/* -------------- checkImmediateTriggersAfterOp ------------------ */
-/* */
-/* Called after an insert, delete, or update operation takes */
-/* place. Fetches before tuple for deletes and updates and */
-/* after tuple for inserts and updates. */
-/* Executes immediate triggers by sending FIRETRIGORD */
-/* */
-/* ---------------------------------------------------------------- */
-void
-Dbtup::checkImmediateTriggersAfterInsert(KeyReqStruct *req_struct,
- Operationrec *regOperPtr,
- Tablerec *regTablePtr,
- bool disk)
-{
- if(refToBlock(req_struct->TC_ref) != DBTC) {
- return;
- }
-
- if ((regOperPtr->op_struct.primary_replica) &&
- (!(regTablePtr->afterInsertTriggers.isEmpty()))) {
- jam();
- fireImmediateTriggers(req_struct,
- regTablePtr->afterInsertTriggers,
- regOperPtr,
- disk);
- }
-}
-
-void
-Dbtup::checkImmediateTriggersAfterUpdate(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTablePtr,
- bool disk)
-{
- if(refToBlock(req_struct->TC_ref) != DBTC) {
- return;
- }
-
- if ((regOperPtr->op_struct.primary_replica) &&
- (!(regTablePtr->afterUpdateTriggers.isEmpty()))) {
- jam();
- fireImmediateTriggers(req_struct,
- regTablePtr->afterUpdateTriggers,
- regOperPtr,
- disk);
- }
- if ((regOperPtr->op_struct.primary_replica) &&
- (!(regTablePtr->constraintUpdateTriggers.isEmpty()))) {
- jam();
- fireImmediateTriggers(req_struct,
- regTablePtr->constraintUpdateTriggers,
- regOperPtr,
- disk);
- }
-}
-
-void
-Dbtup::checkImmediateTriggersAfterDelete(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTablePtr,
- bool disk)
-{
- if(refToBlock(req_struct->TC_ref) != DBTC) {
- return;
- }
-
- if ((regOperPtr->op_struct.primary_replica) &&
- (!(regTablePtr->afterDeleteTriggers.isEmpty()))) {
- jam();
- executeTriggers(req_struct,
- regTablePtr->afterDeleteTriggers,
- regOperPtr,
- disk);
- }
-}
-
-#if 0
-/* ---------------------------------------------------------------- */
-/* --------------------- checkDeferredTriggers -------------------- */
-/* */
-/* Called before commit after an insert, delete, or update */
-/* operation. Fetches before tuple for deletes and updates and */
-/* after tuple for inserts and updates. */
-/* Executes deferred triggers by sending FIRETRIGORD */
-/* */
-/* ---------------------------------------------------------------- */
-void Dbtup::checkDeferredTriggers(Signal* signal,
- Operationrec* const regOperPtr,
- Tablerec* const regTablePtr)
-{
- jam();
- // NYI
-}//Dbtup::checkDeferredTriggers()
-#endif
-
-/* ---------------------------------------------------------------- */
-/* --------------------- checkDetachedTriggers -------------------- */
-/* */
-/* Called at commit after an insert, delete, or update operation. */
-/* Fetches before tuple for deletes and updates and */
-/* after tuple for inserts and updates. */
-/* Executes detached triggers by sending FIRETRIGORD */
-/* */
-/* ---------------------------------------------------------------- */
-void Dbtup::checkDetachedTriggers(KeyReqStruct *req_struct,
- Operationrec* regOperPtr,
- Tablerec* regTablePtr,
- bool disk)
-{
- Uint32 save_type = regOperPtr->op_struct.op_type;
- Tuple_header *save_ptr = req_struct->m_tuple_ptr;
-
- switch (save_type) {
- case ZUPDATE:
- case ZINSERT:
- req_struct->m_tuple_ptr = (Tuple_header*)
- c_undo_buffer.get_ptr(&regOperPtr->m_copy_tuple_location);
- break;
- }
-
- /**
- * Set correct operation type and fix change mask
- * Note ALLOC is set in "orig" tuple
- */
- if (save_ptr->m_header_bits & Tuple_header::ALLOC) {
- if (save_type == ZDELETE) {
- // insert + delete = nothing
- jam();
- return;
- goto end;
- }
- regOperPtr->op_struct.op_type = ZINSERT;
- }
- else if (save_type == ZINSERT) {
- /**
- * Tuple was not created but last op is INSERT.
- * This is possible only on DELETE + INSERT
- */
- regOperPtr->op_struct.op_type = ZUPDATE;
- }
-
- switch(regOperPtr->op_struct.op_type) {
- case(ZINSERT):
- jam();
- if (regTablePtr->subscriptionInsertTriggers.isEmpty()) {
- // Table has no active triggers monitoring inserts at commit
- jam();
- goto end;
- }
-
- // If any fired immediate insert trigger then fetch after tuple
- fireDetachedTriggers(req_struct,
- regTablePtr->subscriptionInsertTriggers,
- regOperPtr, disk);
- break;
- case(ZDELETE):
- jam();
- if (regTablePtr->subscriptionDeleteTriggers.isEmpty()) {
- // Table has no active triggers monitoring deletes at commit
- jam();
- goto end;
- }
-
- // Execute any after delete triggers by sending
- // FIRETRIGORD with the before tuple
- fireDetachedTriggers(req_struct,
- regTablePtr->subscriptionDeleteTriggers,
- regOperPtr, disk);
- break;
- case(ZUPDATE):
- jam();
- if (regTablePtr->subscriptionUpdateTriggers.isEmpty()) {
- // Table has no active triggers monitoring updates at commit
- jam();
- goto end;
- }
-
- // If any fired immediate update trigger then fetch after tuple
- // and send two FIRETRIGORD one with before tuple and one with after tuple
- fireDetachedTriggers(req_struct,
- regTablePtr->subscriptionUpdateTriggers,
- regOperPtr, disk);
- break;
- default:
- ndbrequire(false);
- break;
- }
-
-end:
- regOperPtr->op_struct.op_type = save_type;
- req_struct->m_tuple_ptr = save_ptr;
-}
-
-void
-Dbtup::fireImmediateTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* const regOperPtr,
- bool disk)
-{
- TriggerPtr trigPtr;
- triggerList.first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- if (trigPtr.p->monitorAllAttributes ||
- trigPtr.p->attributeMask.overlaps(req_struct->changeMask)) {
- jam();
- executeTrigger(req_struct,
- trigPtr.p,
- regOperPtr,
- disk);
- }//if
- triggerList.next(trigPtr);
- }//while
-}//Dbtup::fireImmediateTriggers()
-
-#if 0
-void
-Dbtup::fireDeferredTriggers(Signal* signal,
- KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* const regOperPtr)
-{
- TriggerPtr trigPtr;
- triggerList.first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- if (trigPtr.p->monitorAllAttributes ||
- trigPtr.p->attributeMask.overlaps(req_struct->changeMask)) {
- jam();
- executeTrigger(req_struct,
- trigPtr,
- regOperPtr);
- }//if
- triggerList.next(trigPtr);
- }//while
-}//Dbtup::fireDeferredTriggers()
-#endif
-
-void
-Dbtup::fireDetachedTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* const regOperPtr,
- bool disk)
-{
-
- TriggerPtr trigPtr;
-
- /**
- * Set disk page
- */
- req_struct->m_disk_page_ptr.i = m_pgman.m_ptr.i;
-
- ndbrequire(regOperPtr->is_first_operation());
- triggerList.first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- if ((trigPtr.p->monitorReplicas ||
- regOperPtr->op_struct.primary_replica) &&
- (trigPtr.p->monitorAllAttributes ||
- trigPtr.p->attributeMask.overlaps(req_struct->changeMask))) {
- jam();
- executeTrigger(req_struct,
- trigPtr.p,
- regOperPtr,
- disk);
- }
- triggerList.next(trigPtr);
- }
-}
-
-void Dbtup::executeTriggers(KeyReqStruct *req_struct,
- DLList<TupTriggerData>& triggerList,
- Operationrec* regOperPtr,
- bool disk)
-{
- TriggerPtr trigPtr;
- triggerList.first(trigPtr);
- while (trigPtr.i != RNIL) {
- jam();
- executeTrigger(req_struct,
- trigPtr.p,
- regOperPtr,
- disk);
- triggerList.next(trigPtr);
-
- }
-}
-
-void Dbtup::executeTrigger(KeyReqStruct *req_struct,
- TupTriggerData* const trigPtr,
- Operationrec* const regOperPtr,
- bool disk)
-{
- /**
- * The block below does not work together with GREP.
- * I have 2 db nodes (2 replicas) -> one node group.
- * I want to have FIRETRIG_ORD sent to all SumaParticipants,
- * from all nodes in the node group described above. However,
- * only one of the nodes in the node group actually sends the
- * FIRE_TRIG_ORD, and the other node enters this "hack" below.
- * I don't really know what the code snippet below does, but it
- * does not work with GREP the way Lars and I want it.
- * We need to have triggers fired from both the primary and the
- * backup replica, not only the primary as it is now.
- *
- * Note: In Suma, I have changed triggers to be created with
- * setMonitorReplicas(true).
- * /Johan
- *
- * See RT 709
- */
- // XXX quick fix to NR, should fix in LQHKEYREQ instead
- /*
- if (refToBlock(req_struct->TC_ref) == DBLQH) {
- jam();
- return;
- }
- */
- Signal* signal= req_struct->signal;
- BlockReference ref = trigPtr->m_receiverBlock;
- Uint32* const keyBuffer = &cinBuffer[0];
- Uint32* const afterBuffer = &coutBuffer[0];
- Uint32* const beforeBuffer = &clogMemBuffer[0];
-
- Uint32 noPrimKey, noAfterWords, noBeforeWords;
- FragrecordPtr regFragPtr;
- regFragPtr.i= regOperPtr->fragmentPtr;
- ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
-
- if (ref == BACKUP) {
- jam();
- /*
- In order for the implementation of BACKUP to work even when changing
- primaries in the middle of the backup we need to set the trigger on
- all replicas. This check checks whether this is the node where this
- trigger should be fired. The check should preferably have been put
- completely in the BACKUP block but it was about five times simpler
- to put it here and also much faster for the backup (small overhead
- for everybody else.
- */
- signal->theData[0] = trigPtr->triggerId;
- signal->theData[1] = regFragPtr.p->fragmentId;
- EXECUTE_DIRECT(BACKUP, GSN_BACKUP_TRIG_REQ, signal, 2);
- jamEntry();
- if (signal->theData[0] == 0) {
- jam();
- return;
- }
- }
- if (!readTriggerInfo(trigPtr,
- regOperPtr,
- req_struct,
- regFragPtr.p,
- keyBuffer,
- noPrimKey,
- afterBuffer,
- noAfterWords,
- beforeBuffer,
- noBeforeWords,
- disk)) {
- jam();
- return;
- }
-//--------------------------------------------------------------------
-// Now all data for this trigger has been read. It is now time to send
-// the trigger information consisting of two or three sets of TRIG_
-// ATTRINFO signals and one FIRE_TRIG_ORD signal.
-// We start by setting common header info for all TRIG_ATTRINFO signals.
-//--------------------------------------------------------------------
- bool executeDirect;
- TrigAttrInfo* const trigAttrInfo = (TrigAttrInfo *)signal->getDataPtrSend();
- trigAttrInfo->setConnectionPtr(req_struct->TC_index);
- trigAttrInfo->setTriggerId(trigPtr->triggerId);
-
- switch(trigPtr->triggerType) {
- case (TriggerType::SECONDARY_INDEX):
- jam();
- ref = req_struct->TC_ref;
- executeDirect = false;
- break;
- case (TriggerType::SUBSCRIPTION):
- case (TriggerType::SUBSCRIPTION_BEFORE):
- jam();
- // Since only backup uses subscription triggers we send to backup directly for now
- ref = trigPtr->m_receiverBlock;
- executeDirect = true;
- break;
- case (TriggerType::READ_ONLY_CONSTRAINT):
- terrorCode = ZREAD_ONLY_CONSTRAINT_VIOLATION;
- // XXX should return status and abort the rest
- return;
- default:
- ndbrequire(false);
- executeDirect= false; // remove warning
- }//switch
-
- req_struct->no_fired_triggers++;
-
- trigAttrInfo->setAttrInfoType(TrigAttrInfo::PRIMARY_KEY);
- sendTrigAttrInfo(signal, keyBuffer, noPrimKey, executeDirect, ref);
-
- switch(regOperPtr->op_struct.op_type) {
- case(ZINSERT):
- jam();
- // Send AttrInfo signals with new attribute values
- trigAttrInfo->setAttrInfoType(TrigAttrInfo::AFTER_VALUES);
- sendTrigAttrInfo(signal, afterBuffer, noAfterWords, executeDirect, ref);
- break;
- case(ZDELETE):
- if (trigPtr->sendBeforeValues) {
- jam();
- trigAttrInfo->setAttrInfoType(TrigAttrInfo::BEFORE_VALUES);
- sendTrigAttrInfo(signal, beforeBuffer, noBeforeWords, executeDirect,ref);
- }
- break;
- case(ZUPDATE):
- jam();
- if (trigPtr->sendBeforeValues) {
- jam();
- trigAttrInfo->setAttrInfoType(TrigAttrInfo::BEFORE_VALUES);
- sendTrigAttrInfo(signal, beforeBuffer, noBeforeWords, executeDirect,ref);
- }
- trigAttrInfo->setAttrInfoType(TrigAttrInfo::AFTER_VALUES);
- sendTrigAttrInfo(signal, afterBuffer, noAfterWords, executeDirect, ref);
- break;
- default:
- ndbrequire(false);
- }
- sendFireTrigOrd(signal,
- req_struct,
- regOperPtr,
- trigPtr,
- regFragPtr.p->fragmentId,
- noPrimKey,
- noBeforeWords,
- noAfterWords);
-}
-
-Uint32 Dbtup::setAttrIds(Bitmask<MAXNROFATTRIBUTESINWORDS>& attributeMask,
- Uint32 m_no_of_attributesibutes,
- Uint32* inBuffer)
-{
- Uint32 bufIndx = 0;
- for (Uint32 i = 0; i < m_no_of_attributesibutes; i++) {
- jam();
- if (attributeMask.get(i)) {
- jam();
- AttributeHeader::init(&inBuffer[bufIndx++], i, 0);
- }
- }
- return bufIndx;
-}
-
-bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr,
- Operationrec* const regOperPtr,
- KeyReqStruct *req_struct,
- Fragrecord* const regFragPtr,
- Uint32* const keyBuffer,
- Uint32& noPrimKey,
- Uint32* const afterBuffer,
- Uint32& noAfterWords,
- Uint32* const beforeBuffer,
- Uint32& noBeforeWords,
- bool disk)
-{
- noAfterWords = 0;
- noBeforeWords = 0;
- Uint32 readBuffer[MAX_ATTRIBUTES_IN_TABLE];
-
-//---------------------------------------------------------------------------
-// Set-up variables needed by readAttributes operPtr.p, tabptr.p
-//---------------------------------------------------------------------------
- operPtr.p = regOperPtr;
- tabptr.i = regFragPtr->fragTableId;
- ptrCheckGuard(tabptr, cnoOfTablerec, tablerec);
-
- Tablerec* const regTabPtr = tabptr.p;
- Uint32 num_attr= regTabPtr->m_no_of_attributes;
- Uint32 descr_start= regTabPtr->tabDescriptor;
- ndbrequire(descr_start + (num_attr << ZAD_LOG_SIZE) <= cnoOfTabDescrRec);
-
- req_struct->check_offset[MM]= regTabPtr->get_check_offset(MM);
- req_struct->check_offset[DD]= regTabPtr->get_check_offset(DD);
- req_struct->attr_descr= &tableDescriptor[descr_start];
-
-//--------------------------------------------------------------------
-// Read Primary Key Values
-//--------------------------------------------------------------------
- Tuple_header *save0= req_struct->m_tuple_ptr;
- if (regOperPtr->op_struct.op_type == ZDELETE &&
- !regOperPtr->is_first_operation())
- {
- jam();
- req_struct->m_tuple_ptr= (Tuple_header*)
- c_undo_buffer.get_ptr(&req_struct->prevOpPtr.p->m_copy_tuple_location);
- }
-
- if (regTabPtr->need_expand(disk))
- prepare_read(req_struct, regTabPtr, disk);
-
- int ret = readAttributes(req_struct,
- &tableDescriptor[regTabPtr->readKeyArray].tabDescr,
- regTabPtr->noOfKeyAttr,
- keyBuffer,
- ZATTR_BUFFER_SIZE,
- false);
- ndbrequire(ret != -1);
- noPrimKey= ret;
-
- req_struct->m_tuple_ptr = save0;
-
- Uint32 numAttrsToRead;
- if ((regOperPtr->op_struct.op_type == ZUPDATE) &&
- (trigPtr->sendOnlyChangedAttributes)) {
- jam();
-//--------------------------------------------------------------------
-// Update that sends only changed information
-//--------------------------------------------------------------------
- Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
- attributeMask = trigPtr->attributeMask;
- attributeMask.bitAND(req_struct->changeMask);
- numAttrsToRead = setAttrIds(attributeMask, regTabPtr->m_no_of_attributes,
- &readBuffer[0]);
-
- } else if ((regOperPtr->op_struct.op_type == ZDELETE) &&
- (!trigPtr->sendBeforeValues)) {
- jam();
-//--------------------------------------------------------------------
-// Delete without sending before values only read Primary Key
-//--------------------------------------------------------------------
- return true;
- } else {
- jam();
-//--------------------------------------------------------------------
-// All others send all attributes that are monitored, except:
-// Omit unchanged blob inlines on update i.e.
-// attributeMask & ~ (blobAttributeMask & ~ changeMask)
-//--------------------------------------------------------------------
- Bitmask<MAXNROFATTRIBUTESINWORDS> attributeMask;
- attributeMask = trigPtr->attributeMask;
- if (regOperPtr->op_struct.op_type == ZUPDATE) {
- Bitmask<MAXNROFATTRIBUTESINWORDS> tmpMask = regTabPtr->blobAttributeMask;
- tmpMask.bitANDC(req_struct->changeMask);
- attributeMask.bitANDC(tmpMask);
- }
- numAttrsToRead = setAttrIds(attributeMask, regTabPtr->m_no_of_attributes,
- &readBuffer[0]);
- }
- ndbrequire(numAttrsToRead < MAX_ATTRIBUTES_IN_TABLE);
-//--------------------------------------------------------------------
-// Read Main tuple values
-//--------------------------------------------------------------------
- if (regOperPtr->op_struct.op_type != ZDELETE)
- {
- jam();
- int ret = readAttributes(req_struct,
- &readBuffer[0],
- numAttrsToRead,
- afterBuffer,
- ZATTR_BUFFER_SIZE,
- false);
- ndbrequire(ret != -1);
- noAfterWords= ret;
- } else {
- jam();
- noAfterWords = 0;
- }
-
-//--------------------------------------------------------------------
-// Read Copy tuple values for UPDATE's
-//--------------------------------------------------------------------
-// Initialise pagep and tuple offset for read of copy tuple
-//--------------------------------------------------------------------
- if ((regOperPtr->op_struct.op_type == ZUPDATE ||
- regOperPtr->op_struct.op_type == ZDELETE) &&
- (trigPtr->sendBeforeValues)) {
- jam();
-
- Tuple_header *save= req_struct->m_tuple_ptr;
- PagePtr tmp;
- if(regOperPtr->is_first_operation())
- {
- Uint32 *ptr= get_ptr(&tmp, &regOperPtr->m_tuple_location, regTabPtr);
- req_struct->m_tuple_ptr= (Tuple_header*)ptr;
- }
- else
- {
- Uint32 *ptr=
- c_undo_buffer.get_ptr(&req_struct->prevOpPtr.p->m_copy_tuple_location);
-
- req_struct->m_tuple_ptr= (Tuple_header*)ptr;
- }
-
- if (regTabPtr->need_expand(disk))
- prepare_read(req_struct, regTabPtr, disk);
-
- int ret = readAttributes(req_struct,
- &readBuffer[0],
- numAttrsToRead,
- beforeBuffer,
- ZATTR_BUFFER_SIZE,
- false);
- req_struct->m_tuple_ptr= save;
- ndbrequire(ret != -1);
- noBeforeWords = ret;
- if (trigPtr->m_receiverBlock != SUMA &&
- (noAfterWords == noBeforeWords) &&
- (memcmp(afterBuffer, beforeBuffer, noAfterWords << 2) == 0)) {
-//--------------------------------------------------------------------
-// Although a trigger was fired it was not necessary since the old
-// value and the new value was exactly the same
-//--------------------------------------------------------------------
- jam();
- //XXX does this work with collations?
- return false;
- }
- }
- return true;
-}
-
-void Dbtup::sendTrigAttrInfo(Signal* signal,
- Uint32* data,
- Uint32 dataLen,
- bool executeDirect,
- BlockReference receiverReference)
-{
- TrigAttrInfo* const trigAttrInfo = (TrigAttrInfo *)signal->getDataPtrSend();
- Uint32 sigLen;
- Uint32 dataIndex = 0;
- do {
- sigLen = dataLen - dataIndex;
- if (sigLen > TrigAttrInfo::DataLength) {
- jam();
- sigLen = TrigAttrInfo::DataLength;
- }
- MEMCOPY_NO_WORDS(trigAttrInfo->getData(),
- data + dataIndex,
- sigLen);
- if (executeDirect) {
- jam();
- EXECUTE_DIRECT(receiverReference,
- GSN_TRIG_ATTRINFO,
- signal,
- TrigAttrInfo::StaticLength + sigLen);
- jamEntry();
- } else {
- jam();
- sendSignal(receiverReference,
- GSN_TRIG_ATTRINFO,
- signal,
- TrigAttrInfo::StaticLength + sigLen,
- JBB);
- }
- dataIndex += sigLen;
- } while (dataLen != dataIndex);
-}
-
-void Dbtup::sendFireTrigOrd(Signal* signal,
- KeyReqStruct *req_struct,
- Operationrec * const regOperPtr,
- TupTriggerData* const trigPtr,
- Uint32 fragmentId,
- Uint32 noPrimKeyWords,
- Uint32 noBeforeValueWords,
- Uint32 noAfterValueWords)
-{
- FireTrigOrd* const fireTrigOrd = (FireTrigOrd *)signal->getDataPtrSend();
-
- fireTrigOrd->setConnectionPtr(req_struct->TC_index);
- fireTrigOrd->setTriggerId(trigPtr->triggerId);
- fireTrigOrd->fragId= fragmentId;
-
- switch(regOperPtr->op_struct.op_type) {
- case(ZINSERT):
- jam();
- fireTrigOrd->setTriggerEvent(TriggerEvent::TE_INSERT);
- break;
- case(ZDELETE):
- jam();
- fireTrigOrd->setTriggerEvent(TriggerEvent::TE_DELETE);
- break;
- case(ZUPDATE):
- jam();
- fireTrigOrd->setTriggerEvent(TriggerEvent::TE_UPDATE);
- break;
- default:
- ndbrequire(false);
- break;
- }
-
- fireTrigOrd->setNoOfPrimaryKeyWords(noPrimKeyWords);
- fireTrigOrd->setNoOfBeforeValueWords(noBeforeValueWords);
- fireTrigOrd->setNoOfAfterValueWords(noAfterValueWords);
-
- switch(trigPtr->triggerType) {
- case (TriggerType::SECONDARY_INDEX):
- jam();
- sendSignal(req_struct->TC_ref, GSN_FIRE_TRIG_ORD,
- signal, FireTrigOrd::SignalLength, JBB);
- break;
- case (TriggerType::SUBSCRIPTION_BEFORE): // Only Suma
- jam();
- // Since only backup uses subscription triggers we
- // send to backup directly for now
- fireTrigOrd->setGCI(req_struct->gci);
- fireTrigOrd->setHashValue(req_struct->hash_value);
- fireTrigOrd->m_any_value = regOperPtr->m_any_value;
- EXECUTE_DIRECT(trigPtr->m_receiverBlock,
- GSN_FIRE_TRIG_ORD,
- signal,
- FireTrigOrd::SignalLengthSuma);
- break;
- case (TriggerType::SUBSCRIPTION):
- jam();
- // Since only backup uses subscription triggers we
- // send to backup directly for now
- fireTrigOrd->setGCI(req_struct->gci);
- EXECUTE_DIRECT(trigPtr->m_receiverBlock,
- GSN_FIRE_TRIG_ORD,
- signal,
- FireTrigOrd::SignalWithGCILength);
- break;
- default:
- ndbrequire(false);
- break;
- }
-}
-
-/*
- * Ordered index triggers.
- *
- * Insert: add entry to index
- * Update: add entry to index, de|ay remove until commit
- * Delete: do nothing, delay remove until commit
- * Commit: remove entry delayed from update and delete
- * Abort : remove entry added by insert and update
- *
- * See Notes.txt for the details.
- */
-
-int
-Dbtup::executeTuxInsertTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- // fill in constant part
- req->tableId = regFragPtr->fragTableId;
- req->fragId = regFragPtr->fragmentId;
- req->pageId = regOperPtr->m_tuple_location.m_page_no;
- req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
- req->tupVersion = regOperPtr->tupVersion;
- req->opInfo = TuxMaintReq::OpAdd;
- return addTuxEntries(signal, regOperPtr, regTabPtr);
-}
-
-int
-Dbtup::executeTuxUpdateTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- // fill in constant part
- req->tableId = regFragPtr->fragTableId;
- req->fragId = regFragPtr->fragmentId;
- req->pageId = regOperPtr->m_tuple_location.m_page_no;
- req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
- req->tupVersion = regOperPtr->tupVersion;
- req->opInfo = TuxMaintReq::OpAdd;
- return addTuxEntries(signal, regOperPtr, regTabPtr);
-}
-
-int
-Dbtup::addTuxEntries(Signal* signal,
- Operationrec* regOperPtr,
- Tablerec* regTabPtr)
-{
- if (ERROR_INSERTED(4022)) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- terrorCode = 9999;
- return -1;
- }
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- const DLList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
- TriggerPtr triggerPtr;
- Uint32 failPtrI;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != RNIL) {
- jam();
- req->indexId = triggerPtr.p->indexId;
- req->errorCode = RNIL;
- if (ERROR_INSERTED(4023) &&
- ! triggerList.hasNext(triggerPtr)) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- terrorCode = 9999;
- failPtrI = triggerPtr.i;
- goto fail;
- }
- EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength);
- jamEntry();
- if (req->errorCode != 0) {
- jam();
- terrorCode = req->errorCode;
- failPtrI = triggerPtr.i;
- goto fail;
- }
- triggerList.next(triggerPtr);
- }
- return 0;
-fail:
- req->opInfo = TuxMaintReq::OpRemove;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != failPtrI) {
- jam();
- req->indexId = triggerPtr.p->indexId;
- req->errorCode = RNIL;
- EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength);
- jamEntry();
- ndbrequire(req->errorCode == 0);
- triggerList.next(triggerPtr);
- }
-#ifdef VM_TRACE
- ndbout << "aborted partial tux update: op " << hex << regOperPtr << endl;
-#endif
- return -1;
-}
-
-int
-Dbtup::executeTuxDeleteTriggers(Signal* signal,
- Operationrec* const regOperPtr,
- Fragrecord* const regFragPtr,
- Tablerec* const regTabPtr)
-{
- // do nothing
- return 0;
-}
-
-void
-Dbtup::executeTuxCommitTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- Uint32 tupVersion;
- if (regOperPtr->op_struct.op_type == ZINSERT) {
- if (! regOperPtr->op_struct.delete_insert_flag)
- return;
- jam();
- tupVersion= decr_tup_version(regOperPtr->tupVersion);
- } else if (regOperPtr->op_struct.op_type == ZUPDATE) {
- jam();
- tupVersion= decr_tup_version(regOperPtr->tupVersion);
- } else if (regOperPtr->op_struct.op_type == ZDELETE) {
- if (regOperPtr->op_struct.delete_insert_flag)
- return;
- jam();
- tupVersion= regOperPtr->tupVersion;
- } else {
- ndbrequire(false);
- tupVersion= 0; // remove warning
- }
- // fill in constant part
- req->tableId = regFragPtr->fragTableId;
- req->fragId = regFragPtr->fragmentId;
- req->pageId = regOperPtr->m_tuple_location.m_page_no;
- req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
- req->tupVersion = tupVersion;
- req->opInfo = TuxMaintReq::OpRemove;
- removeTuxEntries(signal, regTabPtr);
-}
-
-void
-Dbtup::executeTuxAbortTriggers(Signal* signal,
- Operationrec* regOperPtr,
- Fragrecord* regFragPtr,
- Tablerec* regTabPtr)
-{
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- // get version
- Uint32 tupVersion;
- if (regOperPtr->op_struct.op_type == ZINSERT) {
- jam();
- tupVersion = regOperPtr->tupVersion;
- } else if (regOperPtr->op_struct.op_type == ZUPDATE) {
- jam();
- tupVersion = regOperPtr->tupVersion;
- } else if (regOperPtr->op_struct.op_type == ZDELETE) {
- jam();
- return;
- } else {
- ndbrequire(false);
- tupVersion= 0; // remove warning
- }
- // fill in constant part
- req->tableId = regFragPtr->fragTableId;
- req->fragId = regFragPtr->fragmentId;
- req->pageId = regOperPtr->m_tuple_location.m_page_no;
- req->pageIndex = regOperPtr->m_tuple_location.m_page_idx;
- req->tupVersion = tupVersion;
- req->opInfo = TuxMaintReq::OpRemove;
- removeTuxEntries(signal, regTabPtr);
-}
-
-void
-Dbtup::removeTuxEntries(Signal* signal,
- Tablerec* regTabPtr)
-{
- TuxMaintReq* const req = (TuxMaintReq*)signal->getDataPtrSend();
- const DLList<TupTriggerData>& triggerList = regTabPtr->tuxCustomTriggers;
- TriggerPtr triggerPtr;
- triggerList.first(triggerPtr);
- while (triggerPtr.i != RNIL) {
- jam();
- req->indexId = triggerPtr.p->indexId;
- req->errorCode = RNIL,
- EXECUTE_DIRECT(DBTUX, GSN_TUX_MAINT_REQ,
- signal, TuxMaintReq::SignalLength);
- jamEntry();
- // must succeed
- ndbrequire(req->errorCode == 0);
- triggerList.next(triggerPtr);
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
deleted file mode 100644
index 499a05a40f6..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-/* Copyright (c) 2004-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUP_C
-#define DBTUP_VAR_ALLOC_CPP
-#include "Dbtup.hpp"
-
-void Dbtup::init_list_sizes(void)
-{
- c_min_list_size[0]= 200;
- c_max_list_size[0]= 499;
-
- c_min_list_size[1]= 500;
- c_max_list_size[1]= 999;
-
- c_min_list_size[2]= 1000;
- c_max_list_size[2]= 4079;
-
- c_min_list_size[3]= 4080;
- c_max_list_size[3]= 8159;
-
- c_min_list_size[4]= 0;
- c_max_list_size[4]= 199;
-}
-
-/*
- Allocator for variable sized segments
- Part of the external interface for variable sized segments
-
- This method is used to allocate and free variable sized tuples and
- parts of tuples. This part can be used to implement variable sized
- attributes without wasting memory. It can be used to support small
- BLOB's attached to the record. It can also be used to support adding
- and dropping attributes without the need to copy the entire table.
-
- SYNOPSIS
- fragPtr A pointer to the fragment description
- tabPtr A pointer to the table description
- alloc_size Size of the allocated record
- signal The signal object to be used if a signal needs to
- be sent
- RETURN VALUES
- Returns true if allocation was successful otherwise false
-
- page_offset Page offset of allocated record
- page_index Page index of allocated record
- page_ptr The i and p value of the page where the record was
- allocated
-*/
-Uint32* Dbtup::alloc_var_rec(Fragrecord* fragPtr,
- Tablerec* tabPtr,
- Uint32 alloc_size,
- Local_key* key,
- Uint32 * out_frag_page_id)
-{
- /**
- * TODO alloc fix+var part
- */
- Uint32 *ptr = alloc_fix_rec(fragPtr, tabPtr, key, out_frag_page_id);
- if (unlikely(ptr == 0))
- {
- return 0;
- }
-
- ndbassert(alloc_size >= tabPtr->m_offsets[MM].m_fix_header_size);
-
- alloc_size -= tabPtr->m_offsets[MM].m_fix_header_size;
-
-
- Local_key varref;
- if (likely(alloc_var_part(fragPtr, tabPtr, alloc_size, &varref) != 0))
- {
- Tuple_header* tuple = (Tuple_header*)ptr;
- Var_part_ref* dst = tuple->get_var_part_ref_ptr(tabPtr);
- dst->assign(&varref);
- return ptr;
- }
-
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, key->m_page_no);
- free_fix_rec(fragPtr, tabPtr, key, (Fix_page*)pagePtr.p);
- return 0;
-}
-
-Uint32*
-Dbtup::alloc_var_part(Fragrecord* fragPtr,
- Tablerec* tabPtr,
- Uint32 alloc_size,
- Local_key* key)
-{
- PagePtr pagePtr;
- pagePtr.i= get_alloc_page(fragPtr, (alloc_size + 1));
- if (pagePtr.i == RNIL) {
- jam();
- if ((pagePtr.i= get_empty_var_page(fragPtr)) == RNIL) {
- jam();
- return 0;
- }
- c_page_pool.getPtr(pagePtr);
- ((Var_page*)pagePtr.p)->init();
- pagePtr.p->list_index = MAX_FREE_LIST - 1;
- LocalDLList<Page> list(c_page_pool,
- fragPtr->free_var_page_array[MAX_FREE_LIST-1]);
- list.add(pagePtr);
- /*
- * Tup scan and index build check ZEMPTY_MM to skip un-init()ed
- * page. Change state here. For varsize it means "page in use".
- */
- pagePtr.p->page_state = ZTH_MM_FREE;
- } else {
- c_page_pool.getPtr(pagePtr);
- jam();
- }
- Uint32 idx= ((Var_page*)pagePtr.p)
- ->alloc_record(alloc_size, (Var_page*)ctemp_page, Var_page::CHAIN);
-
- key->m_page_no = pagePtr.i;
- key->m_page_idx = idx;
-
- update_free_page_list(fragPtr, pagePtr);
- return ((Var_page*)pagePtr.p)->get_ptr(idx);
-}
-
-/*
- Deallocator for variable sized segments
- Part of the external interface for variable sized segments
-
- SYNOPSIS
- fragPtr A pointer to the fragment description
- tabPtr A pointer to the table description
- signal The signal object to be used if a signal needs to
- be sent
- page_ptr A reference to the page of the variable sized
- segment
- free_page_index Page index on page of variable sized segment
- which is freed
- RETURN VALUES
- Returns true if deallocation was successful otherwise false
-*/
-void Dbtup::free_var_rec(Fragrecord* fragPtr,
- Tablerec* tabPtr,
- Local_key* key,
- Ptr<Page> pagePtr)
-{
- /**
- * TODO free fix + var part
- */
- Uint32 *ptr = ((Fix_page*)pagePtr.p)->get_ptr(key->m_page_idx, 0);
- Tuple_header* tuple = (Tuple_header*)ptr;
-
- Local_key ref;
- Var_part_ref * varref = tuple->get_var_part_ref_ptr(tabPtr);
- varref->copyout(&ref);
-
- free_fix_rec(fragPtr, tabPtr, key, (Fix_page*)pagePtr.p);
-
- c_page_pool.getPtr(pagePtr, ref.m_page_no);
- ((Var_page*)pagePtr.p)->free_record(ref.m_page_idx, Var_page::CHAIN);
-
- ndbassert(pagePtr.p->free_space <= Var_page::DATA_WORDS);
- if (pagePtr.p->free_space == Var_page::DATA_WORDS - 1)
- {
- jam();
- /*
- This code could be used when we release pages.
- remove_free_page(signal,fragPtr,page_header,page_header->list_index);
- return_empty_page(fragPtr, page_header);
- */
- update_free_page_list(fragPtr, pagePtr);
- } else {
- jam();
- update_free_page_list(fragPtr, pagePtr);
- }
- return;
-}
-
-int
-Dbtup::realloc_var_part(Fragrecord* fragPtr, Tablerec* tabPtr, PagePtr pagePtr,
- Var_part_ref* refptr, Uint32 oldsz, Uint32 newsz)
-{
- Uint32 add = newsz - oldsz;
- Var_page* pageP = (Var_page*)pagePtr.p;
- Local_key oldref;
- refptr->copyout(&oldref);
-
- if (pageP->free_space >= add)
- {
- jam();
- if(!pageP->is_space_behind_entry(oldref.m_page_idx, add))
- {
- if(0) printf("extra reorg");
- jam();
- /**
- * In this case we need to reorganise the page to fit. To ensure we
- * don't complicate matters we make a little trick here where we
- * fool the reorg_page to avoid copying the entry at hand and copy
- * that separately at the end. This means we need to copy it out of
- * the page before reorg_page to save the entry contents.
- */
- Uint32* copyBuffer= cinBuffer;
- memcpy(copyBuffer, pageP->get_ptr(oldref.m_page_idx), 4*oldsz);
- pageP->set_entry_len(oldref.m_page_idx, 0);
- pageP->free_space += oldsz;
- pageP->reorg((Var_page*)ctemp_page);
- memcpy(pageP->get_free_space_ptr(), copyBuffer, 4*oldsz);
- pageP->set_entry_offset(oldref.m_page_idx, pageP->insert_pos);
- add += oldsz;
- }
- pageP->grow_entry(oldref.m_page_idx, add);
- update_free_page_list(fragPtr, pagePtr);
- }
- else
- {
- Local_key newref;
- Uint32 *src = pageP->get_ptr(oldref.m_page_idx);
- Uint32 *dst = alloc_var_part(fragPtr, tabPtr, newsz, &newref);
- if (unlikely(dst == 0))
- return -1;
-
- ndbassert(oldref.m_page_no != newref.m_page_no);
- ndbassert(pageP->get_entry_len(oldref.m_page_idx) == oldsz);
- memcpy(dst, src, 4*oldsz);
- refptr->assign(&newref);
-
- pageP->free_record(oldref.m_page_idx, Var_page::CHAIN);
- update_free_page_list(fragPtr, pagePtr);
- }
-
- return 0;
-}
-
-
-/* ------------------------------------------------------------------------ */
-// Get a page from one of free lists. If the desired free list is empty we
-// try with the next until we have tried all possible lists.
-/* ------------------------------------------------------------------------ */
-Uint32
-Dbtup::get_alloc_page(Fragrecord* fragPtr, Uint32 alloc_size)
-{
- Uint32 i, start_index, loop= 0;
- PagePtr pagePtr;
-
- start_index= calculate_free_list_impl(alloc_size);
- if (start_index == (MAX_FREE_LIST - 1)) {
- jam();
- } else {
- jam();
- ndbrequire(start_index < (MAX_FREE_LIST - 1));
- start_index++;
- }
- for (i= start_index; i < MAX_FREE_LIST; i++) {
- jam();
- if (!fragPtr->free_var_page_array[i].isEmpty()) {
- jam();
- return fragPtr->free_var_page_array[i].firstItem;
- }
- }
- ndbrequire(start_index > 0);
- i= start_index - 1;
- LocalDLList<Page> list(c_page_pool, fragPtr->free_var_page_array[i]);
- for(list.first(pagePtr); !pagePtr.isNull() && loop < 16; )
- {
- jam();
- if (pagePtr.p->free_space >= alloc_size) {
- jam();
- return pagePtr.i;
- }
- loop++;
- list.next(pagePtr);
- }
- return RNIL;
-}
-
-Uint32
-Dbtup::get_empty_var_page(Fragrecord* fragPtr)
-{
- PagePtr ptr;
- LocalSLList<Page> list(c_page_pool, fragPtr->m_empty_pages);
- if (list.remove_front(ptr))
- {
- return ptr.i;
- }
-
- Uint32 cnt;
- allocConsPages(10, cnt, ptr.i);
- fragPtr->noOfVarPages+= cnt;
- if (unlikely(cnt == 0))
- {
- return RNIL;
- }
-
- PagePtr ret = ptr;
- for (Uint32 i = 0; i<cnt; i++, ptr.i++)
- {
- c_page_pool.getPtr(ptr);
- ptr.p->physical_page_id = ptr.i;
- ptr.p->page_state = ZEMPTY_MM;
- ptr.p->nextList = ptr.i + 1;
- ptr.p->prevList = RNIL;
- ptr.p->frag_page_id = RNIL;
- }
-
- if (cnt > 1)
- {
- ptr.p->nextList = RNIL;
- list.add(ret.i + 1, ptr);
- }
-
- c_page_pool.getPtr(ret);
-
- Var_page* page = (Var_page*)ret.p;
- page->chunk_size = cnt;
- page->next_chunk = fragPtr->m_var_page_chunks;
- fragPtr->m_var_page_chunks = ret.i;
-
- return ret.i;
-}
-
-/* ------------------------------------------------------------------------ */
-// Check if the page needs to go to a new free page list.
-/* ------------------------------------------------------------------------ */
-void Dbtup::update_free_page_list(Fragrecord* fragPtr,
- Ptr<Page> pagePtr)
-{
- Uint32 free_space, list_index;
- free_space= pagePtr.p->free_space;
- list_index= pagePtr.p->list_index;
- if ((free_space < c_min_list_size[list_index]) ||
- (free_space > c_max_list_size[list_index])) {
- Uint32 new_list_index= calculate_free_list_impl(free_space);
- if (list_index != MAX_FREE_LIST) {
- jam();
- /*
- * Only remove it from its list if it is in a list
- */
- LocalDLList<Page>
- list(c_page_pool, fragPtr->free_var_page_array[list_index]);
- list.remove(pagePtr);
- }
- if (free_space < c_min_list_size[new_list_index]) {
- /*
- We have not sufficient amount of free space to put it into any
- free list. Thus the page will not be available for new inserts.
- This can only happen for the free list with least guaranteed
- free space.
- */
- jam();
- ndbrequire(new_list_index == 0);
- pagePtr.p->list_index= MAX_FREE_LIST;
- } else {
- jam();
- LocalDLList<Page> list(c_page_pool,
- fragPtr->free_var_page_array[new_list_index]);
- list.add(pagePtr);
- pagePtr.p->list_index = new_list_index;
- }
- }
-}
-
-/* ------------------------------------------------------------------------ */
-// Given size of free space, calculate the free list to put it into
-/* ------------------------------------------------------------------------ */
-Uint32 Dbtup::calculate_free_list_impl(Uint32 free_space_size) const
-{
- Uint32 i;
- for (i = 0; i < MAX_FREE_LIST; i++) {
- jam();
- if (free_space_size <= c_max_list_size[i]) {
- jam();
- return i;
- }
- }
- ndbrequire(false);
- return 0;
-}
-
-Uint32*
-Dbtup::alloc_var_rowid(Fragrecord* fragPtr,
- Tablerec* tabPtr,
- Uint32 alloc_size,
- Local_key* key,
- Uint32 * out_frag_page_id)
-{
- Uint32 *ptr = alloc_fix_rowid(fragPtr, tabPtr, key, out_frag_page_id);
- if (unlikely(ptr == 0))
- {
- return 0;
- }
-
- ndbassert(alloc_size >= tabPtr->m_offsets[MM].m_fix_header_size);
-
- alloc_size -= tabPtr->m_offsets[MM].m_fix_header_size;
-
- Local_key varref;
- if (likely(alloc_var_part(fragPtr, tabPtr, alloc_size, &varref) != 0))
- {
- Tuple_header* tuple = (Tuple_header*)ptr;
- Var_part_ref* dst = (Var_part_ref*)tuple->get_var_part_ref_ptr(tabPtr);
- dst->assign(&varref);
- return ptr;
- }
-
- PagePtr pagePtr;
- c_page_pool.getPtr(pagePtr, key->m_page_no);
- free_fix_rec(fragPtr, tabPtr, key, (Fix_page*)pagePtr.p);
- return 0;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Makefile.am b/storage/ndb/src/kernel/blocks/dbtup/Makefile.am
deleted file mode 100644
index 3c424449dc5..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-EXTRA_PROGRAMS = test_varpage
-test_varpage_SOURCES = test_varpage.cpp tuppage.cpp
-test_varpage_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/strings/libmystrings.a
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Notes.txt b/storage/ndb/src/kernel/blocks/dbtup/Notes.txt
deleted file mode 100644
index c2973bb0a76..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/Notes.txt
+++ /dev/null
@@ -1,198 +0,0 @@
-Operations, tuples, versions
-============================
-
-Operation types.
-
-INSERT insert new original tuple, or insert after delete
-UPDATE update
-DELETE delete
-
-Following need not be considered here.
-
-READ does not change tuples or versions
-WRITE turns into INSERT or UPDATE in LQH
-
-We use more specific names in some cases:
-
-first/INSERT initial insert of new tuple
-delete/INSERT INSERT preceded by DELETE
-DELETE/last DELETE as last operation
-DELETE/insert DELETE followed by INSERT
-
-Tuple + op Can be followed by
--------------- ------------------
-does not exist first/INSERT
-tuple exists UPDATE DELETE
-INSERT UPDATE DELETE
-UPDATE UPDATE DELETE
-DELETE delete/INSERT
-
-Operations on same tuple are kept in doubly linked list until
-commit or abort. The links at both ends are RNIL i.e. the list
-is not circular. The links are:
-
-nextActiveOp the operation BEFORE this one, in event order
-prevActiveOp the operation AFTER this one, in event order
-
-Operations are done on the "original tuple" i.e. the tuple is
-modified in place. If an operation is about to write over data
-in original tuple, it first copies the tuple to a "copy tuple".
-
-Operation Copy tuple
---------- ----------
-first/INSERT no
-delete/INSERT yes (this is in effect an update)
-UPDATE yes
-DELETE no
-
-The operation points to the tuples via:
-
-realPageId page i-value of original tuple
-pageOffset word offset of original tuple on the page
-realPageIdC page i-value of copy tuple or RNIL is no copy exists
-pageOffsetC word offset of copy tuple on the page
-
-The original tuple and the copy tuple (if any) point back to
-the operation via word 0. In copy tuple this pointer is never
-changed. In original tuple however it always points to the LATEST
-existing operation i.e. the one with prevActiveOp == RNIL.
-Thus word 0 of original tuple is changed on 2 occasions:
-
-- when a new operation is added to the list
-- when commit or abort removes the latest operation
-
-Note that commit/abort of operations occurs in random order.
-The list is adjusted accordingly.
-
-Versions
---------
-
-Tuple version is stored in tuple word 1. A new original tuple
-gets version 0. The version is incremented by each new operation
-which makes a copy tuple. Version number wraps around at 15 bits.
-
-When a copy tuple is made, the version in original tuple is copied
-to copy tuple as part of tuple data. This takes place before
-the version in original tuple is updated.
-
-Each operation record contains tuple version called tupVersion.
-
-- at insert of new original tuple, tupVersion is set to 0
-
-- if tuple already exists, the FIRST operation (in event order)
- reads tupVersion from tuple word 1. If the operation is
- not DELETE, the version is incremented
-
-- subsequent operation reads tupVersion from the operation
- BEFORE it (nextActiveOp). If this subsequent operation is
- not DELETE, the version is incremented
-
-When the operation writes the tuple it sets word 1 to tupVersion.
-In detail, per operation type, where INSERT is divided into
-insert of new original tuple and insert after delete:
-
-Operation Copy Increment Set version in original
---------- ---- --------- -----------------------
-first/INSERT no no yes, to 0
-delete/INSERT yes yes yes
-UPDATE yes yes yes
-DELETE no no no
-
-Thus an existing version is incremented if and only if
-a copy tuple is made.
-
-Ordered index maintenance
--------------------------
-
-Each index entry has logical tuple address and tuple version.
-Index entries are added during prepare phase (when each operation
-is executed) and removed during commit or abort phase.
-
-Access to correct tuple version (original or copy) is required
-in TUX which reads index key values 1) to check that at least one
-is not null 2) to do tree search 3) to set min/max prefixes.
-See "Read attributes" below.
-
-An additional complication is that commit/abort of operations
-arrives in random order. So we cannot check for, for example,
-DELETE/insert by looking at prevActiveOp.
-
-Phase Op Action Version in
------ -- ------ ----------
-prepare INSERT add op and original
-prepare UPDATE add op and original
-prepare DELETE none -
-
-commit first/INSERT none -
-commit delete/INSERT remove copy tuple 1)
-commit UPDATE remove copy tuple 1)
-commit DELETE/last remove op and original
-commit DELETE/insert none -
-
-abort INSERT remove op
-abort UPDATE remove op
-abort DELETE none -
-
-1) alternatively, store prevTupVersion in operation record.
-
-Abort from ordered index error
-------------------------------
-
-Obviously, index update failure causes operation failure.
-The operation is then aborted later by TC.
-
-The problem here is with multiple indexes. Some may have been
-updated successfully before the one that failed. Therefore
-the trigger code aborts the successful ones already in
-the prepare phase.
-
-In other words, multiple indexes are treated as one.
-
-Abort from any cause
---------------------
-
-[ hairy stuff ]
-
-Read attributes, query status
------------------------------
-
-TUP_READ_ATTRS signal (or equivalent direct call) reads attribute
-values. Input is logical address of original tuple and tuple
-version. The steps are:
-
-- Translate logical address to physical address of original tuple.
-
-- If version of original tuple in word 1 is right, stop.
-
-- Otherwise word 0 points to LATEST not yet deleted operation.
- Walk through operation list via nextActiveOp.
-
-- If an operation on the list has realPageIdC == RNIL, skip it.
-
-- Otherwise find copy tuple via realPageIdC, pageOffsetC.
- If the version of the copy tuple in word 1 is right, stop.
-
-- Call readAttributes() on the tuple found (original or copy).
-
-In short, the version must exist in some not yet deleted tuple,
-either in original or in some copy.
-
-Note that this must work during all phases since index code
-needs to read index key attributes from correct tuple version in
-each add/remove operation.
-
-TUP_QUERY_TH signal (or equivalent direct call) does same search
-for tuple version. It is called from index scan and returns info
-used to decide if the scan can see the tuple.
-
-This signal may also be called during any phase since commit/abort
-of all operations is not done in one time-slice.
-
-Problems
---------
-
-Current abort code can destroy a tuple version too early. This
-happens in test case "ticuur" (insert-commit-update-update-rollback),
-if abort of first update arrives before abort of second update.
-
-vim: set textwidth=68:
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp
deleted file mode 100644
index bb45f4e0e0e..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Undo_buffer.hpp"
-#define DBTUP_C
-#include "Dbtup.hpp"
-
-#if ZPAGE_STATE_POS != 0
-#error "PROBLEM!"
-#endif
-
-struct UndoPage
-{
- File_formats::Page_header m_page_header;
- Uint32 _tupdata1;
- Uint32 m_state; // Used by buddy alg
- Uint32 m_words_used;
- Uint32 m_ref_count;
- Uint32 m_data[GLOBAL_PAGE_SIZE_WORDS-4-(sizeof(File_formats::Page_header)>>2)];
-
- STATIC_CONST( DATA_WORDS = GLOBAL_PAGE_SIZE_WORDS-4-(sizeof(File_formats::Page_header)>>2) );
-};
-
-Undo_buffer::Undo_buffer(Dbtup* tup)
-{
- m_tup= tup;
- m_first_free= RNIL;
-}
-
-Uint32 *
-Undo_buffer::alloc_copy_tuple(Local_key* dst, Uint32 words)
-{
- UndoPage* page;
- assert(words);
- if(m_first_free == RNIL)
- {
- Uint32 count;
- m_tup->allocConsPages(1, count, m_first_free);
- if(count == 0)
- return 0;
- page= (UndoPage*)m_tup->c_page_pool.getPtr(m_first_free);
- page->m_state= ~ZFREE_COMMON;
- page->m_words_used= 0;
- page->m_ref_count= 0;
- }
-
- page= (UndoPage*)m_tup->c_page_pool.getPtr(m_first_free);
-
- Uint32 pos= page->m_words_used;
- if(words + pos > UndoPage::DATA_WORDS)
- {
- m_first_free= RNIL;
- return alloc_copy_tuple(dst, words);
- }
-
- dst->m_page_no = m_first_free;
- dst->m_page_idx = pos;
-
- page->m_ref_count++;
- page->m_words_used = pos + words;
- return page->m_data + pos;
-}
-
-void
-Undo_buffer::shrink_copy_tuple(Local_key* key, Uint32 words)
-{
- assert(key->m_page_no == m_first_free);
- UndoPage* page= (UndoPage*)m_tup->c_page_pool.getPtr(key->m_page_no);
- assert(page->m_words_used >= words);
- page->m_words_used -= words;
-}
-
-void
-Undo_buffer::free_copy_tuple(Local_key* key)
-{
- UndoPage* page= (UndoPage*)m_tup->c_page_pool.getPtr(key->m_page_no);
- Uint32 cnt= page->m_ref_count;
- assert(cnt);
-
- page->m_ref_count= cnt - 1;
-
- if(cnt - 1 == 0)
- {
- page->m_words_used= 0;
- if(m_first_free == key->m_page_no)
- {
- //ndbout_c("resetting page");
- }
- else
- {
- //ndbout_c("returning page");
- m_tup->returnCommonArea(key->m_page_no, 1);
- }
- }
- key->setNull();
-}
-
-Uint32 *
-Undo_buffer::get_ptr(Local_key* key)
-{
- return ((UndoPage*)(m_tup->c_page_pool.getPtr(key->m_page_no)))->m_data+key->m_page_idx;
-}
-
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp b/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp
deleted file mode 100644
index 67ddefd0480..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __UNDO_BUFFER_HPP
-#define __UNDO_BUFFER_HPP
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-
-struct Undo_buffer
-{
- Undo_buffer(class Dbtup*);
-
- /**
- * Alloc space for a copy tuple of size <em>words</em>
- * store address to copy in dst
- * supply pointer to original in curr
- *
- * @return 0 if unable to alloc space
- */
- Uint32 * alloc_copy_tuple(Local_key* dst, Uint32 words);
-
- /**
- * Shrink size of copy tuple
- * note: Only shrink latest allocated tuple
- */
- void shrink_copy_tuple(Local_key* dst, Uint32 words);
-
- /**
- * Free space for copy tuple at key
- */
- void free_copy_tuple(Local_key* key);
-
- /**
- * Get pointer to copy tuple
- */
- Uint32 * get_ptr(Local_key* key);
-
-private:
- class Dbtup* m_tup;
- Uint32 m_first_free;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp b/storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp
deleted file mode 100644
index 2e52fe04949..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/* Copyright (C) 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <ndb_global.h>
-#include "tuppage.hpp"
-#include <Vector.hpp>
-
-struct Record
-{
- Uint32 idx;
- Uint32 size;
- Uint32* data;
-};
-
-NdbOut&
-operator <<(NdbOut& out, const Record& rec)
-{
- out << "[ idx: " << rec.idx << " sz: " << rec.size << " ]";
- return out;
-}
-
-#define TRACE(x) x
-
-static
-bool
-cmp(const Uint32 *p1, const Uint32 *p2, Uint32 words)
-{
- if(memcmp(p1, p2, 4*words) == 0)
- return true;
-
- for(Uint32 i = 0; i<words; i++)
- printf(" %.8x", p1[i]);
- printf("\n");
-
- for(Uint32 i = 0; i<words; i++)
- printf(" %.8x", p2[i]);
- printf("\n");
-
- return false;
-}
-
-static
-void
-do_test(int loops, int dist[5])
-{
- fprintf(stderr, "do_test(%d, [ %d %d %d %d %d ])\n",
- loops,
- dist[0],
- dist[1],
- dist[2],
- dist[3],
- dist[4]);
- int allocated= 0;
- Record records[8192];
-
- Tup_varsize_page page, tmp;
- page.init();
-
- for(int i = 0; i<loops; i++)
- {
- assert(page.high_index + page.insert_pos <= page.DATA_WORDS);
-
- for(int j = 0; j<allocated; j++)
- {
- Record rec= records[j];
- Uint32* ptr= page.get_ptr(rec.idx);
- Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
- if (page.get_entry_len(rec.idx) != rec.size)
- {
- ndbout << "INVALID LEN " << j << " " << rec << " pos: " << pos << endl;
- ndbout << page << endl;
- abort();
- }
-
- if(!cmp(ptr, rec.data, rec.size))
- {
- ndbout << "FAILED " << j << " " << rec << " pos: " << pos << endl;
- ndbout << page << endl;
- abort();
- }
- }
-
-loop:
- int op;
- int rnd= rand() % 100;
- for(op= 0; op<5; op++)
- if(rnd < dist[op])
- break;
-
- if(allocated == 0)
- op= 0;
- if(page.free_space <= 2 && op == 0) goto loop;
-
- switch(op){
- case 0: // Alloc
- {
- Record rec;
- rec.size= 1 + (rand() % (page.free_space-1));
- rec.data = new Uint32[rec.size];
- for(Uint32 i= 0; i<rec.size; i++)
- {
- rec.data[i] = rand();
- }
- ndbout << "Alloc hi: " << page.high_index << " (" <<
- ((rnd < 30) ? "any" :
- (rnd < 60) ? "dir" :
- (rnd < 80) ? "exp" : "fail") << ") ";
- ndbout << rec.size << flush;
- if (rnd < 30)
- {
- rec.idx= page.alloc_record(rec.size, &tmp, 0);
- }
- else if (rnd < 60)
- {
- // Alloc with id, from directory
- Vector<Uint32> free;
- for(Uint32 i = page.high_index - 1; i > 0; i--)
- {
- if (page.get_index_word(i) & page.FREE)
- {
- free.push_back(i);
- if (free.size() > 100)
- break;
- }
- }
- if (free.size())
- {
- rec.idx = free[rand() % free.size()];
- if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
- {
- abort();
- }
- }
- else
- {
- rec.idx = page.high_index;
- if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
- {
- if (rec.size + 1 != page.free_space)
- abort();
- delete [] rec.data;
- ndbout_c(" FAIL");
- break;
- }
- }
- }
- else if(rnd < 80)
- {
- // Alloc with id, outside of directory
- rec.idx = page.high_index + (rand() % (page.free_space - rec.size));
- if (page.alloc_record(rec.idx, rec.size, &tmp) != rec.idx)
- {
- abort();
- }
- }
- else
- {
- rec.idx = page.high_index + (page.free_space - rec.size) + 1;
- if (page.alloc_record(rec.idx, rec.size, &tmp) == rec.idx)
- {
- abort();
- }
- delete [] rec.data;
- ndbout_c(" FAIL");
- break;
- }
-
- Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
- ndbout << " -> " << rec.idx
- << " pos: " << pos << endl;
- Uint32* ptr= page.get_ptr(rec.idx);
- memcpy(ptr, rec.data, 4*rec.size);
- records[allocated++] = rec;
- break;
- }
- case 1: // Free
- {
- int no= rand() % allocated;
- Record rec= records[no];
- Uint32 pos = page.get_ptr(rec.idx) - page.m_data;
- ndbout << "Free hi: " << page.high_index << " no: " << no << " idx: " << rec.idx << " pos: " << pos << endl;
- Uint32* ptr= page.get_ptr(rec.idx);
- assert(page.get_entry_len(rec.idx) == rec.size);
- cmp(ptr, rec.data, rec.size);
- delete[] rec.data;
- page.free_record(rec.idx, 0);
-
- for (unsigned k = no; k + 1 < allocated; k++)
- records[k] = records[k+1];
- allocated--;
-
- break;
- }
- case 2: // Reorg
- ndbout << "Reorg" << endl;
- page.reorg(&tmp);
- break;
- case 3:
- {
- Uint32 free = page.free_space;
- if (free <= 2)
- {
- goto shrink;
- }
- free /= 2;
- int no = rand() % allocated;
- Record rec= records[no];
- ndbout << "Expand no: " << no << " idx: " << rec.idx
- << " add: " << free << " reorg: "
- << !page.is_space_behind_entry(rec.idx, free)
- << endl;
- if (!page.is_space_behind_entry(rec.idx, free))
- {
- Uint32 buffer[8192];
- Uint32 len = page.get_entry_len(rec.idx);
- memcpy(buffer, page.get_ptr(rec.idx), 4*len);
- page.set_entry_len(rec.idx, 0);
- page.free_space += len;
- page.reorg(&tmp);
- memcpy(page.get_free_space_ptr(), buffer, 4*len);
- page.set_entry_offset(rec.idx, page.insert_pos);
- free += len;
- records[no].size = 0;
- }
-
- page.grow_entry(rec.idx, free);
- records[no].size += free;
- Uint32 *ptr = page.get_ptr(rec.idx);
- Uint32 *new_data = new Uint32[records[no].size];
- for(Uint32 i= 0; i<records[no].size; i++)
- {
- ptr[i] = new_data[i] = rand();
- }
- delete []rec.data;
- records[no].data = new_data;
- break;
- }
- case 4:
- {
- shrink:
- int no = rand() % allocated;
- Record rec = records[no];
- Uint32 sz = rec.size / 2 + 1;
- ndbout << "Shrink no: " << no << " idx: " << rec.idx << " remove: "
- << (rec.size - sz) << endl;
- page.shrink_entry(rec.idx, sz);
- records[no].size = sz;
- break;
- }
- }
-
- }
- ndbout << page << endl;
-}
-
-int
-main(int argc, char **argv)
-{
- ndb_init();
-
- if (argc > 1)
- {
- time_t seed = time(0);
- srand(seed);
- fprintf(stderr, "srand(%d)\n", seed);
- }
- // alloc, free, reorg, grow, shrink
-
- int t1[] = { 10, 60, 70, 85, 100 };
- int t2[] = { 30, 60, 70, 85, 100 };
- int t3[] = { 50, 60, 70, 85, 100 };
-
- do_test(10000, t1);
- do_test(10000, t2);
- do_test(10000, t3);
-
- return 0;
-}
-
-template class Vector<Record>;
-
-// hp3750
-struct Signal { Signal(); int foo; };
-Signal::Signal(){}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp b/storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp
deleted file mode 100644
index 524592b99ee..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "tuppage.hpp"
-#include "Dbtup.hpp"
-
-/**
- * Fix pages maintain a double linked list of free entries
- *
- * Var pages has a directory where each entry is
- * [ C(1), F(1), L(15), P(15) ]
- * C is chain bit, (is it a full tuple or just chain)
- * F is free bit
- * If true, L is prev free entry (in directory)
- * P is next free entry (in directory)
- * else
- * L is len of entry
- * P is pos of entry
- */
-
-Uint32
-Tup_fixsize_page::alloc_record()
-{
- assert(free_space);
- Uint32 page_idx = next_free_index;
- assert(page_idx + 1 < DATA_WORDS);
-
- Uint32 prev = m_data[page_idx] >> 16;
- Uint32 next = m_data[page_idx] & 0xFFFF;
-
- assert(prev == 0xFFFF);
- assert(m_data[page_idx + 1] == FREE_RECORD);
-
- m_data[page_idx + 1] = 0;
- if (next != 0xFFFF)
- {
- assert(free_space > 1);
- Uint32 nextP = m_data[next];
- assert((nextP >> 16) == page_idx);
- m_data[next] = 0xFFFF0000 | (nextP & 0xFFFF);
- }
- else
- {
- assert(free_space == 1);
- }
-
- next_free_index = next;
- free_space--;
- return page_idx;
-}
-
-Uint32
-Tup_fixsize_page::alloc_record(Uint32 page_idx)
-{
- assert(page_idx + 1 < DATA_WORDS);
- if (likely(free_space && m_data[page_idx + 1] == FREE_RECORD))
- {
- Uint32 prev = m_data[page_idx] >> 16;
- Uint32 next = m_data[page_idx] & 0xFFFF;
-
- assert(prev != 0xFFFF || (next_free_index == page_idx));
- if (prev == 0xFFFF)
- {
- next_free_index = next;
- }
- else
- {
- Uint32 prevP = m_data[prev];
- m_data[prev] = (prevP & 0xFFFF0000) | next;
- }
-
- if (next != 0xFFFF)
- {
- Uint32 nextP = m_data[next];
- m_data[next] = (prev << 16) | (nextP & 0xFFFF);
- }
- free_space --;
- m_data[page_idx + 1] = 0;
- return page_idx;
- }
- return ~0;
-}
-
-Uint32
-Tup_fixsize_page::free_record(Uint32 page_idx)
-{
- Uint32 next = next_free_index;
-
- assert(page_idx + 1 < DATA_WORDS);
- assert(m_data[page_idx + 1] != FREE_RECORD);
-
- if (next == 0xFFFF)
- {
- assert(free_space == 0);
- }
- else
- {
- assert(free_space);
- assert(next + 1 < DATA_WORDS);
- Uint32 nextP = m_data[next];
- assert((nextP >> 16) == 0xFFFF);
- m_data[next] = (page_idx << 16) | (nextP & 0xFFFF);
- assert(m_data[next + 1] == FREE_RECORD);
- }
-
- next_free_index = page_idx;
- m_data[page_idx] = 0xFFFF0000 | next;
- m_data[page_idx + 1] = FREE_RECORD;
-
- return ++free_space;
-}
-
-void
-Tup_varsize_page::init()
-{
- free_space= DATA_WORDS - 1;
- high_index= 1;
- insert_pos= 0;
- next_free_index= END_OF_FREE_LIST;
- m_page_header.m_page_type = File_formats::PT_Tup_varsize_page;
-}
-
-Uint32
-Tup_varsize_page::alloc_record(Uint32 page_idx, Uint32 alloc_size,
- Tup_varsize_page* temp)
-{
- assert(page_idx); // 0 is not allowed
- Uint32 free = free_space;
- Uint32 largest_size= DATA_WORDS - (insert_pos + high_index);
- Uint32 free_list = next_free_index;
-
- if (page_idx < high_index)
- {
- Uint32 *ptr = get_index_ptr(page_idx);
- Uint32 word = *ptr;
-
- if (unlikely((free < alloc_size) || ! (word & FREE)))
- {
- return ~0;
- }
-
- if (alloc_size >= largest_size)
- {
- /*
- We can't fit this segment between the insert position and the end of
- the index entries. We will pack the page so that all free space
- exists between the insert position and the end of the index entries.
- */
- reorg(temp);
- }
-
- Uint32 next = (word & NEXT_MASK) >> NEXT_SHIFT;
- Uint32 prev = (word & PREV_MASK) >> PREV_SHIFT;
-
- if (next != END_OF_FREE_LIST)
- {
- Uint32 * next_ptr = get_index_ptr(next);
- Uint32 next_word = * next_ptr;
- * next_ptr = (next_word & ~PREV_MASK) | (prev << PREV_SHIFT);
- }
-
- if (prev != END_OF_FREE_LIST)
- {
- Uint32 * prev_ptr = get_index_ptr(prev);
- Uint32 prev_word = * prev_ptr;
- * prev_ptr = (prev_word & ~NEXT_MASK) | (next << NEXT_SHIFT);
- }
- else
- {
- assert(next_free_index == page_idx);
- next_free_index = next;
- }
-
- * ptr = insert_pos + (alloc_size << LEN_SHIFT);
- free -= alloc_size;
- }
- else
- {
- /**
- * We need to expand directory
- */
- Uint32 hi = high_index;
- Uint32 expand = (page_idx + 1 - hi);
- Uint32 size = alloc_size + expand;
- if (unlikely(size > free))
- {
- return ~0;
- }
-
- if (size >= largest_size)
- {
- /*
- We can't fit this segment between the insert position and the end of
- the index entries. We will pack the page so that all free space
- exists between the insert position and the end of the index entries.
- */
- reorg(temp);
- }
-
- Uint32 *ptr = m_data + DATA_WORDS - hi;
- if (page_idx == hi)
- {
- * ptr = insert_pos + (alloc_size << LEN_SHIFT);
- }
- else
- {
- if (free_list != END_OF_FREE_LIST)
- {
- Uint32 * prev_ptr = get_index_ptr(free_list);
- Uint32 prev_word = * prev_ptr;
- * prev_ptr = (prev_word & ~PREV_MASK) | (hi << PREV_SHIFT);
- }
-
- for (; hi < page_idx;)
- {
- * ptr-- = FREE | (free_list << NEXT_SHIFT) | ((hi+1) << PREV_SHIFT);
- free_list = hi++;
- }
-
- * ptr++ = insert_pos + (alloc_size << LEN_SHIFT);
- * ptr = ((* ptr) & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
-
- next_free_index = hi - 1;
- }
- high_index = hi + 1;
- free -= size;
- }
-
- free_space = free;
- insert_pos += alloc_size;
-
- return page_idx;
-}
-
-Uint32
-Tup_varsize_page::alloc_record(Uint32 alloc_size,
- Tup_varsize_page* temp, Uint32 chain)
-{
- assert(free_space >= alloc_size);
- Uint32 largest_size= DATA_WORDS - (insert_pos + high_index);
- if (alloc_size >= largest_size) {
- /*
- We can't fit this segment between the insert position and the end of
- the index entries. We will pack the page so that all free space
- exists between the insert position and the end of the index entries.
- */
- reorg(temp);
- largest_size= DATA_WORDS - (insert_pos + high_index);
- }
- assert(largest_size > alloc_size);
-
- Uint32 page_idx;
- if (next_free_index == END_OF_FREE_LIST) {
- /*
- We are out of free index slots. We will extend the array of free
- slots
- */
- page_idx= high_index++;
- free_space--;
- } else {
- // Pick an empty slot among the index entries
- page_idx= next_free_index;
- assert((get_index_word(page_idx) & FREE) == FREE);
- assert(((get_index_word(page_idx) & PREV_MASK) >> PREV_SHIFT) ==
- END_OF_FREE_LIST);
- next_free_index= (get_index_word(page_idx) & NEXT_MASK) >> NEXT_SHIFT;
- assert(next_free_index);
- if (next_free_index != END_OF_FREE_LIST)
- {
- Uint32 *ptr = get_index_ptr(next_free_index);
- Uint32 word = *ptr;
- * ptr = (word & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
- }
- }
-
- assert(chain == 0 || chain == CHAIN);
- * get_index_ptr(page_idx) = insert_pos + chain + (alloc_size << LEN_SHIFT);
-
- insert_pos += alloc_size;
- free_space -= alloc_size;
- //ndbout_c("%p->alloc_record(%d%s) -> %d", this,alloc_size, (chain ? " CHAIN" : ""),page_idx);
- return page_idx;
-}
-
-Uint32
-Tup_varsize_page::free_record(Uint32 page_idx, Uint32 chain)
-{
- //ndbout_c("%p->free_record(%d%s)", this, page_idx, (chain ? " CHAIN": ""));
- Uint32 *index_ptr= get_index_ptr(page_idx);
- Uint32 index_word= * index_ptr;
- Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
- Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
- assert(chain == 0 || chain == CHAIN);
- assert((index_word & CHAIN) == chain);
-#ifdef VM_TRACE
- memset(m_data + entry_pos, 0xF2, 4*entry_len);
-#endif
- if (page_idx + 1 == high_index) {
- /*
- We are removing the last in the entry list. We could potentially
- have several free entries also before this. To take that into account
- we will rebuild the free list and thus compress it and update the
- free space accordingly.
- */
- rebuild_index(index_ptr);
- } else {
- if (next_free_index != END_OF_FREE_LIST)
- {
- Uint32 *ptr = get_index_ptr(next_free_index);
- Uint32 word = *ptr;
- assert(((word & PREV_MASK) >> PREV_SHIFT) == END_OF_FREE_LIST);
- * ptr = (word & ~PREV_MASK) | (page_idx << PREV_SHIFT);
- }
- * index_ptr= FREE | next_free_index | (END_OF_FREE_LIST << PREV_SHIFT);
- next_free_index= page_idx;
- assert(next_free_index);
- }
-
- free_space+= entry_len;
- // If we're the "last" entry, decrease insert_pos
- insert_pos -= (entry_pos + entry_len == insert_pos ? entry_len : 0);
-
- return free_space;
-}
-
-void
-Tup_varsize_page::rebuild_index(Uint32* index_ptr)
-{
- Uint32 empty= 1;
- Uint32 *end= m_data + DATA_WORDS;
-
- /**
- * Scan until you find first non empty index pos
- */
- for(index_ptr++; index_ptr < end; index_ptr++)
- if((* index_ptr) & FREE)
- empty++;
- else
- break;
-
- if(index_ptr == end)
- {
- // Totally free page
- high_index = 1;
- free_space += empty;
- next_free_index = END_OF_FREE_LIST;
- return;
- }
-
- Uint32 next= END_OF_FREE_LIST;
- Uint32 dummy;
- Uint32 *prev_ptr = &dummy;
- for(index_ptr++; index_ptr < end; index_ptr++)
- {
- if ((* index_ptr) & FREE)
- {
- * index_ptr= FREE | next;
- next= (end - index_ptr);
- * prev_ptr |= (next << PREV_SHIFT);
- prev_ptr = index_ptr;
- }
- }
-
- * prev_ptr |= (END_OF_FREE_LIST << PREV_SHIFT);
-
- high_index -= empty;
- free_space += empty;
- next_free_index= next;
- assert(next_free_index);
-}
-
-void
-Tup_varsize_page::reorg(Tup_varsize_page* copy_page)
-{
- Uint32 new_insert_pos= 0;
- Uint32 old_insert_pos= insert_pos;
-
- // Copy key data part of page to a temporary page.
- memcpy(copy_page->m_data, m_data, 4*old_insert_pos);
- assert(high_index > 0);
- Uint32* index_ptr= get_index_ptr(high_index-1);
- Uint32 *end_of_page= m_data + DATA_WORDS;
- for (; index_ptr < end_of_page; index_ptr++)
- {
- Uint32 index_word= * index_ptr;
- Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
- if (!(index_word & FREE) && entry_len)
- {
- /*
- We found an index item that needs to be packed.
- We will update the index entry and copy the data to the page.
- */
- Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
- assert(entry_pos + entry_len <= old_insert_pos);
- assert(new_insert_pos + entry_len <= old_insert_pos);
- * index_ptr= (new_insert_pos << POS_SHIFT) + (index_word & ~POS_MASK);
- memcpy(m_data+new_insert_pos, copy_page->m_data+entry_pos, 4*entry_len);
-
- new_insert_pos += entry_len;
- }
- }
- insert_pos= new_insert_pos;
-}
-
-NdbOut&
-operator<< (NdbOut& out, const Tup_varsize_page& page)
-{
- out << "[ Varpage " << &page << ": free: " << page.free_space
- << " (" << (page.DATA_WORDS - (page.insert_pos + page.high_index + 1)) << ")"
- << " insert_pos: " << page.insert_pos
- << " high_index: " << page.high_index
- << " index: " << flush;
-
- const Uint32 *index_ptr= page.m_data+page.DATA_WORDS-1;
- for(Uint32 i = 1; i<page.high_index; i++, index_ptr--)
- {
- out << " [ " << i;
- if(! (*index_ptr & page.FREE))
- out << " pos: " << ((* index_ptr & page.POS_MASK) >> page.POS_SHIFT)
- << " len: " << ((* index_ptr & page.LEN_MASK) >> page.LEN_SHIFT)
- << ((* index_ptr & page.CHAIN) ? " CHAIN " : " ")
- << "]" << flush;
- else
- out << " FREE ]" << flush;
- }
-
- out << " free list: " << flush;
- Uint32 next= page.next_free_index;
- while(next != page.END_OF_FREE_LIST)
- {
- out << next << " " << flush;
- next= ((* (page.m_data+page.DATA_WORDS-next)) & page.NEXT_MASK) >> page.NEXT_SHIFT;
- }
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<< (NdbOut& out, const Tup_fixsize_page& page)
-{
- out << "[ Fixpage " << &page
- << ": frag_page: " << page.frag_page_id
- << " page_no: " << page.m_page_no
- << " file_no: " << page.m_file_no
- << " table: " << page.m_table_id
- << " fragment: " << page.m_fragment_id
- << " uncommitted_used_space: " << page.uncommitted_used_space
- << " free: " << page.free_space;
-
- out << " free list: " << hex << page.next_free_index << " " << flush;
-#if 0
- Uint32 startTuple = page.next_free_index >> 16;
- Uint32 cnt = 0;
- Uint32 next= startTuple;
- while((next & 0xFFFF) != 0xFFFF)
- {
- cnt++;
- out << dec << "(" << (next & 0xFFFF) << " " << hex << next << ") " << flush;
- assert(page.m_data[(next & 0xFFFF) + 1] == Dbtup::Tuple_header::FREE);
- next= * (page.m_data + ( next & 0xFFFF ));
- }
- assert(cnt == page.free_space);
-#endif
- out << "]";
- return out;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp b/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp
deleted file mode 100644
index 9558a911a86..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __NDB_TUP_PAGE_HPP
-#define __NDB_TUP_PAGE_HPP
-
-#include <ndb_types.h>
-#include "../diskpage.hpp"
-
-struct Tup_page
-{
- struct File_formats::Page_header m_page_header;
- Uint32 m_restart_seq;
- Uint32 page_state;
- union {
- Uint32 next_page;
- Uint32 nextList;
- };
- union {
- Uint32 prev_page;
- Uint32 prevList;
- };
- Uint32 first_cluster_page;
- Uint32 last_cluster_page;
- Uint32 next_cluster_page;
- Uint32 prev_cluster_page;
- Uint32 frag_page_id;
- Uint32 physical_page_id;
- Uint32 free_space;
- Uint32 next_free_index;
- Uint32 list_index; // free space in page bits/list, 0x8000 means not in free
- Uint32 uncommitted_used_space;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_table_id;
- Uint32 m_fragment_id;
- Uint32 m_extent_no;
- Uint32 m_extent_info_ptr;
- Uint32 unused_ph[9];
-
- STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
-
- Uint32 m_data[DATA_WORDS];
-};
-
-struct Tup_fixsize_page
-{
- struct File_formats::Page_header m_page_header;
- Uint32 m_restart_seq;
- Uint32 page_state;
- Uint32 next_page;
- Uint32 prev_page;
- Uint32 first_cluster_page;
- Uint32 last_cluster_page;
- Uint32 next_cluster_page;
- Uint32 prev_cluster_page;
- Uint32 frag_page_id;
- Uint32 physical_page_id;
- Uint32 free_space;
- Uint32 next_free_index;
- Uint32 list_index;
- Uint32 uncommitted_used_space;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_table_id;
- Uint32 m_fragment_id;
- Uint32 m_extent_no;
- Uint32 m_extent_info_ptr;
- Uint32 unused_ph[9];
-
- STATIC_CONST( FREE_RECORD = ~(Uint32)0 );
- STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
-
- Uint32 m_data[DATA_WORDS];
-
- Uint32* get_ptr(Uint32 page_idx, Uint32 rec_size){
- assert(page_idx + rec_size <= DATA_WORDS);
- return m_data + page_idx;
- }
-
- /**
- * Alloc record from page
- * return page_idx
- **/
- Tup_fixsize_page() {}
- Uint32 alloc_record();
- Uint32 alloc_record(Uint32 page_idx);
- Uint32 free_record(Uint32 page_idx);
-};
-
-struct Tup_varsize_page
-{
- struct File_formats::Page_header m_page_header;
- Uint32 m_restart_seq;
- Uint32 page_state;
- Uint32 next_page;
- Uint32 prev_page;
- union {
- Uint32 first_cluster_page;
- Uint32 chunk_size;
- };
- union {
- Uint32 last_cluster_page;
- Uint32 next_chunk;
- };
- Uint32 next_cluster_page;
- Uint32 prev_cluster_page;
- Uint32 frag_page_id;
- Uint32 physical_page_id;
- Uint32 free_space;
- Uint32 next_free_index;
- Uint32 list_index;
- Uint32 uncommitted_used_space;
- Uint32 m_page_no;
- Uint32 m_file_no;
- Uint32 m_table_id;
- Uint32 m_fragment_id;
- Uint32 m_extent_no;
- Uint32 m_extent_info_ptr;
- Uint32 high_index; // size of index + 1
- Uint32 insert_pos;
- Uint32 unused_ph[7];
-
- STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
- STATIC_CONST( CHAIN = 0x80000000 );
- STATIC_CONST( FREE = 0x40000000 );
- STATIC_CONST( LEN_MASK = 0x3FFF8000 );
- STATIC_CONST( POS_MASK = 0x00007FFF );
- STATIC_CONST( LEN_SHIFT = 15 );
- STATIC_CONST( POS_SHIFT = 0 );
- STATIC_CONST( END_OF_FREE_LIST = POS_MASK );
-
- STATIC_CONST( NEXT_MASK = POS_MASK );
- STATIC_CONST( NEXT_SHIFT = POS_SHIFT );
- STATIC_CONST( PREV_MASK = LEN_MASK );
- STATIC_CONST( PREV_SHIFT = LEN_SHIFT );
-
- Uint32 m_data[DATA_WORDS];
-
- Tup_varsize_page() {}
- void init();
-
- Uint32* get_free_space_ptr() {
- return m_data+insert_pos;
- }
-
- Uint32 largest_frag_size() const {
- return DATA_WORDS - (high_index + insert_pos);
- }
-
- Uint32 *get_index_ptr(Uint32 page_idx) {
- assert(page_idx < high_index);
- return (m_data + (DATA_WORDS - page_idx));
- }
-
- Uint32 get_index_word(Uint32 page_idx) const {
- assert(page_idx < high_index);
- return * (m_data + (DATA_WORDS - page_idx));
- }
-
- /**
- * Alloc record from page, return page_idx
- * temp is used when having to reorg page before allocating
- */
- Uint32 alloc_record(Uint32 size, Tup_varsize_page* temp, Uint32 chain);
-
- /**
- * Alloc page_idx from page, return page_idx
- * temp is used when having to reorg page before allocating
- */
- Uint32 alloc_record(Uint32 page_idx, Uint32 size, Tup_varsize_page* temp);
-
- /**
- * Free record from page
- */
- Uint32 free_record(Uint32 page_idx, Uint32 chain);
-
- void reorg(Tup_varsize_page* temp);
- void rebuild_index(Uint32* ptr);
-
- /**
- * Check if one can grow tuple wo/ reorg
- */
- bool is_space_behind_entry(Uint32 page_index, Uint32 growth_len) const {
- Uint32 idx= get_index_word(page_index);
- Uint32 pos= (idx & POS_MASK) >> POS_SHIFT;
- Uint32 len= (idx & LEN_MASK) >> LEN_SHIFT;
- if ((pos + len == insert_pos) &&
- (insert_pos + growth_len < DATA_WORDS - high_index))
- return true;
- return false;
- }
-
- void grow_entry(Uint32 page_index, Uint32 growth_len) {
- assert(free_space >= growth_len);
-
- Uint32 *pos= get_index_ptr(page_index);
- Uint32 idx= *pos;
- assert(! (idx & FREE));
- assert((((idx & POS_MASK) >> POS_SHIFT) + ((idx & LEN_MASK) >> LEN_SHIFT))
- == insert_pos);
-
- * pos= idx + (growth_len << LEN_SHIFT);
- insert_pos+= growth_len;
- free_space-= growth_len;
- }
-
- void shrink_entry(Uint32 page_index, Uint32 new_size){
- Uint32 *pos= get_index_ptr(page_index);
- Uint32 idx= *pos;
- Uint32 old_pos = (idx & POS_MASK) >> POS_SHIFT;
- Uint32 old_size = (idx & LEN_MASK) >> LEN_SHIFT;
-
- assert( ! (idx & FREE));
- assert(old_size >= new_size);
-
- * pos= (idx & ~LEN_MASK) + (new_size << LEN_SHIFT);
- Uint32 shrink = old_size - new_size;
-#ifdef VM_TRACE
- memset(m_data + old_pos + new_size, 0xF1, 4 * shrink);
-#endif
- free_space+= shrink;
- if(insert_pos == (old_pos + old_size))
- insert_pos -= shrink;
- }
-
- Uint32* get_ptr(Uint32 page_idx) {
- return m_data + ((get_index_word(page_idx) & POS_MASK) >> POS_SHIFT);
- }
-
- void set_entry_offset(Uint32 page_idx, Uint32 offset){
- Uint32 *pos= get_index_ptr(page_idx);
- * pos = (* pos & ~POS_MASK) + (offset << POS_SHIFT);
- }
-
- void set_entry_len(Uint32 page_idx, Uint32 len) {
- Uint32 *pos= get_index_ptr(page_idx);
- * pos = (*pos & ~LEN_MASK) + (len << LEN_SHIFT);
- }
-
- Uint32 get_entry_len(Uint32 page_idx) const {
- return (get_index_word(page_idx) & LEN_MASK) >> LEN_SHIFT;
- }
-
- Uint32 get_entry_chain(Uint32 page_idx) const {
- return get_index_word(page_idx) & CHAIN;
- }
-};
-
-NdbOut& operator<< (NdbOut& out, const Tup_varsize_page& page);
-NdbOut& operator<< (NdbOut& out, const Tup_fixsize_page& page);
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
deleted file mode 100644
index 55a0c97b74a..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
+++ /dev/null
@@ -1,1208 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBTUX_H
-#define DBTUX_H
-
-#include <ndb_limits.h>
-#include <SimulatedBlock.hpp>
-#include <AttributeDescriptor.hpp>
-#include <AttributeHeader.hpp>
-#include <ArrayPool.hpp>
-#include <DataBuffer.hpp>
-#include <DLFifoList.hpp>
-#include <md5_hash.hpp>
-
-// big brother
-#include <dbtup/Dbtup.hpp>
-
-// signal classes
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/TuxContinueB.hpp>
-#include <signaldata/TupFrag.hpp>
-#include <signaldata/AlterIndx.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/TuxMaint.hpp>
-#include <signaldata/AccScan.hpp>
-#include <signaldata/TuxBound.hpp>
-#include <signaldata/NextScan.hpp>
-#include <signaldata/AccLock.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-
-// debug
-#ifdef VM_TRACE
-#include <NdbOut.hpp>
-#include <OutputStream.hpp>
-#endif
-
-// jams
-#undef jam
-#undef jamEntry
-#ifdef DBTUX_GEN_CPP
-#define jam() jamLine(10000 + __LINE__)
-#define jamEntry() jamEntryLine(10000 + __LINE__)
-#endif
-#ifdef DBTUX_META_CPP
-#define jam() jamLine(20000 + __LINE__)
-#define jamEntry() jamEntryLine(20000 + __LINE__)
-#endif
-#ifdef DBTUX_MAINT_CPP
-#define jam() jamLine(30000 + __LINE__)
-#define jamEntry() jamEntryLine(30000 + __LINE__)
-#endif
-#ifdef DBTUX_NODE_CPP
-#define jam() jamLine(40000 + __LINE__)
-#define jamEntry() jamEntryLine(40000 + __LINE__)
-#endif
-#ifdef DBTUX_TREE_CPP
-#define jam() jamLine(50000 + __LINE__)
-#define jamEntry() jamEntryLine(50000 + __LINE__)
-#endif
-#ifdef DBTUX_SCAN_CPP
-#define jam() jamLine(60000 + __LINE__)
-#define jamEntry() jamEntryLine(60000 + __LINE__)
-#endif
-#ifdef DBTUX_SEARCH_CPP
-#define jam() jamLine(70000 + __LINE__)
-#define jamEntry() jamEntryLine(70000 + __LINE__)
-#endif
-#ifdef DBTUX_CMP_CPP
-#define jam() jamLine(80000 + __LINE__)
-#define jamEntry() jamEntryLine(80000 + __LINE__)
-#endif
-#ifdef DBTUX_STAT_CPP
-#define jam() jamLine(90000 + __LINE__)
-#define jamEntry() jamEntryLine(90000 + __LINE__)
-#endif
-#ifdef DBTUX_DEBUG_CPP
-#define jam() jamLine(100000 + __LINE__)
-#define jamEntry() jamEntryLine(100000 + __LINE__)
-#endif
-#ifndef jam
-#define jam() jamLine(__LINE__)
-#define jamEntry() jamEntryLine(__LINE__)
-#endif
-
-#undef max
-#undef min
-
-class Configuration;
-
-class Dbtux : public SimulatedBlock {
-public:
- Dbtux(Block_context& ctx);
- virtual ~Dbtux();
-
- // pointer to TUP instance in this thread
- Dbtup* c_tup;
-
-private:
- // sizes are in words (Uint32)
- STATIC_CONST( MaxIndexFragments = MAX_FRAG_PER_NODE );
- STATIC_CONST( MaxIndexAttributes = MAX_ATTRIBUTES_IN_INDEX );
- STATIC_CONST( MaxAttrDataSize = 2048 );
-public:
- STATIC_CONST( DescPageSize = 256 );
-private:
- STATIC_CONST( MaxTreeNodeSize = MAX_TTREE_NODE_SIZE );
- STATIC_CONST( MaxPrefSize = MAX_TTREE_PREF_SIZE );
- STATIC_CONST( ScanBoundSegmentSize = 7 );
- STATIC_CONST( MaxAccLockOps = MAX_PARALLEL_OP_PER_SCAN );
- STATIC_CONST( MaxTreeDepth = 32 ); // strict
- BLOCK_DEFINES(Dbtux);
-
- // forward declarations
- struct DescEnt;
-
- // Pointer to array of Uint32 represents attribute data and bounds
-
- typedef Uint32 *Data;
- inline AttributeHeader& ah(Data data) {
- return *reinterpret_cast<AttributeHeader*>(data);
- }
-
- typedef const Uint32* ConstData;
- inline const AttributeHeader& ah(ConstData data) {
- return *reinterpret_cast<const AttributeHeader*>(data);
- }
-
- // AttributeHeader size is assumed to be 1 word
- STATIC_CONST( AttributeHeaderSize = 1 );
-
- /*
- * Logical tuple address, "local key". Identifies table tuples.
- */
- typedef Uint32 TupAddr;
- STATIC_CONST( NullTupAddr = (Uint32)-1 );
-
- /*
- * Physical tuple address in TUP. Provides fast access to table tuple
- * or index node. Valid within the db node and across timeslices.
- * Not valid between db nodes or across restarts.
- *
- * To avoid wasting an Uint16 the pageid is split in two.
- */
- struct TupLoc {
- private:
- Uint16 m_pageId1; // page i-value (big-endian)
- Uint16 m_pageId2;
- Uint16 m_pageOffset; // page offset in words
- public:
- TupLoc();
- TupLoc(Uint32 pageId, Uint16 pageOffset);
- Uint32 getPageId() const;
- void setPageId(Uint32 pageId);
- Uint32 getPageOffset() const;
- void setPageOffset(Uint32 pageOffset);
- bool operator==(const TupLoc& loc) const;
- bool operator!=(const TupLoc& loc) const;
- };
-
- /*
- * There is no const member NullTupLoc since the compiler may not be
- * able to optimize it to TupLoc() constants. Instead null values are
- * constructed on the stack with TupLoc().
- */
-#define NullTupLoc TupLoc()
-
- // tree definitions
-
- /*
- * Tree entry. Points to a tuple in primary table via physical
- * address of "original" tuple and tuple version.
- *
- * ZTUP_VERSION_BITS must be 15 (or less).
- */
- struct TreeEnt;
- friend struct TreeEnt;
- struct TreeEnt {
- TupLoc m_tupLoc; // address of original tuple
- unsigned m_tupVersion : 15; // version
- TreeEnt();
- // methods
- bool eqtuple(const TreeEnt ent) const;
- bool eq(const TreeEnt ent) const;
- int cmp(const TreeEnt ent) const;
- };
- STATIC_CONST( TreeEntSize = sizeof(TreeEnt) >> 2 );
- static const TreeEnt NullTreeEnt;
-
- /*
- * Tree node has 1) fixed part 2) a prefix of index key data for min
- * entry 3) max and min entries 4) rest of entries 5) one extra entry
- * used as work space.
- *
- * struct TreeNode part 1, size 6 words
- * min prefix part 2, size TreeHead::m_prefSize
- * max entry part 3
- * min entry part 3
- * rest of entries part 4
- * work entry part 5
- *
- * There are 3 links to other nodes: left child, right child, parent.
- * Occupancy (number of entries) is at least 1 except temporarily when
- * a node is about to be removed.
- */
- struct TreeNode;
- friend struct TreeNode;
- struct TreeNode {
- TupLoc m_link[3]; // link to 0-left child 1-right child 2-parent
- unsigned m_side : 2; // we are 0-left child 1-right child 2-root
- unsigned m_balance : 2; // balance -1, 0, +1 plus 1 for Solaris CC
- unsigned pad1 : 4;
- Uint8 m_occup; // current number of entries
- Uint32 m_nodeScan; // list of scans at this node
- TreeNode();
- };
- STATIC_CONST( NodeHeadSize = sizeof(TreeNode) >> 2 );
-
- /*
- * Tree node "access size" was for an early version with signal
- * interface to TUP. It is now used only to compute sizes.
- */
- enum AccSize {
- AccNone = 0,
- AccHead = 1, // part 1
- AccPref = 2, // parts 1-3
- AccFull = 3 // parts 1-5
- };
-
- /*
- * Tree header. There is one in each fragment. Contains tree
- * parameters and address of root node.
- */
- struct TreeHead;
- friend struct TreeHead;
- struct TreeHead {
- Uint8 m_nodeSize; // words in tree node
- Uint8 m_prefSize; // words in min prefix
- Uint8 m_minOccup; // min entries in internal node
- Uint8 m_maxOccup; // max entries in node
- Uint32 m_entryCount; // stat: current entries
- TupLoc m_root; // root node
- TreeHead();
- // methods
- unsigned getSize(AccSize acc) const;
- Data getPref(TreeNode* node) const;
- TreeEnt* getEntList(TreeNode* node) const;
- };
-
- /*
- * Tree position. Specifies node, position within node (from 0 to
- * m_occup), and whether the position is at an existing entry or
- * before one (if any). Position m_occup points past the node and is
- * also represented by position 0 of next node. Includes direction
- * used by scan.
- */
- struct TreePos;
- friend struct TreePos;
- struct TreePos {
- TupLoc m_loc; // physical node address
- Uint16 m_pos; // position 0 to m_occup
- Uint8 m_dir; // see scanNext
- TreePos();
- };
-
- // packed metadata
-
- /*
- * Descriptor page. The "hot" metadata for an index is stored as
- * a contiguous array of words on some page.
- */
- struct DescPage;
- friend struct DescPage;
- struct DescPage {
- Uint32 m_nextPage;
- Uint32 m_numFree; // number of free words
- union {
- Uint32 m_data[DescPageSize];
- Uint32 nextPool;
- };
- DescPage();
- };
- typedef Ptr<DescPage> DescPagePtr;
- ArrayPool<DescPage> c_descPagePool;
- Uint32 c_descPageList;
-
- /*
- * Header for index metadata. Size must be multiple of word size.
- */
- struct DescHead {
- unsigned m_indexId : 24;
- unsigned pad1 : 8;
- };
- STATIC_CONST( DescHeadSize = sizeof(DescHead) >> 2 );
-
- /*
- * Attribute metadata. Size must be multiple of word size.
- *
- * Prefix comparison of char data must use strxfrm and binary
- * comparison. The charset is currently unused.
- */
- struct DescAttr {
- Uint32 m_attrDesc; // standard AttributeDescriptor
- Uint16 m_primaryAttrId;
- unsigned m_typeId : 6;
- unsigned m_charset : 10;
- };
- STATIC_CONST( DescAttrSize = sizeof(DescAttr) >> 2 );
-
- /*
- * Complete metadata for one index. The array of attributes has
- * variable size.
- */
- friend struct DescEnt;
- struct DescEnt {
- DescHead m_descHead;
- DescAttr m_descAttr[1]; // variable size data
- };
-
- // range scan
-
- /*
- * Scan bounds are stored in linked list of segments.
- */
- typedef DataBuffer<ScanBoundSegmentSize> ScanBound;
- typedef DataBuffer<ScanBoundSegmentSize>::ConstDataBufferIterator ScanBoundIterator;
- typedef DataBuffer<ScanBoundSegmentSize>::DataBufferPool ScanBoundPool;
- ScanBoundPool c_scanBoundPool;
-
- // ScanLock
- struct ScanLock {
- Uint32 m_accLockOp;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<ScanLock> ScanLockPtr;
- ArrayPool<ScanLock> c_scanLockPool;
-
- /*
- * Scan operation.
- *
- * Tuples are locked one at a time. The current lock op is set to
- * RNIL as soon as the lock is obtained and passed to LQH. We must
- * however remember all locks which LQH has not returned for unlocking
- * since they must be aborted by us when the scan is closed.
- *
- * Scan state describes the entry we are interested in. There is
- * a separate lock wait flag. It may be for current entry or it may
- * be for an entry we were moved away from. In any case nothing
- * happens with current entry before lock wait flag is cleared.
- *
- * An unfinished scan is always linked to some tree node, and has
- * current position and direction (see comments at scanNext). There
- * is also a copy of latest entry found.
- */
- struct ScanOp;
- friend struct ScanOp;
- struct ScanOp {
- enum {
- Undef = 0,
- First = 1, // before first entry
- Current = 2, // at some entry
- Found = 3, // return current as next scan result
- Blocked = 4, // found and waiting for ACC lock
- Locked = 5, // found and locked or no lock needed
- Next = 6, // looking for next extry
- Last = 7, // after last entry
- Aborting = 8, // lock wait at scan close
- Invalid = 9 // cannot return REF to LQH currently
- };
- Uint16 m_state;
- Uint16 m_lockwait;
- Uint32 m_userPtr; // scanptr.i in LQH
- Uint32 m_userRef;
- Uint32 m_tableId;
- Uint32 m_indexId;
- Uint32 m_fragId;
- Uint32 m_fragPtrI;
- Uint32 m_transId1;
- Uint32 m_transId2;
- Uint32 m_savePointId;
- // lock waited for or obtained and not yet passed to LQH
- Uint32 m_accLockOp;
- // locks obtained and passed to LQH but not yet returned by LQH
- DLFifoList<ScanLock>::Head m_accLockOps;
- Uint8 m_readCommitted; // no locking
- Uint8 m_lockMode;
- Uint8 m_descending;
- ScanBound m_boundMin;
- ScanBound m_boundMax;
- ScanBound* m_bound[2]; // pointers to above 2
- Uint16 m_boundCnt[2]; // number of bounds in each
- TreePos m_scanPos; // position
- TreeEnt m_scanEnt; // latest entry found
- Uint32 m_nodeScan; // next scan at node (single-linked)
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- ScanOp(ScanBoundPool& scanBoundPool);
- };
- typedef Ptr<ScanOp> ScanOpPtr;
- ArrayPool<ScanOp> c_scanOpPool;
-
- // indexes and fragments
-
- /*
- * Ordered index. Top level data structure. The primary table (table
- * being indexed) lives in TUP.
- */
- struct Index;
- friend struct Index;
- struct Index {
- enum State {
- NotDefined = 0,
- Defining = 1,
- Online = 2, // triggers activated and build done
- Dropping = 9
- };
- State m_state;
- DictTabInfo::TableType m_tableType;
- Uint32 m_tableId;
- Uint16 unused;
- Uint16 m_numFrags;
- Uint32 m_fragId[MaxIndexFragments];
- Uint32 m_fragPtrI[MaxIndexFragments];
- Uint32 m_descPage; // descriptor page
- Uint16 m_descOff; // offset within the page
- Uint16 m_numAttrs;
- bool m_storeNullKey;
- union {
- Uint32 nextPool;
- };
- Index();
- };
- typedef Ptr<Index> IndexPtr;
- ArrayPool<Index> c_indexPool;
-
- /*
- * Fragment of an index, as known to DIH/TC. Represents the two
- * duplicate fragments known to LQH/ACC/TUP. Includes tree header.
- * There are no maintenance operation records yet.
- */
- struct Frag;
- friend struct Frag;
- struct Frag {
- Uint32 m_tableId; // copy from index level
- Uint32 m_indexId;
- Uint16 unused;
- Uint16 m_fragId;
- Uint32 m_descPage; // copy from index level
- Uint16 m_descOff;
- Uint16 m_numAttrs;
- bool m_storeNullKey;
- TreeHead m_tree;
- TupLoc m_freeLoc; // list of free index nodes
- DLList<ScanOp> m_scanList; // current scans on this fragment
- Uint32 m_tupIndexFragPtrI;
- Uint32 m_tupTableFragPtrI;
- Uint32 m_accTableFragPtrI;
- union {
- Uint32 nextPool;
- };
- Frag(ArrayPool<ScanOp>& scanOpPool);
- };
- typedef Ptr<Frag> FragPtr;
- ArrayPool<Frag> c_fragPool;
-
- /*
- * Fragment metadata operation.
- */
- struct FragOp {
- Uint32 m_userPtr;
- Uint32 m_userRef;
- Uint32 m_indexId;
- Uint32 m_fragId;
- Uint32 m_fragPtrI;
- Uint32 m_fragNo; // fragment number starting at zero
- Uint32 m_numAttrsRecvd;
- union {
- Uint32 nextPool;
- };
- FragOp();
- };
- typedef Ptr<FragOp> FragOpPtr;
- ArrayPool<FragOp> c_fragOpPool;
-
- // node handles
-
- /*
- * A node handle is a reference to a tree node in TUP. It is used to
- * operate on the node. Node handles are allocated on the stack.
- */
- struct NodeHandle;
- friend struct NodeHandle;
- struct NodeHandle {
- Frag& m_frag; // fragment using the node
- TupLoc m_loc; // physical node address
- TreeNode* m_node; // pointer to node storage
- NodeHandle(Frag& frag);
- NodeHandle(const NodeHandle& node);
- NodeHandle& operator=(const NodeHandle& node);
- // check if unassigned
- bool isNull();
- // getters
- TupLoc getLink(unsigned i);
- unsigned getChilds(); // cannot spell
- unsigned getSide();
- unsigned getOccup();
- int getBalance();
- Uint32 getNodeScan();
- // setters
- void setLink(unsigned i, TupLoc loc);
- void setSide(unsigned i);
- void setOccup(unsigned n);
- void setBalance(int b);
- void setNodeScan(Uint32 scanPtrI);
- // access other parts of the node
- Data getPref();
- TreeEnt getEnt(unsigned pos);
- TreeEnt getMinMax(unsigned i);
- // for ndbrequire and ndbassert
- void progError(int line, int cause, const char* file);
- };
-
- // methods
-
- /*
- * DbtuxGen.cpp
- */
- void execCONTINUEB(Signal* signal);
- void execSTTOR(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- // utils
- void setKeyAttrs(const Frag& frag);
- void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData);
- void readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize);
- void copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize);
- void unpackBound(const ScanBound& bound, Data data);
-
- /*
- * DbtuxMeta.cpp
- */
- void execTUXFRAGREQ(Signal* signal);
- void execTUX_ADD_ATTRREQ(Signal* signal);
- void execALTER_INDX_REQ(Signal* signal);
- void execDROP_TAB_REQ(Signal* signal);
- bool allocDescEnt(IndexPtr indexPtr);
- void freeDescEnt(IndexPtr indexPtr);
- void abortAddFragOp(Signal* signal);
- void dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 senderData);
-
- /*
- * DbtuxMaint.cpp
- */
- void execTUX_MAINT_REQ(Signal* signal);
-
- /*
- * DbtuxNode.cpp
- */
- int allocNode(Signal* signal, NodeHandle& node);
- void selectNode(NodeHandle& node, TupLoc loc);
- void insertNode(NodeHandle& node);
- void deleteNode(NodeHandle& node);
- void setNodePref(NodeHandle& node);
- // node operations
- void nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList);
- void nodePushUpScans(NodeHandle& node, unsigned pos);
- void nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& en, Uint32* scanList);
- void nodePopDownScans(NodeHandle& node, unsigned pos);
- void nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList);
- void nodePushDownScans(NodeHandle& node, unsigned pos);
- void nodePopUp(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32 scanList);
- void nodePopUpScans(NodeHandle& node, unsigned pos);
- void nodeSlide(NodeHandle& dstNode, NodeHandle& srcNode, unsigned cnt, unsigned i);
- // scans linked to node
- void addScanList(NodeHandle& node, unsigned pos, Uint32 scanList);
- void removeScanList(NodeHandle& node, unsigned pos, Uint32& scanList);
- void moveScanList(NodeHandle& node, unsigned pos);
- void linkScan(NodeHandle& node, ScanOpPtr scanPtr);
- void unlinkScan(NodeHandle& node, ScanOpPtr scanPtr);
- bool islinkScan(NodeHandle& node, ScanOpPtr scanPtr);
-
- /*
- * DbtuxTree.cpp
- */
- // add entry
- void treeAdd(Frag& frag, TreePos treePos, TreeEnt ent);
- void treeAddFull(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent);
- void treeAddNode(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent, NodeHandle parentNode, unsigned i);
- void treeAddRebalance(Frag& frag, NodeHandle node, unsigned i);
- // remove entry
- void treeRemove(Frag& frag, TreePos treePos);
- void treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos);
- void treeRemoveSemi(Frag& frag, NodeHandle node, unsigned i);
- void treeRemoveLeaf(Frag& frag, NodeHandle node);
- void treeRemoveNode(Frag& frag, NodeHandle node);
- void treeRemoveRebalance(Frag& frag, NodeHandle node, unsigned i);
- // rotate
- void treeRotateSingle(Frag& frag, NodeHandle& node, unsigned i);
- void treeRotateDouble(Frag& frag, NodeHandle& node, unsigned i);
-
- /*
- * DbtuxScan.cpp
- */
- void execACC_SCANREQ(Signal* signal);
- void execTUX_BOUND_INFO(Signal* signal);
- void execNEXT_SCANREQ(Signal* signal);
- void execACC_CHECK_SCAN(Signal* signal);
- void execACCKEYCONF(Signal* signal);
- void execACCKEYREF(Signal* signal);
- void execACC_ABORTCONF(Signal* signal);
- void scanFirst(ScanOpPtr scanPtr);
- void scanFind(ScanOpPtr scanPtr);
- void scanNext(ScanOpPtr scanPtr, bool fromMaintReq);
- bool scanCheck(ScanOpPtr scanPtr, TreeEnt ent);
- bool scanVisible(ScanOpPtr scanPtr, TreeEnt ent);
- void scanClose(Signal* signal, ScanOpPtr scanPtr);
- void abortAccLockOps(Signal* signal, ScanOpPtr scanPtr);
- void addAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp);
- void removeAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp);
- void releaseScanOp(ScanOpPtr& scanPtr);
-
- /*
- * DbtuxSearch.cpp
- */
- bool searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos);
- bool searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos);
- void searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, bool descending, TreePos& treePos);
- void searchToScanAscending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos);
- void searchToScanDescending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos);
-
- /*
- * DbtuxCmp.cpp
- */
- int cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen = MaxAttrDataSize);
- int cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen = MaxAttrDataSize);
-
- /*
- * DbtuxStat.cpp
- */
- void execREAD_PSEUDO_REQ(Signal* signal);
- void statRecordsInRange(ScanOpPtr scanPtr, Uint32* out);
- Uint32 getEntriesBeforeOrAfter(Frag& frag, TreePos pos, unsigned idir);
- unsigned getPathToNode(NodeHandle node, Uint16* path);
-
- /*
- * DbtuxDebug.cpp
- */
- void execDUMP_STATE_ORD(Signal* signal);
-#ifdef VM_TRACE
- struct PrintPar {
- char m_path[100]; // LR prefix
- unsigned m_side; // expected side
- TupLoc m_parent; // expected parent address
- int m_depth; // returned depth
- unsigned m_occup; // returned occupancy
- TreeEnt m_minmax[2]; // returned subtree min and max
- bool m_ok; // returned status
- PrintPar();
- };
- void printTree(Signal* signal, Frag& frag, NdbOut& out);
- void printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par);
- friend class NdbOut& operator<<(NdbOut&, const TupLoc&);
- friend class NdbOut& operator<<(NdbOut&, const TreeEnt&);
- friend class NdbOut& operator<<(NdbOut&, const TreeNode&);
- friend class NdbOut& operator<<(NdbOut&, const TreeHead&);
- friend class NdbOut& operator<<(NdbOut&, const TreePos&);
- friend class NdbOut& operator<<(NdbOut&, const DescAttr&);
- friend class NdbOut& operator<<(NdbOut&, const ScanOp&);
- friend class NdbOut& operator<<(NdbOut&, const Index&);
- friend class NdbOut& operator<<(NdbOut&, const Frag&);
- friend class NdbOut& operator<<(NdbOut&, const FragOp&);
- friend class NdbOut& operator<<(NdbOut&, const NodeHandle&);
- FILE* debugFile;
- NdbOut debugOut;
- unsigned debugFlags;
- enum {
- DebugMeta = 1, // log create and drop index
- DebugMaint = 2, // log maintenance ops
- DebugTree = 4, // log and check tree after each op
- DebugScan = 8, // log scans
- DebugLock = 16 // log ACC locks
- };
- STATIC_CONST( DataFillByte = 0xa2 );
- STATIC_CONST( NodeFillByte = 0xa4 );
-#endif
-
- // start up info
- Uint32 c_internalStartPhase;
- Uint32 c_typeOfStart;
-
- /*
- * Global data set at operation start. Unpacked from index metadata.
- * Not passed as parameter to methods. Invalid across timeslices.
- *
- * TODO inline all into index metadata
- */
-
- // index key attr ids with sizes in AttributeHeader format
- Data c_keyAttrs;
-
- // pointers to index key comparison functions
- NdbSqlUtil::Cmp** c_sqlCmp;
-
- /*
- * Other buffers used during the operation.
- */
-
- // buffer for search key data with headers
- Data c_searchKey;
-
- // buffer for current entry key data with headers
- Data c_entryKey;
-
- // buffer for scan bounds and keyinfo (primary key)
- Data c_dataBuffer;
-
- // inlined utils
- DescEnt& getDescEnt(Uint32 descPage, Uint32 descOff);
- Uint32 getTupAddr(const Frag& frag, TreeEnt ent);
- static unsigned min(unsigned x, unsigned y);
- static unsigned max(unsigned x, unsigned y);
-};
-
-// Dbtux::TupLoc
-
-inline
-Dbtux::TupLoc::TupLoc() :
- m_pageId1(RNIL >> 16),
- m_pageId2(RNIL & 0xFFFF),
- m_pageOffset(0)
-{
-}
-
-inline
-Dbtux::TupLoc::TupLoc(Uint32 pageId, Uint16 pageOffset) :
- m_pageId1(pageId >> 16),
- m_pageId2(pageId & 0xFFFF),
- m_pageOffset(pageOffset)
-{
-}
-
-inline Uint32
-Dbtux::TupLoc::getPageId() const
-{
- return (m_pageId1 << 16) | m_pageId2;
-}
-
-inline void
-Dbtux::TupLoc::setPageId(Uint32 pageId)
-{
- m_pageId1 = (pageId >> 16);
- m_pageId2 = (pageId & 0xFFFF);
-}
-
-inline Uint32
-Dbtux::TupLoc::getPageOffset() const
-{
- return (Uint32)m_pageOffset;
-}
-
-inline void
-Dbtux::TupLoc::setPageOffset(Uint32 pageOffset)
-{
- m_pageOffset = (Uint16)pageOffset;
-}
-
-inline bool
-Dbtux::TupLoc::operator==(const TupLoc& loc) const
-{
- return
- m_pageId1 == loc.m_pageId1 &&
- m_pageId2 == loc.m_pageId2 &&
- m_pageOffset == loc.m_pageOffset;
-}
-
-inline bool
-Dbtux::TupLoc::operator!=(const TupLoc& loc) const
-{
- return ! (*this == loc);
-}
-
-// Dbtux::TreeEnt
-
-inline
-Dbtux::TreeEnt::TreeEnt() :
- m_tupLoc(),
- m_tupVersion(0)
-{
-}
-
-inline bool
-Dbtux::TreeEnt::eqtuple(const TreeEnt ent) const
-{
- return
- m_tupLoc == ent.m_tupLoc;
-}
-
-inline bool
-Dbtux::TreeEnt::eq(const TreeEnt ent) const
-{
- return
- m_tupLoc == ent.m_tupLoc &&
- m_tupVersion == ent.m_tupVersion;
-}
-
-inline int
-Dbtux::TreeEnt::cmp(const TreeEnt ent) const
-{
- if (m_tupLoc.getPageId() < ent.m_tupLoc.getPageId())
- return -1;
- if (m_tupLoc.getPageId() > ent.m_tupLoc.getPageId())
- return +1;
- if (m_tupLoc.getPageOffset() < ent.m_tupLoc.getPageOffset())
- return -1;
- if (m_tupLoc.getPageOffset() > ent.m_tupLoc.getPageOffset())
- return +1;
- /*
- * Guess if one tuple version has wrapped around. This is well
- * defined ordering on existing versions since versions are assigned
- * consecutively and different versions exists only on uncommitted
- * tuple. Assuming max 2**14 uncommitted ops on same tuple.
- */
- const unsigned version_wrap_limit = (1 << (ZTUP_VERSION_BITS - 1));
- if (m_tupVersion < ent.m_tupVersion) {
- if (unsigned(ent.m_tupVersion - m_tupVersion) < version_wrap_limit)
- return -1;
- else
- return +1;
- }
- if (m_tupVersion > ent.m_tupVersion) {
- if (unsigned(m_tupVersion - ent.m_tupVersion) < version_wrap_limit)
- return +1;
- else
- return -1;
- }
- return 0;
-}
-
-// Dbtux::TreeNode
-
-inline
-Dbtux::TreeNode::TreeNode() :
- m_side(2),
- m_balance(0 + 1),
- pad1(0),
- m_occup(0),
- m_nodeScan(RNIL)
-{
- m_link[0] = NullTupLoc;
- m_link[1] = NullTupLoc;
- m_link[2] = NullTupLoc;
-}
-
-// Dbtux::TreeHead
-
-inline
-Dbtux::TreeHead::TreeHead() :
- m_nodeSize(0),
- m_prefSize(0),
- m_minOccup(0),
- m_maxOccup(0),
- m_entryCount(0),
- m_root()
-{
-}
-
-inline unsigned
-Dbtux::TreeHead::getSize(AccSize acc) const
-{
- switch (acc) {
- case AccNone:
- return 0;
- case AccHead:
- return NodeHeadSize;
- case AccPref:
- return NodeHeadSize + m_prefSize + 2 * TreeEntSize;
- case AccFull:
- return m_nodeSize;
- }
- return 0;
-}
-
-inline Dbtux::Data
-Dbtux::TreeHead::getPref(TreeNode* node) const
-{
- Uint32* ptr = (Uint32*)node + NodeHeadSize;
- return ptr;
-}
-
-inline Dbtux::TreeEnt*
-Dbtux::TreeHead::getEntList(TreeNode* node) const
-{
- Uint32* ptr = (Uint32*)node + NodeHeadSize + m_prefSize;
- return (TreeEnt*)ptr;
-}
-
-// Dbtux::TreePos
-
-inline
-Dbtux::TreePos::TreePos() :
- m_loc(),
- m_pos(ZNIL),
- m_dir(255)
-{
-}
-
-// Dbtux::DescPage
-
-inline
-Dbtux::DescPage::DescPage() :
- m_nextPage(RNIL),
- m_numFree(ZNIL)
-{
- for (unsigned i = 0; i < DescPageSize; i++) {
-#ifdef VM_TRACE
- m_data[i] = 0x13571357;
-#else
- m_data[i] = 0;
-#endif
- }
-}
-
-// Dbtux::ScanOp
-
-inline
-Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) :
- m_state(Undef),
- m_lockwait(false),
- m_userPtr(RNIL),
- m_userRef(RNIL),
- m_tableId(RNIL),
- m_indexId(RNIL),
- m_fragPtrI(RNIL),
- m_transId1(0),
- m_transId2(0),
- m_savePointId(0),
- m_accLockOp(RNIL),
- m_accLockOps(),
- m_readCommitted(0),
- m_lockMode(0),
- m_descending(0),
- m_boundMin(scanBoundPool),
- m_boundMax(scanBoundPool),
- m_scanPos(),
- m_scanEnt(),
- m_nodeScan(RNIL)
-{
- m_bound[0] = &m_boundMin;
- m_bound[1] = &m_boundMax;
- m_boundCnt[0] = 0;
- m_boundCnt[1] = 0;
-}
-
-// Dbtux::Index
-
-inline
-Dbtux::Index::Index() :
- m_state(NotDefined),
- m_tableType(DictTabInfo::UndefTableType),
- m_tableId(RNIL),
- m_numFrags(0),
- m_descPage(RNIL),
- m_descOff(0),
- m_numAttrs(0),
- m_storeNullKey(false)
-{
- for (unsigned i = 0; i < MaxIndexFragments; i++) {
- m_fragId[i] = ZNIL;
- m_fragPtrI[i] = RNIL;
- };
-}
-
-// Dbtux::Frag
-
-inline
-Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
- m_tableId(RNIL),
- m_indexId(RNIL),
- m_fragId(ZNIL),
- m_descPage(RNIL),
- m_descOff(0),
- m_numAttrs(ZNIL),
- m_storeNullKey(false),
- m_tree(),
- m_freeLoc(),
- m_scanList(scanOpPool),
- m_tupIndexFragPtrI(RNIL)
-{
- m_tupTableFragPtrI = RNIL;
- m_accTableFragPtrI = RNIL;
-}
-
-// Dbtux::FragOp
-
-inline
-Dbtux::FragOp::FragOp() :
- m_userPtr(RNIL),
- m_userRef(RNIL),
- m_indexId(RNIL),
- m_fragId(ZNIL),
- m_fragPtrI(RNIL),
- m_fragNo(ZNIL),
- m_numAttrsRecvd(ZNIL)
-{
-}
-
-// Dbtux::NodeHandle
-
-inline
-Dbtux::NodeHandle::NodeHandle(Frag& frag) :
- m_frag(frag),
- m_loc(),
- m_node(0)
-{
-}
-
-inline
-Dbtux::NodeHandle::NodeHandle(const NodeHandle& node) :
- m_frag(node.m_frag),
- m_loc(node.m_loc),
- m_node(node.m_node)
-{
-}
-
-inline Dbtux::NodeHandle&
-Dbtux::NodeHandle::operator=(const NodeHandle& node)
-{
- ndbassert(&m_frag == &node.m_frag);
- m_loc = node.m_loc;
- m_node = node.m_node;
- return *this;
-}
-
-inline bool
-Dbtux::NodeHandle::isNull()
-{
- return m_node == 0;
-}
-
-inline Dbtux::TupLoc
-Dbtux::NodeHandle::getLink(unsigned i)
-{
- ndbrequire(i <= 2);
- return m_node->m_link[i];
-}
-
-inline unsigned
-Dbtux::NodeHandle::getChilds()
-{
- return (m_node->m_link[0] != NullTupLoc) + (m_node->m_link[1] != NullTupLoc);
-}
-
-inline unsigned
-Dbtux::NodeHandle::getSide()
-{
- return m_node->m_side;
-}
-
-inline unsigned
-Dbtux::NodeHandle::getOccup()
-{
- return m_node->m_occup;
-}
-
-inline int
-Dbtux::NodeHandle::getBalance()
-{
- return (int)m_node->m_balance - 1;
-}
-
-inline Uint32
-Dbtux::NodeHandle::getNodeScan()
-{
- return m_node->m_nodeScan;
-}
-
-inline void
-Dbtux::NodeHandle::setLink(unsigned i, TupLoc loc)
-{
- ndbrequire(i <= 2);
- m_node->m_link[i] = loc;
-}
-
-inline void
-Dbtux::NodeHandle::setSide(unsigned i)
-{
- ndbrequire(i <= 2);
- m_node->m_side = i;
-}
-
-inline void
-Dbtux::NodeHandle::setOccup(unsigned n)
-{
- TreeHead& tree = m_frag.m_tree;
- ndbrequire(n <= tree.m_maxOccup);
- m_node->m_occup = n;
-}
-
-inline void
-Dbtux::NodeHandle::setBalance(int b)
-{
- ndbrequire(abs(b) <= 1);
- m_node->m_balance = (unsigned)(b + 1);
-}
-
-inline void
-Dbtux::NodeHandle::setNodeScan(Uint32 scanPtrI)
-{
- m_node->m_nodeScan = scanPtrI;
-}
-
-inline Dbtux::Data
-Dbtux::NodeHandle::getPref()
-{
- TreeHead& tree = m_frag.m_tree;
- return tree.getPref(m_node);
-}
-
-inline Dbtux::TreeEnt
-Dbtux::NodeHandle::getEnt(unsigned pos)
-{
- TreeHead& tree = m_frag.m_tree;
- TreeEnt* entList = tree.getEntList(m_node);
- const unsigned occup = m_node->m_occup;
- ndbrequire(pos < occup);
- return entList[(1 + pos) % occup];
-}
-
-inline Dbtux::TreeEnt
-Dbtux::NodeHandle::getMinMax(unsigned i)
-{
- const unsigned occup = m_node->m_occup;
- ndbrequire(i <= 1 && occup != 0);
- return getEnt(i == 0 ? 0 : occup - 1);
-}
-
-// parameters for methods
-
-#ifdef VM_TRACE
-inline
-Dbtux::PrintPar::PrintPar() :
- // caller fills in
- m_path(),
- m_side(255),
- m_parent(),
- // default return values
- m_depth(0),
- m_occup(0),
- m_ok(true)
-{
-}
-#endif
-
-// utils
-
-inline Dbtux::DescEnt&
-Dbtux::getDescEnt(Uint32 descPage, Uint32 descOff)
-{
- DescPagePtr pagePtr;
- pagePtr.i = descPage;
- c_descPagePool.getPtr(pagePtr);
- ndbrequire(descOff < DescPageSize);
- DescEnt* descEnt = (DescEnt*)&pagePtr.p->m_data[descOff];
- return *descEnt;
-}
-
-inline Uint32
-Dbtux::getTupAddr(const Frag& frag, TreeEnt ent)
-{
- const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
- const TupLoc tupLoc = ent.m_tupLoc;
- Uint32 tupAddr = NullTupAddr;
- c_tup->tuxGetTupAddr(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupAddr);
- jamEntry();
- return tupAddr;
-}
-
-inline unsigned
-Dbtux::min(unsigned x, unsigned y)
-{
- return x < y ? x : y;
-}
-
-inline unsigned
-Dbtux::max(unsigned x, unsigned y)
-{
- return x > y ? x : y;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp
deleted file mode 100644
index 32520502991..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_CMP_CPP
-#include "Dbtux.hpp"
-
-/*
- * Search key vs node prefix or entry.
- *
- * The comparison starts at given attribute position. The position is
- * updated by number of equal initial attributes found. The entry data
- * may be partial in which case CmpUnknown may be returned.
- *
- * The attributes are normalized and have variable size given in words.
- */
-int
-Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen)
-{
- const unsigned numAttrs = frag.m_numAttrs;
- const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
- // skip to right position in search key only
- for (unsigned i = 0; i < start; i++) {
- jam();
- searchKey += AttributeHeaderSize + ah(searchKey).getDataSize();
- }
- // number of words of entry data left
- unsigned len2 = maxlen;
- int ret = 0;
- while (start < numAttrs) {
- if (len2 <= AttributeHeaderSize) {
- jam();
- ret = NdbSqlUtil::CmpUnknown;
- break;
- }
- len2 -= AttributeHeaderSize;
- if (! ah(searchKey).isNULL()) {
- if (! ah(entryData).isNULL()) {
- jam();
- // verify attribute id
- const DescAttr& descAttr = descEnt.m_descAttr[start];
- ndbrequire(ah(searchKey).getAttributeId() == descAttr.m_primaryAttrId);
- ndbrequire(ah(entryData).getAttributeId() == descAttr.m_primaryAttrId);
- // sizes
- const unsigned size1 = ah(searchKey).getDataSize();
- const unsigned size2 = min(ah(entryData).getDataSize(), len2);
- len2 -= size2;
- // compare
- NdbSqlUtil::Cmp* const cmp = c_sqlCmp[start];
- const Uint32* const p1 = &searchKey[AttributeHeaderSize];
- const Uint32* const p2 = &entryData[AttributeHeaderSize];
- const bool full = (maxlen == MaxAttrDataSize);
- ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full);
- if (ret != 0) {
- jam();
- break;
- }
- } else {
- jam();
- // not NULL > NULL
- ret = +1;
- break;
- }
- } else {
- if (! ah(entryData).isNULL()) {
- jam();
- // NULL < not NULL
- ret = -1;
- break;
- }
- }
- searchKey += AttributeHeaderSize + ah(searchKey).getDataSize();
- entryData += AttributeHeaderSize + ah(entryData).getDataSize();
- start++;
- }
- return ret;
-}
-
-/*
- * Scan bound vs node prefix or entry.
- *
- * Compare lower or upper bound and index entry data. The entry data
- * may be partial in which case CmpUnknown may be returned. Otherwise
- * returns -1 if the bound is to the left of the entry and +1 if the
- * bound is to the right of the entry.
- *
- * The routine is similar to cmpSearchKey, but 0 is never returned.
- * Suppose all attributes compare equal. Recall that all bounds except
- * possibly the last one are non-strict. Use the given bound direction
- * (0-lower 1-upper) and strictness of last bound to return -1 or +1.
- *
- * Following example illustrates this. We are at (a=2, b=3).
- *
- * idir bounds strict return
- * 0 a >= 2 and b >= 3 no -1
- * 0 a >= 2 and b > 3 yes +1
- * 1 a <= 2 and b <= 3 no +1
- * 1 a <= 2 and b < 3 yes -1
- *
- * The attributes are normalized and have variable size given in words.
- */
-int
-Dbtux::cmpScanBound(const Frag& frag, unsigned idir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen)
-{
- const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
- // direction 0-lower 1-upper
- ndbrequire(idir <= 1);
- // number of words of data left
- unsigned len2 = maxlen;
- // in case of no bounds, init last type to something non-strict
- unsigned type = 4;
- while (boundCount != 0) {
- if (len2 <= AttributeHeaderSize) {
- jam();
- return NdbSqlUtil::CmpUnknown;
- }
- len2 -= AttributeHeaderSize;
- // get and skip bound type (it is used after the loop)
- type = boundInfo[0];
- boundInfo += 1;
- if (! ah(boundInfo).isNULL()) {
- if (! ah(entryData).isNULL()) {
- jam();
- // verify attribute id
- const Uint32 index = ah(boundInfo).getAttributeId();
- ndbrequire(index < frag.m_numAttrs);
- const DescAttr& descAttr = descEnt.m_descAttr[index];
- ndbrequire(ah(entryData).getAttributeId() == descAttr.m_primaryAttrId);
- // sizes
- const unsigned size1 = ah(boundInfo).getDataSize();
- const unsigned size2 = min(ah(entryData).getDataSize(), len2);
- len2 -= size2;
- // compare
- NdbSqlUtil::Cmp* const cmp = c_sqlCmp[index];
- const Uint32* const p1 = &boundInfo[AttributeHeaderSize];
- const Uint32* const p2 = &entryData[AttributeHeaderSize];
- const bool full = (maxlen == MaxAttrDataSize);
- int ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full);
- if (ret != 0) {
- jam();
- return ret;
- }
- } else {
- jam();
- // not NULL > NULL
- return +1;
- }
- } else {
- jam();
- if (! ah(entryData).isNULL()) {
- jam();
- // NULL < not NULL
- return -1;
- }
- }
- boundInfo += AttributeHeaderSize + ah(boundInfo).getDataSize();
- entryData += AttributeHeaderSize + ah(entryData).getDataSize();
- boundCount -= 1;
- }
- // all attributes were equal
- const int strict = (type & 0x1);
- return (idir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1));
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
deleted file mode 100644
index 933ec77258e..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_DEBUG_CPP
-#include "Dbtux.hpp"
-
-/*
- * 12001 log file 0-close 1-open 2-append 3-append to signal log
- * 12002 log flags 1-meta 2-maint 4-tree 8-scan
- */
-void
-Dbtux::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
-#ifdef VM_TRACE
- if (signal->theData[0] == DumpStateOrd::TuxLogToFile) {
- unsigned flag = signal->theData[1];
- const char* const tuxlog = "tux.log";
- FILE* slFile = globalSignalLoggers.getOutputStream();
- if (flag <= 3) {
- if (debugFile != 0) {
- if (debugFile != slFile)
- fclose(debugFile);
- debugFile = 0;
- debugOut = *new NdbOut(*new NullOutputStream());
- }
- if (flag == 1)
- debugFile = fopen(tuxlog, "w");
- if (flag == 2)
- debugFile = fopen(tuxlog, "a");
- if (flag == 3)
- debugFile = slFile;
- if (debugFile != 0)
- debugOut = *new NdbOut(*new FileOutputStream(debugFile));
- }
- return;
- }
- if (signal->theData[0] == DumpStateOrd::TuxSetLogFlags) {
- debugFlags = signal->theData[1];
- return;
- }
- if (signal->theData[0] == DumpStateOrd::TuxMetaDataJunk) {
- abort();
- }
-#endif
-}
-
-#ifdef VM_TRACE
-
-void
-Dbtux::printTree(Signal* signal, Frag& frag, NdbOut& out)
-{
- TreeHead& tree = frag.m_tree;
- PrintPar par;
- strcpy(par.m_path, ".");
- par.m_side = 2;
- par.m_parent = NullTupLoc;
- printNode(frag, out, tree.m_root, par);
- out.m_out->flush();
- if (! par.m_ok) {
- if (debugFile == 0) {
- signal->theData[0] = 12001;
- signal->theData[1] = 1;
- execDUMP_STATE_ORD(signal);
- if (debugFile != 0) {
- printTree(signal, frag, debugOut);
- }
- }
- ndbrequire(false);
- }
-}
-
-void
-Dbtux::printNode(Frag& frag, NdbOut& out, TupLoc loc, PrintPar& par)
-{
- if (loc == NullTupLoc) {
- par.m_depth = 0;
- return;
- }
- TreeHead& tree = frag.m_tree;
- NodeHandle node(frag);
- selectNode(node, loc);
- out << par.m_path << " " << node << endl;
- // check children
- PrintPar cpar[2];
- ndbrequire(strlen(par.m_path) + 1 < sizeof(par.m_path));
- for (unsigned i = 0; i <= 1; i++) {
- sprintf(cpar[i].m_path, "%s%c", par.m_path, "LR"[i]);
- cpar[i].m_side = i;
- cpar[i].m_depth = 0;
- cpar[i].m_parent = loc;
- printNode(frag, out, node.getLink(i), cpar[i]);
- if (! cpar[i].m_ok) {
- par.m_ok = false;
- }
- }
- static const char* const sep = " *** ";
- // check child-parent links
- if (node.getLink(2) != par.m_parent) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "parent loc " << hex << node.getLink(2);
- out << " should be " << hex << par.m_parent << endl;
- }
- if (node.getSide() != par.m_side) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "side " << dec << node.getSide();
- out << " should be " << dec << par.m_side << endl;
- }
- // check balance
- const int balance = -cpar[0].m_depth + cpar[1].m_depth;
- if (node.getBalance() != balance) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "balance " << node.getBalance();
- out << " should be " << balance << endl;
- }
- if (abs(node.getBalance()) > 1) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "balance " << node.getBalance() << " is invalid" << endl;
- }
- // check occupancy
- if (node.getOccup() == 0 || node.getOccup() > tree.m_maxOccup) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "occupancy " << node.getOccup();
- out << " zero or greater than max " << tree.m_maxOccup << endl;
- }
- // check for occupancy of interior node
- if (node.getChilds() == 2 && node.getOccup() < tree.m_minOccup) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "occupancy " << node.getOccup() << " of interior node";
- out << " less than min " << tree.m_minOccup << endl;
- }
-#ifdef dbtux_totally_groks_t_trees
- // check missed semi-leaf/leaf merge
- for (unsigned i = 0; i <= 1; i++) {
- if (node.getLink(i) != NullTupLoc &&
- node.getLink(1 - i) == NullTupLoc &&
- // our semi-leaf seems to satify interior minOccup condition
- node.getOccup() < tree.m_minOccup) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "missed merge with child " << i << endl;
- }
- }
-#endif
- // check inline prefix
- { ConstData data1 = node.getPref();
- Uint32 data2[MaxPrefSize];
- memset(data2, DataFillByte, MaxPrefSize << 2);
- readKeyAttrs(frag, node.getMinMax(0), 0, c_searchKey);
- copyAttrs(frag, c_searchKey, data2, tree.m_prefSize);
- for (unsigned n = 0; n < tree.m_prefSize; n++) {
- if (data1[n] != data2[n]) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << "inline prefix mismatch word " << n;
- out << " value " << hex << data1[n];
- out << " should be " << hex << data2[n] << endl;
- break;
- }
- }
- }
- // check ordering within node
- for (unsigned j = 1; j < node.getOccup(); j++) {
- const TreeEnt ent1 = node.getEnt(j - 1);
- const TreeEnt ent2 = node.getEnt(j);
- unsigned start = 0;
- readKeyAttrs(frag, ent1, start, c_searchKey);
- readKeyAttrs(frag, ent2, start, c_entryKey);
- int ret = cmpSearchKey(frag, start, c_searchKey, c_entryKey);
- if (ret == 0)
- ret = ent1.cmp(ent2);
- if (ret != -1) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << " disorder within node at pos " << j << endl;
- }
- }
- // check ordering wrt subtrees
- for (unsigned i = 0; i <= 1; i++) {
- if (node.getLink(i) == NullTupLoc)
- continue;
- const TreeEnt ent1 = cpar[i].m_minmax[1 - i];
- const TreeEnt ent2 = node.getMinMax(i);
- unsigned start = 0;
- readKeyAttrs(frag, ent1, start, c_searchKey);
- readKeyAttrs(frag, ent2, start, c_entryKey);
- int ret = cmpSearchKey(frag, start, c_searchKey, c_entryKey);
- if (ret == 0)
- ret = ent1.cmp(ent2);
- if (ret != (i == 0 ? -1 : +1)) {
- par.m_ok = false;
- out << par.m_path << sep;
- out << " disorder wrt subtree " << i << endl;
- }
- }
- // return values
- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
- par.m_occup = node.getOccup();
- for (unsigned i = 0; i <= 1; i++) {
- if (node.getLink(i) == NullTupLoc)
- par.m_minmax[i] = node.getMinMax(i);
- else
- par.m_minmax[i] = cpar[i].m_minmax[i];
- }
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::TupLoc& loc)
-{
- if (loc == Dbtux::NullTupLoc) {
- out << "null";
- } else {
- out << dec << loc.getPageId();
- out << "." << dec << loc.getPageOffset();
- }
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::TreeEnt& ent)
-{
- out << ent.m_tupLoc;
- out << "-" << dec << ent.m_tupVersion;
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::TreeNode& node)
-{
- out << "[TreeNode " << hex << &node;
- out << " [left " << node.m_link[0] << "]";
- out << " [right " << node.m_link[1] << "]";
- out << " [up " << node.m_link[2] << "]";
- out << " [side " << dec << node.m_side << "]";
- out << " [occup " << dec << node.m_occup << "]";
- out << " [balance " << dec << (int)node.m_balance - 1 << "]";
- out << " [nodeScan " << hex << node.m_nodeScan << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::TreeHead& tree)
-{
- out << "[TreeHead " << hex << &tree;
- out << " [nodeSize " << dec << tree.m_nodeSize << "]";
- out << " [prefSize " << dec << tree.m_prefSize << "]";
- out << " [minOccup " << dec << tree.m_minOccup << "]";
- out << " [maxOccup " << dec << tree.m_maxOccup << "]";
- out << " [AccHead " << dec << tree.getSize(Dbtux::AccHead) << "]";
- out << " [AccPref " << dec << tree.getSize(Dbtux::AccPref) << "]";
- out << " [AccFull " << dec << tree.getSize(Dbtux::AccFull) << "]";
- out << " [root " << hex << tree.m_root << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::TreePos& pos)
-{
- out << "[TreePos " << hex << &pos;
- out << " [loc " << pos.m_loc << "]";
- out << " [pos " << dec << pos.m_pos << "]";
- out << " [dir " << dec << pos.m_dir << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::DescAttr& descAttr)
-{
- out << "[DescAttr " << hex << &descAttr;
- out << " [attrDesc " << hex << descAttr.m_attrDesc;
- out << " [primaryAttrId " << dec << descAttr.m_primaryAttrId << "]";
- out << " [typeId " << dec << descAttr.m_typeId << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::ScanOp& scan)
-{
- Dbtux* tux = (Dbtux*)globalData.getBlock(DBTUX);
- out << "[ScanOp " << hex << &scan;
- out << " [state " << dec << scan.m_state << "]";
- out << " [lockwait " << dec << scan.m_lockwait << "]";
- out << " [indexId " << dec << scan.m_indexId << "]";
- out << " [fragId " << dec << scan.m_fragId << "]";
- out << " [transId " << hex << scan.m_transId1 << " " << scan.m_transId2 << "]";
- out << " [savePointId " << dec << scan.m_savePointId << "]";
- out << " [accLockOp " << hex << scan.m_accLockOp << "]";
- out << " [accLockOps";
- {
- DLFifoList<Dbtux::ScanLock>::Head head = scan.m_accLockOps;
- LocalDLFifoList<Dbtux::ScanLock> list(tux->c_scanLockPool, head);
- Dbtux::ScanLockPtr lockPtr;
- list.first(lockPtr);
- while (lockPtr.i != RNIL) {
- out << " " << hex << lockPtr.p->m_accLockOp;
- list.next(lockPtr);
- }
- }
- out << "]";
- out << " [readCommitted " << dec << scan.m_readCommitted << "]";
- out << " [lockMode " << dec << scan.m_lockMode << "]";
- out << " [descending " << dec << scan.m_descending << "]";
- out << " [pos " << scan.m_scanPos << "]";
- out << " [ent " << scan.m_scanEnt << "]";
- for (unsigned i = 0; i <= 1; i++) {
- out << " [bound " << dec << i;
- Dbtux::ScanBound& bound = *scan.m_bound[i];
- Dbtux::ScanBoundIterator iter;
- bound.first(iter);
- for (unsigned j = 0; j < bound.getSize(); j++) {
- out << " " << hex << *iter.data;
- bound.next(iter);
- }
- out << "]";
- }
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::Index& index)
-{
- Dbtux* tux = (Dbtux*)globalData.getBlock(DBTUX);
- out << "[Index " << hex << &index;
- out << " [tableId " << dec << index.m_tableId << "]";
- out << " [numFrags " << dec << index.m_numFrags << "]";
- for (unsigned i = 0; i < index.m_numFrags; i++) {
- out << " [frag " << dec << i << " ";
- const Dbtux::Frag& frag = *tux->c_fragPool.getPtr(index.m_fragPtrI[i]);
- out << frag;
- out << "]";
- }
- out << " [descPage " << hex << index.m_descPage << "]";
- out << " [descOff " << dec << index.m_descOff << "]";
- out << " [numAttrs " << dec << index.m_numAttrs << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::Frag& frag)
-{
- out << "[Frag " << hex << &frag;
- out << " [tableId " << dec << frag.m_tableId << "]";
- out << " [indexId " << dec << frag.m_indexId << "]";
- out << " [fragId " << dec << frag.m_fragId << "]";
- out << " [descPage " << hex << frag.m_descPage << "]";
- out << " [descOff " << dec << frag.m_descOff << "]";
- out << " [numAttrs " << dec << frag.m_numAttrs << "]";
- out << " [tree " << frag.m_tree << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::FragOp& fragOp)
-{
- out << "[FragOp " << hex << &fragOp;
- out << " [userPtr " << dec << fragOp.m_userPtr << "]";
- out << " [indexId " << dec << fragOp.m_indexId << "]";
- out << " [fragId " << dec << fragOp.m_fragId << "]";
- out << " [fragNo " << dec << fragOp.m_fragNo << "]";
- out << " numAttrsRecvd " << dec << fragOp.m_numAttrsRecvd << "]";
- out << "]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Dbtux::NodeHandle& node)
-{
- const Dbtux::Frag& frag = node.m_frag;
- const Dbtux::TreeHead& tree = frag.m_tree;
- out << "[NodeHandle " << hex << &node;
- out << " [loc " << node.m_loc << "]";
- out << " [node " << *node.m_node << "]";
- const Uint32* data;
- out << " [pref";
- data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize;
- for (unsigned j = 0; j < tree.m_prefSize; j++)
- out << " " << hex << data[j];
- out << "]";
- out << " [entList";
- unsigned numpos = node.m_node->m_occup;
- data = (const Uint32*)node.m_node + Dbtux::NodeHeadSize + tree.m_prefSize;
- const Dbtux::TreeEnt* entList = (const Dbtux::TreeEnt*)data;
- // print entries in logical order
- for (unsigned pos = 1; pos <= numpos; pos++)
- out << " " << entList[pos % numpos];
- out << "]";
- out << "]";
- return out;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
deleted file mode 100644
index fde64161cab..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_GEN_CPP
-#include "Dbtux.hpp"
-
-Dbtux::Dbtux(Block_context& ctx) :
- SimulatedBlock(DBTUX, ctx),
- c_tup(0),
- c_descPageList(RNIL),
-#ifdef VM_TRACE
- debugFile(0),
- debugOut(*new NullOutputStream()),
- debugFlags(0),
-#endif
- c_internalStartPhase(0),
- c_typeOfStart(NodeState::ST_ILLEGAL_TYPE),
- c_dataBuffer(0)
-{
- BLOCK_CONSTRUCTOR(Dbtux);
- // verify size assumptions (also when release-compiled)
- ndbrequire(
- (sizeof(TreeEnt) & 0x3) == 0 &&
- (sizeof(TreeNode) & 0x3) == 0 &&
- (sizeof(DescHead) & 0x3) == 0 &&
- (sizeof(DescAttr) & 0x3) == 0
- );
- /*
- * DbtuxGen.cpp
- */
- addRecSignal(GSN_CONTINUEB, &Dbtux::execCONTINUEB);
- addRecSignal(GSN_STTOR, &Dbtux::execSTTOR);
- addRecSignal(GSN_READ_CONFIG_REQ, &Dbtux::execREAD_CONFIG_REQ, true);
- /*
- * DbtuxMeta.cpp
- */
- addRecSignal(GSN_TUXFRAGREQ, &Dbtux::execTUXFRAGREQ);
- addRecSignal(GSN_TUX_ADD_ATTRREQ, &Dbtux::execTUX_ADD_ATTRREQ);
- addRecSignal(GSN_ALTER_INDX_REQ, &Dbtux::execALTER_INDX_REQ);
- addRecSignal(GSN_DROP_TAB_REQ, &Dbtux::execDROP_TAB_REQ);
- /*
- * DbtuxMaint.cpp
- */
- addRecSignal(GSN_TUX_MAINT_REQ, &Dbtux::execTUX_MAINT_REQ);
- /*
- * DbtuxScan.cpp
- */
- addRecSignal(GSN_ACC_SCANREQ, &Dbtux::execACC_SCANREQ);
- addRecSignal(GSN_TUX_BOUND_INFO, &Dbtux::execTUX_BOUND_INFO);
- addRecSignal(GSN_NEXT_SCANREQ, &Dbtux::execNEXT_SCANREQ);
- addRecSignal(GSN_ACC_CHECK_SCAN, &Dbtux::execACC_CHECK_SCAN);
- addRecSignal(GSN_ACCKEYCONF, &Dbtux::execACCKEYCONF);
- addRecSignal(GSN_ACCKEYREF, &Dbtux::execACCKEYREF);
- addRecSignal(GSN_ACC_ABORTCONF, &Dbtux::execACC_ABORTCONF);
- /*
- * DbtuxStat.cpp
- */
- addRecSignal(GSN_READ_PSEUDO_REQ, &Dbtux::execREAD_PSEUDO_REQ);
- /*
- * DbtuxDebug.cpp
- */
- addRecSignal(GSN_DUMP_STATE_ORD, &Dbtux::execDUMP_STATE_ORD);
-}
-
-Dbtux::~Dbtux()
-{
-}
-
-void
-Dbtux::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- const Uint32* data = signal->getDataPtr();
- switch (data[0]) {
- case TuxContinueB::DropIndex: // currently unused
- {
- IndexPtr indexPtr;
- c_indexPool.getPtr(indexPtr, data[1]);
- dropIndex(signal, indexPtr, data[2], data[3]);
- }
- break;
- default:
- ndbrequire(false);
- break;
- }
-}
-
-/*
- * STTOR is sent to one block at a time. In NDBCNTR it triggers
- * NDB_STTOR to the "old" blocks. STTOR carries start phase (SP) and
- * NDB_STTOR carries internal start phase (ISP).
- *
- * SP ISP activities
- * 1 none
- * 2 1
- * 3 2 recover metadata, activate indexes
- * 4 3 recover data
- * 5 4-6
- * 6 skip
- * 7 skip
- * 8 7 build non-logged indexes on SR
- *
- * DBTUX catches type of start (IS, SR, NR, INR) at SP 3 and updates
- * internal start phase at SP 7. These are used to prevent index
- * maintenance operations caused by redo log at SR.
- */
-void
-Dbtux::execSTTOR(Signal* signal)
-{
- jamEntry();
- Uint32 startPhase = signal->theData[1];
- switch (startPhase) {
- case 1:
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- c_tup = (Dbtup*)globalData.getBlock(DBTUP);
- ndbrequire(c_tup != 0);
- break;
- case 3:
- jam();
- c_typeOfStart = signal->theData[7];
- break;
- case 7:
- c_internalStartPhase = 6;
- default:
- jam();
- break;
- }
- signal->theData[0] = 0; // garbage
- signal->theData[1] = 0; // garbage
- signal->theData[2] = 0; // garbage
- signal->theData[3] = 1;
- signal->theData[4] = 3; // for c_typeOfStart
- signal->theData[5] = 7; // for c_internalStartPhase
- signal->theData[6] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
-}
-
-void
-Dbtux::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- 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;
- Uint32 nScanBatch;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.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));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_BATCH_SIZE, &nScanBatch));
-
- const Uint32 nDescPage = (nIndex * DescHeadSize + nAttribute * DescAttrSize + DescPageSize - 1) / DescPageSize;
- const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4;
- const Uint32 nScanLock = nScanOp * nScanBatch;
-
- c_indexPool.setSize(nIndex);
- c_fragPool.setSize(nFragment);
- c_descPagePool.setSize(nDescPage);
- c_fragOpPool.setSize(MaxIndexFragments);
- c_scanOpPool.setSize(nScanOp);
- c_scanBoundPool.setSize(nScanBoundWords);
- c_scanLockPool.setSize(nScanLock);
- /*
- * Index id is physical array index. We seize and initialize all
- * index records now.
- */
- IndexPtr indexPtr;
- while (1) {
- jam();
- refresh_watch_dog();
- c_indexPool.seize(indexPtr);
- if (indexPtr.i == RNIL) {
- jam();
- break;
- }
- new (indexPtr.p) Index();
- }
- // allocate buffers
- c_keyAttrs = (Uint32*)allocRecord("c_keyAttrs", sizeof(Uint32), MaxIndexAttributes);
- c_sqlCmp = (NdbSqlUtil::Cmp**)allocRecord("c_sqlCmp", sizeof(NdbSqlUtil::Cmp*), MaxIndexAttributes);
- c_searchKey = (Uint32*)allocRecord("c_searchKey", sizeof(Uint32), MaxAttrDataSize);
- c_entryKey = (Uint32*)allocRecord("c_entryKey", sizeof(Uint32), MaxAttrDataSize);
- c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1);
- // ack
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-// utils
-
-void
-Dbtux::setKeyAttrs(const Frag& frag)
-{
- Data keyAttrs = c_keyAttrs; // global
- NdbSqlUtil::Cmp** sqlCmp = c_sqlCmp; // global
- const unsigned numAttrs = frag.m_numAttrs;
- const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
- for (unsigned i = 0; i < numAttrs; i++) {
- jam();
- const DescAttr& descAttr = descEnt.m_descAttr[i];
- Uint32 size = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc);
- // set attr id and fixed size
- ah(keyAttrs) = AttributeHeader(descAttr.m_primaryAttrId, size);
- keyAttrs += 1;
- // set comparison method pointer
- const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getTypeBinary(descAttr.m_typeId);
- ndbrequire(sqlType.m_cmp != 0);
- *(sqlCmp++) = sqlType.m_cmp;
- }
-}
-
-void
-Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData)
-{
- ConstData keyAttrs = c_keyAttrs; // global
- const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
- const TupLoc tupLoc = ent.m_tupLoc;
- const Uint32 tupVersion = ent.m_tupVersion;
- ndbrequire(start < frag.m_numAttrs);
- const Uint32 numAttrs = frag.m_numAttrs - start;
- // skip to start position in keyAttrs only
- keyAttrs += start;
- int ret = c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), tupVersion, keyAttrs, numAttrs, keyData);
- jamEntry();
- // TODO handle error
- ndbrequire(ret > 0);
-#ifdef VM_TRACE
- if (debugFlags & (DebugMaint | DebugScan)) {
- debugOut << "readKeyAttrs:" << endl;
- ConstData data = keyData;
- Uint32 totalSize = 0;
- for (Uint32 i = start; i < frag.m_numAttrs; i++) {
- Uint32 attrId = ah(data).getAttributeId();
- Uint32 dataSize = ah(data).getDataSize();
- debugOut << i << " attrId=" << attrId << " size=" << dataSize;
- data += 1;
- for (Uint32 j = 0; j < dataSize; j++) {
- debugOut << " " << hex << data[0];
- data += 1;
- }
- debugOut << endl;
- totalSize += 1 + dataSize;
- }
- ndbassert((int)totalSize == ret);
- }
-#endif
-}
-
-void
-Dbtux::readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize)
-{
- const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
- const TupLoc tupLoc = ent.m_tupLoc;
- int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), pkData, true);
- jamEntry();
- // TODO handle error
- ndbrequire(ret > 0);
- pkSize = ret;
-}
-
-/*
- * Copy attribute data with headers. Input is all index key data.
- * Copies whatever fits.
- */
-void
-Dbtux::copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2)
-{
- unsigned n = frag.m_numAttrs;
- unsigned len2 = maxlen2;
- while (n != 0) {
- jam();
- const unsigned dataSize = ah(data1).getDataSize();
- // copy header
- if (len2 == 0)
- return;
- data2[0] = data1[0];
- data1 += 1;
- data2 += 1;
- len2 -= 1;
- // copy data
- for (unsigned i = 0; i < dataSize; i++) {
- if (len2 == 0)
- return;
- data2[i] = data1[i];
- len2 -= 1;
- }
- data1 += dataSize;
- data2 += dataSize;
- n -= 1;
- }
-#ifdef VM_TRACE
- memset(data2, DataFillByte, len2 << 2);
-#endif
-}
-
-void
-Dbtux::unpackBound(const ScanBound& bound, Data dest)
-{
- ScanBoundIterator iter;
- bound.first(iter);
- const unsigned n = bound.getSize();
- unsigned j;
- for (j = 0; j < n; j++) {
- dest[j] = *iter.data;
- bound.next(iter);
- }
-}
-
-BLOCK_FUNCTIONS(Dbtux)
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
deleted file mode 100644
index 65fc1d114f0..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_MAINT_CPP
-#include "Dbtux.hpp"
-
-/*
- * Maintain index.
- */
-
-void
-Dbtux::execTUX_MAINT_REQ(Signal* signal)
-{
- jamEntry();
- TuxMaintReq* const sig = (TuxMaintReq*)signal->getDataPtrSend();
- // ignore requests from redo log
- if (c_internalStartPhase < 6 &&
- c_typeOfStart != NodeState::ST_NODE_RESTART &&
- c_typeOfStart != NodeState::ST_INITIAL_NODE_RESTART) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugMaint) {
- TupLoc tupLoc(sig->pageId, sig->pageIndex);
- debugOut << "opInfo=" << hex << sig->opInfo;
- debugOut << " tableId=" << dec << sig->tableId;
- debugOut << " indexId=" << dec << sig->indexId;
- debugOut << " fragId=" << dec << sig->fragId;
- debugOut << " tupLoc=" << tupLoc;
- debugOut << " tupVersion=" << dec << sig->tupVersion;
- debugOut << " -- ignored at ISP=" << dec << c_internalStartPhase;
- debugOut << " TOS=" << dec << c_typeOfStart;
- debugOut << endl;
- }
-#endif
- sig->errorCode = 0;
- return;
- }
- TuxMaintReq reqCopy = *sig;
- TuxMaintReq* const req = &reqCopy;
- const Uint32 opCode = req->opInfo & 0xFF;
- const Uint32 opFlag = req->opInfo >> 8;
- // get the index
- IndexPtr indexPtr;
- c_indexPool.getPtr(indexPtr, req->indexId);
- ndbrequire(indexPtr.p->m_tableId == req->tableId);
- // get base fragment id and extra bits
- const Uint32 fragId = req->fragId;
- // get the fragment
- FragPtr fragPtr;
- fragPtr.i = RNIL;
- for (unsigned i = 0; i < indexPtr.p->m_numFrags; i++) {
- jam();
- if (indexPtr.p->m_fragId[i] == fragId) {
- jam();
- c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
- break;
- }
- }
- ndbrequire(fragPtr.i != RNIL);
- Frag& frag = *fragPtr.p;
- // set up index keys for this operation
- setKeyAttrs(frag);
- // set up search entry
- TreeEnt ent;
- ent.m_tupLoc = TupLoc(req->pageId, req->pageIndex);
- ent.m_tupVersion = req->tupVersion;
- // read search key
- readKeyAttrs(frag, ent, 0, c_searchKey);
- if (! frag.m_storeNullKey) {
- // check if all keys are null
- const unsigned numAttrs = frag.m_numAttrs;
- bool allNull = true;
- for (unsigned i = 0; i < numAttrs; i++) {
- if (c_searchKey[i] != 0) {
- jam();
- allNull = false;
- break;
- }
- }
- if (allNull) {
- jam();
- req->errorCode = 0;
- *sig = *req;
- return;
- }
- }
-#ifdef VM_TRACE
- if (debugFlags & DebugMaint) {
- debugOut << "opCode=" << dec << opCode;
- debugOut << " opFlag=" << dec << opFlag;
- debugOut << " tableId=" << dec << req->tableId;
- debugOut << " indexId=" << dec << req->indexId;
- debugOut << " fragId=" << dec << req->fragId;
- debugOut << " entry=" << ent;
- debugOut << endl;
- }
-#endif
- // do the operation
- req->errorCode = 0;
- TreePos treePos;
- bool ok;
- switch (opCode) {
- case TuxMaintReq::OpAdd:
- jam();
- ok = searchToAdd(frag, c_searchKey, ent, treePos);
-#ifdef VM_TRACE
- if (debugFlags & DebugMaint) {
- debugOut << treePos << (! ok ? " - error" : "") << endl;
- }
-#endif
- if (! ok) {
- jam();
- // there is no "Building" state so this will have to do
- if (indexPtr.p->m_state == Index::Online) {
- jam();
- req->errorCode = TuxMaintReq::SearchError;
- }
- break;
- }
- /*
- * At most one new node is inserted in the operation. Pre-allocate
- * it so that the operation cannot fail.
- */
- if (frag.m_freeLoc == NullTupLoc) {
- jam();
- NodeHandle node(frag);
- req->errorCode = allocNode(signal, node);
- if (req->errorCode != 0) {
- jam();
- break;
- }
- // link to freelist
- node.setLink(0, frag.m_freeLoc);
- frag.m_freeLoc = node.m_loc;
- ndbrequire(frag.m_freeLoc != NullTupLoc);
- }
- treeAdd(frag, treePos, ent);
- break;
- case TuxMaintReq::OpRemove:
- jam();
- ok = searchToRemove(frag, c_searchKey, ent, treePos);
-#ifdef VM_TRACE
- if (debugFlags & DebugMaint) {
- debugOut << treePos << (! ok ? " - error" : "") << endl;
- }
-#endif
- if (! ok) {
- jam();
- // there is no "Building" state so this will have to do
- if (indexPtr.p->m_state == Index::Online) {
- jam();
- req->errorCode = TuxMaintReq::SearchError;
- }
- break;
- }
- treeRemove(frag, treePos);
- break;
- default:
- ndbrequire(false);
- break;
- }
-#ifdef VM_TRACE
- if (debugFlags & DebugTree) {
- printTree(signal, frag, debugOut);
- }
-#endif
- // copy back
- *sig = *req;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
deleted file mode 100644
index 423ca83af14..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_META_CPP
-#include "Dbtux.hpp"
-#include <my_sys.h>
-
-/*
- * Create index.
- *
- * For historical reasons it looks like we are adding random fragments
- * and attributes to existing index. In fact all fragments must be
- * created at one time and they have identical attributes.
- */
-
-void
-Dbtux::execTUXFRAGREQ(Signal* signal)
-{
- jamEntry();
- if (signal->theData[0] == (Uint32)-1) {
- jam();
- abortAddFragOp(signal);
- return;
- }
- const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr();
- const TuxFragReq* const req = &reqCopy;
- IndexPtr indexPtr;
- indexPtr.i = RNIL;
- FragOpPtr fragOpPtr;
- fragOpPtr.i = RNIL;
- TuxFragRef::ErrorCode errorCode = TuxFragRef::NoError;
- do {
- // get the index record
- if (req->tableId >= c_indexPool.getSize()) {
- jam();
- errorCode = TuxFragRef::InvalidRequest;
- break;
- }
- c_indexPool.getPtr(indexPtr, req->tableId);
- if (indexPtr.p->m_state != Index::NotDefined &&
- indexPtr.p->m_state != Index::Defining) {
- jam();
- errorCode = TuxFragRef::InvalidRequest;
- indexPtr.i = RNIL; // leave alone
- break;
- }
- // get new operation record
- c_fragOpPool.seize(fragOpPtr);
- ndbrequire(fragOpPtr.i != RNIL);
- new (fragOpPtr.p) FragOp();
- fragOpPtr.p->m_userPtr = req->userPtr;
- fragOpPtr.p->m_userRef = req->userRef;
- fragOpPtr.p->m_indexId = req->tableId;
- fragOpPtr.p->m_fragId = req->fragId;
- fragOpPtr.p->m_fragNo = indexPtr.p->m_numFrags;
- fragOpPtr.p->m_numAttrsRecvd = 0;
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Seize frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
- }
-#endif
- // check if index has place for more fragments
- ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments);
- // seize new fragment record
- FragPtr fragPtr;
- c_fragPool.seize(fragPtr);
- if (fragPtr.i == RNIL) {
- jam();
- errorCode = TuxFragRef::NoFreeFragment;
- break;
- }
- new (fragPtr.p) Frag(c_scanOpPool);
- fragPtr.p->m_tableId = req->primaryTableId;
- fragPtr.p->m_indexId = req->tableId;
- fragPtr.p->m_fragId = req->fragId;
- fragPtr.p->m_numAttrs = req->noOfAttr;
- fragPtr.p->m_storeNullKey = true; // not yet configurable
- fragPtr.p->m_tupIndexFragPtrI = req->tupIndexFragPtrI;
- fragPtr.p->m_tupTableFragPtrI = req->tupTableFragPtrI[0];
- fragPtr.p->m_accTableFragPtrI = req->accTableFragPtrI[0];
- // add the fragment to the index
- indexPtr.p->m_fragId[indexPtr.p->m_numFrags] = req->fragId;
- indexPtr.p->m_fragPtrI[indexPtr.p->m_numFrags] = fragPtr.i;
- indexPtr.p->m_numFrags++;
- // save under operation
- fragOpPtr.p->m_fragPtrI = fragPtr.i;
- // prepare to receive attributes
- if (fragOpPtr.p->m_fragNo == 0) {
- jam();
- // receiving first fragment
- ndbrequire(
- indexPtr.p->m_state == Index::NotDefined &&
- DictTabInfo::isOrderedIndex(req->tableType) &&
- req->noOfAttr > 0 &&
- req->noOfAttr <= MaxIndexAttributes &&
- indexPtr.p->m_descPage == RNIL);
- indexPtr.p->m_state = Index::Defining;
- indexPtr.p->m_tableType = (DictTabInfo::TableType)req->tableType;
- indexPtr.p->m_tableId = req->primaryTableId;
- indexPtr.p->m_numAttrs = req->noOfAttr;
- indexPtr.p->m_storeNullKey = true; // not yet configurable
- // allocate attribute descriptors
- if (! allocDescEnt(indexPtr)) {
- jam();
- errorCode = TuxFragRef::NoFreeAttributes;
- break;
- }
- } else {
- // receiving subsequent fragment
- jam();
- ndbrequire(
- indexPtr.p->m_state == Index::Defining &&
- indexPtr.p->m_tableType == (DictTabInfo::TableType)req->tableType &&
- indexPtr.p->m_tableId == req->primaryTableId &&
- indexPtr.p->m_numAttrs == req->noOfAttr);
- }
- // copy metadata address to each fragment
- fragPtr.p->m_descPage = indexPtr.p->m_descPage;
- fragPtr.p->m_descOff = indexPtr.p->m_descOff;
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl;
- }
-#endif
- // error inserts
- if (ERROR_INSERTED(12001) && fragOpPtr.p->m_fragNo == 0 ||
- ERROR_INSERTED(12002) && fragOpPtr.p->m_fragNo == 1) {
- jam();
- errorCode = (TuxFragRef::ErrorCode)1;
- CLEAR_ERROR_INSERT_VALUE;
- break;
- }
- // success
- TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend();
- conf->userPtr = req->userPtr;
- conf->tuxConnectPtr = fragOpPtr.i;
- conf->fragPtr = fragPtr.i;
- conf->fragId = fragPtr.p->m_fragId;
- sendSignal(req->userRef, GSN_TUXFRAGCONF,
- signal, TuxFragConf::SignalLength, JBB);
- return;
- } while (0);
- // error
- TuxFragRef* const ref = (TuxFragRef*)signal->getDataPtrSend();
- ref->userPtr = req->userPtr;
- ref->errorCode = errorCode;
- sendSignal(req->userRef, GSN_TUXFRAGREF,
- signal, TuxFragRef::SignalLength, JBB);
- if (fragOpPtr.i != RNIL) {
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Release on frag error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
- }
-#endif
- c_fragOpPool.release(fragOpPtr);
- }
- if (indexPtr.i != RNIL) {
- jam();
- // let DICT drop the unfinished index
- }
-}
-
-void
-Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
-{
- jamEntry();
- const TuxAddAttrReq reqCopy = *(const TuxAddAttrReq*)signal->getDataPtr();
- const TuxAddAttrReq* const req = &reqCopy;
- // get the records
- FragOpPtr fragOpPtr;
- IndexPtr indexPtr;
- FragPtr fragPtr;
- c_fragOpPool.getPtr(fragOpPtr, req->tuxConnectPtr);
- c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId);
- c_fragPool.getPtr(fragPtr, fragOpPtr.p->m_fragPtrI);
- TuxAddAttrRef::ErrorCode errorCode = TuxAddAttrRef::NoError;
- do {
- // expected attribute id
- const unsigned attrId = fragOpPtr.p->m_numAttrsRecvd++;
- ndbrequire(
- indexPtr.p->m_state == Index::Defining &&
- attrId < indexPtr.p->m_numAttrs &&
- attrId == req->attrId);
- // define the attribute
- DescEnt& descEnt = getDescEnt(indexPtr.p->m_descPage, indexPtr.p->m_descOff);
- DescAttr& descAttr = descEnt.m_descAttr[attrId];
- descAttr.m_attrDesc = req->attrDescriptor;
- descAttr.m_primaryAttrId = req->primaryAttrId;
- descAttr.m_typeId = AttributeDescriptor::getType(req->attrDescriptor);
- descAttr.m_charset = (req->extTypeInfo >> 16);
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Add frag " << fragPtr.i << " attr " << attrId << " " << descAttr << endl;
- }
-#endif
- // check that type is valid and has a binary comparison method
- const NdbSqlUtil::Type& type = NdbSqlUtil::getTypeBinary(descAttr.m_typeId);
- if (type.m_typeId == NdbSqlUtil::Type::Undefined ||
- type.m_cmp == 0) {
- jam();
- errorCode = TuxAddAttrRef::InvalidAttributeType;
- break;
- }
- if (descAttr.m_charset != 0) {
- uint err;
- CHARSET_INFO *cs = all_charsets[descAttr.m_charset];
- ndbrequire(cs != 0);
- if ((err = NdbSqlUtil::check_column_for_ordered_index(descAttr.m_typeId, cs))) {
- jam();
- errorCode = (TuxAddAttrRef::ErrorCode) err;
- break;
- }
- }
- const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd);
- if (ERROR_INSERTED(12003) && fragOpPtr.p->m_fragNo == 0 && attrId == 0 ||
- ERROR_INSERTED(12004) && fragOpPtr.p->m_fragNo == 0 && lastAttr ||
- ERROR_INSERTED(12005) && fragOpPtr.p->m_fragNo == 1 && attrId == 0 ||
- ERROR_INSERTED(12006) && fragOpPtr.p->m_fragNo == 1 && lastAttr) {
- errorCode = (TuxAddAttrRef::ErrorCode)1;
- CLEAR_ERROR_INSERT_VALUE;
- break;
- }
- if (lastAttr) {
- jam();
- // initialize tree header
- TreeHead& tree = fragPtr.p->m_tree;
- new (&tree) TreeHead();
- // make these configurable later
- tree.m_nodeSize = MAX_TTREE_NODE_SIZE;
- tree.m_prefSize = MAX_TTREE_PREF_SIZE;
- const unsigned maxSlack = MAX_TTREE_NODE_SLACK;
- // size up to and including first 2 entries
- const unsigned pref = tree.getSize(AccPref);
- if (! (pref <= tree.m_nodeSize)) {
- jam();
- errorCode = TuxAddAttrRef::InvalidNodeSize;
- break;
- }
- const unsigned slots = (tree.m_nodeSize - pref) / TreeEntSize;
- // leave out work space entry
- tree.m_maxOccup = 2 + slots - 1;
- // min occupancy of interior node must be at least 2
- if (! (2 + maxSlack <= tree.m_maxOccup)) {
- jam();
- errorCode = TuxAddAttrRef::InvalidNodeSize;
- break;
- }
- tree.m_minOccup = tree.m_maxOccup - maxSlack;
- // root node does not exist (also set by ctor)
- tree.m_root = NullTupLoc;
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- if (fragOpPtr.p->m_fragNo == 0) {
- debugOut << "Index id=" << indexPtr.i;
- debugOut << " nodeSize=" << tree.m_nodeSize;
- debugOut << " headSize=" << NodeHeadSize;
- debugOut << " prefSize=" << tree.m_prefSize;
- debugOut << " entrySize=" << TreeEntSize;
- debugOut << " minOccup=" << tree.m_minOccup;
- debugOut << " maxOccup=" << tree.m_maxOccup;
- debugOut << endl;
- }
- }
-#endif
- // fragment is defined
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Release frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
- }
-#endif
- c_fragOpPool.release(fragOpPtr);
- }
- // success
- TuxAddAttrConf* conf = (TuxAddAttrConf*)signal->getDataPtrSend();
- conf->userPtr = fragOpPtr.p->m_userPtr;
- conf->lastAttr = lastAttr;
- sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRCONF,
- signal, TuxAddAttrConf::SignalLength, JBB);
- return;
- } while (0);
- // error
- TuxAddAttrRef* ref = (TuxAddAttrRef*)signal->getDataPtrSend();
- ref->userPtr = fragOpPtr.p->m_userPtr;
- ref->errorCode = errorCode;
- sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRREF,
- signal, TuxAddAttrRef::SignalLength, JBB);
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
- }
-#endif
- c_fragOpPool.release(fragOpPtr);
- // let DICT drop the unfinished index
-}
-
-/*
- * LQH aborts on-going create index operation.
- */
-void
-Dbtux::abortAddFragOp(Signal* signal)
-{
- FragOpPtr fragOpPtr;
- IndexPtr indexPtr;
- c_fragOpPool.getPtr(fragOpPtr, signal->theData[1]);
- c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId);
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Release on abort frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl;
- }
-#endif
- c_fragOpPool.release(fragOpPtr);
- // let DICT drop the unfinished index
-}
-
-/*
- * Set index online. Currently at system restart this arrives before
- * build and is therefore not correct.
- */
-void
-Dbtux::execALTER_INDX_REQ(Signal* signal)
-{
- jamEntry();
- const AlterIndxReq reqCopy = *(const AlterIndxReq*)signal->getDataPtr();
- const AlterIndxReq* const req = &reqCopy;
- // set index online after build
- IndexPtr indexPtr;
- c_indexPool.getPtr(indexPtr, req->getIndexId());
- indexPtr.p->m_state = Index::Online;
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Online index " << indexPtr.i << " " << *indexPtr.p << endl;
- }
-#endif
- // success
- AlterIndxConf* const conf = (AlterIndxConf*)signal->getDataPtrSend();
- conf->setUserRef(reference());
- conf->setConnectionPtr(req->getConnectionPtr());
- conf->setRequestType(req->getRequestType());
- conf->setTableId(req->getTableId());
- conf->setIndexId(req->getIndexId());
- conf->setIndexVersion(req->getIndexVersion());
- sendSignal(req->getUserRef(), GSN_ALTER_INDX_CONF,
- signal, AlterIndxConf::SignalLength, JBB);
-}
-
-/*
- * Drop index.
- *
- * Uses same DROP_TAB_REQ signal as normal tables.
- */
-
-void
-Dbtux::execDROP_TAB_REQ(Signal* signal)
-{
- jamEntry();
- const DropTabReq reqCopy = *(const DropTabReq*)signal->getDataPtr();
- const DropTabReq* const req = &reqCopy;
- IndexPtr indexPtr;
-
- Uint32 tableId = req->tableId;
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- if (tableId >= c_indexPool.getSize()) {
- jam();
- // reply to sender
- DropTabConf* const conf = (DropTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->tableId = tableId;
- sendSignal(senderRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
- return;
- }
-
- c_indexPool.getPtr(indexPtr, req->tableId);
- // drop works regardless of index state
-#ifdef VM_TRACE
- if (debugFlags & DebugMeta) {
- debugOut << "Drop index " << indexPtr.i << " " << *indexPtr.p << endl;
- }
-#endif
- ndbrequire(req->senderRef != 0);
- dropIndex(signal, indexPtr, req->senderRef, req->senderData);
-}
-
-void
-Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 senderData)
-{
- jam();
- indexPtr.p->m_state = Index::Dropping;
- // drop fragments
- while (indexPtr.p->m_numFrags > 0) {
- jam();
- Uint32 i = --indexPtr.p->m_numFrags;
- FragPtr fragPtr;
- c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
- c_fragPool.release(fragPtr);
- }
- // drop attributes
- if (indexPtr.p->m_descPage != RNIL) {
- jam();
- freeDescEnt(indexPtr);
- indexPtr.p->m_descPage = RNIL;
- }
- if (senderRef != 0) {
- jam();
- // reply to sender
- DropTabConf* const conf = (DropTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->tableId = indexPtr.i;
- sendSignal(senderRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
- }
- new (indexPtr.p) Index();
-}
-
-/*
- * Subroutines.
- */
-
-bool
-Dbtux::allocDescEnt(IndexPtr indexPtr)
-{
- jam();
- const unsigned size = DescHeadSize + indexPtr.p->m_numAttrs * DescAttrSize;
- DescPagePtr pagePtr;
- pagePtr.i = c_descPageList;
- while (pagePtr.i != RNIL) {
- jam();
- c_descPagePool.getPtr(pagePtr);
- if (pagePtr.p->m_numFree >= size) {
- jam();
- break;
- }
- pagePtr.i = pagePtr.p->m_nextPage;
- }
- if (pagePtr.i == RNIL) {
- jam();
- if (! c_descPagePool.seize(pagePtr)) {
- jam();
- return false;
- }
- new (pagePtr.p) DescPage();
- // add in front of list
- pagePtr.p->m_nextPage = c_descPageList;
- c_descPageList = pagePtr.i;
- pagePtr.p->m_numFree = DescPageSize;
- }
- ndbrequire(pagePtr.p->m_numFree >= size);
- indexPtr.p->m_descPage = pagePtr.i;
- indexPtr.p->m_descOff = DescPageSize - pagePtr.p->m_numFree;
- pagePtr.p->m_numFree -= size;
- DescEnt& descEnt = getDescEnt(indexPtr.p->m_descPage, indexPtr.p->m_descOff);
- descEnt.m_descHead.m_indexId = indexPtr.i;
- descEnt.m_descHead.pad1 = 0;
- return true;
-}
-
-void
-Dbtux::freeDescEnt(IndexPtr indexPtr)
-{
- DescPagePtr pagePtr;
- c_descPagePool.getPtr(pagePtr, indexPtr.p->m_descPage);
- Uint32* const data = pagePtr.p->m_data;
- const unsigned size = DescHeadSize + indexPtr.p->m_numAttrs * DescAttrSize;
- unsigned off = indexPtr.p->m_descOff;
- // move the gap to the free area at the top
- while (off + size < DescPageSize - pagePtr.p->m_numFree) {
- jam();
- // next entry to move over the gap
- DescEnt& descEnt2 = *(DescEnt*)&data[off + size];
- Uint32 indexId2 = descEnt2.m_descHead.m_indexId;
- Index& index2 = *c_indexPool.getPtr(indexId2);
- unsigned size2 = DescHeadSize + index2.m_numAttrs * DescAttrSize;
- ndbrequire(
- index2.m_descPage == pagePtr.i &&
- index2.m_descOff == off + size);
- // move the entry (overlapping copy if size < size2)
- unsigned i;
- for (i = 0; i < size2; i++) {
- jam();
- data[off + i] = data[off + size + i];
- }
- off += size2;
- // adjust page offset in index and all fragments
- index2.m_descOff -= size;
- for (i = 0; i < index2.m_numFrags; i++) {
- jam();
- Frag& frag2 = *c_fragPool.getPtr(index2.m_fragPtrI[i]);
- frag2.m_descOff -= size;
- ndbrequire(
- frag2.m_descPage == index2.m_descPage &&
- frag2.m_descOff == index2.m_descOff);
- }
- }
- ndbrequire(off + size == DescPageSize - pagePtr.p->m_numFree);
- pagePtr.p->m_numFree += size;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
deleted file mode 100644
index 4cbd9103c94..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp
+++ /dev/null
@@ -1,590 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_NODE_CPP
-#include "Dbtux.hpp"
-
-/*
- * Allocate index node in TUP.
- */
-int
-Dbtux::allocNode(Signal* signal, NodeHandle& node)
-{
- if (ERROR_INSERTED(12007)) {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- return TuxMaintReq::NoMemError;
- }
- Frag& frag = node.m_frag;
- Uint32 pageId = NullTupLoc.getPageId();
- Uint32 pageOffset = NullTupLoc.getPageOffset();
- Uint32* node32 = 0;
- int errorCode = c_tup->tuxAllocNode(signal, frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
- jamEntry();
- if (errorCode == 0) {
- jam();
- node.m_loc = TupLoc(pageId, pageOffset);
- node.m_node = reinterpret_cast<TreeNode*>(node32);
- ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
- } else {
- switch (errorCode) {
- case 827:
- errorCode = TuxMaintReq::NoMemError;
- break;
- }
- }
- return errorCode;
-}
-
-/*
- * Set handle to point to existing node.
- */
-void
-Dbtux::selectNode(NodeHandle& node, TupLoc loc)
-{
- Frag& frag = node.m_frag;
- ndbrequire(loc != NullTupLoc);
- Uint32 pageId = loc.getPageId();
- Uint32 pageOffset = loc.getPageOffset();
- Uint32* node32 = 0;
- c_tup->tuxGetNode(frag.m_tupIndexFragPtrI, pageId, pageOffset, node32);
- jamEntry();
- node.m_loc = loc;
- node.m_node = reinterpret_cast<TreeNode*>(node32);
- ndbrequire(node.m_loc != NullTupLoc && node.m_node != 0);
-}
-
-/*
- * Set handle to point to new node. Uses a pre-allocated node.
- */
-void
-Dbtux::insertNode(NodeHandle& node)
-{
- Frag& frag = node.m_frag;
- // unlink from freelist
- selectNode(node, frag.m_freeLoc);
- frag.m_freeLoc = node.getLink(0);
- new (node.m_node) TreeNode();
-#ifdef VM_TRACE
- TreeHead& tree = frag.m_tree;
- memset(node.getPref(), DataFillByte, tree.m_prefSize << 2);
- TreeEnt* entList = tree.getEntList(node.m_node);
- memset(entList, NodeFillByte, (tree.m_maxOccup + 1) * (TreeEntSize << 2));
-#endif
-}
-
-/*
- * Delete existing node. Simply put it on the freelist.
- */
-void
-Dbtux::deleteNode(NodeHandle& node)
-{
- Frag& frag = node.m_frag;
- ndbrequire(node.getOccup() == 0);
- // link to freelist
- node.setLink(0, frag.m_freeLoc);
- frag.m_freeLoc = node.m_loc;
- // invalidate the handle
- node.m_loc = NullTupLoc;
- node.m_node = 0;
-}
-
-/*
- * Set prefix. Copies the number of words that fits. Includes
- * attribute headers for now. XXX use null mask instead
- */
-void
-Dbtux::setNodePref(NodeHandle& node)
-{
- const Frag& frag = node.m_frag;
- const TreeHead& tree = frag.m_tree;
- readKeyAttrs(frag, node.getMinMax(0), 0, c_entryKey);
- copyAttrs(frag, c_entryKey, node.getPref(), tree.m_prefSize);
-}
-
-// node operations
-
-/*
- * Add entry at position. Move entries greater than or equal to the old
- * one (if any) to the right.
- *
- * X
- * v
- * A B C D E _ _ => A B C X D E _
- * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
- *
- * Add list of scans at the new entry.
- */
-void
-Dbtux::nodePushUp(NodeHandle& node, unsigned pos, const TreeEnt& ent, Uint32 scanList)
-{
- Frag& frag = node.m_frag;
- TreeHead& tree = frag.m_tree;
- const unsigned occup = node.getOccup();
- ndbrequire(occup < tree.m_maxOccup && pos <= occup);
- // fix old scans
- if (node.getNodeScan() != RNIL)
- nodePushUpScans(node, pos);
- // fix node
- TreeEnt* const entList = tree.getEntList(node.m_node);
- entList[occup] = entList[0];
- TreeEnt* const tmpList = entList + 1;
- for (unsigned i = occup; i > pos; i--) {
- jam();
- tmpList[i] = tmpList[i - 1];
- }
- tmpList[pos] = ent;
- entList[0] = entList[occup + 1];
- node.setOccup(occup + 1);
- // add new scans
- if (scanList != RNIL)
- addScanList(node, pos, scanList);
- // fix prefix
- if (occup == 0 || pos == 0)
- setNodePref(node);
-}
-
-void
-Dbtux::nodePushUpScans(NodeHandle& node, unsigned pos)
-{
- const unsigned occup = node.getOccup();
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
- if (scanPos.m_pos >= pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "At pushUp pos=" << pos << " " << node << endl;
- }
-#endif
- scanPos.m_pos++;
- }
- scanPtr.i = scanPtr.p->m_nodeScan;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Remove and return entry at position. Move entries greater than the
- * removed one to the left. This is the opposite of nodePushUp.
- *
- * D
- * ^ ^
- * A B C D E F _ => A B C E F _ _
- * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
- *
- * Scans at removed entry are returned if non-zero location is passed or
- * else moved forward.
- */
-void
-Dbtux::nodePopDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32* scanList)
-{
- Frag& frag = node.m_frag;
- TreeHead& tree = frag.m_tree;
- const unsigned occup = node.getOccup();
- ndbrequire(occup <= tree.m_maxOccup && pos < occup);
- if (node.getNodeScan() != RNIL) {
- // remove or move scans at this position
- if (scanList == 0)
- moveScanList(node, pos);
- else
- removeScanList(node, pos, *scanList);
- // fix other scans
- if (node.getNodeScan() != RNIL)
- nodePopDownScans(node, pos);
- }
- // fix node
- TreeEnt* const entList = tree.getEntList(node.m_node);
- entList[occup] = entList[0];
- TreeEnt* const tmpList = entList + 1;
- ent = tmpList[pos];
- for (unsigned i = pos; i < occup - 1; i++) {
- jam();
- tmpList[i] = tmpList[i + 1];
- }
- entList[0] = entList[occup - 1];
- node.setOccup(occup - 1);
- // fix prefix
- if (occup != 1 && pos == 0)
- setNodePref(node);
-}
-
-void
-Dbtux::nodePopDownScans(NodeHandle& node, unsigned pos)
-{
- const unsigned occup = node.getOccup();
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
- // handled before
- ndbrequire(scanPos.m_pos != pos);
- if (scanPos.m_pos > pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "At popDown pos=" << pos << " " << node << endl;
- }
-#endif
- scanPos.m_pos--;
- }
- scanPtr.i = scanPtr.p->m_nodeScan;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Add entry at existing position. Move entries less than or equal to
- * the old one to the left. Remove and return old min entry.
- *
- * X A
- * ^ v ^
- * A B C D E _ _ => B C D X E _ _
- * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
- *
- * Return list of scans at the removed position 0.
- */
-void
-Dbtux::nodePushDown(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32& scanList)
-{
- Frag& frag = node.m_frag;
- TreeHead& tree = frag.m_tree;
- const unsigned occup = node.getOccup();
- ndbrequire(occup <= tree.m_maxOccup && pos < occup);
- if (node.getNodeScan() != RNIL) {
- // remove scans at 0
- removeScanList(node, 0, scanList);
- // fix other scans
- if (node.getNodeScan() != RNIL)
- nodePushDownScans(node, pos);
- }
- // fix node
- TreeEnt* const entList = tree.getEntList(node.m_node);
- entList[occup] = entList[0];
- TreeEnt* const tmpList = entList + 1;
- TreeEnt oldMin = tmpList[0];
- for (unsigned i = 0; i < pos; i++) {
- jam();
- tmpList[i] = tmpList[i + 1];
- }
- tmpList[pos] = ent;
- ent = oldMin;
- entList[0] = entList[occup];
- // fix prefix
- if (true)
- setNodePref(node);
-}
-
-void
-Dbtux::nodePushDownScans(NodeHandle& node, unsigned pos)
-{
- const unsigned occup = node.getOccup();
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
- // handled before
- ndbrequire(scanPos.m_pos != 0);
- if (scanPos.m_pos <= pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "At pushDown pos=" << pos << " " << node << endl;
- }
-#endif
- scanPos.m_pos--;
- }
- scanPtr.i = scanPtr.p->m_nodeScan;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Remove and return entry at position. Move entries less than the
- * removed one to the right. Replace min entry by the input entry.
- * This is the opposite of nodePushDown.
- *
- * X D
- * v ^ ^
- * A B C D E _ _ => X A B C E _ _
- * 0 1 2 3 4 5 6 0 1 2 3 4 5 6
- *
- * Move scans at removed entry and add scans at the new entry.
- */
-void
-Dbtux::nodePopUp(NodeHandle& node, unsigned pos, TreeEnt& ent, Uint32 scanList)
-{
- Frag& frag = node.m_frag;
- TreeHead& tree = frag.m_tree;
- const unsigned occup = node.getOccup();
- ndbrequire(occup <= tree.m_maxOccup && pos < occup);
- if (node.getNodeScan() != RNIL) {
- // move scans whose entry disappears
- moveScanList(node, pos);
- // fix other scans
- if (node.getNodeScan() != RNIL)
- nodePopUpScans(node, pos);
- }
- // fix node
- TreeEnt* const entList = tree.getEntList(node.m_node);
- entList[occup] = entList[0];
- TreeEnt* const tmpList = entList + 1;
- TreeEnt newMin = ent;
- ent = tmpList[pos];
- for (unsigned i = pos; i > 0; i--) {
- jam();
- tmpList[i] = tmpList[i - 1];
- }
- tmpList[0] = newMin;
- entList[0] = entList[occup];
- // add scans
- if (scanList != RNIL)
- addScanList(node, 0, scanList);
- // fix prefix
- if (true)
- setNodePref(node);
-}
-
-void
-Dbtux::nodePopUpScans(NodeHandle& node, unsigned pos)
-{
- const unsigned occup = node.getOccup();
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- ndbrequire(scanPos.m_loc == node.m_loc && scanPos.m_pos < occup);
- ndbrequire(scanPos.m_pos != pos);
- if (scanPos.m_pos < pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Fix scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "At popUp pos=" << pos << " " << node << endl;
- }
-#endif
- scanPos.m_pos++;
- }
- scanPtr.i = scanPtr.p->m_nodeScan;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Move number of entries from another node to this node before the min
- * (i=0) or after the max (i=1). Expensive but not often used.
- */
-void
-Dbtux::nodeSlide(NodeHandle& dstNode, NodeHandle& srcNode, unsigned cnt, unsigned i)
-{
- ndbrequire(i <= 1);
- while (cnt != 0) {
- TreeEnt ent;
- Uint32 scanList = RNIL;
- nodePopDown(srcNode, i == 0 ? srcNode.getOccup() - 1 : 0, ent, &scanList);
- nodePushUp(dstNode, i == 0 ? 0 : dstNode.getOccup(), ent, scanList);
- cnt--;
- }
-}
-
-// scans linked to node
-
-
-/*
- * Add list of scans to node at given position.
- */
-void
-Dbtux::addScanList(NodeHandle& node, unsigned pos, Uint32 scanList)
-{
- ScanOpPtr scanPtr;
- scanPtr.i = scanList;
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Add scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "To pos=" << pos << " " << node << endl;
- }
-#endif
- const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
- scanPtr.p->m_nodeScan = RNIL;
- linkScan(node, scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- // set position but leave direction alone
- scanPos.m_loc = node.m_loc;
- scanPos.m_pos = pos;
- scanPtr.i = nextPtrI;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Remove list of scans from node at given position. The return
- * location must point to existing list (in fact RNIL always).
- */
-void
-Dbtux::removeScanList(NodeHandle& node, unsigned pos, Uint32& scanList)
-{
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
- TreePos& scanPos = scanPtr.p->m_scanPos;
- ndbrequire(scanPos.m_loc == node.m_loc);
- if (scanPos.m_pos == pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Remove scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "Fron pos=" << pos << " " << node << endl;
- }
-#endif
- unlinkScan(node, scanPtr);
- scanPtr.p->m_nodeScan = scanList;
- scanList = scanPtr.i;
- // unset position but leave direction alone
- scanPos.m_loc = NullTupLoc;
- scanPos.m_pos = ZNIL;
- }
- scanPtr.i = nextPtrI;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Move list of scans away from entry about to be removed. Uses scan
- * method scanNext().
- */
-void
-Dbtux::moveScanList(NodeHandle& node, unsigned pos)
-{
- ScanOpPtr scanPtr;
- scanPtr.i = node.getNodeScan();
- do {
- jam();
- c_scanOpPool.getPtr(scanPtr);
- TreePos& scanPos = scanPtr.p->m_scanPos;
- const Uint32 nextPtrI = scanPtr.p->m_nodeScan;
- ndbrequire(scanPos.m_loc == node.m_loc);
- if (scanPos.m_pos == pos) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Move scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "At pos=" << pos << " " << node << endl;
- }
-#endif
- scanNext(scanPtr, true);
- ndbrequire(! (scanPos.m_loc == node.m_loc && scanPos.m_pos == pos));
- }
- scanPtr.i = nextPtrI;
- } while (scanPtr.i != RNIL);
-}
-
-/*
- * Link scan to the list under the node. The list is single-linked and
- * ordering does not matter.
- */
-void
-Dbtux::linkScan(NodeHandle& node, ScanOpPtr scanPtr)
-{
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Link scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "To node " << node << endl;
- }
-#endif
- ndbrequire(! islinkScan(node, scanPtr) && scanPtr.p->m_nodeScan == RNIL);
- scanPtr.p->m_nodeScan = node.getNodeScan();
- node.setNodeScan(scanPtr.i);
-}
-
-/*
- * Unlink a scan from the list under the node.
- */
-void
-Dbtux::unlinkScan(NodeHandle& node, ScanOpPtr scanPtr)
-{
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Unlink scan " << scanPtr.i << " " << *scanPtr.p << endl;
- debugOut << "From node " << node << endl;
- }
-#endif
- ScanOpPtr currPtr;
- currPtr.i = node.getNodeScan();
- ScanOpPtr prevPtr;
- prevPtr.i = RNIL;
- while (true) {
- jam();
- c_scanOpPool.getPtr(currPtr);
- Uint32 nextPtrI = currPtr.p->m_nodeScan;
- if (currPtr.i == scanPtr.i) {
- jam();
- if (prevPtr.i == RNIL) {
- node.setNodeScan(nextPtrI);
- } else {
- jam();
- prevPtr.p->m_nodeScan = nextPtrI;
- }
- scanPtr.p->m_nodeScan = RNIL;
- // check for duplicates
- ndbrequire(! islinkScan(node, scanPtr));
- return;
- }
- prevPtr = currPtr;
- currPtr.i = nextPtrI;
- }
-}
-
-/*
- * Check if a scan is linked to this node. Only for ndbrequire.
- */
-bool
-Dbtux::islinkScan(NodeHandle& node, ScanOpPtr scanPtr)
-{
- ScanOpPtr currPtr;
- currPtr.i = node.getNodeScan();
- while (currPtr.i != RNIL) {
- jam();
- c_scanOpPool.getPtr(currPtr);
- if (currPtr.i == scanPtr.i) {
- jam();
- return true;
- }
- currPtr.i = currPtr.p->m_nodeScan;
- }
- return false;
-}
-
-void
-Dbtux::NodeHandle::progError(int line, int cause, const char* file)
-{
- ErrorReporter::handleAssert("Dbtux::NodeHandle: assert failed", file, line);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
deleted file mode 100644
index 0b910eff341..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
+++ /dev/null
@@ -1,1123 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_SCAN_CPP
-#include "Dbtux.hpp"
-#include <my_sys.h>
-
-void
-Dbtux::execACC_SCANREQ(Signal* signal)
-{
- jamEntry();
- const AccScanReq reqCopy = *(const AccScanReq*)signal->getDataPtr();
- const AccScanReq* const req = &reqCopy;
- ScanOpPtr scanPtr;
- scanPtr.i = RNIL;
- do {
- // get the index
- IndexPtr indexPtr;
- c_indexPool.getPtr(indexPtr, req->tableId);
- // get the fragment
- FragPtr fragPtr;
- fragPtr.i = RNIL;
- for (unsigned i = 0; i < indexPtr.p->m_numFrags; i++) {
- jam();
- if (indexPtr.p->m_fragId[i] == req->fragmentNo) {
- jam();
- c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
- break;
- }
- }
- ndbrequire(fragPtr.i != RNIL);
- Frag& frag = *fragPtr.p;
- // must be normal DIH/TC fragment
- TreeHead& tree = frag.m_tree;
- // check for empty fragment
- if (tree.m_root == NullTupLoc) {
- jam();
- AccScanConf* const conf = (AccScanConf*)signal->getDataPtrSend();
- conf->scanPtr = req->senderData;
- conf->accPtr = RNIL;
- conf->flag = AccScanConf::ZEMPTY_FRAGMENT;
- sendSignal(req->senderRef, GSN_ACC_SCANCONF,
- signal, AccScanConf::SignalLength, JBB);
- return;
- }
- // seize from pool and link to per-fragment list
- if (! frag.m_scanList.seize(scanPtr)) {
- jam();
- break;
- }
- new (scanPtr.p) ScanOp(c_scanBoundPool);
- scanPtr.p->m_state = ScanOp::First;
- scanPtr.p->m_userPtr = req->senderData;
- scanPtr.p->m_userRef = req->senderRef;
- scanPtr.p->m_tableId = indexPtr.p->m_tableId;
- scanPtr.p->m_indexId = indexPtr.i;
- scanPtr.p->m_fragId = fragPtr.p->m_fragId;
- scanPtr.p->m_fragPtrI = fragPtr.i;
- scanPtr.p->m_transId1 = req->transId1;
- scanPtr.p->m_transId2 = req->transId2;
- scanPtr.p->m_savePointId = req->savePointId;
- scanPtr.p->m_readCommitted = AccScanReq::getReadCommittedFlag(req->requestInfo);
- scanPtr.p->m_lockMode = AccScanReq::getLockMode(req->requestInfo);
- scanPtr.p->m_descending = AccScanReq::getDescendingFlag(req->requestInfo);
- /*
- * readCommitted lockMode keyInfo
- * 1 0 0 - read committed (no lock)
- * 0 0 0 - read latest (read lock)
- * 0 1 1 - read exclusive (write lock)
- */
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Seize scan " << scanPtr.i << " " << *scanPtr.p << endl;
- }
-#endif
- // conf
- AccScanConf* const conf = (AccScanConf*)signal->getDataPtrSend();
- conf->scanPtr = req->senderData;
- conf->accPtr = scanPtr.i;
- conf->flag = AccScanConf::ZNOT_EMPTY_FRAGMENT;
- sendSignal(req->senderRef, GSN_ACC_SCANCONF,
- signal, AccScanConf::SignalLength, JBB);
- return;
- } while (0);
- if (scanPtr.i != RNIL) {
- jam();
- releaseScanOp(scanPtr);
- }
- // LQH does not handle REF
- signal->theData[0] = 0x313;
- sendSignal(req->senderRef, GSN_ACC_SCANREF,
- signal, 1, JBB);
-}
-
-/*
- * Receive bounds for scan in single direct call. The bounds can arrive
- * in any order. Attribute ids are those of index table.
- *
- * Replace EQ by equivalent LE + GE. Check for conflicting bounds.
- * Check that sets of lower and upper bounds are on initial sequences of
- * keys and that all but possibly last bound is non-strict.
- *
- * Finally save the sets of lower and upper bounds (i.e. start key and
- * end key). Full bound type is included but only the strict bit is
- * used since lower and upper have now been separated.
- */
-void
-Dbtux::execTUX_BOUND_INFO(Signal* signal)
-{
- jamEntry();
- // get records
- TuxBoundInfo* const sig = (TuxBoundInfo*)signal->getDataPtrSend();
- const TuxBoundInfo* const req = (const TuxBoundInfo*)sig;
- ScanOp& scan = *c_scanOpPool.getPtr(req->tuxScanPtrI);
- const Index& index = *c_indexPool.getPtr(scan.m_indexId);
- const DescEnt& descEnt = getDescEnt(index.m_descPage, index.m_descOff);
- // collect normalized lower and upper bounds
- struct BoundInfo {
- int type2; // with EQ -> LE/GE
- Uint32 offset; // offset in xfrmData
- Uint32 size;
- };
- BoundInfo boundInfo[2][MaxIndexAttributes];
- const unsigned dstSize = 1024 * MAX_XFRM_MULTIPLY;
- Uint32 xfrmData[dstSize];
- Uint32 dstPos = 0;
- // largest attrId seen plus one
- Uint32 maxAttrId[2] = { 0, 0 };
- // walk through entries
- const Uint32* const data = (Uint32*)sig + TuxBoundInfo::SignalLength;
- Uint32 offset = 0;
- while (offset + 2 <= req->boundAiLength) {
- jam();
- const unsigned type = data[offset];
- const AttributeHeader* ah = (const AttributeHeader*)&data[offset + 1];
- const Uint32 attrId = ah->getAttributeId();
- const Uint32 dataSize = ah->getDataSize();
- if (type > 4 || attrId >= index.m_numAttrs || dstPos + 2 + dataSize > dstSize) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidAttrInfo;
- return;
- }
- // copy header
- xfrmData[dstPos + 0] = data[offset + 0];
- xfrmData[dstPos + 1] = data[offset + 1];
- // copy bound value
- Uint32 dstWords = 0;
- if (! ah->isNULL()) {
- jam();
- const uchar* srcPtr = (const uchar*)&data[offset + 2];
- const DescAttr& descAttr = descEnt.m_descAttr[attrId];
- Uint32 typeId = descAttr.m_typeId;
- Uint32 maxBytes = AttributeDescriptor::getSizeInBytes(descAttr.m_attrDesc);
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, maxBytes, lb, len);
- if (! ok) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidCharFormat;
- return;
- }
- Uint32 srcBytes = lb + len;
- Uint32 srcWords = (srcBytes + 3) / 4;
- if (srcWords != dataSize) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidAttrInfo;
- return;
- }
- uchar* dstPtr = (uchar*)&xfrmData[dstPos + 2];
- if (descAttr.m_charset == 0) {
- memcpy(dstPtr, srcPtr, srcWords << 2);
- dstWords = srcWords;
- } else {
- jam();
- CHARSET_INFO* cs = all_charsets[descAttr.m_charset];
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- // see comment in DbtcMain.cpp
- Uint32 dstLen = xmul * (maxBytes - lb);
- if (dstLen > ((dstSize - dstPos) << 2)) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::TooMuchAttrInfo;
- return;
- }
- int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
- ndbrequire(n != -1);
- while ((n & 3) != 0) {
- dstPtr[n++] = 0;
- }
- dstWords = n / 4;
- }
- }
- for (unsigned j = 0; j <= 1; j++) {
- jam();
- // check if lower/upper bit matches
- const unsigned luBit = (j << 1);
- if ((type & 0x2) != luBit && type != 4)
- continue;
- // EQ -> LE, GE
- const unsigned type2 = (type & 0x1) | luBit;
- // fill in any gap
- while (maxAttrId[j] <= attrId) {
- jam();
- BoundInfo& b = boundInfo[j][maxAttrId[j]];
- maxAttrId[j]++;
- b.type2 = -1;
- }
- BoundInfo& b = boundInfo[j][attrId];
- if (b.type2 != -1) {
- // compare with previously defined bound
- if (b.type2 != (int)type2 ||
- b.size != 2 + dstWords ||
- memcmp(&xfrmData[b.offset + 2], &xfrmData[dstPos + 2], dstWords << 2) != 0) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidBounds;
- return;
- }
- } else {
- // fix length
- AttributeHeader* ah = (AttributeHeader*)&xfrmData[dstPos + 1];
- ah->setDataSize(dstWords);
- // enter new bound
- jam();
- b.type2 = type2;
- b.offset = dstPos;
- b.size = 2 + dstWords;
- }
- }
- // jump to next
- offset += 2 + dataSize;
- dstPos += 2 + dstWords;
- }
- if (offset != req->boundAiLength) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidAttrInfo;
- return;
- }
- for (unsigned j = 0; j <= 1; j++) {
- // save lower/upper bound in index attribute id order
- for (unsigned i = 0; i < maxAttrId[j]; i++) {
- jam();
- const BoundInfo& b = boundInfo[j][i];
- // check for gap or strict bound before last
- if (b.type2 == -1 || (i + 1 < maxAttrId[j] && (b.type2 & 0x1))) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::InvalidBounds;
- return;
- }
- bool ok = scan.m_bound[j]->append(&xfrmData[b.offset], b.size);
- if (! ok) {
- jam();
- scan.m_state = ScanOp::Invalid;
- sig->errorCode = TuxBoundInfo::OutOfBuffers;
- return;
- }
- }
- scan.m_boundCnt[j] = maxAttrId[j];
- }
- // no error
- sig->errorCode = 0;
-}
-
-void
-Dbtux::execNEXT_SCANREQ(Signal* signal)
-{
- jamEntry();
- const NextScanReq reqCopy = *(const NextScanReq*)signal->getDataPtr();
- const NextScanReq* const req = &reqCopy;
- ScanOpPtr scanPtr;
- scanPtr.i = req->accPtr;
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "NEXT_SCANREQ scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- // handle unlock previous and close scan
- switch (req->scanFlag) {
- case NextScanReq::ZSCAN_NEXT:
- jam();
- break;
- case NextScanReq::ZSCAN_NEXT_COMMIT:
- jam();
- case NextScanReq::ZSCAN_COMMIT:
- jam();
- if (! scan.m_readCommitted) {
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Unlock;
- lockReq->accOpPtr = req->accOperationPtr;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- removeAccLockOp(scanPtr, req->accOperationPtr);
- }
- if (req->scanFlag == NextScanReq::ZSCAN_COMMIT) {
- jam();
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- unsigned signalLength = 1;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return;
- }
- break;
- case NextScanReq::ZSCAN_CLOSE:
- jam();
- // unlink from tree node first to avoid state changes
- if (scan.m_scanPos.m_loc != NullTupLoc) {
- jam();
- const TupLoc loc = scan.m_scanPos.m_loc;
- NodeHandle node(frag);
- selectNode(node, loc);
- unlinkScan(node, scanPtr);
- scan.m_scanPos.m_loc = NullTupLoc;
- }
- if (scan.m_lockwait) {
- jam();
- ndbrequire(scan.m_accLockOp != RNIL);
- // use ACC_ABORTCONF to flush out any reply in job buffer
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::AbortWithConf;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal,
- AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_state = ScanOp::Aborting;
- return;
- }
- if (scan.m_state == ScanOp::Locked) {
- jam();
- ndbrequire(scan.m_accLockOp != RNIL);
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal,
- AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- }
- scan.m_state = ScanOp::Aborting;
- scanClose(signal, scanPtr);
- return;
- case NextScanReq::ZSCAN_NEXT_ABORT:
- jam();
- default:
- jam();
- ndbrequire(false);
- break;
- }
- // start looking for next scan result
- AccCheckScan* checkReq = (AccCheckScan*)signal->getDataPtrSend();
- checkReq->accPtr = scanPtr.i;
- checkReq->checkLcpStop = AccCheckScan::ZNOT_CHECK_LCP_STOP;
- EXECUTE_DIRECT(DBTUX, GSN_ACC_CHECK_SCAN, signal, AccCheckScan::SignalLength);
- jamEntry();
-}
-
-void
-Dbtux::execACC_CHECK_SCAN(Signal* signal)
-{
- jamEntry();
- const AccCheckScan reqCopy = *(const AccCheckScan*)signal->getDataPtr();
- const AccCheckScan* const req = &reqCopy;
- ScanOpPtr scanPtr;
- scanPtr.i = req->accPtr;
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "ACC_CHECK_SCAN scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- if (req->checkLcpStop == AccCheckScan::ZCHECK_LCP_STOP) {
- jam();
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return; // stop
- }
- if (scan.m_lockwait) {
- jam();
- // LQH asks if we are waiting for lock and we tell it to ask again
- const TreeEnt ent = scan.m_scanEnt;
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = RNIL; // no tuple returned
- conf->fragId = frag.m_fragId;
- unsigned signalLength = 3;
- // if TC has ordered scan close, it will be detected here
- sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return; // stop
- }
- if (scan.m_state == ScanOp::First) {
- jam();
- // search is done only once in single range scan
- scanFirst(scanPtr);
- }
- if (scan.m_state == ScanOp::Current ||
- scan.m_state == ScanOp::Next) {
- jam();
- // look for next
- scanFind(scanPtr);
- }
- // for reading tuple key in Found or Locked state
- Data pkData = c_dataBuffer;
- unsigned pkSize = 0; // indicates not yet done
- if (scan.m_state == ScanOp::Found) {
- // found an entry to return
- jam();
- ndbrequire(scan.m_accLockOp == RNIL);
- if (! scan.m_readCommitted) {
- jam();
- const TreeEnt ent = scan.m_scanEnt;
- // read tuple key
- readTablePk(frag, ent, pkData, pkSize);
- // get read lock or exclusive lock
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo =
- scan.m_lockMode == 0 ? AccLockReq::LockShared : AccLockReq::LockExclusive;
- lockReq->accOpPtr = RNIL;
- lockReq->userPtr = scanPtr.i;
- lockReq->userRef = reference();
- lockReq->tableId = scan.m_tableId;
- lockReq->fragId = frag.m_fragId;
- lockReq->fragPtrI = frag.m_accTableFragPtrI;
- const Uint32* const buf32 = static_cast<Uint32*>(pkData);
- const Uint64* const buf64 = reinterpret_cast<const Uint64*>(buf32);
- lockReq->hashValue = md5_hash(buf64, pkSize);
- lockReq->tupAddr = getTupAddr(frag, ent);
- lockReq->transId1 = scan.m_transId1;
- lockReq->transId2 = scan.m_transId2;
- // execute
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::LockSignalLength);
- jamEntry();
- switch (lockReq->returnCode) {
- case AccLockReq::Success:
- jam();
- scan.m_state = ScanOp::Locked;
- scan.m_accLockOp = lockReq->accOpPtr;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Lock immediate scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- break;
- case AccLockReq::IsBlocked:
- jam();
- // normal lock wait
- scan.m_state = ScanOp::Blocked;
- scan.m_lockwait = true;
- scan.m_accLockOp = lockReq->accOpPtr;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Lock wait scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- // LQH will wake us up
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return; // stop
- break;
- case AccLockReq::Refused:
- jam();
- // we cannot see deleted tuple (assert only)
- ndbassert(false);
- // skip it
- scan.m_state = ScanOp::Next;
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return; // stop
- break;
- case AccLockReq::NoFreeOp:
- jam();
- // max ops should depend on max scans (assert only)
- ndbassert(false);
- // stay in Found state
- scan.m_state = ScanOp::Found;
- signal->theData[0] = scan.m_userPtr;
- signal->theData[1] = true;
- EXECUTE_DIRECT(DBLQH, GSN_CHECK_LCP_STOP, signal, 2);
- jamEntry();
- return; // stop
- break;
- default:
- ndbrequire(false);
- break;
- }
- } else {
- scan.m_state = ScanOp::Locked;
- }
- }
- if (scan.m_state == ScanOp::Locked) {
- // we have lock or do not need one
- jam();
- // read keys if not already done (uses signal)
- const TreeEnt ent = scan.m_scanEnt;
- // conf signal
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- // the lock is passed to LQH
- Uint32 accLockOp = scan.m_accLockOp;
- if (accLockOp != RNIL) {
- scan.m_accLockOp = RNIL;
- // remember it until LQH unlocks it
- addAccLockOp(scanPtr, accLockOp);
- } else {
- ndbrequire(scan.m_readCommitted);
- // operation RNIL in LQH would signal no tuple returned
- accLockOp = (Uint32)-1;
- }
- conf->accOperationPtr = accLockOp;
- conf->fragId = frag.m_fragId;
- conf->localKey[0] = getTupAddr(frag, ent);
- conf->localKey[1] = 0;
- conf->localKeyLength = 1;
- unsigned signalLength = 6;
- // add key info
- if (! scan.m_readCommitted) {
- sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- } else {
- Uint32 blockNo = refToBlock(scan.m_userRef);
- EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, signalLength);
- }
- // next time look for next entry
- scan.m_state = ScanOp::Next;
- return;
- }
- // XXX in ACC this is checked before req->checkLcpStop
- if (scan.m_state == ScanOp::Last ||
- scan.m_state == ScanOp::Invalid) {
- jam();
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scan.m_userPtr;
- conf->accOperationPtr = RNIL;
- conf->fragId = RNIL;
- unsigned signalLength = 3;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- return;
- }
- ndbrequire(false);
-}
-
-/*
- * Lock succeeded (after delay) in ACC. If the lock is for current
- * entry, set state to Locked. If the lock is for an entry we were
- * moved away from, simply unlock it. Finally, if we are closing the
- * scan, do nothing since we have already sent an abort request.
- */
-void
-Dbtux::execACCKEYCONF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Lock obtained scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- ndbrequire(scan.m_lockwait && scan.m_accLockOp != RNIL);
- scan.m_lockwait = false;
- if (scan.m_state == ScanOp::Blocked) {
- // the lock wait was for current entry
- jam();
- scan.m_state = ScanOp::Locked;
- // LQH has the ball
- return;
- }
- if (scan.m_state != ScanOp::Aborting) {
- // we were moved, release lock
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- // LQH has the ball
- return;
- }
- // lose the lock
- scan.m_accLockOp = RNIL;
- // continue at ACC_ABORTCONF
-}
-
-/*
- * Lock failed (after delay) in ACC. Probably means somebody ahead of
- * us in lock queue deleted the tuple.
- */
-void
-Dbtux::execACCKEYREF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Lock refused scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- ndbrequire(scan.m_lockwait && scan.m_accLockOp != RNIL);
- scan.m_lockwait = false;
- if (scan.m_state != ScanOp::Aborting) {
- jam();
- // release the operation
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = scan.m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- scan.m_accLockOp = RNIL;
- // scan position should already have been moved (assert only)
- if (scan.m_state == ScanOp::Blocked) {
- jam();
- ndbassert(false);
- scan.m_state = ScanOp::Next;
- }
- // LQH has the ball
- return;
- }
- // lose the lock
- scan.m_accLockOp = RNIL;
- // continue at ACC_ABORTCONF
-}
-
-/*
- * Received when scan is closing. This signal arrives after any
- * ACCKEYCON or ACCKEYREF which may have been in job buffer.
- */
-void
-Dbtux::execACC_ABORTCONF(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "ACC_ABORTCONF scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- ndbrequire(scan.m_state == ScanOp::Aborting);
- // most likely we are still in lock wait
- if (scan.m_lockwait) {
- jam();
- scan.m_lockwait = false;
- scan.m_accLockOp = RNIL;
- }
- scanClose(signal, scanPtr);
-}
-
-/*
- * Find start position for single range scan.
- */
-void
-Dbtux::scanFirst(ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Enter first scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- // set up index keys for this operation
- setKeyAttrs(frag);
- // scan direction 0, 1
- const unsigned idir = scan.m_descending;
- unpackBound(*scan.m_bound[idir], c_dataBuffer);
- TreePos treePos;
- searchToScan(frag, c_dataBuffer, scan.m_boundCnt[idir], scan.m_descending, treePos);
- if (treePos.m_loc != NullTupLoc) {
- scan.m_scanPos = treePos;
- // link the scan to node found
- NodeHandle node(frag);
- selectNode(node, treePos.m_loc);
- linkScan(node, scanPtr);
- if (treePos.m_dir == 3) {
- jam();
- // check upper bound
- TreeEnt ent = node.getEnt(treePos.m_pos);
- if (scanCheck(scanPtr, ent))
- scan.m_state = ScanOp::Current;
- else
- scan.m_state = ScanOp::Last;
- } else {
- scan.m_state = ScanOp::Next;
- }
- } else {
- jam();
- scan.m_state = ScanOp::Last;
- }
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Leave first scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
-}
-
-/*
- * Look for entry to return as scan result.
- */
-void
-Dbtux::scanFind(ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Enter find scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- ndbrequire(scan.m_state == ScanOp::Current || scan.m_state == ScanOp::Next);
- while (1) {
- jam();
- if (scan.m_state == ScanOp::Next)
- scanNext(scanPtr, false);
- if (scan.m_state == ScanOp::Current) {
- jam();
- const TreePos pos = scan.m_scanPos;
- NodeHandle node(frag);
- selectNode(node, pos.m_loc);
- const TreeEnt ent = node.getEnt(pos.m_pos);
- if (scanVisible(scanPtr, ent)) {
- jam();
- scan.m_state = ScanOp::Found;
- scan.m_scanEnt = ent;
- break;
- }
- } else {
- jam();
- break;
- }
- scan.m_state = ScanOp::Next;
- }
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Leave find scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
-}
-
-/*
- * Move to next entry. The scan is already linked to some node. When
- * we leave, if an entry was found, it will be linked to a possibly
- * different node. The scan has a position, and a direction which tells
- * from where we came to this position. This is one of (all comments
- * are in terms of ascending scan):
- *
- * 0 - up from left child (scan this node next)
- * 1 - up from right child (proceed to parent)
- * 2 - up from root (the scan ends)
- * 3 - left to right within node (at end proceed to right child)
- * 4 - down from parent (proceed to left child)
- *
- * If an entry was found, scan direction is 3. Therefore tree
- * re-organizations need not worry about scan direction.
- *
- * This method is also used to move a scan when its entry is removed
- * (see moveScanList). If the scan is Blocked, we check if it remains
- * Blocked on a different version of the tuple. Otherwise the tuple is
- * lost and state becomes Current.
- */
-void
-Dbtux::scanNext(ScanOpPtr scanPtr, bool fromMaintReq)
-{
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
-#ifdef VM_TRACE
- if (debugFlags & (DebugMaint | DebugScan)) {
- debugOut << "Enter next scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- // cannot be moved away from tuple we have locked
- ndbrequire(scan.m_state != ScanOp::Locked);
- // set up index keys for this operation
- setKeyAttrs(frag);
- // scan direction
- const unsigned idir = scan.m_descending; // 0, 1
- const int jdir = 1 - 2 * (int)idir; // 1, -1
- // use copy of position
- TreePos pos = scan.m_scanPos;
- // get and remember original node
- NodeHandle origNode(frag);
- selectNode(origNode, pos.m_loc);
- ndbrequire(islinkScan(origNode, scanPtr));
- // current node in loop
- NodeHandle node = origNode;
- // copy of entry found
- TreeEnt ent;
- while (true) {
- jam();
-#ifdef VM_TRACE
- if (debugFlags & (DebugMaint | DebugScan)) {
- debugOut << "Current scan " << scanPtr.i << " pos " << pos << " node " << node << endl;
- }
-#endif
- if (pos.m_dir == 2) {
- // coming up from root ends the scan
- jam();
- pos.m_loc = NullTupLoc;
- break;
- }
- if (node.m_loc != pos.m_loc) {
- jam();
- selectNode(node, pos.m_loc);
- }
- if (pos.m_dir == 4) {
- // coming down from parent proceed to left child
- jam();
- TupLoc loc = node.getLink(idir);
- if (loc != NullTupLoc) {
- jam();
- pos.m_loc = loc;
- pos.m_dir = 4; // unchanged
- continue;
- }
- // pretend we came from left child
- pos.m_dir = idir;
- }
- const unsigned occup = node.getOccup();
- if (occup == 0) {
- jam();
- ndbrequire(fromMaintReq);
- // move back to parent - see comment in treeRemoveInner
- pos.m_loc = node.getLink(2);
- pos.m_dir = node.getSide();
- continue;
- }
- if (pos.m_dir == idir) {
- // coming up from left child scan current node
- jam();
- pos.m_pos = idir == 0 ? (Uint16)-1 : occup;
- pos.m_dir = 3;
- }
- if (pos.m_dir == 3) {
- // before or within node
- jam();
- // advance position - becomes ZNIL (> occup) if 0 and descending
- pos.m_pos += jdir;
- if (pos.m_pos < occup) {
- jam();
- pos.m_dir = 3; // unchanged
- ent = node.getEnt(pos.m_pos);
- if (! scanCheck(scanPtr, ent)) {
- jam();
- pos.m_loc = NullTupLoc;
- }
- break;
- }
- // after node proceed to right child
- TupLoc loc = node.getLink(1 - idir);
- if (loc != NullTupLoc) {
- jam();
- pos.m_loc = loc;
- pos.m_dir = 4;
- continue;
- }
- // pretend we came from right child
- pos.m_dir = 1 - idir;
- }
- if (pos.m_dir == 1 - idir) {
- // coming up from right child proceed to parent
- jam();
- pos.m_loc = node.getLink(2);
- pos.m_dir = node.getSide();
- continue;
- }
- ndbrequire(false);
- }
- // copy back position
- scan.m_scanPos = pos;
- // relink
- if (pos.m_loc != NullTupLoc) {
- ndbrequire(pos.m_dir == 3);
- ndbrequire(pos.m_loc == node.m_loc);
- if (origNode.m_loc != node.m_loc) {
- jam();
- unlinkScan(origNode, scanPtr);
- linkScan(node, scanPtr);
- }
- if (scan.m_state != ScanOp::Blocked) {
- scan.m_state = ScanOp::Current;
- } else {
- jam();
- ndbrequire(fromMaintReq);
- TreeEnt& scanEnt = scan.m_scanEnt;
- ndbrequire(scanEnt.m_tupLoc != NullTupLoc);
- if (scanEnt.eqtuple(ent)) {
- // remains blocked on another version
- scanEnt = ent;
- } else {
- jam();
- scanEnt.m_tupLoc = NullTupLoc;
- scan.m_state = ScanOp::Current;
- }
- }
- } else {
- jam();
- unlinkScan(origNode, scanPtr);
- scan.m_state = ScanOp::Last;
- }
-#ifdef VM_TRACE
- if (debugFlags & (DebugMaint | DebugScan)) {
- debugOut << "Leave next scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
-}
-
-/*
- * Check end key. Return true if scan is still within range.
- */
-bool
-Dbtux::scanCheck(ScanOpPtr scanPtr, TreeEnt ent)
-{
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
- const unsigned idir = scan.m_descending;
- const int jdir = 1 - 2 * (int)idir;
- unpackBound(*scan.m_bound[1 - idir], c_dataBuffer);
- unsigned boundCnt = scan.m_boundCnt[1 - idir];
- readKeyAttrs(frag, ent, 0, c_entryKey);
- int ret = cmpScanBound(frag, 1 - idir, c_dataBuffer, boundCnt, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- if (jdir * ret > 0)
- return true;
- // hit upper bound of single range scan
- return false;
-}
-
-/*
- * Check if an entry is visible to the scan.
- *
- * There is a special check to never accept same tuple twice in a row.
- * This is faster than asking TUP. It also fixes some special cases
- * which are not analyzed or handled yet.
- */
-bool
-Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
-{
- const ScanOp& scan = *scanPtr.p;
- const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
- Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
- Uint32 pageId = ent.m_tupLoc.getPageId();
- Uint32 pageOffset = ent.m_tupLoc.getPageOffset();
- Uint32 tupVersion = ent.m_tupVersion;
- // check for same tuple twice in row
- if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc)
- {
- jam();
- return false;
- }
- Uint32 transId1 = scan.m_transId1;
- Uint32 transId2 = scan.m_transId2;
- bool dirty = scan.m_readCommitted;
- Uint32 savePointId = scan.m_savePointId;
- bool ret = c_tup->tuxQueryTh(tableFragPtrI, pageId, pageOffset, tupVersion, transId1, transId2, dirty, savePointId);
- jamEntry();
- return ret;
-}
-
-/*
- * Finish closing of scan and send conf. Any lock wait has been done
- * already.
- */
-void
-Dbtux::scanClose(Signal* signal, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
- ndbrequire(! scan.m_lockwait && scan.m_accLockOp == RNIL);
- // unlock all not unlocked by LQH
- if (! scan.m_accLockOps.isEmpty()) {
- jam();
- abortAccLockOps(signal, scanPtr);
- }
- // send conf
- NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
- conf->scanPtr = scanPtr.p->m_userPtr;
- conf->accOperationPtr = RNIL;
- conf->fragId = RNIL;
- unsigned signalLength = 3;
- sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
- signal, signalLength, JBB);
- releaseScanOp(scanPtr);
-}
-
-void
-Dbtux::abortAccLockOps(Signal* signal, ScanOpPtr scanPtr)
-{
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Abort locks in scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
- while (list.first(lockPtr)) {
- jam();
- AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend();
- lockReq->returnCode = RNIL;
- lockReq->requestInfo = AccLockReq::Abort;
- lockReq->accOpPtr = lockPtr.p->m_accLockOp;
- EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
- jamEntry();
- ndbrequire(lockReq->returnCode == AccLockReq::Success);
- list.release(lockPtr);
- }
-}
-
-void
-Dbtux::addAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp)
-{
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Add lock " << hex << accLockOp << dec
- << " to scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
-#ifdef VM_TRACE
- list.first(lockPtr);
- while (lockPtr.i != RNIL) {
- ndbrequire(lockPtr.p->m_accLockOp != accLockOp);
- list.next(lockPtr);
- }
-#endif
- bool ok = list.seize(lockPtr);
- ndbrequire(ok);
- ndbrequire(accLockOp != RNIL);
- lockPtr.p->m_accLockOp = accLockOp;
-}
-
-void
-Dbtux::removeAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp)
-{
- ScanOp& scan = *scanPtr.p;
-#ifdef VM_TRACE
- if (debugFlags & (DebugScan | DebugLock)) {
- debugOut << "Remove lock " << hex << accLockOp << dec
- << " from scan " << scanPtr.i << " " << scan << endl;
- }
-#endif
- LocalDLFifoList<ScanLock> list(c_scanLockPool, scan.m_accLockOps);
- ScanLockPtr lockPtr;
- list.first(lockPtr);
- while (lockPtr.i != RNIL) {
- if (lockPtr.p->m_accLockOp == accLockOp) {
- jam();
- break;
- }
- list.next(lockPtr);
- }
- ndbrequire(lockPtr.i != RNIL);
- list.release(lockPtr);
-}
-
-/*
- * Release allocated records.
- */
-void
-Dbtux::releaseScanOp(ScanOpPtr& scanPtr)
-{
-#ifdef VM_TRACE
- if (debugFlags & DebugScan) {
- debugOut << "Release scan " << scanPtr.i << " " << *scanPtr.p << endl;
- }
-#endif
- Frag& frag = *c_fragPool.getPtr(scanPtr.p->m_fragPtrI);
- scanPtr.p->m_boundMin.release();
- scanPtr.p->m_boundMax.release();
- // unlink from per-fragment list and release from pool
- frag.m_scanList.release(scanPtr);
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp
deleted file mode 100644
index 9e84f61ab70..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp
+++ /dev/null
@@ -1,432 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_SEARCH_CPP
-#include "Dbtux.hpp"
-
-/*
- * Search for entry to add.
- *
- * Similar to searchToRemove (see below).
- */
-bool
-Dbtux::searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos)
-{
- const TreeHead& tree = frag.m_tree;
- const unsigned numAttrs = frag.m_numAttrs;
- NodeHandle currNode(frag);
- currNode.m_loc = tree.m_root;
- if (currNode.m_loc == NullTupLoc) {
- // empty tree
- jam();
- return true;
- }
- NodeHandle glbNode(frag); // potential g.l.b of final node
- /*
- * In order to not (yet) change old behaviour, a position between
- * 2 nodes returns the one at the bottom of the tree.
- */
- NodeHandle bottomNode(frag);
- while (true) {
- jam();
- selectNode(currNode, currNode.m_loc);
- int ret;
- // compare prefix
- unsigned start = 0;
- ret = cmpSearchKey(frag, start, searchKey, currNode.getPref(), tree.m_prefSize);
- if (ret == NdbSqlUtil::CmpUnknown) {
- jam();
- // read and compare remaining attributes
- ndbrequire(start < numAttrs);
- readKeyAttrs(frag, currNode.getMinMax(0), start, c_entryKey);
- ret = cmpSearchKey(frag, start, searchKey, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- }
- if (ret == 0) {
- jam();
- // keys are equal, compare entry values
- ret = searchEnt.cmp(currNode.getMinMax(0));
- }
- if (ret < 0) {
- jam();
- const TupLoc loc = currNode.getLink(0);
- if (loc != NullTupLoc) {
- jam();
- // continue to left subtree
- currNode.m_loc = loc;
- continue;
- }
- if (! glbNode.isNull()) {
- jam();
- // move up to the g.l.b but remember the bottom node
- bottomNode = currNode;
- currNode = glbNode;
- }
- } else if (ret > 0) {
- jam();
- const TupLoc loc = currNode.getLink(1);
- if (loc != NullTupLoc) {
- jam();
- // save potential g.l.b
- glbNode = currNode;
- // continue to right subtree
- currNode.m_loc = loc;
- continue;
- }
- } else {
- jam();
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = 0;
- // entry found - error
- return false;
- }
- break;
- }
- // anticipate
- treePos.m_loc = currNode.m_loc;
- // binary search
- int lo = -1;
- int hi = currNode.getOccup();
- int ret;
- while (1) {
- jam();
- // hi - lo > 1 implies lo < j < hi
- int j = (hi + lo) / 2;
- // read and compare attributes
- unsigned start = 0;
- readKeyAttrs(frag, currNode.getEnt(j), start, c_entryKey);
- ret = cmpSearchKey(frag, start, searchKey, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- if (ret == 0) {
- jam();
- // keys are equal, compare entry values
- ret = searchEnt.cmp(currNode.getEnt(j));
- }
- if (ret < 0)
- hi = j;
- else if (ret > 0)
- lo = j;
- else {
- treePos.m_pos = j;
- // entry found - error
- return false;
- }
- if (hi - lo == 1)
- break;
- }
- if (ret < 0) {
- jam();
- treePos.m_pos = hi;
- return true;
- }
- if ((uint) hi < currNode.getOccup()) {
- jam();
- treePos.m_pos = hi;
- return true;
- }
- if (bottomNode.isNull()) {
- jam();
- treePos.m_pos = hi;
- return true;
- }
- jam();
- // backwards compatible for now
- treePos.m_loc = bottomNode.m_loc;
- treePos.m_pos = 0;
- return true;
-}
-
-/*
- * Search for entry to remove.
- *
- * Compares search key to each node min. A move to right subtree can
- * overshoot target node. The last such node is saved. The final node
- * is a semi-leaf or leaf. If search key is less than final node min
- * then the saved node is the g.l.b of the final node and we move back
- * to it.
- */
-bool
-Dbtux::searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos)
-{
- const TreeHead& tree = frag.m_tree;
- const unsigned numAttrs = frag.m_numAttrs;
- NodeHandle currNode(frag);
- currNode.m_loc = tree.m_root;
- if (currNode.m_loc == NullTupLoc) {
- // empty tree - failed
- jam();
- return false;
- }
- NodeHandle glbNode(frag); // potential g.l.b of final node
- while (true) {
- jam();
- selectNode(currNode, currNode.m_loc);
- int ret;
- // compare prefix
- unsigned start = 0;
- ret = cmpSearchKey(frag, start, searchKey, currNode.getPref(), tree.m_prefSize);
- if (ret == NdbSqlUtil::CmpUnknown) {
- jam();
- // read and compare remaining attributes
- ndbrequire(start < numAttrs);
- readKeyAttrs(frag, currNode.getMinMax(0), start, c_entryKey);
- ret = cmpSearchKey(frag, start, searchKey, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- }
- if (ret == 0) {
- jam();
- // keys are equal, compare entry values
- ret = searchEnt.cmp(currNode.getMinMax(0));
- }
- if (ret < 0) {
- jam();
- const TupLoc loc = currNode.getLink(0);
- if (loc != NullTupLoc) {
- jam();
- // continue to left subtree
- currNode.m_loc = loc;
- continue;
- }
- if (! glbNode.isNull()) {
- jam();
- // move up to the g.l.b
- currNode = glbNode;
- }
- } else if (ret > 0) {
- jam();
- const TupLoc loc = currNode.getLink(1);
- if (loc != NullTupLoc) {
- jam();
- // save potential g.l.b
- glbNode = currNode;
- // continue to right subtree
- currNode.m_loc = loc;
- continue;
- }
- } else {
- jam();
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = 0;
- return true;
- }
- break;
- }
- // anticipate
- treePos.m_loc = currNode.m_loc;
- // pos 0 was handled above
- for (unsigned j = 1, occup = currNode.getOccup(); j < occup; j++) {
- jam();
- // compare only the entry
- if (searchEnt.eq(currNode.getEnt(j))) {
- jam();
- treePos.m_pos = j;
- return true;
- }
- }
- treePos.m_pos = currNode.getOccup();
- // not found - failed
- return false;
-}
-
-/*
- * Search for scan start position.
- *
- * Similar to searchToAdd. The routines differ somewhat depending on
- * scan direction and are done by separate methods.
- */
-void
-Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, bool descending, TreePos& treePos)
-{
- const TreeHead& tree = frag.m_tree;
- if (tree.m_root != NullTupLoc) {
- if (! descending)
- searchToScanAscending(frag, boundInfo, boundCount, treePos);
- else
- searchToScanDescending(frag, boundInfo, boundCount, treePos);
- return;
- }
- // empty tree
-}
-
-void
-Dbtux::searchToScanAscending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos)
-{
- const TreeHead& tree = frag.m_tree;
- NodeHandle currNode(frag);
- currNode.m_loc = tree.m_root;
- NodeHandle glbNode(frag); // potential g.l.b of final node
- NodeHandle bottomNode(frag);
- while (true) {
- jam();
- selectNode(currNode, currNode.m_loc);
- int ret;
- // compare prefix
- ret = cmpScanBound(frag, 0, boundInfo, boundCount, currNode.getPref(), tree.m_prefSize);
- if (ret == NdbSqlUtil::CmpUnknown) {
- jam();
- // read and compare all attributes
- readKeyAttrs(frag, currNode.getMinMax(0), 0, c_entryKey);
- ret = cmpScanBound(frag, 0, boundInfo, boundCount, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- }
- if (ret < 0) {
- // bound is left of this node
- jam();
- const TupLoc loc = currNode.getLink(0);
- if (loc != NullTupLoc) {
- jam();
- // continue to left subtree
- currNode.m_loc = loc;
- continue;
- }
- if (! glbNode.isNull()) {
- jam();
- // move up to the g.l.b but remember the bottom node
- bottomNode = currNode;
- currNode = glbNode;
- } else {
- // start scanning this node
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = 0;
- treePos.m_dir = 3;
- return;
- }
- } else {
- // bound is at or right of this node
- jam();
- const TupLoc loc = currNode.getLink(1);
- if (loc != NullTupLoc) {
- jam();
- // save potential g.l.b
- glbNode = currNode;
- // continue to right subtree
- currNode.m_loc = loc;
- continue;
- }
- }
- break;
- }
- for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) {
- jam();
- int ret;
- // read and compare attributes
- readKeyAttrs(frag, currNode.getEnt(j), 0, c_entryKey);
- ret = cmpScanBound(frag, 0, boundInfo, boundCount, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- if (ret < 0) {
- // found first entry satisfying the bound
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = j;
- treePos.m_dir = 3;
- return;
- }
- }
- // bound is to right of this node
- if (! bottomNode.isNull()) {
- jam();
- // start scanning the l.u.b
- treePos.m_loc = bottomNode.m_loc;
- treePos.m_pos = 0;
- treePos.m_dir = 3;
- return;
- }
- // start scanning upwards (pretend we came from right child)
- treePos.m_loc = currNode.m_loc;
- treePos.m_dir = 1;
-}
-
-void
-Dbtux::searchToScanDescending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos)
-{
- const TreeHead& tree = frag.m_tree;
- NodeHandle currNode(frag);
- currNode.m_loc = tree.m_root;
- NodeHandle glbNode(frag); // potential g.l.b of final node
- NodeHandle bottomNode(frag);
- while (true) {
- jam();
- selectNode(currNode, currNode.m_loc);
- int ret;
- // compare prefix
- ret = cmpScanBound(frag, 1, boundInfo, boundCount, currNode.getPref(), tree.m_prefSize);
- if (ret == NdbSqlUtil::CmpUnknown) {
- jam();
- // read and compare all attributes
- readKeyAttrs(frag, currNode.getMinMax(0), 0, c_entryKey);
- ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- }
- if (ret < 0) {
- // bound is left of this node
- jam();
- const TupLoc loc = currNode.getLink(0);
- if (loc != NullTupLoc) {
- jam();
- // continue to left subtree
- currNode.m_loc = loc;
- continue;
- }
- if (! glbNode.isNull()) {
- jam();
- // move up to the g.l.b but remember the bottom node
- bottomNode = currNode;
- currNode = glbNode;
- } else {
- // empty result set
- return;
- }
- } else {
- // bound is at or right of this node
- jam();
- const TupLoc loc = currNode.getLink(1);
- if (loc != NullTupLoc) {
- jam();
- // save potential g.l.b
- glbNode = currNode;
- // continue to right subtree
- currNode.m_loc = loc;
- continue;
- }
- }
- break;
- }
- for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) {
- jam();
- int ret;
- // read and compare attributes
- readKeyAttrs(frag, currNode.getEnt(j), 0, c_entryKey);
- ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey);
- ndbrequire(ret != NdbSqlUtil::CmpUnknown);
- if (ret < 0) {
- if (j > 0) {
- // start scanning from previous entry
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = j - 1;
- treePos.m_dir = 3;
- return;
- }
- // start scanning upwards (pretend we came from left child)
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = 0;
- treePos.m_dir = 0;
- return;
- }
- }
- // start scanning this node
- treePos.m_loc = currNode.m_loc;
- treePos.m_pos = currNode.getOccup() - 1;
- treePos.m_dir = 3;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxStat.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxStat.cpp
deleted file mode 100644
index 143996bf7ff..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxStat.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_STAT_CPP
-#include "Dbtux.hpp"
-
-void
-Dbtux::execREAD_PSEUDO_REQ(Signal* signal)
-{
- jamEntry();
- ScanOpPtr scanPtr;
- scanPtr.i = signal->theData[0];
- c_scanOpPool.getPtr(scanPtr);
- if (signal->theData[1] == AttributeHeader::RECORDS_IN_RANGE) {
- jam();
- statRecordsInRange(scanPtr, &signal->theData[0]);
- } else {
- ndbassert(false);
- }
-}
-
-/*
- * Estimate entries in range. Scan is at first entry. Search for last
- * entry i.e. start of descending scan. Use the 2 positions to estimate
- * entries before and after the range. Finally get entries in range by
- * subtracting from total. Errors come from imperfectly balanced tree
- * and from uncommitted entries which differ only in tuple version.
- *
- * Returns 4 Uint32 values: 0) total entries 1) in range 2) before range
- * 3) after range. 1-3) are estimates and need not add up to 0).
- */
-void
-Dbtux::statRecordsInRange(ScanOpPtr scanPtr, Uint32* out)
-{
- ScanOp& scan = *scanPtr.p;
- Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
- TreeHead& tree = frag.m_tree;
- // get first and last position
- TreePos pos1 = scan.m_scanPos;
- TreePos pos2;
- { // as in scanFirst()
- setKeyAttrs(frag);
- const unsigned idir = 1;
- const ScanBound& bound = *scan.m_bound[idir];
- ScanBoundIterator iter;
- bound.first(iter);
- for (unsigned j = 0; j < bound.getSize(); j++) {
- jam();
- c_dataBuffer[j] = *iter.data;
- bound.next(iter);
- }
- searchToScan(frag, c_dataBuffer, scan.m_boundCnt[idir], true, pos2);
- // committed read (same timeslice) and range not empty
- ndbrequire(pos2.m_loc != NullTupLoc);
- }
- out[0] = frag.m_tree.m_entryCount;
- out[2] = getEntriesBeforeOrAfter(frag, pos1, 0);
- out[3] = getEntriesBeforeOrAfter(frag, pos2, 1);
- if (pos1.m_loc == pos2.m_loc) {
- ndbrequire(pos2.m_pos >= pos1.m_pos);
- out[1] = pos2.m_pos - pos1.m_pos + 1;
- } else {
- Uint32 rem = out[2] + out[3];
- if (out[0] > rem) {
- out[1] = out[0] - rem;
- } else {
- // random guess one node apart
- out[1] = tree.m_maxOccup;
- }
- }
-}
-
-/*
- * Estimate number of entries strictly before or after given position.
- * Each branch to right direction wins parent node and the subtree on
- * the other side. Subtree entries is estimated from depth and total
- * entries by assuming that the tree is perfectly balanced.
- */
-Uint32
-Dbtux::getEntriesBeforeOrAfter(Frag& frag, TreePos pos, unsigned idir)
-{
- NodeHandle node(frag);
- selectNode(node, pos.m_loc);
- Uint16 path[MaxTreeDepth + 1];
- unsigned depth = getPathToNode(node, path);
- ndbrequire(depth != 0 && depth <= MaxTreeDepth);
- TreeHead& tree = frag.m_tree;
- Uint32 cnt = 0;
- Uint32 tot = tree.m_entryCount;
- unsigned i = 0;
- // contribution from levels above
- while (i + 1 < depth) {
- unsigned occup2 = (path[i] >> 8);
- unsigned side = (path[i + 1] & 0xFF);
- // subtree of this node has about half the entries
- tot = tot >= occup2 ? (tot - occup2) / 2 : 0;
- // branch to other side wins parent and a subtree
- if (side != idir) {
- cnt += occup2;
- cnt += tot;
- }
- i++;
- }
- // contribution from this node
- unsigned occup = (path[i] >> 8);
- ndbrequire(pos.m_pos < occup);
- if (idir == 0) {
- if (pos.m_pos != 0)
- cnt += pos.m_pos - 1;
- } else {
- cnt += occup - (pos.m_pos + 1);
- }
- // contribution from levels below
- tot = tot >= occup ? (tot - occup) / 2 : 0;
- cnt += tot;
- return cnt;
-}
-
-/*
- * Construct path to given node. Returns depth. Root node has path
- * 2 and depth 1. In general the path is 2{0,1}* where 0,1 is the side
- * (left,right branch). In addition the occupancy of each node is
- * returned in the upper 8 bits.
- */
-unsigned
-Dbtux::getPathToNode(NodeHandle node, Uint16* path)
-{
- TupLoc loc = node.m_loc;
- unsigned i = MaxTreeDepth;
- while (loc != NullTupLoc) {
- jam();
- selectNode(node, loc);
- path[i] = node.getSide() | (node.getOccup() << 8);
- loc = node.getLink(2);
- ndbrequire(i != 0);
- i--;
- }
- unsigned depth = MaxTreeDepth - i;
- unsigned j = 0;
- while (j < depth) {
- path[j] = path[i + 1 + j];
- j++;
- }
- path[j] = 0xFFFF; // catch bug
- return depth;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp b/storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
deleted file mode 100644
index c130a71b60e..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp
+++ /dev/null
@@ -1,717 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define DBTUX_TREE_CPP
-#include "Dbtux.hpp"
-
-/*
- * Add entry. Handle the case when there is room for one more. This
- * is the common case given slack in nodes.
- */
-void
-Dbtux::treeAdd(Frag& frag, TreePos treePos, TreeEnt ent)
-{
- TreeHead& tree = frag.m_tree;
- NodeHandle node(frag);
- do {
- if (treePos.m_loc != NullTupLoc) {
- // non-empty tree
- jam();
- selectNode(node, treePos.m_loc);
- unsigned pos = treePos.m_pos;
- if (node.getOccup() < tree.m_maxOccup) {
- // node has room
- jam();
- nodePushUp(node, pos, ent, RNIL);
- break;
- }
- treeAddFull(frag, node, pos, ent);
- break;
- }
- jam();
- insertNode(node);
- nodePushUp(node, 0, ent, RNIL);
- node.setSide(2);
- tree.m_root = node.m_loc;
- break;
- } while (0);
- tree.m_entryCount++;
-}
-
-/*
- * Add entry when node is full. Handle the case when there is g.l.b
- * node in left subtree with room for one more. It will receive the min
- * entry of this node. The min entry could be the entry to add.
- */
-void
-Dbtux::treeAddFull(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent)
-{
- TreeHead& tree = frag.m_tree;
- TupLoc loc = lubNode.getLink(0);
- if (loc != NullTupLoc) {
- // find g.l.b node
- NodeHandle glbNode(frag);
- do {
- jam();
- selectNode(glbNode, loc);
- loc = glbNode.getLink(1);
- } while (loc != NullTupLoc);
- if (glbNode.getOccup() < tree.m_maxOccup) {
- // g.l.b node has room
- jam();
- Uint32 scanList = RNIL;
- if (pos != 0) {
- jam();
- // add the new entry and return min entry
- nodePushDown(lubNode, pos - 1, ent, scanList);
- }
- // g.l.b node receives min entry from l.u.b node
- nodePushUp(glbNode, glbNode.getOccup(), ent, scanList);
- return;
- }
- treeAddNode(frag, lubNode, pos, ent, glbNode, 1);
- return;
- }
- treeAddNode(frag, lubNode, pos, ent, lubNode, 0);
-}
-
-/*
- * Add entry when there is no g.l.b node in left subtree or the g.l.b
- * node is full. We must add a new left or right child node which
- * becomes the new g.l.b node.
- */
-void
-Dbtux::treeAddNode(Frag& frag, NodeHandle lubNode, unsigned pos, TreeEnt ent, NodeHandle parentNode, unsigned i)
-{
- NodeHandle glbNode(frag);
- insertNode(glbNode);
- // connect parent and child
- parentNode.setLink(i, glbNode.m_loc);
- glbNode.setLink(2, parentNode.m_loc);
- glbNode.setSide(i);
- Uint32 scanList = RNIL;
- if (pos != 0) {
- jam();
- // add the new entry and return min entry
- nodePushDown(lubNode, pos - 1, ent, scanList);
- }
- // g.l.b node receives min entry from l.u.b node
- nodePushUp(glbNode, 0, ent, scanList);
- // re-balance the tree
- treeAddRebalance(frag, parentNode, i);
-}
-
-/*
- * Re-balance tree after adding a node. The process starts with the
- * parent of the added node.
- */
-void
-Dbtux::treeAddRebalance(Frag& frag, NodeHandle node, unsigned i)
-{
- while (true) {
- // height of subtree i has increased by 1
- int j = (i == 0 ? -1 : +1);
- int b = node.getBalance();
- if (b == 0) {
- // perfectly balanced
- jam();
- node.setBalance(j);
- // height change propagates up
- } else if (b == -j) {
- // height of shorter subtree increased
- jam();
- node.setBalance(0);
- // height of tree did not change - done
- break;
- } else if (b == j) {
- // height of longer subtree increased
- jam();
- NodeHandle childNode(frag);
- selectNode(childNode, node.getLink(i));
- int b2 = childNode.getBalance();
- if (b2 == b) {
- jam();
- treeRotateSingle(frag, node, i);
- } else if (b2 == -b) {
- jam();
- treeRotateDouble(frag, node, i);
- } else {
- // height of subtree increased so it cannot be perfectly balanced
- ndbrequire(false);
- }
- // height of tree did not increase - done
- break;
- } else {
- ndbrequire(false);
- }
- TupLoc parentLoc = node.getLink(2);
- if (parentLoc == NullTupLoc) {
- jam();
- // root node - done
- break;
- }
- i = node.getSide();
- selectNode(node, parentLoc);
- }
-}
-
-/*
- * Remove entry. Optimize for nodes with slack. Handle the case when
- * there is no underflow i.e. occupancy remains at least minOccup. For
- * interior nodes this is a requirement. For others it means that we do
- * not need to consider merge of semi-leaf and leaf.
- */
-void
-Dbtux::treeRemove(Frag& frag, TreePos treePos)
-{
- TreeHead& tree = frag.m_tree;
- unsigned pos = treePos.m_pos;
- NodeHandle node(frag);
- selectNode(node, treePos.m_loc);
- TreeEnt ent;
- do {
- if (node.getOccup() > tree.m_minOccup) {
- // no underflow in any node type
- jam();
- nodePopDown(node, pos, ent, 0);
- break;
- }
- if (node.getChilds() == 2) {
- // underflow in interior node
- jam();
- treeRemoveInner(frag, node, pos);
- break;
- }
- // remove entry in semi/leaf
- nodePopDown(node, pos, ent, 0);
- if (node.getLink(0) != NullTupLoc) {
- jam();
- treeRemoveSemi(frag, node, 0);
- break;
- }
- if (node.getLink(1) != NullTupLoc) {
- jam();
- treeRemoveSemi(frag, node, 1);
- break;
- }
- treeRemoveLeaf(frag, node);
- break;
- } while (0);
- ndbrequire(tree.m_entryCount != 0);
- tree.m_entryCount--;
-}
-
-/*
- * Remove entry when interior node underflows. There is g.l.b node in
- * left subtree to borrow an entry from. The max entry of the g.l.b
- * node becomes the min entry of this node.
- */
-void
-Dbtux::treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos)
-{
- TreeEnt ent;
- // find g.l.b node
- NodeHandle glbNode(frag);
- TupLoc loc = lubNode.getLink(0);
- do {
- jam();
- selectNode(glbNode, loc);
- loc = glbNode.getLink(1);
- } while (loc != NullTupLoc);
- // borrow max entry from semi/leaf
- Uint32 scanList = RNIL;
- nodePopDown(glbNode, glbNode.getOccup() - 1, ent, &scanList);
- // g.l.b may be empty now
- // a descending scan may try to enter the empty g.l.b
- // we prevent this in scanNext
- nodePopUp(lubNode, pos, ent, scanList);
- if (glbNode.getLink(0) != NullTupLoc) {
- jam();
- treeRemoveSemi(frag, glbNode, 0);
- return;
- }
- treeRemoveLeaf(frag, glbNode);
-}
-
-/*
- * Handle semi-leaf after removing an entry. Move entries from leaf to
- * semi-leaf to bring semi-leaf occupancy above minOccup, if possible.
- * The leaf may become empty.
- */
-void
-Dbtux::treeRemoveSemi(Frag& frag, NodeHandle semiNode, unsigned i)
-{
- TreeHead& tree = frag.m_tree;
- ndbrequire(semiNode.getChilds() < 2);
- TupLoc leafLoc = semiNode.getLink(i);
- NodeHandle leafNode(frag);
- selectNode(leafNode, leafLoc);
- if (semiNode.getOccup() < tree.m_minOccup) {
- jam();
- unsigned cnt = min(leafNode.getOccup(), tree.m_minOccup - semiNode.getOccup());
- nodeSlide(semiNode, leafNode, cnt, i);
- if (leafNode.getOccup() == 0) {
- // remove empty leaf
- jam();
- treeRemoveNode(frag, leafNode);
- }
- }
-}
-
-/*
- * Handle leaf after removing an entry. If parent is semi-leaf, move
- * entries to it as in the semi-leaf case. If parent is interior node,
- * do nothing.
- */
-void
-Dbtux::treeRemoveLeaf(Frag& frag, NodeHandle leafNode)
-{
- TreeHead& tree = frag.m_tree;
- TupLoc parentLoc = leafNode.getLink(2);
- if (parentLoc != NullTupLoc) {
- jam();
- NodeHandle parentNode(frag);
- selectNode(parentNode, parentLoc);
- unsigned i = leafNode.getSide();
- if (parentNode.getLink(1 - i) == NullTupLoc) {
- // parent is semi-leaf
- jam();
- if (parentNode.getOccup() < tree.m_minOccup) {
- jam();
- unsigned cnt = min(leafNode.getOccup(), tree.m_minOccup - parentNode.getOccup());
- nodeSlide(parentNode, leafNode, cnt, i);
- }
- }
- }
- if (leafNode.getOccup() == 0) {
- jam();
- // remove empty leaf
- treeRemoveNode(frag, leafNode);
- }
-}
-
-/*
- * Remove empty leaf.
- */
-void
-Dbtux::treeRemoveNode(Frag& frag, NodeHandle leafNode)
-{
- TreeHead& tree = frag.m_tree;
- ndbrequire(leafNode.getChilds() == 0);
- TupLoc parentLoc = leafNode.getLink(2);
- unsigned i = leafNode.getSide();
- deleteNode(leafNode);
- if (parentLoc != NullTupLoc) {
- jam();
- NodeHandle parentNode(frag);
- selectNode(parentNode, parentLoc);
- parentNode.setLink(i, NullTupLoc);
- // re-balance the tree
- treeRemoveRebalance(frag, parentNode, i);
- return;
- }
- // tree is now empty
- tree.m_root = NullTupLoc;
-}
-
-/*
- * Re-balance tree after removing a node. The process starts with the
- * parent of the removed node.
- */
-void
-Dbtux::treeRemoveRebalance(Frag& frag, NodeHandle node, unsigned i)
-{
- while (true) {
- // height of subtree i has decreased by 1
- int j = (i == 0 ? -1 : +1);
- int b = node.getBalance();
- if (b == 0) {
- // perfectly balanced
- jam();
- node.setBalance(-j);
- // height of tree did not change - done
- return;
- } else if (b == j) {
- // height of longer subtree has decreased
- jam();
- node.setBalance(0);
- // height change propagates up
- } else if (b == -j) {
- // height of shorter subtree has decreased
- jam();
- // child on the other side
- NodeHandle childNode(frag);
- selectNode(childNode, node.getLink(1 - i));
- int b2 = childNode.getBalance();
- if (b2 == b) {
- jam();
- treeRotateSingle(frag, node, 1 - i);
- // height of tree decreased and propagates up
- } else if (b2 == -b) {
- jam();
- treeRotateDouble(frag, node, 1 - i);
- // height of tree decreased and propagates up
- } else {
- jam();
- treeRotateSingle(frag, node, 1 - i);
- // height of tree did not change - done
- return;
- }
- } else {
- ndbrequire(false);
- }
- TupLoc parentLoc = node.getLink(2);
- if (parentLoc == NullTupLoc) {
- jam();
- // root node - done
- return;
- }
- i = node.getSide();
- selectNode(node, parentLoc);
- }
-}
-
-/*
- * Single rotation about node 5. One of LL (i=0) or RR (i=1).
- *
- * 0 0
- * | |
- * 5 ==> 3
- * / \ / \
- * 3 6 2 5
- * / \ / / \
- * 2 4 1 4 6
- * /
- * 1
- *
- * In this change 5,3 and 2 must always be there. 0, 1, 2, 4 and 6 are
- * all optional. If 4 are there it changes side.
-*/
-void
-Dbtux::treeRotateSingle(Frag& frag, NodeHandle& node, unsigned i)
-{
- ndbrequire(i <= 1);
- /*
- 5 is the old top node that have been unbalanced due to an insert or
- delete. The balance is still the old balance before the update.
- Verify that bal5 is 1 if RR rotate and -1 if LL rotate.
- */
- NodeHandle node5 = node;
- const TupLoc loc5 = node5.m_loc;
- const int bal5 = node5.getBalance();
- const int side5 = node5.getSide();
- ndbrequire(bal5 + (1 - i) == i);
- /*
- 3 is the new root of this part of the tree which is to swap place with
- node 5. For an insert to cause this it must have the same balance as 5.
- For deletes it can have the balance 0.
- */
- TupLoc loc3 = node5.getLink(i);
- NodeHandle node3(frag);
- selectNode(node3, loc3);
- const int bal3 = node3.getBalance();
- /*
- 2 must always be there but is not changed. Thus we mereley check that it
- exists.
- */
- ndbrequire(node3.getLink(i) != NullTupLoc);
- /*
- 4 is not necessarily there but if it is there it will move from one
- side of 3 to the other side of 5. For LL it moves from the right side
- to the left side and for RR it moves from the left side to the right
- side. This means that it also changes parent from 3 to 5.
- */
- TupLoc loc4 = node3.getLink(1 - i);
- NodeHandle node4(frag);
- if (loc4 != NullTupLoc) {
- jam();
- selectNode(node4, loc4);
- ndbrequire(node4.getSide() == (1 - i) &&
- node4.getLink(2) == loc3);
- node4.setSide(i);
- node4.setLink(2, loc5);
- }//if
-
- /*
- Retrieve the address of 5's parent before it is destroyed
- */
- TupLoc loc0 = node5.getLink(2);
-
- /*
- The next step is to perform the rotation. 3 will inherit 5's parent
- and side. 5 will become a child of 3 on the right side for LL and on
- the left side for RR.
- 5 will get 3 as the parent. It will get 4 as a child and it will be
- on the right side of 3 for LL and left side of 3 for RR.
- The final step of the rotate is to check whether 5 originally had any
- parent. If it had not then 3 is the new root node.
- We will also verify some preconditions for the change to occur.
- 1. 3 must have had 5 as parent before the change.
- 2. 3's side is left for LL and right for RR before change.
- */
- ndbrequire(node3.getLink(2) == loc5);
- ndbrequire(node3.getSide() == i);
- node3.setLink(1 - i, loc5);
- node3.setLink(2, loc0);
- node3.setSide(side5);
- node5.setLink(i, loc4);
- node5.setLink(2, loc3);
- node5.setSide(1 - i);
- if (loc0 != NullTupLoc) {
- jam();
- NodeHandle node0(frag);
- selectNode(node0, loc0);
- node0.setLink(side5, loc3);
- } else {
- jam();
- frag.m_tree.m_root = loc3;
- }//if
- /* The final step of the change is to update the balance of 3 and
- 5 that changed places. There are two cases here. The first case is
- when 3 unbalanced in the same direction by an insert or a delete.
- In this case the changes will make the tree balanced again for both
- 3 and 5.
- The second case only occurs at deletes. In this case 3 starts out
- balanced. In the figure above this could occur if 4 starts out with
- a right node and the rotate is triggered by a delete of 6's only child.
- In this case 5 will change balance but still be unbalanced and 3 will
- be unbalanced in the opposite direction of 5.
- */
- if (bal3 == bal5) {
- jam();
- node3.setBalance(0);
- node5.setBalance(0);
- } else if (bal3 == 0) {
- jam();
- node3.setBalance(-bal5);
- node5.setBalance(bal5);
- } else {
- ndbrequire(false);
- }//if
- /*
- Set node to 3 as return parameter for enabling caller to continue
- traversing the tree.
- */
- node = node3;
-}
-
-/*
- * Double rotation about node 6. One of LR (i=0) or RL (i=1).
- *
- * 0 0
- * | |
- * 6 ==> 4
- * / \ / \
- * 2 7 2 6
- * / \ / \ / \
- * 1 4 1 3 5 7
- * / \
- * 3 5
- *
- * In this change 6, 2 and 4 must be there, all others are optional.
- * We will start by proving a Lemma.
- * Lemma:
- * The height of the sub-trees 1 and 7 and the maximum height of the
- * threes from 3 and 5 are all the same.
- * Proof:
- * maxheight(3,5) is defined as the maximum height of 3 and 5.
- * If height(7) > maxheight(3,5) then the AVL condition is ok and we
- * don't need to perform a rotation.
- * If height(7) < maxheight(3,5) then the balance of 6 would be at least
- * -3 which cannot happen in an AVL tree even before a rotation.
- * Thus we conclude that height(7) == maxheight(3,5)
- *
- * The next step is to prove that the height of 1 is equal to maxheight(3,5).
- * If height(1) - 1 > maxheight(3,5) then we would have
- * balance in 6 equal to -3 at least which cannot happen in an AVL-tree.
- * If height(1) - 1 = maxheight(3,5) then we should have solved the
- * unbalance with a single rotate and not with a double rotate.
- * If height(1) + 1 = maxheight(3,5) then we would be doing a rotate
- * with node 2 as the root of the rotation.
- * If height(1) + k = maxheight(3,5) where k >= 2 then the tree could not have
- * been an AVL-tree before the insert or delete.
- * Thus we conclude that height(1) = maxheight(3,5)
- *
- * Thus we conclude that height(1) = maxheight(3,5) = height(7).
- *
- * Observation:
- * The balance of node 4 before the rotation can be any (-1, 0, +1).
- *
- * The following changes are needed:
- * Node 6:
- * 1) Changes parent from 0 -> 4
- * 2) 1 - i link stays the same
- * 3) i side link is derived from 1 - i side link from 4
- * 4) Side is set to 1 - i
- * 5) Balance change:
- * If balance(4) == 0 then balance(6) = 0
- * since height(3) = height(5) = maxheight(3,5) = height(7)
- * If balance(4) == +1 then balance(6) = 0
- * since height(5) = maxheight(3,5) = height(7)
- * If balance(4) == -1 then balance(6) = 1
- * since height(5) + 1 = maxheight(3,5) = height(7)
- *
- * Node 2:
- * 1) Changes parent from 6 -> 4
- * 2) i side link stays the same
- * 3) 1 - i side link is derived from i side link of 4
- * 4) Side is set to i (thus not changed)
- * 5) Balance change:
- * If balance(4) == 0 then balance(2) = 0
- * since height(3) = height(5) = maxheight(3,5) = height(1)
- * If balance(4) == -1 then balance(2) = 0
- * since height(3) = maxheight(3,5) = height(1)
- * If balance(4) == +1 then balance(6) = 1
- * since height(3) + 1 = maxheight(3,5) = height(1)
- *
- * Node 4:
- * 1) Inherits parent from 6
- * 2) i side link is 2
- * 3) 1 - i side link is 6
- * 4) Side is inherited from 6
- * 5) Balance(4) = 0 independent of previous balance
- * Proof:
- * If height(1) = 0 then only 2, 4 and 6 are involved and then it is
- * trivially true.
- * If height(1) >= 1 then we are sure that 1 and 7 exist with the same
- * height and that if 3 and 5 exist they are of the same height as 1 and
- * 7 and thus we know that 4 is balanced since newheight(2) = newheight(6).
- *
- * If Node 3 exists:
- * 1) Change parent from 4 to 2
- * 2) Change side from i to 1 - i
- *
- * If Node 5 exists:
- * 1) Change parent from 4 to 6
- * 2) Change side from 1 - i to i
- *
- * If Node 0 exists:
- * 1) previous link to 6 is replaced by link to 4 on proper side
- *
- * Node 1 and 7 needs no changes at all.
- *
- * Some additional requires are that balance(2) = - balance(6) = -1/+1 since
- * otherwise we would do a single rotate.
- *
- * The balance(6) is -1 if i == 0 and 1 if i == 1
- *
- */
-void
-Dbtux::treeRotateDouble(Frag& frag, NodeHandle& node, unsigned i)
-{
- TreeHead& tree = frag.m_tree;
-
- // old top node
- NodeHandle node6 = node;
- const TupLoc loc6 = node6.m_loc;
- // the un-updated balance
- const int bal6 = node6.getBalance();
- const unsigned side6 = node6.getSide();
-
- // level 1
- TupLoc loc2 = node6.getLink(i);
- NodeHandle node2(frag);
- selectNode(node2, loc2);
- const int bal2 = node2.getBalance();
-
- // level 2
- TupLoc loc4 = node2.getLink(1 - i);
- NodeHandle node4(frag);
- selectNode(node4, loc4);
- const int bal4 = node4.getBalance();
-
- ndbrequire(i <= 1);
- ndbrequire(bal6 + (1 - i) == i);
- ndbrequire(bal2 == -bal6);
- ndbrequire(node2.getLink(2) == loc6);
- ndbrequire(node2.getSide() == i);
- ndbrequire(node4.getLink(2) == loc2);
-
- // level 3
- TupLoc loc3 = node4.getLink(i);
- TupLoc loc5 = node4.getLink(1 - i);
-
- // fill up leaf before it becomes internal
- if (loc3 == NullTupLoc && loc5 == NullTupLoc) {
- jam();
- if (node4.getOccup() < tree.m_minOccup) {
- jam();
- unsigned cnt = tree.m_minOccup - node4.getOccup();
- ndbrequire(cnt < node2.getOccup());
- nodeSlide(node4, node2, cnt, i);
- ndbrequire(node4.getOccup() >= tree.m_minOccup);
- ndbrequire(node2.getOccup() != 0);
- }
- } else {
- if (loc3 != NullTupLoc) {
- jam();
- NodeHandle node3(frag);
- selectNode(node3, loc3);
- node3.setLink(2, loc2);
- node3.setSide(1 - i);
- }
- if (loc5 != NullTupLoc) {
- jam();
- NodeHandle node5(frag);
- selectNode(node5, loc5);
- node5.setLink(2, node6.m_loc);
- node5.setSide(i);
- }
- }
- // parent
- TupLoc loc0 = node6.getLink(2);
- NodeHandle node0(frag);
- // perform the rotation
- node6.setLink(i, loc5);
- node6.setLink(2, loc4);
- node6.setSide(1 - i);
-
- node2.setLink(1 - i, loc3);
- node2.setLink(2, loc4);
-
- node4.setLink(i, loc2);
- node4.setLink(1 - i, loc6);
- node4.setLink(2, loc0);
- node4.setSide(side6);
-
- if (loc0 != NullTupLoc) {
- jam();
- selectNode(node0, loc0);
- node0.setLink(side6, loc4);
- } else {
- jam();
- frag.m_tree.m_root = loc4;
- }
- // set balance of changed nodes
- node4.setBalance(0);
- if (bal4 == 0) {
- jam();
- node2.setBalance(0);
- node6.setBalance(0);
- } else if (bal4 == -bal2) {
- jam();
- node2.setBalance(0);
- node6.setBalance(bal2);
- } else if (bal4 == bal2) {
- jam();
- node2.setBalance(-bal2);
- node6.setBalance(0);
- } else {
- ndbrequire(false);
- }
- // new top node
- node = node4;
-}
diff --git a/storage/ndb/src/kernel/blocks/dbtux/Times.txt b/storage/ndb/src/kernel/blocks/dbtux/Times.txt
deleted file mode 100644
index 68120084846..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/Times.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-ordered index performance
-=========================
-
-"mc02" 2x1700 MHz linux-2.4.9 gcc-2.96 -O3 one db-node
-
-case a: maintenance: index on Unsigned
-testOIBasic -case u -table 1 -index 2 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging
-
-case b: maintenance: index on Varchar(5) + Varchar(5) + Varchar(20) + Unsigned
-testOIBasic -case u -table 2 -index 5 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging
-
-case c: full scan: index on PK Unsigned
-testOIBasic -case v -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -subloop 1 -nologging
-
-case d: scan 1 tuple via EQ: index on PK Unsigned
-testOIBasic -case w -table 1 -index 1 -fragtype small -threads 10 -rows 100000 -samples 50000 -subloop 1 -nologging -v2
-
-a, b
-1 million rows, pk update without index, pk update with index
-shows ms / 1000 rows for each and pct overhead
-
-c
-1 million rows, index on PK, full table scan, full index scan
-shows ms / 1000 rows for each and index time overhead
-
-d
-1 million rows, index on PK, read table via each pk, scan index for each pk
-shows ms / 1000 rows for each and index time overhead
-samples 10% of all PKs (100,000 pk reads, 100,000 scans)
-
-the "pct" values are from more accurate total times (not shown)
-comments [ ... ] are after the case
-
-040616 mc02/a 40 ms 87 ms 114 pct
- mc02/b 51 ms 128 ms 148 pct
-
-optim 1 mc02/a 38 ms 85 ms 124 pct
- mc02/b 51 ms 123 ms 140 pct
-
-optim 2 mc02/a 41 ms 80 ms 96 pct
- mc02/b 51 ms 117 ms 128 pct
-
-optim 3 mc02/a 43 ms 80 ms 85 pct
- mc02/b 54 ms 118 ms 117 pct
-
-optim 4 mc02/a 42 ms 80 ms 87 pct
- mc02/b 51 ms 119 ms 129 pct
-
-optim 5 mc02/a 43 ms 77 ms 77 pct
- mc02/b 54 ms 118 ms 117 pct
-
-optim 6 mc02/a 42 ms 70 ms 66 pct
- mc02/b 53 ms 109 ms 105 pct
-
-optim 7 mc02/a 42 ms 69 ms 61 pct
- mc02/b 52 ms 106 ms 101 pct
-
-optim 8 mc02/a 42 ms 69 ms 62 pct
- mc02/b 54 ms 104 ms 92 pct
-
-optim 9 mc02/a 43 ms 67 ms 54 pct
- mc02/b 53 ms 102 ms 91 pct
-
-optim 10 mc02/a 44 ms 65 ms 46 pct
- mc02/b 53 ms 88 ms 66 pct
-
-optim 11 mc02/a 43 ms 63 ms 46 pct
- mc02/b 52 ms 86 ms 63 pct
-
-optim 12 mc02/a 38 ms 55 ms 43 pct
- mc02/b 47 ms 77 ms 63 pct
- mc02/c 10 ms 14 ms 47 pct
- mc02/d 176 ms 281 ms 59 pct
-
-optim 13 mc02/a 40 ms 57 ms 42 pct
- mc02/b 47 ms 77 ms 61 pct
- mc02/c 9 ms 13 ms 50 pct
- mc02/d 170 ms 256 ms 50 pct
-
-optim 13 mc02/a 39 ms 59 ms 50 pct
- mc02/b 47 ms 77 ms 61 pct
- mc02/c 9 ms 12 ms 44 pct
- mc02/d 246 ms 289 ms 17 pct
-
-[ after wl-1884 store all-NULL keys (the tests have pctnull=10 per column) ]
-[ case d: bug in testOIBasic killed PK read performance ]
-
-optim 14 mc02/a 41 ms 60 ms 44 pct
- mc02/b 46 ms 81 ms 73 pct
- mc02/c 9 ms 13 ms 37 pct
- mc02/d 242 ms 285 ms 17 pct
-
-[ case b: do long keys suffer from many subroutine calls? ]
-[ case d: bug in testOIBasic killed PK read performance ]
-
-none mc02/a 35 ms 60 ms 71 pct
- mc02/b 42 ms 75 ms 76 pct
- mc02/c 5 ms 12 ms 106 pct
- mc02/d 165 ms 238 ms 44 pct
-
-[ johan re-installed mc02 as fedora gcc-3.3.2, tux uses more C++ stuff than tup]
-
-charsets mc02/a 35 ms 60 ms 71 pct
- mc02/b 42 ms 84 ms 97 pct
- mc02/c 5 ms 12 ms 109 pct
- mc02/d 190 ms 236 ms 23 pct
-
-[ case b: TUX can no longer use pointers to TUP data ]
-
-optim 15 mc02/a 34 ms 60 ms 72 pct
- mc02/b 42 ms 85 ms 100 pct
- mc02/c 5 ms 12 ms 110 pct
- mc02/d 178 ms 242 ms 35 pct
-
-[ corrected wasted space in index node ]
-
-optim 16 mc02/a 34 ms 53 ms 53 pct
- mc02/b 42 ms 75 ms 75 pct
-
-[ binary search of bounding node when adding entry ]
-
-none mc02/a 35 ms 53 ms 51 pct
- mc02/b 42 ms 75 ms 76 pct
-
-[ rewrote treeAdd / treeRemove ]
-
-optim 17 mc02/a 35 ms 52 ms 49 pct
- mc02/b 43 ms 75 ms 75 pct
-
-[ allow slack (2) in interior nodes - almost no effect?? ]
-
-wl-1942 mc02/a 35 ms 52 ms 49 pct
- mc02/b 42 ms 75 ms 76 pct
-
-before mc02/c 5 ms 13 ms 126 pct
- mc02/d 134 ms 238 ms 78 pct
-
-after mc02/c 5 ms 10 ms 70 pct
- mc02/d 178 ms 242 ms 69 pct
-
-[ prelim performance fix for max batch size 16 -> 992 ]
-
-wl-2066 mc02/c 5 ms 10 ms 87 pct
-before mc02/d 140 ms 237 ms 69 pct
-
-wl-2066 mc02/c 5 ms 10 ms 69 pct
-after mc02/d 150 ms 229 ms 52 pct
-
-[ wl-2066 = remove ACC storage, use TUX test to see effect ]
-
-vim: set et:
diff --git a/storage/ndb/src/kernel/blocks/dbtux/tuxstatus.html b/storage/ndb/src/kernel/blocks/dbtux/tuxstatus.html
deleted file mode 100644
index 264809cefd3..00000000000
--- a/storage/ndb/src/kernel/blocks/dbtux/tuxstatus.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<HTML>
-<HEAD>
-<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
-<TITLE>NDB Ordered Index Status</TITLE>
-</HEAD>
-<BODY LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">
-<p>
-<h2>NDB Ordered Index Status</h2>
-<p>
-<h3>Alpha release Jan 30, 2004</h3>
-<p>
-<ul>
- <li>
- Up to 32 index attributes of any type, possibly nullable.
- <li>
- Index build i.e. table need not be empty.
- <li>
- Logging NOT done, index rebuilt at system restart.
- <li>
- Single range scan with lower and upper bounds.
- <li>
- Scan with locking: read latest, read for update.
- <li>
- LIMITED number of parallel scans.
- <li>
- Total result set NOT in index key order.
- <li>
- NDB ODBC optimizer to use ordered index for equality but NOT for ranges.
- <li>
- MySQL optimizer to use ordered index for equality and ranges.
-</ul>
-<p>
-As an example, consider following index on integer attributes.
-<p>
-<tt>SQL&gt;create index X on T (A, B, C) nologging;</tt>
-<p>
-Single range scan means that bounds are set on
-an initial sequence of index keys, and all but last is an equality.
-<br>
-For example following scans are supported (the last 2 not via NDB ODBC).
-<p>
-<tt>SQL&gt;select * from T where A = 1;</tt>
-<br>
-<tt>SQL&gt;select * from T where A = 1 and B = 10 and C = 20;</tt>
-<br>
-<tt>SQL&gt;select * from T where A &lt; 10;</tt>
-<br>
-<tt>SQL&gt;select * from T where A = 1 and 10 &lt; B and B &lt; 20;</tt>
-<p>
-Following scans are NOT supported:
-<p>
-<tt>SQL&gt;select * from T where B = 1;</tt>
-<br>
-<tt>SQL&gt;select * from T where A &lt; 10 and B &lt; 20;</tt>
-<br>
-<h3>Features and dates</h3>
-[ Now = Jan 19 ]
-<p>
-<table border=1 cellpadding=1>
-<tr align="left">
- <th width="40%">Feature</th>
- <th width="15%">Now</th> <th width="15%">Jan 30</th> <th width="15%">Mar 01</th> <th width="15%">Never</th>
-</tr>
-<tr align=left>
- <td>Index maintenance</td>
- <td>X</td> <td>-</td> <td>-</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Basic scan</td>
- <td>X 1)</td> <td>-</td> <td>-</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Scan bounds on nullable attributes</td>
- <td>-</td> <td>X</td> <td>-</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Scan with locking</td>
- <td>-</td> <td>X</td> <td>-</td> <td>-</td>
-</tr>
-<tr align="left">
- <td>NDB ODBC equality bounds</td>
- <td>-</td> <td>X</td> <td>-</td> <td>-</td>
-</tr>
-<tr align="left">
- <td>MySQL integration</td>
- <td>-</td> <td>X</td> <td>-</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Index build</td>
- <td>2)</td> <td>X</td> <td>-</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Unlimited number of scans</td>
- <td>3)</td> <td>-</td> <td>X</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Total ordering</td>
- <td>-</td> <td>-</td> <td>X</td> <td>-</td>
-</tr>
-<tr align=left>
- <td>Multiple range scan</td>
- <td>-</td> <td>-</td> <td>X</td> <td>-</td>
-</tr>
-<tr align="left">
- <td>NDB ODBC range bounds</td>
- <td>-</td> <td>-</td> <td>-</td> <td>X</td>
-</tr>
-<tr align=left>
- <td>Logging</td>
- <td>-</td> <td>-</td> <td>-</td> <td>X</td>
-</tr>
-</table>
-<p>
-1) No locking and bounds must be on non-nullable key attributes.
-<br>
-2) Currently table must be empty when index is created.
-<br>
-3) Currently limited to 11 simultaneous per fragment.
-</BODY>
-</HTML>
diff --git a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp
deleted file mode 100644
index 398c63add84..00000000000
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp
+++ /dev/null
@@ -1,2608 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "DbUtil.hpp"
-
-#include <ndb_version.h>
-
-#include <signaldata/WaitGCP.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/TcKeyConf.hpp>
-#include <signaldata/TcKeyFailConf.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-
-#include <signaldata/UtilSequence.hpp>
-#include <signaldata/UtilPrepare.hpp>
-#include <signaldata/UtilRelease.hpp>
-#include <signaldata/UtilExecute.hpp>
-#include <signaldata/UtilLock.hpp>
-
-#include <SectionReader.hpp>
-#include <Interpreter.hpp>
-#include <AttributeHeader.hpp>
-
-#include <NdbTick.h>
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Startup
- * ------------------------------------------------------------------------
- *
- * Constructors, startup, initializations
- **************************************************************************/
-
-DbUtil::DbUtil(Block_context& ctx) :
- SimulatedBlock(DBUTIL, ctx),
- c_runningPrepares(c_preparePool),
- c_seizingTransactions(c_transactionPool),
- c_runningTransactions(c_transactionPool),
- c_lockQueues(c_lockQueuePool)
-{
- BLOCK_CONSTRUCTOR(DbUtil);
-
- // Add received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &DbUtil::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &DbUtil::execSTTOR);
- addRecSignal(GSN_NDB_STTOR, &DbUtil::execNDB_STTOR);
- addRecSignal(GSN_DUMP_STATE_ORD, &DbUtil::execDUMP_STATE_ORD);
- addRecSignal(GSN_CONTINUEB, &DbUtil::execCONTINUEB);
-
- //addRecSignal(GSN_TCSEIZEREF, &DbUtil::execTCSEIZEREF);
- addRecSignal(GSN_TCSEIZECONF, &DbUtil::execTCSEIZECONF);
- addRecSignal(GSN_TCKEYCONF, &DbUtil::execTCKEYCONF);
- addRecSignal(GSN_TCKEYREF, &DbUtil::execTCKEYREF);
- addRecSignal(GSN_TCROLLBACKREP, &DbUtil::execTCROLLBACKREP);
-
- //addRecSignal(GSN_TCKEY_FAILCONF, &DbUtil::execTCKEY_FAILCONF);
- //addRecSignal(GSN_TCKEY_FAILREF, &DbUtil::execTCKEY_FAILREF);
- addRecSignal(GSN_TRANSID_AI, &DbUtil::execTRANSID_AI);
-
- /**
- * Sequence Service
- */
- addRecSignal(GSN_UTIL_SEQUENCE_REQ, &DbUtil::execUTIL_SEQUENCE_REQ);
- // Debug
- addRecSignal(GSN_UTIL_SEQUENCE_REF, &DbUtil::execUTIL_SEQUENCE_REF);
- addRecSignal(GSN_UTIL_SEQUENCE_CONF, &DbUtil::execUTIL_SEQUENCE_CONF);
-
- /**
- * Locking
- */
- addRecSignal(GSN_UTIL_CREATE_LOCK_REQ, &DbUtil::execUTIL_CREATE_LOCK_REQ);
- addRecSignal(GSN_UTIL_DESTROY_LOCK_REQ, &DbUtil::execUTIL_DESTORY_LOCK_REQ);
- addRecSignal(GSN_UTIL_LOCK_REQ, &DbUtil::execUTIL_LOCK_REQ);
- addRecSignal(GSN_UTIL_UNLOCK_REQ, &DbUtil::execUTIL_UNLOCK_REQ);
-
- /**
- * Backend towards Dict
- */
- addRecSignal(GSN_GET_TABINFOREF, &DbUtil::execGET_TABINFOREF);
- addRecSignal(GSN_GET_TABINFO_CONF, &DbUtil::execGET_TABINFO_CONF);
-
- /**
- * Prepare / Execute / Release Services
- */
- addRecSignal(GSN_UTIL_PREPARE_REQ, &DbUtil::execUTIL_PREPARE_REQ);
- addRecSignal(GSN_UTIL_PREPARE_CONF, &DbUtil::execUTIL_PREPARE_CONF);
- addRecSignal(GSN_UTIL_PREPARE_REF, &DbUtil::execUTIL_PREPARE_REF);
-
- addRecSignal(GSN_UTIL_EXECUTE_REQ, &DbUtil::execUTIL_EXECUTE_REQ);
- addRecSignal(GSN_UTIL_EXECUTE_CONF, &DbUtil::execUTIL_EXECUTE_CONF);
- addRecSignal(GSN_UTIL_EXECUTE_REF, &DbUtil::execUTIL_EXECUTE_REF);
-
- addRecSignal(GSN_UTIL_RELEASE_REQ, &DbUtil::execUTIL_RELEASE_REQ);
- addRecSignal(GSN_UTIL_RELEASE_CONF, &DbUtil::execUTIL_RELEASE_CONF);
- addRecSignal(GSN_UTIL_RELEASE_REF, &DbUtil::execUTIL_RELEASE_REF);
-}
-
-DbUtil::~DbUtil()
-{
-}
-
-BLOCK_FUNCTIONS(DbUtil)
-
-void
-DbUtil::releasePrepare(PreparePtr prepPtr) {
- prepPtr.p->preparePages.release();
- c_runningPrepares.release(prepPtr); // Automatic release in pool
-}
-
-void
-DbUtil::releasePreparedOperation(PreparedOperationPtr prepOpPtr) {
- prepOpPtr.p->attrMapping.release();
- prepOpPtr.p->attrInfo.release();
- prepOpPtr.p->rsInfo.release();
- prepOpPtr.p->pkBitmask.clear();
- c_preparedOperationPool.release(prepOpPtr); // No list holding these structs
-}
-
-void
-DbUtil::releaseTransaction(TransactionPtr transPtr){
- transPtr.p->executePages.release();
- OperationPtr opPtr;
- for(transPtr.p->operations.first(opPtr); opPtr.i != RNIL;
- transPtr.p->operations.next(opPtr)){
- opPtr.p->attrInfo.release();
- opPtr.p->keyInfo.release();
- opPtr.p->rs.release();
- if (opPtr.p->prepOp != 0 && opPtr.p->prepOp_i != RNIL) {
- if (opPtr.p->prepOp->releaseFlag) {
- PreparedOperationPtr prepOpPtr;
- prepOpPtr.i = opPtr.p->prepOp_i;
- prepOpPtr.p = opPtr.p->prepOp;
- releasePreparedOperation(prepOpPtr);
- }
- }
- }
- transPtr.p->operations.release();
- c_runningTransactions.release(transPtr);
-}
-
-void
-DbUtil::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- c_pagePool.setSize(10);
- c_preparePool.setSize(1); // one parallel prepare at a time
- c_preparedOperationPool.setSize(5); // three hardcoded, two for test
- c_operationPool.setSize(64); // 64 parallel operations
- c_transactionPool.setSize(32); // 16 parallel transactions
- c_attrMappingPool.setSize(100);
- c_dataBufPool.setSize(6000); // 6000*11*4 = 264K > 8k+8k*16 = 256k
- {
- SLList<Prepare> tmp(c_preparePool);
- PreparePtr ptr;
- while(tmp.seize(ptr))
- new (ptr.p) Prepare(c_pagePool);
- tmp.release();
- }
- {
- SLList<Operation> tmp(c_operationPool);
- OperationPtr ptr;
- while(tmp.seize(ptr))
- new (ptr.p) Operation(c_dataBufPool, c_dataBufPool, c_dataBufPool);
- tmp.release();
- }
- {
- SLList<PreparedOperation> tmp(c_preparedOperationPool);
- PreparedOperationPtr ptr;
- while(tmp.seize(ptr))
- new (ptr.p) PreparedOperation(c_attrMappingPool,
- c_dataBufPool, c_dataBufPool);
- tmp.release();
- }
- {
- SLList<Transaction> tmp(c_transactionPool);
- TransactionPtr ptr;
- while(tmp.seize(ptr))
- new (ptr.p) Transaction(c_pagePool, c_operationPool);
- tmp.release();
- }
-
- c_lockQueuePool.setSize(5);
- c_lockElementPool.setSize(5);
- c_lockQueues.setSize(8);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-DbUtil::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- const Uint32 startphase = signal->theData[1];
-
- if(startphase == 1){
- c_transId[0] = (number() << 20) + (getOwnNodeId() << 8);
- c_transId[1] = 0;
- }
-
- if(startphase == 6){
- hardcodedPrepare();
- connectTc(signal);
- }
-
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 6;
- signal->theData[5] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
-
- return;
-}
-
-void
-DbUtil::execNDB_STTOR(Signal* signal)
-{
- (void)signal; // Don't want compiler warning
-
- jamEntry();
-}
-
-
-/***************************
- * Seize a number of TC records
- * to use for Util transactions
- */
-
-void
-DbUtil::connectTc(Signal* signal){
-
- TransactionPtr ptr;
- while(c_seizingTransactions.seize(ptr)){
- signal->theData[0] = ptr.i << 1; // See TcCommitConf
- signal->theData[1] = reference();
- sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB);
- }
-}
-
-void
-DbUtil::execTCSEIZECONF(Signal* signal){
- jamEntry();
-
- TransactionPtr ptr;
- ptr.i = signal->theData[0] >> 1;
- c_seizingTransactions.getPtr(ptr, signal->theData[0] >> 1);
- ptr.p->connectPtr = signal->theData[1];
-
- c_seizingTransactions.release(ptr);
-}
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Misc
- * ------------------------------------------------------------------------
- *
- * ContinueB, Dump
- **************************************************************************/
-
-void
-DbUtil::execCONTINUEB(Signal* signal){
- jamEntry();
- const Uint32 Tdata0 = signal->theData[0];
-
- switch(Tdata0){
- default:
- ndbrequire(0);
- }
-}
-
-void
-DbUtil::execDUMP_STATE_ORD(Signal* signal){
- jamEntry();
-
- /****************************************************************************
- * SEQUENCE SERVICE
- *
- * 200 : Simple test of Public Sequence Interface
- * ----------------------------------------------
- * - Sends a SEQUENCE_REQ signal to Util (itself)
- */
- const Uint32 tCase = signal->theData[0];
- if(tCase == 200){
- jam()
- ndbout << "--------------------------------------------------" << endl;
- UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
- Uint32 seqId = 1;
- Uint32 reqTy = UtilSequenceReq::CurrVal;
-
- if(signal->length() > 1) seqId = signal->theData[1];
- if(signal->length() > 2) reqTy = signal->theData[2];
-
- req->senderData = 12;
- req->sequenceId = seqId;
- req->requestType = reqTy;
-
- sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
- signal, UtilSequenceReq::SignalLength, JBB);
- }
-
- /****************************************************************************/
- /* // Obsolete tests, should be rewritten for long signals!!
- if(tCase == 210){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0], 128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete);
- w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
- w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 211){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert);
- w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
- w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
- w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 212){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update);
- w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
- w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
- w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 213){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read);
- w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
- w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 214){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0], 128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete);
- w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
- w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 215){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert);
- w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
- w.add(UtilPrepareReq::AttributeId, (unsigned int)0); // SYSKEY_0
- w.add(UtilPrepareReq::AttributeId, 1); // NEXTID
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 216){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update);
- w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
- w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
- w.add(UtilPrepareReq::AttributeId, 1); // NEXTID
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- if(tCase == 217){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read);
- w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
- w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
- Uint32 length = w.getWordsUsed();
- ndbassert(length <= pageSizeInWords);
-
- sendUtilPrepareReqSignals(signal, propPage, length);
- }
- */
- /****************************************************************************/
- /* // Obsolete tests, should be rewritten for long signals!!
- if(tCase == 220){
- jam();
- ndbout << "--------------------------------------------------" << endl;
- Uint32 prepI = signal->theData[1];
- Uint32 length = signal->theData[2];
- Uint32 attributeValue0 = signal->theData[3];
- Uint32 attributeValue1a = signal->theData[4];
- Uint32 attributeValue1b = signal->theData[5];
- ndbrequire(prepI != 0);
-
- UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtrSend();
-
- req->senderData = 221;
- req->prepareId = prepI;
- req->totalDataLen = length; // Including headers
- req->offset = 0;
-
- AttributeHeader::init(&req->attrData[0], 0, 1); // AttrNo 0, DataSize
- req->attrData[1] = attributeValue0; // AttrValue
- AttributeHeader::init(&req->attrData[2], 1, 2); // AttrNo 1, DataSize
- req->attrData[3] = attributeValue1a; // AttrValue
- req->attrData[4] = attributeValue1b; // AttrValue
-
- printUTIL_EXECUTE_REQ(stdout, signal->getDataPtrSend(), 3 + 5,0);
- sendSignal(DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal, 3 + 5, JBB);
- }
-*/
- /****************************************************************************
- * 230 : PRINT STATE
- */
-#ifdef ARRAY_GUARD
- if(tCase == 230){
- jam();
-
- ndbout << "--------------------------------------------------" << endl;
- if (signal->length() <= 1) {
- ndbout << "Usage: DUMP 230 <recordType> <recordNo>" << endl
- << "[1] Print Prepare (running) records" << endl
- << "[2] Print PreparedOperation records" << endl
- << "[3] Print Transaction records" << endl
- << "[4] Print Operation records" << endl
- << "Ex. \"dump 230 1 2\" prints Prepare record no 2." << endl
- << endl
- << "210 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0" << endl
- << "211 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID" << endl
- << "212 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID" << endl
- << "213 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0" << endl
- << "214 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0 using id" << endl
- << "215 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID using id" << endl
- << "216 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID using id" << endl
- << "217 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0 using id" << endl
- << "220 : EXECUTE_REQ <PrepId> <Len> <Val1> <Val2a> <Val2b>" <<endl
- << "299 : Crash system (using ndbrequire(0))"
- << endl
- << "Ex. \"dump 220 3 5 1 0 17 \" prints Prepare record no 2."
- << endl;
- return;
- }
-
- switch (signal->theData[1]) {
- case 1:
- // ** Print a specific record **
- if (signal->length() >= 3) {
- PreparePtr prepPtr;
- if (!c_preparePool.isSeized(signal->theData[2])) {
- ndbout << "Prepare Id: " << signal->theData[2]
- << " (Not seized!)" << endl;
- } else {
- c_preparePool.getPtr(prepPtr, signal->theData[2]);
- prepPtr.p->print();
- }
- return;
- }
-
- // ** Print all records **
- PreparePtr prepPtr;
- if (!c_runningPrepares.first(prepPtr)) {
- ndbout << "No Prepare records exist" << endl;
- return;
- }
-
- while (!prepPtr.isNull()) {
- prepPtr.p->print();
- c_runningPrepares.next(prepPtr);
- }
- return;
-
- case 2:
- // ** Print a specific record **
- if (signal->length() >= 3) {
- if (!c_preparedOperationPool.isSeized(signal->theData[2])) {
- ndbout << "PreparedOperation Id: " << signal->theData[2]
- << " (Not seized!)" << endl;
- return;
- }
- ndbout << "PreparedOperation Id: " << signal->theData[2] << endl;
- PreparedOperationPtr prepOpPtr;
- c_preparedOperationPool.getPtr(prepOpPtr, signal->theData[2]);
- prepOpPtr.p->print();
- return;
- }
-
- // ** Print all records **
-#if 0 // not implemented
- PreparedOperationPtr prepOpPtr;
- if (!c_runningPreparedOperations.first(prepOpPtr)) {
- ndbout << "No PreparedOperations exist" << endl;
- return;
- }
- while (!prepOpPtr.isNull()) {
- ndbout << "[-PreparedOperation no " << prepOpPtr.i << ":";
- prepOpPtr.p->print();
- ndbout << "]";
- c_runningPreparedOperations.next(prepOpPtr);
- }
-#endif
- return;
-
- case 3:
- // ** Print a specific record **
- if (signal->length() >= 3) {
- ndbout << "Print specific record not implemented." << endl;
- return;
- }
-
- // ** Print all records **
- ndbout << "Print all records not implemented, specify an Id." << endl;
- return;
-
- case 4:
- ndbout << "Not implemented" << endl;
- return;
-
- default:
- ndbout << "Unknown input (try without any data)" << endl;
- return;
- }
- }
-#endif
- if(tCase == 240 && signal->getLength() == 2){
- MutexManager::ActiveMutexPtr ptr;
- ndbrequire(c_mutexMgr.seize(ptr));
- ptr.p->m_mutexId = signal->theData[1];
- Callback c = { safe_cast(&DbUtil::mutex_created), ptr.i };
- ptr.p->m_callback = c;
- c_mutexMgr.create(signal, ptr);
- ndbout_c("c_mutexMgr.create ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
- }
-
- if(tCase == 241 && signal->getLength() == 2){
- MutexManager::ActiveMutexPtr ptr;
- ndbrequire(c_mutexMgr.seize(ptr));
- ptr.p->m_mutexId = signal->theData[1];
- Callback c = { safe_cast(&DbUtil::mutex_locked), ptr.i };
- ptr.p->m_callback = c;
- c_mutexMgr.lock(signal, ptr);
- ndbout_c("c_mutexMgr.lock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
- }
-
- if(tCase == 242 && signal->getLength() == 2){
- MutexManager::ActiveMutexPtr ptr;
- ptr.i = signal->theData[1];
- c_mutexMgr.getPtr(ptr);
- Callback c = { safe_cast(&DbUtil::mutex_unlocked), ptr.i };
- ptr.p->m_callback = c;
- c_mutexMgr.unlock(signal, ptr);
- ndbout_c("c_mutexMgr.unlock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
- }
-
- if(tCase == 243 && signal->getLength() == 3){
- MutexManager::ActiveMutexPtr ptr;
- ndbrequire(c_mutexMgr.seize(ptr));
- ptr.p->m_mutexId = signal->theData[1];
- ptr.p->m_mutexKey = signal->theData[2];
- Callback c = { safe_cast(&DbUtil::mutex_destroyed), ptr.i };
- ptr.p->m_callback = c;
- c_mutexMgr.destroy(signal, ptr);
- ndbout_c("c_mutexMgr.destroy ptrI=%d mutexId=%d key=%d",
- ptr.i, ptr.p->m_mutexId, ptr.p->m_mutexKey);
- }
-}
-
-void
-DbUtil::mutex_created(Signal* signal, Uint32 ptrI, Uint32 retVal){
- MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
- c_mutexMgr.getPtr(ptr);
- ndbout_c("mutex_created - mutexId=%d, retVal=%d",
- ptr.p->m_mutexId, retVal);
- c_mutexMgr.release(ptrI);
-}
-
-void
-DbUtil::mutex_destroyed(Signal* signal, Uint32 ptrI, Uint32 retVal){
- MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
- c_mutexMgr.getPtr(ptr);
- ndbout_c("mutex_destroyed - mutexId=%d, retVal=%d",
- ptr.p->m_mutexId, retVal);
- c_mutexMgr.release(ptrI);
-}
-
-void
-DbUtil::mutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
- MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
- c_mutexMgr.getPtr(ptr);
- ndbout_c("mutex_locked - mutexId=%d, retVal=%d key=%d ptrI=%d",
- ptr.p->m_mutexId, retVal, ptr.p->m_mutexKey, ptrI);
- if(retVal)
- c_mutexMgr.release(ptrI);
-}
-
-void
-DbUtil::mutex_unlocked(Signal* signal, Uint32 ptrI, Uint32 retVal){
- MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
- c_mutexMgr.getPtr(ptr);
- ndbout_c("mutex_unlocked - mutexId=%d, retVal=%d",
- ptr.p->m_mutexId, retVal);
- if(!retVal)
- c_mutexMgr.release(ptrI);
-}
-
-void
-DbUtil::execUTIL_SEQUENCE_REF(Signal* signal){
- jamEntry();
- ndbout << "UTIL_SEQUENCE_REF" << endl;
- printUTIL_SEQUENCE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
-}
-
-void
-DbUtil::execUTIL_SEQUENCE_CONF(Signal* signal){
- jamEntry();
- ndbout << "UTIL_SEQUENCE_CONF" << endl;
- printUTIL_SEQUENCE_CONF(stdout, signal->getDataPtrSend(), signal->length(),0);
-}
-
-void
-DbUtil::execUTIL_PREPARE_CONF(Signal* signal){
- jamEntry();
- ndbout << "UTIL_PREPARE_CONF" << endl;
- printUTIL_PREPARE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0);
-}
-
-void
-DbUtil::execUTIL_PREPARE_REF(Signal* signal){
- jamEntry();
- ndbout << "UTIL_PREPARE_REF" << endl;
- printUTIL_PREPARE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
-}
-
-void
-DbUtil::execUTIL_EXECUTE_CONF(Signal* signal) {
- jamEntry();
- ndbout << "UTIL_EXECUTE_CONF" << endl;
- printUTIL_EXECUTE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0);
-}
-
-void
-DbUtil::execUTIL_EXECUTE_REF(Signal* signal) {
- jamEntry();
-
- ndbout << "UTIL_EXECUTE_REF" << endl;
- printUTIL_EXECUTE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
-}
-
-void
-DbUtil::execUTIL_RELEASE_CONF(Signal* signal) {
- jamEntry();
- ndbout << "UTIL_RELEASE_CONF" << endl;
-}
-
-void
-DbUtil::execUTIL_RELEASE_REF(Signal* signal) {
- jamEntry();
-
- ndbout << "UTIL_RELEASE_REF" << endl;
-}
-
-void
-DbUtil::sendUtilPrepareRef(Signal* signal, UtilPrepareRef::ErrorCode error,
- Uint32 recipient, Uint32 senderData){
- UtilPrepareRef * ref = (UtilPrepareRef *)signal->getDataPtrSend();
- ref->errorCode = error;
- ref->senderData = senderData;
-
- sendSignal(recipient, GSN_UTIL_PREPARE_REF, signal,
- UtilPrepareRef::SignalLength, JBB);
-}
-
-void
-DbUtil::sendUtilExecuteRef(Signal* signal, UtilExecuteRef::ErrorCode error,
- Uint32 TCerror, Uint32 recipient, Uint32 senderData){
-
- UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->errorCode = error;
- ref->TCErrorCode = TCerror;
-
- sendSignal(recipient, GSN_UTIL_EXECUTE_REF, signal,
- UtilPrepareRef::SignalLength, JBB);
-}
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Prepare service
- * ------------------------------------------------------------------------
- *
- * Prepares a transaction by storing info in some structs
- **************************************************************************/
-
-void
-DbUtil::execUTIL_PREPARE_REQ(Signal* signal)
-{
- jamEntry();
-
- /****************
- * Decode Signal
- ****************/
- UtilPrepareReq * req = (UtilPrepareReq *)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
-
- if(signal->getNoOfSections() == 0) {
- // Missing prepare data
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal, UtilPrepareRef::MISSING_PROPERTIES_SECTION,
- senderRef, senderData);
- return;
- }
-
- PreparePtr prepPtr;
- SegmentedSectionPtr ptr;
-
- jam();
- if(!c_runningPrepares.seize(prepPtr)) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR,
- senderRef, senderData);
- return;
- };
- signal->getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION);
- const Uint32 noPages = (ptr.sz + sizeof(Page32)) / sizeof(Page32);
- ndbassert(noPages > 0);
- if (!prepPtr.p->preparePages.seize(noPages)) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR,
- senderRef, senderData);
- c_preparePool.release(prepPtr);
- return;
- }
- // Save SimpleProperties
- Uint32* target = &prepPtr.p->preparePages.getPtr(0)->data[0];
- copy(target, ptr);
- prepPtr.p->prepDataLen = ptr.sz;
- // Release long signal sections
- releaseSections(signal);
- // Check table properties with DICT
- SimplePropertiesSectionReader reader(ptr, getSectionSegmentPool());
- prepPtr.p->clientRef = senderRef;
- prepPtr.p->clientData = senderData;
- // Release long signal sections
- releaseSections(signal);
- readPrepareProps(signal, &reader, prepPtr.i);
-}
-
-void DbUtil::readPrepareProps(Signal* signal,
- SimpleProperties::Reader* reader,
- Uint32 senderData)
-{
- jam();
-#if 0
- printf("DbUtil::readPrepareProps: Received SimpleProperties:\n");
- reader->printAll(ndbout);
-#endif
- ndbrequire(reader->first());
- ndbrequire(reader->getKey() == UtilPrepareReq::NoOfOperations);
- ndbrequire(reader->getUint32() == 1); // Only one op/trans implemented
-
- ndbrequire(reader->next());
- ndbrequire(reader->getKey() == UtilPrepareReq::OperationType);
-
- ndbrequire(reader->next());
- UtilPrepareReq::KeyValue tableKey =
- (UtilPrepareReq::KeyValue) reader->getKey();
- ndbrequire((tableKey == UtilPrepareReq::TableName) ||
- (tableKey == UtilPrepareReq::TableId));
-
- /************************
- * Ask Dict for metadata
- ************************/
- {
- GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- if (tableKey == UtilPrepareReq::TableName) {
- jam();
- char tableName[MAX_TAB_NAME_SIZE];
- req->requestType = GetTabInfoReq::RequestByName |
- GetTabInfoReq::LongSignalConf;
-
- req->tableNameLen = reader->getValueLen(); // Including trailing \0
-
- /********************************************
- * Code signal data and send signals to DICT
- ********************************************/
-
- ndbrequire(req->tableNameLen < MAX_TAB_NAME_SIZE);
- reader->getString((char*)tableName);
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)tableName;
- ptr[0].sz = req->tableNameLen;
- sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB, ptr,1);
-
- }
- else { // (tableKey == UtilPrepareReq::TableId)
- jam();
- req->requestType = GetTabInfoReq::RequestById |
- GetTabInfoReq::LongSignalConf;
- req->tableId = reader->getUint32();
- sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- }
-
- }
-}
-
-/**
- * @note We assume that this signal comes due to a request related
- * to a Prepare struct. DictTabInfo:s 'senderData' denotes
- * the Prepare struct related to the request.
- */
-void
-DbUtil::execGET_TABINFO_CONF(Signal* signal){
- jamEntry();
-
- if(!assembleFragments(signal)){
- jam();
- return;
- }
-
- /****************
- * Decode signal
- ****************/
- GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
- const Uint32 prepI = conf->senderData;
- const Uint32 totalLen = conf->totalLen;
-
- SegmentedSectionPtr dictTabInfoPtr;
- signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
- ndbrequire(dictTabInfoPtr.sz == totalLen);
-
- PreparePtr prepPtr;
- c_runningPrepares.getPtr(prepPtr, prepI);
- prepareOperation(signal, prepPtr);
-}
-
-void
-DbUtil::execGET_TABINFOREF(Signal* signal){
- jamEntry();
-
- GetTabInfoRef * ref = (GetTabInfoRef *)signal->getDataPtr();
- Uint32 prepI = ref->senderData;
-#define EVENT_DEBUG
-#if 0 //def EVENT_DEBUG
- ndbout << "Signal GET_TABINFOREF received." << endl;
- ndbout << "Error Code: " << ref->errorCode << endl;
-
- switch (ref->errorCode) {
- case GetTabInfoRef::InvalidTableId:
- ndbout << " Msg: Invalid table id" << endl;
- break;
- case GetTabInfoRef::TableNotDefined:
- ndbout << " Msg: Table not defined" << endl;
- break;
- case GetTabInfoRef::TableNameToLong:
- ndbout << " Msg: Table node too long" << endl;
- break;
- default:
- ndbout << " Msg: Unknown error returned from Dict" << endl;
- break;
- }
-#endif
-
- PreparePtr prepPtr;
- c_runningPrepares.getPtr(prepPtr, prepI);
-
- sendUtilPrepareRef(signal, UtilPrepareRef::DICT_TAB_INFO_ERROR,
- prepPtr.p->clientRef, prepPtr.p->clientData);
-
- releasePrepare(prepPtr);
-}
-
-
-/******************************************************************************
- * Prepare Operation
- *
- * Using a prepare record, prepare an operation (i.e. create PreparedOperation).
- * Info from both Pepare request (PreparePages) and DictTabInfo is used.
- *
- * Algorithm:
- * -# Seize AttrbuteMapping
- * - Lookup in preparePages how many attributes should be prepared
- * - Seize AttributeMapping
- * -# For each attributes in preparePages
- * - Lookup id and isPK in dictInfoPages
- * - Store "no -> (AttributeId, Position)" in AttributeMapping
- * -# For each map in AttributeMapping
- * - if (isPK) then assign offset
- ******************************************************************************/
-void
-DbUtil::prepareOperation(Signal* signal, PreparePtr prepPtr)
-{
- jam();
-
- /*******************************************
- * Seize and store PreparedOperation struct
- *******************************************/
- PreparedOperationPtr prepOpPtr;
- if(!c_preparedOperationPool.seize(prepOpPtr)) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal, UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR,
- prepPtr.p->clientRef, prepPtr.p->clientData);
- releasePrepare(prepPtr);
- return;
- }
- prepPtr.p->prepOpPtr = prepOpPtr;
-
- /********************
- * Read request info
- ********************/
- SimplePropertiesLinearReader prepPagesReader(&prepPtr.p->preparePages.getPtr(0)->data[0],
- prepPtr.p->prepDataLen);
-
- ndbrequire(prepPagesReader.first());
- ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::NoOfOperations);
- const Uint32 noOfOperations = prepPagesReader.getUint32();
- ndbrequire(noOfOperations == 1);
-
- ndbrequire(prepPagesReader.next());
- ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::OperationType);
- const Uint32 operationType = prepPagesReader.getUint32();
-
- ndbrequire(prepPagesReader.next());
-
- char tableName[MAX_TAB_NAME_SIZE];
- Uint32 tableId;
- UtilPrepareReq::KeyValue tableKey =
- (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
- if (tableKey == UtilPrepareReq::TableId) {
- jam();
- tableId = prepPagesReader.getUint32();
- }
- else {
- jam();
- ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::TableName);
- ndbrequire(prepPagesReader.getValueLen() <= MAX_TAB_NAME_SIZE);
- prepPagesReader.getString(tableName);
- }
- /******************************************************************
- * Seize AttributeMapping (by counting no of attribs in prepPages)
- ******************************************************************/
- Uint32 noOfAttributes = 0; // No of attributes in PreparePages (used later)
- while(prepPagesReader.next()) {
- if (tableKey == UtilPrepareReq::TableName) {
- jam();
- ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeName);
- } else {
- jam();
- ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeId);
- }
- noOfAttributes++;
- }
- ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.seize(noOfAttributes));
- if (operationType == UtilPrepareReq::Read) {
- ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.seize(noOfAttributes));
- }
- /***************************************
- * For each attribute name, lookup info
- ***************************************/
- // Goto start of attribute names
- ndbrequire(prepPagesReader.first() && prepPagesReader.next() &&
- prepPagesReader.next());
-
- DictTabInfo::Table tableDesc; tableDesc.init();
- AttrMappingBuffer::DataBufferIterator attrMappingIt;
- ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.first(attrMappingIt));
-
- ResultSetBuffer::DataBufferIterator rsInfoIt;
- if (operationType == UtilPrepareReq::Read) {
- ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.first(rsInfoIt));
- }
-
- Uint32 noOfPKAttribsStored = 0;
- Uint32 noOfNonPKAttribsStored = 0;
- Uint32 attrLength = 0;
- Uint32 pkAttrLength = 0;
- char attrNameRequested[MAX_ATTR_NAME_SIZE];
- Uint32 attrIdRequested;
-
- while(prepPagesReader.next()) {
- UtilPrepareReq::KeyValue attributeKey =
- (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
-
- ndbrequire((attributeKey == UtilPrepareReq::AttributeName) ||
- (attributeKey == UtilPrepareReq::AttributeId));
- if (attributeKey == UtilPrepareReq::AttributeName) {
- jam();
- ndbrequire(prepPagesReader.getValueLen() <= MAX_ATTR_NAME_SIZE);
-
- prepPagesReader.getString(attrNameRequested);
- attrIdRequested= ~0u;
- } else {
- jam();
- attrIdRequested = prepPagesReader.getUint32();
- }
- /*****************************************
- * Copy DictTabInfo into tableDesc struct
- *****************************************/
-
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
- SimplePropertiesSectionReader dictInfoReader(ptr, getSectionSegmentPool());
-
- SimpleProperties::UnpackStatus unpackStatus;
- unpackStatus = SimpleProperties::unpack(dictInfoReader, &tableDesc,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
- ndbrequire(unpackStatus == SimpleProperties::Break);
-
- /************************
- * Lookup in DictTabInfo
- ************************/
- DictTabInfo::Attribute attrDesc; attrDesc.init();
- char attrName[MAX_ATTR_NAME_SIZE];
- Uint32 attrId= ~(Uint32)0;
- bool attributeFound = false;
- Uint32 noOfKeysFound = 0; // # PK attrs found before attr in DICTdata
- Uint32 noOfNonKeysFound = 0; // # nonPK attrs found before attr in DICTdata
- for (Uint32 i=0; i<tableDesc.NoOfAttributes; i++) {
- if (tableKey == UtilPrepareReq::TableName) {
- jam();
- ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeName);
- ndbrequire(dictInfoReader.getValueLen() <= MAX_ATTR_NAME_SIZE);
- dictInfoReader.getString(attrName);
- attrId= ~(Uint32)0; // attrId not used
- } else { // (tableKey == UtilPrepareReq::TableId)
- jam();
- dictInfoReader.next(); // Skip name
- ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeId);
- attrId = dictInfoReader.getUint32();
- attrName[0]= '\0'; // attrName not used
- }
- unpackStatus = SimpleProperties::unpack(dictInfoReader, &attrDesc,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
- ndbrequire(unpackStatus == SimpleProperties::Break);
- //attrDesc.print(stdout);
-
- if (attrDesc.AttributeKeyFlag) { jam(); noOfKeysFound++; }
- else { jam(); noOfNonKeysFound++; }
- if (attributeKey == UtilPrepareReq::AttributeName) {
- if (strcmp(attrName, attrNameRequested) == 0) {
- attributeFound = true;
- break;
- }
- }
- else // (attributeKey == UtilPrepareReq::AttributeId)
- if (attrId == attrIdRequested) {
- attributeFound = true;
- break;
- }
-
- // Move to next attribute
- ndbassert(dictInfoReader.getKey() == DictTabInfo::AttributeEnd);
- dictInfoReader.next();
- }
-
- /**********************
- * Attribute not found
- **********************/
- if (!attributeFound) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal,
- UtilPrepareRef::DICT_TAB_INFO_ERROR,
- prepPtr.p->clientRef, prepPtr.p->clientData);
- infoEvent("UTIL: Unknown attribute requested: %s in table: %s",
- attrNameRequested, tableName);
- releasePreparedOperation(prepOpPtr);
- releasePrepare(prepPtr);
- return;
- }
-
- /**************************************************************
- * Attribute found - store in mapping (AttributeId, Position)
- **************************************************************/
- AttributeHeader attrMap(attrDesc.AttributeId, // 1. Store AttrId
- 0);
-
- if (attrDesc.AttributeKeyFlag) {
- // ** Attribute belongs to PK **
- prepOpPtr.p->pkBitmask.set(attrDesc.AttributeId);
- attrMap.setDataSize(noOfKeysFound - 1); // 2. Store Position
- noOfPKAttribsStored++;
- } else {
- attrMap.setDataSize(0x3fff); // 2. Store Position (fake)
- noOfNonPKAttribsStored++;
-
- /***********************************************************
- * Error: Read nonPK Attr before all PK attr have been read
- ***********************************************************/
- if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal,
- UtilPrepareRef::DICT_TAB_INFO_ERROR,
- prepPtr.p->clientRef, prepPtr.p->clientData);
- infoEvent("UTIL: Non-PK attr not allowed before "
- "all PK attrs have been defined, table: %s",
- tableName);
- releasePreparedOperation(prepOpPtr);
- releasePrepare(prepPtr);
- return;
- }
- }
- *(attrMappingIt.data) = attrMap.m_value;
-#if 0
- ndbout << "BEFORE: attrLength: " << attrLength << endl;
-#endif
- {
- int len = 0;
- switch (attrDesc.AttributeSize) {
- case DictTabInfo::an8Bit:
- len = (attrDesc.AttributeArraySize + 3)/ 4;
- break;
- case DictTabInfo::a16Bit:
- len = (attrDesc.AttributeArraySize + 1) / 2;
- break;
- case DictTabInfo::a32Bit:
- len = attrDesc.AttributeArraySize;
- break;
- case DictTabInfo::a64Bit:
- len = attrDesc.AttributeArraySize * 2;
- break;
- case DictTabInfo::a128Bit:
- len = attrDesc.AttributeArraySize * 4;
- break;
- }
- attrLength += len;
- if (attrDesc.AttributeKeyFlag)
- pkAttrLength += len;
-
- if (operationType == UtilPrepareReq::Read) {
- AttributeHeader::init(rsInfoIt.data,
- attrDesc.AttributeId, // 1. Store AttrId
- len << 2);
- prepOpPtr.p->rsInfo.next(rsInfoIt, 1);
- }
- }
-#if 0
- ndbout << ": AttributeSize: " << attrDesc.AttributeSize << endl;
- ndbout << ": AttributeArraySize: " << attrDesc.AttributeArraySize << endl;
- ndbout << "AFTER: attrLength: " << attrLength << endl;
-#endif
- //attrMappingIt.print(stdout);
- //prepPtr.p->prepOpPtr.p->attrMapping.print(stdout);
- prepPtr.p->prepOpPtr.p->attrMapping.next(attrMappingIt, 1);
- }
-
- /***************************
- * Error: Not all PKs found
- ***************************/
- if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
- jam();
- releaseSections(signal);
- sendUtilPrepareRef(signal,
- UtilPrepareRef::DICT_TAB_INFO_ERROR,
- prepPtr.p->clientRef, prepPtr.p->clientData);
- infoEvent("UTIL: Not all primary key attributes requested for table: %s",
- tableName);
- releasePreparedOperation(prepOpPtr);
- releasePrepare(prepPtr);
- return;
- }
-
-#if 0
- AttrMappingBuffer::ConstDataBufferIterator tmpIt;
- for (prepPtr.p->prepOpPtr.p->attrMapping.first(tmpIt); tmpIt.curr.i != RNIL;
- prepPtr.p->prepOpPtr.p->attrMapping.next(tmpIt)) {
- AttributeHeader* ah = (AttributeHeader *) tmpIt.data;
- ah->print(stdout);
- }
-#endif
-
- /**********************************************
- * Preparing of PreparedOperation signal train
- **********************************************/
- Uint32 static_len = TcKeyReq::StaticLength;
- prepOpPtr.p->tckey.tableId = tableDesc.TableId;
- prepOpPtr.p->tckey.tableSchemaVersion = tableDesc.TableVersion;
- prepOpPtr.p->noOfKeyAttr = tableDesc.NoOfKeyAttr;
- prepOpPtr.p->keyLen = tableDesc.KeyLength; // Total no of words in PK
- if (prepOpPtr.p->keyLen > TcKeyReq::MaxKeyInfo) {
- jam();
- prepOpPtr.p->tckeyLenInBytes = (static_len + TcKeyReq::MaxKeyInfo) * 4;
- } else {
- jam();
- prepOpPtr.p->tckeyLenInBytes = (static_len + prepOpPtr.p->keyLen) * 4;
- }
- prepOpPtr.p->keyDataPos = static_len; // Start of keyInfo[] in tckeyreq
-
- Uint32 requestInfo = 0;
- TcKeyReq::setAbortOption(requestInfo, TcKeyReq::AbortOnError);
- TcKeyReq::setKeyLength(requestInfo, tableDesc.KeyLength);
- switch(operationType) {
- case(UtilPrepareReq::Read):
- prepOpPtr.p->rsLen =
- attrLength +
- tableDesc.NoOfKeyAttr +
- noOfNonPKAttribsStored; // Read needs a resultset
- prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
- prepOpPtr.p->tckey.attrLen = prepOpPtr.p->noOfAttr;
- TcKeyReq::setOperationType(requestInfo, ZREAD);
- break;
- case(UtilPrepareReq::Update):
- prepOpPtr.p->rsLen = 0;
- prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
- prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
- TcKeyReq::setOperationType(requestInfo, ZUPDATE);
- break;
- case(UtilPrepareReq::Insert):
- prepOpPtr.p->rsLen = 0;
- prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
- prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
- TcKeyReq::setOperationType(requestInfo, ZINSERT);
- break;
- case(UtilPrepareReq::Delete):
- // The number of attributes should equal the size of the primary key
- ndbrequire(tableDesc.KeyLength == attrLength);
- prepOpPtr.p->rsLen = 0;
- prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr;
- prepOpPtr.p->tckey.attrLen = 0;
- TcKeyReq::setOperationType(requestInfo, ZDELETE);
- break;
- case(UtilPrepareReq::Write):
- prepOpPtr.p->rsLen = 0;
- prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
- prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
- TcKeyReq::setOperationType(requestInfo, ZWRITE);
- break;
- }
- TcKeyReq::setAIInTcKeyReq(requestInfo, 0); // Attrinfo sent separately
- prepOpPtr.p->tckey.requestInfo = requestInfo;
-
- /****************************
- * Confirm completed prepare
- ****************************/
- UtilPrepareConf * conf = (UtilPrepareConf *)signal->getDataPtr();
- conf->senderData = prepPtr.p->clientData;
- conf->prepareId = prepPtr.p->prepOpPtr.i;
-
- releaseSections(signal);
- sendSignal(prepPtr.p->clientRef, GSN_UTIL_PREPARE_CONF, signal,
- UtilPrepareConf::SignalLength, JBB);
-
-#if 0
- prepPtr.p->prepOpPtr.p->print();
-#endif
- releasePrepare(prepPtr);
-}
-
-
-void
-DbUtil::execUTIL_RELEASE_REQ(Signal* signal){
- jamEntry();
-
- UtilReleaseReq * req = (UtilReleaseReq *)signal->getDataPtr();
- const Uint32 clientRef = signal->senderBlockRef();
- const Uint32 prepareId = req->prepareId;
- const Uint32 senderData = req->senderData;
-
-#if 0
- /**
- * This only works in when ARRAY_GUARD is defined (debug-mode)
- */
- if (!c_preparedOperationPool.isSeized(prepareId)) {
- UtilReleaseRef * ref = (UtilReleaseRef *)signal->getDataPtr();
- ref->prepareId = prepareId;
- ref->errorCode = UtilReleaseRef::NO_SUCH_PREPARE_SEIZED;
- sendSignal(clientRef, GSN_UTIL_RELEASE_REF, signal,
- UtilReleaseRef::SignalLength, JBB);
- }
-#endif
- PreparedOperationPtr prepOpPtr;
- c_preparedOperationPool.getPtr(prepOpPtr, prepareId);
-
- releasePreparedOperation(prepOpPtr);
-
- UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend();
- conf->senderData = senderData;
- sendSignal(clientRef, GSN_UTIL_RELEASE_CONF, signal,
- UtilReleaseConf::SignalLength, JBB);
-}
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Sequence Service
- * ------------------------------------------------------------------------
- *
- * A service with a stored incrementable number
- **************************************************************************/
-
-void
-DbUtil::hardcodedPrepare() {
- /**
- * Prepare SequenceCurrVal (READ)
- */
- {
- PreparedOperationPtr ptr;
- ndbrequire(c_preparedOperationPool.seizeId(ptr, 0));
- ptr.p->keyLen = 1;
- ptr.p->tckey.attrLen = 1;
- ptr.p->rsLen = 3;
- ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength +
- ptr.p->keyLen + ptr.p->tckey.attrLen) * 4;
- ptr.p->keyDataPos = TcKeyReq::StaticLength;
- ptr.p->tckey.tableId = 0;
- Uint32 requestInfo = 0;
- TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
- TcKeyReq::setOperationType(requestInfo, ZREAD);
- TcKeyReq::setKeyLength(requestInfo, 1);
- TcKeyReq::setAIInTcKeyReq(requestInfo, 1);
- ptr.p->tckey.requestInfo = requestInfo;
- ptr.p->tckey.tableSchemaVersion = 1;
-
- // This is actually attr data
- AttributeHeader::init(&ptr.p->tckey.distrGroupHashValue, 1, 0);
-
- ndbrequire(ptr.p->rsInfo.seize(1));
- ResultSetInfoBuffer::DataBufferIterator it;
- ptr.p->rsInfo.first(it);
- AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words
- }
-
- /**
- * Prepare SequenceNextVal (UPDATE)
- */
- {
- PreparedOperationPtr ptr;
- ndbrequire(c_preparedOperationPool.seizeId(ptr, 1));
- ptr.p->keyLen = 1;
- ptr.p->rsLen = 3;
- ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + ptr.p->keyLen + 5) * 4;
- ptr.p->keyDataPos = TcKeyReq::StaticLength;
- ptr.p->tckey.attrLen = 11;
- ptr.p->tckey.tableId = 0;
- Uint32 requestInfo = 0;
- TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
- TcKeyReq::setOperationType(requestInfo, ZUPDATE);
- TcKeyReq::setKeyLength(requestInfo, 1);
- TcKeyReq::setAIInTcKeyReq(requestInfo, 5);
- TcKeyReq::setInterpretedFlag(requestInfo, 1);
- ptr.p->tckey.requestInfo = requestInfo;
- ptr.p->tckey.tableSchemaVersion = 1;
-
- // Signal is packed, which is why attrInfo is at distrGroupHashValue
- // position
- Uint32 * attrInfo = &ptr.p->tckey.distrGroupHashValue;
- attrInfo[0] = 0; // IntialReadSize
- attrInfo[1] = 5; // InterpretedSize
- attrInfo[2] = 0; // FinalUpdateSize
- attrInfo[3] = 1; // FinalReadSize
- attrInfo[4] = 0; // SubroutineSize
-
- { // AttrInfo
- ndbrequire(ptr.p->attrInfo.seize(6));
- AttrInfoBuffer::DataBufferIterator it;
- ptr.p->attrInfo.first(it);
- * it.data = Interpreter::Read(1, 6);
- ndbrequire(ptr.p->attrInfo.next(it));
- * it.data = Interpreter::LoadConst16(7, 1);
- ndbrequire(ptr.p->attrInfo.next(it));
- * it.data = Interpreter::Add(7, 6, 7);
- ndbrequire(ptr.p->attrInfo.next(it));
- * it.data = Interpreter::Write(1, 7);
- ndbrequire(ptr.p->attrInfo.next(it));
- * it.data = Interpreter::ExitOK();
-
- ndbrequire(ptr.p->attrInfo.next(it));
- AttributeHeader::init(it.data, 1, 0);
- }
-
- { // ResultSet
- ndbrequire(ptr.p->rsInfo.seize(1));
- ResultSetInfoBuffer::DataBufferIterator it;
- ptr.p->rsInfo.first(it);
- AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words
- }
- }
-
- /**
- * Prepare CreateSequence (INSERT)
- */
- {
- PreparedOperationPtr ptr;
- ndbrequire(c_preparedOperationPool.seizeId(ptr, 2));
- ptr.p->keyLen = 1;
- ptr.p->tckey.attrLen = 5;
- ptr.p->rsLen = 0;
- ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength +
- ptr.p->keyLen + ptr.p->tckey.attrLen) * 4;
- ptr.p->keyDataPos = TcKeyReq::StaticLength;
- ptr.p->tckey.tableId = 0;
- Uint32 requestInfo = 0;
- TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
- TcKeyReq::setOperationType(requestInfo, ZINSERT);
- TcKeyReq::setKeyLength(requestInfo, 1);
- TcKeyReq::setAIInTcKeyReq(requestInfo, 0);
- ptr.p->tckey.requestInfo = requestInfo;
- ptr.p->tckey.tableSchemaVersion = 1;
- }
-}
-
-void
-DbUtil::execUTIL_SEQUENCE_REQ(Signal* signal){
- jamEntry();
-
- UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtr();
-
- PreparedOperation * prepOp;
-
- switch(req->requestType){
- case UtilSequenceReq::CurrVal:
- prepOp = c_preparedOperationPool.getPtr(0); //c_SequenceCurrVal
- break;
- case UtilSequenceReq::NextVal:
- prepOp = c_preparedOperationPool.getPtr(1); //c_SequenceNextVal
- break;
- case UtilSequenceReq::Create:
- prepOp = c_preparedOperationPool.getPtr(2); //c_CreateSequence
- break;
- default:
- ndbrequire(false);
- prepOp = 0; // remove warning
- }
-
- /**
- * 1 Transaction with 1 operation
- */
- TransactionPtr transPtr;
- ndbrequire(c_runningTransactions.seize(transPtr));
-
- OperationPtr opPtr;
- ndbrequire(transPtr.p->operations.seize(opPtr));
-
- ndbrequire(opPtr.p->rs.seize(prepOp->rsLen));
- ndbrequire(opPtr.p->keyInfo.seize(prepOp->keyLen));
-
- transPtr.p->gsn = GSN_UTIL_SEQUENCE_REQ;
- transPtr.p->clientRef = signal->senderBlockRef();
- transPtr.p->clientData = req->senderData;
- transPtr.p->sequence.sequenceId = req->sequenceId;
- transPtr.p->sequence.requestType = req->requestType;
-
- opPtr.p->prepOp = prepOp;
- opPtr.p->prepOp_i = RNIL;
-
- KeyInfoBuffer::DataBufferIterator it;
- opPtr.p->keyInfo.first(it);
- it.data[0] = transPtr.p->sequence.sequenceId;
-
- if(req->requestType == UtilSequenceReq::Create){
- ndbrequire(opPtr.p->attrInfo.seize(5));
- AttrInfoBuffer::DataBufferIterator it;
-
- opPtr.p->attrInfo.first(it);
- AttributeHeader::init(it.data, 0, 1 << 2);
-
- ndbrequire(opPtr.p->attrInfo.next(it));
- * it.data = transPtr.p->sequence.sequenceId;
-
- ndbrequire(opPtr.p->attrInfo.next(it));
- AttributeHeader::init(it.data, 1, 2 << 2);
-
- ndbrequire(opPtr.p->attrInfo.next(it));
- * it.data = 0;
-
- ndbrequire(opPtr.p->attrInfo.next(it));
- * it.data = 0;
- }
-
- runTransaction(signal, transPtr);
-}
-
-int
-DbUtil::getResultSet(Signal* signal, const Transaction * transP,
- struct LinearSectionPtr sectionsPtr[]) {
- OperationPtr opPtr;
- ndbrequire(transP->operations.first(opPtr));
- ndbrequire(transP->operations.hasNext(opPtr) == false);
-
- int noAttr = 0;
- int dataSz = 0;
- Uint32* tmpBuf = signal->theData + 25;
- const Uint32* headerBuffer = tmpBuf;
-
- const ResultSetBuffer & rs = opPtr.p->rs;
- ResultSetInfoBuffer::ConstDataBufferIterator it;
-
- // extract headers
- for(rs.first(it); it.curr.i != RNIL; ) {
- *tmpBuf++ = it.data[0];
- rs.next(it, ((AttributeHeader*)&it.data[0])->getDataSize() + 1);
- noAttr++;
- }
-
- if (noAttr == 0)
- return 0;
-
- const Uint32* dataBuffer = tmpBuf;
-
- // extract data
- for(rs.first(it); it.curr.i != RNIL; ) {
- int sz = ((AttributeHeader*)&it.data[0])->getDataSize();
- rs.next(it,1);
- for (int i = 0; i < sz; i++) {
- *tmpBuf++ = *it.data;
- rs.next(it,1);
- dataSz++;
- }
- }
-
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = (Uint32 *)headerBuffer;
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].p = (Uint32 *)dataBuffer;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataSz;
-
- return 1;
-}
-
-void
-DbUtil::reportSequence(Signal* signal, const Transaction * transP){
- OperationPtr opPtr;
- ndbrequire(transP->operations.first(opPtr));
- ndbrequire(transP->operations.hasNext(opPtr) == false);
-
- if(transP->errorCode == 0){
- jam(); // OK
-
- UtilSequenceConf * ret = (UtilSequenceConf *)signal->getDataPtrSend();
- ret->senderData = transP->clientData;
- ret->sequenceId = transP->sequence.sequenceId;
- ret->requestType = transP->sequence.requestType;
-
- bool ok = false;
- switch(transP->sequence.requestType){
- case UtilSequenceReq::CurrVal:
- case UtilSequenceReq::NextVal:{
- ok = true;
- ndbrequire(opPtr.p->rsRecv == 3);
-
- ResultSetBuffer::DataBufferIterator rsit;
- ndbrequire(opPtr.p->rs.first(rsit));
-
- ret->sequenceValue[0] = rsit.data[1];
- ret->sequenceValue[1] = rsit.data[2];
- break;
- }
- case UtilSequenceReq::Create:
- ok = true;
- ret->sequenceValue[0] = 0;
- ret->sequenceValue[1] = 0;
- break;
- }
- ndbrequire(ok);
- sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_CONF, signal,
- UtilSequenceConf::SignalLength, JBB);
- return;
- }
-
- UtilSequenceRef::ErrorCode errCode = UtilSequenceRef::TCError;
-
- switch(transP->sequence.requestType)
- {
- case UtilSequenceReq::CurrVal:
- case UtilSequenceReq::NextVal:{
- if (transP->errorCode == 626)
- errCode = UtilSequenceRef::NoSuchSequence;
- break;
- }
- case UtilSequenceReq::Create:
- break;
- }
-
- UtilSequenceRef * ret = (UtilSequenceRef *)signal->getDataPtrSend();
- ret->senderData = transP->clientData;
- ret->sequenceId = transP->sequence.sequenceId;
- ret->requestType = transP->sequence.requestType;
- ret->errorCode = (Uint32)errCode;
- sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_REF, signal,
- UtilSequenceRef::SignalLength, JBB);
-}
-#if 0
- Ndb ndb("ndb","def");
- NdbConnection* tConnection = ndb.startTransaction();
- NdbOperation* tOperation = tConnection->getNdbOperation("SYSTAB_0");
-
- //#if 0 && API_CODE
- if( tOperation != NULL ) {
- tOperation->interpretedUpdateTuple();
- tOperation->equal((U_Int32)0, keyValue );
- tNextId_Result = tOperation->getValue((U_Int32)1);
- tOperation->incValue((U_Int32)1, (U_Int32)8192);
-
- if (tConnection->execute( Commit ) != -1 ) {
- U_Int64 tValue = tNextId_Result->u_64_value(); // Read result value
- theFirstTransId = tValue;
- theLastTransId = tValue + 8191;
- closeTransaction(tConnection);
- return startTransactionLocal(aPriority, nodeId);
- }
- }
- /**
- * IntialReadSize = 0;
- * InterpretedSize = incValue(1);
- * FinalUpdateSize = 0;
- * FinalReadSize = 1; // Read value
- * SubroutineSize = 0;
- */
-#endif
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Transaction execution request
- * ------------------------------------------------------------------------
- *
- * Handle requests to execute a prepared transaction
- **************************************************************************/
-
-void
-DbUtil::execUTIL_EXECUTE_REQ(Signal* signal)
-{
- jamEntry();
-
- UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtr();
- const Uint32 clientRef = req->senderRef;
- const Uint32 clientData = req->senderData;
- const Uint32 prepareId = req->getPrepareId();
- const bool releaseFlag = req->getReleaseFlag();
-
- if(signal->getNoOfSections() == 0) {
- // Missing prepare data
- jam();
- releaseSections(signal);
- sendUtilExecuteRef(signal, UtilExecuteRef::MissingDataSection,
- 0, clientRef, clientData);
- return;
- }
- /*******************************
- * Get PreparedOperation struct
- *******************************/
- PreparedOperationPtr prepOpPtr;
- c_preparedOperationPool.getPtr(prepOpPtr, prepareId);
-
- prepOpPtr.p->releaseFlag = releaseFlag;
-
- TransactionPtr transPtr;
- OperationPtr opPtr;
- SegmentedSectionPtr headerPtr, dataPtr;
-
- signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
- SectionReader headerReader(headerPtr, getSectionSegmentPool());
- signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
- SectionReader dataReader(dataPtr, getSectionSegmentPool());
-
-#if 0 //def EVENT_DEBUG
- // Debugging
- printf("DbUtil::execUTIL_EXECUTEL_REQ: Headers (%u): ", headerPtr.sz);
- Uint32 word;
- while(headerReader.getWord(&word))
- printf("H'%.8x ", word);
- printf("\n");
- printf("DbUtil::execUTIL_EXECUTEL_REQ: Data (%u): ", dataPtr.sz);
- headerReader.reset();
- while(dataReader.getWord(&word))
- printf("H'%.8x ", word);
- printf("\n");
- dataReader.reset();
-#endif
-
-// Uint32 totalDataLen = headerPtr.sz + dataPtr.sz;
-
- /************************************************************
- * Seize Transaction record
- ************************************************************/
- ndbrequire(c_runningTransactions.seize(transPtr));
- transPtr.p->gsn = GSN_UTIL_EXECUTE_REQ;
- transPtr.p->clientRef = clientRef;
- transPtr.p->clientData = clientData;
- ndbrequire(transPtr.p->operations.seize(opPtr));
- opPtr.p->prepOp = prepOpPtr.p;
- opPtr.p->prepOp_i = prepOpPtr.i;
-
-#if 0 //def EVENT_DEBUG
- printf("opPtr.p->rs.seize( %u )\n", prepOpPtr.p->rsLen);
-#endif
- ndbrequire(opPtr.p->rs.seize(prepOpPtr.p->rsLen));
-
- /***********************************************************
- * Store signal data on linear memory in Transaction record
- ***********************************************************/
- KeyInfoBuffer* keyInfo = &opPtr.p->keyInfo;
- AttrInfoBuffer* attrInfo = &opPtr.p->attrInfo;
- AttributeHeader header;
- Uint32* tempBuf = signal->theData + 25;
- bool dataComplete = true;
-
- while(headerReader.getWord((Uint32 *)&header)) {
- Uint32* bufStart = tempBuf;
- header.insertHeader(tempBuf++);
- for(unsigned int i = 0; i < header.getDataSize(); i++) {
- if (!dataReader.getWord(tempBuf++)) {
- dataComplete = false;
- break;
- }
- }
- bool res = true;
-
-#if 0 //def EVENT_DEBUG
- if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) ==
- TcKeyReq::Read) {
- if(prepOpPtr.p->pkBitmask.get(header.getAttributeId()))
- printf("PrimaryKey\n");
- }
- printf("AttrId %u Hdrsz %d Datasz %u \n",
- header.getAttributeId(),
- header.getHeaderSize(),
- header.getDataSize());
-#endif
-
- if(prepOpPtr.p->pkBitmask.get(header.getAttributeId()))
- // A primary key attribute
- res = keyInfo->append(bufStart + header.getHeaderSize(),
- header.getDataSize());
-
- switch (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo)) {
- case ZREAD:
- res &= attrInfo->append(bufStart, header.getHeaderSize());
- break;
- case ZDELETE:
- // no attrinfo for Delete
- break;
- default:
- res &= attrInfo->append(bufStart,
- header.getHeaderSize() + header.getDataSize());
- }
-
- if (!res) {
- // Failed to allocate buffer data
- jam();
- releaseSections(signal);
- sendUtilExecuteRef(signal, UtilExecuteRef::AllocationError,
- 0, clientRef, clientData);
- releaseTransaction(transPtr);
- return;
- }
- }
- if (!dataComplete) {
- // Missing data in data section
- jam();
- releaseSections(signal);
- sendUtilExecuteRef(signal, UtilExecuteRef::MissingData,
- 0, clientRef, clientData);
- releaseTransaction(transPtr);
- return;
- }
-
- // quick hack for hash index build
- if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){
- prepOpPtr.p->tckey.attrLen =
- prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize();
- TcKeyReq::setKeyLength(prepOpPtr.p->tckey.requestInfo, keyInfo->getSize());
- }
-
-#if 0
- const Uint32 l1 = prepOpPtr.p->tckey.attrLen;
- const Uint32 l2 =
- prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize();
-
- if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){
- ndbrequire(l1 == l2);
- } else {
- ndbout_c("TcKeyReq::Read");
- }
-#endif
-
- releaseSections(signal);
- transPtr.p->noOfRetries = 3;
- runTransaction(signal, transPtr);
-}
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: General transaction machinery
- * ------------------------------------------------------------------------
- * Executes a prepared transaction
- **************************************************************************/
-void
-DbUtil::runTransaction(Signal* signal, TransactionPtr transPtr){
-
- /* Init transaction */
- transPtr.p->sent = 0;
- transPtr.p->recv = 0;
- transPtr.p->errorCode = 0;
- getTransId(transPtr.p);
-
- OperationPtr opPtr;
- ndbrequire(transPtr.p->operations.first(opPtr));
-
- /* First operation */
- Uint32 start = 0;
- TcKeyReq::setStartFlag(start, 1);
- runOperation(signal, transPtr, opPtr, start);
- transPtr.p->sent ++;
-
- /* Rest of operations */
- start = 0;
- while(opPtr.i != RNIL){
- runOperation(signal, transPtr, opPtr, start);
- transPtr.p->sent ++;
- }
- //transPtr.p->print();
-}
-
-void
-DbUtil::runOperation(Signal* signal, TransactionPtr & transPtr,
- OperationPtr & opPtr, Uint32 start) {
- Uint32 opI = opPtr.i;
- Operation * op = opPtr.p;
- const PreparedOperation * pop = op->prepOp;
-
- if(!transPtr.p->operations.next(opPtr)){
- TcKeyReq::setCommitFlag(start, 1); // Last operation
- TcKeyReq::setExecuteFlag(start, 1);
- }
-
-#if 0 //def EVENT_DEBUG
- if (TcKeyReq::getOperationType(pop->tckey.requestInfo) ==
- TcKeyReq::Read) {
- printf("TcKeyReq::Read runOperation\n");
- }
-#endif
-
- /**
- * Init operation w.r.t result set
- */
- initResultSet(op->rs, pop->rsInfo);
- op->rs.first(op->rsIterator);
- op->rsRecv = 0;
-#if 0 //def EVENT_DEBUG
- printf("pop->rsLen %u\n", pop->rsLen);
-#endif
- op->rsExpect = 0;
- op->transPtrI = transPtr.i;
-
- TcKeyReq * tcKey = (TcKeyReq*)signal->getDataPtrSend();
- //ndbout << "*** 6 ***"<< endl; pop->print();
- memcpy(tcKey, &pop->tckey, pop->tckeyLenInBytes);
- //ndbout << "*** 6b ***"<< endl;
- //printTCKEYREQ(stdout, signal->getDataPtrSend(),
- // pop->tckeyLenInBytes >> 2, 0);
- tcKey->apiConnectPtr = transPtr.p->connectPtr;
- tcKey->senderData = opI;
- tcKey->transId1 = transPtr.p->transId[0];
- tcKey->transId2 = transPtr.p->transId[1];
- tcKey->requestInfo |= start;
-
-#if 0 //def EVENT_DEBUG
- // Debugging
- printf("DbUtil::runOperation: KEYINFO\n");
- op->keyInfo.print(stdout);
- printf("DbUtil::runOperation: ATTRINFO\n");
- op->attrInfo.print(stdout);
-#endif
-
- /**
- * Key Info
- */
- //KeyInfoBuffer::DataBufferIterator kit;
- KeyInfoIterator kit;
- op->keyInfo.first(kit);
- Uint32 *keyDst = ((Uint32*)tcKey) + pop->keyDataPos;
- for(Uint32 i = 0; i<8 && kit.curr.i != RNIL; i++, op->keyInfo.next(kit)){
- keyDst[i] = * kit.data;
- }
- //ndbout << "*** 7 ***" << endl;
- //printTCKEYREQ(stdout, signal->getDataPtrSend(),
- // pop->tckeyLenInBytes >> 2, 0);
-
-#if 0 //def EVENT_DEBUG
- printf("DbUtil::runOperation: sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, %d , JBB)\n", pop->tckeyLenInBytes >> 2);
- printTCKEYREQ(stdout, signal->getDataPtr(), pop->tckeyLenInBytes >> 2,0);
-#endif
- sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, pop->tckeyLenInBytes >> 2, JBB);
-
- /**
- * More the 8 words of key info not implemented
- */
- // ndbrequire(kit.curr.i == RNIL); // Yes it is
-
- /**
- * KeyInfo
- */
- KeyInfo* keyInfo = (KeyInfo *)signal->getDataPtrSend();
- keyInfo->connectPtr = transPtr.p->connectPtr;
- keyInfo->transId[0] = transPtr.p->transId[0];
- keyInfo->transId[1] = transPtr.p->transId[1];
- sendKeyInfo(signal, keyInfo, op->keyInfo, kit);
-
- /**
- * AttrInfo
- */
- AttrInfo* attrInfo = (AttrInfo *)signal->getDataPtrSend();
- attrInfo->connectPtr = transPtr.p->connectPtr;
- attrInfo->transId[0] = transPtr.p->transId[0];
- attrInfo->transId[1] = transPtr.p->transId[1];
-
- AttrInfoIterator ait;
- pop->attrInfo.first(ait);
- sendAttrInfo(signal, attrInfo, pop->attrInfo, ait);
-
- op->attrInfo.first(ait);
- sendAttrInfo(signal, attrInfo, op->attrInfo, ait);
-}
-
-void
-DbUtil::sendKeyInfo(Signal* signal,
- KeyInfo* keyInfo,
- const KeyInfoBuffer & keyBuf,
- KeyInfoIterator & kit)
-{
- while(kit.curr.i != RNIL) {
- Uint32 *keyDst = keyInfo->keyData;
- Uint32 keyDataLen = 0;
- for(Uint32 i = 0; i<KeyInfo::DataLength && kit.curr.i != RNIL;
- i++, keyBuf.next(kit)){
- keyDst[i] = * kit.data;
- keyDataLen++;
- }
-#if 0 //def EVENT_DEBUG
- printf("DbUtil::sendKeyInfo: sendSignal(DBTC_REF, GSN_KEYINFO, signal, %d , JBB)\n", KeyInfo::HeaderLength + keyDataLen);
-#endif
- sendSignal(DBTC_REF, GSN_KEYINFO, signal,
- KeyInfo::HeaderLength + keyDataLen, JBB);
- }
-}
-
-void
-DbUtil::sendAttrInfo(Signal* signal,
- AttrInfo* attrInfo,
- const AttrInfoBuffer & attrBuf,
- AttrInfoIterator & ait)
-{
- while(ait.curr.i != RNIL) {
- Uint32 *attrDst = attrInfo->attrData;
- Uint32 i = 0;
- for(i = 0; i<AttrInfo::DataLength && ait.curr.i != RNIL;
- i++, attrBuf.next(ait)){
- attrDst[i] = * ait.data;
- }
-#if 0 //def EVENT_DEBUG
- printf("DbUtil::sendAttrInfo: sendSignal(DBTC_REF, GSN_ATTRINFO, signal, %d , JBB)\n", AttrInfo::HeaderLength + i);
-#endif
- sendSignal(DBTC_REF, GSN_ATTRINFO, signal,
- AttrInfo::HeaderLength + i, JBB);
- }
-}
-
-void
-DbUtil::initResultSet(ResultSetBuffer & rs,
- const ResultSetInfoBuffer & rsi){
-
- ResultSetBuffer::DataBufferIterator rsit;
- rs.first(rsit);
-
- ResultSetInfoBuffer::ConstDataBufferIterator rsiit;
- for(rsi.first(rsiit); rsiit.curr.i != RNIL; rsi.next(rsiit)){
- ndbrequire(rsit.curr.i != RNIL);
-
- rsit.data[0] = rsiit.data[0];
-#if 0 //def EVENT_DEBUG
- printf("Init resultset %u, sz %d\n",
- rsit.curr.i,
- ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1);
-#endif
- rs.next(rsit, ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1);
- }
-}
-
-void
-DbUtil::getTransId(Transaction * transP){
-
- Uint32 tmp[2];
- tmp[0] = c_transId[0];
- tmp[1] = c_transId[1];
-
- transP->transId[0] = tmp[0];
- transP->transId[1] = tmp[1];
-
- c_transId[1] = tmp[1] + 1;
-}
-
-
-
-/**************************************************************************
- * ------------------------------------------------------------------------
- * MODULE: Post Execute
- * ------------------------------------------------------------------------
- *
- * Handles result from a sent transaction
- **************************************************************************/
-
-/**
- * execTRANSID_AI
- *
- * Receive result from transaction
- *
- * NOTE: This codes assumes that
- * TransidAI::DataLength = ResultSetBuffer::getSegmentSize() * n
- */
-void
-DbUtil::execTRANSID_AI(Signal* signal){
- jamEntry();
-#if 0 //def EVENT_DEBUG
- ndbout_c("File: %s line: %u",__FILE__,__LINE__);
-#endif
-
- const Uint32 opI = signal->theData[0];
- const Uint32 transId1 = signal->theData[1];
- const Uint32 transId2 = signal->theData[2];
- const Uint32 dataLen = signal->length() - 3;
-
- Operation * opP = c_operationPool.getPtr(opI);
- TransactionPtr transPtr;
- c_runningTransactions.getPtr(transPtr, opP->transPtrI);
-
- ndbrequire(transId1 == transPtr.p->transId[0] &&
- transId2 == transPtr.p->transId[1]);
- opP->rsRecv += dataLen;
-
- /**
- * Save result
- */
- const Uint32 *src = &signal->theData[3];
- ResultSetBuffer::DataBufferIterator rs = opP->rsIterator;
-
- ndbrequire(opP->rs.import(rs,src,dataLen));
- opP->rs.next(rs, dataLen);
- opP->rsIterator = rs;
-
- if(!opP->complete()){
- jam();
- return;
- }
-
- transPtr.p->recv++;
- if(!transPtr.p->complete()){
- jam();
- return;
- }
-
- finishTransaction(signal, transPtr);
-}
-
-void
-DbUtil::execTCKEYCONF(Signal* signal){
- jamEntry();
-#if 0 //def EVENT_DEBUG
- ndbout_c("File: %s line: %u",__FILE__,__LINE__);
-#endif
-
- TcKeyConf * keyConf = (TcKeyConf*)signal->getDataPtr();
-
- //const Uint32 gci = keyConf->gci;
- const Uint32 transI = keyConf->apiConnectPtr >> 1;
- const Uint32 confInfo = keyConf->confInfo;
- const Uint32 transId1 = keyConf->transId1;
- const Uint32 transId2 = keyConf->transId2;
-
- Uint32 recv = 0;
- const Uint32 ops = TcKeyConf::getNoOfOperations(confInfo);
- for(Uint32 i = 0; i<ops; i++){
- OperationPtr opPtr;
- c_operationPool.getPtr(opPtr, keyConf->operations[i].apiOperationPtr);
-
- ndbrequire(opPtr.p->transPtrI == transI);
- opPtr.p->rsExpect += keyConf->operations[i].attrInfoLen;
- if(opPtr.p->complete()){
- recv++;
- }
- }
-
- /**
- * Check commit ack marker flag
- */
- if (TcKeyConf::getMarkerFlag(confInfo)){
- signal->theData[0] = transId1;
- signal->theData[1] = transId2;
- sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB);
- }//if
-
- TransactionPtr transPtr;
- c_runningTransactions.getPtr(transPtr, transI);
- ndbrequire(transId1 == transPtr.p->transId[0] &&
- transId2 == transPtr.p->transId[1]);
-
- transPtr.p->recv += recv;
- if(!transPtr.p->complete()){
- jam();
- return;
- }
- finishTransaction(signal, transPtr);
-}
-
-void
-DbUtil::execTCKEYREF(Signal* signal){
- jamEntry();
-#if 0 //def EVENT_DEBUG
- ndbout_c("File: %s line: %u",__FILE__,__LINE__);
-#endif
-
- const Uint32 transI = signal->theData[0] >> 1;
- const Uint32 transId1 = signal->theData[1];
- const Uint32 transId2 = signal->theData[2];
- const Uint32 errCode = signal->theData[3];
-
- TransactionPtr transPtr;
- c_runningTransactions.getPtr(transPtr, transI);
- ndbrequire(transId1 == transPtr.p->transId[0] &&
- transId2 == transPtr.p->transId[1]);
-
- //if(getClassification(errCode) == PermanentError){
- //}
-
- //ndbout << "Transaction error (code: " << errCode << ")" << endl;
-
- transPtr.p->errorCode = errCode;
- finishTransaction(signal, transPtr);
-}
-
-void
-DbUtil::execTCROLLBACKREP(Signal* signal){
- jamEntry();
-#if 0 //def EVENT_DEBUG
- ndbout_c("File: %s line: %u",__FILE__,__LINE__);
-#endif
-
- const Uint32 transI = signal->theData[0] >> 1;
- const Uint32 transId1 = signal->theData[1];
- const Uint32 transId2 = signal->theData[2];
- const Uint32 errCode = signal->theData[3];
-
- TransactionPtr transPtr;
- c_runningTransactions.getPtr(transPtr, transI);
- ndbrequire(transId1 == transPtr.p->transId[0] &&
- transId2 == transPtr.p->transId[1]);
-
- //if(getClassification(errCode) == PermanentError){
- //}
-
-#if 0 //def EVENT_DEBUG
- ndbout << "Transaction error (code: " << errCode << ")" << endl;
-#endif
-
- if(transPtr.p->noOfRetries > 0){
- transPtr.p->noOfRetries--;
- switch(errCode){
- case 266:
- case 410:
- case 1204:
-#if 0
- ndbout_c("errCode: %d noOfRetries: %d -> retry",
- errCode, transPtr.p->noOfRetries);
-#endif
- runTransaction(signal, transPtr);
- return;
- }
- }
-
- transPtr.p->errorCode = errCode;
- finishTransaction(signal, transPtr);
-}
-
-void
-DbUtil::finishTransaction(Signal* signal, TransactionPtr transPtr){
-#if 0 //def EVENT_DEBUG
- ndbout_c("Transaction %x %x completed %s",
- transPtr.p->transId[0],
- transPtr.p->transId[1],
- transPtr.p->errorCode == 0 ? "OK" : "FAILED");
-#endif
-
- /*
- How to find the correct RS? Could we have multi-RS/transaction?
-
- Operation * opP = c_operationPool.getPtr(opI);
-
- ResultSetBuffer::DataBufferIterator rsit;
- ndbrequire(opP->rs.first(rsit));
- ndbout << "F Result: " << rsit.data << endl;
-
- while (opP->rs.next(rsit)) {
- ndbout << "R Result: " << rsit.data << endl;
- }
- */
-
- switch(transPtr.p->gsn){
- case GSN_UTIL_SEQUENCE_REQ:
- jam();
- reportSequence(signal, transPtr.p);
- break;
- case GSN_UTIL_EXECUTE_REQ:
- if (transPtr.p->errorCode) {
- UtilExecuteRef * ret = (UtilExecuteRef *)signal->getDataPtrSend();
- ret->senderData = transPtr.p->clientData;
- ret->errorCode = UtilExecuteRef::TCError;
- ret->TCErrorCode = transPtr.p->errorCode;
- sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_REF, signal,
- UtilExecuteRef::SignalLength, JBB);
- } else {
- struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
- UtilExecuteConf * ret = (UtilExecuteConf *)signal->getDataPtrSend();
- ret->senderData = transPtr.p->clientData;
- if (getResultSet(signal, transPtr.p, sectionsPtr)) {
-#if 0 //def EVENT_DEBUG
- for (int j = 0; j < 2; j++) {
- printf("Result set %u %u\n", j,sectionsPtr[j].sz);
- for (int i=0; i < sectionsPtr[j].sz; i++)
- printf("H'%.8x ", sectionsPtr[j].p[i]);
- printf("\n");
- }
-#endif
- sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal,
- UtilExecuteConf::SignalLength, JBB,
- sectionsPtr, UtilExecuteReq::NoOfSections);
- } else
- sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal,
- UtilExecuteConf::SignalLength, JBB);
- }
- break;
- default:
- ndbrequire(0);
- break;
- }
- releaseTransaction(transPtr);
-}
-
-void
-DbUtil::execUTIL_LOCK_REQ(Signal * signal){
- jamEntry();
- UtilLockReq * req = (UtilLockReq*)signal->getDataPtr();
- const Uint32 lockId = req->lockId;
-
- LockQueuePtr lockQPtr;
- if(!c_lockQueues.find(lockQPtr, lockId)){
- jam();
- sendLOCK_REF(signal, req, UtilLockRef::NoSuchLock);
- return;
- }
-
-// const Uint32 requestInfo = req->requestInfo;
- const Uint32 senderNode = refToNode(req->senderRef);
- if(senderNode != getOwnNodeId() && senderNode != 0){
- jam();
- sendLOCK_REF(signal, req, UtilLockRef::DistributedLockNotSupported);
- return;
- }
-
- LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
- lockQPtr.p->m_queue);
- if(req->requestInfo & UtilLockReq::TryLock && !queue.isEmpty()){
- jam();
- sendLOCK_REF(signal, req, UtilLockRef::LockAlreadyHeld);
- return;
- }
-
- LockQueueElementPtr lockEPtr;
- if(!c_lockElementPool.seize(lockEPtr)){
- jam();
- sendLOCK_REF(signal, req, UtilLockRef::OutOfLockRecords);
- return;
- }
-
- lockEPtr.p->m_senderRef = req->senderRef;
- lockEPtr.p->m_senderData = req->senderData;
-
- if(queue.isEmpty()){
- jam();
- sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
- }
-
- queue.add(lockEPtr);
-}
-
-void
-DbUtil::execUTIL_UNLOCK_REQ(Signal* signal){
- jamEntry();
-
- UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtr();
- const Uint32 lockId = req->lockId;
-
- LockQueuePtr lockQPtr;
- if(!c_lockQueues.find(lockQPtr, lockId)){
- jam();
- sendUNLOCK_REF(signal, req, UtilUnlockRef::NoSuchLock);
- return;
- }
-
- LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
- lockQPtr.p->m_queue);
- LockQueueElementPtr lockEPtr;
- if(!queue.first(lockEPtr)){
- jam();
- sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner);
- return;
- }
-
- if(lockQPtr.p->m_lockKey != req->lockKey){
- jam();
- sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner);
- return;
- }
-
- sendUNLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
- queue.release(lockEPtr);
-
- if(queue.first(lockEPtr)){
- jam();
- sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
- return;
- }
-}
-
-void
-DbUtil::sendLOCK_REF(Signal* signal,
- const UtilLockReq * req, UtilLockRef::ErrorCode err){
- const Uint32 senderData = req->senderData;
- const Uint32 senderRef = req->senderRef;
- const Uint32 lockId = req->lockId;
-
- UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->lockId = lockId;
- ref->errorCode = err;
- sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal,
- UtilLockRef::SignalLength, JBB);
-}
-
-void
-DbUtil::sendLOCK_CONF(Signal* signal,
- LockQueue * lockQP,
- LockQueueElement * lockEP){
- const Uint32 senderData = lockEP->m_senderData;
- const Uint32 senderRef = lockEP->m_senderRef;
- const Uint32 lockId = lockQP->m_lockId;
- const Uint32 lockKey = ++lockQP->m_lockKey;
-
- UtilLockConf * conf = (UtilLockConf*)signal->getDataPtrSend();
- conf->senderData = senderData;
- conf->senderRef = reference();
- conf->lockId = lockId;
- conf->lockKey = lockKey;
- sendSignal(senderRef, GSN_UTIL_LOCK_CONF, signal,
- UtilLockConf::SignalLength, JBB);
-}
-
-void
-DbUtil::sendUNLOCK_REF(Signal* signal,
- const UtilUnlockReq* req, UtilUnlockRef::ErrorCode err){
-
- const Uint32 senderData = req->senderData;
- const Uint32 senderRef = req->senderRef;
- const Uint32 lockId = req->lockId;
-
- UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtrSend();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->lockId = lockId;
- ref->errorCode = err;
- sendSignal(senderRef, GSN_UTIL_UNLOCK_REF, signal,
- UtilUnlockRef::SignalLength, JBB);
-}
-
-void
-DbUtil::sendUNLOCK_CONF(Signal* signal,
- LockQueue * lockQP,
- LockQueueElement * lockEP){
- const Uint32 senderData = lockEP->m_senderData;
- const Uint32 senderRef = lockEP->m_senderRef;
- const Uint32 lockId = lockQP->m_lockId;
- ++lockQP->m_lockKey;
-
- UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtrSend();
- conf->senderData = senderData;
- conf->senderRef = reference();
- conf->lockId = lockId;
- sendSignal(senderRef, GSN_UTIL_UNLOCK_CONF, signal,
- UtilUnlockConf::SignalLength, JBB);
-}
-
-void
-DbUtil::execUTIL_CREATE_LOCK_REQ(Signal* signal){
- jamEntry();
- UtilCreateLockReq req = * (UtilCreateLockReq*)signal->getDataPtr();
-
- UtilCreateLockRef::ErrorCode err = UtilCreateLockRef::OK;
-
- do {
- LockQueuePtr lockQPtr;
- if(c_lockQueues.find(lockQPtr, req.lockId)){
- jam();
- err = UtilCreateLockRef::LockIdAlreadyUsed;
- break;
- }
-
- if(req.lockType != UtilCreateLockReq::Mutex){
- jam();
- err = UtilCreateLockRef::UnsupportedLockType;
- break;
- }
-
- if(!c_lockQueues.seize(lockQPtr)){
- jam();
- err = UtilCreateLockRef::OutOfLockQueueRecords;
- break;
- }
-
- new (lockQPtr.p) LockQueue(req.lockId);
- c_lockQueues.add(lockQPtr);
-
- UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtrSend();
- conf->senderData = req.senderData;
- conf->senderRef = reference();
- conf->lockId = req.lockId;
-
- sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_CONF, signal,
- UtilCreateLockConf::SignalLength, JBB);
- return;
- } while(false);
-
- UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtrSend();
- ref->senderData = req.senderData;
- ref->senderRef = reference();
- ref->lockId = req.lockId;
- ref->errorCode = err;
-
- sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_REF, signal,
- UtilCreateLockRef::SignalLength, JBB);
-}
-
-void
-DbUtil::execUTIL_DESTORY_LOCK_REQ(Signal* signal){
- jamEntry();
-
- UtilDestroyLockReq req = * (UtilDestroyLockReq*)signal->getDataPtr();
- UtilDestroyLockRef::ErrorCode err = UtilDestroyLockRef::OK;
- do {
- LockQueuePtr lockQPtr;
- if(!c_lockQueues.find(lockQPtr, req.lockId)){
- jam();
- err = UtilDestroyLockRef::NoSuchLock;
- break;
- }
-
- LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
- lockQPtr.p->m_queue);
- LockQueueElementPtr lockEPtr;
- if(!queue.first(lockEPtr)){
- jam();
- err = UtilDestroyLockRef::NotLockOwner;
- break;
- }
-
- if(lockQPtr.p->m_lockKey != req.lockKey){
- jam();
- err = UtilDestroyLockRef::NotLockOwner;
- break;
- }
-
- /**
- * OK
- */
-
- // Inform all in lock queue that queue has been destroyed
- UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend();
- ref->lockId = req.lockId;
- ref->errorCode = UtilLockRef::NoSuchLock;
- ref->senderRef = reference();
- LockQueueElementPtr loopPtr = lockEPtr;
- for(queue.next(loopPtr); !loopPtr.isNull(); queue.next(loopPtr)){
- jam();
- ref->senderData = loopPtr.p->m_senderData;
- const Uint32 senderRef = loopPtr.p->m_senderRef;
- sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal,
- UtilLockRef::SignalLength, JBB);
- }
- queue.release();
- c_lockQueues.release(lockQPtr);
-
- // Send Destroy conf
- UtilDestroyLockConf* conf=(UtilDestroyLockConf*)signal->getDataPtrSend();
- conf->senderData = req.senderData;
- conf->senderRef = reference();
- conf->lockId = req.lockId;
- sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_CONF, signal,
- UtilDestroyLockConf::SignalLength, JBB);
- return;
- } while(false);
-
- UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtrSend();
- ref->senderData = req.senderData;
- ref->senderRef = reference();
- ref->lockId = req.lockId;
- ref->errorCode = err;
- sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_REF, signal,
- UtilDestroyLockRef::SignalLength, JBB);
-}
-
-template class ArrayPool<DbUtil::Page32>;
diff --git a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp
deleted file mode 100644
index 9f7b7202740..00000000000
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp
+++ /dev/null
@@ -1,485 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DBUTIL_H
-#define DBUTIL_H
-
-#include <ndb_limits.h>
-#include <SimulatedBlock.hpp>
-#include <NodeBitmask.hpp>
-
-#include <ArrayPool.hpp>
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <DLFifoList.hpp>
-#include <DataBuffer.hpp>
-#include <KeyTable.hpp>
-
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/UtilPrepare.hpp>
-#include <signaldata/UtilExecute.hpp>
-#include <signaldata/UtilLock.hpp>
-#include <SimpleProperties.hpp>
-#include <Array.hpp>
-
-#define UTIL_WORDS_PER_PAGE 1023
-
-/**
- * @class DbUtil
- * @brief Database utilities
- *
- * This block implements transactional services which can be used by other
- * blocks.
- *
- * @section secSequence Module: The Sequence Service
- *
- * A sequence is a varaible stored in the database. Each time it is
- * requested with "NextVal" it returns a unique number. If requested
- * with "CurrVal" it returns the current number.
- *
- * - Request: SEQUENCE_REQ
- * Requests the 'NextVal' or 'CurrVal' for sequence variable 'sequenceId'.
- *
- * - Response: SEQUENCE_CONF / REF (if failure)
- * Returns value requested.
- */
-class DbUtil : public SimulatedBlock
-{
-public:
- DbUtil(Block_context& ctx);
- virtual ~DbUtil();
- BLOCK_DEFINES(DbUtil);
-
-protected:
- /**
- * Startup & Misc
- */
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execNDB_STTOR(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- /**
- * Sequence Service : Public interface
- */
- void execUTIL_SEQUENCE_REQ(Signal* signal);
- void execUTIL_SEQUENCE_REF(Signal* signal);
- void execUTIL_SEQUENCE_CONF(Signal* signal);
-
- /**
- * Prepare Service : Public interface
- */
- void execUTIL_PREPARE_REQ(Signal* signal);
- void execUTIL_PREPARE_CONF(Signal* signal);
- void execUTIL_PREPARE_REF(Signal* signal);
-
- /**
- * Delete Service : Public interface
- */
- void execUTIL_DELETE_REQ(Signal* signal);
- void execUTIL_DELETE_REF(Signal* signal);
- void execUTIL_DELETE_CONF(Signal* signal);
-
- /**
- * Execute Service : Public interface
- */
- void execUTIL_EXECUTE_REQ(Signal* signal);
- void execUTIL_EXECUTE_REF(Signal* signal);
- void execUTIL_EXECUTE_CONF(Signal* signal);
-
- /**
- * Prepare Release Service : Public interface
- */
- void execUTIL_RELEASE_REQ(Signal* signal);
- void execUTIL_RELEASE_CONF(Signal* signal);
- void execUTIL_RELEASE_REF(Signal* signal);
-
- /**
- * Backend interface to a used TC service
- */
- void execTCSEIZECONF(Signal* signal);
- void execTCKEYCONF(Signal* signal);
- void execTCKEYREF(Signal* signal);
- void execTCROLLBACKREP(Signal* signal);
- void execTCKEY_FAILCONF(Signal* signal);
- void execTCKEY_FAILREF(Signal* signal);
- void execTRANSID_AI(Signal* signal);
-
- /**
- * Backend interface to a used DICT service
- */
- void execGET_TABINFOREF(Signal*);
- void execGET_TABINFO_CONF(Signal* signal);
-
-private:
-
-public:
- struct PreparedOperation;
-
- typedef DataBuffer<11> KeyInfoBuffer;
- typedef KeyInfoBuffer::ConstDataBufferIterator KeyInfoIterator;
- typedef DataBuffer<11> AttrInfoBuffer;
- typedef AttrInfoBuffer::ConstDataBufferIterator AttrInfoIterator;
- typedef DataBuffer<11> ResultSetBuffer;
- typedef DataBuffer<11> ResultSetInfoBuffer;
- typedef DataBuffer<1> AttrMappingBuffer;
-
- /**
- * @struct Page32
- * @brief For storing SimpleProperties objects and similar temporary data
- */
- struct Page32 {
- Uint32 data[UTIL_WORDS_PER_PAGE];
- Uint32 nextPool; // Note: This used as data when seized
- };
-
- /**
- * @struct Prepare
- * @brief Info regarding prepare request (contains a prepared operation)
- *
- * The prepare phase interprets the table and attribute names sent
- * in the prepare request from the client and asks DICT for meta
- * information.
- */
- struct Prepare {
- Prepare(ArrayPool<Page32> & ap) : preparePages(ap) {}
-
- /*** Client info ***/
- Uint32 clientRef;
- Uint32 clientData;
-
- /**
- * SimpleProp sent in UTIL_PREPARE_REQ
- *
- * Example format:
- * - UtilPrepareReq::NoOfOperations=1
- * - UtilPrepareReq::OperationType=UtilPrepareReq::Delete
- * - UtilPrepareReq::TableName="SYSTAB_0"
- * - UtilPrepareReq::AttributeName="SYSKEY_0"
- */
- Uint32 prepDataLen;
- Array<Page32> preparePages;
-
- /*** PreparedOperation constructed in Prepare phase ***/
- Ptr<PreparedOperation> prepOpPtr;
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
-
- void print() const {
- ndbout << "[-Prepare-" << endl
- << " clientRef: " << clientRef
- << ", clientData: " << clientData
- << "]" << endl;
- }
- };
-
- /**
- * @struct PreparedOperation
- * @brief Contains instantiated TcKeyReq signaldata for operation
- *
- * The prepare phase is finished by storing the request in a
- * PreparedOperation record.
- */
- struct PreparedOperation {
- PreparedOperation(AttrMappingBuffer::DataBufferPool & am,
- AttrInfoBuffer::DataBufferPool & ai,
- ResultSetInfoBuffer::DataBufferPool & rs) :
- releaseFlag(false), attrMapping(am), attrInfo(ai), rsInfo(rs)
- {
- pkBitmask.clear();
- }
-
- /*** Various Operation Info ***/
- Uint32 keyLen; // Length of primary key (fixed size is assumed)
- Uint32 rsLen; // Size of result set
- Uint32 noOfKeyAttr; // Number of key attributes
- Uint32 noOfAttr; // Number of attributes
- bool releaseFlag; // flag if operation release after completion
-
- /**
- * Attribute Mapping
- *
- * This datastructure (buffer of AttributeHeader:s) are used to map
- * each execute request to a TCKEYREQ train of signals.
- *
- * The datastructure contains (AttributeId, Position) pairs, where
- * - AttributeId is id used in database, and
- * - Position is position of attribute value in TCKEYREQ keyinfo
- * part of the train of signals which will be send to TC.
- * Position == 0x3fff means it should *not* be sent
- * in keyinfo part.
- */
- AttrMappingBuffer attrMapping;
-
- /*** First signal in tckeyreq train ***/
- Uint32 tckeyLenInBytes; // TcKeyReq total signal length (in bytes)
- Uint32 keyDataPos; // Where to store keydata[] in tckey signal
- // (in #words from base in tckey signal)
- TcKeyReq tckey; // Signaldata for first signal in train
-
- /*** Attrinfo signals sent to TC (part of tckeyreq train) ***/
- AttrInfoBuffer attrInfo;
-
- /*** Result of executed operation ***/
- ResultSetInfoBuffer rsInfo;
-
- Bitmask<MAX_ATTRIBUTES_IN_TABLE> pkBitmask;
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
-
- void print() const {
- ndbout << "[-PreparedOperation-" << endl
- << " keyLen: " << keyLen
- << ", rsLen: " << rsLen
- << ", noOfKeyAttr: " << noOfKeyAttr
- << ", noOfAttr: " << noOfAttr
- << ", tckeyLenInBytes: " << tckeyLenInBytes
- << ", keyDataPos: " << keyDataPos << endl
- << "-AttrMapping- (AttrId, KeyPos)-pairs "
- << "(Pos=3fff if non-key attr):" << endl;
- attrMapping.print(stdout);
- ndbout << "[-tckey- ";
- printTCKEYREQ(stdout, (Uint32*)&tckey, 8, 0);
- ndbout << "[-attrInfo- ";
- attrInfo.print(stdout);
- ndbout << "[-rsInfo- ";
- rsInfo.print(stdout);
- ndbout << "]]]]" << endl;
- }
- };
-
- /**
- * @struct Operation
- * @brief Used in execution (contains resultset and buffers for result)
- */
- struct Operation {
- Operation(KeyInfoBuffer::DataBufferPool & ki,
- AttrInfoBuffer::DataBufferPool & ai,
- ResultSetBuffer::DataBufferPool & _rs) :
- prepOp_i(RNIL), keyInfo(ki), attrInfo(ai), rs(_rs) {}
-
- PreparedOperation * prepOp;
- Uint32 prepOp_i;
- KeyInfoBuffer keyInfo;
- AttrInfoBuffer attrInfo;
- ResultSetBuffer rs;
- ResultSetBuffer::DataBufferIterator rsIterator;
-
- Uint32 transPtrI;
-
- Uint32 rsRecv;
- Uint32 rsExpect;
- inline bool complete() const { return rsRecv == rsExpect; }
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
-
- void print() const {
- ndbout << "[-Operation-" << endl
- << " transPtrI: " << transPtrI
- << ", rsRecv: " << rsRecv;
- ndbout << "[-PreparedOperation-" << endl;
- prepOp->print();
- ndbout << "[-keyInfo-" << endl;
- keyInfo.print(stdout);
- ndbout << "[-attrInfo-" << endl;
- attrInfo.print(stdout);
- ndbout << "]]" << endl;
- }
- };
-
- /**
- * @struct Transaction
- * @brief Used in execution (contains list of operations)
- */
- struct Transaction {
- Transaction(ArrayPool<Page32> & ap, ArrayPool<Operation> & op) :
- executePages(ap), operations(op) {}
-
- Uint32 clientRef;
- Uint32 clientData;
- Array<Page32> executePages;
-
- Uint32 gsn; // Request type (SEQUENCE, DELETE, etc)
- union {
- /**
- * Sequence transaction
- */
- struct {
- Uint32 sequenceId;
- Uint32 requestType;
- } sequence;
- };
-
- Uint32 connectPtr;
- Uint32 transId[2];
- SLList<Operation> operations;
-
- Uint32 errorCode;
- Uint32 noOfRetries;
- Uint32 sent; // No of operations sent
- Uint32 recv; // No of completed operations received
- inline bool complete() const { return sent == recv; };
-
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
-
- void print() const {
- ndbout << "[-Transaction-" << endl
- << " clientRef: " << clientRef
- << ", clientData: " << clientData
- << ", gsn: " << gsn
- << ", errorCode: " << errorCode
- << endl
- << " sent: " << sent << " operations"
- << ", recv: " << recv << " completed operations";
- OperationPtr opPtr;
- this->operations.first(opPtr);
- while(opPtr.i != RNIL){
- ndbout << "[-Operation-" << endl;
- opPtr.p->print();
- this->operations.next(opPtr);
- }
- ndbout << "]" << endl;
- }
- };
-
- typedef Ptr<Page32> Page32Ptr;
- typedef Ptr<Prepare> PreparePtr;
- typedef Ptr<Transaction> TransactionPtr;
- typedef Ptr<Operation> OperationPtr;
- typedef Ptr<PreparedOperation> PreparedOperationPtr;
-
- Uint32 c_transId[2];
- ArrayPool<Page32> c_pagePool;
- ArrayPool<Prepare> c_preparePool;
- ArrayPool<Operation> c_operationPool;
- ArrayPool<PreparedOperation> c_preparedOperationPool;
- ArrayPool<Transaction> c_transactionPool;
-
- DataBuffer<1>::DataBufferPool c_attrMappingPool;
- DataBuffer<11>::DataBufferPool c_dataBufPool;
- DLList<Prepare> c_runningPrepares;
- DLList<Transaction> c_seizingTransactions; // Being seized at TC
- DLList<Transaction> c_runningTransactions; // Seized and now exec.
-
- void getTransId(Transaction *);
- void initResultSet(ResultSetBuffer &, const ResultSetInfoBuffer &);
- void runTransaction(Signal* signal, TransactionPtr);
- void runOperation(Signal* signal, TransactionPtr &, OperationPtr &, Uint32);
- void sendKeyInfo(Signal* signal,
- KeyInfo* keyInfo,
- const KeyInfoBuffer & keyBuf,
- KeyInfoIterator & kit);
- void sendAttrInfo(Signal*,
- AttrInfo* attrInfo,
- const AttrInfoBuffer &,
- AttrInfoIterator & ait);
- int getResultSet(Signal* signal, const Transaction * transP,
- struct LinearSectionPtr sectionsPtr[]);
- void finishTransaction(Signal*, TransactionPtr);
- void releaseTransaction(TransactionPtr transPtr);
- void hardcodedPrepare();
- void connectTc(Signal* signal);
- void reportSequence(Signal*, const Transaction *);
- void readPrepareProps(Signal* signal,
- SimpleProperties::Reader* reader,
- Uint32 senderData);
- void prepareOperation(Signal*, PreparePtr);
- void sendUtilPrepareRef(Signal*, UtilPrepareRef::ErrorCode, Uint32, Uint32);
- void sendUtilExecuteRef(Signal*, UtilExecuteRef::ErrorCode,
- Uint32, Uint32, Uint32);
- void releasePrepare(PreparePtr);
- void releasePreparedOperation(PreparedOperationPtr);
-
- /***************************************************************************
- * Lock manager
- */
- struct LockQueueElement {
- Uint32 m_senderData;
- Uint32 m_senderRef;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<LockQueueElement> LockQueueElementPtr;
-
- struct LockQueue {
- LockQueue(){}
- LockQueue(Uint32 id) : m_queue() { m_lockId = id; m_lockKey = 0;}
- union {
- Uint32 m_lockId;
- Uint32 key;
- };
- Uint32 m_lockKey;
- DLFifoList<LockQueueElement>::Head m_queue;
- union {
- Uint32 nextHash;
- Uint32 nextPool;
- };
- Uint32 prevHash;
-
- Uint32 hashValue() const {
- return m_lockId;
- }
- bool equal(const LockQueue & rec) const {
- return m_lockId == rec.m_lockId;
- }
- };
- typedef Ptr<LockQueue> LockQueuePtr;
-
-
- ArrayPool<LockQueue> c_lockQueuePool;
- ArrayPool<LockQueueElement> c_lockElementPool;
- KeyTable<LockQueue> c_lockQueues;
-
- void execUTIL_CREATE_LOCK_REQ(Signal* signal);
- void execUTIL_DESTORY_LOCK_REQ(Signal* signal);
- void execUTIL_LOCK_REQ(Signal* signal);
- void execUTIL_UNLOCK_REQ(Signal* signal);
-
- void sendLOCK_REF(Signal*, const UtilLockReq * req, UtilLockRef::ErrorCode);
- void sendLOCK_CONF(Signal*, LockQueue *, LockQueueElement *);
-
- void sendUNLOCK_REF(Signal*, const UtilUnlockReq*, UtilUnlockRef::ErrorCode);
- void sendUNLOCK_CONF(Signal*, LockQueue *, LockQueueElement *);
-
- // For testing of mutex:es
- void mutex_created(Signal* signal, Uint32 mutexId, Uint32 retVal);
- void mutex_destroyed(Signal* signal, Uint32 mutexId, Uint32 retVal);
- void mutex_locked(Signal* signal, Uint32 mutexId, Uint32 retVal);
- void mutex_unlocked(Signal* signal, Uint32 mutexId, Uint32 retVal);
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.txt b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.txt
deleted file mode 100644
index cc8c1985009..00000000000
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-UTIL Protocols
---------------
-Transactions are executed in two phases:
-1) PREPARE
-2) EXECUTE
-
-
-PREPARE PHASE
--------------
-1) ** REQUEST **
- Client (any block) requests prepare service from Util:
-
- Client --UTIL_PREPARE_REQ--> Util
- ...
- Client --UTIL_PREPARE_REQ--> Util
-
-2) ** DICTINFO **
- Util requests Dict for information about table:
-
- Util --GET_TABINFOREQ--> Dict
-
- Util <--DICTTABINFO-- Dict
- ...
- Util <--DICTTABINFO-- Dict
-
-3) ** PREPARE **
- Operation (= transaction) is prepared (DbUtil::prepareOperation)
-
- a) AttrMapping is created (a map used to read of the
- actual execute request attribute values and put them in KEYINFO)
-
- b) TC Signal train is prepared
-
-4) ** CONFIRM **
- Request is confirmed
-
- Client <--UTIL_PREPARE_CONF-- Util
-
-
-EXECUTE PHASE
--------------
-1) Client (any block) requests execute service from Util:
- (Execute can be INSERT, DELETE,...)
-
- Client --UTIL_EXECUTE_REQ--> Util (Multi-signals not yet implemented)
- ...
- Client --UTIL_EXECUTE_REQ--> Util
-
-2) Util --TCKEYREQ--> tc
-
- Util --KEYINFO--> tc (sometimes) (Not yet implemented)
- ...
- Util --KEYINFO--> tc
-
- Util --ATTRINFO--> tc (sometimes)
- ...
- Util --ATTRINFO--> tc
-
-3) Util <--TCKEYCONF-- tc
-
- Util --TC_COMMIT_ACK-->tc (sometimes)
-
- (in parallel with)
-
- Util <--TRANSID_AI-- tc (sometimes)
- ...
- Util <--TRANSID_AI-- tc
-
diff --git a/storage/ndb/src/kernel/blocks/diskpage.cpp b/storage/ndb/src/kernel/blocks/diskpage.cpp
deleted file mode 100644
index c782d1367d9..00000000000
--- a/storage/ndb/src/kernel/blocks/diskpage.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright (C) 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <signaldata/SignalData.hpp>
-#include "diskpage.hpp"
-#include <NdbOut.hpp>
-#include <version.h>
-#include <time.h>
-
-void
-File_formats::Zero_page_header::init(File_type ft,
- Uint32 node_id,
- Uint32 version,
- Uint32 now)
-{
- memcpy(m_magic, "NDBDISK", 8);
- m_byte_order = 0x12345678;
- m_page_size = File_formats::NDB_PAGE_SIZE;
- m_ndb_version = version;
- m_node_id = node_id;
- m_file_type = ft;
- m_time = now;
-}
-
-int
-File_formats::Zero_page_header::validate(File_type ft,
- Uint32 node_id,
- Uint32 version,
- Uint32 now)
-{
- return 0; // TODO Check header
-}
-
-NdbOut&
-operator<<(NdbOut& out, const File_formats::Zero_page_header& obj)
-{
- char buf[256];
- out << "page size: " << obj.m_page_size << endl;
- out << "ndb version: " << obj.m_ndb_version << ", " <<
- ndbGetVersionString(obj.m_ndb_version, 0, buf, sizeof(buf)) << endl;
- out << "ndb node id: " << obj.m_node_id << endl;
- out << "file type: " << obj.m_file_type << endl;
- out << "time: " << obj.m_time << ", "
- << ctime((time_t*)&obj.m_time)<< endl;
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const File_formats::Datafile::Zero_page& obj)
-{
- out << obj.m_page_header << endl;
- out << "m_file_no: " << obj.m_file_no << endl;
- out << "m_tablespace_id: " << obj.m_tablespace_id << endl;
- out << "m_tablespace_version: " << obj.m_tablespace_version << endl;
- out << "m_data_pages: " << obj.m_data_pages << endl;
- out << "m_extent_pages: " << obj.m_extent_pages << endl;
- out << "m_extent_size: " << obj.m_extent_size << endl;
- out << "m_extent_count: " << obj.m_extent_count << endl;
- out << "m_extent_headers_per_page: " << obj.m_extent_headers_per_page << endl;
- out << "m_extent_header_words: " << obj.m_extent_header_words << endl;
- out << "m_extent_header_bits_per_page: " << obj.m_extent_header_bits_per_page << endl;
-
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const File_formats::Undofile::Zero_page& obj)
-{
- out << obj.m_page_header << endl;
- out << "m_file_id: " << obj.m_file_id << endl;
- out << "m_logfile_group_id: " << obj.m_logfile_group_id << endl;
- out << "m_logfile_group_version: " << obj.m_logfile_group_version << endl;
- out << "m_undo_pages: " << obj.m_undo_pages << endl;
-
- return out;
-}
-
diff --git a/storage/ndb/src/kernel/blocks/diskpage.hpp b/storage/ndb/src/kernel/blocks/diskpage.hpp
deleted file mode 100644
index 16098d39b45..00000000000
--- a/storage/ndb/src/kernel/blocks/diskpage.hpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __NDB_DISKPAGE_HPP
-#define __NDB_DISKPAGE_HPP
-
-#include <ndb_types.h>
-
-struct File_formats
-{
- STATIC_CONST( NDB_PAGE_SIZE = 32768 );
- STATIC_CONST( NDB_PAGE_SIZE_WORDS = NDB_PAGE_SIZE >> 2);
-
- enum File_type
- {
- FT_Datafile = 0x1,
- FT_Undofile = 0x2
- };
-
- struct Page_header
- {
- Uint32 m_page_lsn_hi;
- Uint32 m_page_lsn_lo;
- Uint32 m_page_type;
- };
-
- enum Page_type
- {
- PT_Unallocated = 0x0,
- PT_Extent_page = 0x1,
- PT_Tup_fixsize_page = 0x2,
- PT_Tup_varsize_page = 0x3,
- PT_Undopage = 0x4
- };
-
- struct Zero_page_header
- {
- char m_magic[8];
- Uint32 m_byte_order;
- Uint32 m_page_size;
- Uint32 m_ndb_version;
- Uint32 m_node_id;
- Uint32 m_file_type;
- Uint32 m_time; // time(0)
- Zero_page_header() {}
- void init(File_type ft, Uint32 node_id, Uint32 version, Uint32 now);
- int validate(File_type ft, Uint32 node_id, Uint32 version, Uint32 now);
- };
-
- STATIC_CONST( NDB_PAGE_HEADER_WORDS = sizeof(Page_header) >> 2);
-
- struct Datafile
- {
- struct Zero_page
- {
- struct Zero_page_header m_page_header;
- Uint32 m_file_no; // Local_key
- Uint32 m_file_id; // DICT id
- Uint32 m_tablespace_id;
- Uint32 m_tablespace_version;
- Uint32 m_data_pages;
- Uint32 m_extent_pages;
- Uint32 m_extent_size;
- Uint32 m_extent_count;
- Uint32 m_extent_headers_per_page;
- Uint32 m_extent_header_words;
- Uint32 m_extent_header_bits_per_page;
- };
-
- struct Extent_header
- {
- Uint32 m_table;
- union
- {
- Uint32 m_fragment_id;
- Uint32 m_next_free_extent;
- };
- Extent_header() {}
- Uint32 m_page_bitmask[1]; // (BitsPerPage*ExtentSize)/(32*PageSize)
- Uint32 get_free_bits(Uint32 page) const;
- Uint32 get_free_word_offset(Uint32 page) const;
- void update_free_bits(Uint32 page, Uint32 bit);
- bool check_free(Uint32 extent_size) const ;
- };
-
- STATIC_CONST( EXTENT_HEADER_BITMASK_BITS_PER_PAGE = 4 );
- STATIC_CONST( EXTENT_HEADER_FIXED_WORDS = (sizeof(Extent_header)>>2) - 1);
- static Uint32 extent_header_words(Uint32 extent_size_in_pages);
-
- struct Extent_page
- {
- struct Page_header m_page_header;
- Extent_header m_extents[1];
-
- Extent_page() {}
- Extent_header* get_header(Uint32 extent_no, Uint32 extent_size);
- };
-
- STATIC_CONST( EXTENT_PAGE_WORDS = NDB_PAGE_SIZE_WORDS - NDB_PAGE_HEADER_WORDS );
-
- struct Data_page
- {
- struct Page_header m_page_header;
- };
- };
-
- struct Undofile
- {
- struct Zero_page
- {
- struct Zero_page_header m_page_header;
- Uint32 m_file_id;
- Uint32 m_logfile_group_id;
- Uint32 m_logfile_group_version;
- Uint32 m_undo_pages;
- };
- struct Undo_page
- {
- struct Page_header m_page_header;
- Uint32 m_words_used;
- Uint32 m_data[1];
- };
-
- struct Undo_entry
- {
- Uint32 m_file_no;
- Uint32 m_page_no;
- struct
- {
- Uint32 m_len_offset;
- Uint32 m_data[1];
- } m_changes[1];
- Uint32 m_length; // [ 16-bit type | 16 bit length of entry ]
- };
-
- enum Undo_type {
- UNDO_LCP_FIRST = 1 // First LCP record with specific lcp id
- ,UNDO_LCP = 2 // LCP Start
-
- /**
- * TUP Undo record
- */
- ,UNDO_TUP_ALLOC = 3
- ,UNDO_TUP_UPDATE = 4
- ,UNDO_TUP_FREE = 5
- ,UNDO_TUP_CREATE = 6
- ,UNDO_TUP_DROP = 7
- ,UNDO_TUP_ALLOC_EXTENT = 8
- ,UNDO_TUP_FREE_EXTENT = 9
-
- ,UNDO_END = 0x7FFF
- ,UNDO_NEXT_LSN = 0x8000
- };
-
- struct Undo_lcp
- {
- Uint32 m_lcp_id;
- Uint32 m_type_length; // 16 bit type, 16 bit length
- };
- };
- STATIC_CONST( UNDO_PAGE_WORDS = NDB_PAGE_SIZE_WORDS - NDB_PAGE_HEADER_WORDS - 1);
-};
-
-
-/**
- * Compute size of extent header in words
- */
-inline Uint32
-File_formats::Datafile::extent_header_words(Uint32 extent_size_in_pages)
-{
- return EXTENT_HEADER_FIXED_WORDS +
- ((extent_size_in_pages * EXTENT_HEADER_BITMASK_BITS_PER_PAGE + 31) >> 5);
-}
-
-inline
-File_formats::Datafile::Extent_header*
-File_formats::Datafile::Extent_page::get_header(Uint32 no, Uint32 extent_size)
-{
- Uint32 * tmp = (Uint32*)m_extents;
- tmp += no*File_formats::Datafile::extent_header_words(extent_size);
- return (Extent_header*)tmp;
-}
-
-inline
-Uint32
-File_formats::Datafile::Extent_header::get_free_bits(Uint32 page) const
-{
- return ((m_page_bitmask[page >> 3] >> ((page & 7) << 2))) & 15;
-}
-
-inline
-Uint32
-File_formats::Datafile::Extent_header::get_free_word_offset(Uint32 page) const
-{
- return page >> 3;
-}
-
-inline
-void
-File_formats::Datafile::Extent_header::update_free_bits(Uint32 page,
- Uint32 bit)
-{
- Uint32 shift = (page & 7) << 2;
- Uint32 mask = (15 << shift);
- Uint32 org = m_page_bitmask[page >> 3];
- m_page_bitmask[page >> 3] = (org & ~mask) | (bit << shift);
-}
-
-inline
-bool
-File_formats::Datafile::Extent_header::check_free(Uint32 extent_size) const
-{
- Uint32 words = (extent_size * EXTENT_HEADER_BITMASK_BITS_PER_PAGE + 31) >> 5;
- Uint32 sum = 0;
- for(; words; words--)
- sum |= m_page_bitmask[words-1];
-
- if(sum & 0x3333)
- return false;
-
- return true;
-}
-
-#include <NdbOut.hpp>
-NdbOut& operator<<(NdbOut& out, const File_formats::Zero_page_header&);
-NdbOut& operator<<(NdbOut& out, const File_formats::Datafile::Zero_page&);
-NdbOut& operator<<(NdbOut& out, const File_formats::Undofile::Zero_page&);
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp
deleted file mode 100644
index cd3fc0d4fbb..00000000000
--- a/storage/ndb/src/kernel/blocks/lgman.cpp
+++ /dev/null
@@ -1,3209 +0,0 @@
-/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of
- the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "lgman.hpp"
-#include "diskpage.hpp"
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/CreateFilegroupImpl.hpp>
-#include <signaldata/DropFilegroupImpl.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/LCP.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <signaldata/LgmanContinueB.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include "ndbfs/Ndbfs.hpp"
-#include "dbtup/Dbtup.hpp"
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-#include <record_types.hpp>
-
-/**
- * ---<a>-----<b>-----<c>-----<d>---> (time)
- *
- * <a> = start of lcp 1
- * <b> = stop of lcp 1
- * <c> = start of lcp 2
- * <d> = stop of lcp 2
- *
- * If ndb crashes before <d>
- * the entire undo log from crash point until <a> has to be applied
- *
- * at <d> the undo log can be cut til <c>
- */
-
-#define DEBUG_UNDO_EXECUTION 0
-#define DEBUG_SEARCH_LOG_HEAD 0
-
-Lgman::Lgman(Block_context & ctx) :
- SimulatedBlock(LGMAN, ctx),
- m_logfile_group_list(m_logfile_group_pool),
- m_logfile_group_hash(m_logfile_group_pool)
-{
- BLOCK_CONSTRUCTOR(Lgman);
-
- // Add received signals
- addRecSignal(GSN_STTOR, &Lgman::execSTTOR);
- addRecSignal(GSN_READ_CONFIG_REQ, &Lgman::execREAD_CONFIG_REQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &Lgman::execDUMP_STATE_ORD);
- addRecSignal(GSN_CONTINUEB, &Lgman::execCONTINUEB);
-
- addRecSignal(GSN_CREATE_FILE_REQ, &Lgman::execCREATE_FILE_REQ);
- addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Lgman::execCREATE_FILEGROUP_REQ);
-
- addRecSignal(GSN_DROP_FILE_REQ, &Lgman::execDROP_FILE_REQ);
- addRecSignal(GSN_DROP_FILEGROUP_REQ, &Lgman::execDROP_FILEGROUP_REQ);
-
- addRecSignal(GSN_FSWRITEREQ, &Lgman::execFSWRITEREQ);
- addRecSignal(GSN_FSWRITEREF, &Lgman::execFSWRITEREF, true);
- addRecSignal(GSN_FSWRITECONF, &Lgman::execFSWRITECONF);
-
- addRecSignal(GSN_FSOPENREF, &Lgman::execFSOPENREF, true);
- addRecSignal(GSN_FSOPENCONF, &Lgman::execFSOPENCONF);
-
- addRecSignal(GSN_FSCLOSECONF, &Lgman::execFSCLOSECONF);
-
- addRecSignal(GSN_FSREADREF, &Lgman::execFSREADREF, true);
- addRecSignal(GSN_FSREADCONF, &Lgman::execFSREADCONF);
-
- addRecSignal(GSN_LCP_FRAG_ORD, &Lgman::execLCP_FRAG_ORD);
- addRecSignal(GSN_END_LCP_REQ, &Lgman::execEND_LCP_REQ);
- addRecSignal(GSN_SUB_GCP_COMPLETE_REP, &Lgman::execSUB_GCP_COMPLETE_REP);
- addRecSignal(GSN_START_RECREQ, &Lgman::execSTART_RECREQ);
-
- addRecSignal(GSN_END_LCP_CONF, &Lgman::execEND_LCP_CONF);
-
- addRecSignal(GSN_GET_TABINFOREQ, &Lgman::execGET_TABINFOREQ);
-
- m_last_lsn = 1;
- m_logfile_group_hash.setSize(10);
-}
-
-Lgman::~Lgman()
-{
-}
-
-BLOCK_FUNCTIONS(Lgman)
-
-void
-Lgman::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Pool_context pc;
- pc.m_block = this;
- m_log_waiter_pool.wo_pool_init(RT_LGMAN_LOG_WAITER, pc);
- m_file_pool.init(RT_LGMAN_FILE, pc);
- m_logfile_group_pool.init(RT_LGMAN_FILEGROUP, pc);
- m_data_buffer_pool.setSize(10);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-Lgman::execSTTOR(Signal* signal)
-{
- jamEntry();
- sendSTTORRY(signal);
-
- return;
-}//Lgman::execNDB_STTOR()
-
-void
-Lgman::sendSTTORRY(Signal* signal)
-{
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 2;
- signal->theData[5] = 3;
- signal->theData[6] = 4;
- signal->theData[7] = 5;
- signal->theData[8] = 6;
- signal->theData[9] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 10, JBB);
-}
-
-void
-Lgman::execCONTINUEB(Signal* signal){
- jamEntry();
-
- Uint32 type= signal->theData[0];
- Uint32 ptrI = signal->theData[1];
- switch(type){
- case LgmanContinueB::FILTER_LOG:
- jam();
- break;
- case LgmanContinueB::CUT_LOG_TAIL:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- cut_log_tail(signal, ptr);
- return;
- }
- case LgmanContinueB::FLUSH_LOG:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- flush_log(signal, ptr, signal->theData[2]);
- return;
- }
- case LgmanContinueB::PROCESS_LOG_BUFFER_WAITERS:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- process_log_buffer_waiters(signal, ptr);
- return;
- }
- case LgmanContinueB::FIND_LOG_HEAD:
- jam();
- Ptr<Logfile_group> ptr;
- if(ptrI != RNIL)
- {
- m_logfile_group_pool.getPtr(ptr, ptrI);
- find_log_head(signal, ptr);
- }
- else
- {
- init_run_undo_log(signal);
- }
- return;
- case LgmanContinueB::EXECUTE_UNDO_RECORD:
- jam();
- execute_undo_record(signal);
- return;
- case LgmanContinueB::STOP_UNDO_LOG:
- jam();
- stop_run_undo_log(signal);
- return;
- case LgmanContinueB::READ_UNDO_LOG:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- read_undo_log(signal, ptr);
- return;
- }
- case LgmanContinueB::PROCESS_LOG_SYNC_WAITERS:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- process_log_sync_waiters(signal, ptr);
- return;
- }
- case LgmanContinueB::FORCE_LOG_SYNC:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- force_log_sync(signal, ptr, signal->theData[2], signal->theData[3]);
- return;
- }
- case LgmanContinueB::DROP_FILEGROUP:
- {
- jam();
- Ptr<Logfile_group> ptr;
- m_logfile_group_pool.getPtr(ptr, ptrI);
- if (ptr.p->m_state & Logfile_group::LG_THREAD_MASK)
- {
- jam();
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100,
- signal->length());
- return;
- }
- Uint32 ref = signal->theData[2];
- Uint32 data = signal->theData[3];
- drop_filegroup_drop_files(signal, ptr, ref, data);
- return;
- }
- }
-}
-
-void
-Lgman::execDUMP_STATE_ORD(Signal* signal){
- jamEntry();
- if(signal->theData[0] == 12001)
- {
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
- while(!ptr.isNull())
- {
- infoEvent("lfg %d state: %x fs: %d lsn "
- "[ last: %lld s(req): %lld s:ed: %lld lcp: %lld ] waiters: %d %d",
- ptr.p->m_logfile_group_id, ptr.p->m_state,
- ptr.p->m_outstanding_fs,
- ptr.p->m_last_lsn, ptr.p->m_last_sync_req_lsn,
- ptr.p->m_last_synced_lsn, ptr.p->m_last_lcp_lsn,
- !ptr.p->m_log_buffer_waiters.isEmpty(),
- !ptr.p->m_log_sync_waiters.isEmpty());
- if (!ptr.p->m_log_buffer_waiters.isEmpty())
- {
- Ptr<Log_waiter> waiter;
- Local_log_waiter_list
- list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
- list.first(waiter);
- infoEvent(" free_buffer_words: %d head(waiters).sz: %d %d",
- ptr.p->m_free_buffer_words,
- waiter.p->m_size,
- 2*File_formats::UNDO_PAGE_WORDS);
- }
- if (!ptr.p->m_log_sync_waiters.isEmpty())
- {
- Ptr<Log_waiter> waiter;
- Local_log_waiter_list
- list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
- list.first(waiter);
- infoEvent(" m_last_synced_lsn: %lld head(waiters %x).m_sync_lsn: %lld",
- ptr.p->m_last_synced_lsn,
- waiter.i,
- waiter.p->m_sync_lsn);
-
- while(!waiter.isNull())
- {
- ndbout_c("ptr: %x %p lsn: %lld next: %x",
- waiter.i, waiter.p, waiter.p->m_sync_lsn, waiter.p->nextList);
- list.next(waiter);
- }
- }
- m_logfile_group_list.next(ptr);
- }
- }
-}
-
-void
-Lgman::execCREATE_FILEGROUP_REQ(Signal* signal){
- jamEntry();
- CreateFilegroupImplReq* req= (CreateFilegroupImplReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- Ptr<Logfile_group> ptr;
- CreateFilegroupImplRef::ErrorCode err = CreateFilegroupImplRef::NoError;
- do {
- if (m_logfile_group_hash.find(ptr, req->filegroup_id))
- {
- jam();
- err = CreateFilegroupImplRef::FilegroupAlreadyExists;
- break;
- }
-
- if (!m_logfile_group_list.isEmpty())
- {
- jam();
- err = CreateFilegroupImplRef::OneLogfileGroupLimit;
- break;
- }
-
- if (!m_logfile_group_pool.seize(ptr))
- {
- jam();
- err = CreateFilegroupImplRef::OutOfFilegroupRecords;
- break;
- }
-
- new (ptr.p) Logfile_group(req);
-
- if (!alloc_logbuffer_memory(ptr, req->logfile_group.buffer_size))
- {
- jam();
- err= CreateFilegroupImplRef::OutOfLogBufferMemory;
- m_logfile_group_pool.release(ptr);
- break;
- }
-
- m_logfile_group_hash.add(ptr);
- m_logfile_group_list.add(ptr);
-
- if (getNodeState().getNodeRestartInProgress() ||
- getNodeState().getSystemRestartInProgress())
- {
- ptr.p->m_state = Logfile_group::LG_STARTING;
- }
-
- CreateFilegroupImplConf* conf=
- (CreateFilegroupImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILEGROUP_CONF, signal,
- CreateFilegroupImplConf::SignalLength, JBB);
-
- return;
- } while(0);
-
- CreateFilegroupImplRef* ref= (CreateFilegroupImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = err;
- sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF, signal,
- CreateFilegroupImplRef::SignalLength, JBB);
-}
-
-void
-Lgman::execDROP_FILEGROUP_REQ(Signal* signal)
-{
- jamEntry();
-
- Uint32 errorCode = 0;
- DropFilegroupImplReq req = *(DropFilegroupImplReq*)signal->getDataPtr();
- do
- {
- Ptr<Logfile_group> ptr;
- if (!m_logfile_group_hash.find(ptr, req.filegroup_id))
- {
- errorCode = DropFilegroupImplRef::NoSuchFilegroup;
- break;
- }
-
- if (ptr.p->m_version != req.filegroup_version)
- {
- errorCode = DropFilegroupImplRef::InvalidFilegroupVersion;
- break;
- }
-
- switch(req.requestInfo){
- case DropFilegroupImplReq::Prepare:
- break;
- case DropFilegroupImplReq::Commit:
- m_logfile_group_list.remove(ptr);
- ptr.p->m_state |= Logfile_group::LG_DROPPING;
- signal->theData[0] = LgmanContinueB::DROP_FILEGROUP;
- signal->theData[1] = ptr.i;
- signal->theData[2] = req.senderRef;
- signal->theData[3] = req.senderData;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- return;
- case DropFilegroupImplReq::Abort:
- break;
- default:
- ndbrequire(false);
- }
- } while(0);
-
- if (errorCode)
- {
- DropFilegroupImplRef* ref =
- (DropFilegroupImplRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = req.senderData;
- ref->errorCode = errorCode;
- sendSignal(req.senderRef, GSN_DROP_FILEGROUP_REF, signal,
- DropFilegroupImplRef::SignalLength, JBB);
- }
- else
- {
- DropFilegroupImplConf* conf =
- (DropFilegroupImplConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = req.senderData;
- sendSignal(req.senderRef, GSN_DROP_FILEGROUP_CONF, signal,
- DropFilegroupImplConf::SignalLength, JBB);
- }
-}
-
-void
-Lgman::drop_filegroup_drop_files(Signal* signal,
- Ptr<Logfile_group> ptr,
- Uint32 ref, Uint32 data)
-{
- jam();
- ndbrequire(! (ptr.p->m_state & Logfile_group::LG_THREAD_MASK));
- ndbrequire(ptr.p->m_outstanding_fs == 0);
-
- Local_undofile_list list(m_file_pool, ptr.p->m_files);
- Ptr<Undofile> file_ptr;
-
- if (list.first(file_ptr))
- {
- jam();
- ndbrequire(! (file_ptr.p->m_state & Undofile::FS_OUTSTANDING));
- file_ptr.p->m_create.m_senderRef = ref;
- file_ptr.p->m_create.m_senderData = data;
- create_file_abort(signal, ptr, file_ptr);
- return;
- }
-
- Local_undofile_list metalist(m_file_pool, ptr.p->m_meta_files);
- if (metalist.first(file_ptr))
- {
- jam();
- metalist.remove(file_ptr);
- list.add(file_ptr);
- file_ptr.p->m_create.m_senderRef = ref;
- file_ptr.p->m_create.m_senderData = data;
- create_file_abort(signal, ptr, file_ptr);
- return;
- }
-
- free_logbuffer_memory(ptr);
- m_logfile_group_hash.release(ptr);
- DropFilegroupImplConf *conf = (DropFilegroupImplConf*)signal->getDataPtr();
- conf->senderData = data;
- conf->senderRef = reference();
- sendSignal(ref, GSN_DROP_FILEGROUP_CONF, signal,
- DropFilegroupImplConf::SignalLength, JBB);
-}
-
-void
-Lgman::execCREATE_FILE_REQ(Signal* signal)
-{
- jamEntry();
- CreateFileImplReq* req= (CreateFileImplReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 requestInfo = req->requestInfo;
-
- Ptr<Logfile_group> ptr;
- CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
- do {
- if (!m_logfile_group_hash.find(ptr, req->filegroup_id))
- {
- jam();
- err = CreateFileImplRef::InvalidFilegroup;
- break;
- }
-
- if (ptr.p->m_version != req->filegroup_version)
- {
- jam();
- err = CreateFileImplRef::InvalidFilegroupVersion;
- break;
- }
-
- Ptr<Undofile> file_ptr;
- switch(requestInfo){
- case CreateFileImplReq::Commit:
- {
- jam();
- ndbrequire(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id));
- file_ptr.p->m_create.m_senderRef = req->senderRef;
- file_ptr.p->m_create.m_senderData = req->senderData;
- create_file_commit(signal, ptr, file_ptr);
- return;
- }
- case CreateFileImplReq::Abort:
- {
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- if (find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id))
- {
- jam();
- file_ptr.p->m_create.m_senderRef = senderRef;
- file_ptr.p->m_create.m_senderData = senderData;
- create_file_abort(signal, ptr, file_ptr);
- }
- else
- {
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- jam();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- }
- return;
- }
- default: // prepare
- break;
- }
-
- if (!m_file_pool.seize(file_ptr))
- {
- jam();
- err = CreateFileImplRef::OutOfFileRecords;
- break;
- }
-
- if(ERROR_INSERTED(15000) ||
- (sizeof(void*) == 4 && req->file_size_hi & 0xFFFFFFFF))
- {
- jam();
- if(signal->getNoOfSections())
- releaseSections(signal);
-
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = CreateFileImplRef::FileSizeTooLarge;
- sendSignal(senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
- return;
- }
-
- new (file_ptr.p) Undofile(req, ptr.i);
-
- Local_undofile_list tmp(m_file_pool, ptr.p->m_meta_files);
- tmp.add(file_ptr);
-
- open_file(signal, file_ptr, req->requestInfo);
- return;
- } while(0);
-
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = err;
- sendSignal(senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
-}
-
-void
-Lgman::open_file(Signal* signal, Ptr<Undofile> ptr, Uint32 requestInfo)
-{
- FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = ptr.i;
-
- memset(req->fileNumber, 0, sizeof(req->fileNumber));
- FsOpenReq::setVersion(req->fileNumber, 4); // Version 4 = specified filename
-
- req->fileFlags = 0;
- req->fileFlags |= FsOpenReq::OM_READWRITE;
- req->fileFlags |= FsOpenReq::OM_DIRECT;
- req->fileFlags |= FsOpenReq::OM_SYNC;
- switch(requestInfo){
- case CreateFileImplReq::Create:
- req->fileFlags |= FsOpenReq::OM_CREATE_IF_NONE;
- req->fileFlags |= FsOpenReq::OM_INIT;
- ptr.p->m_state = Undofile::FS_CREATING;
- break;
- case CreateFileImplReq::CreateForce:
- req->fileFlags |= FsOpenReq::OM_CREATE;
- req->fileFlags |= FsOpenReq::OM_INIT;
- ptr.p->m_state = Undofile::FS_CREATING;
- break;
- case CreateFileImplReq::Open:
- req->fileFlags |= FsOpenReq::OM_CHECK_SIZE;
- ptr.p->m_state = Undofile::FS_OPENING;
- break;
- default:
- ndbrequire(false);
- }
-
- req->page_size = File_formats::NDB_PAGE_SIZE;
- Uint64 size = (Uint64)ptr.p->m_file_size * (Uint64)File_formats::NDB_PAGE_SIZE;
- req->file_size_hi = size >> 32;
- req->file_size_lo = size & 0xFFFFFFFF;
-
- // Forward filename
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB);
-}
-
-void
-Lgman::execFSWRITEREQ(Signal* signal)
-{
- jamEntry();
- Ptr<Undofile> ptr;
- Ptr<GlobalPage> page_ptr;
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtr();
-
- m_file_pool.getPtr(ptr, req->userPointer);
- m_global_page_pool.getPtr(page_ptr, req->data.pageData[0]);
-
- if (req->varIndex == 0)
- {
- jam();
- File_formats::Undofile::Zero_page* page =
- (File_formats::Undofile::Zero_page*)page_ptr.p;
- page->m_page_header.init(File_formats::FT_Undofile,
- getOwnNodeId(),
- ndbGetOwnVersion(),
- time(0));
- page->m_file_id = ptr.p->m_file_id;
- page->m_logfile_group_id = ptr.p->m_create.m_logfile_group_id;
- page->m_logfile_group_version = ptr.p->m_create.m_logfile_group_version;
- page->m_undo_pages = ptr.p->m_file_size - 1; // minus zero page
- }
- else
- {
- jam();
- File_formats::Undofile::Undo_page* page =
- (File_formats::Undofile::Undo_page*)page_ptr.p;
- page->m_page_header.m_page_lsn_hi = 0;
- page->m_page_header.m_page_lsn_lo = 0;
- page->m_page_header.m_page_type = File_formats::PT_Undopage;
- page->m_words_used = 0;
- }
-}
-
-void
-Lgman::execFSOPENREF(Signal* signal)
-{
- jamEntry();
-
- Ptr<Undofile> ptr;
- Ptr<Logfile_group> lg_ptr;
- FsRef* ref = (FsRef*)signal->getDataPtr();
-
- Uint32 errCode = ref->errorCode;
- Uint32 osErrCode = ref->osErrorCode;
-
- m_file_pool.getPtr(ptr, ref->userPointer);
- m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
-
- {
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = ptr.p->m_create.m_senderData;
- ref->senderRef = reference();
- ref->errorCode = CreateFileImplRef::FileError;
- ref->fsErrCode = errCode;
- ref->osErrCode = osErrCode;
- sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
- }
-
- Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- meta.release(ptr);
-}
-
-#define HEAD 0
-#define TAIL 1
-
-void
-Lgman::execFSOPENCONF(Signal* signal)
-{
- jamEntry();
- Ptr<Undofile> ptr;
-
- FsConf* conf = (FsConf*)signal->getDataPtr();
-
- Uint32 fd = conf->filePointer;
- m_file_pool.getPtr(ptr, conf->userPointer);
-
- ptr.p->m_fd = fd;
-
- {
- Uint32 senderRef = ptr.p->m_create.m_senderRef;
- Uint32 senderData = ptr.p->m_create.m_senderData;
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- }
-}
-
-bool
-Lgman::find_file_by_id(Ptr<Undofile>& ptr,
- Local_undofile_list::Head& head, Uint32 id)
-{
- Local_undofile_list list(m_file_pool, head);
- for(list.first(ptr); !ptr.isNull(); list.next(ptr))
- if(ptr.p->m_file_id == id)
- return true;
- return false;
-}
-
-void
-Lgman::create_file_commit(Signal* signal,
- Ptr<Logfile_group> lg_ptr,
- Ptr<Undofile> ptr)
-{
- Uint32 senderRef = ptr.p->m_create.m_senderRef;
- Uint32 senderData = ptr.p->m_create.m_senderData;
-
- bool first= false;
- if(ptr.p->m_state == Undofile::FS_CREATING &&
- (lg_ptr.p->m_state & Logfile_group::LG_ONLINE))
- {
- jam();
- Local_undofile_list free(m_file_pool, lg_ptr.p->m_files);
- Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- first= free.isEmpty();
- meta.remove(ptr);
- if(!first)
- {
- /**
- * Add log file next after current head
- */
- Ptr<Undofile> curr;
- m_file_pool.getPtr(curr, lg_ptr.p->m_file_pos[HEAD].m_ptr_i);
- if(free.next(curr))
- free.insert(ptr, curr); // inserts before (that's why the extra next)
- else
- free.add(ptr);
-
- ptr.p->m_state = Undofile::FS_ONLINE | Undofile::FS_EMPTY;
- }
- else
- {
- /**
- * First file isn't empty as it can be written to at any time
- */
- free.add(ptr);
- ptr.p->m_state = Undofile::FS_ONLINE;
- lg_ptr.p->m_state |= Logfile_group::LG_FLUSH_THREAD;
- signal->theData[0] = LgmanContinueB::FLUSH_LOG;
- signal->theData[1] = lg_ptr.i;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
- }
- else
- {
- ptr.p->m_state = Undofile::FS_SORTING;
- }
-
- ptr.p->m_online.m_lsn = 0;
- ptr.p->m_online.m_outstanding = 0;
-
- Uint64 add= ptr.p->m_file_size - 1;
- lg_ptr.p->m_free_file_words += add * File_formats::UNDO_PAGE_WORDS;
-
- if(first)
- {
- jam();
-
- Buffer_idx tmp= { ptr.i, 0 };
- lg_ptr.p->m_file_pos[HEAD] = lg_ptr.p->m_file_pos[TAIL] = tmp;
-
- /**
- * Init log tail pointer
- */
- lg_ptr.p->m_tail_pos[0] = tmp;
- lg_ptr.p->m_tail_pos[1] = tmp;
- lg_ptr.p->m_tail_pos[2] = tmp;
- lg_ptr.p->m_next_reply_ptr_i = ptr.i;
- }
-
- validate_logfile_group(lg_ptr, "create_file_commit");
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
-}
-
-void
-Lgman::create_file_abort(Signal* signal,
- Ptr<Logfile_group> lg_ptr,
- Ptr<Undofile> ptr)
-{
- if (ptr.p->m_fd == RNIL)
- {
- ((FsConf*)signal->getDataPtr())->userPointer = ptr.i;
- execFSCLOSECONF(signal);
- return;
- }
-
- FsCloseReq *req= (FsCloseReq*)signal->getDataPtrSend();
- req->filePointer = ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->fileFlag = 0;
- FsCloseReq::setRemoveFileFlag(req->fileFlag, true);
-
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal,
- FsCloseReq::SignalLength, JBB);
-}
-
-void
-Lgman::execFSCLOSECONF(Signal* signal)
-{
- Ptr<Undofile> ptr;
- Ptr<Logfile_group> lg_ptr;
- Uint32 ptrI = ((FsConf*)signal->getDataPtr())->userPointer;
- m_file_pool.getPtr(ptr, ptrI);
-
- Uint32 senderRef = ptr.p->m_create.m_senderRef;
- Uint32 senderData = ptr.p->m_create.m_senderData;
-
- m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
-
- if (lg_ptr.p->m_state & Logfile_group::LG_DROPPING)
- {
- jam();
- {
- Local_undofile_list list(m_file_pool, lg_ptr.p->m_files);
- list.release(ptr);
- }
- drop_filegroup_drop_files(signal, lg_ptr, senderRef, senderData);
- }
- else
- {
- jam();
- Local_undofile_list list(m_file_pool, lg_ptr.p->m_meta_files);
- list.release(ptr);
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- }
-}
-
-void
-Lgman::execDROP_FILE_REQ(Signal* signal)
-{
- jamEntry();
- ndbrequire(false);
-}
-
-#define CONSUMER 0
-#define PRODUCER 1
-
-Lgman::Logfile_group::Logfile_group(const CreateFilegroupImplReq* req)
-{
- m_logfile_group_id = req->filegroup_id;
- m_version = req->filegroup_version;
- m_state = LG_ONLINE;
- m_outstanding_fs = 0;
- m_next_reply_ptr_i = RNIL;
-
- m_last_lsn = 0;
- m_last_synced_lsn = 0;
- m_last_sync_req_lsn = 0;
- m_max_sync_req_lsn = 0;
- m_last_read_lsn = 0;
- m_file_pos[0].m_ptr_i= m_file_pos[1].m_ptr_i = RNIL;
-
- m_free_file_words = 0;
- m_free_buffer_words = 0;
- m_pos[CONSUMER].m_current_page.m_ptr_i = RNIL;// { m_buffer_pages, idx }
- m_pos[CONSUMER].m_current_pos.m_ptr_i = RNIL; // { page ptr.i, m_words_used}
- m_pos[PRODUCER].m_current_page.m_ptr_i = RNIL;// { m_buffer_pages, idx }
- m_pos[PRODUCER].m_current_pos.m_ptr_i = RNIL; // { page ptr.i, m_words_used}
-
- m_tail_pos[2].m_ptr_i= RNIL;
- m_tail_pos[2].m_idx= ~0;
-
- m_tail_pos[0] = m_tail_pos[1] = m_tail_pos[2];
-}
-
-bool
-Lgman::alloc_logbuffer_memory(Ptr<Logfile_group> ptr, Uint32 bytes)
-{
- Uint32 pages= (((bytes + 3) >> 2) + File_formats::NDB_PAGE_SIZE_WORDS - 1)
- / File_formats::NDB_PAGE_SIZE_WORDS;
- Uint32 requested= pages;
- {
- Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
- while(pages)
- {
- Uint32 ptrI;
- Uint32 cnt = pages > 64 ? 64 : pages;
- m_ctx.m_mm.alloc_pages(RG_DISK_OPERATIONS, &ptrI, &cnt, 1);
- if (cnt)
- {
- Buffer_idx range;
- range.m_ptr_i= ptrI;
- range.m_idx = cnt;
-
- ndbrequire(map.append((Uint32*)&range, 2));
- pages -= range.m_idx;
- }
- else
- {
- break;
- }
- }
- }
-
- if(2*pages > requested)
- {
- // less than half allocated
- free_logbuffer_memory(ptr);
- return false;
- }
-
- if(pages != 0)
- {
- warningEvent("Allocated %d pages for log buffer space, logfile_group: %d"
- " , requested %d pages",
- (requested-pages), ptr.p->m_logfile_group_id, requested);
- }
-
- init_logbuffer_pointers(ptr);
- return true;
-}
-
-void
-Lgman::init_logbuffer_pointers(Ptr<Logfile_group> ptr)
-{
- Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
- Page_map::Iterator it;
- union {
- Uint32 tmp[2];
- Buffer_idx range;
- };
-
- map.first(it);
- tmp[0] = *it.data;
- ndbrequire(map.next(it));
- tmp[1] = *it.data;
-
- ptr.p->m_pos[CONSUMER].m_current_page.m_ptr_i = 0; // Index in page map
- ptr.p->m_pos[CONSUMER].m_current_page.m_idx = range.m_idx - 1;// left range
- ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i = range.m_ptr_i; // Which page
- ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = 0; // Page pos
-
- ptr.p->m_pos[PRODUCER].m_current_page.m_ptr_i = 0; // Index in page map
- ptr.p->m_pos[PRODUCER].m_current_page.m_idx = range.m_idx - 1;// left range
- ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i = range.m_ptr_i; // Which page
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0; // Page pos
-
- Uint32 pages= range.m_idx;
- while(map.next(it))
- {
- tmp[0] = *it.data;
- ndbrequire(map.next(it));
- tmp[1] = *it.data;
- pages += range.m_idx;
- }
-
- ptr.p->m_free_buffer_words = pages * File_formats::UNDO_PAGE_WORDS;
-}
-
-Uint32
-Lgman::compute_free_file_pages(Ptr<Logfile_group> ptr)
-{
- Buffer_idx head= ptr.p->m_file_pos[HEAD];
- Buffer_idx tail= ptr.p->m_file_pos[TAIL];
- Uint32 pages = 0;
- if (head.m_ptr_i == tail.m_ptr_i && head.m_idx < tail.m_idx)
- {
- pages += tail.m_idx - head.m_idx;
- }
- else
- {
- Ptr<Undofile> file;
- m_file_pool.getPtr(file, head.m_ptr_i);
- Local_undofile_list list(m_file_pool, ptr.p->m_files);
-
- do
- {
- pages += (file.p->m_file_size - head.m_idx - 1);
- if(!list.next(file))
- list.first(file);
- head.m_idx = 0;
- } while(file.i != tail.m_ptr_i);
-
- pages += tail.m_idx - head.m_idx;
- }
- return pages;
-}
-
-void
-Lgman::free_logbuffer_memory(Ptr<Logfile_group> ptr)
-{
- union {
- Uint32 tmp[2];
- Buffer_idx range;
- };
-
- Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
-
- Page_map::Iterator it;
- map.first(it);
- while(!it.isNull())
- {
- tmp[0] = *it.data;
- ndbrequire(map.next(it));
- tmp[1] = *it.data;
-
- m_ctx.m_mm.release_pages(RG_DISK_OPERATIONS, range.m_ptr_i, range.m_idx);
- map.next(it);
- }
- map.release();
-}
-
-Lgman::Undofile::Undofile(const struct CreateFileImplReq* req, Uint32 ptrI)
-{
- m_fd = RNIL;
- m_file_id = req->file_id;
- m_logfile_group_ptr_i= ptrI;
-
- Uint64 pages = req->file_size_hi;
- pages = (pages << 32) | req->file_size_lo;
- pages /= GLOBAL_PAGE_SIZE;
- m_file_size = pages;
-
- m_create.m_senderRef = req->senderRef; // During META
- m_create.m_senderData = req->senderData; // During META
- m_create.m_logfile_group_id = req->filegroup_id;
-}
-
-Logfile_client::Logfile_client(SimulatedBlock* block,
- Lgman* lgman, Uint32 logfile_group_id)
-{
- m_block= block->number();
- m_lgman= lgman;
- m_logfile_group_id= logfile_group_id;
-}
-
-int
-Logfile_client::sync_lsn(Signal* signal,
- Uint64 lsn, Request* req, Uint32 flags)
-{
- Ptr<Lgman::Logfile_group> ptr;
- if(m_lgman->m_logfile_group_list.first(ptr))
- {
- if(ptr.p->m_last_synced_lsn >= lsn)
- {
- return 1;
- }
-
- bool empty= false;
- Ptr<Lgman::Log_waiter> wait;
- {
- Lgman::Local_log_waiter_list
- list(m_lgman->m_log_waiter_pool, ptr.p->m_log_sync_waiters);
-
- empty= list.isEmpty();
- if(!list.seize(wait))
- return -1;
-
- wait.p->m_block= m_block;
- wait.p->m_sync_lsn= lsn;
- memcpy(&wait.p->m_callback, &req->m_callback,
- sizeof(SimulatedBlock::Callback));
-
- ptr.p->m_max_sync_req_lsn = lsn > ptr.p->m_max_sync_req_lsn ?
- lsn : ptr.p->m_max_sync_req_lsn;
- }
-
- if(ptr.p->m_last_sync_req_lsn < lsn &&
- ! (ptr.p->m_state & Lgman::Logfile_group::LG_FORCE_SYNC_THREAD))
- {
- ptr.p->m_state |= Lgman::Logfile_group::LG_FORCE_SYNC_THREAD;
- signal->theData[0] = LgmanContinueB::FORCE_LOG_SYNC;
- signal->theData[1] = ptr.i;
- signal->theData[2] = lsn >> 32;
- signal->theData[3] = lsn & 0xFFFFFFFF;
- m_lgman->sendSignalWithDelay(m_lgman->reference(),
- GSN_CONTINUEB, signal, 10, 4);
- }
- return 0;
- }
- return -1;
-}
-
-void
-Lgman::force_log_sync(Signal* signal,
- Ptr<Logfile_group> ptr,
- Uint32 lsn_hi, Uint32 lsn_lo)
-{
- Local_log_waiter_list list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
- Uint64 force_lsn = lsn_hi; force_lsn <<= 32; force_lsn += lsn_lo;
-
- if(ptr.p->m_last_sync_req_lsn < force_lsn)
- {
- /**
- * Do force
- */
- Buffer_idx pos= ptr.p->m_pos[PRODUCER].m_current_pos;
- GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
-
- Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
- if(pos.m_idx) // don't flush empty page...
- {
- Uint64 lsn= ptr.p->m_last_lsn - 1;
-
- File_formats::Undofile::Undo_page* undo=
- (File_formats::Undofile::Undo_page*)page;
- undo->m_page_header.m_page_lsn_lo = lsn & 0xFFFFFFFF;
- undo->m_page_header.m_page_lsn_hi = lsn >> 32;
- undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
-
- /**
- * Update free space with extra NOOP
- */
- ndbrequire(ptr.p->m_free_file_words >= free);
- ndbrequire(ptr.p->m_free_buffer_words > free);
- ptr.p->m_free_file_words -= free;
- ptr.p->m_free_buffer_words -= free;
-
- validate_logfile_group(ptr, "force_log_sync");
-
- next_page(ptr.p, PRODUCER);
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0;
- }
- }
-
-
-
- Uint64 max_req_lsn = ptr.p->m_max_sync_req_lsn;
- if(max_req_lsn > force_lsn &&
- max_req_lsn > ptr.p->m_last_sync_req_lsn)
- {
- ndbrequire(ptr.p->m_state & Lgman::Logfile_group::LG_FORCE_SYNC_THREAD);
- signal->theData[0] = LgmanContinueB::FORCE_LOG_SYNC;
- signal->theData[1] = ptr.i;
- signal->theData[2] = max_req_lsn >> 32;
- signal->theData[3] = max_req_lsn & 0xFFFFFFFF;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 4);
- }
- else
- {
- ptr.p->m_state &= ~(Uint32)Lgman::Logfile_group::LG_FORCE_SYNC_THREAD;
- }
-}
-
-void
-Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr)
-{
- Local_log_waiter_list
- list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
-
- if(list.isEmpty())
- {
- return;
- }
-
- bool removed= false;
- Ptr<Log_waiter> waiter;
- list.first(waiter);
- Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
-
- if(waiter.p->m_sync_lsn <= ptr.p->m_last_synced_lsn)
- {
- removed= true;
- Uint32 block = waiter.p->m_block;
- SimulatedBlock* b = globalData.getBlock(block);
- b->execute(signal, waiter.p->m_callback, logfile_group_id);
-
- list.releaseFirst(waiter);
- }
-
- if(removed && !list.isEmpty())
- {
- ptr.p->m_state |= Logfile_group::LG_SYNC_WAITERS_THREAD;
- signal->theData[0] = LgmanContinueB::PROCESS_LOG_SYNC_WAITERS;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
- else
- {
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_SYNC_WAITERS_THREAD;
- }
-}
-
-
-Uint32*
-Lgman::get_log_buffer(Ptr<Logfile_group> ptr, Uint32 sz)
-{
- GlobalPage *page;
- page=m_shared_page_pool.getPtr(ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i);
-
- Uint32 total_free= ptr.p->m_free_buffer_words;
- assert(total_free >= sz);
- Uint32 pos= ptr.p->m_pos[PRODUCER].m_current_pos.m_idx;
- Uint32 free= File_formats::UNDO_PAGE_WORDS - pos;
-
- if(sz <= free)
- {
-next:
- // fits this page wo/ problem
- ndbrequire(total_free > sz);
- ptr.p->m_free_buffer_words = total_free - sz;
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = pos + sz;
- return ((File_formats::Undofile::Undo_page*)page)->m_data + pos;
- }
-
- /**
- * It didn't fit page...fill page with a NOOP log entry
- */
- Uint64 lsn= ptr.p->m_last_lsn - 1;
- File_formats::Undofile::Undo_page* undo=
- (File_formats::Undofile::Undo_page*)page;
- undo->m_page_header.m_page_lsn_lo = lsn & 0xFFFFFFFF;
- undo->m_page_header.m_page_lsn_hi = lsn >> 32;
- undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
-
- /**
- * Update free space with extra NOOP
- */
- ndbrequire(ptr.p->m_free_file_words >= free);
- ptr.p->m_free_file_words -= free;
-
- validate_logfile_group(ptr, "get_log_buffer");
-
- pos= 0;
- assert(total_free >= free);
- total_free -= free;
- page= m_shared_page_pool.getPtr(next_page(ptr.p, PRODUCER));
- goto next;
-}
-
-Uint32
-Lgman::next_page(Logfile_group* ptrP, Uint32 i)
-{
- Uint32 page_ptr_i= ptrP->m_pos[i].m_current_pos.m_ptr_i;
- Uint32 left_in_range= ptrP->m_pos[i].m_current_page.m_idx;
- if(left_in_range > 0)
- {
- ptrP->m_pos[i].m_current_page.m_idx = left_in_range - 1;
- ptrP->m_pos[i].m_current_pos.m_ptr_i = page_ptr_i + 1;
- return page_ptr_i + 1;
- }
- else
- {
- Lgman::Page_map map(m_data_buffer_pool, ptrP->m_buffer_pages);
- Uint32 pos= (ptrP->m_pos[i].m_current_page.m_ptr_i + 2) % map.getSize();
- Lgman::Page_map::Iterator it;
- map.position(it, pos);
-
- union {
- Uint32 tmp[2];
- Lgman::Buffer_idx range;
- };
-
- tmp[0] = *it.data; map.next(it);
- tmp[1] = *it.data;
-
- ptrP->m_pos[i].m_current_page.m_ptr_i = pos; // New index in map
- ptrP->m_pos[i].m_current_page.m_idx = range.m_idx - 1; // Free pages
- ptrP->m_pos[i].m_current_pos.m_ptr_i = range.m_ptr_i; // Current page
- // No need to set ptrP->m_current_pos.m_idx, that is set "in higher"-func
- return range.m_ptr_i;
- }
-}
-
-int
-Logfile_client::get_log_buffer(Signal* signal, Uint32 sz,
- SimulatedBlock::Callback* callback)
-{
- sz += 2; // lsn
- Lgman::Logfile_group key;
- key.m_logfile_group_id= m_logfile_group_id;
- Ptr<Lgman::Logfile_group> ptr;
- if(m_lgman->m_logfile_group_hash.find(ptr, key))
- {
- if(ptr.p->m_free_buffer_words >= (sz + 2*File_formats::UNDO_PAGE_WORDS)&&
- ptr.p->m_log_buffer_waiters.isEmpty())
- {
- return 1;
- }
-
- bool empty= false;
- {
- Ptr<Lgman::Log_waiter> wait;
- Lgman::Local_log_waiter_list
- list(m_lgman->m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
-
- empty= list.isEmpty();
- if(!list.seize(wait))
- {
- return -1;
- }
-
- wait.p->m_size= sz;
- wait.p->m_block= m_block;
- memcpy(&wait.p->m_callback, callback,sizeof(SimulatedBlock::Callback));
- }
-
- return 0;
- }
- return -1;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Lgman::Buffer_idx& pos)
-{
- out << "[ "
- << pos.m_ptr_i << " "
- << pos.m_idx << " ]";
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const Lgman::Logfile_group::Position& pos)
-{
- out << "[ ("
- << pos.m_current_page.m_ptr_i << " "
- << pos.m_current_page.m_idx << ") ("
- << pos.m_current_pos.m_ptr_i << " "
- << pos.m_current_pos.m_idx << ") ]";
- return out;
-}
-
-void
-Lgman::flush_log(Signal* signal, Ptr<Logfile_group> ptr, Uint32 force)
-{
- Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
- Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
-
- jamEntry();
-
- if(consumer.m_current_page == producer.m_current_page)
- {
-
-#if 0
- if (force)
- {
- ndbout_c("force: %d ptr.p->m_file_pos[HEAD].m_ptr_i= %x",
- force, ptr.p->m_file_pos[HEAD].m_ptr_i);
- ndbout_c("consumer.m_current_page: %d %d producer.m_current_page: %d %d",
- consumer.m_current_page.m_ptr_i, consumer.m_current_page.m_idx,
- producer.m_current_page.m_ptr_i, producer.m_current_page.m_idx);
- }
-#endif
- if (! (ptr.p->m_state & Logfile_group::LG_DROPPING))
- {
- jam();
-
- if (ptr.p->m_log_buffer_waiters.isEmpty() || ptr.p->m_outstanding_fs)
- {
- force = 0;
- }
-
- if (force < 2)
- {
- signal->theData[0] = LgmanContinueB::FLUSH_LOG;
- signal->theData[1] = ptr.i;
- signal->theData[2] = force + 1;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal,
- force ? 10 : 100, 3);
- return;
- }
- else
- {
- Buffer_idx pos= producer.m_current_pos;
- GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
-
- Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
-
- ndbout_c("force flush %d %d", pos.m_idx, ptr.p->m_free_buffer_words);
-
- ndbrequire(pos.m_idx); // don't flush empty page...
- Uint64 lsn= ptr.p->m_last_lsn - 1;
-
- File_formats::Undofile::Undo_page* undo=
- (File_formats::Undofile::Undo_page*)page;
- undo->m_page_header.m_page_lsn_lo = lsn & 0xFFFFFFFF;
- undo->m_page_header.m_page_lsn_hi = lsn >> 32;
- undo->m_words_used= File_formats::UNDO_PAGE_WORDS - free;
-
- /**
- * Update free space with extra NOOP
- */
- ndbrequire(ptr.p->m_free_file_words >= free);
- ndbrequire(ptr.p->m_free_buffer_words > free);
- ptr.p->m_free_file_words -= free;
- ptr.p->m_free_buffer_words -= free;
-
- validate_logfile_group(ptr, "force_log_flush");
-
- next_page(ptr.p, PRODUCER);
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 0;
- producer = ptr.p->m_pos[PRODUCER];
- // break through
- }
- }
- else
- {
- jam();
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_FLUSH_THREAD;
- return;
- }
- }
-
- bool full= false;
- Uint32 tot= 0;
- while(!(consumer.m_current_page == producer.m_current_page) && !full)
- {
- validate_logfile_group(ptr, "before flush log");
-
- Uint32 cnt; // pages written
- Uint32 page= consumer.m_current_pos.m_ptr_i;
- if(consumer.m_current_page.m_ptr_i == producer.m_current_page.m_ptr_i)
- {
- if(consumer.m_current_page.m_idx > producer.m_current_page.m_idx)
- {
- jam();
- Uint32 tmp=
- consumer.m_current_page.m_idx - producer.m_current_page.m_idx;
- cnt= write_log_pages(signal, ptr, page, tmp);
- assert(cnt <= tmp);
-
- consumer.m_current_pos.m_ptr_i += cnt;
- consumer.m_current_page.m_idx -= cnt;
- full= (tmp > cnt);
- }
- else
- {
- // Only 1 chunk
- ndbrequire(ptr.p->m_buffer_pages.getSize() == 2);
- Uint32 tmp= consumer.m_current_page.m_idx + 1;
- cnt= write_log_pages(signal, ptr, page, tmp);
- assert(cnt <= tmp);
-
- if(cnt == tmp)
- {
- jam();
- /**
- * Entire chunk is written
- * move to next
- */
- ptr.p->m_pos[CONSUMER].m_current_page.m_idx= 0;
- next_page(ptr.p, CONSUMER);
- consumer = ptr.p->m_pos[CONSUMER];
- }
- else
- {
- jam();
- /**
- * Failed to write entire chunk...
- */
- full= true;
- consumer.m_current_page.m_idx -= cnt;
- consumer.m_current_pos.m_ptr_i += cnt;
- }
- }
- }
- else
- {
- Uint32 tmp= consumer.m_current_page.m_idx + 1;
- cnt= write_log_pages(signal, ptr, page, tmp);
- assert(cnt <= tmp);
-
- if(cnt == tmp)
- {
- jam();
- /**
- * Entire chunk is written
- * move to next
- */
- ptr.p->m_pos[CONSUMER].m_current_page.m_idx= 0;
- next_page(ptr.p, CONSUMER);
- consumer = ptr.p->m_pos[CONSUMER];
- }
- else
- {
- jam();
- /**
- * Failed to write entire chunk...
- */
- full= true;
- consumer.m_current_page.m_idx -= cnt;
- consumer.m_current_pos.m_ptr_i += cnt;
- }
- }
-
- tot += cnt;
- if(cnt)
- validate_logfile_group(ptr, " after flush_log");
- }
-
- ptr.p->m_pos[CONSUMER]= consumer;
-
- if (! (ptr.p->m_state & Logfile_group::LG_DROPPING))
- {
- signal->theData[0] = LgmanContinueB::FLUSH_LOG;
- signal->theData[1] = ptr.i;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
- else
- {
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_FLUSH_THREAD;
- }
-}
-
-void
-Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr)
-{
- Uint32 free_buffer= ptr.p->m_free_buffer_words;
- Local_log_waiter_list
- list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
-
- if(list.isEmpty())
- {
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_WAITERS_THREAD;
- return;
- }
-
- bool removed= false;
- Ptr<Log_waiter> waiter;
- list.first(waiter);
- Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
- if(waiter.p->m_size + 2*File_formats::UNDO_PAGE_WORDS < free_buffer)
- {
- removed= true;
- Uint32 block = waiter.p->m_block;
- SimulatedBlock* b = globalData.getBlock(block);
- b->execute(signal, waiter.p->m_callback, logfile_group_id);
-
- list.releaseFirst(waiter);
- }
-
- if(removed && !list.isEmpty())
- {
- ptr.p->m_state |= Logfile_group::LG_WAITERS_THREAD;
- signal->theData[0] = LgmanContinueB::PROCESS_LOG_BUFFER_WAITERS;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
- else
- {
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_WAITERS_THREAD;
- }
-}
-
-#define REALLY_SLOW_FS 0
-
-Uint32
-Lgman::write_log_pages(Signal* signal, Ptr<Logfile_group> ptr,
- Uint32 pageId, Uint32 in_pages)
-{
- assert(in_pages);
- Ptr<Undofile> filePtr;
- Buffer_idx head= ptr.p->m_file_pos[HEAD];
- Buffer_idx tail= ptr.p->m_file_pos[TAIL];
- m_file_pool.getPtr(filePtr, head.m_ptr_i);
-
- if(filePtr.p->m_online.m_outstanding > 0)
- {
- jam();
- return 0;
- }
-
- Uint32 sz= filePtr.p->m_file_size - 1; // skip zero
- Uint32 max, pages= in_pages;
-
- if(!(head.m_ptr_i == tail.m_ptr_i && head.m_idx < tail.m_idx))
- {
- max= sz - head.m_idx;
- }
- else
- {
- max= tail.m_idx - head.m_idx;
- }
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = filePtr.p->m_fd;
- req->userReference = reference();
- req->userPointer = filePtr.i;
- req->varIndex = 1+head.m_idx; // skip zero page
- req->numberOfPages = pages;
- req->data.pageData[0] = pageId;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatSharedPage);
-
- if(max > pages)
- {
- jam();
- max= pages;
- head.m_idx += max;
- ptr.p->m_file_pos[HEAD] = head;
-
- if (REALLY_SLOW_FS)
- sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal, REALLY_SLOW_FS,
- FsReadWriteReq::FixedLength + 1);
- else
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- filePtr.p->m_online.m_outstanding = max;
- filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
-
- File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
- m_shared_page_pool.getPtr(pageId + max - 1);
- Uint64 lsn = 0;
- lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
- lsn += page->m_page_header.m_page_lsn_lo;
-
- filePtr.p->m_online.m_lsn = lsn; // Store last writereq lsn on file
- ptr.p->m_last_sync_req_lsn = lsn; // And logfile_group
- }
- else
- {
- jam();
- req->numberOfPages = max;
- FsReadWriteReq::setSyncFlag(req->operationFlag, 1);
-
- if (REALLY_SLOW_FS)
- sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal, REALLY_SLOW_FS,
- FsReadWriteReq::FixedLength + 1);
- else
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- filePtr.p->m_online.m_outstanding = max;
- filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
-
- File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
- m_shared_page_pool.getPtr(pageId + max - 1);
- Uint64 lsn = 0;
- lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
- lsn += page->m_page_header.m_page_lsn_lo;
-
- filePtr.p->m_online.m_lsn = lsn; // Store last writereq lsn on file
- ptr.p->m_last_sync_req_lsn = lsn; // And logfile_group
-
- Ptr<Undofile> next = filePtr;
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- if(!files.next(next))
- {
- jam();
- files.first(next);
- }
- ndbout_c("changing file from %d to %d", filePtr.i, next.i);
- filePtr.p->m_state |= Undofile::FS_MOVE_NEXT;
- next.p->m_state &= ~(Uint32)Undofile::FS_EMPTY;
-
- head.m_idx= 0;
- head.m_ptr_i= next.i;
- ptr.p->m_file_pos[HEAD] = head;
- if(max < pages)
- max += write_log_pages(signal, ptr, pageId + max, pages - max);
- }
-
- assert(max);
- return max;
-}
-
-void
-Lgman::execFSWRITEREF(Signal* signal)
-{
- jamEntry();
- SimulatedBlock::execFSWRITEREF(signal);
- ndbrequire(false);
-}
-
-void
-Lgman::execFSWRITECONF(Signal* signal)
-{
- jamEntry();
- FsConf * conf = (FsConf*)signal->getDataPtr();
- Ptr<Undofile> ptr;
- m_file_pool.getPtr(ptr, conf->userPointer);
-
- ndbrequire(ptr.p->m_state & Undofile::FS_OUTSTANDING);
- ptr.p->m_state &= ~(Uint32)Undofile::FS_OUTSTANDING;
-
- Ptr<Logfile_group> lg_ptr;
- m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
-
- Uint32 cnt= lg_ptr.p->m_outstanding_fs;
- ndbrequire(cnt);
-
- if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
- {
- Uint32 tot= 0;
- Uint64 lsn = 0;
- {
- Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
- while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
- {
- Uint32 state= ptr.p->m_state;
- Uint32 pages= ptr.p->m_online.m_outstanding;
- ndbrequire(pages);
- ptr.p->m_online.m_outstanding= 0;
- ptr.p->m_state &= ~(Uint32)Undofile::FS_MOVE_NEXT;
- tot += pages;
- cnt--;
-
- lsn = ptr.p->m_online.m_lsn;
-
- if((state & Undofile::FS_MOVE_NEXT) && !files.next(ptr))
- files.first(ptr);
- }
- }
-
- ndbassert(tot);
- lg_ptr.p->m_outstanding_fs = cnt;
- lg_ptr.p->m_free_buffer_words += (tot * File_formats::UNDO_PAGE_WORDS);
- lg_ptr.p->m_next_reply_ptr_i = ptr.i;
- lg_ptr.p->m_last_synced_lsn = lsn;
-
- if(! (lg_ptr.p->m_state & Logfile_group::LG_SYNC_WAITERS_THREAD))
- {
- process_log_sync_waiters(signal, lg_ptr);
- }
-
- if(! (lg_ptr.p->m_state & Logfile_group::LG_WAITERS_THREAD))
- {
- process_log_buffer_waiters(signal, lg_ptr);
- }
- }
- else
- {
- ndbout_c("miss matched writes");
- }
-
- return;
-}
-
-void
-Lgman::execLCP_FRAG_ORD(Signal* signal)
-{
- jamEntry();
-
- LcpFragOrd * ord = (LcpFragOrd *)signal->getDataPtr();
- Uint32 lcp_id= ord->lcpId;
- Uint32 frag_id = ord->fragmentId;
- Uint32 table_id = ord->tableId;
-
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
-
- Uint32 entry= lcp_id == m_latest_lcp ?
- File_formats::Undofile::UNDO_LCP : File_formats::Undofile::UNDO_LCP_FIRST;
- if(!ptr.isNull() && ! (ptr.p->m_state & Logfile_group::LG_CUT_LOG_THREAD))
- {
- jam();
- ptr.p->m_state |= Logfile_group::LG_CUT_LOG_THREAD;
- signal->theData[0] = LgmanContinueB::CUT_LOG_TAIL;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
-
- if(!ptr.isNull() && ptr.p->m_last_lsn)
- {
- Uint32 undo[3];
- undo[0] = lcp_id;
- undo[1] = (table_id << 16) | frag_id;
- undo[2] = (entry << 16 ) | (sizeof(undo) >> 2);
-
- Uint64 last_lsn= m_last_lsn;
-
- if(ptr.p->m_last_lsn == last_lsn
-#ifdef VM_TRACE
- && ((rand() % 100) > 50)
-#endif
- )
- {
- undo[2] |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
- Uint32 *dst= get_log_buffer(ptr, sizeof(undo) >> 2);
- memcpy(dst, undo, sizeof(undo));
- ndbrequire(ptr.p->m_free_file_words >= (sizeof(undo) >> 2));
- ptr.p->m_free_file_words -= (sizeof(undo) >> 2);
- }
- else
- {
- Uint32 *dst= get_log_buffer(ptr, (sizeof(undo) >> 2) + 2);
- * dst++ = last_lsn >> 32;
- * dst++ = last_lsn & 0xFFFFFFFF;
- memcpy(dst, undo, sizeof(undo));
- ndbrequire(ptr.p->m_free_file_words >= (sizeof(undo) >> 2));
- ptr.p->m_free_file_words -= ((sizeof(undo) >> 2) + 2);
- }
- ptr.p->m_last_lcp_lsn = last_lsn;
- m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
-
- validate_logfile_group(ptr, "execLCP_FRAG_ORD");
- }
-
- while(!ptr.isNull())
- {
- if (ptr.p->m_last_lsn)
- {
- /**
- * First LCP_FRAGORD for each LCP, sets tail pos
- */
- if(m_latest_lcp != lcp_id)
- {
- ptr.p->m_tail_pos[0] = ptr.p->m_tail_pos[1];
- ptr.p->m_tail_pos[1] = ptr.p->m_tail_pos[2];
- ptr.p->m_tail_pos[2] = ptr.p->m_file_pos[HEAD];
- }
-
- if(0)
- ndbout_c
- ("execLCP_FRAG_ORD (%d %d) (%d %d) (%d %d) free pages: %ld",
- ptr.p->m_tail_pos[0].m_ptr_i, ptr.p->m_tail_pos[0].m_idx,
- ptr.p->m_tail_pos[1].m_ptr_i, ptr.p->m_tail_pos[1].m_idx,
- ptr.p->m_tail_pos[2].m_ptr_i, ptr.p->m_tail_pos[2].m_idx,
- (long) (ptr.p->m_free_file_words / File_formats::UNDO_PAGE_WORDS));
- }
- m_logfile_group_list.next(ptr);
- }
-
- m_latest_lcp = lcp_id;
-}
-
-void
-Lgman::execEND_LCP_REQ(Signal* signal)
-{
- EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
- ndbrequire(m_latest_lcp == req->backupId);
-
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
- bool wait= false;
- while(!ptr.isNull())
- {
- Uint64 lcp_lsn = ptr.p->m_last_lcp_lsn;
- if(ptr.p->m_last_synced_lsn < lcp_lsn)
- {
- wait= true;
- if(signal->getSendersBlockRef() != reference())
- {
- Logfile_client tmp(this, this, ptr.p->m_logfile_group_id);
- Logfile_client::Request req;
- req.m_callback.m_callbackData = ptr.i;
- req.m_callback.m_callbackFunction = safe_cast(&Lgman::endlcp_callback);
- ndbrequire(tmp.sync_lsn(signal, lcp_lsn, &req, 0) == 0);
- }
- }
- else
- {
- ptr.p->m_last_lcp_lsn = 0;
- }
- m_logfile_group_list.next(ptr);
- }
-
- if(wait)
- {
- return;
- }
-
- signal->theData[0] = 0;
- sendSignal(DBLQH_REF, GSN_END_LCP_CONF, signal, 1, JBB);
-}
-
-void
-Lgman::endlcp_callback(Signal* signal, Uint32 ptr, Uint32 res)
-{
- EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
- req->backupId = m_latest_lcp;
- execEND_LCP_REQ(signal);
-}
-
-void
-Lgman::cut_log_tail(Signal* signal, Ptr<Logfile_group> ptr)
-{
- bool done= true;
- if (likely(ptr.p->m_last_lsn))
- {
- Buffer_idx tmp= ptr.p->m_tail_pos[0];
- Buffer_idx tail= ptr.p->m_file_pos[TAIL];
-
- Ptr<Undofile> filePtr;
- m_file_pool.getPtr(filePtr, tail.m_ptr_i);
-
- if(!(tmp == tail))
- {
- Uint32 free;
- if(tmp.m_ptr_i == tail.m_ptr_i && tail.m_idx < tmp.m_idx)
- {
- free= tmp.m_idx - tail.m_idx;
- ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
- ptr.p->m_file_pos[TAIL] = tmp;
- }
- else
- {
- free= filePtr.p->m_file_size - tail.m_idx - 1;
- ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
-
- Ptr<Undofile> next = filePtr;
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
- ndbrequire(next.i != filePtr.i);
- if(next.isNull())
- {
- jam();
- files.first(next);
- while((next.p->m_state & Undofile::FS_EMPTY) && files.next(next))
- ndbrequire(next.i != filePtr.i);
- }
-
- tmp.m_idx= 0;
- tmp.m_ptr_i= next.i;
- ptr.p->m_file_pos[TAIL] = tmp;
- done= false;
- }
- }
-
- validate_logfile_group(ptr, "cut log");
- }
-
- if (done)
- {
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_CUT_LOG_THREAD;
- m_logfile_group_list.next(ptr);
- }
-
- if(!done || !ptr.isNull())
- {
- ptr.p->m_state |= Logfile_group::LG_CUT_LOG_THREAD;
- signal->theData[0] = LgmanContinueB::CUT_LOG_TAIL;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
-}
-
-void
-Lgman::execSUB_GCP_COMPLETE_REP(Signal* signal)
-{
- jamEntry();
-
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
-
- /**
- * Filter all logfile groups in parallell
- */
- return; // NOT IMPLETMENT YET
-
- signal->theData[0] = LgmanContinueB::FILTER_LOG;
- while(!ptr.isNull())
- {
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- m_logfile_group_list.next(ptr);
- }
-}
-
-int
-Lgman::alloc_log_space(Uint32 ref, Uint32 words)
-{
- ndbrequire(words);
- words += 2; // lsn
- Logfile_group key;
- key.m_logfile_group_id= ref;
- Ptr<Logfile_group> ptr;
- if(m_logfile_group_hash.find(ptr, key) &&
- ptr.p->m_free_file_words >= (words + (4 * File_formats::UNDO_PAGE_WORDS)))
- {
- ptr.p->m_free_file_words -= words;
- validate_logfile_group(ptr, "alloc_log_space");
- return 0;
- }
-
- if(ptr.isNull())
- {
- return -1;
- }
-
- return 1501;
-}
-
-int
-Lgman::free_log_space(Uint32 ref, Uint32 words)
-{
- ndbrequire(words);
- Logfile_group key;
- key.m_logfile_group_id= ref;
- Ptr<Logfile_group> ptr;
- if(m_logfile_group_hash.find(ptr, key))
- {
- ptr.p->m_free_file_words += (words + 2);
- validate_logfile_group(ptr, "free_log_space");
- return 0;
- }
- ndbrequire(false);
- return -1;
-}
-
-Uint64
-Logfile_client::add_entry(const Change* src, Uint32 cnt)
-{
- Uint32 i, tot= 0;
- for(i= 0; i<cnt; i++)
- {
- tot += src[i].len;
- }
-
- Uint32 *dst;
- Uint64 last_lsn= m_lgman->m_last_lsn;
- {
- Lgman::Logfile_group key;
- key.m_logfile_group_id= m_logfile_group_id;
- Ptr<Lgman::Logfile_group> ptr;
- if(m_lgman->m_logfile_group_hash.find(ptr, key))
- {
- Uint64 last_lsn_filegroup= ptr.p->m_last_lsn;
- if(last_lsn_filegroup == last_lsn
-#ifdef VM_TRACE
- && ((rand() % 100) > 50)
-#endif
- )
- {
- dst= m_lgman->get_log_buffer(ptr, tot);
- for(i= 0; i<cnt; i++)
- {
- memcpy(dst, src[i].ptr, 4*src[i].len);
- dst += src[i].len;
- }
- * (dst - 1) |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
- ptr.p->m_free_file_words += 2;
- ptr.p->m_free_buffer_words += 2;
- m_lgman->validate_logfile_group(ptr);
- }
- else
- {
- dst= m_lgman->get_log_buffer(ptr, tot + 2);
- * dst++ = last_lsn >> 32;
- * dst++ = last_lsn & 0xFFFFFFFF;
- for(i= 0; i<cnt; i++)
- {
- memcpy(dst, src[i].ptr, 4*src[i].len);
- dst += src[i].len;
- }
- }
- }
-
- m_lgman->m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
-
- return last_lsn;
- }
-}
-
-void
-Lgman::execSTART_RECREQ(Signal* signal)
-{
- m_latest_lcp = signal->theData[0];
-
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
-
- if(ptr.i != RNIL)
- {
- infoEvent("Applying undo to LCP: %d", m_latest_lcp);
- ndbout_c("Applying undo to LCP: %d", m_latest_lcp);
- find_log_head(signal, ptr);
- return;
- }
-
- signal->theData[0] = reference();
- sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
-}
-
-void
-Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
-{
- ndbrequire(ptr.p->m_state &
- (Logfile_group::LG_STARTING | Logfile_group::LG_SORTING));
-
- if(ptr.p->m_meta_files.isEmpty() && ptr.p->m_files.isEmpty())
- {
- jam();
- /**
- * Logfile_group wo/ any files
- */
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_STARTING;
- ptr.p->m_state |= Logfile_group::LG_ONLINE;
- m_logfile_group_list.next(ptr);
- signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- ptr.p->m_state = Logfile_group::LG_SORTING;
-
- /**
- * Read first page from each undofile (1 file at a time...)
- */
- Local_undofile_list files(m_file_pool, ptr.p->m_meta_files);
- Ptr<Undofile> file_ptr;
- files.first(file_ptr);
-
- if(!file_ptr.isNull())
- {
- /**
- * Use log buffer memory when reading
- */
- Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
- file_ptr.p->m_online.m_outstanding= page_id;
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = file_ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = file_ptr.i;
- req->varIndex = 1; // skip zero page
- req->numberOfPages = 1;
- req->data.pageData[0] = page_id;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatSharedPage);
-
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
- return;
- }
- else
- {
- /**
- * All files have read first page
- * and m_files is sorted acording to lsn
- */
- ndbrequire(!ptr.p->m_files.isEmpty());
- Local_undofile_list read_files(m_file_pool, ptr.p->m_files);
- read_files.last(file_ptr);
-
-
- /**
- * Init binary search
- */
- ptr.p->m_state = Logfile_group::LG_SEARCHING;
- file_ptr.p->m_state = Undofile::FS_SEARCHING;
- ptr.p->m_file_pos[TAIL].m_idx = 1; // left page
- ptr.p->m_file_pos[HEAD].m_idx = file_ptr.p->m_file_size;
- ptr.p->m_file_pos[HEAD].m_ptr_i = ((file_ptr.p->m_file_size - 1) >> 1) + 1;
-
- Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
- file_ptr.p->m_online.m_outstanding= page_id;
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = file_ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = file_ptr.i;
- req->varIndex = ptr.p->m_file_pos[HEAD].m_ptr_i;
- req->numberOfPages = 1;
- req->data.pageData[0] = page_id;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatSharedPage);
-
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
- return;
- }
-}
-
-void
-Lgman::execFSREADCONF(Signal* signal)
-{
- jamEntry();
-
- Ptr<Undofile> ptr;
- Ptr<Logfile_group> lg_ptr;
- FsConf* conf = (FsConf*)signal->getDataPtr();
-
- m_file_pool.getPtr(ptr, conf->userPointer);
- m_logfile_group_pool.getPtr(lg_ptr, ptr.p->m_logfile_group_ptr_i);
-
- ndbrequire(ptr.p->m_state & Undofile::FS_OUTSTANDING);
- ptr.p->m_state &= ~(Uint32)Undofile::FS_OUTSTANDING;
-
- Uint32 cnt= lg_ptr.p->m_outstanding_fs;
- ndbrequire(cnt);
-
- if((ptr.p->m_state & Undofile::FS_EXECUTING)== Undofile::FS_EXECUTING)
- {
- jam();
-
- if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
- {
- Uint32 tot= 0;
- Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
- while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
- {
- Uint32 state= ptr.p->m_state;
- Uint32 pages= ptr.p->m_online.m_outstanding;
- ndbrequire(pages);
- ptr.p->m_online.m_outstanding= 0;
- ptr.p->m_state &= ~(Uint32)Undofile::FS_MOVE_NEXT;
- tot += pages;
- cnt--;
-
- if((state & Undofile::FS_MOVE_NEXT) && !files.prev(ptr))
- files.last(ptr);
- }
-
- lg_ptr.p->m_outstanding_fs = cnt;
- lg_ptr.p->m_pos[PRODUCER].m_current_pos.m_idx += tot;
- lg_ptr.p->m_next_reply_ptr_i = ptr.i;
- }
- return;
- }
-
- lg_ptr.p->m_outstanding_fs = cnt - 1;
-
- Ptr<GlobalPage> page_ptr;
- m_shared_page_pool.getPtr(page_ptr, ptr.p->m_online.m_outstanding);
- ptr.p->m_online.m_outstanding= 0;
-
- File_formats::Undofile::Undo_page* page =
- (File_formats::Undofile::Undo_page*)page_ptr.p;
-
- Uint64 lsn = 0;
- lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
- lsn += page->m_page_header.m_page_lsn_lo;
-
- switch(ptr.p->m_state){
- case Undofile::FS_SORTING:
- jam();
- break;
- case Undofile::FS_SEARCHING:
- jam();
- find_log_head_in_file(signal, lg_ptr, ptr, lsn);
- return;
- default:
- case Undofile::FS_EXECUTING:
- case Undofile::FS_CREATING:
- case Undofile::FS_DROPPING:
- case Undofile::FS_ONLINE:
- case Undofile::FS_OPENING:
- case Undofile::FS_EMPTY:
- jam();
- ndbrequire(false);
- }
-
- /**
- * Prepare for execution
- */
- ptr.p->m_state = Undofile::FS_EXECUTING;
- ptr.p->m_online.m_lsn = lsn;
-
- /**
- * Insert into m_files
- */
- {
- Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
- meta.remove(ptr);
-
- Ptr<Undofile> loop;
- files.first(loop);
- while(!loop.isNull() && loop.p->m_online.m_lsn <= lsn)
- files.next(loop);
-
- if(loop.isNull())
- {
- /**
- * File has highest lsn, add last
- */
- jam();
- files.add(ptr);
- }
- else
- {
- /**
- * Insert file in correct position in file list
- */
- files.insert(ptr, loop);
- }
- }
- find_log_head(signal, lg_ptr);
-}
-
-void
-Lgman::execFSREADREF(Signal* signal)
-{
- jamEntry();
- SimulatedBlock::execFSREADREF(signal);
- ndbrequire(false);
-}
-
-void
-Lgman::find_log_head_in_file(Signal* signal,
- Ptr<Logfile_group> ptr,
- Ptr<Undofile> file_ptr,
- Uint64 last_lsn)
-{
- // a b
- // 3 4 5 0 1
- Uint32 curr= ptr.p->m_file_pos[HEAD].m_ptr_i;
- Uint32 head= ptr.p->m_file_pos[HEAD].m_idx;
- Uint32 tail= ptr.p->m_file_pos[TAIL].m_idx;
-
- ndbrequire(head > tail);
- Uint32 diff = head - tail;
-
- if(DEBUG_SEARCH_LOG_HEAD)
- printf("tail: %d(%lld) head: %d last: %d(%lld) -> ",
- tail, file_ptr.p->m_online.m_lsn,
- head, curr, last_lsn);
- if(last_lsn > file_ptr.p->m_online.m_lsn)
- {
- if(DEBUG_SEARCH_LOG_HEAD)
- printf("moving tail ");
-
- file_ptr.p->m_online.m_lsn = last_lsn;
- ptr.p->m_file_pos[TAIL].m_idx = tail = curr;
- }
- else
- {
- if(DEBUG_SEARCH_LOG_HEAD)
- printf("moving head ");
-
- ptr.p->m_file_pos[HEAD].m_idx = head = curr;
- }
-
- if(diff > 1)
- {
- // We need to find more pages to be sure...
- ptr.p->m_file_pos[HEAD].m_ptr_i = curr = ((head + tail) >> 1);
-
- if(DEBUG_SEARCH_LOG_HEAD)
- ndbout_c("-> new search tail: %d(%lld) head: %d -> %d",
- tail, file_ptr.p->m_online.m_lsn,
- head, curr);
-
- Uint32 page_id = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
- file_ptr.p->m_online.m_outstanding= page_id;
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = file_ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = file_ptr.i;
- req->varIndex = curr;
- req->numberOfPages = 1;
- req->data.pageData[0] = page_id;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatSharedPage);
-
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- file_ptr.p->m_state |= Undofile::FS_OUTSTANDING;
- return;
- }
-
- ndbrequire(diff == 1);
- if(DEBUG_SEARCH_LOG_HEAD)
- ndbout_c("-> found last page: %d", tail);
-
- ptr.p->m_state = 0;
- file_ptr.p->m_state = Undofile::FS_EXECUTING;
- ptr.p->m_last_lsn = file_ptr.p->m_online.m_lsn;
- ptr.p->m_last_read_lsn = file_ptr.p->m_online.m_lsn;
- ptr.p->m_last_synced_lsn = file_ptr.p->m_online.m_lsn;
- m_last_lsn = file_ptr.p->m_online.m_lsn;
-
- /**
- * Set HEAD position
- */
- ptr.p->m_file_pos[HEAD].m_ptr_i = file_ptr.i;
- ptr.p->m_file_pos[HEAD].m_idx = tail;
-
- ptr.p->m_file_pos[TAIL].m_ptr_i = file_ptr.i;
- ptr.p->m_file_pos[TAIL].m_idx = tail - 1;
- ptr.p->m_next_reply_ptr_i = file_ptr.i;
-
- {
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- if(tail == 1)
- {
- /**
- * HEAD is first page in a file...
- * -> PREV should be in previous file
- */
- Ptr<Undofile> prev = file_ptr;
- if(!files.prev(prev))
- {
- files.last(prev);
- }
- ptr.p->m_file_pos[TAIL].m_ptr_i = prev.i;
- ptr.p->m_file_pos[TAIL].m_idx = prev.p->m_file_size - 1;
- ptr.p->m_next_reply_ptr_i = prev.i;
- }
-
- SimulatedBlock* fs = globalData.getBlock(NDBFS);
- infoEvent("Undo head - %s page: %d lsn: %lld",
- fs->get_filename(file_ptr.p->m_fd),
- tail, file_ptr.p->m_online.m_lsn);
- g_eventLogger.info("Undo head - %s page: %d lsn: %lld",
- fs->get_filename(file_ptr.p->m_fd),
- tail, file_ptr.p->m_online.m_lsn);
-
- for(files.prev(file_ptr); !file_ptr.isNull(); files.prev(file_ptr))
- {
- infoEvent(" - next - %s(%lld)",
- fs->get_filename(file_ptr.p->m_fd),
- file_ptr.p->m_online.m_lsn);
-
- g_eventLogger.info(" - next - %s(%lld)",
- fs->get_filename(file_ptr.p->m_fd),
- file_ptr.p->m_online.m_lsn);
- }
- }
-
- /**
- * Start next logfile group
- */
- m_logfile_group_list.next(ptr);
- signal->theData[0] = LgmanContinueB::FIND_LOG_HEAD;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Lgman::init_run_undo_log(Signal* signal)
-{
- /**
- * Perform initial sorting of logfile groups
- */
- Ptr<Logfile_group> group;
- Logfile_group_list& list= m_logfile_group_list;
- Logfile_group_list tmp(m_logfile_group_pool);
-
- list.first(group);
- while(!group.isNull())
- {
- Ptr<Logfile_group> ptr= group;
- list.next(group);
- list.remove(ptr);
-
- {
- /**
- * Init buffer pointers
- */
- ptr.p->m_free_buffer_words -= File_formats::UNDO_PAGE_WORDS;
- ptr.p->m_pos[CONSUMER].m_current_page.m_idx = 0; // 0 more pages read
- ptr.p->m_pos[PRODUCER].m_current_page.m_idx = 0; // 0 more pages read
-
- Uint32 page = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
- File_formats::Undofile::Undo_page* pageP =
- (File_formats::Undofile::Undo_page*)m_shared_page_pool.getPtr(page);
-
- ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = pageP->m_words_used;
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 1;
- ptr.p->m_last_read_lsn++;
- }
-
- /**
- * Start producer thread
- */
- signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-
- /**
- * Insert in correct position in list of logfile_group's
- */
- Ptr<Logfile_group> pos;
- for(tmp.first(pos); !pos.isNull(); tmp.next(pos))
- if(ptr.p->m_last_read_lsn >= pos.p->m_last_read_lsn)
- break;
-
- if(pos.isNull())
- tmp.add(ptr);
- else
- tmp.insert(ptr, pos);
-
- ptr.p->m_state =
- Logfile_group::LG_EXEC_THREAD | Logfile_group::LG_READ_THREAD;
- }
- list = tmp;
-
- execute_undo_record(signal);
-}
-
-void
-Lgman::read_undo_log(Signal* signal, Ptr<Logfile_group> ptr)
-{
- Uint32 cnt, free= ptr.p->m_free_buffer_words;
-
- if(! (ptr.p->m_state & Logfile_group::LG_EXEC_THREAD))
- {
- jam();
- /**
- * Logfile_group is done...
- */
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_READ_THREAD;
- stop_run_undo_log(signal);
- return;
- }
-
- if(free <= File_formats::UNDO_PAGE_WORDS)
- {
- signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
- signal->theData[1] = ptr.i;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
- return;
- }
-
- Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
- Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
-
- if(producer.m_current_page.m_idx == 0)
- {
- /**
- * zero pages left in range -> switch range
- */
- Lgman::Page_map::Iterator it;
- Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
- Uint32 sz = map.getSize();
- Uint32 pos= (producer.m_current_page.m_ptr_i + sz - 2) % sz;
- map.position(it, pos);
- union {
- Uint32 _tmp[2];
- Lgman::Buffer_idx range;
- };
- _tmp[0] = *it.data; map.next(it); _tmp[1] = *it.data;
- producer.m_current_page.m_ptr_i = pos;
- producer.m_current_page.m_idx = range.m_idx;
- producer.m_current_pos.m_ptr_i = range.m_ptr_i + range.m_idx;
- }
-
- if(producer.m_current_page.m_ptr_i == consumer.m_current_page.m_ptr_i &&
- producer.m_current_pos.m_ptr_i > consumer.m_current_pos.m_ptr_i)
- {
- Uint32 max=
- producer.m_current_pos.m_ptr_i - consumer.m_current_pos.m_ptr_i - 1;
- ndbrequire(free >= max * File_formats::UNDO_PAGE_WORDS);
- cnt= read_undo_pages(signal, ptr, producer.m_current_pos.m_ptr_i, max);
- ndbrequire(cnt <= max);
- producer.m_current_pos.m_ptr_i -= cnt;
- producer.m_current_page.m_idx -= cnt;
- }
- else
- {
- Uint32 max= producer.m_current_page.m_idx;
- ndbrequire(free >= max * File_formats::UNDO_PAGE_WORDS);
- cnt= read_undo_pages(signal, ptr, producer.m_current_pos.m_ptr_i, max);
- ndbrequire(cnt <= max);
- producer.m_current_pos.m_ptr_i -= cnt;
- producer.m_current_page.m_idx -= cnt;
- }
-
- ndbrequire(free >= cnt * File_formats::UNDO_PAGE_WORDS);
- free -= (cnt * File_formats::UNDO_PAGE_WORDS);
- ptr.p->m_free_buffer_words = free;
- ptr.p->m_pos[PRODUCER] = producer;
-
- signal->theData[0] = LgmanContinueB::READ_UNDO_LOG;
- signal->theData[1] = ptr.i;
-
- if(free > File_formats::UNDO_PAGE_WORDS)
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- else
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
-}
-
-Uint32
-Lgman::read_undo_pages(Signal* signal, Ptr<Logfile_group> ptr,
- Uint32 pageId, Uint32 pages)
-{
- ndbrequire(pages);
- Ptr<Undofile> filePtr;
- Buffer_idx tail= ptr.p->m_file_pos[TAIL];
- m_file_pool.getPtr(filePtr, tail.m_ptr_i);
-
- if(filePtr.p->m_online.m_outstanding > 0)
- {
- jam();
- return 0;
- }
-
- Uint32 max= tail.m_idx;
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = filePtr.p->m_fd;
- req->userReference = reference();
- req->userPointer = filePtr.i;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatSharedPage);
-
-
- if(max > pages)
- {
- jam();
- tail.m_idx -= pages;
-
- req->varIndex = 1 + tail.m_idx;
- req->numberOfPages = pages;
- req->data.pageData[0] = pageId - pages;
- ptr.p->m_file_pos[TAIL] = tail;
-
- if(DEBUG_UNDO_EXECUTION)
- ndbout_c("a reading from file: %d page(%d-%d) into (%d-%d)",
- ptr.i, 1 + tail.m_idx, 1+tail.m_idx+pages-1,
- pageId - pages, pageId - 1);
-
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
- filePtr.p->m_online.m_outstanding = pages;
- max = pages;
- }
- else
- {
- jam();
-
- ndbrequire(tail.m_idx - max == 0);
- req->varIndex = 1;
- req->numberOfPages = max;
- req->data.pageData[0] = pageId - max;
-
- if(DEBUG_UNDO_EXECUTION)
- ndbout_c("b reading from file: %d page(%d-%d) into (%d-%d)",
- ptr.i, 1 , 1+max-1,
- pageId - max, pageId - 1);
-
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-
- ptr.p->m_outstanding_fs++;
- filePtr.p->m_online.m_outstanding = max;
- filePtr.p->m_state |= Undofile::FS_OUTSTANDING | Undofile::FS_MOVE_NEXT;
-
- Ptr<Undofile> prev = filePtr;
- {
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- if(!files.prev(prev))
- {
- jam();
- files.last(prev);
- }
- }
- if(DEBUG_UNDO_EXECUTION)
- ndbout_c("changing file from %d to %d", filePtr.i, prev.i);
-
- tail.m_idx= prev.p->m_file_size - 1;
- tail.m_ptr_i= prev.i;
- ptr.p->m_file_pos[TAIL] = tail;
- if(max < pages && filePtr.i != prev.i)
- max += read_undo_pages(signal, ptr, pageId - max, pages - max);
- }
-
- return max;
-
-}
-
-void
-Lgman::execute_undo_record(Signal* signal)
-{
- Uint64 lsn;
- const Uint32* ptr;
- Dbtup* tup= (Dbtup*)globalData.getBlock(DBTUP);
- if((ptr = get_next_undo_record(&lsn)))
- {
- Uint32 len= (* ptr) & 0xFFFF;
- Uint32 type= (* ptr) >> 16;
- Uint32 mask= type & ~(Uint32)File_formats::Undofile::UNDO_NEXT_LSN;
- switch(mask){
- case File_formats::Undofile::UNDO_END:
- stop_run_undo_log(signal);
- return;
- case File_formats::Undofile::UNDO_LCP:
- case File_formats::Undofile::UNDO_LCP_FIRST:
- {
- Uint32 lcp = * (ptr - len + 1);
- if(m_latest_lcp && lcp > m_latest_lcp)
- {
- if (0)
- {
- const Uint32 * base = ptr - len + 1;
- Uint32 lcp = base[0];
- Uint32 tableId = base[1] >> 16;
- Uint32 fragId = base[1] & 0xFFFF;
-
- ndbout_c("NOT! ignoring lcp: %u tab: %u frag: %u",
- lcp, tableId, fragId);
- }
- }
-
- if(m_latest_lcp == 0 ||
- lcp < m_latest_lcp ||
- (lcp == m_latest_lcp &&
- mask == File_formats::Undofile::UNDO_LCP_FIRST))
- {
- stop_run_undo_log(signal);
- return;
- }
- // Fallthrough
- }
- case File_formats::Undofile::UNDO_TUP_ALLOC:
- case File_formats::Undofile::UNDO_TUP_UPDATE:
- case File_formats::Undofile::UNDO_TUP_FREE:
- case File_formats::Undofile::UNDO_TUP_CREATE:
- case File_formats::Undofile::UNDO_TUP_DROP:
- case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
- case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
- tup->disk_restart_undo(signal, lsn, mask, ptr - len + 1, len);
- return;
- default:
- ndbrequire(false);
- }
- }
- signal->theData[0] = LgmanContinueB::EXECUTE_UNDO_RECORD;
- sendSignal(LGMAN_REF, GSN_CONTINUEB, signal, 1, JBB);
-
- return;
-}
-
-const Uint32*
-Lgman::get_next_undo_record(Uint64 * this_lsn)
-{
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
-
- Logfile_group::Position consumer= ptr.p->m_pos[CONSUMER];
- Logfile_group::Position producer= ptr.p->m_pos[PRODUCER];
- if(producer.m_current_pos.m_idx < 2)
- {
- jam();
- /**
- * Wait for fetching pages...
- */
- return 0;
- }
-
- Uint32 pos = consumer.m_current_pos.m_idx;
- Uint32 page = consumer.m_current_pos.m_ptr_i;
-
- File_formats::Undofile::Undo_page* pageP=(File_formats::Undofile::Undo_page*)
- m_shared_page_pool.getPtr(page);
-
- if(pos == 0)
- {
- /**
- * End of log
- */
- pageP->m_data[0] = (File_formats::Undofile::UNDO_END << 16) | 1 ;
- pageP->m_page_header.m_page_lsn_hi = 0;
- pageP->m_page_header.m_page_lsn_lo = 0;
- pos= consumer.m_current_pos.m_idx= pageP->m_words_used = 1;
- this_lsn = 0;
- return pageP->m_data;
- }
-
- Uint32 *record= pageP->m_data + pos - 1;
- Uint32 len= (* record) & 0xFFFF;
- ndbrequire(len);
- Uint32 *prev= record - len;
- Uint64 lsn = 0;
-
- // Same page
- if(((* record) >> 16) & File_formats::Undofile::UNDO_NEXT_LSN)
- {
- lsn = ptr.p->m_last_read_lsn - 1;
- ndbrequire((Int64)lsn >= 0);
- }
- else
- {
- ndbrequire(pos >= 3);
- lsn += * (prev - 1); lsn <<= 32;
- lsn += * (prev - 0);
- len += 2;
- ndbrequire((Int64)lsn >= 0);
- }
-
-
- ndbrequire(pos >= len);
-
- if(pos == len)
- {
- /**
- * Switching page
- */
- ndbrequire(producer.m_current_pos.m_idx);
- ptr.p->m_pos[PRODUCER].m_current_pos.m_idx --;
-
- if(consumer.m_current_page.m_idx)
- {
- consumer.m_current_page.m_idx--; // left in range
- consumer.m_current_pos.m_ptr_i --; // page
- }
- else
- {
- // 0 pages left in range...switch range
- Lgman::Page_map::Iterator it;
- Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
- Uint32 sz = map.getSize();
- Uint32 tmp = (consumer.m_current_page.m_ptr_i + sz - 2) % sz;
-
- map.position(it, tmp);
- union {
- Uint32 _tmp[2];
- Lgman::Buffer_idx range;
- };
-
- _tmp[0] = *it.data; map.next(it); _tmp[1] = *it.data;
-
- consumer.m_current_page.m_idx = range.m_idx - 1; // left in range
- consumer.m_current_page.m_ptr_i = tmp; // pos in map
-
- consumer.m_current_pos.m_ptr_i = range.m_ptr_i + range.m_idx - 1; // page
- }
-
- if(DEBUG_UNDO_EXECUTION)
- ndbout_c("reading from %d", consumer.m_current_pos.m_ptr_i);
-
- pageP=(File_formats::Undofile::Undo_page*)
- m_shared_page_pool.getPtr(consumer.m_current_pos.m_ptr_i);
-
- pos= consumer.m_current_pos.m_idx= pageP->m_words_used;
-
- Uint64 tmp = 0;
- tmp += pageP->m_page_header.m_page_lsn_hi; tmp <<= 32;
- tmp += pageP->m_page_header.m_page_lsn_lo;
-
- prev = pageP->m_data + pos - 1;
-
- if(((* prev) >> 16) & File_formats::Undofile::UNDO_NEXT_LSN)
- ndbrequire(lsn + 1 == ptr.p->m_last_read_lsn);
-
- ptr.p->m_pos[CONSUMER] = consumer;
- ptr.p->m_free_buffer_words += File_formats::UNDO_PAGE_WORDS;
- }
- else
- {
- ptr.p->m_pos[CONSUMER].m_current_pos.m_idx -= len;
- }
-
- * this_lsn = ptr.p->m_last_read_lsn = lsn;
-
- /**
- * Re-sort log file groups
- */
- Ptr<Logfile_group> sort = ptr;
- if(m_logfile_group_list.next(sort))
- {
- while(!sort.isNull() && sort.p->m_last_read_lsn > lsn)
- m_logfile_group_list.next(sort);
-
- if(sort.i != ptr.p->nextList)
- {
- m_logfile_group_list.remove(ptr);
- if(sort.isNull())
- m_logfile_group_list.add(ptr);
- else
- m_logfile_group_list.insert(ptr, sort);
- }
- }
- return record;
-}
-
-void
-Lgman::stop_run_undo_log(Signal* signal)
-{
- bool running = false, outstanding = false;
- Ptr<Logfile_group> ptr;
- m_logfile_group_list.first(ptr);
- while(!ptr.isNull())
- {
- /**
- * Mark exec thread as completed
- */
- ptr.p->m_state &= ~(Uint32)Logfile_group::LG_EXEC_THREAD;
-
- if(ptr.p->m_state & Logfile_group::LG_READ_THREAD)
- {
- /**
- * Thread is still running...wait for it to complete
- */
- running = true;
- }
- else if(ptr.p->m_outstanding_fs)
- {
- outstanding = true; // a FSREADREQ is outstanding...wait for it
- }
- else if(ptr.p->m_state != Logfile_group::LG_ONLINE)
- {
- /**
- * Fix log TAIL
- */
- ndbrequire(ptr.p->m_state == 0);
- ptr.p->m_state = Logfile_group::LG_ONLINE;
- Buffer_idx tail= ptr.p->m_file_pos[TAIL];
- Uint32 pages= ptr.p->m_pos[PRODUCER].m_current_pos.m_idx;
-
- while(pages)
- {
- Ptr<Undofile> file;
- m_file_pool.getPtr(file, tail.m_ptr_i);
- Uint32 page= tail.m_idx;
- Uint32 size= file.p->m_file_size;
- ndbrequire(size >= page);
- Uint32 diff= size - page;
-
- if(pages >= diff)
- {
- pages -= diff;
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- if(!files.next(file))
- files.first(file);
- tail.m_idx = 1;
- tail.m_ptr_i= file.i;
- }
- else
- {
- tail.m_idx += pages;
- pages= 0;
- }
- }
- ptr.p->m_tail_pos[0] = tail;
- ptr.p->m_tail_pos[1] = tail;
- ptr.p->m_tail_pos[2] = tail;
- ptr.p->m_file_pos[TAIL] = tail;
-
- init_logbuffer_pointers(ptr);
-
- {
- Buffer_idx head= ptr.p->m_file_pos[HEAD];
- Ptr<Undofile> file;
- m_file_pool.getPtr(file, head.m_ptr_i);
- if (head.m_idx == file.p->m_file_size - 1)
- {
- Local_undofile_list files(m_file_pool, ptr.p->m_files);
- if(!files.next(file))
- {
- jam();
- files.first(file);
- }
- head.m_idx = 0;
- head.m_ptr_i = file.i;
- ptr.p->m_file_pos[HEAD] = head;
- }
- }
-
- ptr.p->m_free_file_words = (Uint64)File_formats::UNDO_PAGE_WORDS *
- (Uint64)compute_free_file_pages(ptr);
- ptr.p->m_next_reply_ptr_i = ptr.p->m_file_pos[HEAD].m_ptr_i;
-
- ptr.p->m_state |= Logfile_group::LG_FLUSH_THREAD;
- signal->theData[0] = LgmanContinueB::FLUSH_LOG;
- signal->theData[1] = ptr.i;
- signal->theData[2] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-
- if(1)
- {
- SimulatedBlock* fs = globalData.getBlock(NDBFS);
- Ptr<Undofile> hf, tf;
- m_file_pool.getPtr(tf, tail.m_ptr_i);
- m_file_pool.getPtr(hf, ptr.p->m_file_pos[HEAD].m_ptr_i);
- infoEvent("Logfile group: %d ", ptr.p->m_logfile_group_id);
- g_eventLogger.info("Logfile group: %d ", ptr.p->m_logfile_group_id);
- infoEvent(" head: %s page: %d",
- fs->get_filename(hf.p->m_fd),
- ptr.p->m_file_pos[HEAD].m_idx);
- g_eventLogger.info(" head: %s page: %d",
- fs->get_filename(hf.p->m_fd),
- ptr.p->m_file_pos[HEAD].m_idx);
- infoEvent(" tail: %s page: %d",
- fs->get_filename(tf.p->m_fd), tail.m_idx);
- g_eventLogger.info(" tail: %s page: %d",
- fs->get_filename(tf.p->m_fd), tail.m_idx);
- }
- }
-
- m_logfile_group_list.next(ptr);
- }
-
- if(running)
- {
- jam();
- return;
- }
-
- if(outstanding)
- {
- jam();
- signal->theData[0] = LgmanContinueB::STOP_UNDO_LOG;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
- return;
- }
-
- infoEvent("Flushing page cache after undo completion");
- g_eventLogger.info("Flushing page cache after undo completion");
-
- /**
- * Start flushing pages (local, LCP)
- */
- LcpFragOrd * ord = (LcpFragOrd *)signal->getDataPtr();
- ord->lcpId = m_latest_lcp;
- sendSignal(PGMAN_REF, GSN_LCP_FRAG_ORD, signal,
- LcpFragOrd::SignalLength, JBB);
-
- EndLcpReq* req= (EndLcpReq*)signal->getDataPtr();
- req->senderRef = reference();
- sendSignal(PGMAN_REF, GSN_END_LCP_REQ, signal,
- EndLcpReq::SignalLength, JBB);
-}
-
-void
-Lgman::execEND_LCP_CONF(Signal* signal)
-{
- Dbtup* tup= (Dbtup*)globalData.getBlock(DBTUP);
- tup->disk_restart_undo(signal, 0, File_formats::Undofile::UNDO_END, 0, 0);
-
- /**
- * pgman has completed flushing all pages
- *
- * insert "fake" LCP record preventing undo to be "rerun"
- */
- Uint32 undo[3];
- undo[0] = m_latest_lcp;
- undo[1] = (0 << 16) | 0;
- undo[2] = (File_formats::Undofile::UNDO_LCP_FIRST << 16 )
- | (sizeof(undo) >> 2);
-
- Ptr<Logfile_group> ptr;
- ndbrequire(m_logfile_group_list.first(ptr));
-
- Uint64 last_lsn= m_last_lsn;
- if(ptr.p->m_last_lsn == last_lsn
-#ifdef VM_TRACE
- && ((rand() % 100) > 50)
-#endif
- )
- {
- undo[2] |= File_formats::Undofile::UNDO_NEXT_LSN << 16;
- Uint32 *dst= get_log_buffer(ptr, sizeof(undo) >> 2);
- memcpy(dst, undo, sizeof(undo));
- ndbrequire(ptr.p->m_free_file_words >= (sizeof(undo) >> 2));
- ptr.p->m_free_file_words -= (sizeof(undo) >> 2);
- }
- else
- {
- Uint32 *dst= get_log_buffer(ptr, (sizeof(undo) >> 2) + 2);
- * dst++ = last_lsn >> 32;
- * dst++ = last_lsn & 0xFFFFFFFF;
- memcpy(dst, undo, sizeof(undo));
- ndbrequire(ptr.p->m_free_file_words >= ((sizeof(undo) >> 2) + 2));
- ptr.p->m_free_file_words -= ((sizeof(undo) >> 2) + 2);
- }
- m_last_lsn = ptr.p->m_last_lsn = last_lsn + 1;
-
- ptr.p->m_last_synced_lsn = last_lsn;
- while(m_logfile_group_list.next(ptr))
- ptr.p->m_last_synced_lsn = last_lsn;
-
- infoEvent("Flushing complete");
- g_eventLogger.info("Flushing complete");
-
- signal->theData[0] = reference();
- sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
-}
-
-#ifdef VM_TRACE
-void
-Lgman::validate_logfile_group(Ptr<Logfile_group> ptr, const char * heading)
-{
- do
- {
- if (ptr.p->m_file_pos[HEAD].m_ptr_i == RNIL)
- break;
-
- Uint32 pages = compute_free_file_pages(ptr);
-
- Uint32 group_pages =
- ((ptr.p->m_free_file_words + File_formats::UNDO_PAGE_WORDS - 1)/ File_formats::UNDO_PAGE_WORDS) ;
- Uint32 last = ptr.p->m_free_file_words % File_formats::UNDO_PAGE_WORDS;
-
- if(! (pages >= group_pages))
- {
- ndbout << heading << " Tail: " << ptr.p->m_file_pos[TAIL]
- << " Head: " << ptr.p->m_file_pos[HEAD]
- << " free: " << group_pages << "(" << last << ")"
- << " found: " << pages;
- for(Uint32 i = 0; i<3; i++)
- {
- ndbout << " - " << ptr.p->m_tail_pos[i];
- }
- ndbout << endl;
-
- ndbrequire(pages >= group_pages);
- }
- } while(0);
-}
-#endif
-
-void Lgman::execGET_TABINFOREQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal))
- {
- return;
- }
-
- GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
-
- const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
- BlockReference retRef= req->senderRef;
- Uint32 senderData= req->senderData;
- Uint32 tableId= req->tableId;
-
- if(reqType == GetTabInfoReq::RequestByName){
- jam();
- if(signal->getNoOfSections())
- releaseSections(signal);
-
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
- return;
- }
-
- Logfile_group key;
- key.m_logfile_group_id= tableId;
- Ptr<Logfile_group> ptr;
- m_logfile_group_hash.find(ptr, key);
-
- if(ptr.p->m_logfile_group_id != tableId)
- {
- jam();
- if(signal->getNoOfSections())
- releaseSections(signal);
-
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
- return;
- }
-
-
- GetTabInfoConf *conf = (GetTabInfoConf *)&signal->theData[0];
-
- conf->senderData= senderData;
- conf->tableId= tableId;
- conf->freeWordsHi= ptr.p->m_free_file_words >> 32;
- conf->freeWordsLo= ptr.p->m_free_file_words & 0xFFFFFFFF;
- conf->tableType= DictTabInfo::LogfileGroup;
- conf->senderRef= reference();
- sendSignal(retRef, GSN_GET_TABINFO_CONF, signal,
- GetTabInfoConf::SignalLength, JBB);
-}
-
-void Lgman::sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq * req,
- GetTabInfoRef::ErrorCode errorCode)
-{
- jamEntry();
- GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
- /**
- * The format of GetTabInfo Req/Ref is the same
- */
- BlockReference retRef = req->senderRef;
- ref->errorCode = errorCode;
-
- sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
-}
diff --git a/storage/ndb/src/kernel/blocks/lgman.hpp b/storage/ndb/src/kernel/blocks/lgman.hpp
deleted file mode 100644
index c15e0d029e6..00000000000
--- a/storage/ndb/src/kernel/blocks/lgman.hpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LGMAN_H
-#define LGMAN_H
-
-#include <SimulatedBlock.hpp>
-
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <DLFifoList.hpp>
-#include <KeyTable.hpp>
-#include <DLHashTable.hpp>
-#include <NodeBitmask.hpp>
-#include "diskpage.hpp"
-#include <signaldata/GetTabInfo.hpp>
-
-#include <WOPool.hpp>
-#include <SLFifoList.hpp>
-
-class Lgman : public SimulatedBlock
-{
-public:
- Lgman(Block_context& ctx);
- virtual ~Lgman();
- BLOCK_DEFINES(Lgman);
-
-protected:
-
- void execSTTOR(Signal* signal);
- void sendSTTORRY(Signal*);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- void execCREATE_FILE_REQ(Signal* signal);
- void execCREATE_FILEGROUP_REQ(Signal* signal);
- void execDROP_FILE_REQ(Signal* signal);
- void execDROP_FILEGROUP_REQ(Signal* signal);
-
- void execFSWRITEREQ(Signal*);
- void execFSWRITEREF(Signal*);
- void execFSWRITECONF(Signal*);
-
- void execFSOPENREF(Signal*);
- void execFSOPENCONF(Signal*);
-
- void execFSCLOSEREF(Signal*);
- void execFSCLOSECONF(Signal*);
-
- void execFSREADREF(Signal*);
- void execFSREADCONF(Signal*);
-
- void execLCP_FRAG_ORD(Signal*);
- void execEND_LCP_REQ(Signal*);
- void execSUB_GCP_COMPLETE_REP(Signal*);
-
- void execSTART_RECREQ(Signal*);
- void execEND_LCP_CONF(Signal*);
-
- void execGET_TABINFOREQ(Signal*);
-
- void sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq * req,
- GetTabInfoRef::ErrorCode errorCode);
-
-public:
- struct Log_waiter
- {
- Callback m_callback;
- union {
- Uint32 m_size;
- Uint64 m_sync_lsn;
- };
- Uint32 m_block;
- Uint32 nextList;
- Uint32 m_magic;
- };
-
- typedef RecordPool<Log_waiter, WOPool> Log_waiter_pool;
- typedef SLFifoListImpl<Log_waiter_pool, Log_waiter> Log_waiter_list;
- typedef LocalSLFifoListImpl<Log_waiter_pool, Log_waiter> Local_log_waiter_list;
-
- struct Undofile
- {
- Undofile(){}
- Undofile(const struct CreateFileImplReq*, Uint32 lg_ptr_i);
-
- Uint32 m_magic;
- Uint32 m_file_id; // Dict obj id
- Uint32 m_logfile_group_ptr_i;
-
- Uint32 m_file_size;
- Uint32 m_state;
- Uint32 m_fd; // When speaking to NDBFS
-
- enum FileState
- {
- FS_CREATING = 0x1 // File is being created
- ,FS_DROPPING = 0x2 // File is being dropped
- ,FS_ONLINE = 0x4 // File is online
- ,FS_OPENING = 0x8 // File is being opened during SR
- ,FS_SORTING = 0x10 // Files in group are being sorted
- ,FS_SEARCHING = 0x20 // File is being searched for end of log
- ,FS_EXECUTING = 0x40 // File is used for executing UNDO log
- ,FS_EMPTY = 0x80 // File is empty (used when online)
- ,FS_OUTSTANDING = 0x100 // File has outstanding request
- ,FS_MOVE_NEXT = 0x200 // When receiving reply move to next file
- };
-
- union {
- struct {
- Uint32 m_outstanding; // Outstaning pages
- Uint64 m_lsn; // Used when finding log head
- } m_online;
- struct {
- Uint32 m_senderData;
- Uint32 m_senderRef;
- Uint32 m_logfile_group_id;
- Uint32 m_logfile_group_version;
- } m_create;
- };
-
- Uint32 nextList;
- union {
- Uint32 prevList;
- Uint32 nextPool;
- };
- };
-
- typedef RecordPool<Undofile, RWPool> Undofile_pool;
- typedef DLFifoListImpl<Undofile_pool, Undofile> Undofile_list;
- typedef LocalDLFifoListImpl<Undofile_pool, Undofile> Local_undofile_list;
- typedef LocalDataBuffer<15> Page_map;
-
- struct Buffer_idx
- {
- Uint32 m_ptr_i;
- Uint32 m_idx;
- bool operator== (const Buffer_idx& bi) const {
- return (m_ptr_i == bi.m_ptr_i && m_idx == bi.m_idx);
- }
- };
-
- struct Logfile_group
- {
- Logfile_group(){}
- Logfile_group(const struct CreateFilegroupImplReq*);
-
- Uint32 m_magic;
- union {
- Uint32 key;
- Uint32 m_logfile_group_id;
- };
- Uint32 m_version;
- Uint16 m_state;
- Uint16 m_outstanding_fs;
- Uint32 m_next_reply_ptr_i;
-
- enum Logfile_group_state
- {
- LG_ONLINE = 0x001
- ,LG_SORTING = 0x002 // Sorting files
- ,LG_SEARCHING = 0x004 // Searching in last file
- ,LG_EXEC_THREAD = 0x008 // Execute thread is running
- ,LG_READ_THREAD = 0x010 // Read thread is running
- ,LG_FORCE_SYNC_THREAD = 0x020
- ,LG_SYNC_WAITERS_THREAD = 0x040
- ,LG_CUT_LOG_THREAD = 0x080
- ,LG_WAITERS_THREAD = 0x100
- ,LG_FLUSH_THREAD = 0x200
- ,LG_DROPPING = 0x400
- ,LG_STARTING = 0x800
- };
-
- static const Uint32 LG_THREAD_MASK = Logfile_group::LG_FORCE_SYNC_THREAD |
- Logfile_group::LG_SYNC_WAITERS_THREAD |
- Logfile_group::LG_CUT_LOG_THREAD |
- Logfile_group::LG_WAITERS_THREAD |
- Logfile_group::LG_FLUSH_THREAD;
-
- Uint64 m_last_lsn;
- Uint64 m_last_sync_req_lsn; // Outstanding
- Uint64 m_last_synced_lsn; //
- Uint64 m_max_sync_req_lsn; // User requested lsn
- union {
- Uint64 m_last_read_lsn;
- Uint64 m_last_lcp_lsn;
- };
- Log_waiter_list::Head m_log_sync_waiters;
-
- Buffer_idx m_tail_pos[3]; // 0 is cut, 1 is saved, 2 is current
- Buffer_idx m_file_pos[2]; // 0 tail, 1 head = { file_ptr_i, page_no }
- Uint64 m_free_file_words; // Free words in logfile group
-
- Undofile_list::Head m_files; // Files in log
- Undofile_list::Head m_meta_files;// Files being created or dropped
-
- Uint32 m_free_buffer_words; // Free buffer page words
- Log_waiter_list::Head m_log_buffer_waiters;
- Page_map::Head m_buffer_pages; // Pairs of { ptr.i, count }
- struct Position {
- Buffer_idx m_current_page; // { m_buffer_pages.i, left in range }
- Buffer_idx m_current_pos; // { page ptr.i, m_words_used }
- } m_pos[2]; // 0 is reader (lgman) 1 is writer (tup)
-
- Uint32 nextHash;
- Uint32 prevHash;
- Uint32 nextList;
- union {
- Uint32 prevList;
- Uint32 nextPool;
- };
- Uint32 hashValue() const {
- return key;
- }
- bool equal(const Logfile_group& rec) const {
- return key == rec.key;
- }
- };
-
- typedef RecordPool<Logfile_group, RWPool> Logfile_group_pool;
- typedef DLFifoListImpl<Logfile_group_pool, Logfile_group> Logfile_group_list;
- typedef LocalDLFifoListImpl<Logfile_group_pool, Logfile_group> Local_logfile_group_list;
- typedef KeyTableImpl<Logfile_group_pool, Logfile_group> Logfile_group_hash;
-
- /**
- * Alloc/free space in log
- * Alloction will be removed at either/or
- * 1) Logfile_client::add_entry
- * 2) free_log_space
- */
- int alloc_log_space(Uint32 logfile_ref, Uint32 words);
- int free_log_space(Uint32 logfile_ref, Uint32 words);
-
-private:
- friend class Logfile_client;
-
- Undofile_pool m_file_pool;
- Logfile_group_pool m_logfile_group_pool;
- Log_waiter_pool m_log_waiter_pool;
-
- Page_map::DataBufferPool m_data_buffer_pool;
-
- Uint64 m_last_lsn;
- Uint32 m_latest_lcp;
- Logfile_group_list m_logfile_group_list;
- Logfile_group_hash m_logfile_group_hash;
-
- bool alloc_logbuffer_memory(Ptr<Logfile_group>, Uint32 pages);
- void init_logbuffer_pointers(Ptr<Logfile_group>);
- void free_logbuffer_memory(Ptr<Logfile_group>);
- Uint32 compute_free_file_pages(Ptr<Logfile_group>);
- Uint32* get_log_buffer(Ptr<Logfile_group>, Uint32 sz);
- void process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group>);
- Uint32 next_page(Logfile_group* ptrP, Uint32 i);
-
- void force_log_sync(Signal*, Ptr<Logfile_group>, Uint32 lsnhi, Uint32 lnslo);
- void process_log_sync_waiters(Signal* signal, Ptr<Logfile_group>);
-
- void cut_log_tail(Signal*, Ptr<Logfile_group> ptr);
- void endlcp_callback(Signal*, Uint32, Uint32);
- void open_file(Signal*, Ptr<Undofile>, Uint32 requestInfo);
-
- void flush_log(Signal*, Ptr<Logfile_group>, Uint32 force);
- Uint32 write_log_pages(Signal*, Ptr<Logfile_group>,
- Uint32 pageId, Uint32 pages);
-
- void find_log_head(Signal* signal, Ptr<Logfile_group> ptr);
- void find_log_head_in_file(Signal*, Ptr<Logfile_group>,Ptr<Undofile>,Uint64);
-
- void init_run_undo_log(Signal*);
- void read_undo_log(Signal*, Ptr<Logfile_group> ptr);
- Uint32 read_undo_pages(Signal*, Ptr<Logfile_group>,
- Uint32 pageId, Uint32 pages);
-
- void execute_undo_record(Signal*);
- const Uint32* get_next_undo_record(Uint64* lsn);
- void stop_run_undo_log(Signal* signal);
- void init_tail_ptr(Signal* signal, Ptr<Logfile_group> ptr);
-
- bool find_file_by_id(Ptr<Undofile>&, Undofile_list::Head&, Uint32 id);
- void create_file_commit(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
- void create_file_abort(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
-
-#ifdef VM_TRACE
- void validate_logfile_group(Ptr<Logfile_group> ptr, const char * = 0);
-#else
- void validate_logfile_group(Ptr<Logfile_group> ptr, const char * = 0) {}
-#endif
-
- void drop_filegroup_drop_files(Signal*, Ptr<Logfile_group>,
- Uint32 ref, Uint32 data);
-};
-
-class Logfile_client {
- Uint32 m_block;
- Lgman * m_lgman;
-public:
- Uint32 m_logfile_group_id;
-
- Logfile_client() {}
- Logfile_client(SimulatedBlock* block, Lgman*, Uint32 logfile_group_id);
-
- struct Request
- {
- SimulatedBlock::Callback m_callback;
- };
-
- /**
- * Request flags
- */
- enum RequestFlags
- {
- };
-
- /**
- * Make sure a lsn is stored
- * @return -1, on error
- * 0, request in queued
- * >0, done
- */
- int sync_lsn(Signal*, Uint64, Request*, Uint32 flags);
-
- /**
- * Undolog entries
- */
- struct Change
- {
- const void * ptr;
- Uint32 len;
- };
-
- Uint64 add_entry(const void*, Uint32 len);
- Uint64 add_entry(const Change*, Uint32 cnt);
-
- Uint64 add_entry(Local_key, void * base, Change*);
- Uint64 add_entry(Local_key, Uint32 off, Uint32 change);
-
- /**
- * Check for space in log buffer
- *
- * return >0 if available
- * 0 on time slice
- * -1 on error
- */
- int get_log_buffer(Signal*, Uint32 sz, SimulatedBlock::Callback* m_callback);
-
-private:
- Uint32* get_log_buffer(Uint32 sz);
-};
-
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/mutexes.hpp b/storage/ndb/src/kernel/blocks/mutexes.hpp
deleted file mode 100644
index 64df5d45d27..00000000000
--- a/storage/ndb/src/kernel/blocks/mutexes.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KERNEL_MUTEXES_HPP
-#define KERNEL_MUTEXES_HPP
-
-#include <ndb_types.h>
-
-/**
- * This mutex is used by:
- * DIH - before sending START_LCP to all participants
- * DICT - before commiting a CREATE TABLE
- * BACKUP - before sending DEFINE_BACKUP
- */
-#define DIH_START_LCP_MUTEX 0
-#define DICT_COMMIT_TABLE_MUTEX 0
-
-/**
- * This mutex is used by
- * DIH - before switching primary replica
- * BACKUP - before sending DEFINE_BACKUP
- */
-#define DIH_SWITCH_PRIMARY_MUTEX 1
-#define BACKUP_DEFINE_MUTEX 1
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
deleted file mode 100644
index 03ed858db1e..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDBCNTR_H
-#define NDBCNTR_H
-
-
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include <ndb_limits.h>
-#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>
-
-#ifdef NDBCNTR_C
-/*
-2.1 GLOBAL SYMBOLS
-------------------
-*/
-/*
-2.2 LOCAL SYMBOLS
------------------
-*/
-#define ZNO_NDB_BLOCKS 6 /* ACC, DICT, DIH, LQH, TC, TUP */
-
-#define ZNOT_AVAILABLE 913
-
-//------- OTHERS ---------------------------------------------
-#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
-#define ZSTART_PHASE_2 2
-#define ZSTART_PHASE_3 3
-#define ZSTART_PHASE_4 4
-#define ZSTART_PHASE_5 5
-#define ZSTART_PHASE_6 6
-#define ZSTART_PHASE_7 7
-#define ZSTART_PHASE_8 8
-#define ZSTART_PHASE_9 9
-#define ZSTART_PHASE_END 255
-#define ZWAITPOINT_4_1 1
-#define ZWAITPOINT_4_2 2
-#define ZWAITPOINT_5_1 3
-#define ZWAITPOINT_5_2 4
-#define ZWAITPOINT_6_1 5
-#define ZWAITPOINT_6_2 6
-#define ZWAITPOINT_7_1 7
-#define ZWAITPOINT_7_2 8
-#define ZSYSTAB_VERSION 1
-#endif
-
-class Ndbcntr: public SimulatedBlock {
-public:
-// Records
-
-/* FSREADREQ FSWRITEREQ */
-/**
- * 2.3 RECORDS AND FILESIZES
- * ------------------------------------------------------------
- */
-
- struct StartRecord {
- 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;
-
- struct NdbBlocksRec {
- BlockReference blockref;
- }; /* p2c: size = 2 bytes */
-
- typedef Ptr<NdbBlocksRec> NdbBlocksRecPtr;
-
- /**
- * Ndbcntr creates and initializes system tables on initial system start.
- * The tables are defined in static structs in NdbcntrSysTable.cpp.
- */
- struct SysColumn {
- unsigned pos;
- const char* name;
- // DictTabInfo
- DictTabInfo::ExtType type;
- Uint32 length;
- bool keyFlag;
- bool nullable;
- };
- struct SysTable {
- const char* name;
- unsigned columnCount;
- const SysColumn* columnList;
- // DictTabInfo
- DictTabInfo::TableType tableType;
- DictTabInfo::FragmentType fragmentType;
- bool tableLoggedFlag;
- // saved table id
- mutable Uint32 tableId;
- };
- struct SysIndex {
- const char* name;
- const SysTable* primaryTable;
- Uint32 columnCount;
- Uint32 columnList[4];
- // DictTabInfo
- DictTabInfo::TableType indexType;
- DictTabInfo::FragmentType fragmentType;
- bool indexLoggedFlag;
- // saved index table id
- mutable Uint32 indexId;
- };
- static const SysTable* g_sysTableList[];
- static const unsigned g_sysTableCount;
- // the system tables
- static const SysTable g_sysTable_SYSTAB_0;
- static const SysTable g_sysTable_NDBEVENTS_0;
-
-public:
- Ndbcntr(Block_context&);
- virtual ~Ndbcntr();
-
-private:
- BLOCK_DEFINES(Ndbcntr);
-
- // Transit signals
- void execAPI_START_REP(Signal*);
- void execCONTINUEB(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execREAD_NODESREF(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_FAILREP(Signal* signal);
- void execSYSTEM_ERROR(Signal* signal);
-
- // Received signals
- void execDUMP_STATE_ORD(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execTCSEIZECONF(Signal* signal);
- void execTCSEIZEREF(Signal* signal);
- void execTCRELEASECONF(Signal* signal);
- void execTCRELEASEREF(Signal* signal);
- void execTCKEYCONF(Signal* signal);
- void execTCKEYREF(Signal* signal);
- void execTCROLLBACKREP(Signal* signal);
- void execGETGCICONF(Signal* signal);
- void execDIH_RESTARTCONF(Signal* signal);
- void execDIH_RESTARTREF(Signal* signal);
- void execCREATE_TABLE_REF(Signal* signal);
- void execCREATE_TABLE_CONF(Signal* signal);
- void execNDB_STTORRY(Signal* signal);
- void execNDB_STARTCONF(Signal* signal);
- void execREAD_NODESREQ(Signal* signal);
- void execNDB_STARTREF(Signal* signal);
-
- void execSTOP_PERM_REF(Signal* signal);
- void execSTOP_PERM_CONF(Signal* signal);
-
- void execSTOP_ME_REF(Signal* signal);
- void execSTOP_ME_CONF(Signal* signal);
-
- void execWAIT_GCP_REF(Signal* signal);
- void execWAIT_GCP_CONF(Signal* signal);
-
- void execSTOP_REQ(Signal* signal);
- void execSTOP_CONF(Signal* signal);
- void execRESUME_REQ(Signal* signal);
-
- void execCHANGE_NODE_STATE_CONF(Signal* signal);
-
- void execABORT_ALL_REF(Signal* signal);
- void execABORT_ALL_CONF(Signal* signal);
-
- // Statement blocks
- void sendCreateTabReq(Signal* signal, const char* buffer, Uint32 bufLen);
- void startInsertTransactions(Signal* signal);
- void initData(Signal* signal);
- void resetStartVariables(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, int line);
-
- void createSystableLab(Signal* signal, unsigned index);
- void crSystab7Lab(Signal* signal);
- void crSystab8Lab(Signal* signal);
- void crSystab9Lab(Signal* signal);
-
- void startPhase1Lab(Signal* signal);
- void startPhase2Lab(Signal* signal);
- void startPhase3Lab(Signal* signal);
- void startPhase4Lab(Signal* signal);
- void startPhase5Lab(Signal* signal);
- // jump 2 to resync phase counters
- void startPhase8Lab(Signal* signal);
- void startPhase9Lab(Signal* signal);
- void ph2ALab(Signal* signal);
- void ph2CLab(Signal* signal);
- void ph2ELab(Signal* signal);
- void ph2FLab(Signal* signal);
- void ph2GLab(Signal* signal);
- void ph3ALab(Signal* signal);
- void ph4ALab(Signal* signal);
- void ph4BLab(Signal* signal);
- void ph4CLab(Signal* signal);
- void ph5ALab(Signal* signal);
- void ph6ALab(Signal* signal);
- void ph6BLab(Signal* signal);
- void ph7ALab(Signal* signal);
- void ph8ALab(Signal* signal);
-
-
- void waitpoint41Lab(Signal* signal);
- void waitpoint51Lab(Signal* signal);
- void waitpoint52Lab(Signal* signal);
- void waitpoint61Lab(Signal* signal);
- void waitpoint71Lab(Signal* signal);
-
- void updateNodeState(Signal* signal, const NodeState & newState) const ;
- void getNodeGroup(Signal* signal);
-
- // Initialisation
- void initData();
- void initRecords();
-
- // Variables
- /**------------------------------------------------------------------------
- * 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
- *------------------------------------------------------------------------*/
- NdbBlocksRec *ndbBlocksRec;
-
- /*
- 2.4 COMMON STORED VARIABLES
- */
- UintR cgciSystab;
- UintR ckey;
- //UintR csystabId;
- UintR cnoWaitrep6;
- UintR cnoWaitrep7;
- UintR ctcConnectionP;
- UintR ctcReqInfo;
- Uint8 ctransidPhase;
- Uint16 cresponses;
-
- Uint8 cstartPhase;
- Uint16 cinternalStartphase;
-
- Uint16 cmasterNodeId;
- Uint16 cndbBlocksCount;
- Uint16 cnoStartNodes;
- UintR cnoWaitrep;
- NodeState::StartType ctypeOfStart;
- Uint16 cdynamicNodeId;
-
- Uint32 c_fsRemoveCount;
- Uint32 c_nodeGroup;
- void clearFilesystem(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 {
- public:
- StopRecord(Ndbcntr & _cntr) : cntr(_cntr) {
- stopReq.senderRef = 0;
- }
-
- Ndbcntr & cntr;
- StopReq stopReq; // Signal data
- NDB_TICKS stopInitiatedTime; // When was the stop initiated
-
- bool checkNodeFail(Signal* signal);
- void checkTimeout(Signal* signal);
- void checkApiTimeout(Signal* signal);
- void checkTcTimeout(Signal* signal);
- void checkLqhTimeout_1(Signal* signal);
- void checkLqhTimeout_2(Signal* signal);
-
- BlockNumber number() const { return cntr.number(); }
- void progError(int line, int cause, const char * extra) {
- cntr.progError(line, cause, extra);
- }
-
- enum StopNodesStep {
- SR_BLOCK_GCP_START_GCP = 0,
- SR_WAIT_COMPLETE_GCP = 1,
- SR_UNBLOCK_GCP_START_GCP = 2,
- SR_QMGR_STOP_REQ = 3,
- SR_WAIT_NODE_FAILURES = 4,
- SR_CLUSTER_SHUTDOWN = 12
- } m_state;
- SignalCounter m_stop_req_counter;
- };
-private:
- StopRecord c_stopRec;
- friend struct StopRecord;
-
- struct Missra {
- Missra(Ndbcntr & ref) : cntr(ref) { }
-
- Uint32 currentBlockIndex;
- Uint32 currentStartPhase;
- Uint32 nextStartPhase[NO_OF_BLOCKS];
-
- 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) {
- cntr.progError(line, cause, extra);
- }
- Ndbcntr & cntr;
- };
-
- Missra c_missra;
- friend struct Missra;
-
- void execSTTORRY(Signal* signal);
- void execSTART_ORD(Signal* signal);
- void execREAD_CONFIG_CONF(Signal*);
-
- friend struct UpgradeStartup;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
deleted file mode 100644
index 3b1120926f6..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#define NDBCNTR_C
-#include "Ndbcntr.hpp"
-#include <ndb_limits.h>
-
-#define DEBUG(x) { ndbout << "Ndbcntr::" << x << endl; }
-
-
-void Ndbcntr::initData()
-{
- c_start.reset();
- cmasterNodeId = 0;
- cnoStartNodes = 0;
- cnoWaitrep = 0;
- // Records with constant sizes
- ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC];
-}//Ndbcntr::initData()
-
-void Ndbcntr::initRecords()
-{
- // Records with dynamic sizes
-}//Ndbcntr::initRecords()
-
-Ndbcntr::Ndbcntr(Block_context& ctx):
- SimulatedBlock(NDBCNTR, ctx),
- cnoWaitrep6(0),
- cnoWaitrep7(0),
- c_stopRec(* this),
- c_missra(* this)
-{
-
- BLOCK_CONSTRUCTOR(Ndbcntr);
-
- // Transit signals
- addRecSignal(GSN_CONTINUEB, &Ndbcntr::execCONTINUEB);
- addRecSignal(GSN_READ_NODESCONF, &Ndbcntr::execREAD_NODESCONF);
- addRecSignal(GSN_READ_NODESREF, &Ndbcntr::execREAD_NODESREF);
- 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_CNTR_START_REP, &Ndbcntr::execCNTR_START_REP);
- addRecSignal(GSN_API_START_REP, &Ndbcntr::execAPI_START_REP, true);
- addRecSignal(GSN_NODE_FAILREP, &Ndbcntr::execNODE_FAILREP);
- addRecSignal(GSN_SYSTEM_ERROR , &Ndbcntr::execSYSTEM_ERROR);
-
- // Received signals
- addRecSignal(GSN_DUMP_STATE_ORD, &Ndbcntr::execDUMP_STATE_ORD);
- addRecSignal(GSN_READ_CONFIG_REQ, &Ndbcntr::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &Ndbcntr::execSTTOR);
- addRecSignal(GSN_TCSEIZECONF, &Ndbcntr::execTCSEIZECONF);
- addRecSignal(GSN_TCSEIZEREF, &Ndbcntr::execTCSEIZEREF);
- addRecSignal(GSN_TCRELEASECONF, &Ndbcntr::execTCRELEASECONF);
- addRecSignal(GSN_TCRELEASEREF, &Ndbcntr::execTCRELEASEREF);
- addRecSignal(GSN_TCKEYCONF, &Ndbcntr::execTCKEYCONF);
- addRecSignal(GSN_TCKEYREF, &Ndbcntr::execTCKEYREF);
- addRecSignal(GSN_TCROLLBACKREP, &Ndbcntr::execTCROLLBACKREP);
- addRecSignal(GSN_GETGCICONF, &Ndbcntr::execGETGCICONF);
- addRecSignal(GSN_DIH_RESTARTCONF, &Ndbcntr::execDIH_RESTARTCONF);
- addRecSignal(GSN_DIH_RESTARTREF, &Ndbcntr::execDIH_RESTARTREF);
- addRecSignal(GSN_CREATE_TABLE_REF, &Ndbcntr::execCREATE_TABLE_REF);
- addRecSignal(GSN_CREATE_TABLE_CONF, &Ndbcntr::execCREATE_TABLE_CONF);
- addRecSignal(GSN_NDB_STTORRY, &Ndbcntr::execNDB_STTORRY);
- addRecSignal(GSN_NDB_STARTCONF, &Ndbcntr::execNDB_STARTCONF);
- addRecSignal(GSN_READ_NODESREQ, &Ndbcntr::execREAD_NODESREQ);
- addRecSignal(GSN_NDB_STARTREF, &Ndbcntr::execNDB_STARTREF);
-
- addRecSignal(GSN_STOP_PERM_REF, &Ndbcntr::execSTOP_PERM_REF);
- addRecSignal(GSN_STOP_PERM_CONF, &Ndbcntr::execSTOP_PERM_CONF);
-
- addRecSignal(GSN_STOP_ME_REF, &Ndbcntr::execSTOP_ME_REF);
- addRecSignal(GSN_STOP_ME_CONF, &Ndbcntr::execSTOP_ME_CONF);
-
- addRecSignal(GSN_STOP_REQ, &Ndbcntr::execSTOP_REQ);
- addRecSignal(GSN_STOP_CONF, &Ndbcntr::execSTOP_CONF);
- addRecSignal(GSN_RESUME_REQ, &Ndbcntr::execRESUME_REQ);
-
- addRecSignal(GSN_WAIT_GCP_REF, &Ndbcntr::execWAIT_GCP_REF);
- addRecSignal(GSN_WAIT_GCP_CONF, &Ndbcntr::execWAIT_GCP_CONF);
- addRecSignal(GSN_CHANGE_NODE_STATE_CONF,
- &Ndbcntr::execCHANGE_NODE_STATE_CONF);
-
- addRecSignal(GSN_ABORT_ALL_REF, &Ndbcntr::execABORT_ALL_REF);
- addRecSignal(GSN_ABORT_ALL_CONF, &Ndbcntr::execABORT_ALL_CONF);
-
- addRecSignal(GSN_START_ORD, &Ndbcntr::execSTART_ORD);
- addRecSignal(GSN_STTORRY, &Ndbcntr::execSTTORRY);
- addRecSignal(GSN_READ_CONFIG_CONF, &Ndbcntr::execREAD_CONFIG_CONF);
-
- addRecSignal(GSN_FSREMOVECONF, &Ndbcntr::execFSREMOVECONF);
-
- initData();
- ctypeOfStart = NodeState::ST_ILLEGAL_TYPE;
- c_start.m_startTime = NdbTick_CurrentMillisecond();
-}//Ndbcntr::Ndbcntr()
-
-Ndbcntr::~Ndbcntr()
-{
- delete []ndbBlocksRec;
-
-}//Ndbcntr::~Ndbcntr()
-
-BLOCK_FUNCTIONS(Ndbcntr)
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
deleted file mode 100644
index 4c58509f9a1..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ /dev/null
@@ -1,3094 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#define NDBCNTR_C
-#include "Ndbcntr.hpp"
-
-#include <ndb_limits.h>
-#include <ndb_version.h>
-#include <SimpleProperties.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/CreateTable.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/TcKeyConf.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/NodeStateSignalData.hpp>
-#include <signaldata/StopPerm.hpp>
-#include <signaldata/StopMe.hpp>
-#include <signaldata/WaitGCP.hpp>
-#include <signaldata/CheckNodeGroups.hpp>
-#include <signaldata/StartOrd.hpp>
-#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 <signaldata/FailRep.hpp>
-
-#include <AttributeHeader.hpp>
-#include <Configuration.hpp>
-#include <DebuggerNames.hpp>
-
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-// used during shutdown for reporting current startphase
-// accessed from Emulator.cpp, NdbShutdown()
-Uint32 g_currentStartPhase;
-
-/**
- * ALL_BLOCKS Used during start phases and while changing node state
- *
- * NDBFS_REF Has to be before NDBCNTR_REF (due to "ndb -i" stuff)
- */
-struct BlockInfo {
- BlockReference Ref; // BlockReference
- Uint32 NextSP; // Next start phase
- Uint32 ErrorInsertStart;
- Uint32 ErrorInsertStop;
-};
-
-static BlockInfo ALL_BLOCKS[] = {
- { NDBFS_REF, 0 , 2000, 2999 },
- { 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 },
- { NDBCNTR_REF, 0 , 1000, 1999 },
- { CMVMI_REF, 1 , 9000, 9999 }, // before QMGR
- { QMGR_REF, 1 , 1, 999 },
- { TRIX_REF, 1 , 0, 0 },
- { BACKUP_REF, 1 , 10000, 10999 },
- { DBUTIL_REF, 1 , 11000, 11999 },
- { SUMA_REF, 1 , 13000, 13999 },
- { DBTUX_REF, 1 , 12000, 12999 }
- ,{ TSMAN_REF, 1 , 0, 0 }
- ,{ LGMAN_REF, 1 , 0, 0 }
- ,{ PGMAN_REF, 1 , 0, 0 }
- ,{ RESTORE_REF,1 , 0, 0 }
-};
-
-static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo);
-
-static BlockReference readConfigOrder[ALL_BLOCKS_SZ] = {
- CMVMI_REF,
- DBTUP_REF,
- DBACC_REF,
- DBTC_REF,
- DBLQH_REF,
- DBTUX_REF,
- DBDICT_REF,
- DBDIH_REF,
- NDBFS_REF,
- NDBCNTR_REF,
- QMGR_REF,
- TRIX_REF,
- BACKUP_REF,
- DBUTIL_REF,
- SUMA_REF,
- TSMAN_REF,
- LGMAN_REF,
- PGMAN_REF,
- RESTORE_REF
-};
-
-/*******************************/
-/* CONTINUEB */
-/*******************************/
-void Ndbcntr::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- UintR Ttemp1 = signal->theData[0];
- switch (Ttemp1) {
- case ZSTARTUP:{
- if(getNodeState().startLevel == NodeState::SL_STARTED){
- jam();
- return;
- }
-
- if(cmasterNodeId == getOwnNodeId() && c_start.m_starting.isclear()){
- jam();
- trySystemRestart(signal);
- // Fall-through
- }
-
- Uint64 now = NdbTick_CurrentMillisecond();
- if(now > c_start.m_startFailureTimeout)
- {
- jam();
- Uint32 to_3= 0;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3);
- BaseString tmp;
- tmp.append("Shutting down node as total restart time exceeds "
- " StartFailureTimeout as set in config file ");
- if(to_3 == 0)
- tmp.append(" 0 (inifinite)");
- else
- tmp.appfmt(" %d", to_3);
-
- progError(__LINE__, NDBD_EXIT_RESTART_TIMEOUT, tmp.c_str());
- }
-
- signal->theData[0] = ZSTARTUP;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
- break;
- }
- case ZSHUTDOWN:
- jam();
- c_stopRec.checkTimeout(signal);
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
-}//Ndbcntr::execCONTINUEB()
-
-void
-Ndbcntr::execAPI_START_REP(Signal* signal)
-{
- if(refToBlock(signal->getSendersBlockRef()) == QMGR)
- {
- for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
- sendSignal(ALL_BLOCKS[i].Ref, GSN_API_START_REP, signal, 1, JBB);
- }
- }
-}
-/*******************************/
-/* SYSTEM_ERROR */
-/*******************************/
-void Ndbcntr::execSYSTEM_ERROR(Signal* signal)
-{
- const SystemError * const sysErr = (SystemError *)signal->getDataPtr();
- char buf[100];
- int killingNode = refToNode(sysErr->errorRef);
- Uint32 data1 = sysErr->data1;
-
- jamEntry();
- switch (sysErr->errorCode){
- case SystemError::GCPStopDetected:
- BaseString::snprintf(buf, sizeof(buf),
- "Node %d killed this node because "
- "GCP stop was detected",
- killingNode);
- break;
-
- case SystemError::CopyFragRefError:
- CRASH_INSERTION(1000);
- BaseString::snprintf(buf, sizeof(buf),
- "Killed by node %d as "
- "copyfrag failed, error: %u",
- killingNode, data1);
- break;
-
- case SystemError::StartFragRefError:
- BaseString::snprintf(buf, sizeof(buf),
- "Node %d killed this node because "
- "it replied StartFragRef error code: %u.",
- killingNode, data1);
- break;
-
- case SystemError::CopySubscriptionRef:
- BaseString::snprintf(buf, sizeof(buf),
- "Node %d killed this node because "
- "it could not copy a subscription during node restart. "
- "Copy subscription error code: %u.",
- killingNode, data1);
- break;
- case SystemError::CopySubscriberRef:
- BaseString::snprintf(buf, sizeof(buf),
- "Node %d killed this node because "
- "it could not start a subscriber during node restart. "
- "Copy subscription error code: %u.",
- killingNode, data1);
- break;
- default:
- BaseString::snprintf(buf, sizeof(buf), "System error %d, "
- " this node was killed by node %d",
- sysErr->errorCode, killingNode);
- break;
- }
-
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR, buf);
- return;
-}//Ndbcntr::execSYSTEM_ERROR()
-
-void
-Ndbcntr::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void Ndbcntr::execSTTOR(Signal* signal)
-{
- jamEntry();
- cstartPhase = signal->theData[1];
-
- cndbBlocksCount = 0;
- cinternalStartphase = cstartPhase - 1;
-
- switch (cstartPhase) {
- case 0:
- if(m_ctx.m_config.getInitialStart()){
- jam();
- c_fsRemoveCount = 0;
- clearFilesystem(signal);
- return;
- }
- sendSttorry(signal);
- break;
- case ZSTART_PHASE_1:
- jam();
- {
- Uint32 db_watchdog_interval = 0;
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndb_mgm_get_int_parameter(p, CFG_DB_WATCHDOG_INTERVAL, &db_watchdog_interval);
- ndbrequire(db_watchdog_interval);
- update_watch_dog_timer(db_watchdog_interval);
- }
- startPhase1Lab(signal);
- break;
- case ZSTART_PHASE_2:
- jam();
- startPhase2Lab(signal);
- break;
- case ZSTART_PHASE_3:
- jam();
- startPhase3Lab(signal);
- break;
- case ZSTART_PHASE_4:
- jam();
- startPhase4Lab(signal);
- break;
- case ZSTART_PHASE_5:
- jam();
- startPhase5Lab(signal);
- break;
- case 6:
- jam();
- getNodeGroup(signal);
- // Fall through
- break;
- case ZSTART_PHASE_8:
- jam();
- startPhase8Lab(signal);
- break;
- case ZSTART_PHASE_9:
- jam();
- startPhase9Lab(signal);
- break;
- default:
- jam();
- sendSttorry(signal);
- break;
- }//switch
-}//Ndbcntr::execSTTOR()
-
-void
-Ndbcntr::getNodeGroup(Signal* signal){
- jam();
- CheckNodeGroups * sd = (CheckNodeGroups*)signal->getDataPtrSend();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::GetNodeGroup;
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
- jamEntry();
- c_nodeGroup = sd->output;
- sendSttorry(signal);
-}
-
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-void Ndbcntr::execNDB_STTORRY(Signal* signal)
-{
- jamEntry();
- switch (cstartPhase) {
- case ZSTART_PHASE_2:
- jam();
- ph2GLab(signal);
- return;
- break;
- case ZSTART_PHASE_3:
- jam();
- ph3ALab(signal);
- return;
- break;
- case ZSTART_PHASE_4:
- jam();
- ph4BLab(signal);
- return;
- break;
- case ZSTART_PHASE_5:
- jam();
- ph5ALab(signal);
- return;
- break;
- case ZSTART_PHASE_6:
- jam();
- ph6ALab(signal);
- return;
- break;
- case ZSTART_PHASE_7:
- jam();
- ph6BLab(signal);
- return;
- break;
- case ZSTART_PHASE_8:
- jam();
- ph7ALab(signal);
- return;
- break;
- case ZSTART_PHASE_9:
- jam();
- ph8ALab(signal);
- return;
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
-}//Ndbcntr::execNDB_STTORRY()
-
-void Ndbcntr::startPhase1Lab(Signal* signal)
-{
- jamEntry();
-
- initData(signal);
-
- cdynamicNodeId = 0;
-
- NdbBlocksRecPtr ndbBlocksPtr;
- ndbBlocksPtr.i = 0;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBLQH_REF;
- ndbBlocksPtr.i = 1;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBDICT_REF;
- ndbBlocksPtr.i = 2;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBTUP_REF;
- ndbBlocksPtr.i = 3;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBACC_REF;
- ndbBlocksPtr.i = 4;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBTC_REF;
- ndbBlocksPtr.i = 5;
- ptrAss(ndbBlocksPtr, ndbBlocksRec);
- ndbBlocksPtr.p->blockref = DBDIH_REF;
- sendSttorry(signal);
- return;
-}
-
-void Ndbcntr::execREAD_NODESREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execREAD_NODESREF()
-
-
-/*******************************/
-/* NDB_STARTREF */
-/*******************************/
-void Ndbcntr::execNDB_STARTREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execNDB_STARTREF()
-
-/*******************************/
-/* STTOR */
-/*******************************/
-void Ndbcntr::startPhase2Lab(Signal* signal)
-{
- 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()
-
-/*******************************/
-/* DIH_RESTARTCONF */
-/*******************************/
-void Ndbcntr::execDIH_RESTARTCONF(Signal* signal)
-{
- jamEntry();
- //cmasterDihId = signal->theData[0];
- c_start.m_lastGci = signal->theData[1];
- ctypeOfStart = NodeState::ST_SYSTEM_RESTART;
- ph2ALab(signal);
- return;
-}//Ndbcntr::execDIH_RESTARTCONF()
-
-/*******************************/
-/* DIH_RESTARTREF */
-/*******************************/
-void Ndbcntr::execDIH_RESTARTREF(Signal* signal)
-{
- jamEntry();
- ctypeOfStart = NodeState::ST_INITIAL_START;
- ph2ALab(signal);
- return;
-}//Ndbcntr::execDIH_RESTARTREF()
-
-void Ndbcntr::ph2ALab(Signal* signal)
-{
- /******************************/
- /* request configured nodes */
- /* from QMGR */
- /* READ_NODESREQ */
- /******************************/
- 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 ~(Uint64)0;
- return time + timeoutValue;
-}
-
-/*******************************/
-/* READ_NODESCONF */
-/*******************************/
-void Ndbcntr::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
- const ReadNodesConf * readNodes = (ReadNodesConf *)&signal->theData[0];
-
- cmasterNodeId = readNodes->masterNodeId;
- cdynamicNodeId = readNodes->ndynamicId;
-
- /**
- * All defined nodes...
- */
- c_allDefinedNodes.assign(NdbNodeBitmask::Size, readNodes->allNodes);
- c_clusterNodes.assign(NdbNodeBitmask::Size, readNodes->clusterNodes);
-
- Uint32 to_1 = 30000;
- Uint32 to_2 = 0;
- Uint32 to_3 = 0;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.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_startTime = NdbTick_CurrentMillisecond();
- 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);
-
- UpgradeStartup::sendCmAppChg(* this, signal, 0); // ADD
-
- sendCntrStartReq(signal);
-
- signal->theData[0] = ZSTARTUP;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
-
- return;
-}
-
-void
-Ndbcntr::execCM_ADD_REP(Signal* signal){
- jamEntry();
- c_clusterNodes.set(signal->theData[0]);
-}
-
-void
-Ndbcntr::sendCntrStartReq(Signal * signal){
- jamEntry();
-
- 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);
-}
-
-void
-Ndbcntr::execCNTR_START_REF(Signal * signal){
- jamEntry();
- const CntrStartRef * ref = (CntrStartRef*)signal->getDataPtr();
-
- switch(ref->errorCode){
- case CntrStartRef::NotMaster:
- jam();
- cmasterNodeId = ref->masterNodeId;
- sendCntrStartReq(signal);
- return;
- case CntrStartRef::StopInProgress:
- jam();
- progError(__LINE__, NDBD_EXIT_RESTART_DURING_SHUTDOWN);
- }
- 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;
-
- 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
-
-#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);
-
- /**
- * Inform all interested blocks that node has started
- */
- for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
- sendSignal(ALL_BLOCKS[i].Ref, GSN_NODE_START_REP, signal, 1, JBB);
- }
-
- if(!c_start.m_starting.isclear()){
- jam();
- return;
- }
-
- if(cmasterNodeId != getOwnNodeId()){
- jam();
- c_start.reset();
- return;
- }
-
- if(c_start.m_waiting.isclear()){
- jam();
- c_start.reset();
- return;
- }
-
- startWaitingNodes(signal);
-}
-
-void
-Ndbcntr::execCNTR_START_REQ(Signal * signal){
- jamEntry();
- const CntrStartReq * req = (CntrStartReq*)signal->getDataPtr();
-
- const Uint32 nodeId = req->nodeId;
- const Uint32 lastGci = req->lastGci;
- const NodeState::StartType st = (NodeState::StartType)req->startType;
-
- if(cmasterNodeId == 0){
- jam();
- // Has not completed READNODES yet
- sendSignalWithDelay(reference(), GSN_CNTR_START_REQ, signal, 100,
- signal->getLength());
- return;
- }
-
- if(cmasterNodeId != getOwnNodeId()){
- jam();
- sendCntrStartRef(signal, nodeId, CntrStartRef::NotMaster);
- return;
- }
-
- const NodeState & nodeState = getNodeState();
- switch(nodeState.startLevel){
- case NodeState::SL_NOTHING:
- case NodeState::SL_CMVMI:
- jam();
- ndbrequire(false);
- case NodeState::SL_STARTING:
- case NodeState::SL_STARTED:
- jam();
- 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:
- jam();
- c_start.m_withoutLog.set(nodeId);
- break;
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- c_start.m_withLog.set(nodeId);
- if(starting && lastGci > c_start.m_lastGci){
- jam();
- 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(starting){
- jam();
- 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:
- case NodeState::ST_ILLEGAL_TYPE:
- ndbrequire(false);
- }
-
- const bool startInProgress = !c_start.m_starting.isclear();
-
- if((starting && startInProgress) || (startInProgress && !parallellNR)){
- jam();
- // We're already starting together with a bunch of nodes
- // Let this node wait...
- return;
- }
-
- if(starting){
- jam();
- trySystemRestart(signal);
- } else {
- jam();
- startWaitingNodes(signal);
- }
- return;
-}
-
-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)){
- jam();
- 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()){
- jam();
- 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()){
- jam();
- 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;
-}
-
-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);
-
- if(!allClusterNodes){
- jam();
- return false;
- }
-
- NodeState::StartType srType = NodeState::ST_SYSTEM_RESTART;
- if(c_start.m_waiting.equal(c_start.m_withoutLog))
- {
- jam();
- 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;
- case CheckNodeGroups::Partitioning:
- jam();
- bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0);
-
- if(allNodes){
- if(allowPartition){
- jam();
- break;
- }
- ndbrequire(false); // All nodes -> partitioning, which is not allowed
- }
-
- 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;
-}
-
-void Ndbcntr::ph2GLab(Signal* signal)
-{
- if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }//if
- sendSttorry(signal);
- return;
-}//Ndbcntr::ph2GLab()
-
-/*
-4.4 START PHASE 3 */
-/*###########################################################################*/
-// SEND SIGNAL NDBSTTOR TO ALL BLOCKS, ACC, DICT, DIH, LQH, TC AND TUP
-// WHEN ALL BLOCKS HAVE RETURNED THEIR NDB_STTORRY ALL BLOCK HAVE FINISHED
-// THEIR LOCAL CONNECTIONs SUCESSFULLY
-// AND THEN WE CAN SEND APPL_STARTREG TO INFORM QMGR THAT WE ARE READY TO
-// SET UP DISTRIBUTED CONNECTIONS.
-/*--------------------------------------------------------------*/
-// THIS IS NDB START PHASE 3.
-/*--------------------------------------------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
-void Ndbcntr::startPhase3Lab(Signal* signal)
-{
- ph3ALab(signal);
- return;
-}//Ndbcntr::startPhase3Lab()
-
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-void Ndbcntr::ph3ALab(Signal* signal)
-{
- if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }//if
-
- sendSttorry(signal);
- return;
-}//Ndbcntr::ph3ALab()
-
-/*
-4.5 START PHASE 4 */
-/*###########################################################################*/
-// WAIT FOR ALL NODES IN CLUSTER TO CHANGE STATE INTO ZSTART ,
-// APPL_CHANGEREP IS ALWAYS SENT WHEN SOMEONE HAVE
-// CHANGED THEIR STATE. APPL_STARTCONF INDICATES THAT ALL NODES ARE IN START
-// STATE SEND NDB_STARTREQ TO DIH AND THEN WAIT FOR NDB_STARTCONF
-/*---------------------------------------------------------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
-void Ndbcntr::startPhase4Lab(Signal* signal)
-{
- ph4ALab(signal);
-}//Ndbcntr::startPhase4Lab()
-
-
-void Ndbcntr::ph4ALab(Signal* signal)
-{
- ph4BLab(signal);
- return;
-}//Ndbcntr::ph4ALab()
-
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-void Ndbcntr::ph4BLab(Signal* signal)
-{
-/*--------------------------------------*/
-/* CASE: CSTART_PHASE = ZSTART_PHASE_4 */
-/*--------------------------------------*/
- if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }//if
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- sendSttorry(signal);
- return;
- }//if
- waitpoint41Lab(signal);
- return;
-}//Ndbcntr::ph4BLab()
-
-void Ndbcntr::waitpoint41Lab(Signal* signal)
-{
- if (getOwnNodeId() == cmasterNodeId) {
- jam();
-/*--------------------------------------*/
-/* MASTER WAITS UNTIL ALL SLAVES HAS */
-/* SENT THE REPORTS */
-/*--------------------------------------*/
- 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
-// DATA IT USES THAT DATA TO SET UP WHICH FRAGMENTS THAT ARE TO START AND
-// WHERE THEY ARE TO START. THEN
-// IT SETS UP THE FRAGMENTS AND RECOVERS THEM BY:
-// 1) READING A LOCAL CHECKPOINT FROM DISK.
-// 2) EXECUTING THE UNDO LOG ON INDEX AND DATA.
-// 3) EXECUTING THE FRAGMENT REDO LOG FROM ONE OR SEVERAL NODES TO
-// RESTORE THE RESTART CONFIGURATION OF DATA IN NDB CLUSTER.
-/*---------------------------------------------------------------------------*/
- signal->theData[0] = reference();
- signal->theData[1] = ctypeOfStart;
- sendSignal(DBDIH_REF, GSN_NDB_STARTREQ, signal, 2, JBB);
- }//if
- } else {
- jam();
-/*--------------------------------------*/
-/* SLAVE NODES WILL PASS HERE ONCE AND */
-/* SEND A WAITPOINT REPORT TO MASTER. */
-/* SLAVES WONT DO ANYTHING UNTIL THEY */
-/* RECEIVE A WAIT REPORT FROM THE MASTER*/
-/*--------------------------------------*/
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_4_1;
- sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
- GSN_CNTR_WAITREP, signal, 2, JBB);
- }//if
- return;
-}//Ndbcntr::waitpoint41Lab()
-
-/*******************************/
-/* NDB_STARTCONF */
-/*******************************/
-void Ndbcntr::execNDB_STARTCONF(Signal* signal)
-{
- jamEntry();
-
- 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()
-
-/*
-4.6 START PHASE 5 */
-/*###########################################################################*/
-// SEND APPL_RUN TO THE QMGR IN THIS BLOCK
-// SEND NDB_STTOR ALL BLOCKS ACC, DICT, DIH, LQH, TC AND TUP THEN WAIT FOR
-// THEIR NDB_STTORRY
-/*---------------------------------------------------------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
-void Ndbcntr::startPhase5Lab(Signal* signal)
-{
- ph5ALab(signal);
- return;
-}//Ndbcntr::startPhase5Lab()
-
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-/*---------------------------------------------------------------------------*/
-// THIS IS NDB START PHASE 5.
-/*---------------------------------------------------------------------------*/
-// IN THIS START PHASE TUP INITIALISES DISK FILES FOR DISK STORAGE IF INITIAL
-// START. DIH WILL START UP
-// THE GLOBAL CHECKPOINT PROTOCOL AND WILL CONCLUDE ANY UNFINISHED TAKE OVERS
-// THAT STARTED BEFORE THE SYSTEM CRASH.
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::ph5ALab(Signal* signal)
-{
- if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }//if
-
- cstartPhase = cstartPhase + 1;
- cinternalStartphase = cstartPhase - 1;
- if (getOwnNodeId() == cmasterNodeId) {
- switch(ctypeOfStart){
- case NodeState::ST_INITIAL_START:
- jam();
- /*--------------------------------------*/
- /* MASTER CNTR IS RESPONSIBLE FOR */
- /* CREATING SYSTEM TABLES */
- /*--------------------------------------*/
- createSystableLab(signal, 0);
- return;
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- waitpoint52Lab(signal);
- return;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- break;
- case NodeState::ST_ILLEGAL_TYPE:
- jam();
- break;
- }
- ndbrequire(false);
- }
-
- /**
- * Not master
- */
- NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
- switch(ctypeOfStart){
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- /*----------------------------------------------------------------------*/
- // SEND NDB START PHASE 5 IN NODE RESTARTS TO COPY DATA TO THE NEWLY
- // STARTED NODE.
- /*----------------------------------------------------------------------*/
- 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(DBDIH_REF, GSN_NDB_STTOR, signal,
- NdbSttor::SignalLength, JBB);
- return;
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- /*--------------------------------------*/
- /* DURING SYSTEMRESTART AND INITALSTART:*/
- /* SLAVE NODES WILL PASS HERE ONCE AND */
- /* SEND A WAITPOINT REPORT TO MASTER. */
- /* SLAVES WONT DO ANYTHING UNTIL THEY */
- /* RECEIVE A WAIT REPORT FROM THE MASTER*/
- /* WHEN THE MASTER HAS FINISHED HIS WORK*/
- /*--------------------------------------*/
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_5_2;
- sendSignal(calcNdbCntrBlockRef(cmasterNodeId),
- GSN_CNTR_WAITREP, signal, 2, JBB);
- return;
- default:
- ndbrequire(false);
- }
-}//Ndbcntr::ph5ALab()
-
-void Ndbcntr::waitpoint52Lab(Signal* signal)
-{
- cnoWaitrep = cnoWaitrep + 1;
-/*---------------------------------------------------------------------------*/
-// THIS WAITING POINT IS ONLY USED BY A MASTER NODE. WE WILL EXECUTE NDB START
-// PHASE 5 FOR DIH IN THE
-// MASTER. THIS WILL START UP LOCAL CHECKPOINTS AND WILL ALSO CONCLUDE ANY
-// UNFINISHED LOCAL CHECKPOINTS
-// BEFORE THE SYSTEM CRASH. THIS WILL ENSURE THAT WE ALWAYS RESTART FROM A
-// WELL KNOWN STATE.
-/*---------------------------------------------------------------------------*/
-/*--------------------------------------*/
-/* MASTER WAITS UNTIL HE RECEIVED WAIT */
-/* REPORTS FROM ALL SLAVE CNTR */
-/*--------------------------------------*/
- if (cnoWaitrep == cnoStartNodes) {
- jam();
- cnoWaitrep = 0;
-
- NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->nodeId = getOwnNodeId();
- req->internalStartPhase = cinternalStartphase;
- req->typeOfStart = ctypeOfStart;
- req->masterNodeId = cmasterNodeId;
-#ifdef TRACE_STTOR
- ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase);
-#endif
- sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal,
- NdbSttor::SignalLength, JBB);
- }//if
- return;
-}//Ndbcntr::waitpoint52Lab()
-
-/*******************************/
-/* NDB_STTORRY */
-/*******************************/
-void Ndbcntr::ph6ALab(Signal* signal)
-{
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- waitpoint51Lab(signal);
- return;
- }//if
-
- 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()
-
-void Ndbcntr::waitpoint51Lab(Signal* signal)
-{
- cstartPhase = cstartPhase + 1;
-/*---------------------------------------------------------------------------*/
-// A FINAL STEP IS NOW TO SEND NDB_STTOR TO TC. THIS MAKES IT POSSIBLE TO
-// CONNECT TO TC FOR APPLICATIONS.
-// THIS IS NDB START PHASE 6 WHICH IS FOR ALL BLOCKS IN ALL NODES.
-/*---------------------------------------------------------------------------*/
- cinternalStartphase = cstartPhase - 1;
- cndbBlocksCount = 0;
- ph6BLab(signal);
- return;
-}//Ndbcntr::waitpoint51Lab()
-
-void Ndbcntr::ph6BLab(Signal* signal)
-{
- // c_missra.currentStartPhase - cstartPhase - cinternalStartphase =
- // 5 - 7 - 6
- if (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }//if
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- sendSttorry(signal);
- return;
- }
- waitpoint61Lab(signal);
-}
-
-void Ndbcntr::waitpoint61Lab(Signal* signal)
-{
- if (getOwnNodeId() == cmasterNodeId) {
- jam();
- cnoWaitrep6++;
- if (cnoWaitrep6 == cnoStartNodes) {
- jam();
- 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();
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_6_1;
- sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
- }
-}
-
-// Start phase 8 (internal 7)
-void Ndbcntr::startPhase8Lab(Signal* signal)
-{
- cinternalStartphase = cstartPhase - 1;
- cndbBlocksCount = 0;
- ph7ALab(signal);
-}
-
-void Ndbcntr::ph7ALab(Signal* signal)
-{
- while (cndbBlocksCount < ZNO_NDB_BLOCKS) {
- jam();
- sendNdbSttor(signal);
- return;
- }
- if ((ctypeOfStart == NodeState::ST_NODE_RESTART) ||
- (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) {
- jam();
- sendSttorry(signal);
- return;
- }
- waitpoint71Lab(signal);
-}
-
-void Ndbcntr::waitpoint71Lab(Signal* signal)
-{
- if (getOwnNodeId() == cmasterNodeId) {
- jam();
- cnoWaitrep7++;
- if (cnoWaitrep7 == cnoStartNodes) {
- jam();
- 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();
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ZWAITPOINT_7_1;
- sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB);
- }
-}
-
-// Start phase 9 (internal 8)
-void Ndbcntr::startPhase9Lab(Signal* signal)
-{
- cinternalStartphase = cstartPhase - 1;
- cndbBlocksCount = 0;
- ph8ALab(signal);
-}
-
-void Ndbcntr::ph8ALab(Signal* signal)
-{
-/*---------------------------------------------------------------------------*/
-// NODES WHICH PERFORM A NODE RESTART NEEDS TO GET THE DYNAMIC ID'S
-// OF THE OTHER NODES HERE.
-/*---------------------------------------------------------------------------*/
- sendSttorry(signal);
- resetStartVariables(signal);
- return;
-}//Ndbcntr::ph8BLab()
-
-/*******************************/
-/* CNTR_WAITREP */
-/*******************************/
-void Ndbcntr::execCNTR_WAITREP(Signal* signal)
-{
- Uint16 twaitPoint;
-
- jamEntry();
- twaitPoint = signal->theData[1];
- switch (twaitPoint) {
- case ZWAITPOINT_4_1:
- jam();
- waitpoint41Lab(signal);
- break;
- case ZWAITPOINT_4_2:
- jam();
- sendSttorry(signal);
- break;
- case ZWAITPOINT_5_1:
- jam();
- waitpoint51Lab(signal);
- break;
- case ZWAITPOINT_5_2:
- jam();
- waitpoint52Lab(signal);
- break;
- case ZWAITPOINT_6_1:
- jam();
- waitpoint61Lab(signal);
- break;
- case ZWAITPOINT_6_2:
- jam();
- sendSttorry(signal);
- break;
- case ZWAITPOINT_7_1:
- jam();
- waitpoint71Lab(signal);
- break;
- case ZWAITPOINT_7_2:
- jam();
- sendSttorry(signal);
- break;
- default:
- jam();
- systemErrorLab(signal, __LINE__);
- break;
- }//switch
-}//Ndbcntr::execCNTR_WAITREP()
-
-/*******************************/
-/* NODE_FAILREP */
-/*******************************/
-void Ndbcntr::execNODE_FAILREP(Signal* signal)
-{
- jamEntry();
-
- if (ERROR_INSERTED(1001))
- {
- sendSignalWithDelay(reference(), GSN_NODE_FAILREP, signal, 100,
- signal->getLength());
- return;
- }
-
- 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();
-
- 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){
- jam();
-
- const Uint32 phase = st.starting.startPhase;
-
- const bool tStartConf = (phase > 2) || (phase == 2 && cndbBlocksCount > 0);
-
- if(tMasterFailed){
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED,
- "Unhandled node failure during restart");
- }
-
- if(tStartConf && tStarting){
- // One of other starting nodes has crashed...
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED,
- "Unhandled node failure of starting node during restart");
- }
-
- if(tStartConf && tStarted){
- // One of other started nodes has crashed...
- progError(__LINE__, NDBD_EXIT_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
-
- return;
- }
-
- ndbrequire(!allFailed.get(getOwnNodeId()));
-
- NodeFailRep * rep = (NodeFailRep *)&signal->theData[0];
- rep->masterNodeId = cmasterNodeId;
-
- sendSignal(DBTC_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(DBLQH_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(DBDIH_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(DBDICT_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(BACKUP_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(SUMA_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- sendSignal(QMGR_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- if (c_stopRec.stopReq.senderRef)
- {
- jam();
- switch(c_stopRec.m_state){
- case StopRecord::SR_WAIT_NODE_FAILURES:
- {
- jam();
- NdbNodeBitmask tmp;
- tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
- tmp.bitANDC(allFailed);
- tmp.copyto(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
-
- if (tmp.isclear())
- {
- jam();
- if (c_stopRec.stopReq.senderRef != RNIL)
- {
- jam();
- StopConf * const stopConf = (StopConf *)&signal->theData[0];
- stopConf->senderData = c_stopRec.stopReq.senderData;
- stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
- sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal,
- StopConf::SignalLength, JBB);
- }
-
- c_stopRec.stopReq.senderRef = 0;
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = StopRecord::SR_UNBLOCK_GCP_START_GCP;
- req->requestType = WaitGCPReq::UnblockStartGcp;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBA);
- }
- break;
- }
- case StopRecord::SR_QMGR_STOP_REQ:
- {
- NdbNodeBitmask tmp;
- tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
- tmp.bitANDC(allFailed);
-
- if (tmp.isclear())
- {
- Uint32 nodeId = allFailed.find(0);
- tmp.set(nodeId);
-
- StopConf* conf = (StopConf*)signal->getDataPtrSend();
- conf->senderData = c_stopRec.stopReq.senderData;
- conf->nodeId = nodeId;
- sendSignal(reference(),
- GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
- }
-
- tmp.copyto(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
-
- break;
- }
- case StopRecord::SR_BLOCK_GCP_START_GCP:
- case StopRecord::SR_WAIT_COMPLETE_GCP:
- case StopRecord::SR_UNBLOCK_GCP_START_GCP:
- case StopRecord::SR_CLUSTER_SHUTDOWN:
- break;
- }
- }
-
- signal->theData[0] = NDB_LE_NODE_FAILREP;
- signal->theData[2] = 0;
-
- Uint32 nodeId = 0;
- while(!allFailed.isclear()){
- nodeId = allFailed.find(nodeId + 1);
- allFailed.clear(nodeId);
- signal->theData[1] = nodeId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }//for
-
- return;
-}//Ndbcntr::execNODE_FAILREP()
-
-/*******************************/
-/* READ_NODESREQ */
-/*******************************/
-void Ndbcntr::execREAD_NODESREQ(Signal* signal)
-{
- jamEntry();
-
- /*----------------------------------------------------------------------*/
- // ANY BLOCK MAY SEND A REQUEST ABOUT NDB NODES AND VERSIONS IN THE
- // SYSTEM. THIS REQUEST CAN ONLY BE HANDLED IN
- // ABSOLUTE STARTPHASE 3 OR LATER
- /*----------------------------------------------------------------------*/
- BlockReference TuserBlockref = signal->theData[0];
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
-
- /**
- * 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());
- }
-
- 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);
-
- } else {
- jam();
- signal->theData[0] = ZNOT_AVAILABLE;
- sendSignal(TuserBlockref, GSN_READ_NODESREF, signal, 1, JBB);
- }//if
-}//Ndbcntr::execREAD_NODESREQ()
-
-/*----------------------------------------------------------------------*/
-// SENDS APPL_ERROR TO QMGR AND THEN SET A POINTER OUT OF BOUNDS
-/*----------------------------------------------------------------------*/
-void Ndbcntr::systemErrorLab(Signal* signal, int line)
-{
- progError(line, NDBD_EXIT_NDBREQUIRE); /* BUG INSERTION */
- return;
-}//Ndbcntr::systemErrorLab()
-
-/*###########################################################################*/
-/* CNTR MASTER CREATES AND INITIALIZES A SYSTEMTABLE AT INITIALSTART */
-/* |-2048| # 1 00000001 | */
-/* | : | : | */
-/* | -1 | # 1 00000001 | */
-/* | 1 | 0 | tupleid sequence now created on first use */
-/* | : | : | v */
-/* | 2048| 0 | v */
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::createSystableLab(Signal* signal, unsigned index)
-{
- if (index >= g_sysTableCount) {
- ndbassert(index == g_sysTableCount);
- startInsertTransactions(signal);
- return;
- }
- const SysTable& table = *g_sysTableList[index];
- Uint32 propPage[256];
- LinearWriter w(propPage, 256);
-
- // XXX remove commented-out lines later
-
- w.first();
- w.add(DictTabInfo::TableName, table.name);
- w.add(DictTabInfo::TableLoggedFlag, table.tableLoggedFlag);
- //w.add(DictTabInfo::TableKValue, 6);
- //w.add(DictTabInfo::MinLoadFactor, 70);
- //w.add(DictTabInfo::MaxLoadFactor, 80);
- w.add(DictTabInfo::FragmentTypeVal, (Uint32)table.fragmentType);
- //w.add(DictTabInfo::NoOfKeyAttr, 1);
- w.add(DictTabInfo::NoOfAttributes, (Uint32)table.columnCount);
- //w.add(DictTabInfo::NoOfNullable, (Uint32)0);
- //w.add(DictTabInfo::NoOfVariable, (Uint32)0);
- //w.add(DictTabInfo::KeyLength, 1);
- w.add(DictTabInfo::TableTypeVal, (Uint32)table.tableType);
- w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
-
- for (unsigned i = 0; i < table.columnCount; i++) {
- const SysColumn& column = table.columnList[i];
- ndbassert(column.pos == i);
- w.add(DictTabInfo::AttributeName, column.name);
- w.add(DictTabInfo::AttributeId, (Uint32)i);
- w.add(DictTabInfo::AttributeKeyFlag, (Uint32)column.keyFlag);
- w.add(DictTabInfo::AttributeStorageType,
- (Uint32)NDB_STORAGETYPE_MEMORY);
- w.add(DictTabInfo::AttributeArrayType,
- (Uint32)NDB_ARRAYTYPE_FIXED);
- w.add(DictTabInfo::AttributeNullableFlag, (Uint32)column.nullable);
- w.add(DictTabInfo::AttributeExtType, (Uint32)column.type);
- w.add(DictTabInfo::AttributeExtLength, (Uint32)column.length);
- w.add(DictTabInfo::AttributeEnd, (Uint32)true);
- }
- w.add(DictTabInfo::TableEnd, (Uint32)true);
-
- Uint32 length = w.getWordsUsed();
- LinearSectionPtr ptr[3];
- ptr[0].p = &propPage[0];
- ptr[0].sz = length;
-
- CreateTableReq* const req = (CreateTableReq*)signal->getDataPtrSend();
- req->senderData = index;
- req->senderRef = reference();
- sendSignal(DBDICT_REF, GSN_CREATE_TABLE_REQ, signal,
- CreateTableReq::SignalLength, JBB, ptr, 1);
- return;
-}//Ndbcntr::createSystableLab()
-
-void Ndbcntr::execCREATE_TABLE_REF(Signal* signal)
-{
- jamEntry();
- progError(__LINE__,NDBD_EXIT_NDBREQUIRE, "CREATE_TABLE_REF");
- return;
-}//Ndbcntr::execDICTTABREF()
-
-void Ndbcntr::execCREATE_TABLE_CONF(Signal* signal)
-{
- jamEntry();
- CreateTableConf * const conf = (CreateTableConf*)signal->getDataPtrSend();
- //csystabId = conf->tableId;
- ndbrequire(conf->senderData < g_sysTableCount);
- const SysTable& table = *g_sysTableList[conf->senderData];
- table.tableId = conf->tableId;
- createSystableLab(signal, conf->senderData + 1);
- //startInsertTransactions(signal);
- return;
-}//Ndbcntr::execDICTTABCONF()
-
-/*******************************/
-/* DICTRELEASECONF */
-/*******************************/
-void Ndbcntr::startInsertTransactions(Signal* signal)
-{
- jamEntry();
-
- ckey = 1;
- ctransidPhase = ZTRUE;
- signal->theData[0] = 0;
- signal->theData[1] = reference();
- sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB);
- return;
-}//Ndbcntr::startInsertTransactions()
-
-/*******************************/
-/* TCSEIZECONF */
-/*******************************/
-void Ndbcntr::execTCSEIZECONF(Signal* signal)
-{
- jamEntry();
- ctcConnectionP = signal->theData[1];
- crSystab7Lab(signal);
- return;
-}//Ndbcntr::execTCSEIZECONF()
-
-const unsigned int RowsPerCommit = 16;
-void Ndbcntr::crSystab7Lab(Signal* signal)
-{
- UintR tkey;
- UintR Tmp;
-
- TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
-
- UintR reqInfo_Start = 0;
- tcKeyReq->setOperationType(reqInfo_Start, ZINSERT); // Insert
- tcKeyReq->setKeyLength (reqInfo_Start, 1);
- tcKeyReq->setAIInTcKeyReq (reqInfo_Start, 5);
- tcKeyReq->setAbortOption (reqInfo_Start, TcKeyReq::AbortOnError);
-
-/* KEY LENGTH = 1, ATTRINFO LENGTH IN TCKEYREQ = 5 */
- cresponses = 0;
- const UintR guard0 = ckey + (RowsPerCommit - 1);
- for (Tmp = ckey; Tmp <= guard0; Tmp++) {
- UintR reqInfo = reqInfo_Start;
- if (Tmp == ckey) { // First iteration, Set start flag
- jam();
- tcKeyReq->setStartFlag(reqInfo, 1);
- } //if
- if (Tmp == guard0) { // Last iteration, Set commit flag
- jam();
- tcKeyReq->setCommitFlag(reqInfo, 1);
- tcKeyReq->setExecuteFlag(reqInfo, 1);
- } //if
- if (ctransidPhase == ZTRUE) {
- jam();
- tkey = 0;
- tkey = tkey - Tmp;
- } else {
- jam();
- tkey = Tmp;
- }//if
-
- tcKeyReq->apiConnectPtr = ctcConnectionP;
- tcKeyReq->attrLen = 5;
- tcKeyReq->tableId = g_sysTable_SYSTAB_0.tableId;
- tcKeyReq->requestInfo = reqInfo;
- tcKeyReq->tableSchemaVersion = ZSYSTAB_VERSION;
- tcKeyReq->transId1 = 0;
- tcKeyReq->transId2 = ckey;
-
-//-------------------------------------------------------------
-// There is no optional part in this TCKEYREQ. There is one
-// key word and five ATTRINFO words.
-//-------------------------------------------------------------
- Uint32* tKeyDataPtr = &tcKeyReq->scanInfo;
- Uint32* tAIDataPtr = &tKeyDataPtr[1];
-
- tKeyDataPtr[0] = tkey;
-
- AttributeHeader::init(&tAIDataPtr[0], 0, 1 << 2);
- tAIDataPtr[1] = tkey;
- AttributeHeader::init(&tAIDataPtr[2], 1, 2 << 2);
- tAIDataPtr[3] = (tkey << 16);
- tAIDataPtr[4] = 1;
- sendSignal(DBTC_REF, GSN_TCKEYREQ, signal,
- TcKeyReq::StaticLength + 6, JBB);
- }//for
- ckey = ckey + RowsPerCommit;
- return;
-}//Ndbcntr::crSystab7Lab()
-
-/*******************************/
-/* TCKEYCONF09 */
-/*******************************/
-void Ndbcntr::execTCKEYCONF(Signal* signal)
-{
- const TcKeyConf * const keyConf = (TcKeyConf *)&signal->theData[0];
-
- jamEntry();
- cgciSystab = keyConf->gci;
- UintR confInfo = keyConf->confInfo;
-
- if (TcKeyConf::getMarkerFlag(confInfo)){
- Uint32 transId1 = keyConf->transId1;
- Uint32 transId2 = keyConf->transId2;
- signal->theData[0] = transId1;
- signal->theData[1] = transId2;
- sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB);
- }//if
-
- cresponses = cresponses + TcKeyConf::getNoOfOperations(confInfo);
- if (TcKeyConf::getCommitFlag(confInfo)){
- jam();
- ndbrequire(cresponses == RowsPerCommit);
-
- crSystab8Lab(signal);
- return;
- }
- return;
-}//Ndbcntr::tckeyConfLab()
-
-void Ndbcntr::crSystab8Lab(Signal* signal)
-{
- if (ckey < ZSIZE_SYSTAB) {
- jam();
- crSystab7Lab(signal);
- return;
- } else if (ctransidPhase == ZTRUE) {
- jam();
- ckey = 1;
- ctransidPhase = ZFALSE;
- // skip 2nd loop - tupleid sequence now created on first use
- }//if
- signal->theData[0] = ctcConnectionP;
- signal->theData[1] = reference();
- signal->theData[2] = 0;
- sendSignal(DBTC_REF, GSN_TCRELEASEREQ, signal, 2, JBB);
- return;
-}//Ndbcntr::crSystab8Lab()
-
-/*******************************/
-/* TCRELEASECONF */
-/*******************************/
-void Ndbcntr::execTCRELEASECONF(Signal* signal)
-{
- jamEntry();
- waitpoint52Lab(signal);
- return;
-}//Ndbcntr::execTCRELEASECONF()
-
-void Ndbcntr::crSystab9Lab(Signal* signal)
-{
- signal->theData[1] = reference();
- sendSignalWithDelay(DBDIH_REF, GSN_GETGCIREQ, signal, 100, 2);
- return;
-}//Ndbcntr::crSystab9Lab()
-
-/*******************************/
-/* GETGCICONF */
-/*******************************/
-void Ndbcntr::execGETGCICONF(Signal* signal)
-{
- jamEntry();
-
-#ifndef NO_GCP
- if (signal->theData[1] < cgciSystab) {
- jam();
-/*--------------------------------------*/
-/* MAKE SURE THAT THE SYSTABLE IS */
-/* NOW SAFE ON DISK */
-/*--------------------------------------*/
- crSystab9Lab(signal);
- return;
- }//if
-#endif
- waitpoint52Lab(signal);
- return;
-}//Ndbcntr::execGETGCICONF()
-
-void Ndbcntr::execTCKEYREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execTCKEYREF()
-
-void Ndbcntr::execTCROLLBACKREP(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execTCROLLBACKREP()
-
-void Ndbcntr::execTCRELEASEREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execTCRELEASEREF()
-
-void Ndbcntr::execTCSEIZEREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Ndbcntr::execTCSEIZEREF()
-
-
-/*---------------------------------------------------------------------------*/
-/*INITIALIZE VARIABLES AND RECORDS */
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::initData(Signal* signal)
-{
- c_start.reset();
- cmasterNodeId = 0;
- cnoStartNodes = 0;
- cnoWaitrep = 0;
-}//Ndbcntr::initData()
-
-
-/*---------------------------------------------------------------------------*/
-/*RESET VARIABLES USED DURING THE START */
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::resetStartVariables(Signal* signal)
-{
- cnoStartNodes = 0;
- cnoWaitrep6 = cnoWaitrep7 = 0;
-}//Ndbcntr::resetStartVariables()
-
-
-/*---------------------------------------------------------------------------*/
-// SEND THE SIGNAL
-// INPUT CNDB_BLOCKS_COUNT
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::sendNdbSttor(Signal* signal)
-{
- NdbBlocksRecPtr ndbBlocksPtr;
-
- ndbBlocksPtr.i = cndbBlocksCount;
- ptrCheckGuard(ndbBlocksPtr, ZSIZE_NDB_BLOCKS_REC, ndbBlocksRec);
-
- NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->nodeId = getOwnNodeId();
- req->internalStartPhase = cinternalStartphase;
- req->typeOfStart = ctypeOfStart;
- req->masterNodeId = cmasterNodeId;
-
- for (int i = 0; i < 16; i++) {
- // Garbage
- req->config[i] = 0x88776655;
- //cfgBlockPtr.p->cfgData[i];
- }
-
- //#define MAX_STARTPHASE 2
-#ifdef TRACE_STTOR
- ndbout_c("sending NDB_STTOR(%d) to %s",
- cinternalStartphase,
- getBlockName( refToBlock(ndbBlocksPtr.p->blockref)));
-#endif
- sendSignal(ndbBlocksPtr.p->blockref, GSN_NDB_STTOR, signal, 22, JBB);
- cndbBlocksCount++;
-}//Ndbcntr::sendNdbSttor()
-
-/*---------------------------------------------------------------------------*/
-// JUST SEND THE SIGNAL
-/*---------------------------------------------------------------------------*/
-void Ndbcntr::sendSttorry(Signal* signal)
-{
- signal->theData[3] = ZSTART_PHASE_1;
- signal->theData[4] = ZSTART_PHASE_2;
- signal->theData[5] = ZSTART_PHASE_3;
- signal->theData[6] = ZSTART_PHASE_4;
- signal->theData[7] = ZSTART_PHASE_5;
- signal->theData[8] = ZSTART_PHASE_6;
- // skip simulated phase 7
- signal->theData[9] = ZSTART_PHASE_8;
- signal->theData[10] = ZSTART_PHASE_9;
- signal->theData[11] = ZSTART_PHASE_END;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 12, JBB);
-}//Ndbcntr::sendSttorry()
-
-void
-Ndbcntr::execDUMP_STATE_ORD(Signal* signal)
-{
- DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
- Uint32 arg = dumpState->args[0];
-
- if(arg == 13){
- infoEvent("Cntr: cstartPhase = %d, cinternalStartphase = %d, block = %d",
- cstartPhase, cinternalStartphase, cndbBlocksCount);
- infoEvent("Cntr: cmasterNodeId = %d", cmasterNodeId);
- }
-
- if (arg == DumpStateOrd::NdbcntrTestStopOnError){
- if (m_ctx.m_config.stopOnError() == true)
- ((Configuration&)m_ctx.m_config).stopOnError(false);
-
- const BlockReference tblockref = calcNdbCntrBlockRef(getOwnNodeId());
-
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::TestStopOnError;
- sysErr->errorRef = reference();
- sendSignal(tblockref, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBA);
- }
-
- if (arg == DumpStateOrd::NdbcntrStopNodes)
- {
- NdbNodeBitmask mask;
- for(Uint32 i = 1; i<signal->getLength(); i++)
- mask.set(signal->theData[i]);
-
- StopReq* req = (StopReq*)signal->getDataPtrSend();
- req->senderRef = RNIL;
- req->senderData = 123;
- req->requestInfo = 0;
- req->singleuser = 0;
- req->singleUserApi = 0;
- mask.copyto(NdbNodeBitmask::Size, req->nodes);
- StopReq::setPerformRestart(req->requestInfo, 1);
- StopReq::setNoStart(req->requestInfo, 1);
- StopReq::setStopNodes(req->requestInfo, 1);
- StopReq::setStopAbort(req->requestInfo, 1);
-
- sendSignal(reference(), GSN_STOP_REQ, signal,
- StopReq::SignalLength, JBB);
- return;
- }
-
-}//Ndbcntr::execDUMP_STATE_ORD()
-
-void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{
- NodeStateRep * const stateRep = (NodeStateRep *)&signal->theData[0];
-
- if (newState.startLevel == NodeState::SL_STARTED)
- {
- CRASH_INSERTION(1000);
- }
-
- stateRep->nodeState = newState;
- stateRep->nodeState.masterNodeId = cmasterNodeId;
- stateRep->nodeState.setNodeGroup(c_nodeGroup);
-
- for(Uint32 i = 0; i<ALL_BLOCKS_SZ; i++){
- sendSignal(ALL_BLOCKS[i].Ref, GSN_NODE_STATE_REP, signal,
- NodeStateRep::SignalLength, JBB);
- }
-}
-
-void
-Ndbcntr::execRESUME_REQ(Signal* signal){
- //ResumeReq * const req = (ResumeReq *)&signal->theData[0];
- //ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
-
- jamEntry();
-
- signal->theData[0] = NDB_LE_SingleUser;
- signal->theData[1] = 2;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- //Uint32 senderData = req->senderData;
- //BlockReference senderRef = req->senderRef;
- NodeState newState(NodeState::SL_STARTED);
- updateNodeState(signal, newState);
- c_stopRec.stopReq.senderRef=0;
-}
-
-void
-Ndbcntr::execSTOP_REQ(Signal* signal){
- StopReq * const req = (StopReq *)&signal->theData[0];
- StopRef * const ref = (StopRef *)&signal->theData[0];
- Uint32 singleuser = req->singleuser;
- jamEntry();
- Uint32 senderData = req->senderData;
- BlockReference senderRef = req->senderRef;
- bool abort = StopReq::getStopAbort(req->requestInfo);
- bool stopnodes = StopReq::getStopNodes(req->requestInfo);
-
- if(!singleuser &&
- (getNodeState().startLevel < NodeState::SL_STARTED ||
- (abort && !stopnodes)))
- {
- /**
- * Node is not started yet
- *
- * So stop it quickly
- */
- jam();
- const Uint32 reqInfo = req->requestInfo;
- if(StopReq::getPerformRestart(reqInfo)){
- jam();
- StartOrd * startOrd = (StartOrd *)&signal->theData[0];
- startOrd->restartInfo = reqInfo;
- sendSignal(CMVMI_REF, GSN_START_ORD, signal, 1, JBA);
- } else {
- jam();
- sendSignal(CMVMI_REF, GSN_STOP_ORD, signal, 1, JBA);
- }
- return;
- }
-
- if(c_stopRec.stopReq.senderRef != 0 ||
- (cmasterNodeId == getOwnNodeId() && !c_start.m_starting.isclear()))
- {
- /**
- * Requested a system shutdown
- */
- if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
- jam();
- sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
- StopReq::SignalLength);
- return;
- }
-
- /**
- * Requested a node shutdown
- */
- if(c_stopRec.stopReq.senderRef &&
- StopReq::getSystemStop(c_stopRec.stopReq.requestInfo))
- ref->errorCode = StopRef::SystemShutdownInProgress;
- else
- ref->errorCode = StopRef::NodeShutdownInProgress;
- ref->senderData = senderData;
- ref->masterNodeId = cmasterNodeId;
-
- if (senderRef != RNIL)
- sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
- return;
- }
-
- if (stopnodes && !abort)
- {
- jam();
- ref->errorCode = StopRef::UnsupportedNodeShutdown;
- ref->senderData = senderData;
- ref->masterNodeId = cmasterNodeId;
- if (senderRef != RNIL)
- sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
- return;
- }
-
- if (stopnodes && cmasterNodeId != getOwnNodeId())
- {
- jam();
- ref->errorCode = StopRef::MultiNodeShutdownNotMaster;
- ref->senderData = senderData;
- ref->masterNodeId = cmasterNodeId;
- if (senderRef != RNIL)
- sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
- return;
- }
-
- c_stopRec.stopReq = * req;
- c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
-
- if (stopnodes)
- {
- jam();
-
- if(!c_stopRec.checkNodeFail(signal))
- {
- jam();
- return;
- }
-
- char buf[100];
- NdbNodeBitmask mask;
- mask.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
- infoEvent("Initiating shutdown abort of %s", mask.getText(buf));
- ndbout_c("Initiating shutdown abort of %s", mask.getText(buf));
-
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = StopRecord::SR_BLOCK_GCP_START_GCP;
- req->requestType = WaitGCPReq::BlockStartGcp;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
- return;
- }
- else if(!singleuser)
- {
- if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo))
- {
- jam();
- if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo))
- {
- ((Configuration&)m_ctx.m_config).stopOnError(false);
- }
- }
- if(!c_stopRec.checkNodeFail(signal))
- {
- jam();
- return;
- }
- signal->theData[0] = NDB_LE_NDBStopStarted;
- signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- }
- else
- {
- signal->theData[0] = NDB_LE_SingleUser;
- signal->theData[1] = 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
- }
-
- NodeState newState(NodeState::SL_STOPPING_1,
- StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
-
- if(singleuser) {
- newState.setSingleUser(true);
- newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
- }
- updateNodeState(signal, newState);
- signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void
-Ndbcntr::StopRecord::checkTimeout(Signal* signal){
- jamEntry();
-
- if(!cntr.getNodeState().getSingleUserMode())
- if(!checkNodeFail(signal)){
- jam();
- return;
- }
-
- switch(cntr.getNodeState().startLevel){
- case NodeState::SL_STOPPING_1:
- checkApiTimeout(signal);
- break;
- case NodeState::SL_STOPPING_2:
- checkTcTimeout(signal);
- break;
- case NodeState::SL_STOPPING_3:
- checkLqhTimeout_1(signal);
- break;
- case NodeState::SL_STOPPING_4:
- checkLqhTimeout_2(signal);
- break;
- case NodeState::SL_SINGLEUSER:
- break;
- default:
- ndbrequire(false);
- }
-}
-
-bool
-Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
- jam();
- if(StopReq::getSystemStop(stopReq.requestInfo)){
- jam();
- return true;
- }
-
- /**
- * Check if I can survive me stopping
- */
- NodeBitmask ndbMask;
- ndbMask.assign(cntr.c_startedNodes);
-
- if (StopReq::getStopNodes(stopReq.requestInfo))
- {
- NdbNodeBitmask tmp;
- tmp.assign(NdbNodeBitmask::Size, stopReq.nodes);
-
- NdbNodeBitmask ndbStopNodes;
- ndbStopNodes.assign(NdbNodeBitmask::Size, stopReq.nodes);
- ndbStopNodes.bitAND(ndbMask);
- ndbStopNodes.copyto(NdbNodeBitmask::Size, stopReq.nodes);
-
- ndbMask.bitANDC(tmp);
-
- bool allNodesStopped = true;
- int i ;
- for( i = 0; i < (int) NdbNodeBitmask::Size; i++ ){
- if ( stopReq.nodes[i] != 0 ){
- allNodesStopped = false;
- break;
- }
- }
-
- if ( allNodesStopped ) {
- StopConf * const stopConf = (StopConf *)&signal->theData[0];
- stopConf->senderData = stopReq.senderData;
- stopConf->nodeState = (Uint32) NodeState::SL_NOTHING;
- cntr.sendSignal(stopReq.senderRef, GSN_STOP_CONF, signal,
- StopConf::SignalLength, JBB);
- stopReq.senderRef = 0;
- return false;
- }
-
- }
- else
- {
- ndbMask.clear(cntr.getOwnNodeId());
- }
-
- CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
- sd->blockRef = cntr.reference();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
- sd->mask = ndbMask;
- cntr.EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
- jamEntry();
- switch (sd->output) {
- case CheckNodeGroups::Win:
- case CheckNodeGroups::Partitioning:
- return true;
- break;
- }
-
- StopRef * const ref = (StopRef *)&signal->theData[0];
-
- ref->senderData = stopReq.senderData;
- ref->errorCode = StopRef::NodeShutdownWouldCauseSystemCrash;
- ref->masterNodeId = cntr.cmasterNodeId;
-
- const BlockReference bref = stopReq.senderRef;
- if (bref != RNIL)
- cntr.sendSignal(bref, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
-
- stopReq.senderRef = 0;
-
- if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
- {
- NodeState newState(NodeState::SL_STARTED);
- cntr.updateNodeState(signal, newState);
- }
-
- signal->theData[0] = NDB_LE_NDBStopAborted;
- cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
-
- return false;
-}
-
-void
-Ndbcntr::StopRecord::checkApiTimeout(Signal* signal){
- const Int32 timeout = stopReq.apiTimeout;
- const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
- const NDB_TICKS now = NdbTick_CurrentMillisecond();
- if((timeout >= 0 && now >= alarm)){
- // || checkWithApiInSomeMagicWay)
- jam();
- NodeState newState(NodeState::SL_STOPPING_2,
- StopReq::getSystemStop(stopReq.requestInfo));
- if(stopReq.singleuser) {
- newState.setSingleUser(true);
- newState.setSingleUserApi(stopReq.singleUserApi);
- }
- cntr.updateNodeState(signal, newState);
-
- stopInitiatedTime = now;
- }
-
- signal->theData[0] = ZSHUTDOWN;
- cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void
-Ndbcntr::StopRecord::checkTcTimeout(Signal* signal){
- const Int32 timeout = stopReq.transactionTimeout;
- const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
- const NDB_TICKS now = NdbTick_CurrentMillisecond();
- if((timeout >= 0 && now >= alarm)){
- // || checkWithTcInSomeMagicWay)
- jam();
- if(stopReq.getSystemStop(stopReq.requestInfo) || stopReq.singleuser){
- jam();
- if(stopReq.singleuser)
- {
- jam();
- AbortAllReq * req = (AbortAllReq*)&signal->theData[0];
- req->senderRef = cntr.reference();
- req->senderData = 12;
- cntr.sendSignal(DBTC_REF, GSN_ABORT_ALL_REQ, signal,
- AbortAllReq::SignalLength, JBB);
- }
- else
- {
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = cntr.reference();
- req->senderData = StopRecord::SR_CLUSTER_SHUTDOWN;
- req->requestType = WaitGCPReq::CompleteForceStart;
- cntr.sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
- }
- } else {
- jam();
- StopPermReq * req = (StopPermReq*)&signal->theData[0];
- req->senderRef = cntr.reference();
- req->senderData = 12;
- cntr.sendSignal(DBDIH_REF, GSN_STOP_PERM_REQ, signal,
- StopPermReq::SignalLength, JBB);
- }
- return;
- }
- signal->theData[0] = ZSHUTDOWN;
- cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void Ndbcntr::execSTOP_PERM_REF(Signal* signal){
- //StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
-
- jamEntry();
-
- signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void Ndbcntr::execSTOP_PERM_CONF(Signal* signal){
- jamEntry();
-
- AbortAllReq * req = (AbortAllReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = 12;
- sendSignal(DBTC_REF, GSN_ABORT_ALL_REQ, signal,
- AbortAllReq::SignalLength, JBB);
-}
-
-void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
- jamEntry();
- if(c_stopRec.stopReq.singleuser) {
- jam();
-
- NodeState newState(NodeState::SL_SINGLEUSER);
- newState.setSingleUser(true);
- newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
- updateNodeState(signal, newState);
- c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
-
- StopConf * const stopConf = (StopConf *)&signal->theData[0];
- stopConf->senderData = c_stopRec.stopReq.senderData;
- stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
- sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
-
- c_stopRec.stopReq.senderRef = 0; // the command is done
-
- signal->theData[0] = NDB_LE_SingleUser;
- signal->theData[1] = 1;
- signal->theData[2] = c_stopRec.stopReq.singleUserApi;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }
- else
- {
- jam();
- NodeState newState(NodeState::SL_STOPPING_3,
- StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
- updateNodeState(signal, newState);
-
- c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
-
- signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
- }
-}
-
-void Ndbcntr::execABORT_ALL_REF(Signal* signal){
- jamEntry();
-
- StopRef * const stopRef = (StopRef *)&signal->theData[0];
- stopRef->senderData = c_stopRec.stopReq.senderData;
- stopRef->errorCode = StopRef::TransactionAbortFailed;
- stopRef->masterNodeId = cmasterNodeId;
- sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
-}
-
-void
-Ndbcntr::StopRecord::checkLqhTimeout_1(Signal* signal){
- const Int32 timeout = stopReq.readOperationTimeout;
- const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
- const NDB_TICKS now = NdbTick_CurrentMillisecond();
-
- if((timeout >= 0 && now >= alarm)){
- // || checkWithLqhInSomeMagicWay)
- jam();
-
- ChangeNodeStateReq * req = (ChangeNodeStateReq*)&signal->theData[0];
-
- NodeState newState(NodeState::SL_STOPPING_4,
- StopReq::getSystemStop(stopReq.requestInfo));
- req->nodeState = newState;
- req->senderRef = cntr.reference();
- req->senderData = 12;
- cntr.sendSignal(DBLQH_REF, GSN_CHANGE_NODE_STATE_REQ, signal, 2, JBB);
- return;
- }
- signal->theData[0] = ZSHUTDOWN;
- cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void Ndbcntr::execCHANGE_NODE_STATE_CONF(Signal* signal){
- jamEntry();
- signal->theData[0] = reference();
- signal->theData[1] = 12;
- sendSignal(DBDIH_REF, GSN_STOP_ME_REQ, signal, 2, JBB);
-}
-
-void Ndbcntr::execSTOP_ME_REF(Signal* signal){
- jamEntry();
- ndbrequire(false);
-}
-
-
-void Ndbcntr::execSTOP_ME_CONF(Signal* signal){
- jamEntry();
-
- NodeState newState(NodeState::SL_STOPPING_4,
- StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
- updateNodeState(signal, newState);
-
- c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
- signal->theData[0] = ZSHUTDOWN;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void
-Ndbcntr::StopRecord::checkLqhTimeout_2(Signal* signal){
- const Int32 timeout = stopReq.operationTimeout;
- const NDB_TICKS alarm = stopInitiatedTime + (NDB_TICKS)timeout;
- const NDB_TICKS now = NdbTick_CurrentMillisecond();
-
- if((timeout >= 0 && now >= alarm)){
- // || checkWithLqhInSomeMagicWay)
- jam();
- if(StopReq::getPerformRestart(stopReq.requestInfo)){
- jam();
- StartOrd * startOrd = (StartOrd *)&signal->theData[0];
- startOrd->restartInfo = stopReq.requestInfo;
- cntr.sendSignal(CMVMI_REF, GSN_START_ORD, signal, 2, JBA);
- } else {
- jam();
- cntr.sendSignal(CMVMI_REF, GSN_STOP_ORD, signal, 1, JBA);
- }
- return;
- }
- signal->theData[0] = ZSHUTDOWN;
- cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
-}
-
-void Ndbcntr::execWAIT_GCP_REF(Signal* signal){
- jamEntry();
-
- //WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
-
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = StopRecord::SR_CLUSTER_SHUTDOWN;
- req->requestType = WaitGCPReq::CompleteForceStart;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
-}
-
-void Ndbcntr::execWAIT_GCP_CONF(Signal* signal){
- jamEntry();
-
- WaitGCPConf* conf = (WaitGCPConf*)signal->getDataPtr();
-
- switch(conf->senderData){
- case StopRecord::SR_BLOCK_GCP_START_GCP:
- {
- jam();
- /**
- *
- */
- if(!c_stopRec.checkNodeFail(signal))
- {
- jam();
- goto unblock;
- }
-
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = StopRecord::SR_WAIT_COMPLETE_GCP;
- req->requestType = WaitGCPReq::CompleteIfRunning;
-
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
- return;
- }
- case StopRecord::SR_UNBLOCK_GCP_START_GCP:
- {
- jam();
- return;
- }
- case StopRecord::SR_WAIT_COMPLETE_GCP:
- {
- jam();
- if(!c_stopRec.checkNodeFail(signal))
- {
- jam();
- goto unblock;
- }
-
- NdbNodeBitmask tmp;
- tmp.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
- c_stopRec.m_stop_req_counter = tmp;
- NodeReceiverGroup rg(QMGR, tmp);
- StopReq * stopReq = (StopReq *)&signal->theData[0];
- * stopReq = c_stopRec.stopReq;
- stopReq->senderRef = reference();
- sendSignal(rg, GSN_STOP_REQ, signal, StopReq::SignalLength, JBA);
- c_stopRec.m_state = StopRecord::SR_QMGR_STOP_REQ;
- return;
- }
- case StopRecord::SR_CLUSTER_SHUTDOWN:
- {
- jam();
- break;
- }
- }
-
- {
- ndbrequire(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
- NodeState newState(NodeState::SL_STOPPING_3, true);
-
- /**
- * Inform QMGR so that arbitrator won't kill us
- */
- NodeStateRep * rep = (NodeStateRep *)&signal->theData[0];
- rep->nodeState = newState;
- rep->nodeState.masterNodeId = cmasterNodeId;
- rep->nodeState.setNodeGroup(c_nodeGroup);
- EXECUTE_DIRECT(QMGR, GSN_NODE_STATE_REP, signal,
- NodeStateRep::SignalLength);
-
- if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
- jam();
- StartOrd * startOrd = (StartOrd *)&signal->theData[0];
- startOrd->restartInfo = c_stopRec.stopReq.requestInfo;
- sendSignalWithDelay(CMVMI_REF, GSN_START_ORD, signal, 500,
- StartOrd::SignalLength);
- } else {
- jam();
- sendSignalWithDelay(CMVMI_REF, GSN_STOP_ORD, signal, 500, 1);
- }
- return;
- }
-
-unblock:
- WaitGCPReq * req = (WaitGCPReq*)&signal->theData[0];
- req->senderRef = reference();
- req->senderData = StopRecord::SR_UNBLOCK_GCP_START_GCP;
- req->requestType = WaitGCPReq::UnblockStartGcp;
- sendSignal(DBDIH_REF, GSN_WAIT_GCP_REQ, signal,
- WaitGCPReq::SignalLength, JBB);
-}
-
-void
-Ndbcntr::execSTOP_CONF(Signal* signal)
-{
- jamEntry();
- StopConf *conf = (StopConf*)signal->getDataPtr();
- ndbrequire(c_stopRec.m_state == StopRecord::SR_QMGR_STOP_REQ);
- c_stopRec.m_stop_req_counter.clearWaitingFor(conf->nodeId);
- if (c_stopRec.m_stop_req_counter.done())
- {
- char buf[100];
- NdbNodeBitmask mask;
- mask.assign(NdbNodeBitmask::Size, c_stopRec.stopReq.nodes);
- infoEvent("Stopping of %s", mask.getText(buf));
- ndbout_c("Stopping of %s", mask.getText(buf));
-
- /**
- * Kill any node...
- */
- FailRep * const failRep = (FailRep *)&signal->theData[0];
- failRep->failCause = FailRep::ZMULTI_NODE_SHUTDOWN;
- NodeReceiverGroup rg(QMGR, c_clusterNodes);
- Uint32 nodeId = 0;
- while ((nodeId = NdbNodeBitmask::find(c_stopRec.stopReq.nodes, nodeId+1))
- != NdbNodeBitmask::NotFound)
- {
- failRep->failNodeId = nodeId;
- sendSignal(rg, GSN_FAIL_REP, signal, FailRep::SignalLength, JBA);
- }
- c_stopRec.m_state = StopRecord::SR_WAIT_NODE_FAILURES;
- return;
- }
-}
-
-void Ndbcntr::execSTTORRY(Signal* signal){
- jamEntry();
- 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();
- c_missra.execSTART_ORD(signal);
-}
-
-#define CLEAR_DX 13
-#define CLEAR_LCP 3
-
-void
-Ndbcntr::clearFilesystem(Signal* signal)
-{
- const Uint32 lcp = c_fsRemoveCount >= CLEAR_DX;
-
- FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = 0;
- req->directory = 1;
- req->ownDirectory = 1;
-
- if (lcp == 0)
- {
- FsOpenReq::setVersion(req->fileNumber, 3);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL); // Can by any...
- FsOpenReq::v1_setDisk(req->fileNumber, c_fsRemoveCount);
- }
- else
- {
- FsOpenReq::setVersion(req->fileNumber, 5);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
- FsOpenReq::v5_setLcpNo(req->fileNumber, c_fsRemoveCount - CLEAR_DX);
- FsOpenReq::v5_setTableId(req->fileNumber, 0);
- FsOpenReq::v5_setFragmentId(req->fileNumber, 0);
- }
- sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
- FsRemoveReq::SignalLength, JBA);
- c_fsRemoveCount++;
-}
-
-void
-Ndbcntr::execFSREMOVECONF(Signal* signal){
- jamEntry();
- if(c_fsRemoveCount == CLEAR_DX + CLEAR_LCP){
- jam();
- sendSttorry(signal);
- } else {
- jam();
- ndbrequire(c_fsRemoveCount < CLEAR_DX + CLEAR_LCP);
- clearFilesystem(signal);
- }//if
-}
-
-void Ndbcntr::Missra::execSTART_ORD(Signal* signal){
- signal->theData[0] = NDB_LE_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 = readConfigOrder[currentBlockIndex];
-
-#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<ALL_BLOCKS_SZ; i++){
- if(ALL_BLOCKS[i].NextSP < currentStartPhase)
- currentStartPhase = ALL_BLOCKS[i].NextSP;
- }
-
- 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(readConfigOrder[currentBlockIndex])
- == 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));
-
- /**
- * Update next start phase
- */
- for (Uint32 i = 3; i < 25; i++){
- jam();
- if (signal->theData[i] > currentStartPhase){
- jam();
- ALL_BLOCKS[currentBlockIndex].NextSP = signal->theData[i];
- break;
- }
- }
-
- currentBlockIndex++;
- sendNextSTTOR(signal);
-}
-
-void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
-
- for(; currentStartPhase < 255 ;
- currentStartPhase++, g_currentStartPhase = currentStartPhase){
- jam();
-
- const Uint32 start = currentBlockIndex;
-
- if (currentStartPhase == ZSTART_PHASE_6)
- {
- // Ndbd has passed the critical startphases.
- // Change error handler from "startup" state
- // to normal state.
- ErrorReporter::setErrorHandlerShutdownType();
- }
-
- for(; currentBlockIndex < ALL_BLOCKS_SZ; currentBlockIndex++){
- jam();
- if(ALL_BLOCKS[currentBlockIndex].NextSP == currentStartPhase){
- jam();
- signal->theData[0] = 0;
- signal->theData[1] = currentStartPhase;
- signal->theData[2] = 0;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- signal->theData[5] = 0;
- signal->theData[6] = 0;
- signal->theData[7] = cntr.ctypeOfStart;
-
- const BlockReference ref = ALL_BLOCKS[currentBlockIndex].Ref;
-
-#ifdef MAX_STARTPHASE
- ndbrequire(currentStartPhase <= MAX_STARTPHASE);
-#endif
-
-#ifdef TRACE_STTOR
- ndbout_c("sending STTOR(%d) to %s(ref=%x index=%d)",
- currentStartPhase,
- getBlockName( refToBlock(ref)),
- ref,
- currentBlockIndex);
-#endif
-
- cntr.sendSignal(ref, GSN_STTOR, signal, 8, JBB);
-
- return;
- }
- }
-
- currentBlockIndex = 0;
-
- NodeState newState(NodeState::SL_STARTING, currentStartPhase,
- (NodeState::StartType)cntr.ctypeOfStart);
- cntr.updateNodeState(signal, newState);
-
- if(start != 0){
- /**
- * At least one wanted this start phase, report it
- */
- jam();
- signal->theData[0] = NDB_LE_StartPhaseCompleted;
- signal->theData[1] = currentStartPhase;
- signal->theData[2] = cntr.ctypeOfStart;
- cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }
- }
-
- signal->theData[0] = NDB_LE_NDBStartCompleted;
- signal->theData[1] = NDB_VERSION;
- cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- 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){
-
- if(cntr.getNodeInfo(cntr.cmasterNodeId).m_version >= MAKE_VERSION(3,5,0)){
- jam();
- return;
- }
-
- /**
- * Old NDB running
- */
-
- 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(__LINE__,NDBD_EXIT_NDBREQUIRE,
- "UpgradeStartup::execCM_APPCHG");
-}
-
-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(__LINE__,NDBD_EXIT_NDBREQUIRE,
- "UpgradeStartup::sendCntrMasterReq "
- "NdbNodeBitmask::NotFound");
- }
-
- 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(__LINE__,NDBD_EXIT_NDBREQUIRE,
- "UpgradeStartup::execCNTR_MASTER_REPLY");
-}
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp
deleted file mode 100644
index 9b4b12867b7..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Ndbcntr.hpp"
-
-#define arrayLength(x) sizeof(x)/sizeof(x[0])
-
-// SYSTAB_0
-
-static const Ndbcntr::SysColumn
-column_SYSTAB_0[] = {
- { 0, "SYSKEY_0",
- DictTabInfo::ExtUnsigned, 1,
- true, false
- },
- { 1, "NEXTID",
- DictTabInfo::ExtBigunsigned, 1,
- false, false
- }
-};
-
-const Ndbcntr::SysTable
-Ndbcntr::g_sysTable_SYSTAB_0 = {
- "sys/def/SYSTAB_0",
- arrayLength(column_SYSTAB_0), column_SYSTAB_0,
- DictTabInfo::SystemTable,
- DictTabInfo::AllNodesSmallTable,
- true, ~0
-};
-
-// NDB$EVENTS_0
-
-static const Ndbcntr::SysColumn
-column_NDBEVENTS_0[] = {
- { 0, "NAME",
- DictTabInfo::ExtBinary, MAX_TAB_NAME_SIZE,
- true, false
- },
- { 1, "EVENT_TYPE",
- DictTabInfo::ExtUnsigned, 1,
- false, false
- },
- { 2, "TABLEID",
- DictTabInfo::ExtUnsigned, 1,
- false, false
- },
- { 3, "TABLEVERSION",
- DictTabInfo::ExtUnsigned, 1,
- false, false
- },
- { 4, "TABLE_NAME",
- DictTabInfo::ExtBinary, MAX_TAB_NAME_SIZE,
- false, false
- },
- { 5, "ATTRIBUTE_MASK",
- DictTabInfo::ExtUnsigned, MAXNROFATTRIBUTESINWORDS,
- false, false
- },
- { 6, "SUBID",
- DictTabInfo::ExtUnsigned, 1,
- false, false
- },
- { 7, "SUBKEY",
- DictTabInfo::ExtUnsigned, 1,
- false, false
- },
-};
-
-const Ndbcntr::SysTable
-Ndbcntr::g_sysTable_NDBEVENTS_0 = {
- "sys/def/NDB$EVENTS_0",
- arrayLength(column_NDBEVENTS_0), column_NDBEVENTS_0,
- DictTabInfo::SystemTable,
- DictTabInfo::AllNodesSmallTable,
- true, ~0
-};
-
-// all
-
-const Ndbcntr::SysTable*
-Ndbcntr::g_sysTableList[] = {
- &g_sysTable_SYSTAB_0,
- &g_sysTable_NDBEVENTS_0
-};
-
-//TODO Backup needs this info to allocate appropriate number of records
-//BackupInit.cpp
-const unsigned
-Ndbcntr::g_sysTableCount = arrayLength(Ndbcntr::g_sysTableList);
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp
deleted file mode 100644
index e26e611dd7e..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp
+++ /dev/null
@@ -1,1387 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <my_pthread.h>
-
-#ifdef HAVE_XFS_XFS_H
-#include <xfs/xfs.h>
-#endif
-
-#include "AsyncFile.hpp"
-
-#include <ErrorHandlingMacros.hpp>
-#include <kernel_types.h>
-#include <ndbd_malloc.hpp>
-#include <NdbThread.h>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-
-// use this to test broken pread code
-//#define HAVE_BROKEN_PREAD
-
-#ifdef HAVE_BROKEN_PREAD
-#undef HAVE_PWRITE
-#undef HAVE_PREAD
-#endif
-
-#if defined NDB_WIN32
-#else
-// For readv and writev
-#include <sys/uio.h>
-#endif
-
-#ifndef NDB_WIN32
-#include <dirent.h>
-#endif
-
-// Use this define if you want printouts from AsyncFile class
-//#define DEBUG_ASYNCFILE
-
-#ifdef DEBUG_ASYNCFILE
-#include <NdbOut.hpp>
-#define DEBUG(x) x
-#define PRINT_ERRORANDFLAGS(f) printErrorAndFlags(f)
-void printErrorAndFlags(Uint32 used_flags);
-#else
-#define DEBUG(x)
-#define PRINT_ERRORANDFLAGS(f)
-#endif
-
-// Define the size of the write buffer (for each thread)
-#define WRITEBUFFERSIZE 262144
-
-const char *actionName[] = {
- "open",
- "close",
- "closeRemove",
- "read",
- "readv",
- "write",
- "writev",
- "writeSync",
- "writevSync",
- "sync",
- "end" };
-
-static int numAsyncFiles = 0;
-
-extern "C" void * runAsyncFile(void* arg)
-{
- ((AsyncFile*)arg)->run();
- return (NULL);
-}
-
-AsyncFile::AsyncFile(SimulatedBlock& fs) :
- theFileName(),
-#ifdef NDB_WIN32
- hFile(INVALID_HANDLE_VALUE),
-#else
- theFd(-1),
-#endif
- theReportTo(0),
- theMemoryChannelPtr(NULL),
- m_fs(fs)
-{
- m_page_ptr.setNull();
- m_current_request= m_last_request= 0;
- m_open_flags = 0;
-}
-
-void
-AsyncFile::doStart()
-{
- // Stacksize for filesystem threads
-#if !defined(DBUG_OFF) && defined (__hpux)
- // Empirical evidence indicates at least 32k
- const NDB_THREAD_STACKSIZE stackSize = 32768;
-#else
- // Otherwise an 8k stack should be enough
- const NDB_THREAD_STACKSIZE stackSize = 8192;
-#endif
-
- char buf[16];
- numAsyncFiles++;
- BaseString::snprintf(buf, sizeof(buf), "AsyncFile%d", numAsyncFiles);
-
- theStartMutexPtr = NdbMutex_Create();
- theStartConditionPtr = NdbCondition_Create();
- NdbMutex_Lock(theStartMutexPtr);
- theStartFlag = false;
- theThreadPtr = NdbThread_Create(runAsyncFile,
- (void**)this,
- stackSize,
- (char*)&buf,
- NDB_THREAD_PRIO_MEAN);
- if (theThreadPtr == 0)
- ERROR_SET(fatal, NDBD_EXIT_MEMALLOC, "","Could not allocate file system thread");
-
- NdbCondition_Wait(theStartConditionPtr,
- theStartMutexPtr);
- NdbMutex_Unlock(theStartMutexPtr);
- NdbMutex_Destroy(theStartMutexPtr);
- NdbCondition_Destroy(theStartConditionPtr);
-}
-
-AsyncFile::~AsyncFile()
-{
- void *status;
- Request request;
- request.action = Request::end;
- theMemoryChannelPtr->writeChannel( &request );
- NdbThread_WaitFor(theThreadPtr, &status);
- NdbThread_Destroy(&theThreadPtr);
- delete theMemoryChannelPtr;
-}
-
-void
-AsyncFile::reportTo( MemoryChannel<Request> *reportTo )
-{
- theReportTo = reportTo;
-}
-
-void AsyncFile::execute(Request* request)
-{
- theMemoryChannelPtr->writeChannel( request );
-}
-
-void
-AsyncFile::run()
-{
- Request *request;
- // Create theMemoryChannel in the thread that will wait for it
- NdbMutex_Lock(theStartMutexPtr);
- theMemoryChannelPtr = new MemoryChannel<Request>();
- theStartFlag = true;
- // Create write buffer for bigger writes
- theWriteBufferSize = WRITEBUFFERSIZE;
- theWriteBufferUnaligned = (char *) ndbd_malloc(theWriteBufferSize +
- NDB_O_DIRECT_WRITE_ALIGNMENT-1);
- theWriteBuffer = (char *)
- (((UintPtr)theWriteBufferUnaligned + NDB_O_DIRECT_WRITE_ALIGNMENT - 1) &
- ~(UintPtr)(NDB_O_DIRECT_WRITE_ALIGNMENT - 1));
-
- NdbMutex_Unlock(theStartMutexPtr);
- NdbCondition_Signal(theStartConditionPtr);
-
- if (!theWriteBuffer) {
- DEBUG(ndbout_c("AsyncFile::writeReq, Failed allocating write buffer"));
- return;
- }//if
-
- while (1) {
- request = theMemoryChannelPtr->readChannel();
- if (!request) {
- DEBUG(ndbout_c("Nothing read from Memory Channel in AsyncFile"));
- endReq();
- return;
- }//if
- m_current_request= request;
- switch (request->action) {
- case Request:: open:
- openReq(request);
- break;
- case Request:: close:
- closeReq(request);
- break;
- case Request:: closeRemove:
- closeReq(request);
- removeReq(request);
- break;
- case Request:: readPartial:
- case Request:: read:
- readReq(request);
- break;
- case Request:: readv:
- readvReq(request);
- break;
- case Request:: write:
- writeReq(request);
- break;
- case Request:: writev:
- writevReq(request);
- break;
- case Request:: writeSync:
- writeReq(request);
- syncReq(request);
- break;
- case Request:: writevSync:
- writevReq(request);
- syncReq(request);
- break;
- case Request:: sync:
- syncReq(request);
- break;
- case Request:: append:
- appendReq(request);
- break;
- case Request:: append_synch:
- appendReq(request);
- syncReq(request);
- break;
- case Request::rmrf:
- rmrfReq(request, (char*)theFileName.c_str(), request->par.rmrf.own_directory);
- break;
- case Request:: end:
- if (theFd > 0)
- closeReq(request);
- endReq();
- return;
- default:
- DEBUG(ndbout_c("Invalid Request"));
- abort();
- break;
- }//switch
- m_last_request= request;
- m_current_request= 0;
-
- // No need to signal as ndbfs only uses tryRead
- theReportTo->writeChannelNoSignal(request);
- }//while
-}//AsyncFile::run()
-
-#ifdef O_DIRECT
-static char g_odirect_readbuf[2*GLOBAL_PAGE_SIZE -1];
-#endif
-
-int
-AsyncFile::check_odirect_write(Uint32 flags, int& new_flags, int mode)
-{
- assert(new_flags & (O_CREAT | O_TRUNC));
-#ifdef O_DIRECT
- int ret;
- char * bufptr = (char*)((UintPtr(g_odirect_readbuf)+(GLOBAL_PAGE_SIZE - 1)) & ~(GLOBAL_PAGE_SIZE - 1));
- while (((ret = ::write(theFd, bufptr, GLOBAL_PAGE_SIZE)) == -1) &&
- (errno == EINTR));
- if (ret == -1)
- {
- new_flags &= ~O_DIRECT;
- ndbout_c("%s Failed to write using O_DIRECT, disabling",
- theFileName.c_str());
- }
-
- close(theFd);
- theFd = ::open(theFileName.c_str(), new_flags, mode);
- if (theFd == -1)
- return errno;
-#endif
-
- return 0;
-}
-
-int
-AsyncFile::check_odirect_read(Uint32 flags, int &new_flags, int mode)
-{
-#ifdef O_DIRECT
- int ret;
- char * bufptr = (char*)((UintPtr(g_odirect_readbuf)+(GLOBAL_PAGE_SIZE - 1)) & ~(GLOBAL_PAGE_SIZE - 1));
- while (((ret = ::read(theFd, bufptr, GLOBAL_PAGE_SIZE)) == -1) &&
- (errno == EINTR));
- if (ret == -1)
- {
- ndbout_c("%s Failed to read using O_DIRECT, disabling",
- theFileName.c_str());
- goto reopen;
- }
-
- if(lseek(theFd, 0, SEEK_SET) != 0)
- {
- return errno;
- }
-
- if ((flags & FsOpenReq::OM_CHECK_SIZE) == 0)
- {
- struct stat buf;
- if ((fstat(theFd, &buf) == -1))
- {
- return errno;
- }
- else if ((buf.st_size % GLOBAL_PAGE_SIZE) != 0)
- {
- ndbout_c("%s filesize not a multiple of %d, disabling O_DIRECT",
- theFileName.c_str(), GLOBAL_PAGE_SIZE);
- goto reopen;
- }
- }
-
- return 0;
-
-reopen:
- close(theFd);
- new_flags &= ~O_DIRECT;
- theFd = ::open(theFileName.c_str(), new_flags, mode);
- if (theFd == -1)
- return errno;
-#endif
- return 0;
-}
-
-void AsyncFile::openReq(Request* request)
-{
- m_auto_sync_freq = 0;
- m_write_wo_sync = 0;
- m_open_flags = request->par.open.flags;
-
- // for open.flags, see signal FSOPENREQ
-#ifdef NDB_WIN32
- DWORD dwCreationDisposition;
- DWORD dwDesiredAccess = 0;
- DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
- DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_NO_BUFFERING;
- Uint32 flags = request->par.open.flags;
-
- // Convert file open flags from Solaris to Windows
- if ((flags & FsOpenReq::OM_CREATE) && (flags & FsOpenReq::OM_TRUNCATE)){
- dwCreationDisposition = CREATE_ALWAYS;
- } else if (flags & FsOpenReq::OM_TRUNCATE){
- dwCreationDisposition = TRUNCATE_EXISTING;
- } else if (flags & FsOpenReq::OM_CREATE){
- dwCreationDisposition = CREATE_NEW;
- } else {
- dwCreationDisposition = OPEN_EXISTING;
- }
-
- switch(flags & 3){
- case FsOpenReq::OM_READONLY:
- dwDesiredAccess = GENERIC_READ;
- break;
- case FsOpenReq::OM_WRITEONLY:
- dwDesiredAccess = GENERIC_WRITE;
- break;
- case FsOpenReq::OM_READWRITE:
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
- break;
- default:
- request->error = 1000;
- break;
- return;
- }
-
- hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
- 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
-
- if(INVALID_HANDLE_VALUE == hFile) {
- request->error = GetLastError();
- if(((ERROR_PATH_NOT_FOUND == request->error) || (ERROR_INVALID_NAME == request->error))
- && (flags & FsOpenReq::OM_CREATE)) {
- createDirectories();
- hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
- 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
-
- if(INVALID_HANDLE_VALUE == hFile)
- request->error = GetLastError();
- else
- request->error = 0;
-
- return;
- }
- }
- else {
- request->error = 0;
- return;
- }
-#else
- Uint32 flags = request->par.open.flags;
- int new_flags = 0;
-
- // Convert file open flags from Solaris to Liux
- if (flags & FsOpenReq::OM_CREATE)
- {
- new_flags |= O_CREAT;
- }
-
- if (flags & FsOpenReq::OM_TRUNCATE){
-#if 0
- if(Global_unlinkO_CREAT){
- unlink(theFileName.c_str());
- } else
-#endif
- new_flags |= O_TRUNC;
- }
-
- if (flags & FsOpenReq::OM_AUTOSYNC)
- {
- m_auto_sync_freq = request->par.open.auto_sync_size;
- }
-
- if (flags & FsOpenReq::OM_APPEND){
- new_flags |= O_APPEND;
- }
-
- if (flags & FsOpenReq::OM_DIRECT)
-#ifdef O_DIRECT
- {
- new_flags |= O_DIRECT;
- }
-#endif
-
- if ((flags & FsOpenReq::OM_SYNC) && ! (flags & FsOpenReq::OM_INIT))
- {
-#ifdef O_SYNC
- new_flags |= O_SYNC;
-#endif
- }
-
- const char * rw = "";
- switch(flags & 0x3){
- case FsOpenReq::OM_READONLY:
- rw = "r";
- new_flags |= O_RDONLY;
- break;
- case FsOpenReq::OM_WRITEONLY:
- rw = "w";
- new_flags |= O_WRONLY;
- break;
- case FsOpenReq::OM_READWRITE:
- rw = "rw";
- new_flags |= O_RDWR;
- break;
- default:
- request->error = 1000;
- break;
- return;
- }
-
- // allow for user to choose any permissionsa with umask
- const int mode = S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP |
- S_IROTH | S_IWOTH;
- if (flags & FsOpenReq::OM_CREATE_IF_NONE)
- {
- Uint32 tmp_flags = new_flags;
-#ifdef O_DIRECT
- tmp_flags &= ~O_DIRECT;
-#endif
- if ((theFd = ::open(theFileName.c_str(), tmp_flags, mode)) != -1)
- {
- close(theFd);
- request->error = FsRef::fsErrFileExists;
- return;
- }
- new_flags |= O_CREAT;
- }
-
-no_odirect:
- if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode)))
- {
- PRINT_ERRORANDFLAGS(new_flags);
- if ((errno == ENOENT) && (new_flags & O_CREAT))
- {
- createDirectories();
- if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode)))
- {
-#ifdef O_DIRECT
- if (new_flags & O_DIRECT)
- {
- new_flags &= ~O_DIRECT;
- goto no_odirect;
- }
-#endif
- PRINT_ERRORANDFLAGS(new_flags);
- request->error = errno;
- return;
- }
- }
-#ifdef O_DIRECT
- else if (new_flags & O_DIRECT)
- {
- new_flags &= ~O_DIRECT;
- goto no_odirect;
- }
-#endif
- else
- {
- request->error = errno;
- return;
- }
- }
-
- if (flags & FsOpenReq::OM_CHECK_SIZE)
- {
- struct stat buf;
- if ((fstat(theFd, &buf) == -1))
- {
- request->error = errno;
- }
- else if((Uint64)buf.st_size != request->par.open.file_size)
- {
- request->error = FsRef::fsErrInvalidFileSize;
- }
- if (request->error)
- return;
- }
-
- if (flags & FsOpenReq::OM_INIT)
- {
- off_t off = 0;
- const off_t sz = request->par.open.file_size;
- Uint32 tmp[sizeof(SignalHeader)+25];
- Signal * signal = (Signal*)(&tmp[0]);
- FsReadWriteReq* req = (FsReadWriteReq*)signal->getDataPtrSend();
-
- Uint32 index = 0;
- Uint32 block = refToBlock(request->theUserReference);
-
-#ifdef HAVE_XFS_XFS_H
- if(platform_test_xfs_fd(theFd))
- {
- ndbout_c("Using xfsctl(XFS_IOC_RESVSP64) to allocate disk space");
- xfs_flock64_t fl;
- fl.l_whence= 0;
- fl.l_start= 0;
- fl.l_len= (off64_t)sz;
- if(xfsctl(NULL, theFd, XFS_IOC_RESVSP64, &fl) < 0)
- ndbout_c("failed to optimally allocate disk space");
- }
-#endif
-#ifdef HAVE_POSIX_FALLOCATE
- posix_fallocate(theFd, 0, sz);
-#endif
-
- while(off < sz)
- {
- req->filePointer = 0; // DATA 0
- req->userPointer = request->theUserPointer; // DATA 2
- req->numberOfPages = 1; // DATA 5
- req->varIndex = index++;
- req->data.pageData[0] = m_page_ptr.i;
-
- m_fs.EXECUTE_DIRECT(block, GSN_FSWRITEREQ, signal,
- FsReadWriteReq::FixedLength + 1);
- retry:
- Uint32 size = request->par.open.page_size;
- char* buf = (char*)m_page_ptr.p;
- while(size > 0){
- const int n = write(theFd, buf, size);
- if(n == -1 && errno == EINTR)
- {
- continue;
- }
- if(n == -1 || n == 0)
- {
- break;
- }
- size -= n;
- buf += n;
- }
- if(size != 0)
- {
- int err = errno;
-#ifdef O_DIRECT
- if ((new_flags & O_DIRECT) && off == 0)
- {
- ndbout_c("error on first write(%d), disable O_DIRECT", err);
- new_flags &= ~O_DIRECT;
- close(theFd);
- theFd = ::open(theFileName.c_str(), new_flags, mode);
- if (theFd != -1)
- goto retry;
- }
-#endif
- close(theFd);
- unlink(theFileName.c_str());
- request->error = err;
- return;
- }
- off += request->par.open.page_size;
- }
- if(lseek(theFd, 0, SEEK_SET) != 0)
- request->error = errno;
- }
- else if (flags & FsOpenReq::OM_DIRECT)
- {
-#ifdef O_DIRECT
- if (flags & (FsOpenReq::OM_TRUNCATE | FsOpenReq::OM_CREATE))
- {
- request->error = check_odirect_write(flags, new_flags, mode);
- }
- else
- {
- request->error = check_odirect_read(flags, new_flags, mode);
- }
-
- if (request->error)
- return;
-#endif
- }
-#ifdef VM_TRACE
- if (flags & FsOpenReq::OM_DIRECT)
- {
-#ifdef O_DIRECT
- ndbout_c("%s %s O_DIRECT: %d",
- theFileName.c_str(), rw,
- !!(new_flags & O_DIRECT));
-#else
- ndbout_c("%s %s O_DIRECT: 0",
- theFileName.c_str(), rw);
-#endif
- }
-#endif
- if ((flags & FsOpenReq::OM_SYNC) && (flags & FsOpenReq::OM_INIT))
- {
-#ifdef O_SYNC
- /**
- * reopen file with O_SYNC
- */
- close(theFd);
- new_flags &= ~(O_CREAT | O_TRUNC);
- new_flags |= O_SYNC;
- theFd = ::open(theFileName.c_str(), new_flags, mode);
- if (theFd == -1)
- {
- request->error = errno;
- }
-#endif
- }
-#endif
-}
-
-int
-AsyncFile::readBuffer(Request* req, char * buf, size_t size, off_t offset){
- int return_value;
- req->par.readWrite.pages[0].size = 0;
-#ifdef NDB_WIN32
- DWORD dwSFP = SetFilePointer(hFile, offset, 0, FILE_BEGIN);
- if(dwSFP != offset) {
- return GetLastError();
- }
-#elif ! defined(HAVE_PREAD)
- off_t seek_val;
- while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
- && errno == EINTR);
- if(seek_val == (off_t)-1)
- {
- return errno;
- }
-#endif
-
- while (size > 0) {
- size_t bytes_read = 0;
-
-#ifdef NDB_WIN32
- DWORD dwBytesRead;
- BOOL bRead = ReadFile(hFile,
- buf,
- size,
- &dwBytesRead,
- 0);
- if(!bRead){
- return GetLastError();
- }
- bytes_read = dwBytesRead;
-#elif ! defined(HAVE_PREAD)
- return_value = ::read(theFd, buf, size);
-#else // UNIX
- return_value = ::pread(theFd, buf, size, offset);
-#endif
-#ifndef NDB_WIN32
- if (return_value == -1 && errno == EINTR) {
- DEBUG(ndbout_c("EINTR in read"));
- continue;
- } else if (return_value == -1){
- return errno;
- } else {
- bytes_read = return_value;
- }
-#endif
-
- req->par.readWrite.pages[0].size += bytes_read;
- if(bytes_read == 0){
- if(req->action == Request::readPartial)
- {
- return 0;
- }
- DEBUG(ndbout_c("Read underflow %d %d\n %x\n%d %d",
- size, offset, buf, bytes_read, return_value));
- return ERR_ReadUnderflow;
- }
-
- if(bytes_read != size){
- DEBUG(ndbout_c("Warning partial read %d != %d",
- bytes_read, size));
- }
-
- buf += bytes_read;
- size -= bytes_read;
- offset += bytes_read;
- }
- return 0;
-}
-
-void
-AsyncFile::readReq( Request * request)
-{
- for(int i = 0; i < request->par.readWrite.numberOfPages ; i++) {
- off_t offset = request->par.readWrite.pages[i].offset;
- size_t size = request->par.readWrite.pages[i].size;
- char * buf = request->par.readWrite.pages[i].buf;
-
- int err = readBuffer(request, buf, size, offset);
- if(err != 0){
- request->error = err;
- return;
- }
- }
-}
-
-void
-AsyncFile::readvReq( Request * request)
-{
-#if ! defined(HAVE_PREAD)
- readReq(request);
- return;
-#elif defined NDB_WIN32
- // ReadFileScatter?
- readReq(request);
- return;
-#else
- int return_value;
- int length = 0;
- struct iovec iov[20]; // the parameter in the signal restricts this to 20 deep
- for(int i=0; i < request->par.readWrite.numberOfPages ; i++) {
- iov[i].iov_base= request->par.readWrite.pages[i].buf;
- iov[i].iov_len= request->par.readWrite.pages[i].size;
- length = length + iov[i].iov_len;
- }
- lseek( theFd, request->par.readWrite.pages[0].offset, SEEK_SET );
- return_value = ::readv(theFd, iov, request->par.readWrite.numberOfPages);
- if (return_value == -1) {
- request->error = errno;
- return;
- } else if (return_value != length) {
- request->error = 1011;
- return;
- }
-#endif
-}
-
-int
-AsyncFile::extendfile(Request* request) {
-#if ! defined(HAVE_PWRITE)
- // Find max size of this file in this request
- int maxOffset = 0;
- int maxSize = 0;
- for(int i=0; i < request->par.readWrite.numberOfPages ; i++) {
- if (request->par.readWrite.pages[i].offset > maxOffset) {
- maxOffset = request->par.readWrite.pages[i].offset;
- maxSize = request->par.readWrite.pages[i].size;
- }
- }
- DEBUG(ndbout_c("extendfile: maxOffset=%d, size=%d", maxOffset, maxSize));
-
- // Allocate a buffer and fill it with zeros
- void* pbuf = ndbd_malloc(maxSize);
- memset(pbuf, 0, maxSize);
- for (int p = 0; p <= maxOffset; p = p + maxSize) {
- int return_value;
- return_value = lseek(theFd,
- p,
- SEEK_SET);
- if((return_value == -1 ) || (return_value != p)) {
- ndbd_free(pbuf,maxSize);
- return -1;
- }
- return_value = ::write(theFd,
- pbuf,
- maxSize);
- if ((return_value == -1) || (return_value != maxSize)) {
- ndbd_free(pbuf,maxSize);
- return -1;
- }
- }
- ndbd_free(pbuf,maxSize);
-
- DEBUG(ndbout_c("extendfile: \"%s\" OK!", theFileName.c_str()));
- return 0;
-#else
- request = request;
- DEBUG(ndbout_c("no pwrite"));
- abort();
- return -1;
-#endif
-}
-
-void
-AsyncFile::writeReq( Request * request)
-{
- int page_num = 0;
- bool write_not_complete = true;
-
- while(write_not_complete) {
- int totsize = 0;
- off_t offset = request->par.readWrite.pages[page_num].offset;
- char* bufptr = theWriteBuffer;
-
- write_not_complete = false;
- if (request->par.readWrite.numberOfPages > 1) {
- off_t page_offset = offset;
-
- // Multiple page write, copy to buffer for one write
- for(int i=page_num; i < request->par.readWrite.numberOfPages; i++) {
- memcpy(bufptr,
- request->par.readWrite.pages[i].buf,
- request->par.readWrite.pages[i].size);
- bufptr += request->par.readWrite.pages[i].size;
- totsize += request->par.readWrite.pages[i].size;
- if (((i + 1) < request->par.readWrite.numberOfPages)) {
- // There are more pages to write
- // Check that offsets are consequtive
- off_t tmp = page_offset + request->par.readWrite.pages[i].size;
- if (tmp != request->par.readWrite.pages[i+1].offset) {
- // Next page is not aligned with previous, not allowed
- DEBUG(ndbout_c("Page offsets are not aligned"));
- request->error = EINVAL;
- return;
- }
- if ((unsigned)(totsize + request->par.readWrite.pages[i+1].size) > (unsigned)theWriteBufferSize) {
- // We are not finished and the buffer is full
- write_not_complete = true;
- // Start again with next page
- page_num = i + 1;
- break;
- }
- }
- page_offset += request->par.readWrite.pages[i].size;
- }
- bufptr = theWriteBuffer;
- } else {
- // One page write, write page directly
- bufptr = request->par.readWrite.pages[0].buf;
- totsize = request->par.readWrite.pages[0].size;
- }
- int err = writeBuffer(bufptr, totsize, offset);
- if(err != 0){
- request->error = err;
- return;
- }
- } // while(write_not_complete)
-
- if(m_auto_sync_freq && m_write_wo_sync > m_auto_sync_freq){
- syncReq(request);
- }
-}
-
-int
-AsyncFile::writeBuffer(const char * buf, size_t size, off_t offset,
- size_t chunk_size)
-{
- size_t bytes_to_write = chunk_size;
- int return_value;
-
- m_write_wo_sync += size;
-
-#ifdef NDB_WIN32
- DWORD dwSFP = SetFilePointer(hFile, offset, 0, FILE_BEGIN);
- if(dwSFP != offset) {
- return GetLastError();
- }
-#elif ! defined(HAVE_PWRITE)
- off_t seek_val;
- while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
- && errno == EINTR);
- if(seek_val == (off_t)-1)
- {
- return errno;
- }
-#endif
-
- while (size > 0) {
- if (size < bytes_to_write){
- // We are at the last chunk
- bytes_to_write = size;
- }
- size_t bytes_written = 0;
-
-#ifdef NDB_WIN32
- DWORD dwWritten;
- BOOL bWrite = WriteFile(hFile, buf, bytes_to_write, &dwWritten, 0);
- if(!bWrite) {
- return GetLastError();
- }
- bytes_written = dwWritten;
- if (bytes_written != bytes_to_write) {
- DEBUG(ndbout_c("Warning partial write %d != %d", bytes_written, bytes_to_write));
- }
-
-#elif ! defined(HAVE_PWRITE)
- return_value = ::write(theFd, buf, bytes_to_write);
-#else // UNIX
- return_value = ::pwrite(theFd, buf, bytes_to_write, offset);
-#endif
-#ifndef NDB_WIN32
- if (return_value == -1 && errno == EINTR) {
- bytes_written = 0;
- DEBUG(ndbout_c("EINTR in write"));
- } else if (return_value == -1){
- return errno;
- } else {
- bytes_written = return_value;
-
- if(bytes_written == 0){
- DEBUG(ndbout_c("no bytes written"));
- abort();
- }
-
- if(bytes_written != bytes_to_write){
- DEBUG(ndbout_c("Warning partial write %d != %d",
- bytes_written, bytes_to_write));
- }
- }
-#endif
-
- buf += bytes_written;
- size -= bytes_written;
- offset += bytes_written;
- }
- return 0;
-}
-
-void
-AsyncFile::writevReq( Request * request)
-{
- // WriteFileGather on WIN32?
- writeReq(request);
-}
-
-
-void
-AsyncFile::closeReq(Request * request)
-{
- if (m_open_flags & (
- FsOpenReq::OM_WRITEONLY |
- FsOpenReq::OM_READWRITE |
- FsOpenReq::OM_APPEND )) {
- syncReq(request);
- }
-#ifdef NDB_WIN32
- if(!CloseHandle(hFile)) {
- request->error = GetLastError();
- }
- hFile = INVALID_HANDLE_VALUE;
-#else
- if (-1 == ::close(theFd)) {
-#ifndef DBUG_OFF
- if (theFd == -1) {
- DEBUG(ndbout_c("close on fd = -1"));
- abort();
- }
-#endif
- request->error = errno;
- }
- theFd = -1;
-#endif
-}
-
-bool AsyncFile::isOpen(){
-#ifdef NDB_WIN32
- return (hFile != INVALID_HANDLE_VALUE);
-#else
- return (theFd != -1);
-#endif
-}
-
-
-void
-AsyncFile::syncReq(Request * request)
-{
- if(m_auto_sync_freq && m_write_wo_sync == 0){
- return;
- }
-#ifdef NDB_WIN32
- if(!FlushFileBuffers(hFile)) {
- request->error = GetLastError();
- return;
- }
-#else
- if (-1 == ::fsync(theFd)){
- request->error = errno;
- return;
- }
-#endif
- m_write_wo_sync = 0;
-}
-
-void
-AsyncFile::appendReq(Request * request){
-
- const char * buf = request->par.append.buf;
- Uint32 size = request->par.append.size;
-
- m_write_wo_sync += size;
-
-#ifdef NDB_WIN32
- DWORD dwWritten = 0;
- while(size > 0){
- if(!WriteFile(hFile, buf, size, &dwWritten, 0)){
- request->error = GetLastError();
- return ;
- }
-
- buf += dwWritten;
- size -= dwWritten;
- }
-#else
- while(size > 0){
- const int n = write(theFd, buf, size);
- if(n == -1 && errno == EINTR){
- continue;
- }
- if(n == -1){
- request->error = errno;
- return;
- }
- if(n == 0){
- DEBUG(ndbout_c("append with n=0"));
- abort();
- }
- size -= n;
- buf += n;
- }
-#endif
-
- if(m_auto_sync_freq && m_write_wo_sync > m_auto_sync_freq){
- syncReq(request);
- }
-}
-
-void
-AsyncFile::removeReq(Request * request)
-{
-#ifdef NDB_WIN32
- if(!DeleteFile(theFileName.c_str())) {
- request->error = GetLastError();
- }
-#else
- if (-1 == ::remove(theFileName.c_str())) {
- request->error = errno;
-
- }
-#endif
-}
-
-void
-AsyncFile::rmrfReq(Request * request, char * path, bool removePath){
- Uint32 path_len = strlen(path);
- Uint32 path_max_copy = PATH_MAX - path_len;
- char* path_add = &path[path_len];
-#ifndef NDB_WIN32
- if(!request->par.rmrf.directory){
- // Remove file
- if(unlink((const char *)path) != 0 && errno != ENOENT)
- request->error = errno;
- return;
- }
- // Remove directory
- DIR* dirp = opendir((const char *)path);
- if(dirp == 0){
- if(errno != ENOENT)
- request->error = errno;
- return;
- }
- struct dirent * dp;
- while ((dp = readdir(dirp)) != NULL){
- if ((strcmp(".", dp->d_name) != 0) && (strcmp("..", dp->d_name) != 0)) {
- BaseString::snprintf(path_add, (size_t)path_max_copy, "%s%s",
- DIR_SEPARATOR, dp->d_name);
- if(remove((const char*)path) == 0){
- path[path_len] = 0;
- continue;
- }
-
- rmrfReq(request, path, true);
- path[path_len] = 0;
- if(request->error != 0){
- closedir(dirp);
- return;
- }
- }
- }
- closedir(dirp);
- if(removePath && rmdir((const char *)path) != 0){
- request->error = errno;
- }
- return;
-#else
-
- if(!request->par.rmrf.directory){
- // Remove file
- if(!DeleteFile(path)){
- DWORD dwError = GetLastError();
- if(dwError!=ERROR_FILE_NOT_FOUND)
- request->error = dwError;
- }
- return;
- }
-
- strcat(path, "\\*");
- WIN32_FIND_DATA ffd;
- HANDLE hFindFile = FindFirstFile(path, &ffd);
- path[path_len] = 0;
- if(INVALID_HANDLE_VALUE==hFindFile){
- DWORD dwError = GetLastError();
- if(dwError!=ERROR_PATH_NOT_FOUND)
- request->error = dwError;
- return;
- }
-
- do {
- if(0!=strcmp(".", ffd.cFileName) && 0!=strcmp("..", ffd.cFileName)){
- strcat(path, "\\");
- strcat(path, ffd.cFileName);
- if(DeleteFile(path)) {
- path[path_len] = 0;
- continue;
- }//if
-
- rmrfReq(request, path, true);
- path[path_len] = 0;
- if(request->error != 0){
- FindClose(hFindFile);
- return;
- }
- }
- } while(FindNextFile(hFindFile, &ffd));
-
- FindClose(hFindFile);
-
- if(removePath && !RemoveDirectory(path))
- request->error = GetLastError();
-
-#endif
-}
-
-void AsyncFile::endReq()
-{
- // Thread is ended with return
- if (theWriteBufferUnaligned)
- ndbd_free(theWriteBufferUnaligned, theWriteBufferSize);
-}
-
-
-void AsyncFile::createDirectories()
-{
- char* tmp;
- const char * name = theFileName.c_str();
- const char * base = theFileName.get_base_name();
- while((tmp = (char *)strstr(base, DIR_SEPARATOR)))
- {
- char t = tmp[0];
- tmp[0] = 0;
-#ifdef NDB_WIN32
- CreateDirectory(name, 0);
-#else
- mkdir(name, S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
-#endif
- tmp[0] = t;
- base = tmp + sizeof(DIR_SEPARATOR);
- }
-}
-
-#ifdef DEBUG_ASYNCFILE
-void printErrorAndFlags(Uint32 used_flags) {
- char buf[255];
- sprintf(buf, "PEAF: errno=%d \"", errno);
-
- switch(errno) {
- case EACCES:
- strcat(buf, "EACCES");
- break;
- case EDQUOT:
- strcat(buf, "EDQUOT");
- break;
- case EEXIST :
- strcat(buf, "EEXIST");
- break;
- case EINTR :
- strcat(buf, "EINTR");
- break;
- case EFAULT :
- strcat(buf, "EFAULT");
- break;
- case EIO :
- strcat(buf, "EIO");
- break;
- case EISDIR :
- strcat(buf, "EISDIR");
- break;
- case ELOOP :
- strcat(buf, "ELOOP");
- break;
- case EMFILE :
- strcat(buf, "EMFILE");
- break;
- case ENFILE :
- strcat(buf, "ENFILE");
- break;
- case ENOENT :
- strcat(buf, "ENOENT ");
- break;
- case ENOSPC :
- strcat(buf, "ENOSPC");
- break;
- case ENOTDIR :
- strcat(buf, "ENOTDIR");
- break;
- case ENXIO :
- strcat(buf, "ENXIO");
- break;
- case EOPNOTSUPP:
- strcat(buf, "EOPNOTSUPP");
- break;
- case EMULTIHOP :
- strcat(buf, "EMULTIHOP");
- break;
- case ENOLINK :
- strcat(buf, "ENOLINK");
- break;
- case ENOSR :
- strcat(buf, "ENOSR");
- break;
- case EOVERFLOW :
- strcat(buf, "EOVERFLOW");
- break;
- case EROFS :
- strcat(buf, "EROFS");
- break;
- case EAGAIN :
- strcat(buf, "EAGAIN");
- break;
- case EINVAL :
- strcat(buf, "EINVAL");
- break;
- case ENOMEM :
- strcat(buf, "ENOMEM");
- break;
- case ETXTBSY :
- strcat(buf, "ETXTBSY");
- break;
- case ENAMETOOLONG:
- strcat(buf, "ENAMETOOLONG");
- break;
- case EBADF:
- strcat(buf, "EBADF");
- break;
- case ESPIPE:
- strcat(buf, "ESPIPE");
- break;
- case ESTALE:
- strcat(buf, "ESTALE");
- break;
- default:
- strcat(buf, "EOTHER");
- break;
- }
- strcat(buf, "\" ");
- strcat(buf, " flags: ");
- switch(used_flags & 3){
- case O_RDONLY:
- strcat(buf, "O_RDONLY, ");
- break;
- case O_WRONLY:
- strcat(buf, "O_WRONLY, ");
- break;
- case O_RDWR:
- strcat(buf, "O_RDWR, ");
- break;
- default:
- strcat(buf, "Unknown!!, ");
- }
-
- if((used_flags & O_APPEND)==O_APPEND)
- strcat(buf, "O_APPEND, ");
- if((used_flags & O_CREAT)==O_CREAT)
- strcat(buf, "O_CREAT, ");
- if((used_flags & O_EXCL)==O_EXCL)
- strcat(buf, "O_EXCL, ");
- if((used_flags & O_NOCTTY) == O_NOCTTY)
- strcat(buf, "O_NOCTTY, ");
- if((used_flags & O_NONBLOCK)==O_NONBLOCK)
- strcat(buf, "O_NONBLOCK, ");
- if((used_flags & O_TRUNC)==O_TRUNC)
- strcat(buf, "O_TRUNC, ");
- if((used_flags & O_DSYNC)==O_DSYNC)
- strcat(buf, "O_DSYNC, ");
- if((used_flags & O_NDELAY)==O_NDELAY)
- strcat(buf, "O_NDELAY, ");
- if((used_flags & O_RSYNC)==O_RSYNC)
- strcat(buf, "O_RSYNC, ");
-#ifdef O_SYNC
- if((used_flags & O_SYNC)==O_SYNC)
- strcat(buf, "O_SYNC, ");
-#endif
- DEBUG(ndbout_c(buf));
-
-}
-#endif
-
-NdbOut&
-operator<<(NdbOut& out, const Request& req)
-{
- out << "[ Request: file: " << hex << req.file
- << " userRef: " << hex << req.theUserReference
- << " userData: " << dec << req.theUserPointer
- << " theFilePointer: " << req.theFilePointer
- << " action: ";
- switch(req.action){
- case Request::open:
- out << "open";
- break;
- case Request::close:
- out << "close";
- break;
- case Request::closeRemove:
- out << "closeRemove";
- break;
- case Request::read: // Allways leave readv directly after
- out << "read";
- break;
- case Request::readv:
- out << "readv";
- break;
- case Request::write:// Allways leave writev directly after
- out << "write";
- break;
- case Request::writev:
- out << "writev";
- break;
- case Request::writeSync:// Allways leave writevSync directly after
- out << "writeSync";
- break;
- // writeSync because SimblockAsyncFileSystem depends on it
- case Request::writevSync:
- out << "writevSync";
- break;
- case Request::sync:
- out << "sync";
- break;
- case Request::end:
- out << "end";
- break;
- case Request::append:
- out << "append";
- break;
- case Request::rmrf:
- out << "rmrf";
- break;
- default:
- out << (Uint32)req.action;
- break;
- }
- out << " ]";
- return out;
-}
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp
deleted file mode 100644
index 71b6b34e2c0..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef AsyncFile_H
-#define AsyncFile_H
-
-//===========================================================================
-//
-// .DESCRIPTION
-// Asynchronous file, All actions are executed concurrently with other
-// activity of the process.
-// Because all action are performed in a seperated thread the result of
-// of a action is send back tru a memory channel.
-// For the asyncronise notivication of a finished request all the calls
-// have a request as paramater, the user can use the userData pointer
-// to add information it needs when the request is send back.
-//
-//
-// .TYPICAL USE:
-// Writing or reading data to/from disk concurrently to other activities.
-//
-//===========================================================================
-//=============================================================================
-//
-// .PUBLIC
-//
-//=============================================================================
-///////////////////////////////////////////////////////////////////////////////
-//
-// AsyncFile( );
-// Description:
-// Initialisation of the class.
-// Parameters:
-// -
-///////////////////////////////////////////////////////////////////////////////
-//
-// ~AsyncFile( );
-// Description:
-// Tell the thread to stop and wait for it to return
-// Parameters:
-// -
-///////////////////////////////////////////////////////////////////////////////
-//
-// doStart( );
-// Description:
-// Spawns the new thread.
-// Parameters:
-// Base path of filesystem
-//
-///////////////////////////////////////////////////////////////////////////////
-//
-// void execute(Request *request);
-// Description:
-// performens the requered action.
-// Parameters:
-// request: request to be called when open is finished.
-// action= open|close|read|write|sync
-// if action is open then:
-// par.open.flags= UNIX open flags, see man open
-// par.open.name= name of the file to open
-// if action is read or write then:
-// par.readWrite.buf= user provided buffer to read/write
-// the data from/to
-// par.readWrite.size= how many bytes must be read/written
-// par.readWrite.offset= absolute offset in file in bytes
-// return:
-// return values are stored in the request error field:
-// error= return state of the action, UNIX error see man open/errno
-// userData= is untouched can be used be user.
-//
-///////////////////////////////////////////////////////////////////////////////
-//
-// void reportTo( MemoryChannel<Request> *reportTo );
-// Description:
-// set the channel where the file must report the result of the
-// actions back to.
-// Parameters:
-// reportTo: the memory channel to use use MemoryChannelMultipleWriter
-// if more
-// than one file uses this channel to report back.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include <kernel_types.h>
-#include "MemoryChannel.hpp"
-#include "Filename.hpp"
-
-const int ERR_ReadUnderflow = 1000;
-
-const int WRITECHUNK = 262144;
-
-class AsyncFile;
-
-class Request
-{
-public:
- Request() {}
-
- enum Action {
- open,
- close,
- closeRemove,
- read, // Allways leave readv directly after
- // read because SimblockAsyncFileSystem depends on it
- readv,
- write,// Allways leave writev directly after
- // write because SimblockAsyncFileSystem depends on it
- writev,
- writeSync,// Allways leave writevSync directly after
- // writeSync because SimblockAsyncFileSystem depends on it
- writevSync,
- sync,
- end,
- append,
- append_synch,
- rmrf,
- readPartial
- };
- Action action;
- union {
- struct {
- Uint32 flags;
- Uint32 page_size;
- Uint64 file_size;
- Uint32 auto_sync_size;
- } open;
- struct {
- int numberOfPages;
- struct{
- char *buf;
- size_t size;
- off_t offset;
- } pages[16];
- } readWrite;
- struct {
- const char * buf;
- size_t size;
- } append;
- struct {
- bool directory;
- bool own_directory;
- } rmrf;
- } par;
- int error;
-
- void set(BlockReference userReference,
- Uint32 userPointer,
- Uint16 filePointer);
- BlockReference theUserReference;
- Uint32 theUserPointer;
- Uint16 theFilePointer;
- // Information for open, needed if the first open action fails.
- AsyncFile* file;
- Uint32 theTrace;
-};
-
-NdbOut& operator <<(NdbOut&, const Request&);
-
-inline
-void
-Request::set(BlockReference userReference,
- Uint32 userPointer, Uint16 filePointer)
-{
- theUserReference= userReference;
- theUserPointer= userPointer;
- theFilePointer= filePointer;
-}
-
-class AsyncFile
-{
- friend class Ndbfs;
-public:
- AsyncFile(SimulatedBlock& fs);
- ~AsyncFile();
-
- void reportTo( MemoryChannel<Request> *reportTo );
-
- void execute( Request* request );
-
- void doStart();
- // its a thread so its always running
- void run();
-
- bool isOpen();
-
- Filename theFileName;
- Request *m_current_request, *m_last_request;
-private:
-
- void openReq(Request *request);
- void readReq(Request *request);
- void readvReq(Request *request);
- void writeReq(Request *request);
- void writevReq(Request *request);
-
- void closeReq(Request *request);
- void syncReq(Request *request);
- void removeReq(Request *request);
- void appendReq(Request *request);
- void rmrfReq(Request *request, char * path, bool removePath);
- void endReq();
-
- int readBuffer(Request*, char * buf, size_t size, off_t offset);
- int writeBuffer(const char * buf, size_t size, off_t offset,
- size_t chunk_size = WRITECHUNK);
-
- int extendfile(Request* request);
- void createDirectories();
-
-#ifdef NDB_WIN32
- HANDLE hFile;
-#else
- int theFd;
-#endif
-
- Uint32 m_open_flags; // OM_ flags from request to open file
-
- MemoryChannel<Request> *theReportTo;
- MemoryChannel<Request>* theMemoryChannelPtr;
-
- struct NdbThread* theThreadPtr;
- NdbMutex* theStartMutexPtr;
- NdbCondition* theStartConditionPtr;
- bool theStartFlag;
- int theWriteBufferSize;
- char* theWriteBuffer;
- void* theWriteBufferUnaligned;
-
- size_t m_write_wo_sync; // Writes wo/ sync
- size_t m_auto_sync_freq; // Auto sync freq in bytes
-
- int check_odirect_read(Uint32 flags, int&new_flags, int mode);
- int check_odirect_write(Uint32 flags, int&new_flags, int mode);
-public:
- SimulatedBlock& m_fs;
- Ptr<GlobalPage> m_page_ptr;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp
deleted file mode 100644
index cb7896fb144..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp
+++ /dev/null
@@ -1,695 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//#define TESTDEBUG 1
-
-#include <ndb_global.h>
-
-#include <kernel_types.h>
-#include <Pool.hpp>
-#include "AsyncFile.hpp"
-#include "NdbOut.hpp"
-#include "NdbTick.h"
-#include "NdbThread.h"
-#include "NdbMain.h"
-
-// Test and benchmark functionality of AsyncFile
-// -n Number of files
-// -r Number of simultaneous requests
-// -s Filesize, number of pages
-// -l Number of iterations
-// -remove, remove files after close
-// -reverse, write files in reverse order, start with the last page
-
-#define MAXFILES 255
-#define DEFAULT_NUM_FILES 1
-#define MAXREQUESTS 256
-#define DEFAULT_NUM_REQUESTS 1
-#define MAXFILESIZE 4096
-#define DEFAULT_FILESIZE 2048
-#define FVERSION 0x01000000
-#define PAGESIZE 8192
-
-#define TIMER_START { Uint64 starttick = NdbTick_CurrentMillisecond()
-#define TIMER_PRINT(str, ops) Uint64 stoptick = NdbTick_CurrentMillisecond();\
- Uint64 totaltime = (stoptick-starttick); \
- ndbout << ops << " " << str << \
- " total time " << (int)totaltime << "ms" << endl;\
- char buf[255];\
- sprintf(buf, "%d %s/sec\n",(int)((ops*1000)/totaltime), str);\
- ndbout <<buf << endl;}
-
-static int numberOfFiles = DEFAULT_NUM_FILES;
-static int numberOfRequests = DEFAULT_NUM_REQUESTS;
-static int fileSize = DEFAULT_FILESIZE;
-static int removeFiles = 0;
-static int writeFilesReverse = 0;
-static int numberOfIterations = 1;
-Uint32 FileNameArray[4];
-
-Pool<AsyncFile>* files;
-AsyncFile* openFiles[MAXFILES];
-Pool<Request>* theRequestPool;
-MemoryChannelMultipleWriter<Request>* theReportChannel;
-
-char WritePages[MAXFILES][PAGESIZE];
-char ReadPages[MAXFILES][PAGESIZE];
-
-int readArguments(int argc, const char** argv);
-int openFile(int fileNum);
-int openFileWait();
-int closeFile(int fileNum);
-int closeFileWait();
-int writeFile( int fileNum, int pagenum);
-int writeFileWait();
-int writeSyncFile( int fileNum, int pagenum);
-int writeSyncFileWait();
-int readFile( int fileNum, int pagenum);
-int readFileWait();
-
-
-NDB_COMMAND(aftest, "aftest", "aftest [-n <Number of files>] [-r <Number of simultaneous requests>] [-s <Filesize, number of pages>] [-l <Number of iterations>] [-remove, remove files after close] [-reverse, write files in reverse order, start with the last page]", "Test the AsyncFile class of Ndb", 8192)
-{
- int s, numReq, numOps;
-
- readArguments(argc, argv);
-
- files = new Pool<AsyncFile>(numberOfFiles, 2);
- theRequestPool = new Pool<Request>;
- theReportChannel = new MemoryChannelMultipleWriter<Request>;
-
- ndbout << "AsyncFileTest starting" << endl;
- ndbout << " " << numberOfFiles << " files" << endl;
- ndbout << " " << numberOfRequests << " requests" << endl;
- ndbout << " " << fileSize << " * 8k files" << endl << endl;
- ndbout << " " << numberOfIterations << " iterations" << endl << endl;
-
- NdbThread_SetConcurrencyLevel(numberOfFiles+2);
-
- // initialize data to write to files
- for (int i = 0; i < MAXFILES; i++) {
- for (int j = 0; j < PAGESIZE; j++){
- WritePages[i][j] = (64+i+j)%256;
- }
- // memset(&WritePages[i][0], i+64, PAGESIZE);
- }
-
- // Set file directory and name
- // /T27/F27/NDBFS/S27Pnn.data
- FileNameArray[0] = 27; // T27
- FileNameArray[1] = 27; // F27
- FileNameArray[2] = 27; // S27
- FileNameArray[3] = FVERSION; // Version
-
- for (int l = 0; l < numberOfIterations; l++)
- {
-
- ndbout << "Opening files" << endl;
- // Open files
- for (int f = 0; f < numberOfFiles; f++)
- {
- openFile(f);
-
- }
-
- // Wait for answer
- openFileWait();
-
- ndbout << "Files opened!" << endl<< endl;
-
- // Write to files
- ndbout << "Started writing" << endl;
- TIMER_START;
- s = 0;
- numReq = 0;
- numOps = 0;
- while ( s < fileSize)
- {
- for (int r = 0; r < numberOfRequests; r++)
- {
- for (int f = 0; f < numberOfFiles; f++)
- {
- writeFile(f, s);
- numReq++;
- numOps++;
- }
-
- s++;
- }
-
- while (numReq > 0)
- {
- writeFileWait();
- numReq--;
- }
-
- }
-
- TIMER_PRINT("writes", numOps);
-
-
- ndbout << "Started reading" << endl;
- TIMER_START;
-
- // Read from files
- s = 0;
- numReq = 0;
- numOps = 0;
- while ( s < fileSize)
- {
- for (int r = 0; r < numberOfRequests; r++)
- {
- for (int f = 0; f < numberOfFiles; f++)
- {
- readFile(f, s);
- numReq++;
- numOps++;
- }
-
- s++;
-
- }
-
- while (numReq > 0)
- {
- readFileWait();
- numReq--;
- }
-
- }
- TIMER_PRINT("reads", numOps);
-
- ndbout << "Started writing with sync" << endl;
- TIMER_START;
-
- // Write to files
- s = 0;
- numReq = 0;
- numOps = 0;
- while ( s < fileSize)
- {
- for (int r = 0; r < numberOfRequests; r++)
- {
- for (int f = 0; f < numberOfFiles; f++)
- {
- writeSyncFile(f, s);
- numReq++;
- numOps++;
- }
-
- s++;
- }
-
- while (numReq > 0)
- {
- writeSyncFileWait();
- numReq--;
- }
-
- }
-
- TIMER_PRINT("writeSync", numOps);
-
- // Close files
- ndbout << "Closing files" << endl;
- for (int f = 0; f < numberOfFiles; f++)
- {
- closeFile(f);
-
- }
-
- // Wait for answer
- closeFileWait();
-
- ndbout << "Files closed!" << endl<< endl;
- }
-
- // Deallocate memory
- delete files;
- delete theReportChannel;
- delete theRequestPool;
-
- return 0;
-
-}
-
-
-
-int forward( AsyncFile * file, Request* request )
-{
- file->execute(request);
- ERROR_CHECK 0;
- return 1;
-}
-
-int openFile( int fileNum)
-{
- AsyncFile* file = (AsyncFile *)files->get();
-
- FileNameArray[3] = fileNum | FVERSION;
- file->fileName().set( NDBFS_REF, &FileNameArray[0] );
- ndbout << "openFile: " << file->fileName().c_str() << endl;
-
- if( ERROR_STATE ) {
- ERROR_RESET;
- files->put( file );
- ndbout << "Failed to set filename" << endl;
- return 1;
- }
- file->reportTo(theReportChannel);
-
- Request* request = theRequestPool->get();
- request->action= Request::open;
- request->error= 0;
- request->par.open.flags = 0x302; //O_RDWR | O_CREAT | O_TRUNC ; // 770
- request->set(NDBFS_REF, 0x23456789, fileNum );
- request->file = file;
-
- if (!forward(file,request)) {
- // Something went wrong
- ndbout << "Could not forward open request" << endl;
- theRequestPool->put(request);
- return 1;
- }
- return 0;
-}
-
-int closeFile( int fileNum)
-{
-
- AsyncFile* file = openFiles[fileNum];
-
- Request* request = theRequestPool->get();
- if (removeFiles == 1)
- request->action = Request::closeRemove;
- else
- request->action= Request::close;
-
- request->error= 0;
- request->set(NDBFS_REF, 0x23456789, fileNum );
- request->file = file;
-
- if (!forward(file,request)) {
- // Something went wrong
- ndbout << "Could not forward close request" << endl;
- theRequestPool->put(request);
- return 1;
- }
- return 0;
-}
-
-int writeFile( int fileNum, int pagenum)
-{
- AsyncFile* file = openFiles[fileNum];
-#ifdef TESTDEBUG
- ndbout << "writeFile" << fileNum <<": "<<pagenum<<", " << file->fileName().c_str()<< endl;
-#endif
- Request *request = theRequestPool->get();
- request->action = Request::write;
- request->error = 0;
- request->set(NDBFS_REF, pagenum, fileNum);
- request->file = openFiles[fileNum];
-
- // Write only one page, choose the correct page for each file using fileNum
- request->par.readWrite.pages[0].buf = &WritePages[fileNum][0];
- request->par.readWrite.pages[0].size = PAGESIZE;
- if (writeFilesReverse == 1)
- {
- // write the last page in the files first
- // This is a normal way for the Blocks in Ndb to write to a file
- request->par.readWrite.pages[0].offset = (fileSize - pagenum - 1) * PAGESIZE;
- }
- else
- {
- request->par.readWrite.pages[0].offset = pagenum * PAGESIZE;
- }
- request->par.readWrite.numberOfPages = 1;
-
- if (!forward(file,request)) {
- // Something went wrong
- ndbout << "Could not forward write request" << endl;
- theRequestPool->put(request);
- return 1;
- }
- return 0;
-
-}
-
-int writeSyncFile( int fileNum, int pagenum)
-{
- AsyncFile* file = openFiles[fileNum];
-#ifdef TESTDEBUG
- ndbout << "writeFile" << fileNum <<": "<<pagenum<<", " << file->fileName().c_str() << endl;
-#endif
- Request *request = theRequestPool->get();
- request->action = Request::writeSync;
- request->error = 0;
- request->set(NDBFS_REF, pagenum, fileNum);
- request->file = openFiles[fileNum];
-
- // Write only one page, choose the correct page for each file using fileNum
- request->par.readWrite.pages[0].buf = &WritePages[fileNum][0];
- request->par.readWrite.pages[0].size = PAGESIZE;
- request->par.readWrite.pages[0].offset = pagenum * PAGESIZE;
- request->par.readWrite.numberOfPages = 1;
-
- if (!forward(file,request)) {
- // Something went wrong
- ndbout << "Could not forward write request" << endl;
- theRequestPool->put(request);
- return 1;
- }
- return 0;
-
-}
-
-int readFile( int fileNum, int pagenum)
-{
- AsyncFile* file = openFiles[fileNum];
-#ifdef TESTDEBUG
- ndbout << "readFile" << fileNum <<": "<<pagenum<<", " << file->fileName().c_str() << endl;
-#endif
- Request *request = theRequestPool->get();
- request->action = Request::read;
- request->error = 0;
- request->set(NDBFS_REF, pagenum, fileNum);
- request->file = openFiles[fileNum];
-
- // Read only one page, choose the correct page for each file using fileNum
- request->par.readWrite.pages[0].buf = &ReadPages[fileNum][0];
- request->par.readWrite.pages[0].size = PAGESIZE;
- request->par.readWrite.pages[0].offset = pagenum * PAGESIZE;
- request->par.readWrite.numberOfPages = 1;
-
- if (!forward(file,request)) {
- // Something went wrong
- ndbout << "Could not forward read request" << endl;
- theRequestPool->put(request);
- return 1;
- }
- return 0;
-
-}
-
-int openFileWait()
-{
- int openedFiles = 0;
- while (openedFiles < numberOfFiles)
- {
- Request* request = theReportChannel->readChannel();
- if (request)
- {
- if (request->action == Request::open)
- {
- if (request->error ==0)
- {
-#ifdef TESTDEBUG
- ndbout << "Opened file " << request->file->fileName().c_str() << endl;
-#endif
- openFiles[request->theFilePointer] = request->file;
- }
- else
- {
- ndbout << "error while opening file" << endl;
- exit(1);
- }
- theRequestPool->put(request);
- openedFiles++;
- }
- else
- {
- ndbout << "Unexpected request received" << endl;
- }
- }
- else
- {
- ndbout << "Nothing read from theReportChannel" << endl;
- }
- }
- return 0;
-}
-
-int closeFileWait()
-{
- int closedFiles = 0;
- while (closedFiles < numberOfFiles)
- {
- Request* request = theReportChannel->readChannel();
- if (request)
- {
- if (request->action == Request::close || request->action == Request::closeRemove)
- {
- if (request->error ==0)
- {
-#ifdef TESTDEBUG
- ndbout << "Closed file " << request->file->fileName().c_str() << endl;
-#endif
- openFiles[request->theFilePointer] = NULL;
- files->put(request->file);
- }
- else
- {
- ndbout << "error while closing file" << endl;
- exit(1);
- }
- theRequestPool->put(request);
- closedFiles++;
- }
- else
- {
- ndbout << "Unexpected request received" << endl;
- }
- }
- else
- {
- ndbout << "Nothing read from theReportChannel" << endl;
- }
- }
- return 0;
-}
-
-int writeFileWait()
-{
- Request* request = theReportChannel->readChannel();
- if (request)
- {
- if (request->action == Request::write)
- {
- if (request->error == 0)
- {
-#ifdef TESTDEBUG
- ndbout << "writeFileWait"<<request->theFilePointer<<", " << request->theUserPointer<<" "<< request->file->fileName().c_str() << endl;
-#endif
-
- }
- else
- {
- ndbout << "error while writing file, error=" << request->error << endl;
- exit(1);
- }
- theRequestPool->put(request);
- }
- else
- {
- ndbout << "Unexpected request received" << endl;
- }
- }
- else
- {
- ndbout << "Nothing read from theReportChannel" << endl;
- }
- return 0;
-}
-
-int writeSyncFileWait()
-{
- Request* request = theReportChannel->readChannel();
- if (request)
- {
- if (request->action == Request::writeSync)
- {
- if (request->error == 0)
- {
-#ifdef TESTDEBUG
- ndbout << "writeFileWait"<<request->theFilePointer<<", " << request->theUserPointer<<" "<< request->file->fileName().c_str() << endl;
-#endif
-
- }
- else
- {
- ndbout << "error while writing file" << endl;
- exit(1);
- }
- theRequestPool->put(request);
- }
- else
- {
- ndbout << "Unexpected request received" << endl;
- }
- }
- else
- {
- ndbout << "Nothing read from theReportChannel" << endl;
- }
- return 0;
-}
-
-int readFileWait()
-{
- Request* request = theReportChannel->readChannel();
- if (request)
- {
- if (request->action == Request::read)
- {
- if (request->error == 0)
- {
-#ifdef TESTDEBUG
- ndbout << "readFileWait"<<request->theFilePointer<<", " << request->theUserPointer<<" "<< request->file->fileName().c_str() << endl;
-#endif
- if (memcmp(&(ReadPages[request->theFilePointer][0]), &(WritePages[request->theFilePointer][0]), PAGESIZE)!=0)
- {
- ndbout <<"Verification error!" << endl;
- for (int i = 0; i < PAGESIZE; i++ ){
- ndbout <<" Compare Page " << i << " : " << ReadPages[request->theFilePointer][i] <<", " <<WritePages[request->theFilePointer][i] << endl;;
- if( ReadPages[request->theFilePointer][i] !=WritePages[request->theFilePointer][i])
-
- exit(1);
- }
- }
-
- }
- else
- {
- ndbout << "error while reading file" << endl;
- exit(1);
- }
- theRequestPool->put(request);
- }
- else
- {
- ndbout << "Unexpected request received" << endl;
- }
- }
- else
- {
- ndbout << "Nothing read from theReportChannel" << endl;
- }
- return 0;
-}
-
-int readArguments(int argc, const char** argv)
-{
-
- int i = 1;
- while (argc > 1)
- {
- if (strcmp(argv[i], "-n") == 0)
- {
- numberOfFiles = atoi(argv[i+1]);
- if ((numberOfFiles < 1) || (numberOfFiles > MAXFILES))
- {
- ndbout << "Wrong number of files, default = "<<DEFAULT_NUM_FILES << endl;
- numberOfFiles = DEFAULT_NUM_FILES;
- }
- }
- else if (strcmp(argv[i], "-r") == 0)
- {
- numberOfRequests = atoi(argv[i+1]);
- if ((numberOfRequests < 1) || (numberOfRequests > MAXREQUESTS))
- {
- ndbout << "Wrong number of requests, default = "<<DEFAULT_NUM_REQUESTS << endl;
- numberOfRequests = DEFAULT_NUM_REQUESTS;
- }
- }
- else if (strcmp(argv[i], "-s") == 0)
- {
- fileSize = atoi(argv[i+1]);
- if ((fileSize < 1) || (fileSize > MAXFILESIZE))
- {
- ndbout << "Wrong number of 8k pages, default = "<<DEFAULT_FILESIZE << endl;
- fileSize = DEFAULT_FILESIZE;
- }
- }
- else if (strcmp(argv[i], "-l") == 0)
- {
- numberOfIterations = atoi(argv[i+1]);
- if ((numberOfIterations < 1))
- {
- ndbout << "Wrong number of iterations, default = 1" << endl;
- numberOfIterations = 1;
- }
- }
- else if (strcmp(argv[i], "-remove") == 0)
- {
- removeFiles = 1;
- argc++;
- i--;
- }
- else if (strcmp(argv[i], "-reverse") == 0)
- {
- ndbout << "Writing files reversed" << endl;
- writeFilesReverse = 1;
- argc++;
- i--;
- }
-
- argc -= 2;
- i = i + 2;
- }
-
- if ((fileSize % numberOfRequests)!= 0)
- {
- numberOfRequests = numberOfRequests - (fileSize % numberOfRequests);
- ndbout <<"numberOfRequest must be modulo of filesize" << endl;
- ndbout << "New numberOfRequest="<<numberOfRequests<<endl;
- }
- return 0;
-}
-
-
-// Needed for linking...
-
-void ErrorReporter::handleError(ErrorCategory type, int messageID,
- const char* problemData, const char* objRef, NdbShutdownType stype)
-{
-
- ndbout << "ErrorReporter::handleError activated" << endl;
- ndbout << "type= " << type << endl;
- ndbout << "messageID= " << messageID << endl;
- ndbout << "problemData= " << problemData << endl;
- ndbout << "objRef= " << objRef << endl;
-
- exit(1);
-}
-
-void ErrorReporter::handleAssert(const char* message, const char* file, int line)
-{
- ndbout << "ErrorReporter::handleAssert activated" << endl;
- ndbout << "message= " << message << endl;
- ndbout << "file= " << file << endl;
- ndbout << "line= " << line << endl;
- exit(1);
-}
-
-
-GlobalData globalData;
-
-
-Signal::Signal()
-{
-
-}
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/Makefile b/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/Makefile
deleted file mode 100644
index b0356e6da68..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-include .defs.mk
-
-TYPE := kernel
-
-BIN_TARGET := aftest
-BIN_TARGET_ARCHIVES := ndbfs portlib trace signaldataprint
-
-SOURCES = AsyncFileTest.cpp
-
-CFLAGS_AsyncFileTest.cpp = -I../
-
-include $(NDB_TOP)/Epilogue.mk
-
-
-# run basic tests
-run_test :
- $(NDB_TOP)/bin/$(BIN_TARGET)
- $(NDB_TOP)/bin/$(BIN_TARGET) -n 8 -r 8 -l 10 -remove
- $(NDB_TOP)/bin/$(BIN_TARGET) -n 8 -r 8 -l 10 -reverse -remove
- $(NDB_TOP)/bin/$(BIN_TARGET) -n 8 -r 8 -l 10 -s 512 -remove
- $(NDB_TOP)/bin/$(BIN_TARGET) -n 8 -r 4 -l 1000
-
-
-
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp b/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp
deleted file mode 100644
index d0e078a27a7..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "CircularIndex.hpp"
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp b/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp
deleted file mode 100644
index 9f604e64156..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef CircularIndex_H
-#define CircularIndex_H
-
-//===========================================================================
-//
-// .DESCRIPTION
-// Building block for circular buffers. It increment as a normal index.
-// untill it it becomes the maximum size then it becomes zero.
-//
-// .TYPICAL USE:
-// to implement a circular buffer.
-//
-// .EXAMPLE:
-// See MemoryChannel.C
-//===========================================================================
-
-///////////////////////////////////////////////////////////////////////////////
-// CircularIndex( int start= 0,int size=256 );
-// Constuctor
-// Parameters:
-// start: where to start to index
-// size : range of the index, will be from 0 to size-1
-///////////////////////////////////////////////////////////////////////////////
-// operator int ();
-// returns the index
-///////////////////////////////////////////////////////////////////////////////
-// void operator ++ ();
-// increments the index with one, of size is reached it is set to zero
-///////////////////////////////////////////////////////////////////////////////
-// friend int full( const CircularIndex& write, const CircularIndex& read );
-// Taken the write index and the read index from a buffer it is calculated
-// if the buffer is full
-// Parameters:
-// write: index used a write index for the buffer
-// read : index used a read index for the buffer
-// return
-// 0 : not full
-// 1 : full
-///////////////////////////////////////////////////////////////////////////////
-// friend int empty( const CircularIndex& write, const CircularIndex& read );
-// Taken the write index and the read index from a buffer it is calculated
-// if the buffer is empty
-// Parameters:
-// write: index used a write index for the buffer
-// read : index used a read index for the buffer
-// return
-// 0 : not empty
-// 1 : empty
-///////////////////////////////////////////////////////////////////////////////
-
-class CircularIndex
-{
-public:
- inline CircularIndex( int start= 0,int size=256 );
- operator int () const;
- CircularIndex& operator ++ ();
- friend int full( const CircularIndex& write, const CircularIndex& read );
- friend int empty( const CircularIndex& write, const CircularIndex& read );
-private:
- int theSize;
- int theIndex;
-};
-
-inline CircularIndex::operator int () const
-{
- return theIndex;
-}
-
-inline CircularIndex& CircularIndex::operator ++ ()
-{
- ++theIndex;
- if( theIndex >= theSize ){
- theIndex= 0;
- }
- return *this;
-}
-
-
-inline int full( const CircularIndex& write, const CircularIndex& read )
-{
- int readTmp= read.theIndex;
-
- if( read.theIndex < write.theIndex )
- readTmp += read.theSize;
-
- return ( readTmp - write.theIndex) == 1;
-}
-
-inline int empty( const CircularIndex& write, const CircularIndex& read )
-{
- return read.theIndex == write.theIndex;
-}
-
-
-inline CircularIndex::CircularIndex( int start,int size ):
- theSize(size),
- theIndex(start)
-{
-}
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp b/storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp
deleted file mode 100644
index 27200ebfbda..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-
-#include "Filename.hpp"
-#include "ErrorHandlingMacros.hpp"
-#include "RefConvert.hpp"
-#include "DebuggerNames.hpp"
-
-#include <signaldata/FsOpenReq.hpp>
-
-static const char* fileExtension[] = {
- ".Data",
- ".FragLog",
- ".LocLog",
- ".FragList",
- ".TableList",
- ".SchemaLog",
- ".sysfile",
- ".log",
- ".ctl"
-};
-
-static const Uint32 noOfExtensions = sizeof(fileExtension)/sizeof(char*);
-
-Filename::Filename()
-{
-}
-
-Filename::~Filename(){
-}
-
-void
-Filename::set(Filename::NameSpec& spec,
- BlockReference blockReference,
- const Uint32 filenumber[4], bool dir)
-{
- char buf[PATH_MAX];
-
- const Uint32 type = FsOpenReq::getSuffix(filenumber);
- const Uint32 version = FsOpenReq::getVersion(filenumber);
-
- size_t sz;
- if (version == 2)
- {
- sz = BaseString::snprintf(theName, sizeof(theName), "%s",
- spec.backup_path.c_str());
- m_base_name = theName + spec.backup_path.length();
- }
- else
- {
- sz = BaseString::snprintf(theName, sizeof(theName), "%s",
- spec.fs_path.c_str());
- m_base_name = theName + spec.fs_path.length();
- }
-
- switch(version){
- case 1 :{
- const Uint32 diskNo = FsOpenReq::v1_getDisk(filenumber);
- const Uint32 table = FsOpenReq::v1_getTable(filenumber);
- const Uint32 frag = FsOpenReq::v1_getFragment(filenumber);
- const Uint32 S_val = FsOpenReq::v1_getS(filenumber);
- const Uint32 P_val = FsOpenReq::v1_getP(filenumber);
-
- if (diskNo < 0xff){
- BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR);
- strcat(theName, buf);
- }
-
- {
- const char* blockName = getBlockName( refToBlock(blockReference) );
- if (blockName == NULL){
- ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","No Block Name");
- return;
- }
- BaseString::snprintf(buf, sizeof(buf), "%s%s", blockName, DIR_SEPARATOR);
- strcat(theName, buf);
- }
-
- if (table < 0xffffffff){
- BaseString::snprintf(buf, sizeof(buf), "T%d%s", table, DIR_SEPARATOR);
- strcat(theName, buf);
- }
-
- if (frag < 0xffffffff){
- BaseString::snprintf(buf, sizeof(buf), "F%d%s", frag, DIR_SEPARATOR);
- strcat(theName, buf);
- }
-
-
- if (S_val < 0xffffffff){
- BaseString::snprintf(buf, sizeof(buf), "S%d", S_val);
- strcat(theName, buf);
- }
-
- if (P_val < 0xff){
- BaseString::snprintf(buf, sizeof(buf), "P%d", P_val);
- strcat(theName, buf);
- }
-
- }
- break;
- case 2:{
- const Uint32 seq = FsOpenReq::v2_getSequence(filenumber);
- const Uint32 nodeId = FsOpenReq::v2_getNodeId(filenumber);
- const Uint32 count = FsOpenReq::v2_getCount(filenumber);
-
- BaseString::snprintf(buf, sizeof(buf), "BACKUP%sBACKUP-%d%s",
- DIR_SEPARATOR, seq, DIR_SEPARATOR);
- strcat(theName, buf);
- if(count == 0xffffffff) {
- BaseString::snprintf(buf, sizeof(buf), "BACKUP-%d.%d",
- seq, nodeId); strcat(theName, buf);
- } else {
- BaseString::snprintf(buf, sizeof(buf), "BACKUP-%d-%d.%d",
- seq, count, nodeId); strcat(theName, buf);
- }
- break;
- }
- break;
- case 3:{
- const Uint32 diskNo = FsOpenReq::v1_getDisk(filenumber);
-
- if(diskNo == 0xFF){
- ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","Invalid disk specification");
- }
-
- BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR);
- strcat(theName, buf);
- }
- break;
- case 5:
- {
- Uint32 tableId = FsOpenReq::v5_getTableId(filenumber);
- Uint32 lcpNo = FsOpenReq::v5_getLcpNo(filenumber);
- Uint32 fragId = FsOpenReq::v5_getFragmentId(filenumber);
- BaseString::snprintf(buf, sizeof(buf), "LCP/%d/T%dF%d", lcpNo, tableId, fragId);
- strcat(theName, buf);
- break;
- }
- default:
- ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","Wrong version");
- }
- if (type >= noOfExtensions){
- ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","File Type doesn't exist");
- return;
- }
- strcat(theName, fileExtension[type]);
-
- if(dir == true){
- for(int l = strlen(theName) - 1; l >= 0; l--){
- if(theName[l] == DIR_SEPARATOR[0]){
- theName[l] = 0;
- break;
- }
- }
- }
-}
-
-void
-Filename::set(Filename::NameSpec& spec,
- SegmentedSectionPtr ptr, class SectionSegmentPool& pool)
-{
- char buf[PATH_MAX];
- copy((Uint32*)&buf[0], ptr);
- if(buf[0] == DIR_SEPARATOR[0])
- {
- strncpy(theName, buf, PATH_MAX);
- m_base_name = theName;
- }
- else
- {
- snprintf(theName, sizeof(theName), "%s%s", spec.fs_path.c_str(), buf);
- m_base_name = theName + spec.fs_path.length();
- }
-}
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp b/storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp
deleted file mode 100644
index 37c79c3970f..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Filename_H
-#define Filename_H
-
-//===========================================================================
-//
-// .DESCRIPTION
-// Takes a 128 bits value (done as a array of four longs) and
-// makes a filename out of it acording the following schema
-// Bits 0-31 T
-// Bits 32-63 F
-// Bits 64-95 S
-// Bits 96-103 P
-// Bits 104-111 D
-// Bits 112-119 File Type
-// Bits 120-127 Version number of Filename
-//
-// T, is used to find/create a directory. If T = 0xFFFF then the
-// file is on top level. In that case the F is of no relevance.
-// F, same as T.
-// S, is used to find/create a filename. If S= 0xFFFF then it is ignored.
-// P, same as S
-// D, is used to find/create the root directory, this is the
-// directory before the blockname. If D= 0xFF then it is ignored.
-// File Type
-// 0 => .Data
-// 1 => .FragLog
-// 2 => .LocLog
-// 3 => .FragList
-// 4 => .TableList
-// 5 => .SchemaLog
-// 6 => .sysfile
-// 15=> ignored
-// Version number of Filename, current version is 0x1, must be
-// used for the this style of options.
-//
-//
-//===========================================================================
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-#include <SimulatedBlock.hpp>
-
-class Filename
-{
-public:
- // filenumber is 64 bits but is split in to 4 32bits words
- Filename();
- ~Filename();
-
- struct NameSpec {
- NameSpec(BaseString& f, BaseString&b) :
- fs_path(f), backup_path(b) {}
- BaseString& fs_path;
- BaseString& backup_path;
- };
-
- void set(NameSpec& spec,
- BlockReference, const Uint32 fileno[4], bool = false);
- void set(NameSpec& spec,
- SegmentedSectionPtr ptr, class SectionSegmentPool&);
-
- const char* c_str() const; // Complete name including dirname
- const char* get_base_name() const; // Exclude fs (or backup) path
-private:
- char theName[PATH_MAX];
- char * m_base_name;
-};
-
-// inline methods
-inline const char* Filename::c_str() const {
- return theName;
-}
-
-inline const char* Filename::get_base_name() const {
- return m_base_name;
-}
-
-#endif
-
-
-
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp b/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp
deleted file mode 100644
index 4bd5a06debe..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//#include "MemoryChannel.hpp"
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp b/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp
deleted file mode 100644
index 279b69703ec..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef MemoryChannel_H
-#define MemoryChannel_H
-
-//===========================================================================
-//
-// .DESCRIPTION
-// Pointer based communication channel for communication between two
-// thread. It does not copy any data in or out the channel so the
-// item that is put in can not be used untill the other thread has
-// given it back. There is no support for detecting the return of a
-// item. The channel is half-duplex.
-// For comminication between 1 writer and 1 reader use the MemoryChannel
-// class, for comminication between multiple writer and 1 reader use the
-// MemoryChannelMultipleWriter. There is no support for multiple readers.
-//
-// .TYPICAL USE:
-// to communicate between threads.
-//
-// .EXAMPLE:
-// See AsyncFile.C
-//===========================================================================
-//
-//
-// MemoryChannel( int size= 256);
-// Constuctor
-// Parameters:
-// size : amount of pointer it can hold
-//
-// void operator ++ ();
-// increments the index with one, if size is reached it is set to zero
-//
-// virtual void write( T *t);
-// Puts the item in the channel if the channel is full an error is reported.
-// Parameters:
-// t: pointer to item to put in the channel, after this the item
-// is shared with the other thread.
-// errors
-// AFS_ERROR_CHANNALFULL, channel is full
-//
-// T* read();
-// Reads a itemn from the channel, if channel is empty it blocks untill
-// an item can be read.
-// return
-// T : item from the channel
-//
-// T* tryRead();
-// Reads a item from the channel, if channel is empty it returns zero.
-// return
-// T : item from the channel or zero if channel is empty.
-//
-
-#include "ErrorHandlingMacros.hpp"
-#include "CircularIndex.hpp"
-#include "NdbMutex.h"
-#include "NdbCondition.h"
-#include <NdbOut.hpp>
-
-
-template <class T>
-class MemoryChannel
-{
-public:
- MemoryChannel( int size= 512);
- virtual ~MemoryChannel( );
-
- void writeChannel( T *t);
- void writeChannelNoSignal( T *t);
- T* readChannel();
- T* tryReadChannel();
-
-private:
- int theSize;
- T **theChannel;
- CircularIndex theWriteIndex;
- CircularIndex theReadIndex;
- NdbMutex* theMutexPtr;
- NdbCondition* theConditionPtr;
-
- template<class U>
- friend NdbOut& operator<<(NdbOut& out, const MemoryChannel<U> & chn);
-};
-
-template <class T>
-NdbOut& operator<<(NdbOut& out, const MemoryChannel<T> & chn)
-{
- NdbMutex_Lock(chn.theMutexPtr);
- out << "[ theSize: " << chn.theSize
- << " theReadIndex: " << (int)chn.theReadIndex
- << " theWriteIndex: " << (int)chn.theWriteIndex << " ]";
- NdbMutex_Unlock(chn.theMutexPtr);
- return out;
-}
-
-template <class T> MemoryChannel<T>::MemoryChannel( int size):
- theSize(size),
- theChannel(new T*[size] ),
- theWriteIndex(0, size),
- theReadIndex(0, size)
-{
- theMutexPtr = NdbMutex_Create();
- theConditionPtr = NdbCondition_Create();
-}
-
-template <class T> MemoryChannel<T>::~MemoryChannel( )
-{
- NdbMutex_Destroy(theMutexPtr);
- NdbCondition_Destroy(theConditionPtr);
- delete [] theChannel;
-}
-
-template <class T> void MemoryChannel<T>::writeChannel( T *t)
-{
-
- NdbMutex_Lock(theMutexPtr);
- if(full(theWriteIndex, theReadIndex) || theChannel == NULL) abort();
- theChannel[theWriteIndex]= t;
- ++theWriteIndex;
- NdbMutex_Unlock(theMutexPtr);
- NdbCondition_Signal(theConditionPtr);
-}
-
-template <class T> void MemoryChannel<T>::writeChannelNoSignal( T *t)
-{
-
- NdbMutex_Lock(theMutexPtr);
- if(full(theWriteIndex, theReadIndex) || theChannel == NULL) abort();
- theChannel[theWriteIndex]= t;
- ++theWriteIndex;
- NdbMutex_Unlock(theMutexPtr);
-}
-
-template <class T> T* MemoryChannel<T>::readChannel()
-{
- T* tmp;
-
- NdbMutex_Lock(theMutexPtr);
- while ( empty(theWriteIndex, theReadIndex) )
- {
- NdbCondition_Wait(theConditionPtr,
- theMutexPtr);
- }
-
- tmp= theChannel[theReadIndex];
- ++theReadIndex;
- NdbMutex_Unlock(theMutexPtr);
- return tmp;
-}
-
-template <class T> T* MemoryChannel<T>::tryReadChannel()
-{
- T* tmp= 0;
- NdbMutex_Lock(theMutexPtr);
- if ( !empty(theWriteIndex, theReadIndex) )
- {
- tmp= theChannel[theReadIndex];
- ++theReadIndex;
- }
- NdbMutex_Unlock(theMutexPtr);
- return tmp;
-}
-
-#endif // MemoryChannel_H
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/Makefile b/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/Makefile
deleted file mode 100644
index 68f71bfc4cd..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include .defs.mk
-
-TYPE := kernel
-
-BIN_TARGET := mctest
-BIN_TARGET_ARCHIVES := portlib
-
-SOURCES = MemoryChannelTest.cpp
-
-CFLAGS_MemoryChannelTest.cpp = -I../
-
-include $(NDB_TOP)/Epilogue.mk
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp b/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp
deleted file mode 100644
index 26707969975..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "MemoryChannel.hpp"
-#include "NdbThread.h"
-#include "NdbSleep.h"
-#include "NdbOut.hpp"
-#include "NdbMain.h"
-
-
-
-MemoryChannel<int>* theMemoryChannel;
-
-
-extern "C" void* runProducer(void*arg)
-{
- // The producer will items into the MemoryChannel
- int count = *(int*)arg;
- int* p;
- int i = 0;
- while (i <= count)
- {
- p = new int(i);
- ndbout << "P: " << *p << endl;
- theMemoryChannel->writeChannel(p);
- if (i%5==0)
- NdbSleep_MilliSleep(i);
- i++;
- }
- return NULL;
-}
-
-extern "C" void* runConsumer(void* arg)
-{
- // The producer will read items from MemoryChannel and print on screen
- int count = *(int*)arg;
- int* p;
- int i = 0;
- while (i < count)
- {
- p = theMemoryChannel->readChannel();
- ndbout << "C: " << *p << endl;
- i = *p;
- delete p;
-
- }
- return NULL;
-}
-
-
-
-class ArgStruct
-{
-public:
- ArgStruct(int _items, int _no){
- items=_items;
- no=_no;
- };
- int items;
- int no;
-};
-
-MemoryChannelMultipleWriter<ArgStruct>* theMemoryChannel2;
-
-extern "C" void* runProducer2(void*arg)
-{
- // The producer will items into the MemoryChannel
- ArgStruct* pArg = (ArgStruct*)arg;
- int count = pArg->items;
- ArgStruct* p;
- int i = 0;
- while (i < count)
- {
- p = new ArgStruct(i, pArg->no);
- ndbout << "P"<<pArg->no<<": " << i << endl;
- theMemoryChannel2->writeChannel(p);
- NdbSleep_MilliSleep(i);
- i++;
- }
- return NULL;
-}
-
-extern "C" void* runConsumer2(void* arg)
-{
- // The producer will read items from MemoryChannel and print on screen
- ArgStruct* pArg = (ArgStruct*)arg;
- int count = pArg->items * pArg->no;
- ArgStruct* p;
- int i = 0;
- while (i < count)
- {
- p = theMemoryChannel2->readChannel();
- ndbout << "C: "<< p->no << ", " << p->items << endl;
- i++;
- delete p;
- }
- ndbout << "Consumer2: " << count << " received" << endl;
- return NULL;
-}
-
-
-
-
-//#if defined MEMORYCHANNELTEST
-
-//int main(int argc, char **argv)
-NDB_COMMAND(mctest, "mctest", "mctest", "Test the memory channel used in Ndb", 32768)
-{
-
- ndbout << "==== testing MemoryChannel ====" << endl;
-
- theMemoryChannel = new MemoryChannel<int>;
- theMemoryChannel2 = new MemoryChannelMultipleWriter<ArgStruct>;
-
- NdbThread* consumerThread;
- NdbThread* producerThread;
-
- NdbThread_SetConcurrencyLevel(2);
-
- int numItems = 100;
- producerThread = NdbThread_Create(runProducer,
- (void**)&numItems,
- 4096,
- (char*)"producer");
-
- consumerThread = NdbThread_Create(runConsumer,
- (void**)&numItems,
- 4096,
- (char*)"consumer");
-
-
- void *status;
- NdbThread_WaitFor(consumerThread, &status);
- NdbThread_WaitFor(producerThread, &status);
-
- ndbout << "==== testing MemoryChannelMultipleWriter ====" << endl;
-#define NUM_THREADS2 5
- NdbThread_SetConcurrencyLevel(NUM_THREADS2+2);
- NdbThread* producerThreads[NUM_THREADS2];
-
- ArgStruct *pArg;
- for (int j = 0; j < NUM_THREADS2; j++)
- {
- char buf[25];
- sprintf((char*)&buf, "producer%d", j);
- pArg = new ArgStruct(numItems, j);
- producerThreads[j] = NdbThread_Create(runProducer2,
- (void**)pArg,
- 4096,
- (char*)&buf);
- }
-
- pArg = new ArgStruct(numItems, NUM_THREADS2);
- consumerThread = NdbThread_Create(runConsumer2,
- (void**)pArg,
- 4096,
- (char*)"consumer");
-
-
- NdbThread_WaitFor(consumerThread, &status);
- for (int j = 0; j < NUM_THREADS2; j++)
- {
- NdbThread_WaitFor(producerThreads[j], &status);
- }
-
-
- return 0;
-
-}
-
-void ErrorReporter::handleError(ErrorCategory type, int messageID,
- const char* problemData, const char* objRef,
- NdbShutdownType nst)
-{
-
- ndbout << "ErrorReporter::handleError activated" << endl;
- exit(1);
-}
-
-//#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
deleted file mode 100644
index 779d44d4176..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
+++ /dev/null
@@ -1,1109 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "Ndbfs.hpp"
-#include "AsyncFile.hpp"
-#include "Filename.hpp"
-
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/FsAppendReq.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/NdbfsContinueB.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-
-#include <RefConvert.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-#include <Configuration.hpp>
-
-#define DEBUG(x) { ndbout << "FS::" << x << endl; }
-
-inline
-int pageSize( const NewVARIABLE* baseAddrRef )
-{
- int log_psize;
- int log_qsize = baseAddrRef->bits.q;
- int log_vsize = baseAddrRef->bits.v;
- if (log_vsize < 3)
- log_vsize = 3;
- log_psize = log_qsize + log_vsize - 3;
- return (1 << log_psize);
-}
-
-
-Ndbfs::Ndbfs(Block_context& ctx) :
- SimulatedBlock(NDBFS, ctx),
- scanningInProgress(false),
- theLastId(0),
- theRequestPool(0),
- m_maxOpenedFiles(0)
-{
- BLOCK_CONSTRUCTOR(Ndbfs);
-
- // Set received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &Ndbfs::execREAD_CONFIG_REQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &Ndbfs::execDUMP_STATE_ORD);
- addRecSignal(GSN_STTOR, &Ndbfs::execSTTOR);
- addRecSignal(GSN_FSOPENREQ, &Ndbfs::execFSOPENREQ);
- addRecSignal(GSN_FSCLOSEREQ, &Ndbfs::execFSCLOSEREQ);
- addRecSignal(GSN_FSWRITEREQ, &Ndbfs::execFSWRITEREQ);
- addRecSignal(GSN_FSREADREQ, &Ndbfs::execFSREADREQ);
- addRecSignal(GSN_FSSYNCREQ, &Ndbfs::execFSSYNCREQ);
- addRecSignal(GSN_CONTINUEB, &Ndbfs::execCONTINUEB);
- addRecSignal(GSN_FSAPPENDREQ, &Ndbfs::execFSAPPENDREQ);
- addRecSignal(GSN_FSREMOVEREQ, &Ndbfs::execFSREMOVEREQ);
- // Set send signals
-}
-
-Ndbfs::~Ndbfs()
-{
- // Delete all files
- // AsyncFile destuctor will take care of deleting
- // the thread it has created
- for (unsigned i = 0; i < theFiles.size(); i++){
- AsyncFile* file = theFiles[i];
- delete file;
- theFiles[i] = NULL;
- }//for
- theFiles.clear();
- if (theRequestPool)
- delete theRequestPool;
-}
-
-void
-Ndbfs::execREAD_CONFIG_REQ(Signal* signal)
-{
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
- theFileSystemPath.assfmt("%sndb_%u_fs%s", m_ctx.m_config.fileSystemPath(),
- getOwnNodeId(), DIR_SEPARATOR);
- theBackupFilePath.assign(m_ctx.m_config.backupFilePath());
-
- theRequestPool = new Pool<Request>;
-
- m_maxFiles = 0;
- ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles);
- Uint32 noIdleFiles = 27;
- ndb_mgm_get_int_parameter(p, CFG_DB_INITIAL_OPEN_FILES, &noIdleFiles);
- if (noIdleFiles > m_maxFiles && m_maxFiles != 0)
- m_maxFiles = noIdleFiles;
- // Create idle AsyncFiles
- for (Uint32 i = 0; i < noIdleFiles; i++){
- theIdleFiles.push_back(createAsyncFile());
- }
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-/* Received a restart signal.
- * Answer it like any other block
- * PR0 : StartCase
- * DR0 : StartPhase
- * DR1 : ?
- * DR2 : ?
- * DR3 : ?
- * DR4 : ?
- * DR5 : SignalKey
- */
-void
-Ndbfs::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- if(signal->theData[1] == 0){ // StartPhase 0
- jam();
-
- {
-#ifdef NDB_WIN32
- CreateDirectory(theFileSystemPath.c_str(), 0);
-#else
- mkdir(theFileSystemPath.c_str(),
- S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
-#endif
- }
-
- cownref = NDBFS_REF;
- // close all open files
- ndbrequire(theOpenFiles.size() == 0);
-
- scanningInProgress = false;
-
- signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
-
- signal->theData[3] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal,4, JBB);
- return;
- }
- ndbrequire(0);
-}
-
-int
-Ndbfs::forward( AsyncFile * file, Request* request)
-{
- jam();
- file->execute(request);
- return 1;
-}
-
-void
-Ndbfs::execFSOPENREQ(Signal* signal)
-{
- jamEntry();
- const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
- const BlockReference userRef = fsOpenReq->userReference;
- AsyncFile* file = getIdleFile();
- ndbrequire(file != NULL);
- Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
-
- Uint32 userPointer = fsOpenReq->userPointer;
-
- if(fsOpenReq->fileFlags & FsOpenReq::OM_INIT)
- {
- Ptr<GlobalPage> page_ptr;
- if(m_global_page_pool.seize(page_ptr) == false)
- {
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrOutOfMemory);
- fsRef->osErrorCode = ~0; // Indicate local error
- sendSignal(userRef, GSN_FSOPENREF, signal, 3, JBB);
- return;
- }
- file->m_page_ptr = page_ptr;
- }
- else
- {
- ndbassert(file->m_page_ptr.isNull());
- file->m_page_ptr.setNull();
- }
-
- if(signal->getNoOfSections() == 0){
- jam();
- file->theFileName.set(spec, userRef, fsOpenReq->fileNumber);
- } else {
- jam();
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, FsOpenReq::FILENAME);
- file->theFileName.set(spec, ptr, g_sectionSegmentPool);
- releaseSections(signal);
- }
- file->reportTo(&theFromThreads);
- if (getenv("NDB_TRACE_OPEN"))
- ndbout_c("open(%s)", file->theFileName.c_str());
-
- Request* request = theRequestPool->get();
- request->action = Request::open;
- request->error = 0;
- request->set(userRef, userPointer, newId() );
- request->file = file;
- request->theTrace = signal->getTrace();
- request->par.open.flags = fsOpenReq->fileFlags;
- request->par.open.page_size = fsOpenReq->page_size;
- request->par.open.file_size = fsOpenReq->file_size_hi;
- request->par.open.file_size <<= 32;
- request->par.open.file_size |= fsOpenReq->file_size_lo;
- request->par.open.auto_sync_size = fsOpenReq->auto_sync_size;
-
- ndbrequire(forward(file, request));
-}
-
-void
-Ndbfs::execFSREMOVEREQ(Signal* signal)
-{
- jamEntry();
- const FsRemoveReq * const req = (FsRemoveReq *)signal->getDataPtr();
- const BlockReference userRef = req->userReference;
- AsyncFile* file = getIdleFile();
- ndbrequire(file != NULL);
-
- Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
- file->theFileName.set(spec, userRef, req->fileNumber, req->directory);
- file->reportTo(&theFromThreads);
-
- Request* request = theRequestPool->get();
- request->action = Request::rmrf;
- request->par.rmrf.directory = req->directory;
- request->par.rmrf.own_directory = req->ownDirectory;
- request->error = 0;
- request->set(userRef, req->userPointer, newId() );
- request->file = file;
- request->theTrace = signal->getTrace();
-
- ndbrequire(forward(file, request));
-}
-
-/*
- * PR0: File Pointer DR0: User reference DR1: User Pointer DR2: Flag bit 0= 1
- * remove file
- */
-void
-Ndbfs::execFSCLOSEREQ(Signal * signal)
-{
- jamEntry();
- const FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
- const BlockReference userRef = fsCloseReq->userReference;
- const Uint16 filePointer = (Uint16)fsCloseReq->filePointer;
- const UintR userPointer = fsCloseReq->userPointer;
-
- AsyncFile* openFile = theOpenFiles.find(filePointer);
- if (openFile == NULL) {
- // The file was not open, send error back to sender
- jam();
- // Initialise FsRef signal
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
- fsRef->osErrorCode = ~0; // Indicate local error
- sendSignal(userRef, GSN_FSCLOSEREF, signal, 3, JBB);
- return;
- }
-
- Request *request = theRequestPool->get();
- if( fsCloseReq->getRemoveFileFlag(fsCloseReq->fileFlag) == true ) {
- jam();
- request->action = Request::closeRemove;
- } else {
- jam();
- request->action = Request::close;
- }
- request->set(userRef, fsCloseReq->userPointer, filePointer);
- request->file = openFile;
- request->error = 0;
- request->theTrace = signal->getTrace();
-
- ndbrequire(forward(openFile, request));
-}
-
-void
-Ndbfs::readWriteRequest(int action, Signal * signal)
-{
- const FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
- Uint16 filePointer = (Uint16)fsRWReq->filePointer;
- const UintR userPointer = fsRWReq->userPointer;
- const BlockReference userRef = fsRWReq->userReference;
- const BlockNumber blockNumber = refToBlock(userRef);
-
- AsyncFile* openFile = theOpenFiles.find(filePointer);
-
- const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsRWReq->varIndex];
- UintPtr tPageSize;
- UintPtr tClusterSize;
- UintPtr tNRR;
- UintPtr tPageOffset;
- char* tWA;
- FsRef::NdbfsErrorCodeType errorCode;
-
- Request *request = theRequestPool->get();
- request->error = 0;
- request->set(userRef, userPointer, filePointer);
- request->file = openFile;
- request->action = (Request::Action) action;
- request->theTrace = signal->getTrace();
-
- Uint32 format = fsRWReq->getFormatFlag(fsRWReq->operationFlag);
-
- if (fsRWReq->numberOfPages == 0) { //Zero pages not allowed
- jam();
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
-
- if(format != FsReadWriteReq::fsFormatGlobalPage &&
- format != FsReadWriteReq::fsFormatSharedPage)
- {
- if (fsRWReq->varIndex >= getBatSize(blockNumber)) {
- jam();// Ensure that a valid variable is used
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
- if (myBaseAddrRef == NULL) {
- jam(); // Ensure that a valid variable is used
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
- if (openFile == NULL) {
- jam(); //file not open
- errorCode = FsRef::fsErrFileDoesNotExist;
- goto error;
- }
- tPageSize = pageSize(myBaseAddrRef);
- tClusterSize = myBaseAddrRef->ClusterSize;
- tNRR = myBaseAddrRef->nrr;
- tWA = (char*)myBaseAddrRef->WA;
-
- switch (format) {
-
- // List of memory and file pages pairs
- case FsReadWriteReq::fsFormatListOfPairs: {
- jam();
- for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
- jam();
- const UintPtr varIndex = fsRWReq->data.listOfPair[i].varIndex;
- const UintPtr fileOffset = fsRWReq->data.listOfPair[i].fileOffset;
- if (varIndex >= tNRR) {
- jam();
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }//if
- request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
- request->par.readWrite.pages[i].size = tPageSize;
- request->par.readWrite.pages[i].offset = fileOffset * tPageSize;
- }//for
- request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
- break;
- }//case
-
- // Range of memory page with one file page
- case FsReadWriteReq::fsFormatArrayOfPages: {
- if ((fsRWReq->numberOfPages + fsRWReq->data.arrayOfPages.varIndex) > tNRR) {
- jam();
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }//if
- const UintPtr varIndex = fsRWReq->data.arrayOfPages.varIndex;
- const UintPtr fileOffset = fsRWReq->data.arrayOfPages.fileOffset;
-
- request->par.readWrite.pages[0].offset = fileOffset * tPageSize;
- request->par.readWrite.pages[0].size = tPageSize * fsRWReq->numberOfPages;
- request->par.readWrite.numberOfPages = 1;
- request->par.readWrite.pages[0].buf = &tWA[varIndex * tPageSize];
- break;
- }//case
-
- // List of memory pages followed by one file page
- case FsReadWriteReq::fsFormatListOfMemPages: {
-
- tPageOffset = fsRWReq->data.listOfMemPages.varIndex[fsRWReq->numberOfPages];
- tPageOffset *= tPageSize;
-
- for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
- jam();
- UintPtr varIndex = fsRWReq->data.listOfMemPages.varIndex[i];
-
- if (varIndex >= tNRR) {
- jam();
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }//if
- request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
- request->par.readWrite.pages[i].size = tPageSize;
- request->par.readWrite.pages[i].offset = tPageOffset + (i*tPageSize);
- }//for
- request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
- break;
- // make it a writev or readv
- }//case
-
- default: {
- jam();
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }//default
- }//switch
- }
- else if (format == FsReadWriteReq::fsFormatGlobalPage)
- {
- Ptr<GlobalPage> ptr;
- m_global_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
- request->par.readWrite.pages[0].buf = (char*)ptr.p;
- request->par.readWrite.pages[0].size = ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->numberOfPages;
- request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
- request->par.readWrite.numberOfPages = 1;
- }
- else
- {
- ndbrequire(format == FsReadWriteReq::fsFormatSharedPage);
- Ptr<GlobalPage> ptr;
- m_shared_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
- request->par.readWrite.pages[0].buf = (char*)ptr.p;
- request->par.readWrite.pages[0].size = ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->numberOfPages;
- request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
- request->par.readWrite.numberOfPages = 1;
- }
-
- ndbrequire(forward(openFile, request));
- return;
-
-error:
- theRequestPool->put(request);
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->setErrorCode(fsRef->errorCode, errorCode);
- fsRef->osErrorCode = ~0; // Indicate local error
- switch (action) {
- case Request:: write:
- case Request:: writeSync: {
- jam();
- sendSignal(userRef, GSN_FSWRITEREF, signal, 3, JBB);
- break;
- }//case
- case Request:: readPartial:
- case Request:: read: {
- jam();
- sendSignal(userRef, GSN_FSREADREF, signal, 3, JBB);
- }//case
- }//switch
- return;
-}
-
-/*
- PR0: File Pointer , theData[0]
- DR0: User reference, theData[1]
- DR1: User Pointer, etc.
- DR2: Flag
- DR3: Var number
- DR4: amount of pages
- DR5->: Memory Page id and File page id according to Flag
-*/
-void
-Ndbfs::execFSWRITEREQ(Signal* signal)
-{
- jamEntry();
- const FsReadWriteReq * const fsWriteReq = (FsReadWriteReq *)&signal->theData[0];
-
- if (fsWriteReq->getSyncFlag(fsWriteReq->operationFlag) == true){
- jam();
- readWriteRequest( Request::writeSync, signal );
- } else {
- jam();
- readWriteRequest( Request::write, signal );
- }
-}
-
-/*
- PR0: File Pointer
- DR0: User reference
- DR1: User Pointer
- DR2: Flag
- DR3: Var number
- DR4: amount of pages
- DR5->: Memory Page id and File page id according to Flag
-*/
-void
-Ndbfs::execFSREADREQ(Signal* signal)
-{
- jamEntry();
- FsReadWriteReq * req = (FsReadWriteReq *)signal->getDataPtr();
- if (FsReadWriteReq::getPartialReadFlag(req->operationFlag))
- readWriteRequest( Request::readPartial, signal );
- else
- readWriteRequest( Request::read, signal );
-}
-
-/*
- * PR0: File Pointer DR0: User reference DR1: User Pointer
- */
-void
-Ndbfs::execFSSYNCREQ(Signal * signal)
-{
- jamEntry();
- Uint16 filePointer = (Uint16)signal->theData[0];
- BlockReference userRef = signal->theData[1];
- const UintR userPointer = signal->theData[2];
- AsyncFile* openFile = theOpenFiles.find(filePointer);
-
- if (openFile == NULL) {
- jam(); //file not open
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
- fsRef->osErrorCode = ~0; // Indicate local error
- sendSignal(userRef, GSN_FSSYNCREF, signal, 3, JBB);
- return;
- }
-
- Request *request = theRequestPool->get();
- request->error = 0;
- request->action = Request::sync;
- request->set(userRef, userPointer, filePointer);
- request->file = openFile;
- request->theTrace = signal->getTrace();
-
- ndbrequire(forward(openFile,request));
-}
-
-void
-Ndbfs::execFSAPPENDREQ(Signal * signal)
-{
- const FsAppendReq * const fsReq = (FsAppendReq *)&signal->theData[0];
- const Uint16 filePointer = (Uint16)fsReq->filePointer;
- const UintR userPointer = fsReq->userPointer;
- const BlockReference userRef = fsReq->userReference;
- const BlockNumber blockNumber = refToBlock(userRef);
-
- FsRef::NdbfsErrorCodeType errorCode;
-
- AsyncFile* openFile = theOpenFiles.find(filePointer);
- const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsReq->varIndex];
-
- const Uint32* tWA = (const Uint32*)myBaseAddrRef->WA;
- const Uint32 tSz = myBaseAddrRef->nrr;
- const Uint32 offset = fsReq->offset;
- const Uint32 size = fsReq->size;
- const Uint32 synch_flag = fsReq->synch_flag;
- Request *request = theRequestPool->get();
-
- if (openFile == NULL) {
- jam();
- errorCode = FsRef::fsErrFileDoesNotExist;
- goto error;
- }
-
- if (myBaseAddrRef == NULL) {
- jam(); // Ensure that a valid variable is used
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
-
- if (fsReq->varIndex >= getBatSize(blockNumber)) {
- jam();// Ensure that a valid variable is used
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
-
- if(offset + size > tSz){
- jam(); // Ensure that a valid variable is used
- errorCode = FsRef::fsErrInvalidParameters;
- goto error;
- }
-
- request->error = 0;
- request->set(userRef, userPointer, filePointer);
- request->file = openFile;
- request->theTrace = signal->getTrace();
-
- request->par.append.buf = (const char *)(tWA + offset);
- request->par.append.size = size << 2;
-
- if (!synch_flag)
- request->action = Request::append;
- else
- request->action = Request::append_synch;
- ndbrequire(forward(openFile, request));
- return;
-
-error:
- jam();
- theRequestPool->put(request);
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->setErrorCode(fsRef->errorCode, errorCode);
- fsRef->osErrorCode = ~0; // Indicate local error
-
- jam();
- sendSignal(userRef, GSN_FSAPPENDREF, signal, 3, JBB);
- return;
-}
-
-Uint16
-Ndbfs::newId()
-{
- // finds a new key, eg a new filepointer
- for (int i = 1; i < SHRT_MAX; i++)
- {
- if (theLastId == SHRT_MAX) {
- jam();
- theLastId = 1;
- } else {
- jam();
- theLastId++;
- }
-
- if(theOpenFiles.find(theLastId) == NULL) {
- jam();
- return theLastId;
- }
- }
- ndbrequire(1 == 0);
- // The program will not reach this point
- return 0;
-}
-
-AsyncFile*
-Ndbfs::createAsyncFile(){
-
- // Check limit of open files
- if (m_maxFiles !=0 && theFiles.size() == m_maxFiles) {
- // Print info about all open files
- for (unsigned i = 0; i < theFiles.size(); i++){
- AsyncFile* file = theFiles[i];
- ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
- }
- ERROR_SET(fatal, NDBD_EXIT_AFS_MAXOPEN,""," Ndbfs::createAsyncFile");
- }
-
- AsyncFile* file = new AsyncFile(* this);
- file->doStart();
-
- // Put the file in list of all files
- theFiles.push_back(file);
-
-#ifdef VM_TRACE
- infoEvent("NDBFS: Created new file thread %d", theFiles.size());
-#endif
-
- return file;
-}
-
-AsyncFile*
-Ndbfs::getIdleFile(){
- AsyncFile* file;
- if (theIdleFiles.size() > 0){
- file = theIdleFiles[0];
- theIdleFiles.erase(0);
- } else {
- file = createAsyncFile();
- }
- return file;
-}
-
-
-
-void
-Ndbfs::report(Request * request, Signal* signal)
-{
- const Uint32 orgTrace = signal->getTrace();
- signal->setTrace(request->theTrace);
- const BlockReference ref = request->theUserReference;
-
- if(!request->file->m_page_ptr.isNull())
- {
- m_global_page_pool.release(request->file->m_page_ptr);
- request->file->m_page_ptr.setNull();
- }
-
- if (request->error) {
- jam();
- // Initialise FsRef signal
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = request->theUserPointer;
- if(request->error & FsRef::FS_ERR_BIT)
- {
- fsRef->errorCode = request->error;
- fsRef->osErrorCode = 0;
- }
- else
- {
- fsRef->setErrorCode(fsRef->errorCode, translateErrno(request->error));
- fsRef->osErrorCode = request->error;
- }
- switch (request->action) {
- case Request:: open: {
- jam();
- // Put the file back in idle files list
- theIdleFiles.push_back(request->file);
- sendSignal(ref, GSN_FSOPENREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request:: closeRemove:
- case Request:: close: {
- jam();
- sendSignal(ref, GSN_FSCLOSEREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request:: writeSync:
- case Request:: writevSync:
- case Request:: write:
- case Request:: writev: {
- jam();
- sendSignal(ref, GSN_FSWRITEREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request:: read:
- case Request:: readPartial:
- case Request:: readv: {
- jam();
- sendSignal(ref, GSN_FSREADREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request:: sync: {
- jam();
- sendSignal(ref, GSN_FSSYNCREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request::append:
- case Request::append_synch:
- {
- jam();
- sendSignal(ref, GSN_FSAPPENDREF, signal, FsRef::SignalLength, JBB);
- break;
- }
- case Request::rmrf: {
- jam();
- // Put the file back in idle files list
- theIdleFiles.push_back(request->file);
- sendSignal(ref, GSN_FSREMOVEREF, signal, FsRef::SignalLength, JBB);
- break;
- }
-
- case Request:: end: {
- // Report nothing
- break;
- }
- }//switch
- } else {
- jam();
- FsConf * const fsConf = (FsConf *)&signal->theData[0];
- fsConf->userPointer = request->theUserPointer;
- switch (request->action) {
- case Request:: open: {
- jam();
- theOpenFiles.insert(request->file, request->theFilePointer);
-
- // Keep track on max number of opened files
- if (theOpenFiles.size() > m_maxOpenedFiles)
- m_maxOpenedFiles = theOpenFiles.size();
-
- fsConf->filePointer = request->theFilePointer;
- sendSignal(ref, GSN_FSOPENCONF, signal, 3, JBB);
- break;
- }
- case Request:: closeRemove:
- case Request:: close: {
- jam();
- // removes the file from OpenFiles list
- theOpenFiles.erase(request->theFilePointer);
- // Put the file in idle files list
- theIdleFiles.push_back(request->file);
- sendSignal(ref, GSN_FSCLOSECONF, signal, 1, JBB);
- break;
- }
- case Request:: writeSync:
- case Request:: writevSync:
- case Request:: write:
- case Request:: writev: {
- jam();
- sendSignal(ref, GSN_FSWRITECONF, signal, 1, JBB);
- break;
- }
- case Request:: read:
- case Request:: readv: {
- jam();
- sendSignal(ref, GSN_FSREADCONF, signal, 1, JBB);
- break;
- }
- case Request:: readPartial: {
- jam();
- fsConf->bytes_read = request->par.readWrite.pages[0].size;
- sendSignal(ref, GSN_FSREADCONF, signal, 2, JBB);
- break;
- }
- case Request:: sync: {
- jam();
- sendSignal(ref, GSN_FSSYNCCONF, signal, 1, JBB);
- break;
- }//case
- case Request::append:
- case Request::append_synch:
- {
- jam();
- signal->theData[1] = request->par.append.size;
- sendSignal(ref, GSN_FSAPPENDCONF, signal, 2, JBB);
- break;
- }
- case Request::rmrf: {
- jam();
- // Put the file in idle files list
- theIdleFiles.push_back(request->file);
- sendSignal(ref, GSN_FSREMOVECONF, signal, 1, JBB);
- break;
- }
- case Request:: end: {
- // Report nothing
- break;
- }
- }
- }//if
- signal->setTrace(orgTrace);
-}
-
-
-bool
-Ndbfs::scanIPC(Signal* signal)
-{
- Request* request = theFromThreads.tryReadChannel();
- jam();
- if (request) {
- jam();
- report(request, signal);
- theRequestPool->put(request);
- return true;
- }
- return false;
-}
-
-#if defined NDB_WIN32
-Uint32 Ndbfs::translateErrno(int aErrno)
-{
- switch (aErrno)
- {
- //permission denied
- case ERROR_ACCESS_DENIED:
-
- return FsRef::fsErrPermissionDenied;
- //temporary not accessible
- case ERROR_PATH_BUSY:
- case ERROR_NO_MORE_SEARCH_HANDLES:
-
- return FsRef::fsErrTemporaryNotAccessible;
- //no space left on device
- case ERROR_HANDLE_DISK_FULL:
- case ERROR_DISK_FULL:
-
- return FsRef::fsErrNoSpaceLeftOnDevice;
- //none valid parameters
- case ERROR_INVALID_HANDLE:
- case ERROR_INVALID_DRIVE:
- case ERROR_INVALID_ACCESS:
- case ERROR_HANDLE_EOF:
- case ERROR_BUFFER_OVERFLOW:
-
- return FsRef::fsErrInvalidParameters;
- //environment error
- case ERROR_CRC:
- case ERROR_ARENA_TRASHED:
- case ERROR_BAD_ENVIRONMENT:
- case ERROR_INVALID_BLOCK:
- case ERROR_WRITE_FAULT:
- case ERROR_READ_FAULT:
- case ERROR_OPEN_FAILED:
-
- return FsRef::fsErrEnvironmentError;
-
- //no more process resources
- case ERROR_TOO_MANY_OPEN_FILES:
- case ERROR_NOT_ENOUGH_MEMORY:
- case ERROR_OUTOFMEMORY:
- return FsRef::fsErrNoMoreResources;
- //no file
- case ERROR_FILE_NOT_FOUND:
- return FsRef::fsErrFileDoesNotExist;
-
- case ERR_ReadUnderflow:
- return FsRef::fsErrReadUnderflow;
-
- default:
- return FsRef::fsErrUnknown;
- }
-}
-#else
-Uint32 Ndbfs::translateErrno(int aErrno)
-{
- switch (aErrno)
- {
- //permission denied
- case EACCES:
- case EROFS:
- case ENXIO:
- return FsRef::fsErrPermissionDenied;
- //temporary not accessible
- case EAGAIN:
- case ETIMEDOUT:
- case ENOLCK:
- case EINTR:
- case EIO:
- return FsRef::fsErrTemporaryNotAccessible;
- //no space left on device
- case ENFILE:
- case EDQUOT:
-#ifdef ENOSR
- case ENOSR:
-#endif
- case ENOSPC:
- case EFBIG:
- return FsRef::fsErrNoSpaceLeftOnDevice;
- //none valid parameters
- case EINVAL:
- case EBADF:
- case ENAMETOOLONG:
- case EFAULT:
- case EISDIR:
- case ENOTDIR:
- case EEXIST:
- case ETXTBSY:
- return FsRef::fsErrInvalidParameters;
- //environment error
- case ELOOP:
-#ifdef ENOLINK
- case ENOLINK:
-#endif
-#ifdef EMULTIHOP
- case EMULTIHOP:
-#endif
-#ifdef EOPNOTSUPP
- case EOPNOTSUPP:
-#endif
-#ifdef ESPIPE
- case ESPIPE:
-#endif
- case EPIPE:
- return FsRef::fsErrEnvironmentError;
-
- //no more process resources
- case EMFILE:
- case ENOMEM:
- return FsRef::fsErrNoMoreResources;
- //no file
- case ENOENT:
- return FsRef::fsErrFileDoesNotExist;
-
- case ERR_ReadUnderflow:
- return FsRef::fsErrReadUnderflow;
-
- default:
- return FsRef::fsErrUnknown;
- }
-}
-#endif
-
-
-
-void
-Ndbfs::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- if (signal->theData[0] == NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY) {
- jam();
-
- // Also send CONTINUEB to ourself in order to scan for
- // incoming answers from AsyncFile on MemoryChannel theFromThreads
- signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
- if (scanningInProgress == true) {
- jam();
- return;
- }
- }
- if (scanIPC(signal)) {
- jam();
- scanningInProgress = true;
- signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_NO_DELAY;
- sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
- } else {
- jam();
- scanningInProgress = false;
- }
- return;
-}
-
-void
-Ndbfs::execDUMP_STATE_ORD(Signal* signal)
-{
- if(signal->theData[0] == 19){
- return;
- }
- if(signal->theData[0] == DumpStateOrd::NdbfsDumpFileStat){
- infoEvent("NDBFS: Files: %d Open files: %d",
- theFiles.size(),
- theOpenFiles.size());
- infoEvent(" Idle files: %d Max opened files: %d",
- theIdleFiles.size(),
- m_maxOpenedFiles);
- infoEvent(" Max files: %d",
- m_maxFiles);
- infoEvent(" Requests: %d",
- theRequestPool->size());
-
- return;
- }
- if(signal->theData[0] == DumpStateOrd::NdbfsDumpOpenFiles){
- infoEvent("NDBFS: Dump open files: %d", theOpenFiles.size());
-
- for (unsigned i = 0; i < theOpenFiles.size(); i++){
- AsyncFile* file = theOpenFiles.getFile(i);
- infoEvent("%2d (0x%x): %s", i,file, file->theFileName.c_str());
- }
- return;
- }
- if(signal->theData[0] == DumpStateOrd::NdbfsDumpAllFiles){
- infoEvent("NDBFS: Dump all files: %d", theFiles.size());
-
- for (unsigned i = 0; i < theFiles.size(); i++){
- AsyncFile* file = theFiles[i];
- infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
- }
- return;
- }
- if(signal->theData[0] == DumpStateOrd::NdbfsDumpIdleFiles){
- infoEvent("NDBFS: Dump idle files: %d", theIdleFiles.size());
-
- for (unsigned i = 0; i < theIdleFiles.size(); i++){
- AsyncFile* file = theIdleFiles[i];
- infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
- }
- return;
- }
-
- if(signal->theData[0] == 404)
- {
- ndbrequire(signal->getLength() == 2);
- Uint32 file= signal->theData[1];
- AsyncFile* openFile = theOpenFiles.find(file);
- ndbrequire(openFile != 0);
- ndbout_c("File: %s %p", openFile->theFileName.c_str(), openFile);
- Request* curr = openFile->m_current_request;
- Request* last = openFile->m_last_request;
- if(curr)
- ndbout << "Current request: " << *curr << endl;
- if(last)
- ndbout << "Last request: " << *last << endl;
-
- ndbout << "theReportTo " << *openFile->theReportTo << endl;
- ndbout << "theMemoryChannelPtr" << *openFile->theMemoryChannelPtr << endl;
-
- ndbout << "All files: " << endl;
- for (unsigned i = 0; i < theFiles.size(); i++){
- AsyncFile* file = theFiles[i];
- ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
- }
- }
-}//Ndbfs::execDUMP_STATE_ORD()
-
-const char*
-Ndbfs::get_filename(Uint32 fd) const
-{
- jamEntry();
- const AsyncFile* openFile = theOpenFiles.find(fd);
- if(openFile)
- return openFile->theFileName.get_base_name();
- return "";
-}
-
-
-BLOCK_FUNCTIONS(Ndbfs)
-
-template class Vector<AsyncFile*>;
-template class Vector<OpenFiles::OpenFileItem>;
-template class MemoryChannel<Request>;
-template class Pool<Request>;
-template NdbOut& operator<<(NdbOut&, const MemoryChannel<Request>&);
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp
deleted file mode 100644
index df39890af49..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SIMBLOCKASYNCFILESYSTEM_H
-#define SIMBLOCKASYNCFILESYSTEM_H
-
-#include <pc.hpp>
-#include <SimulatedBlock.hpp>
-#include "Pool.hpp"
-#include "AsyncFile.hpp"
-#include "OpenFiles.hpp"
-
-
-
-// Because one NDB Signal request can result in multiple requests to
-// AsyncFile one class must be made responsible to keep track
-// of all out standing request and when all are finished the result
-// must be reported to the sending block.
-
-
-class Ndbfs : public SimulatedBlock
-{
-public:
- Ndbfs(Block_context&);
- virtual ~Ndbfs();
-
- virtual const char* get_filename(Uint32 fd) const;
-protected:
- BLOCK_DEFINES(Ndbfs);
-
- // The signal processing functions
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execFSOPENREQ(Signal* signal);
- void execFSCLOSEREQ(Signal* signal);
- void execFSWRITEREQ(Signal* signal);
- void execFSREADREQ(Signal* signal);
- void execFSSYNCREQ(Signal* signal);
- void execFSAPPENDREQ(Signal* signal);
- void execFSREMOVEREQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- bool scanningInProgress;
- Uint16 newId();
-
-private:
- int forward(AsyncFile *file, Request* Request);
- void report(Request* request, Signal* signal);
- bool scanIPC(Signal* signal);
-
- // Declared but not defined
- Ndbfs(Ndbfs & );
- void operator = (Ndbfs &);
-
- // Used for uniqe number generation
- Uint16 theLastId;
- BlockReference cownref;
-
- // Communication from files
- MemoryChannel<Request> theFromThreads;
-
- Pool<Request>* theRequestPool;
-
- AsyncFile* createAsyncFile();
- AsyncFile* getIdleFile();
-
- Vector<AsyncFile*> theFiles; // List all created AsyncFiles
- Vector<AsyncFile*> theIdleFiles; // List of idle AsyncFiles
- OpenFiles theOpenFiles; // List of open AsyncFiles
-
- BaseString theFileSystemPath;
- BaseString theBackupFilePath;
-
- // Statistics variables
- Uint32 m_maxOpenedFiles;
-
- // Limit for max number of AsyncFiles created
- Uint32 m_maxFiles;
-
- void readWriteRequest( int action, Signal * signal );
-
- static Uint32 translateErrno(int aErrno);
-};
-
-class VoidFs : public SimulatedBlock
-{
-public:
- VoidFs(Block_context&);
- virtual ~VoidFs();
-
-protected:
- BLOCK_DEFINES(VoidFs);
-
- // The signal processing functions
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execFSOPENREQ(Signal* signal);
- void execFSCLOSEREQ(Signal* signal);
- void execFSWRITEREQ(Signal* signal);
- void execFSREADREQ(Signal* signal);
- void execFSSYNCREQ(Signal* signal);
- void execFSAPPENDREQ(Signal* signal);
- void execFSREMOVEREQ(Signal* signal);
- void execSTTOR(Signal* signal);
-
-private:
- // Declared but not defined
- VoidFs(VoidFs & );
- void operator = (VoidFs &);
-
- // Used for uniqe number generation
- Uint32 c_maxFileNo;
-};
-
-#endif
-
-
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp b/storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp
deleted file mode 100644
index ed1e99a1409..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef OPENFILES_H
-#define OPENFILES_H
-
-#include <Vector.hpp>
-
-class OpenFiles
-{
-public:
- OpenFiles(){ }
-
- /* Get a pointer to the file with id */
- AsyncFile* find(Uint16 id) const;
- /* Insert file with id */
- bool insert(AsyncFile* file, Uint16 id);
- /* Erase file with id */
- bool erase(Uint16 id);
- /* Get number of open files */
- unsigned size();
-
- Uint16 getId(unsigned i);
- AsyncFile* getFile(unsigned i);
-
-
-private:
-
- class OpenFileItem {
- public:
- OpenFileItem(): m_file(NULL), m_id(0){};
-
- AsyncFile* m_file;
- Uint16 m_id;
- };
-
- Vector<OpenFileItem> m_files;
-};
-
-
-//*****************************************************************************
-inline AsyncFile* OpenFiles::find(Uint16 id) const {
- for (unsigned i = 0; i < m_files.size(); i++){
- if (m_files[i].m_id == id){
- return m_files[i].m_file;
- }
- }
- return NULL;
-}
-
-//*****************************************************************************
-inline bool OpenFiles::erase(Uint16 id){
- for (unsigned i = 0; i < m_files.size(); i++){
- if (m_files[i].m_id == id){
- m_files.erase(i);
- return true;
- }
- }
- // Item was not found in list
- return false;
-}
-
-
-//*****************************************************************************
-inline bool OpenFiles::insert(AsyncFile* file, Uint16 id){
- // Check if file has already been opened
- for (unsigned i = 0; i < m_files.size(); i++){
- if(m_files[i].m_file == NULL)
- continue;
-
- if(strcmp(m_files[i].m_file->theFileName.c_str(),
- file->theFileName.c_str()) == 0)
- {
- BaseString names;
- names.assfmt("open: >%s< existing: >%s<",
- file->theFileName.c_str(),
- m_files[i].m_file->theFileName.c_str());
- ERROR_SET(fatal, NDBD_EXIT_AFS_ALREADY_OPEN, names.c_str(),
- "OpenFiles::insert()");
- }
- }
-
- // Insert the file into vector
- OpenFileItem openFile;
- openFile.m_id = id;
- openFile.m_file = file;
- m_files.push_back(openFile);
-
- return true;
-}
-
-//*****************************************************************************
-inline Uint16 OpenFiles::getId(unsigned i){
- return m_files[i].m_id;
-}
-
-//*****************************************************************************
-inline AsyncFile* OpenFiles::getFile(unsigned i){
- return m_files[i].m_file;
-}
-
-//*****************************************************************************
-inline unsigned OpenFiles::size(){
- return m_files.size();
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp b/storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp
deleted file mode 100644
index e78167d2350..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef FOR_LIB_POOL_H
-#define FOR_LIB_POOL_H
-
-
-//===========================================================================
-//
-// .PUBLIC
-//
-//===========================================================================
-
-////////////////////////////////////////////////////////////////
-//
-// enum { defInitSize = 256, defIncSize = 64 };
-// Description: type to store initial and incremental size in.
-//
-////////////////////////////////////////////////////////////////
-//
-// Pool(int anInitSize = defInitSize, int anIncSize = defIncSize);
-// Description:
-// Constructor. Allocates anInitSize of objects <template argument>.
-// When the pool runs out of elements, anIncSize elements are added to the
-// pool. (When the pool is not optimized to allocate multiple elements
-// more efficient, the anIncSize MUST be set to 1 to get the best
-// performance...
-//
-// Parameters:
-// defInitSize: Initial size of the pool (# of elements in the pool)
-// defIncSize: # of elements added to the pool when a request to an empty
-// pool is made.
-// Return value:
-// _
-// Errors:
-// -
-// Asserts:
-// _
-//
-////////////////////////////////////////////////////////////////
-//
-// virtual ~Pool();
-// Description:
-// Elements in the pool are all deallocated.
-// Parameters:
-// _
-// Return value:
-// _
-// Errors:
-// -
-// Asserts:
-// theEmptyNodeList==0. No elements are in still in use.
-//
-////////////////////////////////////////////////////////////////
-//
-// T& get();
-// Description:
-// get's an element from the Pool.
-// Parameters:
-// _
-// Return value:
-// T& the element extracted from the Pool. (element must be cleared to
-// mimick newly created element)
-// Errors:
-// -
-// Asserts:
-// _
-//
-////////////////////////////////////////////////////////////////
-//
-// void put(T& aT);
-// Description:
-// Returns an element to the pool.
-// Parameters:
-// aT The element to put back in the pool
-// Return value:
-// void
-// Errors:
-// -
-// Asserts:
-// The pool has "empty" elements, to put element back in...
-//
-//===========================================================================
-//
-// .PRIVATE
-//
-//===========================================================================
-
-////////////////////////////////////////////////////////////////
-//
-// void allocate(int aSize);
-// Description:
-// add aSize elements to the pool
-// Parameters:
-// aSize: # of elements to add to the pool
-// Return value:
-// void
-// Errors:
-// -
-// Asserts:
-// _
-//
-////////////////////////////////////////////////////////////////
-//
-// void deallocate();
-// Description:
-// frees all elements kept in the pool.
-// Parameters:
-// _
-// Return value:
-// void
-// Errors:
-// -
-// Asserts:
-// No elements are "empty" i.e. in use.
-//
-//===========================================================================
-//
-// .PRIVATE
-//
-//===========================================================================
-
-////////////////////////////////////////////////////////////////
-//
-// Pool<T>& operator=(const Pool<T>& cp);
-// Description:
-// Prohibit use of assignement operator.
-// Parameters:
-// cp
-// Return value:
-// Pool<T>&
-// Asserts:
-// _
-//
-////////////////////////////////////////////////////////////////
-//
-// Pool(const Pool<T>& cp);
-// Description:
-// Prohibit use of default copy constructor.
-// Parameters:
-// cp
-// Return value:
-// _
-// Errors:
-// -
-// Asserts:
-// _
-//
-////////////////////////////////////////////////////////////////
-//
-// int initSize;
-// Description: size of the initial size of the pool
-//
-////////////////////////////////////////////////////////////////
-//
-// int incSize;
-// Description: # of elements added to the pool when pool is exhausted.
-//
-////////////////////////////////////////////////////////////////
-//
-// PoolElement<T>* theFullNodeList;
-// Description: List to contain all "unused" elements in the pool
-//
-////////////////////////////////////////////////////////////////
-//
-// PoolElement<T>* theEmptyNodeList;
-// Description: List to contain all "in use" elements in the pool
-//
-//-------------------------------------------------------------------------
-
-template <class T>
-class Pool
-{
-public:
- enum { defInitSize = 256, defIncSize = 64 };
-
- Pool(int anInitSize = defInitSize, int anIncSize = defIncSize) :
- theIncSize(anIncSize),
- theTop(0),
- theCurrentSize(0),
- theList(0)
- {
- allocate(anInitSize);
- }
-
- virtual ~Pool(void)
- {
- for (int i=0; i <theTop ; ++i)
- delete theList[i];
-
- delete []theList;
- }
-
- T* get();
- void put(T* aT);
-
- unsigned size(){ return theTop; };
-
-protected:
- void allocate(int aSize)
- {
- T** tList = theList;
- int i;
- theList = new T*[aSize+theCurrentSize];
- // allocate full list
- for (i = 0; i < theTop; i++) {
- theList[i] = tList[i];
- }
- delete []tList;
- for (; (theTop < aSize); theTop++){
- theList[theTop] = (T*)new T;
- }
- theCurrentSize += aSize;
- }
-
-private:
- Pool<T>& operator=(const Pool<T>& cp);
- Pool(const Pool<T>& cp);
-
- int theIncSize;
- int theTop;
- int theCurrentSize;
-
- T** theList;
-};
-
-//******************************************************************************
-template <class T> inline T* Pool<T>::get()
-{
- T* tmp;
- if( theTop == 0 )
- {
- allocate(theIncSize);
- }
- --theTop;
- tmp = theList[theTop];
- return tmp;
-}
-
-//
-//******************************************************************************
-template <class T> inline void Pool<T>::put(T* aT)
-{
- theList[theTop]= aT;
- ++theTop;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp b/storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp
deleted file mode 100644
index f2bf41b64b6..00000000000
--- a/storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <limits.h>
-#include <errno.h>
-
-#include "Ndbfs.hpp"
-#include "AsyncFile.hpp"
-#include "Filename.hpp"
-
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/FsAppendReq.hpp>
-#include <signaldata/FsRemoveReq.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/NdbfsContinueB.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-
-#include <RefConvert.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-#include <Configuration.hpp>
-
-#define DEBUG(x) { ndbout << "FS::" << x << endl; }
-
-VoidFs::VoidFs(Block_context & ctx) :
- SimulatedBlock(NDBFS, ctx)
-{
- BLOCK_CONSTRUCTOR(VoidFs);
-
- // Set received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &VoidFs::execREAD_CONFIG_REQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &VoidFs::execDUMP_STATE_ORD);
- addRecSignal(GSN_STTOR, &VoidFs::execSTTOR);
- addRecSignal(GSN_FSOPENREQ, &VoidFs::execFSOPENREQ);
- addRecSignal(GSN_FSCLOSEREQ, &VoidFs::execFSCLOSEREQ);
- addRecSignal(GSN_FSWRITEREQ, &VoidFs::execFSWRITEREQ);
- addRecSignal(GSN_FSREADREQ, &VoidFs::execFSREADREQ);
- addRecSignal(GSN_FSSYNCREQ, &VoidFs::execFSSYNCREQ);
- addRecSignal(GSN_FSAPPENDREQ, &VoidFs::execFSAPPENDREQ);
- addRecSignal(GSN_FSREMOVEREQ, &VoidFs::execFSREMOVEREQ);
- // Set send signals
-}
-
-VoidFs::~VoidFs()
-{
-}
-
-void
-VoidFs::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
-VoidFs::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- if(signal->theData[1] == 0){ // StartPhase 0
- jam();
- signal->theData[3] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 4, JBB);
- return;
- }
- ndbrequire(0);
-}
-
-void
-VoidFs::execFSOPENREQ(Signal* signal)
-{
- jamEntry();
- const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
- const BlockReference userRef = fsOpenReq->userReference;
- const Uint32 userPointer = fsOpenReq->userPointer;
-
- Uint32 flags = fsOpenReq->fileFlags;
- if(flags == FsOpenReq::OM_READONLY){
- // Initialise FsRef signal
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->errorCode = FsRef::fsErrFileDoesNotExist;
- fsRef->osErrorCode = ~0;
- sendSignal(userRef, GSN_FSOPENREF, signal, 3, JBB);
- return;
- }
-
- if(flags & FsOpenReq::OM_WRITEONLY || flags & FsOpenReq::OM_READWRITE){
- signal->theData[0] = userPointer;
- signal->theData[1] = c_maxFileNo++;
- sendSignal(userRef, GSN_FSOPENCONF, signal, 2, JBB);
- }
-}
-
-void
-VoidFs::execFSREMOVEREQ(Signal* signal)
-{
- jamEntry();
- const FsRemoveReq * const req = (FsRemoveReq *)signal->getDataPtr();
- const Uint32 userRef = req->userReference;
- const Uint32 userPointer = req->userPointer;
-
- signal->theData[0] = userPointer;
- sendSignal(userRef, GSN_FSREMOVECONF, signal, 1, JBB);
-}
-
-/*
- * PR0: File Pointer DR0: User reference DR1: User Pointer DR2: Flag bit 0= 1
- * remove file
- */
-void
-VoidFs::execFSCLOSEREQ(Signal * signal)
-{
- jamEntry();
-
- const FsCloseReq * const req = (FsCloseReq *)signal->getDataPtr();
- const Uint32 userRef = req->userReference;
- const Uint32 userPointer = req->userPointer;
-
- signal->theData[0] = userPointer;
- sendSignal(userRef, GSN_FSCLOSECONF, signal, 1, JBB);
-}
-
-void
-VoidFs::execFSWRITEREQ(Signal* signal)
-{
- jamEntry();
- const FsReadWriteReq * const req = (FsReadWriteReq *)signal->getDataPtr();
- const Uint32 userRef = req->userReference;
- const Uint32 userPointer = req->userPointer;
-
- signal->theData[0] = userPointer;
- sendSignal(userRef, GSN_FSWRITECONF, signal, 1, JBB);
-}
-
-void
-VoidFs::execFSREADREQ(Signal* signal)
-{
- jamEntry();
-
- const FsReadWriteReq * const req = (FsReadWriteReq *)signal->getDataPtr();
- const Uint32 userRef = req->userReference;
- const Uint32 userPointer = req->userPointer;
-
- signal->theData[0] = userPointer;
- sendSignal(userRef, GSN_FSREADCONF, signal, 1, JBB);
-#if 0
- FsRef * const fsRef = (FsRef *)&signal->theData[0];
- fsRef->userPointer = userPointer;
- fsRef->errorCode = FsRef::fsErrEnvironmentError;
- fsRef->osErrorCode = ~0; // Indicate local error
- sendSignal(userRef, GSN_FSREADREF, signal, 3, JBB);
-#endif
-}
-
-void
-VoidFs::execFSSYNCREQ(Signal * signal)
-{
- jamEntry();
-
- BlockReference userRef = signal->theData[1];
- const UintR userPointer = signal->theData[2];
-
- signal->theData[0] = userPointer;
- sendSignal(userRef, GSN_FSSYNCCONF, signal, 1, JBB);
-
- return;
-}
-
-void
-VoidFs::execFSAPPENDREQ(Signal * signal)
-{
- const FsAppendReq * const fsReq = (FsAppendReq *)&signal->theData[0];
- const UintR userPointer = fsReq->userPointer;
- const BlockReference userRef = fsReq->userReference;
- const Uint32 size = fsReq->size;
-
- signal->theData[0] = userPointer;
- signal->theData[1] = size << 2;
- sendSignal(userRef, GSN_FSAPPENDCONF, signal, 2, JBB);
-}
-
-void
-VoidFs::execDUMP_STATE_ORD(Signal* signal)
-{
-}//VoidFs::execDUMP_STATE_ORD()
-
-
-
-BLOCK_FUNCTIONS(VoidFs)
-
diff --git a/storage/ndb/src/kernel/blocks/new-block.tar.gz b/storage/ndb/src/kernel/blocks/new-block.tar.gz
deleted file mode 100644
index 327503ea0b1..00000000000
--- a/storage/ndb/src/kernel/blocks/new-block.tar.gz
+++ /dev/null
Binary files differ
diff --git a/storage/ndb/src/kernel/blocks/pgman.cpp b/storage/ndb/src/kernel/blocks/pgman.cpp
deleted file mode 100644
index 9d184f7401b..00000000000
--- a/storage/ndb/src/kernel/blocks/pgman.cpp
+++ /dev/null
@@ -1,2514 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "pgman.hpp"
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/PgmanContinueB.hpp>
-#include <signaldata/LCP.hpp>
-
-#include <dbtup/Dbtup.hpp>
-
-#include <DebuggerNames.hpp>
-
-/**
- * Requests that make page dirty
- */
-#define DIRTY_FLAGS (Page_request::COMMIT_REQ | \
- Page_request::DIRTY_REQ | \
- Page_request::ALLOC_REQ)
-
-// todo use this
-#ifdef VM_TRACE
-#define dbg(x) \
- do { if (! debugFlag) break; debugOut << "PGMAN: " << x << endl; } while (0)
-#else
-#define dbg(x)
-#endif
-
-static bool g_dbg_lcp = false;
-#if 1
-#define DBG_LCP(x)
-#else
-#define DBG_LCP(x) if(g_dbg_lcp) ndbout << x
-#endif
-
-Pgman::Pgman(Block_context& ctx) :
- SimulatedBlock(PGMAN, ctx),
- m_file_map(m_data_buffer_pool),
- m_page_hashlist(m_page_entry_pool),
- m_page_stack(m_page_entry_pool),
- m_page_queue(m_page_entry_pool)
-#ifdef VM_TRACE
- ,debugOut(* new NullOutputStream())
- ,debugFlag(false)
-#endif
-{
- BLOCK_CONSTRUCTOR(Pgman);
-
- // Add received signals
- addRecSignal(GSN_STTOR, &Pgman::execSTTOR);
- addRecSignal(GSN_READ_CONFIG_REQ, &Pgman::execREAD_CONFIG_REQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &Pgman::execDUMP_STATE_ORD);
- addRecSignal(GSN_CONTINUEB, &Pgman::execCONTINUEB);
- addRecSignal(GSN_FSREADREF, &Pgman::execFSREADREF, true);
- addRecSignal(GSN_FSREADCONF, &Pgman::execFSREADCONF);
- addRecSignal(GSN_FSWRITEREF, &Pgman::execFSWRITEREF, true);
- addRecSignal(GSN_FSWRITECONF, &Pgman::execFSWRITECONF);
-
- addRecSignal(GSN_LCP_FRAG_ORD, &Pgman::execLCP_FRAG_ORD);
- addRecSignal(GSN_END_LCP_REQ, &Pgman::execEND_LCP_REQ);
-
- // loop status
- m_stats_loop_on = false;
- m_busy_loop_on = false;
- m_cleanup_loop_on = false;
- m_lcp_loop_on = false;
-
- // LCP variables
- m_last_lcp = 0;
- m_last_lcp_complete = 0;
- m_lcp_curr_bucket = ~(Uint32)0;
- m_lcp_outstanding = 0;
-
- // clean-up variables
- m_cleanup_ptr.i = RNIL;
-
- // should be a factor larger than number of pool pages
- m_data_buffer_pool.setSize(16);
- m_page_hashlist.setSize(512);
-
- for (Uint32 k = 0; k < Page_entry::SUBLIST_COUNT; k++)
- m_page_sublist[k] = new Page_sublist(m_page_entry_pool);
-}
-
-Pgman::~Pgman()
-{
- for (Uint32 k = 0; k < Page_entry::SUBLIST_COUNT; k++)
- delete m_page_sublist[k];
-}
-
-BLOCK_FUNCTIONS(Pgman)
-
-void
-Pgman::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint64 page_buffer = 64*1024*1024;
- ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
-
- if (page_buffer > 0)
- {
- page_buffer = (page_buffer + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE; // in pages
- m_param.m_max_pages = page_buffer;
- m_page_entry_pool.setSize(m_param.m_lirs_stack_mult * page_buffer);
- m_param.m_max_hot_pages = (page_buffer * 9) / 10;
- }
-
- Pool_context pc;
- pc.m_block = this;
- m_page_request_pool.wo_pool_init(RT_PGMAN_PAGE_REQUEST, pc);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-Pgman::Param::Param() :
- m_max_pages(64), // smallish for testing
- m_lirs_stack_mult(10),
- m_max_hot_pages(56),
- m_max_loop_count(256),
- m_max_io_waits(256),
- m_stats_loop_delay(1000),
- m_cleanup_loop_delay(200),
- m_lcp_loop_delay(0)
-{
-}
-
-Pgman::Stats::Stats() :
- m_num_pages(0),
- m_page_hits(0),
- m_page_faults(0),
- m_current_io_waits(0)
-{
-}
-
-void
-Pgman::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- const Uint32 startPhase = signal->theData[1];
-
- switch (startPhase) {
- case 1:
- {
- Lgman* lgman = (Lgman*)globalData.getBlock(LGMAN);
- new (&m_lgman) Logfile_client(this, lgman, 0);
- c_tup = (Dbtup*)globalData.getBlock(DBTUP);
- }
- break;
- case 3:
- {
- // start forever loops
- do_stats_loop(signal);
- do_cleanup_loop(signal);
- m_stats_loop_on = true;
- m_cleanup_loop_on = true;
- }
- break;
- case 7:
- break;
- default:
- break;
- }
-
- sendSTTORRY(signal);
-}
-
-void
-Pgman::sendSTTORRY(Signal* signal)
-{
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 3;
- signal->theData[5] = 7;
- signal->theData[6] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);
-}
-
-void
-Pgman::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- Uint32 data1 = signal->theData[1];
-
- switch (signal->theData[0]) {
- case PgmanContinueB::STATS_LOOP:
- jam();
- do_stats_loop(signal);
- break;
- case PgmanContinueB::BUSY_LOOP:
- jam();
- do_busy_loop(signal);
- break;
- case PgmanContinueB::CLEANUP_LOOP:
- jam();
- do_cleanup_loop(signal);
- break;
- case PgmanContinueB::LCP_LOOP:
- jam();
- do_lcp_loop(signal);
- break;
- case PgmanContinueB::LCP_LOCKED:
- {
- jam();
- Ptr<Page_entry> ptr;
- Page_sublist& pl = *m_page_sublist[Page_entry::SL_LOCKED];
- if (data1 != RNIL)
- {
- pl.getPtr(ptr, data1);
- process_lcp_locked(signal, ptr);
- }
- else
- {
- if (ERROR_INSERTED(11007))
- {
- ndbout << "No more writes..." << endl;
- SET_ERROR_INSERT_VALUE(11008);
- signal->theData[0] = 9999;
- sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 10000, 1);
- }
- signal->theData[0] = m_end_lcp_req.senderData;
- sendSignal(m_end_lcp_req.senderRef, GSN_END_LCP_CONF, signal, 1, JBB);
- }
- return;
- }
- default:
- ndbrequire(false);
- break;
- }
-}
-
-// page entry
-
-Pgman::Page_entry::Page_entry(Uint32 file_no, Uint32 page_no) :
- m_file_no(file_no),
- m_state(0),
- m_page_no(page_no),
- m_real_page_i(RNIL),
- m_lsn(0),
- m_last_lcp(0),
- m_dirty_count(0),
- m_copy_page_i(RNIL),
- m_busy_count(0),
- m_requests()
-{
-}
-
-// page lists
-
-Uint32
-Pgman::get_sublist_no(Page_state state)
-{
- if (state == 0)
- {
- return ZNIL;
- }
- if (state & Page_entry::REQUEST)
- {
- if (! (state & Page_entry::BOUND))
- {
- return Page_entry::SL_BIND;
- }
- if (! (state & Page_entry::MAPPED))
- {
- if (! (state & Page_entry::PAGEIN))
- {
- return Page_entry::SL_MAP;
- }
- return Page_entry::SL_MAP_IO;
- }
- if (! (state & Page_entry::PAGEOUT))
- {
- return Page_entry::SL_CALLBACK;
- }
- return Page_entry::SL_CALLBACK_IO;
- }
- if (state & Page_entry::BUSY)
- {
- return Page_entry::SL_BUSY;
- }
- if (state & Page_entry::LOCKED)
- {
- return Page_entry::SL_LOCKED;
- }
- if (state == Page_entry::ONSTACK) {
- return Page_entry::SL_IDLE;
- }
- return Page_entry::SL_OTHER;
-}
-
-void
-Pgman::set_page_state(Ptr<Page_entry> ptr, Page_state new_state)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >set_page_state: state=" << hex << new_state << endl;
- debugOut << "PGMAN: " << ptr << ": before" << endl;
-#endif
-
- Page_state old_state = ptr.p->m_state;
- if (old_state != new_state)
- {
- Uint32 old_list_no = get_sublist_no(old_state);
- Uint32 new_list_no = get_sublist_no(new_state);
- if (old_state != 0)
- {
- ndbrequire(old_list_no != ZNIL);
- if (old_list_no != new_list_no)
- {
- Page_sublist& old_list = *m_page_sublist[old_list_no];
- old_list.remove(ptr);
- }
- }
- if (new_state != 0)
- {
- ndbrequire(new_list_no != ZNIL);
- if (old_list_no != new_list_no)
- {
- Page_sublist& new_list = *m_page_sublist[new_list_no];
- new_list.add(ptr);
- }
- }
- ptr.p->m_state = new_state;
- }
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << ": after" << endl;
- debugOut << "PGMAN: <set_page_state" << endl;
-#endif
-}
-
-// seize/release pages and entries
-
-bool
-Pgman::seize_cache_page(Ptr<GlobalPage>& gptr)
-{
- // page cache has no own pool yet
- bool ok = m_global_page_pool.seize(gptr);
-
- // zero is reserved as return value for queued request
- if (ok && gptr.i == 0)
- ok = m_global_page_pool.seize(gptr);
-
- if (ok)
- {
- ndbrequire(m_stats.m_num_pages < m_param.m_max_pages);
- m_stats.m_num_pages++;
- }
- return ok;
-}
-
-void
-Pgman::release_cache_page(Uint32 i)
-{
- m_global_page_pool.release(i);
-
- ndbrequire(m_stats.m_num_pages != 0);
- m_stats.m_num_pages--;
-}
-
-bool
-Pgman::find_page_entry(Ptr<Page_entry>& ptr, Uint32 file_no, Uint32 page_no)
-{
- Page_entry key;
- key.m_file_no = file_no;
- key.m_page_no = page_no;
-
- if (m_page_hashlist.find(ptr, key))
- {
-#ifdef VM_TRACE
- debugOut << "PGMAN: find_page_entry" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- return true;
- }
- return false;
-}
-
-Uint32
-Pgman::seize_page_entry(Ptr<Page_entry>& ptr, Uint32 file_no, Uint32 page_no)
-{
- if (m_page_entry_pool.seize(ptr))
- {
- new (ptr.p) Page_entry(file_no, page_no);
- m_page_hashlist.add(ptr);
-
-#ifdef VM_TRACE
- ptr.p->m_this = this;
- debugOut << "PGMAN: seize_page_entry" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- return true;
- }
- return false;
-}
-
-bool
-Pgman::get_page_entry(Ptr<Page_entry>& ptr, Uint32 file_no, Uint32 page_no)
-{
- if (find_page_entry(ptr, file_no, page_no))
- {
- jam();
- ndbrequire(ptr.p->m_state != 0);
- m_stats.m_page_hits++;
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: get_page_entry: found" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- return true;
- }
-
- if (m_page_entry_pool.getNoOfFree() == 0)
- {
- jam();
- Page_sublist& pl_idle = *m_page_sublist[Page_entry::SL_IDLE];
- Ptr<Page_entry> idle_ptr;
- if (pl_idle.first(idle_ptr))
- {
- jam();
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: get_page_entry: re-use idle entry" << endl;
- debugOut << "PGMAN: " << idle_ptr << endl;
-#endif
-
- Page_state state = idle_ptr.p->m_state;
- ndbrequire(state == Page_entry::ONSTACK);
-
- Page_stack& pl_stack = m_page_stack;
- ndbrequire(pl_stack.hasPrev(idle_ptr));
- pl_stack.remove(idle_ptr);
- state &= ~ Page_entry::ONSTACK;
- set_page_state(idle_ptr, state);
- ndbrequire(idle_ptr.p->m_state == 0);
-
- release_page_entry(idle_ptr);
- }
- }
-
- if (seize_page_entry(ptr, file_no, page_no))
- {
- jam();
- ndbrequire(ptr.p->m_state == 0);
- m_stats.m_page_faults++;
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: get_page_entry: seize" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- return true;
- }
-
- ndbrequire(false);
-
- return false;
-}
-
-void
-Pgman::release_page_entry(Ptr<Page_entry>& ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: release_page_entry" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- Page_state state = ptr.p->m_state;
-
- ndbrequire(ptr.p->m_requests.isEmpty());
-
- ndbrequire(! (state & Page_entry::ONSTACK));
- ndbrequire(! (state & Page_entry::ONQUEUE));
- ndbrequire(ptr.p->m_real_page_i == RNIL);
-
- if (! (state & Page_entry::LOCKED))
- ndbrequire(! (state & Page_entry::REQUEST));
-
- if (ptr.p->m_copy_page_i != RNIL)
- {
- m_global_page_pool.release(ptr.p->m_copy_page_i);
- }
-
- set_page_state(ptr, 0);
- m_page_hashlist.remove(ptr);
- m_page_entry_pool.release(ptr);
-}
-
-// LIRS
-
-/*
- * After the hot entry at stack bottom is removed, additional entries
- * are removed until next hot entry is found. There are 3 cases for the
- * removed entry: 1) a bound entry is already on queue 2) an unbound
- * entry with open requests enters queue at bind time 3) an unbound
- * entry without requests is returned to entry pool.
- */
-void
-Pgman::lirs_stack_prune()
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >lirs_stack_prune" << endl;
-#endif
- Page_stack& pl_stack = m_page_stack;
- Ptr<Page_entry> ptr;
-
- while (pl_stack.first(ptr)) // first is stack bottom
- {
- Page_state state = ptr.p->m_state;
- if (state & Page_entry::HOT)
- {
- jam();
- break;
- }
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << ": prune from stack" << endl;
-#endif
-
- pl_stack.remove(ptr);
- state &= ~ Page_entry::ONSTACK;
- set_page_state(ptr, state);
-
- if (state & Page_entry::BOUND)
- {
- jam();
- ndbrequire(state & Page_entry::ONQUEUE);
- }
- else if (state & Page_entry::REQUEST)
- {
- // enters queue at bind
- jam();
- ndbrequire(! (state & Page_entry::ONQUEUE));
- }
- else
- {
- jam();
- release_page_entry(ptr);
- }
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <lirs_stack_prune" << endl;
-#endif
-}
-
-/*
- * Remove the hot entry at stack bottom and make it cold and do stack
- * pruning. There are 2 cases for the removed entry: 1) a bound entry
- * is moved to queue 2) an unbound entry must have requests and enters
- * queue at bind time.
- */
-void
-Pgman::lirs_stack_pop()
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: lirs_stack_pop" << endl;
-#endif
- Page_stack& pl_stack = m_page_stack;
- Page_queue& pl_queue = m_page_queue;
-
- Ptr<Page_entry> ptr;
- bool ok = pl_stack.first(ptr);
- ndbrequire(ok);
- Page_state state = ptr.p->m_state;
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << ": pop from stack" << endl;
-#endif
-
- ndbrequire(state & Page_entry::HOT);
- ndbrequire(state & Page_entry::ONSTACK);
- pl_stack.remove(ptr);
- state &= ~ Page_entry::HOT;
- state &= ~ Page_entry::ONSTACK;
- ndbrequire(! (state & Page_entry::ONQUEUE));
-
- if (state & Page_entry::BOUND)
- {
- jam();
- pl_queue.add(ptr);
- state |= Page_entry::ONQUEUE;
- }
- else
- {
- // enters queue at bind
- jam();
- ndbrequire(state & Page_entry::REQUEST);
- }
-
- set_page_state(ptr, state);
- lirs_stack_prune();
-}
-
-/*
- * Update LIRS lists when page is referenced.
- */
-void
-Pgman::lirs_reference(Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >lirs_reference" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- Page_stack& pl_stack = m_page_stack;
- Page_queue& pl_queue = m_page_queue;
-
- Page_state state = ptr.p->m_state;
- ndbrequire(! (state & Page_entry::LOCKED));
-
- // even non-LIRS cache pages are counted on l.h.s.
- if (m_stats.m_num_pages >= m_param.m_max_hot_pages)
- {
- if (state & Page_entry::HOT)
- {
- // case 1
- jam();
- ndbrequire(state & Page_entry::ONSTACK);
- bool at_bottom = ! pl_stack.hasPrev(ptr);
- pl_stack.remove(ptr);
- pl_stack.add(ptr);
- if (at_bottom)
- {
- jam();
- lirs_stack_prune();
- }
- }
- else if (state & Page_entry::ONSTACK)
- {
- // case 2a 3a
- jam();
- pl_stack.remove(ptr);
- if (! pl_stack.isEmpty())
- {
- jam();
- lirs_stack_pop();
- }
- pl_stack.add(ptr);
- state |= Page_entry::HOT;
- if (state & Page_entry::ONQUEUE)
- {
- jam();
- move_cleanup_ptr(ptr);
- pl_queue.remove(ptr);
- state &= ~ Page_entry::ONQUEUE;
- }
- }
- else
- {
- // case 2b 3b
- jam();
- pl_stack.add(ptr);
- state |= Page_entry::ONSTACK;
- if (state & Page_entry::ONQUEUE)
- {
- jam();
- move_cleanup_ptr(ptr);
- pl_queue.remove(ptr);
- state &= ~ Page_entry::ONQUEUE;
- }
- if (state & Page_entry::BOUND)
- {
- jam();
- pl_queue.add(ptr);
- state |= Page_entry::ONQUEUE;
- }
- else
- {
- // enters queue at bind
- jam();
- }
- }
- }
- else
- {
-#ifdef VM_TRACE
- debugOut << "PGMAN: filling up initial hot pages: "
- << m_stats.m_num_pages << " of "
- << m_param.m_max_hot_pages << endl;
-#endif
- jam();
- if (state & Page_entry::ONSTACK)
- {
- jam();
- bool at_bottom = ! pl_stack.hasPrev(ptr);
- pl_stack.remove(ptr);
- if (at_bottom)
- {
- jam();
- ndbassert(state & Page_entry::HOT);
- lirs_stack_prune();
- }
- }
- pl_stack.add(ptr);
- state |= Page_entry::ONSTACK;
- state |= Page_entry::HOT;
- // it could be on queue already
- if (state & Page_entry::ONQUEUE) {
- jam();
- pl_queue.remove(ptr);
- state &= ~Page_entry::ONQUEUE;
- }
- }
-
- set_page_state(ptr, state);
-#ifdef VM_TRACE
- debugOut << "PGMAN: <lirs_reference" << endl;
-#endif
-}
-
-// continueB loops
-
-void
-Pgman::do_stats_loop(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: do_stats_loop" << endl;
- verify_all();
-#endif
- Uint32 delay = m_param.m_stats_loop_delay;
- signal->theData[0] = PgmanContinueB::STATS_LOOP;
- sendSignalWithDelay(PGMAN_REF, GSN_CONTINUEB, signal, delay, 1);
-}
-
-void
-Pgman::do_busy_loop(Signal* signal, bool direct)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >do_busy_loop on=" << m_busy_loop_on
- << " direct=" << direct << endl;
-#endif
- Uint32 restart = false;
- if (direct)
- {
- // may not cover the calling entry
- (void)process_bind(signal);
- (void)process_map(signal);
- // callback must be queued
- if (! m_busy_loop_on)
- {
- restart = true;
- m_busy_loop_on = true;
- }
- }
- else
- {
- ndbrequire(m_busy_loop_on);
- restart += process_bind(signal);
- restart += process_map(signal);
- restart += process_callback(signal);
- if (! restart)
- {
- m_busy_loop_on = false;
- }
- }
- if (restart)
- {
- signal->theData[0] = PgmanContinueB::BUSY_LOOP;
- sendSignal(PGMAN_REF, GSN_CONTINUEB, signal, 1, JBB);
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <do_busy_loop on=" << m_busy_loop_on
- << " restart=" << restart << endl;
-#endif
-}
-
-void
-Pgman::do_cleanup_loop(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: do_cleanup_loop" << endl;
-#endif
- process_cleanup(signal);
-
- Uint32 delay = m_param.m_cleanup_loop_delay;
- signal->theData[0] = PgmanContinueB::CLEANUP_LOOP;
- sendSignalWithDelay(PGMAN_REF, GSN_CONTINUEB, signal, delay, 1);
-}
-
-void
-Pgman::do_lcp_loop(Signal* signal, bool direct)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >do_lcp_loop on=" << m_lcp_loop_on
- << " direct=" << direct << endl;
-#endif
- Uint32 restart = false;
- if (direct)
- {
- ndbrequire(! m_lcp_loop_on);
- restart = true;
- m_lcp_loop_on = true;
- }
- else
- {
- ndbrequire(m_lcp_loop_on);
- restart += process_lcp(signal);
- if (! restart)
- {
- m_lcp_loop_on = false;
- }
- }
- if (restart)
- {
- Uint32 delay = m_param.m_lcp_loop_delay;
- signal->theData[0] = PgmanContinueB::LCP_LOOP;
- if (delay)
- sendSignalWithDelay(PGMAN_REF, GSN_CONTINUEB, signal, delay, 1);
- else
- sendSignal(PGMAN_REF, GSN_CONTINUEB, signal, 1, JBB);
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <do_lcp_loop on=" << m_lcp_loop_on
- << " restart=" << restart << endl;
-#endif
-}
-
-// busy loop
-
-bool
-Pgman::process_bind(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >process_bind" << endl;
-#endif
- int max_count = 32;
- Page_sublist& pl_bind = *m_page_sublist[Page_entry::SL_BIND];
-
- while (! pl_bind.isEmpty() && --max_count >= 0)
- {
- jam();
- Ptr<Page_entry> ptr;
- pl_bind.first(ptr);
- if (! process_bind(signal, ptr))
- {
- jam();
- break;
- }
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <process_bind" << endl;
-#endif
- return ! pl_bind.isEmpty();
-}
-
-bool
-Pgman::process_bind(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << " : process_bind" << endl;
-#endif
- Page_queue& pl_queue = m_page_queue;
- Ptr<GlobalPage> gptr;
-
- if (m_stats.m_num_pages < m_param.m_max_pages)
- {
- jam();
- bool ok = seize_cache_page(gptr);
- // to handle failure requires some changes in LIRS
- ndbrequire(ok);
- }
- else
- {
- jam();
- Ptr<Page_entry> clean_ptr;
- if (! pl_queue.first(clean_ptr))
- {
- jam();
-#ifdef VM_TRACE
- debugOut << "PGMAN: bind failed: queue empty" << endl;
-#endif
- // XXX busy loop
- return false;
- }
- Page_state clean_state = clean_ptr.p->m_state;
- // under unusual circumstances it could still be paging in
- if (! (clean_state & Page_entry::MAPPED) ||
- clean_state & Page_entry::DIRTY ||
- clean_state & Page_entry::REQUEST)
- {
- jam();
-#ifdef VM_TRACE
- debugOut << "PGMAN: bind failed: queue front not evictable" << endl;
- debugOut << "PGMAN: " << clean_ptr << endl;
-#endif
- // XXX busy loop
- return false;
- }
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << clean_ptr << " : evict" << endl;
-#endif
-
- ndbassert(clean_ptr.p->m_dirty_count == 0);
- ndbrequire(clean_state & Page_entry::ONQUEUE);
- ndbrequire(clean_state & Page_entry::BOUND);
- ndbrequire(clean_state & Page_entry::MAPPED);
-
- move_cleanup_ptr(clean_ptr);
- pl_queue.remove(clean_ptr);
- clean_state &= ~ Page_entry::ONQUEUE;
-
- gptr.i = clean_ptr.p->m_real_page_i;
-
- clean_ptr.p->m_real_page_i = RNIL;
- clean_state &= ~ Page_entry::BOUND;
- clean_state &= ~ Page_entry::MAPPED;
-
- set_page_state(clean_ptr, clean_state);
-
- if (! (clean_state & Page_entry::ONSTACK))
- release_page_entry(clean_ptr);
-
- m_global_page_pool.getPtr(gptr);
- }
-
- Page_state state = ptr.p->m_state;
-
- ptr.p->m_real_page_i = gptr.i;
- state |= Page_entry::BOUND;
- if (state & Page_entry::EMPTY)
- {
- jam();
- state |= Page_entry::MAPPED;
- }
-
- if (! (state & Page_entry::LOCKED) &&
- ! (state & Page_entry::ONQUEUE) &&
- ! (state & Page_entry::HOT))
- {
- jam();
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << " : add to queue at bind" << endl;
-#endif
-
- pl_queue.add(ptr);
- state |= Page_entry::ONQUEUE;
- }
-
- set_page_state(ptr, state);
- return true;
-}
-
-bool
-Pgman::process_map(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >process_map" << endl;
-#endif
- int max_count = 0;
- if (m_param.m_max_io_waits > m_stats.m_current_io_waits) {
- max_count = m_param.m_max_io_waits - m_stats.m_current_io_waits;
- max_count = max_count / 2 + 1;
- }
- Page_sublist& pl_map = *m_page_sublist[Page_entry::SL_MAP];
-
- while (! pl_map.isEmpty() && --max_count >= 0)
- {
- jam();
- Ptr<Page_entry> ptr;
- pl_map.first(ptr);
- if (! process_map(signal, ptr))
- {
- jam();
- break;
- }
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <process_map" << endl;
-#endif
- return ! pl_map.isEmpty();
-}
-
-bool
-Pgman::process_map(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << " : process_map" << endl;
-#endif
- pagein(signal, ptr);
- return true;
-}
-
-bool
-Pgman::process_callback(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >process_callback" << endl;
-#endif
- int max_count = 1;
- Page_sublist& pl_callback = *m_page_sublist[Page_entry::SL_CALLBACK];
-
- Ptr<Page_entry> ptr;
- pl_callback.first(ptr);
-
- while (! ptr.isNull() && --max_count >= 0)
- {
- jam();
- Ptr<Page_entry> curr = ptr;
- pl_callback.next(ptr);
-
- if (! process_callback(signal, curr))
- {
- jam();
- break;
- }
- }
-#ifdef VM_TRACE
- debugOut << "PGMAN: <process_callback" << endl;
-#endif
- return ! pl_callback.isEmpty();
-}
-
-bool
-Pgman::process_callback(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << " : process_callback" << endl;
-#endif
- int max_count = 1;
- Page_state state = ptr.p->m_state;
-
- while (! ptr.p->m_requests.isEmpty() && --max_count >= 0)
- {
- jam();
- SimulatedBlock* b;
- Callback callback;
- {
- /**
- * Make sure list is in own scope if callback will access this
- * list again (destructor restores list head).
- */
- Local_page_request_list req_list(m_page_request_pool, ptr.p->m_requests);
- Ptr<Page_request> req_ptr;
-
- req_list.first(req_ptr);
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << req_ptr << " : process_callback" << endl;
-#endif
-
-#ifdef ERROR_INSERT
- if (req_ptr.p->m_flags & Page_request::DELAY_REQ)
- {
- Uint64 now = NdbTick_CurrentMillisecond();
- if (now < req_ptr.p->m_delay_until_time)
- {
- break;
- }
- }
-#endif
-
- b = globalData.getBlock(req_ptr.p->m_block);
- callback = req_ptr.p->m_callback;
-
- if (req_ptr.p->m_flags & DIRTY_FLAGS)
- {
- jam();
- state |= Page_entry::DIRTY;
- ndbassert(ptr.p->m_dirty_count);
- ptr.p->m_dirty_count --;
- }
-
- req_list.releaseFirst(req_ptr);
- }
- ndbrequire(state & Page_entry::BOUND);
- ndbrequire(state & Page_entry::MAPPED);
-
- // callback may re-enter PGMAN and change page state
- set_page_state(ptr, state);
- b->execute(signal, callback, ptr.p->m_real_page_i);
- state = ptr.p->m_state;
- }
-
- if (ptr.p->m_requests.isEmpty())
- {
- jam();
- state &= ~ Page_entry::REQUEST;
- }
- set_page_state(ptr, state);
- return true;
-}
-
-// cleanup loop
-
-bool
-Pgman::process_cleanup(Signal* signal)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: >process_cleanup" << endl;
-#endif
- Page_queue& pl_queue = m_page_queue;
-
- // XXX for now start always from beginning
- m_cleanup_ptr.i = RNIL;
-
- if (m_cleanup_ptr.i == RNIL && ! pl_queue.first(m_cleanup_ptr))
- {
- jam();
-#ifdef VM_TRACE
- debugOut << "PGMAN: <process_cleanup: empty queue" << endl;
-#endif
- return false;
- }
-
- int max_loop_count = m_param.m_max_loop_count;
- int max_count = 0;
- if (m_param.m_max_io_waits > m_stats.m_current_io_waits) {
- max_count = m_param.m_max_io_waits - m_stats.m_current_io_waits;
- max_count = max_count / 2 + 1;
- }
-
- Ptr<Page_entry> ptr = m_cleanup_ptr;
- while (max_loop_count != 0 && max_count != 0)
- {
- Page_state state = ptr.p->m_state;
- ndbrequire(! (state & Page_entry::LOCKED));
- if (state & Page_entry::BUSY)
- {
-#ifdef VM_TRACE
- debugOut << "PGMAN: process_cleanup: break on busy page" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- break;
- }
- if (state & Page_entry::DIRTY &&
- ! (state & Page_entry::PAGEIN) &&
- ! (state & Page_entry::PAGEOUT))
- {
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << " : process_cleanup" << endl;
-#endif
- c_tup->disk_page_unmap_callback(0,
- ptr.p->m_real_page_i,
- ptr.p->m_dirty_count);
- pageout(signal, ptr);
- max_count--;
- }
- if (! pl_queue.hasNext(ptr))
- break;
- pl_queue.next(ptr);
- max_loop_count--;
- }
- m_cleanup_ptr = ptr;
-#ifdef VM_TRACE
- debugOut << "PGMAN: <process_cleanup" << endl;
-#endif
- return true;
-}
-
-/*
- * Call this before queue.remove(ptr). If the removed entry is the
- * clean-up pointer, move it towards front.
- */
-void
-Pgman::move_cleanup_ptr(Ptr<Page_entry> ptr)
-{
- Page_queue& pl_queue = m_page_queue;
- if (ptr.i == m_cleanup_ptr.i)
- {
- jam();
- pl_queue.prev(m_cleanup_ptr);
- }
-}
-
-// LCP
-
-
-void
-Pgman::execLCP_FRAG_ORD(Signal* signal)
-{
- if (ERROR_INSERTED(11008))
- {
- ndbout_c("Ignore LCP_FRAG_ORD");
- return;
- }
- LcpFragOrd* ord = (LcpFragOrd*)signal->getDataPtr();
- ndbrequire(ord->lcpId >= m_last_lcp_complete + 1 || m_last_lcp_complete == 0);
- m_last_lcp = ord->lcpId;
- DBG_LCP("Pgman::execLCP_FRAG_ORD lcp: " << m_last_lcp << endl);
-
-#ifdef VM_TRACE
- debugOut
- << "PGMAN: execLCP_FRAG_ORD"
- << " this=" << m_last_lcp << " last_complete=" << m_last_lcp_complete
- << " bucket=" << m_lcp_curr_bucket << endl;
-#endif
-}
-
-void
-Pgman::execEND_LCP_REQ(Signal* signal)
-{
- if (ERROR_INSERTED(11008))
- {
- ndbout_c("Ignore END_LCP");
- return;
- }
-
- EndLcpReq* req = (EndLcpReq*)signal->getDataPtr();
- m_end_lcp_req = *req;
-
- DBG_LCP("execEND_LCP_REQ" << endl);
-
- ndbrequire(!m_lcp_outstanding);
- m_lcp_curr_bucket = 0;
-
-#ifdef VM_TRACE
- debugOut
- << "PGMAN: execEND_LCP_REQ"
- << " this=" << m_last_lcp << " last_complete=" << m_last_lcp_complete
- << " bucket=" << m_lcp_curr_bucket
- << " outstanding=" << m_lcp_outstanding << endl;
-#endif
-
- m_last_lcp_complete = m_last_lcp;
-
- do_lcp_loop(signal, true);
-}
-
-bool
-Pgman::process_lcp(Signal* signal)
-{
- Page_hashlist& pl_hash = m_page_hashlist;
-
- int max_count = 0;
- if (m_param.m_max_io_waits > m_stats.m_current_io_waits) {
- max_count = m_param.m_max_io_waits - m_stats.m_current_io_waits;
- max_count = max_count / 2 + 1;
- }
-
-#ifdef VM_TRACE
- debugOut
- << "PGMAN: process_lcp"
- << " this=" << m_last_lcp << " last_complete=" << m_last_lcp_complete
- << " bucket=" << m_lcp_curr_bucket
- << " outstanding=" << m_lcp_outstanding << endl;
-#endif
-
- // start or re-start from beginning of current hash bucket
- if (m_lcp_curr_bucket != ~(Uint32)0)
- {
- Page_hashlist::Iterator iter;
- pl_hash.next(m_lcp_curr_bucket, iter);
- Uint32 loop = 0;
- while (iter.curr.i != RNIL &&
- m_lcp_outstanding < (Uint32) max_count &&
- (loop ++ < 32 || iter.bucket == m_lcp_curr_bucket))
- {
- Ptr<Page_entry>& ptr = iter.curr;
- Page_state state = ptr.p->m_state;
-
- DBG_LCP("LCP " << ptr << " - ");
-
- if (ptr.p->m_last_lcp < m_last_lcp &&
- (state & Page_entry::DIRTY) &&
- (! (state & Page_entry::LOCKED)))
- {
- if(! (state & Page_entry::BOUND))
- {
- ndbout << ptr << endl;
- ndbrequire(false);
- }
- if (state & Page_entry::BUSY)
- {
- DBG_LCP(" BUSY" << endl);
- break; // wait for it
- }
- else if (state & Page_entry::PAGEOUT)
- {
- DBG_LCP(" PAGEOUT -> state |= LCP" << endl);
- set_page_state(ptr, state | Page_entry::LCP);
- }
- else
- {
- DBG_LCP(" pageout()" << endl);
- ptr.p->m_state |= Page_entry::LCP;
- c_tup->disk_page_unmap_callback(0,
- ptr.p->m_real_page_i,
- ptr.p->m_dirty_count);
- pageout(signal, ptr);
- }
- ptr.p->m_last_lcp = m_last_lcp;
- m_lcp_outstanding++;
- }
- else
- {
- DBG_LCP(" NOT DIRTY" << endl);
- }
- pl_hash.next(iter);
- }
-
- m_lcp_curr_bucket = (iter.curr.i != RNIL ? iter.bucket : ~(Uint32)0);
- }
-
- if (m_lcp_curr_bucket == ~(Uint32)0 && !m_lcp_outstanding)
- {
- Ptr<Page_entry> ptr;
- Page_sublist& pl = *m_page_sublist[Page_entry::SL_LOCKED];
- if (pl.first(ptr))
- {
- process_lcp_locked(signal, ptr);
- }
- else
- {
- if (ERROR_INSERTED(11007))
- {
- ndbout << "No more writes..." << endl;
- signal->theData[0] = 9999;
- sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 10000, 1);
- SET_ERROR_INSERT_VALUE(11008);
- }
- signal->theData[0] = m_end_lcp_req.senderData;
- sendSignal(m_end_lcp_req.senderRef, GSN_END_LCP_CONF, signal, 1, JBB);
- }
- return false;
- }
-
- return true;
-}
-
-void
-Pgman::process_lcp_locked(Signal* signal, Ptr<Page_entry> ptr)
-{
- CRASH_INSERTION(11006);
-
- ptr.p->m_last_lcp = m_last_lcp;
- if (ptr.p->m_state & Page_entry::DIRTY)
- {
- Ptr<GlobalPage> org, copy;
- ndbrequire(m_global_page_pool.seize(copy));
- m_global_page_pool.getPtr(org, ptr.p->m_real_page_i);
- memcpy(copy.p, org.p, sizeof(GlobalPage));
- ptr.p->m_copy_page_i = copy.i;
-
- m_lcp_outstanding++;
- ptr.p->m_state |= Page_entry::LCP;
- pageout(signal, ptr);
- return;
- }
-
- Page_sublist& pl = *m_page_sublist[Page_entry::SL_LOCKED];
- pl.next(ptr);
-
- signal->theData[0] = PgmanContinueB::LCP_LOCKED;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Pgman::process_lcp_locked_fswriteconf(Signal* signal, Ptr<Page_entry> ptr)
-{
- Ptr<GlobalPage> org, copy;
- m_global_page_pool.getPtr(copy, ptr.p->m_copy_page_i);
- m_global_page_pool.getPtr(org, ptr.p->m_real_page_i);
- memcpy(org.p, copy.p, sizeof(GlobalPage));
- m_global_page_pool.release(copy);
-
- ptr.p->m_copy_page_i = RNIL;
-
- Page_sublist& pl = *m_page_sublist[Page_entry::SL_LOCKED];
- pl.next(ptr);
-
- signal->theData[0] = PgmanContinueB::LCP_LOCKED;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-// page read and write
-
-void
-Pgman::pagein(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: pagein" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- ndbrequire(! (ptr.p->m_state & Page_entry::PAGEIN));
- set_page_state(ptr, ptr.p->m_state | Page_entry::PAGEIN);
-
- fsreadreq(signal, ptr);
- m_stats.m_current_io_waits++;
-}
-
-void
-Pgman::fsreadconf(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: fsreadconf" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
- ndbrequire(ptr.p->m_state & Page_entry::PAGEIN);
- Page_state state = ptr.p->m_state;
-
- state &= ~ Page_entry::PAGEIN;
- state &= ~ Page_entry::EMPTY;
- state |= Page_entry::MAPPED;
- set_page_state(ptr, state);
-
- {
- /**
- * Update lsn record on page
- * as it can be modified/flushed wo/ update_lsn has been called
- * (e.g. prealloc) and it then would get lsn 0, which is bad
- * when running undo and following SR
- */
- Ptr<GlobalPage> pagePtr;
- m_global_page_pool.getPtr(pagePtr, ptr.p->m_real_page_i);
- File_formats::Datafile::Data_page* page =
- (File_formats::Datafile::Data_page*)pagePtr.p;
-
- Uint64 lsn = 0;
- lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
- lsn += page->m_page_header.m_page_lsn_lo;
- ptr.p->m_lsn = lsn;
- }
-
- ndbrequire(m_stats.m_current_io_waits > 0);
- m_stats.m_current_io_waits--;
-
- ptr.p->m_last_lcp = m_last_lcp_complete;
- do_busy_loop(signal, true);
-}
-
-void
-Pgman::pageout(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: pageout" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- Page_state state = ptr.p->m_state;
- ndbrequire(state & Page_entry::BOUND);
- ndbrequire(state & Page_entry::MAPPED);
- ndbrequire(! (state & Page_entry::BUSY));
- ndbrequire(! (state & Page_entry::PAGEOUT));
-
- state |= Page_entry::PAGEOUT;
-
- // update lsn on page prior to write
- Ptr<GlobalPage> pagePtr;
- m_global_page_pool.getPtr(pagePtr, ptr.p->m_real_page_i);
- File_formats::Datafile::Data_page* page =
- (File_formats::Datafile::Data_page*)pagePtr.p;
- page->m_page_header.m_page_lsn_hi = ptr.p->m_lsn >> 32;
- page->m_page_header.m_page_lsn_lo = ptr.p->m_lsn & 0xFFFFFFFF;
-
- // undo WAL
- Logfile_client::Request req;
- req.m_callback.m_callbackData = ptr.i;
- req.m_callback.m_callbackFunction = safe_cast(&Pgman::logsync_callback);
- int ret = m_lgman.sync_lsn(signal, ptr.p->m_lsn, &req, 0);
- if (ret > 0)
- {
- fswritereq(signal, ptr);
- m_stats.m_current_io_waits++;
- }
- else
- {
- ndbrequire(ret == 0);
- state |= Page_entry::LOGSYNC;
- }
- set_page_state(ptr, state);
-}
-
-void
-Pgman::logsync_callback(Signal* signal, Uint32 ptrI, Uint32 res)
-{
- Ptr<Page_entry> ptr;
- m_page_entry_pool.getPtr(ptr, ptrI);
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: logsync_callback" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- // it is OK to be "busy" at this point (the commit is queued)
- Page_state state = ptr.p->m_state;
- ndbrequire(state & Page_entry::PAGEOUT);
- ndbrequire(state & Page_entry::LOGSYNC);
- state &= ~ Page_entry::LOGSYNC;
- set_page_state(ptr, state);
-
- fswritereq(signal, ptr);
- m_stats.m_current_io_waits++;
-}
-
-void
-Pgman::fswriteconf(Signal* signal, Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: fswriteconf" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- Page_state state = ptr.p->m_state;
- ndbrequire(state & Page_entry::PAGEOUT);
-
- c_tup->disk_page_unmap_callback(1,
- ptr.p->m_real_page_i,
- ptr.p->m_dirty_count);
-
- state &= ~ Page_entry::PAGEOUT;
- state &= ~ Page_entry::EMPTY;
- state &= ~ Page_entry::DIRTY;
-
- ndbrequire(m_stats.m_current_io_waits > 0);
- m_stats.m_current_io_waits--;
-
- if (state & Page_entry::LCP)
- {
- ndbrequire(m_lcp_outstanding);
- m_lcp_outstanding--;
- state &= ~ Page_entry::LCP;
-
- if (ptr.p->m_copy_page_i != RNIL)
- {
- process_lcp_locked_fswriteconf(signal, ptr);
- }
- }
-
- set_page_state(ptr, state);
- do_busy_loop(signal, true);
-}
-
-// file system interface
-
-void
-Pgman::fsreadreq(Signal* signal, Ptr<Page_entry> ptr)
-{
- File_map::ConstDataBufferIterator it;
- bool ret = m_file_map.first(it) && m_file_map.next(it, ptr.p->m_file_no);
- ndbrequire(ret);
- Uint32 fd = * it.data;
-
- ndbrequire(ptr.p->m_page_no > 0);
-
- FsReadWriteReq* req = (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = fd;
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->varIndex = ptr.p->m_page_no;
- req->numberOfPages = 1;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatGlobalPage);
- req->data.pageData[0] = ptr.p->m_real_page_i;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
-}
-
-void
-Pgman::execFSREADCONF(Signal* signal)
-{
- jamEntry();
- FsConf* conf = (FsConf*)signal->getDataPtr();
- Ptr<Page_entry> ptr;
- m_page_entry_pool.getPtr(ptr, conf->userPointer);
-
- fsreadconf(signal, ptr);
-}
-
-void
-Pgman::execFSREADREF(Signal* signal)
-{
- jamEntry();
- SimulatedBlock::execFSREADREF(signal);
- ndbrequire(false);
-}
-
-void
-Pgman::fswritereq(Signal* signal, Ptr<Page_entry> ptr)
-{
- File_map::ConstDataBufferIterator it;
- m_file_map.first(it);
- m_file_map.next(it, ptr.p->m_file_no);
- Uint32 fd = * it.data;
-
- ndbrequire(ptr.p->m_page_no > 0);
-
- FsReadWriteReq* req = (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = fd;
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->varIndex = ptr.p->m_page_no;
- req->numberOfPages = 1;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatGlobalPage);
- req->data.pageData[0] = ptr.p->m_real_page_i;
-
-#if ERROR_INSERT_CODE
- if (ptr.p->m_state & Page_entry::LOCKED)
- {
- sendSignalWithDelay(NDBFS_REF, GSN_FSWRITEREQ, signal,
- 3000, FsReadWriteReq::FixedLength + 1);
- ndbout_c("pageout locked (3s)");
- return;
- }
-#endif
-
- if (!ERROR_INSERTED(11008))
- {
- sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBA);
- }
-}
-
-void
-Pgman::execFSWRITECONF(Signal* signal)
-{
- jamEntry();
- FsConf* conf = (FsConf*)signal->getDataPtr();
- Ptr<Page_entry> ptr;
- m_page_entry_pool.getPtr(ptr, conf->userPointer);
-
- fswriteconf(signal, ptr);
-}
-
-
-void
-Pgman::execFSWRITEREF(Signal* signal)
-{
- jamEntry();
- SimulatedBlock::execFSWRITEREF(signal);
- ndbrequire(false);
-}
-
-// client methods
-
-int
-Pgman::get_page(Signal* signal, Ptr<Page_entry> ptr, Page_request page_req)
-{
- jamEntry();
-#ifdef VM_TRACE
- Ptr<Page_request> tmp = { &page_req, RNIL};
- debugOut << "PGMAN: >get_page" << endl;
- debugOut << "PGMAN: " << ptr << endl;
- debugOut << "PGMAN: " << tmp << endl;
-#endif
- Uint32 req_flags = page_req.m_flags;
-
- if (req_flags & Page_request::EMPTY_PAGE)
- {
- // Only one can "init" a page at a time
- //ndbrequire(ptr.p->m_requests.isEmpty());
- }
-
- Page_state state = ptr.p->m_state;
- bool is_new = (state == 0);
- bool busy_count = false;
-
- if (req_flags & Page_request::LOCK_PAGE)
- {
- jam();
- state |= Page_entry::LOCKED;
- }
-
- if (req_flags & Page_request::ALLOC_REQ)
- {
- jam();
- }
- else if (req_flags & Page_request::COMMIT_REQ)
- {
- busy_count = true;
- state |= Page_entry::BUSY;
- }
- else if ((req_flags & Page_request::OP_MASK) != ZREAD)
- {
- jam();
- }
-
- // update LIRS
- if (! (state & Page_entry::LOCKED) &&
- ! (req_flags & Page_request::CORR_REQ))
- {
- jam();
- set_page_state(ptr, state);
- lirs_reference(ptr);
- state = ptr.p->m_state;
- }
-
- const Page_state LOCKED = Page_entry::LOCKED | Page_entry::MAPPED;
- if ((state & LOCKED) == LOCKED &&
- ! (req_flags & Page_request::UNLOCK_PAGE))
- {
- ptr.p->m_state |= (req_flags & DIRTY_FLAGS ? Page_entry::DIRTY : 0);
- if (ptr.p->m_copy_page_i != RNIL)
- {
- return ptr.p->m_copy_page_i;
- }
-
- return ptr.p->m_real_page_i;
- }
-
- bool only_request = ptr.p->m_requests.isEmpty();
-#ifdef ERROR_INSERT
- if (req_flags & Page_request::DELAY_REQ)
- {
- jam();
- only_request = false;
- }
-#endif
- if (only_request &&
- state & Page_entry::MAPPED)
- {
- if (! (state & Page_entry::PAGEOUT))
- {
- if (req_flags & DIRTY_FLAGS)
- state |= Page_entry::DIRTY;
-
- ptr.p->m_busy_count += busy_count;
- set_page_state(ptr, state);
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: <get_page: immediate" << endl;
-#endif
-
- ndbrequire(ptr.p->m_real_page_i != RNIL);
- return ptr.p->m_real_page_i;
- }
- }
-
- if (! (req_flags & (Page_request::LOCK_PAGE | Page_request::UNLOCK_PAGE)))
- {
- ndbrequire(! (state & Page_entry::LOCKED));
- }
-
- // queue the request
- Ptr<Pgman::Page_request> req_ptr;
- {
- Local_page_request_list req_list(m_page_request_pool, ptr.p->m_requests);
- if (! (req_flags & Page_request::ALLOC_REQ))
- req_list.seizeLast(req_ptr);
- else
- req_list.seizeFirst(req_ptr);
- }
-
- if (req_ptr.i == RNIL)
- {
- if (is_new)
- {
- release_page_entry(ptr);
- }
- return -1;
- }
-
- req_ptr.p->m_block = page_req.m_block;
- req_ptr.p->m_flags = page_req.m_flags;
- req_ptr.p->m_callback = page_req.m_callback;
-#ifdef ERROR_INSERT
- req_ptr.p->m_delay_until_time = page_req.m_delay_until_time;
-#endif
-
- state |= Page_entry::REQUEST;
- if (only_request && (req_flags & Page_request::EMPTY_PAGE))
- {
- state |= Page_entry::EMPTY;
- }
-
- if (req_flags & Page_request::UNLOCK_PAGE)
- {
- // keep it locked
- }
-
- ptr.p->m_busy_count += busy_count;
- ptr.p->m_dirty_count += !!(req_flags & DIRTY_FLAGS);
- set_page_state(ptr, state);
-
- do_busy_loop(signal, true);
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << req_ptr << endl;
- debugOut << "PGMAN: <get_page: queued" << endl;
-#endif
- return 0;
-}
-
-void
-Pgman::update_lsn(Ptr<Page_entry> ptr, Uint32 block, Uint64 lsn)
-{
- jamEntry();
-#ifdef VM_TRACE
- const char* bname = getBlockName(block, "?");
- debugOut << "PGMAN: >update_lsn: block=" << bname << " lsn=" << lsn << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- Page_state state = ptr.p->m_state;
- ptr.p->m_lsn = lsn;
-
- if (state & Page_entry::BUSY)
- {
- ndbrequire(ptr.p->m_busy_count != 0);
- if (--ptr.p->m_busy_count == 0)
- {
- state &= ~ Page_entry::BUSY;
- }
- }
-
- state |= Page_entry::DIRTY;
- set_page_state(ptr, state);
-
-#ifdef VM_TRACE
- debugOut << "PGMAN: " << ptr << endl;
- debugOut << "PGMAN: <update_lsn" << endl;
-#endif
-}
-
-Uint32
-Pgman::create_data_file()
-{
- File_map::DataBufferIterator it;
- if(m_file_map.first(it))
- {
- do
- {
- if(*it.data == RNIL)
- {
- *it.data = (1u << 31) | it.pos;
- return it.pos;
- }
- } while(m_file_map.next(it));
- }
-
- Uint32 file_no = m_file_map.getSize();
- Uint32 fd = (1u << 31) | file_no;
-
- if (m_file_map.append(&fd, 1))
- {
- return file_no;
- }
- return RNIL;
-}
-
-Uint32
-Pgman::alloc_data_file(Uint32 file_no)
-{
- Uint32 sz = m_file_map.getSize();
- if (file_no >= sz)
- {
- Uint32 len = file_no - sz + 1;
- Uint32 fd = RNIL;
- while (len--)
- {
- if (! m_file_map.append(&fd, 1))
- return RNIL;
- }
- }
-
- File_map::DataBufferIterator it;
- m_file_map.first(it);
- m_file_map.next(it, file_no);
- if (* it.data != RNIL)
- return RNIL;
-
- *it.data = (1u << 31) | file_no;
- return file_no;
-}
-
-void
-Pgman::map_file_no(Uint32 file_no, Uint32 fd)
-{
- File_map::DataBufferIterator it;
- m_file_map.first(it);
- m_file_map.next(it, file_no);
-
- assert(*it.data == ((1u << 31) | file_no));
- *it.data = fd;
-}
-
-void
-Pgman::free_data_file(Uint32 file_no, Uint32 fd)
-{
- File_map::DataBufferIterator it;
- m_file_map.first(it);
- m_file_map.next(it, file_no);
-
- if (fd == RNIL)
- {
- ndbrequire(*it.data == ((1u << 31) | file_no));
- }
- else
- {
- ndbrequire(*it.data == fd);
- }
- *it.data = RNIL;
-}
-
-int
-Pgman::drop_page(Ptr<Page_entry> ptr)
-{
-#ifdef VM_TRACE
- debugOut << "PGMAN: drop_page" << endl;
- debugOut << "PGMAN: " << ptr << endl;
-#endif
-
- Page_stack& pl_stack = m_page_stack;
- Page_queue& pl_queue = m_page_queue;
-
- Page_state state = ptr.p->m_state;
- if (! (state & (Page_entry::PAGEIN | Page_entry::PAGEOUT)))
- {
- ndbrequire(state & Page_entry::BOUND);
- ndbrequire(state & Page_entry::MAPPED);
-
- if (state & Page_entry::ONSTACK)
- {
- jam();
- bool at_bottom = ! pl_stack.hasPrev(ptr);
- pl_stack.remove(ptr);
- state &= ~ Page_entry::ONSTACK;
- if (at_bottom)
- {
- jam();
- ndbassert(state & Page_entry::HOT);
- lirs_stack_prune();
- }
- }
-
- if (state & Page_entry::ONQUEUE)
- {
- jam();
- pl_queue.remove(ptr);
- state &= ~ Page_entry::ONQUEUE;
- }
-
- ndbassert(ptr.p->m_real_page_i != RNIL);
- if (ptr.p->m_real_page_i != RNIL)
- {
- jam();
- release_cache_page(ptr.p->m_real_page_i);
- ptr.p->m_real_page_i = RNIL;
- }
-
- set_page_state(ptr, state);
- release_page_entry(ptr);
- return 1;
- }
-
- ndbrequire(false);
- return -1;
-}
-
-// debug
-
-#ifdef VM_TRACE
-
-void
-Pgman::verify_page_entry(Ptr<Page_entry> ptr)
-{
- Uint32 ptrI = ptr.i;
- Page_state state = ptr.p->m_state;
-
- bool has_req = state & Page_entry::REQUEST;
- bool has_req2 = ! ptr.p->m_requests.isEmpty();
- ndbrequire(has_req == has_req2 || dump_page_lists(ptrI));
-
- bool is_bound = state & Page_entry::BOUND;
- bool is_bound2 = ptr.p->m_real_page_i != RNIL;
- ndbrequire(is_bound == is_bound2 || dump_page_lists(ptrI));
-
- bool is_mapped = state & Page_entry::MAPPED;
- // mapped implies bound
- ndbrequire(! is_mapped || is_bound || dump_page_lists(ptrI));
- // bound is mapped or has open requests
- ndbrequire(! is_bound || is_mapped || has_req || dump_page_lists(ptrI));
-
- bool on_stack = state & Page_entry::ONSTACK;
- bool is_hot = state & Page_entry::HOT;
- // hot entry must be on stack
- ndbrequire(! is_hot || on_stack || dump_page_lists(ptrI));
-
- bool on_queue = state & Page_entry::ONQUEUE;
- // hot entry is not on queue
- ndbrequire(! is_hot || ! on_queue || dump_page_lists(ptrI));
-
- bool is_locked = state & Page_entry::LOCKED;
- bool on_queue2 = ! is_locked && ! is_hot && is_bound;
- ndbrequire(on_queue == on_queue2 || dump_page_lists(ptrI));
-
- // entries waiting to enter queue
- bool to_queue = ! is_locked && ! is_hot && ! is_bound && has_req;
-
- // page is either LOCKED or under LIRS
- bool is_lirs = on_stack || to_queue || on_queue;
- ndbrequire(is_locked == ! is_lirs || dump_page_lists(ptrI));
-
- bool pagein = state & Page_entry::PAGEIN;
- bool pageout = state & Page_entry::PAGEOUT;
- // cannot read and write at same time
- ndbrequire(! pagein || ! pageout || dump_page_lists(ptrI));
-
- Uint32 no = get_sublist_no(state);
- switch (no) {
- case Page_entry::SL_BIND:
- ndbrequire(! pagein && ! pageout || dump_page_lists(ptrI));
- break;
- case Page_entry::SL_MAP:
- ndbrequire(! pagein && ! pageout || dump_page_lists(ptrI));
- break;
- case Page_entry::SL_MAP_IO:
- ndbrequire(pagein && ! pageout || dump_page_lists(ptrI));
- break;
- case Page_entry::SL_CALLBACK:
- ndbrequire(! pagein && ! pageout || dump_page_lists(ptrI));
- break;
- case Page_entry::SL_CALLBACK_IO:
- ndbrequire(! pagein && pageout || dump_page_lists(ptrI));
- break;
- case Page_entry::SL_BUSY:
- break;
- case Page_entry::SL_LOCKED:
- break;
- case Page_entry::SL_IDLE:
- break;
- case Page_entry::SL_OTHER:
- break;
- default:
- ndbrequire(false || dump_page_lists(ptrI));
- break;
- }
-}
-
-void
-Pgman::verify_page_lists()
-{
- Page_hashlist& pl_hash = m_page_hashlist;
- Page_stack& pl_stack = m_page_stack;
- Page_queue& pl_queue = m_page_queue;
- Ptr<Page_entry> ptr;
-
- Uint32 stack_count = 0;
- Uint32 queue_count = 0;
- Uint32 queuewait_count = 0;
- Uint32 locked_bound_count = 0;
-
- Page_hashlist::Iterator iter;
- pl_hash.next(0, iter);
- while (iter.curr.i != RNIL)
- {
- verify_page_entry(iter.curr);
-
- Page_state state = iter.curr.p->m_state;
- if (state & Page_entry::ONSTACK)
- stack_count++;
- if (state & Page_entry::ONQUEUE)
- queue_count++;
- if (! (state & Page_entry::LOCKED) &&
- ! (state & Page_entry::HOT) &&
- (state & Page_entry::REQUEST) &&
- ! (state & Page_entry::BOUND))
- queuewait_count++;
- if (state & Page_entry::LOCKED &&
- state & Page_entry::BOUND)
- locked_bound_count++;
- pl_hash.next(iter);
- }
-
- ndbrequire(stack_count == pl_stack.count() || dump_page_lists());
- ndbrequire(queue_count == pl_queue.count() || dump_page_lists());
-
- Uint32 hot_count = 0;
- Uint32 hot_bound_count = 0;
- Uint32 cold_bound_count = 0;
- Uint32 stack_request_count = 0;
- Uint32 queue_request_count = 0;
-
- Uint32 i1 = RNIL;
- for (pl_stack.first(ptr); ptr.i != RNIL; pl_stack.next(ptr))
- {
- ndbrequire(i1 != ptr.i);
- i1 = ptr.i;
- Page_state state = ptr.p->m_state;
- ndbrequire(state & Page_entry::ONSTACK || dump_page_lists());
- if (! pl_stack.hasPrev(ptr))
- ndbrequire(state & Page_entry::HOT || dump_page_lists());
- if (state & Page_entry::HOT) {
- hot_count++;
- if (state & Page_entry::BOUND)
- hot_bound_count++;
- }
- if (state & Page_entry::REQUEST)
- stack_request_count++;
- }
-
- Uint32 i2 = RNIL;
- for (pl_queue.first(ptr); ptr.i != RNIL; pl_queue.next(ptr))
- {
- ndbrequire(i2 != ptr.i);
- i2 = ptr.i;
- Page_state state = ptr.p->m_state;
- ndbrequire(state & Page_entry::ONQUEUE || dump_page_lists());
- ndbrequire(state & Page_entry::BOUND || dump_page_lists());
- cold_bound_count++;
- if (state & Page_entry::REQUEST)
- queue_request_count++;
- }
-
- Uint32 tot_bound_count =
- locked_bound_count + hot_bound_count + cold_bound_count;
- ndbrequire(m_stats.m_num_pages == tot_bound_count || dump_page_lists());
-
- Uint32 k;
- Uint32 entry_count = 0;
-
- for (k = 0; k < Page_entry::SUBLIST_COUNT; k++)
- {
- const Page_sublist& pl = *m_page_sublist[k];
- for (pl.first(ptr); ptr.i != RNIL; pl.next(ptr))
- {
- ndbrequire(get_sublist_no(ptr.p->m_state) == k || dump_page_lists());
- entry_count++;
- }
- }
-
- ndbrequire(entry_count == pl_hash.count() || dump_page_lists());
-
- debugOut << "PGMAN: loop"
- << " stats=" << m_stats_loop_on
- << " busy=" << m_busy_loop_on
- << " cleanup=" << m_cleanup_loop_on
- << " lcp=" << m_lcp_loop_on << endl;
-
- debugOut << "PGMAN:"
- << " entry:" << pl_hash.count()
- << " cache:" << m_stats.m_num_pages
- << "(" << locked_bound_count << "L)"
- << " stack:" << pl_stack.count()
- << " hot:" << hot_count
- << " hot_bound:" << hot_bound_count
- << " stack_request:" << stack_request_count
- << " queue:" << pl_queue.count()
- << " queue_request:" << queue_request_count
- << " queuewait:" << queuewait_count << endl;
-
- debugOut << "PGMAN:";
- for (k = 0; k < Page_entry::SUBLIST_COUNT; k++)
- {
- const Page_sublist& pl = *m_page_sublist[k];
- debugOut << " " << get_sublist_name(k) << ":" << pl.count();
- }
- debugOut << endl;
-}
-
-void
-Pgman::verify_all()
-{
- Page_sublist& pl_bind = *m_page_sublist[Page_entry::SL_BIND];
- Page_sublist& pl_map = *m_page_sublist[Page_entry::SL_MAP];
- Page_sublist& pl_callback = *m_page_sublist[Page_entry::SL_CALLBACK];
-
- if (! pl_bind.isEmpty() || ! pl_map.isEmpty() || ! pl_callback.isEmpty())
- {
- ndbrequire(m_busy_loop_on || dump_page_lists());
- }
- verify_page_lists();
-}
-
-bool
-Pgman::dump_page_lists(Uint32 ptrI)
-{
- if (! debugFlag)
- open_debug_file(1);
-
- debugOut << "PGMAN: page list dump" << endl;
- if (ptrI != RNIL)
- debugOut << "PGMAN: error on PE [" << ptrI << "]" << endl;
-
- Page_hashlist& pl_hash = m_page_hashlist;
- Page_stack& pl_stack = m_page_stack;
- Page_queue& pl_queue = m_page_queue;
- Ptr<Page_entry> ptr;
- Uint32 n;
- char buf[40];
-
- debugOut << "hash:" << endl;
- Page_hashlist::Iterator iter;
- pl_hash.next(0, iter);
- n = 0;
- while (iter.curr.i != RNIL)
- {
- sprintf(buf, "%03d", n++);
- debugOut << buf << " " << iter.curr << endl;
- pl_hash.next(iter);
- }
-
- debugOut << "stack:" << endl;
- n = 0;
- for (pl_stack.first(ptr); ptr.i != RNIL; pl_stack.next(ptr))
- {
- sprintf(buf, "%03d", n++);
- debugOut << buf << " " << ptr << endl;
- }
-
- debugOut << "queue:" << endl;
- n = 0;
- for (pl_queue.first(ptr); ptr.i != RNIL; pl_queue.next(ptr))
- {
- sprintf(buf, "%03d", n++);
- debugOut << buf << " " << ptr << endl;
- }
-
- Uint32 k;
- for (k = 0; k < Page_entry::SUBLIST_COUNT; k++)
- {
- debugOut << get_sublist_name(k) << ":" << endl;
- const Page_sublist& pl = *m_page_sublist[k];
- for (pl.first(ptr); ptr.i != RNIL; pl.next(ptr))
- {
- sprintf(buf, "%03d", n++);
- debugOut << buf << " " << ptr << endl;
- }
- }
-
- if (! debugFlag)
- open_debug_file(0);
-
- return false;
-}
-
-#endif
-
-const char*
-Pgman::get_sublist_name(Uint32 list_no)
-{
- switch (list_no) {
- case Page_entry::SL_BIND:
- return "bind";
- case Page_entry::SL_MAP:
- return "map";
- case Page_entry::SL_MAP_IO:
- return "map_io";
- case Page_entry::SL_CALLBACK:
- return "callback";
- case Page_entry::SL_CALLBACK_IO:
- return "callback_io";
- case Page_entry::SL_BUSY:
- return "busy";
- case Page_entry::SL_LOCKED:
- return "locked";
- case Page_entry::SL_IDLE:
- return "idle";
- case Page_entry::SL_OTHER:
- return "other";
- }
- return "?";
-}
-
-NdbOut&
-operator<<(NdbOut& out, Ptr<Pgman::Page_request> ptr)
-{
- const Pgman::Page_request& pr = *ptr.p;
- const char* bname = getBlockName(pr.m_block, "?");
- out << "PR";
- if (ptr.i != RNIL)
- out << " [" << dec << ptr.i << "]";
- out << " block=" << bname;
- out << " flags=" << hex << pr.m_flags;
- out << "," << dec << (pr.m_flags & Pgman::Page_request::OP_MASK);
- {
- if (pr.m_flags & Pgman::Page_request::LOCK_PAGE)
- out << ",lock_page";
- if (pr.m_flags & Pgman::Page_request::EMPTY_PAGE)
- out << ",empty_page";
- if (pr.m_flags & Pgman::Page_request::ALLOC_REQ)
- out << ",alloc_req";
- if (pr.m_flags & Pgman::Page_request::COMMIT_REQ)
- out << ",commit_req";
- if (pr.m_flags & Pgman::Page_request::DIRTY_REQ)
- out << ",dirty_req";
- if (pr.m_flags & Pgman::Page_request::CORR_REQ)
- out << ",corr_req";
- }
- return out;
-}
-
-NdbOut&
-operator<<(NdbOut& out, Ptr<Pgman::Page_entry> ptr)
-{
- const Pgman::Page_entry pe = *ptr.p;
- Uint32 list_no = Pgman::get_sublist_no(pe.m_state);
- out << "PE [" << dec << ptr.i << "]";
- out << " state=" << hex << pe.m_state;
- {
- if (pe.m_state & Pgman::Page_entry::REQUEST)
- out << ",request";
- if (pe.m_state & Pgman::Page_entry::EMPTY)
- out << ",empty";
- if (pe.m_state & Pgman::Page_entry::BOUND)
- out << ",bound";
- if (pe.m_state & Pgman::Page_entry::MAPPED)
- out << ",mapped";
- if (pe.m_state & Pgman::Page_entry::DIRTY)
- out << ",dirty";
- if (pe.m_state & Pgman::Page_entry::USED)
- out << ",used";
- if (pe.m_state & Pgman::Page_entry::BUSY)
- out << ",busy";
- if (pe.m_state & Pgman::Page_entry::LOCKED)
- out << ",locked";
- if (pe.m_state & Pgman::Page_entry::PAGEIN)
- out << ",pagein";
- if (pe.m_state & Pgman::Page_entry::PAGEOUT)
- out << ",pageout";
- if (pe.m_state & Pgman::Page_entry::LOGSYNC)
- out << ",logsync";
- if (pe.m_state & Pgman::Page_entry::LCP)
- out << ",lcp";
- if (pe.m_state & Pgman::Page_entry::HOT)
- out << ",hot";
- if (pe.m_state & Pgman::Page_entry::ONSTACK)
- out << ",onstack";
- if (pe.m_state & Pgman::Page_entry::ONQUEUE)
- out << ",onqueue";
- }
- out << " list=";
- if (list_no == ZNIL)
- out << "NONE";
- else
- {
- out << dec << list_no;
- out << "," << Pgman::get_sublist_name(list_no);
- }
- out << " diskpage=" << dec << pe.m_file_no << "," << pe.m_page_no;
- if (pe.m_real_page_i == RNIL)
- out << " realpage=RNIL";
- else
- out << " realpage=" << dec << pe.m_real_page_i;
- out << " lsn=" << dec << pe.m_lsn;
- out << " busy_count=" << dec << pe.m_busy_count;
-#ifdef VM_TRACE
- {
- Pgman::Page_stack& pl_stack = pe.m_this->m_page_stack;
- if (! pl_stack.hasNext(ptr))
- out << " top";
- if (! pl_stack.hasPrev(ptr))
- out << " bottom";
- }
- {
- Pgman::Local_page_request_list
- req_list(ptr.p->m_this->m_page_request_pool, ptr.p->m_requests);
- if (! req_list.isEmpty())
- {
- Ptr<Pgman::Page_request> req_ptr;
- out << " req:";
- for (req_list.first(req_ptr); req_ptr.i != RNIL; req_list.next(req_ptr))
- {
- out << " " << req_ptr;
- }
- }
- }
-#endif
- return out;
-}
-
-#ifdef VM_TRACE
-void
-Pgman::open_debug_file(Uint32 flag)
-{
- if (flag)
- {
- FILE* f = globalSignalLoggers.getOutputStream();
- debugOut = *new NdbOut(*new FileOutputStream(f));
- }
- else
- {
- debugOut = *new NdbOut(*new NullOutputStream());
- }
-}
-#endif
-
-void
-Pgman::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
- Page_hashlist& pl_hash = m_page_hashlist;
-#ifdef VM_TRACE
- if (signal->theData[0] == 11000 && signal->getLength() == 2)
- {
- Uint32 flag = signal->theData[1];
- open_debug_file(flag);
- debugFlag = flag;
- }
-#endif
-
- if (signal->theData[0] == 11001)
- {
- // XXX print hash list if no sublist
- Uint32 list = 0;
- if (signal->getLength() > 1)
- list = signal->theData[1];
-
- Page_sublist& pl = *m_page_sublist[list];
- Ptr<Page_entry> ptr;
-
- for (pl.first(ptr); ptr.i != RNIL; pl.next(ptr))
- {
- ndbout << ptr << endl;
- infoEvent(" PE [ file: %d page: %d ] state: %x lsn: %lld lcp: %d busy: %d req-list: %d",
- ptr.p->m_file_no, ptr.p->m_page_no,
- ptr.p->m_state, ptr.p->m_lsn, ptr.p->m_last_lcp,
- ptr.p->m_busy_count,
- !ptr.p->m_requests.isEmpty());
- }
- }
-
- if (signal->theData[0] == 11002 && signal->getLength() == 3)
- {
- Page_entry key;
- key.m_file_no = signal->theData[1];
- key.m_page_no = signal->theData[2];
-
- Ptr<Page_entry> ptr;
- if (pl_hash.find(ptr, key))
- {
- ndbout << "pageout " << ptr << endl;
- c_tup->disk_page_unmap_callback(0,
- ptr.p->m_real_page_i,
- ptr.p->m_dirty_count);
- pageout(signal, ptr);
- }
- }
-
-
- if (signal->theData[0] == 11003)
- {
-#ifdef VM_TRACE
- verify_page_lists();
- dump_page_lists();
-#else
- ndbout << "Only in VM_TRACE builds" << endl;
-#endif
- }
-
- if (signal->theData[0] == 11004)
- {
- ndbout << "Dump LCP bucket m_lcp_outstanding: " << m_lcp_outstanding;
- if (m_lcp_curr_bucket != ~(Uint32)0)
- {
- Page_hashlist::Iterator iter;
- pl_hash.next(m_lcp_curr_bucket, iter);
-
- ndbout_c(" %d", m_lcp_curr_bucket);
-
- while (iter.curr.i != RNIL && iter.bucket == m_lcp_curr_bucket)
- {
- Ptr<Page_entry>& ptr = iter.curr;
- ndbout << ptr << endl;
- pl_hash.next(iter);
- }
-
- ndbout_c("-- done");
- }
- else
- {
- ndbout_c(" == ~0");
- }
- }
-
- if (signal->theData[0] == 11005)
- {
- g_dbg_lcp = ~g_dbg_lcp;
- }
-
- if (signal->theData[0] == 11006)
- {
- SET_ERROR_INSERT_VALUE(11006);
- }
-
- if (signal->theData[0] == 11007)
- {
- SET_ERROR_INSERT_VALUE(11007);
- }
-
- if (signal->theData[0] == 11008)
- {
- SET_ERROR_INSERT_VALUE(11008);
- }
-}
-
-// page cache client
-
-Page_cache_client::Page_cache_client(SimulatedBlock* block, Pgman* pgman)
-{
- m_block = block->number();
- m_pgman = pgman;
-}
diff --git a/storage/ndb/src/kernel/blocks/pgman.hpp b/storage/ndb/src/kernel/blocks/pgman.hpp
deleted file mode 100644
index aaff8ca03c4..00000000000
--- a/storage/ndb/src/kernel/blocks/pgman.hpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef PGMAN_H
-#define PGMAN_H
-
-#include <SimulatedBlock.hpp>
-
-#include <DLCHashTable.hpp>
-#include <DLCFifoList.hpp>
-#include <NodeBitmask.hpp>
-#include <signaldata/LCP.hpp>
-#include "lgman.hpp"
-
-#include <NdbOut.hpp>
-#include <OutputStream.hpp>
-
-/*
- * PGMAN
- *
- * PAGE ENTRIES AND REQUESTS
- *
- * Central structure is "page entry". It corresponds to a disk page
- * identified by file and page number (file_no, page_no).
- *
- * A page entry is created by first request for the disk page.
- * Subsequent requests are queued under the same page entry.
- *
- * There is a limited number of in-memory "cache pages", also called
- * "buffer pages" or "real pages". These are used by the more numerous
- * page entries to buffer the disk pages.
- *
- * A new or non-resident page entry must first be "bound" to an
- * available cache page. Next the disk page must be "mapped" to the
- * cache page. If the page is empty (never written) it is considered
- * mapped trivially. Otherwise the cache page must be updated via
- * "pagein" from disk. A bound and mapped page is called "resident".
- *
- * Updating a resident cache page makes it "dirty". A background
- * clean-up process makes dirty pages "clean" via "pageout" to disk.
- * Write ahead logging (WAL) of the page is done first i.e. UNDO log is
- * flushed up to the page log sequence number (LSN) by calling a TSMAN
- * method. The reason for this is obvious but not relevant to PGMAN.
- *
- * A local check point (LCP) periodically performs a complete pageout of
- * dirty pages. It must iterate over a list which will cover all pages
- * which had been dirty since LCP start.
- *
- * A clean page is a candidate ("victim") for being "unmapped" and
- * "evicted" from the cache, to allow another page to become resident.
- * This process is called "page replacement".
- *
- * PAGE REPLACEMENT
- *
- * Page replacement uses the LIRS algorithm (Jiang-Zhang).
- *
- * The "recency" of a page is the time between now and the last request
- * for the page. The "inter-reference recency" (IRR) of a page is the
- * time between the last 2 requests for the page. "Time" is advanced by
- * request for any page.
- *
- * Page entries are divided into "hot" ("lir") and "cold" ("hir"). Here
- * lir/hir refers to low/high IRR. Hot pages are always resident but
- * cold pages need not be.
- *
- * Number of hot pages is limited to slightly less than number of cache
- * pages. Until this number is reached, all used cache pages are hot.
- * Then the algorithm described next is applied. The algorithm avoids
- * storing any of the actual recency values.
- *
- * Primary data structure is the "stack". It contains all hot entries
- * and recently referenced cold entries (resident or not). The stack is
- * in recency order with most recent (lowest recency) entry on top.
- * Entries which are less recent than the least recent hot page are
- * removed ("stack pruning"). So the bottom page is always hot.
- *
- * The cold entries on the stack are undergoing a "trial period". If
- * they are referenced soon again (see IRR), they become hot. Otherwise
- * they fall off the bottom of the stack.
- *
- * Secondary data structure is the "queue". It contains all resident
- * cold pages (on stack or not). When a hot page is removed from the
- * stack it is added to the end of the queue. When page replacement
- * needs a page it removes it from the front of the queue.
- *
- * Page requests cause the input entry to be inserted and updated in
- * LIRS lists. Remember that an entry can be present on both stack and
- * queue. The rules per type of input entry are:
- *
- * 1. Hot. Move input entry to stack top. If input entry was at stack
- * bottom, do stack pruning.
- *
- * 2. Cold resident. Move input entry to stack top. Then:
- *
- * 2a. If input entry was on stack, change it to hot, remove it from
- * queue, change stack bottom entry to cold and move the bottom entry to
- * queue end, and do stack pruning.
- *
- * 2b. If input entry was on queue only, leave it cold but move it to
- * end of queue.
- *
- * 3. Cold non-resident. Remove entry at queue front and evict it from
- * the cache. If the evicted entry was on stack, it remains as unbound
- * entry on stack, to continue its trial period. Map input entry to the
- * freed cache page. Move input entry to stack top. Then:
- *
- * 3a. If input entry was on stack, change it to hot, change stack
- * bottom entry to cold and move the bottom entry to queue end, and do
- * stack pruning.
- *
- * 3b. If input entry was new, leave it cold but move it to end of
- * queue.
- *
- * LIRS CHANGES
- *
- * In LIRS the 'resident' requirement is changed as follows:
- *
- * Stack entries, including hot ones, can have any state. Unbound stack
- * entries are created by new requests and by pages evicted from queue
- * front which are still on stack.
- *
- * Queue entries must be bound. They become resident and evictable
- * within a finite time. A page is "evictable" if it is mapped, clean,
- * and has no requests.
- *
- * An unbound entry which should be on queue is added there at bind
- * time. Such entries are created when an unbound entry with open
- * requests is popped (hot) or pruned (cold) from the stack. This can
- * happen if the cache is too small.
- *
- * CLEANUP PROCESS
- *
- * LIRS (and related algorithms) do not address dirty pages. From above
- * it is obvious that the clean-up process should process dirty queue
- * entries proceeding from front to end. This also favors pages with
- * lower LSN numbers which minimizes amount of WAL to write.
- *
- * In fact the clean-up process holds a permanent pointer into the queue
- * where all entries strictly towards the front are clean. For such an
- * entry to become dirty it must be referenced again which moves it to
- * queue end and past the clean-up pointer. (In practice, until this
- * works, cleanup recycles back to queue front).
- *
- * PAGE LISTS
- *
- * Page entries are put on a number of lists.
- *
- * 1. Hash table on (file_no, page_no). Used for fast lookup and for
- * LCP to iterate over.
- *
- * The other lists are doubly-linked FIFOs. In general entries are
- * added to the end (last entry) and processed from the front (first
- * entry). When used as stack, end is top and front is bottom.
- *
- * 2. The LIRS stack and queue. These control page replacement.
- *
- * 3. Page entries are divided into disjoint "sublists" based on page
- * "state" i.e. the set of page properties. Some sublists drive page
- * processing and have next entry to process at the front.
- *
- * Current sublists are as follows. Those that drive processing are
- * marked with a plus (+).
- *
- * SL_BIND + waiting for available buffer page
- * SL_MAP + waiting to start pagein from disk
- * SL_MAP_IO - above in i/o wait (the pagein)
- * SL_CALLBACK + request done, waiting to invoke callbacks
- * SL_CALLBACK_IO - above in i/o wait (pageout by cleanup)
- * SL_BUSY - being written to by PGMAN client
- * SL_LOCKED - permanently locked to cache
- * SL_OTHER - default sublist
- *
- * PAGE PROCESSING
- *
- * Page processing uses a number independent continueB loops.
- *
- * 1. The "stats loop". Started at node start. Checks lists in debug
- * mode. In the future could gather statistics and adjust parameters
- * based on load. Continues via delay signal.
- *
- * 2. The "busy loop". Started by page request. Each loop does bind,
- * map, and callback of a number of entries. Continues via no-delay
- * signal until nothing to do.
- *
- * 3. The "cleanup loop". Started at node start. Each loop starts
- * pageout of a number of dirty queue entries. Continues via delay
- * signal.
- *
- * 4. The "LCP loop". Started periodically by NDB. Each loop starts
- * pageout of a number of hash list entries. Continues via delay signal
- * until done.
- *
- * SPECIAL CASES
- *
- * LOCKED pages are not put on stack or queue. They are flushed to disk
- * by LCP but not by clean-up.
- *
- * A TUP scan is likely to access a page repeatedly within a short time.
- * This can make the page hot when it should not be. Such "correlated
- * requests" are handled by a request flag which modifies default LIRS
- * processing. [fill in details later]
- *
- * Also PK operations make 2 rapid page references. The 2nd one is for
- * commit. This too should be handled as a correlated request.
- *
- * CLIENT TSMAN
- *
- * TSMAN reads "meta" pages such as extent headers. There are currently
- * "locked" forever in PGMAN cache.
- *
- * CLIENT DBTUP
- *
- * DBTUP works with copy pages (or UNDO buffers) in memory. The real
- * page is updated only between page request with COMMIT_REQ flag and
- * a subsequent LSN update. These need not occur in same timeslice
- * since DBTUP may need to flush UNDO log in-between.
- *
- * The page is "busy" if any transaction is between COMMIT_REQ and LSN
- * update. A busy page must be locked in buffer cache. No pageout of
- * a busy page can be started by clean-up or LCP.
- */
-
-class Pgman : public SimulatedBlock
-{
-public:
- Pgman(Block_context& ctx);
- virtual ~Pgman();
- BLOCK_DEFINES(Pgman);
-
-private:
- friend class Page_cache_client;
-
- struct Page_entry; // CC
- friend struct Page_entry;
-
- struct Page_request {
- enum Flags {
- OP_MASK = 0x000F // 4 bits for TUP operation
- ,LOCK_PAGE = 0x0020 // lock page in memory
- ,EMPTY_PAGE = 0x0040 // empty (new) page
- ,ALLOC_REQ = 0x0080 // part of alloc
- ,COMMIT_REQ = 0x0100 // part of commit
- ,DIRTY_REQ = 0x0200 // make page dirty wo/ update_lsn
- ,UNLOCK_PAGE = 0x0400
- ,CORR_REQ = 0x0800 // correlated request (no LIRS update)
-#ifdef ERROR_INSERT
- ,DELAY_REQ = 0x1000 // Force request to be delayed
-#endif
- };
-
- Uint16 m_block;
- Uint16 m_flags;
- SimulatedBlock::Callback m_callback;
-
-#ifdef ERROR_INSERT
- Uint64 m_delay_until_time;
-#endif
- Uint32 nextList;
- Uint32 m_magic;
- };
-
- typedef RecordPool<Page_request, WOPool> Page_request_pool;
- typedef SLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
- typedef LocalSLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
-
- struct Page_entry_stack_ptr {
- Uint32 nextList;
- Uint32 prevList;
- };
-
- struct Page_entry_queue_ptr {
- Uint32 nextList;
- Uint32 prevList;
- };
-
- struct Page_entry_sublist_ptr {
- Uint32 nextList;
- Uint32 prevList;
- };
-
- typedef Uint16 Page_state;
-
- struct Page_entry : Page_entry_stack_ptr,
- Page_entry_queue_ptr,
- Page_entry_sublist_ptr {
- Page_entry() {}
- Page_entry(Uint32 file_no, Uint32 page_no);
-
- enum State {
- NO_STATE = 0x0000
- ,REQUEST = 0x0001 // has outstanding request
- ,EMPTY = 0x0002 // empty (never written) page
- ,BOUND = 0x0004 // m_real_page_ptr assigned
- ,MAPPED = 0x0008 // bound, and empty or paged in
- ,DIRTY = 0x0010 // page is modified
- ,USED = 0x0020 // used by some tx (not set currently)
- ,BUSY = 0x0040 // page is being written to
- ,LOCKED = 0x0080 // locked in cache (forever)
- ,PAGEIN = 0x0100 // paging in
- ,PAGEOUT = 0x0200 // paging out
- ,LOGSYNC = 0x0400 // undo WAL as part of pageout
- ,LCP = 0x1000 // page is LCP flushed
- ,HOT = 0x2000 // page is hot
- ,ONSTACK = 0x4000 // page is on LIRS stack
- ,ONQUEUE = 0x8000 // page is on LIRS queue
- };
-
- enum Sublist {
- SL_BIND = 0
- ,SL_MAP = 1
- ,SL_MAP_IO = 2
- ,SL_CALLBACK = 3
- ,SL_CALLBACK_IO = 4
- ,SL_BUSY = 5
- ,SL_LOCKED = 6
- ,SL_IDLE = 7
- ,SL_OTHER = 8
- ,SUBLIST_COUNT = 9
- };
-
- Uint16 m_file_no; // disk page address set at seize
- Page_state m_state; // flags (0 for new entry)
-
- Uint32 m_page_no;
- Uint32 m_real_page_i;
- Uint64 m_lsn;
-
- Uint32 m_last_lcp;
- Uint32 m_dirty_count;
- Uint32 m_copy_page_i;
- union {
- Uint32 m_busy_count; // non-zero means BUSY
- Uint32 nextPool;
- };
-
- Page_request_list::Head m_requests;
-
- Uint32 nextHash;
- Uint32 prevHash;
-
- Uint32 hashValue() const { return m_file_no << 16 | m_page_no; }
- bool equal(const Page_entry& obj) const {
- return
- m_file_no == obj.m_file_no && m_page_no == obj.m_page_no;
- }
-
-#ifdef VM_TRACE
- Pgman* m_this;
-#endif
- };
-
- typedef DLCHashTable<Page_entry> Page_hashlist;
- typedef DLCFifoList<Page_entry, Page_entry_stack_ptr> Page_stack;
- typedef DLCFifoList<Page_entry, Page_entry_queue_ptr> Page_queue;
- typedef DLCFifoList<Page_entry, Page_entry_sublist_ptr> Page_sublist;
-
- class Dbtup *c_tup;
- Logfile_client m_lgman;
-
- // loop status
- bool m_stats_loop_on;
- bool m_busy_loop_on;
- bool m_cleanup_loop_on;
- bool m_lcp_loop_on;
-
- // LCP variables
- Uint32 m_last_lcp;
- Uint32 m_last_lcp_complete;
- Uint32 m_lcp_curr_bucket;
- Uint32 m_lcp_outstanding; // remaining i/o waits
- EndLcpReq m_end_lcp_req;
-
- // clean-up variables
- Ptr<Page_entry> m_cleanup_ptr;
-
- // file map
- typedef DataBuffer<15> File_map;
- File_map m_file_map;
- File_map::DataBufferPool m_data_buffer_pool;
-
- // page entries and requests
- Page_request_pool m_page_request_pool;
- ArrayPool<Page_entry> m_page_entry_pool;
- Page_hashlist m_page_hashlist;
- Page_stack m_page_stack;
- Page_queue m_page_queue;
- Page_sublist* m_page_sublist[Page_entry::SUBLIST_COUNT];
-
- // configuration
- struct Param {
- Param();
- Uint32 m_max_pages; // max number of cache pages
- Uint32 m_lirs_stack_mult; // in m_max_pages (around 3-10)
- Uint32 m_max_hot_pages; // max hot cache pages (up to 99%)
- Uint32 m_max_loop_count; // limit purely local loops
- Uint32 m_max_io_waits;
- Uint32 m_stats_loop_delay;
- Uint32 m_cleanup_loop_delay;
- Uint32 m_lcp_loop_delay;
- } m_param;
-
- // runtime sizes and statistics
- struct Stats {
- Stats();
- Uint32 m_num_pages; // current number of cache pages
- Uint32 m_page_hits;
- Uint32 m_page_faults;
- Uint32 m_current_io_waits;
- } m_stats;
-
-protected:
- void execSTTOR(Signal* signal);
- void sendSTTORRY(Signal*);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- void execLCP_FRAG_ORD(Signal*);
- void execEND_LCP_REQ(Signal*);
-
- void execFSREADCONF(Signal*);
- void execFSREADREF(Signal*);
- void execFSWRITECONF(Signal*);
- void execFSWRITEREF(Signal*);
-
- void execDUMP_STATE_ORD(Signal* signal);
-
-private:
- static Uint32 get_sublist_no(Page_state state);
- void set_page_state(Ptr<Page_entry> ptr, Page_state new_state);
-
- bool seize_cache_page(Ptr<GlobalPage>& gptr);
- void release_cache_page(Uint32 i);
-
- bool find_page_entry(Ptr<Page_entry>&, Uint32 file_no, Uint32 page_no);
- Uint32 seize_page_entry(Ptr<Page_entry>&, Uint32 file_no, Uint32 page_no);
- bool get_page_entry(Ptr<Page_entry>&, Uint32 file_no, Uint32 page_no);
- void release_page_entry(Ptr<Page_entry>&);
-
- void lirs_stack_prune();
- void lirs_stack_pop();
- void lirs_reference(Ptr<Page_entry> ptr);
-
- void do_stats_loop(Signal*);
- void do_busy_loop(Signal*, bool direct = false);
- void do_cleanup_loop(Signal*);
- void do_lcp_loop(Signal*, bool direct = false);
-
- bool process_bind(Signal*);
- bool process_bind(Signal*, Ptr<Page_entry> ptr);
- bool process_map(Signal*);
- bool process_map(Signal*, Ptr<Page_entry> ptr);
- bool process_callback(Signal*);
- bool process_callback(Signal*, Ptr<Page_entry> ptr);
-
- bool process_cleanup(Signal*);
- void move_cleanup_ptr(Ptr<Page_entry> ptr);
-
- bool process_lcp(Signal*);
- void process_lcp_locked(Signal* signal, Ptr<Page_entry> ptr);
- void process_lcp_locked_fswriteconf(Signal* signal, Ptr<Page_entry> ptr);
-
- void pagein(Signal*, Ptr<Page_entry>);
- void fsreadreq(Signal*, Ptr<Page_entry>);
- void fsreadconf(Signal*, Ptr<Page_entry>);
- void pageout(Signal*, Ptr<Page_entry>);
- void logsync_callback(Signal*, Uint32 ptrI, Uint32 res);
- void fswritereq(Signal*, Ptr<Page_entry>);
- void fswriteconf(Signal*, Ptr<Page_entry>);
-
- int get_page(Signal*, Ptr<Page_entry>, Page_request page_req);
- void update_lsn(Ptr<Page_entry>, Uint32 block, Uint64 lsn);
- Uint32 create_data_file();
- Uint32 alloc_data_file(Uint32 file_no);
- void map_file_no(Uint32 file_no, Uint32 fd);
- void free_data_file(Uint32 file_no, Uint32 fd = RNIL);
- int drop_page(Ptr<Page_entry>);
-
-#ifdef VM_TRACE
- NdbOut debugOut;
- bool debugFlag;
- void verify_page_entry(Ptr<Page_entry> ptr);
- void verify_page_lists();
- void verify_all();
- bool dump_page_lists(Uint32 ptrI = RNIL);
- void open_debug_file(Uint32 flag);
-#endif
- static const char* get_sublist_name(Uint32 list_no);
- friend class NdbOut& operator<<(NdbOut&, Ptr<Page_request>);
- friend class NdbOut& operator<<(NdbOut&, Ptr<Page_entry>);
-};
-
-class NdbOut& operator<<(NdbOut&, Ptr<Pgman::Page_request>);
-class NdbOut& operator<<(NdbOut&, Ptr<Pgman::Page_entry>);
-
-class Page_cache_client
-{
- Uint32 m_block;
- Pgman* m_pgman;
-
-public:
- Page_cache_client(SimulatedBlock* block, Pgman*);
-
- struct Request {
- Local_key m_page;
- SimulatedBlock::Callback m_callback;
-
-#ifdef ERROR_INSERT
- Uint64 m_delay_until_time;
-#endif
- };
-
- Ptr<GlobalPage> m_ptr; // TODO remove
-
- enum RequestFlags {
- LOCK_PAGE = Pgman::Page_request::LOCK_PAGE
- ,EMPTY_PAGE = Pgman::Page_request::EMPTY_PAGE
- ,ALLOC_REQ = Pgman::Page_request::ALLOC_REQ
- ,COMMIT_REQ = Pgman::Page_request::COMMIT_REQ
- ,DIRTY_REQ = Pgman::Page_request::DIRTY_REQ
- ,UNLOCK_PAGE = Pgman::Page_request::UNLOCK_PAGE
- ,CORR_REQ = Pgman::Page_request::CORR_REQ
-#ifdef ERROR_INSERT
- ,DELAY_REQ = Pgman::Page_request::DELAY_REQ
-#endif
- };
-
- /**
- * Get a page
- * @note This request may return true even if previous request
- * for same page return false, and it's callback has not been called
- * @return -1, on error
- * 0, request is queued
- * >0, real_page_id
- */
- int get_page(Signal*, Request&, Uint32 flags);
-
- void update_lsn(Local_key, Uint64 lsn);
-
- /**
- * Drop page
- *
- * @return -1 on error
- * 0 is request is queued
- * >0 is ok
- */
- int drop_page(Local_key, Uint32 page_id);
-
- /**
- * Create file record
- */
- Uint32 create_data_file();
-
- /**
- * Alloc datafile record
- */
- Uint32 alloc_data_file(Uint32 file_no);
-
- /**
- * Map file_no to m_fd
- */
- void map_file_no(Uint32 m_file_no, Uint32 m_fd);
-
- /**
- * Free file
- */
- void free_data_file(Uint32 file_no, Uint32 fd = RNIL);
-};
-
-inline int
-Page_cache_client::get_page(Signal* signal, Request& req, Uint32 flags)
-{
- Ptr<Pgman::Page_entry> entry_ptr;
- Uint32 file_no = req.m_page.m_file_no;
- Uint32 page_no = req.m_page.m_page_no;
-
-#ifdef VM_TRACE
- m_pgman->debugOut
- << "PGCLI: get_page " << file_no << "," << page_no
- << " flags=" << hex << flags << endl;
-#endif
-
- // find or seize
- bool ok = m_pgman->get_page_entry(entry_ptr, file_no, page_no);
- if (! ok)
- {
- return -1;
- }
-
- Pgman::Page_request page_req;
- page_req.m_block = m_block;
- page_req.m_flags = flags;
- page_req.m_callback = req.m_callback;
-#ifdef ERROR_INSERT
- page_req.m_delay_until_time = req.m_delay_until_time;
-#endif
-
- int i = m_pgman->get_page(signal, entry_ptr, page_req);
- if (i > 0)
- {
- // TODO remove
- m_pgman->m_global_page_pool.getPtr(m_ptr, (Uint32)i);
- }
- return i;
-}
-
-inline void
-Page_cache_client::update_lsn(Local_key key, Uint64 lsn)
-{
- Ptr<Pgman::Page_entry> entry_ptr;
- Uint32 file_no = key.m_file_no;
- Uint32 page_no = key.m_page_no;
-
-#ifdef VM_TRACE
- m_pgman->debugOut
- << "PGCLI: update_lsn " << file_no << "," << page_no
- << " lsn=" << lsn << endl;
-#endif
-
- bool found = m_pgman->find_page_entry(entry_ptr, file_no, page_no);
- assert(found);
-
- m_pgman->update_lsn(entry_ptr, m_block, lsn);
-}
-
-inline
-int
-Page_cache_client::drop_page(Local_key key, Uint32 page_id)
-{
- Ptr<Pgman::Page_entry> entry_ptr;
- Uint32 file_no = key.m_file_no;
- Uint32 page_no = key.m_page_no;
-
-#ifdef VM_TRACE
- m_pgman->debugOut
- << "PGCLI: drop_page " << file_no << "," << page_no << endl;
-#endif
-
- bool found = m_pgman->find_page_entry(entry_ptr, file_no, page_no);
- assert(found);
- assert(entry_ptr.p->m_real_page_i == page_id);
-
- return m_pgman->drop_page(entry_ptr);
-}
-
-inline Uint32
-Page_cache_client::create_data_file()
-{
- return m_pgman->create_data_file();
-}
-
-inline Uint32
-Page_cache_client::alloc_data_file(Uint32 file_no)
-{
- return m_pgman->alloc_data_file(file_no);
-}
-
-inline void
-Page_cache_client::map_file_no(Uint32 file_no, Uint32 fd)
-{
- m_pgman->map_file_no(file_no, fd);
-}
-
-inline void
-Page_cache_client::free_data_file(Uint32 file_no, Uint32 fd)
-{
- m_pgman->free_data_file(file_no, fd);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/print_file.cpp b/storage/ndb/src/kernel/blocks/print_file.cpp
deleted file mode 100644
index acaf9dd48e6..00000000000
--- a/storage/ndb/src/kernel/blocks/print_file.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-#include <UtilBuffer.hpp>
-#include "diskpage.hpp"
-#include <ndb_limits.h>
-#include <dbtup/tuppage.hpp>
-
-static void print_usage(const char*);
-static int print_zero_page(int, void *, Uint32 sz);
-static int print_extent_page(int, void*, Uint32 sz);
-static int print_undo_page(int, void*, Uint32 sz);
-static int print_data_page(int, void*, Uint32 sz);
-static bool print_page(int page_no)
-{
- return false;
-}
-
-int g_verbosity = 1;
-int g_page_size = File_formats::NDB_PAGE_SIZE;
-int (* g_print_page)(int count, void*, Uint32 sz) = print_zero_page;
-
-File_formats::Undofile::Zero_page g_uf_zero;
-File_formats::Datafile::Zero_page g_df_zero;
-
-int main(int argc, char ** argv)
-{
- for(int i = 1; i<argc; i++){
- if(!strncmp(argv[i], "-v", 2))
- {
- int pos= 2;
- do {
- g_verbosity++;
- } while(argv[i][pos++] == 'v');
- continue;
- }
- else if(!strcmp(argv[i], "-q"))
- {
- g_verbosity--;
- continue;
- }
- else if(!strcmp(argv[i], "-?") ||
- !strcmp(argv[i], "--?") ||
- !strcmp(argv[i], "-h") ||
- !strcmp(argv[i], "--help"))
- {
- print_usage(argv[0]);
- exit(0);
- }
-
- const char * filename = argv[i];
-
- struct stat sbuf;
- const int res = stat(filename, &sbuf);
- if(res != 0){
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- continue;
- }
- const Uint32 bytes = sbuf.st_size;
-
- UtilBuffer buffer;
-
- FILE * f = fopen(filename, "rb");
- if(f == 0){
- ndbout << "Failed to open file" << endl;
- continue;
- }
-
- Uint32 sz;
- Uint32 j = 0;
- do {
- buffer.grow(g_page_size);
- sz = fread(buffer.get_data(), 1, g_page_size, f);
- if((* g_print_page)(j++, buffer.get_data(), sz))
- break;
- } while(sz == g_page_size);
-
- fclose(f);
- continue;
- }
- return 0;
-}
-
-void
-print_usage(const char* prg)
-{
- ndbout << prg << " [-v]+ [-q]+ <file>+" << endl;
-}
-
-int
-print_zero_page(int i, void * ptr, Uint32 sz){
- File_formats::Zero_page_header* page = (File_formats::Zero_page_header*)ptr;
- if(memcmp(page->m_magic, "NDBDISK", 8) != 0)
- {
- ndbout << "Invalid magic: file is not ndb disk data file" << endl;
- return 1;
- }
-
- if(page->m_byte_order != 0x12345678)
- {
- ndbout << "Unhandled byteorder" << endl;
- return 1;
- }
-
- switch(page->m_file_type)
- {
- case File_formats::FT_Datafile:
- {
- g_df_zero = (* (File_formats::Datafile::Zero_page*)ptr);
- ndbout << "-- Datafile -- " << endl;
- ndbout << g_df_zero << endl;
- g_print_page = print_extent_page;
- return 0;
- }
- break;
- case File_formats::FT_Undofile:
- {
- g_uf_zero = (* (File_formats::Undofile::Zero_page*)ptr);
- ndbout << "-- Undofile -- " << endl;
- ndbout << g_uf_zero << endl;
- g_print_page = print_undo_page;
- return 0;
- }
- break;
- default:
- ndbout << "Unhandled file type: " << page->m_file_type << endl;
- return 1;
- }
-
- if(page->m_page_size !=g_page_size)
- {
- /**
- * Todo
- * lseek
- * g_page_size = page->m_page_size;
- */
- ndbout << "Unhandled page size: " << page->m_page_size << endl;
- return 1;
- }
-
- return 0;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const File_formats::Datafile::Extent_header& obj)
-{
- if(obj.m_table == RNIL)
- {
- if(obj.m_next_free_extent != RNIL)
- out << " FREE, next free: " << obj.m_next_free_extent;
- else
- out << " FREE, next free: RNIL";
- }
- else
- {
- out << "table: " << obj.m_table
- << " fragment: " << obj.m_fragment_id << " ";
- for(Uint32 i = 0; i<g_df_zero.m_extent_size; i++)
- {
- char t[2];
- BaseString::snprintf(t, sizeof(t), "%x", obj.get_free_bits(i));
- out << t;
- }
- }
- return out;
-}
-
-int
-print_extent_page(int count, void* ptr, Uint32 sz){
- if(count == g_df_zero.m_extent_pages)
- {
- g_print_page = print_data_page;
- }
- Uint32 header_words =
- File_formats::Datafile::extent_header_words(g_df_zero.m_extent_size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS / header_words;
-
- int no = count * per_page;
-
- const int max = count < g_df_zero.m_extent_pages ?
- per_page : g_df_zero.m_extent_count % per_page;
-
- File_formats::Datafile::Extent_page * page =
- (File_formats::Datafile::Extent_page*)ptr;
-
- ndbout << "Extent page: " << count
- << ", lsn = [ "
- << page->m_page_header.m_page_lsn_hi << " "
- << page->m_page_header.m_page_lsn_lo << "]"
- << endl;
- for(int i = 0; i<max; i++)
- {
- ndbout << " extent " << no+i << ": "
- << (* page->get_header(i, g_df_zero.m_extent_size)) << endl;
- }
- return 0;
-}
-
-int
-print_data_page(int count, void* ptr, Uint32 sz){
-
- File_formats::Datafile::Data_page * page =
- (File_formats::Datafile::Data_page*)ptr;
-
- ndbout << "Data page: " << count
- << ", lsn = [ "
- << page->m_page_header.m_page_lsn_hi << " "
- << page->m_page_header.m_page_lsn_lo << "]" ;
-
- if(g_verbosity > 1 || print_page(count))
- {
- switch(page->m_page_header.m_page_type){
- case File_formats::PT_Unallocated:
- break;
- case File_formats::PT_Tup_fixsize_page:
- ndbout << " fix ";
- if(g_verbosity > 2 || print_page(count))
- ndbout << (* (Tup_fixsize_page*)page);
- break;
- case File_formats::PT_Tup_varsize_page:
- ndbout << " var ";
- if(g_verbosity > 2 || print_page(count))
- ndbout << endl << (* (Tup_varsize_page*)page);
- break;
- default:
- ndbout << " unknown page type: %d" << page->m_page_header.m_page_type;
- }
- }
- ndbout << endl;
- return 0;
-}
-
-#define DBTUP_C
-#include "dbtup/Dbtup.hpp"
-
-int
-print_undo_page(int count, void* ptr, Uint32 sz){
- if(count > g_uf_zero.m_undo_pages + 1)
- {
- ndbout_c(" ERROR to many pages in file!!");
- return 1;
- }
-
- File_formats::Undofile::Undo_page * page =
- (File_formats::Undofile::Undo_page*)ptr;
-
- if(page->m_page_header.m_page_lsn_hi != 0 ||
- page->m_page_header.m_page_lsn_lo != 0)
- {
- ndbout << "Undo page: " << count
- << ", lsn = [ "
- << page->m_page_header.m_page_lsn_hi << " "
- << page->m_page_header.m_page_lsn_lo << "] "
- << "words used: " << page->m_words_used << endl;
-
- Uint64 lsn= 0;
- lsn += page->m_page_header.m_page_lsn_hi;
- lsn <<= 32;
- lsn += page->m_page_header.m_page_lsn_lo;
- lsn++;
-
- if(g_verbosity >= 3)
- {
- Uint32 pos= page->m_words_used - 1;
- while(pos + 1 != 0)
- {
- Uint32 len= page->m_data[pos] & 0xFFFF;
- Uint32 type= page->m_data[pos] >> 16;
- const Uint32* src= page->m_data + pos - len + 1;
- Uint32 next_pos= pos - len;
- if(type & File_formats::Undofile::UNDO_NEXT_LSN)
- {
- type &= ~(Uint32)File_formats::Undofile::UNDO_NEXT_LSN;
- lsn--;
- }
- else
- {
- lsn = 0;
- lsn += * (src - 2);
- lsn <<= 32;
- lsn += * (src - 1);
- next_pos -= 2;
- }
- if(g_verbosity > 3)
- printf(" %.4d - %.4d : ", pos - len + 1, pos);
- switch(type){
- case File_formats::Undofile::UNDO_LCP_FIRST:
- case File_formats::Undofile::UNDO_LCP:
- printf("[ %lld LCP %d tab: %d frag: %d ]", lsn,
- src[0], src[1] >> 16, src[1] & 0xFFFF);
- if(g_verbosity <= 3)
- printf("\n");
- break;
- case File_formats::Undofile::UNDO_TUP_ALLOC:
- if(g_verbosity > 3)
- {
- Dbtup::Disk_undo::Alloc *req= (Dbtup::Disk_undo::Alloc*)src;
- printf("[ %lld A %d %d %d ]",
- lsn,
- req->m_file_no_page_idx >> 16,
- req->m_file_no_page_idx & 0xFFFF,
- req->m_page_no);
- }
- break;
- case File_formats::Undofile::UNDO_TUP_UPDATE:
- if(g_verbosity > 3)
- {
- Dbtup::Disk_undo::Update *req= (Dbtup::Disk_undo::Update*)src;
- printf("[ %lld U %d %d %d gci: %d ]",
- lsn,
- req->m_file_no_page_idx >> 16,
- req->m_file_no_page_idx & 0xFFFF,
- req->m_page_no,
- req->m_gci);
- }
- break;
- case File_formats::Undofile::UNDO_TUP_FREE:
- if(g_verbosity > 3)
- {
- Dbtup::Disk_undo::Free *req= (Dbtup::Disk_undo::Free*)src;
- printf("[ %lld F %d %d %d gci: %d ]",
- lsn,
- req->m_file_no_page_idx >> 16,
- req->m_file_no_page_idx & 0xFFFF,
- req->m_page_no,
- req->m_gci);
- }
- break;
- case File_formats::Undofile::UNDO_TUP_CREATE:
- {
- Dbtup::Disk_undo::Create *req = (Dbtup::Disk_undo::Create*)src;
- printf("[ %lld Create %d ]", lsn, req->m_table);
- if(g_verbosity <= 3)
- printf("\n");
- break;
- }
- case File_formats::Undofile::UNDO_TUP_DROP:
- {
- Dbtup::Disk_undo::Drop *req = (Dbtup::Disk_undo::Drop*)src;
- printf("[ %lld Drop %d ]", lsn, req->m_table);
- if(g_verbosity <= 3)
- printf("\n");
- break;
- }
- case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
- {
- Dbtup::Disk_undo::AllocExtent *req = (Dbtup::Disk_undo::AllocExtent*)src;
- printf("[ %lld AllocExtent tab: %d frag: %d file: %d page: %d ]",
- lsn,
- req->m_table,
- req->m_fragment,
- req->m_file_no,
- req->m_page_no);
- if(g_verbosity <= 3)
- printf("\n");
- break;
- }
- case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
- {
- Dbtup::Disk_undo::FreeExtent *req = (Dbtup::Disk_undo::FreeExtent*)src;
- printf("[ %lld FreeExtent tab: %d frag: %d file: %d page: %d ]",
- lsn,
- req->m_table,
- req->m_fragment,
- req->m_file_no,
- req->m_page_no);
- if(g_verbosity <= 3)
- printf("\n");
- break;
- }
- default:
- ndbout_c("[ Unknown type %d len: %d, pos: %d ]", type, len, pos);
- if(!(len && type))
- {
- pos= 0;
- while(pos < page->m_words_used)
- {
- printf("%.8x ", page->m_data[pos]);
- if((pos + 1) % 7 == 0)
- ndbout_c("");
- pos++;
- }
- }
- assert(len && type);
- }
- pos = next_pos;
- if(g_verbosity > 3)
- printf("\n");
- }
- }
- }
-
- if(count == g_uf_zero.m_undo_pages + 1)
- {
- }
-
- return 0;
-}
-
-// hp3750
-Signal::Signal(){}
diff --git a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
deleted file mode 100644
index 79de0715d01..00000000000
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef QMGR_H
-#define QMGR_H
-
-
-#include <pc.hpp>
-#include <NdbTick.h>
-#include <SimulatedBlock.hpp>
-#include <NodeBitmask.hpp>
-#include <SignalCounter.hpp>
-
-#include <signaldata/EventReport.hpp>
-#include <signaldata/ArbitSignalData.hpp>
-#include <signaldata/CmRegSignalData.hpp>
-#include <signaldata/ApiRegSignalData.hpp>
-#include <signaldata/FailRep.hpp>
-#include <signaldata/AllocNodeId.hpp>
-
-#include <SafeCounter.hpp>
-#include <RequestTracker.hpp>
-#include <signaldata/StopReq.hpp>
-
-#include "timer.hpp"
-
-#ifdef QMGR_C
-
-#define NO_REG_APP 1
-
-/* Delay values, ms -----------------------------*/
-#define ZDELAY_REGREQ 1000
-
-/* Type of refuse in CM_NODEINFOREF -------------*/
-#define ZNOT_RUNNING 0
-
-/* Type of continue in CONTINUEB ----------------*/
-#define ZREGREQ_TIMELIMIT 0
-#define ZHB_HANDLING 1
-#define ZREGREQ_MASTER_TIMELIMIT 2
-#define ZAPI_HB_HANDLING 3
-#define ZTIMER_HANDLING 4
-#define ZARBIT_HANDLING 5
-#define ZSTART_FAILURE_LIMIT 6
-
-/* Error Codes ------------------------------*/
-#define ZERRTOOMANY 1101
-#define ZERRALREADYREG 1102
-#define ZERRNHMISSING 1103
-#define ZERRNLMISSING 1104
-#define ZERRAPPMISSING 1105
-#define ZERROR_NOT_IN_CFGFILE 1106
-#define ZERROR_TIMEOUT 1107
-#define ZERROR_NOT_ZINIT 1108
-#define ZERROR_NODEINFOREF 1109
-#define ZERROR_NOTLOCALQMGR 1110
-#define ZERROR_NOTRUNNING 1111
-#define ZCOULD_NOT_OCCUR_ERROR 1112
-#define ZTIME_OUT_ERROR 1113
-#define ZERROR_NOT_DEAD 1114
-#define ZDECLARED_FAIL_ERROR 1115
-#define ZOWN_NODE_ERROR 1116
-#define ZWRONG_STATE_ERROR 1117
-#define ZNODE_ZERO_ERROR 1118
-#define ZWRONG_NODE_ERROR 1119
-
-#endif
-
-
-class Qmgr : public SimulatedBlock {
-public:
- // State values
- enum QmgrState {
- Q_NOT_ACTIVE = 0,
- Q_ACTIVE = 1
- };
-
- enum FailState {
- NORMAL = 0,
- WAITING_FOR_FAILCONF1 = 1,
- 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 {
- StartRecord() {}
- void reset(){
- m_startKey++;
- m_startNode = 0;
- m_gsn = RNIL;
- m_nodes.clearWaitingFor();
- }
- Uint32 m_startKey;
- Uint32 m_startNode;
- Uint64 m_startTimeout;
-
- Uint32 m_gsn;
- SignalCounter m_nodes;
- Uint32 m_latest_gci;
-
- Uint32 m_start_type;
- NdbNodeBitmask m_skip_nodes;
- NdbNodeBitmask m_starting_nodes;
- NdbNodeBitmask m_starting_nodes_w_log;
-
- Uint16 m_president_candidate;
- Uint32 m_president_candidate_gci;
- Uint16 m_regReqReqSent;
- Uint16 m_regReqReqRecv;
- Uint32 m_node_gci[MAX_NDB_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
-
- /**
- * Nodes which we're checking for partitioned cluster
- *
- * i.e. nodes that connect to use, when we already have elected president
- */
- NdbNodeBitmask c_readnodes_nodes;
-
- Uint32 c_maxDynamicId;
-
- // Records
- struct NodeRec {
- UintR ndynamicId;
- Phase phase;
-
- QmgrState sendPrepFailReqStatus;
- QmgrState sendCommitFailReqStatus;
- QmgrState sendPresToStatus;
- FailState failState;
- BlockReference rcv[2]; // remember which failconf we have received
- BlockReference blockRef;
-
- NodeRec() { }
- }; /* p2c: size = 52 bytes */
-
- typedef Ptr<NodeRec> NodeRecPtr;
-
- enum ArbitState {
- ARBIT_NULL = 0,
- ARBIT_INIT = 1, // create new ticket
- ARBIT_FIND = 2, // find candidate arbitrator node
- ARBIT_PREP1 = 3, // PREP db nodes with null ticket
- ARBIT_PREP2 = 4, // PREP db nodes with current ticket
- ARBIT_START = 5, // START arbitrator API thread
- ARBIT_RUN = 6, // running with arbitrator
- ARBIT_CHOOSE = 7, // ask arbitrator after network partition
- ARBIT_CRASH = 8 // crash ourselves
- };
-
- struct ArbitRec {
- ArbitRec() {}
- ArbitState state; // state
- bool newstate; // flag to initialize new state
- unsigned thread; // identifies a continueB "thread"
- NodeId node; // current arbitrator candidate
- ArbitTicket ticket; // ticket
- NodeBitmask apiMask[1+2]; // arbitrators 0=all 1,2=per rank
- NodeBitmask newMask; // new nodes to process in RUN state
- Uint8 sendCount; // control send/recv of signals
- Uint8 recvCount;
- NodeBitmask recvMask; // left to recv
- Uint32 code; // code field from signal
- Uint32 failureNr; // cfailureNr at arbitration start
- Uint32 timeout; // timeout for CHOOSE state
- NDB_TICKS timestamp; // timestamp for checking timeouts
-
- inline bool match(ArbitSignalData* sd) {
- return
- node == sd->node &&
- ticket.match(sd->ticket);
- }
-
- inline void setTimestamp() {
- timestamp = NdbTick_CurrentMillisecond();
- }
-
- inline NDB_TICKS getTimediff() {
- NDB_TICKS now = NdbTick_CurrentMillisecond();
- return now < timestamp ? 0 : now - timestamp;
- }
- };
-
-public:
- Qmgr(Block_context&);
- virtual ~Qmgr();
-
-private:
- BLOCK_DEFINES(Qmgr);
-
- // Transit signals
- void execDEBUG_SIG(Signal* signal);
- void execCONTINUEB(Signal* signal);
- void execCM_HEARTBEAT(Signal* signal);
- void execCM_ADD(Signal* signal);
- void execCM_ACKADD(Signal* signal);
- void execCM_REGREQ(Signal* signal);
- void execCM_REGCONF(Signal* signal);
- void execCM_REGREF(Signal* signal);
- void execCM_NODEINFOREQ(Signal* signal);
- void execCM_NODEINFOCONF(Signal* signal);
- void execCM_NODEINFOREF(Signal* signal);
- void execPREP_FAILREQ(Signal* signal);
- void execPREP_FAILCONF(Signal* signal);
- void execPREP_FAILREF(Signal* signal);
- void execCOMMIT_FAILREQ(Signal* signal);
- void execCOMMIT_FAILCONF(Signal* signal);
- void execFAIL_REP(Signal* signal);
- void execPRES_TOREQ(Signal* signal);
- void execPRES_TOCONF(Signal* signal);
- void execDISCONNECT_REP(Signal* signal);
- void execSYSTEM_ERROR(Signal* signal);
- void execSTOP_REQ(Signal* signal);
-
- // Received signals
- void execDUMP_STATE_ORD(Signal* signal);
- void execCONNECT_REP(Signal* signal);
- void execNDB_FAILCONF(Signal* signal);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execCM_INFOCONF(Signal* signal);
- void execCLOSE_COMCONF(Signal* signal);
- void execAPI_REGREQ(Signal* signal);
- void execAPI_FAILCONF(Signal* signal);
- void execREAD_NODESREQ(Signal* signal);
- void execAPI_FAILREQ(Signal* signal);
-
- void execREAD_NODESREF(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
-
- void execDIH_RESTARTREF(Signal* signal);
- void execDIH_RESTARTCONF(Signal* signal);
-
- void execAPI_VERSION_REQ(Signal* signal);
- void execAPI_BROADCAST_REP(Signal* signal);
-
- void execNODE_FAILREP(Signal *);
- void execALLOC_NODEID_REQ(Signal *);
- void execALLOC_NODEID_CONF(Signal *);
- void execALLOC_NODEID_REF(Signal *);
- void completeAllocNodeIdReq(Signal *);
-
- void execSTART_ORD(Signal*);
-
- // Arbitration signals
- void execARBIT_CFG(Signal* signal);
- void execARBIT_PREPREQ(Signal* signal);
- void execARBIT_PREPCONF(Signal* signal);
- void execARBIT_PREPREF(Signal* signal);
- void execARBIT_STARTCONF(Signal* signal);
- void execARBIT_STARTREF(Signal* signal);
- void execARBIT_CHOOSECONF(Signal* signal);
- void execARBIT_CHOOSEREF(Signal* signal);
- void execARBIT_STOPREP(Signal* signal);
-
- // Statement blocks
- void check_readnodes_reply(Signal* signal, Uint32 nodeId, Uint32 gsn);
- Uint32 check_startup(Signal* signal);
-
- void api_failed(Signal* signal, Uint32 aFailedNode);
- void node_failed(Signal* signal, Uint16 aFailedNode);
- void checkStartInterface(Signal* signal);
- void failReport(Signal* signal,
- Uint16 aFailedNode,
- UintR aSendFailRep,
- FailRep::FailCause failCause);
- void findNeighbours(Signal* signal);
- Uint16 translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId);
-
- void initData(Signal* signal);
- 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(Signal* signal);
- void cmInfoconf010Lab(Signal* signal);
-
- void apiHbHandlingLab(Signal* signal);
- void timerHandlingLab(Signal* signal);
- void hbReceivedLab(Signal* signal);
- void sendCmRegrefLab(Signal* signal, BlockReference ref,
- CmRegRef::ErrorCode);
- void systemErrorBecauseOtherNodeFailed(Signal* signal, Uint32 line, NodeId);
- void systemErrorLab(Signal* signal, Uint32 line,
- const char* message = NULL);
- void prepFailReqLab(Signal* signal);
- void prepFailConfLab(Signal* signal);
- void prepFailRefLab(Signal* signal);
- void commitFailReqLab(Signal* signal);
- void commitFailConfLab(Signal* signal);
- void failReportLab(Signal* signal, Uint16 aFailedNode,
- FailRep::FailCause aFailCause);
- void sendCommitFailReq(Signal* signal);
- void presToConfLab(Signal* signal);
- void sendSttorryLab(Signal* signal);
- void sttor020Lab(Signal* signal);
- void closeComConfLab(Signal* signal);
- void apiRegReqLab(Signal* signal);
- void regreqTimeLimitLab(Signal* signal);
- void regreqTimeMasterLimitLab(Signal* signal);
- void cmRegreq010Lab(Signal* signal);
- void cmRegconf010Lab(Signal* signal);
- void sttor010Lab(Signal* signal);
- void sendHeartbeat(Signal* signal);
- void checkHeartbeat(Signal* signal);
- void setHbDelay(UintR aHbDelay);
- void setHbApiDelay(UintR aHbApiDelay);
- void setArbitTimeout(UintR aArbitTimeout);
-
- // Interface to arbitration module
- void handleArbitStart(Signal* signal);
- void handleArbitApiFail(Signal* signal, Uint16 nodeId);
- void handleArbitNdbAdd(Signal* signal, Uint16 nodeId);
- void handleArbitCheck(Signal* signal);
-
- // Private arbitration routines
- Uint32 getArbitDelay();
- Uint32 getArbitTimeout();
- void startArbitThread(Signal* signal);
- void runArbitThread(Signal* signal);
- void stateArbitInit(Signal* signal);
- void stateArbitFind(Signal* signal);
- void stateArbitPrep(Signal* signal);
- void stateArbitStart(Signal* signal);
- void stateArbitRun(Signal* signal);
- void stateArbitChoose(Signal* signal);
- void stateArbitCrash(Signal* signal);
- void computeArbitNdbMask(NodeBitmask& aMask);
- void reportArbitEvent(Signal* signal, Ndb_logevent_type type);
-
- // Initialisation
- void initData();
- void initRecords();
-
- // Transit signals
- // Variables
-
- 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,
- GlobalSignalNumber gsn,
- Uint32 blockRef,
- Uint32 failNo,
- Uint32 noOfNodes,
- const NodeId theNodes[]);
-
-
-
- /* Wait this time until we try to join the */
- /* cluster again */
-
- /**** Common stored variables ****/
-
- NodeRec *nodeRec;
- ArbitRec arbitRec;
-
- /* Block references ------------------------------*/
- BlockReference cpdistref; /* Dist. ref of president */
-
- /* Node numbers. ---------------------------------*/
- Uint16 cneighbourl; /* Node no. of lower neighbour */
- Uint16 cneighbourh; /* Node no. of higher neighbour */
- Uint16 cpresident; /* Node no. of president */
-
- /* Counters --------------------------------------*/
- Uint16 cnoOfNodes; /* Static node counter */
- /* Status flags ----------------------------------*/
-
- Uint32 c_restartPartialTimeout;
- Uint32 c_restartPartionedTimeout;
- Uint32 c_restartFailureTimeout;
- Uint64 c_start_election_time;
-
- Uint16 creadyDistCom;
-
- Uint16 cdelayRegreq;
- Uint16 cpresidentAlive;
- Uint16 cnoFailedNodes;
- Uint16 cnoPrepFailedNodes;
- Uint16 cnoCommitFailedNodes;
- Uint16 cactivateApiCheck;
- UintR chbApiDelay;
-
- UintR ccommitFailureNr;
- UintR cprepareFailureNr;
- UintR ctoFailureNr;
- UintR cfailureNr;
-
- QmgrState ctoStatus;
- UintR cLqhTimeSignalCount;
- bool cHbSent;
- NDB_TICKS clatestTransactionCheck;
-
- class Timer interface_check_timer;
- class Timer hb_check_timer;
- class Timer hb_send_timer;
- class Timer hb_api_timer;
-
-
- Uint16 cfailedNodes[MAX_NDB_NODES];
- Uint16 cprepFailedNodes[MAX_NDB_NODES];
- Uint16 ccommitFailedNodes[MAX_NDB_NODES];
-
- struct OpAllocNodeIdReq {
- RequestTracker m_tracker;
- AllocNodeIdReq m_req;
- Uint32 m_connectCount;
- Uint32 m_error;
- };
-
- struct OpAllocNodeIdReq opAllocNodeIdReq;
-
- StopReq c_stopReq;
- bool check_multi_node_shutdown(Signal* signal);
-
-#ifdef ERROR_INSERT
- Uint32 c_error_insert_extra;
-#endif
-
- void recompute_version_info(Uint32 type);
- void recompute_version_info(Uint32 type, Uint32 version);
- void execNODE_VERSION_REP(Signal* signal);
- void sendApiVersionRep(Signal* signal, NodeRecPtr nodePtr);
- void sendVersionedDb(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Uint32 minversion);
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
deleted file mode 100644
index ce93b889d92..00000000000
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#define QMGR_C
-#include "Qmgr.hpp"
-
-#define DEBUG(x) { ndbout << "Qmgr::" << x << endl; }
-
-
-void Qmgr::initData()
-{
- creadyDistCom = ZFALSE;
-
- // Records with constant sizes
- nodeRec = new NodeRec[MAX_NODES];
-
- cnoCommitFailedNodes = 0;
- c_maxDynamicId = 0;
- c_clusterNodes.clear();
- c_stopReq.senderRef = 0;
-
- /**
- * Check sanity for NodeVersion
- */
- ndbrequire((Uint32)NodeInfo::DB == 0);
- ndbrequire((Uint32)NodeInfo::API == 1);
- ndbrequire((Uint32)NodeInfo::MGM == 2);
-
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->blockRef = reference();
-
- c_connectedNodes.set(getOwnNodeId());
- setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION;
-
-
- /**
- * Timeouts
- */
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint32 hbDBAPI = 1500;
- ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI);
-
- setHbApiDelay(hbDBAPI);
-}//Qmgr::initData()
-
-void Qmgr::initRecords()
-{
- // Records with dynamic sizes
-}//Qmgr::initRecords()
-
-Qmgr::Qmgr(Block_context& ctx)
- : SimulatedBlock(QMGR, ctx)
-{
- BLOCK_CONSTRUCTOR(Qmgr);
-
- // Transit signals
- addRecSignal(GSN_DUMP_STATE_ORD, &Qmgr::execDUMP_STATE_ORD);
- addRecSignal(GSN_STOP_REQ, &Qmgr::execSTOP_REQ);
- addRecSignal(GSN_DEBUG_SIG, &Qmgr::execDEBUG_SIG);
- addRecSignal(GSN_CONTINUEB, &Qmgr::execCONTINUEB);
- addRecSignal(GSN_CM_HEARTBEAT, &Qmgr::execCM_HEARTBEAT);
- addRecSignal(GSN_CM_ADD, &Qmgr::execCM_ADD);
- addRecSignal(GSN_CM_ACKADD, &Qmgr::execCM_ACKADD);
- addRecSignal(GSN_CM_REGREQ, &Qmgr::execCM_REGREQ);
- addRecSignal(GSN_CM_REGCONF, &Qmgr::execCM_REGCONF);
- addRecSignal(GSN_CM_REGREF, &Qmgr::execCM_REGREF);
- addRecSignal(GSN_CM_NODEINFOREQ, &Qmgr::execCM_NODEINFOREQ);
- addRecSignal(GSN_CM_NODEINFOCONF, &Qmgr::execCM_NODEINFOCONF);
- addRecSignal(GSN_CM_NODEINFOREF, &Qmgr::execCM_NODEINFOREF);
- addRecSignal(GSN_PREP_FAILREQ, &Qmgr::execPREP_FAILREQ);
- addRecSignal(GSN_PREP_FAILCONF, &Qmgr::execPREP_FAILCONF);
- addRecSignal(GSN_PREP_FAILREF, &Qmgr::execPREP_FAILREF);
- addRecSignal(GSN_COMMIT_FAILREQ, &Qmgr::execCOMMIT_FAILREQ);
- addRecSignal(GSN_COMMIT_FAILCONF, &Qmgr::execCOMMIT_FAILCONF);
- addRecSignal(GSN_FAIL_REP, &Qmgr::execFAIL_REP);
- addRecSignal(GSN_PRES_TOREQ, &Qmgr::execPRES_TOREQ);
- addRecSignal(GSN_PRES_TOCONF, &Qmgr::execPRES_TOCONF);
-
- // Received signals
- addRecSignal(GSN_CONNECT_REP, &Qmgr::execCONNECT_REP);
- addRecSignal(GSN_NDB_FAILCONF, &Qmgr::execNDB_FAILCONF);
- addRecSignal(GSN_READ_CONFIG_REQ, &Qmgr::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &Qmgr::execSTTOR);
- addRecSignal(GSN_CLOSE_COMCONF, &Qmgr::execCLOSE_COMCONF);
- addRecSignal(GSN_API_REGREQ, &Qmgr::execAPI_REGREQ);
- addRecSignal(GSN_API_VERSION_REQ, &Qmgr::execAPI_VERSION_REQ);
- addRecSignal(GSN_DISCONNECT_REP, &Qmgr::execDISCONNECT_REP);
- addRecSignal(GSN_API_FAILREQ, &Qmgr::execAPI_FAILREQ);
- addRecSignal(GSN_API_FAILCONF, &Qmgr::execAPI_FAILCONF);
- addRecSignal(GSN_READ_NODESREQ, &Qmgr::execREAD_NODESREQ);
- addRecSignal(GSN_API_BROADCAST_REP, &Qmgr::execAPI_BROADCAST_REP);
-
- addRecSignal(GSN_NODE_FAILREP, &Qmgr::execNODE_FAILREP);
- addRecSignal(GSN_ALLOC_NODEID_REQ, &Qmgr::execALLOC_NODEID_REQ);
- addRecSignal(GSN_ALLOC_NODEID_CONF, &Qmgr::execALLOC_NODEID_CONF);
- addRecSignal(GSN_ALLOC_NODEID_REF, &Qmgr::execALLOC_NODEID_REF);
-
- // Arbitration signals
- addRecSignal(GSN_ARBIT_PREPREQ, &Qmgr::execARBIT_PREPREQ);
- addRecSignal(GSN_ARBIT_PREPCONF, &Qmgr::execARBIT_PREPCONF);
- addRecSignal(GSN_ARBIT_PREPREF, &Qmgr::execARBIT_PREPREF);
- addRecSignal(GSN_ARBIT_STARTCONF, &Qmgr::execARBIT_STARTCONF);
- addRecSignal(GSN_ARBIT_STARTREF, &Qmgr::execARBIT_STARTREF);
- addRecSignal(GSN_ARBIT_CHOOSECONF, &Qmgr::execARBIT_CHOOSECONF);
- addRecSignal(GSN_ARBIT_CHOOSEREF, &Qmgr::execARBIT_CHOOSEREF);
- addRecSignal(GSN_ARBIT_STOPREP, &Qmgr::execARBIT_STOPREP);
-
- addRecSignal(GSN_READ_NODESREF, &Qmgr::execREAD_NODESREF);
- addRecSignal(GSN_READ_NODESCONF, &Qmgr::execREAD_NODESCONF);
-
- addRecSignal(GSN_DIH_RESTARTREF, &Qmgr::execDIH_RESTARTREF);
- addRecSignal(GSN_DIH_RESTARTCONF, &Qmgr::execDIH_RESTARTCONF);
- addRecSignal(GSN_NODE_VERSION_REP, &Qmgr::execNODE_VERSION_REP);
- addRecSignal(GSN_START_ORD, &Qmgr::execSTART_ORD);
-
- initData();
-}//Qmgr::Qmgr()
-
-Qmgr::~Qmgr()
-{
- delete []nodeRec;
-}//Qmgr::~Qmgr()
-
-
-BLOCK_FUNCTIONS(Qmgr)
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
deleted file mode 100644
index 1a309e34c2d..00000000000
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ /dev/null
@@ -1,5268 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#define QMGR_C
-#include "Qmgr.hpp"
-#include <pc.hpp>
-#include <NdbTick.h>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/StartOrd.hpp>
-#include <signaldata/CmInit.hpp>
-#include <signaldata/CloseComReqConf.hpp>
-#include <signaldata/PrepFailReqRef.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/CheckNodeGroups.hpp>
-#include <signaldata/ArbitSignalData.hpp>
-#include <signaldata/ApiRegSignalData.hpp>
-#include <signaldata/ApiVersion.hpp>
-#include <signaldata/BlockCommitOrd.hpp>
-#include <signaldata/FailRep.hpp>
-#include <signaldata/DisconnectRep.hpp>
-#include <signaldata/ApiBroadcast.hpp>
-
-#include <ndb_version.h>
-
-#ifdef DEBUG_ARBIT
-#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
-
-/**
- * c_start.m_gsn = GSN_CM_REGREQ
- * Possible for all nodes
- * c_start.m_nodes contains all nodes in config
- *
- * c_start.m_gsn = GSN_CM_NODEINFOREQ;
- * Set when receiving CM_REGCONF
- * State possible for starting node only (not in cluster)
- *
- * c_start.m_nodes contains all node in alive cluster that
- * that has not replied to GSN_CM_NODEINFOREQ
- * passed by president in GSN_CM_REGCONF
- *
- * c_start.m_gsn = GSN_CM_ADD
- * Possible for president only
- * Set when receiving and accepting CM_REGREQ (to include node)
- *
- * c_start.m_nodes contains all nodes in alive cluster + starting node
- * that has not replied to GSN_CM_ADD
- * by sending GSN_CM_ACKADD
- *
- * c_start.m_gsn = GSN_CM_NODEINFOCONF
- * Possible for non presidents only
- * c_start.m_nodes contains a node that has been accepted by president
- * but has not connected to us yet
- */
-
-// Signal entries and statement blocks
-/* 4 P R O G R A M */
-/*******************************/
-/* CMHEART_BEAT */
-/*******************************/
-void Qmgr::execCM_HEARTBEAT(Signal* signal)
-{
- NodeRecPtr hbNodePtr;
- jamEntry();
- hbNodePtr.i = signal->theData[0];
- ptrCheckGuard(hbNodePtr, MAX_NDB_NODES, nodeRec);
- setNodeInfo(hbNodePtr.i).m_heartbeat_cnt= 0;
- return;
-}//Qmgr::execCM_HEARTBEAT()
-
-/*******************************/
-/* CM_NODEINFOREF */
-/*******************************/
-void Qmgr::execCM_NODEINFOREF(Signal* signal)
-{
- jamEntry();
- systemErrorLab(signal, __LINE__);
- return;
-}//Qmgr::execCM_NODEINFOREF()
-
-/*******************************/
-/* CONTINUEB */
-/*******************************/
-void Qmgr::execCONTINUEB(Signal* signal)
-{
- jamEntry();
- 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 (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) {
- jam();
- return;
- }//if
- regreqTimeLimitLab(signal);
- break;
- case ZREGREQ_MASTER_TIMELIMIT:
- jam();
- if (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) {
- jam();
- return;
- }//if
- //regreqMasterTimeLimitLab(signal);
- failReportLab(signal, c_start.m_startNode, FailRep::ZSTART_IN_REGREQ);
- return;
- break;
- case ZTIMER_HANDLING:
- jam();
- timerHandlingLab(signal);
- return;
- break;
- case ZARBIT_HANDLING:
- jam();
- runArbitThread(signal);
- return;
- break;
- case ZSTART_FAILURE_LIMIT:{
- if (cpresident != ZNIL)
- {
- jam();
- return;
- }
- Uint64 now = NdbTick_CurrentMillisecond();
-
- if (now > (c_start_election_time + c_restartFailureTimeout))
- {
- jam();
- BaseString tmp;
- tmp.append("Shutting down node as total restart time exceeds "
- " StartFailureTimeout as set in config file ");
- if(c_restartFailureTimeout == (Uint32) ~0)
- tmp.append(" 0 (inifinite)");
- else
- tmp.appfmt(" %d", c_restartFailureTimeout);
-
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR, tmp.c_str());
- }
- signal->theData[0] = ZSTART_FAILURE_LIMIT;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
- return;
- }
- default:
- jam();
- // ZCOULD_NOT_OCCUR_ERROR;
- systemErrorLab(signal, __LINE__);
- return;
- break;
- }//switch
- return;
-}//Qmgr::execCONTINUEB()
-
-
-void Qmgr::execDEBUG_SIG(Signal* signal)
-{
- NodeRecPtr debugNodePtr;
- jamEntry();
- debugNodePtr.i = signal->theData[0];
- ptrCheckGuard(debugNodePtr, MAX_NODES, nodeRec);
- return;
-}//Qmgr::execDEBUG_SIG()
-
-/*******************************/
-/* FAIL_REP */
-/*******************************/
-void Qmgr::execFAIL_REP(Signal* signal)
-{
- const FailRep * const failRep = (FailRep *)&signal->theData[0];
- const NodeId failNodeId = failRep->failNodeId;
- const FailRep::FailCause failCause = (FailRep::FailCause)failRep->failCause;
-
- jamEntry();
- failReportLab(signal, failNodeId, failCause);
- return;
-}//Qmgr::execFAIL_REP()
-
-/*******************************/
-/* PRES_TOREQ */
-/*******************************/
-void Qmgr::execPRES_TOREQ(Signal* signal)
-{
- jamEntry();
- BlockReference Tblockref = signal->theData[0];
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = ccommitFailureNr;
- sendSignal(Tblockref, GSN_PRES_TOCONF, signal, 2, JBA);
- return;
-}//Qmgr::execPRES_TOREQ()
-
-void
-Qmgr::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-Qmgr::execSTART_ORD(Signal* signal)
-{
- /**
- * Start timer handling
- */
- signal->theData[0] = ZTIMER_HANDLING;
- sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 1, JBB);
-
- NodeRecPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++)
- {
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->ndynamicId = 0;
- if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB)
- {
- nodePtr.p->phase = ZINIT;
- c_definedNodes.set(nodePtr.i);
- } else {
- nodePtr.p->phase = ZAPI_INACTIVE;
- }
-
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
- nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
- nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
- nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
- nodePtr.p->failState = NORMAL;
- nodePtr.p->rcv[0] = 0;
- nodePtr.p->rcv[1] = 0;
- }//for
-}
-
-/*
-4.2 ADD NODE MODULE*/
-/*##########################################################################*/
-/*
-4.2.1 STTOR */
-/**--------------------------------------------------------------------------
- * Start phase signal, must be handled by all blocks.
- * QMGR is only interested in the first phase.
- * During phase one we clear all registered applications.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* STTOR */
-/*******************************/
-void Qmgr::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- switch(signal->theData[1]){
- case 1:
- initData(signal);
- startphase1(signal);
- recompute_version_info(NodeInfo::DB);
- recompute_version_info(NodeInfo::API);
- recompute_version_info(NodeInfo::MGM);
- 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;
- }
-
- sendSttorryLab(signal);
- return;
-}//Qmgr::execSTTOR()
-
-void Qmgr::sendSttorryLab(Signal* signal)
-{
-/****************************<*/
-/*< STTORRY <*/
-/****************************<*/
- signal->theData[3] = 7;
- signal->theData[4] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- return;
-}//Qmgr::sendSttorryLab()
-
-void Qmgr::startphase1(Signal* signal)
-{
- jamEntry();
-
-
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrAss(nodePtr, nodeRec);
- nodePtr.p->phase = ZSTARTING;
-
- signal->theData[0] = reference();
- sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB);
- return;
-}
-
-void
-Qmgr::execDIH_RESTARTREF(Signal*signal)
-{
- jamEntry();
-
- c_start.m_latest_gci = 0;
- execCM_INFOCONF(signal);
-}
-
-void
-Qmgr::execDIH_RESTARTCONF(Signal*signal)
-{
- jamEntry();
-
- c_start.m_latest_gci = signal->theData[1];
- execCM_INFOCONF(signal);
-}
-
-void Qmgr::setHbDelay(UintR aHbDelay)
-{
- hb_send_timer.setDelay(aHbDelay < 10 ? 10 : aHbDelay);
- hb_send_timer.reset();
- hb_check_timer.setDelay(aHbDelay < 10 ? 10 : aHbDelay);
- hb_check_timer.reset();
-}
-
-void Qmgr::setHbApiDelay(UintR aHbApiDelay)
-{
- chbApiDelay = (aHbApiDelay < 100 ? 100 : aHbApiDelay);
- hb_api_timer.setDelay(chbApiDelay);
- hb_api_timer.reset();
-}
-
-void Qmgr::setArbitTimeout(UintR aArbitTimeout)
-{
- arbitRec.timeout = (aArbitTimeout < 10 ? 10 : aArbitTimeout);
-}
-
-void Qmgr::execCONNECT_REP(Signal* signal)
-{
- jamEntry();
- const Uint32 nodeId = signal->theData[0];
-
- if (ERROR_INSERTED(931))
- {
- jam();
- ndbout_c("Discarding CONNECT_REP(%d)", nodeId);
- infoEvent("Discarding CONNECT_REP(%d)", nodeId);
- return;
- }
-
- c_connectedNodes.set(nodeId);
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NODES, nodeRec);
- switch(nodePtr.p->phase){
- case ZRUNNING:
- ndbrequire(!c_clusterNodes.get(nodeId));
- case ZSTARTING:
- jam();
- break;
- case ZPREPARE_FAIL:
- case ZFAIL_CLOSING:
- jam();
- return;
- case ZAPI_ACTIVE:
- case ZAPI_INACTIVE:
- return;
- case ZINIT:
- ndbrequire(getNodeInfo(nodeId).m_type == NodeInfo::MGM);
- break;
- default:
- ndbrequire(false);
- }
-
- if (getNodeInfo(nodeId).getType() != NodeInfo::DB)
- {
- jam();
- return;
- }
-
- switch(c_start.m_gsn){
- case GSN_CM_REGREQ:
- jam();
- sendCmRegReq(signal, nodeId);
-
- /**
- * We're waiting for CM_REGCONF c_start.m_nodes contains all configured
- * nodes
- */
- ndbrequire(nodePtr.p->phase == ZSTARTING);
- ndbrequire(c_start.m_nodes.isWaitingFor(nodeId));
- return;
- case GSN_CM_NODEINFOREQ:
- jam();
-
- if (c_start.m_nodes.isWaitingFor(nodeId))
- {
- jam();
- ndbrequire(getOwnNodeId() != cpresident);
- ndbrequire(nodePtr.p->phase == ZSTARTING);
- sendCmNodeInfoReq(signal, nodeId, nodePtr.p);
- return;
- }
- return;
- case GSN_CM_NODEINFOCONF:{
- jam();
-
- ndbrequire(getOwnNodeId() != cpresident);
- ndbrequire(nodePtr.p->phase == ZRUNNING);
- if (c_start.m_nodes.isWaitingFor(nodeId))
- {
- jam();
- c_start.m_nodes.clearWaitingFor(nodeId);
- c_start.m_gsn = RNIL;
-
- NodeRecPtr addNodePtr;
- addNodePtr.i = nodeId;
- ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec);
- cmAddPrepare(signal, addNodePtr, nodePtr.p);
- return;
- }
- }
- default:
- (void)1;
- }
-
- ndbrequire(!c_start.m_nodes.isWaitingFor(nodeId));
- ndbrequire(!c_readnodes_nodes.get(nodeId));
- c_readnodes_nodes.set(nodeId);
- signal->theData[0] = reference();
- sendSignal(calcQmgrBlockRef(nodeId), GSN_READ_NODESREQ, signal, 1, JBA);
- return;
-}//Qmgr::execCONNECT_REP()
-
-void
-Qmgr::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
- check_readnodes_reply(signal,
- refToNode(signal->getSendersBlockRef()),
- GSN_READ_NODESCONF);
-}
-
-void
-Qmgr::execREAD_NODESREF(Signal* signal)
-{
- jamEntry();
- check_readnodes_reply(signal,
- refToNode(signal->getSendersBlockRef()),
- GSN_READ_NODESREF);
-}
-
-/*******************************/
-/* CM_INFOCONF */
-/*******************************/
-void Qmgr::execCM_INFOCONF(Signal* signal)
-{
- /**
- * Open communcation to all DB nodes
- */
- 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);
-
- cpresident = ZNIL;
- cpresidentAlive = ZFALSE;
- c_start_election_time = NdbTick_CurrentMillisecond();
-
- signal->theData[0] = ZSTART_FAILURE_LIMIT;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
-
- cmInfoconf010Lab(signal);
-
- return;
-}//Qmgr::execCM_INFOCONF()
-
-Uint32 g_start_type = 0;
-NdbNodeBitmask g_nowait_nodes; // Set by clo
-
-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;
- c_start.m_starting_nodes.clear();
- c_start.m_starting_nodes_w_log.clear();
- c_start.m_regReqReqSent = 0;
- c_start.m_regReqReqRecv = 0;
- c_start.m_skip_nodes = g_nowait_nodes;
- c_start.m_skip_nodes.bitAND(c_definedNodes);
- c_start.m_start_type = g_start_type;
-
- NodeRecPtr nodePtr;
- cnoOfNodes = 0;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
-
- if(getNodeInfo(nodePtr.i).getType() != NodeInfo::DB)
- continue;
-
- c_start.m_nodes.setWaitingFor(nodePtr.i);
- cnoOfNodes++;
-
- if(!c_connectedNodes.get(nodePtr.i))
- continue;
-
- sendCmRegReq(signal, nodePtr.i);
- }
-
- //----------------------------------------
- /* Wait for a while. When it returns */
- /* we will check if we got any CM_REGREF*/
- /* or CM_REGREQ (lower nodeid than our */
- /* own). */
- //----------------------------------------
- signal->theData[0] = ZREGREQ_TIMELIMIT;
- 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){
- CmRegReq * req = (CmRegReq *)&signal->theData[0];
- req->blockRef = reference();
- req->nodeId = getOwnNodeId();
- req->version = NDB_VERSION;
- req->latest_gci = c_start.m_latest_gci;
- req->start_type = c_start.m_start_type;
- c_start.m_skip_nodes.copyto(NdbNodeBitmask::Size, req->skip_nodes);
- const Uint32 ref = calcQmgrBlockRef(nodeId);
- sendSignal(ref, GSN_CM_REGREQ, signal, CmRegReq::SignalLength, JBB);
- DEBUG_START(GSN_CM_REGREQ, nodeId, "");
-
- c_start.m_regReqReqSent++;
-}
-
-/*
-4.4.11 CM_REGREQ */
-/**--------------------------------------------------------------------------
- * If this signal is received someone tries to get registrated.
- * Only the president have the authority make decissions about new nodes,
- * so only a president or a node that claims to be the president may send a
- * reply to this signal.
- * This signal can occur any time after that STTOR was received.
- * CPRESIDENT: Timelimit has expired and someone has
- * decided to enter the president role
- * CPRESIDENT_CANDIDATE:
- * Assigned when we receive a CM_REGREF, if we got more than one REF
- * then we always keep the lowest nodenumber.
- * We accept this nodeno as president when our timelimit expires
- * We should consider the following cases:
- * 1- We are the president. If we are busy by adding new nodes to cluster,
- * then we have to refuse this node to be added.
- * The refused node will try in ZREFUSE_ADD_TIME seconds again.
- * If we are not busy then we confirm
- *
- * 2- We know the president, we dont bother us about this REQ.
- * The president has also got this REQ and will take care of it.
- *
- * 3- The president are not known. We have received CM_INIT, so we compare the
- * senders node number to GETOWNNODEID().
- * If we have a lower number than the sender then we will claim
- * that we are the president so we send him a refuse signal back.
- * We have to wait for the CONTINUEB signal before we can enter the
- * president role. If our GETOWNNODEID() if larger than sender node number,
- * we are not the president and just have to wait for the
- * reply signal (REF) to our CM_REGREQ_2.
- * 4- We havent received the CM_INIT signal so we don't know who we are.
- * Ignore the request.
- *--------------------------------------------------------------------------*/
-/*******************************/
-/* CM_REGREQ */
-/*******************************/
-static
-int
-check_start_type(Uint32 starting, Uint32 own)
-{
- if (starting == (1 << NodeState::ST_INITIAL_START) &&
- ((own & (1 << NodeState::ST_INITIAL_START)) == 0))
- {
- return 1;
- }
- return 0;
-}
-
-void Qmgr::execCM_REGREQ(Signal* signal)
-{
- DEBUG_START3(signal, "");
-
- NodeRecPtr addNodePtr;
- jamEntry();
-
- CmRegReq * const cmRegReq = (CmRegReq *)&signal->theData[0];
- const BlockReference Tblockref = cmRegReq->blockRef;
- const Uint32 startingVersion = cmRegReq->version;
- addNodePtr.i = cmRegReq->nodeId;
- Uint32 gci = 1;
- Uint32 start_type = ~0;
- NdbNodeBitmask skip_nodes;
-
- if (signal->getLength() == CmRegReq::SignalLength)
- {
- jam();
- gci = cmRegReq->latest_gci;
- start_type = cmRegReq->start_type;
- skip_nodes.assign(NdbNodeBitmask::Size, cmRegReq->skip_nodes);
- }
-
- if (creadyDistCom == ZFALSE) {
- jam();
- /* NOT READY FOR DISTRIBUTED COMMUNICATION.*/
- return;
- }//if
-
- if (!ndbCompatible_ndb_ndb(NDB_VERSION, startingVersion)) {
- jam();
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZINCOMPATIBLE_VERSION);
- return;
- }
-
- if (check_start_type(start_type, c_start.m_start_type))
- {
- jam();
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZINCOMPATIBLE_START_TYPE);
- return;
- }
-
- if (cpresident != getOwnNodeId())
- {
- jam();
-
- if (cpresident == ZNIL)
- {
- /***
- * We don't know the president.
- * If the node to be added has lower node id
- * than our president cancidate. Set it as
- * candidate
- */
- jam();
- if (gci > c_start.m_president_candidate_gci ||
- (gci == c_start.m_president_candidate_gci &&
- addNodePtr.i < c_start.m_president_candidate))
- {
- jam();
- c_start.m_president_candidate = addNodePtr.i;
- c_start.m_president_candidate_gci = gci;
- }
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZELECTION);
- return;
- }
-
- /**
- * We are not the president.
- * We know the president.
- * President will answer.
- */
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_PRESIDENT);
- return;
- }//if
-
- if (c_start.m_startNode != 0)
- {
- jam();
- /**
- * President busy by adding another node
- */
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY_PRESIDENT);
- return;
- }//if
-
- if (ctoStatus == Q_ACTIVE)
- {
- jam();
- /**
- * Active taking over as president
- */
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY_TO_PRES);
- return;
- }//if
-
- if (getNodeInfo(addNodePtr.i).m_type != NodeInfo::DB)
- {
- jam();
- /**
- * The new node is not in config file
- */
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_IN_CFG);
- return;
- }
-
- if (getNodeState().getSingleUserMode())
- {
- /**
- * The cluster is in single user mode.
- * Data node is not allowed to get added in the cluster
- * while in single user mode.
- */
- // handle rolling upgrade
- {
- unsigned int get_major = getMajor(startingVersion);
- unsigned int get_minor = getMinor(startingVersion);
- unsigned int get_build = getBuild(startingVersion);
-
- if (startingVersion < NDBD_QMGR_SINGLEUSER_VERSION_5) {
- jam();
-
- infoEvent("QMGR: detect upgrade: new node %u old version %u.%u.%u",
- (unsigned int)addNodePtr.i, get_major, get_minor, get_build);
- /**
- * The new node is old version, send ZINCOMPATIBLE_VERSION instead
- * of ZSINGLE_USER_MODE.
- */
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZINCOMPATIBLE_VERSION);
- } else {
- jam();
-
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZSINGLE_USER_MODE);
- }//if
- }
-
- return;
- }//if
-
- ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec);
- Phase phase = addNodePtr.p->phase;
- if (phase != ZINIT)
- {
- jam();
- DEBUG("phase = " << phase);
- sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_DEAD);
- return;
- }
-
- jam();
- /**
- * WE ARE PRESIDENT AND WE ARE NOT BUSY ADDING ANOTHER NODE.
- * WE WILL TAKE CARE OF THE INCLUSION OF THIS NODE INTO THE CLUSTER.
- * WE NEED TO START TIME SUPERVISION OF THIS. SINCE WE CANNOT STOP
- * TIMED SIGNAL IF THE INCLUSION IS INTERRUPTED WE IDENTIFY
- * EACH INCLUSION WITH A UNIQUE IDENTITY. THIS IS CHECKED WHEN
- * THE SIGNAL ARRIVES. IF IT HAS CHANGED THEN WE SIMPLY IGNORE
- * THE TIMED SIGNAL.
- */
-
- /**
- * Update start record
- */
- c_start.m_startKey++;
- c_start.m_startNode = addNodePtr.i;
-
- /**
- * Assign dynamic id
- */
- UintR TdynId = ++c_maxDynamicId;
- setNodeInfo(addNodePtr.i).m_version = startingVersion;
- recompute_version_info(NodeInfo::DB, 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;
- c_clusterNodes.copyto(NdbNodeBitmask::Size, cmRegConf->allNdbNodes);
- sendSignal(Tblockref, GSN_CM_REGCONF, signal,
- CmRegConf::SignalLength, JBA);
- 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()
-
-void Qmgr::sendCmRegrefLab(Signal* signal, BlockReference TBRef,
- CmRegRef::ErrorCode Terror)
-{
- CmRegRef* ref = (CmRegRef*)signal->getDataPtrSend();
- ref->blockRef = reference();
- ref->nodeId = getOwnNodeId();
- ref->errorCode = Terror;
- ref->presidentCandidate =
- (cpresident == ZNIL ? c_start.m_president_candidate : cpresident);
- ref->candidate_latest_gci = c_start.m_president_candidate_gci;
- ref->latest_gci = c_start.m_latest_gci;
- ref->start_type = c_start.m_start_type;
- c_start.m_skip_nodes.copyto(NdbNodeBitmask::Size, ref->skip_nodes);
- sendSignal(TBRef, GSN_CM_REGREF, signal,
- CmRegRef::SignalLength, JBB);
- DEBUG_START(GSN_CM_REGREF, refToNode(TBRef), "");
- return;
-}//Qmgr::sendCmRegrefLab()
-
-/*
-4.4.11 CM_REGCONF */
-/**--------------------------------------------------------------------------
- * President gives permission to a node which wants to join the cluster.
- * The president will prepare the cluster that a new node will be added to
- * cluster. When the new node has set up all connections to the cluster,
- * the president will send commit to all clusternodes so the phase of the
- * new node can be changed to ZRUNNING.
- *--------------------------------------------------------------------------*/
-/*******************************/
-/* CM_REGCONF */
-/*******************************/
-void Qmgr::execCM_REGCONF(Signal* signal)
-{
- DEBUG_START3(signal, "");
-
- NodeRecPtr myNodePtr;
- NodeRecPtr nodePtr;
- jamEntry();
-
- const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0];
-
- if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) {
- jam();
- char buf[128];
- BaseString::snprintf(buf,sizeof(buf),
- "incompatible version own=0x%x other=0x%x, "
- " shutting down",
- NDB_VERSION, cmRegConf->presidentVersion);
- systemErrorLab(signal, __LINE__, buf);
- return;
- }
-
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
-
- ndbrequire(c_start.m_gsn == GSN_CM_REGREQ);
- ndbrequire(myNodePtr.p->phase == ZSTARTING);
-
- cpdistref = cmRegConf->presidentBlockRef;
- cpresident = cmRegConf->presidentNodeId;
- UintR TdynamicId = cmRegConf->dynamicId;
- c_maxDynamicId = TdynamicId;
- c_clusterNodes.assign(NdbNodeBitmask::Size, cmRegConf->allNdbNodes);
-
- myNodePtr.p->ndynamicId = TdynamicId;
-
-/*--------------------------------------------------------------*/
-// Send this as an EVENT REPORT to inform about hearing about
-// other NDB node proclaiming to be president.
-/*--------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_CM_REGCONF;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = cpresident;
- signal->theData[3] = TdynamicId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- if (c_clusterNodes.get(nodePtr.i)){
- jam();
- ptrAss(nodePtr, nodeRec);
-
- ndbrequire(nodePtr.p->phase == ZINIT);
- nodePtr.p->phase = ZRUNNING;
-
- if(c_connectedNodes.get(nodePtr.i)){
- jam();
- sendCmNodeInfoReq(signal, nodePtr.i, myNodePtr.p);
- }
- }
- }
-
- c_start.m_gsn = GSN_CM_NODEINFOREQ;
- c_start.m_nodes = c_clusterNodes;
-
- return;
-}//Qmgr::execCM_REGCONF()
-
-void
-Qmgr::check_readnodes_reply(Signal* signal, Uint32 nodeId, Uint32 gsn)
-{
- NodeRecPtr myNodePtr;
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
-
- NodeRecPtr nodePtr;
- nodePtr.i = nodeId;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
-
- ndbrequire(c_readnodes_nodes.get(nodeId));
- ReadNodesConf* conf = (ReadNodesConf*)signal->getDataPtr();
- if (gsn == GSN_READ_NODESREF)
- {
- jam();
-retry:
- signal->theData[0] = reference();
- sendSignal(calcQmgrBlockRef(nodeId), GSN_READ_NODESREQ, signal, 1, JBA);
- return;
- }
-
- if (conf->masterNodeId == ZNIL)
- {
- jam();
- goto retry;
- }
-
- Uint32 president = conf->masterNodeId;
- if (president == cpresident)
- {
- jam();
- c_readnodes_nodes.clear(nodeId);
- return;
- }
-
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "check StartPartialTimeout, "
- "node %d thinks %d is president, "
- "I think president is: %d",
- nodeId, president, cpresident);
-
- ndbout_c(buf);
- CRASH_INSERTION(933);
-
- if (getNodeState().startLevel == NodeState::SL_STARTED)
- {
- jam();
- NdbNodeBitmask part;
- part.assign(NdbNodeBitmask::Size, conf->clusterNodes);
- FailRep* rep = (FailRep*)signal->getDataPtrSend();
- rep->failCause = FailRep::ZPARTITIONED_CLUSTER;
- rep->president = cpresident;
- c_clusterNodes.copyto(NdbNodeBitmask::Size, rep->partition);
- Uint32 ref = calcQmgrBlockRef(nodeId);
- Uint32 i = 0;
- while((i = part.find(i + 1)) != NdbNodeBitmask::NotFound)
- {
- if (i == nodeId)
- continue;
- rep->failNodeId = i;
- sendSignal(ref, GSN_FAIL_REP, signal, FailRep::SignalLength, JBA);
- }
- rep->failNodeId = nodeId;
- sendSignal(ref, GSN_FAIL_REP, signal, FailRep::SignalLength, JBB);
- return;
- }
-
- CRASH_INSERTION(932);
-
- progError(__LINE__,
- NDBD_EXIT_PARTITIONED_SHUTDOWN,
- buf);
-
- ndbrequire(false);
-}
-
-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 */
-/**--------------------------------------------------------------------------
- * Only a president or a president candidate can refuse a node to get added to
- * the cluster.
- * Refuse reasons:
- * ZBUSY We know that the sender is the president and we have to
- * make a new CM_REGREQ.
- * ZNOT_IN_CFG This node number is not specified in the configfile,
- * SYSTEM ERROR
- * ZELECTION Sender is a president candidate, his timelimit
- * hasn't expired so maybe someone else will show up.
- * Update the CPRESIDENT_CANDIDATE, then wait for our
- * timelimit to expire.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* CM_REGREF */
-/*******************************/
-static
-const char *
-get_start_type_string(Uint32 st)
-{
- static char buf[256];
-
- if (st == 0)
- {
- return "<ANY>";
- }
- else
- {
- buf[0] = 0;
- for(Uint32 i = 0; i<NodeState::ST_ILLEGAL_TYPE; i++)
- {
- if (st & (1 << i))
- {
- if (buf[0])
- strcat(buf, "/");
- switch(i){
- case NodeState::ST_INITIAL_START:
- strcat(buf, "inital start");
- break;
- case NodeState::ST_SYSTEM_RESTART:
- strcat(buf, "system restart");
- break;
- case NodeState::ST_NODE_RESTART:
- strcat(buf, "node restart");
- break;
- case NodeState::ST_INITIAL_NODE_RESTART:
- strcat(buf, "initial node restart");
- break;
- }
- }
- }
- return buf;
- }
-}
-
-void Qmgr::execCM_REGREF(Signal* signal)
-{
- jamEntry();
-
- CmRegRef* ref = (CmRegRef*)signal->getDataPtr();
- UintR TaddNodeno = ref->nodeId;
- UintR TrefuseReason = ref->errorCode;
- Uint32 candidate = ref->presidentCandidate;
- Uint32 node_gci = 1;
- Uint32 candidate_gci = 1;
- Uint32 start_type = ~0;
- NdbNodeBitmask skip_nodes;
- DEBUG_START3(signal, TrefuseReason);
-
- if (signal->getLength() == CmRegRef::SignalLength)
- {
- jam();
- node_gci = ref->latest_gci;
- candidate_gci = ref->candidate_latest_gci;
- start_type = ref->start_type;
- skip_nodes.assign(NdbNodeBitmask::Size, ref->skip_nodes);
- }
-
- c_start.m_regReqReqRecv++;
-
- // Ignore block reference in data[0]
-
- if(candidate != c_start.m_president_candidate)
- {
- jam();
- c_start.m_regReqReqRecv = ~0;
- }
-
- c_start.m_starting_nodes.set(TaddNodeno);
- if (node_gci)
- {
- jam();
- c_start.m_starting_nodes_w_log.set(TaddNodeno);
- }
- c_start.m_node_gci[TaddNodeno] = node_gci;
-
- skip_nodes.bitAND(c_definedNodes);
- c_start.m_skip_nodes.bitOR(skip_nodes);
-
- char buf[100];
- switch (TrefuseReason) {
- case CmRegRef::ZINCOMPATIBLE_VERSION:
- jam();
- systemErrorLab(signal, __LINE__,
- "incompatible version, "
- "connection refused by running ndb node");
- case CmRegRef::ZINCOMPATIBLE_START_TYPE:
- jam();
- BaseString::snprintf(buf, sizeof(buf),
- "incompatible start type detected: node %d"
- " reports %s(%d) my start type: %s(%d)",
- TaddNodeno,
- get_start_type_string(start_type), start_type,
- get_start_type_string(c_start.m_start_type),
- c_start.m_start_type);
- progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT, buf);
- break;
- case CmRegRef::ZBUSY:
- case CmRegRef::ZBUSY_TO_PRES:
- case CmRegRef::ZBUSY_PRESIDENT:
- jam();
- cpresidentAlive = ZTRUE;
- signal->theData[3] = 0;
- break;
- case CmRegRef::ZNOT_IN_CFG:
- jam();
- progError(__LINE__, NDBD_EXIT_NODE_NOT_IN_CONFIG);
- break;
- case CmRegRef::ZNOT_DEAD:
- jam();
- progError(__LINE__, NDBD_EXIT_NODE_NOT_DEAD);
- break;
- case CmRegRef::ZSINGLE_USER_MODE:
- jam();
- progError(__LINE__, NDBD_EXIT_SINGLE_USER_MODE);
- break;
- /**
- * For generic refuse error.
- * e.g. in online upgrade, we can use this error code instead
- * of the incompatible error code.
- */
- case CmRegRef::ZGENERIC:
- jam();
- progError(__LINE__, NDBD_EXIT_GENERIC);
- break;
- case CmRegRef::ZELECTION:
- jam();
- if (candidate_gci > c_start.m_president_candidate_gci ||
- (candidate_gci == c_start.m_president_candidate_gci &&
- candidate < c_start.m_president_candidate))
- {
- jam();
- //----------------------------------------
- /* We may already have a candidate */
- /* choose the lowest nodeno */
- //----------------------------------------
- signal->theData[3] = 2;
- c_start.m_president_candidate = candidate;
- c_start.m_president_candidate_gci = candidate_gci;
- } else {
- signal->theData[3] = 4;
- }//if
- break;
- case CmRegRef::ZNOT_PRESIDENT:
- jam();
- cpresidentAlive = ZTRUE;
- signal->theData[3] = 3;
- break;
- default:
- jam();
- signal->theData[3] = 5;
- /*empty*/;
- break;
- }//switch
-/*--------------------------------------------------------------*/
-// Send this as an EVENT REPORT to inform about hearing about
-// other NDB node proclaiming not to be president.
-/*--------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_CM_REGREF;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = TaddNodeno;
-//-----------------------------------------
-// signal->theData[3] filled in above
-//-----------------------------------------
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- if(cpresidentAlive == ZTRUE)
- {
- jam();
- DEBUG("cpresidentAlive");
- return;
- }
-
- if(c_start.m_regReqReqSent != c_start.m_regReqReqRecv)
- {
- jam();
- DEBUG(c_start.m_regReqReqSent << " != " << c_start.m_regReqReqRecv);
- return;
- }
-
- if(c_start.m_president_candidate != getOwnNodeId())
- {
- jam();
- DEBUG("i'm not the candidate");
- return;
- }
-
- /**
- * All connected nodes has agreed
- */
- if(check_startup(signal))
- {
- jam();
- electionWon(signal);
- }
-
- return;
-}//Qmgr::execCM_REGREF()
-
-Uint32
-Qmgr::check_startup(Signal* signal)
-{
- Uint64 now = NdbTick_CurrentMillisecond();
- Uint64 partial_timeout = c_start_election_time + c_restartPartialTimeout;
- Uint64 partitioned_timeout = partial_timeout + c_restartPartionedTimeout;
-
- /**
- * First see if we should wait more...
- */
- NdbNodeBitmask tmp;
- tmp.bitOR(c_start.m_skip_nodes);
- tmp.bitOR(c_start.m_starting_nodes);
-
- NdbNodeBitmask wait;
- wait.assign(c_definedNodes);
- wait.bitANDC(tmp);
-
- Uint32 retVal = 0;
- Uint32 incompleteng = MAX_NDB_NODES; // Illegal value
- NdbNodeBitmask report_mask;
-
- if ((c_start.m_latest_gci == 0) ||
- (c_start.m_start_type == (1 << NodeState::ST_INITIAL_START)))
- {
- if (!tmp.equal(c_definedNodes))
- {
- jam();
- signal->theData[1] = 1;
- signal->theData[2] = ~0;
- report_mask.assign(wait);
- retVal = 0;
- goto start_report;
- }
- else
- {
- jam();
- signal->theData[1] = 0x8000;
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 1;
- goto start_report;
- }
- }
- {
- const bool all = c_start.m_starting_nodes.equal(c_definedNodes);
- CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
-
- {
- /**
- * Check for missing node group directly
- */
- NdbNodeBitmask check;
- check.assign(c_definedNodes);
- check.bitANDC(c_start.m_starting_nodes); // Not connected nodes
- check.bitOR(c_start.m_starting_nodes_w_log);
-
- sd->blockRef = reference();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
- sd->mask = check;
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
-
- if (sd->output == CheckNodeGroups::Lose)
- {
- jam();
- goto missing_nodegroup;
- }
- }
-
- sd->blockRef = reference();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
- sd->mask = c_start.m_starting_nodes;
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
-
- const Uint32 result = sd->output;
-
- sd->blockRef = reference();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
- sd->mask = c_start.m_starting_nodes_w_log;
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
-
- const Uint32 result_w_log = sd->output;
-
- if (tmp.equal(c_definedNodes))
- {
- /**
- * All nodes (wrt no-wait nodes) has connected...
- * this means that we will now start or die
- */
- jam();
- switch(result_w_log){
- case CheckNodeGroups::Lose:
- {
- jam();
- goto missing_nodegroup;
- }
- case CheckNodeGroups::Win:
- signal->theData[1] = all ? 0x8001 : 0x8002;
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 1;
- goto check_log;
- case CheckNodeGroups::Partitioning:
- ndbrequire(result != CheckNodeGroups::Lose);
- signal->theData[1] =
- all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003);
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 1;
- goto check_log;
- }
- }
-
- if (now < partial_timeout)
- {
- jam();
- signal->theData[1] = c_restartPartialTimeout == (Uint32) ~0 ? 2 : 3;
- signal->theData[2] = Uint32((partial_timeout - now + 500) / 1000);
- report_mask.assign(wait);
- retVal = 0;
- goto start_report;
- }
-
- /**
- * Start partial has passed...check for partitioning...
- */
- switch(result_w_log){
- case CheckNodeGroups::Lose:
- jam();
- goto missing_nodegroup;
- case CheckNodeGroups::Partitioning:
- if (now < partitioned_timeout && result != CheckNodeGroups::Win)
- {
- goto missinglog;
- }
- // Fall through...
- case CheckNodeGroups::Win:
- signal->theData[1] =
- all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003);
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 2;
- goto check_log;
- }
- }
- ndbrequire(false);
-
-check_log:
- jam();
- {
- Uint32 save[4+4*NdbNodeBitmask::Size];
- memcpy(save, signal->theData, sizeof(save));
-
- signal->theData[0] = 0;
- c_start.m_starting_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
- memcpy(signal->theData+1+NdbNodeBitmask::Size, c_start.m_node_gci,
- 4*MAX_NDB_NODES);
- EXECUTE_DIRECT(DBDIH, GSN_DIH_RESTARTREQ, signal,
- 1+NdbNodeBitmask::Size+MAX_NDB_NODES);
-
- incompleteng = signal->theData[0];
- memcpy(signal->theData, save, sizeof(save));
-
- if (incompleteng != MAX_NDB_NODES)
- {
- jam();
- if (retVal == 1)
- {
- jam();
- goto incomplete_log;
- }
- else if (retVal == 2)
- {
- if (now <= partitioned_timeout)
- {
- jam();
- goto missinglog;
- }
- else
- {
- goto incomplete_log;
- }
- }
- ndbrequire(false);
- }
- }
- goto start_report;
-
-missinglog:
- signal->theData[1] = c_restartPartionedTimeout == (Uint32) ~0 ? 4 : 5;
- signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000);
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 0;
- goto start_report;
-
-start_report:
- jam();
- {
- Uint32 sz = NdbNodeBitmask::Size;
- signal->theData[0] = NDB_LE_StartReport;
- signal->theData[3] = sz;
- Uint32* ptr = signal->theData+4;
- c_definedNodes.copyto(sz, ptr); ptr += sz;
- c_start.m_starting_nodes.copyto(sz, ptr); ptr += sz;
- c_start.m_skip_nodes.copyto(sz, ptr); ptr += sz;
- report_mask.copyto(sz, ptr); ptr+= sz;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal,
- 4+4*NdbNodeBitmask::Size, JBB);
- }
- return retVal;
-
-missing_nodegroup:
- jam();
- {
- char buf[100], mask1[100], mask2[100];
- c_start.m_starting_nodes.getText(mask1);
- tmp.assign(c_start.m_starting_nodes);
- tmp.bitANDC(c_start.m_starting_nodes_w_log);
- tmp.getText(mask2);
- BaseString::snprintf(buf, sizeof(buf),
- "Unable to start missing node group! "
- " starting: %s (missing fs for: %s)",
- mask1, mask2);
- progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
- return 0; // Deadcode
- }
-
-incomplete_log:
- jam();
- {
- char buf[100], mask1[100];
- c_start.m_starting_nodes.getText(mask1);
- BaseString::snprintf(buf, sizeof(buf),
- "Incomplete log for node group: %d! "
- " starting nodes: %s",
- incompleteng, mask1);
- progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
- return 0; // Deadcode
- }
-}
-
-void
-Qmgr::electionWon(Signal* signal){
- NodeRecPtr myNodePtr;
- cpresident = getOwnNodeId(); /* This node becomes president. */
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
-
- myNodePtr.p->phase = ZRUNNING;
-
- cpdistref = reference();
- cneighbourl = ZNIL;
- cneighbourh = ZNIL;
- myNodePtr.p->ndynamicId = 1;
- c_maxDynamicId = 1;
- c_clusterNodes.clear();
- c_clusterNodes.set(getOwnNodeId());
-
- cpresidentAlive = ZTRUE;
- c_start_election_time = ~0;
- c_start.reset();
-
- signal->theData[0] = NDB_LE_CM_REGCONF;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = cpresident;
- signal->theData[3] = 1;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
-
- c_start.m_starting_nodes.clear(getOwnNodeId());
- if (c_start.m_starting_nodes.isclear())
- {
- jam();
- sendSttorryLab(signal);
- }
-}
-
-/*
-4.4.11 CONTINUEB */
-/*--------------------------------------------------------------------------*/
-/* */
-/*--------------------------------------------------------------------------*/
-/****************************>---------------------------------------------*/
-/* CONTINUEB > SENDER: Own block, Own node */
-/****************************>-------+INPUT : TCONTINUEB_TYPE */
-/*--------------------------------------------------------------*/
-void Qmgr::regreqTimeLimitLab(Signal* signal)
-{
- if(cpresident == ZNIL)
- {
- if (c_start.m_president_candidate == ZNIL)
- {
- jam();
- c_start.m_president_candidate = getOwnNodeId();
- }
-
- cmInfoconf010Lab(signal);
- }
-}//Qmgr::regreqTimelimitLab()
-
-/**---------------------------------------------------------------------------
- * The new node will take care of giving information about own node and ask
- * all other nodes for nodeinfo. The new node will use CM_NODEINFOREQ for
- * that purpose. When the setup of connections to all running, the president
- * will send a commit to all running nodes + the new node
- * INPUT: NODE_PTR1, must be set as ZNIL if we don't enter CONNECT_NODES)
- * from signal CM_NODEINFOCONF.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* CM_NODEINFOCONF */
-/*******************************/
-void Qmgr::execCM_NODEINFOCONF(Signal* signal)
-{
- DEBUG_START3(signal, "");
-
- jamEntry();
-
- CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtr();
-
- 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);
-
- /**
- * Update node info
- */
- 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;
- recompute_version_info(NodeInfo::DB, version);
-
- if(!c_start.m_nodes.done()){
- jam();
- return;
- }
-
- /**********************************************<*/
- /* Send an ack. back to the president. */
- /* CM_ACKADD */
- /* The new node has been registered by all */
- /* running nodes and has stored nodeinfo about */
- /* all running nodes. The new node has to wait */
- /* for CM_ADD (commit) from president to become */
- /* a running node in the cluster. */
- /**********************************************<*/
- sendCmAckAdd(signal, getOwnNodeId(), CmAdd::Prepare);
- return;
-}//Qmgr::execCM_NODEINFOCONF()
-
-/**---------------------------------------------------------------------------
- * A new node sends nodeinfo about himself. The new node asks for
- * corresponding nodeinfo back in the CM_NODEINFOCONF.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* CM_NODEINFOREQ */
-/*******************************/
-void Qmgr::execCM_NODEINFOREQ(Signal* signal)
-{
- 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;
- c_maxDynamicId = req->dynamicId;
-
- 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();
-
-#if 1
- warningEvent("Recieved request to incorperate node %u, "
- "while error handling has not yet completed",
- nodePtr.i);
-
- ndbrequire(getOwnNodeId() != cpresident);
- ndbrequire(signal->header.theVerId_signalNumber == GSN_CM_ADD);
- c_start.m_nodes.clearWaitingFor();
- c_start.m_nodes.setWaitingFor(nodePtr.i);
- c_start.m_gsn = GSN_CM_NODEINFOCONF;
-#else
- warningEvent("Enabling communication to CM_ADD node %u state=%d",
- nodePtr.i,
- nodePtr.p->phase);
- 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);
-#endif
- return;
- case ZSTARTING:
- break;
- case ZRUNNING:
- case ZPREPARE_FAIL:
- case ZAPI_ACTIVE:
- case ZAPI_INACTIVE:
- ndbrequire(false);
- }
-
- sendCmAckAdd(signal, nodePtr.i, CmAdd::Prepare);
- sendApiVersionRep(signal, nodePtr);
-
- /* 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::sendApiVersionRep(Signal* signal, NodeRecPtr nodePtr)
-{
- if (getNodeInfo(nodePtr.i).m_version >= NDBD_NODE_VERSION_REP)
- {
- jam();
- Uint32 ref = calcQmgrBlockRef(nodePtr.i);
- for(Uint32 i = 1; i<MAX_NODES; i++)
- {
- jam();
- Uint32 version = getNodeInfo(i).m_version;
- Uint32 type = getNodeInfo(i).m_type;
- if (type != NodeInfo::DB && version)
- {
- jam();
- signal->theData[0] = i;
- signal->theData[1] = version;
- sendSignal(ref, GSN_NODE_VERSION_REP, signal, 2, JBB);
- }
- }
- }
-}
-
-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 */
-/**--------------------------------------------------------------------------
- * Prepare a running node to add a new node to the cluster. The running node
- * will change phase of the new node fron ZINIT to ZWAITING. The running node
- * will also mark that we have received a prepare. When the new node has sent
- * us nodeinfo we can send an acknowledgement back to the president. When all
- * running nodes has acknowledged the new node, the president will send a
- * commit and we can change phase of the new node to ZRUNNING. The president
- * will also send CM_ADD to himself.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* CM_ADD */
-/*******************************/
-void Qmgr::execCM_ADD(Signal* signal)
-{
- NodeRecPtr addNodePtr;
- 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);
-
- DEBUG_START3(signal, type);
-
- if(nodePtr.p->phase == ZSTARTING){
- jam();
- /**
- * 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:
- cmAddPrepare(signal, addNodePtr, nodePtr.p);
- break;
- case CmAdd::AddCommit:{
- jam();
- ndbrequire(addNodePtr.p->phase == ZSTARTING);
- addNodePtr.p->phase = ZRUNNING;
- setNodeInfo(addNodePtr.i).m_heartbeat_cnt= 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
- */
- signal->theData[0] = addNodePtr.i;
- sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA);
-
- sendCmAckAdd(signal, addNodePtr.i, CmAdd::AddCommit);
- if(getOwnNodeId() != cpresident){
- jam();
- c_start.reset();
- }
- break;
- }
- case CmAdd::CommitNew:
- jam();
- ndbrequire(false);
- }
-
-}//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;
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 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);
-
- sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew);
-}
-
-/* 4.10.7 CM_ACKADD - PRESIDENT IS RECEIVER - */
-/*---------------------------------------------------------------------------*/
-/* Entry point for an ack add signal.
- * The TTYPE defines if it is a prepare or a commit. */
-/*---------------------------------------------------------------------------*/
-void Qmgr::execCM_ACKADD(Signal* signal)
-{
- NodeRecPtr addNodePtr;
- NodeRecPtr senderNodePtr;
- jamEntry();
-
- CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtr();
- 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 (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();
-
- /*----------------------------------------------------------------------*/
- /* 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;
- NodeReceiverGroup rg(QMGR, c_clusterNodes);
- sendSignal(rg, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA);
- DEBUG_START2(GSN_CM_ADD, rg, "AddCommit");
- return;
- }
- case CmAdd::AddCommit:{
- jam();
-
- /****************************************/
- /* 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;
-
- sendSignal(calcQmgrBlockRef(addNodePtr.i), GSN_CM_ADD, signal,
- CmAdd::SignalLength, JBA);
- DEBUG_START(GSN_CM_ADD, addNodePtr.i, "CommitNew");
- return;
- }
- case CmAdd::CommitNew:
- jam();
- /**
- * Tell arbitration about new node.
- */
- handleArbitNdbAdd(signal, addNodePtr.i);
- c_start.reset();
-
- if (c_start.m_starting_nodes.get(addNodePtr.i))
- {
- jam();
- c_start.m_starting_nodes.clear(addNodePtr.i);
- if (c_start.m_starting_nodes.isclear())
- {
- jam();
- sendSttorryLab(signal);
- }
- }
- return;
- }//switch
- ndbrequire(false);
-}//Qmgr::execCM_ACKADD()
-
-/**-------------------------------------------------------------------------
- * WE HAVE BEEN INCLUDED INTO THE CLUSTER. IT IS NOW TIME TO CALCULATE WHICH
- * ARE OUR LEFT AND RIGHT NEIGHBOURS FOR THE HEARTBEAT PROTOCOL.
- *--------------------------------------------------------------------------*/
-void Qmgr::findNeighbours(Signal* signal)
-{
- UintR toldLeftNeighbour;
- UintR tfnLeftFound;
- UintR tfnMaxFound;
- UintR tfnMinFound;
- UintR tfnRightFound;
- NodeRecPtr fnNodePtr;
- NodeRecPtr fnOwnNodePtr;
-
- toldLeftNeighbour = cneighbourl;
- tfnLeftFound = 0;
- tfnMaxFound = 0;
- tfnMinFound = (UintR)-1;
- tfnRightFound = (UintR)-1;
- fnOwnNodePtr.i = getOwnNodeId();
- ptrCheckGuard(fnOwnNodePtr, MAX_NDB_NODES, nodeRec);
- for (fnNodePtr.i = 1; fnNodePtr.i < MAX_NDB_NODES; fnNodePtr.i++) {
- jam();
- ptrAss(fnNodePtr, nodeRec);
- if (fnNodePtr.i != fnOwnNodePtr.i) {
- if (fnNodePtr.p->phase == ZRUNNING) {
- if (tfnMinFound > fnNodePtr.p->ndynamicId) {
- jam();
- tfnMinFound = fnNodePtr.p->ndynamicId;
- }//if
- if (tfnMaxFound < fnNodePtr.p->ndynamicId) {
- jam();
- tfnMaxFound = fnNodePtr.p->ndynamicId;
- }//if
- if (fnOwnNodePtr.p->ndynamicId > fnNodePtr.p->ndynamicId) {
- jam();
- if (fnNodePtr.p->ndynamicId > tfnLeftFound) {
- jam();
- tfnLeftFound = fnNodePtr.p->ndynamicId;
- }//if
- } else {
- jam();
- if (fnNodePtr.p->ndynamicId < tfnRightFound) {
- jam();
- tfnRightFound = fnNodePtr.p->ndynamicId;
- }//if
- }//if
- }//if
- }//if
- }//for
- if (tfnLeftFound == 0) {
- if (tfnMinFound == (UintR)-1) {
- jam();
- cneighbourl = ZNIL;
- } else {
- jam();
- cneighbourl = translateDynamicIdToNodeId(signal, tfnMaxFound);
- }//if
- } else {
- jam();
- cneighbourl = translateDynamicIdToNodeId(signal, tfnLeftFound);
- }//if
- if (tfnRightFound == (UintR)-1) {
- if (tfnMaxFound == 0) {
- jam();
- cneighbourh = ZNIL;
- } else {
- jam();
- cneighbourh = translateDynamicIdToNodeId(signal, tfnMinFound);
- }//if
- } else {
- jam();
- cneighbourh = translateDynamicIdToNodeId(signal, tfnRightFound);
- }//if
- if (toldLeftNeighbour != cneighbourl) {
- jam();
- if (cneighbourl != ZNIL) {
- jam();
- /**-------------------------------------------------------------------*/
- /* WE ARE SUPERVISING A NEW LEFT NEIGHBOUR. WE START WITH ALARM COUNT
- * EQUAL TO ZERO.
- *---------------------------------------------------------------------*/
- fnNodePtr.i = cneighbourl;
- ptrCheckGuard(fnNodePtr, MAX_NDB_NODES, nodeRec);
- setNodeInfo(fnNodePtr.i).m_heartbeat_cnt= 0;
- }//if
- }//if
-
- signal->theData[0] = NDB_LE_FIND_NEIGHBOURS;
- signal->theData[1] = getOwnNodeId();
- signal->theData[2] = cneighbourl;
- signal->theData[3] = cneighbourh;
- signal->theData[4] = fnOwnNodePtr.p->ndynamicId;
- UintR Tlen = 5;
- for (fnNodePtr.i = 1; fnNodePtr.i < MAX_NDB_NODES; fnNodePtr.i++) {
- jam();
- ptrAss(fnNodePtr, nodeRec);
- if (fnNodePtr.i != fnOwnNodePtr.i) {
- if (fnNodePtr.p->phase == ZRUNNING) {
- jam();
- signal->theData[Tlen] = fnNodePtr.i;
- signal->theData[Tlen + 1] = fnNodePtr.p->ndynamicId;
- if (Tlen < 25) {
- /*----------------------------------------------------------------*/
- // This code can only report 11 nodes.
- // We need to update this when increasing the number of nodes
- // supported.
- /*-----------------------------------------------------------------*/
- Tlen += 2;
- }
- }//if
- }//if
- }//for
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, Tlen, JBB);
-}//Qmgr::findNeighbours()
-
-/*
-4.10.7 INIT_DATA */
-/*---------------------------------------------------------------------------*/
-/*---------------------------------------------------------------------------*/
-void Qmgr::initData(Signal* signal)
-{
- cfailureNr = 1;
- ccommitFailureNr = 1;
- cprepareFailureNr = 1;
- cnoFailedNodes = 0;
- cnoPrepFailedNodes = 0;
- creadyDistCom = ZFALSE;
- cpresident = ZNIL;
- c_start.m_president_candidate = ZNIL;
- c_start.m_president_candidate_gci = 0;
- cpdistref = 0;
- cneighbourh = ZNIL;
- cneighbourl = ZNIL;
- cdelayRegreq = ZDELAY_REGREQ;
- cactivateApiCheck = 0;
- ctoStatus = Q_NOT_ACTIVE;
-
- interface_check_timer.setDelay(1000);
- interface_check_timer.reset();
- clatestTransactionCheck = 0;
-
- cLqhTimeSignalCount = 0;
-
- // catch-all for missing initializations
- memset(&arbitRec, 0, sizeof(arbitRec));
-
- /**
- * Timeouts
- */
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Uint32 hbDBDB = 1500;
- Uint32 arbitTimeout = 1000;
- c_restartPartialTimeout = 30000;
- c_restartPartionedTimeout = 60000;
- c_restartFailureTimeout = ~0;
- ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB);
- ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout);
- ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT,
- &c_restartPartialTimeout);
- ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT,
- &c_restartPartionedTimeout);
- ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT,
- &c_restartFailureTimeout);
-
- if(c_restartPartialTimeout == 0)
- {
- c_restartPartialTimeout = ~0;
- }
-
- if (c_restartPartionedTimeout ==0)
- {
- c_restartPartionedTimeout = ~0;
- }
-
- if (c_restartFailureTimeout == 0)
- {
- c_restartFailureTimeout = ~0;
- }
-
- setHbDelay(hbDBDB);
- 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 =
- m_ctx.m_config.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);
- }
-}//Qmgr::initData()
-
-
-/**---------------------------------------------------------------------------
- * HERE WE RECEIVE THE JOB TABLE SIGNAL EVERY 10 MILLISECONDS.
- * WE WILL USE THIS TO CHECK IF IT IS TIME TO CHECK THE NEIGHBOUR NODE.
- * WE WILL ALSO SEND A SIGNAL TO BLOCKS THAT NEED A TIME SIGNAL AND
- * DO NOT WANT TO USE JOB TABLE SIGNALS.
- *---------------------------------------------------------------------------*/
-void Qmgr::timerHandlingLab(Signal* signal)
-{
- NDB_TICKS TcurrentTime = NdbTick_CurrentMillisecond();
- NodeRecPtr myNodePtr;
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
-
- if (myNodePtr.p->phase == ZRUNNING) {
- jam();
- /**---------------------------------------------------------------------
- * WE ARE ONLY PART OF HEARTBEAT CLUSTER IF WE ARE UP AND RUNNING.
- *---------------------------------------------------------------------*/
- if (hb_send_timer.check(TcurrentTime)) {
- jam();
- sendHeartbeat(signal);
- hb_send_timer.reset();
- }
- if (hb_check_timer.check(TcurrentTime)) {
- jam();
- checkHeartbeat(signal);
- hb_check_timer.reset();
- }
- }
-
- if (interface_check_timer.check(TcurrentTime)) {
- jam();
- interface_check_timer.reset();
- checkStartInterface(signal);
- }
-
- if (hb_api_timer.check(TcurrentTime))
- {
- jam();
- hb_api_timer.reset();
- apiHbHandlingLab(signal);
- }
-
- if (cactivateApiCheck != 0) {
- jam();
- if (clatestTransactionCheck == 0) {
- //-------------------------------------------------------------
- // Initialise the Transaction check timer.
- //-------------------------------------------------------------
- clatestTransactionCheck = TcurrentTime;
- }//if
- int counter = 0;
- while (TcurrentTime > ((NDB_TICKS)10 + clatestTransactionCheck)) {
- jam();
- clatestTransactionCheck += (NDB_TICKS)10;
- sendSignal(DBTC_REF, GSN_TIME_SIGNAL, signal, 1, JBB);
- cLqhTimeSignalCount++;
- if (cLqhTimeSignalCount >= 100) {
- cLqhTimeSignalCount = 0;
- sendSignal(DBLQH_REF, GSN_TIME_SIGNAL, signal, 1, JBB);
- }//if
- counter++;
- if (counter > 1) {
- jam();
- break;
- } else {
- ;
- }//if
- }//while
- }//if
-
- //--------------------------------------------------
- // Resend this signal with 10 milliseconds delay.
- //--------------------------------------------------
- signal->theData[0] = ZTIMER_HANDLING;
- sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 10, 1);
- return;
-}//Qmgr::timerHandlingLab()
-
-/*---------------------------------------------------------------------------*/
-/* THIS MODULE HANDLES THE SENDING AND RECEIVING OF HEARTBEATS. */
-/*---------------------------------------------------------------------------*/
-void Qmgr::sendHeartbeat(Signal* signal)
-{
- NodeRecPtr localNodePtr;
- localNodePtr.i = cneighbourh;
- if (localNodePtr.i == ZNIL) {
- jam();
- /**---------------------------------------------------------------------
- * THERE ARE NO NEIGHBOURS. THIS IS POSSIBLE IF WE ARE THE ONLY NODE IN
- * THE CLUSTER.IN THIS CASE WE DO NOT NEED TO SEND ANY HEARTBEAT SIGNALS.
- *-----------------------------------------------------------------------*/
- return;
- }//if
- ptrCheckGuard(localNodePtr, MAX_NDB_NODES, nodeRec);
- signal->theData[0] = getOwnNodeId();
-
- sendSignal(localNodePtr.p->blockRef, GSN_CM_HEARTBEAT, signal, 1, JBA);
-#ifdef VM_TRACE
- signal->theData[0] = NDB_LE_SentHeartbeat;
- signal->theData[1] = localNodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-#endif
-}//Qmgr::sendHeartbeat()
-
-void Qmgr::checkHeartbeat(Signal* signal)
-{
- NodeRecPtr nodePtr;
-
- nodePtr.i = cneighbourl;
- if (nodePtr.i == ZNIL) {
- jam();
- /**---------------------------------------------------------------------
- * THERE ARE NO NEIGHBOURS. THIS IS POSSIBLE IF WE ARE THE ONLY NODE IN
- * THE CLUSTER. IN THIS CASE WE DO NOT NEED TO CHECK ANY HEARTBEATS.
- *-----------------------------------------------------------------------*/
- return;
- }//if
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
-
- setNodeInfo(nodePtr.i).m_heartbeat_cnt++;
- ndbrequire(nodePtr.p->phase == ZRUNNING);
- ndbrequire(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB);
-
- if(getNodeInfo(nodePtr.i).m_heartbeat_cnt > 2){
- signal->theData[0] = NDB_LE_MissedHeartbeat;
- signal->theData[1] = nodePtr.i;
- signal->theData[2] = getNodeInfo(nodePtr.i).m_heartbeat_cnt - 1;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }
-
- if (getNodeInfo(nodePtr.i).m_heartbeat_cnt > 4) {
- jam();
- /**----------------------------------------------------------------------
- * OUR LEFT NEIGHBOUR HAVE KEPT QUIET FOR THREE CONSECUTIVE HEARTBEAT
- * PERIODS. THUS WE DECLARE HIM DOWN.
- *----------------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_DeadDueToHeartbeat;
- signal->theData[1] = nodePtr.i;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- failReportLab(signal, nodePtr.i, FailRep::ZHEARTBEAT_FAILURE);
- return;
- }//if
-}//Qmgr::checkHeartbeat()
-
-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(nodeId).getType();
- if(type == NodeInfo::DB)
- continue;
-
- if(type == NodeInfo::INVALID)
- continue;
-
- if (c_connectedNodes.get(nodeId))
- {
- jam();
- setNodeInfo(TnodePtr.i).m_heartbeat_cnt++;
-
- if(getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 2)
- {
- signal->theData[0] = NDB_LE_MissedHeartbeat;
- signal->theData[1] = nodeId;
- signal->theData[2] = getNodeInfo(TnodePtr.i).m_heartbeat_cnt - 1;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
- }
-
- if (getNodeInfo(TnodePtr.i).m_heartbeat_cnt > 4)
- {
- jam();
- /*------------------------------------------------------------------*/
- /* THE API NODE HAS NOT SENT ANY HEARTBEAT FOR THREE SECONDS.
- * WE WILL DISCONNECT FROM IT NOW.
- *------------------------------------------------------------------*/
- /*------------------------------------------------------------------*/
- /* We call node_failed to release all connections for this api node */
- /*------------------------------------------------------------------*/
- signal->theData[0] = NDB_LE_DeadDueToHeartbeat;
- signal->theData[1] = nodeId;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
- api_failed(signal, nodeId);
- }//if
- }//if
- }//for
- return;
-}//Qmgr::apiHbHandlingLab()
-
-void Qmgr::checkStartInterface(Signal* signal)
-{
- NodeRecPtr nodePtr;
- /*------------------------------------------------------------------------*/
- // This method is called once per second. After a disconnect we wait at
- // least three seconds before allowing new connects. We will also ensure
- // that handling of the failure is completed before we allow new connections.
- /*------------------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) {
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZFAIL_CLOSING) {
- jam();
- setNodeInfo(nodePtr.i).m_heartbeat_cnt++;
- if (c_connectedNodes.get(nodePtr.i)){
- jam();
- /*-------------------------------------------------------------------*/
- // We need to ensure that the connection is not restored until it has
- // been disconnected for at least three seconds.
- /*-------------------------------------------------------------------*/
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
- }//if
- if ((getNodeInfo(nodePtr.i).m_heartbeat_cnt > 3)
- && (nodePtr.p->failState == NORMAL)) {
- /**------------------------------------------------------------------
- * WE HAVE DISCONNECTED THREE SECONDS AGO. WE ARE NOW READY TO
- * CONNECT AGAIN AND ACCEPT NEW REGISTRATIONS FROM THIS NODE.
- * WE WILL NOT ALLOW CONNECTIONS OF API NODES UNTIL API FAIL HANDLING
- * IS COMPLETE.
- *-------------------------------------------------------------------*/
- nodePtr.p->failState = NORMAL;
- if (getNodeInfo(nodePtr.i).m_type != NodeInfo::DB){
- jam();
- nodePtr.p->phase = ZAPI_INACTIVE;
- } else {
- jam();
- nodePtr.p->phase = ZINIT;
- }//if
-
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
- signal->theData[0] = 0;
- signal->theData[1] = nodePtr.i;
- sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA);
- } else {
- if(((getNodeInfo(nodePtr.i).m_heartbeat_cnt + 1) % 60) == 0){
- char buf[100];
- BaseString::snprintf(buf, sizeof(buf),
- "Failure handling of node %d has not completed in %d min."
- " - state = %d",
- nodePtr.i,
- (getNodeInfo(nodePtr.i).m_heartbeat_cnt + 1)/60,
- nodePtr.p->failState);
- warningEvent(buf);
- }
- }
- }//if
- }//for
- return;
-}//Qmgr::checkStartInterface()
-
-/**-------------------------------------------------------------------------
- * This method is called when a DISCONNECT_REP signal arrived which means that
- * the API node is gone and we want to release resources in TC/DICT blocks.
- *---------------------------------------------------------------------------*/
-void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo)
-{
- NodeRecPtr failedNodePtr;
-
- jamEntry();
- failedNodePtr.i = failedNodeNo;
- signal->theData[0] = failedNodePtr.i;
- signal->theData[1] = QMGR_REF;
-
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
-
- ndbrequire(failedNodePtr.p->failState == NORMAL);
-
- failedNodePtr.p->failState = WAITING_FOR_FAILCONF1;
- NodeReceiverGroup rg(QMGR, c_clusterNodes);
- sendSignal(rg, GSN_API_FAILREQ, signal, 2, JBA);
- sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA);
- sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA);
- sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
-}//Qmgr::sendApiFailReq()
-
-void Qmgr::execAPI_FAILREQ(Signal* signal)
-{
- jamEntry();
- NodeRecPtr failedNodePtr;
- failedNodePtr.i = signal->theData[0];
- // signal->theData[1] == QMGR_REF
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
-
- ndbrequire(getNodeInfo(failedNodePtr.i).getType() != NodeInfo::DB);
-
- api_failed(signal, signal->theData[0]);
-}
-
-void Qmgr::execAPI_FAILCONF(Signal* signal)
-{
- NodeRecPtr failedNodePtr;
-
- jamEntry();
- failedNodePtr.i = signal->theData[0];
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
-
- if (failedNodePtr.p->failState == WAITING_FOR_FAILCONF1){
- jam();
-
- failedNodePtr.p->rcv[0] = signal->theData[1];
- failedNodePtr.p->failState = WAITING_FOR_FAILCONF2;
-
- } else if (failedNodePtr.p->failState == WAITING_FOR_FAILCONF2) {
- failedNodePtr.p->rcv[1] = signal->theData[1];
- failedNodePtr.p->failState = NORMAL;
-
- if (failedNodePtr.p->rcv[0] == failedNodePtr.p->rcv[1]) {
- jam();
- systemErrorLab(signal, __LINE__);
- } else {
- jam();
- failedNodePtr.p->rcv[0] = 0;
- failedNodePtr.p->rcv[1] = 0;
- }//if
- } else {
- jam();
-#ifdef VM_TRACE
- ndbout << "failedNodePtr.p->failState = "
- << (Uint32)(failedNodePtr.p->failState) << endl;
-#endif
- systemErrorLab(signal, __LINE__);
- }//if
- return;
-}//Qmgr::execAPI_FAILCONF()
-
-void Qmgr::execNDB_FAILCONF(Signal* signal)
-{
- NodeRecPtr failedNodePtr;
- NodeRecPtr nodePtr;
-
- jamEntry();
- failedNodePtr.i = signal->theData[0];
-
- if (ERROR_INSERTED(930))
- {
- CLEAR_ERROR_INSERT_VALUE;
- infoEvent("Discarding NDB_FAILCONF for %u", failedNodePtr.i);
- return;
- }
-
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
- if (failedNodePtr.p->failState == WAITING_FOR_NDB_FAILCONF){
- failedNodePtr.p->failState = NORMAL;
- } else {
- jam();
-
- char buf[100];
- BaseString::snprintf(buf, 100,
- "Received NDB_FAILCONF for node %u with state: %d %d",
- failedNodePtr.i,
- failedNodePtr.p->phase,
- failedNodePtr.p->failState);
- progError(__LINE__, 0, buf);
- systemErrorLab(signal, __LINE__);
- }//if
- if (cpresident == getOwnNodeId()) {
- jam();
- /**
- * Prepare a NFCompleteRep and send to all connected API's
- * They can then abort all transaction waiting for response from
- * the failed node
- */
- NFCompleteRep * const nfComp = (NFCompleteRep *)&signal->theData[0];
- nfComp->blockNo = QMGR_REF;
- nfComp->nodeId = getOwnNodeId();
- nfComp->failedNodeId = failedNodePtr.i;
-
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZAPI_ACTIVE){
- jam();
- sendSignal(nodePtr.p->blockRef, GSN_NF_COMPLETEREP, signal,
- NFCompleteRep::SignalLength, JBA);
- }//if
- }//for
- }
- return;
-}//Qmgr::execNDB_FAILCONF()
-
-/*******************************/
-/* DISCONNECT_REP */
-/*******************************/
-const char *lookupConnectionError(Uint32 err);
-
-void Qmgr::execDISCONNECT_REP(Signal* signal)
-{
- jamEntry();
- const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
- const Uint32 nodeId = rep->nodeId;
- const Uint32 err = rep->err;
- c_connectedNodes.clear(nodeId);
- c_readnodes_nodes.clear(nodeId);
-
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NODES, nodeRec);
-
- char buf[100];
- if (getNodeInfo(nodeId).getType() == NodeInfo::DB &&
- getNodeState().startLevel < NodeState::SL_STARTED)
- {
- jam();
- CRASH_INSERTION(932);
- BaseString::snprintf(buf, 100, "Node %u disconnected", nodeId);
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
- ndbrequire(false);
- }
-
- if (getNodeInfo(nodeId).getType() != NodeInfo::DB)
- {
- jam();
- api_failed(signal, nodeId);
- return;
- }
-
- switch(nodePtr.p->phase){
- case ZRUNNING:
- jam();
- break;
- case ZINIT:
- ndbrequire(false);
- case ZSTARTING:
- progError(__LINE__, NDBD_EXIT_CONNECTION_SETUP_FAILED,
- lookupConnectionError(err));
- ndbrequire(false);
- case ZPREPARE_FAIL:
- ndbrequire(false);
- case ZFAIL_CLOSING:
- ndbrequire(false);
- case ZAPI_ACTIVE:
- ndbrequire(false);
- case ZAPI_INACTIVE:
- {
- BaseString::snprintf(buf, 100, "Node %u disconnected", nodeId);
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
- ndbrequire(false);
- }
- }
- node_failed(signal, nodeId);
-}//DISCONNECT_REP
-
-void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode)
-{
- NodeRecPtr failedNodePtr;
- /**------------------------------------------------------------------------
- * A COMMUNICATION LINK HAS BEEN DISCONNECTED. WE MUST TAKE SOME ACTION
- * DUE TO THIS.
- *-----------------------------------------------------------------------*/
- failedNodePtr.i = aFailedNode;
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
-
- ndbrequire(getNodeInfo(failedNodePtr.i).getType() == NodeInfo::DB);
-
- /**---------------------------------------------------------------------
- * THE OTHER NODE IS AN NDB NODE, WE HANDLE IT AS IF A HEARTBEAT
- * FAILURE WAS DISCOVERED.
- *---------------------------------------------------------------------*/
- switch(failedNodePtr.p->phase){
- case ZRUNNING:
- jam();
- failReportLab(signal, aFailedNode, FailRep::ZLINK_FAILURE);
- return;
- case ZFAIL_CLOSING:
- jam();
- return;
- case ZSTARTING:
- c_start.reset();
- // Fall-through
- default:
- jam();
- /*---------------------------------------------------------------------*/
- // The other node is still not in the cluster but disconnected.
- // We must restart communication in three seconds.
- /*---------------------------------------------------------------------*/
- failedNodePtr.p->failState = NORMAL;
- failedNodePtr.p->phase = ZFAIL_CLOSING;
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
-
- CloseComReqConf * const closeCom =
- (CloseComReqConf *)&signal->theData[0];
-
- closeCom->xxxBlockRef = reference();
- closeCom->failNo = 0;
- closeCom->noOfNodes = 1;
- NodeBitmask::clear(closeCom->theNodes);
- NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
- sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
- CloseComReqConf::SignalLength, JBA);
- }//if
- return;
-}
-
-void
-Qmgr::api_failed(Signal* signal, Uint32 nodeId)
-{
- NodeRecPtr failedNodePtr;
- /**------------------------------------------------------------------------
- * A COMMUNICATION LINK HAS BEEN DISCONNECTED. WE MUST TAKE SOME ACTION
- * DUE TO THIS.
- *-----------------------------------------------------------------------*/
- failedNodePtr.i = nodeId;
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
-
- if (failedNodePtr.p->phase == ZFAIL_CLOSING)
- {
- /**
- * Failure handling already in progress
- */
- jam();
- return;
- }
-
- if (failedNodePtr.p->phase == ZAPI_ACTIVE)
- {
- jam();
- sendApiFailReq(signal, nodeId);
- arbitRec.code = ArbitCode::ApiFail;
- handleArbitApiFail(signal, nodeId);
- }
- else
- {
- /**
- * Always inform SUMA
- */
- jam();
- signal->theData[0] = nodeId;
- signal->theData[1] = QMGR_REF;
- sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
- failedNodePtr.p->failState = NORMAL;
- }
-
- failedNodePtr.p->phase = ZFAIL_CLOSING;
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
- setNodeInfo(failedNodePtr.i).m_version = 0;
- recompute_version_info(getNodeInfo(failedNodePtr.i).m_type);
-
- CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
- closeCom->xxxBlockRef = reference();
- closeCom->failNo = 0;
- closeCom->noOfNodes = 1;
- NodeBitmask::clear(closeCom->theNodes);
- NodeBitmask::set(closeCom->theNodes, failedNodePtr.i);
- sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
- CloseComReqConf::SignalLength, JBA);
-
- if (getNodeInfo(failedNodePtr.i).getType() == NodeInfo::MGM)
- {
- /**
- * Allow MGM do reconnect "directly"
- */
- jam();
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt = 3;
- }
-}
-
-/**--------------------------------------------------------------------------
- * AN API NODE IS REGISTERING. IF FOR THE FIRST TIME WE WILL ENABLE
- * COMMUNICATION WITH ALL NDB BLOCKS.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* API_REGREQ */
-/*******************************/
-void Qmgr::execAPI_REGREQ(Signal* signal)
-{
- jamEntry();
-
- ApiRegReq* req = (ApiRegReq*)signal->getDataPtr();
- const Uint32 version = req->version;
- const BlockReference ref = req->ref;
-
- NodeRecPtr apiNodePtr;
- apiNodePtr.i = refToNode(ref);
- ptrCheckGuard(apiNodePtr, MAX_NODES, nodeRec);
-
-#if 0
- ndbout_c("Qmgr::execAPI_REGREQ: Recd API_REGREQ (NodeId=%d)", apiNodePtr.i);
-#endif
-
- bool compatability_check;
- NodeInfo::NodeType type= getNodeInfo(apiNodePtr.i).getType();
- switch(type){
- case NodeInfo::API:
- compatability_check = ndbCompatible_ndb_api(NDB_VERSION, version);
- break;
- case NodeInfo::MGM:
- compatability_check = ndbCompatible_ndb_mgmt(NDB_VERSION, version);
- break;
- case NodeInfo::DB:
- case NodeInfo::INVALID:
- default:
- sendApiRegRef(signal, ref, ApiRegRef::WrongType);
- infoEvent("Invalid connection attempt with type %d", type);
- return;
- }
-
- if (!compatability_check) {
- jam();
- char buf[NDB_VERSION_STRING_BUF_SZ];
- infoEvent("Connection attempt from %s id=%d with %s "
- "incompatible with %s",
- type == NodeInfo::API ? "api or mysqld" : "management server",
- apiNodePtr.i,
- ndbGetVersionString(version,"",buf,sizeof(buf)),
- NDB_VERSION_STRING);
- apiNodePtr.p->phase = ZAPI_INACTIVE;
- sendApiRegRef(signal, ref, ApiRegRef::UnsupportedVersion);
- return;
- }
-
- setNodeInfo(apiNodePtr.i).m_version = version;
- setNodeInfo(apiNodePtr.i).m_heartbeat_cnt= 0;
-
- ApiRegConf * const apiRegConf = (ApiRegConf *)&signal->theData[0];
- apiRegConf->qmgrRef = reference();
- apiRegConf->apiHeartbeatFrequency = (chbApiDelay / 10);
- apiRegConf->version = NDB_VERSION;
- NodeState state= apiRegConf->nodeState = getNodeState();
- {
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- Uint32 dynamicId = nodePtr.p->ndynamicId;
-
- if(apiRegConf->nodeState.masterNodeId != getOwnNodeId()){
- jam();
- apiRegConf->nodeState.dynamicId = dynamicId;
- } else {
- apiRegConf->nodeState.dynamicId = -dynamicId;
- }
- }
- NodeVersionInfo info = getNodeVersionInfo();
- apiRegConf->minDbVersion = info.m_type[NodeInfo::DB].m_min_version;
- apiRegConf->nodeState.m_connected_nodes.assign(c_connectedNodes);
- sendSignal(ref, GSN_API_REGCONF, signal, ApiRegConf::SignalLength, JBB);
-
- if (apiNodePtr.p->phase == ZAPI_INACTIVE &&
- (state.startLevel == NodeState::SL_STARTED ||
- state.getSingleUserMode() ||
- (state.startLevel == NodeState::SL_STARTING &&
- state.starting.startPhase >= 100)))
- {
- jam();
- /**----------------------------------------------------------------------
- * THE API NODE IS REGISTERING. WE WILL ACCEPT IT BY CHANGING STATE AND
- * SENDING A CONFIRM.
- *----------------------------------------------------------------------*/
- apiNodePtr.p->phase = ZAPI_ACTIVE;
- apiNodePtr.p->blockRef = ref;
- signal->theData[0] = apiNodePtr.i;
- sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA);
-
- recompute_version_info(type, version);
-
- signal->theData[0] = apiNodePtr.i;
- signal->theData[1] = version;
- NodeReceiverGroup rg(QMGR, c_clusterNodes);
- rg.m_nodes.clear(getOwnNodeId());
- sendVersionedDb(rg, GSN_NODE_VERSION_REP, signal, 2, JBB,
- NDBD_NODE_VERSION_REP);
-
- signal->theData[0] = apiNodePtr.i;
- EXECUTE_DIRECT(NDBCNTR, GSN_API_START_REP, signal, 1);
- }
- return;
-}//Qmgr::execAPI_REGREQ()
-
-void
-Qmgr::sendVersionedDb(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Uint32 minversion)
-{
- jam();
- NodeVersionInfo info = getNodeVersionInfo();
- if (info.m_type[NodeInfo::DB].m_min_version >= minversion)
- {
- jam();
- sendSignal(rg, gsn, signal, length, jbuf);
- }
- else
- {
- jam();
- Uint32 i = 0, cnt = 0;
- while((i = rg.m_nodes.find(i + 1)) != NodeBitmask::NotFound)
- {
- jam();
- if (getNodeInfo(i).m_version >= minversion)
- {
- jam();
- cnt++;
- sendSignal(numberToRef(rg.m_block, i), gsn, signal, length, jbuf);
- }
- }
- ndbassert((cnt == 0 && rg.m_nodes.count() == 0) ||
- (cnt < rg.m_nodes.count()));
- }
-}
-
-void
-Qmgr::execAPI_VERSION_REQ(Signal * signal) {
- jamEntry();
- ApiVersionReq * const req = (ApiVersionReq *)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 nodeId = req->nodeId;
-
- ApiVersionConf * conf = (ApiVersionConf *)req;
- if(getNodeInfo(nodeId).m_connected)
- {
- conf->version = getNodeInfo(nodeId).m_version;
- struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
- conf->inet_addr= in.s_addr;
- }
- else
- {
- conf->version = 0;
- conf->inet_addr= 0;
- }
- conf->nodeId = nodeId;
-
- sendSignal(senderRef,
- GSN_API_VERSION_CONF,
- signal,
- ApiVersionConf::SignalLength, JBB);
-}
-
-void
-Qmgr::execNODE_VERSION_REP(Signal* signal)
-{
- jamEntry();
- Uint32 nodeId = signal->theData[0];
- Uint32 version = signal->theData[1];
-
- if (nodeId < MAX_NODES)
- {
- jam();
- Uint32 type = getNodeInfo(nodeId).m_type;
- setNodeInfo(nodeId).m_version = version;
- recompute_version_info(type, version);
- }
-}
-
-void
-Qmgr::recompute_version_info(Uint32 type, Uint32 version)
-{
- NodeVersionInfo& info = setNodeVersionInfo();
- switch(type){
- case NodeInfo::DB:
- case NodeInfo::API:
- case NodeInfo::MGM:
- break;
- default:
- return;
- }
-
- if (info.m_type[type].m_min_version == 0 ||
- version < info.m_type[type].m_min_version)
- info.m_type[type].m_min_version = version;
- if (version > info.m_type[type].m_max_version)
- info.m_type[type].m_max_version = version;
-}
-
-void
-Qmgr::recompute_version_info(Uint32 type)
-{
- switch(type){
- case NodeInfo::DB:
- case NodeInfo::API:
- case NodeInfo::MGM:
- break;
- default:
- return;
- }
-
- Uint32 min = ~0, max = 0;
- Uint32 cnt = type == NodeInfo::DB ? MAX_NDB_NODES : MAX_NODES;
- for (Uint32 i = 1; i<cnt; i++)
- {
- if (getNodeInfo(i).m_type == type)
- {
- Uint32 version = getNodeInfo(i).m_version;
-
- if (version)
- {
- if (version < min)
- min = version;
- if (version > max)
- max = version;
- }
- }
- }
-
- NodeVersionInfo& info = setNodeVersionInfo();
- info.m_type[type].m_min_version = min == ~(Uint32)0 ? 0 : min;
- info.m_type[type].m_max_version = max;
-}
-
-#if 0
-bool
-Qmgr::checkAPIVersion(NodeId nodeId,
- Uint32 apiVersion, Uint32 ownVersion) const {
- bool ret=true;
- /**
- * First implementation...
- */
- if ((getMajor(apiVersion) < getMajor(ownVersion) ||
- getMinor(apiVersion) < getMinor(ownVersion)) &&
- apiVersion >= API_UPGRADE_VERSION) {
- jam();
- if ( getNodeInfo(nodeId).getType() != NodeInfo::MGM ) {
- jam();
- ret = false;
- } else {
- jam();
- /* we have a software upgrade situation, mgmtsrvr should be
- * the highest, let him decide what to do
- */
- ;
- }
- }
- return ret;
-}
-#endif
-
-void
-Qmgr::sendApiRegRef(Signal* signal, Uint32 Tref, ApiRegRef::ErrorCode err){
- ApiRegRef* ref = (ApiRegRef*)signal->getDataPtrSend();
- ref->ref = reference();
- ref->version = NDB_VERSION;
- ref->errorCode = err;
- sendSignal(Tref, GSN_API_REGREF, signal, ApiRegRef::SignalLength, JBB);
-}
-
-/**--------------------------------------------------------------------------
- * A NODE HAS BEEN DECLARED AS DOWN. WE WILL CLOSE THE COMMUNICATION TO THIS
- * NODE IF NOT ALREADY DONE. IF WE ARE PRESIDENT OR BECOMES PRESIDENT BECAUSE
- * OF A FAILED PRESIDENT THEN WE WILL TAKE FURTHER ACTION.
- *---------------------------------------------------------------------------*/
-void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
- FailRep::FailCause aFailCause)
-{
- NodeRecPtr nodePtr;
- NodeRecPtr failedNodePtr;
- NodeRecPtr myNodePtr;
- UintR TnoFailedNodes;
-
- failedNodePtr.i = aFailedNode;
- ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
- FailRep* rep = (FailRep*)signal->getDataPtr();
-
- if (check_multi_node_shutdown(signal))
- {
- jam();
- return;
- }
-
- if (failedNodePtr.i == getOwnNodeId()) {
- jam();
-
- Uint32 code = NDBD_EXIT_NODE_DECLARED_DEAD;
- const char * msg = 0;
- char extra[100];
- switch(aFailCause){
- case FailRep::ZOWN_FAILURE:
- msg = "Own failure";
- break;
- case FailRep::ZOTHER_NODE_WHEN_WE_START:
- case FailRep::ZOTHERNODE_FAILED_DURING_START:
- msg = "Other node died during start";
- break;
- case FailRep::ZIN_PREP_FAIL_REQ:
- msg = "Prep fail";
- break;
- case FailRep::ZSTART_IN_REGREQ:
- msg = "Start timeout";
- break;
- case FailRep::ZHEARTBEAT_FAILURE:
- msg = "Hearbeat failure";
- break;
- case FailRep::ZLINK_FAILURE:
- msg = "Connection failure";
- break;
- case FailRep::ZPARTITIONED_CLUSTER:
- {
- code = NDBD_EXIT_PARTITIONED_SHUTDOWN;
- char buf1[100], buf2[100];
- c_clusterNodes.getText(buf1);
- if (signal->getLength()== FailRep::SignalLength + FailRep::ExtraLength &&
- signal->header.theVerId_signalNumber == GSN_FAIL_REP)
- {
- jam();
- NdbNodeBitmask part;
- part.assign(NdbNodeBitmask::Size, rep->partition);
- part.getText(buf2);
- BaseString::snprintf(extra, sizeof(extra),
- "Our cluster: %s other cluster: %s",
- buf1, buf2);
- }
- else
- {
- jam();
- BaseString::snprintf(extra, sizeof(extra),
- "Our cluster: %s", buf1);
- }
- msg = extra;
- break;
- }
- case FailRep::ZMULTI_NODE_SHUTDOWN:
- msg = "Multi node shutdown";
- break;
- default:
- msg = "<UNKNOWN>";
- }
-
- CRASH_INSERTION(932);
-
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "We(%u) have been declared dead by %u reason: %s(%u)",
- getOwnNodeId(),
- refToNode(signal->getSendersBlockRef()),
- msg ? msg : "<Unknown>",
- aFailCause);
-
- progError(__LINE__, code, buf);
- return;
- }//if
-
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
- if (myNodePtr.p->phase != ZRUNNING) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
-
- if (getNodeState().startLevel < NodeState::SL_STARTED)
- {
- jam();
- CRASH_INSERTION(932);
- char buf[100];
- BaseString::snprintf(buf, 100, "Node failure during restart");
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
- ndbrequire(false);
- }
-
- TnoFailedNodes = cnoFailedNodes;
- failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause);
- if (cpresident == getOwnNodeId()) {
- jam();
- if (ctoStatus == Q_NOT_ACTIVE) {
- jam();
- /**--------------------------------------------------------------------
- * AS PRESIDENT WE ARE REQUIRED TO START THE EXCLUSION PROCESS SUCH THAT
- * THE APPLICATION SEE NODE FAILURES IN A CONSISTENT ORDER.
- * IF WE HAVE BECOME PRESIDENT NOW (CTO_STATUS = ACTIVE) THEN WE HAVE
- * TO COMPLETE THE PREVIOUS COMMIT FAILED NODE PROCESS BEFORE STARTING
- * A NEW.
- * CTO_STATUS = ACTIVE CAN ALSO MEAN THAT WE ARE PRESIDENT AND ARE
- * CURRENTLY COMMITTING A SET OF NODE CRASHES. IN THIS CASE IT IS NOT
- * ALLOWED TO START PREPARING NEW NODE CRASHES.
- *---------------------------------------------------------------------*/
- if (TnoFailedNodes != cnoFailedNodes) {
- jam();
- cfailureNr = cfailureNr + 1;
- for (nodePtr.i = 1;
- nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- sendPrepFailReq(signal, nodePtr.i);
- }//if
- }//for
- }//if
- }//if
- }//if
- return;
-}//Qmgr::failReportLab()
-
-/**-------------------------------------------------------------------------
- * WE HAVE RECEIVED A PREPARE TO EXCLUDE A NUMBER OF NODES FROM THE CLUSTER.
- * WE WILL FIRST CHECK THAT WE HAVE NOT ANY MORE NODES THAT
- * WE ALSO HAVE EXCLUDED
- *--------------------------------------------------------------------------*/
-/*******************************/
-/* PREP_FAILREQ */
-/*******************************/
-void Qmgr::execPREP_FAILREQ(Signal* signal)
-{
- NodeRecPtr myNodePtr;
- jamEntry();
-
- if (check_multi_node_shutdown(signal))
- {
- jam();
- return;
- }
-
- PrepFailReqRef * const prepFail = (PrepFailReqRef *)&signal->theData[0];
-
- BlockReference Tblockref = prepFail->xxxBlockRef;
- Uint16 TfailureNr = prepFail->failNo;
- cnoPrepFailedNodes = prepFail->noOfNodes;
- UintR arrayIndex = 0;
- Uint32 Tindex;
- for (Tindex = 0; Tindex < MAX_NDB_NODES; Tindex++) {
- if (NodeBitmask::get(prepFail->theNodes, Tindex)){
- cprepFailedNodes[arrayIndex] = Tindex;
- arrayIndex++;
- }//if
- }//for
- UintR guard0;
-
- /**
- * Block commit until node failures has stabilized
- *
- * @See RT352
- */
- BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
- block->failNo = TfailureNr;
- EXECUTE_DIRECT(DBDIH, GSN_BLOCK_COMMIT_ORD, signal,
- BlockCommitOrd::SignalLength);
-
- myNodePtr.i = getOwnNodeId();
- ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
- if (myNodePtr.p->phase != ZRUNNING) {
- jam();
- systemErrorLab(signal, __LINE__);
- return;
- }//if
-
- if (getNodeState().startLevel < NodeState::SL_STARTED)
- {
- jam();
- CRASH_INSERTION(932);
- char buf[100];
- BaseString::snprintf(buf, 100, "Node failure during restart");
- progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
- ndbrequire(false);
- }
-
- guard0 = cnoPrepFailedNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Tindex = 0; Tindex <= guard0; Tindex++) {
- jam();
- failReport(signal,
- cprepFailedNodes[Tindex],
- (UintR)ZFALSE,
- FailRep::ZIN_PREP_FAIL_REQ);
- }//for
- sendCloseComReq(signal, Tblockref, TfailureNr);
- cnoCommitFailedNodes = 0;
- cprepareFailureNr = TfailureNr;
- return;
-}//Qmgr::execPREP_FAILREQ()
-
-/**---------------------------------------------------------------------------
- * THE CRASHED NODES HAS BEEN EXCLUDED FROM COMMUNICATION.
- * WE WILL CHECK WHETHER ANY MORE NODES HAVE FAILED DURING THE PREPARE PROCESS.
- * IF SO WE WILL REFUSE THE PREPARE PHASE AND EXPECT A NEW PREPARE MESSAGE
- * WITH ALL FAILED NODES INCLUDED.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* CLOSE_COMCONF */
-/*******************************/
-void Qmgr::execCLOSE_COMCONF(Signal* signal)
-{
- jamEntry();
-
- CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
-
- BlockReference Tblockref = closeCom->xxxBlockRef;
- Uint16 TfailureNr = closeCom->failNo;
-
- cnoPrepFailedNodes = closeCom->noOfNodes;
- UintR arrayIndex = 0;
- UintR Tindex = 0;
- for(Tindex = 0; Tindex < MAX_NDB_NODES; Tindex++){
- if(NodeBitmask::get(closeCom->theNodes, Tindex)){
- cprepFailedNodes[arrayIndex] = Tindex;
- arrayIndex++;
- }
- }
- UintR tprepFailConf;
- UintR Tindex2;
- UintR guard0;
- UintR guard1;
- UintR Tfound;
- Uint16 TfailedNodeNo;
-
- tprepFailConf = ZTRUE;
- if (cnoFailedNodes > 0) {
- jam();
- guard0 = cnoFailedNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Tindex = 0; Tindex <= guard0; Tindex++) {
- jam();
- TfailedNodeNo = cfailedNodes[Tindex];
- Tfound = ZFALSE;
- guard1 = cnoPrepFailedNodes - 1;
- arrGuard(guard1, MAX_NDB_NODES);
- for (Tindex2 = 0; Tindex2 <= guard1; Tindex2++) {
- jam();
- if (TfailedNodeNo == cprepFailedNodes[Tindex2]) {
- jam();
- Tfound = ZTRUE;
- }//if
- }//for
- if (Tfound == ZFALSE) {
- jam();
- tprepFailConf = ZFALSE;
- arrGuard(cnoPrepFailedNodes, MAX_NDB_NODES);
- cprepFailedNodes[cnoPrepFailedNodes] = TfailedNodeNo;
- cnoPrepFailedNodes = cnoPrepFailedNodes + 1;
- }//if
- }//for
- }//if
- if (tprepFailConf == ZFALSE) {
- jam();
- for (Tindex = 1; Tindex < MAX_NDB_NODES; Tindex++) {
- cfailedNodes[Tindex] = cprepFailedNodes[Tindex];
- }//for
- cnoFailedNodes = cnoPrepFailedNodes;
- sendPrepFailReqRef(signal,
- Tblockref,
- GSN_PREP_FAILREF,
- reference(),
- cfailureNr,
- cnoPrepFailedNodes,
- cprepFailedNodes);
- } else {
- jam();
- cnoCommitFailedNodes = cnoPrepFailedNodes;
- guard0 = cnoPrepFailedNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Tindex = 0; Tindex <= guard0; Tindex++) {
- jam();
- arrGuard(Tindex, MAX_NDB_NODES);
- ccommitFailedNodes[Tindex] = cprepFailedNodes[Tindex];
- }//for
- signal->theData[0] = getOwnNodeId();
- signal->theData[1] = TfailureNr;
- sendSignal(Tblockref, GSN_PREP_FAILCONF, signal, 2, JBA);
- }//if
- return;
-}//Qmgr::execCLOSE_COMCONF()
-
-/*---------------------------------------------------------------------------*/
-/* WE HAVE RECEIVED A CONFIRM OF THAT THIS NODE HAVE PREPARED THE FAILURE. */
-/*---------------------------------------------------------------------------*/
-/*******************************/
-/* PREP_FAILCONF */
-/*******************************/
-void Qmgr::execPREP_FAILCONF(Signal* signal)
-{
- NodeRecPtr nodePtr;
- NodeRecPtr replyNodePtr;
- jamEntry();
- replyNodePtr.i = signal->theData[0];
- Uint16 TfailureNr = signal->theData[1];
- if (TfailureNr != cfailureNr) {
- jam();
- /**----------------------------------------------------------------------
- * WE HAVE ALREADY STARTING A NEW ATTEMPT TO EXCLUDE A NUMBER OF NODES.
- * IGNORE
- *----------------------------------------------------------------------*/
- return;
- }//if
- ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec);
- replyNodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- if (nodePtr.p->sendPrepFailReqStatus == Q_ACTIVE) {
- jam();
- return;
- }//if
- }//if
- }//for
- /**
- * Check node count and groups and invoke arbitrator if necessary.
- * Continues via sendCommitFailReq() if successful.
- */
- arbitRec.failureNr = cfailureNr;
- const NodeState & s = getNodeState();
- if(s.startLevel == NodeState::SL_STOPPING_3 && s.stopping.systemShutdown){
- jam();
- /**
- * We're performing a system shutdown,
- * don't let artibtrator shut us down
- */
- return;
- }
- handleArbitCheck(signal);
- return;
-}//Qmgr::execPREP_FAILCONF()
-
-void
-Qmgr::sendCommitFailReq(Signal* signal)
-{
- NodeRecPtr nodePtr;
- jam();
- if (arbitRec.failureNr != cfailureNr) {
- jam();
- /**----------------------------------------------------------------------
- * WE HAVE ALREADY STARTING A NEW ATTEMPT TO EXCLUDE A NUMBER OF NODES.
- * IGNORE
- *----------------------------------------------------------------------*/
- return;
- }//if
- /**-----------------------------------------------------------------------
- * WE HAVE SUCCESSFULLY PREPARED A SET OF NODE FAILURES. WE WILL NOW COMMIT
- * THESE NODE FAILURES.
- *-------------------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
-
-#ifdef ERROR_INSERT
- if (ERROR_INSERTED(935) && nodePtr.i == c_error_insert_extra)
- {
- ndbout_c("skipping node %d", c_error_insert_extra);
- CLEAR_ERROR_INSERT_VALUE;
- signal->theData[0] = 9999;
- sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
- continue;
- }
-#endif
-
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE;
- signal->theData[0] = cpdistref;
- signal->theData[1] = cfailureNr;
- sendSignal(nodePtr.p->blockRef, GSN_COMMIT_FAILREQ, signal, 2, JBA);
- }//if
- }//for
- ctoStatus = Q_ACTIVE;
- cnoFailedNodes = 0;
- return;
-}//sendCommitFailReq()
-
-/*---------------------------------------------------------------------------*/
-/* SOME NODE HAVE DISCOVERED A NODE FAILURE THAT WE HAVE NOT YET DISCOVERED. */
-/* WE WILL START ANOTHER ROUND OF PREPARING A SET OF NODE FAILURES. */
-/*---------------------------------------------------------------------------*/
-/*******************************/
-/* PREP_FAILREF */
-/*******************************/
-void Qmgr::execPREP_FAILREF(Signal* signal)
-{
- NodeRecPtr nodePtr;
- jamEntry();
-
- PrepFailReqRef * const prepFail = (PrepFailReqRef *)&signal->theData[0];
-
- Uint16 TfailureNr = prepFail->failNo;
- cnoPrepFailedNodes = prepFail->noOfNodes;
-
- UintR arrayIndex = 0;
- UintR Tindex = 0;
- for(Tindex = 0; Tindex < MAX_NDB_NODES; Tindex++) {
- jam();
- if(NodeBitmask::get(prepFail->theNodes, Tindex)){
- jam();
- cprepFailedNodes[arrayIndex] = Tindex;
- arrayIndex++;
- }//if
- }//for
- if (TfailureNr != cfailureNr) {
- jam();
- /**---------------------------------------------------------------------
- * WE HAVE ALREADY STARTING A NEW ATTEMPT TO EXCLUDE A NUMBER OF NODES.
- * IGNORE
- *----------------------------------------------------------------------*/
- return;
- }//if
- UintR guard0;
- UintR Ti;
-
- cnoFailedNodes = cnoPrepFailedNodes;
- guard0 = cnoPrepFailedNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- for (Ti = 0; Ti <= guard0; Ti++) {
- jam();
- cfailedNodes[Ti] = cprepFailedNodes[Ti];
- }//for
- cfailureNr = cfailureNr + 1;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- sendPrepFailReq(signal, nodePtr.i);
- }//if
- }//for
- return;
-}//Qmgr::execPREP_FAILREF()
-
-static
-Uint32
-clear_nodes(Uint32 dstcnt, Uint16 dst[], Uint32 srccnt, const Uint16 src[])
-{
- if (srccnt == 0)
- return dstcnt;
-
- Uint32 pos = 0;
- for (Uint32 i = 0; i<dstcnt; i++)
- {
- Uint32 node = dst[i];
- for (Uint32 j = 0; j<srccnt; j++)
- {
- if (node == dst[j])
- {
- node = RNIL;
- break;
- }
- }
- if (node != RNIL)
- {
- dst[pos++] = node;
- }
- }
- return pos;
-}
-
-/*---------------------------------------------------------------------------*/
-/* THE PRESIDENT IS NOW COMMITTING THE PREVIOUSLY PREPARED NODE FAILURE. */
-/*---------------------------------------------------------------------------*/
-/***********************/
-/* COMMIT_FAILREQ */
-/***********************/
-void Qmgr::execCOMMIT_FAILREQ(Signal* signal)
-{
- NodeRecPtr nodePtr;
- jamEntry();
- BlockReference Tblockref = signal->theData[0];
- UintR TfailureNr = signal->theData[1];
- if (Tblockref != cpdistref) {
- jam();
- return;
- }//if
- UintR guard0;
- UintR Tj;
-
- /**
- * Block commit until node failures has stabilized
- *
- * @See RT352
- */
- UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
- unblock->failNo = TfailureNr;
- EXECUTE_DIRECT(DBDIH, GSN_UNBLOCK_COMMIT_ORD, signal,
- UnblockCommitOrd::SignalLength);
-
- if ((ccommitFailureNr != TfailureNr) &&
- (cnoCommitFailedNodes > 0)) {
- jam();
- /**-----------------------------------------------------------------------
- * WE ONLY DO THIS PART OF THE COMMIT HANDLING THE FIRST TIME WE HEAR THIS
- * SIGNAL. WE CAN HEAR IT SEVERAL TIMES IF THE PRESIDENTS KEEP FAILING.
- *-----------------------------------------------------------------------*/
- ccommitFailureNr = TfailureNr;
- 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();
- NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]);
- }//if
- sendSignal(NDBCNTR_REF, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
-
- guard0 = cnoCommitFailedNodes - 1;
- arrGuard(guard0, MAX_NDB_NODES);
- /**--------------------------------------------------------------------
- * WE MUST PREPARE TO ACCEPT THE CRASHED NODE INTO THE CLUSTER AGAIN BY
- * SETTING UP CONNECTIONS AGAIN AFTER THREE SECONDS OF DELAY.
- *--------------------------------------------------------------------*/
- for (Tj = 0; Tj <= guard0; Tj++) {
- jam();
- nodePtr.i = ccommitFailedNodes[Tj];
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- nodePtr.p->phase = ZFAIL_CLOSING;
- nodePtr.p->failState = WAITING_FOR_NDB_FAILCONF;
- setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
- setNodeInfo(nodePtr.i).m_version = 0;
- c_clusterNodes.clear(nodePtr.i);
- }//for
- recompute_version_info(NodeInfo::DB);
- /*----------------------------------------------------------------------*/
- /* WE INFORM THE API'S WE HAVE CONNECTED ABOUT THE FAILED NODES. */
- /*----------------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZAPI_ACTIVE) {
- jam();
-
- NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
-
- nodeFail->failNo = ccommitFailureNr;
- nodeFail->noOfNodes = cnoCommitFailedNodes;
- NodeBitmask::clear(nodeFail->theNodes);
- for(unsigned i = 0; i < cnoCommitFailedNodes; i++) {
- jam();
- NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]);
- }//for
- sendSignal(nodePtr.p->blockRef, GSN_NODE_FAILREP, signal,
- NodeFailRep::SignalLength, JBB);
- }//if
- }//for
-
- /**
- * Remove committed nodes from failed/prepared
- */
- cnoFailedNodes = clear_nodes(cnoFailedNodes,
- cfailedNodes,
- cnoCommitFailedNodes,
- ccommitFailedNodes);
- cnoPrepFailedNodes = clear_nodes(cnoPrepFailedNodes,
- cprepFailedNodes,
- cnoCommitFailedNodes,
- ccommitFailedNodes);
- cnoCommitFailedNodes = 0;
- }//if
- /**-----------------------------------------------------------------------
- * WE WILL ALWAYS ACKNOWLEDGE THE COMMIT EVEN WHEN RECEIVING IT MULTIPLE
- * TIMES SINCE IT WILL ALWAYS COME FROM A NEW PRESIDENT.
- *------------------------------------------------------------------------*/
- signal->theData[0] = getOwnNodeId();
- sendSignal(Tblockref, GSN_COMMIT_FAILCONF, signal, 1, JBA);
- return;
-}//Qmgr::execCOMMIT_FAILREQ()
-
-/*--------------------------------------------------------------------------*/
-/* WE HAVE RECEIVED A CONFIRM OF THAT THIS NODE HAVE COMMITTED THE FAILURES.*/
-/*--------------------------------------------------------------------------*/
-/*******************************/
-/* COMMIT_FAILCONF */
-/*******************************/
-void Qmgr::execCOMMIT_FAILCONF(Signal* signal)
-{
- NodeRecPtr nodePtr;
- NodeRecPtr replyNodePtr;
- jamEntry();
- replyNodePtr.i = signal->theData[0];
-
- ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec);
- replyNodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- if (nodePtr.p->sendCommitFailReqStatus == Q_ACTIVE) {
- jam();
- return;
- }//if
- }//if
- }//for
- /*-----------------------------------------------------------------------*/
- /* WE HAVE SUCCESSFULLY COMMITTED A SET OF NODE FAILURES. */
- /*-----------------------------------------------------------------------*/
- ctoStatus = Q_NOT_ACTIVE;
- if (cnoFailedNodes != 0) {
- jam();
- /**----------------------------------------------------------------------
- * A FAILURE OCCURRED IN THE MIDDLE OF THE COMMIT PROCESS. WE ARE NOW
- * READY TO START THE FAILED NODE PROCESS FOR THIS NODE.
- *----------------------------------------------------------------------*/
- cfailureNr = cfailureNr + 1;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- sendPrepFailReq(signal, nodePtr.i);
- }//if
- }//for
- }//if
- return;
-}//Qmgr::execCOMMIT_FAILCONF()
-
-/**--------------------------------------------------------------------------
- * IF THE PRESIDENT FAILS IN THE MIDDLE OF THE COMMIT OF A FAILED NODE THEN
- * THE NEW PRESIDENT NEEDS TO QUERY THE COMMIT STATUS IN THE RUNNING NODES.
- *---------------------------------------------------------------------------*/
-/*******************************/
-/* PRES_TOCONF */
-/*******************************/
-void Qmgr::execPRES_TOCONF(Signal* signal)
-{
- NodeRecPtr nodePtr;
- NodeRecPtr replyNodePtr;
- jamEntry();
- replyNodePtr.i = signal->theData[0];
- UintR TfailureNr = signal->theData[1];
- if (ctoFailureNr < TfailureNr) {
- jam();
- ctoFailureNr = TfailureNr;
- }//if
- ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec);
- replyNodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->sendPresToStatus == Q_ACTIVE) {
- jam();
- return;
- }//if
- }//for
- /*-------------------------------------------------------------------------*/
- /* WE ARE NOW READY TO DISCOVER WHETHER THE FAILURE WAS COMMITTED OR NOT. */
- /*-------------------------------------------------------------------------*/
- if (ctoFailureNr > ccommitFailureNr) {
- jam();
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE;
- signal->theData[0] = cpdistref;
- signal->theData[1] = ctoFailureNr;
- sendSignal(nodePtr.p->blockRef, GSN_COMMIT_FAILREQ, signal, 2, JBA);
- }//if
- }//for
- return;
- }//if
- /*-------------------------------------------------------------------------*/
- /* WE ARE NOW READY TO START THE NEW NODE FAILURE PROCESS. */
- /*-------------------------------------------------------------------------*/
- ctoStatus = Q_NOT_ACTIVE;
- cfailureNr = cfailureNr + 1;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- sendPrepFailReq(signal, nodePtr.i);
- }//if
- }//for
- return;
-}//Qmgr::execPRES_TOCONF()
-
-/*--------------------------------------------------------------------------*/
-// Provide information about the configured NDB nodes in the system.
-/*--------------------------------------------------------------------------*/
-void Qmgr::execREAD_NODESREQ(Signal* signal)
-{
- jamEntry();
-
- BlockReference TBref = signal->theData[0];
-
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
-
- NodeRecPtr nodePtr;
- nodePtr.i = getOwnNodeId();
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
-
- NdbNodeBitmask tmp = c_definedNodes;
- tmp.bitANDC(c_clusterNodes);
-
- 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, Uint32 line,
- NodeId failedNodeId) {
- jam();
-
- // Broadcast that this node is failing to other nodes
- failReport(signal, getOwnNodeId(), (UintR)ZTRUE, FailRep::ZOWN_FAILURE);
-
- char buf[100];
- BaseString::snprintf(buf, 100,
- "Node was shutdown during startup because node %d failed",
- failedNodeId);
-
- progError(line, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
-}
-
-
-void Qmgr::systemErrorLab(Signal* signal, Uint32 line, const char * message)
-{
- jam();
- // Broadcast that this node is failing to other nodes
- failReport(signal, getOwnNodeId(), (UintR)ZTRUE, FailRep::ZOWN_FAILURE);
-
- // If it's known why shutdown occured
- // an error message has been passed to this function
- progError(line, NDBD_EXIT_NDBREQUIRE, message);
-
- return;
-}//Qmgr::systemErrorLab()
-
-
-/**---------------------------------------------------------------------------
- * A FAILURE HAVE BEEN DISCOVERED ON A NODE. WE NEED TO CLEAR A
- * NUMBER OF VARIABLES.
- *---------------------------------------------------------------------------*/
-void Qmgr::failReport(Signal* signal,
- Uint16 aFailedNode,
- UintR aSendFailRep,
- FailRep::FailCause aFailCause)
-{
- UintR tfrMinDynamicId;
- NodeRecPtr failedNodePtr;
- NodeRecPtr nodePtr;
- NodeRecPtr presidentNodePtr;
-
-
- failedNodePtr.i = aFailedNode;
- ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRec);
- if (failedNodePtr.p->phase == ZRUNNING) {
- jam();
-/* WE ALSO NEED TO ADD HERE SOME CODE THAT GETS OUR NEW NEIGHBOURS. */
- if (cpresident == getOwnNodeId()) {
- jam();
- if (failedNodePtr.p->sendCommitFailReqStatus == Q_ACTIVE) {
- jam();
- signal->theData[0] = failedNodePtr.i;
- sendSignal(QMGR_REF, GSN_COMMIT_FAILCONF, signal, 1, JBA);
- }//if
- if (failedNodePtr.p->sendPresToStatus == Q_ACTIVE) {
- jam();
- signal->theData[0] = failedNodePtr.i;
- signal->theData[1] = ccommitFailureNr;
- sendSignal(QMGR_REF, GSN_PRES_TOCONF, signal, 2, JBA);
- }//if
- }//if
- failedNodePtr.p->phase = ZPREPARE_FAIL;
- failedNodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
- failedNodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
- failedNodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
- setNodeInfo(failedNodePtr.i).m_heartbeat_cnt= 0;
- if (aSendFailRep == ZTRUE) {
- jam();
- if (failedNodePtr.i != getOwnNodeId()) {
- jam();
- FailRep * const failRep = (FailRep *)&signal->theData[0];
- failRep->failNodeId = failedNodePtr.i;
- failRep->failCause = aFailCause;
- sendSignal(failedNodePtr.p->blockRef, GSN_FAIL_REP, signal,
- FailRep::SignalLength, JBA);
- }//if
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- FailRep * const failRep = (FailRep *)&signal->theData[0];
- failRep->failNodeId = failedNodePtr.i;
- failRep->failCause = aFailCause;
- sendSignal(nodePtr.p->blockRef, GSN_FAIL_REP, signal,
- FailRep::SignalLength, JBA);
- }//if
- }//for
- }//if
- if (failedNodePtr.i == getOwnNodeId()) {
- jam();
- return;
- }//if
- failedNodePtr.p->ndynamicId = 0;
- findNeighbours(signal);
- if (failedNodePtr.i == cpresident) {
- jam();
- /**--------------------------------------------------------------------
- * IF PRESIDENT HAVE FAILED WE MUST CALCULATE THE NEW PRESIDENT BY
- * FINDING THE NODE WITH THE MINIMUM DYNAMIC IDENTITY.
- *---------------------------------------------------------------------*/
- tfrMinDynamicId = (UintR)-1;
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- if (nodePtr.p->ndynamicId < tfrMinDynamicId) {
- jam();
- tfrMinDynamicId = nodePtr.p->ndynamicId;
- cpresident = nodePtr.i;
- }//if
- }//if
- }//for
- presidentNodePtr.i = cpresident;
- ptrCheckGuard(presidentNodePtr, MAX_NDB_NODES, nodeRec);
- cpdistref = presidentNodePtr.p->blockRef;
- if (cpresident == getOwnNodeId()) {
- CRASH_INSERTION(920);
- cfailureNr = cprepareFailureNr;
- ctoFailureNr = 0;
- ctoStatus = Q_ACTIVE;
- c_start.reset(); // Don't take over nodes being started
- if (cnoCommitFailedNodes > 0) {
- jam();
- /**-----------------------------------------------------------------
- * IN THIS SITUATION WE ARE UNCERTAIN OF WHETHER THE NODE FAILURE
- * PROCESS WAS COMMITTED. WE NEED TO QUERY THE OTHER NODES ABOUT
- * THEIR STATUS.
- *-----------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES;
- nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- nodePtr.p->sendPresToStatus = Q_ACTIVE;
- signal->theData[0] = cpdistref;
- signal->theData[1] = cprepareFailureNr;
- sendSignal(nodePtr.p->blockRef, GSN_PRES_TOREQ,
- signal, 1, JBA);
- }//if
- }//for
- } else {
- jam();
- /*-----------------------------------------------------------------*/
- // In this case it could be that a commit process is still ongoing.
- // If so we must conclude it as the new master.
- /*-----------------------------------------------------------------*/
- for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES;
- nodePtr.i++) {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZRUNNING) {
- jam();
- nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE;
- signal->theData[0] = cpdistref;
- signal->theData[1] = ccommitFailureNr;
- sendSignal(nodePtr.p->blockRef, GSN_COMMIT_FAILREQ, signal,
- 2, JBA);
- }//if
- }//for
- }//if
- }//if
- }//if
- arrGuard(cnoFailedNodes, MAX_NDB_NODES);
- cfailedNodes[cnoFailedNodes] = failedNodePtr.i;
- cnoFailedNodes = cnoFailedNodes + 1;
- }//if
-}//Qmgr::failReport()
-
-/*---------------------------------------------------------------------------*/
-/* INPUT: TTDI_DYN_ID */
-/* OUTPUT: TTDI_NODE_ID */
-/*---------------------------------------------------------------------------*/
-Uint16 Qmgr::translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId)
-{
- NodeRecPtr tdiNodePtr;
- Uint16 TtdiNodeId = ZNIL;
-
- for (tdiNodePtr.i = 1; tdiNodePtr.i < MAX_NDB_NODES; tdiNodePtr.i++) {
- jam();
- ptrAss(tdiNodePtr, nodeRec);
- if (tdiNodePtr.p->ndynamicId == TdynamicId) {
- jam();
- TtdiNodeId = tdiNodePtr.i;
- break;
- }//if
- }//for
- if (TtdiNodeId == ZNIL) {
- jam();
- systemErrorLab(signal, __LINE__);
- }//if
- return TtdiNodeId;
-}//Qmgr::translateDynamicIdToNodeId()
-
-/**--------------------------------------------------------------------------
- * WHEN RECEIVING PREPARE FAILURE REQUEST WE WILL IMMEDIATELY CLOSE
- * COMMUNICATION WITH ALL THOSE NODES.
- *--------------------------------------------------------------------------*/
-void Qmgr::sendCloseComReq(Signal* signal, BlockReference TBRef, Uint16 aFailNo)
-{
- CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0];
-
- closeCom->xxxBlockRef = TBRef;
- closeCom->failNo = aFailNo;
- closeCom->noOfNodes = cnoPrepFailedNodes;
-
- NodeBitmask::clear(closeCom->theNodes);
-
- for(int i = 0; i < cnoPrepFailedNodes; i++) {
- const NodeId nodeId = cprepFailedNodes[i];
- jam();
- NodeBitmask::set(closeCom->theNodes, nodeId);
- }
-
- sendSignal(CMVMI_REF, GSN_CLOSE_COMREQ, signal,
- CloseComReqConf::SignalLength, JBA);
-
-}//Qmgr::sendCloseComReq()
-
-void
-Qmgr::sendPrepFailReqRef(Signal* signal,
- Uint32 dstBlockRef,
- GlobalSignalNumber gsn,
- Uint32 blockRef,
- Uint32 failNo,
- Uint32 noOfNodes,
- const NodeId theNodes[]){
-
- PrepFailReqRef * const prepFail = (PrepFailReqRef *)&signal->theData[0];
- prepFail->xxxBlockRef = blockRef;
- prepFail->failNo = failNo;
- prepFail->noOfNodes = noOfNodes;
-
- NodeBitmask::clear(prepFail->theNodes);
-
- for(Uint32 i = 0; i<noOfNodes; i++){
- const NodeId nodeId = theNodes[i];
- NodeBitmask::set(prepFail->theNodes, nodeId);
- }
-
- sendSignal(dstBlockRef, gsn, signal, PrepFailReqRef::SignalLength, JBA);
-}
-
-
-/**--------------------------------------------------------------------------
- * SEND PREPARE FAIL REQUEST FROM PRESIDENT.
- *---------------------------------------------------------------------------*/
-void Qmgr::sendPrepFailReq(Signal* signal, Uint16 aNode)
-{
- NodeRecPtr sendNodePtr;
- sendNodePtr.i = aNode;
- ptrCheckGuard(sendNodePtr, MAX_NDB_NODES, nodeRec);
- sendNodePtr.p->sendPrepFailReqStatus = Q_ACTIVE;
-
- sendPrepFailReqRef(signal,
- sendNodePtr.p->blockRef,
- GSN_PREP_FAILREQ,
- reference(),
- cfailureNr,
- cnoFailedNodes,
- cfailedNodes);
-}//Qmgr::sendPrepFailReq()
-
-/**
- * Arbitration module. Rest of QMGR calls us only via
- * the "handle" routines.
- */
-
-/**
- * Should < 1/2 nodes die unconditionally. Affects only >= 3-way
- * replication.
- */
-static const bool g_ndb_arbit_one_half_rule = false;
-
-/**
- * Config signals are logically part of CM_INIT.
- */
-void
-Qmgr::execARBIT_CFG(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- unsigned rank = sd->code;
- ndbrequire(1 <= rank && rank <= 2);
- arbitRec.apiMask[0].bitOR(sd->mask);
- arbitRec.apiMask[rank] = sd->mask;
-}
-
-/**
- * ContinueB delay (0=JBA 1=JBB)
- */
-Uint32 Qmgr::getArbitDelay()
-{
- switch (arbitRec.state) {
- case ARBIT_NULL:
- jam();
- break;
- case ARBIT_INIT:
- jam();
- case ARBIT_FIND:
- jam();
- case ARBIT_PREP1:
- jam();
- case ARBIT_PREP2:
- jam();
- case ARBIT_START:
- jam();
- return 100;
- case ARBIT_RUN:
- jam();
- return 1000;
- case ARBIT_CHOOSE:
- jam();
- return 10;
- case ARBIT_CRASH: // if we could wait
- jam();
- return 100;
- }
- ndbrequire(false);
- return (Uint32)-1;
-}
-
-/**
- * Time to wait for reply. There is only 1 config parameter
- * (timeout for CHOOSE). XXX The rest are guesses.
- */
-Uint32 Qmgr::getArbitTimeout()
-{
- switch (arbitRec.state) {
- case ARBIT_NULL:
- jam();
- break;
- case ARBIT_INIT: // not used
- jam();
- case ARBIT_FIND: // not used
- jam();
- return 1000;
- case ARBIT_PREP1:
- jam();
- case ARBIT_PREP2:
- jam();
- return 1000 + cnoOfNodes * hb_send_timer.getDelay();
- case ARBIT_START:
- jam();
- return 1000 + arbitRec.timeout;
- case ARBIT_RUN: // not used (yet)
- jam();
- return 1000;
- case ARBIT_CHOOSE:
- jam();
- return arbitRec.timeout;
- case ARBIT_CRASH: // if we could wait
- jam();
- return 100;
- }
- ndbrequire(false);
- return (Uint32)-1;
-}
-
-/**
- * Start arbitration thread when we are president and database
- * is opened for the first time.
- *
- * XXX Do arbitration check just like on node failure. Since
- * there is no arbitrator yet, must win on counts alone.
- */
-void
-Qmgr::handleArbitStart(Signal* signal)
-{
- jam();
- ndbrequire(cpresident == getOwnNodeId());
- ndbrequire(arbitRec.state == ARBIT_NULL);
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- startArbitThread(signal);
-}
-
-/**
- * Handle API node failure. Called also by non-president nodes.
- * If we are president go back to INIT state, otherwise to NULL.
- * Start new thread to save time.
- */
-void
-Qmgr::handleArbitApiFail(Signal* signal, Uint16 nodeId)
-{
- if (arbitRec.node != nodeId) {
- jam();
- return;
- }
- reportArbitEvent(signal, NDB_LE_ArbitState);
- arbitRec.node = 0;
- switch (arbitRec.state) {
- case ARBIT_NULL: // should not happen
- jam();
- case ARBIT_INIT:
- jam();
- case ARBIT_FIND:
- jam();
- break;
- case ARBIT_PREP1: // start from beginning
- jam();
- case ARBIT_PREP2:
- jam();
- case ARBIT_START:
- jam();
- case ARBIT_RUN:
- if (cpresident == getOwnNodeId()) {
- jam();
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- startArbitThread(signal);
- } else {
- jam();
- arbitRec.state = ARBIT_NULL;
- }
- break;
- case ARBIT_CHOOSE: // XXX too late
- jam();
- case ARBIT_CRASH:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }
-}
-
-/**
- * Handle NDB node add. Ignore if arbitration thread not yet
- * started. If PREP is not ready, go back to INIT. Otherwise
- * the new node gets arbitrator and ticket once we reach RUN state.
- * Start new thread to save time.
- */
-void
-Qmgr::handleArbitNdbAdd(Signal* signal, Uint16 nodeId)
-{
- jam();
- ndbrequire(cpresident == getOwnNodeId());
- switch (arbitRec.state) {
- case ARBIT_NULL: // before db opened
- jam();
- break;
- case ARBIT_INIT: // start from beginning
- jam();
- case ARBIT_FIND:
- jam();
- case ARBIT_PREP1:
- jam();
- case ARBIT_PREP2:
- jam();
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- startArbitThread(signal);
- break;
- case ARBIT_START: // process in RUN state
- jam();
- case ARBIT_RUN:
- jam();
- arbitRec.newMask.set(nodeId);
- break;
- case ARBIT_CHOOSE: // XXX too late
- jam();
- case ARBIT_CRASH:
- jam();
- break;
- default:
- ndbrequire(false);
- break;
- }
-}
-
-/**
- * Check if current nodeset can survive. The decision is
- * based on node count, node groups, and on external arbitrator
- * (if we have one). Always starts a new thread because
- * 1) CHOOSE cannot wait 2) if we are new president we need
- * a thread 3) if we are old president it does no harm.
- */
-void
-Qmgr::handleArbitCheck(Signal* signal)
-{
- jam();
- ndbrequire(cpresident == getOwnNodeId());
- NodeBitmask ndbMask;
- computeArbitNdbMask(ndbMask);
- if (g_ndb_arbit_one_half_rule &&
- 2 * ndbMask.count() < cnoOfNodes) {
- jam();
- arbitRec.code = ArbitCode::LoseNodes;
- } else {
- jam();
- CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
- sd->blockRef = reference();
- sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck;
- sd->mask = ndbMask;
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
- jamEntry();
- switch (sd->output) {
- case CheckNodeGroups::Win:
- jam();
- arbitRec.code = ArbitCode::WinGroups;
- break;
- case CheckNodeGroups::Lose:
- jam();
- arbitRec.code = ArbitCode::LoseGroups;
- break;
- case CheckNodeGroups::Partitioning:
- jam();
- arbitRec.code = ArbitCode::Partitioning;
- if (g_ndb_arbit_one_half_rule &&
- 2 * ndbMask.count() > cnoOfNodes) {
- jam();
- arbitRec.code = ArbitCode::WinNodes;
- }
- break;
- default:
- ndbrequire(false);
- break;
- }
- }
- switch (arbitRec.code) {
- case ArbitCode::LoseNodes:
- jam();
- case ArbitCode::LoseGroups:
- jam();
- goto crashme;
- case ArbitCode::WinNodes:
- jam();
- case ArbitCode::WinGroups:
- jam();
- if (arbitRec.state == ARBIT_RUN) {
- jam();
- break;
- }
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- break;
- case ArbitCode::Partitioning:
- if (arbitRec.state == ARBIT_RUN) {
- jam();
- arbitRec.state = ARBIT_CHOOSE;
- arbitRec.newstate = true;
- break;
- }
- if (arbitRec.apiMask[0].count() != 0) {
- jam();
- arbitRec.code = ArbitCode::LoseNorun;
- } else {
- jam();
- arbitRec.code = ArbitCode::LoseNocfg;
- }
- goto crashme;
- default:
- crashme:
- jam();
- arbitRec.state = ARBIT_CRASH;
- arbitRec.newstate = true;
- break;
- }
- reportArbitEvent(signal, NDB_LE_ArbitResult);
- switch (arbitRec.state) {
- default:
- jam();
- arbitRec.newMask.bitAND(ndbMask); // delete failed nodes
- arbitRec.recvMask.bitAND(ndbMask);
- sendCommitFailReq(signal); // start commit of failed nodes
- break;
- case ARBIT_CHOOSE:
- jam();
- case ARBIT_CRASH:
- jam();
- break;
- }
- startArbitThread(signal);
-}
-
-/**
- * Start a new continueB thread. The thread id is incremented
- * so that any old thread will exit.
- */
-void
-Qmgr::startArbitThread(Signal* signal)
-{
- jam();
- ndbrequire(cpresident == getOwnNodeId());
- arbitRec.code = ArbitCode::ThreadStart;
- reportArbitEvent(signal, NDB_LE_ArbitState);
- signal->theData[1] = ++arbitRec.thread;
- runArbitThread(signal);
-}
-
-/**
- * Handle arbitration thread. The initial thread normally ends
- * up in RUN state. New thread can be started to save time.
- */
-void
-Qmgr::runArbitThread(Signal* signal)
-{
-#ifdef DEBUG_ARBIT
- NodeBitmask ndbMask;
- computeArbitNdbMask(ndbMask);
- ndbout << "arbit thread:";
- ndbout << " state=" << arbitRec.state;
- ndbout << " newstate=" << arbitRec.newstate;
- ndbout << " thread=" << arbitRec.thread;
- ndbout << " node=" << arbitRec.node;
- ndbout << " ticket=" << arbitRec.ticket.getText();
- ndbout << " ndbmask=" << ndbMask.getText();
- ndbout << " sendcount=" << arbitRec.sendCount;
- ndbout << " recvcount=" << arbitRec.recvCount;
- ndbout << " recvmask=" << arbitRec.recvMask.getText();
- ndbout << " code=" << arbitRec.code;
- ndbout << endl;
-#endif
- if (signal->theData[1] != arbitRec.thread) {
- jam();
- return; // old thread dies
- }
- switch (arbitRec.state) {
- case ARBIT_INIT: // main thread
- jam();
- stateArbitInit(signal);
- break;
- case ARBIT_FIND:
- jam();
- stateArbitFind(signal);
- break;
- case ARBIT_PREP1:
- jam();
- case ARBIT_PREP2:
- jam();
- stateArbitPrep(signal);
- break;
- case ARBIT_START:
- jam();
- stateArbitStart(signal);
- break;
- case ARBIT_RUN:
- jam();
- stateArbitRun(signal);
- break;
- case ARBIT_CHOOSE: // partitition thread
- jam();
- stateArbitChoose(signal);
- break;
- case ARBIT_CRASH:
- jam();
- stateArbitCrash(signal);
- break;
- default:
- ndbrequire(false);
- break;
- }
- signal->theData[0] = ZARBIT_HANDLING;
- signal->theData[1] = arbitRec.thread;
- signal->theData[2] = arbitRec.state; // just for signal log
- Uint32 delay = getArbitDelay();
- if (delay == 0) {
- jam();
- sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 3, JBA);
- } else if (delay == 1) {
- jam();
- sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 3, JBB);
- } else {
- jam();
- sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, delay, 3);
- }//if
-}
-
-/**
- * Handle INIT state. Generate next ticket. Switch to FIND
- * state without delay.
- */
-void
-Qmgr::stateArbitInit(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.node = 0;
- arbitRec.ticket.update();
- arbitRec.newMask.clear();
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- arbitRec.state = ARBIT_FIND;
- arbitRec.newstate = true;
- stateArbitFind(signal);
-}
-
-/**
- * Handle FIND state. Find first arbitrator which is alive
- * and invoke PREP state without delay. If none are found,
- * loop in FIND state. This is forever if no arbitrators
- * are configured (not the normal case).
- *
- * XXX Add adaptive behaviour to avoid getting stuck on API
- * nodes which are alive but do not respond or die too soon.
- */
-void
-Qmgr::stateArbitFind(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- NodeRecPtr aPtr;
- for (unsigned rank = 1; rank <= 2; rank++) {
- jam();
- aPtr.i = 0;
- const unsigned stop = NodeBitmask::NotFound;
- while ((aPtr.i = arbitRec.apiMask[rank].find(aPtr.i + 1)) != stop) {
- jam();
- ptrAss(aPtr, nodeRec);
- if (aPtr.p->phase != ZAPI_ACTIVE)
- continue;
- arbitRec.node = aPtr.i;
- arbitRec.state = ARBIT_PREP1;
- arbitRec.newstate = true;
- stateArbitPrep(signal);
- return;
- }
- }
-}
-
-/**
- * Handle PREP states. First round nulls any existing tickets.
- * Second round sends new ticket. When all confirms have been
- * received invoke START state immediately.
- */
-void
-Qmgr::stateArbitPrep(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.sendCount = 0; // send all at once
- computeArbitNdbMask(arbitRec.recvMask); // to send and recv
- arbitRec.recvMask.clear(getOwnNodeId());
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- if (! arbitRec.sendCount) {
- jam();
- NodeRecPtr aPtr;
- aPtr.i = 0;
- const unsigned stop = NodeBitmask::NotFound;
- while ((aPtr.i = arbitRec.recvMask.find(aPtr.i + 1)) != stop) {
- jam();
- ptrAss(aPtr, nodeRec);
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- sd->sender = getOwnNodeId();
- if (arbitRec.state == ARBIT_PREP1) {
- jam();
- sd->code = ArbitCode::PrepPart1;
- } else {
- jam();
- sd->code = ArbitCode::PrepPart2;
- }
- sd->node = arbitRec.node;
- sd->ticket = arbitRec.ticket;
- sd->mask.clear();
- sendSignal(aPtr.p->blockRef, GSN_ARBIT_PREPREQ, signal,
- ArbitSignalData::SignalLength, JBB);
- }
- arbitRec.setTimestamp(); // send time
- arbitRec.sendCount = 1;
- return;
- }
- if (arbitRec.code != 0) { // error
- jam();
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- return;
- }
- if (arbitRec.recvMask.count() == 0) { // recv all
- if (arbitRec.state == ARBIT_PREP1) {
- jam();
- arbitRec.state = ARBIT_PREP2;
- arbitRec.newstate = true;
- } else {
- jam();
- arbitRec.state = ARBIT_START;
- arbitRec.newstate = true;
- stateArbitStart(signal);
- }
- return;
- }
- if (arbitRec.getTimediff() > getArbitTimeout()) {
- jam();
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- return;
- }
-}
-
-void
-Qmgr::execARBIT_PREPREQ(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (getOwnNodeId() == cpresident) {
- jam();
- return; // wrong state
- }
- if (sd->sender != cpresident) {
- jam();
- return; // wrong state
- }
- NodeRecPtr aPtr;
- aPtr.i = sd->sender;
- ptrAss(aPtr, nodeRec);
- switch (sd->code) {
- case ArbitCode::PrepPart1: // zero them just to be sure
- jam();
- arbitRec.node = 0;
- arbitRec.ticket.clear();
- break;
- case ArbitCode::PrepPart2: // non-president enters RUN state
- jam();
- case ArbitCode::PrepAtrun:
- jam();
- arbitRec.node = sd->node;
- arbitRec.ticket = sd->ticket;
- arbitRec.code = sd->code;
- reportArbitEvent(signal, NDB_LE_ArbitState);
- arbitRec.state = ARBIT_RUN;
- arbitRec.newstate = true;
- if (sd->code == ArbitCode::PrepAtrun) {
- jam();
- return;
- }
- break;
- default:
- jam();
- ndbrequire(false);
- }
- sd->sender = getOwnNodeId();
- sd->code = 0;
- sendSignal(aPtr.p->blockRef, GSN_ARBIT_PREPCONF, signal,
- ArbitSignalData::SignalLength, JBB);
-}
-
-void
-Qmgr::execARBIT_PREPCONF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (! arbitRec.match(sd)) {
- jam();
- return; // stray signal
- }
- if (arbitRec.state != ARBIT_PREP1 && arbitRec.state != ARBIT_PREP2) {
- jam();
- return; // wrong state
- }
- if (! arbitRec.recvMask.get(sd->sender)) {
- jam();
- return; // wrong state
- }
- arbitRec.recvMask.clear(sd->sender);
- if (arbitRec.code == 0 && sd->code != 0) {
- jam();
- arbitRec.code = sd->code;
- }//if
-}
-
-void
-Qmgr::execARBIT_PREPREF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (sd->code == 0) {
- jam();
- sd->code = ArbitCode::ErrUnknown;
- }
- execARBIT_PREPCONF(signal);
-}
-
-/**
- * Handle START state. On first call send start request to
- * the chosen arbitrator. Then wait for a CONF.
- */
-void
-Qmgr::stateArbitStart(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.sendCount = 0;
- arbitRec.recvCount = 0;
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- if (! arbitRec.sendCount) {
- jam();
- BlockReference blockRef = calcApiClusterMgrBlockRef(arbitRec.node);
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- sd->sender = getOwnNodeId();
- sd->code = 0;
- sd->node = arbitRec.node;
- sd->ticket = arbitRec.ticket;
- sd->mask.clear();
- sendSignal(blockRef, GSN_ARBIT_STARTREQ, signal,
- ArbitSignalData::SignalLength, JBB);
- arbitRec.sendCount = 1;
- arbitRec.setTimestamp(); // send time
- return;
- }
- if (arbitRec.recvCount) {
- jam();
- reportArbitEvent(signal, NDB_LE_ArbitState);
- if (arbitRec.code == ArbitCode::ApiStart) {
- jam();
- arbitRec.state = ARBIT_RUN;
- arbitRec.newstate = true;
- return;
- }
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- return;
- }
- if (arbitRec.getTimediff() > getArbitTimeout()) {
- jam();
- arbitRec.code = ArbitCode::ErrTimeout;
- reportArbitEvent(signal, NDB_LE_ArbitState);
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- return;
- }
-}
-
-void
-Qmgr::execARBIT_STARTCONF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (! arbitRec.match(sd)) {
- jam();
- return; // stray signal
- }
- if (arbitRec.state != ARBIT_START) {
- jam();
- return; // wrong state
- }
- if (arbitRec.recvCount) {
- jam();
- return; // wrong state
- }
- arbitRec.code = sd->code;
- arbitRec.recvCount = 1;
-}
-
-void
-Qmgr::execARBIT_STARTREF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (sd->code == 0) {
- jam();
- sd->code = ArbitCode::ErrUnknown;
- }
- execARBIT_STARTCONF(signal);
-}
-
-/**
- * Handle RUN state. Send ticket to any new nodes which have
- * appeared after PREP state. We don't care about a CONF.
- */
-void
-Qmgr::stateArbitRun(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- NodeRecPtr aPtr;
- aPtr.i = 0;
- const unsigned stop = NodeBitmask::NotFound;
- while ((aPtr.i = arbitRec.newMask.find(aPtr.i + 1)) != stop) {
- jam();
- arbitRec.newMask.clear(aPtr.i);
- ptrAss(aPtr, nodeRec);
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- sd->sender = getOwnNodeId();
- sd->code = ArbitCode::PrepAtrun;
- sd->node = arbitRec.node;
- sd->ticket = arbitRec.ticket;
- sd->mask.clear();
- sendSignal(aPtr.p->blockRef, GSN_ARBIT_PREPREQ, signal,
- ArbitSignalData::SignalLength, JBB);
- }
-}
-
-/**
- * Handle CHOOSE state. Entered only from RUN state when
- * there is a possible network partitioning. Send CHOOSE to
- * the arbitrator. On win switch to INIT state because a new
- * ticket must be created.
- */
-void
-Qmgr::stateArbitChoose(Signal* signal)
-{
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
-
- arbitRec.sendCount = 0;
- arbitRec.recvCount = 0;
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
- if (! arbitRec.sendCount) {
- jam();
- BlockReference blockRef = calcApiClusterMgrBlockRef(arbitRec.node);
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- sd->sender = getOwnNodeId();
- sd->code = 0;
- sd->node = arbitRec.node;
- sd->ticket = arbitRec.ticket;
- computeArbitNdbMask(sd->mask);
- sendSignal(blockRef, GSN_ARBIT_CHOOSEREQ, signal,
- ArbitSignalData::SignalLength, JBA);
- arbitRec.sendCount = 1;
- arbitRec.setTimestamp(); // send time
- return;
- }
- if (arbitRec.recvCount) {
- jam();
- reportArbitEvent(signal, NDB_LE_ArbitResult);
- if (arbitRec.code == ArbitCode::WinChoose) {
- jam();
- sendCommitFailReq(signal); // start commit of failed nodes
- arbitRec.state = ARBIT_INIT;
- arbitRec.newstate = true;
- return;
- }
- arbitRec.state = ARBIT_CRASH;
- arbitRec.newstate = true;
- stateArbitCrash(signal); // do it at once
- return;
- }
- if (arbitRec.getTimediff() > getArbitTimeout()) {
- jam();
- arbitRec.code = ArbitCode::ErrTimeout;
- reportArbitEvent(signal, NDB_LE_ArbitState);
- arbitRec.state = ARBIT_CRASH;
- arbitRec.newstate = true;
- stateArbitCrash(signal); // do it at once
- return;
- }
-}
-
-void
-Qmgr::execARBIT_CHOOSECONF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (!arbitRec.match(sd)) {
- jam();
- return; // stray signal
- }
- if (arbitRec.state != ARBIT_CHOOSE) {
- jam();
- return; // wrong state
- }
- if (arbitRec.recvCount) {
- jam();
- return; // wrong state
- }
- arbitRec.recvCount = 1;
- arbitRec.code = sd->code;
-}
-
-void
-Qmgr::execARBIT_CHOOSEREF(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (sd->code == 0) {
- jam();
- sd->code = ArbitCode::ErrUnknown;
- }
- execARBIT_CHOOSECONF(signal);
-}
-
-/**
- * Handle CRASH state. We must crash immediately.
- * XXX tell other nodes in our party to crash too.
- */
-void
-Qmgr::stateArbitCrash(Signal* signal)
-{
- jam();
- if (arbitRec.newstate) {
- jam();
- CRASH_INSERTION((Uint32)910 + arbitRec.state);
- arbitRec.setTimestamp();
- arbitRec.code = 0;
- arbitRec.newstate = false;
- }
-#ifdef ndb_arbit_crash_wait_for_event_report_to_get_out
- if (! (arbitRec.getTimediff() > getArbitTimeout()))
- return;
-#endif
- CRASH_INSERTION(932);
- progError(__LINE__, NDBD_EXIT_ARBIT_SHUTDOWN,
- "Arbitrator decided to shutdown this node");
-}
-
-/**
- * Arbitrator may inform us that it will exit. This lets us
- * start looking sooner for a new one. Handle it like API node
- * failure.
- */
-void
-Qmgr::execARBIT_STOPREP(Signal* signal)
-{
- jamEntry();
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- if (! arbitRec.match(sd)) {
- jam();
- return; // stray signal
- }
- arbitRec.code = ArbitCode::ApiExit;
- handleArbitApiFail(signal, arbitRec.node);
-}
-
-void
-Qmgr::computeArbitNdbMask(NodeBitmask& aMask)
-{
- NodeRecPtr aPtr;
- aMask.clear();
- for (aPtr.i = 1; aPtr.i < MAX_NDB_NODES; aPtr.i++) {
- jam();
- ptrAss(aPtr, nodeRec);
- if (getNodeInfo(aPtr.i).getType() == NodeInfo::DB && aPtr.p->phase == ZRUNNING){
- jam();
- aMask.set(aPtr.i);
- }
- }
-}
-
-/**
- * Report arbitration event. We use arbitration signal format
- * where sender (word 0) is event type.
- */
-void
-Qmgr::reportArbitEvent(Signal* signal, Ndb_logevent_type type)
-{
- ArbitSignalData* sd = (ArbitSignalData*)&signal->theData[0];
- sd->sender = type;
- sd->code = arbitRec.code | (arbitRec.state << 16);
- sd->node = arbitRec.node;
- sd->ticket = arbitRec.ticket;
- sd->mask.clear();
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal,
- ArbitSignalData::SignalLength, JBB);
-}
-
-// end of arbitration module
-
-void
-Qmgr::execDUMP_STATE_ORD(Signal* signal)
-{
- switch (signal->theData[0]) {
- case 1:
- infoEvent("creadyDistCom = %d, cpresident = %d\n",
- creadyDistCom, cpresident);
- infoEvent("cpresidentAlive = %d, cpresidentCand = %d (gci: %d)\n",
- cpresidentAlive,
- c_start.m_president_candidate,
- c_start.m_president_candidate_gci);
- infoEvent("ctoStatus = %d\n", ctoStatus);
- for(Uint32 i = 1; i<MAX_NDB_NODES; i++){
- NodeRecPtr nodePtr;
- nodePtr.i = i;
- ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
- char buf[100];
- switch(nodePtr.p->phase){
- case ZINIT:
- sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase);
- break;
- 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;
- case ZAPI_INACTIVE:
- sprintf(buf, "Node %d: ZAPI_INACTIVE(%d)", i, nodePtr.p->phase);
- break;
- case ZAPI_ACTIVE:
- sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase);
- break;
- default:
- sprintf(buf, "Node %d: <UNKNOWN>(%d)", i, nodePtr.p->phase);
- break;
- }
- infoEvent(buf);
- }
- }
-
-#ifdef ERROR_INSERT
- if (signal->theData[0] == 935 && signal->getLength() == 2)
- {
- SET_ERROR_INSERT_VALUE(935);
- c_error_insert_extra = signal->theData[1];
- }
-#endif
-}//Qmgr::execDUMP_STATE_ORD()
-
-
-void
-Qmgr::execAPI_BROADCAST_REP(Signal* signal)
-{
- jamEntry();
- ApiBroadcastRep api= *(const ApiBroadcastRep*)signal->getDataPtr();
-
- Uint32 len = signal->getLength() - ApiBroadcastRep::SignalLength;
- memmove(signal->theData, signal->theData+ApiBroadcastRep::SignalLength,
- 4*len);
-
- NodeBitmask mask;
- NodeRecPtr nodePtr;
- for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++)
- {
- jam();
- ptrAss(nodePtr, nodeRec);
- if (nodePtr.p->phase == ZAPI_ACTIVE &&
- getNodeInfo(nodePtr.i).m_version >= api.minVersion)
- {
- mask.set(nodePtr.i);
- }
- }
-
- NodeReceiverGroup rg(API_CLUSTERMGR, mask);
- sendSignal(rg, api.gsn, signal, len, JBB); // forward sections
-}
-
-void
-Qmgr::execNODE_FAILREP(Signal * signal)
-{
- jamEntry();
- // make sure any distributed signals get acknowledged
- // destructive of the signal
- c_counterMgr.execNODE_FAILREP(signal);
-}
-
-void
-Qmgr::execALLOC_NODEID_REQ(Signal * signal)
-{
- jamEntry();
- const AllocNodeIdReq * req = (AllocNodeIdReq*)signal->getDataPtr();
- Uint32 senderRef = req->senderRef;
- Uint32 nodeId = req->nodeId;
- Uint32 nodeType = req->nodeType;
- Uint32 error = 0;
-
- if (refToBlock(senderRef) != QMGR) // request from management server
- {
- /* master */
-
- if (getOwnNodeId() != cpresident)
- error = AllocNodeIdRef::NotMaster;
- else if (!opAllocNodeIdReq.m_tracker.done())
- error = AllocNodeIdRef::Busy;
- else if (c_connectedNodes.get(nodeId))
- error = AllocNodeIdRef::NodeConnected;
-
- if (error)
- {
- jam();
- AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = error;
- ref->masterRef = numberToRef(QMGR, cpresident);
- sendSignal(senderRef, GSN_ALLOC_NODEID_REF, signal,
- AllocNodeIdRef::SignalLength, JBB);
- return;
- }
-
- if (ERROR_INSERTED(934) && nodeId != getOwnNodeId())
- {
- CRASH_INSERTION(934);
- }
-
- opAllocNodeIdReq.m_req = *req;
- opAllocNodeIdReq.m_error = 0;
- opAllocNodeIdReq.m_connectCount = getNodeInfo(refToNode(senderRef)).m_connectCount;
-
- jam();
- AllocNodeIdReq * req = (AllocNodeIdReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- NodeReceiverGroup rg(QMGR, c_clusterNodes);
- RequestTracker & p = opAllocNodeIdReq.m_tracker;
- p.init<AllocNodeIdRef>(c_counterMgr, rg, GSN_ALLOC_NODEID_REF, 0);
-
- sendSignal(rg, GSN_ALLOC_NODEID_REQ, signal,
- AllocNodeIdReq::SignalLength, JBB);
- return;
- }
-
- /* participant */
-
- if (c_connectedNodes.get(nodeId))
- error = AllocNodeIdRef::NodeConnected;
- else
- {
- NodeRecPtr nodePtr;
- nodePtr.i = nodeId;
- ptrAss(nodePtr, nodeRec);
- if (nodeType != getNodeInfo(nodeId).m_type)
- error = AllocNodeIdRef::NodeTypeMismatch;
- else if (nodePtr.p->failState != NORMAL)
- error = AllocNodeIdRef::NodeFailureHandlingNotCompleted;
- }
-
- if (error)
- {
- AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = error;
- sendSignal(senderRef, GSN_ALLOC_NODEID_REF, signal,
- AllocNodeIdRef::SignalLength, JBB);
- return;
- }
-
- AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_ALLOC_NODEID_CONF, signal,
- AllocNodeIdConf::SignalLength, JBB);
-}
-
-void
-Qmgr::execALLOC_NODEID_CONF(Signal * signal)
-{
- /* master */
-
- jamEntry();
- const AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtr();
- opAllocNodeIdReq.m_tracker.reportConf(c_counterMgr,
- refToNode(conf->senderRef));
- completeAllocNodeIdReq(signal);
-}
-
-
-void
-Qmgr::execALLOC_NODEID_REF(Signal * signal)
-{
- /* master */
-
- jamEntry();
- const AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtr();
- if (ref->errorCode == AllocNodeIdRef::NF_FakeErrorREF)
- {
- opAllocNodeIdReq.m_tracker.ignoreRef(c_counterMgr,
- refToNode(ref->senderRef));
- }
- else
- {
- opAllocNodeIdReq.m_tracker.reportRef(c_counterMgr,
- refToNode(ref->senderRef));
- if (opAllocNodeIdReq.m_error == 0)
- opAllocNodeIdReq.m_error = ref->errorCode;
- }
- completeAllocNodeIdReq(signal);
-}
-
-void
-Qmgr::completeAllocNodeIdReq(Signal *signal)
-{
- /* master */
-
- if (!opAllocNodeIdReq.m_tracker.done())
- {
- jam();
- return;
- }
-
- if (opAllocNodeIdReq.m_connectCount !=
- getNodeInfo(refToNode(opAllocNodeIdReq.m_req.senderRef)).m_connectCount)
- {
- // management server not same version as the original requester
- jam();
- return;
- }
-
- if (opAllocNodeIdReq.m_tracker.hasRef())
- {
- jam();
- AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = opAllocNodeIdReq.m_req.senderData;
- ref->nodeId = opAllocNodeIdReq.m_req.nodeId;
- ref->errorCode = opAllocNodeIdReq.m_error;
- ref->masterRef = numberToRef(QMGR, cpresident);
- ndbassert(AllocNodeIdRef::SignalLength == 5);
- sendSignal(opAllocNodeIdReq.m_req.senderRef, GSN_ALLOC_NODEID_REF, signal,
- AllocNodeIdRef::SignalLength, JBB);
- return;
- }
- jam();
- AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = opAllocNodeIdReq.m_req.senderData;
- conf->nodeId = opAllocNodeIdReq.m_req.nodeId;
- ndbassert(AllocNodeIdConf::SignalLength == 3);
- sendSignal(opAllocNodeIdReq.m_req.senderRef, GSN_ALLOC_NODEID_CONF, signal,
- AllocNodeIdConf::SignalLength, JBB);
-}
-
-void
-Qmgr::execSTOP_REQ(Signal* signal)
-{
- jamEntry();
- c_stopReq = * (StopReq*)signal->getDataPtr();
-
- if (c_stopReq.senderRef)
- {
- jam();
- ndbrequire(NdbNodeBitmask::get(c_stopReq.nodes, getOwnNodeId()));
-
- StopConf *conf = (StopConf*)signal->getDataPtrSend();
- conf->senderData = c_stopReq.senderData;
- conf->nodeState = getOwnNodeId();
- sendSignal(c_stopReq.senderRef,
- GSN_STOP_CONF, signal, StopConf::SignalLength, JBA);
- }
-}
-
-bool
-Qmgr::check_multi_node_shutdown(Signal* signal)
-{
- if (c_stopReq.senderRef &&
- NdbNodeBitmask::get(c_stopReq.nodes, getOwnNodeId()))
- {
- jam();
- if(StopReq::getPerformRestart(c_stopReq.requestInfo))
- {
- jam();
- StartOrd * startOrd = (StartOrd *)&signal->theData[0];
- startOrd->restartInfo = c_stopReq.requestInfo;
- EXECUTE_DIRECT(CMVMI, GSN_START_ORD, signal, 2);
- } else {
- EXECUTE_DIRECT(CMVMI, GSN_STOP_ORD, signal, 1);
- }
- return true;
- }
- return false;
-}
diff --git a/storage/ndb/src/kernel/blocks/qmgr/timer.hpp b/storage/ndb/src/kernel/blocks/qmgr/timer.hpp
deleted file mode 100644
index 5668e788a64..00000000000
--- a/storage/ndb/src/kernel/blocks/qmgr/timer.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/**
- * @class Timer
- * @brief A timer class that can't be fooled by NTP:ing the system clock to old time
- */
-class Timer {
-public:
- Timer() {
- m_delay = 10;
- };
-
- Timer(NDB_TICKS delay_time) {
- m_delay = delay_time;
- }
-
- /**
- * Set/Get alarm time of timer
- */
- inline void setDelay(NDB_TICKS delay_time) { m_delay = delay_time; }
- inline NDB_TICKS getDelay() { return m_delay; }
-
- /**
- * Start timer
- */
- inline void reset() {
- m_current_time = NdbTick_CurrentMillisecond();
- m_alarm_time = m_current_time + m_delay;
- }
-
- /**
- * Check for alarm
- */
- inline bool check() { return check(NdbTick_CurrentMillisecond()); }
-
- inline bool check(NDB_TICKS check_time) {
- /**
- * Standard alarm check
- */
- if (check_time > m_alarm_time) return true;
-
- /**
- * Time progressing, but it is not alarm time yet
- */
- if (check_time >= m_current_time) return false;
-
- /**
- * Time has moved backwards
- */
- reset();
- return false;
- }
-
-private:
- NDB_TICKS m_current_time;
- NDB_TICKS m_alarm_time;
- NDB_TICKS m_delay;
-};
diff --git a/storage/ndb/src/kernel/blocks/record_types.hpp b/storage/ndb/src/kernel/blocks/record_types.hpp
deleted file mode 100644
index 0c5ff3b5b2b..00000000000
--- a/storage/ndb/src/kernel/blocks/record_types.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2003, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KERNEL_RECORDS_HPP
-#define KERNEL_RECORDS_HPP
-
-/**
- * Resource groups
- */
-
-/**
- * Operations for dd
- * PGMAN_PAGE_REQUEST
- * LGMAN_LOG_WAITER
- * DBTUP_PAGE_REQUEST
- */
-#define RG_DISK_OPERATIONS 1
-
-/**
- * Records for dd
- * DBTUP_EXTENT_INFO
- */
-#define RG_DISK_RECORDS 2
-
-/**
- *
- */
-#define RG_RESERVED 0
-#define RG_COUNT 3
-
-/**
- * Record types
- */
-#define RT_PGMAN_PAGE_REQUEST MAKE_TID( 1, RG_DISK_OPERATIONS)
-#define RT_LGMAN_LOG_WAITER MAKE_TID( 2, RG_DISK_OPERATIONS)
-#define RT_DBTUP_PAGE_REQUEST MAKE_TID( 3, RG_DISK_OPERATIONS)
-
-#define RT_DBTUP_EXTENT_INFO MAKE_TID( 4, RG_DISK_RECORDS)
-#define RT_DBDICT_FILE MAKE_TID( 5, RG_DISK_RECORDS)
-#define RT_DBDICT_FILEGROUP MAKE_TID( 6, RG_DISK_RECORDS)
-#define RT_LGMAN_FILE MAKE_TID( 7, RG_DISK_RECORDS)
-#define RT_LGMAN_FILEGROUP MAKE_TID( 8, RG_DISK_RECORDS)
-#define RT_TSMAN_FILE MAKE_TID( 9, RG_DISK_RECORDS)
-#define RT_TSMAN_FILEGROUP MAKE_TID(10, RG_DISK_RECORDS)
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/restore.cpp b/storage/ndb/src/kernel/blocks/restore.cpp
deleted file mode 100644
index c090139c181..00000000000
--- a/storage/ndb/src/kernel/blocks/restore.cpp
+++ /dev/null
@@ -1,1286 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "restore.hpp"
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/RestoreImpl.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/LqhKey.hpp>
-#include <AttributeHeader.hpp>
-#include <md5_hash.hpp>
-#include <Dblqh.hpp>
-#include <dbtup/Dbtup.hpp>
-#include <KeyDescriptor.hpp>
-
-#define PAGES LCP_RESTORE_BUFFER
-
-Restore::Restore(Block_context& ctx) :
- SimulatedBlock(RESTORE, ctx),
- m_file_list(m_file_pool),
- m_file_hash(m_file_pool)
-{
- BLOCK_CONSTRUCTOR(Restore);
-
- // Add received signals
- addRecSignal(GSN_STTOR, &Restore::execSTTOR);
- addRecSignal(GSN_DUMP_STATE_ORD, &Restore::execDUMP_STATE_ORD);
- addRecSignal(GSN_CONTINUEB, &Restore::execCONTINUEB);
- addRecSignal(GSN_READ_CONFIG_REQ, &Restore::execREAD_CONFIG_REQ, true);
-
- addRecSignal(GSN_RESTORE_LCP_REQ, &Restore::execRESTORE_LCP_REQ);
-
- addRecSignal(GSN_FSOPENREF, &Restore::execFSOPENREF, true);
- addRecSignal(GSN_FSOPENCONF, &Restore::execFSOPENCONF);
- addRecSignal(GSN_FSREADREF, &Restore::execFSREADREF, true);
- addRecSignal(GSN_FSREADCONF, &Restore::execFSREADCONF);
- addRecSignal(GSN_FSCLOSEREF, &Restore::execFSCLOSEREF, true);
- addRecSignal(GSN_FSCLOSECONF, &Restore::execFSCLOSECONF);
-
- addRecSignal(GSN_LQHKEYREF, &Restore::execLQHKEYREF);
- addRecSignal(GSN_LQHKEYCONF, &Restore::execLQHKEYCONF);
-
- ndbrequire(sizeof(Column) == 8);
-}
-
-Restore::~Restore()
-{
-}
-
-BLOCK_FUNCTIONS(Restore)
-
-void
-Restore::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- c_lqh = (Dblqh*)globalData.getBlock(DBLQH);
- c_tup = (Dbtup*)globalData.getBlock(DBTUP);
- sendSTTORRY(signal);
-
- return;
-}//Restore::execNDB_STTOR()
-
-void
-Restore::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
- ndbrequire(req->noOfParameters == 0);
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
-#if 0
- Uint32 noBackups = 0, noTables = 0, noAttribs = 0;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &m_diskless));
- ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups);
- // ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &noTables));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs));
-
- noAttribs++; //RT 527 bug fix
-
- c_backupPool.setSize(noBackups);
- c_backupFilePool.setSize(3 * noBackups);
- c_tablePool.setSize(noBackups * noTables);
- c_attributePool.setSize(noBackups * noAttribs);
- c_triggerPool.setSize(noBackups * 3 * noTables);
-
- // 2 = no of replicas
- c_fragmentPool.setSize(noBackups * NO_OF_FRAG_PER_NODE * noTables);
-
- Uint32 szMem = 0;
- 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.
- c_pagePool.setSize(noPages + NO_OF_PAGES_META_FILE + 2);
-
- Uint32 szDataBuf = (2 * 1024 * 1024);
- Uint32 szLogBuf = (2 * 1024 * 1024);
- Uint32 szWrite = 32768;
- 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;
- c_defaults.m_minWriteSize = szWrite;
- c_defaults.m_maxWriteSize = szWrite;
-
- { // Init all tables
- ArrayList<Table> tables(c_tablePool);
- TablePtr ptr;
- while(tables.seize(ptr)){
- new (ptr.p) Table(c_attributePool, c_fragmentPool);
- }
- tables.release();
- }
-
- {
- ArrayList<BackupFile> ops(c_backupFilePool);
- BackupFilePtr ptr;
- while(ops.seize(ptr)){
- new (ptr.p) BackupFile(* this, c_pagePool);
- }
- ops.release();
- }
-
- {
- ArrayList<BackupRecord> recs(c_backupPool);
- BackupRecordPtr ptr;
- while(recs.seize(ptr)){
- new (ptr.p) BackupRecord(* this, c_pagePool, c_tablePool,
- c_backupFilePool, c_triggerPool);
- }
- recs.release();
- }
-
- // Initialize BAT for interface to file system
- {
- Page32Ptr p;
- ndbrequire(c_pagePool.seizeId(p, 0));
- c_startOfPages = (Uint32 *)p.p;
- c_pagePool.release(p);
-
- NewVARIABLE* bat = allocateBat(1);
- bat[0].WA = c_startOfPages;
- bat[0].nrr = c_pagePool.getSize()*sizeof(Page32)/sizeof(Uint32);
- }
-#endif
- m_file_pool.setSize(1);
- Uint32 cnt = 2*MAX_ATTRIBUTES_IN_TABLE;
- cnt += PAGES;
- cnt += List::getSegmentSize()-1;
- cnt /= List::getSegmentSize();
- cnt += 2;
- m_databuffer_pool.setSize(cnt);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-Restore::sendSTTORRY(Signal* signal){
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 3;
- signal->theData[5] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
-}
-
-void
-Restore::execCONTINUEB(Signal* signal){
- jamEntry();
-
- switch(signal->theData[0]){
- case RestoreContinueB::RESTORE_NEXT:
- {
- FilePtr file_ptr;
- m_file_pool.getPtr(file_ptr, signal->theData[1]);
- restore_next(signal, file_ptr);
- return;
- }
- case RestoreContinueB::READ_FILE:
- {
- FilePtr file_ptr;
- m_file_pool.getPtr(file_ptr, signal->theData[1]);
- read_file(signal, file_ptr);
- return;
- }
- default:
- ndbrequire(false);
- }
-}
-
-void
-Restore::execDUMP_STATE_ORD(Signal* signal){
- jamEntry();
-}
-
-void
-Restore::execRESTORE_LCP_REQ(Signal* signal){
- jamEntry();
-
- Uint32 err= 0;
- RestoreLcpReq* req= (RestoreLcpReq*)signal->getDataPtr();
- Uint32 senderRef= req->senderRef;
- Uint32 senderData= req->senderData;
- do
- {
- FilePtr file_ptr;
- if(!m_file_list.seize(file_ptr))
- {
- err= RestoreLcpRef::NoFileRecord;
- break;
- }
-
- if((err= init_file(req, file_ptr)))
- {
- break;
- }
-
- open_file(signal, file_ptr);
- return;
- } while(0);
-
- RestoreLcpRef* ref= (RestoreLcpRef*)signal->getDataPtrSend();
- ref->senderData= senderData;
- ref->senderRef= reference();
- ref->errorCode = err;
- sendSignal(senderRef, GSN_RESTORE_LCP_REF, signal,
- RestoreLcpRef::SignalLength, JBB);
-}
-
-Uint32
-Restore::init_file(const RestoreLcpReq* req, FilePtr file_ptr)
-{
- new (file_ptr.p) File();
- file_ptr.p->m_sender_ref = req->senderRef;
- file_ptr.p->m_sender_data = req->senderData;
-
- file_ptr.p->m_fd = RNIL;
- file_ptr.p->m_file_type = BackupFormat::LCP_FILE;
- file_ptr.p->m_status = File::FIRST_READ;
-
- file_ptr.p->m_lcp_no = req->lcpNo;
- file_ptr.p->m_table_id = req->tableId;
- file_ptr.p->m_fragment_id = req->fragmentId;
- file_ptr.p->m_table_version = RNIL;
-
- file_ptr.p->m_bytes_left = 0; // Bytes read from FS
- file_ptr.p->m_current_page_ptr_i = RNIL;
- file_ptr.p->m_current_page_pos = 0;
- file_ptr.p->m_current_page_index = 0;
- file_ptr.p->m_current_file_page = 0;
- file_ptr.p->m_outstanding_reads = 0;
- file_ptr.p->m_outstanding_operations = 0;
- file_ptr.p->m_rows_restored = 0;
- LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
- LocalDataBuffer<15> columns(m_databuffer_pool, file_ptr.p->m_columns);
-
- ndbassert(columns.isEmpty());
- columns.release();
-
- ndbassert(pages.isEmpty());
- pages.release();
-
- Uint32 buf_size= PAGES*GLOBAL_PAGE_SIZE;
- Uint32 page_count= (buf_size+GLOBAL_PAGE_SIZE-1)/GLOBAL_PAGE_SIZE;
- if(!pages.seize(page_count))
- {
- return RestoreLcpRef::OutOfDataBuffer;
- }
-
- List::Iterator it;
- for(pages.first(it); !it.isNull(); pages.next(it))
- {
- * it.data = RNIL;
- }
-
- Uint32 err= 0;
- for(pages.first(it); !it.isNull(); pages.next(it))
- {
- Ptr<GlobalPage> page_ptr;
- if(!m_global_page_pool.seize(page_ptr))
- {
- err= RestoreLcpRef::OutOfReadBufferPages;
- break;
- }
- * it.data = page_ptr.i;
- }
-
- if(err)
- {
- for(pages.first(it); !it.isNull(); pages.next(it))
- {
- if(* it.data == RNIL)
- break;
- m_global_page_pool.release(* it.data);
- }
- }
- else
- {
- pages.first(it);
- file_ptr.p->m_current_page_ptr_i = *it.data;
- }
- return err;
-}
-
-void
-Restore::release_file(FilePtr file_ptr)
-{
- LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
- LocalDataBuffer<15> columns(m_databuffer_pool, file_ptr.p->m_columns);
-
- List::Iterator it;
- for(pages.first(it); !it.isNull(); pages.next(it))
- {
- if(* it.data == RNIL)
- continue;
- m_global_page_pool.release(* it.data);
- }
-
- ndbout_c("RESTORE table: %d %lld rows applied",
- file_ptr.p->m_table_id,
- file_ptr.p->m_rows_restored);
-
- columns.release();
- pages.release();
- m_file_list.release(file_ptr);
-}
-
-void
-Restore::open_file(Signal* signal, FilePtr file_ptr)
-{
- FsOpenReq * req = (FsOpenReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->fileFlags = FsOpenReq::OM_READONLY ;
- req->userPointer = file_ptr.i;
-
- FsOpenReq::setVersion(req->fileNumber, 5);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
- FsOpenReq::v5_setLcpNo(req->fileNumber, file_ptr.p->m_lcp_no);
- FsOpenReq::v5_setTableId(req->fileNumber, file_ptr.p->m_table_id);
- FsOpenReq::v5_setFragmentId(req->fileNumber, file_ptr.p->m_fragment_id);
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBA);
-}
-
-void
-Restore::execFSOPENREF(Signal* signal)
-{
- FsRef* ref= (FsRef*)signal->getDataPtr();
- FilePtr file_ptr;
- jamEntry();
- m_file_pool.getPtr(file_ptr, ref->userPointer);
-
- Uint32 errCode= ref->errorCode;
- Uint32 osError= ref->osErrorCode;
-
- RestoreLcpRef* rep= (RestoreLcpRef*)signal->getDataPtrSend();
- rep->senderData= file_ptr.p->m_sender_data;
- rep->errorCode = errCode;
- rep->extra[0] = osError;
- sendSignal(file_ptr.p->m_sender_ref,
- GSN_RESTORE_LCP_REF, signal, RestoreLcpRef::SignalLength+1, JBB);
-
- release_file(file_ptr);
-}
-
-void
-Restore::execFSOPENCONF(Signal* signal)
-{
- jamEntry();
- FilePtr file_ptr;
- FsConf* conf= (FsConf*)signal->getDataPtr();
- m_file_pool.getPtr(file_ptr, conf->userPointer);
-
- file_ptr.p->m_fd = conf->filePointer;
-
- /**
- * Start thread's
- */
-
- file_ptr.p->m_status |= File::FILE_THREAD_RUNNING;
- signal->theData[0] = RestoreContinueB::READ_FILE;
- signal->theData[1] = file_ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-
- file_ptr.p->m_status |= File::RESTORE_THREAD_RUNNING;
- signal->theData[0] = RestoreContinueB::RESTORE_NEXT;
- signal->theData[1] = file_ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Restore::restore_next(Signal* signal, FilePtr file_ptr)
-{
- Uint32 *data, len= 0;
- Uint32 status = file_ptr.p->m_status;
- Uint32 page_count = file_ptr.p->m_pages.getSize();
- do
- {
- Uint32 left= file_ptr.p->m_bytes_left;
- if(left < 8)
- {
- /**
- * Not enought bytes to read header
- */
- break;
- }
- Ptr<GlobalPage> page_ptr, next_page_ptr = { 0, 0 };
- m_global_page_pool.getPtr(page_ptr, file_ptr.p->m_current_page_ptr_i);
- List::Iterator it;
-
- Uint32 pos= file_ptr.p->m_current_page_pos;
- if(status & File::READING_RECORDS)
- {
- /**
- * We are reading records
- */
- len= ntohl(* (page_ptr.p->data + pos)) + 1;
- }
- else
- {
- /**
- * Section length is in 2 word
- */
- if(pos + 1 == GLOBAL_PAGE_SIZE_WORDS)
- {
- /**
- * But that's stored on next page...
- * and since we have atleast 8 bytes left in buffer
- * we can be sure that that's in buffer
- */
- LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
- Uint32 next_page = file_ptr.p->m_current_page_index + 1;
- pages.position(it, next_page % page_count);
- m_global_page_pool.getPtr(next_page_ptr, * it.data);
- len= ntohl(* next_page_ptr.p->data);
- }
- else
- {
- len= ntohl(* (page_ptr.p->data + pos + 1));
- }
- }
-
- if(file_ptr.p->m_status & File::FIRST_READ)
- {
- len= 3;
- file_ptr.p->m_status &= ~(Uint32)File::FIRST_READ;
- }
-
- if(4 * len > left)
- {
- /**
- * Not enought bytes to read "record"
- */
- ndbout_c("records: %d len: %x left: %d",
- status & File::READING_RECORDS, 4*len, left);
-
- if (unlikely((status & File:: FILE_THREAD_RUNNING) == 0))
- {
- ndbrequire(false);
- }
- len= 0;
- break;
- }
-
- /**
- * Entire record is in buffer
- */
-
- if(pos + len >= GLOBAL_PAGE_SIZE_WORDS)
- {
- /**
- * But it's split over pages
- */
- if(next_page_ptr.p == 0)
- {
- LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
- Uint32 next_page = file_ptr.p->m_current_page_index + 1;
- pages.position(it, next_page % page_count);
- m_global_page_pool.getPtr(next_page_ptr, * it.data);
- }
- file_ptr.p->m_current_page_ptr_i = next_page_ptr.i;
- file_ptr.p->m_current_page_pos = (pos + len) - GLOBAL_PAGE_SIZE_WORDS;
- file_ptr.p->m_current_page_index =
- (file_ptr.p->m_current_page_index + 1) % page_count;
-
- Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos);
- memcpy(page_ptr.p, page_ptr.p->data+pos, 4 * first);
- memcpy(page_ptr.p->data+first, next_page_ptr.p, 4 * (len - first));
- data= page_ptr.p->data;
- }
- else
- {
- file_ptr.p->m_current_page_pos = pos + len;
- data= page_ptr.p->data+pos;
- }
-
- file_ptr.p->m_bytes_left -= 4*len;
-
- if(status & File::READING_RECORDS)
- {
- if(len == 1)
- {
- file_ptr.p->m_status = status & ~(Uint32)File::READING_RECORDS;
- }
- else
- {
- parse_record(signal, file_ptr, data, len);
- }
- }
- else
- {
- switch(ntohl(* data)){
- case BackupFormat::FILE_HEADER:
- parse_file_header(signal, file_ptr, data-3, len+3);
- break;
- case BackupFormat::FRAGMENT_HEADER:
- file_ptr.p->m_status = status | File::READING_RECORDS;
- parse_fragment_header(signal, file_ptr, data, len);
- break;
- case BackupFormat::FRAGMENT_FOOTER:
- parse_fragment_footer(signal, file_ptr, data, len);
- break;
- case BackupFormat::TABLE_LIST:
- parse_table_list(signal, file_ptr, data, len);
- break;
- case BackupFormat::TABLE_DESCRIPTION:
- parse_table_description(signal, file_ptr, data, len);
- break;
- case BackupFormat::GCP_ENTRY:
- parse_gcp_entry(signal, file_ptr, data, len);
- break;
- case BackupFormat::EMPTY_ENTRY:
- // skip
- break;
- case 0x4e444242: // 'NDBB'
- if (check_file_version(signal, ntohl(* (data+2))) == 0)
- {
- break;
- }
- default:
- parse_error(signal, file_ptr, __LINE__, ntohl(* data));
- }
- }
- } while(0);
-
- if(file_ptr.p->m_bytes_left == 0 && status & File::FILE_EOF)
- {
- file_ptr.p->m_status &= ~(Uint32)File::RESTORE_THREAD_RUNNING;
- /**
- * File is finished...
- */
- close_file(signal, file_ptr);
- return;
- }
-
- signal->theData[0] = RestoreContinueB::RESTORE_NEXT;
- signal->theData[1] = file_ptr.i;
-
- if(len)
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- else
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
-}
-
-void
-Restore::read_file(Signal* signal, FilePtr file_ptr)
-{
- Uint32 left= file_ptr.p->m_bytes_left;
- Uint32 page_count = file_ptr.p->m_pages.getSize();
- Uint32 free= GLOBAL_PAGE_SIZE * page_count - left;
- Uint32 read_count= free/GLOBAL_PAGE_SIZE;
-
- if(read_count <= file_ptr.p->m_outstanding_reads)
- {
- signal->theData[0] = RestoreContinueB::READ_FILE;
- signal->theData[1] = file_ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- read_count -= file_ptr.p->m_outstanding_reads;
- Uint32 curr_page= file_ptr.p->m_current_page_index;
- LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = file_ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = file_ptr.i;
- req->numberOfPages = 1;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatGlobalPage);
- FsReadWriteReq::setPartialReadFlag(req->operationFlag, 1);
-
- Uint32 start= (curr_page + page_count - read_count) % page_count;
-
- List::Iterator it;
- pages.position(it, start);
- do
- {
- file_ptr.p->m_outstanding_reads++;
- req->varIndex = file_ptr.p->m_current_file_page++;
- req->data.pageData[0] = *it.data;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBB);
-
- start++;
- if(start == page_count)
- {
- start= 0;
- pages.position(it, start);
- }
- else
- {
- pages.next(it);
- }
- } while(start != curr_page);
-}
-
-void
-Restore::execFSREADREF(Signal * signal)
-{
- jamEntry();
- SimulatedBlock::execFSREADREF(signal);
- ndbrequire(false);
-}
-
-void
-Restore::execFSREADCONF(Signal * signal)
-{
- jamEntry();
- FilePtr file_ptr;
- FsConf* conf= (FsConf*)signal->getDataPtr();
- m_file_pool.getPtr(file_ptr, conf->userPointer);
-
- file_ptr.p->m_bytes_left += conf->bytes_read;
-
- ndbassert(file_ptr.p->m_outstanding_reads);
- file_ptr.p->m_outstanding_reads--;
-
- if(file_ptr.p->m_outstanding_reads == 0)
- {
- ndbassert(conf->bytes_read <= GLOBAL_PAGE_SIZE);
- if(conf->bytes_read == GLOBAL_PAGE_SIZE)
- {
- read_file(signal, file_ptr);
- }
- else
- {
- file_ptr.p->m_status |= File::FILE_EOF;
- file_ptr.p->m_status &= ~(Uint32)File::FILE_THREAD_RUNNING;
- }
- }
-}
-
-void
-Restore::close_file(Signal* signal, FilePtr file_ptr)
-{
- FsCloseReq * req = (FsCloseReq *)signal->getDataPtrSend();
- req->filePointer = file_ptr.p->m_fd;
- req->userPointer = file_ptr.i;
- req->userReference = reference();
- req->fileFlag = 0;
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
-}
-
-void
-Restore::execFSCLOSEREF(Signal * signal)
-{
- jamEntry();
- SimulatedBlock::execFSCLOSEREF(signal);
- ndbrequire(false);
-}
-
-void
-Restore::execFSCLOSECONF(Signal * signal)
-{
- jamEntry();
- FilePtr file_ptr;
- FsConf* conf= (FsConf*)signal->getDataPtr();
- m_file_pool.getPtr(file_ptr, conf->userPointer);
-
- file_ptr.p->m_fd = RNIL;
-
- if(file_ptr.p->m_outstanding_operations == 0)
- {
- RestoreLcpConf* rep= (RestoreLcpConf*)signal->getDataPtrSend();
- rep->senderData= file_ptr.p->m_sender_data;
- sendSignal(file_ptr.p->m_sender_ref,
- GSN_RESTORE_LCP_CONF, signal,
- RestoreLcpConf::SignalLength, JBB);
- release_file(file_ptr);
- }
-}
-
-void
-Restore::parse_file_header(Signal* signal,
- FilePtr file_ptr,
- const Uint32* data, Uint32 len)
-{
- const BackupFormat::FileHeader* fh= (BackupFormat::FileHeader*)data;
-
- if(memcmp(fh->Magic, "NDBBCKUP", 8) != 0)
- {
- parse_error(signal, file_ptr, __LINE__, *data);
- return;
- }
-
- if (check_file_version(signal, ntohl(fh->NdbVersion)))
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->NdbVersion));
- return;
- }
- ndbassert(ntohl(fh->SectionType) == BackupFormat::FILE_HEADER);
-
- if(ntohl(fh->SectionLength) != len-3)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
- return;
- }
-
- if(ntohl(fh->FileType) != BackupFormat::LCP_FILE)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->FileType));
- return;
- }
-
- if(fh->ByteOrder != 0x12345678)
- {
- parse_error(signal, file_ptr, __LINE__, fh->ByteOrder);
- return;
- }
-}
-
-void
-Restore::parse_table_list(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
- const BackupFormat::CtlFile::TableList* fh=
- (BackupFormat::CtlFile::TableList*)data;
-
- if(ntohl(fh->TableIds[0]) != file_ptr.p->m_table_id)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableIds[0]));
- return;
- }
-}
-
-void
-Restore::parse_table_description(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
- bool lcp = file_ptr.p->is_lcp();
- Uint32 disk= 0;
- const BackupFormat::CtlFile::TableDescription* fh=
- (BackupFormat::CtlFile::TableDescription*)data;
-
- LocalDataBuffer<15> columns(m_databuffer_pool, file_ptr.p->m_columns);
-
- SimplePropertiesLinearReader it(fh->DictTabInfo, len);
- it.first();
-
- DictTabInfo::Table tmpTab; tmpTab.init();
- SimpleProperties::UnpackStatus stat;
- stat = SimpleProperties::unpack(it, &tmpTab,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
- ndbrequire(stat == SimpleProperties::Break);
-
- if(tmpTab.TableId != file_ptr.p->m_table_id)
- {
- parse_error(signal, file_ptr, __LINE__, tmpTab.TableId);
- return;
- }
-
- Column c;
- Uint32 colstore[sizeof(Column)/sizeof(Uint32)];
-
- for(Uint32 i = 0; i<tmpTab.NoOfAttributes; i++) {
- jam();
- DictTabInfo::Attribute tmp; tmp.init();
- stat = SimpleProperties::unpack(it, &tmp,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
-
- ndbrequire(stat == SimpleProperties::Break);
- it.next(); // Move Past EndOfAttribute
-
- const Uint32 arr = tmp.AttributeArraySize;
- const Uint32 sz = 1 << tmp.AttributeSize;
- const Uint32 sz32 = (sz * arr + 31) >> 5;
- const bool varsize = tmp.AttributeArrayType != NDB_ARRAYTYPE_FIXED;
-
- c.m_id = tmp.AttributeId;
- c.m_size = sz32;
- c.m_flags = (tmp.AttributeKeyFlag ? Column::COL_KEY : 0);
- c.m_flags |= (tmp.AttributeStorageType == NDB_STORAGETYPE_DISK ?
- Column::COL_DISK : 0);
-
- if(lcp && (c.m_flags & Column::COL_DISK))
- {
- /**
- * Restore does not currently handle disk attributes
- * which is fine as restore LCP shouldn't
- */
- disk++;
- continue;
- }
-
- if(!tmp.AttributeNullableFlag && !varsize)
- {
- }
- else if (true) // null mask dropped in 5.1
- {
- c.m_flags |= (varsize ? Column::COL_VAR : 0);
- c.m_flags |= (tmp.AttributeNullableFlag ? Column::COL_NULL : 0);
- }
-
- memcpy(colstore, &c, sizeof(Column));
- if(!columns.append(colstore, sizeof(Column)/sizeof(Uint32)))
- {
- parse_error(signal, file_ptr, __LINE__, i);
- return;
- }
- }
-
- if(lcp)
- {
- if (disk)
- {
- c.m_id = AttributeHeader::DISK_REF;
- c.m_size = 2;
- c.m_flags = 0;
- memcpy(colstore, &c, sizeof(Column));
- if(!columns.append(colstore, sizeof(Column)/sizeof(Uint32)))
- {
- parse_error(signal, file_ptr, __LINE__, 0);
- return;
- }
- }
-
- {
- c.m_id = AttributeHeader::ROWID;
- c.m_size = 2;
- c.m_flags = 0;
- memcpy(colstore, &c, sizeof(Column));
- if(!columns.append(colstore, sizeof(Column)/sizeof(Uint32)))
- {
- parse_error(signal, file_ptr, __LINE__, 0);
- return;
- }
- }
-
- if (tmpTab.RowGCIFlag)
- {
- c.m_id = AttributeHeader::ROW_GCI;
- c.m_size = 2;
- c.m_flags = 0;
- memcpy(colstore, &c, sizeof(Column));
- if(!columns.append(colstore, sizeof(Column)/sizeof(Uint32)))
- {
- parse_error(signal, file_ptr, __LINE__, 0);
- return;
- }
- }
- }
-
- file_ptr.p->m_table_version = tmpTab.TableVersion;
-}
-
-void
-Restore::parse_fragment_header(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
- const BackupFormat::DataFile::FragmentHeader* fh=
- (BackupFormat::DataFile::FragmentHeader*)data;
- if(ntohl(fh->TableId) != file_ptr.p->m_table_id)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableId));
- return;
- }
-
- if(ntohl(fh->ChecksumType) != 0)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
- return;
- }
-
- file_ptr.p->m_fragment_id = ntohl(fh->FragmentNo);
-
- if(file_ptr.p->is_lcp())
- {
- /**
- * Temporary reset DBTUP's #disk attributes on table
- */
- c_tup->start_restore_lcp(file_ptr.p->m_table_id,
- file_ptr.p->m_fragment_id);
- }
-}
-
-void
-Restore::parse_record(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
- List::Iterator it;
- LocalDataBuffer<15> columns(m_databuffer_pool, file_ptr.p->m_columns);
-
- Uint32 * const key_start = signal->getDataPtrSend()+24;
- Uint32 * const attr_start = key_start + MAX_KEY_SIZE_IN_WORDS;
-
- data += 1;
- const Uint32* const dataStart = data;
-
- Uint32 *keyData = key_start;
- Uint32 *attrData = attr_start;
- union {
- Column c;
- Uint32 _align[sizeof(Column)/sizeof(Uint32)];
- };
- bool disk = false;
- bool rowid = false;
- bool gci = false;
- Uint32 tableId = file_ptr.p->m_table_id;
-
- Uint64 gci_val;
- Local_key rowid_val;
- columns.first(it);
- while(!it.isNull())
- {
- _align[0] = *it.data; ndbrequire(columns.next(it));
- _align[1] = *it.data; columns.next(it);
-
- if (c.m_id == AttributeHeader::ROWID)
- {
- rowid_val.m_page_no = data[0];
- rowid_val.m_page_idx = data[1];
- data += 2;
- rowid = true;
- continue;
- }
-
- if (c.m_id == AttributeHeader::ROW_GCI)
- {
- memcpy(&gci_val, data, 8);
- data += 2;
- gci = true;
- continue;
- }
-
- if (! (c.m_flags & (Column::COL_VAR | Column::COL_NULL)))
- {
- ndbrequire(data < dataStart + len);
-
- if(c.m_flags & Column::COL_KEY)
- {
- memcpy(keyData, data, 4*c.m_size);
- keyData += c.m_size;
- }
-
- AttributeHeader::init(attrData++, c.m_id, c.m_size << 2);
- memcpy(attrData, data, 4*c.m_size);
- attrData += c.m_size;
- data += c.m_size;
- }
-
- if(c.m_flags & Column::COL_DISK)
- disk= true;
- }
-
- // second part is data driven
- while (data + 2 < dataStart + len) {
- Uint32 sz= ntohl(*data); data++;
- Uint32 id= ntohl(*data); data++; // column_no
-
- ndbrequire(columns.position(it, 2 * id));
-
- _align[0] = *it.data; ndbrequire(columns.next(it));
- _align[1] = *it.data;
-
- Uint32 sz32 = (sz + 3) >> 2;
- ndbassert(c.m_flags & (Column::COL_VAR | Column::COL_NULL));
- if (c.m_flags & Column::COL_KEY)
- {
- memcpy(keyData, data, 4 * sz32);
- keyData += sz32;
- }
-
- AttributeHeader::init(attrData++, c.m_id, sz);
- memcpy(attrData, data, sz);
-
- attrData += sz32;
- data += sz32;
- }
-
- ndbrequire(data == dataStart + len - 1);
-
- ndbrequire(disk == false); // Not supported...
- ndbrequire(rowid == true);
- Uint32 keyLen = keyData - key_start;
- Uint32 attrLen = attrData - attr_start;
- LqhKeyReq * req = (LqhKeyReq *)signal->getDataPtrSend();
-
- const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tableId);
- if (desc->noOfKeyAttr != desc->noOfVarKeys)
- {
- reorder_key(desc, key_start, keyLen);
- }
-
- Uint32 hashValue;
- if (g_key_descriptor_pool.getPtr(tableId)->hasCharAttr)
- hashValue = calulate_hash(tableId, key_start);
- else
- hashValue = md5_hash((Uint64*)key_start, keyLen);
-
- Uint32 tmp= 0;
- LqhKeyReq::setAttrLen(tmp, attrLen);
- req->attrLen = tmp;
-
- tmp= 0;
- LqhKeyReq::setKeyLen(tmp, keyLen);
- LqhKeyReq::setLastReplicaNo(tmp, 0);
- /* ---------------------------------------------------------------------- */
- // Indicate Application Reference is present in bit 15
- /* ---------------------------------------------------------------------- */
- LqhKeyReq::setApplicationAddressFlag(tmp, 0);
- LqhKeyReq::setDirtyFlag(tmp, 1);
- LqhKeyReq::setSimpleFlag(tmp, 1);
- LqhKeyReq::setOperation(tmp, ZINSERT);
- LqhKeyReq::setSameClientAndTcFlag(tmp, 0);
- LqhKeyReq::setAIInLqhKeyReq(tmp, 0);
- LqhKeyReq::setNoDiskFlag(tmp, disk ? 0 : 1);
- LqhKeyReq::setRowidFlag(tmp, 1);
- LqhKeyReq::setGCIFlag(tmp, gci);
- req->clientConnectPtr = file_ptr.i;
- req->hashValue = hashValue;
- req->requestInfo = tmp;
- req->tcBlockref = reference();
- req->savePointId = 0;
- req->tableSchemaVersion = file_ptr.p->m_table_id +
- (file_ptr.p->m_table_version << 16);
- req->fragmentData = file_ptr.p->m_fragment_id;
- req->transId1 = 0;
- req->transId2 = 0;
- req->scanInfo = 0;
- memcpy(req->variableData, key_start, 16);
- Uint32 pos = keyLen > 4 ? 4 : keyLen;
- req->variableData[pos++] = rowid_val.m_page_no;
- req->variableData[pos++] = rowid_val.m_page_idx;
- if (gci)
- req->variableData[pos++] = (Uint32)gci_val;
- file_ptr.p->m_outstanding_operations++;
- EXECUTE_DIRECT(DBLQH, GSN_LQHKEYREQ, signal,
- LqhKeyReq::FixedSignalLength+pos);
-
- if(keyLen > 4)
- {
- c_lqh->receive_keyinfo(signal,
- key_start + 4,
- keyLen - 4);
- }
-
- c_lqh->receive_attrinfo(signal, attr_start, attrLen);
-}
-
-void
-Restore::reorder_key(const KeyDescriptor* desc,
- Uint32 *data, Uint32 len)
-{
- Uint32 i;
- Uint32 *var= data;
- Uint32 Tmp[MAX_KEY_SIZE_IN_WORDS];
- for(i = 0; i<desc->noOfKeyAttr; i++)
- {
- Uint32 attr = desc->keyAttr[i].attributeDescriptor;
- switch(AttributeDescriptor::getArrayType(attr)){
- case NDB_ARRAYTYPE_FIXED:
- var += AttributeDescriptor::getSizeInWords(attr);
- }
- }
-
- Uint32 *dst = Tmp;
- Uint32 *src = data;
- for(i = 0; i<desc->noOfKeyAttr; i++)
- {
- Uint32 sz;
- Uint32 attr = desc->keyAttr[i].attributeDescriptor;
- switch(AttributeDescriptor::getArrayType(attr)){
- case NDB_ARRAYTYPE_FIXED:
- sz = AttributeDescriptor::getSizeInWords(attr);
- memcpy(dst, src, 4 * sz);
- src += sz;
- break;
- case NDB_ARRAYTYPE_SHORT_VAR:
- sz = (1 + ((char*)var)[0] + 3) >> 2;
- memcpy(dst, var, 4 * sz);
- var += sz;
- break;
- case NDB_ARRAYTYPE_MEDIUM_VAR:
- sz = (2 + ((char*)var)[0] + 256*((char*)var)[1] + 3) >> 2;
- memcpy(dst, var, 4 * sz);
- var += sz;
- break;
- default:
- ndbrequire(false);
- sz = 0;
- }
- dst += sz;
- }
- ndbassert((Uint32) (dst - Tmp) == len);
- memcpy(data, Tmp, 4*len);
-}
-
-Uint32
-Restore::calulate_hash(Uint32 tableId, const Uint32 *src)
-{
- jam();
- Uint64 Tmp[(MAX_KEY_SIZE_IN_WORDS*MAX_XFRM_MULTIPLY) >> 1];
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX];
- Uint32 keyLen = xfrm_key(tableId, src, (Uint32*)Tmp, sizeof(Tmp) >> 2,
- keyPartLen);
- ndbrequire(keyLen);
-
- return md5_hash(Tmp, keyLen);
-}
-
-void
-Restore::execLQHKEYREF(Signal* signal)
-{
- FilePtr file_ptr;
- LqhKeyRef* ref = (LqhKeyRef*)signal->getDataPtr();
- m_file_pool.getPtr(file_ptr, ref->connectPtr);
-
- char buf[255], name[100];
- BaseString::snprintf(name, sizeof(name), "%u/T%dF%d",
- file_ptr.p->m_lcp_no,
- file_ptr.p->m_table_id,
- file_ptr.p->m_fragment_id);
-
- BaseString::snprintf(buf, sizeof(buf),
- "Error %d during restore of %s",
- ref->errorCode, name);
-
- progError(__LINE__, NDBD_EXIT_INVALID_LCP_FILE, buf);
- ndbrequire(false);
-}
-
-void
-Restore::execLQHKEYCONF(Signal* signal)
-{
- FilePtr file_ptr;
- LqhKeyConf * conf = (LqhKeyConf *)signal->getDataPtr();
- m_file_pool.getPtr(file_ptr, conf->connectPtr);
-
- ndbassert(file_ptr.p->m_outstanding_operations);
- file_ptr.p->m_outstanding_operations--;
- file_ptr.p->m_rows_restored++;
- if(file_ptr.p->m_outstanding_operations == 0 && file_ptr.p->m_fd == RNIL)
- {
- RestoreLcpConf* rep= (RestoreLcpConf*)signal->getDataPtrSend();
- rep->senderData= file_ptr.p->m_sender_data;
- sendSignal(file_ptr.p->m_sender_ref,
- GSN_RESTORE_LCP_CONF, signal,
- RestoreLcpConf::SignalLength, JBB);
- release_file(file_ptr);
- }
-}
-
-void
-Restore::parse_fragment_footer(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
- const BackupFormat::DataFile::FragmentFooter* fh=
- (BackupFormat::DataFile::FragmentFooter*)data;
- if(ntohl(fh->TableId) != file_ptr.p->m_table_id)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->TableId));
- return;
- }
-
- if(ntohl(fh->Checksum) != 0)
- {
- parse_error(signal, file_ptr, __LINE__, ntohl(fh->SectionLength));
- return;
- }
-
- if(file_ptr.p->is_lcp())
- {
- /**
- * Temporary reset DBTUP's #disk attributes on table
- */
- c_tup->complete_restore_lcp(file_ptr.p->m_table_id,
- file_ptr.p->m_fragment_id);
- }
-
- file_ptr.p->m_fragment_id = RNIL;
-}
-
-void
-Restore::parse_gcp_entry(Signal* signal, FilePtr file_ptr,
- const Uint32 *data, Uint32 len)
-{
-
-}
-
-void
-Restore::parse_error(Signal* signal,
- FilePtr file_ptr, Uint32 line, Uint32 extra)
-{
- char buf[255], name[100];
- BaseString::snprintf(name, sizeof(name), "%u/T%dF%d",
- file_ptr.p->m_lcp_no,
- file_ptr.p->m_table_id,
- file_ptr.p->m_fragment_id);
-
- BaseString::snprintf(buf, sizeof(buf),
- "Parse error in file: %s, extra: %d",
- name, extra);
-
- progError(line, NDBD_EXIT_INVALID_LCP_FILE, buf);
- ndbrequire(false);
-}
-
-NdbOut&
-operator << (NdbOut& ndbout, const Restore::Column& col)
-{
- ndbout << "[ Col: id: " << col.m_id
- << " size: " << col.m_size
- << " key: " << (Uint32)(col.m_flags & Restore::Column::COL_KEY)
- << " variable: " << (Uint32)(col.m_flags & Restore::Column::COL_VAR)
- << " null: " << (Uint32)(col.m_flags & Restore::Column::COL_NULL)
- << " disk: " << (Uint32)(col.m_flags & Restore::Column::COL_DISK)
- << "]";
-
- return ndbout;
-}
-
-int
-Restore::check_file_version(Signal* signal, Uint32 file_version)
-{
- if (file_version < MAKE_VERSION(5,1,6))
- {
- char buf[255];
- char verbuf[255];
- ndbGetVersionString(file_version, 0, verbuf, sizeof(verbuf));
- BaseString::snprintf(buf, sizeof(buf),
- "Unsupported version of LCP files found on disk, "
- " found: %s", verbuf);
-
- progError(__LINE__,
- NDBD_EXIT_SR_RESTARTCONFLICT,
- buf);
- return -1;
- }
- return 0;
-}
diff --git a/storage/ndb/src/kernel/blocks/restore.hpp b/storage/ndb/src/kernel/blocks/restore.hpp
deleted file mode 100644
index eadb8712bd2..00000000000
--- a/storage/ndb/src/kernel/blocks/restore.hpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Restore_H
-#define Restore_H
-
-#include <SimulatedBlock.hpp>
-
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <KeyTable.hpp>
-#include <DLHashTable.hpp>
-#include <DataBuffer.hpp>
-#include <NodeBitmask.hpp>
-#include <backup/BackupFormat.hpp>
-
-class Restore : public SimulatedBlock
-{
-public:
- Restore(Block_context& ctx);
- virtual ~Restore();
- BLOCK_DEFINES(Restore);
-
-protected:
-
- void execSTTOR(Signal* signal);
- void sendSTTORRY(Signal*);
- void execREAD_CONFIG_REQ(Signal*);
- void execDUMP_STATE_ORD(Signal* signal);
- void execCONTINUEB(Signal* signal);
- void execRESTORE_LCP_REQ(Signal* signal);
-
- void execFSOPENREF(Signal*);
- void execFSOPENCONF(Signal*);
- void execFSREADREF(Signal*);
- void execFSREADCONF(Signal*);
- void execFSCLOSEREF(Signal*);
- void execFSCLOSECONF(Signal*);
-
- void execLQHKEYREF(Signal*);
- void execLQHKEYCONF(Signal*);
-
- typedef DataBuffer<15> List;
-
-public:
- struct Column
- {
- Uint16 m_id;
- Uint16 m_size;
- Uint16 m_unused;
- Uint16 m_flags;
-
- enum Flags
- {
- COL_KEY = 0x1,
- COL_VAR = 0x2,
- COL_DISK = 0x4,
- COL_NULL = 0x8
- };
- };
-private:
-
- struct File; // CC
- friend struct File;
-
- struct File
- {
- File() {}
- Uint32 m_sender_ref;
- Uint32 m_sender_data;
-
- Uint32 m_fd; // File pointer
- Uint32 m_file_type; // File type
- Uint32 m_status;
-
- enum StatusFlags
- {
- FILE_EOF = 1,
- FILE_THREAD_RUNNING = 2,
- RESTORE_THREAD_RUNNING = 4,
- FIRST_READ = 8,
- READING_RECORDS = 16
- };
-
- Uint32 m_table_id;
- Uint32 m_table_version;
- Uint32 m_fragment_id;
- List::Head m_columns;
-
- Uint32 m_current_page_ptr_i;
- Uint32 m_current_page_pos;
- Uint32 m_bytes_left; // Bytes read from FS
- Uint32 m_current_file_page; // Where in file
- Uint32 m_outstanding_reads; //
- Uint32 m_outstanding_operations;
- Uint64 m_rows_restored;
-
- Uint32 m_current_page_index; // Where in page list are we
- List::Head m_pages;
-
- Uint32 nextHash;
- Uint32 prevHash;
- Uint32 nextList;
- Uint32 prevList;
- Uint32 nextPool;
- Uint32 m_lcp_no;
-
- bool is_lcp() const { return m_file_type == BackupFormat::LCP_FILE;}
- };
- typedef Ptr<File> FilePtr;
-
- Uint32 init_file(const struct RestoreLcpReq*, FilePtr);
- void release_file(FilePtr);
-
- void open_file(Signal*, FilePtr);
- void read_file(Signal*, FilePtr);
- void restore_next(Signal*, FilePtr);
- void parse_file_header(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_table_list(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_table_description(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_fragment_header(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_record(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_fragment_footer(Signal*, FilePtr, const Uint32*, Uint32 len);
- void parse_gcp_entry(Signal*, FilePtr, const Uint32*, Uint32 len);
- void close_file(Signal*, FilePtr);
-
- void reorder_key(const struct KeyDescriptor*, Uint32* data, Uint32 len);
- Uint32 calulate_hash(Uint32 tableId, const Uint32 *src);
-
- void parse_error(Signal*, FilePtr, Uint32 line, Uint32 extra);
- int check_file_version(Signal*, Uint32 file_version);
-public:
-
-private:
- class Dblqh* c_lqh;
- class Dbtup* c_tup;
- DLList<File> m_file_list;
- KeyTable<File> m_file_hash;
- ArrayPool<File> m_file_pool;
-
- List::DataBufferPool m_databuffer_pool;
-};
-
-NdbOut& operator << (NdbOut&, const Restore::Column&);
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
deleted file mode 100644
index 40d0bb16406..00000000000
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ /dev/null
@@ -1,5202 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <my_config.h>
-#include "Suma.hpp"
-
-#include <ndb_version.h>
-
-#include <NdbTCP.h>
-#include <Bitmask.hpp>
-#include <SimpleProperties.hpp>
-
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/ReadNodesConf.hpp>
-
-#include <signaldata/ListTables.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/GetTableId.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <signaldata/ScanFrag.hpp>
-#include <signaldata/TransIdAI.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/AlterTrig.hpp>
-#include <signaldata/DropTrig.hpp>
-#include <signaldata/FireTrigOrd.hpp>
-#include <signaldata/TrigAttrInfo.hpp>
-#include <signaldata/CheckNodeGroups.hpp>
-#include <signaldata/GCPSave.hpp>
-#include <signaldata/CreateTab.hpp>
-#include <signaldata/DropTab.hpp>
-#include <signaldata/AlterTable.hpp>
-#include <signaldata/AlterTab.hpp>
-#include <signaldata/DihFragCount.hpp>
-#include <signaldata/SystemError.hpp>
-
-#include <ndbapi/NdbDictionary.hpp>
-
-#include <DebuggerNames.hpp>
-#include <../dbtup/Dbtup.hpp>
-#include <../dbdih/Dbdih.hpp>
-
-//#define HANDOVER_DEBUG
-//#define NODEFAIL_DEBUG
-//#define NODEFAIL_DEBUG2
-//#define DEBUG_SUMA_SEQUENCE
-//#define EVENT_DEBUG
-//#define EVENT_PH3_DEBUG
-//#define EVENT_DEBUG2
-#if 0
-#undef DBUG_ENTER
-#undef DBUG_PRINT
-#undef DBUG_RETURN
-#undef DBUG_VOID_RETURN
-
-#define DBUG_ENTER(a) {ndbout_c("%s:%d >%s", __FILE__, __LINE__, a);}
-#define DBUG_PRINT(a,b) {ndbout << __FILE__ << ":" << __LINE__ << " " << a << ": "; ndbout_c b ;}
-#define DBUG_RETURN(a) { ndbout_c("%s:%d <", __FILE__, __LINE__); return(a); }
-#define DBUG_VOID_RETURN { ndbout_c("%s:%d <", __FILE__, __LINE__); return; }
-#endif
-
-/**
- * @todo:
- * SUMA crashes if an index is created at the same time as
- * global replication. Very easy to reproduce using testIndex.
- * Note: This only happens occasionally, but is quite easy to reprod.
- */
-
-Uint32 g_subPtrI = RNIL;
-static const Uint32 SUMA_SEQUENCE = 0xBABEBABE;
-
-static const Uint32 MAX_CONCURRENT_GCP = 2;
-
-/**************************************************************
- *
- * Start of suma
- *
- */
-
-#define PRINT_ONLY 0
-
-void
-Suma::getNodeGroupMembers(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::getNodeGroupMembers");
- /**
- * Ask DIH for nodeGroupMembers
- */
- CheckNodeGroups * sd = (CheckNodeGroups*)signal->getDataPtrSend();
- sd->blockRef = reference();
- sd->requestType =
- CheckNodeGroups::Direct |
- CheckNodeGroups::GetNodeGroupMembers;
- sd->nodeId = getOwnNodeId();
- EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal,
- CheckNodeGroups::SignalLength);
- jamEntry();
-
- c_nodeGroup = sd->output;
- c_nodes_in_nodegroup_mask.assign(sd->mask);
- c_noNodesInGroup = c_nodes_in_nodegroup_mask.count();
- Uint32 i, pos= 0;
-
- for (i = 0; i < MAX_NDB_NODES; i++) {
- if (sd->mask.get(i))
- {
- c_nodesInGroup[pos++] = i;
- }
- }
-
- const Uint32 replicas= c_noNodesInGroup;
-
- Uint32 buckets= 1;
- for(i = 1; i <= replicas; i++)
- buckets *= i;
-
- for(i = 0; i<buckets; i++)
- {
- Bucket* ptr= c_buckets+i;
- for(Uint32 j= 0; j< replicas; j++)
- {
- ptr->m_nodes[j] = c_nodesInGroup[(i + j) % replicas];
- }
- }
-
- c_no_of_buckets= buckets;
- ndbrequire(c_noNodesInGroup > 0); // at least 1 node in the nodegroup
-
-#ifndef DBUG_OFF
- for (Uint32 i = 0; i < c_noNodesInGroup; i++) {
- DBUG_PRINT("exit",("Suma: NodeGroup %u, me %u, "
- "member[%u] %u",
- c_nodeGroup, getOwnNodeId(),
- i, c_nodesInGroup[i]));
- }
-#endif
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- // SumaParticipant
- Uint32 noTables, noAttrs;
- ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES,
- &noTables);
- ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES,
- &noAttrs);
-
- c_tablePool.setSize(noTables);
- c_tables.setSize(noTables);
-
- c_subscriptions.setSize(noTables);
- c_subscriberPool.setSize(2*noTables);
-
- c_subscriptionPool.setSize(noTables);
- c_syncPool.setSize(2);
- c_dataBufferPool.setSize(noAttrs);
-
- // Calculate needed gcp pool as 10 records + the ones needed
- // during a possible api timeout
- Uint32 dbApiHbInterval, gcpInterval;
- ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL,
- &dbApiHbInterval);
- ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL,
- &gcpInterval);
- c_gcp_pool.setSize(10 + (4*dbApiHbInterval)/gcpInterval);
-
- c_page_chunk_pool.setSize(50);
-
- {
- SLList<SyncRecord> tmp(c_syncPool);
- Ptr<SyncRecord> ptr;
- while(tmp.seize(ptr))
- new (ptr.p) SyncRecord(* this, c_dataBufferPool);
- tmp.release();
- }
-
- // Suma
- c_masterNodeId = getOwnNodeId();
-
- c_nodeGroup = c_noNodesInGroup = 0;
- for (int i = 0; i < MAX_REPLICAS; i++) {
- c_nodesInGroup[i] = 0;
- }
-
- m_first_free_page= RNIL;
-
- c_no_of_buckets = 0;
- memset(c_buckets, 0, sizeof(c_buckets));
- for(Uint32 i = 0; i<NO_OF_BUCKETS; i++)
- {
- Bucket* bucket= c_buckets+i;
- bucket->m_buffer_tail = RNIL;
- bucket->m_buffer_head.m_page_id = RNIL;
- bucket->m_buffer_head.m_page_pos = Buffer_page::DATA_WORDS;
- }
-
- m_max_seen_gci = 0; // FIRE_TRIG_ORD
- m_max_sent_gci = 0; // FIRE_TRIG_ORD -> send
- m_last_complete_gci = 0; // SUB_GCP_COMPLETE_REP
- m_gcp_complete_rep_count = 0;
- m_out_of_buffer_gci = 0;
-
- c_startup.m_wait_handover= false;
- c_failedApiNodes.clear();
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-Suma::execSTTOR(Signal* signal) {
- jamEntry();
-
- DBUG_ENTER("Suma::execSTTOR");
- const Uint32 startphase = signal->theData[1];
- const Uint32 typeOfStart = signal->theData[7];
-
- DBUG_PRINT("info",("startphase = %u, typeOfStart = %u",
- startphase, typeOfStart));
-
- if(startphase == 3)
- {
- jam();
- ndbrequire((m_tup = (Dbtup*)globalData.getBlock(DBTUP)) != 0);
- signal->theData[0] = reference();
- sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
- DBUG_VOID_RETURN;
- }
-
- if(startphase == 5)
- {
- if (ERROR_INSERTED(13029)) /* Hold startphase 5 */
- {
- sendSignalWithDelay(SUMA_REF, GSN_STTOR, signal,
- 30, signal->getLength());
- DBUG_VOID_RETURN;
- }
-
- c_startup.m_restart_server_node_id = 0;
- getNodeGroupMembers(signal);
- if (typeOfStart == NodeState::ST_NODE_RESTART ||
- typeOfStart == NodeState::ST_INITIAL_NODE_RESTART)
- {
- jam();
-
- send_start_me_req(signal);
- DBUG_VOID_RETURN;
- }
- }
-
- if(startphase == 7)
- {
- if (typeOfStart != NodeState::ST_NODE_RESTART &&
- typeOfStart != NodeState::ST_INITIAL_NODE_RESTART)
- {
- for( Uint32 i = 0; i < c_no_of_buckets; i++)
- {
- if (get_responsible_node(i) == getOwnNodeId())
- {
- // I'm running this bucket
- DBUG_PRINT("info",("bucket %u set to true", i));
- m_active_buckets.set(i);
- ndbout_c("m_active_buckets.set(%d)", i);
- }
- }
- }
-
- if(!m_active_buckets.isclear())
- {
- NdbNodeBitmask tmp;
- Uint32 bucket = 0;
- while ((bucket = m_active_buckets.find(bucket)) != Bucket_mask::NotFound)
- {
- tmp.set(get_responsible_node(bucket, c_nodes_in_nodegroup_mask));
- bucket++;
- }
-
- ndbassert(tmp.get(getOwnNodeId()));
- m_gcp_complete_rep_count = tmp.count();// I contribute 1 gcp complete rep
- }
- else
- m_gcp_complete_rep_count = 0; // I contribute 1 gcp complete rep
-
- if(typeOfStart == NodeState::ST_INITIAL_START &&
- c_masterNodeId == getOwnNodeId())
- {
- jam();
- createSequence(signal);
- DBUG_VOID_RETURN;
- }//if
-
- if (ERROR_INSERTED(13030))
- {
- ndbout_c("Dont start handover");
- DBUG_VOID_RETURN;
- }
- }//if
-
- if(startphase == 100)
- {
- /**
- * Allow API's to connect
- */
- sendSTTORRY(signal);
- DBUG_VOID_RETURN;
- }
-
- if(startphase == 101)
- {
- if (typeOfStart == NodeState::ST_NODE_RESTART ||
- typeOfStart == NodeState::ST_INITIAL_NODE_RESTART)
- {
- /**
- * Handover code here
- */
- c_startup.m_wait_handover= true;
- check_start_handover(signal);
- DBUG_VOID_RETURN;
- }
- }
- sendSTTORRY(signal);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::send_start_me_req(Signal* signal)
-{
- Uint32 nodeId= c_startup.m_restart_server_node_id;
- do {
- nodeId = c_alive_nodes.find(nodeId + 1);
-
- if(nodeId == getOwnNodeId())
- continue;
- if(nodeId == NdbNodeBitmask::NotFound)
- {
- nodeId = 0;
- continue;
- }
- break;
- } while(true);
-
-
- infoEvent("Suma: asking node %d to recreate subscriptions on me", nodeId);
- c_startup.m_restart_server_node_id= nodeId;
- sendSignal(calcSumaBlockRef(nodeId),
- GSN_SUMA_START_ME_REQ, signal, 1, JBB);
-}
-
-void
-Suma::execSUMA_START_ME_REF(Signal* signal)
-{
- const SumaStartMeRef* ref= (SumaStartMeRef*)signal->getDataPtr();
- ndbrequire(ref->errorCode == SumaStartMeRef::Busy);
-
- infoEvent("Suma: node %d refused %d",
- c_startup.m_restart_server_node_id, ref->errorCode);
-
- c_startup.m_restart_server_node_id++;
- send_start_me_req(signal);
-}
-
-void
-Suma::execSUMA_START_ME_CONF(Signal* signal)
-{
- infoEvent("Suma: node %d has completed restoring me",
- c_startup.m_restart_server_node_id);
- sendSTTORRY(signal);
- c_startup.m_restart_server_node_id= 0;
-}
-
-void
-Suma::createSequence(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::createSequence");
-
- UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
-
- req->senderData = RNIL;
- req->sequenceId = SUMA_SEQUENCE;
- req->requestType = UtilSequenceReq::Create;
- sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
- signal, UtilSequenceReq::SignalLength, JBB);
- // execUTIL_SEQUENCE_CONF will call createSequenceReply()
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::createSequenceReply(Signal* signal,
- UtilSequenceConf * conf,
- UtilSequenceRef * ref)
-{
- jam();
-
- if (ref != NULL)
- {
- switch ((UtilSequenceRef::ErrorCode)ref->errorCode)
- {
- case UtilSequenceRef::NoSuchSequence:
- ndbrequire(false);
- case UtilSequenceRef::TCError:
- {
- char buf[128];
- snprintf(buf, sizeof(buf),
- "Startup failed during sequence creation. TC error %d",
- ref->TCErrorCode);
- progError(__LINE__, NDBD_EXIT_RESOURCE_ALLOC_ERROR, buf);
- }
- }
- ndbrequire(false);
- }
-
- sendSTTORRY(signal);
-}
-
-void
-Suma::execREAD_NODESCONF(Signal* signal){
- jamEntry();
- ReadNodesConf * const conf = (ReadNodesConf *)signal->getDataPtr();
-
- if(getNodeState().getNodeRestartInProgress())
- {
- c_alive_nodes.assign(NdbNodeBitmask::Size, conf->startedNodes);
- c_alive_nodes.set(getOwnNodeId());
- }
- else
- {
- c_alive_nodes.assign(NdbNodeBitmask::Size, conf->startingNodes);
- NdbNodeBitmask tmp;
- tmp.assign(NdbNodeBitmask::Size, conf->startedNodes);
- ndbrequire(tmp.isclear()); // No nodes can be started during SR
- }
-
- c_masterNodeId = conf->masterNodeId;
-
- sendSTTORRY(signal);
-}
-
-void
-Suma::execAPI_START_REP(Signal* signal)
-{
- Uint32 nodeId = signal->theData[0];
- c_connected_nodes.set(nodeId);
-
- check_start_handover(signal);
-}
-
-void
-Suma::check_start_handover(Signal* signal)
-{
- if(c_startup.m_wait_handover)
- {
- NodeBitmask tmp;
- tmp.assign(c_connected_nodes);
- tmp.bitAND(c_subscriber_nodes);
- if(!c_subscriber_nodes.equal(tmp))
- {
- return;
- }
-
- c_startup.m_wait_handover= false;
- send_handover_req(signal);
- }
-}
-
-void
-Suma::send_handover_req(Signal* signal)
-{
- c_startup.m_handover_nodes.assign(c_alive_nodes);
- c_startup.m_handover_nodes.bitAND(c_nodes_in_nodegroup_mask);
- c_startup.m_handover_nodes.clear(getOwnNodeId());
- Uint32 gci= m_last_complete_gci + 3;
-
- SumaHandoverReq* req= (SumaHandoverReq*)signal->getDataPtrSend();
- char buf[255];
- c_startup.m_handover_nodes.getText(buf);
- infoEvent("Suma: initiate handover with nodes %s GCI: %d",
- buf, gci);
-
- req->gci = gci;
- req->nodeId = getOwnNodeId();
-
- NodeReceiverGroup rg(SUMA, c_startup.m_handover_nodes);
- sendSignal(rg, GSN_SUMA_HANDOVER_REQ, signal,
- SumaHandoverReq::SignalLength, JBB);
-}
-
-void
-Suma::sendSTTORRY(Signal* signal){
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 3;
- signal->theData[5] = 5;
- signal->theData[6] = 7;
- signal->theData[7] = 100;
- signal->theData[8] = 101;
- signal->theData[9] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 10, JBB);
-}
-
-void
-Suma::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
-}
-
-void
-Suma::execCONTINUEB(Signal* signal){
- jamEntry();
- Uint32 type= signal->theData[0];
- switch(type){
- case SumaContinueB::RELEASE_GCI:
- release_gci(signal, signal->theData[1], signal->theData[2]);
- return;
- case SumaContinueB::RESEND_BUCKET:
- resend_bucket(signal,
- signal->theData[1],
- signal->theData[2],
- signal->theData[3],
- signal->theData[4]);
- return;
- case SumaContinueB::OUT_OF_BUFFER_RELEASE:
- out_of_buffer_release(signal, signal->theData[1]);
- return;
- }
-}
-
-/*****************************************************************************
- *
- * Node state handling
- *
- *****************************************************************************/
-
-void Suma::execAPI_FAILREQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execAPI_FAILREQ");
- Uint32 failedApiNode = signal->theData[0];
- //BlockReference retRef = signal->theData[1];
-
- if (c_startup.m_restart_server_node_id &&
- c_startup.m_restart_server_node_id != RNIL)
- {
- jam();
- sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal,
- 200, signal->getLength());
- DBUG_VOID_RETURN;
- }
-
- if (c_failedApiNodes.get(failedApiNode))
- {
- jam();
- DBUG_VOID_RETURN;
- }
-
- if (!c_subscriber_nodes.get(failedApiNode))
- {
- jam();
- DBUG_VOID_RETURN;
- }
-
- c_failedApiNodes.set(failedApiNode);
- c_connected_nodes.clear(failedApiNode);
- bool found = removeSubscribersOnNode(signal, failedApiNode);
-
- if(!found){
- jam();
- c_failedApiNodes.clear(failedApiNode);
- }
-
- SubGcpCompleteAck * const ack = (SubGcpCompleteAck*)signal->getDataPtr();
- Ptr<Gcp_record> gcp;
- for(c_gcp_list.first(gcp); !gcp.isNull(); c_gcp_list.next(gcp))
- {
- jam();
- ack->rep.gci = gcp.p->m_gci;
- if(gcp.p->m_subscribers.get(failedApiNode))
- {
- jam();
- gcp.p->m_subscribers.clear(failedApiNode);
- ack->rep.senderRef = numberToRef(0, failedApiNode);
- sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_ACK, signal,
- SubGcpCompleteAck::SignalLength, JBB);
- }
- }
-
- c_subscriber_nodes.clear(failedApiNode);
-
- check_start_handover(signal);
-
- DBUG_VOID_RETURN;
-}//execAPI_FAILREQ()
-
-bool
-Suma::removeSubscribersOnNode(Signal *signal, Uint32 nodeId)
-{
- DBUG_ENTER("Suma::removeSubscribersOnNode");
- bool found = false;
-
- KeyTable<Table>::Iterator it;
- LINT_INIT(it.bucket);
- LINT_INIT(it.curr.p);
- for(c_tables.first(it);!it.isNull();c_tables.next(it))
- {
- LocalDLList<Subscriber> subbs(c_subscriberPool,it.curr.p->c_subscribers);
- SubscriberPtr i_subbPtr;
- for(subbs.first(i_subbPtr);!i_subbPtr.isNull();)
- {
- SubscriberPtr subbPtr = i_subbPtr;
- subbs.next(i_subbPtr);
- jam();
- if (refToNode(subbPtr.p->m_senderRef) == nodeId) {
- jam();
- subbs.remove(subbPtr);
- c_removeDataSubscribers.add(subbPtr);
- found = true;
- }
- }
- if (subbs.isEmpty())
- {
- // ToDo handle this
- }
- }
- if(found){
- jam();
- sendSubStopReq(signal);
- }
- DBUG_RETURN(found);
-}
-
-void
-Suma::sendSubStopReq(Signal *signal, bool unlock){
- static bool remove_lock = false;
- jam();
- DBUG_ENTER("Suma::sendSubStopReq");
-
- SubscriberPtr subbPtr;
- c_removeDataSubscribers.first(subbPtr);
- if (subbPtr.isNull()){
- jam();
-#if 0
- signal->theData[0] = failedApiNode;
- signal->theData[1] = reference();
- sendSignal(retRef, GSN_API_FAILCONF, signal, 2, JBB);
-#endif
- c_failedApiNodes.clear();
-
- remove_lock = false;
- DBUG_VOID_RETURN;
- }
-
- if(remove_lock && !unlock) {
- jam();
- DBUG_VOID_RETURN;
- }
- remove_lock = true;
-
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
-
- SubStopReq * const req = (SubStopReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = subbPtr.i;
- req->subscriberRef = subbPtr.p->m_senderRef;
- req->subscriberData = subbPtr.p->m_senderData;
- req->subscriptionId = subPtr.p->m_subscriptionId;
- req->subscriptionKey = subPtr.p->m_subscriptionKey;
- req->part = SubscriptionData::TableData;
-
- sendSignal(SUMA_REF,GSN_SUB_STOP_REQ,signal,SubStopReq::SignalLength,JBB);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_STOP_CONF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execSUB_STOP_CONF");
- ndbassert(signal->getNoOfSections() == 0);
- sendSubStopReq(signal,true);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_STOP_REF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execSUB_STOP_REF");
- ndbassert(signal->getNoOfSections() == 0);
-
- SubStopRef * const ref = (SubStopRef*)signal->getDataPtr();
-
- Uint32 senderData = ref->senderData;
- Uint32 subscriptionId = ref->subscriptionId;
- Uint32 subscriptionKey = ref->subscriptionKey;
- Uint32 part = ref->part;
- Uint32 subscriberData = ref->subscriberData;
- Uint32 subscriberRef = ref->subscriberRef;
-
- if(ref->errorCode != 1411){
- ndbrequire(false);
- }
-
- SubStopReq * const req = (SubStopReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- req->subscriberRef = subscriberRef;
- req->subscriberData = subscriberData;
- req->subscriptionId = subscriptionId;
- req->subscriptionKey = subscriptionKey;
- req->part = part;
-
- sendSignal(SUMA_REF,GSN_SUB_STOP_REQ,signal,SubStopReq::SignalLength,JBB);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execNODE_FAILREP(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execNODE_FAILREP");
- ndbassert(signal->getNoOfSections() == 0);
-
- const NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
- NdbNodeBitmask failed; failed.assign(NdbNodeBitmask::Size, rep->theNodes);
-
- if(failed.get(Restart.nodeId))
- {
- Restart.resetRestart(signal);
- }
-
- if (ERROR_INSERTED(13032))
- {
- Uint32 node = c_subscriber_nodes.find(0);
- if (node != NodeBitmask::NotFound)
- {
- ndbout_c("Inserting API_FAILREQ node: %u", node);
- signal->theData[0] = node;
- EXECUTE_DIRECT(QMGR, GSN_API_FAILREQ, signal, 1);
- }
- }
-
- signal->theData[0] = SumaContinueB::RESEND_BUCKET;
-
- NdbNodeBitmask tmp;
- tmp.assign(c_alive_nodes);
- tmp.bitANDC(failed);
-
- NdbNodeBitmask takeover_nodes;
-
- if(c_nodes_in_nodegroup_mask.overlaps(failed))
- {
- for( Uint32 i = 0; i < c_no_of_buckets; i++)
- {
- if(m_active_buckets.get(i))
- continue;
- else if(m_switchover_buckets.get(i))
- {
- Uint32 state= c_buckets[i].m_state;
- if((state & Bucket::BUCKET_HANDOVER) &&
- failed.get(get_responsible_node(i)))
- {
- m_active_buckets.set(i);
- m_switchover_buckets.clear(i);
- ndbout_c("aborting handover");
- }
- else if(state & Bucket::BUCKET_STARTING)
- {
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR,
- "Nodefailure during SUMA takeover");
- }
- }
- else if(get_responsible_node(i, tmp) == getOwnNodeId())
- {
- start_resend(signal, i);
- }
- }
- }
-
- c_alive_nodes.assign(tmp);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execINCL_NODEREQ(Signal* signal){
- jamEntry();
-
- const Uint32 senderRef = signal->theData[0];
- const Uint32 nodeId = signal->theData[1];
-
- ndbrequire(!c_alive_nodes.get(nodeId));
- c_alive_nodes.set(nodeId);
-
- signal->theData[0] = nodeId;
- signal->theData[1] = reference();
- sendSignal(senderRef, GSN_INCL_NODECONF, signal, 2, JBB);
-}
-
-void
-Suma::execSIGNAL_DROPPED_REP(Signal* signal){
- jamEntry();
- ndbrequire(false);
-}
-
-/********************************************************************
- *
- * Dump state
- *
- */
-
-static unsigned
-count_subscribers(const DLList<Suma::Subscriber> &subs)
-{
- unsigned n= 0;
- Suma::SubscriberPtr i_subbPtr;
- subs.first(i_subbPtr);
- while(!i_subbPtr.isNull()){
- n++;
- subs.next(i_subbPtr);
- }
- return n;
-}
-
-void
-Suma::execDUMP_STATE_ORD(Signal* signal){
- jamEntry();
-
- Uint32 tCase = signal->theData[0];
-#if 0
- if(tCase >= 8000 && tCase <= 8003){
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, g_subPtrI);
-
- Ptr<SyncRecord> syncPtr;
- c_syncPool.getPtr(syncPtr, subPtr.p->m_syncPtrI);
-
- if(tCase == 8000){
- syncPtr.p->startMeta(signal);
- }
-
- if(tCase == 8001){
- syncPtr.p->startScan(signal);
- }
-
- if(tCase == 8002){
- syncPtr.p->startTrigger(signal);
- }
-
- if(tCase == 8003){
- subPtr.p->m_subscriptionType = SubCreateReq::SingleTableScan;
- LocalDataBuffer<15> attrs(c_dataBufferPool, syncPtr.p->m_attributeList);
- Uint32 tab = 0;
- Uint32 att[] = { 0, 1, 1 };
- syncPtr.p->m_tableList.append(&tab, 1);
- attrs.append(att, 3);
- }
- }
-#endif
- if(tCase == 8004){
- infoEvent("Suma: c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree());
-
- infoEvent("Suma: c_tablePool size: %d free: %d",
- c_tablePool.getSize(),
- c_tablePool.getNoOfFree());
-
- infoEvent("Suma: c_subscriptionPool size: %d free: %d",
- c_subscriptionPool.getSize(),
- c_subscriptionPool.getNoOfFree());
-
- infoEvent("Suma: c_syncPool size: %d free: %d",
- c_syncPool.getSize(),
- c_syncPool.getNoOfFree());
-
- infoEvent("Suma: c_dataBufferPool size: %d free: %d",
- c_dataBufferPool.getSize(),
- c_dataBufferPool.getNoOfFree());
-
- infoEvent("Suma: c_metaSubscribers count: %d",
- count_subscribers(c_metaSubscribers));
-#if 0
- infoEvent("Suma: c_dataSubscribers count: %d",
- count_subscribers(c_dataSubscribers));
- infoEvent("Suma: c_prepDataSubscribers count: %d",
- count_subscribers(c_prepDataSubscribers));
-#endif
- infoEvent("Suma: c_removeDataSubscribers count: %d",
- count_subscribers(c_removeDataSubscribers));
- }
-
- if(tCase == 8005)
- {
- for(Uint32 i = 0; i<c_no_of_buckets; i++)
- {
- Bucket* ptr= c_buckets + i;
- infoEvent("Bucket %d %d%d-%x switch gci: %d max_acked_gci: %d max_gci: %d tail: %d head: %d",
- i,
- m_active_buckets.get(i),
- m_switchover_buckets.get(i),
- ptr->m_state,
- ptr->m_switchover_gci,
- ptr->m_max_acked_gci,
- ptr->m_buffer_head.m_max_gci,
- ptr->m_buffer_tail,
- ptr->m_buffer_head.m_page_id);
- }
- }
-
- if (tCase == 8006)
- {
- SET_ERROR_INSERT_VALUE(13029);
- }
-
- if (tCase == 8007)
- {
- c_startup.m_restart_server_node_id = MAX_NDB_NODES + 1;
- SET_ERROR_INSERT_VALUE(13029);
- }
-
- if (tCase == 8008)
- {
- CLEAR_ERROR_INSERT_VALUE;
- }
-
- if (tCase == 8010)
- {
- char buf1[255], buf2[255];
- c_subscriber_nodes.getText(buf1);
- c_connected_nodes.getText(buf2);
- infoEvent("c_subscriber_nodes: %s", buf1);
- infoEvent("c_connected_nodes: %s", buf2);
- }
-
- if (tCase == 8009)
- {
- if (ERROR_INSERTED(13030))
- {
- CLEAR_ERROR_INSERT_VALUE;
- sendSTTORRY(signal);
- }
- else
- {
- SET_ERROR_INSERT_VALUE(13030);
- }
- return;
- }
-
- if (tCase == 8011)
- {
- jam();
- Uint32 bucket = signal->theData[1];
- KeyTable<Table>::Iterator it;
- if (signal->getLength() == 1)
- {
- jam();
- bucket = 0;
- infoEvent("-- Starting dump of subscribers --");
- }
-
- c_tables.next(bucket, it);
- const Uint32 RT_BREAK = 16;
- for(Uint32 i = 0; i<RT_BREAK || it.bucket == bucket; i++)
- {
- jam();
- if(it.curr.i == RNIL)
- {
- jam();
- infoEvent("-- Ending dump of subscribers --");
- return;
- }
-
- infoEvent("Table: %u ver: %u #n: %u (ref,data,subscritopn)",
- it.curr.p->m_tableId,
- it.curr.p->m_schemaVersion,
- it.curr.p->n_subscribers);
-
- Ptr<Subscriber> ptr;
- LocalDLList<Subscriber> list(c_subscriberPool, it.curr.p->c_subscribers);
- for (list.first(ptr); !ptr.isNull(); list.next(ptr), i++)
- {
- jam();
- infoEvent(" [ %x %u %u ]",
- ptr.p->m_senderRef,
- ptr.p->m_senderData,
- ptr.p->m_subPtrI);
- }
- c_tables.next(it);
- }
-
- signal->theData[0] = tCase;
- signal->theData[1] = it.bucket;
- sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 100, 2);
- return;
- }
-}
-
-/*************************************************************
- *
- * Creation of subscription id's
- *
- ************************************************************/
-
-void
-Suma::execCREATE_SUBID_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execCREATE_SUBID_REQ");
- ndbassert(signal->getNoOfSections() == 0);
- CRASH_INSERTION(13001);
-
- CreateSubscriptionIdReq const * req =
- (CreateSubscriptionIdReq*)signal->getDataPtr();
- SubscriberPtr subbPtr;
- if(!c_subscriberPool.seize(subbPtr)){
- jam();
- sendSubIdRef(signal, req->senderRef, req->senderData, 1412);
- DBUG_VOID_RETURN;
- }
- DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree()));
-
- subbPtr.p->m_senderRef = req->senderRef;
- subbPtr.p->m_senderData = req->senderData;
-
- UtilSequenceReq * utilReq = (UtilSequenceReq*)signal->getDataPtrSend();
- utilReq->senderData = subbPtr.i;
- utilReq->sequenceId = SUMA_SEQUENCE;
- utilReq->requestType = UtilSequenceReq::NextVal;
- sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
- signal, UtilSequenceReq::SignalLength, JBB);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execUTIL_SEQUENCE_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execUTIL_SEQUENCE_CONF");
- ndbassert(signal->getNoOfSections() == 0);
- CRASH_INSERTION(13002);
-
- UtilSequenceConf * conf = (UtilSequenceConf*)signal->getDataPtr();
- if(conf->requestType == UtilSequenceReq::Create) {
- jam();
- createSequenceReply(signal, conf, NULL);
- DBUG_VOID_RETURN;
- }
-
- Uint64 subId;
- memcpy(&subId,conf->sequenceValue,8);
- SubscriberPtr subbPtr;
- c_subscriberPool.getPtr(subbPtr,conf->senderData);
-
- CreateSubscriptionIdConf * subconf = (CreateSubscriptionIdConf*)conf;
- subconf->senderRef = reference();
- subconf->senderData = subbPtr.p->m_senderData;
- subconf->subscriptionId = (Uint32)subId;
- subconf->subscriptionKey =(getOwnNodeId() << 16) | (Uint32)(subId & 0xFFFF);
-
- sendSignal(subbPtr.p->m_senderRef, GSN_CREATE_SUBID_CONF, signal,
- CreateSubscriptionIdConf::SignalLength, JBB);
-
- c_subscriberPool.release(subbPtr);
- DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree()));
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execUTIL_SEQUENCE_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execUTIL_SEQUENCE_REF");
- ndbassert(signal->getNoOfSections() == 0);
- UtilSequenceRef * ref = (UtilSequenceRef*)signal->getDataPtr();
- Uint32 err= ref->errorCode;
-
- if(ref->requestType == UtilSequenceReq::Create) {
- jam();
- createSequenceReply(signal, NULL, ref);
- DBUG_VOID_RETURN;
- }
-
- Uint32 subData = ref->senderData;
-
- SubscriberPtr subbPtr;
- c_subscriberPool.getPtr(subbPtr,subData);
- sendSubIdRef(signal, subbPtr.p->m_senderRef, subbPtr.p->m_senderData, err);
- c_subscriberPool.release(subbPtr);
- DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree()));
- DBUG_VOID_RETURN;
-}//execUTIL_SEQUENCE_REF()
-
-
-void
-Suma::sendSubIdRef(Signal* signal,
- Uint32 senderRef, Uint32 senderData, Uint32 errCode)
-{
- jam();
- DBUG_ENTER("Suma::sendSubIdRef");
- CreateSubscriptionIdRef * ref =
- (CreateSubscriptionIdRef *)signal->getDataPtrSend();
-
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->errorCode = errCode;
- sendSignal(senderRef,
- GSN_CREATE_SUBID_REF,
- signal,
- CreateSubscriptionIdRef::SignalLength,
- JBB);
-
- releaseSections(signal);
- DBUG_VOID_RETURN;
-}
-
-/**********************************************************
- * Suma participant interface
- *
- * Creation of subscriptions
- */
-
-void
-Suma::addTableId(Uint32 tableId,
- SubscriptionPtr subPtr, SyncRecord *psyncRec)
-{
- DBUG_ENTER("Suma::addTableId");
- DBUG_PRINT("enter",("tableId: %u subPtr.i: %u", tableId, subPtr.i));
- subPtr.p->m_tableId= tableId;
- if(psyncRec != NULL)
- psyncRec->m_tableList.append(&tableId, 1);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_CREATE_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUB_CREATE_REQ");
- ndbassert(signal->getNoOfSections() == 0);
- CRASH_INSERTION(13003);
-
- const SubCreateReq req = *(SubCreateReq*)signal->getDataPtr();
-
- const Uint32 subRef = req.senderRef;
- const Uint32 subData = req.senderData;
- const Uint32 subId = req.subscriptionId;
- const Uint32 subKey = req.subscriptionKey;
- const Uint32 type = req.subscriptionType & SubCreateReq::RemoveFlags;
- const Uint32 flags = req.subscriptionType & SubCreateReq::GetFlags;
- const bool addTableFlag = (flags & SubCreateReq::AddTableFlag) != 0;
- const bool restartFlag = (flags & SubCreateReq::RestartFlag) != 0;
- const Uint32 reportAll = (flags & SubCreateReq::ReportAll) ?
- Subscription::REPORT_ALL : 0;
- const Uint32 reportSubscribe = (flags & SubCreateReq::ReportSubscribe) ?
- Subscription::REPORT_SUBSCRIBE : 0;
- const Uint32 tableId = req.tableId;
- Subscription::State state = (Subscription::State) req.state;
- if (signal->getLength() != SubCreateReq::SignalLength2)
- {
- /*
- api or restarted by older version
- if restarted by old version, do the best we can
- */
- state = Subscription::DEFINED;
- }
-
- Subscription key;
- key.m_subscriptionId = subId;
- key.m_subscriptionKey = subKey;
-
- DBUG_PRINT("enter",("key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
- key.m_subscriptionId, key.m_subscriptionKey));
-
- SubscriptionPtr subPtr;
-
- if (addTableFlag) {
- ndbrequire(restartFlag); //TODO remove this
-
- if(!c_subscriptions.find(subPtr, key)) {
- jam();
- sendSubCreateRef(signal, 1407);
- DBUG_VOID_RETURN;
- }
- jam();
- if (restartFlag)
- {
- ndbrequire(type != SubCreateReq::SingleTableScan);
- ndbrequire(req.tableId != subPtr.p->m_tableId);
- ndbrequire(type != SubCreateReq::TableEvent);
- addTableId(req.tableId, subPtr, 0);
- }
- } else {
- if (c_startup.m_restart_server_node_id &&
- subRef != calcSumaBlockRef(c_startup.m_restart_server_node_id))
- {
- /**
- * only allow "restart_server" Suma's to come through
- * for restart purposes
- */
- jam();
- sendSubCreateRef(signal, 1415);
- DBUG_VOID_RETURN;
- }
- // Check that id/key is unique
- if(c_subscriptions.find(subPtr, key)) {
- jam();
- sendSubCreateRef(signal, 1415);
- DBUG_VOID_RETURN;
- }
- if(!c_subscriptions.seize(subPtr)) {
- jam();
- sendSubCreateRef(signal, 1412);
- DBUG_VOID_RETURN;
- }
- DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d",
- c_subscriptionPool.getSize(),
- c_subscriptionPool.getNoOfFree()));
- jam();
- subPtr.p->m_senderRef = subRef;
- subPtr.p->m_senderData = subData;
- subPtr.p->m_subscriptionId = subId;
- subPtr.p->m_subscriptionKey = subKey;
- subPtr.p->m_subscriptionType = type;
- subPtr.p->m_options = reportSubscribe | reportAll;
- subPtr.p->m_tableId = tableId;
- subPtr.p->m_table_ptrI = RNIL;
- subPtr.p->m_state = state;
- subPtr.p->n_subscribers = 0;
- subPtr.p->m_current_sync_ptrI = RNIL;
-
- fprintf(stderr, "table %d options %x\n", subPtr.p->m_tableId, subPtr.p->m_options);
- DBUG_PRINT("info",("Added: key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
- key.m_subscriptionId, key.m_subscriptionKey));
-
- c_subscriptions.add(subPtr);
- }
-
- SubCreateConf * const conf = (SubCreateConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = subPtr.p->m_senderData;
- sendSignal(subRef, GSN_SUB_CREATE_CONF, signal, SubCreateConf::SignalLength, JBB);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::sendSubCreateRef(Signal* signal, Uint32 errCode)
-{
- jam();
- SubCreateRef * ref = (SubCreateRef *)signal->getDataPtrSend();
- ref->errorCode = errCode;
- sendSignal(signal->getSendersBlockRef(), GSN_SUB_CREATE_REF, signal,
- SubCreateRef::SignalLength, JBB);
- return;
-}
-
-/**********************************************************
- *
- * Setting upp trigger for subscription
- *
- */
-
-void
-Suma::execSUB_SYNC_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUB_SYNC_REQ");
- ndbassert(signal->getNoOfSections() <= 1);
- CRASH_INSERTION(13004);
-
- SubSyncReq * const req = (SubSyncReq*)signal->getDataPtr();
-
- SubscriptionPtr subPtr;
- Subscription key;
- key.m_subscriptionId = req->subscriptionId;
- key.m_subscriptionKey = req->subscriptionKey;
-
- DBUG_PRINT("enter",("key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
- key.m_subscriptionId, key.m_subscriptionKey));
-
- if(!c_subscriptions.find(subPtr, key))
- {
- jam();
- DBUG_PRINT("info",("Not found"));
- sendSubSyncRef(signal, 1407);
- DBUG_VOID_RETURN;
- }
-
- bool ok = false;
- SubscriptionData::Part part = (SubscriptionData::Part)req->part;
-
- Ptr<SyncRecord> syncPtr;
- if(!c_syncPool.seize(syncPtr))
- {
- jam();
- sendSubSyncRef(signal, 1416);
- DBUG_VOID_RETURN;
- }
- DBUG_PRINT("info",("c_syncPool size: %d free: %d",
- c_syncPool.getSize(),
- c_syncPool.getNoOfFree()));
-
- syncPtr.p->m_senderRef = req->senderRef;
- syncPtr.p->m_senderData = req->senderData;
- syncPtr.p->m_subscriptionPtrI = subPtr.i;
- syncPtr.p->ptrI = syncPtr.i;
- syncPtr.p->m_error = 0;
-
- subPtr.p->m_current_sync_ptrI = syncPtr.i;
-
- {
- jam();
- syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1);
- if(signal->getNoOfSections() > 0){
- SegmentedSectionPtr ptr(0,0,0);
- signal->getSection(ptr, SubSyncReq::ATTRIBUTE_LIST);
- LocalDataBuffer<15> attrBuf(c_dataBufferPool,syncPtr.p->m_attributeList);
- append(attrBuf, ptr, getSectionSegmentPool());
- releaseSections(signal);
- }
- }
-
- TablePtr tabPtr;
- initTable(signal,subPtr.p->m_tableId,tabPtr,syncPtr);
- tabPtr.p->n_subscribers++;
- if (subPtr.p->m_options & Subscription::REPORT_ALL)
- tabPtr.p->m_reportAll = true;
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
- DBUG_VOID_RETURN;
-
- switch(part){
- case SubscriptionData::MetaData:
- ndbrequire(false);
-#if 0
- ok = true;
- jam();
- if (subPtr.p->m_subscriptionType == SubCreateReq::DatabaseSnapshot) {
- TableList::DataBufferIterator it;
- syncPtr.p->m_tableList.first(it);
- if(it.isNull()) {
- /**
- * Get all tables from dict
- */
- ListTablesReq * req = (ListTablesReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = syncPtr.i;
- req->requestData = 0;
- /**
- * @todo: accomodate scan of index tables?
- */
- req->setTableType(DictTabInfo::UserTable);
-
- sendSignal(DBDICT_REF, GSN_LIST_TABLES_REQ, signal,
- ListTablesReq::SignalLength, JBB);
- break;
- }
- }
-
- syncPtr.p->startMeta(signal);
-#endif
- break;
- case SubscriptionData::TableData: {
- ok = true;
- jam();
- syncPtr.p->startScan(signal);
- break;
- }
- }
- ndbrequire(ok);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::sendSubSyncRef(Signal* signal, Uint32 errCode){
- jam();
- SubSyncRef * ref= (SubSyncRef *)signal->getDataPtrSend();
- ref->errorCode = errCode;
- releaseSections(signal);
- sendSignal(signal->getSendersBlockRef(),
- GSN_SUB_SYNC_REF,
- signal,
- SubSyncRef::SignalLength,
- JBB);
- return;
-}
-
-/**********************************************************
- * Dict interface
- */
-
-#if 0
-void
-Suma::execLIST_TABLES_CONF(Signal* signal){
- jamEntry();
- CRASH_INSERTION(13005);
- ListTablesConf* const conf = (ListTablesConf*)signal->getDataPtr();
- SyncRecord* tmp = c_syncPool.getPtr(conf->senderData);
- tmp->runLIST_TABLES_CONF(signal);
-}
-#endif
-
-
-/*************************************************************************
- *
- *
- */
-#if 0
-void
-Suma::Table::runLIST_TABLES_CONF(Signal* signal){
- jam();
-
- ListTablesConf * const conf = (ListTablesConf*)signal->getDataPtr();
- const Uint32 len = signal->length() - ListTablesConf::HeaderLength;
-
- SubscriptionPtr subPtr;
- suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
-
- for (unsigned i = 0; i < len; i++) {
- subPtr.p->m_maxTables++;
- suma.addTableId(ListTablesConf::getTableId(conf->tableData[i]), subPtr, this);
- }
-
- // for (unsigned i = 0; i < len; i++)
- // conf->tableData[i] = ListTablesConf::getTableId(conf->tableData[i]);
- // m_tableList.append(&conf->tableData[0], len);
-
-#if 0
- TableList::DataBufferIterator it;
- int i = 0;
- for(m_tableList.first(it);!it.isNull();m_tableList.next(it)) {
- ndbout_c("%u listtableconf tableid %d", i++, *it.data);
- }
-#endif
-
- if(len == ListTablesConf::DataLength){
- jam();
- // we expect more LIST_TABLE_CONF
- return;
- }
-
-#if 0
- subPtr.p->m_currentTable = 0;
- subPtr.p->m_maxTables = 0;
-
- TableList::DataBufferIterator it;
- for(m_tableList.first(it); !it.isNull(); m_tableList.next(it)) {
- subPtr.p->m_maxTables++;
- suma.addTableId(*it.data, subPtr, NULL);
-#ifdef NODEFAIL_DEBUG
- ndbout_c(" listtableconf tableid %d",*it.data);
-#endif
- }
-#endif
-
- startMeta(signal);
-}
-#endif
-
-
-int
-Suma::initTable(Signal *signal, Uint32 tableId, TablePtr &tabPtr,
- SubscriberPtr subbPtr)
-{
- DBUG_ENTER("Suma::initTable SubscriberPtr");
- DBUG_PRINT("enter",("tableId: %d", tableId));
-
- int r= initTable(signal,tableId,tabPtr);
-
- {
- LocalDLList<Subscriber> subscribers(c_subscriberPool,
- tabPtr.p->c_subscribers);
- subscribers.add(subbPtr);
- }
-
- DBUG_PRINT("info",("added subscriber: %i", subbPtr.i));
-
- if (r)
- {
- jam();
- // we have to wait getting tab info
- DBUG_RETURN(1);
- }
-
- if (tabPtr.p->setupTrigger(signal, *this))
- {
- jam();
- // we have to wait for triggers to be setup
- DBUG_RETURN(1);
- }
-
- int ret = completeOneSubscriber(signal, tabPtr, subbPtr);
- if (ret == -1)
- {
- jam();
- LocalDLList<Subscriber> subscribers(c_subscriberPool,
- tabPtr.p->c_subscribers);
- subscribers.release(subbPtr);
- }
- completeInitTable(signal, tabPtr);
- DBUG_RETURN(0);
-}
-
-int
-Suma::initTable(Signal *signal, Uint32 tableId, TablePtr &tabPtr,
- Ptr<SyncRecord> syncPtr)
-{
- jam();
- DBUG_ENTER("Suma::initTable Ptr<SyncRecord>");
- DBUG_PRINT("enter",("tableId: %d", tableId));
-
- int r= initTable(signal,tableId,tabPtr);
-
- {
- LocalDLList<SyncRecord> syncRecords(c_syncPool,tabPtr.p->c_syncRecords);
- syncRecords.add(syncPtr);
- }
-
- if (r)
- {
- // we have to wait getting tab info
- DBUG_RETURN(1);
- }
- completeInitTable(signal, tabPtr);
- DBUG_RETURN(0);
-}
-
-int
-Suma::initTable(Signal *signal, Uint32 tableId, TablePtr &tabPtr)
-{
- jam();
- DBUG_ENTER("Suma::initTable");
-
- if (!c_tables.find(tabPtr, tableId) ||
- tabPtr.p->m_state == Table::DROPPED ||
- tabPtr.p->m_state == Table::ALTERED)
- {
- // table not being prepared
- // seize a new table, initialize and add to c_tables
- ndbrequire(c_tablePool.seize(tabPtr));
- DBUG_PRINT("info",("c_tablePool size: %d free: %d",
- c_tablePool.getSize(),
- c_tablePool.getNoOfFree()));
- new (tabPtr.p) Table;
-
- tabPtr.p->m_tableId= tableId;
- tabPtr.p->m_ptrI= tabPtr.i;
- tabPtr.p->n_subscribers = 0;
- DBUG_PRINT("info",("Suma::Table[%u,i=%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.i, tabPtr.p->n_subscribers));
-
- tabPtr.p->m_reportAll = false;
-
- tabPtr.p->m_error = 0;
- tabPtr.p->m_schemaVersion = RNIL;
- tabPtr.p->m_state = Table::DEFINING;
- tabPtr.p->m_drop_subbPtr.p = 0;
- for (int j= 0; j < 3; j++)
- {
- tabPtr.p->m_hasTriggerDefined[j] = 0;
- tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
- tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
- }
-
- c_tables.add(tabPtr);
-
- GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = tabPtr.i;
- req->requestType =
- GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
- req->tableId = tableId;
-
- DBUG_PRINT("info",("GET_TABINFOREQ id %d", req->tableId));
-
- if (ERROR_INSERTED(13031))
- {
- jam();
- CLEAR_ERROR_INSERT_VALUE;
- GetTabInfoRef* ref = (GetTabInfoRef*)signal->getDataPtrSend();
- ref->tableId = tableId;
- ref->senderData = tabPtr.i;
- ref->errorCode = GetTabInfoRef::TableNotDefined;
- sendSignal(reference(), GSN_GET_TABINFOREF, signal,
- GetTabInfoRef::SignalLength, JBB);
- DBUG_RETURN(1);
- }
-
- sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
- GetTabInfoReq::SignalLength, JBB);
- DBUG_RETURN(1);
- }
- if (tabPtr.p->m_state == Table::DEFINING)
- {
- DBUG_RETURN(1);
- }
- // ToDo should be a ref signal instead
- ndbrequire(tabPtr.p->m_state == Table::DEFINED);
- DBUG_RETURN(0);
-}
-
-int
-Suma::completeOneSubscriber(Signal *signal, TablePtr tabPtr, SubscriberPtr subbPtr)
-{
- jam();
- DBUG_ENTER("Suma::completeOneSubscriber");
-
- if (tabPtr.p->m_error &&
- (c_startup.m_restart_server_node_id == 0 ||
- tabPtr.p->m_state != Table::DROPPED))
- {
- jam();
- sendSubStartRef(signal,subbPtr,tabPtr.p->m_error,
- SubscriptionData::TableData);
- tabPtr.p->n_subscribers--;
- DBUG_RETURN(-1);
- }
- else
- {
- jam();
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
- subPtr.p->m_table_ptrI= tabPtr.i;
- sendSubStartComplete(signal,subbPtr, m_last_complete_gci + 3,
- SubscriptionData::TableData);
- }
- DBUG_RETURN(0);
-}
-
-void
-Suma::completeAllSubscribers(Signal *signal, TablePtr tabPtr)
-{
- jam();
- DBUG_ENTER("Suma::completeAllSubscribers");
- // handle all subscribers
- {
- LocalDLList<Subscriber> subscribers(c_subscriberPool,
- tabPtr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(subscribers.first(subbPtr); !subbPtr.isNull();)
- {
- jam();
- Ptr<Subscriber> tmp = subbPtr;
- subscribers.next(subbPtr);
- int ret = completeOneSubscriber(signal, tabPtr, tmp);
- if (ret == -1)
- {
- jam();
- subscribers.release(tmp);
- }
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::completeInitTable(Signal *signal, TablePtr tabPtr)
-{
- jam();
- DBUG_ENTER("Suma::completeInitTable");
-
- // handle all syncRecords
- while (!tabPtr.p->c_syncRecords.isEmpty())
- {
- Ptr<SyncRecord> syncPtr;
- {
- LocalDLList<SyncRecord> syncRecords(c_syncPool,
- tabPtr.p->c_syncRecords);
- syncRecords.first(syncPtr);
- syncRecords.remove(syncPtr);
- }
- syncPtr.p->ptrI = syncPtr.i;
- if (tabPtr.p->m_error == 0)
- {
- jam();
- syncPtr.p->startScan(signal);
- }
- else
- {
- jam();
- syncPtr.p->completeScan(signal, tabPtr.p->m_error);
- tabPtr.p->n_subscribers--;
- }
- }
-
- if (tabPtr.p->m_error)
- {
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
- tabPtr.p->checkRelease(*this);
- }
- else
- {
- tabPtr.p->m_state = Table::DEFINED;
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-void
-Suma::execGET_TABINFOREF(Signal* signal){
- jamEntry();
- GetTabInfoRef* ref = (GetTabInfoRef*)signal->getDataPtr();
- Uint32 tableId = ref->tableId;
- Uint32 senderData = ref->senderData;
- GetTabInfoRef::ErrorCode errorCode =
- (GetTabInfoRef::ErrorCode) ref->errorCode;
- int do_resend_request = 0;
- TablePtr tabPtr;
- c_tablePool.getPtr(tabPtr, senderData);
- switch (errorCode)
- {
- case GetTabInfoRef::TableNotDefined:
- // wrong state
- break;
- case GetTabInfoRef::InvalidTableId:
- // no such table
- break;
- case GetTabInfoRef::Busy:
- do_resend_request = 1;
- break;
- case GetTabInfoRef::TableNameTooLong:
- ndbrequire(false);
- break;
- case GetTabInfoRef::NoFetchByName:
- break;
- }
- if (do_resend_request)
- {
- GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = senderData;
- req->requestType =
- GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
- req->tableId = tableId;
- sendSignalWithDelay(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
- 30, GetTabInfoReq::SignalLength);
- return;
- }
- tabPtr.p->m_state = Table::DROPPED;
- tabPtr.p->m_error = errorCode;
- completeAllSubscribers(signal, tabPtr);
- completeInitTable(signal, tabPtr);
-}
-
-void
-Suma::execGET_TABINFO_CONF(Signal* signal){
- jamEntry();
-
- CRASH_INSERTION(13006);
-
- if(!assembleFragments(signal)){
- return;
- }
-
- GetTabInfoConf* conf = (GetTabInfoConf*)signal->getDataPtr();
- Uint32 tableId = conf->tableId;
- TablePtr tabPtr;
- c_tablePool.getPtr(tabPtr, conf->senderData);
- SegmentedSectionPtr ptr(0,0,0);
- signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
- ndbrequire(tabPtr.p->parseTable(ptr, *this));
- releaseSections(signal);
- /**
- * We need to gather fragment info
- */
- jam();
- DihFragCountReq* req = (DihFragCountReq*)signal->getDataPtrSend();
- req->m_connectionData = RNIL;
- req->m_tableRef = tableId;
- req->m_senderData = tabPtr.i;
- sendSignal(DBDIH_REF, GSN_DI_FCOUNTREQ, signal,
- DihFragCountReq::SignalLength, JBB);
-}
-
-bool
-Suma::Table::parseTable(SegmentedSectionPtr ptr,
- Suma &suma)
-{
- DBUG_ENTER("Suma::Table::parseTable");
-
- SimplePropertiesSectionReader it(ptr, suma.getSectionSegmentPool());
-
- SimpleProperties::UnpackStatus s;
- DictTabInfo::Table tableDesc; tableDesc.init();
- s = SimpleProperties::unpack(it, &tableDesc,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
-
- jam();
- suma.suma_ndbrequire(s == SimpleProperties::Break);
-
-#if 0
-ToDo handle this
- if(m_schemaVersion != tableDesc.TableVersion){
- jam();
-
- release(* this);
-
- // oops wrong schema version in stored tabledesc
- // we need to find all subscriptions with old table desc
- // and all subscribers to this
- // hopefully none
- c_tables.release(tabPtr);
- DBUG_PRINT("info",("c_tablePool size: %d free: %d",
- suma.c_tablePool.getSize(),
- suma.c_tablePool.getNoOfFree()));
- tabPtr.setNull();
- DLHashTable<Suma::Subscription>::Iterator i_subPtr;
- c_subscriptions.first(i_subPtr);
- SubscriptionPtr subPtr;
- for(;!i_subPtr.isNull();c_subscriptions.next(i_subPtr)){
- jam();
- c_subscriptions.getPtr(subPtr, i_subPtr.curr.i);
- SyncRecord* tmp = c_syncPool.getPtr(subPtr.p->m_syncPtrI);
- if (tmp == syncPtr_p) {
- jam();
- continue;
- }
- if (subPtr.p->m_tables.get(tableId)) {
- jam();
- subPtr.p->m_tables.clear(tableId); // remove this old table reference
- TableList::DataBufferIterator it;
- for(tmp->m_tableList.first(it);!it.isNull();tmp->m_tableList.next(it)) {
- jam();
- if (*it.data == tableId){
- jam();
- Uint32 *pdata = it.data;
- tmp->m_tableList.next(it);
- for(;!it.isNull();tmp->m_tableList.next(it)) {
- jam();
- *pdata = *it.data;
- pdata = it.data;
- }
- *pdata = RNIL; // todo remove this last item...
- break;
- }
- }
- }
- }
- }
-#endif
-
- if(m_attributes.getSize() != 0){
- jam();
- DBUG_RETURN(true);
- }
-
- /**
- * Initialize table object
- */
- Uint32 noAttribs = tableDesc.NoOfAttributes;
- Uint32 notFixed = (tableDesc.NoOfNullable+tableDesc.NoOfVariable);
- m_schemaVersion = tableDesc.TableVersion;
-
- // The attribute buffer
- LocalDataBuffer<15> attrBuf(suma.c_dataBufferPool, m_attributes);
-
- // Temporary buffer
- DataBuffer<15> theRest(suma.c_dataBufferPool);
-
- if(!attrBuf.seize(noAttribs)){
- jam();
- suma.suma_ndbrequire(false);
- DBUG_RETURN(false);
- }
-
- if(!theRest.seize(notFixed)){
- jam();
- suma.suma_ndbrequire(false);
- DBUG_RETURN(false);
- }
-
- DataBuffer<15>::DataBufferIterator attrIt; // Fixed not nullable
- DataBuffer<15>::DataBufferIterator restIt; // variable + nullable
- attrBuf.first(attrIt);
- theRest.first(restIt);
-
- for(Uint32 i = 0; i < noAttribs; i++) {
- DictTabInfo::Attribute attrDesc; attrDesc.init();
- s = SimpleProperties::unpack(it, &attrDesc,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
- jam();
- suma.suma_ndbrequire(s == SimpleProperties::Break);
-
- if (!attrDesc.AttributeNullableFlag
- /* && !attrDesc.AttributeVariableFlag */) {
- jam();
- * attrIt.data = attrDesc.AttributeId;
- attrBuf.next(attrIt);
- } else {
- jam();
- * restIt.data = attrDesc.AttributeId;
- theRest.next(restIt);
- }
-
- // Move to next attribute
- it.next();
- }
-
- /**
- * Put the rest in end of attrBuf
- */
- theRest.first(restIt);
- for(; !restIt.isNull(); theRest.next(restIt)){
- * attrIt.data = * restIt.data;
- attrBuf.next(attrIt);
- }
-
- theRest.release();
-
- DBUG_RETURN(true);
-}
-
-void
-Suma::execDI_FCOUNTREF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execDI_FCOUNTREF");
- DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
- switch ((DihFragCountRef::ErrorCode) ref->m_error)
- {
- case DihFragCountRef::ErroneousTableState:
- jam();
- if (ref->m_tableStatus == Dbdih::TabRecord::TS_CREATING)
- {
- const Uint32 tableId = ref->m_senderData;
- const Uint32 tabPtr_i = ref->m_tableRef;
- DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtrSend();
-
- req->m_connectionData = RNIL;
- req->m_tableRef = tabPtr_i;
- req->m_senderData = tableId;
- sendSignalWithDelay(DBDIH_REF, GSN_DI_FCOUNTREQ, signal,
- DihFragCountReq::SignalLength,
- DihFragCountReq::RetryInterval);
- DBUG_VOID_RETURN;
- }
- ndbrequire(false);
- default:
- ndbrequire(false);
- }
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execDI_FCOUNTCONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execDI_FCOUNTCONF");
- ndbassert(signal->getNoOfSections() == 0);
- DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
- const Uint32 userPtr = conf->m_connectionData;
- const Uint32 fragCount = conf->m_fragmentCount;
- const Uint32 tableId = conf->m_tableRef;
-
- ndbrequire(userPtr == RNIL && signal->length() == 5);
-
- TablePtr tabPtr;
- tabPtr.i= conf->m_senderData;
- ndbrequire((tabPtr.p= c_tablePool.getPtr(tabPtr.i)) != 0);
- ndbrequire(tabPtr.p->m_tableId == tableId);
-
- LocalDataBuffer<15> fragBuf(c_dataBufferPool, tabPtr.p->m_fragments);
- ndbrequire(fragBuf.getSize() == 0);
-
- tabPtr.p->m_fragCount = fragCount;
-
- signal->theData[0] = RNIL;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = tableId;
- signal->theData[3] = 0; // Frag no
- sendSignal(DBDIH_REF, GSN_DIGETPRIMREQ, signal, 4, JBB);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execDIGETPRIMCONF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execDIGETPRIMCONF");
- ndbassert(signal->getNoOfSections() == 0);
-
- const Uint32 userPtr = signal->theData[0];
- const Uint32 nodeCount = signal->theData[6];
- const Uint32 tableId = signal->theData[7];
- const Uint32 fragNo = signal->theData[8];
-
- ndbrequire(userPtr == RNIL && signal->length() == 9);
- ndbrequire(nodeCount > 0 && nodeCount <= MAX_REPLICAS);
-
- TablePtr tabPtr;
- tabPtr.i= signal->theData[1];
- ndbrequire((tabPtr.p= c_tablePool.getPtr(tabPtr.i)) != 0);
- ndbrequire(tabPtr.p->m_tableId == tableId);
-
- {
- LocalDataBuffer<15> fragBuf(c_dataBufferPool,tabPtr.p->m_fragments);
-
- /**
- * Add primary node for fragment to list
- */
- FragmentDescriptor fd;
- fd.m_fragDesc.m_nodeId = signal->theData[2];
- fd.m_fragDesc.m_fragmentNo = fragNo;
- signal->theData[2] = fd.m_dummy;
- fragBuf.append(&signal->theData[2], 1);
- }
-
- const Uint32 nextFrag = fragNo + 1;
- if(nextFrag == tabPtr.p->m_fragCount)
- {
- /**
- * Complete frag info for table
- * table is not up to date
- */
-
- if (tabPtr.p->c_subscribers.isEmpty())
- {
- completeInitTable(signal,tabPtr);
- DBUG_VOID_RETURN;
- }
- tabPtr.p->setupTrigger(signal, *this);
- DBUG_VOID_RETURN;
- }
- signal->theData[0] = RNIL;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = tableId;
- signal->theData[3] = nextFrag; // Frag no
- sendSignal(DBDIH_REF, GSN_DIGETPRIMREQ, signal, 4, JBB);
-
- DBUG_VOID_RETURN;
-}
-
-#if 0
-void
-Suma::SyncRecord::completeTableInit(Signal* signal)
-{
- jam();
- SubscriptionPtr subPtr;
- suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
-
-#if PRINT_ONLY
- ndbout_c("GSN_SUB_SYNC_CONF (meta)");
-#else
-
- suma.releaseSections(signal);
-
- if (m_error) {
- SubSyncRef * const ref = (SubSyncRef*)signal->getDataPtrSend();
- ref->senderRef = suma.reference();
- ref->senderData = subPtr.p->m_senderData;
- ref->errorCode = SubSyncRef::Undefined;
- suma.sendSignal(subPtr.p->m_senderRef, GSN_SUB_SYNC_REF, signal,
- SubSyncRef::SignalLength, JBB);
- } else {
- SubSyncConf * const conf = (SubSyncConf*)signal->getDataPtrSend();
- conf->senderRef = suma.reference();
- conf->senderData = subPtr.p->m_senderData;
- suma.sendSignal(subPtr.p->m_senderRef, GSN_SUB_SYNC_CONF, signal,
- SubSyncConf::SignalLength, JBB);
- }
-#endif
-}
-#endif
-
-/**********************************************************
- *
- * Scan interface
- *
- */
-
-void
-Suma::SyncRecord::startScan(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::SyncRecord::startScan");
-
- /**
- * Get fraginfo
- */
- m_currentTable = 0;
- m_currentFragment = 0;
- nextScan(signal);
- DBUG_VOID_RETURN;
-}
-
-bool
-Suma::SyncRecord::getNextFragment(TablePtr * tab,
- FragmentDescriptor * fd)
-{
- jam();
- SubscriptionPtr subPtr;
- suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
- TableList::DataBufferIterator tabIt;
- DataBuffer<15>::DataBufferIterator fragIt;
-
- m_tableList.position(tabIt, m_currentTable);
- for(; !tabIt.curr.isNull(); m_tableList.next(tabIt), m_currentTable++)
- {
- TablePtr tabPtr;
- ndbrequire(suma.c_tables.find(tabPtr, * tabIt.data));
- LocalDataBuffer<15> fragBuf(suma.c_dataBufferPool, tabPtr.p->m_fragments);
-
- fragBuf.position(fragIt, m_currentFragment);
- for(; !fragIt.curr.isNull(); fragBuf.next(fragIt), m_currentFragment++)
- {
- FragmentDescriptor tmp;
- tmp.m_dummy = * fragIt.data;
- if(tmp.m_fragDesc.m_nodeId == suma.getOwnNodeId()){
- * fd = tmp;
- * tab = tabPtr;
- return true;
- }
- }
- m_currentFragment = 0;
-
- tabPtr.p->n_subscribers--;
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
- tabPtr.p->checkRelease(suma);
- }
- return false;
-}
-
-void
-Suma::SyncRecord::nextScan(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::SyncRecord::nextScan");
- TablePtr tabPtr;
- FragmentDescriptor fd;
- SubscriptionPtr subPtr;
- if(!getNextFragment(&tabPtr, &fd)){
- jam();
- completeScan(signal);
- DBUG_VOID_RETURN;
- }
- suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
-
- DataBuffer<15>::Head head = m_attributeList;
- if(head.getSize() == 0){
- head = tabPtr.p->m_attributes;
- }
- LocalDataBuffer<15> attrBuf(suma.c_dataBufferPool, head);
-
- ScanFragReq * req = (ScanFragReq *)signal->getDataPtrSend();
- const Uint32 parallelism = 16;
- const Uint32 attrLen = 5 + attrBuf.getSize();
-
- req->senderData = ptrI;
- req->resultRef = suma.reference();
- req->tableId = tabPtr.p->m_tableId;
- req->requestInfo = 0;
- req->savePointId = 0;
- ScanFragReq::setLockMode(req->requestInfo, 0);
- ScanFragReq::setHoldLockFlag(req->requestInfo, 1);
- ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
- ScanFragReq::setAttrLen(req->requestInfo, attrLen);
- req->fragmentNoKeyLen = fd.m_fragDesc.m_fragmentNo;
- req->schemaVersion = tabPtr.p->m_schemaVersion;
- req->transId1 = 0;
- req->transId2 = (SUMA << 20) + (suma.getOwnNodeId() << 8);
- req->clientOpPtr = (ptrI << 16);
- req->batch_size_rows= parallelism;
- req->batch_size_bytes= 0;
- suma.sendSignal(DBLQH_REF, GSN_SCAN_FRAGREQ, signal,
- ScanFragReq::SignalLength, JBB);
-
- signal->theData[0] = ptrI;
- signal->theData[1] = 0;
- signal->theData[2] = (SUMA << 20) + (suma.getOwnNodeId() << 8);
-
- // Return all
- signal->theData[3] = attrBuf.getSize();
- signal->theData[4] = 0;
- signal->theData[5] = 0;
- signal->theData[6] = 0;
- signal->theData[7] = 0;
-
- Uint32 dataPos = 8;
- DataBuffer<15>::DataBufferIterator it;
- for(attrBuf.first(it); !it.curr.isNull(); attrBuf.next(it)){
- AttributeHeader::init(&signal->theData[dataPos++], * it.data, 0);
- if(dataPos == 25){
- suma.sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, 25, JBB);
- dataPos = 3;
- }
- }
- if(dataPos != 3){
- suma.sendSignal(DBLQH_REF, GSN_ATTRINFO, signal, dataPos, JBB);
- }
-
- m_currentTableId = tabPtr.p->m_tableId;
- m_currentNoOfAttributes = attrBuf.getSize();
-
- DBUG_VOID_RETURN;
-}
-
-
-void
-Suma::execSCAN_FRAGREF(Signal* signal){
- jamEntry();
-
-// ScanFragRef * const ref = (ScanFragRef*)signal->getDataPtr();
- ndbrequire(false);
-}
-
-void
-Suma::execSCAN_FRAGCONF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execSCAN_FRAGCONF");
- ndbassert(signal->getNoOfSections() == 0);
- CRASH_INSERTION(13011);
-
- ScanFragConf * const conf = (ScanFragConf*)signal->getDataPtr();
-
- const Uint32 completed = conf->fragmentCompleted;
- const Uint32 senderData = conf->senderData;
- const Uint32 completedOps = conf->completedOps;
-
- Ptr<SyncRecord> syncPtr;
- c_syncPool.getPtr(syncPtr, senderData);
-
- if(completed != 2){
- jam();
-
-#if PRINT_ONLY
- SubSyncContinueConf * const conf =
- (SubSyncContinueConf*)signal->getDataPtrSend();
- conf->subscriptionId = subPtr.p->m_subscriptionId;
- conf->subscriptionKey = subPtr.p->m_subscriptionKey;
- execSUB_SYNC_CONTINUE_CONF(signal);
-#else
- SubSyncContinueReq * const req = (SubSyncContinueReq*)signal->getDataPtrSend();
- req->subscriberData = syncPtr.p->m_senderData;
- req->noOfRowsSent = completedOps;
- sendSignal(syncPtr.p->m_senderRef, GSN_SUB_SYNC_CONTINUE_REQ, signal,
- SubSyncContinueReq::SignalLength, JBB);
-#endif
- DBUG_VOID_RETURN;
- }
-
- ndbrequire(completedOps == 0);
-
- syncPtr.p->m_currentFragment++;
- syncPtr.p->nextScan(signal);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_SYNC_CONTINUE_CONF(Signal* signal){
- jamEntry();
- ndbassert(signal->getNoOfSections() == 0);
-
- CRASH_INSERTION(13012);
-
- SubSyncContinueConf * const conf =
- (SubSyncContinueConf*)signal->getDataPtr();
-
- SubscriptionPtr subPtr;
- Subscription key;
- key.m_subscriptionId = conf->subscriptionId;
- key.m_subscriptionKey = conf->subscriptionKey;
-
- ndbrequire(c_subscriptions.find(subPtr, key));
-
- ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
- req->senderData = subPtr.p->m_current_sync_ptrI;
- req->closeFlag = 0;
- req->transId1 = 0;
- req->transId2 = (SUMA << 20) + (getOwnNodeId() << 8);
- req->batch_size_rows = 16;
- req->batch_size_bytes = 0;
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
-}
-
-void
-Suma::SyncRecord::completeScan(Signal* signal, int error)
-{
- jam();
- DBUG_ENTER("Suma::SyncRecord::completeScan");
- // m_tableList.release();
-
-#if PRINT_ONLY
- ndbout_c("GSN_SUB_SYNC_CONF (data)");
-#else
- if (error == 0)
- {
- SubSyncConf * const conf = (SubSyncConf*)signal->getDataPtrSend();
- conf->senderRef = suma.reference();
- conf->senderData = m_senderData;
- suma.sendSignal(m_senderRef, GSN_SUB_SYNC_CONF, signal,
- SubSyncConf::SignalLength, JBB);
- }
- else
- {
- SubSyncRef * const ref = (SubSyncRef*)signal->getDataPtrSend();
- ref->senderRef = suma.reference();
- ref->senderData = m_senderData;
- suma.sendSignal(m_senderRef, GSN_SUB_SYNC_REF, signal,
- SubSyncRef::SignalLength, JBB);
- }
-#endif
-
- release();
-
- Ptr<Subscription> subPtr;
- suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
- ndbrequire(subPtr.p->m_current_sync_ptrI == ptrI);
- subPtr.p->m_current_sync_ptrI = RNIL;
-
- suma.c_syncPool.release(ptrI);
- DBUG_PRINT("info",("c_syncPool size: %d free: %d",
- suma.c_syncPool.getSize(),
- suma.c_syncPool.getNoOfFree()));
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSCAN_HBREP(Signal* signal){
- jamEntry();
-#if 0
- ndbout << "execSCAN_HBREP" << endl << hex;
- for(int i = 0; i<signal->length(); i++){
- ndbout << signal->theData[i] << " ";
- if(((i + 1) % 8) == 0)
- ndbout << endl << hex;
- }
- ndbout << endl;
-#endif
-}
-
-/**********************************************************
- *
- * Suma participant interface
- *
- * Creation of subscriber
- *
- */
-
-void
-Suma::execSUB_START_REQ(Signal* signal){
- jamEntry();
- ndbassert(signal->getNoOfSections() == 0);
- DBUG_ENTER("Suma::execSUB_START_REQ");
- SubStartReq * const req = (SubStartReq*)signal->getDataPtr();
-
- CRASH_INSERTION(13013);
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 subscriberData = req->subscriberData;
- Uint32 subscriberRef = req->subscriberRef;
- SubscriptionData::Part part = (SubscriptionData::Part)req->part;
-
- Subscription key;
- key.m_subscriptionId = req->subscriptionId;
- key.m_subscriptionKey = req->subscriptionKey;
-
- if (c_startup.m_restart_server_node_id &&
- senderRef != calcSumaBlockRef(c_startup.m_restart_server_node_id))
- {
- /**
- * only allow "restart_server" Suma's to come through
- * for restart purposes
- */
- jam();
- Uint32 err = c_startup.m_restart_server_node_id != RNIL ? 1405 :
- SubStartRef::NF_FakeErrorREF;
-
- sendSubStartRef(signal, err);
- DBUG_VOID_RETURN;
- }
-
- SubscriptionPtr subPtr;
- if(!c_subscriptions.find(subPtr, key)){
- jam();
- sendSubStartRef(signal, 1407);
- DBUG_VOID_RETURN;
- }
-
- if (subPtr.p->m_state == Subscription::LOCKED) {
- jam();
- DBUG_PRINT("info",("Locked"));
- sendSubStartRef(signal, 1411);
- DBUG_VOID_RETURN;
- }
-
- if (subPtr.p->m_state == Subscription::DROPPED &&
- c_startup.m_restart_server_node_id == 0) {
- jam();
- DBUG_PRINT("info",("Dropped"));
- sendSubStartRef(signal, 1418);
- DBUG_VOID_RETURN;
- }
-
- ndbrequire(subPtr.p->m_state == Subscription::DEFINED ||
- c_startup.m_restart_server_node_id);
-
- SubscriberPtr subbPtr;
- if(!c_subscriberPool.seize(subbPtr)){
- jam();
- sendSubStartRef(signal, 1412);
- DBUG_VOID_RETURN;
- }
-
- if (c_startup.m_restart_server_node_id == 0 &&
- !c_connected_nodes.get(refToNode(subscriberRef)))
-
- {
- jam();
- c_subscriberPool.release(subbPtr);
- sendSubStartRef(signal, SubStartRef::PartiallyConnected);
- DBUG_VOID_RETURN;
- }
-
- DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree()));
-
- c_subscriber_nodes.set(refToNode(subscriberRef));
-
- // setup subscription record
- if (subPtr.p->m_state == Subscription::DEFINED)
- subPtr.p->m_state = Subscription::LOCKED;
- // store these here for later use
- subPtr.p->m_senderRef = senderRef;
- subPtr.p->m_senderData = senderData;
-
- // setup subscriber record
- subbPtr.p->m_senderRef = subscriberRef;
- subbPtr.p->m_senderData = subscriberData;
- subbPtr.p->m_subPtrI= subPtr.i;
-
- DBUG_PRINT("info",("subscriber: %u[%u,%u] subscription: %u[%u,%u] "
- "tableId: %u id: %u key: %u",
- subbPtr.i, subbPtr.p->m_senderRef, subbPtr.p->m_senderData,
- subPtr.i, subPtr.p->m_senderRef, subPtr.p->m_senderData,
- subPtr.p->m_tableId,
- subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
-
- TablePtr tabPtr;
- switch(part){
- case SubscriptionData::MetaData:
- jam();
- c_metaSubscribers.add(subbPtr);
- sendSubStartComplete(signal, subbPtr, 0, part);
- DBUG_VOID_RETURN;
- case SubscriptionData::TableData:
- jam();
- initTable(signal,subPtr.p->m_tableId,tabPtr,subbPtr);
- tabPtr.p->n_subscribers++;
- if (subPtr.p->m_options & Subscription::REPORT_ALL)
- tabPtr.p->m_reportAll = true;
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
- DBUG_VOID_RETURN;
- }
- ndbrequire(false);
-}
-
-void
-Suma::sendSubStartComplete(Signal* signal,
- SubscriberPtr subbPtr,
- Uint32 firstGCI,
- SubscriptionData::Part part)
-{
- jam();
- DBUG_ENTER("Suma::sendSubStartComplete");
-
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
- ndbrequire(subPtr.p->m_state == Subscription::LOCKED ||
- (subPtr.p->m_state == Subscription::DROPPED &&
- c_startup.m_restart_server_node_id));
- if (subPtr.p->m_state == Subscription::LOCKED)
- {
- jam();
- subPtr.p->m_state = Subscription::DEFINED;
- }
- subPtr.p->n_subscribers++;
-
- DBUG_PRINT("info",("subscriber: %u[%u,%u] subscription: %u[%u,%u] "
- "tableId: %u[i=%u] id: %u key: %u",
- subbPtr.i, subbPtr.p->m_senderRef, subbPtr.p->m_senderData,
- subPtr.i, subPtr.p->m_senderRef, subPtr.p->m_senderData,
- subPtr.p->m_tableId, subPtr.p->m_table_ptrI,
- subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
-
- SubStartConf * const conf = (SubStartConf*)signal->getDataPtrSend();
-
- conf->senderRef = reference();
- conf->senderData = subPtr.p->m_senderData;
- conf->subscriptionId = subPtr.p->m_subscriptionId;
- conf->subscriptionKey = subPtr.p->m_subscriptionKey;
- conf->firstGCI = firstGCI;
- conf->part = (Uint32) part;
-
- DBUG_PRINT("info",("subscriber: %u id: %u key: %u", subbPtr.i,
- subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
- sendSignal(subPtr.p->m_senderRef, GSN_SUB_START_CONF, signal,
- SubStartConf::SignalLength, JBB);
-
- reportAllSubscribers(signal, NdbDictionary::Event::_TE_SUBSCRIBE,
- subPtr, subbPtr);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::sendSubStartRef(Signal* signal, Uint32 errCode)
-{
- jam();
- SubStartRef * ref = (SubStartRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = errCode;
- releaseSections(signal);
- sendSignal(signal->getSendersBlockRef(), GSN_SUB_START_REF, signal,
- SubStartRef::SignalLength, JBB);
-}
-void
-Suma::sendSubStartRef(Signal* signal,
- SubscriberPtr subbPtr, Uint32 error,
- SubscriptionData::Part part)
-{
- jam();
-
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
-
- ndbrequire(subPtr.p->m_state == Subscription::LOCKED ||
- (subPtr.p->m_state == Subscription::DROPPED &&
- c_startup.m_restart_server_node_id));
- if (subPtr.p->m_state == Subscription::LOCKED)
- {
- jam();
- subPtr.p->m_state = Subscription::DEFINED;
- }
-
- SubStartRef * ref= (SubStartRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = subPtr.p->m_senderData;
- ref->subscriptionId = subPtr.p->m_subscriptionId;
- ref->subscriptionKey = subPtr.p->m_subscriptionKey;
- ref->part = (Uint32) part;
- ref->errorCode = error;
-
- sendSignal(subPtr.p->m_senderRef, GSN_SUB_START_REF, signal,
- SubStartRef::SignalLength, JBB);
-}
-
-/**********************************************************
- * Suma participant interface
- *
- * Stopping and removing of subscriber
- *
- */
-
-void
-Suma::execSUB_STOP_REQ(Signal* signal){
- jamEntry();
- ndbassert(signal->getNoOfSections() == 0);
- DBUG_ENTER("Suma::execSUB_STOP_REQ");
-
- CRASH_INSERTION(13019);
-
- SubStopReq * const req = (SubStopReq*)signal->getDataPtr();
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- Uint32 subscriberRef = req->subscriberRef;
- Uint32 subscriberData = req->subscriberData;
- SubscriptionPtr subPtr;
- Subscription key;
- key.m_subscriptionId = req->subscriptionId;
- key.m_subscriptionKey = req->subscriptionKey;
- Uint32 part = req->part;
-
- if (key.m_subscriptionKey == 0 &&
- key.m_subscriptionId == 0 &&
- subscriberData == 0)
- {
- SubStopConf* conf = (SubStopConf*)signal->getDataPtrSend();
-
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->subscriptionId = key.m_subscriptionId;
- conf->subscriptionKey = key.m_subscriptionKey;
- conf->subscriberData = subscriberData;
-
- sendSignal(senderRef, GSN_SUB_STOP_CONF, signal,
- SubStopConf::SignalLength, JBB);
-
- removeSubscribersOnNode(signal, refToNode(senderRef));
- DBUG_VOID_RETURN;
- }
-
- if (c_startup.m_restart_server_node_id &&
- senderRef != calcSumaBlockRef(c_startup.m_restart_server_node_id))
- {
- /**
- * only allow "restart_server" Suma's to come through
- * for restart purposes
- */
- jam();
- Uint32 err = c_startup.m_restart_server_node_id != RNIL ? 1405 :
- SubStopRef::NF_FakeErrorREF;
-
- sendSubStopRef(signal, err);
- DBUG_VOID_RETURN;
- }
-
- if(!c_subscriptions.find(subPtr, key)){
- jam();
- DBUG_PRINT("error", ("not found"));
- sendSubStopRef(signal, 1407);
- DBUG_VOID_RETURN;
- }
-
- if (subPtr.p->m_state == Subscription::LOCKED) {
- jam();
- DBUG_PRINT("error", ("locked"));
- sendSubStopRef(signal, 1411);
- DBUG_VOID_RETURN;
- }
-
- ndbrequire(part == SubscriptionData::TableData);
-
- TablePtr tabPtr;
- tabPtr.i = subPtr.p->m_table_ptrI;
- if (tabPtr.i == RNIL ||
- !(tabPtr.p = c_tables.getPtr(tabPtr.i)) ||
- tabPtr.p->m_tableId != subPtr.p->m_tableId)
- {
- jam();
- DBUG_PRINT("error", ("no such table id %u[i=%u]",
- subPtr.p->m_tableId, subPtr.p->m_table_ptrI));
- sendSubStopRef(signal, 1417);
- DBUG_VOID_RETURN;
- }
-
- if (tabPtr.p->m_drop_subbPtr.p != 0) {
- jam();
- DBUG_PRINT("error", ("table locked"));
- sendSubStopRef(signal, 1420);
- DBUG_VOID_RETURN;
- }
-
- DBUG_PRINT("info",("subscription: %u tableId: %u[i=%u] id: %u key: %u",
- subPtr.i, subPtr.p->m_tableId, tabPtr.i,
- subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
-
- SubscriberPtr subbPtr;
- if (senderRef == reference()){
- jam();
- c_subscriberPool.getPtr(subbPtr, senderData);
- ndbrequire(subbPtr.p->m_subPtrI == subPtr.i &&
- subbPtr.p->m_senderRef == subscriberRef &&
- subbPtr.p->m_senderData == subscriberData);
- c_removeDataSubscribers.remove(subbPtr);
- }
- else
- {
- jam();
- LocalDLList<Subscriber>
- subscribers(c_subscriberPool,tabPtr.p->c_subscribers);
-
- DBUG_PRINT("info",("search: subscription: %u, ref: %u, data: %d",
- subPtr.i, subscriberRef, subscriberData));
- for (subscribers.first(subbPtr);!subbPtr.isNull();subscribers.next(subbPtr))
- {
- jam();
- DBUG_PRINT("info",
- ("search: subscription: %u, ref: %u, data: %u, subscriber %u",
- subbPtr.p->m_subPtrI, subbPtr.p->m_senderRef,
- subbPtr.p->m_senderData, subbPtr.i));
- if (subbPtr.p->m_subPtrI == subPtr.i &&
- subbPtr.p->m_senderRef == subscriberRef &&
- subbPtr.p->m_senderData == subscriberData)
- {
- jam();
- DBUG_PRINT("info",("found"));
- break;
- }
- }
- /**
- * If we didn't find anyone, send ref
- */
- if (subbPtr.isNull()) {
- jam();
- DBUG_PRINT("error", ("subscriber not found"));
- sendSubStopRef(signal, 1407);
- DBUG_VOID_RETURN;
- }
- subscribers.remove(subbPtr);
- }
-
- subPtr.p->m_senderRef = senderRef; // store ref to requestor
- subPtr.p->m_senderData = senderData; // store ref to requestor
-
- tabPtr.p->m_drop_subbPtr = subbPtr;
-
- if (subPtr.p->m_state == Subscription::DEFINED)
- {
- jam();
- subPtr.p->m_state = Subscription::LOCKED;
- }
-
- if (tabPtr.p->m_state == Table::DROPPED)
- // not ALTERED here since trigger must be removed
- {
- jam();
- tabPtr.p->n_subscribers--;
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
- tabPtr.p->checkRelease(*this);
- sendSubStopComplete(signal, tabPtr.p->m_drop_subbPtr);
- tabPtr.p->m_drop_subbPtr.p = 0;
- }
- else
- {
- jam();
- tabPtr.p->dropTrigger(signal,*this);
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::sendSubStopComplete(Signal* signal, SubscriberPtr subbPtr)
-{
- jam();
- DBUG_ENTER("Suma::sendSubStopComplete");
- CRASH_INSERTION(13020);
-
- DBUG_PRINT("info",("removed subscriber: %i", subbPtr.i));
-
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
-
- Uint32 senderRef= subPtr.p->m_senderRef;
- Uint32 senderData= subPtr.p->m_senderData;
-
- subPtr.p->n_subscribers--;
- ndbassert( subPtr.p->m_state == Subscription::LOCKED ||
- subPtr.p->m_state == Subscription::DROPPED );
- if ( subPtr.p->m_state == Subscription::LOCKED )
- {
- jam();
- subPtr.p->m_state = Subscription::DEFINED;
- if (subPtr.p->n_subscribers == 0)
- {
- jam();
-#if 1
- subPtr.p->m_table_ptrI = RNIL;
-#else
- TablePtr tabPtr;
- tabPtr.i = subPtr.p->m_table_ptrI;
- if ((tabPtr.p= c_tablePool.getPtr(tabPtr.i)) &&
- (tabPtr.p->m_state == Table::DROPPED ||
- tabPtr.p->m_state == Table::ALTERED) &&
- false)
- {
- // last subscriber, and table is dropped
- // safe to drop subscription
- c_subscriptions.release(subPtr);
- DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d",
- c_subscriptionPool.getSize(),
- c_subscriptionPool.getNoOfFree()));
- }
- else
- {
- subPtr.p->m_table_ptrI = RNIL;
- }
- ndbassert(tabPtr.p != 0);
-#endif
- }
- }
- else if ( subPtr.p->n_subscribers == 0 )
- {
- // subscription is marked to be removed
- // and there are no subscribers left
- jam();
- ndbassert(subPtr.p->m_state == Subscription::DROPPED);
- completeSubRemove(subPtr);
- }
-
- // let subscriber know that subscrber is stopped
- {
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();
- data->gci = m_last_complete_gci + 1; // XXX ???
- data->tableId = 0;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo,
- NdbDictionary::Event::_TE_STOP);
- SubTableData::setNdbdNodeId(data->requestInfo,
- getOwnNodeId());
- data->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB);
- }
-
- SubStopConf * const conf = (SubStopConf*)signal->getDataPtrSend();
-
- conf->senderRef= reference();
- conf->senderData= senderData;
-
- sendSignal(senderRef, GSN_SUB_STOP_CONF, signal,
- SubStopConf::SignalLength, JBB);
-
- c_subscriberPool.release(subbPtr);
- DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
- c_subscriberPool.getSize(),
- c_subscriberPool.getNoOfFree()));
-
- reportAllSubscribers(signal, NdbDictionary::Event::_TE_UNSUBSCRIBE,
- subPtr, subbPtr);
-
- DBUG_VOID_RETURN;
-}
-
-// report new started subscriber to all other subscribers
-void
-Suma::reportAllSubscribers(Signal *signal,
- NdbDictionary::Event::_TableEvent table_event,
- SubscriptionPtr subPtr,
- SubscriberPtr subbPtr)
-{
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();
-
- if (table_event == NdbDictionary::Event::_TE_SUBSCRIBE &&
- !c_startup.m_restart_server_node_id)
- {
- data->gci = m_last_complete_gci + 1;
- data->tableId = subPtr.p->m_tableId;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo,
- NdbDictionary::Event::_TE_ACTIVE);
- SubTableData::setNdbdNodeId(data->requestInfo, getOwnNodeId());
- SubTableData::setReqNodeId(data->requestInfo,
- refToNode(subbPtr.p->m_senderRef));
- data->changeMask = 0;
- data->totalLen = 0;
- data->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB);
- }
-
- if (!(subPtr.p->m_options & Subscription::REPORT_SUBSCRIBE))
- {
- return;
- }
- if (subPtr.p->n_subscribers == 0)
- {
- ndbrequire(table_event != NdbDictionary::Event::_TE_SUBSCRIBE);
- return;
- }
-
-//#ifdef VM_TRACE
- ndbout_c("reportAllSubscribers subPtr.i: %d subPtr.p->n_subscribers: %d",
- subPtr.i, subPtr.p->n_subscribers);
-//#endif
- data->gci = m_last_complete_gci + 1;
- data->tableId = subPtr.p->m_tableId;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo, table_event);
- SubTableData::setNdbdNodeId(data->requestInfo, getOwnNodeId());
- data->changeMask = 0;
- data->totalLen = 0;
-
- TablePtr tabPtr;
- c_tables.getPtr(tabPtr, subPtr.p->m_table_ptrI);
- LocalDLList<Subscriber> subbs(c_subscriberPool, tabPtr.p->c_subscribers);
- SubscriberPtr i_subbPtr;
- for(subbs.first(i_subbPtr); !i_subbPtr.isNull(); subbs.next(i_subbPtr))
- {
- if (i_subbPtr.p->m_subPtrI == subPtr.i)
- {
- SubTableData::setReqNodeId(data->requestInfo,
- refToNode(subbPtr.p->m_senderRef));
- data->senderData = i_subbPtr.p->m_senderData;
- sendSignal(i_subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB);
-//#ifdef VM_TRACE
- ndbout_c("sent %s(%d) to node %d, req_nodeid: %d senderData: %d",
- table_event == NdbDictionary::Event::_TE_SUBSCRIBE ?
- "SUBSCRIBE" : "UNSUBSCRIBE", (int) table_event,
- refToNode(i_subbPtr.p->m_senderRef),
- refToNode(subbPtr.p->m_senderRef), data->senderData
- );
-//#endif
- if (i_subbPtr.i != subbPtr.i)
- {
- SubTableData::setReqNodeId(data->requestInfo,
- refToNode(i_subbPtr.p->m_senderRef));
-
- data->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB);
-//#ifdef VM_TRACE
- ndbout_c("sent %s(%d) to node %d, req_nodeid: %d senderData: %d",
- table_event == NdbDictionary::Event::_TE_SUBSCRIBE ?
- "SUBSCRIBE" : "UNSUBSCRIBE", (int) table_event,
- refToNode(subbPtr.p->m_senderRef),
- refToNode(i_subbPtr.p->m_senderRef), data->senderData
- );
-//#endif
- }
- }
- }
-}
-
-void
-Suma::sendSubStopRef(Signal* signal, Uint32 errCode)
-{
- jam();
- DBUG_ENTER("Suma::sendSubStopRef");
- SubStopRef * ref = (SubStopRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->errorCode = errCode;
- sendSignal(signal->getSendersBlockRef(),
- GSN_SUB_STOP_REF,
- signal,
- SubStopRef::SignalLength,
- JBB);
- DBUG_VOID_RETURN;
-}
-
-/**********************************************************
- *
- * Trigger admin interface
- *
- */
-
-int
-Suma::Table::setupTrigger(Signal* signal,
- Suma &suma)
-{
- jam();
- DBUG_ENTER("Suma::Table::setupTrigger");
-
- int ret= 0;
-
- AttributeMask attrMask;
- createAttributeMask(attrMask, suma);
-
- for(Uint32 j = 0; j<3; j++)
- {
- Uint32 triggerId = (m_schemaVersion << 18) | (j << 16) | m_ptrI;
- if(m_hasTriggerDefined[j] == 0)
- {
- suma.suma_ndbrequire(m_triggerIds[j] == ILLEGAL_TRIGGER_ID);
- DBUG_PRINT("info",("DEFINING trigger on table %u[%u]", m_tableId, j));
- CreateTrigReq * const req = (CreateTrigReq*)signal->getDataPtrSend();
- req->setUserRef(SUMA_REF);
- req->setConnectionPtr(m_ptrI);
- req->setTriggerType(TriggerType::SUBSCRIPTION_BEFORE);
- req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
- req->setMonitorReplicas(true);
- req->setMonitorAllAttributes(j == TriggerEvent::TE_DELETE);
- req->setReceiverRef(SUMA_REF);
- req->setTriggerId(triggerId);
- req->setTriggerEvent((TriggerEvent::Value)j);
- req->setTableId(m_tableId);
- req->setAttributeMask(attrMask);
- req->setReportAllMonitoredAttributes(m_reportAll);
- suma.sendSignal(DBTUP_REF, GSN_CREATE_TRIG_REQ,
- signal, CreateTrigReq::SignalLength, JBB);
- ret= 1;
- }
- else
- {
- m_hasTriggerDefined[j]++;
- DBUG_PRINT("info",("REFCOUNT trigger on table %u[%u] %u",
- m_tableId, j, m_hasTriggerDefined[j]));
- }
- }
- DBUG_RETURN(ret);
-}
-
-void
-Suma::Table::createAttributeMask(AttributeMask& mask,
- Suma &suma)
-{
- jam();
- mask.clear();
- DataBuffer<15>::DataBufferIterator it;
- LocalDataBuffer<15> attrBuf(suma.c_dataBufferPool, m_attributes);
- for(attrBuf.first(it); !it.curr.isNull(); attrBuf.next(it)){
- mask.set(* it.data);
- }
-}
-
-void
-Suma::execCREATE_TRIG_CONF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execCREATE_TRIG_CONF");
- ndbassert(signal->getNoOfSections() == 0);
- CreateTrigConf * const conf = (CreateTrigConf*)signal->getDataPtr();
- const Uint32 triggerId = conf->getTriggerId();
- Uint32 type = (triggerId >> 16) & 0x3;
- Uint32 tableId = conf->getTableId();
-
-
- DBUG_PRINT("enter", ("type: %u tableId: %u[i=%u==%u]",
- type, tableId,conf->getConnectionPtr(),triggerId & 0xFFFF));
-
- TablePtr tabPtr;
- c_tables.getPtr(tabPtr, conf->getConnectionPtr());
- ndbrequire(tabPtr.p->m_tableId == tableId);
- ndbrequire(tabPtr.p->m_state == Table::DEFINING);
-
- ndbrequire(type < 3);
- tabPtr.p->m_triggerIds[type] = triggerId;
- ndbrequire(tabPtr.p->m_hasTriggerDefined[type] == 0);
- tabPtr.p->m_hasTriggerDefined[type] = 1;
-
- if (type == 2)
- {
- completeAllSubscribers(signal, tabPtr);
- completeInitTable(signal,tabPtr);
- DBUG_VOID_RETURN;
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execCREATE_TRIG_REF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execCREATE_TRIG_REF");
- ndbassert(signal->getNoOfSections() == 0);
- CreateTrigRef * const ref = (CreateTrigRef*)signal->getDataPtr();
- const Uint32 triggerId = ref->getTriggerId();
- Uint32 type = (triggerId >> 16) & 0x3;
- Uint32 tableId = ref->getTableId();
-
- DBUG_PRINT("enter", ("type: %u tableId: %u[i=%u==%u]",
- type, tableId,ref->getConnectionPtr(),triggerId & 0xFFFF));
-
- TablePtr tabPtr;
- c_tables.getPtr(tabPtr, ref->getConnectionPtr());
- ndbrequire(tabPtr.p->m_tableId == tableId);
- ndbrequire(tabPtr.p->m_state == Table::DEFINING);
-
- tabPtr.p->m_error= ref->getErrorCode();
-
- ndbrequire(type < 3);
-
- if (type == 2)
- {
- completeAllSubscribers(signal, tabPtr);
- completeInitTable(signal,tabPtr);
- DBUG_VOID_RETURN;
- }
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Table::dropTrigger(Signal* signal,Suma& suma)
-{
- jam();
- DBUG_ENTER("Suma::dropTrigger");
-
- m_hasOutstandingTriggerReq[0] =
- m_hasOutstandingTriggerReq[1] =
- m_hasOutstandingTriggerReq[2] = 1;
- for(Uint32 j = 0; j<3; j++){
- jam();
- suma.suma_ndbrequire(m_triggerIds[j] != ILLEGAL_TRIGGER_ID);
- if(m_hasTriggerDefined[j] == 1) {
- jam();
-
- DropTrigReq * const req = (DropTrigReq*)signal->getDataPtrSend();
- req->setConnectionPtr(m_ptrI);
- req->setUserRef(SUMA_REF); // Sending to myself
- req->setRequestType(DropTrigReq::RT_USER);
- req->setTriggerType(TriggerType::SUBSCRIPTION_BEFORE);
- req->setTriggerActionTime(TriggerActionTime::TA_DETACHED);
- req->setIndexId(RNIL);
-
- req->setTableId(m_tableId);
- req->setTriggerId(m_triggerIds[j]);
- req->setTriggerEvent((TriggerEvent::Value)j);
-
- DBUG_PRINT("info",("DROPPING trigger %u = %u %u %u on table %u[%u]",
- m_triggerIds[j],
- TriggerType::SUBSCRIPTION_BEFORE,
- TriggerActionTime::TA_DETACHED,
- j,
- m_tableId, j));
- suma.sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ,
- signal, DropTrigReq::SignalLength, JBB);
- } else {
- jam();
- suma.suma_ndbrequire(m_hasTriggerDefined[j] > 1);
- runDropTrigger(signal,m_triggerIds[j],suma);
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execDROP_TRIG_REF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execDROP_TRIG_REF");
- ndbassert(signal->getNoOfSections() == 0);
- DropTrigRef * const ref = (DropTrigRef*)signal->getDataPtr();
- if (ref->getErrorCode() != DropTrigRef::TriggerNotFound)
- {
- ndbrequire(false);
- }
- TablePtr tabPtr;
- c_tables.getPtr(tabPtr, ref->getConnectionPtr());
- ndbrequire(ref->getTableId() == tabPtr.p->m_tableId);
-
- tabPtr.p->runDropTrigger(signal, ref->getTriggerId(), *this);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execDROP_TRIG_CONF(Signal* signal){
- jamEntry();
- DBUG_ENTER("Suma::execDROP_TRIG_CONF");
- ndbassert(signal->getNoOfSections() == 0);
-
- DropTrigConf * const conf = (DropTrigConf*)signal->getDataPtr();
- TablePtr tabPtr;
- c_tables.getPtr(tabPtr, conf->getConnectionPtr());
- ndbrequire(conf->getTableId() == tabPtr.p->m_tableId);
-
- tabPtr.p->runDropTrigger(signal, conf->getTriggerId(),*this);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Table::runDropTrigger(Signal* signal,
- Uint32 triggerId,
- Suma &suma)
-{
- jam();
- Uint32 type = (triggerId >> 16) & 0x3;
-
- suma.suma_ndbrequire(type < 3);
- suma.suma_ndbrequire(m_triggerIds[type] == triggerId);
- suma.suma_ndbrequire(m_hasTriggerDefined[type] > 0);
- suma.suma_ndbrequire(m_hasOutstandingTriggerReq[type] == 1);
- m_hasTriggerDefined[type]--;
- m_hasOutstandingTriggerReq[type] = 0;
- if (m_hasTriggerDefined[type] == 0)
- {
- jam();
- m_triggerIds[type] = ILLEGAL_TRIGGER_ID;
- }
- if( m_hasOutstandingTriggerReq[0] ||
- m_hasOutstandingTriggerReq[1] ||
- m_hasOutstandingTriggerReq[2])
- {
- // more to come
- jam();
- return;
- }
-
-#if 0
- ndbout_c("trigger completed");
-#endif
-
-
- n_subscribers--;
- DBUG_PRINT("info",("Suma::Table[%u]::n_subscribers: %u",
- m_tableId, n_subscribers));
- checkRelease(suma);
-
- suma.sendSubStopComplete(signal, m_drop_subbPtr);
- m_drop_subbPtr.p = 0;
-}
-
-void Suma::suma_ndbrequire(bool v) { ndbrequire(v); }
-
-void
-Suma::Table::checkRelease(Suma &suma)
-{
- jam();
- DBUG_ENTER("Suma::Table::checkRelease");
- if (n_subscribers == 0)
- {
- jam();
- suma.suma_ndbrequire(m_hasTriggerDefined[0] == 0);
- suma.suma_ndbrequire(m_hasTriggerDefined[1] == 0);
- suma.suma_ndbrequire(m_hasTriggerDefined[2] == 0);
- if (!c_subscribers.isEmpty())
- {
- LocalDLList<Subscriber>
- subscribers(suma.c_subscriberPool,c_subscribers);
- SubscriberPtr subbPtr;
- for (subscribers.first(subbPtr);!subbPtr.isNull();
- subscribers.next(subbPtr))
- {
- jam();
- DBUG_PRINT("info",("subscriber: %u", subbPtr.i));
- }
- suma.suma_ndbrequire(false);
- }
- if (!c_syncRecords.isEmpty())
- {
- LocalDLList<SyncRecord>
- syncRecords(suma.c_syncPool,c_syncRecords);
- Ptr<SyncRecord> syncPtr;
- for (syncRecords.first(syncPtr);!syncPtr.isNull();
- syncRecords.next(syncPtr))
- {
- jam();
- DBUG_PRINT("info",("syncRecord: %u", syncPtr.i));
- }
- suma.suma_ndbrequire(false);
- }
- release(suma);
- suma.c_tables.remove(m_ptrI);
- suma.c_tablePool.release(m_ptrI);
- DBUG_PRINT("info",("c_tablePool size: %d free: %d",
- suma.c_tablePool.getSize(),
- suma.c_tablePool.getNoOfFree()));
- }
- else
- {
- DBUG_PRINT("info",("n_subscribers: %d", n_subscribers));
- }
- DBUG_VOID_RETURN;
-}
-
-/**********************************************************
- * Scan data interface
- *
- * Assumption: one execTRANSID_AI contains all attr info
- *
- */
-
-#define SUMA_BUF_SZ1 MAX_KEY_SIZE_IN_WORDS + MAX_TUPLE_SIZE_IN_WORDS
-#define SUMA_BUF_SZ MAX_ATTRIBUTES_IN_TABLE + SUMA_BUF_SZ1
-
-static Uint32 f_bufferLock = 0;
-static Uint32 f_buffer[SUMA_BUF_SZ];
-static Uint32 f_trigBufferSize = 0;
-static Uint32 b_bufferLock = 0;
-static Uint32 b_buffer[SUMA_BUF_SZ];
-static Uint32 b_trigBufferSize = 0;
-
-void
-Suma::execTRANSID_AI(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execTRANSID_AI");
-
- CRASH_INSERTION(13015);
- TransIdAI * const data = (TransIdAI*)signal->getDataPtr();
- const Uint32 opPtrI = data->connectPtr;
- const Uint32 length = signal->length() - 3;
-
- if(f_bufferLock == 0){
- f_bufferLock = opPtrI;
- } else {
- ndbrequire(f_bufferLock == opPtrI);
- }
-
- Ptr<SyncRecord> syncPtr;
- c_syncPool.getPtr(syncPtr, (opPtrI >> 16));
-
- Uint32 sum = 0;
- Uint32 * dst = f_buffer + MAX_ATTRIBUTES_IN_TABLE;
- Uint32 * headers = f_buffer;
- const Uint32 * src = &data->attrData[0];
- const Uint32 * const end = &src[length];
-
- const Uint32 attribs = syncPtr.p->m_currentNoOfAttributes;
- for(Uint32 i = 0; i<attribs; i++){
- Uint32 tmp = * src++;
- * headers++ = tmp;
- Uint32 len = AttributeHeader::getDataSize(tmp);
-
- memcpy(dst, src, 4 * len);
- dst += len;
- src += len;
- sum += len;
- }
-
- ndbrequire(src == end);
-
- /**
- * Send data to subscriber
- */
- LinearSectionPtr ptr[3];
- ptr[0].p = f_buffer;
- ptr[0].sz = attribs;
-
- ptr[1].p = f_buffer + MAX_ATTRIBUTES_IN_TABLE;
- ptr[1].sz = sum;
-
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, syncPtr.p->m_subscriptionPtrI);
-
- /**
- * Initialize signal
- */
- SubTableData * sdata = (SubTableData*)signal->getDataPtrSend();
- Uint32 ref = subPtr.p->m_senderRef;
- sdata->tableId = syncPtr.p->m_currentTableId;
- sdata->senderData = subPtr.p->m_senderData;
- sdata->requestInfo = 0;
- SubTableData::setOperation(sdata->requestInfo,
- NdbDictionary::Event::_TE_SCAN); // Scan
- sdata->gci = 0; // Undefined
-#if PRINT_ONLY
- ndbout_c("GSN_SUB_TABLE_DATA (scan) #attr: %d len: %d", attribs, sum);
-#else
- sendSignal(ref,
- GSN_SUB_TABLE_DATA,
- signal,
- SubTableData::SignalLength, JBB,
- ptr, 2);
-#endif
-
- /**
- * Reset f_bufferLock
- */
- f_bufferLock = 0;
-
- DBUG_VOID_RETURN;
-}
-
-/**********************************************************
- *
- * Trigger data interface
- *
- */
-
-void
-Suma::execTRIG_ATTRINFO(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execTRIG_ATTRINFO");
-
- CRASH_INSERTION(13016);
- TrigAttrInfo* const trg = (TrigAttrInfo*)signal->getDataPtr();
- const Uint32 trigId = trg->getTriggerId();
-
- const Uint32 dataLen = signal->length() - TrigAttrInfo::StaticLength;
-
- if(trg->getAttrInfoType() == TrigAttrInfo::BEFORE_VALUES){
- jam();
-
- ndbrequire(b_bufferLock == trigId);
-
- memcpy(b_buffer + b_trigBufferSize, trg->getData(), 4 * dataLen);
- b_trigBufferSize += dataLen;
-
- // printf("before values %u %u %u\n",trigId, dataLen, b_trigBufferSize);
- } else {
- jam();
-
- if(f_bufferLock == 0){
- f_bufferLock = trigId;
- f_trigBufferSize = 0;
- b_bufferLock = trigId;
- b_trigBufferSize = 0;
- } else {
- ndbrequire(f_bufferLock == trigId);
- }
-
- memcpy(f_buffer + f_trigBufferSize, trg->getData(), 4 * dataLen);
- f_trigBufferSize += dataLen;
- }
-
-
- DBUG_VOID_RETURN;
-}
-
-#ifdef NODEFAIL_DEBUG2
-static int theCounts[64] = {0};
-#endif
-
-Uint32
-Suma::get_responsible_node(Uint32 bucket) const
-{
- // id will contain id to responsible suma or
- // RNIL if we don't have nodegroup info yet
-
- jam();
- Uint32 node;
- const Bucket* ptr= c_buckets + bucket;
- for(Uint32 i = 0; i<MAX_REPLICAS; i++)
- {
- node= ptr->m_nodes[i];
- if(c_alive_nodes.get(node))
- {
- break;
- }
- }
-
-
-#ifdef NODEFAIL_DEBUG2
- if(node != 0)
- {
- theCounts[node]++;
- ndbout_c("Suma:responsible n=%u, D=%u, id = %u, count=%u",
- n,D, id, theCounts[node]);
- }
-#endif
- return node;
-}
-
-Uint32
-Suma::get_responsible_node(Uint32 bucket, const NdbNodeBitmask& mask) const
-{
- jam();
- Uint32 node;
- const Bucket* ptr= c_buckets + bucket;
- for(Uint32 i = 0; i<MAX_REPLICAS; i++)
- {
- node= ptr->m_nodes[i];
- if(mask.get(node))
- {
- return node;
- }
- }
-
- return 0;
-}
-
-bool
-Suma::check_switchover(Uint32 bucket, Uint32 gci)
-{
- const Uint32 send_mask = (Bucket::BUCKET_STARTING | Bucket::BUCKET_TAKEOVER);
- bool send = c_buckets[bucket].m_state & send_mask;
- ndbassert(m_switchover_buckets.get(bucket));
- if(unlikely(gci >= c_buckets[bucket].m_switchover_gci))
- {
- return send;
- }
- return !send;
-}
-
-static
-Uint32
-reformat(Signal* signal, LinearSectionPtr ptr[3],
- Uint32 * src_1, Uint32 sz_1,
- Uint32 * src_2, Uint32 sz_2)
-{
- Uint32 noOfAttrs = 0, dataLen = 0;
- Uint32 * headers = signal->theData + 25;
- Uint32 * dst = signal->theData + 25 + MAX_ATTRIBUTES_IN_TABLE;
-
- ptr[0].p = headers;
- ptr[1].p = dst;
-
- while(sz_1 > 0){
- jam();
- Uint32 tmp = * src_1 ++;
- * headers ++ = tmp;
- Uint32 len = AttributeHeader::getDataSize(tmp);
- memcpy(dst, src_1, 4 * len);
- dst += len;
- src_1 += len;
-
- noOfAttrs++;
- dataLen += len;
- sz_1 -= (1 + len);
- }
- assert(sz_1 == 0);
-
- ptr[0].sz = noOfAttrs;
- ptr[1].sz = dataLen;
-
- ptr[2].p = src_2;
- ptr[2].sz = sz_2;
-
- return sz_2 > 0 ? 3 : 2;
-}
-
-void
-Suma::execFIRE_TRIG_ORD(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execFIRE_TRIG_ORD");
- ndbassert(signal->getNoOfSections() == 0);
-
- CRASH_INSERTION(13016);
- FireTrigOrd* const trg = (FireTrigOrd*)signal->getDataPtr();
- const Uint32 trigId = trg->getTriggerId();
- const Uint32 hashValue = trg->getHashValue();
- const Uint32 gci = trg->getGCI();
- const Uint32 event = trg->getTriggerEvent();
- const Uint32 any_value = trg->getAnyValue();
- TablePtr tabPtr;
- tabPtr.i = trigId & 0xFFFF;
-
- DBUG_PRINT("enter",("tabPtr.i=%u", tabPtr.i));
- ndbrequire(f_bufferLock == trigId);
- /**
- * Reset f_bufferLock
- */
- f_bufferLock = 0;
- b_bufferLock = 0;
-
- ndbrequire((tabPtr.p = c_tablePool.getPtr(tabPtr.i)) != 0);
- Uint32 tableId = tabPtr.p->m_tableId;
-
- Uint32 bucket= hashValue % c_no_of_buckets;
- m_max_seen_gci = (gci > m_max_seen_gci ? gci : m_max_seen_gci);
- if(m_active_buckets.get(bucket) ||
- (m_switchover_buckets.get(bucket) && (check_switchover(bucket, gci))))
- {
- m_max_sent_gci = (gci > m_max_sent_gci ? gci : m_max_sent_gci);
- Uint32 sz = trg->getNoOfPrimaryKeyWords()+trg->getNoOfAfterValueWords();
- ndbrequire(sz == f_trigBufferSize);
-
- LinearSectionPtr ptr[3];
- const Uint32 nptr= reformat(signal, ptr,
- f_buffer, sz, b_buffer, b_trigBufferSize);
- Uint32 ptrLen= 0;
- for(Uint32 i =0; i < nptr; i++)
- ptrLen+= ptr[i].sz;
- /**
- * Signal to subscriber(s)
- */
- ndbrequire((tabPtr.p = c_tablePool.getPtr(tabPtr.i)) != 0);
-
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg;
- data->gci = gci;
- data->tableId = tableId;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo, event);
- data->logType = 0;
- data->anyValue = any_value;
- data->totalLen = ptrLen;
-
- {
- LocalDLList<Subscriber> list(c_subscriberPool,tabPtr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(list.first(subbPtr); !subbPtr.isNull(); list.next(subbPtr))
- {
- DBUG_PRINT("info",("GSN_SUB_TABLE_DATA to node %d",
- refToNode(subbPtr.p->m_senderRef)));
- data->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB, ptr, nptr);
- }
- }
- }
- else
- {
- const uint buffer_header_sz = 4;
- Uint32* dst;
- Uint32 sz = f_trigBufferSize + b_trigBufferSize + buffer_header_sz;
- if((dst = get_buffer_ptr(signal, bucket, gci, sz)))
- {
- * dst++ = tableId;
- * dst++ = tabPtr.p->m_schemaVersion;
- * dst++ = (event << 16) | f_trigBufferSize;
- * dst++ = any_value;
- memcpy(dst, f_buffer, f_trigBufferSize << 2);
- dst += f_trigBufferSize;
- memcpy(dst, b_buffer, b_trigBufferSize << 2);
- }
- }
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_GCP_COMPLETE_REP(Signal* signal)
-{
- jamEntry();
- ndbassert(signal->getNoOfSections() == 0);
-
- SubGcpCompleteRep * rep = (SubGcpCompleteRep*)signal->getDataPtrSend();
- Uint32 gci = m_last_complete_gci = rep->gci;
- m_max_seen_gci = (gci > m_max_seen_gci ? gci : m_max_seen_gci);
-
- /**
- *
- */
- if(!m_switchover_buckets.isclear())
- {
- NdbNodeBitmask takeover_nodes;
- NdbNodeBitmask handover_nodes;
- Uint32 i = m_switchover_buckets.find(0);
- for(; i != Bucket_mask::NotFound; i = m_switchover_buckets.find(i + 1))
- {
- if(c_buckets[i].m_switchover_gci == gci)
- {
- Uint32 state = c_buckets[i].m_state;
- m_switchover_buckets.clear(i);
- printf("switchover complete bucket %d state: %x", i, state);
- if(state & Bucket::BUCKET_STARTING)
- {
- /**
- * NR case
- */
- m_active_buckets.set(i);
- c_buckets[i].m_state &= ~(Uint32)Bucket::BUCKET_STARTING;
- ndbout_c("starting");
- m_gcp_complete_rep_count = 1;
- }
- else if(state & Bucket::BUCKET_TAKEOVER)
- {
- /**
- * NF case
- */
- Bucket* bucket= c_buckets + i;
- Page_pos pos= bucket->m_buffer_head;
- ndbrequire(pos.m_max_gci < gci);
-
- Buffer_page* page= (Buffer_page*)
- m_tup->c_page_pool.getPtr(pos.m_page_id);
- ndbout_c("takeover %d", pos.m_page_id);
- page->m_max_gci = pos.m_max_gci;
- page->m_words_used = pos.m_page_pos;
- page->m_next_page = RNIL;
- memset(&bucket->m_buffer_head, 0, sizeof(bucket->m_buffer_head));
- bucket->m_buffer_head.m_page_id = RNIL;
- bucket->m_buffer_head.m_page_pos = Buffer_page::DATA_WORDS + 1;
-
- m_active_buckets.set(i);
- c_buckets[i].m_state &= ~(Uint32)Bucket::BUCKET_TAKEOVER;
- takeover_nodes.set(c_buckets[i].m_switchover_node);
- }
- else
- {
- /**
- * NR, living node
- */
- ndbrequire(state & Bucket::BUCKET_HANDOVER);
- c_buckets[i].m_state &= ~(Uint32)Bucket::BUCKET_HANDOVER;
- handover_nodes.set(c_buckets[i].m_switchover_node);
- ndbout_c("handover");
- }
- }
- }
- ndbassert(handover_nodes.count() == 0 ||
- m_gcp_complete_rep_count > handover_nodes.count());
- m_gcp_complete_rep_count -= handover_nodes.count();
- m_gcp_complete_rep_count += takeover_nodes.count();
-
- if(getNodeState().startLevel == NodeState::SL_STARTING &&
- m_switchover_buckets.isclear() &&
- c_startup.m_handover_nodes.isclear())
- {
- sendSTTORRY(signal);
- }
- }
-
- if(ERROR_INSERTED(13010))
- {
- CLEAR_ERROR_INSERT_VALUE;
- ndbout_c("Don't send GCP_COMPLETE_REP(%d)", gci);
- return;
- }
-
- /**
- * Signal to subscribers
- */
- rep->gci = gci;
- rep->senderRef = reference();
- rep->gcp_complete_rep_count = m_gcp_complete_rep_count;
-
- if(m_gcp_complete_rep_count && !c_subscriber_nodes.isclear())
- {
- CRASH_INSERTION(13033);
-
- NodeReceiverGroup rg(API_CLUSTERMGR, c_subscriber_nodes);
- sendSignal(rg, GSN_SUB_GCP_COMPLETE_REP, signal,
- SubGcpCompleteRep::SignalLength, JBB);
-
- Ptr<Gcp_record> gcp;
- if(c_gcp_list.seize(gcp))
- {
- gcp.p->m_gci = gci;
- gcp.p->m_subscribers = c_subscriber_nodes;
- }
- }
-
- /**
- * Add GCP COMPLETE REP to buffer
- */
- for(Uint32 i = 0; i<c_no_of_buckets; i++)
- {
- if(m_active_buckets.get(i))
- continue;
-
- if (!c_subscriber_nodes.isclear())
- {
- //Uint32* dst;
- get_buffer_ptr(signal, i, gci, 0);
- }
- }
-
- if(gci == m_out_of_buffer_gci)
- {
- infoEvent("Reenable event buffer");
- m_out_of_buffer_gci = 0;
- }
-}
-
-void
-Suma::execCREATE_TAB_CONF(Signal *signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execCREATE_TAB_CONF");
-
-#if 0
- CreateTabConf * const conf = (CreateTabConf*)signal->getDataPtr();
- Uint32 tableId = conf->senderData;
-
- TablePtr tabPtr;
- initTable(signal,tableId,tabPtr);
-#endif
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execDROP_TAB_CONF(Signal *signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execDROP_TAB_CONF");
- ndbassert(signal->getNoOfSections() == 0);
-
- DropTabConf * const conf = (DropTabConf*)signal->getDataPtr();
- Uint32 senderRef= conf->senderRef;
- Uint32 tableId= conf->tableId;
-
- TablePtr tabPtr;
- if (!c_tables.find(tabPtr, tableId) ||
- tabPtr.p->m_state == Table::DROPPED ||
- tabPtr.p->m_state == Table::ALTERED)
- {
- DBUG_VOID_RETURN;
- }
-
- DBUG_PRINT("info",("drop table id: %d[i=%u]", tableId, tabPtr.i));
-
- tabPtr.p->m_state = Table::DROPPED;
- for (int j= 0; j < 3; j++)
- {
- if (!tabPtr.p->m_hasOutstandingTriggerReq[j])
- {
- tabPtr.p->m_hasTriggerDefined[j] = 0;
- tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
- tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
- }
- else
- tabPtr.p->m_hasTriggerDefined[j] = 1;
- }
- if (senderRef == 0)
- {
- DBUG_VOID_RETURN;
- }
- // dict coordinator sends info to API
-
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();
- data->gci = m_last_complete_gci+1;
- data->tableId = tableId;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo,NdbDictionary::Event::_TE_DROP);
- SubTableData::setReqNodeId(data->requestInfo, refToNode(senderRef));
-
- {
- LocalDLList<Subscriber> subbs(c_subscriberPool,tabPtr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(subbs.first(subbPtr);!subbPtr.isNull();subbs.next(subbPtr))
- {
- jam();
- /*
- * get subscription ptr for this subscriber
- */
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
- if(subPtr.p->m_subscriptionType != SubCreateReq::TableEvent) {
- jam();
- continue;
- //continue in for-loop if the table is not part of
- //the subscription. Otherwise, send data to subscriber.
- }
- data->senderData= subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB);
- DBUG_PRINT("info",("sent to subscriber %d", subbPtr.i));
- }
- }
- DBUG_VOID_RETURN;
-}
-
-static Uint32 b_dti_buf[MAX_WORDS_META_FILE];
-
-void
-Suma::execALTER_TAB_REQ(Signal *signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execALTER_TAB_REQ");
- ndbassert(signal->getNoOfSections() == 1);
-
- AlterTabReq * const req = (AlterTabReq*)signal->getDataPtr();
- Uint32 senderRef= req->senderRef;
- Uint32 tableId= req->tableId;
- Uint32 changeMask= req->changeMask;
- TablePtr tabPtr;
- if (!c_tables.find(tabPtr, tableId) ||
- tabPtr.p->m_state == Table::DROPPED ||
- tabPtr.p->m_state == Table::ALTERED)
- {
- DBUG_VOID_RETURN;
- }
-
- DBUG_PRINT("info",("alter table id: %d[i=%u]", tableId, tabPtr.i));
- Table::State old_state = tabPtr.p->m_state;
- tabPtr.p->m_state = Table::ALTERED;
- // triggers must be removed, waiting for sub stop req for that
-
- if (senderRef == 0)
- {
- DBUG_VOID_RETURN;
- }
- // dict coordinator sends info to API
-
- // Copy DICT_TAB_INFO to local buffer
- SegmentedSectionPtr tabInfoPtr;
- signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
-#ifndef DBUG_OFF
- ndbout_c("DICT_TAB_INFO in SUMA, tabInfoPtr.sz = %d", tabInfoPtr.sz);
- SimplePropertiesSectionReader reader(tabInfoPtr, getSectionSegmentPool());
- reader.printAll(ndbout);
-#endif
- copy(b_dti_buf, tabInfoPtr);
- LinearSectionPtr ptr[3];
- ptr[0].p = b_dti_buf;
- ptr[0].sz = tabInfoPtr.sz;
-
- releaseSections(signal);
-
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();
- data->gci = m_last_complete_gci+1;
- data->tableId = tableId;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo,
- NdbDictionary::Event::_TE_ALTER);
- SubTableData::setReqNodeId(data->requestInfo, refToNode(senderRef));
- data->logType = 0;
- data->changeMask = changeMask;
- data->totalLen = tabInfoPtr.sz;
- {
- LocalDLList<Subscriber> subbs(c_subscriberPool,tabPtr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(subbs.first(subbPtr);!subbPtr.isNull();subbs.next(subbPtr))
- {
- jam();
- /*
- * get subscription ptr for this subscriber
- */
- SubscriptionPtr subPtr;
- c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
- if(subPtr.p->m_subscriptionType != SubCreateReq::TableEvent) {
- jam();
- continue;
- //continue in for-loop if the table is not part of
- //the subscription. Otherwise, send data to subscriber.
- }
-
- data->senderData= subbPtr.p->m_senderData;
- Callback c = { 0, 0 };
- sendFragmentedSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB, ptr, 1, c);
- DBUG_PRINT("info",("sent to subscriber %d", subbPtr.i));
- }
- }
- if (AlterTableReq::getFrmFlag(changeMask))
- {
- // Frm changes only are handled on-line
- tabPtr.p->m_state = old_state;
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_GCP_COMPLETE_ACK(Signal* signal)
-{
- jamEntry();
- ndbassert(signal->getNoOfSections() == 0);
-
- SubGcpCompleteAck * const ack = (SubGcpCompleteAck*)signal->getDataPtr();
- Uint32 gci = ack->rep.gci;
- Uint32 senderRef = ack->rep.senderRef;
- m_max_seen_gci = (gci > m_max_seen_gci ? gci : m_max_seen_gci);
-
- if (refToBlock(senderRef) == SUMA) {
- jam();
- // Ack from other SUMA
- Uint32 nodeId= refToNode(senderRef);
- for(Uint32 i = 0; i<c_no_of_buckets; i++)
- {
- if(m_active_buckets.get(i) ||
- (m_switchover_buckets.get(i) && (check_switchover(i, gci))) ||
- (!m_switchover_buckets.get(i) && get_responsible_node(i) == nodeId))
- {
- release_gci(signal, i, gci);
- }
- }
- return;
- }
-
- // Ack from User and not an ack from other SUMA, redistribute in nodegroup
-
- Uint32 nodeId = refToNode(senderRef);
-
- jam();
- Ptr<Gcp_record> gcp;
- for(c_gcp_list.first(gcp); !gcp.isNull(); c_gcp_list.next(gcp))
- {
- if(gcp.p->m_gci == gci)
- {
- gcp.p->m_subscribers.clear(nodeId);
- if(!gcp.p->m_subscribers.isclear())
- {
- jam();
- return;
- }
- break;
- }
- }
-
- if(gcp.isNull())
- {
- ndbout_c("ACK wo/ gcp record (gci: %d)", gci);
- }
- else
- {
- c_gcp_list.release(gcp);
- }
-
- CRASH_INSERTION(13011);
- if(ERROR_INSERTED(13012))
- {
- CLEAR_ERROR_INSERT_VALUE;
- ndbout_c("Don't redistribute SUB_GCP_COMPLETE_ACK");
- return;
- }
-
- ack->rep.senderRef = reference();
- NodeReceiverGroup rg(SUMA, c_nodes_in_nodegroup_mask);
- sendSignal(rg, GSN_SUB_GCP_COMPLETE_ACK, signal,
- SubGcpCompleteAck::SignalLength, JBB);
-}
-
-/**************************************************************
- *
- * Removing subscription
- *
- */
-
-void
-Suma::execSUB_REMOVE_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUB_REMOVE_REQ");
- ndbassert(signal->getNoOfSections() == 0);
-
- CRASH_INSERTION(13021);
-
- const SubRemoveReq req = *(SubRemoveReq*)signal->getDataPtr();
- SubscriptionPtr subPtr;
- Subscription key;
- key.m_subscriptionId = req.subscriptionId;
- key.m_subscriptionKey = req.subscriptionKey;
-
- DBUG_PRINT("enter",("key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
- key.m_subscriptionId, key.m_subscriptionKey));
-
- if(!c_subscriptions.find(subPtr, key))
- {
- jam();
- DBUG_PRINT("info",("Not found"));
- sendSubRemoveRef(signal, req, 1407);
- DBUG_VOID_RETURN;
- }
- if (subPtr.p->m_state == Subscription::LOCKED)
- {
- /**
- * we are currently setting up triggers etc. for this event
- */
- jam();
- sendSubRemoveRef(signal, req, 1413);
- DBUG_VOID_RETURN;
- }
- if (subPtr.p->m_state == Subscription::DROPPED)
- {
- /**
- * already dropped
- */
- jam();
- sendSubRemoveRef(signal, req, 1419);
- DBUG_VOID_RETURN;
- }
-
- ndbrequire(subPtr.p->m_state == Subscription::DEFINED);
- DBUG_PRINT("info",("n_subscribers: %u", subPtr.p->n_subscribers));
-
- if (subPtr.p->n_subscribers == 0)
- {
- // no subscribers on the subscription
- // remove it
- jam();
- completeSubRemove(subPtr);
- }
- else
- {
- // subscribers left on the subscription
- // mark it to be removed once all subscribers
- // are removed
- jam();
- subPtr.p->m_state = Subscription::DROPPED;
- }
-
- SubRemoveConf * const conf = (SubRemoveConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = req.senderData;
- conf->subscriptionId = req.subscriptionId;
- conf->subscriptionKey = req.subscriptionKey;
-
- sendSignal(req.senderRef, GSN_SUB_REMOVE_CONF, signal,
- SubRemoveConf::SignalLength, JBB);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::completeSubRemove(SubscriptionPtr subPtr)
-{
- DBUG_ENTER("Suma::completeSubRemove");
- //Uint32 subscriptionId = subPtr.p->m_subscriptionId;
- //Uint32 subscriptionKey = subPtr.p->m_subscriptionKey;
-
- c_subscriptions.release(subPtr);
- DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d",
- c_subscriptionPool.getSize(),
- c_subscriptionPool.getNoOfFree()));
-
- /**
- * I was the last subscription to be remove so clear c_tables
- */
-#if 0
- ndbout_c("c_subscriptionPool.getSize() %d c_subscriptionPool.getNoOfFree()%d",
- c_subscriptionPool.getSize(),c_subscriptionPool.getNoOfFree());
-#endif
-
- if(c_subscriptionPool.getSize() == c_subscriptionPool.getNoOfFree()) {
- jam();
-#if 0
- ndbout_c("SUB_REMOVE_REQ:Clearing c_tables");
-#endif
- int count= 0;
- KeyTable<Table>::Iterator it;
- for(c_tables.first(it); !it.isNull(); )
- {
- // ndbrequire(false);
-
- DBUG_PRINT("error",("trailing table id: %d[i=%d] n_subscribers: %d m_state: %d",
- it.curr.p->m_tableId,
- it.curr.p->m_ptrI,
- it.curr.p->n_subscribers,
- it.curr.p->m_state));
-
- LocalDLList<Subscriber> subbs(c_subscriberPool,it.curr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(subbs.first(subbPtr);!subbPtr.isNull();subbs.next(subbPtr))
- {
- DBUG_PRINT("error",("subscriber %d, m_subPtrI: %d", subbPtr.i, subbPtr.p->m_subPtrI));
- }
-
- it.curr.p->release(* this);
- TablePtr tabPtr = it.curr;
- c_tables.next(it);
- c_tables.remove(tabPtr);
- c_tablePool.release(tabPtr);
- DBUG_PRINT("info",("c_tablePool size: %d free: %d",
- c_tablePool.getSize(),
- c_tablePool.getNoOfFree()));
- count++;
- }
- DBUG_ASSERT(count == 0);
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::sendSubRemoveRef(Signal* signal, const SubRemoveReq& req,
- Uint32 errCode)
-{
- jam();
- DBUG_ENTER("Suma::sendSubRemoveRef");
- SubRemoveRef * ref = (SubRemoveRef *)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = req.senderData;
- ref->subscriptionId = req.subscriptionId;
- ref->subscriptionKey = req.subscriptionKey;
- ref->errorCode = errCode;
- releaseSections(signal);
- sendSignal(signal->getSendersBlockRef(), GSN_SUB_REMOVE_REF,
- signal, SubRemoveRef::SignalLength, JBB);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Table::release(Suma & suma){
- jam();
-
- LocalDataBuffer<15> attrBuf(suma.c_dataBufferPool, m_attributes);
- attrBuf.release();
-
- LocalDataBuffer<15> fragBuf(suma.c_dataBufferPool, m_fragments);
- fragBuf.release();
-
- m_state = UNDEFINED;
-#ifndef DBUG_OFF
- if (n_subscribers != 0)
- abort();
-#endif
-}
-
-void
-Suma::SyncRecord::release(){
- jam();
- m_tableList.release();
-
- LocalDataBuffer<15> attrBuf(suma.c_dataBufferPool, m_attributeList);
- attrBuf.release();
-}
-
-
-/**************************************************************
- *
- * Restarting remote node functions, master functionality
- * (slave does nothing special)
- * - triggered on INCL_NODEREQ calling startNode
- * - included node will issue START_ME when it's ready to start
- * the subscribers
- *
- */
-
-void
-Suma::execSUMA_START_ME_REQ(Signal* signal) {
- jamEntry();
- DBUG_ENTER("Suma::execSUMA_START_ME");
- ndbassert(signal->getNoOfSections() == 0);
- Restart.runSUMA_START_ME_REQ(signal, signal->getSendersBlockRef());
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_CREATE_REF(Signal* signal) {
- jamEntry();
- DBUG_ENTER("Suma::execSUB_CREATE_REF");
- ndbassert(signal->getNoOfSections() == 0);
- SubCreateRef *const ref= (SubCreateRef *)signal->getDataPtr();
- Uint32 error= ref->errorCode;
- if (error != 1415)
- {
- /*
- * This will happen if an api node connects during while other node
- * is restarting, and in this case the subscription will already
- * have been created.
- * ToDo: more complete handling of api nodes joining during
- * node restart
- */
- Uint32 senderRef = signal->getSendersBlockRef();
- BlockReference cntrRef = calcNdbCntrBlockRef(refToNode(senderRef));
- // for some reason we did not manage to create a subscription
- // on the starting node
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::CopySubscriptionRef;
- sysErr->errorRef = reference();
- sysErr->data1 = error;
- sysErr->data2 = 0;
- sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBB);
- Restart.resetRestart(signal);
- DBUG_VOID_RETURN;
- }
- // SubCreateConf has same signaldata as SubCreateRef
- Restart.runSUB_CREATE_CONF(signal);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_CREATE_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUB_CREATE_CONF");
- ndbassert(signal->getNoOfSections() == 0);
- Restart.runSUB_CREATE_CONF(signal);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_START_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUB_START_CONF");
- ndbassert(signal->getNoOfSections() == 0);
- Restart.runSUB_START_CONF(signal);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::execSUB_START_REF(Signal* signal) {
- jamEntry();
- DBUG_ENTER("Suma::execSUB_START_REF");
- ndbassert(signal->getNoOfSections() == 0);
- SubStartRef *const ref= (SubStartRef *)signal->getDataPtr();
- Uint32 error= ref->errorCode;
- {
- Uint32 senderRef = signal->getSendersBlockRef();
- BlockReference cntrRef = calcNdbCntrBlockRef(refToNode(senderRef));
- // for some reason we did not manage to start a subscriber
- // on the starting node
- SystemError * const sysErr = (SystemError*)&signal->theData[0];
- sysErr->errorCode = SystemError::CopySubscriberRef;
- sysErr->errorRef = reference();
- sysErr->data1 = error;
- sysErr->data2 = 0;
- sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
- SystemError::SignalLength, JBB);
- Restart.resetRestart(signal);
- }
- DBUG_VOID_RETURN;
-}
-
-Suma::Restart::Restart(Suma& s) : suma(s)
-{
- nodeId = 0;
-}
-
-void
-Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::runSUMA_START_ME");
-
- if(nodeId != 0)
- {
- SumaStartMeRef* ref= (SumaStartMeRef*)signal->getDataPtrSend();
- ref->errorCode = SumaStartMeRef::Busy;
- suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal,
- SumaStartMeRef::SignalLength, JBB);
- DBUG_VOID_RETURN;
- }
-
- nodeId = refToNode(sumaRef);
- startNode(signal, sumaRef);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::startNode(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::startNode");
-
- // right now we can only handle restarting one node
- // at a time in a node group
-
- createSubscription(signal, sumaRef);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::createSubscription(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::createSubscription");
- suma.c_subscriptions.first(c_subIt);
- nextSubscription(signal, sumaRef);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::nextSubscription(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::nextSubscription");
-
- if (c_subIt.isNull())
- {
- jam();
- completeSubscription(signal, sumaRef);
- DBUG_VOID_RETURN;
- }
- SubscriptionPtr subPtr;
- subPtr.i = c_subIt.curr.i;
- subPtr.p = suma.c_subscriptions.getPtr(subPtr.i);
-
- suma.c_subscriptions.next(c_subIt);
-
- SubCreateReq * req = (SubCreateReq *)signal->getDataPtrSend();
-
- req->senderRef = suma.reference();
- req->senderData = subPtr.i;
- req->subscriptionId = subPtr.p->m_subscriptionId;
- req->subscriptionKey = subPtr.p->m_subscriptionKey;
- req->subscriptionType = subPtr.p->m_subscriptionType |
- SubCreateReq::RestartFlag;
-
- switch (subPtr.p->m_subscriptionType) {
- case SubCreateReq::TableEvent:
- jam();
- req->tableId = subPtr.p->m_tableId;
- req->state = subPtr.p->m_state;
- suma.sendSignal(sumaRef, GSN_SUB_CREATE_REQ, signal,
- SubCreateReq::SignalLength2, JBB);
- DBUG_VOID_RETURN;
- case SubCreateReq::SingleTableScan:
- jam();
- nextSubscription(signal, sumaRef);
- DBUG_VOID_RETURN;
- case SubCreateReq::SelectiveTableSnapshot:
- case SubCreateReq::DatabaseSnapshot:
- ndbrequire(false);
- }
- ndbrequire(false);
-}
-
-void
-Suma::Restart::runSUB_CREATE_CONF(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::Restart::runSUB_CREATE_CONF");
-
- const Uint32 senderRef = signal->senderBlockRef();
- Uint32 sumaRef = signal->getSendersBlockRef();
-
- SubCreateConf * const conf = (SubCreateConf *)signal->getDataPtr();
-
- SubscriptionPtr subPtr;
- suma.c_subscriptions.getPtr(subPtr,conf->senderData);
-
- switch(subPtr.p->m_subscriptionType) {
- case SubCreateReq::TableEvent:
- if (1)
- {
- jam();
- nextSubscription(signal, sumaRef);
- } else {
- jam();
- SubCreateReq * req = (SubCreateReq *)signal->getDataPtrSend();
-
- req->senderRef = suma.reference();
- req->senderData = subPtr.i;
- req->subscriptionId = subPtr.p->m_subscriptionId;
- req->subscriptionKey = subPtr.p->m_subscriptionKey;
- req->subscriptionType = subPtr.p->m_subscriptionType |
- SubCreateReq::RestartFlag |
- SubCreateReq::AddTableFlag;
-
- req->tableId = 0;
-
- suma.sendSignal(senderRef, GSN_SUB_CREATE_REQ, signal,
- SubCreateReq::SignalLength, JBB);
- }
- DBUG_VOID_RETURN;
- case SubCreateReq::SingleTableScan:
- case SubCreateReq::SelectiveTableSnapshot:
- case SubCreateReq::DatabaseSnapshot:
- ndbrequire(false);
- }
- ndbrequire(false);
-}
-
-void
-Suma::Restart::completeSubscription(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::completeSubscription");
- startSubscriber(signal, sumaRef);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::startSubscriber(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::startSubscriber");
- suma.c_tables.first(c_tabIt);
- if (c_tabIt.isNull())
- {
- completeSubscriber(signal, sumaRef);
- DBUG_VOID_RETURN;
- }
- SubscriberPtr subbPtr;
- {
- LocalDLList<Subscriber>
- subbs(suma.c_subscriberPool,c_tabIt.curr.p->c_subscribers);
- subbs.first(subbPtr);
- }
- nextSubscriber(signal, sumaRef, subbPtr);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::nextSubscriber(Signal* signal, Uint32 sumaRef,
- SubscriberPtr subbPtr)
-{
- jam();
- DBUG_ENTER("Suma::Restart::nextSubscriber");
- while (subbPtr.isNull())
- {
- jam();
- DBUG_PRINT("info",("prev tableId %u",c_tabIt.curr.p->m_tableId));
- suma.c_tables.next(c_tabIt);
- if (c_tabIt.isNull())
- {
- completeSubscriber(signal, sumaRef);
- DBUG_VOID_RETURN;
- }
- DBUG_PRINT("info",("next tableId %u",c_tabIt.curr.p->m_tableId));
-
- LocalDLList<Subscriber>
- subbs(suma.c_subscriberPool,c_tabIt.curr.p->c_subscribers);
- subbs.first(subbPtr);
- }
-
- /*
- * get subscription ptr for this subscriber
- */
-
- SubscriptionPtr subPtr;
- suma.c_subscriptions.getPtr(subPtr, subbPtr.p->m_subPtrI);
- switch (subPtr.p->m_subscriptionType) {
- case SubCreateReq::TableEvent:
- jam();
- sendSubStartReq(subPtr, subbPtr, signal, sumaRef);
- DBUG_VOID_RETURN;
- case SubCreateReq::SelectiveTableSnapshot:
- case SubCreateReq::DatabaseSnapshot:
- case SubCreateReq::SingleTableScan:
- ndbrequire(false);
- }
- ndbrequire(false);
-}
-
-void
-Suma::Restart::sendSubStartReq(SubscriptionPtr subPtr, SubscriberPtr subbPtr,
- Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::sendSubStartReq");
- SubStartReq * req = (SubStartReq *)signal->getDataPtrSend();
-
- req->senderRef = suma.reference();
- req->senderData = subbPtr.i;
- req->subscriptionId = subPtr.p->m_subscriptionId;
- req->subscriptionKey = subPtr.p->m_subscriptionKey;
- req->part = SubscriptionData::TableData;
- req->subscriberData = subbPtr.p->m_senderData;
- req->subscriberRef = subbPtr.p->m_senderRef;
-
- // restarting suma will not respond to this until startphase 5
- // since it is not until then data copying has been completed
- DBUG_PRINT("info",("Restarting subscriber: %u on key: [%u,%u] %u",
- subbPtr.i,
- subPtr.p->m_subscriptionId,
- subPtr.p->m_subscriptionKey,
- subPtr.p->m_tableId));
-
- suma.sendSignal(sumaRef, GSN_SUB_START_REQ,
- signal, SubStartReq::SignalLength2, JBB);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::runSUB_START_CONF(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::Restart::runSUB_START_CONF");
-
- SubStartConf * const conf = (SubStartConf*)signal->getDataPtr();
-
- Subscription key;
- SubscriptionPtr subPtr;
- key.m_subscriptionId = conf->subscriptionId;
- key.m_subscriptionKey = conf->subscriptionKey;
- ndbrequire(suma.c_subscriptions.find(subPtr, key));
-
- TablePtr tabPtr;
- ndbrequire(suma.c_tables.find(tabPtr, subPtr.p->m_tableId));
-
- SubscriberPtr subbPtr;
- {
- LocalDLList<Subscriber>
- subbs(suma.c_subscriberPool,tabPtr.p->c_subscribers);
- subbs.getPtr(subbPtr, conf->senderData);
- DBUG_PRINT("info",("Restarted subscriber: %u on key: [%u,%u] table: %u",
- subbPtr.i,key.m_subscriptionId,key.m_subscriptionKey,
- subPtr.p->m_tableId));
- subbs.next(subbPtr);
- }
-
- Uint32 sumaRef = signal->getSendersBlockRef();
- nextSubscriber(signal, sumaRef, subbPtr);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::completeSubscriber(Signal* signal, Uint32 sumaRef)
-{
- DBUG_ENTER("Suma::Restart::completeSubscriber");
- completeRestartingNode(signal, sumaRef);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::completeRestartingNode(Signal* signal, Uint32 sumaRef)
-{
- jam();
- DBUG_ENTER("Suma::Restart::completeRestartingNode");
- //SumaStartMeConf *conf= (SumaStartMeConf*)signal->getDataPtrSend();
- suma.sendSignal(sumaRef, GSN_SUMA_START_ME_CONF, signal,
- SumaStartMeConf::SignalLength, JBB);
- resetRestart(signal);
- DBUG_VOID_RETURN;
-}
-
-void
-Suma::Restart::resetRestart(Signal* signal)
-{
- jam();
- DBUG_ENTER("Suma::Restart::resetRestart");
- nodeId = 0;
- DBUG_VOID_RETURN;
-}
-
-// only run on restarting suma
-
-void
-Suma::execSUMA_HANDOVER_REQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Suma::execSUMA_HANDOVER_REQ");
- // Uint32 sumaRef = signal->getSendersBlockRef();
- SumaHandoverReq const * req = (SumaHandoverReq *)signal->getDataPtr();
-
- Uint32 gci = req->gci;
- Uint32 nodeId = req->nodeId;
- Uint32 new_gci = m_last_complete_gci + MAX_CONCURRENT_GCP + 1;
-
- Uint32 start_gci = (gci > new_gci ? gci : new_gci);
- // mark all active buckets really belonging to restarting SUMA
-
- Bucket_mask tmp;
- for( Uint32 i = 0; i < c_no_of_buckets; i++)
- {
- if(get_responsible_node(i) == nodeId)
- {
- if (m_active_buckets.get(i))
- {
- // I'm running this bucket but it should really be the restarted node
- tmp.set(i);
- m_active_buckets.clear(i);
- m_switchover_buckets.set(i);
- c_buckets[i].m_switchover_gci = start_gci;
- c_buckets[i].m_state |= Bucket::BUCKET_HANDOVER;
- c_buckets[i].m_switchover_node = nodeId;
- ndbout_c("prepare to handover bucket: %d", i);
- }
- else if(m_switchover_buckets.get(i))
- {
- ndbout_c("dont handover bucket: %d %d", i, nodeId);
- }
- }
- }
-
- SumaHandoverConf* conf= (SumaHandoverConf*)signal->getDataPtrSend();
- tmp.copyto(BUCKET_MASK_SIZE, conf->theBucketMask);
- conf->gci = start_gci;
- conf->nodeId = getOwnNodeId();
- sendSignal(calcSumaBlockRef(nodeId), GSN_SUMA_HANDOVER_CONF, signal,
- SumaHandoverConf::SignalLength, JBB);
-
- DBUG_VOID_RETURN;
-}
-
-// only run on all but restarting suma
-void
-Suma::execSUMA_HANDOVER_REF(Signal* signal)
-{
- ndbrequire(false);
-}
-
-void
-Suma::execSUMA_HANDOVER_CONF(Signal* signal) {
- jamEntry();
- DBUG_ENTER("Suma::execSUMA_HANDOVER_CONF");
-
- SumaHandoverConf const * conf = (SumaHandoverConf *)signal->getDataPtr();
-
- Uint32 gci = conf->gci;
- Uint32 nodeId = conf->nodeId;
- Bucket_mask tmp;
- tmp.assign(BUCKET_MASK_SIZE, conf->theBucketMask);
-#ifdef HANDOVER_DEBUG
- ndbout_c("Suma::execSUMA_HANDOVER_CONF, gci = %u", gci);
-#endif
-
- for( Uint32 i = 0; i < c_no_of_buckets; i++)
- {
- if (tmp.get(i))
- {
- ndbrequire(get_responsible_node(i) == getOwnNodeId());
- // We should run this bucket, but _nodeId_ is
- c_buckets[i].m_switchover_gci = gci;
- c_buckets[i].m_state |= Bucket::BUCKET_STARTING;
- }
- }
-
- char buf[255];
- tmp.getText(buf);
- infoEvent("Suma: handover from node %d gci: %d buckets: %s (%d)",
- nodeId, gci, buf, c_no_of_buckets);
- m_switchover_buckets.bitOR(tmp);
- c_startup.m_handover_nodes.clear(nodeId);
- DBUG_VOID_RETURN;
-}
-
-#ifdef NOT_USED
-static
-NdbOut&
-operator<<(NdbOut & out, const Suma::Page_pos & pos)
-{
- out << "[ Page_pos:"
- << " m_page_id: " << pos.m_page_id
- << " m_page_pos: " << pos.m_page_pos
- << " m_max_gci: " << pos.m_max_gci
- << " ]";
- return out;
-}
-#endif
-
-Uint32*
-Suma::get_buffer_ptr(Signal* signal, Uint32 buck, Uint32 gci, Uint32 sz)
-{
- sz += 1; // len
- Bucket* bucket= c_buckets+buck;
- Page_pos pos= bucket->m_buffer_head;
-
- Buffer_page* page = 0;
- Uint32 *ptr = 0;
-
- if (likely(pos.m_page_id != RNIL))
- {
- page= (Buffer_page*)m_tup->c_page_pool.getPtr(pos.m_page_id);
- ptr= page->m_data + pos.m_page_pos;
- }
-
- const bool same_gci = (gci == pos.m_last_gci) && (!ERROR_INSERTED(13022));
-
- pos.m_page_pos += sz;
- pos.m_last_gci = gci;
- Uint32 max = pos.m_max_gci > gci ? pos.m_max_gci : gci;
-
- if(likely(same_gci && pos.m_page_pos <= Buffer_page::DATA_WORDS))
- {
- pos.m_max_gci = max;
- bucket->m_buffer_head = pos;
- * ptr++ = (0x8000 << 16) | sz; // Same gci
- return ptr;
- }
- else if(pos.m_page_pos + 1 <= Buffer_page::DATA_WORDS)
- {
-loop:
- pos.m_max_gci = max;
- pos.m_page_pos += 1;
- bucket->m_buffer_head = pos;
- * ptr++ = (sz + 1);
- * ptr++ = gci;
- return ptr;
- }
- else
- {
- /**
- * new page
- * 1) save header on last page
- * 2) seize new page
- */
- Uint32 next;
- if(unlikely((next= seize_page()) == RNIL))
- {
- /**
- * Out of buffer
- */
- out_of_buffer(signal);
- return 0;
- }
-
- if(likely(pos.m_page_id != RNIL))
- {
- page->m_max_gci = pos.m_max_gci;
- page->m_words_used = pos.m_page_pos - sz;
- page->m_next_page= next;
- }
- else
- {
- bucket->m_buffer_tail = next;
- }
-
- memset(&pos, 0, sizeof(pos));
- pos.m_page_id = next;
- pos.m_page_pos = sz;
- pos.m_last_gci = gci;
-
- page= (Buffer_page*)m_tup->c_page_pool.getPtr(pos.m_page_id);
- page->m_next_page= RNIL;
- ptr= page->m_data;
- goto loop; //
- }
-}
-
-void
-Suma::out_of_buffer(Signal* signal)
-{
- if(m_out_of_buffer_gci)
- {
- return;
- }
-
- m_out_of_buffer_gci = m_last_complete_gci - 1;
- infoEvent("Out of event buffer: nodefailure will cause event failures");
-
- out_of_buffer_release(signal, 0);
-}
-
-void
-Suma::out_of_buffer_release(Signal* signal, Uint32 buck)
-{
- Bucket* bucket= c_buckets+buck;
- Uint32 tail= bucket->m_buffer_tail;
-
- if(tail != RNIL)
- {
- Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
- bucket->m_buffer_tail = page->m_next_page;
- free_page(tail, page);
- signal->theData[0] = SumaContinueB::OUT_OF_BUFFER_RELEASE;
- signal->theData[1] = buck;
- sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- /**
- * Clear head
- */
- bucket->m_buffer_head.m_page_id = RNIL;
- bucket->m_buffer_head.m_page_pos = Buffer_page::DATA_WORDS + 1;
-
- buck++;
- if(buck != c_no_of_buckets)
- {
- signal->theData[0] = SumaContinueB::OUT_OF_BUFFER_RELEASE;
- signal->theData[1] = buck;
- sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- /**
- * Finished will all release
- * prepare for inclusion
- */
- m_out_of_buffer_gci = m_max_seen_gci > m_last_complete_gci
- ? m_max_seen_gci + 1 : m_last_complete_gci + 1;
-}
-
-Uint32
-Suma::seize_page()
-{
- if(unlikely(m_out_of_buffer_gci))
- {
- return RNIL;
- }
-loop:
- Ptr<Page_chunk> ptr;
- Uint32 ref= m_first_free_page;
- if(likely(ref != RNIL))
- {
- m_first_free_page = ((Buffer_page*)m_tup->c_page_pool.getPtr(ref))->m_next_page;
- Uint32 chunk = ((Buffer_page*)m_tup->c_page_pool.getPtr(ref))->m_page_chunk_ptr_i;
- c_page_chunk_pool.getPtr(ptr, chunk);
- ndbassert(ptr.p->m_free);
- ptr.p->m_free--;
- return ref;
- }
-
- if(!c_page_chunk_pool.seize(ptr))
- return RNIL;
-
- Uint32 count;
- m_tup->allocConsPages(16, count, ref);
- if (count == 0)
- return RNIL;
-
- ndbout_c("alloc_chunk(%d %d) - ", ref, count);
-
- m_first_free_page = ptr.p->m_page_id = ref;
- ptr.p->m_size = count;
- ptr.p->m_free = count;
-
- Buffer_page* page;
- LINT_INIT(page);
- for(Uint32 i = 0; i<count; i++)
- {
- page = (Buffer_page*)m_tup->c_page_pool.getPtr(ref);
- page->m_page_state= SUMA_SEQUENCE;
- page->m_page_chunk_ptr_i = ptr.i;
- page->m_next_page = ++ref;
- }
- page->m_next_page = RNIL;
-
- goto loop;
-}
-
-void
-Suma::free_page(Uint32 page_id, Buffer_page* page)
-{
- Ptr<Page_chunk> ptr;
- ndbrequire(page->m_page_state == SUMA_SEQUENCE);
-
- Uint32 chunk= page->m_page_chunk_ptr_i;
-
- c_page_chunk_pool.getPtr(ptr, chunk);
-
- ptr.p->m_free ++;
- page->m_next_page = m_first_free_page;
- ndbrequire(ptr.p->m_free <= ptr.p->m_size);
-
- m_first_free_page = page_id;
-}
-
-void
-Suma::release_gci(Signal* signal, Uint32 buck, Uint32 gci)
-{
- Bucket* bucket= c_buckets+buck;
- Uint32 tail= bucket->m_buffer_tail;
- Page_pos head= bucket->m_buffer_head;
- Uint32 max_acked = bucket->m_max_acked_gci;
-
- const Uint32 mask = Bucket::BUCKET_TAKEOVER | Bucket::BUCKET_RESEND;
- if(unlikely(bucket->m_state & mask))
- {
- jam();
- ndbout_c("release_gci(%d, %d) -> node failure -> abort", buck, gci);
- return;
- }
-
- bucket->m_max_acked_gci = (max_acked > gci ? max_acked : gci);
- if(unlikely(tail == RNIL))
- {
- return;
- }
-
- if(tail == head.m_page_id)
- {
- if(gci >= head.m_max_gci)
- {
- jam();
- if (ERROR_INSERTED(13034))
- {
- jam();
- SET_ERROR_INSERT_VALUE(13035);
- return;
- }
- if (ERROR_INSERTED(13035))
- {
- CLEAR_ERROR_INSERT_VALUE;
- NodeReceiverGroup rg(CMVMI, c_nodes_in_nodegroup_mask);
- rg.m_nodes.clear(getOwnNodeId());
- signal->theData[0] = 9999;
- sendSignal(rg, GSN_NDB_TAMPER, signal, 1, JBA);
- return;
- }
- head.m_page_pos = 0;
- head.m_max_gci = gci;
- head.m_last_gci = 0;
- bucket->m_buffer_head = head;
- }
- return;
- }
- else
- {
- jam();
- Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
- Uint32 max_gci = page->m_max_gci;
- Uint32 next_page = page->m_next_page;
-
- ndbassert(max_gci);
-
- if(gci >= max_gci)
- {
- jam();
- free_page(tail, page);
-
- bucket->m_buffer_tail = next_page;
- signal->theData[0] = SumaContinueB::RELEASE_GCI;
- signal->theData[1] = buck;
- signal->theData[2] = gci;
- sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 3, JBB);
- return;
- }
- else
- {
- //ndbout_c("do nothing...");
- }
- }
-}
-
-static Uint32 g_cnt = 0;
-
-void
-Suma::start_resend(Signal* signal, Uint32 buck)
-{
- printf("start_resend(%d, ", buck);
-
- if(m_out_of_buffer_gci)
- {
- progError(__LINE__, NDBD_EXIT_SYSTEM_ERROR,
- "Nodefailure while out of event buffer");
- return;
- }
-
- /**
- * Resend from m_max_acked_gci + 1 until max_gci + 1
- */
- Bucket* bucket= c_buckets + buck;
- Page_pos pos= bucket->m_buffer_head;
-
- if(pos.m_page_id == RNIL)
- {
- jam();
- m_active_buckets.set(buck);
- m_gcp_complete_rep_count ++;
- ndbout_c("empty bucket(RNIL) -> active");
- return;
- }
-
- Uint32 min= bucket->m_max_acked_gci + 1;
- Uint32 max = pos.m_max_gci;
-
- ndbrequire(max <= m_max_seen_gci);
-
- if(min > max)
- {
- ndbrequire(pos.m_page_id == bucket->m_buffer_tail);
- m_active_buckets.set(buck);
- m_gcp_complete_rep_count ++;
- ndbout_c("empty bucket -> active");
- return;
- }
-
- g_cnt = 0;
- bucket->m_state |= (Bucket::BUCKET_TAKEOVER | Bucket::BUCKET_RESEND);
- bucket->m_switchover_node = get_responsible_node(buck);
- bucket->m_switchover_gci = max + 1;
-
- m_switchover_buckets.set(buck);
-
- signal->theData[1] = buck;
- signal->theData[2] = min;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
-
- ndbout_c("min: %d - max: %d) page: %d", min, max, bucket->m_buffer_tail);
- ndbrequire(max >= min);
-}
-
-void
-Suma::resend_bucket(Signal* signal, Uint32 buck, Uint32 min_gci,
- Uint32 pos, Uint32 last_gci)
-{
- Bucket* bucket= c_buckets+buck;
- Uint32 tail= bucket->m_buffer_tail;
-
- Buffer_page* page= (Buffer_page*)m_tup->c_page_pool.getPtr(tail);
- Uint32 max_gci = page->m_max_gci;
- Uint32 next_page = page->m_next_page;
- Uint32 *ptr = page->m_data + pos;
- Uint32 *end = page->m_data + page->m_words_used;
- bool delay = false;
-
- ndbrequire(tail != RNIL);
-
- if(tail == bucket->m_buffer_head.m_page_id)
- {
- max_gci= bucket->m_buffer_head.m_max_gci;
- end= page->m_data + bucket->m_buffer_head.m_page_pos;
- next_page= RNIL;
-
- if(ptr == end)
- {
- delay = true;
- goto next;
- }
- }
- else if(pos == 0 && min_gci > max_gci)
- {
- free_page(tail, page);
- tail = bucket->m_buffer_tail = next_page;
- ndbout_c("pos==0 && min_gci(%d) > max_gci(%d) resend switching page to %d", min_gci, max_gci, tail);
- goto next;
- }
-
-#if 0
- for(Uint32 i = 0; i<page->m_words_used; i++)
- {
- printf("%.8x ", page->m_data[i]);
- if(((i + 1) % 8) == 0)
- printf("\n");
- }
- printf("\n");
-#endif
-
- while(ptr < end)
- {
- Uint32 *src = ptr;
- Uint32 tmp = * src++;
- Uint32 sz = tmp & 0xFFFF;
-
- ptr += sz;
-
- if(! (tmp & (0x8000 << 16)))
- {
- sz--;
- last_gci = * src ++;
- }
- else
- {
- ndbrequire(ptr - sz > page->m_data);
- }
-
- if(last_gci < min_gci)
- {
- continue;
- }
-
- ndbrequire(sz);
- sz --; // remove *len* part of sz
-
- if(sz == 0)
- {
- SubGcpCompleteRep * rep = (SubGcpCompleteRep*)signal->getDataPtrSend();
- rep->gci = last_gci;
- rep->senderRef = reference();
- rep->gcp_complete_rep_count = 1;
-
- char buf[255];
- c_subscriber_nodes.getText(buf);
- ndbout_c("resending GCI: %d rows: %d -> %s", last_gci, g_cnt, buf);
- g_cnt = 0;
-
- NodeReceiverGroup rg(API_CLUSTERMGR, c_subscriber_nodes);
- sendSignal(rg, GSN_SUB_GCP_COMPLETE_REP, signal,
- SubGcpCompleteRep::SignalLength, JBB);
- }
- else
- {
- const uint buffer_header_sz = 4;
- g_cnt++;
- Uint32 table = * src++ ;
- Uint32 schemaVersion = * src++;
- Uint32 event = * src >> 16;
- Uint32 sz_1 = (* src ++) & 0xFFFF;
- Uint32 any_value = * src++;
-
- ndbassert(sz - buffer_header_sz >= sz_1);
-
- LinearSectionPtr ptr[3];
- const Uint32 nptr= reformat(signal, ptr,
- src, sz_1,
- src + sz_1, sz - buffer_header_sz - sz_1);
- Uint32 ptrLen= 0;
- for(Uint32 i =0; i < nptr; i++)
- ptrLen+= ptr[i].sz;
-
- /**
- * Signal to subscriber(s)
- */
- Ptr<Table> tabPtr;
- if (c_tables.find(tabPtr, table) &&
- tabPtr.p->m_schemaVersion == schemaVersion)
- {
- SubTableData * data = (SubTableData*)signal->getDataPtrSend();//trg;
- data->gci = last_gci;
- data->tableId = table;
- data->requestInfo = 0;
- SubTableData::setOperation(data->requestInfo, event);
- data->logType = 0;
- data->anyValue = any_value;
- data->totalLen = ptrLen;
-
- {
- LocalDLList<Subscriber>
- list(c_subscriberPool,tabPtr.p->c_subscribers);
- SubscriberPtr subbPtr;
- for(list.first(subbPtr); !subbPtr.isNull(); list.next(subbPtr))
- {
- DBUG_PRINT("info",("GSN_SUB_TABLE_DATA to node %d",
- refToNode(subbPtr.p->m_senderRef)));
- data->senderData = subbPtr.p->m_senderData;
- sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
- SubTableData::SignalLength, JBB, ptr, nptr);
- }
- }
- }
- }
-
- break;
- }
-
- if(ptr == end && (tail != bucket->m_buffer_head.m_page_id))
- {
- /**
- * release...
- */
- free_page(tail, page);
- tail = bucket->m_buffer_tail = next_page;
- pos = 0;
- last_gci = 0;
- ndbout_c("ptr == end -> resend switching page to %d", tail);
- }
- else
- {
- pos = (ptr - page->m_data);
- }
-
-next:
- if(tail == RNIL)
- {
- bucket->m_state &= ~(Uint32)Bucket::BUCKET_RESEND;
- ndbassert(! (bucket->m_state & Bucket::BUCKET_TAKEOVER));
- ndbout_c("resend done...");
- return;
- }
-
- signal->theData[0] = SumaContinueB::RESEND_BUCKET;
- signal->theData[1] = buck;
- signal->theData[2] = min_gci;
- signal->theData[3] = pos;
- signal->theData[4] = last_gci;
- if(!delay)
- sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 5, JBB);
- else
- sendSignalWithDelay(SUMA_REF, GSN_CONTINUEB, signal, 10, 5);
-}
-
-template void append(DataBuffer<11>&,SegmentedSectionPtr,SectionSegmentPool&);
-
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.hpp b/storage/ndb/src/kernel/blocks/suma/Suma.hpp
deleted file mode 100644
index 095b7f93bb3..00000000000
--- a/storage/ndb/src/kernel/blocks/suma/Suma.hpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SUMA_H
-#define SUMA_H
-
-#include <ndb_limits.h>
-#include <SimulatedBlock.hpp>
-
-#include <NodeBitmask.hpp>
-
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <DLFifoList.hpp>
-#include <KeyTable.hpp>
-#include <DataBuffer.hpp>
-#include <SignalCounter.hpp>
-#include <AttributeHeader.hpp>
-#include <AttributeList.hpp>
-
-#include <signaldata/UtilSequence.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <ndbapi/NdbDictionary.hpp>
-
-class Suma : public SimulatedBlock {
- BLOCK_DEFINES(Suma);
-public:
- Suma(Block_context& ctx);
- virtual ~Suma();
-
- /**
- * Private interface
- */
- void execSUB_CREATE_REQ(Signal* signal);
- void execSUB_REMOVE_REQ(Signal* signal);
-
- void execSUB_START_REQ(Signal* signal);
- void execSUB_STOP_REQ(Signal* signal);
-
- void execSUB_SYNC_REQ(Signal* signal);
- void execSUB_ABORT_SYNC_REQ(Signal* signal);
-
- void execSUB_STOP_CONF(Signal* signal);
- void execSUB_STOP_REF(Signal* signal);
-
- /**
- * Dict interface
- */
-#if 0
- void execLIST_TABLES_REF(Signal* signal);
- void execLIST_TABLES_CONF(Signal* signal);
-#endif
- void execGET_TABINFOREF(Signal* signal);
- void execGET_TABINFO_CONF(Signal* signal);
-
- void execGET_TABLEID_CONF(Signal* signal);
- void execGET_TABLEID_REF(Signal* signal);
-
- void execDROP_TAB_CONF(Signal* signal);
- void execALTER_TAB_REQ(Signal* signal);
- void execCREATE_TAB_CONF(Signal* signal);
- /**
- * Scan interface
- */
- void execSCAN_HBREP(Signal* signal);
- void execSCAN_FRAGREF(Signal* signal);
- void execSCAN_FRAGCONF(Signal* signal);
- void execTRANSID_AI(Signal* signal);
- void execSUB_SYNC_CONTINUE_REF(Signal* signal);
- void execSUB_SYNC_CONTINUE_CONF(Signal* signal);
-
- /**
- * Trigger logging
- */
- void execTRIG_ATTRINFO(Signal* signal);
- void execFIRE_TRIG_ORD(Signal* signal);
- void execSUB_GCP_COMPLETE_REP(Signal* signal);
-
- /**
- * DIH signals
- */
- void execDI_FCOUNTREF(Signal* signal);
- void execDI_FCOUNTCONF(Signal* signal);
- void execDIGETPRIMREF(Signal* signal);
- void execDIGETPRIMCONF(Signal* signal);
-
- /**
- * Trigger administration
- */
- void execCREATE_TRIG_REF(Signal* signal);
- void execCREATE_TRIG_CONF(Signal* signal);
- void execDROP_TRIG_REF(Signal* signal);
- void execDROP_TRIG_CONF(Signal* signal);
-
- /**
- * continueb
- */
- void execCONTINUEB(Signal* signal);
-
-public:
-
- void suma_ndbrequire(bool v);
-
- typedef DataBuffer<15> TableList;
-
- union FragmentDescriptor {
- struct {
- Uint16 m_fragmentNo;
- Uint16 m_nodeId;
- } m_fragDesc;
- Uint32 m_dummy;
- };
-
- /**
- * Used when sending SCAN_FRAG
- */
- union AttributeDescriptor {
- struct {
- Uint16 attrId;
- Uint16 unused;
- } m_attrDesc;
- Uint32 m_dummy;
- };
-
- struct Subscriber {
- Uint32 m_senderRef;
- Uint32 m_senderData;
- Uint32 m_subPtrI; //reference to subscription
- Uint32 nextList;
-
- union { Uint32 nextPool; Uint32 prevList; };
- };
- typedef Ptr<Subscriber> SubscriberPtr;
-
- /**
- * Subscriptions
- */
-
- struct Subscription {
- Subscription() {}
- Uint32 m_senderRef;
- Uint32 m_senderData;
- Uint32 m_subscriptionId;
- Uint32 m_subscriptionKey;
- Uint32 m_subscriptionType;
- Uint16 m_options;
-
- enum Options {
- REPORT_ALL = 0x1,
- REPORT_SUBSCRIBE = 0x2
- };
-
- enum State {
- UNDEFINED,
- LOCKED,
- DEFINED,
- DROPPED
- };
- State m_state;
- Uint32 n_subscribers;
-
- Uint32 nextHash;
- union { Uint32 prevHash; Uint32 nextPool; };
-
- Uint32 hashValue() const {
- return m_subscriptionId + m_subscriptionKey;
- }
-
- bool equal(const Subscription & s) const {
- return
- m_subscriptionId == s.m_subscriptionId &&
- m_subscriptionKey == s.m_subscriptionKey;
- }
- /**
- * The following holds the tables included
- * in the subscription.
- */
- Uint32 m_tableId;
- Uint32 m_table_ptrI;
- Uint32 m_current_sync_ptrI;
- };
- typedef Ptr<Subscription> SubscriptionPtr;
-
- class Table;
- friend class Table;
- typedef Ptr<Table> TablePtr;
-
- struct SyncRecord {
- SyncRecord(Suma& s, DataBuffer<15>::DataBufferPool & p)
- : m_tableList(p), suma(s)
-#ifdef ERROR_INSERT
- , cerrorInsert(s.cerrorInsert)
-#endif
- {}
-
- void release();
-
- Uint32 m_senderRef;
- Uint32 m_senderData;
-
- Uint32 m_subscriptionPtrI;
- Uint32 m_error;
- Uint32 m_currentTable;
- TableList m_tableList; // Tables to sync
- TableList::DataBufferIterator m_tableList_it;
-
- /**
- * Sync data
- */
- Uint32 m_currentFragment; // Index in tabPtr.p->m_fragments
- DataBuffer<15>::Head m_attributeList; // Attribute if other than default
- DataBuffer<15>::Head m_tabList; // tables if other than default
-
- Uint32 m_currentTableId; // Current table
- Uint32 m_currentNoOfAttributes; // No of attributes for current table
-
- void startScan(Signal*);
- void nextScan(Signal*);
- bool getNextFragment(TablePtr * tab, FragmentDescriptor * fd);
- void completeScan(Signal*, int error= 0);
-
- Suma & suma;
-#ifdef ERROR_INSERT
- UintR &cerrorInsert;
-#endif
- BlockNumber number() const { return suma.number(); }
- void progError(int line, int cause, const char * extra) {
- suma.progError(line, cause, extra);
- }
-
- Uint32 prevList; Uint32 ptrI;
- union { Uint32 nextPool; Uint32 nextList; };
- };
- friend struct SyncRecord;
-
- int initTable(Signal *signal,Uint32 tableId, TablePtr &tabPtr,
- Ptr<SyncRecord> syncPtr);
- int initTable(Signal *signal,Uint32 tableId, TablePtr &tabPtr,
- SubscriberPtr subbPtr);
- int initTable(Signal *signal,Uint32 tableId, TablePtr &tabPtr);
-
- int completeOneSubscriber(Signal* signal, TablePtr tabPtr, SubscriberPtr subbPtr);
- void completeAllSubscribers(Signal* signal, TablePtr tabPtr);
- void completeInitTable(Signal* signal, TablePtr tabPtr);
-
- struct Table {
- Table() { m_tableId = ~0; n_subscribers = 0; }
- void release(Suma&);
- void checkRelease(Suma &suma);
-
- DLList<Subscriber>::Head c_subscribers;
- DLList<SyncRecord>::Head c_syncRecords;
-
- enum State {
- UNDEFINED,
- DEFINING,
- DEFINED,
- DROPPED,
- ALTERED
- };
- State m_state;
-
- Uint32 m_ptrI;
- SubscriberPtr m_drop_subbPtr;
-
- Uint32 n_subscribers;
- bool m_reportAll;
-
- bool parseTable(SegmentedSectionPtr ptr, Suma &suma);
- /**
- * Create triggers
- */
- int setupTrigger(Signal* signal, Suma &suma);
- void completeTrigger(Signal* signal);
- void createAttributeMask(AttributeMask&, Suma &suma);
-
- /**
- * Drop triggers
- */
- void dropTrigger(Signal* signal,Suma&);
- void runDropTrigger(Signal* signal, Uint32 triggerId,Suma&);
-
- /**
- * Sync meta
- */
-#if 0
- void runLIST_TABLES_CONF(Signal* signal);
-#endif
-
- union { Uint32 m_tableId; Uint32 key; };
- Uint32 m_schemaVersion;
- Uint8 m_hasTriggerDefined[3]; // Insert/Update/Delete
- Uint8 m_hasOutstandingTriggerReq[3]; // Insert/Update/Delete
- Uint32 m_triggerIds[3]; // Insert/Update/Delete
-
- Uint32 m_error;
- /**
- * Default order in which to ask for attributes during scan
- * 1) Fixed, not nullable
- * 2) Rest
- */
- DataBuffer<15>::Head m_attributes; // Attribute id's
-
- /**
- * Fragments
- */
- Uint32 m_fragCount;
- DataBuffer<15>::Head m_fragments; // Fragment descriptors
-
- /**
- * Hash table stuff
- */
- Uint32 nextHash;
- union { Uint32 prevHash; Uint32 nextPool; };
- Uint32 hashValue() const {
- return m_tableId;
- }
- bool equal(const Table& rec) const {
- return m_tableId == rec.m_tableId;
- }
- };
-
- /**
- *
- */
- DLList<Subscriber> c_metaSubscribers;
- DLList<Subscriber> c_removeDataSubscribers;
-
- /**
- * Lists
- */
- KeyTable<Table> c_tables;
- DLHashTable<Subscription> c_subscriptions;
-
- /**
- * Pools
- */
- ArrayPool<Subscriber> c_subscriberPool;
- ArrayPool<Table> c_tablePool;
- ArrayPool<Subscription> c_subscriptionPool;
- ArrayPool<SyncRecord> c_syncPool;
- DataBuffer<15>::DataBufferPool c_dataBufferPool;
-
- NodeBitmask c_failedApiNodes;
-
- /**
- * Functions
- */
- bool removeSubscribersOnNode(Signal *signal, Uint32 nodeId);
-
- bool checkTableTriggers(SegmentedSectionPtr ptr);
-
- void addTableId(Uint32 TableId,
- SubscriptionPtr subPtr, SyncRecord *psyncRec);
-
- void sendSubIdRef(Signal* signal,Uint32 senderRef,Uint32 senderData,Uint32 errorCode);
- void sendSubCreateRef(Signal* signal, Uint32 errorCode);
- void sendSubStartRef(Signal*, SubscriberPtr, Uint32 errorCode, SubscriptionData::Part);
- void sendSubStartRef(Signal* signal, Uint32 errorCode);
- void sendSubStopRef(Signal* signal, Uint32 errorCode);
- void sendSubSyncRef(Signal* signal, Uint32 errorCode);
- void sendSubRemoveRef(Signal* signal, const SubRemoveReq& ref,
- Uint32 errorCode);
- void sendSubStartComplete(Signal*, SubscriberPtr, Uint32,
- SubscriptionData::Part);
- void sendSubStopComplete(Signal*, SubscriberPtr);
- void sendSubStopReq(Signal* signal, bool unlock= false);
-
- void completeSubRemove(SubscriptionPtr subPtr);
-
- void reportAllSubscribers(Signal *signal,
- NdbDictionary::Event::_TableEvent table_event,
- SubscriptionPtr subPtr,
- SubscriberPtr subbPtr);
-
- Uint32 getFirstGCI(Signal* signal);
-
- /**
- * Table admin
- */
- void convertNameToId( SubscriptionPtr subPtr, Signal * signal);
-
- /**
- * Public interface
- */
- void execCREATE_SUBSCRIPTION_REQ(Signal* signal);
- void execDROP_SUBSCRIPTION_REQ(Signal* signal);
-
- void execSTART_SUBSCRIPTION_REQ(Signal* signal);
- void execSTOP_SUBSCRIPTION_REQ(Signal* signal);
-
- void execSYNC_SUBSCRIPTION_REQ(Signal* signal);
- void execABORT_SYNC_REQ(Signal* signal);
-
- /**
- * Framework signals
- */
-
- void getNodeGroupMembers(Signal* signal);
-
- void execREAD_CONFIG_REQ(Signal* signal);
-
- void execSTTOR(Signal* signal);
- void sendSTTORRY(Signal*);
- void execNDB_STTOR(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execREAD_NODESCONF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
- void execSIGNAL_DROPPED_REP(Signal* signal);
- void execAPI_START_REP(Signal* signal);
- void execAPI_FAILREQ(Signal* signal) ;
-
- void execSUB_GCP_COMPLETE_ACK(Signal* signal);
-
- /**
- * Controller interface
- */
- void execSUB_CREATE_REF(Signal* signal);
- void execSUB_CREATE_CONF(Signal* signal);
-
- void execSUB_DROP_REF(Signal* signal);
- void execSUB_DROP_CONF(Signal* signal);
-
- void execSUB_START_REF(Signal* signal);
- void execSUB_START_CONF(Signal* signal);
-
- void execSUB_ABORT_SYNC_REF(Signal* signal);
- void execSUB_ABORT_SYNC_CONF(Signal* signal);
-
- void execSUMA_START_ME_REQ(Signal* signal);
- void execSUMA_START_ME_REF(Signal* signal);
- void execSUMA_START_ME_CONF(Signal* signal);
- void execSUMA_HANDOVER_REQ(Signal* signal);
- void execSUMA_HANDOVER_REF(Signal* signal);
- void execSUMA_HANDOVER_CONF(Signal* signal);
-
- /**
- * Subscription generation interface
- */
- void createSequence(Signal* signal);
- void createSequenceReply(Signal* signal,
- UtilSequenceConf* conf,
- UtilSequenceRef* ref);
- void execUTIL_SEQUENCE_CONF(Signal* signal);
- void execUTIL_SEQUENCE_REF(Signal* signal);
- void execCREATE_SUBID_REQ(Signal* signal);
-
- /**
- * for Suma that is restarting another
- */
-
- struct Restart {
- Restart(Suma& s);
-
- Suma & suma;
- Uint32 nodeId;
-
- DLHashTable<Subscription>::Iterator c_subIt;
- KeyTable<Table>::Iterator c_tabIt;
-
- void progError(int line, int cause, const char * extra) {
- suma.progError(line, cause, extra);
- }
-
- void resetNode(Uint32 sumaRef);
- void runSUMA_START_ME_REQ(Signal*, Uint32 sumaRef);
- void startNode(Signal*, Uint32 sumaRef);
-
- void createSubscription(Signal* signal, Uint32 sumaRef);
- void nextSubscription(Signal* signal, Uint32 sumaRef);
- void runSUB_CREATE_CONF(Signal* signal);
- void completeSubscription(Signal* signal, Uint32 sumaRef);
-
- void startSubscriber(Signal* signal, Uint32 sumaRef);
- void nextSubscriber(Signal* signal, Uint32 sumaRef, SubscriberPtr subbPtr);
- void sendSubStartReq(SubscriptionPtr subPtr, SubscriberPtr subbPtr,
- Signal* signal, Uint32 sumaRef);
- void runSUB_START_CONF(Signal* signal);
- void completeSubscriber(Signal* signal, Uint32 sumaRef);
-
- void completeRestartingNode(Signal* signal, Uint32 sumaRef);
- void resetRestart(Signal* signal);
- } Restart;
-
-private:
- friend class Restart;
- /**
- * Variables
- */
- NodeId c_masterNodeId;
- NdbNodeBitmask c_alive_nodes;
-
- /**
- * for restarting Suma not to start sending data too early
- */
- struct Startup
- {
- bool m_wait_handover;
- Uint32 m_restart_server_node_id;
- NdbNodeBitmask m_handover_nodes;
- } c_startup;
-
- NodeBitmask c_connected_nodes; // (NODE/API) START REP / (API/NODE) FAIL REQ
- NodeBitmask c_subscriber_nodes; //
-
- /**
- * for all Suma's to keep track of other Suma's in Node group
- */
- Uint32 c_nodeGroup;
- Uint32 c_noNodesInGroup;
- Uint32 c_nodesInGroup[MAX_REPLICAS];
- NdbNodeBitmask c_nodes_in_nodegroup_mask; // NodeId's of nodes in nodegroup
-
- void send_start_me_req(Signal* signal);
- void check_start_handover(Signal* signal);
- void send_handover_req(Signal* signal);
-
- Uint32 get_responsible_node(Uint32 B) const;
- Uint32 get_responsible_node(Uint32 B, const NdbNodeBitmask& mask) const;
- bool check_switchover(Uint32 bucket, Uint32 gci);
-
-public:
- struct Page_pos
- {
- Uint32 m_page_id;
- Uint32 m_page_pos;
- Uint32 m_max_gci; // max gci on page
- Uint32 m_last_gci; // last gci on page
- };
-private:
-
- struct Bucket
- {
- enum {
- BUCKET_STARTING = 0x1 // On starting node
- ,BUCKET_HANDOVER = 0x2 // On running node
- ,BUCKET_TAKEOVER = 0x4 // On takeing over node
- ,BUCKET_RESEND = 0x8 // On takeing over node
- };
- Uint16 m_state;
- Uint16 m_switchover_node;
- Uint16 m_nodes[MAX_REPLICAS];
- Uint32 m_switchover_gci;
- Uint32 m_max_acked_gci;
- Uint32 m_buffer_tail; // Page
- Page_pos m_buffer_head;
- };
-
- struct Buffer_page
- {
- STATIC_CONST( DATA_WORDS = 8192 - 9);
- Uint32 _tupdata1;
- Uint32 _tupdata2;
- Uint32 _tupdata3;
- Uint32 _tupdata4;
- Uint32 m_page_state; // Used by TUP buddy algorithm
- Uint32 m_page_chunk_ptr_i;
- Uint32 m_next_page;
- Uint32 m_words_used; //
- Uint32 m_max_gci; //
- Uint32 m_data[DATA_WORDS];
- };
-
- STATIC_CONST( NO_OF_BUCKETS = 24 ); // 24 = 4*3*2*1!
- Uint32 c_no_of_buckets;
- struct Bucket c_buckets[NO_OF_BUCKETS];
-
- STATIC_CONST( BUCKET_MASK_SIZE = (((NO_OF_BUCKETS+31)>> 5)) );
- typedef Bitmask<BUCKET_MASK_SIZE> Bucket_mask;
- Bucket_mask m_active_buckets;
- Bucket_mask m_switchover_buckets;
-
- class Dbtup* m_tup;
- void init_buffers();
- Uint32* get_buffer_ptr(Signal*, Uint32 buck, Uint32 gci, Uint32 sz);
- Uint32 seize_page();
- void free_page(Uint32 page_id, Buffer_page* page);
- void out_of_buffer(Signal*);
- void out_of_buffer_release(Signal* signal, Uint32 buck);
-
- void start_resend(Signal*, Uint32 bucket);
- void resend_bucket(Signal*, Uint32 bucket, Uint32 gci,
- Uint32 page_pos, Uint32 last_gci);
- void release_gci(Signal*, Uint32 bucket, Uint32 gci);
-
- Uint32 m_max_seen_gci; // FIRE_TRIG_ORD
- Uint32 m_max_sent_gci; // FIRE_TRIG_ORD -> send
- Uint32 m_last_complete_gci; // SUB_GCP_COMPLETE_REP
- Uint32 m_out_of_buffer_gci;
- Uint32 m_gcp_complete_rep_count;
-
- struct Gcp_record
- {
- Uint32 m_gci;
- NodeBitmask m_subscribers;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- ArrayPool<Gcp_record> c_gcp_pool;
- DLFifoList<Gcp_record> c_gcp_list;
-
- struct Page_chunk
- {
- Uint32 m_page_id;
- Uint32 m_size;
- Uint32 m_free;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- Uint32 m_first_free_page;
- ArrayPool<Page_chunk> c_page_chunk_pool;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.txt b/storage/ndb/src/kernel/blocks/suma/Suma.txt
deleted file mode 100644
index eba031226ef..00000000000
--- a/storage/ndb/src/kernel/blocks/suma/Suma.txt
+++ /dev/null
@@ -1,192 +0,0 @@
-Protocols involving SUMA:
-
-
-
-USER SUMA UTIL
-========================================================
-CREATE_SUBID_REQ
-------------------------->
- UTIL_SEQUENCE
- ---------------------->
- <----------------------
-CREATE_SUBID_CONF
-<-------------------------
-
-
-
-
-USER SUMA DICT
-========================================================
-SUB_CREATE_REQ
-------------------------->
- case SelectiveTableSnapshot:
- GET_TABLEID
- ---------------------->
- <----------------------
-SUB_CREATE_CONF
-<-------------------------
-
-
-
-
-
-USER SUMA DICT
-========================================================
-SUB_SYNC_REQ::MetaData
-------------------------->
- case DatabaseSnapshot:
- LIST_TABLES
- ---------------------->
- <----------------------
-for each table...
- GET_TABINFO
- ---------------------->
- <----------------------
-SUB_META_DATA DIH
-<------------------------- =======
- DI_FCOUNT
- ---------------------->
- <----------------------
- DI_GETPRIM
- ---------------------->
- <----------------------
-..end for each table
-SUB_SYNC_CONF
-<-------------------------
-
-
-
-
-USER SUMA LQH
-========================================================
-SUB_SYNC_REQ::TableData
-------------------------->
-for each table...
- SCAN_FRAG_REQ
- ---------------------->
- ATTRINFO
- ---------------------->
- SCAN_FRAG_CONF
- <----------------------
-SUB_SYNC_CONTINUE
-<-------------------------
-------------------------->
- SCAN_NEXTREQ
- ---------------------->
-...end for each table
-
-
-
-??????????
- SCAN_HBREP
- <----------------------
-
-
-
-USER SUMA
-===============================
-SUB_START_REQ::MetaData
-------------------------->
-SUB_START_CONF
-<-------------------------
-
-
-
-USER SUMA TUP
-========================================================
-SUB_START_REQ::TableData
-------------------------->
-for each table...
- CREATE_TRIG
- ---------------------->
- <----------------------
-...end for each table
-SUB_START_CONF
-<-------------------------
-
-
-USER SUMA XXX
-========================================================
- TRANSID_AI
- <----------------------
-SUB_TABLE_DATA
-<-------------------------
-
-
-
-
-
-USER SUMA XXX
-========================================================
- TRIG_ATTRINFO
- <----------------------
- FIRE_TRIG_ORD
- <----------------------
-SUB_TABLE_DATA
-<-------------------------
-
-
-
-USER SUMA XXX
-========================================================
- SUB_GCP_COMPLETE_REP
- <----------------------
-SUB_GCP_COMPLETE_REP
-<-------------------------
-
-for event only:
-SUB_GCP_COMPLETE_ACK
-------------------------->
- when all subscribers have sent ACK on gci
- send to all other suma's in node group:
- SUB_GCP_COMPLETE_ACK
- ---------------------->
-
-
-USER SUMA
-===============================
-SUB_STOP_REQ
-------------------------->
-SUB_STOP_CONF
-<-------------------------
-
-
-
-USER SUMA
-===============================
-SUB_REMOVE_REQ
-------------------------->
-SUB_REMOVE_CONF
-<-------------------------
-
-
-
-MASTER SUMA RESTARTING SUMA
-=========================================
-INCL_NODEREQ
-<---------------------------------------------------------
-for each subscription...
-SUB_CREATE_REQ
-------------------------->...
-<-------------------------
-SUB_SYNC_REQ::MetaData
-------------------------->...
-<-------------------------
-... end for each subscription
-
-
- SUMA_START_ME (sent asynchronously in start phase 5 to all suma's in node group)
-<-------------------------
- ------------------------->
-
-for each subscriber...
-SUB_START_REQ (not before SUMA_START_ME)
-------------------------->
-<-------------------------
-... end for each subscriber
-
-SUMA_HANDOVER_REQ
-------------------------->
- SUMA_HANDOVER_CONF (to all suma's in node group)
-<-------------------------
- ------------------------->
diff --git a/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp b/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp
deleted file mode 100644
index 9d4e2c41907..00000000000
--- a/storage/ndb/src/kernel/blocks/suma/SumaInit.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Suma.hpp"
-
-#include <Properties.hpp>
-#include <Configuration.hpp>
-
-Suma::Suma(Block_context& ctx) :
- SimulatedBlock(SUMA, ctx),
- c_metaSubscribers(c_subscriberPool),
- c_removeDataSubscribers(c_subscriberPool),
- c_tables(c_tablePool),
- c_subscriptions(c_subscriptionPool),
- Restart(*this),
- c_gcp_list(c_gcp_pool)
-{
- BLOCK_CONSTRUCTOR(Suma);
-
- // Add received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &Suma::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &Suma::execSTTOR);
- addRecSignal(GSN_NDB_STTOR, &Suma::execNDB_STTOR);
- addRecSignal(GSN_DUMP_STATE_ORD, &Suma::execDUMP_STATE_ORD);
- addRecSignal(GSN_READ_NODESCONF, &Suma::execREAD_NODESCONF);
- addRecSignal(GSN_API_START_REP, &Suma::execAPI_START_REP, true);
- addRecSignal(GSN_API_FAILREQ, &Suma::execAPI_FAILREQ);
- addRecSignal(GSN_NODE_FAILREP, &Suma::execNODE_FAILREP);
- addRecSignal(GSN_INCL_NODEREQ, &Suma::execINCL_NODEREQ);
- addRecSignal(GSN_CONTINUEB, &Suma::execCONTINUEB);
- addRecSignal(GSN_SIGNAL_DROPPED_REP, &Suma::execSIGNAL_DROPPED_REP, true);
- addRecSignal(GSN_UTIL_SEQUENCE_CONF, &Suma::execUTIL_SEQUENCE_CONF);
- addRecSignal(GSN_UTIL_SEQUENCE_REF, &Suma::execUTIL_SEQUENCE_REF);
- addRecSignal(GSN_CREATE_SUBID_REQ,
- &Suma::execCREATE_SUBID_REQ);
-
- addRecSignal(GSN_SUB_CREATE_CONF, &Suma::execSUB_CREATE_CONF);
- addRecSignal(GSN_SUB_CREATE_REF, &Suma::execSUB_CREATE_REF);
-
- addRecSignal(GSN_SUB_START_CONF, &Suma::execSUB_START_CONF);
- addRecSignal(GSN_SUB_START_REF, &Suma::execSUB_START_REF);
-
- addRecSignal(GSN_SUMA_START_ME_REQ, &Suma::execSUMA_START_ME_REQ);
- addRecSignal(GSN_SUMA_START_ME_REF, &Suma::execSUMA_START_ME_REF);
- addRecSignal(GSN_SUMA_START_ME_CONF, &Suma::execSUMA_START_ME_CONF);
- addRecSignal(GSN_SUMA_HANDOVER_REQ, &Suma::execSUMA_HANDOVER_REQ);
- addRecSignal(GSN_SUMA_HANDOVER_REF, &Suma::execSUMA_HANDOVER_REF);
- addRecSignal(GSN_SUMA_HANDOVER_CONF, &Suma::execSUMA_HANDOVER_CONF);
-
- addRecSignal(GSN_SUB_GCP_COMPLETE_ACK,
- &Suma::execSUB_GCP_COMPLETE_ACK);
-
- /**
- * SUMA participant if
- */
- addRecSignal(GSN_SUB_CREATE_REQ, &Suma::execSUB_CREATE_REQ);
- addRecSignal(GSN_SUB_REMOVE_REQ, &Suma::execSUB_REMOVE_REQ);
- addRecSignal(GSN_SUB_START_REQ, &Suma::execSUB_START_REQ);
- addRecSignal(GSN_SUB_STOP_REQ, &Suma::execSUB_STOP_REQ);
- addRecSignal(GSN_SUB_STOP_REF, &Suma::execSUB_STOP_REF);
- addRecSignal(GSN_SUB_STOP_CONF, &Suma::execSUB_STOP_CONF);
- addRecSignal(GSN_SUB_SYNC_REQ, &Suma::execSUB_SYNC_REQ);
-
- /**
- * Dict interface
- */
- addRecSignal(GSN_DROP_TAB_CONF, &Suma::execDROP_TAB_CONF);
- addRecSignal(GSN_ALTER_TAB_REQ, &Suma::execALTER_TAB_REQ);
- addRecSignal(GSN_CREATE_TAB_CONF, &Suma::execCREATE_TAB_CONF);
-
-#if 0
- addRecSignal(GSN_LIST_TABLES_CONF, &Suma::execLIST_TABLES_CONF);
-#endif
- addRecSignal(GSN_GET_TABINFO_CONF, &Suma::execGET_TABINFO_CONF);
- addRecSignal(GSN_GET_TABINFOREF, &Suma::execGET_TABINFOREF);
-#if 0
- addRecSignal(GSN_GET_TABLEID_CONF, &Suma::execGET_TABLEID_CONF);
- addRecSignal(GSN_GET_TABLEID_REF, &Suma::execGET_TABLEID_REF);
-#endif
- /**
- * Dih interface
- */
- addRecSignal(GSN_DI_FCOUNTCONF, &Suma::execDI_FCOUNTCONF);
- addRecSignal(GSN_DI_FCOUNTREF, &Suma::execDI_FCOUNTREF);
- addRecSignal(GSN_DIGETPRIMCONF, &Suma::execDIGETPRIMCONF);
-
- /**
- * Scan interface
- */
- addRecSignal(GSN_SCAN_HBREP, &Suma::execSCAN_HBREP);
- addRecSignal(GSN_TRANSID_AI, &Suma::execTRANSID_AI);
- addRecSignal(GSN_SCAN_FRAGREF, &Suma::execSCAN_FRAGREF);
- addRecSignal(GSN_SCAN_FRAGCONF, &Suma::execSCAN_FRAGCONF);
-#if 0
- addRecSignal(GSN_SUB_SYNC_CONTINUE_REF,
- &Suma::execSUB_SYNC_CONTINUE_REF);
-#endif
- addRecSignal(GSN_SUB_SYNC_CONTINUE_CONF,
- &Suma::execSUB_SYNC_CONTINUE_CONF);
-
- /**
- * Trigger stuff
- */
- addRecSignal(GSN_TRIG_ATTRINFO, &Suma::execTRIG_ATTRINFO);
- addRecSignal(GSN_FIRE_TRIG_ORD, &Suma::execFIRE_TRIG_ORD);
-
- addRecSignal(GSN_CREATE_TRIG_REF, &Suma::execCREATE_TRIG_REF);
- addRecSignal(GSN_CREATE_TRIG_CONF, &Suma::execCREATE_TRIG_CONF);
- addRecSignal(GSN_DROP_TRIG_REF, &Suma::execDROP_TRIG_REF);
- addRecSignal(GSN_DROP_TRIG_CONF, &Suma::execDROP_TRIG_CONF);
-
- addRecSignal(GSN_SUB_GCP_COMPLETE_REP,
- &Suma::execSUB_GCP_COMPLETE_REP);
-
- c_startup.m_restart_server_node_id = RNIL; // Server for my NR
-}
-
-Suma::~Suma()
-{
-}
-
-BLOCK_FUNCTIONS(Suma)
-
diff --git a/storage/ndb/src/kernel/blocks/trix/Trix.cpp b/storage/ndb/src/kernel/blocks/trix/Trix.cpp
deleted file mode 100644
index 5689e602ff0..00000000000
--- a/storage/ndb/src/kernel/blocks/trix/Trix.cpp
+++ /dev/null
@@ -1,997 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Trix.hpp"
-
-#include <string.h>
-#include <kernel_types.h>
-#include <NdbOut.hpp>
-
-#include <signaldata/ReadNodesConf.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/BuildIndx.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <signaldata/UtilPrepare.hpp>
-#include <signaldata/UtilExecute.hpp>
-#include <signaldata/UtilRelease.hpp>
-#include <SectionReader.hpp>
-#include <AttributeHeader.hpp>
-
-#define CONSTRAINT_VIOLATION 893
-
-#define DEBUG(x) { ndbout << "TRIX::" << x << endl; }
-
-/**
- *
- */
-Trix::Trix(Block_context& ctx) :
- SimulatedBlock(TRIX, ctx),
- c_theNodes(c_theNodeRecPool),
- c_masterNodeId(0),
- c_masterTrixRef(0),
- c_noNodesFailed(0),
- c_noActiveNodes(0),
- c_theSubscriptions(c_theSubscriptionRecPool)
-{
- BLOCK_CONSTRUCTOR(Trix);
-
- // Add received signals
- addRecSignal(GSN_READ_CONFIG_REQ, &Trix::execREAD_CONFIG_REQ);
- addRecSignal(GSN_STTOR, &Trix::execSTTOR);
- addRecSignal(GSN_NDB_STTOR, &Trix::execNDB_STTOR); // Forwarded from DICT
- addRecSignal(GSN_READ_NODESCONF, &Trix::execREAD_NODESCONF);
- addRecSignal(GSN_READ_NODESREF, &Trix::execREAD_NODESREF);
- addRecSignal(GSN_NODE_FAILREP, &Trix::execNODE_FAILREP);
- addRecSignal(GSN_INCL_NODEREQ, &Trix::execINCL_NODEREQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &Trix::execDUMP_STATE_ORD);
-
- // Index build
- addRecSignal(GSN_BUILDINDXREQ, &Trix::execBUILDINDXREQ);
- // Dump testing
- addRecSignal(GSN_BUILDINDXCONF, &Trix::execBUILDINDXCONF);
- addRecSignal(GSN_BUILDINDXREF, &Trix::execBUILDINDXREF);
-
-
- addRecSignal(GSN_UTIL_PREPARE_CONF, &Trix::execUTIL_PREPARE_CONF);
- addRecSignal(GSN_UTIL_PREPARE_REF, &Trix::execUTIL_PREPARE_REF);
- addRecSignal(GSN_UTIL_EXECUTE_CONF, &Trix::execUTIL_EXECUTE_CONF);
- addRecSignal(GSN_UTIL_EXECUTE_REF, &Trix::execUTIL_EXECUTE_REF);
- addRecSignal(GSN_UTIL_RELEASE_CONF, &Trix::execUTIL_RELEASE_CONF);
- addRecSignal(GSN_UTIL_RELEASE_REF, &Trix::execUTIL_RELEASE_REF);
-
-
- // Suma signals
- addRecSignal(GSN_SUB_CREATE_CONF, &Trix::execSUB_CREATE_CONF);
- addRecSignal(GSN_SUB_CREATE_REF, &Trix::execSUB_CREATE_REF);
- addRecSignal(GSN_SUB_REMOVE_CONF, &Trix::execSUB_REMOVE_CONF);
- addRecSignal(GSN_SUB_REMOVE_REF, &Trix::execSUB_REMOVE_REF);
- addRecSignal(GSN_SUB_SYNC_CONF, &Trix::execSUB_SYNC_CONF);
- addRecSignal(GSN_SUB_SYNC_REF, &Trix::execSUB_SYNC_REF);
- addRecSignal(GSN_SUB_SYNC_CONTINUE_REQ, &Trix::execSUB_SYNC_CONTINUE_REQ);
- addRecSignal(GSN_SUB_TABLE_DATA, &Trix::execSUB_TABLE_DATA);
-}
-
-/**
- *
- */
-Trix::~Trix()
-{
-}
-
-void
-Trix::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- // Allocate pool sizes
- c_theAttrOrderBufferPool.setSize(100);
- c_theSubscriptionRecPool.setSize(100);
-
- DLList<SubscriptionRecord> subscriptions(c_theSubscriptionRecPool);
- SubscriptionRecPtr subptr;
- while(subscriptions.seize(subptr) == true) {
- new (subptr.p) SubscriptionRecord(c_theAttrOrderBufferPool);
- }
- subscriptions.release();
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-/**
- *
- */
-void Trix::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- //const Uint32 startphase = signal->theData[1];
- const Uint32 theSignalKey = signal->theData[6];
-
- signal->theData[0] = theSignalKey;
- signal->theData[3] = 1;
- signal->theData[4] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- return;
-}//Trix::execSTTOR()
-
-/**
- *
- */
-void Trix::execNDB_STTOR(Signal* signal)
-{
- jamEntry();
- BlockReference ndbcntrRef = signal->theData[0];
- Uint16 startphase = signal->theData[2]; /* RESTART PHASE */
- Uint16 mynode = signal->theData[1];
- //Uint16 restarttype = signal->theData[3];
- //UintR configInfo1 = signal->theData[6]; /* CONFIGRATION INFO PART 1 */
- //UintR configInfo2 = signal->theData[7]; /* CONFIGRATION INFO PART 2 */
- switch (startphase) {
- case 3:
- jam();
- /* SYMBOLIC START PHASE 4 */
- /* ABSOLUTE PHASE 5 */
- /* REQUEST NODE IDENTITIES FROM DBDIH */
- signal->theData[0] = calcTrixBlockRef(mynode);
- sendSignal(ndbcntrRef, GSN_READ_NODESREQ, signal, 1, JBB);
- return;
- break;
- case 6:
- break;
- default:
- break;
- }
-}
-
-/**
- *
- */
-void Trix::execREAD_NODESCONF(Signal* signal)
-{
- jamEntry();
-
- ReadNodesConf * const readNodes = (ReadNodesConf *)signal->getDataPtr();
- //Uint32 noOfNodes = readNodes->noOfNodes;
- NodeRecPtr nodeRecPtr;
-
- c_masterNodeId = readNodes->masterNodeId;
- c_masterTrixRef = RNIL;
- c_noNodesFailed = 0;
-
- for(unsigned i = 0; i < MAX_NDB_NODES; i++) {
- jam();
- if(NodeBitmask::get(readNodes->allNodes, i)) {
- // Node is defined
- jam();
- ndbrequire(c_theNodes.seizeId(nodeRecPtr, i));
- nodeRecPtr.p->trixRef = calcTrixBlockRef(i);
- if (i == c_masterNodeId) {
- c_masterTrixRef = nodeRecPtr.p->trixRef;
- }
- if(NodeBitmask::get(readNodes->inactiveNodes, i)){
- // Node is not active
- jam();
- /**-----------------------------------------------------------------
- * THIS NODE IS DEFINED IN THE CLUSTER BUT IS NOT ALIVE CURRENTLY.
- * WE ADD THE NODE TO THE SET OF FAILED NODES AND ALSO SET THE
- * BLOCKSTATE TO BUSY TO AVOID ADDING TRIGGERS OR INDEXES WHILE
- * NOT ALL NODES ARE ALIVE.
- *------------------------------------------------------------------*/
- arrGuard(c_noNodesFailed, MAX_NDB_NODES);
- nodeRecPtr.p->alive = false;
- c_noNodesFailed++;
- c_blockState = Trix::NODE_FAILURE;
- }
- else {
- // Node is active
- jam();
- c_noActiveNodes++;
- nodeRecPtr.p->alive = true;
- }
- }
- }
- if (c_noNodesFailed == 0) {
- c_blockState = Trix::STARTED;
- }
-}
-
-/**
- *
- */
-void Trix::execREAD_NODESREF(Signal* signal)
-{
- // NYI
-}
-
-/**
- *
- */
-void Trix::execNODE_FAILREP(Signal* signal)
-{
- jamEntry();
- NodeFailRep * const nodeFail = (NodeFailRep *) signal->getDataPtr();
-
- //Uint32 failureNr = nodeFail->failNo;
- //Uint32 numberNodes = nodeFail->noOfNodes;
- Uint32 masterNodeId = nodeFail->masterNodeId;
-
- NodeRecPtr nodeRecPtr;
-
- for(c_theNodes.first(nodeRecPtr);
- nodeRecPtr.i != RNIL;
- c_theNodes.next(nodeRecPtr)) {
- if(NodeBitmask::get(nodeFail->theNodes, nodeRecPtr.i)) {
- nodeRecPtr.p->alive = false;
- c_noNodesFailed++;
- c_noActiveNodes--;
- }
- }
- if (c_masterNodeId != masterNodeId) {
- c_masterNodeId = masterNodeId;
- NodeRecord* nodeRec = c_theNodes.getPtr(masterNodeId);
- c_masterTrixRef = nodeRec->trixRef;
- }
-}
-
-/**
- *
- */
-void Trix::execINCL_NODEREQ(Signal* signal)
-{
- jamEntry();
- UintR node_id = signal->theData[1];
- NodeRecord* nodeRec = c_theNodes.getPtr(node_id);
- nodeRec->alive = true;
- c_noNodesFailed--;
- c_noActiveNodes++;
- nodeRec->trixRef = calcTrixBlockRef(node_id);
- if (c_noNodesFailed == 0) {
- c_blockState = Trix::STARTED;
- }
-}
-
-// Debugging
-void
-Trix::execDUMP_STATE_ORD(Signal* signal)
-{
- jamEntry();
-
- DumpStateOrd * dumpStateOrd = (DumpStateOrd *)signal->getDataPtr();
-
- switch(dumpStateOrd->args[0]) {
- case(300): {// ok
- // index2 -T; index2 -I -n10000; index2 -c
- // all dump 300 0 0 0 0 0 4 2
- // select_count INDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[1] = {1};
- Uint32 keyColumns[1] = {0};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 1, keyColumns, 1, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- case(301): { // ok
- // index2 -T; index2 -I -n10000; index2 -c -p
- // all dump 301 0 0 0 0 0 4 2
- // select_count INDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[2] = {0, 1};
- Uint32 keyColumns[1] = {0};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 2, keyColumns, 1, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- case(302): { // ok
- // index -T; index -I -n1000; index -c -p
- // all dump 302 0 0 0 0 0 4 2
- // select_count PNUMINDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[3] = {0, 3, 5};
- Uint32 keyColumns[1] = {0};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 3, keyColumns, 1, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- case(303): { // ok
- // index -T -2; index -I -2 -n1000; index -c -p
- // all dump 303 0 0 0 0 0 4 2
- // select_count PNUMINDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[3] = {0, 3, 5};
- Uint32 keyColumns[2] = {0, 1};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 3, keyColumns, 2, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- case(304): { // ok
- // index -T -L; index -I -L -n1000; index -c -p
- // all dump 304 0 0 0 0 0 4 2
- // select_count PNUMINDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[3] = {0, 3, 5};
- Uint32 keyColumns[1] = {0};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 3, keyColumns, 1, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- case(305): { // ok
- // index -T -2 -L; index -I -2 -L -n1000; index -c -p
- // all dump 305 0 0 0 0 0 4 2
- // select_count PNUMINDEX0000
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtrSend();
-
- MEMCOPY_NO_WORDS(buildIndxReq,
- signal->theData + 1,
- BuildIndxReq::SignalLength);
- buildIndxReq->setUserRef(reference()); // return to me
- buildIndxReq->setParallelism(10);
- Uint32 indexColumns[3] = {0, 3, 5};
- Uint32 keyColumns[2] = {0, 1};
- struct LinearSectionPtr orderPtr[2];
- buildIndxReq->setColumnOrder(indexColumns, 3, keyColumns, 2, orderPtr);
- sendSignal(reference(),
- GSN_BUILDINDXREQ,
- signal,
- BuildIndxReq::SignalLength,
- JBB,
- orderPtr,
- BuildIndxReq::NoOfSections);
- break;
- }
- default: {
- // Ignore
- }
- }
-}
-
-// Build index
-/**
- *
- */
-void Trix:: execBUILDINDXREQ(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix:: execBUILDINDXREQ");
-
- BuildIndxReq * buildIndxReq = (BuildIndxReq *)signal->getDataPtr();
-
- // Seize a subscription record
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- if (!c_theSubscriptions.seizeId(subRecPtr, buildIndxReq->getBuildId())) {
- // Failed to allocate subscription record
- BuildIndxRef * buildIndxRef = (BuildIndxRef *)signal->getDataPtrSend();
-
- buildIndxRef->setErrorCode(BuildIndxRef::AllocationFailure);
- releaseSections(signal);
- sendSignal(buildIndxReq->getUserRef(),
- GSN_BUILDINDXREF, signal, BuildIndxRef::SignalLength, JBB);
- DBUG_VOID_RETURN;
- }
- subRec = subRecPtr.p;
- subRec->errorCode = BuildIndxRef::NoError;
- subRec->userReference = buildIndxReq->getUserRef();
- subRec->connectionPtr = buildIndxReq->getConnectionPtr();
- subRec->subscriptionId = buildIndxReq->getBuildId();
- subRec->subscriptionKey = buildIndxReq->getBuildKey();
- subRec->indexType = buildIndxReq->getIndexType();
- subRec->sourceTableId = buildIndxReq->getTableId();
- subRec->targetTableId = buildIndxReq->getIndexId();
- subRec->parallelism = buildIndxReq->getParallelism();
- subRec->expectedConf = 0;
- subRec->subscriptionCreated = false;
- subRec->pendingSubSyncContinueConf = false;
- subRec->prepareId = RNIL;
-
- // Get column order segments
- Uint32 noOfSections = signal->getNoOfSections();
- if(noOfSections > 0) {
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, BuildIndxReq::INDEX_COLUMNS);
- append(subRec->attributeOrder, ptr, getSectionSegmentPool());
- subRec->noOfIndexColumns = ptr.sz;
- }
- if(noOfSections > 1) {
- SegmentedSectionPtr ptr;
- signal->getSection(ptr, BuildIndxReq::KEY_COLUMNS);
- append(subRec->attributeOrder, ptr, getSectionSegmentPool());
- subRec->noOfKeyColumns = ptr.sz;
- }
-#if 0
- // Debugging
- printf("Trix:: execBUILDINDXREQ: Attribute order:\n");
- subRec->attributeOrder.print(stdout);
-#endif
- releaseSections(signal);
- prepareInsertTransactions(signal, subRecPtr);
- DBUG_VOID_RETURN;
-}
-
-void Trix:: execBUILDINDXCONF(Signal* signal)
-{
- printf("Trix:: execBUILDINDXCONF\n");
-}
-
-void Trix:: execBUILDINDXREF(Signal* signal)
-{
- printf("Trix:: execBUILDINDXREF\n");
-}
-
-void Trix::execUTIL_PREPARE_CONF(Signal* signal)
-{
- jamEntry();
- UtilPrepareConf * utilPrepareConf = (UtilPrepareConf *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = utilPrepareConf->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execUTIL_PREPARE_CONF: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- subRec->prepareId = utilPrepareConf->prepareId;
- setupSubscription(signal, subRecPtr);
-}
-
-void Trix::execUTIL_PREPARE_REF(Signal* signal)
-{
- jamEntry();
- UtilPrepareRef * utilPrepareRef = (UtilPrepareRef *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = utilPrepareRef->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execUTIL_PREPARE_REF: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- subRec->errorCode = BuildIndxRef::InternalError;
-}
-
-void Trix::execUTIL_EXECUTE_CONF(Signal* signal)
-{
- jamEntry();
- UtilExecuteConf * utilExecuteConf = (UtilExecuteConf *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = utilExecuteConf->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("rix::execUTIL_EXECUTE_CONF: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- subRec->expectedConf--;
- checkParallelism(signal, subRec);
- if (subRec->expectedConf == 0)
- buildComplete(signal, subRecPtr);
-}
-
-void Trix::execUTIL_EXECUTE_REF(Signal* signal)
-{
- jamEntry();
- UtilExecuteRef * utilExecuteRef = (UtilExecuteRef *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = utilExecuteRef->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execUTIL_EXECUTE_REF: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- ndbrequire(utilExecuteRef->errorCode == UtilExecuteRef::TCError);
- if(utilExecuteRef->TCErrorCode == CONSTRAINT_VIOLATION)
- buildFailed(signal, subRecPtr, BuildIndxRef::IndexNotUnique);
- else
- buildFailed(signal, subRecPtr, BuildIndxRef::InternalError);
-}
-
-void Trix::execSUB_CREATE_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix::execSUB_CREATE_CONF");
- SubCreateConf * subCreateConf = (SubCreateConf *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = subCreateConf->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_CREATE_CONF: Failed to find subscription data %u\n", subRecPtr.i);
- DBUG_VOID_RETURN;
- }
- subRec->subscriptionCreated = true;
- subRecPtr.p = subRec;
-
- DBUG_PRINT("info",("i: %u subscriptionId: %u, subscriptionKey: %u",
- subRecPtr.i, subRecPtr.p->subscriptionId,
- subRecPtr.p->subscriptionKey));
-
- startTableScan(signal, subRecPtr);
- DBUG_VOID_RETURN;
-}
-
-void Trix::execSUB_CREATE_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix::execSUB_CREATE_REF");
- // THIS SIGNAL IS NEVER SENT FROM SUMA?
- /*
- SubCreateRef * subCreateRef = (SubCreateRef *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = subCreateRef->subscriberData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_CREATE_REF: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- buildFailed(signal, subRecPtr, BuildIndxRef::InternalError);
- */
- DBUG_VOID_RETURN;
-}
-
-void Trix::execSUB_SYNC_CONF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix::execSUB_SYNC_CONF");
- SubSyncConf * subSyncConf = (SubSyncConf *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = subSyncConf->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_SYNC_CONF: Failed to find subscription data %u\n",
- subRecPtr.i);
- DBUG_VOID_RETURN;
- }
-
- subRecPtr.p = subRec;
- subRec->expectedConf--;
- checkParallelism(signal, subRec);
- if (subRec->expectedConf == 0)
- buildComplete(signal, subRecPtr);
- DBUG_VOID_RETURN;
-}
-
-void Trix::execSUB_SYNC_REF(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix::execSUB_SYNC_REF");
- SubSyncRef * subSyncRef = (SubSyncRef *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
-
- subRecPtr.i = subSyncRef->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_SYNC_REF: Failed to find subscription data %u\n", subRecPtr.i);
- DBUG_VOID_RETURN;
- }
- subRecPtr.p = subRec;
- buildFailed(signal, subRecPtr, BuildIndxRef::InternalError);
- DBUG_VOID_RETURN;
-}
-
-void Trix::execSUB_SYNC_CONTINUE_REQ(Signal* signal)
-{
- SubSyncContinueReq * subSyncContinueReq =
- (SubSyncContinueReq *) signal->getDataPtr();
-
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
- subRecPtr.i = subSyncContinueReq->subscriberData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_SYNC_CONTINUE_REQ: Failed to find subscription data %u\n", subRecPtr.i);
- return;
- }
- subRecPtr.p = subRec;
- subRec->pendingSubSyncContinueConf = true;
- checkParallelism(signal, subRec);
-}
-
-void Trix::execSUB_TABLE_DATA(Signal* signal)
-{
- jamEntry();
- DBUG_ENTER("Trix::execSUB_TABLE_DATA");
- SubTableData * subTableData = (SubTableData *)signal->getDataPtr();
- SubscriptionRecPtr subRecPtr;
- SubscriptionRecord* subRec;
- subRecPtr.i = subTableData->senderData;
- if ((subRec = c_theSubscriptions.getPtr(subRecPtr.i)) == NULL) {
- printf("Trix::execSUB_TABLE_DATA: Failed to find subscription data %u\n", subRecPtr.i);
- DBUG_VOID_RETURN;
- }
- subRecPtr.p = subRec;
- SegmentedSectionPtr headerPtr, dataPtr;
- if (!signal->getSection(headerPtr, 0)) {
- printf("Trix::execSUB_TABLE_DATA: Failed to get header section\n");
- }
- if (!signal->getSection(dataPtr, 1)) {
- printf("Trix::execSUB_TABLE_DATA: Failed to get data section\n");
- }
- executeInsertTransaction(signal, subRecPtr, headerPtr, dataPtr);
- DBUG_VOID_RETURN;
-}
-
-void Trix::setupSubscription(Signal* signal, SubscriptionRecPtr subRecPtr)
-{
- jam();
- DBUG_ENTER("Trix::setupSubscription");
- SubscriptionRecord* subRec = subRecPtr.p;
- SubCreateReq * subCreateReq = (SubCreateReq *)signal->getDataPtrSend();
-// Uint32 listLen = subRec->noOfIndexColumns + subRec->noOfKeyColumns;
- subCreateReq->senderRef = reference();
- subCreateReq->senderData = subRecPtr.i;
- subCreateReq->subscriptionId = subRec->subscriptionId;
- subCreateReq->subscriptionKey = subRec->subscriptionKey;
- subCreateReq->tableId = subRec->sourceTableId;
- subCreateReq->subscriptionType = SubCreateReq::SingleTableScan;
-
- DBUG_PRINT("info",("i: %u subscriptionId: %u, subscriptionKey: %u",
- subRecPtr.i, subCreateReq->subscriptionId,
- subCreateReq->subscriptionKey));
-
- sendSignal(SUMA_REF, GSN_SUB_CREATE_REQ,
- signal, SubCreateReq::SignalLength, JBB);
- DBUG_VOID_RETURN;
-}
-
-void Trix::startTableScan(Signal* signal, SubscriptionRecPtr subRecPtr)
-{
- jam();
-
- Uint32 attributeList[MAX_ATTRIBUTES_IN_TABLE * 2];
- SubscriptionRecord* subRec = subRecPtr.p;
- AttrOrderBuffer::DataBufferIterator iter;
- Uint32 i = 0;
-
- bool moreAttributes = subRec->attributeOrder.first(iter);
- while (moreAttributes) {
- attributeList[i++] = *iter.data;
- moreAttributes = subRec->attributeOrder.next(iter);
- }
- // Merge index and key column segments
- struct LinearSectionPtr orderPtr[3];
- orderPtr[0].p = attributeList;
- orderPtr[0].sz = subRec->attributeOrder.getSize();
-
- SubSyncReq * subSyncReq = (SubSyncReq *)signal->getDataPtrSend();
- subSyncReq->senderRef = reference();
- subSyncReq->senderData = subRecPtr.i;
- subSyncReq->subscriptionId = subRec->subscriptionId;
- subSyncReq->subscriptionKey = subRec->subscriptionKey;
- subSyncReq->part = SubscriptionData::TableData;
-
- subRecPtr.p->expectedConf = 1;
-
- DBUG_PRINT("info",("i: %u subscriptionId: %u, subscriptionKey: %u",
- subRecPtr.i, subSyncReq->subscriptionId,
- subSyncReq->subscriptionKey));
-
- sendSignal(SUMA_REF, GSN_SUB_SYNC_REQ,
- signal, SubSyncReq::SignalLength, JBB, orderPtr, 1);
-}
-
-void Trix::prepareInsertTransactions(Signal* signal,
- SubscriptionRecPtr subRecPtr)
-{
- SubscriptionRecord* subRec = subRecPtr.p;
- UtilPrepareReq * utilPrepareReq =
- (UtilPrepareReq *)signal->getDataPtrSend();
-
- jam();
- utilPrepareReq->senderRef = reference();
- utilPrepareReq->senderData = subRecPtr.i;
-
- const Uint32 pageSizeInWords = 128;
- Uint32 propPage[pageSizeInWords];
- LinearWriter w(&propPage[0],128);
- w.first();
- w.add(UtilPrepareReq::NoOfOperations, 1);
- w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Write);
- w.add(UtilPrepareReq::TableId, subRec->targetTableId);
- // Add index attributes in increasing order and one PK attribute
- for(Uint32 i = 0; i < subRec->noOfIndexColumns + 1; i++)
- w.add(UtilPrepareReq::AttributeId, i);
-
-#if 0
- // Debugging
- SimplePropertiesLinearReader reader(propPage, w.getWordsUsed());
- printf("Trix::prepareInsertTransactions: Sent SimpleProperties:\n");
- reader.printAll(ndbout);
-#endif
-
- struct LinearSectionPtr sectionsPtr[UtilPrepareReq::NoOfSections];
- sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].p = propPage;
- sectionsPtr[UtilPrepareReq::PROPERTIES_SECTION].sz = w.getWordsUsed();
- sendSignal(DBUTIL_REF, GSN_UTIL_PREPARE_REQ, signal,
- UtilPrepareReq::SignalLength, JBB,
- sectionsPtr, UtilPrepareReq::NoOfSections);
-}
-
-void Trix::executeInsertTransaction(Signal* signal,
- SubscriptionRecPtr subRecPtr,
- SegmentedSectionPtr headerPtr,
- SegmentedSectionPtr dataPtr)
-{
- jam();
- SubscriptionRecord* subRec = subRecPtr.p;
- UtilExecuteReq * utilExecuteReq =
- (UtilExecuteReq *)signal->getDataPtrSend();
- Uint32* headerBuffer = signal->theData + 25;
- Uint32* dataBuffer = headerBuffer + headerPtr.sz;
-
- utilExecuteReq->senderRef = reference();
- utilExecuteReq->senderData = subRecPtr.i;
- utilExecuteReq->prepareId = subRec->prepareId;
-#if 0
- printf("Header size %u\n", headerPtr.sz);
- for(int i = 0; i < headerPtr.sz; i++)
- printf("H'%.8x ", headerBuffer[i]);
- printf("\n");
-
- printf("Data size %u\n", dataPtr.sz);
- for(int i = 0; i < dataPtr.sz; i++)
- printf("H'%.8x ", dataBuffer[i]);
- printf("\n");
-#endif
- // Save scan result in linear buffers
- copy(headerBuffer, headerPtr);
- copy(dataBuffer, dataPtr);
-
- // Calculate packed key size
- Uint32 noOfKeyData = 0;
- for(Uint32 i = 0; i < headerPtr.sz; i++) {
- AttributeHeader* keyAttrHead = (AttributeHeader *) headerBuffer + i;
-
- // Filter out NULL attributes
- if (keyAttrHead->isNULL())
- return;
-
- if (i < subRec->noOfIndexColumns)
- // Renumber index attributes in consequtive order
- keyAttrHead->setAttributeId(i);
- else
- // Calculate total size of PK attribute
- noOfKeyData += keyAttrHead->getDataSize();
- }
- // Increase expected CONF count
- subRec->expectedConf++;
-
- // Pack key attributes
- AttributeHeader::init(headerBuffer + subRec->noOfIndexColumns,
- subRec->noOfIndexColumns,
- noOfKeyData << 2);
-
- struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = headerBuffer;
- sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz =
- subRec->noOfIndexColumns + 1;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].p = dataBuffer;
- sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataPtr.sz;
- sendSignal(DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal,
- UtilExecuteReq::SignalLength, JBB,
- sectionsPtr, UtilExecuteReq::NoOfSections);
-}
-
-void Trix::buildComplete(Signal* signal, SubscriptionRecPtr subRecPtr)
-{
- SubRemoveReq * const req = (SubRemoveReq*)signal->getDataPtrSend();
- req->senderRef = reference();
- req->senderData = subRecPtr.i;
- req->subscriptionId = subRecPtr.p->subscriptionId;
- req->subscriptionKey = subRecPtr.p->subscriptionKey;
- sendSignal(SUMA_REF, GSN_SUB_REMOVE_REQ, signal,
- SubRemoveReq::SignalLength, JBB);
-}
-
-void Trix::buildFailed(Signal* signal,
- SubscriptionRecPtr subRecPtr,
- BuildIndxRef::ErrorCode errorCode)
-{
- SubscriptionRecord* subRec = subRecPtr.p;
-
- subRec->errorCode = errorCode;
- // Continue accumulating since we currently cannot stop SUMA
- subRec->expectedConf--;
- checkParallelism(signal, subRec);
- if (subRec->expectedConf == 0)
- buildComplete(signal, subRecPtr);
-}
-
-void
-Trix::execSUB_REMOVE_REF(Signal* signal){
- jamEntry();
- //@todo
- ndbrequire(false);
-}
-
-void
-Trix::execSUB_REMOVE_CONF(Signal* signal){
- jamEntry();
-
- SubRemoveConf * const conf = (SubRemoveConf*)signal->getDataPtrSend();
-
- SubscriptionRecPtr subRecPtr;
- c_theSubscriptions.getPtr(subRecPtr, conf->senderData);
-
- if(subRecPtr.p->prepareId != RNIL){
- jam();
-
- UtilReleaseReq * const req = (UtilReleaseReq*)signal->getDataPtrSend();
- req->prepareId = subRecPtr.p->prepareId;
- req->senderData = subRecPtr.i;
-
- sendSignal(DBUTIL_REF, GSN_UTIL_RELEASE_REQ, signal,
- UtilReleaseReq::SignalLength , JBB);
- return;
- }
-
- {
- UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend();
- conf->senderData = subRecPtr.i;
- execUTIL_RELEASE_CONF(signal);
- }
-}
-
-void
-Trix::execUTIL_RELEASE_REF(Signal* signal){
- jamEntry();
- ndbrequire(false);
-}
-
-void
-Trix::execUTIL_RELEASE_CONF(Signal* signal){
-
- UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend();
-
- SubscriptionRecPtr subRecPtr;
- c_theSubscriptions.getPtr(subRecPtr, conf->senderData);
-
- if(subRecPtr.p->errorCode == BuildIndxRef::NoError){
- // Build is complete, reply to original sender
- BuildIndxConf * buildIndxConf = (BuildIndxConf *)signal->getDataPtrSend();
- buildIndxConf->setUserRef(subRecPtr.p->userReference);
- buildIndxConf->setConnectionPtr(subRecPtr.p->connectionPtr);
- buildIndxConf->setRequestType(BuildIndxReq::RT_TRIX);
- buildIndxConf->setIndexType(subRecPtr.p->indexType);
- buildIndxConf->setTableId(subRecPtr.p->sourceTableId);
- buildIndxConf->setIndexId(subRecPtr.p->targetTableId);
-
- sendSignal(subRecPtr.p->userReference, GSN_BUILDINDXCONF, signal,
- BuildIndxConf::SignalLength , JBB);
- } else {
- // Build failed, reply to original sender
- BuildIndxRef * buildIndxRef = (BuildIndxRef *)signal->getDataPtrSend();
- buildIndxRef->setUserRef(subRecPtr.p->userReference);
- buildIndxRef->setConnectionPtr(subRecPtr.p->connectionPtr);
- buildIndxRef->setRequestType(BuildIndxReq::RT_TRIX);
- buildIndxRef->setIndexType(subRecPtr.p->indexType);
- buildIndxRef->setTableId(subRecPtr.p->sourceTableId);
- buildIndxRef->setIndexId(subRecPtr.p->targetTableId);
- buildIndxRef->setErrorCode(subRecPtr.p->errorCode);
-
- sendSignal(subRecPtr.p->userReference, GSN_BUILDINDXREF, signal,
- BuildIndxRef::SignalLength , JBB);
- }
-
- // Release subscription record
- subRecPtr.p->attributeOrder.release();
- c_theSubscriptions.release(subRecPtr.i);
-}
-
-void Trix::checkParallelism(Signal* signal, SubscriptionRecord* subRec)
-{
- if ((subRec->pendingSubSyncContinueConf) &&
- (subRec->expectedConf < subRec->parallelism)) {
- SubSyncContinueConf * subSyncContinueConf =
- (SubSyncContinueConf *) signal->getDataPtrSend();
- subSyncContinueConf->subscriptionId = subRec->subscriptionId;
- subSyncContinueConf->subscriptionKey = subRec->subscriptionKey;
- sendSignal(SUMA_REF, GSN_SUB_SYNC_CONTINUE_CONF, signal,
- SubSyncContinueConf::SignalLength , JBB);
- subRec->pendingSubSyncContinueConf = false;
- }
-}
-
-BLOCK_FUNCTIONS(Trix)
-
-template void append(DataBuffer<15>&,SegmentedSectionPtr,SectionSegmentPool&);
diff --git a/storage/ndb/src/kernel/blocks/trix/Trix.hpp b/storage/ndb/src/kernel/blocks/trix/Trix.hpp
deleted file mode 100644
index f8163f64849..00000000000
--- a/storage/ndb/src/kernel/blocks/trix/Trix.hpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TRIX_H
-#define TRIX_H
-
-#include <SimulatedBlock.hpp>
-#include <trigger_definitions.h>
-#include <DataBuffer.hpp>
-#include <SimpleProperties.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/CreateTrig.hpp>
-#include <signaldata/BuildIndx.hpp>
-
-// Error codes
-#define INTERNAL_ERROR_ILLEGAL_CALL 4344
-#define INTERNAL_ERROR_TRIX_BUSY 4345
-
-/**
- * TRIX - This block manages triggers and index (in coop with DICT)
- */
-class Trix : public SimulatedBlock
-{
-public:
- Trix(Block_context&);
- virtual ~Trix();
-
-public:
- // Subscription data, when communicating with SUMA
-
- enum RequestType {
- TABLE_REORG = 0,
- INDEX_BUILD = 1
- };
- typedef DataBuffer<11> AttrOrderBuffer;
-
-private:
- // Private attributes
-
- BLOCK_DEFINES(Trix);
-
- // Declared but not defined
- //DBtrix(const Trix &obj);
- //void operator = (const Trix &);
-
- // Block state
- enum BlockState {
- NOT_STARTED,
- STARTED,
- NODE_FAILURE,
- IDLE,
- BUSY
- };
-
- BlockState c_blockState;
-
- // Node data needed when communicating with remote TRIX:es
- struct NodeRecord {
- bool alive;
- BlockReference trixRef;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- typedef Ptr<NodeRecord> NodeRecPtr;
-
- /**
- * The pool of node records
- */
- ArrayPool<NodeRecord> c_theNodeRecPool;
-
- /**
- * The list of other NDB nodes
- */
- DLList<NodeRecord> c_theNodes;
-
- Uint32 c_masterNodeId;
- BlockReference c_masterTrixRef;
- Uint16 c_noNodesFailed;
- Uint16 c_noActiveNodes;
-
- AttrOrderBuffer::DataBufferPool c_theAttrOrderBufferPool;
-
- struct SubscriptionRecord {
- SubscriptionRecord(AttrOrderBuffer::DataBufferPool & aop):
- attributeOrder(aop)
- {}
- RequestType requestType;
- BlockReference userReference; // For user
- Uint32 connectionPtr; // For user
- Uint32 subscriptionId; // For Suma
- Uint32 subscriptionKey; // For Suma
- Uint32 prepareId; // For DbUtil
- Uint32 indexType;
- Uint32 sourceTableId;
- Uint32 targetTableId;
- AttrOrderBuffer attributeOrder;
- Uint32 noOfIndexColumns;
- Uint32 noOfKeyColumns;
- Uint32 parallelism;
- BuildIndxRef::ErrorCode errorCode;
- bool subscriptionCreated;
- bool pendingSubSyncContinueConf;
- Uint32 expectedConf; // Count in n UTIL_EXECUTE_CONF + 1 SUB_SYNC_CONF
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- typedef Ptr<SubscriptionRecord> SubscriptionRecPtr;
-
- /**
- * The pool of node records
- */
- ArrayPool<SubscriptionRecord> c_theSubscriptionRecPool;
-
- /**
- * The list of other subscriptions
- */
- DLList<SubscriptionRecord> c_theSubscriptions;
-
- // System start
- void execREAD_CONFIG_REQ(Signal* signal);
- void execSTTOR(Signal* signal);
- void execNDB_STTOR(Signal* signal);
-
- // Node management
- void execREAD_NODESCONF(Signal* signal);
- void execREAD_NODESREF(Signal* signal);
- void execNODE_FAILREP(Signal* signal);
- void execINCL_NODEREQ(Signal* signal);
- // Debugging
- void execDUMP_STATE_ORD(Signal* signal);
-
- // Build index
- void execBUILDINDXREQ(Signal* signal);
- void execBUILDINDXCONF(Signal* signal);
- void execBUILDINDXREF(Signal* signal);
-
- void execUTIL_PREPARE_CONF(Signal* signal);
- void execUTIL_PREPARE_REF(Signal* signal);
- void execUTIL_EXECUTE_CONF(Signal* signal);
- void execUTIL_EXECUTE_REF(Signal* signal);
- void execUTIL_RELEASE_CONF(Signal* signal);
- void execUTIL_RELEASE_REF(Signal* signal);
-
- // Suma signals
- void execSUB_CREATE_CONF(Signal* signal);
- void execSUB_CREATE_REF(Signal* signal);
- void execSUB_REMOVE_CONF(Signal* signal);
- void execSUB_REMOVE_REF(Signal* signal);
- void execSUB_SYNC_CONF(Signal* signal);
- void execSUB_SYNC_REF(Signal* signal);
- void execSUB_SYNC_CONTINUE_REQ(Signal* signal);
- void execSUB_TABLE_DATA(Signal* signal);
-
- // Utility functions
- void setupSubscription(Signal* signal, SubscriptionRecPtr subRecPtr);
- void startTableScan(Signal* signal, SubscriptionRecPtr subRecPtr);
- void prepareInsertTransactions(Signal* signal, SubscriptionRecPtr subRecPtr);
- void executeInsertTransaction(Signal* signal, SubscriptionRecPtr subRecPtr,
- SegmentedSectionPtr headerPtr,
- SegmentedSectionPtr dataPtr);
- void buildComplete(Signal* signal, SubscriptionRecPtr subRecPtr);
- void buildFailed(Signal* signal,
- SubscriptionRecPtr subRecPtr,
- BuildIndxRef::ErrorCode);
- void checkParallelism(Signal* signal, SubscriptionRecord* subRec);
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/blocks/tsman.cpp b/storage/ndb/src/kernel/blocks/tsman.cpp
deleted file mode 100644
index 90f83c8ac82..00000000000
--- a/storage/ndb/src/kernel/blocks/tsman.cpp
+++ /dev/null
@@ -1,2224 +0,0 @@
-/* Copyright (c) 2003, 2005-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "tsman.hpp"
-#include "pgman.hpp"
-#include "diskpage.hpp"
-#include <signaldata/FsRef.hpp>
-#include <signaldata/FsConf.hpp>
-#include <signaldata/FsOpenReq.hpp>
-#include <signaldata/FsCloseReq.hpp>
-#include <signaldata/CreateFilegroupImpl.hpp>
-#include <signaldata/DropFilegroupImpl.hpp>
-#include <signaldata/FsReadWriteReq.hpp>
-#include <signaldata/Extent.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/TsmanContinueB.hpp>
-#include <signaldata/GetTabInfo.hpp>
-#include <dbtup/Dbtup.hpp>
-
-#define JONAS 0
-
-#define COMMITTED_MASK ((1 << 0) | (1 << 1))
-#define UNCOMMITTED_MASK ((1 << 2) | (1 << 3))
-#define UNCOMMITTED_SHIFT 2
-
-#define DBG_UNDO 0
-
-Tsman::Tsman(Block_context& ctx,
- class Pgman* pg, class Lgman* lg) :
- SimulatedBlock(TSMAN, ctx),
- m_file_hash(m_file_pool),
- m_tablespace_list(m_tablespace_pool),
- m_tablespace_hash(m_tablespace_pool),
- m_page_cache_client(this, pg),
- m_lgman(lg)
-{
- BLOCK_CONSTRUCTOR(Tsman);
-
- Uint32 SZ = File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
- ndbrequire((COMMITTED_MASK & UNCOMMITTED_MASK) == 0);
- ndbrequire((COMMITTED_MASK | UNCOMMITTED_MASK) == ((1 << SZ) - 1));
-
- // Add received signals
- addRecSignal(GSN_STTOR, &Tsman::execSTTOR);
- addRecSignal(GSN_READ_CONFIG_REQ, &Tsman::execREAD_CONFIG_REQ);
- addRecSignal(GSN_DUMP_STATE_ORD, &Tsman::execDUMP_STATE_ORD);
- addRecSignal(GSN_CONTINUEB, &Tsman::execCONTINUEB);
-
- addRecSignal(GSN_CREATE_FILE_REQ, &Tsman::execCREATE_FILE_REQ);
- addRecSignal(GSN_CREATE_FILEGROUP_REQ, &Tsman::execCREATE_FILEGROUP_REQ);
-
- addRecSignal(GSN_DROP_FILE_REQ, &Tsman::execDROP_FILE_REQ);
- addRecSignal(GSN_DROP_FILEGROUP_REQ, &Tsman::execDROP_FILEGROUP_REQ);
-
- addRecSignal(GSN_FSWRITEREQ, &Tsman::execFSWRITEREQ);
-
- addRecSignal(GSN_FSOPENREF, &Tsman::execFSOPENREF, true);
- addRecSignal(GSN_FSOPENCONF, &Tsman::execFSOPENCONF);
-
- //addRecSignal(GSN_FSCLOSEREF, &Tsman::execFSCLOSEREF);
- addRecSignal(GSN_FSCLOSECONF, &Tsman::execFSCLOSECONF);
- addRecSignal(GSN_FSREADCONF, &Tsman::execFSREADCONF);
-
- addRecSignal(GSN_ALLOC_EXTENT_REQ, &Tsman::execALLOC_EXTENT_REQ);
- addRecSignal(GSN_FREE_EXTENT_REQ, &Tsman::execFREE_EXTENT_REQ);
-
- addRecSignal(GSN_START_RECREQ, &Tsman::execSTART_RECREQ);
-
- addRecSignal(GSN_LCP_FRAG_ORD, &Tsman::execLCP_FRAG_ORD);
- addRecSignal(GSN_END_LCP_REQ, &Tsman::execEND_LCP_REQ);
-
- addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ);
-
- m_tablespace_hash.setSize(10);
- m_file_hash.setSize(10);
- m_lcp_ongoing = false;
-}
-
-Tsman::~Tsman()
-{
-}
-
-BLOCK_FUNCTIONS(Tsman)
-
-void
-Tsman::execREAD_CONFIG_REQ(Signal* signal)
-{
- jamEntry();
-
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
-
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
-
- const ndb_mgm_configuration_iterator * p =
- m_ctx.m_config.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- Pool_context pc;
- pc.m_block = this;
-
- m_file_pool.init(RT_TSMAN_FILE, pc);
- m_tablespace_pool.init(RT_TSMAN_FILEGROUP, pc);
-
- ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
- ReadConfigConf::SignalLength, JBB);
-}
-
-void
-Tsman::execSTTOR(Signal* signal)
-{
- jamEntry();
-
- sendSTTORRY(signal);
-
- return;
-}
-
-void
-Tsman::sendSTTORRY(Signal* signal){
- signal->theData[0] = 0;
- signal->theData[3] = 1;
- signal->theData[4] = 3;
- signal->theData[5] = 255; // No more start phases from missra
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
-}
-
-void
-Tsman::execCONTINUEB(Signal* signal){
- jamEntry();
- Uint32 type = signal->theData[0];
- Uint32 ptrI = signal->theData[1];
- switch(type){
- case TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS:
- scan_tablespace(signal, ptrI);
- return;
- case TsmanContinueB::SCAN_DATAFILE_EXTENT_HEADERS:
- scan_datafile(signal, ptrI, signal->theData[2]);
- return;
- case TsmanContinueB::END_LCP:
- end_lcp(signal, ptrI, signal->theData[2], signal->theData[3]);
- return;
- case TsmanContinueB::RELEASE_EXTENT_PAGES:
- {
- Ptr<Datafile> ptr;
- m_file_pool.getPtr(ptr, ptrI);
- release_extent_pages(signal, ptr);
- return;
- }
- case TsmanContinueB::LOAD_EXTENT_PAGES:
- {
- Ptr<Datafile> ptr;
- m_file_pool.getPtr(ptr, ptrI);
- load_extent_pages(signal, ptr);
- return;
- }
- }
- ndbrequire(false);
-}
-
-#ifdef VM_TRACE
-struct TsmanChunk
-{
- Uint32 page_count;
- Local_key start_page;
- Vector<Uint32> bitmask;
-};
-template class Vector<TsmanChunk>;
-#endif
-
-void
-Tsman::execDUMP_STATE_ORD(Signal* signal){
- jamEntry();
-
- /**
- * 9000
- */
-
- if(signal->theData[0] == DumpStateOrd::DumpTsman + 0)
- {
- Uint32 id = signal->theData[1];
-
- AllocExtentReq* req = (AllocExtentReq*)signal->theData;
- req->request.tablespace_id = id;
- req->request.table_id = 0;
- req->request.fragment_id = 0;
- execALLOC_EXTENT_REQ(signal);
-
- if(req->reply.errorCode == 0){
- ndbout_c("Success");
- ndbout_c("page: %d %d count: %d",
- req->reply.page_id.m_file_no,
- req->reply.page_id.m_page_no,
- req->reply.page_count);
- } else {
- ndbout_c("Error: %d", req->reply.errorCode);
- }
- }
-
- if(signal->theData[0] == DumpStateOrd::DumpTsman + 1)
- {
- Uint32 id = signal->theData[1];
- Uint32 file= signal->theData[2];
- Uint32 page= signal->theData[3];
- Uint32 bits= signal->theData[4];
-
- AllocPageReq* req = (AllocPageReq*)signal->theData;
- req->request.tablespace_id = id;
- req->request.table_id = 0;
- req->request.fragment_id = 0;
- req->key.m_page_no= page;
- req->key.m_file_no= file;
- req->bits= bits;
- execALLOC_PAGE_REQ(signal);
-
- if(req->reply.errorCode == 0){
- ndbout_c("Success");
- ndbout_c("page: %d %d bits: %d",
- req->key.m_file_no,
- req->key.m_page_no,
- req->bits);
- } else {
- ndbout_c("Error: %d", req->reply.errorCode);
- }
- }
-
-#ifdef VM_TRACE
- if(signal->theData[0] == DumpStateOrd::DumpTsman + 2)
- {
- Uint32 id = signal->theData[1];
- Vector<TsmanChunk> chunks;
- for(size_t i = 0; i<1000; i++)
- {
- /**
- * 0) Alloc extent ok
- * 1) toggle page bits
- * 2) Free extent
- */
- Uint32 sz = chunks.size();
- switch((rand() * sz) % 2){
- case 0:
- {
- ndbout_c("case 0");
- AllocExtentReq* req = (AllocExtentReq*)signal->theData;
- req->request.tablespace_id = id;
- req->request.table_id = 0;
- req->request.fragment_id = 0;
- execALLOC_EXTENT_REQ(signal);
- if(req->reply.errorCode == 0){
- TsmanChunk c;
- c.start_page = req->reply.page_id;
- c.page_count = req->reply.page_count;
- Uint32 words = File_formats::Datafile::extent_header_words(c.page_count);
- ndbout_c("execALLOC_EXTENT_REQ - OK - [ %d %d ] count: %d(%d)",
- c.start_page.m_file_no,
- c.start_page.m_page_no,
- c.page_count,
- words);
- Uint32 zero = 0;
- chunks.push_back(c);
- chunks.back().bitmask.fill(words, zero);
-
- ndbout_c("execALLOC_EXTENT_REQ - OK - [ %d %d ] count: %d",
- chunks.back().start_page.m_file_no,
- chunks.back().start_page.m_page_no,
- chunks.back().page_count);
- } else {
- ndbout_c("Error: %d", req->reply.errorCode);
- }
- break;
- }
- case 1:
- {
- Uint32 chunk = rand() % sz;
- Uint32 count = chunks[chunk].page_count;
- Uint32 page = rand() % count;
- ndbout_c("case 1 - %d %d %d", chunk, count, page);
-
- File_formats::Datafile::Extent_header* header =
- (File_formats::Datafile::Extent_header*)
- (chunks[chunk].bitmask.getBase());
- Uint32 curr_bits = header->get_free_bits(page);
- Uint32 new_bits = curr_bits ^ rand();
- Local_key key = chunks[chunk].start_page;
- key.m_page_no += page;
- ndbrequire(update_page_free_bits(signal, &key, new_bits) == 0);
- }
- }
- }
- }
-#endif
-
- if(signal->theData[0] == DumpStateOrd::DumpTsman + 3)
- {
- GetTabInfoReq* req = (GetTabInfoReq*)signal->theData;
- req->requestType= GetTabInfoReq::RequestById;
- req->tableId= signal->theData[1];
-
- execGET_TABINFOREQ(signal);
-
- }
-
-}
-
-void
-Tsman::execCREATE_FILEGROUP_REQ(Signal* signal){
- jamEntry();
- CreateFilegroupImplReq* req= (CreateFilegroupImplReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- Ptr<Tablespace> ptr;
- CreateFilegroupImplRef::ErrorCode err = CreateFilegroupImplRef::NoError;
- do {
- if (m_tablespace_hash.find(ptr, req->filegroup_id))
- {
- jam();
- err = CreateFilegroupImplRef::FilegroupAlreadyExists;
- break;
- }
-
- if (!m_tablespace_pool.seize(ptr))
- {
- jam();
- err = CreateFilegroupImplRef::OutOfFilegroupRecords;
- break;
- }
-
- new (ptr.p) Tablespace(this, m_lgman, req);
- m_tablespace_hash.add(ptr);
- m_tablespace_list.add(ptr);
-
- ptr.p->m_state = Tablespace::TS_ONLINE;
-
- CreateFilegroupImplConf* conf=
- (CreateFilegroupImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILEGROUP_CONF, signal,
- CreateFilegroupImplConf::SignalLength, JBB);
- return;
- } while(0);
-
- CreateFilegroupImplRef* ref= (CreateFilegroupImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = err;
- sendSignal(senderRef, GSN_CREATE_FILEGROUP_REF, signal,
- CreateFilegroupImplRef::SignalLength, JBB);
-}
-
-NdbOut&
-operator<<(NdbOut& out, const File_formats::Datafile::Extent_header & obj)
-{
- out << "table: " << obj.m_table
- << " fragment: " << obj.m_fragment_id << " ";
- for(Uint32 i = 0; i<32; i++)
- {
- char t[2];
- BaseString::snprintf(t, sizeof(t), "%x", obj.get_free_bits(i));
- out << t;
- }
- return out;
-}
-
-void
-Tsman::execDROP_FILEGROUP_REQ(Signal* signal){
- jamEntry();
-
- Uint32 errorCode = 0;
- DropFilegroupImplReq req = *(DropFilegroupImplReq*)signal->getDataPtr();
- Ptr<Tablespace> ptr;
- do
- {
- if (!m_tablespace_hash.find(ptr, req.filegroup_id))
- {
- errorCode = DropFilegroupImplRef::NoSuchFilegroup;
- break;
- }
-
- if (ptr.p->m_version != req.filegroup_version)
- {
- errorCode = DropFilegroupImplRef::InvalidFilegroupVersion;
- break;
- }
-
- if (! (ptr.p->m_meta_files.isEmpty() && ptr.p->m_free_files.isEmpty() &&
- ptr.p->m_full_files.isEmpty()))
- {
- errorCode = DropFilegroupImplRef::FilegroupInUse;
- break;
- }
-
- switch(req.requestInfo){
- case DropFilegroupImplReq::Prepare:
- ptr.p->m_state = Tablespace::TS_DROPPING;
- break;
- case DropFilegroupImplReq::Commit:
- m_tablespace_list.remove(ptr);
- m_tablespace_hash.release(ptr);
- break;
- case DropFilegroupImplReq::Abort:
- ptr.p->m_state = Tablespace::TS_ONLINE;
- break;
- default:
- ndbrequire(false);
- }
- } while(0);
-
- if (errorCode)
- {
- DropFilegroupImplRef* ref =
- (DropFilegroupImplRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = req.senderData;
- ref->errorCode = errorCode;
- sendSignal(req.senderRef, GSN_DROP_FILEGROUP_REF, signal,
- DropFilegroupImplRef::SignalLength, JBB);
- }
- else
- {
- DropFilegroupImplConf* conf =
- (DropFilegroupImplConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = req.senderData;
- sendSignal(req.senderRef, GSN_DROP_FILEGROUP_CONF, signal,
- DropFilegroupImplConf::SignalLength, JBB);
- }
-}
-
-bool
-Tsman::find_file_by_id(Ptr<Datafile>& ptr,
- Datafile_list::Head& head,
- Uint32 id)
-{
- Local_datafile_list list(m_file_pool, head);
- for(list.first(ptr); !ptr.isNull(); list.next(ptr))
- if(ptr.p->m_file_id == id)
- return true;
- return false;
-}
-
-void
-Tsman::execCREATE_FILE_REQ(Signal* signal){
- jamEntry();
- CreateFileImplReq* req= (CreateFileImplReq*)signal->getDataPtr();
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- Ptr<Tablespace> ptr;
- CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
- do {
- if (!m_tablespace_hash.find(ptr, req->filegroup_id))
- {
- jam();
- err = CreateFileImplRef::InvalidFilegroup;
- break;
- }
-
- if (ptr.p->m_version != req->filegroup_version)
- {
- jam();
- err = CreateFileImplRef::InvalidFilegroupVersion;
- break;
- }
-
- if (ptr.p->m_state != Tablespace::TS_ONLINE)
- {
- jam();
- err = CreateFileImplRef::FilegroupNotOnline;
- break;
- }
-
- Ptr<Datafile> file_ptr;
- switch(req->requestInfo){
- case CreateFileImplReq::Commit:
- {
- ndbrequire(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id));
- file_ptr.p->m_create.m_senderRef = req->senderRef;
- file_ptr.p->m_create.m_senderData = req->senderData;
- file_ptr.p->m_create.m_requestInfo = req->requestInfo;
-
- m_page_cache_client.map_file_no(file_ptr.p->m_file_no, file_ptr.p->m_fd);
- file_ptr.p->m_create.m_loading_extent_page = 1;
- load_extent_pages(signal, file_ptr);
- return;
- }
- case CreateFileImplReq::Abort:
- {
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- if(find_file_by_id(file_ptr, ptr.p->m_meta_files, req->file_id))
- {
- file_ptr.p->m_create.m_senderRef = senderRef;
- file_ptr.p->m_create.m_senderData = senderData;
- file_ptr.p->m_create.m_requestInfo = req->requestInfo;
- create_file_abort(signal, file_ptr);
- return;
- }
- else
- {
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- return;
- }
- }
- default:
- // Prepare
- break;
- }
-
- if (!m_file_pool.seize(file_ptr))
- {
- jam();
- err = CreateFileImplRef::OutOfFileRecords;
- break;
- }
-
- if(ERROR_INSERTED(16000) ||
- (sizeof(void*) == 4 && req->file_size_hi & 0xFFFFFFFF))
- {
- jam();
- if(signal->getNoOfSections())
- releaseSections(signal);
-
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = CreateFileImplRef::FileSizeTooLarge;
- sendSignal(senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
- return;
- }
-
- new (file_ptr.p) Datafile(req);
- Local_datafile_list tmp(m_file_pool, ptr.p->m_meta_files);
- tmp.add(file_ptr);
-
- file_ptr.p->m_state = Datafile::FS_CREATING;
- file_ptr.p->m_tablespace_ptr_i = ptr.i;
- file_ptr.p->m_extent_size = ptr.p->m_extent_size;
-
- err = (CreateFileImplRef::ErrorCode)open_file(signal, ptr, file_ptr, req);
- if(err)
- break;
- return;
- } while(0);
-
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = senderData;
- ref->senderRef = reference();
- ref->errorCode = err;
- sendSignal(senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
-}
-
-static inline Uint64 DIV(Uint64 a, Uint64 b){ return (a + b - 1) / b;}
-
-void
-Tsman::release_extent_pages(Signal* signal, Ptr<Datafile> ptr)
-{
- Uint32 page = ptr.p->m_create.m_extent_pages;
- if (page > 0)
- {
- Page_cache_client::Request preq;
- preq.m_page.m_file_no = ptr.p->m_file_no;
- preq.m_page.m_page_no = page;
-
- preq.m_callback.m_callbackData = ptr.i;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Tsman::release_extent_pages_callback);
-
- int page_id;
- int flags = Page_cache_client::UNLOCK_PAGE;
- if((page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- execute(signal, preq.m_callback, page_id);
- }
- return;
- }
-
- create_file_abort(signal, ptr);
-}
-
-void
-Tsman::release_extent_pages_callback(Signal* signal,
- Uint32 ptrI,
- Uint32 page_id)
-{
- Ptr<Datafile> ptr;
- m_file_pool.getPtr(ptr, ptrI);
- Local_key key;
- key.m_file_no = ptr.p->m_file_no;
- key.m_page_no = ptr.p->m_create.m_extent_pages;
- ndbrequire(m_page_cache_client.drop_page(key, page_id));
- ptr.p->m_create.m_extent_pages--;
-
- signal->theData[0] = TsmanContinueB::RELEASE_EXTENT_PAGES;
- signal->theData[1] = ptr.i;
-
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Tsman::create_file_abort(Signal* signal, Ptr<Datafile> ptr)
-{
- if (ptr.p->m_fd == RNIL)
- {
- ((FsConf*)signal->getDataPtr())->userPointer = ptr.i;
- execFSCLOSECONF(signal);
- return;
- }
-
- FsCloseReq *req= (FsCloseReq*)signal->getDataPtrSend();
- req->filePointer = ptr.p->m_fd;
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->fileFlag = 0;
- FsCloseReq::setRemoveFileFlag(req->fileFlag, true);
-
- sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal,
- FsCloseReq::SignalLength, JBB);
-}
-
-void
-Tsman::execFSCLOSECONF(Signal* signal)
-{
- Ptr<Datafile> ptr;
- Ptr<Tablespace> lg_ptr;
- Uint32 ptrI = ((FsConf*)signal->getDataPtr())->userPointer;
- m_file_pool.getPtr(ptr, ptrI);
-
- Uint32 senderRef = ptr.p->m_create.m_senderRef;
- Uint32 senderData = ptr.p->m_create.m_senderData;
-
- if (ptr.p->m_state == Datafile::FS_CREATING)
- {
- m_page_cache_client.free_data_file(ptr.p->m_file_no);
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- }
- else if(ptr.p->m_state == Datafile::FS_DROPPING)
- {
- m_file_hash.remove(ptr);
- m_page_cache_client.free_data_file(ptr.p->m_file_no, ptr.p->m_fd);
- DropFileImplConf* conf= (DropFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_DROP_FILE_CONF, signal,
- DropFileImplConf::SignalLength, JBB);
-
- }
- else
- {
- ndbrequire(false);
- }
-
- {
- m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
- Local_datafile_list list(m_file_pool, lg_ptr.p->m_meta_files);
- list.release(ptr);
- }
-}
-
-int
-Tsman::open_file(Signal* signal,
- Ptr<Tablespace> ts_ptr,
- Ptr<Datafile> ptr, CreateFileImplReq* org)
-{
- Uint32 requestInfo = org->requestInfo;
- Uint32 hi = org->file_size_hi;
- Uint32 lo = org->file_size_lo;
-
- if(requestInfo == CreateFileImplReq::Create ||
- requestInfo == CreateFileImplReq::CreateForce){
- jam();
- Uint32 file_no = m_page_cache_client.create_data_file();
- if(file_no == RNIL)
- {
- return CreateFileImplRef::OutOfFileRecords;
- }
- ptr.p->m_file_no = file_no;
- }
-
- FsOpenReq* req = (FsOpenReq*)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = ptr.i;
-
- memset(req->fileNumber, 0, sizeof(req->fileNumber));
- FsOpenReq::setVersion(req->fileNumber, 4); // Version 4 = specified filename
-
- req->fileFlags = 0;
- req->fileFlags |= FsOpenReq::OM_READWRITE;
- req->fileFlags |= FsOpenReq::OM_DIRECT;
- switch(requestInfo){
- case CreateFileImplReq::Create:
- req->fileFlags |= FsOpenReq::OM_CREATE_IF_NONE;
- req->fileFlags |= FsOpenReq::OM_INIT;
- break;
- case CreateFileImplReq::CreateForce:
- req->fileFlags |= FsOpenReq::OM_CREATE;
- req->fileFlags |= FsOpenReq::OM_INIT;
- break;
- case CreateFileImplReq::Open:
- req->fileFlags |= FsOpenReq::OM_CHECK_SIZE;
- break;
- default:
- ndbrequire(false);
- }
-
- req->page_size = File_formats::NDB_PAGE_SIZE;
- req->file_size_hi = hi;
- req->file_size_lo = lo;
-
- Uint64 pages = (Uint64(hi) << 32 | lo) / File_formats::NDB_PAGE_SIZE;
- Uint32 extent_size = ts_ptr.p->m_extent_size; // Extent size in #pages
- Uint64 extents = (pages + extent_size - 1) / extent_size;
- extents = extents ? extents : 1;
- Uint64 data_pages = extents * extent_size;
-
- Uint32 eh_words = File_formats::Datafile::extent_header_words(extent_size);
- ndbrequire(eh_words < File_formats::Datafile::EXTENT_PAGE_WORDS);
- Uint32 extents_per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint64 extent_pages = (extents + extents_per_page - 1) / extents_per_page;
-
- ptr.p->m_create.m_extent_pages = extent_pages;
- ptr.p->m_create.m_data_pages = data_pages;
- // Forward filename
-
- /**
- * Update file size
- */
- pages = 1 + extent_pages + data_pages;
- Uint64 bytes = pages * File_formats::NDB_PAGE_SIZE;
- hi = bytes >> 32;
- lo = bytes & 0xFFFFFFFF;
- req->file_size_hi = hi;
- req->file_size_lo = lo;
-
- sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, FsOpenReq::SignalLength, JBB);
-
- return 0;
-}
-
-void
-Tsman::execFSWRITEREQ(Signal* signal)
-{
- /**
- * This is currently run in other thread -> no jam
- */
- //jamEntry();
- Ptr<Datafile> ptr;
- Ptr<GlobalPage> page_ptr;
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtr();
-
- m_file_pool.getPtr(ptr, req->userPointer);
- m_global_page_pool.getPtr(page_ptr, req->data.pageData[0]);
- memset(page_ptr.p, 0, File_formats::NDB_PAGE_SIZE);
-
- Uint32 page_no = req->varIndex;
- Uint32 size = ptr.p->m_extent_size;
- Uint32 extent_pages = ptr.p->m_create.m_extent_pages;
- Uint32 datapages = ptr.p->m_create.m_data_pages;
-
- Uint32 header_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS / header_words;
- Uint32 extents = datapages/size;
-
- if (page_no == 0)
- {
- //jam();
- Ptr<Tablespace> lg_ptr;
- m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- File_formats::Datafile::Zero_page* page =
- (File_formats::Datafile::Zero_page*)page_ptr.p;
- page->m_page_header.init(File_formats::FT_Datafile,
- getOwnNodeId(),
- ndbGetOwnVersion(),
- time(0));
- page->m_file_no = ptr.p->m_file_no;
- page->m_file_id = ptr.p->m_file_id;
- page->m_tablespace_id = lg_ptr.p->m_tablespace_id;
- page->m_tablespace_version = lg_ptr.p->m_version;
- page->m_data_pages = extents * size;
- page->m_extent_pages = extent_pages;
- page->m_extent_size = size;
- page->m_extent_count = extents;
- page->m_extent_headers_per_page = per_page;
- page->m_extent_header_words = header_words;
- page->m_extent_header_bits_per_page =
- File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
- }
- else if ((page_no-1) < extent_pages)
- {
- //jam();
-
- Uint32 curr_extent = page_no*per_page;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)page_ptr.p;
- page->m_page_header.m_page_lsn_hi = 0;
- page->m_page_header.m_page_lsn_lo = 0;
- page->m_page_header.m_page_type = File_formats::PT_Unallocated;
-
- for(Uint32 i = 0; i<per_page; i++)
- {
- File_formats::Datafile::Extent_header * head = page->get_header(i, size);
- memset(head, 0, 4*header_words);
- head->m_table = RNIL;
- head->m_next_free_extent = ++curr_extent;
- }
- if (page_no == extent_pages)
- {
- Uint32 last = extents % per_page;
- page->get_header(last - 1, size)->m_next_free_extent = RNIL;
- }
- }
- else
- {
- //jam();
- File_formats::Datafile::Data_page* page =
- (File_formats::Datafile::Data_page*)page_ptr.p;
- page->m_page_header.m_page_lsn_hi = 0;
- page->m_page_header.m_page_lsn_lo = 0;
- }
-}
-
-void
-Tsman::create_file_ref(Signal* signal,
- Ptr<Tablespace> lg_ptr,
- Ptr<Datafile> ptr,
- Uint32 error, Uint32 fsError, Uint32 osError)
-{
- CreateFileImplRef* ref= (CreateFileImplRef*)signal->getDataPtr();
- ref->senderData = ptr.p->m_create.m_senderData;
- ref->senderRef = reference();
- ref->errorCode = (CreateFileImplRef::ErrorCode)error;
- ref->fsErrCode = fsError;
- ref->osErrCode = osError;
- sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_REF, signal,
- CreateFileImplRef::SignalLength, JBB);
-
- Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- meta.release(ptr);
-}
-
-void
-Tsman::execFSOPENREF(Signal* signal)
-{
- jamEntry();
-
- Ptr<Datafile> ptr;
- Ptr<Tablespace> lg_ptr;
- FsRef* ref = (FsRef*)signal->getDataPtr();
-
- Uint32 errCode = ref->errorCode;
- Uint32 osErrCode = ref->osErrorCode;
-
- m_file_pool.getPtr(ptr, ref->userPointer);
- m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- create_file_ref(signal, lg_ptr, ptr,
- CreateFileImplRef::FileError, errCode, osErrCode);
-}
-
-void
-Tsman::execFSOPENCONF(Signal* signal)
-{
- jamEntry();
- Ptr<Datafile> ptr;
- Ptr<Tablespace> lg_ptr;
- FsConf* conf = (FsConf*)signal->getDataPtr();
-
- m_file_pool.getPtr(ptr, conf->userPointer);
- m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- Uint32 fd = ptr.p->m_fd = conf->filePointer;
-
- switch(ptr.p->m_create.m_requestInfo){
- case CreateFileImplReq::Create:
- case CreateFileImplReq::CreateForce:
- {
- jam();
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = ptr.p->m_create.m_senderData;
- conf->senderRef = reference();
- sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- return;
- }
- case CreateFileImplReq::Open:
- {
- jam();
- /**
- * Read zero page and compare values
- * can't use page cache as file's file_no is not known
- */
- Ptr<GlobalPage> page_ptr;
- if(m_global_page_pool.seize(page_ptr) == false)
- {
- jam();
- create_file_ref(signal, lg_ptr, ptr,
- CreateFileImplRef::OutOfMemory, 0, 0);
- return;
- }
-
- ptr.p->m_create.m_page_ptr_i = page_ptr.i;
-
- FsReadWriteReq* req= (FsReadWriteReq*)signal->getDataPtrSend();
- req->filePointer = fd;
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->varIndex = 0;
- req->numberOfPages = 1;
- req->operationFlag = 0;
- FsReadWriteReq::setFormatFlag(req->operationFlag,
- FsReadWriteReq::fsFormatGlobalPage);
- req->data.pageData[0] = page_ptr.i;
- sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
- FsReadWriteReq::FixedLength + 1, JBB);
- return;
- }
- }
-}
-
-void
-Tsman::execFSREADCONF(Signal* signal){
- jamEntry();
- Ptr<Datafile> ptr;
- Ptr<Tablespace> lg_ptr;
- FsConf* conf = (FsConf*)signal->getDataPtr();
-
- /**
- * We currently on read pages here as part of CREATE_FILE
- * (other read is done using pgman)
- */
- m_file_pool.getPtr(ptr, conf->userPointer);
- m_tablespace_hash.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- Ptr<GlobalPage> page_ptr;
- m_global_page_pool.getPtr(page_ptr, ptr.p->m_create.m_page_ptr_i);
-
- File_formats::Datafile::Zero_page* page =
- (File_formats::Datafile::Zero_page*)page_ptr.p;
-
- CreateFileImplRef::ErrorCode err = CreateFileImplRef::NoError;
- Uint32 fsError = 0;
- Uint32 osError = 0;
-
- do {
- err = CreateFileImplRef::InvalidFileMetadata;
- fsError = page->m_page_header.validate(File_formats::FT_Datafile,
- getOwnNodeId(),
- ndbGetOwnVersion(),
- time(0));
- if(fsError)
- break;
-
- osError = 1;
- if(page->m_file_id != ptr.p->m_file_id)
- break;
-
- osError = 2;
- if(page->m_tablespace_id != lg_ptr.p->m_tablespace_id)
- break;
-
- osError = 3;
- if(page->m_tablespace_version != lg_ptr.p->m_version)
- break;
-
- osError = 4;
- if(page->m_data_pages != ptr.p->m_create.m_data_pages)
- break;
-
- osError = 5;
- if(page->m_extent_pages != ptr.p->m_create.m_extent_pages)
- break;
-
- osError = 6;
- if(page->m_extent_size != ptr.p->m_extent_size)
- break;
-
- osError = 7;
- if(page->m_extent_header_bits_per_page !=
- File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE)
- break;
-
- osError = 8;
- Uint32 eh_words =
- File_formats::Datafile::extent_header_words(ptr.p->m_extent_size);
- if(page->m_extent_header_words != eh_words)
- break;
-
- osError = 9;
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- if(page->m_extent_headers_per_page != per_page)
- break;
-
- osError = 10;
- Uint32 extents = page->m_data_pages / ptr.p->m_extent_size;
- if(page->m_extent_count != extents)
- break;
-
- osError = 11;
- ptr.p->m_file_no = page->m_file_no;
- if(m_page_cache_client.alloc_data_file(ptr.p->m_file_no) == RNIL)
- {
- jam();
- break;
- }
-
- /**
- *
- */
- m_global_page_pool.release(page_ptr);
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = ptr.p->m_create.m_senderData;
- conf->senderRef = reference();
- sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
- return;
- } while(0);
-
- m_global_page_pool.release(page_ptr);
- create_file_ref(signal, lg_ptr, ptr, err, fsError, osError);
-}
-
-void
-Tsman::execFSREADREF(Signal* signal)
-{
- jamEntry();
- Ptr<Datafile> ptr;
- Ptr<Tablespace> lg_ptr;
- FsRef* ref = (FsRef*)signal->getDataPtr();
-
- m_file_pool.getPtr(ptr, ref->userPointer);
- m_tablespace_hash.find(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- m_global_page_pool.release(ptr.p->m_create.m_page_ptr_i);
- create_file_ref(signal, lg_ptr, ptr, CreateFileImplRef::FileReadError,
- ref->errorCode, ref->osErrorCode);
-}
-
-void
-Tsman::load_extent_pages(Signal* signal, Ptr<Datafile> ptr)
-{
- /**
- * Currently all extent header pages needs to be locked in memory
- */
- Page_cache_client::Request preq;
- preq.m_page.m_file_no = ptr.p->m_file_no;
- preq.m_page.m_page_no = ptr.p->m_create.m_loading_extent_page;
-
- preq.m_callback.m_callbackData = ptr.i;
- preq.m_callback.m_callbackFunction =
- safe_cast(&Tsman::load_extent_page_callback);
-
- int page_id;
- int flags = Page_cache_client::LOCK_PAGE;
- if((page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- load_extent_page_callback(signal, ptr.i, (Uint32)page_id);
- }
-
- if(page_id < 0)
- {
- ndbrequire(false);
- }
-}
-
-void
-Tsman::load_extent_page_callback(Signal* signal,
- Uint32 callback,
- Uint32 real_page_ptr_i)
-{
- jamEntry();
- Ptr<Datafile> ptr;
- m_file_pool.getPtr(ptr, callback);
-
- if(++ptr.p->m_create.m_loading_extent_page <= ptr.p->m_create.m_extent_pages)
- {
- signal->theData[0] = TsmanContinueB::LOAD_EXTENT_PAGES;
- signal->theData[1] = ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- return;
- }
-
- Uint32 senderRef = ptr.p->m_create.m_senderRef;
- Uint32 senderData = ptr.p->m_create.m_senderData;
- Uint32 extent_pages = ptr.p->m_create.m_extent_pages;
- Uint32 requestInfo = ptr.p->m_create.m_requestInfo;
- Uint32 data_pages = ptr.p->m_create.m_data_pages;
- ndbassert(requestInfo == CreateFileImplReq::Commit);
-
- Uint32 eh= File_formats::Datafile::extent_header_words(ptr.p->m_extent_size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh;
-
- ptr.p->m_state = Datafile::FS_ONLINE;
- ptr.p->m_online.m_offset_data_pages = 1 + extent_pages;
- ptr.p->m_online.m_first_free_extent = per_page;
- ptr.p->m_online.m_lcp_free_extent_head = RNIL;
- ptr.p->m_online.m_lcp_free_extent_tail = RNIL;
- ptr.p->m_online.m_data_pages = data_pages;
- ptr.p->m_online.m_used_extent_cnt = 0;
- ptr.p->m_online.m_extent_headers_per_extent_page = per_page;
-
- Ptr<Tablespace> ts_ptr;
- m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i);
- if (getNodeState().startLevel >= NodeState::SL_STARTED ||
- (getNodeState().getNodeRestartInProgress() &&
- getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
- {
- Local_datafile_list free(m_file_pool, ts_ptr.p->m_free_files);
- Local_datafile_list meta(m_file_pool, ts_ptr.p->m_meta_files);
- meta.remove(ptr);
- free.add(ptr);
- }
- m_file_hash.add(ptr);
-
- CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
- conf->senderData = senderData;
- conf->senderRef = reference();
- sendSignal(senderRef, GSN_CREATE_FILE_CONF, signal,
- CreateFileImplConf::SignalLength, JBB);
-}
-
-void
-Tsman::execSTART_RECREQ(Signal* signal)
-{
- Ptr<Tablespace> lg_ptr;
- m_tablespace_list.first(lg_ptr);
-
- signal->theData[0] = TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS;
- signal->theData[1] = lg_ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
-}
-
-void
-Tsman::scan_tablespace(Signal* signal, Uint32 ptrI)
-{
- Ptr<Tablespace> lg_ptr;
- if(ptrI == RNIL)
- {
- signal->theData[0] = reference();
- sendSignal(DBLQH_REF, GSN_START_RECCONF, signal, 1, JBB);
- return;
- }
-
- m_tablespace_pool.getPtr(lg_ptr, ptrI);
-
- Ptr<Datafile> file_ptr;
- {
- Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- meta.first(file_ptr);
- }
-
- scan_datafile(signal, lg_ptr.i, file_ptr.i);
-}
-
-void
-Tsman::scan_datafile(Signal* signal, Uint32 ptrI, Uint32 filePtrI)
-{
- Ptr<Datafile> file_ptr;
- Ptr<Tablespace> lg_ptr;
- m_tablespace_pool.getPtr(lg_ptr, ptrI);
- if(filePtrI == RNIL)
- {
- m_tablespace_list.next(lg_ptr);
- signal->theData[0] = TsmanContinueB::SCAN_TABLESPACE_EXTENT_HEADERS;
- signal->theData[1] = lg_ptr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
- }
- else
- {
- m_file_pool.getPtr(file_ptr, filePtrI);
- scan_extent_headers(signal, file_ptr);
- }
-}
-
-void
-Tsman::scan_extent_headers(Signal* signal, Ptr<Datafile> ptr)
-{
- Ptr<Tablespace> lg_ptr;
- m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
-
- Uint32 firstFree= RNIL;
- Uint32 size = ptr.p->m_extent_size;
- Uint32 per_page = ptr.p->m_online.m_extent_headers_per_extent_page;
- Uint32 pages= ptr.p->m_online.m_offset_data_pages - 1;
- Uint32 datapages= ptr.p->m_online.m_data_pages;
- Dbtup* tup= (Dbtup*)globalData.getBlock(DBTUP);
- ndbrequire(tup != 0);
- for(Uint32 i = 0; i < pages; i++)
- {
- Uint32 page_no = pages - i;
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
- preq.m_page.m_file_no = ptr.p->m_file_no;
-
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id = m_page_cache_client.get_page(signal, preq, flags);
- ndbrequire(real_page_id > 0);
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)m_page_cache_client.m_ptr.p;
-
- Uint32 extents= per_page;
- if(page_no == pages)
- {
- /**
- * Last extent header page...
- * set correct no of extent headers
- */
- extents= (datapages / size) % per_page;
- }
- for(Uint32 j = 0; j<extents; j++)
- {
- Uint32 extent_no = extents - j - 1;
- File_formats::Datafile::Extent_header* header=
- page->get_header(extent_no, size);
- if (header->m_table == RNIL)
- {
- header->m_next_free_extent = firstFree;
- firstFree = page_no * per_page + extent_no;
- }
- else
- {
- Uint32 tableId= header->m_table;
- Uint32 fragmentId= header->m_fragment_id;
- Local_key key;
- key.m_file_no = ptr.p->m_file_no;
- key.m_page_no =
- pages + 1 + size * (page_no * per_page + extent_no - per_page);
- key.m_page_idx = page_no * per_page + extent_no;
- if(!tup->disk_restart_alloc_extent(tableId, fragmentId, &key, size))
- {
- ptr.p->m_online.m_used_extent_cnt++;
- for(Uint32 i = 0; i<size; i++, key.m_page_no++)
- {
- Uint32 bits= header->get_free_bits(i) & COMMITTED_MASK;
- header->update_free_bits(i, bits | (bits << UNCOMMITTED_SHIFT));
- tup->disk_restart_page_bits(tableId, fragmentId, &key, bits);
- }
- }
- else
- {
- header->m_table = RNIL;
- header->m_next_free_extent = firstFree;
- firstFree = page_no * per_page + extent_no;
- }
- }
- }
- }
- ptr.p->m_online.m_first_free_extent= firstFree;
-
- Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
- Ptr<Datafile> next = ptr;
- meta.next(next);
- if(firstFree != RNIL)
- {
- Local_datafile_list free(m_file_pool, lg_ptr.p->m_free_files);
- meta.remove(ptr);
- free.add(ptr);
- }
- else
- {
- Local_datafile_list full(m_file_pool, lg_ptr.p->m_full_files);
- meta.remove(ptr);
- full.add(ptr);
- }
-
- signal->theData[0] = TsmanContinueB::SCAN_DATAFILE_EXTENT_HEADERS;
- signal->theData[1] = lg_ptr.i;
- signal->theData[2] = next.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
-}
-
-void
-Tsman::execDROP_FILE_REQ(Signal* signal)
-{
- jamEntry();
- DropFileImplReq req = *(DropFileImplReq*)signal->getDataPtr();
- Ptr<Datafile> file_ptr;
- Ptr<Tablespace> fg_ptr;
-
- Uint32 errorCode = 0;
- do
- {
- if (!m_tablespace_hash.find(fg_ptr, req.filegroup_id))
- {
- errorCode = DropFileImplRef::InvalidFilegroup;
- break;
- }
-
- if (fg_ptr.p->m_version != req.filegroup_version)
- {
- errorCode = DropFileImplRef::InvalidFilegroupVersion;
- break;
- }
-
- switch(req.requestInfo){
- case DropFileImplReq::Prepare:{
- if (find_file_by_id(file_ptr, fg_ptr.p->m_full_files, req.file_id))
- {
- jam();
- Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
- full.remove(file_ptr);
- }
- else if(find_file_by_id(file_ptr, fg_ptr.p->m_free_files, req.file_id))
- {
- jam();
- Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
- free.remove(file_ptr);
- }
- else if(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id))
- {
- jam();
- Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
- meta.remove(file_ptr);
- }
- else
- {
- errorCode = DropFileImplRef::NoSuchFile;
- break;
- }
-
- Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
- meta.add(file_ptr);
-
- if (file_ptr.p->m_online.m_used_extent_cnt ||
- file_ptr.p->m_state != Datafile::FS_ONLINE)
- {
- errorCode = DropFileImplRef::FileInUse;
- break;
- }
-
- file_ptr.p->m_state = Datafile::FS_DROPPING;
- break;
- }
- case DropFileImplReq::Commit:
- ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
- file_ptr.p->m_create.m_extent_pages =
- file_ptr.p->m_online.m_offset_data_pages - 1;
- file_ptr.p->m_create.m_senderRef = req.senderRef;
- file_ptr.p->m_create.m_senderData = req.senderData;
- release_extent_pages(signal, file_ptr);
- return;
- case DropFileImplReq::Abort:{
- ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
- file_ptr.p->m_state = Datafile::FS_ONLINE;
- Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
- meta.remove(file_ptr);
- if (file_ptr.p->m_online.m_first_free_extent != RNIL)
- {
- Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
- free.add(file_ptr);
- }
- else
- {
- Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
- full.add(file_ptr);
- }
- break;
- }
- }
- } while(0);
-
- if (errorCode)
- {
- DropFileImplRef* ref = (DropFileImplRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = req.senderData;
- ref->errorCode = errorCode;
- sendSignal(req.senderRef, GSN_DROP_FILE_REF, signal,
- DropFileImplRef::SignalLength, JBB);
- }
- else
- {
- DropFileImplConf* conf = (DropFileImplConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = req.senderData;
- sendSignal(req.senderRef, GSN_DROP_FILE_CONF, signal,
- DropFileImplConf::SignalLength, JBB);
- }
-}
-
-Tsman::Tablespace::Tablespace(Tsman* ts, Lgman* lg,
- const CreateFilegroupImplReq* req)
- : m_logfile_client(ts, lg, req->tablespace.logfile_group_id)
-{
- m_tablespace_id = req->filegroup_id;
- m_version = req->filegroup_version;
-
- m_extent_size = DIV(req->tablespace.extent_size, File_formats::NDB_PAGE_SIZE);}
-
-Tsman::Datafile::Datafile(const struct CreateFileImplReq* req)
-{
- m_file_id = req->file_id;
-
- m_file_no = RNIL;
- m_fd = RNIL;
- m_online.m_first_free_extent = RNIL;
-
- m_create.m_senderRef = req->senderRef; // During META
- m_create.m_senderData = req->senderData; // During META
- m_create.m_requestInfo = req->requestInfo;
-}
-
-void
-Tsman::execALLOC_EXTENT_REQ(Signal* signal)
-{
- jamEntry();
- Ptr<Tablespace> ts_ptr;
- Ptr<Datafile> file_ptr;
- AllocExtentReq req = *(AllocExtentReq*)signal->getDataPtr();
- AllocExtentReq::ErrorCode err;
-
- ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
- Local_datafile_list tmp(m_file_pool, ts_ptr.p->m_free_files);
-
- if (tmp.first(file_ptr))
- {
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 extent = file_ptr.p->m_online.m_first_free_extent;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
- preq.m_page.m_file_no = file_ptr.p->m_file_no;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
-
- ndbrequire(header->m_table == RNIL);
- Uint32 next_free = header->m_next_free_extent;
-
- /**
- * Init header
- */
- bzero(header, 4*eh_words);
- header->m_table = req.request.table_id;
- header->m_fragment_id = req.request.fragment_id;
-
- /**
- * Check if file is full
- */
- file_ptr.p->m_online.m_used_extent_cnt++;
- file_ptr.p->m_online.m_first_free_extent = next_free;
- if (next_free == RNIL)
- {
- jam();
- Local_datafile_list full(m_file_pool, ts_ptr.p->m_full_files);
- tmp.remove(file_ptr);
- full.add(file_ptr);
- }
-
- /**
- * Pack return values
- */
- ndbassert(extent >= per_page);
- preq.m_page.m_page_no = data_off + size * (extent - /* zero */ per_page);
- preq.m_page.m_page_idx = extent; // extent_no
-
- AllocExtentReq* rep = (AllocExtentReq*)signal->getDataPtr();
- rep->reply.errorCode = 0;
- rep->reply.page_id = preq.m_page;
- rep->reply.page_count = size;
- return;
- }
- else
- {
- jam();
- err = AllocExtentReq::UnmappedExtentPageIsNotImplemented;
- }
- }
- else
- {
- jam();
- err = AllocExtentReq::NoExtentAvailable;
- Local_datafile_list full_tmp(m_file_pool, ts_ptr.p->m_full_files);
- if (tmp.isEmpty() && full_tmp.isEmpty())
- {
- jam();
- err = AllocExtentReq::NoDatafile;
- }
- }
-
- /**
- * Pack return values
- */
- AllocExtentReq* rep = (AllocExtentReq*)signal->getDataPtr();
- rep->reply.errorCode = err;
- return;
-}
-
-void
-Tsman::execFREE_EXTENT_REQ(Signal* signal)
-{
- jamEntry();
- Ptr<Datafile> file_ptr;
- FreeExtentReq req = *(FreeExtentReq*)signal->getDataPtr();
- FreeExtentReq::ErrorCode err = (FreeExtentReq::ErrorCode)0;
-
- Datafile file_key;
- file_key.m_file_no = req.request.key.m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(req.request.key.m_page_no, file_ptr.p);
- Uint32 extent =
- (req.request.key.m_page_no - val.m_extent_pages) / val.m_extent_size +
- file_ptr.p->m_online.m_extent_headers_per_extent_page;
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = req.request.key.m_file_no;
-
- ndbout << "Free extent: " << req.request.key << endl;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(val.m_extent_no, val.m_extent_size);
-
- ndbrequire(header->m_table == req.request.table_id);
- header->m_table = RNIL;
-
- file_ptr.p->m_online.m_used_extent_cnt--;
- if (m_lcp_ongoing)
- {
- jam();
- header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head;
- if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL)
- file_ptr.p->m_online.m_lcp_free_extent_tail= extent;
- file_ptr.p->m_online.m_lcp_free_extent_head= extent;
- }
- else
- {
- jam();
- header->m_next_free_extent = file_ptr.p->m_online.m_first_free_extent;
- if (file_ptr.p->m_online.m_first_free_extent == RNIL)
- {
- /**
- * Move from full to free
- */
- Ptr<Tablespace> ptr;
- m_tablespace_pool.getPtr(ptr, file_ptr.p->m_tablespace_ptr_i);
- Local_datafile_list free(m_file_pool, ptr.p->m_free_files);
- Local_datafile_list full(m_file_pool, ptr.p->m_full_files);
- full.remove(file_ptr);
- free.add(file_ptr);
- }
- file_ptr.p->m_online.m_first_free_extent = extent;
- }
- }
- else
- {
- jam();
- err = FreeExtentReq::UnmappedExtentPageIsNotImplemented;
- }
-
- /**
- * Pack return values
- */
- FreeExtentReq* rep = (FreeExtentReq*)signal->getDataPtr();
- rep->reply.errorCode = err;
- return;
-}
-
-int
-Tsman::update_page_free_bits(Signal* signal,
- Local_key *key,
- unsigned committed_bits)
-{
- jamEntry();
-
- /**
- * 1) Compute which extent_no key belongs to
- * 2) Find out which page extent_no belongs to
- * 3) Undo log m_page_bitmask
- * 4) Update m_page_bitmask
- */
- Ptr<Datafile> file_ptr;
- Datafile file_key;
- file_key.m_file_no = key->m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(key->m_page_no, file_ptr.p);
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = key->m_file_no;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = Page_cache_client::COMMIT_REQ;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(val.m_extent_no, val.m_extent_size);
-
- if (header->m_table == RNIL)
- {
- ndbout << "update page free bits page: " << *key
- << " " << *header << endl;
- }
-
- if (0)
- {
- ndbout << "update page free bits page(" << committed_bits << ") "
- << *key << " " << *header << endl;
- }
-
- ndbrequire(header->m_table != RNIL);
-
- Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
-
- /**
- * Toggle word
- */
- ndbassert((committed_bits & ~(COMMITTED_MASK)) == 0);
- Uint32 src = header->get_free_bits(page_no_in_extent) & UNCOMMITTED_MASK;
- header->update_free_bits(page_no_in_extent, src | committed_bits);
-
- m_page_cache_client.update_lsn(preq.m_page, 0);
-
- return 0;
- }
-
- return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
-}
-
-int
-Tsman::get_page_free_bits(Signal* signal, Local_key *key,
- unsigned* uncommitted,
- unsigned* committed)
-{
- jamEntry();
-
- Ptr<Datafile> file_ptr;
- Datafile file_key;
- file_key.m_file_no = key->m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(key->m_page_no, file_ptr.p);
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = key->m_file_no;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = 0;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(val.m_extent_no, val.m_extent_size);
-
- ndbrequire(header->m_table != RNIL);
-
- Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
- Uint32 bits = header->get_free_bits(page_no_in_extent);
- *uncommitted = (bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
- *committed = (bits & COMMITTED_MASK);
- return 0;
- }
-
- return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
-}
-
-int
-Tsman::unmap_page(Signal* signal, Local_key *key, Uint32 uncommitted_bits)
-{
- jamEntry();
-
- /**
- * 1) Compute which extent_no key belongs to
- * 2) Find out which page extent_no belongs to
- * 3) Undo log m_page_bitmask
- * 4) Update m_page_bitmask
- */
- Ptr<Datafile> file_ptr;
- Datafile file_key;
- file_key.m_file_no = key->m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(key->m_page_no, file_ptr.p);
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = key->m_file_no;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = 0;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(val.m_extent_no, val.m_extent_size);
-
- if (header->m_table == RNIL)
- {
- ndbout << "trying to unmap page: " << *key
- << " " << *header << endl;
- }
- ndbrequire(header->m_table != RNIL);
-
- Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
-
- /**
- * Toggle word
- */
- ndbassert(((uncommitted_bits << UNCOMMITTED_SHIFT) & ~UNCOMMITTED_MASK) == 0);
- Uint32 src = header->get_free_bits(page_no_in_extent) & COMMITTED_MASK;
- header->update_free_bits(page_no_in_extent,
- src | (uncommitted_bits << UNCOMMITTED_SHIFT));
- }
-
- return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
-}
-
-int
-Tsman::restart_undo_page_free_bits(Signal* signal,
- Uint32 tableId,
- Uint32 fragId,
- Local_key *key,
- unsigned bits)
-{
- jamEntry();
-
- /**
- * 1) Compute which extent_no key belongs to
- * 2) Find out which page extent_no belongs to
- * 3) Undo log m_page_bitmask
- * 4) Update m_page_bitmask
- */
- Ptr<Datafile> file_ptr;
- Datafile file_key;
- file_key.m_file_no = key->m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(key->m_page_no, file_ptr.p);
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = key->m_file_no;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(val.m_extent_no, val.m_extent_size);
-
- if (header->m_table == RNIL)
- {
- if (DBG_UNDO)
- ndbout_c("tsman: apply undo - skip table == RNIL");
- return 0;
- }
-
- Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
- Uint32 src = header->get_free_bits(page_no_in_extent);
-
- ndbrequire(header->m_table == tableId);
- ndbrequire(header->m_fragment_id == fragId);
-
- /**
- * Toggle word
- */
- if (DBG_UNDO)
- {
- ndbout << "tsman: apply "
- << *key << " " << (src & COMMITTED_MASK)
- << " -> " << bits << endl;
- }
-
- ndbassert((bits & ~(COMMITTED_MASK)) == 0);
- header->update_free_bits(page_no_in_extent,
- bits | (bits << UNCOMMITTED_SHIFT));
-
- return 0;
- }
-
- return AllocExtentReq::UnmappedExtentPageIsNotImplemented;
-}
-
-void
-Tsman::execALLOC_PAGE_REQ(Signal* signal)
-{
- jamEntry();
-
- AllocPageReq *rep= (AllocPageReq*)signal->getDataPtr();
- AllocPageReq req = *rep;
- AllocPageReq::ErrorCode
- err= AllocPageReq::UnmappedExtentPageIsNotImplemented;
-
- /**
- * 1) Compute which extent_no key belongs to
- * 2) Find out which page extent_no belongs to
- * 3) Undo log m_page_bitmask
- * 4) Update m_page_bitmask
- */
- Ptr<Datafile> file_ptr;
- Datafile file_key;
- file_key.m_file_no = req.key.m_file_no;
- ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- struct req val = lookup_extent(req.key.m_page_no, file_ptr.p);
- Uint32 page_no_in_extent = calc_page_no_in_extent(req.key.m_page_no, &val);
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = val.m_extent_page_no;
- preq.m_page.m_file_no = req.key.m_file_no;
-
- Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
-
- /**
- * Handling of unmapped extent header pages is not implemented
- */
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id;
- Uint32 page_no;
- Uint32 src_bits;
- File_formats::Datafile::Extent_header* header;
- if ((real_page_id = m_page_cache_client.get_page(signal, preq, flags)) > 0)
- {
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- header= page->get_header(val.m_extent_no, val.m_extent_size);
-
- ndbrequire(header->m_table == req.request.table_id);
-
- Uint32 word = header->get_free_word_offset(page_no_in_extent);
- Uint32 shift = SZ * (page_no_in_extent & 7);
-
- /**
- * 0 = 00 - free - 100% free
- * 1 = 01 - atleast 70% free, 70= pct_free + 2 * (100 - pct_free) / 3
- * 2 = 10 - atleast 40% free, 40= pct_free + (100 - pct_free) / 3
- * 3 = 11 - full - less than pct_free% free, pct_free=10%
- */
-
- Uint32 reqbits = req.bits << UNCOMMITTED_SHIFT;
-
- /**
- * Search
- */
- Uint32 *src= header->m_page_bitmask + word;
- for(page_no= page_no_in_extent; page_no<val.m_extent_size; page_no++)
- {
- src_bits= (* src >> shift) & ((1 << SZ) - 1);
- if((src_bits & UNCOMMITTED_MASK) <= reqbits)
- {
- goto found;
- }
- shift += SZ;
- src = src + (shift >> 5);
- shift &= 31;
- }
-
- shift= 0;
- src= header->m_page_bitmask;
- for(page_no= 0; page_no<page_no_in_extent; page_no++)
- {
- src_bits= (* src >> shift) & ((1 << SZ) - 1);
- if((src_bits & UNCOMMITTED_MASK) <= reqbits)
- {
- goto found;
- }
- shift += SZ;
- src = src + (shift >> 5);
- shift &= 31;
- }
-
-#if 0
- printf("req.bits: %d bits: ", req.bits);
- for(Uint32 i = 0; i<size; i++)
- {
- printf("%x", header->get_free_bits(i));
- }
- ndbout_c("");
-#endif
- err= AllocPageReq::NoPageFree;
- }
-
- rep->reply.errorCode = err;
- return;
-
-found:
- header->update_free_bits(page_no, src_bits | UNCOMMITTED_MASK);
- rep->bits= (src_bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
- rep->key.m_page_no = req.key.m_page_no + page_no - page_no_in_extent;
- rep->reply.errorCode= 0;
- return;
-}
-
-void
-Tsman::execLCP_FRAG_ORD(Signal* signal)
-{
- jamEntry();
- ndbrequire(!m_lcp_ongoing);
- m_lcp_ongoing = true;
-}
-
-void
-Tsman::execEND_LCP_REQ(Signal* signal)
-{
- jamEntry();
- ndbrequire(m_lcp_ongoing);
- m_lcp_ongoing = false;
-
- /**
- * Move extents from "lcp" free list to real free list
- */
- Ptr<Tablespace> ptr;
- if(m_tablespace_list.first(ptr))
- {
- signal->theData[0] = TsmanContinueB::END_LCP;
- signal->theData[1] = ptr.i;
- signal->theData[2] = 0; // free
- signal->theData[3] = RNIL; // first
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- }
-}
-
-void
-Tsman::end_lcp(Signal* signal, Uint32 ptrI, Uint32 list, Uint32 filePtrI)
-{
- Ptr<Tablespace> ptr;
- m_tablespace_list.getPtr(ptr, ptrI);
-
- Ptr<Datafile> file;
- file.i = filePtrI;
- Uint32 nextFile = RNIL;
-
- switch(list){
- case 0:
- {
- Local_datafile_list tmp(m_file_pool, ptr.p->m_free_files);
- if(file.i == RNIL)
- {
- if(!tmp.first(file))
- {
- list= 1;
- goto next;
- }
- }
- else
- {
- tmp.getPtr(file);
- }
- break;
- }
- case 1:
- {
- Local_datafile_list tmp(m_file_pool, ptr.p->m_full_files);
- if(file.i == RNIL)
- {
- if(!tmp.first(file))
- {
- list= 0;
- if(m_tablespace_list.next(ptr))
- goto next;
- return;
- }
- }
- else
- {
- tmp.getPtr(file);
- }
- break;
- }
- default:
- ndbrequire(false);
- }
-
- nextFile = file.p->nextList;
-
- /**
- * Move extents...
- */
- if(file.p->m_online.m_lcp_free_extent_head != RNIL)
- {
- ndbout_c("moving extents (%d %d) to real free list %d",
- file.p->m_online.m_lcp_free_extent_head,
- file.p->m_online.m_lcp_free_extent_tail,
- file.p->m_online.m_first_free_extent);
-
- if(file.p->m_online.m_first_free_extent == RNIL)
- {
- ndbrequire(list == 1);
- file.p->m_online.m_first_free_extent =
- file.p->m_online.m_lcp_free_extent_head;
- file.p->m_online.m_lcp_free_extent_head = RNIL;
- file.p->m_online.m_lcp_free_extent_tail = RNIL;
-
- Local_datafile_list free(m_file_pool, ptr.p->m_free_files);
- Local_datafile_list full(m_file_pool, ptr.p->m_full_files);
- full.remove(file);
- free.add(file);
- }
- else
- {
- Uint32 extent = file.p->m_online.m_lcp_free_extent_tail;
- Uint32 size = ptr.p->m_extent_size;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
-
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
-
- Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
- preq.m_page.m_file_no = file.p->m_file_no;
-
- int flags = Page_cache_client::DIRTY_REQ;
- int real_page_id;
- ndbrequire((real_page_id = m_page_cache_client.get_page(signal, preq,
- flags)) > 0);
-
- GlobalPage* ptr_p = m_page_cache_client.m_ptr.p;
-
- File_formats::Datafile::Extent_page* page =
- (File_formats::Datafile::Extent_page*)ptr_p;
- File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
-
- header->m_next_free_extent = file.p->m_online.m_first_free_extent;
- file.p->m_online.m_first_free_extent =
- file.p->m_online.m_lcp_free_extent_head;
-
- file.p->m_online.m_lcp_free_extent_head = RNIL;
- file.p->m_online.m_lcp_free_extent_tail = RNIL;
- }
- }
-
-
- /**
- * next file
- */
- file.i = nextFile;
- if(file.i == RNIL)
- {
- if(list == 0)
- list = 1;
- else
- {
- list = 0;
- m_tablespace_list.next(ptr);
- }
- }
-
-next:
- if(ptr.i != RNIL)
- {
- signal->theData[0] = TsmanContinueB::END_LCP;
- signal->theData[1] = ptr.i;
- signal->theData[2] = list;
- signal->theData[3] = file.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
- }
-}
-
-int
-Tablespace_client::get_tablespace_info(CreateFilegroupImplReq* rep)
-{
- Ptr<Tsman::Tablespace> ts_ptr;
- if(m_tsman->m_tablespace_hash.find(ts_ptr, m_tablespace_id));
- {
- rep->tablespace.extent_size = ts_ptr.p->m_extent_size;
- rep->tablespace.logfile_group_id =
- ts_ptr.p->m_logfile_client.m_logfile_group_id;
- return 0;
- }
- return -1;
-}
-
-void Tsman::execGET_TABINFOREQ(Signal* signal)
-{
- jamEntry();
-
- if(!assembleFragments(signal))
- {
- return;
- }
-
- GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
-
- Uint32 tableId= req->tableId;
- const Uint32 reqType = req->requestType & (~GetTabInfoReq::LongSignalConf);
- BlockReference retRef= req->senderRef;
- Uint32 senderData= req->senderData;
-
- if(reqType == GetTabInfoReq::RequestByName){
- jam();
- releaseSections(signal);
-
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::NoFetchByName);
- return;
- }
-
- Datafile_hash::Iterator iter;
- ndbrequire(m_file_hash.first(iter));
-
- while(iter.curr.p->m_file_id != tableId && m_file_hash.next(iter))
- ;
-
- if(iter.curr.p->m_file_id != tableId)
- {
- sendGET_TABINFOREF(signal, req, GetTabInfoRef::InvalidTableId);
- return;
- }
-
- const Ptr<Datafile> &file_ptr= iter.curr;
-
- jam();
-
- Uint32 total_free_extents = file_ptr.p->m_online.m_data_pages;
- total_free_extents /= file_ptr.p->m_extent_size;
- total_free_extents -= file_ptr.p->m_online.m_used_extent_cnt;
-
- GetTabInfoConf *conf = (GetTabInfoConf *)&signal->theData[0];
-
- conf->senderData= senderData;
- conf->tableId= tableId;
- conf->freeExtents= total_free_extents;
- conf->tableType= DictTabInfo::Datafile;
- conf->senderRef= reference();
- sendSignal(retRef, GSN_GET_TABINFO_CONF, signal,
- GetTabInfoConf::SignalLength, JBB);
-}
-
-void Tsman::sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq * req,
- GetTabInfoRef::ErrorCode errorCode)
-{
- jamEntry();
- GetTabInfoRef * const ref = (GetTabInfoRef *)&signal->theData[0];
- /**
- * The format of GetTabInfo Req/Ref is the same
- */
- BlockReference retRef = req->senderRef;
- ref->errorCode = errorCode;
-
- sendSignal(retRef, GSN_GET_TABINFOREF, signal, signal->length(), JBB);
-}
diff --git a/storage/ndb/src/kernel/blocks/tsman.hpp b/storage/ndb/src/kernel/blocks/tsman.hpp
deleted file mode 100644
index 6f005c1bfad..00000000000
--- a/storage/ndb/src/kernel/blocks/tsman.hpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TSMAN_H
-#define TSMAN_H
-
-#include <SimulatedBlock.hpp>
-
-#include <SLList.hpp>
-#include <DLList.hpp>
-#include <NodeBitmask.hpp>
-#include <signaldata/GetTabInfo.hpp>
-
-#include "lgman.hpp"
-#include "pgman.hpp"
-
-class Tsman : public SimulatedBlock
-{
-public:
- Tsman(Block_context&, Pgman*, Lgman*);
- virtual ~Tsman();
- BLOCK_DEFINES(Tsman);
-
-protected:
-
- void execSTTOR(Signal* signal);
- void sendSTTORRY(Signal*);
- void execREAD_CONFIG_REQ(Signal* signal);
- void execDUMP_STATE_ORD(Signal* signal);
- void execCONTINUEB(Signal* signal);
-
- void execCREATE_FILE_REQ(Signal* signal);
- void execCREATE_FILEGROUP_REQ(Signal* signal);
- void execDROP_FILE_REQ(Signal* signal);
- void execDROP_FILEGROUP_REQ(Signal* signal);
-
- void execSTART_RECREQ(Signal*);
-
- void execFSWRITEREQ(Signal*);
- void execFSOPENREF(Signal*);
- void execFSOPENCONF(Signal*);
- void execFSREADREF(Signal*);
- void execFSREADCONF(Signal*);
-
- void execFSCLOSEREF(Signal*);
- void execFSCLOSECONF(Signal*);
-
- void execALLOC_EXTENT_REQ(Signal*);
- void execFREE_EXTENT_REQ(Signal*);
-
- void execALLOC_PAGE_REQ(Signal* signal);
-
- void execLCP_FRAG_ORD(Signal*);
- void execEND_LCP_REQ(Signal*);
- void end_lcp(Signal*, Uint32 tablespace, Uint32 list, Uint32 file);
-
- void execGET_TABINFOREQ(Signal*);
-
- void sendGET_TABINFOREF(Signal* signal,
- GetTabInfoReq * req,
- GetTabInfoRef::ErrorCode errorCode);
-
-public:
- struct Datafile
- {
- Datafile(){}
- Datafile(const struct CreateFileImplReq*);
-
- /**
- * m_file_no
- * - Unique among datafiles on this node
- * - Part of local key
- * - Set by pgman
- */
- Uint32 m_magic;
- Uint32 m_file_no;
- Uint32 m_file_id; // Used when talking to DICT
- Uint32 m_fd; // NDBFS
-
- Uint32 m_tablespace_ptr_i;
- Uint32 m_extent_size;
- Uint32 m_state;
-
- enum FileState
- {
- FS_CREATING = 0x1,
- FS_ONLINE = 0x2,
- FS_DROPPING = 0x4
- };
-
- union {
- struct {
- Uint32 m_first_free_extent;
- Uint32 m_lcp_free_extent_head; // extents freed but not LCP
- Uint32 m_lcp_free_extent_tail;
- Uint32 m_offset_data_pages; // 1(zero) + extent header pages
- Uint32 m_data_pages;
- Uint32 m_used_extent_cnt;
- Uint32 m_extent_headers_per_extent_page;
- } m_online;
- struct {
- Uint32 m_senderData;
- Uint32 m_senderRef;
- Uint32 m_data_pages;
- Uint32 m_extent_pages;
- Uint32 m_requestInfo;
- union {
- Uint32 m_page_ptr_i;
- Uint32 m_loading_extent_page;
- };
- } m_create;
- };
-
- Uint32 nextHash;
- Uint32 prevHash;
- Uint32 nextList;
- union {
- Uint32 prevList;
- Uint32 nextPool;
- };
-
- Uint32 hashValue() const {
- return m_file_no;
- }
- bool equal(const Datafile& rec) const {
- return m_file_no == rec.m_file_no;
- }
- };
-
- typedef RecordPool<Datafile, RWPool> Datafile_pool;
- typedef DLListImpl<Datafile_pool, Datafile> Datafile_list;
- typedef LocalDLListImpl<Datafile_pool, Datafile> Local_datafile_list;
- typedef DLHashTableImpl<Datafile_pool, Datafile> Datafile_hash;
-
- struct Tablespace
- {
- Tablespace(){}
- Tablespace(Tsman*, Lgman*, const struct CreateFilegroupImplReq*);
-
- Uint32 m_magic;
- union {
- Uint32 key;
- Uint32 m_tablespace_id;
- };
- Uint32 m_version;
- Uint32 m_state;
-
- enum TablespaceState
- {
- TS_CREATING = 0x1,
- TS_ONLINE = 0x2,
- TS_DROPPING = 0x4
- };
-
- Uint32 m_extent_size; // In pages
- Datafile_list::Head m_free_files; // Files w/ free space
- Logfile_client m_logfile_client;
-
- Datafile_list::Head m_full_files; // Files wo/ free space
- Datafile_list::Head m_meta_files; // Files being created/dropped
-
- Uint32 nextHash;
- Uint32 prevHash;
- Uint32 nextList;
- union {
- Uint32 prevList;
- Uint32 nextPool;
- };
-
- Uint32 hashValue() const {
- return key;
- }
- bool equal(const Tablespace& rec) const {
- return key == rec.key;
- }
- };
-
- typedef RecordPool<Tablespace, RWPool> Tablespace_pool;
- typedef DLListImpl<Tablespace_pool, Tablespace> Tablespace_list;
- typedef LocalDLListImpl<Tablespace_pool, Tablespace> Local_tablespace_list;
- typedef KeyTableImpl<Tablespace_pool, Tablespace> Tablespace_hash;
-
-private:
- friend class Tablespace_client;
- Datafile_pool m_file_pool;
- Tablespace_pool m_tablespace_pool;
-
- bool m_lcp_ongoing;
- Datafile_hash m_file_hash;
- Tablespace_list m_tablespace_list;
- Tablespace_hash m_tablespace_hash;
- Page_cache_client m_page_cache_client;
- Lgman * const m_lgman;
-
- int open_file(Signal*, Ptr<Tablespace>, Ptr<Datafile>, CreateFileImplReq*);
- void load_extent_pages(Signal* signal, Ptr<Datafile> ptr);
- void load_extent_page_callback(Signal*, Uint32, Uint32);
- void create_file_ref(Signal*, Ptr<Tablespace>, Ptr<Datafile>,
- Uint32,Uint32,Uint32);
- int update_page_free_bits(Signal*, Local_key*, unsigned committed_bits);
-
- int get_page_free_bits(Signal*, Local_key*, unsigned*, unsigned*);
- int unmap_page(Signal*, Local_key*, unsigned uncommitted_bits);
- int restart_undo_page_free_bits(Signal*, Uint32, Uint32, Local_key*,
- unsigned committed_bits);
-
- int alloc_extent(Signal* signal, Uint32 tablespace, Local_key* key);
- int alloc_page_from_extent(Signal*, Uint32, Local_key*, Uint32 bits);
-
- void scan_tablespace(Signal*, Uint32 ptrI);
- void scan_datafile(Signal*, Uint32, Uint32);
- void scan_extent_headers(Signal*, Ptr<Datafile>);
-
- bool find_file_by_id(Ptr<Datafile>&, Datafile_list::Head&, Uint32 id);
- void create_file_abort(Signal* signal, Ptr<Datafile>);
-
- void release_extent_pages(Signal* signal, Ptr<Datafile> ptr);
- void release_extent_pages_callback(Signal*, Uint32, Uint32);
-
- struct req
- {
- Uint32 m_extent_pages;
- Uint32 m_extent_size;
- Uint32 m_extent_no; // on extent page
- Uint32 m_extent_page_no;
- };
-
- struct req lookup_extent(Uint32 page_no, const Datafile*) const;
- Uint32 calc_page_no_in_extent(Uint32 page_no, const struct req* val) const;
-};
-
-inline
-Tsman::req
-Tsman::lookup_extent(Uint32 page_no, const Datafile * filePtrP) const
-{
- struct req val;
- val.m_extent_size = filePtrP->m_extent_size;
- val.m_extent_pages = filePtrP->m_online.m_offset_data_pages;
- Uint32 per_page = filePtrP->m_online.m_extent_headers_per_extent_page;
-
- Uint32 extent =
- (page_no - val.m_extent_pages) / val.m_extent_size + per_page;
-
- val.m_extent_page_no = extent / per_page;
- val.m_extent_no = extent % per_page;
- return val;
-}
-
-inline
-Uint32
-Tsman::calc_page_no_in_extent(Uint32 page_no, const Tsman::req* val) const
-{
- return (page_no - val->m_extent_pages) % val->m_extent_size;
-}
-
-class Tablespace_client
-{
-public:
- Tsman * m_tsman;
- Signal* m_signal;
- Uint32 m_table_id;
- Uint32 m_fragment_id;
- Uint32 m_tablespace_id;
-
-public:
- Tablespace_client(Signal* signal, Tsman* tsman,
- Uint32 table, Uint32 fragment, Uint32 tablespaceId) {
- m_tsman= tsman;
- m_signal= signal;
- m_table_id= table;
- m_fragment_id= fragment;
- m_tablespace_id= tablespaceId;
- }
-
- Tablespace_client(Signal* signal, Tsman* tsman, Local_key* key);
-
- /**
- * Return >0 if success, no of pages in extent, sets key
- * <0 if failure, -error code
- */
- int alloc_extent(Local_key* key);
-
- /**
- * Allocated a page from an extent
- * performs linear search in extent free bits until it find
- * page that has atleast <em>bits</em> bits free
- *
- * Start search from key->m_page_no
- * and return found page in key->m_page_no
- * this make sequential calls find sequential pages
- *
- * If page is found, then the _unlogged_ "page allocated bit" is set
- * so that page can't be allocated twice unless freed first
- *
- * Note: user of allocated page should use update_page_free_bits
- * to undo log changes in free space on page
- *
- * Return <0 if none found
- * >=0 if found, then free bits of page found is returned
- */
- int alloc_page_from_extent(Local_key* key, unsigned bits);
-
- /**
- * Free extent
- */
- int free_extent(Local_key* key, Uint64 lsn);
-
- /**
- * Update page free bits
- */
- int update_page_free_bits(Local_key*, unsigned bits);
-
- /**
- * Get page free bits
- */
- int get_page_free_bits(Local_key*,
- unsigned* uncommitted, unsigned* committed);
-
- /**
- * Update unlogged page free bit
- */
- int unmap_page(Local_key*, Uint32 bits);
-
- /**
- * Undo handling of page bits
- */
- int restart_undo_page_free_bits(Local_key*, unsigned bits);
-
- /**
- * Get tablespace info
- *
- * Store result in <em>rep</em>
- *
- * Return 0 - on sucess
- * <0 - on error
- */
- int get_tablespace_info(CreateFilegroupImplReq* rep);
-
- /**
- * Update lsn of page corresponing to key
- */
- int update_lsn(Local_key* key, Uint64 lsn);
-};
-
-#include <signaldata/Extent.hpp>
-
-inline
-int
-Tablespace_client::alloc_extent(Local_key* key)
-{
- AllocExtentReq* req = (AllocExtentReq*)m_signal->theData;
- req->request.table_id = m_table_id;
- req->request.fragment_id = m_fragment_id;
- req->request.tablespace_id = m_tablespace_id;
- m_tsman->execALLOC_EXTENT_REQ(m_signal);
-
- if(req->reply.errorCode == 0){
- * key = req->reply.page_id;
- return req->reply.page_count;
- } else {
- return -req->reply.errorCode;
- }
-}
-
-inline
-int
-Tablespace_client::alloc_page_from_extent(Local_key* key, Uint32 bits)
-{
- AllocPageReq* req = (AllocPageReq*)m_signal->theData;
- req->key= *key;
- req->bits= bits;
- req->request.table_id = m_table_id;
- req->request.fragment_id = m_fragment_id;
- req->request.tablespace_id = m_tablespace_id;
- m_tsman->execALLOC_PAGE_REQ(m_signal);
-
- if(req->reply.errorCode == 0){
- *key = req->key;
- return req->bits;
- } else {
- return -req->reply.errorCode;
- }
-}
-
-inline
-int
-Tablespace_client::free_extent(Local_key* key, Uint64 lsn)
-{
- FreeExtentReq* req = (FreeExtentReq*)m_signal->theData;
- req->request.key = *key;
- req->request.table_id = m_table_id;
- req->request.tablespace_id = m_tablespace_id;
- req->request.lsn_hi = (Uint32)(lsn >> 32);
- req->request.lsn_lo = (Uint32)(lsn & 0xFFFFFFFF);
- m_tsman->execFREE_EXTENT_REQ(m_signal);
-
- if(req->reply.errorCode == 0){
- return 0;
- } else {
- return -req->reply.errorCode;
- }
-}
-
-inline
-int
-Tablespace_client::update_page_free_bits(Local_key *key,
- unsigned committed_bits)
-{
- return m_tsman->update_page_free_bits(m_signal, key, committed_bits);
-}
-
-inline
-int
-Tablespace_client::get_page_free_bits(Local_key *key,
- unsigned* uncommited,
- unsigned* commited)
-{
- return m_tsman->get_page_free_bits(m_signal, key, uncommited, commited);
-}
-
-inline
-int
-Tablespace_client::unmap_page(Local_key *key, unsigned uncommitted_bits)
-{
- return m_tsman->unmap_page(m_signal, key, uncommitted_bits);
-}
-
-inline
-int
-Tablespace_client::restart_undo_page_free_bits(Local_key* key,
- unsigned committed_bits)
-{
- return m_tsman->restart_undo_page_free_bits(m_signal,
- m_table_id,
- m_fragment_id,
- key,
- committed_bits);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp b/storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp
deleted file mode 100644
index aefc1b89f11..00000000000
--- a/storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ERRORHANDLINGMACROS_H
-#define ERRORHANDLINGMACROS_H
-
-#include <ndbd_exit_codes.h>
-#include "ErrorReporter.hpp"
-
-extern const char programName[];
-
-enum NotUsed
-{
- warning,
- ecError,
- fatal,
- assert
-};
-
-#define ERROR_SET_SIGNAL(not_used, messageID, problemData, objectRef) \
- ErrorReporter::handleError(messageID, problemData, objectRef, NST_ErrorHandlerSignal)
-#define ERROR_SET(not_used, messageID, problemData, objectRef) \
- ErrorReporter::handleError(messageID, problemData, objectRef)
- // Description:
- // Call ErrorHandler with the supplied arguments. The
- // ErrorHandler decides how to report the error.
- // Parameters:
- // messageID IN Code identifying the error. If less
- // than 1000 a unix error is assumed. If
- // greater than 1000 the code is treated
- // as the specific problem code.
- // problemData IN A (short) text describing the error.
- // The context information is added to
- // this text.
- // objectRef IN The name of the "victim" of the error.
- // Specify NULL if not applicable.
- // Return value:
- // -
- // Reported errors:
- // -
- // Additional information:
- // -
-
-#endif
diff --git a/storage/ndb/src/kernel/error/ErrorReporter.cpp b/storage/ndb/src/kernel/error/ErrorReporter.cpp
deleted file mode 100644
index 0e3712b739b..00000000000
--- a/storage/ndb/src/kernel/error/ErrorReporter.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <ndbd_exit_codes.h>
-#include "ErrorReporter.hpp"
-
-#include <FastScheduler.hpp>
-#include <DebuggerNames.hpp>
-#include <NdbHost.h>
-#include <NdbConfig.h>
-#include <Configuration.hpp>
-#include "EventLogger.hpp"
-
-#include <NdbAutoPtr.hpp>
-
-#define MESSAGE_LENGTH 500
-
-static int WriteMessage(int thrdMessageID,
- const char* thrdProblemData,
- const char* thrdObjRef,
- Uint32 thrdTheEmulatedJamIndex,
- Uint8 thrdTheEmulatedJam[]);
-
-static void dumpJam(FILE* jamStream,
- Uint32 thrdTheEmulatedJamIndex,
- Uint8 thrdTheEmulatedJam[]);
-
-extern EventLogger g_eventLogger;
-const char*
-ErrorReporter::formatTimeStampString(){
- TimeModule DateTime; /* To create "theDateTimeString" */
-
- static char theDateTimeString[39];
- /* Used to store the generated timestamp */
- /* ex: "Wednesday 18 September 2000 - 18:54:37" */
-
- DateTime.setTimeStamp();
-
- BaseString::snprintf(theDateTimeString, 39, "%s %d %s %d - %s:%s:%s",
- DateTime.getDayName(), DateTime.getDayOfMonth(),
- DateTime.getMonthName(), DateTime.getYear(), DateTime.getHour(),
- DateTime.getMinute(), DateTime.getSecond());
-
- return (const char *)&theDateTimeString;
-}
-
-int
-ErrorReporter::get_trace_no(){
-
- FILE *stream;
- unsigned int traceFileNo;
-
- char *file_name= NdbConfig_NextTraceFileName(globalData.ownId);
- NdbAutoPtr<char> tmp_aptr(file_name);
-
- /*
- * Read last number from tracefile
- */
- stream = fopen(file_name, "r+");
- if (stream == NULL){
- traceFileNo = 1;
- } else {
- char buf[255];
- fgets(buf, 255, stream);
- const int scan = sscanf(buf, "%u", &traceFileNo);
- if(scan != 1){
- traceFileNo = 1;
- }
- fclose(stream);
- traceFileNo++;
- }
-
- /**
- * Wrap tracefile no
- */
- Uint32 tmp = globalEmulatorData.theConfiguration->maxNoOfErrorLogs();
- if (traceFileNo > tmp ) {
- traceFileNo = 1;
- }
-
- /**
- * Save new number to the file
- */
- stream = fopen(file_name, "w");
- if(stream != NULL){
- fprintf(stream, "%u", traceFileNo);
- fclose(stream);
- }
-
- return traceFileNo;
-}
-
-
-void
-ErrorReporter::formatMessage(int faultID,
- const char* problemData,
- const char* objRef,
- const char* theNameOfTheTraceFile,
- char* messptr){
- int processId;
- ndbd_exit_classification cl;
- ndbd_exit_status st;
- const char *exit_msg = ndbd_exit_message(faultID, &cl);
- const char *exit_cl_msg = ndbd_exit_classification_message(cl, &st);
- const char *exit_st_msg = ndbd_exit_status_message(st);
-
- processId = NdbHost_GetProcessId();
-
- BaseString::snprintf(messptr, MESSAGE_LENGTH,
- "Time: %s\n"
- "Status: %s\n"
- "Message: %s (%s)\n"
- "Error: %d\n"
- "Error data: %s\n"
- "Error object: %s\n"
- "Program: %s\n"
- "Pid: %d\n"
- "Trace: %s\n"
- "Version: %s\n"
- "***EOM***\n",
- formatTimeStampString() ,
- exit_st_msg,
- exit_msg, exit_cl_msg,
- faultID,
- (problemData == NULL) ? "" : problemData,
- objRef,
- my_progname,
- processId,
- theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>",
- NDB_VERSION_STRING);
-
- // Add trailing blanks to get a fixed lenght of the message
- while (strlen(messptr) <= MESSAGE_LENGTH-3){
- strcat(messptr, " ");
- }
-
- strcat(messptr, "\n");
-
- return;
-}
-
-NdbShutdownType ErrorReporter::s_errorHandlerShutdownType = NST_ErrorHandler;
-
-void
-ErrorReporter::setErrorHandlerShutdownType(NdbShutdownType nst)
-{
- s_errorHandlerShutdownType = nst;
-}
-
-void childReportError(int error);
-
-void
-ErrorReporter::handleAssert(const char* message, const char* file, int line, int ec)
-{
- char refMessage[100];
-
-#ifdef NO_EMULATED_JAM
- BaseString::snprintf(refMessage, 100, "file: %s lineNo: %d",
- file, line);
-#else
- const Uint32 blockNumber = theEmulatedJamBlockNumber;
- const char *blockName = getBlockName(blockNumber);
-
- BaseString::snprintf(refMessage, 100, "%s line: %d (block: %s)",
- file, line, blockName);
-#endif
- WriteMessage(ec, message, refMessage,
- theEmulatedJamIndex, theEmulatedJam);
-
- childReportError(ec);
-
- NdbShutdown(s_errorHandlerShutdownType);
- exit(1); // Deadcode
-}
-
-void
-ErrorReporter::handleError(int messageID,
- const char* problemData,
- const char* objRef,
- NdbShutdownType nst)
-{
- WriteMessage(messageID, problemData,
- objRef, theEmulatedJamIndex, theEmulatedJam);
-
- g_eventLogger.info(problemData);
- g_eventLogger.info(objRef);
-
- childReportError(messageID);
-
- if(messageID == NDBD_EXIT_ERROR_INSERT){
- NdbShutdown(NST_ErrorInsert);
- } else {
- if (nst == NST_ErrorHandler)
- nst = s_errorHandlerShutdownType;
- NdbShutdown(nst);
- }
-}
-
-int
-WriteMessage(int thrdMessageID,
- const char* thrdProblemData, const char* thrdObjRef,
- Uint32 thrdTheEmulatedJamIndex,
- Uint8 thrdTheEmulatedJam[]){
- FILE *stream;
- unsigned offset;
- unsigned long maxOffset; // Maximum size of file.
- char theMessage[MESSAGE_LENGTH];
-
- /**
- * Format trace file name
- */
- char *theTraceFileName= 0;
- if (globalData.ownId > 0)
- theTraceFileName= NdbConfig_TraceFileName(globalData.ownId,
- ErrorReporter::get_trace_no());
- NdbAutoPtr<char> tmp_aptr1(theTraceFileName);
-
- // The first 69 bytes is info about the current offset
- Uint32 noMsg = globalEmulatorData.theConfiguration->maxNoOfErrorLogs();
-
- maxOffset = (69 + (noMsg * MESSAGE_LENGTH));
-
- char *theErrorFileName= (char *)NdbConfig_ErrorFileName(globalData.ownId);
- NdbAutoPtr<char> tmp_aptr2(theErrorFileName);
-
- stream = fopen(theErrorFileName, "r+");
- if (stream == NULL) { /* If the file could not be opened. */
-
- // Create a new file, and skip the first 69 bytes,
- // which are info about the current offset
- stream = fopen(theErrorFileName, "w");
- if(stream == NULL)
- {
- fprintf(stderr,"Unable to open error log file: %s\n", theErrorFileName);
- return -1;
- }
- fprintf(stream, "%s%u%s", "Current byte-offset of file-pointer is: ", 69,
- " \n\n\n");
-
- // ...and write the error-message...
- ErrorReporter::formatMessage(thrdMessageID,
- thrdProblemData, thrdObjRef,
- theTraceFileName, theMessage);
- fprintf(stream, "%s", theMessage);
- fflush(stream);
-
- /* ...and finally, at the beginning of the file,
- store the position where to
- start writing the next message. */
- offset = ftell(stream);
- // If we have not reached the maximum number of messages...
- if (offset <= (maxOffset - MESSAGE_LENGTH)){
- fseek(stream, 40, SEEK_SET);
- // ...set the current offset...
- fprintf(stream,"%d", offset);
- } else {
- fseek(stream, 40, SEEK_SET);
- // ...otherwise, start over from the beginning.
- fprintf(stream, "%u%s", 69, " ");
- }
- } else {
- // Go to the latest position in the file...
- fseek(stream, 40, SEEK_SET);
- fscanf(stream, "%u", &offset);
- fseek(stream, offset, SEEK_SET);
-
- // ...and write the error-message there...
- ErrorReporter::formatMessage(thrdMessageID,
- thrdProblemData, thrdObjRef,
- theTraceFileName, theMessage);
- fprintf(stream, "%s", theMessage);
- fflush(stream);
-
- /* ...and finally, at the beginning of the file,
- store the position where to
- start writing the next message. */
- offset = ftell(stream);
-
- // If we have not reached the maximum number of messages...
- if (offset <= (maxOffset - MESSAGE_LENGTH)){
- fseek(stream, 40, SEEK_SET);
- // ...set the current offset...
- fprintf(stream,"%d", offset);
- } else {
- fseek(stream, 40, SEEK_SET);
- // ...otherwise, start over from the beginning.
- fprintf(stream, "%u%s", 69, " ");
- }
- }
- fflush(stream);
- fclose(stream);
-
- if (theTraceFileName) {
- // Open the tracefile...
- FILE *jamStream = fopen(theTraceFileName, "w");
-
- // ...and "dump the jam" there.
- // ErrorReporter::dumpJam(jamStream);
- if(thrdTheEmulatedJam != 0){
- dumpJam(jamStream, thrdTheEmulatedJamIndex, thrdTheEmulatedJam);
- }
-
- /* Dont print the jobBuffers until a way to copy them,
- like the other variables,
- is implemented. Otherwise when NDB keeps running,
- with this function running
- in the background, the jobBuffers will change during runtime. And when
- they're printed here, they will not be correct anymore.
- */
- globalScheduler.dumpSignalMemory(jamStream);
-
- fclose(jamStream);
- }
-
- return 0;
-}
-
-void
-dumpJam(FILE *jamStream,
- Uint32 thrdTheEmulatedJamIndex,
- Uint8 thrdTheEmulatedJam[]) {
-#ifndef NO_EMULATED_JAM
- // print header
- const int maxaddr = 8;
- fprintf(jamStream, "JAM CONTENTS up->down left->right ?=not block entry\n");
- fprintf(jamStream, "%-7s ", "BLOCK");
- for (int i = 0; i < maxaddr; i++)
- fprintf(jamStream, "%-6s ", "ADDR");
- fprintf(jamStream, "\n");
-
- // treat as array of Uint32
- const Uint32 *base = (Uint32 *)thrdTheEmulatedJam;
- const int first = thrdTheEmulatedJamIndex / sizeof(Uint32); // oldest
- int cnt, idx;
-
- // look for first block entry
- for (cnt = 0, idx = first; cnt < EMULATED_JAM_SIZE; cnt++, idx++) {
- if (idx >= EMULATED_JAM_SIZE)
- idx = 0;
- const Uint32 aJamEntry = base[idx];
- if (aJamEntry > (1 << 20))
- break;
- }
-
- // 1. if first entry is a block entry, it is printed in the main loop
- // 2. else if any block entry exists, the jam starts in an unknown block
- // 3. else if no block entry exists, the block is theEmulatedJamBlockNumber
- // a "?" indicates first addr is not a block entry
- if (cnt == 0)
- ;
- else if (cnt < EMULATED_JAM_SIZE)
- fprintf(jamStream, "%-7s?", "");
- else {
- const Uint32 aBlockNumber = theEmulatedJamBlockNumber;
- const char *aBlockName = getBlockName(aBlockNumber);
- if (aBlockName != 0)
- fprintf(jamStream, "%-7s?", aBlockName);
- else
- fprintf(jamStream, "0x%-5X?", aBlockNumber);
- }
-
- // loop over all entries
- int cntaddr = 0;
- for (cnt = 0, idx = first; cnt < EMULATED_JAM_SIZE; cnt++, idx++) {
- globalData.incrementWatchDogCounter(4); // watchdog not to kill us ?
- if (idx >= EMULATED_JAM_SIZE)
- idx = 0;
- const Uint32 aJamEntry = base[idx];
- if (aJamEntry > (1 << 20)) {
- const Uint32 aBlockNumber = aJamEntry >> 20;
- const char *aBlockName = getBlockName(aBlockNumber);
- if (cnt > 0)
- fprintf(jamStream, "\n");
- if (aBlockName != 0)
- fprintf(jamStream, "%-7s ", aBlockName);
- else
- fprintf(jamStream, "0x%-5X ", aBlockNumber);
- cntaddr = 0;
- }
- if (cntaddr == maxaddr) {
- fprintf(jamStream, "\n%-7s ", "");
- cntaddr = 0;
- }
- fprintf(jamStream, "%06u ", aJamEntry & 0xFFFFF);
- cntaddr++;
- }
- fprintf(jamStream, "\n");
- fflush(jamStream);
-#endif // ifndef NO_EMULATED_JAM
-}
diff --git a/storage/ndb/src/kernel/error/ErrorReporter.hpp b/storage/ndb/src/kernel/error/ErrorReporter.hpp
deleted file mode 100644
index 8d61948fe49..00000000000
--- a/storage/ndb/src/kernel/error/ErrorReporter.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ERRORREPORTER_H
-#define ERRORREPORTER_H
-
-#include <ndb_global.h>
-#include <ndbd_exit_codes.h>
-
-#include "TimeModule.hpp"
-#include <Emulator.hpp>
-
-class ErrorReporter
-{
-public:
- static void setErrorHandlerShutdownType(NdbShutdownType nst = NST_ErrorHandler);
- static void handleAssert(const char* message,
- const char* file,
- int line, int ec = NDBD_EXIT_PRGERR) __attribute__((__noreturn__));
-
- static void handleError(int faultID,
- const char* problemData,
- const char* objRef,
- enum NdbShutdownType = NST_ErrorHandler);
-
- static void handleWarning(int faultID,
- const char* problemData,
- const char* objRef);
-
- static void formatMessage(int faultID,
- const char* problemData,
- const char* objRef,
- const char* theNameOfTheTraceFile,
- char* messptr);
-
- static int get_trace_no();
-
- static const char* formatTimeStampString();
-
-private:
- static enum NdbShutdownType s_errorHandlerShutdownType;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/error/Makefile.am b/storage/ndb/src/kernel/error/Makefile.am
deleted file mode 100644
index 5f904cdac61..00000000000
--- a/storage/ndb/src/kernel/error/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LIBRARIES = liberror.a
-
-liberror_a_SOURCES = TimeModule.cpp \
- ErrorReporter.cpp \
- ndbd_exit_codes.c
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-windoze-dsp: liberror.dsp
-
-liberror.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(liberror_a_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/kernel/error/TimeModule.cpp b/storage/ndb/src/kernel/error/TimeModule.cpp
deleted file mode 100644
index 2fabae586aa..00000000000
--- a/storage/ndb/src/kernel/error/TimeModule.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <ndb_global.h>
-#include "TimeModule.hpp"
-
-static const char* cMonth[] = { "x", "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"};
-
-static const char* cDay[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
- "Saturday", "Sunday"};
-
-static const char* cHour[] = { "00","01","02","03","04","05","06","07","08","09","10","11","12",
- "13","14","15","16","17","18","19","20","21","22","23"};
-
-static const char* cMinute[] = { "00","01","02","03","04","05","06","07","08","09","10","11","12",
- "13","14","15","16","17","18","19","20","21","22","23","24","25",
- "26","27","28","29","30","31","32","33","34","35","36","37","38",
- "39","40","41","42","43","44","45","46","47","48","49","50","51",
- "52","53","54","55","56","57","58","59"};
-
-static const char* cSecond[] = { "00","01","02","03","04","05","06","07","08","09","10","11","12",
- "13","14","15","16","17","18","19","20","21","22","23","24","25",
- "26","27","28","29","30","31","32","33","34","35","36","37","38",
- "39","40","41","42","43","44","45","46","47","48","49","50","51",
- "52","53","54","55","56","57","58","59"};
-
-
-TimeModule::TimeModule(){
-}
-
-TimeModule::~TimeModule(){
-}
-
-void
-TimeModule::setTimeStamp()
-{
- struct tm* rightnow;
- time_t now;
-
- time(&now);
-
- rightnow = localtime(&now);
-
- iYear = rightnow->tm_year+1900; // localtime returns current year -1900
- iMonth = rightnow->tm_mon+1; // and month 0-11
- iMonthDay = rightnow->tm_mday;
- iWeekDay = rightnow->tm_wday;
- iHour = rightnow->tm_hour;
- iMinute = rightnow->tm_min;
- iSecond = rightnow->tm_sec;
-}
-
-int
-TimeModule::getYear() const
-{
- return iYear;
-}
-
-int
-TimeModule::getMonthNumber() const
-{
- return iMonth;
-}
-
-const char*
-TimeModule::getMonthName() const {
- return cMonth[iMonth];
-}
-
-int
-TimeModule::getDayOfMonth() const {
- return iMonthDay;
-}
-
-const char*
-TimeModule::getDayName() const {
- return cDay[iWeekDay];
-}
-
-const char*
-TimeModule::getHour() const {
- return cHour[iHour];
-}
-
-const char*
-TimeModule::getMinute() const {
- return cMinute[iMinute];
-}
-
-const char*
-TimeModule::getSecond() const {
- return cSecond[iSecond];
-}
diff --git a/storage/ndb/src/kernel/error/TimeModule.hpp b/storage/ndb/src/kernel/error/TimeModule.hpp
deleted file mode 100644
index 8ea21750865..00000000000
--- a/storage/ndb/src/kernel/error/TimeModule.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef _TimeModule_
-#define _TimeModule_
-
-class TimeModule {
-public:
- TimeModule();
- ~TimeModule();
-
- void setTimeStamp();
-
- int getYear() const;
- int getMonthNumber() const;
- int getDayOfMonth() const;
- const char* getMonthName() const;
- const char* getDayName() const;
- const char* getHour() const;
- const char* getMinute() const;
- const char* getSecond() const;
-
-private:
- int iYear;
- int iMonth;
- int iMonthDay;
- int iWeekDay;
- int iHour;
- int iMinute;
- int iSecond;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/error/ndbd_exit_codes.c b/storage/ndb/src/kernel/error/ndbd_exit_codes.c
deleted file mode 100644
index 4224e7191f6..00000000000
--- a/storage/ndb/src/kernel/error/ndbd_exit_codes.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndbd_exit_codes.h>
-
-typedef struct ErrStruct {
- int faultId;
- ndbd_exit_classification classification;
- const char* text;
-} ErrStruct;
-
-/**
- * Shorter names in table below
- */
-
-#define XST_S ndbd_exit_st_success
-#define XST_U ndbd_exit_st_unknown
-#define XST_P ndbd_exit_st_permanent
-#define XST_R ndbd_exit_st_temporary
-#define XST_I ndbd_exit_st_filesystem_error
-
-#define XNE ndbd_exit_cl_none
-#define XUE ndbd_exit_cl_unknown
-#define XIE ndbd_exit_cl_internal_error
-#define XCE ndbd_exit_cl_configuration_error
-#define XAE ndbd_exit_cl_arbitration_error
-#define XRE ndbd_exit_cl_restart_error
-#define XCR ndbd_exit_cl_resource_configuration_error
-#define XFF ndbd_exit_cl_filesystem_full_error
-#define XFI ndbd_exit_cl_filesystem_inconsistency_error
-#define XFL ndbd_exit_cl_filesystem_limit
-
-static const ErrStruct errArray[] =
-{
- {NDBD_EXIT_GENERIC, XRE, "Generic error"},
- {NDBD_EXIT_PRGERR, XIE, "Assertion"},
- {NDBD_EXIT_NODE_NOT_IN_CONFIG, XCE,
- "node id in the configuration has the wrong type, (i.e. not an NDB node)"},
- {NDBD_EXIT_SYSTEM_ERROR, XIE,
- "System error, node killed during node restart by other node"},
- {NDBD_EXIT_INDEX_NOTINRANGE, XIE, "Array index out of range"},
- {NDBD_EXIT_ARBIT_SHUTDOWN, XAE, "Node lost connection to other nodes and "
- "can not form a unpartitioned cluster, please investigate if there are "
- "error(s) on other node(s)"},
- {NDBD_EXIT_PARTITIONED_SHUTDOWN, XAE, "Partitioned cluster detected. "
- "Please check if cluster is already running"},
- {NDBD_EXIT_NODE_DECLARED_DEAD, XAE,
- "Node declared dead. See error log for details"},
- {NDBD_EXIT_POINTER_NOTINRANGE, XIE, "Pointer too large"},
- {NDBD_EXIT_SR_OTHERNODEFAILED, XRE, "Another node failed during system "
- "restart, please investigate error(s) on other node(s)"},
- {NDBD_EXIT_NODE_NOT_DEAD, XRE, "Internal node state conflict, "
- "most probably resolved by restarting node again"},
- {NDBD_EXIT_SR_REDOLOG, XFI, "Error while reading the REDO log"},
- {NDBD_EXIT_SR_SCHEMAFILE, XFI, "Error while reading the schema file"},
- /* Currently unused? */
- {2311, XIE, "Conflict when selecting restart type"},
- {NDBD_EXIT_NO_MORE_UNDOLOG, XCR,
- "No more free UNDO log, increase UndoIndexBuffer"},
- {NDBD_EXIT_SR_UNDOLOG, XFI,
- "Error while reading the datapages and UNDO log"},
- {NDBD_EXIT_SINGLE_USER_MODE, XRE, "Data node is not allowed to get added "
- "to the cluster while it is in single user mode"},
- {NDBD_EXIT_MEMALLOC, XCE, "Memory allocation failure, "
- "please decrease some configuration parameters"},
- {NDBD_EXIT_BLOCK_JBUFCONGESTION, XIE, "Job buffer congestion"},
- {NDBD_EXIT_TIME_QUEUE_SHORT, XIE, "Error in short time queue"},
- {NDBD_EXIT_TIME_QUEUE_LONG, XIE, "Error in long time queue"},
- {NDBD_EXIT_TIME_QUEUE_DELAY, XIE, "Error in time queue, too long delay"},
- {NDBD_EXIT_TIME_QUEUE_INDEX, XIE, "Time queue index out of range"},
- {NDBD_EXIT_BLOCK_BNR_ZERO, XIE, "Send signal error"},
- {NDBD_EXIT_WRONG_PRIO_LEVEL, XIE, "Wrong priority level when sending signal"},
- {NDBD_EXIT_NDBREQUIRE, XIE, "Internal program error (failed ndbrequire)"},
- {NDBD_EXIT_NDBASSERT, XIE, "Internal program error (failed ndbassert)"},
- {NDBD_EXIT_ERROR_INSERT, XNE, "Error insert executed" },
- /* this error message is complemented by additional info when generated */
- {NDBD_EXIT_INVALID_CONFIG, XCE,
- "Invalid configuration received from Management Server"},
-
- {NDBD_EXIT_RESOURCE_ALLOC_ERROR, XCE,
- "Resource allocation error, please review the configuration"},
-
- /* this error message is complemented by additional info when
- generated, such as signal, and text
- */
- {NDBD_EXIT_OS_SIGNAL_RECEIVED, XIE, "Error OS signal received"},
-
- {NDBD_EXIT_SR_RESTARTCONFLICT, XRE,
- "Partial system restart causing conflicting file systems"},
-
- /* VM */
- {NDBD_EXIT_OUT_OF_LONG_SIGNAL_MEMORY, XCR,
- "Signal lost, out of long signal memory, please increase LongMessageBuffer"},
- {NDBD_EXIT_WATCHDOG_TERMINATE, XIE, "WatchDog terminate, internal error "
- "or massive overload on the machine running this node"},
- {NDBD_EXIT_SIGNAL_LOST_SEND_BUFFER_FULL, XCR,
- "Signal lost, out of send buffer memory, please increase SendBufferMemory or lower the load"},
- {NDBD_EXIT_SIGNAL_LOST, XIE, "Signal lost (unknown reason)"},
- {NDBD_EXIT_ILLEGAL_SIGNAL, XIE,
- "Illegal signal (version mismatch a possibility)"},
- {NDBD_EXIT_CONNECTION_SETUP_FAILED, XCE, "Connection setup failed"},
-
- /* Ndbcntr */
- {NDBD_EXIT_RESTART_TIMEOUT, XCE,
- "Total restart time too long, consider increasing StartFailureTimeout "
- "or investigate error(s) on other node(s)"},
- {NDBD_EXIT_RESTART_DURING_SHUTDOWN, XRE,
- "Node started while node shutdown in progress. "
- "Please wait until shutdown complete before starting node"},
-
- /* DIH */
- {NDBD_EXIT_MAX_CRASHED_REPLICAS, XFL,
- "Too many crashed replicas (8 consecutive node restart failures)"},
- {NDBD_EXIT_MASTER_FAILURE_DURING_NR, XRE,
- "Unhandled master failure during node restart"},
- {NDBD_EXIT_LOST_NODE_GROUP, XAE,
- "All nodes in a node group are unavailable"},
- {NDBD_EXIT_NO_RESTORABLE_REPLICA, XFI,
- "Unable to find a restorable replica"},
-
- /* ACC */
- {NDBD_EXIT_SR_OUT_OF_INDEXMEMORY, XCR,
- "Out of index memory during system restart, please increase IndexMemory"},
-
- /* TUP */
- {NDBD_EXIT_SR_OUT_OF_DATAMEMORY, XCR,
- "Out of data memory during system restart, please increase DataMemory"},
-
- /* Ndbfs error messages */
- /* Most codes will have additional info, such as OS error code */
- {NDBD_EXIT_AFS_NOPATH, XIE, "No file system path"},
- {2802, XIE, "Channel is full"},
- {2803, XIE, "No more threads"},
- {NDBD_EXIT_AFS_PARAMETER, XIE, "Bad parameter"},
- {NDBD_EXIT_AFS_INVALIDPATH, XCE, "Illegal file system path"},
- {NDBD_EXIT_AFS_MAXOPEN, XCR,
- "Max number of open files exceeded, please increase MaxNoOfOpenFiles"},
- {NDBD_EXIT_AFS_ALREADY_OPEN, XIE, "File has already been opened"},
-
- {NDBD_EXIT_AFS_ENVIRONMENT , XIE, "Environment error using file"},
- {NDBD_EXIT_AFS_TEMP_NO_ACCESS , XIE, "Temporary on access to file"},
- {NDBD_EXIT_AFS_DISK_FULL , XFF, "The file system is full"},
- {NDBD_EXIT_AFS_PERMISSION_DENIED , XCE, "Received permission denied for file"},
- {NDBD_EXIT_AFS_INVALID_PARAM , XCE, "Invalid parameter for file"},
- {NDBD_EXIT_AFS_UNKNOWN , XIE, "Unknown file system error"},
- {NDBD_EXIT_AFS_NO_MORE_RESOURCES , XIE,
- "System reports no more file system resources"},
- {NDBD_EXIT_AFS_NO_SUCH_FILE , XFI, "File not found"},
- {NDBD_EXIT_AFS_READ_UNDERFLOW , XFI, "Read underflow"},
-
- {NDBD_EXIT_INVALID_LCP_FILE, XFI, "Invalid LCP" },
- {NDBD_EXIT_INSUFFICENT_NODES, XRE, "Insufficent nodes for system restart" },
-
- /* Sentinel */
- {0, XUE,
- "No message slogan found (please report a bug if you get this error code)"}
-};
-
-typedef struct StatusExitMessage {
- ndbd_exit_status status;
- const char * message;
-} StatusExitMessage;
-
-typedef struct StatusExitClassification {
- ndbd_exit_status status;
- ndbd_exit_classification classification;
- const char * message;
-} StatusExitClassification;
-
-/**
- * Mapping between classification and status
- */
-static
-const
-StatusExitMessage StatusExitMessageMapping[] = {
- { XST_S, "Success"},
- { XST_U ,"Unknown"},
- { XST_P, "Permanent error, external action needed"},
- { XST_R, "Temporary error, restart node"},
- { XST_I, "Ndbd file system error, restart node initial"}
-};
-
-static
-const
-int NbExitStatus = sizeof(StatusExitMessageMapping)/sizeof(StatusExitMessage);
-
-static
-const
-StatusExitClassification StatusExitClassificationMapping[] = {
- { XST_S, XNE, "No error"},
- { XST_U, XUE, "Unknown"},
- { XST_R, XIE, "Internal error, programming error or missing error message, "
- "please report a bug"},
- { XST_P, XCE, "Configuration error"},
- { XST_R, XAE, "Arbitration error"},
- { XST_R, XRE, "Restart error"},
- { XST_P, XCR, "Resource configuration error"},
- { XST_P, XFF, "File system full"},
- { XST_I, XFI, "Ndbd file system inconsistency error, please report a bug"},
- { XST_I, XFL, "Ndbd file system limit exceeded"}
-};
-
-static const int NbExitClassification =
-sizeof(StatusExitClassificationMapping)/sizeof(StatusExitClassification);
-
-const char *ndbd_exit_message(int faultId, ndbd_exit_classification *cl)
-{
- int i = 0;
- while (errArray[i].faultId != faultId && errArray[i].faultId != 0)
- i++;
- *cl = errArray[i].classification;
- return errArray[i].text;
-}
-
-static const char* empty_xstring = "";
-
-const
-char *ndbd_exit_classification_message(ndbd_exit_classification classification,
- ndbd_exit_status *status)
-{
- int i;
- for (i= 0; i < NbExitClassification; i++)
- {
- if (StatusExitClassificationMapping[i].classification == classification)
- {
- *status = StatusExitClassificationMapping[i].status;
- return StatusExitClassificationMapping[i].message;
- }
- }
- *status = XST_U;
- return empty_xstring;
-}
-
-const char *ndbd_exit_status_message(ndbd_exit_status status)
-{
- int i;
- for (i= 0; i < NbExitStatus; i++)
- if (StatusExitMessageMapping[i].status == status)
- return StatusExitMessageMapping[i].message;
- return empty_xstring;
-}
-
-int ndbd_exit_string(int err_no, char *str, unsigned int size)
-{
- unsigned int len;
-
- ndbd_exit_classification cl;
- ndbd_exit_status st;
- const char *msg = ndbd_exit_message(err_no, &cl);
- if (msg[0] != '\0' && cl != XUE)
- {
- const char *cl_msg = ndbd_exit_classification_message(cl, &st);
- const char *st_msg = ndbd_exit_status_message(st);
-
- len = my_snprintf(str, size-1, "%s: %s: %s", msg, st_msg, cl_msg);
- str[size-1]= '\0';
-
- return len;
- }
- return -1;
-}
diff --git a/storage/ndb/src/kernel/main.cpp b/storage/ndb/src/kernel/main.cpp
deleted file mode 100644
index a9660a6ff86..00000000000
--- a/storage/ndb/src/kernel/main.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-
-#include <ndb_version.h>
-#include "Configuration.hpp"
-#include <ConfigRetriever.hpp>
-#include <TransporterRegistry.hpp>
-
-#include "vm/SimBlockList.hpp"
-#include "ThreadConfig.hpp"
-#include <SignalLoggerManager.hpp>
-#include <NdbOut.hpp>
-#include <NdbMain.h>
-#include <NdbDaemon.h>
-#include <NdbSleep.h>
-#include <NdbConfig.h>
-#include <WatchDog.hpp>
-
-#include <LogLevel.hpp>
-#include <EventLogger.hpp>
-
-#include <NdbAutoPtr.hpp>
-
-#include <Properties.hpp>
-
-#include <mgmapi_debug.h>
-
-#if defined NDB_SOLARIS // ok
-#include <sys/processor.h> // For system informatio
-#endif
-
-extern EventLogger g_eventLogger;
-extern NdbMutex * theShutdownMutex;
-
-void catchsigs(bool ignore); // for process signal handling
-
-#define MAX_FAILED_STARTUPS 3
-// Flag set by child through SIGUSR1 to signal a failed startup
-static bool failed_startup_flag = false;
-// Counter for consecutive failed startups
-static Uint32 failed_startups = 0;
-extern "C" void handler_shutdown(int signum); // for process signal handling
-extern "C" void handler_error(int signum); // for process signal handling
-extern "C" void handler_sigusr1(int signum); // child signalling failed restart
-
-// Shows system information
-void systemInfo(const Configuration & conf,
- const LogLevel & ll);
-
-// These are used already before fork if fetch_configuration() fails
-// (e.g. Unable to alloc node id). Set them to something reasonable.
-static FILE *child_info_file_r= stdin;
-static FILE *child_info_file_w= stdout;
-
-static void writeChildInfo(const char *token, int val)
-{
- fprintf(child_info_file_w, "%s=%d\n", token, val);
- fflush(child_info_file_w);
-}
-
-void childReportSignal(int signum)
-{
- writeChildInfo("signal", signum);
-}
-
-void childReportError(int error)
-{
- writeChildInfo("error", error);
-}
-
-void childExit(int code, Uint32 currentStartPhase)
-{
- writeChildInfo("sphase", currentStartPhase);
- writeChildInfo("exit", code);
- fprintf(child_info_file_w, "\n");
- fclose(child_info_file_r);
- fclose(child_info_file_w);
- exit(code);
-}
-
-void childAbort(int code, Uint32 currentStartPhase)
-{
- writeChildInfo("sphase", currentStartPhase);
- writeChildInfo("exit", code);
- fprintf(child_info_file_w, "\n");
- fclose(child_info_file_r);
- fclose(child_info_file_w);
- signal(6, SIG_DFL);
- abort();
-}
-
-static int insert(const char * pair, Properties & p)
-{
- BaseString tmp(pair);
-
- tmp.trim(" \t\n\r");
- Vector<BaseString> split;
- tmp.split(split, ":=", 2);
- if(split.size() != 2)
- return -1;
- p.put(split[0].trim().c_str(), split[1].trim().c_str());
- return 0;
-}
-
-static int readChildInfo(Properties &info)
-{
- fclose(child_info_file_w);
- char buf[128];
- while (fgets(buf,sizeof(buf),child_info_file_r))
- insert(buf,info);
- fclose(child_info_file_r);
- return 0;
-}
-
-static bool get_int_property(Properties &info,
- const char *token, Uint32 *int_val)
-{
- const char *str_val= 0;
- if (!info.get(token, &str_val))
- return false;
- char *endptr;
- long int tmp= strtol(str_val, &endptr, 10);
- if (str_val == endptr)
- return false;
- *int_val = tmp;
- return true;
-}
-
-int reportShutdown(class Configuration *config, int error_exit, int restart)
-{
- Uint32 error= 0, signum= 0, sphase= 256;
- Properties info;
- readChildInfo(info);
-
- get_int_property(info, "signal", &signum);
- get_int_property(info, "error", &error);
- get_int_property(info, "sphase", &sphase);
-
- Uint32 length, theData[25];
- EventReport *rep = (EventReport *)theData;
-
- rep->setNodeId(globalData.ownId);
- if (restart)
- theData[1] = 1 |
- (globalData.theRestartFlag == initial_state ? 2 : 0) |
- (config->getInitialStart() ? 4 : 0);
- else
- theData[1] = 0;
-
- if (error_exit == 0)
- {
- rep->setEventType(NDB_LE_NDBStopCompleted);
- theData[2] = signum;
- length = 3;
- }
- else
- {
- rep->setEventType(NDB_LE_NDBStopForced);
- theData[2] = signum;
- theData[3] = error;
- theData[4] = sphase;
- theData[5] = 0; // extra
- length = 6;
- }
-
- { // Log event
- const EventReport * const eventReport = (EventReport *)&theData[0];
- g_eventLogger.log(eventReport->getEventType(), theData,
- eventReport->getNodeId(), 0);
- }
-
- for (unsigned n = 0; n < config->m_mgmds.size(); n++)
- {
- NdbMgmHandle h = ndb_mgm_create_handle();
- if (h == 0 ||
- ndb_mgm_set_connectstring(h, config->m_mgmds[n].c_str()) ||
- ndb_mgm_connect(h,
- 1, //no_retries
- 0, //retry_delay_in_seconds
- 0 //verbose
- ))
- goto handle_error;
-
- {
- if (ndb_mgm_report_event(h, theData, length))
- goto handle_error;
- }
- goto do_next;
-
-handle_error:
- if (h)
- {
- BaseString tmp(ndb_mgm_get_latest_error_msg(h));
- tmp.append(" : ");
- tmp.append(ndb_mgm_get_latest_error_desc(h));
- g_eventLogger.warning("Unable to report shutdown reason to %s: %s",
- config->m_mgmds[n].c_str(), tmp.c_str());
- }
- else
- {
- g_eventLogger.error("Unable to report shutdown reason to %s",
- config->m_mgmds[n].c_str());
- }
-do_next:
- if (h)
- {
- ndb_mgm_disconnect(h);
- ndb_mgm_destroy_handle(&h);
- }
- }
- return 0;
-}
-
-int main(int argc, char** argv)
-{
- NDB_INIT(argv[0]);
- // Print to stdout/console
- g_eventLogger.createConsoleHandler();
- g_eventLogger.setCategory("ndbd");
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_INFO);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_CRITICAL);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_WARNING);
-
- g_eventLogger.m_logLevel.setLogLevel(LogLevel::llStartUp, 15);
-
- globalEmulatorData.create();
-
- // Parse command line options
- Configuration* theConfig = globalEmulatorData.theConfiguration;
- if(!theConfig->init(argc, argv)){
- return NRT_Default;
- }
-
- { // Do configuration
-#ifndef NDB_WIN32
- signal(SIGPIPE, SIG_IGN);
-#endif
- theConfig->fetch_configuration();
- }
-
- my_setwd(NdbConfig_get_path(0), MYF(0));
-
- if (theConfig->getDaemonMode()) {
- // Become a daemon
- char *lockfile= NdbConfig_PidFileName(globalData.ownId);
- char *logfile= NdbConfig_StdoutFileName(globalData.ownId);
- NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
-
- if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
- ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
- return 1;
- }
- }
-
-#ifndef NDB_WIN32
- signal(SIGUSR1, handler_sigusr1);
-
- pid_t child = -1;
- while (! theConfig->getForegroundMode()) // the cond is const
- {
- // setup reporting between child and parent
- int filedes[2];
- if (pipe(filedes))
- {
- g_eventLogger.error("pipe() failed with errno=%d (%s)",
- errno, strerror(errno));
- return 1;
- }
- else
- {
- if (!(child_info_file_w= fdopen(filedes[1],"w")))
- {
- g_eventLogger.error("fdopen() failed with errno=%d (%s)",
- errno, strerror(errno));
- }
- if (!(child_info_file_r= fdopen(filedes[0],"r")))
- {
- g_eventLogger.error("fdopen() failed with errno=%d (%s)",
- errno, strerror(errno));
- }
- }
-
- if ((child = fork()) <= 0)
- break; // child or error
-
- /**
- * Parent
- */
-
- catchsigs(true);
-
- /**
- * We no longer need the mgm connection in this process
- * (as we are the angel, not ndb)
- *
- * We don't want to purge any allocated resources (nodeid), so
- * we set that option to false
- */
- theConfig->closeConfiguration(false);
-
- int status = 0, error_exit = 0, signum = 0;
- while(waitpid(child, &status, 0) != child);
- if(WIFEXITED(status)){
- switch(WEXITSTATUS(status)){
- case NRT_Default:
- g_eventLogger.info("Angel shutting down");
- reportShutdown(theConfig, 0, 0);
- exit(0);
- break;
- case NRT_NoStart_Restart:
- theConfig->setInitialStart(false);
- globalData.theRestartFlag = initial_state;
- break;
- case NRT_NoStart_InitialStart:
- theConfig->setInitialStart(true);
- globalData.theRestartFlag = initial_state;
- break;
- case NRT_DoStart_InitialStart:
- theConfig->setInitialStart(true);
- globalData.theRestartFlag = perform_start;
- break;
- default:
- error_exit = 1;
- if(theConfig->stopOnError()){
- /**
- * Error shutdown && stopOnError()
- */
- reportShutdown(theConfig, error_exit, 0);
- exit(0);
- }
- // Fall-through
- case NRT_DoStart_Restart:
- theConfig->setInitialStart(false);
- globalData.theRestartFlag = perform_start;
- break;
- }
- } else {
- error_exit = 1;
- if (WIFSIGNALED(status))
- {
- signum = WTERMSIG(status);
- childReportSignal(signum);
- }
- else
- {
- signum = 127;
- g_eventLogger.info("Unknown exit reason. Stopped.");
- }
- if(theConfig->stopOnError()){
- /**
- * Error shutdown && stopOnError()
- */
- reportShutdown(theConfig, error_exit, 0);
- exit(0);
- }
- }
-
- if (!failed_startup_flag)
- {
- // Reset the counter for consecutive failed startups
- failed_startups = 0;
- }
- else if (failed_startups >= MAX_FAILED_STARTUPS && !theConfig->stopOnError())
- {
- /**
- * Error shutdown && stopOnError()
- */
- g_eventLogger.alert("Ndbd has failed %u consecutive startups. "
- "Not restarting", failed_startups);
- reportShutdown(theConfig, error_exit, 0);
- exit(0);
- }
- failed_startup_flag = false;
- reportShutdown(theConfig, error_exit, 1);
- g_eventLogger.info("Ndb has terminated (pid %d) restarting", child);
- theConfig->fetch_configuration();
- }
-
- if (child >= 0)
- g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid());
- else if (child > 0)
- g_eventLogger.info("Ndb pid: %d", getpid());
- else
- g_eventLogger.info("Ndb started in foreground");
-#else
- g_eventLogger.info("Ndb started");
-#endif
- theConfig->setupConfiguration();
- systemInfo(* theConfig, * theConfig->m_logLevel);
-
- // Load blocks
- globalEmulatorData.theSimBlockList->load(globalEmulatorData);
-
- // Set thread concurrency for Solaris' light weight processes
- int status;
- status = NdbThread_SetConcurrencyLevel(30);
- assert(status == 0);
-
-#ifdef VM_TRACE
- // Create a signal logger
- char *buf= NdbConfig_SignalLogFileName(globalData.ownId);
- NdbAutoPtr<char> tmp_aptr(buf);
- FILE * signalLog = fopen(buf, "a");
- globalSignalLoggers.setOwnNodeId(globalData.ownId);
- globalSignalLoggers.setOutputStream(signalLog);
-#if 0 // to log startup
- globalSignalLoggers.log(SignalLoggerManager::LogInOut, "BLOCK=DBDICT,DBDIH");
- globalData.testOn = 1;
-#endif
-#endif
-
- catchsigs(false);
-
- /**
- * Do startup
- */
-
- ErrorReporter::setErrorHandlerShutdownType(NST_ErrorHandlerStartup);
-
- switch(globalData.theRestartFlag){
- case initial_state:
- globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
- break;
- case perform_start:
- globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
- globalEmulatorData.theThreadConfig->doStart(NodeState::SL_STARTING);
- break;
- default:
- assert("Illegal state globalData.theRestartFlag" == 0);
- }
-
- globalTransporterRegistry.startSending();
- globalTransporterRegistry.startReceiving();
- if (!globalTransporterRegistry.start_service(*globalEmulatorData.m_socket_server)){
- ndbout_c("globalTransporterRegistry.start_service() failed");
- exit(-1);
- }
-
- // Re-use the mgm handle as a transporter
- if(!globalTransporterRegistry.connect_client(
- theConfig->get_config_retriever()->get_mgmHandlePtr()))
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
- "Connection to mgmd terminated before setup was complete",
- "StopOnError missing");
-
- if (!globalTransporterRegistry.start_clients()){
- ndbout_c("globalTransporterRegistry.start_clients() failed");
- exit(-1);
- }
-
- globalEmulatorData.theWatchDog->doStart();
-
- globalEmulatorData.m_socket_server->startServer();
-
- // theConfig->closeConfiguration();
-
- globalEmulatorData.theThreadConfig->ipControlLoop();
-
- NdbShutdown(NST_Normal);
-
- return NRT_Default;
-}
-
-
-void
-systemInfo(const Configuration & config, const LogLevel & logLevel){
-#ifdef NDB_WIN32
- int processors = 0;
- int speed;
- SYSTEM_INFO sinfo;
- GetSystemInfo(&sinfo);
- processors = sinfo.dwNumberOfProcessors;
- HKEY hKey;
- if(ERROR_SUCCESS==RegOpenKeyEx
- (HKEY_LOCAL_MACHINE,
- TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
- 0, KEY_READ, &hKey)) {
- DWORD dwMHz;
- DWORD cbData = sizeof(dwMHz);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,
- "~MHz", 0, 0, (LPBYTE)&dwMHz, &cbData)) {
- speed = int(dwMHz);
- }
- RegCloseKey(hKey);
- }
-#elif defined NDB_SOLARIS // ok
- // Search for at max 16 processors among the first 256 processor ids
- processor_info_t pinfo; memset(&pinfo, 0, sizeof(pinfo));
- int pid = 0;
- while(processors < 16 && pid < 256){
- if(!processor_info(pid++, &pinfo))
- processors++;
- }
- speed = pinfo.pi_clock;
-#endif
-
- if(logLevel.getLogLevel(LogLevel::llStartUp) > 0){
- g_eventLogger.info("NDB Cluster -- DB node %d", globalData.ownId);
- g_eventLogger.info("%s --", NDB_VERSION_STRING);
- if (config.get_mgmd_host())
- g_eventLogger.info("Configuration fetched at %s port %d",
- config.get_mgmd_host(), config.get_mgmd_port());
-#ifdef NDB_SOLARIS // ok
- g_eventLogger.info("NDB is running on a machine with %d processor(s) at %d MHz",
- processor, speed);
-#endif
- }
- if(logLevel.getLogLevel(LogLevel::llStartUp) > 3){
- Uint32 t = config.timeBetweenWatchDogCheck();
- g_eventLogger.info("WatchDog timer is set to %d ms", t);
- }
-
-}
-
-#define handler_register(signum, handler, ignore)\
-{\
- if (ignore) {\
- if(signum != SIGCHLD)\
- signal(signum, SIG_IGN);\
- } else\
- signal(signum, handler);\
-}
-
-void
-catchsigs(bool ignore){
-#if !defined NDB_WIN32
-
- static const int signals_shutdown[] = {
-#ifdef SIGBREAK
- SIGBREAK,
-#endif
- SIGHUP,
- SIGINT,
-#if defined SIGPWR
- SIGPWR,
-#elif defined SIGINFO
- SIGINFO,
-#endif
- SIGQUIT,
- SIGTERM,
-#ifdef SIGTSTP
- SIGTSTP,
-#endif
- SIGTTIN,
- SIGTTOU
- };
-
- static const int signals_error[] = {
- SIGABRT,
- SIGALRM,
-#ifdef SIGBUS
- SIGBUS,
-#endif
- SIGCHLD,
- SIGFPE,
- SIGILL,
-#ifdef SIGIO
- SIGIO,
-#endif
-#ifdef SIGPOLL
- SIGPOLL,
-#endif
- SIGSEGV
- };
-
- static const int signals_ignore[] = {
- SIGPIPE
- };
-
- size_t i;
- for(i = 0; i < sizeof(signals_shutdown)/sizeof(signals_shutdown[0]); i++)
- handler_register(signals_shutdown[i], handler_shutdown, ignore);
- for(i = 0; i < sizeof(signals_error)/sizeof(signals_error[0]); i++)
- handler_register(signals_error[i], handler_error, ignore);
- for(i = 0; i < sizeof(signals_ignore)/sizeof(signals_ignore[0]); i++)
- handler_register(signals_ignore[i], SIG_IGN, ignore);
-#ifdef SIGTRAP
- Configuration* theConfig = globalEmulatorData.theConfiguration;
- if (! theConfig->getForegroundMode())
- handler_register(SIGTRAP, handler_error, ignore);
-#endif
-#endif
-}
-
-extern "C"
-void
-handler_shutdown(int signum){
- g_eventLogger.info("Received signal %d. Performing stop.", signum);
- childReportError(0);
- childReportSignal(signum);
- globalData.theRestartFlag = perform_stop;
-}
-
-extern "C"
-void
-handler_error(int signum){
- // only let one thread run shutdown
- static long thread_id= 0;
-
- if (thread_id != 0 && thread_id == my_thread_id())
- {
- // Shutdown thread received signal
-#ifndef NDB_WIN32
- signal(signum, SIG_DFL);
- kill(getpid(), signum);
-#endif
- while(true)
- NdbSleep_MilliSleep(10);
- }
- if(theShutdownMutex && NdbMutex_Trylock(theShutdownMutex) != 0)
- while(true)
- NdbSleep_MilliSleep(10);
- thread_id= my_thread_id();
- g_eventLogger.info("Received signal %d. Running error handler.", signum);
- childReportSignal(signum);
- // restart the system
- char errorData[64], *info= 0;
-#ifdef HAVE_STRSIGNAL
- info= strsignal(signum);
-#endif
- BaseString::snprintf(errorData, sizeof(errorData), "Signal %d received; %s", signum,
- info ? info : "No text for signal available");
- ERROR_SET_SIGNAL(fatal, NDBD_EXIT_OS_SIGNAL_RECEIVED, errorData, __FILE__);
-}
-
-extern "C"
-void
-handler_sigusr1(int signum)
-{
- if (!failed_startup_flag)
- {
- failed_startups++;
- failed_startup_flag = true;
- }
- g_eventLogger.info("Angel received ndbd startup failure count %u.", failed_startups);
-}
diff --git a/storage/ndb/src/kernel/vm/Array.hpp b/storage/ndb/src/kernel/vm/Array.hpp
deleted file mode 100644
index 7d9f955c296..00000000000
--- a/storage/ndb/src/kernel/vm/Array.hpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ARRAY_HPP
-#define ARRAY_HPP
-
-#include "ArrayPool.hpp"
-
-#include <pc.hpp>
-#include <ErrorReporter.hpp>
-
-/**
- * Template class used for implementing an
- * array of object retreived from a pool
- */
-template <class T>
-class Array {
-public:
- Array(ArrayPool<T> & thePool);
-
- /**
- * Allocate an <b>n</b> objects from pool
- * These can now be addressed with 0 <= ptr.i < n
- */
- bool seize(Uint32 i);
-
- /**
- * Release all object from array
- */
- void release();
-
- /**
- * Return current size of array
- */
- Uint32 getSize() const;
-
- /**
- * empty
- */
- inline bool empty() const { return sz == 0;}
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const ;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const;
-
-private:
- Uint32 base, sz;
- ArrayPool<T> & thePool;
-};
-
-template<class T>
-inline
-Array<T>::Array(ArrayPool<T> & _pool)
- : thePool(_pool)
-{
- sz = 0;
- base = RNIL;
-}
-
-template<class T>
-inline
-bool
-Array<T>::seize(Uint32 n){
- if(base == RNIL && n > 0){
- base = thePool.seizeN(n);
- if(base != RNIL){
- sz = n;
- return true;
- }
- return false;
- }
- ErrorReporter::handleAssert("Array<T>::seize failed", __FILE__, __LINE__);
- return false;
-}
-
-template<class T>
-inline
-void
-Array<T>::release(){
- if(base != RNIL){
- thePool.releaseN(base, sz);
- sz = 0;
- base = RNIL;
- return;
- }
-}
-
-template<class T>
-inline
-Uint32
-Array<T>::getSize() const {
- return sz;
-}
-
-template <class T>
-inline
-void
-Array<T>::getPtr(Ptr<T> & p, Uint32 i) const {
- p.i = i;
-#ifdef ARRAY_GUARD
- if(i < sz && base != RNIL){
- p.p = thePool.getPtr(i + base);
- return;
- } else {
- ErrorReporter::handleAssert("Array::getPtr failed", __FILE__, __LINE__);
- }
-#endif
- p.p = thePool.getPtr(i + base);
-}
-
-template<class T>
-inline
-void
-Array<T>::getPtr(Ptr<T> & ptr) const {
-#ifdef ARRAY_GUARD
- if(ptr.i < sz && base != RNIL){
- ptr.p = thePool.getPtr(ptr.i + base);
- return;
- } else {
- ErrorReporter::handleAssert("Array<T>::getPtr failed", __FILE__, __LINE__);
- }
-#endif
- ptr.p = thePool.getPtr(ptr.i + base);
-}
-
-template<class T>
-inline
-T *
-Array<T>::getPtr(Uint32 i) const {
-#ifdef ARRAY_GUARD
- if(i < sz && base != RNIL){
- return thePool.getPtr(i + base);
- } else {
- ErrorReporter::handleAssert("Array<T>::getPtr failed", __FILE__, __LINE__);
- }
-#endif
- return thePool.getPtr(i + base);
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/ArrayPool.hpp b/storage/ndb/src/kernel/vm/ArrayPool.hpp
deleted file mode 100644
index dbc6319a583..00000000000
--- a/storage/ndb/src/kernel/vm/ArrayPool.hpp
+++ /dev/null
@@ -1,985 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ARRAY_POOL_HPP
-#define ARRAY_POOL_HPP
-
-#include <ndb_global.h>
-#include "ndbd_malloc.hpp"
-
-#include <pc.hpp>
-#include "Pool.hpp"
-#include <ErrorReporter.hpp>
-#include <NdbMem.h>
-#include <Bitmask.hpp>
-#include <mgmapi.h>
-
-template <class T> class Array;
-
-/**
- * Template class used for implementing an
- * pool of object (in an array with a free list)
- */
-template <class T>
-class ArrayPool {
-public:
- ArrayPool();
- ~ArrayPool();
-
- /**
- * Set the size of the pool
- *
- * Note, can currently only be called once
- */
- bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true,
- bool guard = true, Uint32 paramId = 0);
- bool set(T*, Uint32 cnt, bool align = false);
- void clear() { theArray = 0; }
-
- inline Uint32 getNoOfFree() const {
- return noOfFree;
- }
-
- inline Uint32 getSize() const {
- return size;
- }
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &);
- void getPtr(ConstPtr<T> &) const;
- void getPtr(Ptr<T> &, bool CrashOnBoundaryError);
- void getPtr(ConstPtr<T> &, bool CrashOnBoundaryError) const;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i);
- const T * getConstPtr(Uint32 i) const;
- T * getPtr(Uint32 i, bool CrashOnBoundaryError);
- const T * getConstPtr(Uint32 i, bool CrashOnBoundaryError) const;
-
- /**
- * Update p & i value for ptr according to <b>i</b> value
- */
- void getPtr(Ptr<T> &, Uint32 i);
- void getPtr(ConstPtr<T> &, Uint32 i) const;
- void getPtr(Ptr<T> &, Uint32 i, bool CrashOnBoundaryError);
- void getPtr(ConstPtr<T> &, Uint32 i, bool CrashOnBoundaryError) const;
-
- /**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
- bool seize(Ptr<T> &);
-
- /**
- * Allocate object <b>i</b> from pool - update Ptr
- */
- bool seizeId(Ptr<T> &, Uint32 i);
-
- /**
- * Check if <b>i</b> is allocated.
- */
- bool findId(Uint32 i) const;
-
- /**
- * Return an object to pool
- */
- void release(Uint32 i);
-
- /**
- * Return an object to pool
- */
- void release(Ptr<T> &);
-
-#ifdef ARRAY_GUARD
- /**
- * Checks if i is a correct seized record
- *
- * @note Since this is either an expensive method,
- * or needs bitmask stuff, this method is only
- * recommended for debugging.
- *
- */
- bool isSeized(Uint32 i) const {
- if (i>=size) return false;
- return BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i);
- }
-#endif
-
-protected:
- friend class Array<T>;
-
- /**
- * Allocate <b>n</b> consecutive object from pool
- * return base
- */
- Uint32 seizeN(Uint32 n);
-
- /**
- * Deallocate <b>n<b> consecutive object to pool
- * starting from base
- */
- void releaseN(Uint32 base, Uint32 n);
-
-public:
- /**
- * Release a singel linked list in o(1)
- * @param first i-value of first element in list
- * @param last i-value of last element in list
- * @note nextPool must be used as next pointer in list
- */
- void releaseList(Uint32 n, Uint32 first, Uint32 last);
- //private:
-
-#ifdef DEBUG
- Uint32 getNoOfFree2() const {
- Uint32 c2 = size;
- for(Uint32 i = 0; i<((size + 31)>> 5); i++){
- Uint32 w = theAllocatedBitmask[i];
- for(Uint32 j = 0; j<32; j++){
- if((w & 1) == 1){
- c2--;
- }
- w >>= 1;
- }
- }
- return c2;
- }
-
- Uint32 getNoOfFree3() const {
- Uint32 c = 0;
- Ptr<T> p;
- p.i = firstFree;
- while(p.i != RNIL){
- c++;
- p.p = &theArray[p.i];
- p.i = p.p->next;
- }
- return c;
- }
-#endif
-
-protected:
- Uint32 firstFree;
- Uint32 size;
- Uint32 noOfFree;
- T * theArray;
- void * alloc_ptr;
- Uint32 bitmaskSz;
- Uint32 *theAllocatedBitmask;
-};
-
-template <class T>
-inline
-ArrayPool<T>::ArrayPool(){
- firstFree = RNIL;
- size = 0;
- noOfFree = 0;
- theArray = 0;
- alloc_ptr = 0;
-#ifdef ARRAY_GUARD
- theAllocatedBitmask = 0;
-#endif
-}
-
-template <class T>
-inline
-ArrayPool<T>::~ArrayPool(){
- if(theArray != 0){
- ndbd_free(alloc_ptr, size * sizeof(T));
- theArray = 0;
- alloc_ptr = 0;
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- delete []theAllocatedBitmask;
- theAllocatedBitmask = 0;
-#endif
- }
-}
-
-/**
- * Set the size of the pool
- *
- * Note, can currently only be called once
- */
-template <class T>
-inline
-bool
-ArrayPool<T>::setSize(Uint32 noOfElements,
- bool align, bool exit_on_error, bool guard, Uint32 paramId){
- if(size == 0){
- if(noOfElements == 0)
- return true;
- Uint64 real_size = (Uint64)noOfElements * sizeof(T);
- size_t req_size = (size_t)real_size;
- Uint64 real_size_align = real_size + sizeof(T);
- size_t req_size_align = (size_t)real_size_align;
-
- if(align)
- {
- if((Uint64)req_size_align == real_size_align && req_size_align > 0)
- alloc_ptr = ndbd_malloc(req_size_align);
- UintPtr p = (UintPtr)alloc_ptr;
- UintPtr mod = p % sizeof(T);
- if (mod)
- {
- p += sizeof(T) - mod;
- }
- theArray = (T *)p;
- }
- else if((Uint64)req_size == real_size && req_size > 0)
- theArray = (T *)(alloc_ptr = ndbd_malloc(req_size));
-
- if(theArray == 0)
- {
- char errmsg[255] = "ArrayPool<T>::setSize malloc failed";
- struct ndb_mgm_param_info param_info;
- size_t size = sizeof(ndb_mgm_param_info);
- if (!exit_on_error)
- return false;
-
- if(0 != paramId && 0 == ndb_mgm_get_db_parameter_info(paramId, &param_info, &size)) {
- BaseString::snprintf(errmsg, sizeof(errmsg),
- "Malloc memory for %s failed", param_info.m_name);
- }
-
- ErrorReporter::handleAssert(errmsg,
- __FILE__, __LINE__, NDBD_EXIT_MEMALLOC);
- return false; // not reached
- }
- size = noOfElements;
- noOfFree = noOfElements;
-
- /**
- * Set next pointers
- */
- T * t = &theArray[0];
- for(Uint32 i = 0; i<size; i++){
- t->nextPool = (i + 1);
- t++;
- }
- theArray[size-1].nextPool = RNIL;
- firstFree = 0;
-
-#ifdef ARRAY_GUARD
- if (guard)
- {
- bitmaskSz = (noOfElements + 31) >> 5;
- theAllocatedBitmask = new Uint32[bitmaskSz];
- BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask);
- }
-#endif
-
- return true;
- }
- if (!exit_on_error)
- return false;
-
- ErrorReporter::handleAssert("ArrayPool<T>::setSize called twice", __FILE__, __LINE__);
- return false; // not reached
-}
-
-template <class T>
-inline
-bool
-ArrayPool<T>::set(T* ptr, Uint32 cnt, bool align){
- if (size == 0)
- {
- alloc_ptr = ptr;
- if(align)
- {
- UintPtr p = (UintPtr)alloc_ptr;
- UintPtr mod = p % sizeof(T);
- if (mod)
- {
- p += sizeof(T) - mod;
- cnt --;
- }
- theArray = (T *)p;
- }
- else
- {
- theArray = (T *)alloc_ptr;
- }
-
- size = cnt;
- noOfFree = 0;
- return true;
- }
- ErrorReporter::handleAssert("ArrayPool<T>::set called twice",
- __FILE__, __LINE__);
- return false; // not reached
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(Ptr<T> & ptr){
- Uint32 i = ptr.i;
- if(likely (i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(ConstPtr<T> & ptr) const {
- Uint32 i = ptr.i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i){
- ptr.i = i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i) const {
- ptr.i = i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-T *
-ArrayPool<T>::getPtr(Uint32 i){
- if(likely(i < size)){
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return &theArray[i];
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-#endif
- return &theArray[i];
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-}
-
-template <class T>
-inline
-const T *
-ArrayPool<T>::getConstPtr(Uint32 i) const {
- if(likely(i < size)){
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return &theArray[i];
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-#endif
- return &theArray[i];
- } else {
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(Ptr<T> & ptr, bool CrashOnBoundaryError){
- Uint32 i = ptr.i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ptr.i = RNIL;
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(ConstPtr<T> & ptr, bool CrashOnBoundaryError) const {
- Uint32 i = ptr.i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ptr.i = RNIL;
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(Ptr<T> & ptr, Uint32 i, bool CrashOnBoundaryError){
- ptr.i = i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ptr.i = RNIL;
- }
-}
-
-template <class T>
-inline
-void
-ArrayPool<T>::getPtr(ConstPtr<T> & ptr, Uint32 i,
- bool CrashOnBoundaryError) const {
- ptr.i = i;
- if(likely(i < size)){
- ptr.p = &theArray[i];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return;
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- }
-#endif
- } else {
- ptr.i = RNIL;
- }
-}
-
-template <class T>
-inline
-T *
-ArrayPool<T>::getPtr(Uint32 i, bool CrashOnBoundaryError){
- if(likely(i < size)){
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return &theArray[i];
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-#endif
- return &theArray[i];
- } else {
- return 0;
- }
-}
-
-template <class T>
-inline
-const T *
-ArrayPool<T>::getConstPtr(Uint32 i, bool CrashOnBoundaryError) const {
- if(likely(i < size)){
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i))
- return &theArray[i];
- /**
- * Getting a non-seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::getConstPtr", __FILE__,__LINE__);
- return 0;
- }
-#endif
- return &theArray[i];
- } else {
- return 0;
- }
-}
-
-/**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
-template <class T>
-inline
-bool
-ArrayPool<T>::seize(Ptr<T> & ptr){
- Uint32 ff = firstFree;
- if(ff != RNIL){
- firstFree = theArray[ff].nextPool;
-
- ptr.i = ff;
- ptr.p = &theArray[ff];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
- BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
- noOfFree--;
- return true;
- } else {
- /**
- * Seizing an already seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
- return false;
- }
- }
-#endif
- noOfFree--;
- return true;
- }
- ptr.i = RNIL;
- ptr.p = NULL;
- return false;
-}
-
-template <class T>
-inline
-bool
-ArrayPool<T>::seizeId(Ptr<T> & ptr, Uint32 i){
- Uint32 ff = firstFree;
- Uint32 prev = RNIL;
- while(ff != i && ff != RNIL){
- prev = ff;
- ff = theArray[ff].nextPool;
- }
-
- if(ff != RNIL){
- if(prev == RNIL)
- firstFree = theArray[ff].nextPool;
- else
- theArray[prev].nextPool = theArray[ff].nextPool;
-
- ptr.i = ff;
- ptr.p = &theArray[ff];
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, ff)){
- BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, ff);
- noOfFree--;
- return true;
- } else {
- /**
- * Seizing an already seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::seizeId", __FILE__, __LINE__);
- return false;
- }
- }
-#endif
- noOfFree--;
- return true;
- }
- ptr.i = RNIL;
- ptr.p = NULL;
- return false;
-}
-
-template <class T>
-inline
-bool
-ArrayPool<T>::findId(Uint32 i) const {
- if (i >= size)
- return false;
- Uint32 ff = firstFree;
- while(ff != i && ff != RNIL){
- ff = theArray[ff].nextPool;
- }
- return (ff == RNIL);
-}
-
-template<class T>
-Uint32
-ArrayPool<T>::seizeN(Uint32 n){
- Uint32 curr = firstFree;
- Uint32 prev = RNIL;
- Uint32 sz = 0;
- while(sz < n && curr != RNIL){
- if(theArray[curr].nextPool == (curr + 1)){
- sz++;
- } else {
- sz = 0;
- prev = curr;
- }
- curr = theArray[curr].nextPool;
- }
- if(sz != n){
- return RNIL;
- }
- const Uint32 base = curr - n;
- if(base == firstFree){
- firstFree = curr;
- } else {
- theArray[prev].nextPool = curr;
- }
-
- noOfFree -= n;
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- for(Uint32 j = base; j<curr; j++){
- if(!BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, j)){
- BitmaskImpl::set(bitmaskSz, theAllocatedBitmask, j);
- } else {
- /**
- * Seizing an already seized element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::seize", __FILE__, __LINE__);
- return RNIL;
- }
- }
- }
-#endif
- return base;
-}
-
-template<class T>
-inline
-void
-ArrayPool<T>::releaseN(Uint32 base, Uint32 n){
- Uint32 curr = firstFree;
- Uint32 prev = RNIL;
- while(curr < base){
- prev = curr;
- curr = theArray[curr].nextPool;
- }
- if(curr == firstFree){
- firstFree = base;
- } else {
- theArray[prev].nextPool = base;
- }
- const Uint32 end = base + n;
- for(Uint32 i = base; i<end; i++){
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
- BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
- } else {
- /**
- * Relesing a already released element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
- return;
- }
- }
-#endif
- theArray[i].nextPool = i + 1;
- }
- theArray[end-1].nextPool = curr;
- noOfFree += n;
-}
-
-template<class T>
-inline
-void
-ArrayPool<T>::releaseList(Uint32 n, Uint32 first, Uint32 last){
-
- if(first < size && last < size){
- Uint32 ff = firstFree;
- firstFree = first;
- theArray[last].nextPool = ff;
- noOfFree += n;
-
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- Uint32 tmp = first;
- for(Uint32 i = 0; i<n; i++){
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, tmp)){
- BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, tmp);
- } else {
- /**
- * Relesing a already released element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::releaseList",
- __FILE__, __LINE__);
- return;
- }
- tmp = theArray[tmp].nextPool;
- }
- }
-#endif
- return;
- }
- ErrorReporter::handleAssert("ArrayPool<T>::releaseList", __FILE__, __LINE__);
-}
-
-/**
- * Return an object to pool
- */
-template <class T>
-inline
-void
-ArrayPool<T>::release(Uint32 _i){
- const Uint32 i = _i;
- if(likely(i < size)){
- Uint32 ff = firstFree;
- theArray[i].nextPool = ff;
- firstFree = i;
-
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
- BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
- noOfFree++;
- return;
- }
- /**
- * Relesing a already released element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
- }
-#endif
- noOfFree++;
- return;
- }
- ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
-}
-
-/**
- * Return an object to pool
- */
-template <class T>
-inline
-void
-ArrayPool<T>::release(Ptr<T> & ptr){
- Uint32 i = ptr.i;
- if(likely(i < size)){
- Uint32 ff = firstFree;
- theArray[i].nextPool = ff;
- firstFree = i;
-
-#ifdef ARRAY_GUARD
- if (theAllocatedBitmask)
- {
- if(BitmaskImpl::get(bitmaskSz, theAllocatedBitmask, i)){
- BitmaskImpl::clear(bitmaskSz, theAllocatedBitmask, i);
- //assert(noOfFree() == noOfFree2());
- noOfFree++;
- return;
- }
- /**
- * Relesing a already released element
- */
- ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
- }
-#endif
- noOfFree++;
- return;
- }
- ErrorReporter::handleAssert("ArrayPool<T>::release", __FILE__, __LINE__);
-}
-
-template <class T>
-class UnsafeArrayPool : public ArrayPool<T> {
-public:
- /**
- * Update p value for ptr according to i value
- * ignore if it's allocated or not
- */
- void getPtrForce(Ptr<T> &);
- void getPtrForce(ConstPtr<T> &) const;
- T * getPtrForce(Uint32 i);
- const T * getConstPtrForce(Uint32 i) const;
- void getPtrForce(Ptr<T> &, Uint32 i);
- void getPtrForce(ConstPtr<T> &, Uint32 i) const;
-};
-
-template <class T>
-inline
-void
-UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr){
- Uint32 i = ptr.i;
- if(likely(i < this->size)){
- ptr.p = &this->theArray[i];
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-void
-UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr) const{
- Uint32 i = ptr.i;
- if(likely(i < this->size)){
- ptr.p = &this->theArray[i];
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-T *
-UnsafeArrayPool<T>::getPtrForce(Uint32 i){
- if(likely(i < this->size)){
- return &this->theArray[i];
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- return 0;
- }
-}
-
-template <class T>
-inline
-const T *
-UnsafeArrayPool<T>::getConstPtrForce(Uint32 i) const {
- if(likely(i < this->size)){
- return &this->theArray[i];
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- return 0;
- }
-}
-
-template <class T>
-inline
-void
-UnsafeArrayPool<T>::getPtrForce(Ptr<T> & ptr, Uint32 i){
- ptr.i = i;
- if(likely(i < this->size)){
- ptr.p = &this->theArray[i];
- return ;
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-void
-UnsafeArrayPool<T>::getPtrForce(ConstPtr<T> & ptr, Uint32 i) const{
- ptr.i = i;
- if(likely(i < this->size)){
- ptr.p = &this->theArray[i];
- return ;
- } else {
- ErrorReporter::handleAssert("UnsafeArrayPool<T>::getPtr",
- __FILE__, __LINE__);
- }
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/CArray.hpp b/storage/ndb/src/kernel/vm/CArray.hpp
deleted file mode 100644
index 4ae1451756b..00000000000
--- a/storage/ndb/src/kernel/vm/CArray.hpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef CARRAY_HPP
-#define CARRAY_HPP
-
-#include "ndbd_malloc.hpp"
-
-/**
- * Template class used for implementing an c - array
- */
-template <class T>
-class CArray {
-public:
- CArray();
- ~CArray();
-
- /**
- * Set the size of the pool
- *
- * Note, can currently only be called once
- */
- bool setSize(Uint32 noOfElements, bool exit_on_error = true);
-
- /**
- * Get size
- */
- Uint32 getSize() const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const;
-
- /**
- * Update p & i value for ptr according to <b>i</b> value
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
-private:
- Uint32 size;
- T * theArray;
-};
-
-template <class T>
-inline
-CArray<T>::CArray(){
- size = 0;
- theArray = 0;
-}
-
-template <class T>
-inline
-CArray<T>::~CArray(){
- if(theArray != 0){
- ndbd_free(theArray, size * sizeof(T));
- theArray = 0;
- }
-}
-
-/**
- * Set the size of the pool
- *
- * Note, can currently only be called once
- */
-template <class T>
-inline
-bool
-CArray<T>::setSize(Uint32 noOfElements, bool exit_on_error){
- if(size == noOfElements)
- return true;
-
- theArray = (T *)ndbd_malloc(noOfElements * sizeof(T));
- if(theArray == 0)
- {
- if (!exit_on_error)
- return false;
- ErrorReporter::handleAssert("CArray<T>::setSize malloc failed",
- __FILE__, __LINE__, NDBD_EXIT_MEMALLOC);
- return false; // not reached
- }
- size = noOfElements;
- return true;
-}
-
-template<class T>
-inline
-Uint32
-CArray<T>::getSize() const {
- return size;
-}
-
-template <class T>
-inline
-void
-CArray<T>::getPtr(Ptr<T> & ptr) const {
- const Uint32 i = ptr.i;
- if(i < size){
- ptr.p = &theArray[i];
- return;
- } else {
- ErrorReporter::handleAssert("CArray<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-template <class T>
-inline
-T *
-CArray<T>::getPtr(Uint32 i) const {
- if(i < size){
- return &theArray[i];
- } else {
- ErrorReporter::handleAssert("CArray<T>::getPtr", __FILE__, __LINE__);
- return 0;
- }
-}
-
-template <class T>
-inline
-void
-CArray<T>::getPtr(Ptr<T> & ptr, Uint32 i) const {
- ptr.i = i;
- if(i < size){
- ptr.p = &theArray[i];
- return;
- } else {
- ErrorReporter::handleAssert("CArray<T>::getPtr", __FILE__, __LINE__);
- }
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/Callback.hpp b/storage/ndb/src/kernel/vm/Callback.hpp
deleted file mode 100644
index d7f2caf2f54..00000000000
--- a/storage/ndb/src/kernel/vm/Callback.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef BLOCK_CALLBACK_HPP
-#define BLOCK_CALLBACK_HPP
-
-/**
- * Block callbacks
- */
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/ClusterConfiguration.cpp b/storage/ndb/src/kernel/vm/ClusterConfiguration.cpp
deleted file mode 100644
index 263b22e34af..00000000000
--- a/storage/ndb/src/kernel/vm/ClusterConfiguration.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "ClusterConfiguration.hpp"
-#include <ErrorHandlingMacros.hpp>
-
-#include <pc.hpp>
-#include <BlockNumbers.h>
-#include <signaldata/AccSizeAltReq.hpp>
-#include <signaldata/DictSizeAltReq.hpp>
-#include <signaldata/DihSizeAltReq.hpp>
-#include <signaldata/LqhSizeAltReq.hpp>
-#include <signaldata/TcSizeAltReq.hpp>
-#include <signaldata/TupSizeAltReq.hpp>
-#include <signaldata/TuxSizeAltReq.hpp>
-
-ClusterConfiguration::ClusterConfiguration()
-{
- for (unsigned i= 0; i< MAX_SIZEALT_BLOCKS; i++) // initialize
- for (unsigned j= 0; j< MAX_SIZEALT_RECORD; j++) {
- the_clusterData.SizeAltData.varSize[i][j].valid = false;
- the_clusterData.SizeAltData.varSize[i][j].nrr = 0;
- }
-
- for (unsigned i1 = 0; i1< 5; i1++) // initialize
- for (unsigned j1= 0; j1< CmvmiCfgConf::NO_OF_WORDS; j1++)
- the_clusterData.ispValues[i1][j1] = 0;
-
- the_clusterData.SizeAltData.noOfNodes = 0;
- the_clusterData.SizeAltData.noOfNDBNodes = 0;
- the_clusterData.SizeAltData.noOfAPINodes = 0;
- the_clusterData.SizeAltData.noOfMGMNodes = 0;
-}
-
-ClusterConfiguration::~ClusterConfiguration(){
-}
-
-void
-setValue(VarSize* dst, const int index, UintR variableValue){
- assert(dst != NULL);
- assert(index >= 0 && index < MAX_SIZEALT_RECORD);
-
- dst[index].nrr = variableValue;
- dst[index].valid = true;
-}
-
-void
-ClusterConfiguration::calcSizeAlteration()
-{
- SizeAlt *size = &the_clusterData.SizeAltData;
-
- size->noOfTables++; // Remove impact of system table
- size->noOfTables += size->noOfIndexes; // Indexes are tables too
- size->noOfAttributes += 2; // ---"----
-
- size->noOfTables *= 2; // Remove impact of Dict need 2 ids for each table
-
- Uint32 noOfDBNodes = size->noOfNDBNodes;
- if (noOfDBNodes > 15) {
- noOfDBNodes = 15;
- }//if
- Uint32 noOfLocalScanRecords = (noOfDBNodes * size->noOfScanRecords) + 1;
- Uint32 noOfTCScanRecords = size->noOfScanRecords;
- {
- /**
- * Acc Size Alt values
- */
- size->blockNo[ACC] = DBACC;
-
- VarSize * const acc = &(size->varSize[ACC][0]);
-
- // Can keep 65536 pages (= 0.5 GByte)
- setValue(acc, AccSizeAltReq::IND_DIR_RANGE,
- 4 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(acc, AccSizeAltReq::IND_DIR_ARRAY,
- (size->noOfIndexPages >> 8) +
- 4 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(acc, AccSizeAltReq::IND_FRAGMENT,
- 2 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->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.
- /*-----------------------------------------------------------------------*/
- setValue(acc, AccSizeAltReq::IND_OP_RECS,
- size->noOfReplicas*((16 * size->noOfOperations) / 10 + 50) +
- (noOfLocalScanRecords * MAX_PARALLEL_SCANS_PER_FRAG) +
- NODE_RECOVERY_SCAN_OP_RECORDS);
-
- setValue(acc, AccSizeAltReq::IND_OVERFLOW_RECS,
- size->noOfIndexPages +
- 2 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(acc, AccSizeAltReq::IND_PAGE8,
- size->noOfIndexPages + 32);
-
- setValue(acc, AccSizeAltReq::IND_ROOT_FRAG,
- NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(acc, AccSizeAltReq::IND_TABLE,
- size->noOfTables);
-
- setValue(acc, AccSizeAltReq::IND_SCAN,
- noOfLocalScanRecords);
- }
-
- {
- /**
- * Dict Size Alt values
- */
- size->blockNo[DICT] = DBDICT;
-
- VarSize * const dict = &(size->varSize[DICT][0]);
-
- setValue(dict, DictSizeAltReq::IND_ATTRIBUTE,
- size->noOfAttributes);
-
- setValue(dict, DictSizeAltReq::IND_CONNECT,
- size->noOfOperations + 32);
-
- setValue(dict, DictSizeAltReq::IND_FRAG_CONNECT,
- NO_OF_FRAG_PER_NODE * size->noOfNDBNodes * size->noOfReplicas);
-
- setValue(dict, DictSizeAltReq::IND_TABLE,
- size->noOfTables);
-
- setValue(dict, DictSizeAltReq::IND_TC_CONNECT,
- 2* size->noOfOperations);
- }
-
- {
- /**
- * Dih Size Alt values
- */
- size->blockNo[DIH] = DBDIH;
-
- VarSize * const dih = &(size->varSize[DIH][0]);
-
- setValue(dih, DihSizeAltReq::IND_API_CONNECT,
- 2 * size->noOfTransactions);
-
- setValue(dih, DihSizeAltReq::IND_CONNECT,
- size->noOfOperations + 46);
-
- setValue(dih, DihSizeAltReq::IND_FRAG_CONNECT,
- NO_OF_FRAG_PER_NODE * size->noOfTables * size->noOfNDBNodes);
-
- int temp;
- temp = size->noOfReplicas - 2;
- if (temp < 0)
- temp = 1;
- else
- temp++;
- setValue(dih, DihSizeAltReq::IND_MORE_NODES,
- temp * NO_OF_FRAG_PER_NODE *
- size->noOfTables * size->noOfNDBNodes);
-
- setValue(dih, DihSizeAltReq::IND_REPLICAS,
- NO_OF_FRAG_PER_NODE * size->noOfTables *
- size->noOfNDBNodes * size->noOfReplicas);
-
- setValue(dih, DihSizeAltReq::IND_TABLE,
- size->noOfTables);
- }
-
- {
- /**
- * Lqh Size Alt values
- */
- size->blockNo[LQH] = DBLQH;
-
- VarSize * const lqh = &(size->varSize[LQH][0]);
-
- setValue(lqh, LqhSizeAltReq::IND_FRAG,
- NO_OF_FRAG_PER_NODE * size->noOfTables * size->noOfReplicas);
-
- setValue(lqh, LqhSizeAltReq::IND_CONNECT,
- size->noOfReplicas*((11 * size->noOfOperations) / 10 + 50));
-
- setValue(lqh, LqhSizeAltReq::IND_TABLE,
- size->noOfTables);
-
- setValue(lqh, LqhSizeAltReq::IND_TC_CONNECT,
- size->noOfReplicas*((16 * size->noOfOperations) / 10 + 50));
-
- setValue(lqh, LqhSizeAltReq::IND_REPLICAS,
- size->noOfReplicas);
-
- setValue(lqh, LqhSizeAltReq::IND_LOG_FILES,
- (4 * the_clusterData.ispValues[1][4]));
-
- setValue(lqh, LqhSizeAltReq::IND_SCAN,
- noOfLocalScanRecords);
-
- }
-
- {
- /**
- * Tc Size Alt values
- */
- size->blockNo[TC] = DBTC;
-
- VarSize * const tc = &(size->varSize[TC][0]);
-
- setValue(tc, TcSizeAltReq::IND_API_CONNECT,
- 3 * size->noOfTransactions);
-
- setValue(tc, TcSizeAltReq::IND_TC_CONNECT,
- size->noOfOperations + 16 + size->noOfTransactions);
-
- setValue(tc, TcSizeAltReq::IND_TABLE,
- size->noOfTables);
-
- setValue(tc, TcSizeAltReq::IND_LOCAL_SCAN,
- noOfLocalScanRecords);
-
- setValue(tc, TcSizeAltReq::IND_TC_SCAN,
- noOfTCScanRecords);
- }
-
- {
- /**
- * Tup Size Alt values
- */
- size->blockNo[TUP] = DBTUP;
-
- VarSize * const tup = &(size->varSize[TUP][0]);
-
- setValue(tup, TupSizeAltReq::IND_DISK_PAGE_ARRAY,
- 2 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(tup, TupSizeAltReq::IND_DISK_PAGE_REPRESENT,
- size->noOfDiskClusters);
-
- setValue(tup, TupSizeAltReq::IND_FRAG,
- 2 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(tup, TupSizeAltReq::IND_PAGE_CLUSTER,
- size->noOfFreeClusters);
-
- setValue(tup, TupSizeAltReq::IND_LOGIC_PAGE,
- size->noOfDiskBufferPages + size->noOfDiskClusters);
-
- setValue(tup, TupSizeAltReq::IND_OP_RECS,
- size->noOfReplicas*((16 * size->noOfOperations) / 10 + 50));
-
- setValue(tup, TupSizeAltReq::IND_PAGE,
- size->noOfDataPages);
-
- setValue(tup, TupSizeAltReq::IND_PAGE_RANGE,
- 4 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas);
-
- setValue(tup, TupSizeAltReq::IND_TABLE,
- size->noOfTables);
-
- setValue(tup, TupSizeAltReq::IND_TABLE_DESC,
- 4 * NO_OF_FRAG_PER_NODE * size->noOfAttributes* size->noOfReplicas +
- 12 * NO_OF_FRAG_PER_NODE * size->noOfTables* size->noOfReplicas );
-
- setValue(tup, TupSizeAltReq::IND_DELETED_BLOCKS,
- size->noOfFreeClusters);
-
- setValue(tup, TupSizeAltReq::IND_STORED_PROC,
- noOfLocalScanRecords);
- }
-
- {
- /**
- * Tux Size Alt values
- */
- size->blockNo[TUX] = DBTUX;
-
- VarSize * const tux = &(size->varSize[TUX][0]);
-
- setValue(tux, TuxSizeAltReq::IND_INDEX,
- size->noOfTables);
-
- setValue(tux, TuxSizeAltReq::IND_FRAGMENT,
- 2 * NO_OF_FRAG_PER_NODE * size->noOfTables * size->noOfReplicas);
-
- setValue(tux, TuxSizeAltReq::IND_ATTRIBUTE,
- size->noOfIndexes * 4);
-
- setValue(tux, TuxSizeAltReq::IND_SCAN,
- noOfLocalScanRecords);
- }
-}
-
-const ClusterConfiguration::ClusterData&
-ClusterConfiguration::clusterData() const
-{
- return the_clusterData;
-}
-
-void ClusterConfiguration::init(const Properties & p, const Properties & db){
- const char * msg = "Invalid configuration fetched";
-
- ClusterData & cd = the_clusterData;
-
- struct AttribStorage { const char * attrib; Uint32 * storage; };
- AttribStorage tmp[] = {
- {"MaxNoOfConcurrentScans", &cd.SizeAltData.noOfScanRecords },
- {"MaxNoOfTables", &cd.SizeAltData.noOfTables },
- {"MaxNoOfIndexes", &cd.SizeAltData.noOfIndexes },
- {"NoOfReplicas", &cd.SizeAltData.noOfReplicas },
- {"MaxNoOfAttributes", &cd.SizeAltData.noOfAttributes },
- {"MaxNoOfConcurrentOperations", &cd.SizeAltData.noOfOperations },
- {"MaxNoOfConcurrentTransactions", &cd.SizeAltData.noOfTransactions },
- {"NoOfIndexPages", &cd.SizeAltData.noOfIndexPages },
- {"NoOfDataPages", &cd.SizeAltData.noOfDataPages },
- {"NoOfDiskBufferPages", &cd.SizeAltData.noOfDiskBufferPages },
- {"NoOfDiskClusters", &cd.SizeAltData.noOfDiskClusters },
- {"NoOfFreeDiskClusters", &cd.SizeAltData.noOfFreeClusters },
- {"TimeToWaitAlive", &cd.ispValues[0][0] },
- {"HeartbeatIntervalDbDb", &cd.ispValues[0][2] },
- {"HeartbeatIntervalDbApi", &cd.ispValues[0][3] },
- {"ArbitrationTimeout", &cd.ispValues[0][5] },
- {"TimeBetweenLocalCheckpoints", &cd.ispValues[1][2] },
- {"NoOfFragmentLogFiles", &cd.ispValues[1][4] },
- {"MaxNoOfConcurrentScans", &cd.SizeAltData.noOfScanRecords },
- {"NoOfConcurrentCheckpointsDuringRestart", &cd.ispValues[1][5] },
- {"TransactionDeadlockDetectionTimeout", &cd.ispValues[1][6] },
- {"NoOfConcurrentProcessesHandleTakeover", &cd.ispValues[1][7] },
- {"TimeBetweenGlobalCheckpoints", &cd.ispValues[2][3] },
- {"NoOfConcurrentCheckpointsAfterRestart", &cd.ispValues[2][4] },
- {"TransactionInactiveTimeout", &cd.ispValues[2][7] },
- {"NoOfDiskPagesToDiskDuringRestartTUP", &cd.ispValues[3][8] },
- {"NoOfDiskPagesToDiskAfterRestartTUP", &cd.ispValues[3][9] },
- {"NoOfDiskPagesToDiskDuringRestartACC", &cd.ispValues[3][10] },
- {"NoOfDiskPagesToDiskAfterRestartACC", &cd.ispValues[3][11] },
- {"NoOfDiskClustersPerDiskFile", &cd.ispValues[4][8] },
- {"NoOfDiskFiles", &cd.ispValues[4][9] },
- {"NoOfReplicas", &cd.ispValues[2][2] }
- };
-
-
- const int sz = sizeof(tmp)/sizeof(AttribStorage);
- for(int i = 0; i<sz; i++){
- if(!db.get(tmp[i].attrib, tmp[i].storage)){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf), "%s not found", tmp[i].attrib);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- }
-
- if(!p.get("NoOfNodes", &cd.SizeAltData.noOfNodes)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "NoOfNodes missing");
- }
-
- Properties::Iterator it(&p);
- const char * name = 0;
- Uint32 nodeNo = 0;
- for(name = it.first(); name != NULL; name = it.next()){
- if(strncmp(name, "Node_", strlen("Node_")) == 0){
-
- Uint32 nodeId;
- const char * nodeType;
- const Properties * node;
-
- if(!p.get(name, &node)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data missing");
- }
-
- if(!node->get("Id", &nodeId)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Id) missing");
- }
-
- if(!node->get("Type", &nodeType)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Type) missing");
- }
-
- if(nodeId > MAX_NODES){
- char buf[255];
- snprintf(buf, sizeof(buf),
- "Maximum DB node id allowed is: %d", MAX_NDB_NODES);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
-
- if(nodeId == 0){
- char buf[255];
- snprintf(buf, sizeof(buf),
- "Minimum node id allowed in the cluster is: 1");
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
-
- for(unsigned j = 0; j<nodeNo; j++){
- if(cd.nodeData[j].nodeId == nodeId){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id");
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- }
-
- {
- for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
- Uint32 logLevel;
- if(db.get(LogLevel::LOGLEVEL_CATEGORY_NAME[j].name, &logLevel)){
- cd.SizeAltData.logLevel.setLogLevel((LogLevel::EventCategory)j,
- logLevel);
- }
- }
- }
-
- cd.nodeData[nodeNo].nodeId = nodeId;
- const char* tmpApiMgmProperties = 0;
- if(strcmp("DB", nodeType) == 0){
- cd.nodeData[nodeNo].nodeType = NodeInfo::DB;
- cd.SizeAltData.noOfNDBNodes++; // No of NDB processes
-
- if(nodeId > MAX_NDB_NODES){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", MAX_NDB_NODES);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- if(cd.SizeAltData.noOfNDBNodes > MAX_NDB_NODES){
- char buf[255];
- BaseString::snprintf(buf, sizeof(buf),
- "Maximum %d ndb nodes is allowed in the cluster",
- MAX_NDB_NODES);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- } else if(strcmp("API", nodeType) == 0){
- cd.nodeData[nodeNo].nodeType = NodeInfo::API;
- cd.SizeAltData.noOfAPINodes++; // No of API processes
- tmpApiMgmProperties = "API";
- } else if(strcmp("REP", nodeType) == 0){
- cd.nodeData[nodeNo].nodeType = NodeInfo::REP;
- //cd.SizeAltData.noOfAPINodes++; // No of API processes
- tmpApiMgmProperties = "REP";
- } else if(strcmp("MGM", nodeType) == 0){
- cd.nodeData[nodeNo].nodeType = NodeInfo::MGM;
- cd.SizeAltData.noOfMGMNodes++; // No of MGM processes
- tmpApiMgmProperties = "MGM";
- } else {
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
- "Invalid configuration: Unknown node type",
- nodeType);
- }
-
- if (tmpApiMgmProperties) {
- /*
- const Properties* q = 0;
-
- if (!p.get(tmpApiMgmProperties, nodeId, &q)) {
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, tmpApiMgmProperties);
- } else {
- */
- Uint32 rank = 0;
- if (node->get("ArbitrationRank", &rank) && rank > 0) {
- cd.nodeData[nodeNo].arbitRank = rank;
- // }
- }
- } else {
- cd.nodeData[nodeNo].arbitRank = 0;
- }
-
- nodeNo++;
- }
- }
- cd.SizeAltData.exist = true;
- calcSizeAlteration();
-}
-
-
diff --git a/storage/ndb/src/kernel/vm/ClusterConfiguration.hpp b/storage/ndb/src/kernel/vm/ClusterConfiguration.hpp
deleted file mode 100644
index be0930e5db4..00000000000
--- a/storage/ndb/src/kernel/vm/ClusterConfiguration.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ClusterConfiguration_H
-#define ClusterConfiguration_H
-
-#include <kernel_types.h>
-#include <ndb_limits.h>
-#include <Properties.hpp>
-#include <ErrorReporter.hpp>
-#include <signaldata/CmvmiCfgConf.hpp>
-#include <signaldata/SetLogLevelOrd.hpp>
-#include <NodeInfo.hpp>
-
-// MaxNumber of sizealteration records in each block
-// MaxNumber of blocks with sizealteration, (size of array)
-#define MAX_SIZEALT_RECORD 16
-#define MAX_SIZEALT_BLOCKS 8
-
-enum NdbBlockName { ACC = 0, DICT, DIH, LQH, TC, TUP, TUX, NDB_SIZEALT_OFF };
-// NDB_SIZEALT_OFF is used for block without sizealteration
-// IMPORTANT to assign NDB_SIZEALT_OFF as largest value
-
-struct VarSize {
- int nrr;
- bool valid;
-};
-
-struct SizeAlt {
- unsigned int noOfTables;
- unsigned int noOfIndexes;
- unsigned int noOfReplicas;
- unsigned int noOfNDBNodes;
- unsigned int noOfAPINodes;
- unsigned int noOfMGMNodes;
- unsigned int noOfNodes;
- unsigned int noOfDiskLessNodes;
- unsigned int noOfAttributes;
- unsigned int noOfOperations;
- unsigned int noOfTransactions;
- unsigned int noOfIndexPages;
- unsigned int noOfDataPages;
- unsigned int noOfDiskBufferPages;
- unsigned int noOfFreeClusters;
- unsigned int noOfDiskClusters;
- unsigned int noOfScanRecords;
- bool exist;
- VarSize varSize[MAX_SIZEALT_BLOCKS][MAX_SIZEALT_RECORD];
- unsigned short blockNo[MAX_SIZEALT_BLOCKS];
- LogLevel logLevel;
-};
-
-
-class ClusterConfiguration
-{
-public:
-
- struct NodeData {
- NodeData() {
- nodeId = MAX_NODES+1;
- nodeType = NodeInfo::INVALID;
- arbitRank = ~0;
- }
- NodeId nodeId;
- NodeInfo::NodeType nodeType;
- unsigned arbitRank;
- };
-
- struct ClusterData
- {
- SizeAlt SizeAltData;
- NodeData nodeData[MAX_NODES];
- Uint32 ispValues[5][CmvmiCfgConf::NO_OF_WORDS];
- };
-
- ClusterConfiguration();
- ~ClusterConfiguration();
- const ClusterData& clusterData() const;
-
- void init(const Properties & p, const Properties & db);
-protected:
-
-private:
-
- ClusterData the_clusterData;
-
- void calcSizeAlteration();
-
-};
-
-#endif // ClusterConfiguration_H
-
diff --git a/storage/ndb/src/kernel/vm/Configuration.cpp b/storage/ndb/src/kernel/vm/Configuration.cpp
deleted file mode 100644
index c84b068ce9c..00000000000
--- a/storage/ndb/src/kernel/vm/Configuration.cpp
+++ /dev/null
@@ -1,902 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_opts.h>
-
-#include "Configuration.hpp"
-#include <ErrorHandlingMacros.hpp>
-#include "GlobalData.hpp"
-
-#include <ConfigRetriever.hpp>
-#include <IPCConfig.hpp>
-#include <ndb_version.h>
-#include <NdbMem.h>
-#include <NdbOut.hpp>
-#include <WatchDog.hpp>
-
-#include <mgmapi_configuration.hpp>
-#include <mgmapi_config_parameters_debug.h>
-#include <kernel_config_parameters.h>
-
-#include <kernel_types.h>
-#include <ndb_limits.h>
-#include <ndbapi_limits.h>
-#include "pc.hpp"
-#include <LogLevel.hpp>
-#include <NdbSleep.h>
-
-extern "C" {
- void ndbSetOwnVersion();
-}
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-enum ndbd_options {
- OPT_INITIAL = NDB_STD_OPTIONS_LAST,
- OPT_NODAEMON,
- OPT_FOREGROUND,
- OPT_NOWAIT_NODES,
- OPT_INITIAL_START
-};
-
-NDB_STD_OPTS_VARS;
-// XXX should be my_bool ???
-static int _daemon, _no_daemon, _foreground, _initial, _no_start;
-static int _initialstart;
-static const char* _nowait_nodes = 0;
-static const char* _bind_address = 0;
-
-extern Uint32 g_start_type;
-extern NdbNodeBitmask g_nowait_nodes;
-
-const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };
-
-/**
- * Arguments to NDB process
- */
-static struct my_option my_long_options[] =
-{
- NDB_STD_OPTS("ndbd"),
- { "initial", OPT_INITIAL,
- "Perform initial start of ndbd, including cleaning the file system. "
- "Consult documentation before using this",
- &_initial, &_initial, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "nostart", 'n',
- "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
- &_no_start, &_no_start, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "daemon", 'd', "Start ndbd as daemon (default)",
- &_daemon, &_daemon, 0,
- GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
- { "nodaemon", OPT_NODAEMON,
- "Do not start ndbd as daemon, provided for testing purposes",
- &_no_daemon, &_no_daemon, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "foreground", OPT_FOREGROUND,
- "Run real ndbd in foreground, provided for debugging purposes"
- " (implies --nodaemon)",
- &_foreground, &_foreground, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "nowait-nodes", OPT_NOWAIT_NODES,
- "Nodes that will not be waited for during start",
- &_nowait_nodes, &_nowait_nodes, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "initial-start", OPT_INITIAL_START,
- "Perform initial start",
- &_initialstart, &_initialstart, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "bind-address", OPT_NOWAIT_NODES,
- "Local bind address",
- &_bind_address, &_bind_address, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-static void short_usage_sub(void)
-{
- printf("Usage: %s [OPTIONS]\n", my_progname);
-}
-static void usage()
-{
- short_usage_sub();
- ndb_std_print_version();
- print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
- puts("");
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
-
-bool
-Configuration::init(int argc, char** argv)
-{
- load_defaults("my",load_default_groups,&argc,&argv);
-
- int ho_error;
-#ifndef DBUG_OFF
- opt_debug= "d:t:O,/tmp/ndbd.trace";
-#endif
- if ((ho_error=handle_options(&argc, &argv, my_long_options,
- ndb_std_get_one_option)))
- exit(ho_error);
-
- if (_no_daemon || _foreground) {
- _daemon= 0;
- }
-
- DBUG_PRINT("info", ("no_start=%d", _no_start));
- DBUG_PRINT("info", ("initial=%d", _initial));
- DBUG_PRINT("info", ("daemon=%d", _daemon));
- DBUG_PRINT("info", ("foreground=%d", _foreground));
- DBUG_PRINT("info", ("connect_str=%s", opt_connect_str));
-
- ndbSetOwnVersion();
-
- // Check the start flag
- if (_no_start)
- globalData.theRestartFlag = initial_state;
- else
- globalData.theRestartFlag = perform_start;
-
- // Check the initial flag
- if (_initial)
- _initialStart = true;
-
- // Check connectstring
- if (opt_connect_str)
- _connectString = strdup(opt_connect_str);
-
- // Check daemon flag
- if (_daemon)
- _daemonMode = true;
- if (_foreground)
- _foregroundMode = true;
-
- // Save programname
- if(argc > 0 && argv[0] != 0)
- _programName = strdup(argv[0]);
- else
- _programName = strdup("");
-
- globalData.ownId= 0;
-
- if (_nowait_nodes)
- {
- BaseString str(_nowait_nodes);
- Vector<BaseString> arr;
- str.split(arr, ",");
- for (Uint32 i = 0; i<arr.size(); i++)
- {
- char *endptr = 0;
- long val = strtol(arr[i].c_str(), &endptr, 10);
- if (*endptr)
- {
- ndbout_c("Unable to parse nowait-nodes argument: %s : %s",
- arr[i].c_str(), _nowait_nodes);
- exit(-1);
- }
- if (! (val > 0 && val < MAX_NDB_NODES))
- {
- ndbout_c("Invalid nodeid specified in nowait-nodes: %ld : %s",
- val, _nowait_nodes);
- exit(-1);
- }
- g_nowait_nodes.set(val);
- }
- }
-
- if (_initialstart)
- {
- _initialStart = true;
- g_start_type |= (1 << NodeState::ST_INITIAL_START);
- }
-
- return true;
-}
-
-Configuration::Configuration()
-{
- _programName = 0;
- _connectString = 0;
- _fsPath = 0;
- _backupPath = 0;
- _initialStart = false;
- _daemonMode = false;
- _foregroundMode = false;
- m_config_retriever= 0;
- m_clusterConfig= 0;
- m_clusterConfigIter= 0;
- m_logLevel= 0;
-}
-
-Configuration::~Configuration(){
- if (opt_connect_str)
- free(_connectString);
-
- if(_programName != NULL)
- free(_programName);
-
- if(_fsPath != NULL)
- free(_fsPath);
-
- if(_backupPath != NULL)
- free(_backupPath);
-
- if (m_config_retriever) {
- delete m_config_retriever;
- }
-
- if(m_logLevel) {
- delete m_logLevel;
- }
-}
-
-void
-Configuration::closeConfiguration(bool end_session){
- m_config_retriever->end_session(end_session);
- if (m_config_retriever) {
- delete m_config_retriever;
- }
- m_config_retriever= 0;
-}
-
-void
-Configuration::fetch_configuration(){
- /**
- * Fetch configuration from management server
- */
- if (m_config_retriever) {
- delete m_config_retriever;
- }
-
- m_mgmd_port= 0;
- m_config_retriever= new ConfigRetriever(getConnectString(),
- NDB_VERSION,
- NODE_TYPE_DB,
- _bind_address);
-
- if (m_config_retriever->hasError())
- {
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
- "Could not connect initialize handle to management server",
- m_config_retriever->getErrorString());
- }
-
- if(m_config_retriever->do_connect(12,5,1) == -1){
- const char * s = m_config_retriever->getErrorString();
- if(s == 0)
- s = "No error given!";
- /* Set stop on error to true otherwise NDB will
- go into an restart loop...
- */
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not connect to ndb_mgmd", s);
- }
-
- m_mgmd_port= m_config_retriever->get_mgmd_port();
- m_mgmd_host.assign(m_config_retriever->get_mgmd_host());
-
- ConfigRetriever &cr= *m_config_retriever;
-
- /**
- * if we have a nodeid set (e.g in a restart situation)
- * reuse it
- */
- if (globalData.ownId)
- cr.setNodeId(globalData.ownId);
-
- globalData.ownId = cr.allocNodeId(globalData.ownId ? 10 : 2 /*retry*/,
- 3 /*delay*/);
-
- if(globalData.ownId == 0){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
- "Unable to alloc node id", m_config_retriever->getErrorString());
- }
-
- ndb_mgm_configuration * p = cr.getConfig();
- if(p == 0){
- const char * s = cr.getErrorString();
- if(s == 0)
- s = "No error given!";
-
- /* Set stop on error to true otherwise NDB will
- go into an restart loop...
- */
-
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not fetch configuration"
- "/invalid configuration", s);
- }
- if(m_clusterConfig)
- free(m_clusterConfig);
-
- m_clusterConfig = p;
-
- ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
- if (iter.find(CFG_NODE_ID, globalData.ownId)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
- }
-
- if(iter.get(CFG_DB_STOP_ON_ERROR, &_stopOnError)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "StopOnError missing");
- }
-
- m_mgmds.clear();
- for(ndb_mgm_first(&iter); ndb_mgm_valid(&iter); ndb_mgm_next(&iter))
- {
- Uint32 nodeType, port;
- char const *hostname;
-
- ndb_mgm_get_int_parameter(&iter,CFG_TYPE_OF_SECTION,&nodeType);
-
- if (nodeType != NodeInfo::MGM)
- continue;
-
- if (ndb_mgm_get_string_parameter(&iter,CFG_NODE_HOST, &hostname) ||
- ndb_mgm_get_int_parameter(&iter,CFG_MGM_PORT, &port) ||
- hostname == 0 || hostname[0] == 0)
- {
- continue;
- }
- BaseString connectstring(hostname);
- connectstring.appfmt(":%d", port);
-
- m_mgmds.push_back(connectstring);
- }
-}
-
-static char * get_and_validate_path(ndb_mgm_configuration_iterator &iter,
- Uint32 param, const char *param_string)
-{
- const char* path = NULL;
- if(iter.get(param, &path)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched missing ",
- param_string);
- }
-
- if(path == 0 || strlen(path) == 0){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
- "Invalid configuration fetched. Configuration does not contain valid ",
- param_string);
- }
-
- // check that it is pointing on a valid directory
- //
- char buf2[PATH_MAX];
- memset(buf2, 0,sizeof(buf2));
-#ifdef NDB_WIN32
- char* szFilePart;
- if(!GetFullPathName(path, sizeof(buf2), buf2, &szFilePart) ||
- (GetFileAttributes(buf2) & FILE_ATTRIBUTE_READONLY))
-#else
- if((::realpath(path, buf2) == NULL)||
- (::access(buf2, W_OK) != 0))
-#endif
- {
- ERROR_SET(fatal, NDBD_EXIT_AFS_INVALIDPATH, path, param_string);
- }
-
- if (strcmp(&buf2[strlen(buf2) - 1], DIR_SEPARATOR))
- strcat(buf2, DIR_SEPARATOR);
-
- return strdup(buf2);
-}
-
-void
-Configuration::setupConfiguration(){
-
- DBUG_ENTER("Configuration::setupConfiguration");
-
- ndb_mgm_configuration * p = m_clusterConfig;
-
- /**
- * Configure transporters
- */
- {
- int res = IPCConfig::configureTransporters(globalData.ownId,
- * p,
- globalTransporterRegistry);
- if(res <= 0){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "No transporters configured");
- }
- }
-
- /**
- * Setup cluster configuration data
- */
- ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
- if (iter.find(CFG_NODE_ID, globalData.ownId)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
- }
-
- unsigned type;
- if(!(iter.get(CFG_TYPE_OF_SECTION, &type) == 0 && type == NODE_TYPE_DB)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "I'm wrong type of node");
- }
-
- if(iter.get(CFG_DB_NO_SAVE_MSGS, &_maxErrorLogs)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "MaxNoOfSavedMessages missing");
- }
-
- if(iter.get(CFG_DB_MEMLOCK, &_lockPagesInMainMemory)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "LockPagesInMainMemory missing");
- }
-
- if(iter.get(CFG_DB_WATCHDOG_INTERVAL, &_timeBetweenWatchDogCheck)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "TimeBetweenWatchDogCheck missing");
- }
-
- if(iter.get(CFG_DB_WATCHDOG_INTERVAL_INITIAL, &_timeBetweenWatchDogCheckInitial)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "TimeBetweenWatchDogCheckInitial missing");
- }
-
- /**
- * Get paths
- */
- if (_fsPath)
- free(_fsPath);
- _fsPath= get_and_validate_path(iter, CFG_DB_FILESYSTEM_PATH, "FileSystemPath");
- if (_backupPath)
- free(_backupPath);
- _backupPath= get_and_validate_path(iter, CFG_DB_BACKUP_DATADIR, "BackupDataDir");
-
- if(iter.get(CFG_DB_STOP_ON_ERROR_INSERT, &m_restartOnErrorInsert)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
- "RestartOnErrorInsert missing");
- }
-
- /**
- * Create the watch dog thread
- */
- {
- if (_timeBetweenWatchDogCheckInitial < _timeBetweenWatchDogCheck)
- _timeBetweenWatchDogCheckInitial = _timeBetweenWatchDogCheck;
-
- Uint32 t = _timeBetweenWatchDogCheckInitial;
- t = globalEmulatorData.theWatchDog ->setCheckInterval(t);
- _timeBetweenWatchDogCheckInitial = t;
- }
-
- ConfigValues* cf = ConfigValuesFactory::extractCurrentSection(iter.m_config);
-
- if(m_clusterConfigIter)
- ndb_mgm_destroy_iterator(m_clusterConfigIter);
- m_clusterConfigIter = ndb_mgm_create_configuration_iterator
- (p, CFG_SECTION_NODE);
-
- calcSizeAlt(cf);
-
- DBUG_VOID_RETURN;
-}
-
-Uint32
-Configuration::lockPagesInMainMemory() const {
- return _lockPagesInMainMemory;
-}
-
-int
-Configuration::timeBetweenWatchDogCheck() const {
- return _timeBetweenWatchDogCheck;
-}
-
-void
-Configuration::timeBetweenWatchDogCheck(int value) {
- _timeBetweenWatchDogCheck = value;
-}
-
-int
-Configuration::maxNoOfErrorLogs() const {
- return _maxErrorLogs;
-}
-
-void
-Configuration::maxNoOfErrorLogs(int val){
- _maxErrorLogs = val;
-}
-
-bool
-Configuration::stopOnError() const {
- return _stopOnError;
-}
-
-void
-Configuration::stopOnError(bool val){
- _stopOnError = val;
-}
-
-int
-Configuration::getRestartOnErrorInsert() const {
- return m_restartOnErrorInsert;
-}
-
-void
-Configuration::setRestartOnErrorInsert(int i){
- m_restartOnErrorInsert = i;
-}
-
-const char *
-Configuration::getConnectString() const {
- return _connectString;
-}
-
-char *
-Configuration::getConnectStringCopy() const {
- if(_connectString != 0)
- return strdup(_connectString);
- 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 noOfUniqueHashIndexes = 0;
- unsigned int noOfOrderedIndexes = 0;
- unsigned int noOfTriggers = 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 noOfLocalOperations = 0;
- unsigned int noOfTransactions = 0;
- unsigned int noOfIndexPages = 0;
- unsigned int noOfDataPages = 0;
- unsigned int noOfScanRecords = 0;
- unsigned int noOfLocalScanRecords = 0;
- unsigned int noBatchSize = 0;
- m_logLevel = new LogLevel();
-
- struct AttribStorage { int paramId; Uint32 * storage; bool computable; };
- AttribStorage tmp[] = {
- { CFG_DB_NO_SCANS, &noOfScanRecords, false },
- { CFG_DB_NO_LOCAL_SCANS, &noOfLocalScanRecords, true },
- { CFG_DB_BATCH_SIZE, &noBatchSize, false },
- { CFG_DB_NO_TABLES, &noOfTables, false },
- { CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false },
- { CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false },
- { CFG_DB_NO_TRIGGERS, &noOfTriggers, true },
- { CFG_DB_NO_REPLICAS, &noOfReplicas, false },
- { CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false },
- { CFG_DB_NO_OPS, &noOfOperations, false },
- { CFG_DB_NO_LOCAL_OPS, &noOfLocalOperations, true },
- { CFG_DB_NO_TRANSACTIONS, &noOfTransactions, false }
- };
-
- 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)){
- if (tmp[i].computable) {
- *tmp[i].storage = 0;
- } else {
- BaseString::snprintf(buf, sizeof(buf),"ConfigParam: %d not found", tmp[i].paramId);
- ERROR_SET(fatal, NDBD_EXIT_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){
- BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
-
- if(indexMem == 0){
- BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
-
- noOfDataPages = (dataMem / 32768);
- noOfIndexPages = (indexMem / 8192);
-
- for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
- Uint32 tmp;
- if(!ndb_mgm_get_int_parameter(&db, CFG_MIN_LOGLEVEL+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, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Id) missing");
- }
-
- if(ndb_mgm_get_int_parameter(p, CFG_TYPE_OF_SECTION, &nodeType)){
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Type) missing");
- }
-
- if(nodeId > MAX_NODES || nodeId == 0){
- BaseString::snprintf(buf, sizeof(buf),
- "Invalid node id: %d", nodeId);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
-
- if(nodes.get(nodeId)){
- BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d",
- nodeId);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- nodes.set(nodeId);
-
- switch(nodeType){
- case NODE_TYPE_DB:
- noOfDBNodes++; // No of NDB processes
-
- if(nodeId > MAX_NDB_NODES){
- BaseString::snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d",
- MAX_NDB_NODES);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- break;
- case NODE_TYPE_API:
- noOfAPINodes++; // No of API processes
- break;
- case NODE_TYPE_MGM:
- noOfMGMNodes++; // No of MGM processes
- break;
- default:
- BaseString::snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType);
- ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
- }
- }
- noOfNodes = nodeNo;
-
- noOfTables+= 2; // Add System tables
- noOfAttributes += 9; // Add System table attributes
-
- ConfigValues::Iterator it2(*ownConfig, db.m_config);
- it2.set(CFG_DB_NO_TABLES, noOfTables);
- it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes);
- {
- Uint32 neededNoOfTriggers = /* types: Insert/Update/Delete/Custom */
- 3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */
- 3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */
- 3 * noOfTables + /* for backup, I/U/D */
- noOfOrderedIndexes; /* for ordered indexes, C */
- if (noOfTriggers < neededNoOfTriggers)
- {
- noOfTriggers= neededNoOfTriggers;
- it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers);
- }
- }
-
- /**
- * Do size calculations
- */
- ConfigValuesFactory cfg(ownConfig);
-
- Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
- noOfUniqueHashIndexes;
- Uint32 noOfMetaTablesDict= noOfMetaTables;
- if (noOfMetaTablesDict > MAX_TABLES)
- noOfMetaTablesDict= MAX_TABLES;
-
- {
- /**
- * Dict Size Alt values
- */
- cfg.put(CFG_DICT_ATTRIBUTE,
- noOfAttributes);
-
- cfg.put(CFG_DICT_TABLE,
- noOfMetaTablesDict);
- }
-
-
- if (noOfLocalScanRecords == 0) {
- noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1;
- }
- if (noOfLocalOperations == 0) {
- noOfLocalOperations= (11 * noOfOperations) / 10;
- }
- Uint32 noOfTCScanRecords = noOfScanRecords;
-
- {
- Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/;
- /**
- * Acc Size Alt values
- */
- // Can keep 65536 pages (= 0.5 GByte)
- cfg.put(CFG_ACC_DIR_RANGE,
- 2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
-
- cfg.put(CFG_ACC_DIR_ARRAY,
- (noOfIndexPages >> 8) +
- 2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
-
- cfg.put(CFG_ACC_FRAGMENT,
- NO_OF_FRAG_PER_NODE * noOfAccTables* 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,
- (noOfLocalOperations + 50) +
- (noOfLocalScanRecords * noBatchSize) +
- NODE_RECOVERY_SCAN_OP_RECORDS);
-
- cfg.put(CFG_ACC_OVERFLOW_RECS,
- noOfIndexPages +
- NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
-
- cfg.put(CFG_ACC_PAGE8,
- noOfIndexPages + 32);
-
- cfg.put(CFG_ACC_TABLE, noOfAccTables);
-
- cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords);
- }
-
- {
- /**
- * Dih Size Alt values
- */
- cfg.put(CFG_DIH_API_CONNECT,
- 2 * noOfTransactions);
-
- cfg.put(CFG_DIH_CONNECT,
- noOfOperations + noOfTransactions + 46);
-
- Uint32 noFragPerTable= ((noOfDBNodes + NO_OF_FRAGS_PER_CHUNK - 1) >>
- LOG_NO_OF_FRAGS_PER_CHUNK) <<
- LOG_NO_OF_FRAGS_PER_CHUNK;
-
- cfg.put(CFG_DIH_FRAG_CONNECT,
- noFragPerTable * noOfMetaTables);
-
- int temp;
- temp = noOfReplicas - 2;
- if (temp < 0)
- temp = 1;
- else
- temp++;
- cfg.put(CFG_DIH_MORE_NODES,
- temp * NO_OF_FRAG_PER_NODE *
- noOfMetaTables * noOfDBNodes);
-
- cfg.put(CFG_DIH_REPLICAS,
- NO_OF_FRAG_PER_NODE * noOfMetaTables *
- noOfDBNodes * noOfReplicas);
-
- cfg.put(CFG_DIH_TABLE,
- noOfMetaTables);
- }
-
- {
- /**
- * Lqh Size Alt values
- */
- cfg.put(CFG_LQH_FRAG,
- NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas);
-
- cfg.put(CFG_LQH_TABLE,
- noOfMetaTables);
-
- cfg.put(CFG_LQH_TC_CONNECT,
- noOfLocalOperations + 50);
-
- cfg.put(CFG_LQH_SCAN,
- noOfLocalScanRecords);
- }
-
- {
- /**
- * Tc Size Alt values
- */
- cfg.put(CFG_TC_API_CONNECT,
- 3 * noOfTransactions);
-
- cfg.put(CFG_TC_TC_CONNECT,
- (2 * noOfOperations) + 16 + noOfTransactions);
-
- cfg.put(CFG_TC_TABLE,
- noOfMetaTables);
-
- cfg.put(CFG_TC_LOCAL_SCAN,
- noOfLocalScanRecords);
-
- cfg.put(CFG_TC_SCAN,
- noOfTCScanRecords);
- }
-
- {
- /**
- * Tup Size Alt values
- */
- cfg.put(CFG_TUP_FRAG,
- NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
-
- cfg.put(CFG_TUP_OP_RECS,
- noOfLocalOperations + 50);
-
- cfg.put(CFG_TUP_PAGE,
- noOfDataPages);
-
- cfg.put(CFG_TUP_PAGE_RANGE,
- 2 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
-
- cfg.put(CFG_TUP_TABLE,
- noOfMetaTables);
-
- cfg.put(CFG_TUP_TABLE_DESC,
- 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
- 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
-
- cfg.put(CFG_TUP_STORED_PROC,
- noOfLocalScanRecords);
- }
-
- {
- /**
- * Tux Size Alt values
- */
- cfg.put(CFG_TUX_INDEX,
- noOfMetaTables /*noOfOrderedIndexes*/);
-
- cfg.put(CFG_TUX_FRAGMENT,
- NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
-
- cfg.put(CFG_TUX_ATTRIBUTE,
- noOfOrderedIndexes * 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/storage/ndb/src/kernel/vm/Configuration.hpp b/storage/ndb/src/kernel/vm/Configuration.hpp
deleted file mode 100644
index 9aefbf9c248..00000000000
--- a/storage/ndb/src/kernel/vm/Configuration.hpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Configuration_H
-#define Configuration_H
-
-#include <util/BaseString.hpp>
-#include <mgmapi.h>
-#include <ndb_types.h>
-
-class ConfigRetriever;
-
-class Configuration {
-public:
- Configuration();
- ~Configuration();
-
- /**
- * Returns false if arguments are invalid
- */
- bool init(int argc, char** argv);
-
- void fetch_configuration();
- void setupConfiguration();
- void closeConfiguration(bool end_session= true);
-
- Uint32 lockPagesInMainMemory() const;
-
- int timeBetweenWatchDogCheck() const ;
- void timeBetweenWatchDogCheck(int value);
-
- int maxNoOfErrorLogs() const ;
- void maxNoOfErrorLogs(int val);
-
- bool stopOnError() const;
- void stopOnError(bool val);
-
- int getRestartOnErrorInsert() const;
- void setRestartOnErrorInsert(int);
-
- // Cluster configuration
- const char * programName() const;
- const char * fileSystemPath() const;
- const char * backupFilePath() const;
- const char * getConnectString() const;
- char * getConnectStringCopy() const;
-
- /**
- *
- */
- bool getInitialStart() const;
- void setInitialStart(bool val);
- bool getDaemonMode() const;
- bool getForegroundMode() const;
-
- const ndb_mgm_configuration_iterator * getOwnConfigIterator() const;
-
- Uint32 get_mgmd_port() const {return m_mgmd_port;};
- const char *get_mgmd_host() const {return m_mgmd_host.c_str();};
- ConfigRetriever* get_config_retriever() { return m_config_retriever; };
-
- class LogLevel * m_logLevel;
-private:
- friend class Cmvmi;
- friend class Qmgr;
- friend int reportShutdown(class Configuration *config, int error, int restart);
-
- ndb_mgm_configuration_iterator * getClusterConfigIterator() const;
-
- Uint32 _stopOnError;
- Uint32 m_restartOnErrorInsert;
- Uint32 _maxErrorLogs;
- Uint32 _lockPagesInMainMemory;
- Uint32 _timeBetweenWatchDogCheck;
- Uint32 _timeBetweenWatchDogCheckInitial;
-
- ndb_mgm_configuration * m_ownConfig;
- ndb_mgm_configuration * m_clusterConfig;
-
- ndb_mgm_configuration_iterator * m_clusterConfigIter;
- ndb_mgm_configuration_iterator * m_ownConfigIterator;
-
- ConfigRetriever *m_config_retriever;
-
- Vector<BaseString> m_mgmds;
-
- /**
- * arguments to NDB process
- */
- char * _programName;
- char * _fsPath;
- char * _backupPath;
- bool _initialStart;
- char * _connectString;
- Uint32 m_mgmd_port;
- BaseString m_mgmd_host;
- bool _daemonMode; // if not, angel in foreground
- bool _foregroundMode; // no angel, raw ndbd in foreground
-
- void calcSizeAlt(class ConfigValues * );
-};
-
-inline
-const char *
-Configuration::programName() const {
- return _programName;
-}
-
-inline
-const char *
-Configuration::fileSystemPath() const {
- return _fsPath;
-}
-
-inline
-const char *
-Configuration::backupFilePath() const {
- return _backupPath;
-}
-
-inline
-bool
-Configuration::getInitialStart() const {
- return _initialStart;
-}
-
-inline
-bool
-Configuration::getDaemonMode() const {
- return _daemonMode;
-}
-
-inline
-bool
-Configuration::getForegroundMode() const {
- return _foregroundMode;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLCFifoList.hpp b/storage/ndb/src/kernel/vm/DLCFifoList.hpp
deleted file mode 100644
index ad449c08f4a..00000000000
--- a/storage/ndb/src/kernel/vm/DLCFifoList.hpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DLC_FIFOLIST_HPP
-#define DLC_FIFOLIST_HPP
-
-#include "DLFifoList.hpp"
-#include <NdbOut.hpp>
-
-// Adds "count" to DLFifoList
-template <class T, class U = T>
-class DLCFifoList : public DLFifoList<T, U> {
-public:
- // List head
- struct Head : public DLFifoList<T, U>::Head {
- Head() : m_count(0) {}
- Uint32 m_count;
- };
-
- // Ctor
- DLCFifoList(ArrayPool<T> & thePool) :
- DLFifoList<T, U>(thePool)
- {}
-
- // Get count
- Uint32 count() const { return head.m_count; }
-
- // Redefine methods which do add or remove
-
- bool seize(Ptr<T>& ptr) {
- if (DLFifoList<T, U>::seize(ptr)) {
- head.m_count++;
- return true;
- }
- return false;
- }
-
- bool seizeId(Ptr<T>& ptr, Uint32 i) {
- if (DLFifoList<T, U>::seizeId(ptr)) {
- head.m_count++;
- return true;
- }
- return false;
- }
-
- void add(Ptr<T>& ptr) {
- DLFifoList<T, U>::add(ptr);
- head.m_count++;
- }
-
- void remove(Ptr<T>& ptr) {
- DLFifoList<T, U>::remove(ptr);
- head.m_count--;
- }
-
- void release(Uint32 i) {
- DLFifoList<T, U>::release(i);
- head.m_count--;
- }
-
- void release(Ptr<T>& ptr) {
- DLFifoList<T, U>::release(ptr);
- head.m_count--;
- }
-
- void release() {
- DLFifoList<T, U>::release();
- head.m_count = 0;
- }
-
- DLCFifoList<T>& operator=(const DLCFifoList<T>& src){
- assert(&this->thePool == &src.thePool);
- this->head = src.head;
- return * this;
- }
-
-protected:
- Head head;
-};
-
-// Local variant
-template <class T, class U = T>
-class LocalDLCFifoList : public DLCFifoList<T, U> {
-public:
- LocalDLCFifoList(ArrayPool<T> & thePool,
- typename DLCFifoList<T, U>::Head &_src)
- : DLCFifoList<T, U>(thePool), src(_src)
- {
- this->head = src;
-#ifdef VM_TRACE
- assert(src.in_use == false);
- src.in_use = true;
-#endif
- }
-
- ~LocalDLCFifoList() {
-#ifdef VM_TRACE
- assert(src.in_use == true);
-#endif
- src = this->head;
- }
-private:
- typename DLCFifoList<T, U>::Head & src;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLCHashTable.hpp b/storage/ndb/src/kernel/vm/DLCHashTable.hpp
deleted file mode 100644
index fb224f2bd4c..00000000000
--- a/storage/ndb/src/kernel/vm/DLCHashTable.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DLC_HASHTABLE_HPP
-#define DLC_HASHTABLE_HPP
-
-#include <ndb_global.h>
-#include "DLHashTable.hpp"
-
-// Adds "count" to DLHashTable
-template <class T, class U = T>
-class DLCHashTable : public DLHashTable<T, U> {
-public:
- // Ctor
- DLCHashTable(ArrayPool<T> & thePool) :
- DLHashTable<T, U>(thePool),
- m_count(0)
- {}
-
- // Get count
- Uint32 count() const { return m_count; }
-
- // Redefine methods which do add or remove
-
- void add(Ptr<T>& ptr) {
- DLHashTable<T, U>::add(ptr);
- m_count++;
- }
-
- void remove(Ptr<T>& ptr, const T & key) {
- DLHashTable<T, U>::remove(ptr, key);
- m_count--;
- }
-
- void remove(Uint32 i) {
- DLHashTable<T, U>::remove(i);
- m_count--;
- }
-
- void remove(Ptr<T>& ptr) {
- DLHashTable<T, U>::remove(ptr);
- m_count--;
- }
-
- void removeAll() {
- DLHashTable<T, U>::removeAll();
- m_count = 0;
- }
-
- void release(Ptr<T>& ptr, const T & key) {
- DLHashTable<T, U>::release(ptr, key);
- m_count--;
- }
-
- void release(Uint32 i) {
- DLHashTable<T, U>::release(i);
- m_count--;
- }
-
- void release(Ptr<T>& ptr) {
- DLHashTable<T, U>::release(ptr);
- m_count--;
- }
-
-private:
- Uint32 m_count;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLFifoList.hpp b/storage/ndb/src/kernel/vm/DLFifoList.hpp
deleted file mode 100644
index b78df5126c5..00000000000
--- a/storage/ndb/src/kernel/vm/DLFifoList.hpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DLFIFOLIST_HPP
-#define DLFIFOLIST_HPP
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-#include "Pool.hpp"
-
-/**
- * Template class used for implementing an
- * list of object retreived from a pool
- */
-template <typename P, typename T, typename U = T>
-class DLFifoListImpl
-{
-public:
- /**
- * List head
- */
- struct Head
- {
- Head();
- Uint32 firstItem;
- Uint32 lastItem;
-
-#ifdef VM_TRACE
- bool in_use;
-#endif
-
- inline bool isEmpty() const { return firstItem == RNIL;}
- };
-
- DLFifoListImpl(P & thePool);
-
- bool seizeFirst(Ptr<T> &);
- bool seizeLast(Ptr<T> &);
- bool seize(Ptr<T> & ptr) { return seizeLast(ptr);}
-
- void release(Ptr<T> &);
- void release(); // release all
-
- void addFirst(Ptr<T> &);
- void addLast(Ptr<T> &);
- void add(Ptr<T> & ptr) { addLast(ptr);}
-
- /**
- * Insert object <em>ptr</ptr> _before_ <em>loc</em>
- */
- void insert(Ptr<T> & ptr, Ptr<T>& loc);
-
- void remove();
- void remove(Ptr<T> &);
- void remove(T*);
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const ;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const ;
-
- /**
- * Update ptr to first element in list
- *
- * Return i
- */
- bool first(Ptr<T> &) const ;
-
- /**
- * Update ptr to first element in list
- *
- * Return i
- */
- bool last(Ptr<T> &) const ;
-
- /**
- * Get next element
- *
- * NOTE ptr must be both p & i
- */
- bool next(Ptr<T> &) const ;
-
- /**
- * Get next element
- *
- * NOTE ptr must be both p & i
- */
- bool prev(Ptr<T> &) const ;
-
- /**
- * Check if next exists i.e. this is not last
- *
- * NOTE ptr must be both p & i
- */
- bool hasNext(const Ptr<T> &) const;
-
- /**
- * Check if next exists i.e. this is not last
- *
- * NOTE ptr must be both p & i
- */
- bool hasPrev(const Ptr<T> &) const;
-
- inline bool isEmpty() const { return head.firstItem == RNIL;}
-
- /**
- * Copy list (head)
- * Will construct to identical lists
- */
- DLFifoListImpl<P,T,U>& operator=(const DLFifoListImpl<P,T,U>& src){
- assert(&thePool == &src.thePool);
- this->head = src.head;
- return * this;
- }
-
-protected:
- Head head;
- P & thePool;
-};
-
-template <typename P, typename T, typename U = T>
-class LocalDLFifoListImpl : public DLFifoListImpl<P,T,U>
-{
-public:
- LocalDLFifoListImpl(P & thePool, typename DLFifoListImpl<P,T,U>::Head &_src)
- : DLFifoListImpl<P,T,U>(thePool), src(_src)
- {
- this->head = src;
-#ifdef VM_TRACE
- assert(src.in_use == false);
- src.in_use = true;
-#endif
- }
-
- ~LocalDLFifoListImpl(){
-#ifdef VM_TRACE
- assert(src.in_use == true);
-#endif
- src = this->head;
- }
-private:
- typename DLFifoListImpl<P,T,U>::Head & src;
-};
-
-template <typename P, typename T, typename U>
-inline
-DLFifoListImpl<P,T,U>::DLFifoListImpl(P & _pool):
- thePool(_pool)
-{
-}
-
-template <typename P, typename T, typename U>
-inline
-DLFifoListImpl<P,T,U>::Head::Head()
-{
- firstItem = RNIL;
- lastItem = RNIL;
-#ifdef VM_TRACE
- in_use = false;
-#endif
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::seizeFirst(Ptr<T> & p)
-{
- if (likely(thePool.seize(p)))
- {
- addFirst(p);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::seizeLast(Ptr<T> & p)
-{
- if (likely(thePool.seize(p)))
- {
- addLast(p);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::addFirst(Ptr<T> & p)
-{
- Uint32 ff = head.firstItem;
-
- p.p->U::prevList = RNIL;
- p.p->U::nextList = ff;
- head.firstItem = p.i;
- if (ff == RNIL)
- {
- head.lastItem = p.i;
- }
- else
- {
- T * t2 = thePool.getPtr(ff);
- t2->U::prevList = p.i;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::addLast(Ptr<T> & p)
-{
- T * t = p.p;
- Uint32 last = head.lastItem;
- head.lastItem = p.i;
-
- t->U::nextList = RNIL;
- t->U::prevList = last;
-
- if(last != RNIL)
- {
- T * t2 = thePool.getPtr(last);
- t2->U::nextList = p.i;
- }
- else
- {
- head.firstItem = p.i;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::insert(Ptr<T> & ptr, Ptr<T> & loc)
-{
- Uint32 prev= loc.p->U::prevList;
- if(loc.i == head.firstItem)
- {
- head.firstItem = ptr.i;
- assert(prev == RNIL);
- }
- else
- {
- T* t2 = thePool.getPtr(prev);
- t2->U::nextList = ptr.i;
- }
-
- loc.p->U::prevList = ptr.i;
- ptr.p->U::prevList = prev;
- ptr.p->U::nextList = loc.i;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::remove()
-{
- head.firstItem = RNIL;
- head.lastItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::remove(Ptr<T> & p)
-{
- remove(p.p);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::remove(T * t)
-{
- Uint32 ni = t->U::nextList;
- Uint32 pi = t->U::prevList;
-
- if(ni != RNIL)
- {
- T * t = thePool.getPtr(ni);
- t->U::prevList = pi;
- }
- else
- {
- // We are releasing last
- head.lastItem = pi;
- }
-
- if(pi != RNIL)
- {
- T * t = thePool.getPtr(pi);
- t->U::nextList = ni;
- }
- else
- {
- // We are releasing first
- head.firstItem = ni;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::release()
-{
- Ptr<T> ptr;
- Uint32 curr = head.firstItem;
- while(curr != RNIL)
- {
- thePool.getPtr(ptr, curr);
- curr = ptr.p->U::nextList;
- thePool.release(ptr);
- }
- head.firstItem = RNIL;
- head.lastItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::release(Ptr<T> & p)
-{
- remove(p.p);
- thePool.release(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
-{
- p.i = i;
- p.p = thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p) const
-{
- thePool.getPtr(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-T *
-DLFifoListImpl<P,T,U>::getPtr(Uint32 i) const
-{
- return thePool.getPtr(i);
-}
-
-/**
- * Update ptr to first element in list
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::first(Ptr<T> & p) const
-{
- p.i = head.firstItem;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::last(Ptr<T> & p) const
-{
- p.i = head.lastItem;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::next(Ptr<T> & p) const
-{
- p.i = p.p->U::nextList;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::prev(Ptr<T> & p) const
-{
- p.i = p.p->U::prevList;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
-{
- return p.p->U::nextList != RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLFifoListImpl<P,T,U>::hasPrev(const Ptr<T> & p) const
-{
- return p.p->U::prevList != RNIL;
-}
-
-// Specializations
-
-template <typename T, typename U = T>
-class DLFifoList : public DLFifoListImpl<ArrayPool<T>, T, U>
-{
-public:
- DLFifoList(ArrayPool<T> & p) : DLFifoListImpl<ArrayPool<T>, T, U>(p) {}
-};
-
-template <typename T, typename U = T>
-class LocalDLFifoList : public LocalDLFifoListImpl<ArrayPool<T>,T,U> {
-public:
- LocalDLFifoList(ArrayPool<T> & p, typename DLFifoList<T,U>::Head & _src)
- : LocalDLFifoListImpl<ArrayPool<T>,T,U>(p, _src) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLHashTable.hpp b/storage/ndb/src/kernel/vm/DLHashTable.hpp
deleted file mode 100644
index 1accadc1749..00000000000
--- a/storage/ndb/src/kernel/vm/DLHashTable.hpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DL_HASHTABLE_HPP
-#define DL_HASHTABLE_HPP
-
-#include <ndb_global.h>
-#include "ArrayPool.hpp"
-
-/**
- * DLHashTable implements a hashtable using chaining
- * (with a double linked list)
- *
- * The entries in the hashtable must have the following methods:
- * -# bool equal(const class T &) const;
- * Which should return equal if the to objects have the same key
- * -# Uint32 hashValue() const;
- * Which should return a 32 bit hashvalue
- */
-template <typename P, typename T, typename U = T>
-class DLHashTableImpl
-{
-public:
- DLHashTableImpl(P & thePool);
- ~DLHashTableImpl();
-
- /**
- * Set the no of bucket in the hashtable
- *
- * Note, can currently only be called once
- */
- bool setSize(Uint32 noOfElements);
-
- /**
- * Seize element from pool - return i
- *
- * Note *must* be added using <b>add</b> (even before hash.release)
- * or be released using pool
- */
- bool seize(Ptr<T> &);
-
- /**
- * Add an object to the hashtable
- */
- void add(Ptr<T> &);
-
- /**
- * Find element key in hashtable update Ptr (i & p)
- * (using key.equal(...))
- * @return true if found and false otherwise
- */
- bool find(Ptr<T> &, const T & key) const;
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Get element using ptr.i (update ptr.p)
- */
- void getPtr(Ptr<T> &) const;
-
- /**
- * Get P value for i
- */
- T * getPtr(Uint32 i) const;
-
- /**
- * Remove element (and set Ptr to removed element)
- * Note does not return to pool
- */
- void remove(Ptr<T> &, const T & key);
-
- /**
- * Remove element
- * Note does not return to pool
- */
- void remove(Uint32 i);
-
- /**
- * Remove element
- * Note does not return to pool
- */
- void remove(Ptr<T> &);
-
- /**
- * Remove all elements, but dont return them to pool
- */
- void removeAll();
-
- /**
- * Remove element and return to pool
- */
- void release(Uint32 i);
-
- /**
- * Remove element and return to pool
- */
- void release(Ptr<T> &);
-
- class Iterator {
- public:
- Ptr<T> curr;
- Uint32 bucket;
- inline bool isNull() const { return curr.isNull();}
- inline void setNull() { curr.setNull(); }
- };
-
- /**
- * Sets curr.p according to curr.i
- */
- void getPtr(Iterator & iter) const ;
-
- /**
- * First element in bucket
- */
- bool first(Iterator & iter) const;
-
- /**
- * Next Element
- *
- * param iter - A "fully set" iterator
- */
- bool next(Iterator & iter) const;
-
- /**
- * Get next element starting from bucket
- *
- * @param bucket - Which bucket to start from
- * @param iter - An "uninitialized" iterator
- */
- bool next(Uint32 bucket, Iterator & iter) const;
-
-private:
- Uint32 mask;
- Uint32 * hashValues;
- P & thePool;
-};
-
-template <typename P, typename T, typename U>
-inline
-DLHashTableImpl<P, T, U>::DLHashTableImpl(P & _pool)
- : thePool(_pool)
-{
- mask = 0;
- hashValues = 0;
-}
-
-template <typename P, typename T, typename U>
-inline
-DLHashTableImpl<P, T, U>::~DLHashTableImpl()
-{
- if(hashValues != 0)
- delete [] hashValues;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::setSize(Uint32 size)
-{
- Uint32 i = 1;
- while(i < size) i *= 2;
-
- if(mask == (i - 1))
- {
- /**
- * The size is already set to <b>size</b>
- */
- return true;
- }
-
- if(mask != 0)
- {
- /**
- * The mask is already set
- */
- return false;
- }
-
- mask = (i - 1);
- hashValues = new Uint32[i];
- for(Uint32 j = 0; j<i; j++)
- hashValues[j] = RNIL;
-
- return true;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::add(Ptr<T> & obj)
-{
- const Uint32 hv = obj.p->hashValue() & mask;
- const Uint32 i = hashValues[hv];
-
- if(i == RNIL)
- {
- hashValues[hv] = obj.i;
- obj.p->U::nextHash = RNIL;
- obj.p->U::prevHash = RNIL;
- }
- else
- {
- T * tmp = thePool.getPtr(i);
- tmp->U::prevHash = obj.i;
- obj.p->U::nextHash = i;
- obj.p->U::prevHash = RNIL;
-
- hashValues[hv] = obj.i;
- }
-}
-
-/**
- * First element
- */
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::first(Iterator & iter) const
-{
- Uint32 i = 0;
- while(i <= mask && hashValues[i] == RNIL) i++;
- if(i <= mask)
- {
- iter.bucket = i;
- iter.curr.i = hashValues[i];
- iter.curr.p = thePool.getPtr(iter.curr.i);
- return true;
- }
- else
- {
- iter.curr.i = RNIL;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::next(Iterator & iter) const
-{
- if(iter.curr.p->U::nextHash == RNIL)
- {
- Uint32 i = iter.bucket + 1;
- while(i <= mask && hashValues[i] == RNIL) i++;
- if(i <= mask)
- {
- iter.bucket = i;
- iter.curr.i = hashValues[i];
- iter.curr.p = thePool.getPtr(iter.curr.i);
- return true;
- }
- else
- {
- iter.curr.i = RNIL;
- return false;
- }
- }
-
- iter.curr.i = iter.curr.p->U::nextHash;
- iter.curr.p = thePool.getPtr(iter.curr.i);
- return true;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::remove(Ptr<T> & ptr, const T & key)
-{
- const Uint32 hv = key.hashValue() & mask;
-
- Uint32 i;
- T * p;
- Ptr<T> prev;
- LINT_INIT(prev.p);
- prev.i = RNIL;
-
- i = hashValues[hv];
- while(i != RNIL)
- {
- p = thePool.getPtr(i);
- if(key.equal(* p))
- {
- const Uint32 next = p->U::nextHash;
- if(prev.i == RNIL)
- {
- hashValues[hv] = next;
- }
- else
- {
- prev.p->U::nextHash = next;
- }
-
- if(next != RNIL)
- {
- T * nextP = thePool.getPtr(next);
- nextP->U::prevHash = prev.i;
- }
-
- ptr.i = i;
- ptr.p = p;
- return;
- }
- prev.p = p;
- prev.i = i;
- i = p->U::nextHash;
- }
- ptr.i = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::remove(Uint32 i)
-{
- Ptr<T> tmp;
- tmp.i = i;
- tmp.p = thePool.getPtr(i);
- remove(tmp);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::release(Uint32 i)
-{
- Ptr<T> tmp;
- tmp.i = i;
- tmp.p = thePool.getPtr(i);
- release(tmp);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::remove(Ptr<T> & ptr)
-{
- const Uint32 next = ptr.p->U::nextHash;
- const Uint32 prev = ptr.p->U::prevHash;
-
- if(prev != RNIL)
- {
- T * prevP = thePool.getPtr(prev);
- prevP->U::nextHash = next;
- }
- else
- {
- const Uint32 hv = ptr.p->hashValue() & mask;
- if (hashValues[hv] == ptr.i)
- {
- hashValues[hv] = next;
- }
- else
- {
- // Will add assert in 5.1
- }
- }
-
- if(next != RNIL)
- {
- T * nextP = thePool.getPtr(next);
- nextP->U::prevHash = prev;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::release(Ptr<T> & ptr)
-{
- const Uint32 next = ptr.p->U::nextHash;
- const Uint32 prev = ptr.p->U::prevHash;
-
- if(prev != RNIL)
- {
- T * prevP = thePool.getPtr(prev);
- prevP->U::nextHash = next;
- }
- else
- {
- const Uint32 hv = ptr.p->hashValue() & mask;
- if (hashValues[hv] == ptr.i)
- {
- hashValues[hv] = next;
- }
- else
- {
- // Will add assert in 5.1
- }
- }
-
- if(next != RNIL)
- {
- T * nextP = thePool.getPtr(next);
- nextP->U::prevHash = prev;
- }
-
- thePool.release(ptr);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::removeAll()
-{
- for(Uint32 i = 0; i<=mask; i++)
- hashValues[i] = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::next(Uint32 bucket, Iterator & iter) const
-{
- while (bucket <= mask && hashValues[bucket] == RNIL)
- bucket++;
-
- if (bucket > mask)
- {
- iter.bucket = bucket;
- iter.curr.i = RNIL;
- return false;
- }
-
- iter.bucket = bucket;
- iter.curr.i = hashValues[bucket];
- iter.curr.p = thePool.getPtr(iter.curr.i);
- return true;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::seize(Ptr<T> & ptr)
-{
- if(thePool.seize(ptr)){
- ptr.p->U::nextHash = ptr.p->U::prevHash = RNIL;
- return true;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const
-{
- ptr.i = i;
- ptr.p = thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLHashTableImpl<P, T, U>::getPtr(Ptr<T> & ptr) const
-{
- thePool.getPtr(ptr);
-}
-
-template <typename P, typename T, typename U>
-inline
-T *
-DLHashTableImpl<P, T, U>::getPtr(Uint32 i) const
-{
- return thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLHashTableImpl<P, T, U>::find(Ptr<T> & ptr, const T & key) const
-{
- const Uint32 hv = key.hashValue() & mask;
-
- Uint32 i;
- T * p;
-
- i = hashValues[hv];
- while(i != RNIL)
- {
- p = thePool.getPtr(i);
- if(key.equal(* p))
- {
- ptr.i = i;
- ptr.p = p;
- return true;
- }
- i = p->U::nextHash;
- }
- ptr.i = RNIL;
- ptr.p = NULL;
- return false;
-}
-
-// Specializations
-
-template <typename T, typename U = T>
-class DLHashTable : public DLHashTableImpl<ArrayPool<T>, T, U>
-{
-public:
- DLHashTable(ArrayPool<T> & p) : DLHashTableImpl<ArrayPool<T>, T, U>(p) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLHashTable2.hpp b/storage/ndb/src/kernel/vm/DLHashTable2.hpp
deleted file mode 100644
index 85567bfc9bd..00000000000
--- a/storage/ndb/src/kernel/vm/DLHashTable2.hpp
+++ /dev/null
@@ -1,515 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DL_HASHTABLE2_HPP
-#define DL_HASHTABLE2_HPP
-
-#include <ndb_global.h>
-#include "ArrayPool.hpp"
-
-/**
- * DLHashTable2 is a DLHashTable variant meant for cases where different
- * DLHashTable instances share a common pool (based on a union U).
- *
- * Calls T constructor after seize from pool and T destructor before
- * release (in all forms) into pool.
- */
-template <class T, class U>
-class DLHashTable2 {
-public:
- DLHashTable2(ArrayPool<U> & thePool);
- ~DLHashTable2();
-
- /**
- * Set the no of bucket in the hashtable
- *
- * Note, can currently only be called once
- */
- bool setSize(Uint32 noOfElements);
-
- /**
- * Seize element from pool - return i
- *
- * Note *must* be added using <b>add</b> (even before hash.release)
- * or be released using pool
- */
- bool seize(Ptr<T> &);
-
- /**
- * Add an object to the hashtable
- */
- void add(Ptr<T> &);
-
- /**
- * Find element key in hashtable update Ptr (i & p)
- * (using key.equal(...))
- * @return true if found and false otherwise
- */
- bool find(Ptr<T> &, const T & key) const;
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Get element using ptr.i (update ptr.p)
- */
- void getPtr(Ptr<T> &) const;
-
- /**
- * Get P value for i
- */
- T * getPtr(Uint32 i) const;
-
- /**
- * Remove element (and set Ptr to removed element)
- * Note does not return to pool
- */
- void remove(Ptr<T> &, const T & key);
-
- /**
- * Remove element
- * Note does not return to pool
- */
- void remove(Uint32 i);
-
- /**
- * Remove element
- * Note does not return to pool
- */
- void remove(Ptr<T> &);
-
- /**
- * Remove all elements, but dont return them to pool
- */
- void removeAll();
-
- /**
- * Remove element (and set Ptr to removed element)
- * And return element to pool
- */
- void release(Ptr<T> &, const T & key);
-
- /**
- * Remove element and return to pool
- */
- void release(Uint32 i);
-
- /**
- * Remove element and return to pool
- */
- void release(Ptr<T> &);
-
- class Iterator {
- public:
- Ptr<T> curr;
- Uint32 bucket;
- inline bool isNull() const { return curr.isNull();}
- inline void setNull() { curr.setNull(); }
- };
-
- /**
- * Sets curr.p according to curr.i
- */
- void getPtr(Iterator & iter) const ;
-
- /**
- * First element in bucket
- */
- bool first(Iterator & iter) const;
-
- /**
- * Next Element
- *
- * param iter - A "fully set" iterator
- */
- bool next(Iterator & iter) const;
-
- /**
- * Get next element starting from bucket
- *
- * @param bucket - Which bucket to start from
- * @param iter - An "uninitialized" iterator
- */
- bool next(Uint32 bucket, Iterator & iter) const;
-
- inline bool isEmpty() const { Iterator iter; return ! first(iter); }
-
-private:
- Uint32 mask;
- Uint32 * hashValues;
- ArrayPool<U> & thePool;
-};
-
-template<class T, class U>
-inline
-DLHashTable2<T, U>::DLHashTable2(ArrayPool<U> & _pool)
- : thePool(_pool)
-{
- mask = 0;
- hashValues = 0;
-}
-
-template<class T, class U>
-inline
-DLHashTable2<T, U>::~DLHashTable2(){
- if(hashValues != 0)
- delete [] hashValues;
-}
-
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::setSize(Uint32 size){
- Uint32 i = 1;
- while(i < size) i *= 2;
-
- if(mask == (i - 1)){
- /**
- * The size is already set to <b>size</b>
- */
- return true;
- }
-
- if(mask != 0){
- /**
- * The mask is already set
- */
- return false;
- }
-
- mask = (i - 1);
- hashValues = new Uint32[i];
- for(Uint32 j = 0; j<i; j++)
- hashValues[j] = RNIL;
-
- return true;
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::add(Ptr<T> & obj){
- const Uint32 hv = obj.p->hashValue() & mask;
- const Uint32 i = hashValues[hv];
-
- if(i == RNIL){
- hashValues[hv] = obj.i;
- obj.p->nextHash = RNIL;
- obj.p->prevHash = RNIL;
- } else {
-
- T * tmp = (T*)thePool.getPtr(i); // cast
- tmp->prevHash = obj.i;
- obj.p->nextHash = i;
- obj.p->prevHash = RNIL;
-
- hashValues[hv] = obj.i;
- }
-}
-
-/**
- * First element
- */
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::first(Iterator & iter) const {
- Uint32 i = 0;
- while(i <= mask && hashValues[i] == RNIL) i++;
- if(i <= mask){
- iter.bucket = i;
- iter.curr.i = hashValues[i];
- iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
- return true;
- } else {
- iter.curr.i = RNIL;
- }
- return false;
-}
-
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::next(Iterator & iter) const {
- if(iter.curr.p->nextHash == RNIL){
- Uint32 i = iter.bucket + 1;
- while(i <= mask && hashValues[i] == RNIL) i++;
- if(i <= mask){
- iter.bucket = i;
- iter.curr.i = hashValues[i];
- iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
- return true;
- } else {
- iter.curr.i = RNIL;
- return false;
- }
- }
-
- iter.curr.i = iter.curr.p->nextHash;
- iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
- return true;
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::remove(Ptr<T> & ptr, const T & key){
- const Uint32 hv = key.hashValue() & mask;
-
- Uint32 i;
- T * p;
- Ptr<T> prev;
- prev.i = RNIL;
-
- i = hashValues[hv];
- while(i != RNIL){
- p = (T*)thePool.getPtr(i); // cast
- if(key.equal(* p)){
- const Uint32 next = p->nextHash;
- if(prev.i == RNIL){
- hashValues[hv] = next;
- } else {
- prev.p->nextHash = next;
- }
-
- if(next != RNIL){
- T * nextP = (T*)thePool.getPtr(next); // cast
- nextP->prevHash = prev.i;
- }
-
- ptr.i = i;
- ptr.p = p;
- return;
- }
- prev.p = p;
- prev.i = i;
- i = p->nextHash;
- }
- ptr.i = RNIL;
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::release(Ptr<T> & ptr, const T & key){
- const Uint32 hv = key.hashValue() & mask;
-
- Uint32 i;
- T * p;
- Ptr<T> prev;
- prev.i = RNIL;
-
- i = hashValues[hv];
- while(i != RNIL){
- p = (T*)thePool.getPtr(i); // cast
- if(key.equal(* p)){
- const Uint32 next = p->nextHash;
- if(prev.i == RNIL){
- hashValues[hv] = next;
- } else {
- prev.p->nextHash = next;
- }
-
- if(next != RNIL){
- T * nextP = (T*)thePool.getPtr(next); // cast
- nextP->prevHash = prev.i;
- }
-
- p->~T(); // dtor
- thePool.release(i);
- ptr.i = i;
- ptr.p = p; // invalid
- return;
- }
- prev.p = p;
- prev.i = i;
- i = p->nextHash;
- }
- ptr.i = RNIL;
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::remove(Uint32 i){
- Ptr<T> tmp;
- tmp.i = i;
- tmp.p = (T*)thePool.getPtr(i); // cast
- remove(tmp);
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::release(Uint32 i){
- Ptr<T> tmp;
- tmp.i = i;
- tmp.p = (T*)thePool.getPtr(i); // cast
- release(tmp);
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::remove(Ptr<T> & ptr){
- const Uint32 next = ptr.p->nextHash;
- const Uint32 prev = ptr.p->prevHash;
-
- if(prev != RNIL){
- T * prevP = (T*)thePool.getPtr(prev); // cast
- prevP->nextHash = next;
- } else {
- const Uint32 hv = ptr.p->hashValue() & mask;
- if (hashValues[hv] == ptr.i)
- {
- hashValues[hv] = next;
- }
- else
- {
- // Will add assert in 5.1
- }
- }
-
- if(next != RNIL){
- T * nextP = (T*)thePool.getPtr(next); // cast
- nextP->prevHash = prev;
- }
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::release(Ptr<T> & ptr){
- const Uint32 next = ptr.p->nextHash;
- const Uint32 prev = ptr.p->prevHash;
-
- if(prev != RNIL){
- T * prevP = (T*)thePool.getPtr(prev); // cast
- prevP->nextHash = next;
- } else {
- const Uint32 hv = ptr.p->hashValue() & mask;
- if (hashValues[hv] == ptr.i)
- {
- hashValues[hv] = next;
- }
- else
- {
- // Will add assert in 5.1
- }
- }
-
- if(next != RNIL){
- T * nextP = (T*)thePool.getPtr(next); // cast
- nextP->prevHash = prev;
- }
-
- thePool.release(ptr.i);
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::removeAll(){
- for(Uint32 i = 0; i<=mask; i++)
- hashValues[i] = RNIL;
-}
-
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::next(Uint32 bucket, Iterator & iter) const {
- while (bucket <= mask && hashValues[bucket] == RNIL)
- bucket++;
-
- if (bucket > mask) {
- iter.bucket = bucket;
- iter.curr.i = RNIL;
- return false;
- }
-
- iter.bucket = bucket;
- iter.curr.i = hashValues[bucket];
- iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
- return true;
-}
-
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::seize(Ptr<T> & ptr){
- Ptr<U> ptr2;
- thePool.seize(ptr2);
- ptr.i = ptr2.i;
- ptr.p = (T*)ptr2.p; // cast
- if (ptr.p != NULL){
- ptr.p->nextHash = RNIL;
- ptr.p->prevHash = RNIL;
- new (ptr.p) T; // ctor
- }
- return !ptr.isNull();
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const {
- ptr.i = i;
- ptr.p = (T*)thePool.getPtr(i); // cast
-}
-
-template<class T, class U>
-inline
-void
-DLHashTable2<T, U>::getPtr(Ptr<T> & ptr) const {
- Ptr<U> ptr2;
- thePool.getPtr(ptr2);
- ptr.i = ptr2.i;
- ptr.p = (T*)ptr2.p; // cast
-}
-
-template<class T, class U>
-inline
-T *
-DLHashTable2<T, U>::getPtr(Uint32 i) const {
- return (T*)thePool.getPtr(i); // cast
-}
-
-template<class T, class U>
-inline
-bool
-DLHashTable2<T, U>::find(Ptr<T> & ptr, const T & key) const {
- const Uint32 hv = key.hashValue() & mask;
-
- Uint32 i;
- T * p;
-
- i = hashValues[hv];
- while(i != RNIL){
- p = (T*)thePool.getPtr(i); // cast
- if(key.equal(* p)){
- ptr.i = i;
- ptr.p = p;
- return true;
- }
- i = p->nextHash;
- }
- ptr.i = RNIL;
- ptr.p = NULL;
- return false;
-}
-#endif
diff --git a/storage/ndb/src/kernel/vm/DLList.hpp b/storage/ndb/src/kernel/vm/DLList.hpp
deleted file mode 100644
index f691ae8ad26..00000000000
--- a/storage/ndb/src/kernel/vm/DLList.hpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DLLIST_HPP
-#define DLLIST_HPP
-
-#include "ArrayPool.hpp"
-
-/**
- * Template class used for implementing an
- * list of object retreived from a pool
- */
-template <typename P, typename T, typename U = T>
-class DLListImpl
-{
-public:
- /**
- * List head
- */
- struct HeadPOD {
- Uint32 firstItem;
- inline bool isEmpty() const { return firstItem == RNIL; }
- inline void init () { firstItem = RNIL; }
- };
-
- struct Head : public HeadPOD
- {
- Head();
- Head& operator=(const HeadPOD& src) {
- this->firstItem = src.firstItem;
- return *this;
- }
- };
-
- DLListImpl(P& thePool);
-
- /**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
- bool seize(Ptr<T> &);
-
- /**
- * Allocate object <b>i</b> from pool - update Ptr
- *
- * Return i
- */
- bool seizeId(Ptr<T> &, Uint32 i);
-
- /**
- * Check if <b>i</b> is allocated.
- */
- bool findId(Uint32 i) const;
-
- /**
- * Return an object to pool
- */
- void release(Uint32 i);
-
- /**
- * Return an object to pool
- */
- void release(Ptr<T> &);
-
- /**
- * Return all objects to the pool
- */
- void release();
-
- /**
- * Remove all objects from list
- */
- void remove();
-
- /**
- * Add object to list
- *
- * @NOTE MUST be seized from correct pool
- */
- void add(Ptr<T> &);
-
- /**
- * Add a list to list
- * @NOTE all elements _must_ be correctly initilized correctly wrt next/prev
- */
- void add(Uint32 first, Ptr<T> & last);
-
- /**
- * Remove object from list
- *
- * @NOTE Does not return it to pool
- */
- void remove(Ptr<T> &);
-
- /**
- * Remove object from list
- *
- * @NOTE Does not return it to pool
- */
- void remove(T*);
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const ;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const ;
-
- /**
- * Update ptr to first element in list
- *
- * @return True if element exists, false otherwise
- */
- bool first(Ptr<T> &) const ;
-
- /**
- * Get next element
- *
- * @note ptr must have both p & i values
- *
- * @return True if element exists, false otherwise
- */
- bool next(Ptr<T> &) const ;
-
- /**
- * Check if next exists
- *
- * @note ptr must have both p & i values
- * @return True if element exists, false otherwise
- */
- bool hasNext(const Ptr<T> &) const;
-
- inline bool isEmpty() const { return head.firstItem == RNIL;}
-
-protected:
- Head head;
- P & thePool;
-};
-
-template <typename P, typename T, typename U = T>
-class LocalDLListImpl : public DLListImpl<P,T,U>
-{
-public:
- LocalDLListImpl(P & thePool, typename DLListImpl<P,T,U>::HeadPOD & _src)
- : DLListImpl<P,T,U>(thePool), src(_src)
- {
- this->head = src;
- }
-
- ~LocalDLListImpl(){
- src = this->head;
- }
-private:
- typename DLListImpl<P,T,U>::HeadPOD & src;
-};
-
-template <typename P, typename T, typename U>
-inline
-DLListImpl<P,T,U>::DLListImpl(P & _pool)
- : thePool(_pool)
-{
-}
-
-template <typename P, typename T, typename U>
-inline
-DLListImpl<P,T,U>::Head::Head()
-{
- this->init();
-}
-
-/**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::seize(Ptr<T> & p)
-{
- if (likely(thePool.seize(p)))
- {
- add(p);
- return true;
- }
- return false;
-}
-
-/**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::seizeId(Ptr<T> & p, Uint32 ir)
-{
- if (likely(thePool.seizeId(p, ir)))
- {
- add(p);
- return true;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::findId(Uint32 i) const
-{
- return thePool.findId(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::add(Ptr<T> & p)
-{
- T * t = p.p;
- Uint32 ff = head.firstItem;
-
- t->U::nextList = ff;
- t->U::prevList = RNIL;
- head.firstItem = p.i;
-
- if(ff != RNIL)
- {
- T * t2 = thePool.getPtr(ff);
- t2->U::prevList = p.i;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::add(Uint32 first, Ptr<T> & lastPtr)
-{
- Uint32 ff = head.firstItem;
-
- head.firstItem = first;
- lastPtr.p->U::nextList = ff;
-
- if(ff != RNIL)
- {
- T * t2 = thePool.getPtr(ff);
- t2->U::prevList = lastPtr.i;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::remove(Ptr<T> & p)
-{
- remove(p.p);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::remove(T * p)
-{
- T * t = p;
- Uint32 ni = t->U::nextList;
- Uint32 pi = t->U::prevList;
-
- if(ni != RNIL){
- T * tn = thePool.getPtr(ni);
- tn->U::prevList = pi;
- }
-
- if(pi != RNIL){
- T * tp = thePool.getPtr(pi);
- tp->U::nextList = ni;
- } else {
- head.firstItem = ni;
- }
-}
-
-/**
- * Return an object to pool
- */
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::release(Uint32 i)
-{
- Ptr<T> p;
- p.i = i;
- p.p = thePool.getPtr(i);
- release(p);
-}
-
-/**
- * Return an object to pool
- */
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::release(Ptr<T> & p)
-{
- remove(p);
- thePool.release(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::release()
-{
- Ptr<T> ptr;
- Uint32 curr = head.firstItem;
- while(curr != RNIL)
- {
- thePool.getPtr(ptr, curr);
- curr = ptr.p->U::nextList;
- thePool.release(ptr);
- }
- head.firstItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::remove()
-{
- head.firstItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
-{
- p.i = i;
- p.p = thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-DLListImpl<P,T,U>::getPtr(Ptr<T> & p) const
-{
- thePool.getPtr(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-T *
-DLListImpl<P,T,U>::getPtr(Uint32 i) const
-{
- return thePool.getPtr(i);
-}
-
-/**
- * Update ptr to first element in list
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::first(Ptr<T> & p) const
-{
- Uint32 i = head.firstItem;
- p.i = i;
- if(i != RNIL)
- {
- p.p = thePool.getPtr(i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::next(Ptr<T> & p) const
-{
- Uint32 i = p.p->U::nextList;
- p.i = i;
- if(i != RNIL){
- p.p = thePool.getPtr(i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-DLListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
-{
- return p.p->U::nextList != RNIL;
-}
-
-// Specializations
-
-template <typename T, typename U = T>
-class DLList : public DLListImpl<ArrayPool<T>, T, U>
-{
-public:
- DLList(ArrayPool<T> & p) : DLListImpl<ArrayPool<T>, T, U>(p) {}
-};
-
-template <typename T, typename U = T>
-class LocalDLList : public LocalDLListImpl<ArrayPool<T>, T, U> {
-public:
- LocalDLList(ArrayPool<T> & p, typename DLList<T,U>::HeadPOD & _src)
- : LocalDLListImpl<ArrayPool<T>, T, U>(p, _src) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DataBuffer.hpp b/storage/ndb/src/kernel/vm/DataBuffer.hpp
deleted file mode 100644
index a1956229d8b..00000000000
--- a/storage/ndb/src/kernel/vm/DataBuffer.hpp
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DATA_BUFFER_HPP
-#define DATA_BUFFER_HPP
-
-#include "ArrayPool.hpp"
-
-/**
- * @class DataBuffer
- * @brief Buffer of data words
- *
- * @note The buffer is divided into segments (of size sz)
- */
-template <Uint32 sz>
-class DataBuffer {
-public:
- struct Segment {
- Uint32 nextPool;
- Uint32 data[sz];
- NdbOut& print(NdbOut& out){
- out << "[DataBuffer<" << sz << ">::Segment this="
- << this << dec << " nextPool= "
- << nextPool << " ]";
- return out;
- }
- };
-public:
- typedef ArrayPool<Segment> DataBufferPool;
-
- /**
- * Head/anchor for data buffer
- */
- struct Head {
- Head() ;
-
- Uint32 used; // Words used
- Uint32 firstItem; // First segment (or RNIL)
- Uint32 lastItem; // Last segment (or RNIL)
-
- /**
- * Get size of databuffer, in words
- */
- Uint32 getSize() const { return used;}
-
- /**
- * Get segment size in words (template argument)
- */
- static Uint32 getSegmentSize() { return sz;}
- };
-
- /** Constructor */
- DataBuffer(DataBufferPool &);
-
- /** Seize <b>n</b> words, Release */
- bool seize(Uint32 n);
- void release();
-
- /**
- * Get size of databuffer, in words
- */
- Uint32 getSize() const;
-
- /**
- * Check if buffer is empty
- */
- bool isEmpty() const;
-
- /**
- * Get segment size in words (template argument)
- */
- static Uint32 getSegmentSize();
-
- void print(FILE*) const;
-
- /* ----------------------------------------------------------------------- */
-
- struct DataBufferIterator {
- Ptr<Segment> curr; // Ptr to current segment
- Uint32* data; // Pointer to current data (word)
- Uint32 ind; // Word index within a segment
- Uint32 pos; // Absolute word position within DataBuffer
-
- void print(FILE* out) {
- fprintf(out, "[DataBufferIterator curr.i=%d, data=%p, ind=%d, pos=%d]\n",
- curr.i, (void*) data, ind, pos);
- };
-
- inline bool isNull() const { return curr.isNull();}
- inline void setNull() { curr.setNull(); data = 0; ind = pos = RNIL;}
- };
- typedef DataBufferIterator Iterator;
-
- struct ConstDataBufferIterator {
- ConstPtr<Segment> curr;
- const Uint32 * data;
- Uint32 ind;
- Uint32 pos;
-
- inline bool isNull() const { return curr.isNull();}
- inline void setNull() { curr.setNull(); data = 0; ind = pos = RNIL;}
- };
-
- /**
- * Iterator
- * @parameter hops Number of words to jump forward
- * @note DataBuffer::next returns false if applied to last word.
- */
- bool first(DataBufferIterator &);
- bool next(DataBufferIterator &);
- bool next(DataBufferIterator &, Uint32 hops);
- bool nextPool(DataBufferIterator &);
-
- /**
- * Set iterator to position
- */
- bool position(DataBufferIterator& it, Uint32 pos);
-
- /** Iterator */
- bool first(ConstDataBufferIterator &) const;
- bool next(ConstDataBufferIterator &) const;
- bool next(ConstDataBufferIterator &, Uint32 hops) const;
- bool nextPool(ConstDataBufferIterator &) const;
-
- /**
- * Returns true if it is possible to store <em>len</em>
- * no of words at position given in iterator.
- */
- bool importable(const DataBufferIterator, Uint32 len);
-
- /**
- * Stores <em>len</em> no of words starting at location <em>src</em> in
- * databuffer at position given in iterator.
- *
- * @return true if success, false otherwise.
- * @note Iterator is not advanced.
- */
- bool import(const DataBufferIterator &, const Uint32* src, Uint32 len);
-
- /**
- * Increases size with appends <em>len</em> words
- * @return true if success, false otherwise.
- */
- bool append(const Uint32* src, Uint32 len);
-
-protected:
- Head head;
- DataBufferPool & thePool;
-
-private:
- /**
- * This is NOT a public method, since the intension is that the import
- * method using iterators will be more effective in the future
- */
- bool import(Uint32 pos, const Uint32* src, Uint32 len);
-};
-
-template<Uint32 sz>
-class LocalDataBuffer : public DataBuffer<sz> {
-public:
- LocalDataBuffer(typename DataBuffer<sz>::DataBufferPool & thePool,
- typename DataBuffer<sz>::Head & _src)
- : DataBuffer<sz>(thePool), src(_src)
- {
- this->head = src;
- }
-
- ~LocalDataBuffer(){
- src = this->head;
- }
-private:
- typename DataBuffer<sz>::Head & src;
-};
-
-template<Uint32 sz>
-inline
-DataBuffer<sz>::Head::Head(){
- used = 0;
- firstItem = RNIL;
- lastItem = RNIL;
-}
-
-template<Uint32 sz>
-inline
-bool DataBuffer<sz>::importable(const DataBufferIterator it, Uint32 len){
- return (it.pos + len < head.used);
-}
-
-template<Uint32 sz>
-inline
-bool DataBuffer<sz>::position(DataBufferIterator& it, Uint32 p){
-
- // TODO: The current implementation is not the most effective one.
- // A more effective implementation would start at the current
- // position of the iterator.
-
- if(!first(it)){
- return false;
- }
- return next(it, p);
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::import(const DataBufferIterator & it,
- const Uint32* src, Uint32 len){
-
-#if 0
- DataBufferIterator it;
- position(it, _it.pos);
-
- for(; len > 0; len--){
- Uint32 s = * src;
- * it.data = s;
- next(it);
- src++;
- }
- return true;
-#else
- Uint32 ind = (it.pos % sz);
- Uint32 left = sz - ind;
- Segment * p = it.curr.p;
-
- while(len > left){
- memcpy(&p->data[ind], src, 4 * left);
- src += left;
- len -= left;
- ind = 0;
- left = sz;
- p = thePool.getPtr(p->nextPool);
- }
-
- memcpy(&p->data[ind], src, 4 * len);
- return true;
-#endif
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::append(const Uint32* src, Uint32 len){
- if(len == 0)
- return true;
-
- Uint32 pos = head.used;
- if(!seize(len)){
- return false;
- }
- DataBufferIterator it;
-
- if(position(it, pos) && import(it, src, len)){
- return true;
- }
- abort();
- return false;
-}
-
-template<Uint32 sz>
-inline
-void DataBuffer<sz>::print(FILE* out) const {
- fprintf(out, "[DataBuffer used=%d words, segmentsize=%d words",
- head.used, sz);
-
- if (head.firstItem == RNIL) {
- fprintf(out, ": No segments seized.]\n");
- return;
- } else {
- fprintf(out, "\n");
- }
-
- Ptr<Segment> ptr;
- ptr.i = head.firstItem;
-
- Uint32 acc = 0;
- for(; ptr.i != RNIL; ){
- thePool.getPtr(ptr);
- const Uint32 * rest = ptr.p->data;
- for(Uint32 i = 0; i<sz; i++){
- fprintf(out, " H'%.8x", rest[i]);
- if(acc++ == 6){
- acc = 0;
- fprintf(out, "\n");
- }
- }
- ptr.i = ptr.p->nextPool;
- }
- fprintf(out, " ]\n");
-}
-
-template<Uint32 sz>
-inline
-DataBuffer<sz>::DataBuffer(DataBufferPool & p) : thePool(p){
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::seize(Uint32 n){
- Uint32 rest; // Free space in last segment (currently)
- Segment* prevPtr;
-
- if(head.firstItem == RNIL){
- rest = 0;
- prevPtr = (Segment*)&head.firstItem;
- } else {
- rest = (sz - (head.used % sz)) % sz;
- prevPtr = thePool.getPtr(head.lastItem);
- }
-
- /**
- * Check for space
- */
- Uint32 free = thePool.getNoOfFree() * sz + rest;
- if(n > free){
- release();
- return false;
- }
-
- Uint32 used = head.used + n;
- Ptr<Segment> currPtr;
- currPtr.i = head.lastItem;
-
- while(n >= sz){
- if(0)
- ndbout_c("n(%d) %c sz(%d)", n, (n>sz?'>':(n<sz?'<':'=')), sz);
-
- thePool.seize(currPtr); assert(currPtr.i != RNIL);
- prevPtr->nextPool = currPtr.i;
-
- prevPtr = currPtr.p;
- prevPtr->nextPool = RNIL;
- n -= sz;
- }
-
- if(0){
- Uint32 pos = rest + n;
- ndbout_c("rest(%d), n(%d) pos=%d %c sz(%d)",
- rest, n, pos, (pos>sz?'>':(pos<sz?'<':'=')), sz);
- }
-
- if(n > rest){
- thePool.seize(currPtr);
- assert(currPtr.i != RNIL);
- prevPtr->nextPool = currPtr.i;
- currPtr.p->nextPool = RNIL;
- }
-
- head.used = used;
- head.lastItem = currPtr.i;
-
-#if 0
- {
- ndbout_c("Before validate - %d", head.used);
- if(head.used == 0){
- assert(head.firstItem == RNIL);
- assert(head.lastItem == RNIL);
- } else {
- Ptr<Segment> tmp;
- tmp.i = head.firstItem;
- for(Uint32 i = head.used; i > sz; i -= sz){
- ndbout << tmp.i << " ";
- tmp.p = thePool.getPtr(tmp.i);
- tmp.i = tmp.p->nextPool;
- }
- ndbout_c("%d", tmp.i);
- assert(head.lastItem == tmp.i);
- }
- ndbout_c("After validate");
- }
-#endif
- return true;
-}
-
-template<Uint32 sz>
-inline
-void
-DataBuffer<sz>::release(){
- Uint32 used = head.used + sz - 1;
- if(head.firstItem != RNIL){
- thePool.releaseList(used / sz, head.firstItem, head.lastItem);
- head.used = 0;
- head.firstItem = RNIL;
- head.lastItem = RNIL;
- }
-}
-
-template<Uint32 sz>
-inline
-Uint32
-DataBuffer<sz>::getSegmentSize(){
- return sz;
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::first(DataBufferIterator & it){
- return first((ConstDataBufferIterator&)it);
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::next(DataBufferIterator & it){
- return next((ConstDataBufferIterator&)it);
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::next(DataBufferIterator & it, Uint32 hops){
- return next((ConstDataBufferIterator&)it, hops);
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::first(ConstDataBufferIterator & it) const {
- it.curr.i = head.firstItem;
- if(it.curr.i == RNIL){
- it.setNull();
- return false;
- }
- thePool.getPtr(it.curr);
- it.data = &it.curr.p->data[0];
- it.ind = 0;
- it.pos = 0;
- return true;
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::next(ConstDataBufferIterator & it) const {
- it.ind ++;
- it.data ++;
- it.pos ++;
- if(it.ind < sz && it.pos < head.used){
- return true;
- }
-
- if(it.pos < head.used){
- it.curr.i = it.curr.p->nextPool;
-#ifdef ARRAY_GUARD
- if(it.curr.i == RNIL){
- /**
- * This is actually "internal error"
- * pos can't be less than head.used and at the same time we can't
- * find next segment
- *
- * Note this must not "really" be checked since thePool.getPtr will
- * abort when trying to get RNIL. That's why the check is within
- * ARRAY_GUARD
- */
- ErrorReporter::handleAssert("DataBuffer<sz>::next", __FILE__, __LINE__);
- }
-#endif
- thePool.getPtr(it.curr);
- it.data = &it.curr.p->data[0];
- it.ind = 0;
- return true;
- }
- it.setNull();
- return false;
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::next(ConstDataBufferIterator & it, Uint32 hops) const {
-#if 0
- for (Uint32 i=0; i<hops; i++) {
- if (!this->next(it))
- return false;
- }
- return true;
-#else
- if(it.pos + hops < head.used){
- while(hops >= sz){
- it.curr.i = it.curr.p->nextPool;
- thePool.getPtr(it.curr);
- hops -= sz;
- it.pos += sz;
- }
-
- it.ind += hops;
- it.pos += hops;
- if(it.ind < sz){
- it.data = &it.curr.p->data[it.ind];
- return true;
- }
-
- it.curr.i = it.curr.p->nextPool;
- thePool.getPtr(it.curr);
- it.ind -= sz;
- it.data = &it.curr.p->data[it.ind];
- return true;
- }
- it.setNull();
- return false;
-#endif
-}
-
-template<Uint32 sz>
-inline
-Uint32
-DataBuffer<sz>::getSize() const {
- return head.used;
-}
-
-template<Uint32 sz>
-inline
-bool
-DataBuffer<sz>::isEmpty() const {
- return (head.used == 0);
-}
-
-#endif
-
diff --git a/storage/ndb/src/kernel/vm/DynArr256.cpp b/storage/ndb/src/kernel/vm/DynArr256.cpp
deleted file mode 100644
index 6f3229c085c..00000000000
--- a/storage/ndb/src/kernel/vm/DynArr256.cpp
+++ /dev/null
@@ -1,1021 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "DynArr256.hpp"
-#include <stdio.h>
-#include <assert.h>
-#include <NdbOut.hpp>
-
-#define DA256_BITS 5
-#define DA256_MASK 31
-
-struct DA256CL
-{
- Uint32 m_magic;
- Uint32 m_data[15];
-};
-
-struct DA256Free
-{
- Uint32 m_magic;
- Uint32 m_next_free;
-};
-
-struct DA256Node
-{
- struct DA256CL m_lines[17];
-};
-
-struct DA256Page
-{
- struct DA256CL m_header[2];
- struct DA256Node m_nodes[30];
-};
-
-#define require(x) require_impl(x, __LINE__)
-//#define DA256_USE_PX
-//#define DA256_USE_PREFETCH
-#define DA256_EXTRA_SAFE
-
-
-#ifdef UNIT_TEST
-#ifdef USE_CALLGRIND
-#include <valgrind/callgrind.h>
-#else
-#define CALLGRIND_TOGGLE_COLLECT()
-#endif
-Uint32 allocatedpages = 0;
-Uint32 allocatednodes = 0;
-Uint32 releasednodes = 0;
-#endif
-
-inline
-void
-require_impl(bool x, int line)
-{
- if (!x)
- {
- ndbout_c("LINE: %d", line);
- abort();
- }
-}
-
-DynArr256Pool::DynArr256Pool()
-{
- m_type_id = RNIL;
- m_first_free = RNIL;
- m_memroot = 0;
-}
-
-void
-DynArr256Pool::init(Uint32 type_id, const Pool_context & pc)
-{
- m_ctx = pc;
- m_type_id = type_id;
- m_memroot = (DA256Page*)m_ctx.get_memroot();
-}
-
-static const Uint32 g_max_sizes[5] = { 0, 256, 65536, 16777216, ~0 };
-
-/**
- * sz = 0 = 1 - 0 level
- * sz = 1 = 256^1 - 1 level
- * sz = 2 = 256^2 - 2 level
- * sz = 3 = 256^3 - 3 level
- * sz = 4 = 256^4 - 4 level
- */
-Uint32 *
-DynArr256::get(Uint32 pos) const
-{
- Uint32 sz = m_head.m_sz;
- Uint32 ptrI = m_head.m_ptr_i;
- DA256Page * memroot = m_pool.m_memroot;
- Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;
-
- if (unlikely(pos >= g_max_sizes[sz]))
- {
- return 0;
- }
-
-#ifdef DA256_USE_PX
- Uint32 px[4] = { (pos >> 24) & 255,
- (pos >> 16) & 255,
- (pos >> 8) & 255,
- (pos >> 0) & 255 };
-#endif
-
- Uint32* retVal = &m_head.m_ptr_i;
- for(; sz --;)
- {
- if (unlikely(ptrI == RNIL))
- {
- return 0;
- }
-#ifdef DA256_USE_PX
- Uint32 p0 = px[sz];
-#else
- Uint32 shr = sz << 3;
- Uint32 p0 = (pos >> shr) & 255;
-#endif
- Uint32 page_no = ptrI >> DA256_BITS;
- Uint32 page_idx = ptrI & DA256_MASK;
- DA256Page * page = memroot + page_no;
-
- Uint32 *magic_ptr, p;
- if (p0 != 255)
- {
- Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
- Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
-
- p = 0;
- retVal = (ptr + 1 + p0 + line);
- magic_ptr =(ptr + (p0 & ~15));
- }
- else
- {
- Uint32 b = (page_idx + 1) >> 4;
- Uint32 * ptr = (Uint32*)(page->m_header+b);
-
- p = page_idx - (b << 4) + b;
- retVal = (ptr + 1 + p);
- magic_ptr = ptr;
- }
-
- ptrI = *retVal;
- Uint32 magic = *magic_ptr;
-
- if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
- goto err;
- }
-
- return retVal;
-err:
- require(false);
- return 0;
-}
-
-Uint32 *
-DynArr256::set(Uint32 pos)
-{
- Uint32 sz = m_head.m_sz;
- Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;
- DA256Page * memroot = m_pool.m_memroot;
-
- if (unlikely(pos >= g_max_sizes[sz]))
- {
- if (unlikely(!expand(pos)))
- {
- return 0;
- }
- sz = m_head.m_sz;
- }
-
-#ifdef DA256_USE_PX
- Uint32 px[4] = { (pos >> 24) & 255,
- (pos >> 16) & 255,
- (pos >> 8) & 255,
- (pos >> 0) & 255 };
-#endif
-
- Uint32 ptrI = m_head.m_ptr_i;
- Uint32 *retVal = &m_head.m_ptr_i;
- for(; sz --;)
- {
-#ifdef DA256_USE_PX
- Uint32 p0 = px[sz];
-#else
- Uint32 shr = sz << 3;
- Uint32 p0 = (pos >> shr) & 255;
-#endif
- if (ptrI == RNIL)
- {
- if (unlikely((ptrI = m_pool.seize()) == RNIL))
- {
- return 0;
- }
- * retVal = ptrI;
- }
-
- Uint32 page_no = ptrI >> DA256_BITS;
- Uint32 page_idx = ptrI & DA256_MASK;
- DA256Page * page = memroot + page_no;
-
- Uint32 *magic_ptr, p;
- if (p0 != 255)
- {
- Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
- Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
-
- p = 0;
- magic_ptr = (ptr + (p0 & ~15));
- retVal = (ptr + 1 + p0 + line);
- }
- else
- {
- Uint32 b = (page_idx + 1) >> 4;
- Uint32 * ptr = (Uint32*)(page->m_header+b);
-
- p = page_idx - (b << 4) + b;
- magic_ptr = ptr;
- retVal = (ptr + 1 + p);
- }
-
- ptrI = * retVal;
- Uint32 magic = *magic_ptr;
-
- if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
- goto err;
- }
-
- return retVal;
-
-err:
- require(false);
- return 0;
-}
-
-static
-inline
-void
-initpage(DA256Page* p, Uint32 page_no, Uint32 type_id)
-{
- Uint32 i, j;
-#ifdef DA256_USE_PREFETCH
-#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96)
-#ifdef DA256_EXTRA_SAFE
- for (i = 0; i<(30 * 17 + 2); i++)
- {
- __builtin_prefetch (p->m_header + i, 1);
- }
-#else
- {
- __builtin_prefetch (p->m_header + 0, 1);
- __builtin_prefetch (p->m_header + 1, 1);
- for (i = 0; i<30; i++)
- {
- __builtin_prefetch (p->m_nodes + i, 1);
- }
- }
-#endif
-#endif
-#endif
- DA256CL* cl;
- for (i = 0; i<2; i++)
- {
- cl = p->m_header + i;
- cl->m_magic = (~type_id << 16);
- }
-
- DA256Free* free;
-
- for (i = 0; i<30; i++)
- {
- free = (DA256Free*)(p->m_nodes+i);
- free->m_magic = type_id;
- free->m_next_free = (page_no << DA256_BITS) + (i + 1);
-#ifdef DA256_EXTRA_SAFE
- DA256Node* node = p->m_nodes+i;
- for (j = 0; j<17; j++)
- node->m_lines[j].m_magic = type_id;
-#endif
- }
-
- free = (DA256Free*)(p->m_nodes+29);
- free->m_next_free = RNIL;
-}
-
-bool
-DynArr256::expand(Uint32 pos)
-{
- Uint32 i;
- Uint32 idx = 0;
- Uint32 alloc[5];
- Uint32 sz = m_head.m_sz;
-
- for (; pos >= g_max_sizes[sz]; sz++);
-
- if (m_head.m_sz == 0)
- {
- m_head.m_sz = sz;
- return true;
- }
-
- sz = m_head.m_sz;
- for (; pos >= g_max_sizes[sz]; sz++)
- {
- Uint32 ptrI = m_pool.seize();
- if (unlikely(ptrI == RNIL))
- goto err;
- alloc[idx++] = ptrI;
- }
-
- alloc[idx] = m_head.m_ptr_i;
- m_head.m_sz = 1;
- for (Uint32 i = 0; i<idx; i++)
- {
- m_head.m_ptr_i = alloc[i];
- Uint32 * ptr = get(0);
- * ptr = alloc[i + 1];
- }
-
- m_head.m_sz = sz;
- m_head.m_ptr_i = alloc[0];
-
- return true;
-
-err:
- for (i = 0; i<idx; i++)
- m_pool.release(alloc[i]);
- return false;
-}
-
-void
-DynArr256::init(ReleaseIterator &iter)
-{
- iter.m_sz = 1;
- iter.m_pos = 0;
- iter.m_ptr_i[0] = RNIL;
- iter.m_ptr_i[1] = m_head.m_ptr_i;
- iter.m_ptr_i[2] = RNIL;
- iter.m_ptr_i[3] = RNIL;
- iter.m_ptr_i[4] = RNIL;
-}
-
-/**
- * Iter is in next pos
- *
- * 0 - done
- * 1 - data
- * 2 - no data
- */
-Uint32
-DynArr256::release(ReleaseIterator &iter, Uint32 * retptr)
-{
- Uint32 sz = iter.m_sz;
- Uint32 ptrI = iter.m_ptr_i[sz];
- Uint32 page_no = ptrI >> DA256_BITS;
- Uint32 page_idx = ptrI & DA256_MASK;
- Uint32 type_id = (~m_pool.m_type_id) & 0xFFFF;
- DA256Page * memroot = m_pool.m_memroot;
- DA256Page * page = memroot + page_no;
-
- if (ptrI != RNIL)
- {
- Uint32 p0 = iter.m_pos & 255;
- for (; p0<256; p0++)
- {
- Uint32 *retVal, *magic_ptr, p;
- if (p0 != 255)
- {
- Uint32 line = ((p0 << 8) + (p0 << 4) + p0 + 255) >> 12;
- Uint32 * ptr = (Uint32*)(page->m_nodes + page_idx);
-
- p = 0;
- retVal = (ptr + 1 + p0 + line);
- magic_ptr =(ptr + (p0 & ~15));
- }
- else
- {
- Uint32 b = (page_idx + 1) >> 4;
- Uint32 * ptr = (Uint32*)(page->m_header+b);
-
- p = page_idx - (b << 4) + b;
- retVal = (ptr + 1 + p);
- magic_ptr = ptr;
- }
-
- Uint32 magic = *magic_ptr;
- Uint32 val = *retVal;
- if (unlikely(! ((magic & (1 << p)) && (magic >> 16) == type_id)))
- goto err;
-
- if (sz == m_head.m_sz)
- {
- * retptr = val;
- p0++;
- if (p0 != 256)
- {
- /**
- * Move next
- */
- iter.m_pos &= ~(Uint32)255;
- iter.m_pos |= p0;
- }
- else
- {
- /**
- * Move up
- */
- m_pool.release(ptrI);
- iter.m_sz --;
- iter.m_pos >>= 8;
- }
- return 1;
- }
- else if (val != RNIL)
- {
- iter.m_sz++;
- iter.m_ptr_i[iter.m_sz] = val;
- iter.m_pos = (p0 << 8);
- * retVal = RNIL;
- return 2;
- }
- }
-
- assert(p0 == 256);
- m_pool.release(ptrI);
- iter.m_sz --;
- iter.m_pos >>= 8;
- return 2;
- }
-
- new (&m_head) Head();
- return 0;
-
-err:
- require(false);
- return false;
-}
-
-static
-inline
-bool
-seizenode(DA256Page* page, Uint32 idx, Uint32 type_id)
-{
- Uint32 i;
- Uint32 b = (idx + 1) >> 4;
- Uint32 p = idx - (b << 4) + b;
-
- DA256Node * ptr = (DA256Node*)(page->m_nodes + idx);
-
-#ifdef DA256_USE_PREFETCH
-#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96)
- __builtin_prefetch (page->m_header + b, 1);
- for (i = 0; i<17; i++)
- {
- __builtin_prefetch (ptr->m_lines+i, 1);
- }
-#endif
-#endif
-
-#ifdef DA256_EXTRA_SAFE
- Uint32 check = type_id;
-#endif
- type_id = ((~type_id) << 16) | 0xFFFF;
-
-#ifdef DA256_EXTRA_SAFE
- if (unlikely(((page->m_header + b)->m_magic & (1 << p)) != 0))
- {
- return false;
- }
-#endif
-
- (page->m_header + b)->m_magic |= (1 << p);
- (page->m_header + b)->m_data[p] = RNIL;
- for (i = 0; i<17; i++)
- {
- DA256CL * line = ptr->m_lines + i;
-#ifdef DA256_EXTRA_SAFE
- if (unlikely(line->m_magic != check))
- {
- return false;
- }
-#endif
- line->m_magic = type_id;
- for (Uint32 j = 0; j<15; j++)
- line->m_data[j] = RNIL;
- }
-
-#ifdef UNIT_TEST
- allocatednodes++;
-#endif
- return true;
-}
-
-static
-bool
-releasenode(DA256Page* page, Uint32 idx, Uint32 type_id)
-{
- Uint32 i;
- Uint32 b = (idx + 1) >> 4;
- Uint32 p = idx - (b << 4) + b;
-
- DA256Node * ptr = (DA256Node*)(page->m_nodes + idx);
-
-#ifdef DA256_USE_PREFETCH
-#if defined(__GNUC__) && !(__GNUC__ == 2 && __GNUC_MINOR__ < 96)
- __builtin_prefetch (page->m_header + b, 1);
- for (i = 0; i<17; i++)
- {
- __builtin_prefetch (ptr->m_lines+i, 1);
- }
-#endif
-#endif
-
-#ifdef DA256_EXTRA_SAFE
- Uint32 check = ((~type_id) << 16) | 0xFFFF;
-#endif
-
-#ifdef DA256_EXTRA_SAFE
- if (unlikely((((page->m_header + b)->m_magic & (1 << p)) == 0)))
- {
- return false;
- }
-#endif
-
- (page->m_header + b)->m_magic ^= (1 << p);
- for (i = 0; i<17; i++)
- {
- DA256CL * line = ptr->m_lines + i;
-#ifdef DA256_EXTRA_SAFE
- if (unlikely(line->m_magic != check))
- {
- return false;
- }
-#endif
- line->m_magic = type_id;
- }
-
-#ifdef UNIT_TEST
- releasednodes++;
-#endif
-
- return true;
-}
-
-Uint32
-DynArr256Pool::seize()
-{
- Uint32 ff = m_first_free;
- Uint32 type_id = m_type_id;
-
- DA256Page* page;
- DA256Page * memroot = m_memroot;
- if (ff == RNIL)
- {
- Uint32 page_no;
- if (likely((page = (DA256Page*)m_ctx.alloc_page(type_id, &page_no)) != 0))
- {
- initpage(page, page_no, type_id);
-#ifdef UNIT_TEST
- allocatedpages++;
-#endif
- }
- else
- {
- return RNIL;
- }
- ff = (page_no << DA256_BITS);
- }
- else
- {
- page = memroot + (ff >> DA256_BITS);
- }
-
- Uint32 idx = ff & DA256_MASK;
- DA256Free * ptr = (DA256Free*)(page->m_nodes + idx);
- if (likely(ptr->m_magic == type_id))
- {
- Uint32 next = ptr->m_next_free;
- if (likely(seizenode(page, idx, type_id)))
- {
- m_first_free = next;
- return ff;
- }
- }
-
-//error:
- require(false);
- return 0;
-}
-
-void
-DynArr256Pool::release(Uint32 ptrI)
-{
- Uint32 ff = m_first_free;
- Uint32 type_id = m_type_id;
-
- Uint32 page_no = ptrI >> DA256_BITS;
- Uint32 page_idx = ptrI & DA256_MASK;
- DA256Page * memroot = m_memroot;
- DA256Page * page = memroot + page_no;
-
- DA256Free * ptr = (DA256Free*)(page->m_nodes + page_idx);
- if (likely(releasenode(page, page_idx, type_id)))
- {
- ptr->m_next_free = ff;
- ptr->m_magic = type_id;
- m_first_free = ptrI;
- return;
- }
- require(false);
-}
-
-#ifdef UNIT_TEST
-
-#include <NdbTick.h>
-#include "ndbd_malloc_impl.hpp"
-#include "SimulatedBlock.hpp"
-
-Ndbd_mem_manager mm;
-Configuration cfg;
-Block_context ctx(cfg, mm);
-struct BB : public SimulatedBlock
-{
- BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {}
-};
-
-BB block(DBACC, ctx);
-
-static
-void
-simple(DynArr256 & arr, int argc, char* argv[])
-{
- ndbout_c("argc: %d", argc);
- for (Uint32 i = 1; i<(Uint32)argc; i++)
- {
- Uint32 * s = arr.set(atoi(argv[i]));
- {
- bool found = false;
- for (Uint32 j = 1; j<i; j++)
- {
- if (atoi(argv[i]) == atoi(argv[j]))
- {
- found = true;
- break;
- }
- }
- if (!found)
- * s = i;
- }
-
- Uint32 * g = arr.get(atoi(argv[i]));
- Uint32 v = g ? *g : ~0;
- ndbout_c("p: %p %p %d", s, g, v);
- }
-}
-
-static
-void
-basic(DynArr256& arr, int argc, char* argv[])
-{
-#define MAXLEN 65536
-
- Uint32 len = 0;
- Uint32 save[2*MAXLEN];
- for (Uint32 i = 0; i<MAXLEN; i++)
- {
- int op = (rand() % 100) > 50;
- if (len == 0)
- op = 1;
- if (len == MAXLEN)
- op = 0;
- switch(op){
- case 0:{ // get
- Uint32 item = (rand() % len) << 1;
- Uint32 idx = save[item];
- Uint32 val = save[item+1];
- //ndbout_c("get(%d)", idx);
- Uint32 *p = arr.get(idx);
- assert(p);
- assert(* p == val);
- break;
- }
- case 1:{ // set
- Uint32 item = len << 1;
- Uint32 idx = i; //rand() & 0xFFFFF; // & 0xFFFFF; //rand(); //(65536*i) / 10000;
- Uint32 val = rand();
-#if 0
- for(Uint32 j = 0; j < item; j += 2)
- {
- if (save[j] == idx)
- {
- item = j;
- break;
- }
- }
-#endif
- //ndbout_c("set(%d, %x)", idx, val);
- Uint32 *p = arr.set(idx);
- assert(* p);
- if (item == (len << 1))
- {
- *p = val;
- len++;
- }
- else
- {
- assert(* p == save[item+1]);
- * p = val;
- }
- save[item] = idx;
- save[item+1] = val;
- }
- }
- }
-}
-
-unsigned long long
-micro()
-{
- struct timeval tv;
- gettimeofday(&tv, 0);
- unsigned long long ret = tv.tv_sec;
- ret *= 1000000;
- ret += tv.tv_usec;
- return ret;
-}
-
-static
-void
-read(DynArr256& arr, int argc, char ** argv)
-{
- Uint32 cnt = 100000;
- Uint64 mbytes = 16*1024;
- Uint32 seed = time(0);
- Uint32 seq = 0, seqmask = 0;
-
- for (Uint32 i = 2; i<argc; i++)
- {
- if (strncmp(argv[i], "--mbytes=", sizeof("--mbytes=")-1) == 0)
- {
- mbytes = atoi(argv[i]+sizeof("--mbytes=")-1);
- if (argv[i][strlen(argv[i])-1] == 'g' ||
- argv[i][strlen(argv[i])-1] == 'G')
- mbytes *= 1024;
- }
- else if (strncmp(argv[i], "--cnt=", sizeof("--cnt=")-1) == 0)
- {
- cnt = atoi(argv[i]+sizeof("--cnt=")-1);
- }
- else if (strncmp(argv[i], "--seq", sizeof("--seq")-1) == 0)
- {
- seq = 1;
- }
- }
-
- /**
- * Populate with 5Mb
- */
- Uint32 maxidx = (1024*mbytes+31) / 32;
- Uint32 nodes = (maxidx+255) / 256;
- Uint32 pages = (nodes + 29)/ 30;
- ndbout_c("%lldmb data -> %d entries (%dkb)",
- mbytes, maxidx, 32*pages);
-
- for (Uint32 i = 0; i<maxidx; i++)
- {
- Uint32 *ptr = arr.set(i);
- assert(ptr);
- * ptr = i;
- }
-
- srand(seed);
-
- if (seq)
- {
- seq = rand();
- seqmask = ~(Uint32)0;
- }
-
- ndbout_c("Timing %d %s reads (seed: %u)", cnt,
- seq ? "sequential" : "random", seed);
-
- for (Uint32 i = 0; i<10; i++)
- {
- Uint32 sum0 = 0, sum1 = 0;
- Uint64 start = micro();
- for (Uint32 i = 0; i<cnt; i++)
- {
- Uint32 idx = ((rand() & (~seqmask)) + ((i + seq) & seqmask)) % maxidx;
- Uint32 *ptr = arr.get(idx);
- sum0 += idx;
- sum1 += *ptr;
- }
- start = micro() - start;
- float uspg = start; uspg /= cnt;
- ndbout_c("Elapsed %lldus diff: %d -> %f us/get", start, sum0 - sum1, uspg);
- }
-}
-
-static
-void
-write(DynArr256& arr, int argc, char ** argv)
-{
- Uint32 seq = 0, seqmask = 0;
- Uint32 cnt = 100000;
- Uint64 mbytes = 16*1024;
- Uint32 seed = time(0);
-
- for (Uint32 i = 2; i<argc; i++)
- {
- if (strncmp(argv[i], "--mbytes=", sizeof("--mbytes=")-1) == 0)
- {
- mbytes = atoi(argv[i]+sizeof("--mbytes=")-1);
- if (argv[i][strlen(argv[i])-1] == 'g' ||
- argv[i][strlen(argv[i])-1] == 'G')
- mbytes *= 1024;
- }
- else if (strncmp(argv[i], "--cnt=", sizeof("--cnt=")-1) == 0)
- {
- cnt = atoi(argv[i]+sizeof("--cnt=")-1);
- }
- else if (strncmp(argv[i], "--seq", sizeof("--seq")-1) == 0)
- {
- seq = 1;
- }
- }
-
- /**
- * Populate with 5Mb
- */
- Uint32 maxidx = (1024*mbytes+31) / 32;
- Uint32 nodes = (maxidx+255) / 256;
- Uint32 pages = (nodes + 29)/ 30;
- ndbout_c("%lldmb data -> %d entries (%dkb)",
- mbytes, maxidx, 32*pages);
-
- srand(seed);
-
- if (seq)
- {
- seq = rand();
- seqmask = ~(Uint32)0;
- }
-
- ndbout_c("Timing %d %s writes (seed: %u)", cnt,
- seq ? "sequential" : "random", seed);
- for (Uint32 i = 0; i<10; i++)
- {
- Uint64 start = micro();
- for (Uint32 i = 0; i<cnt; i++)
- {
- Uint32 idx = ((rand() & (~seqmask)) + ((i + seq) & seqmask)) % maxidx;
- Uint32 *ptr = arr.set(idx);
- *ptr = i;
- }
- start = micro() - start;
- float uspg = start; uspg /= cnt;
- ndbout_c("Elapsed %lldus -> %f us/set", start, uspg);
- DynArr256::ReleaseIterator iter;
- arr.init(iter);
- Uint32 val;
- while(arr.release(iter, &val));
- }
-}
-
-int
-main(int argc, char** argv)
-{
- if (0)
- {
- for (Uint32 i = 0; i<30; i++)
- {
- Uint32 b = (i + 1) >> 4;
- Uint32 p = i - (b << 4) + b;
- printf("[ %d %d %d ]\n", i, b, p);
- }
- return 0;
- }
-
- Pool_context pc;
- pc.m_block = &block;
-
- Resource_limit rl;
- rl.m_min = 0;
- rl.m_max = 10000;
- rl.m_resource_id = 0;
- mm.set_resource_limit(rl);
- if(!mm.init())
- {
- abort();
- }
-
- DynArr256Pool pool;
- pool.init(0x2001, pc);
-
- DynArr256::Head head;
- DynArr256 arr(pool, head);
-
- if (strcmp(argv[1], "--simple") == 0)
- simple(arr, argc, argv);
- else if (strcmp(argv[1], "--basic") == 0)
- basic(arr, argc, argv);
- else if (strcmp(argv[1], "--read") == 0)
- read(arr, argc, argv);
- else if (strcmp(argv[1], "--write") == 0)
- write(arr, argc, argv);
-
- DynArr256::ReleaseIterator iter;
- arr.init(iter);
- Uint32 cnt = 0, val;
- while (arr.release(iter, &val)) cnt++;
-
- ndbout_c("allocatedpages: %d allocatednodes: %d releasednodes: %d"
- " releasecnt: %d",
- allocatedpages,
- allocatednodes,
- releasednodes,
- cnt);
-
- return 0;
-#if 0
- printf("sizeof(DA256Page): %d\n", sizeof(DA256Page));
-
- DA256Page page;
-
- for (Uint32 i = 0; i<10000; i++)
- {
- Uint32 arg = rand() & 255;
- Uint32 base = 0;
- Uint32 idx = arg & 256;
- printf("%d\n", arg);
-
- assert(base <= 30);
-
- if (idx == 255)
- {
- Uint32 b = (base + 1) >> 4;
- Uint32 p = base - (b << 4) + b;
- Uint32 magic = page.m_header[b].m_magic;
- Uint32 retVal = page.m_header[b].m_data[p];
-
- require(magic & (1 << p));
- return retVal;
- }
- else
- {
- // 4 bit extra offset per idx
- Uint32 line = idx / 15;
- Uint32 off = idx % 15;
-
- {
- Uint32 pos = 1 + idx + line;
- Uint32 magic = pos & ~15;
-
- Uint32 * ptr = (Uint32*)&page.m_nodes[base];
- assert((ptr + pos) == &page.m_nodes[base].m_lines[line].m_data[off]);
- assert((ptr + magic) == &page.m_nodes[base].m_lines[line].m_magic);
- }
- }
- }
-#endif
-}
-
-Uint32 g_currentStartPhase;
-Uint32 g_start_type;
-NdbNodeBitmask g_nowait_nodes;
-
-void childExit(int code, Uint32 currentStartPhase)
-{
- abort();
-}
-
-void childAbort(int code, Uint32 currentStartPhase)
-{
- abort();
-}
-
-void childReportError(int error)
-{
- abort();
-}
-
-void
-UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
-}
-
-void
-UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){
-}
-
-void
-UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){
-}
-
-void
-UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){
-}
-
-#include <SimBlockList.hpp>
-
-void
-SimBlockList::unload()
-{
-
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/DynArr256.hpp b/storage/ndb/src/kernel/vm/DynArr256.hpp
deleted file mode 100644
index 162f81d3173..00000000000
--- a/storage/ndb/src/kernel/vm/DynArr256.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DYNARR256_HPP
-#define DYNARR256_HPP
-
-#include "Pool.hpp"
-
-class DynArr256;
-struct DA256Page;
-
-class DynArr256Pool
-{
- friend class DynArr256;
-public:
- DynArr256Pool();
-
- void init(Uint32 type_id, const Pool_context& pc);
-
-protected:
- Uint32 m_type_id;
- Uint32 m_first_free;
- Pool_context m_ctx;
- struct DA256Page* m_memroot;
-
-private:
- Uint32 seize();
- void release(Uint32);
-};
-
-class DynArr256
-{
-public:
- struct Head
- {
- Head() { m_ptr_i = RNIL; m_sz = 0;}
-
- Uint32 m_ptr_i;
- Uint32 m_sz;
-
- bool isEmpty() const { return m_sz == 0;}
- };
-
- DynArr256(DynArr256Pool & pool, Head& head) :
- m_head(head), m_pool(pool){}
-
- Uint32* set(Uint32 pos);
- Uint32* get(Uint32 pos) const ;
-
- struct ReleaseIterator
- {
- Uint32 m_sz;
- Uint32 m_pos;
- Uint32 m_ptr_i[5];
- };
-
- void init(ReleaseIterator&);
- /**
- * return 0 - done
- * 1 - data (in retptr)
- * 2 - nodata
- */
- Uint32 release(ReleaseIterator&, Uint32* retptr);
-protected:
- Head & m_head;
- DynArr256Pool & m_pool;
-
- bool expand(Uint32 pos);
- void handle_invalid_ptr(Uint32 pos, Uint32 ptrI, Uint32 p0);
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/Emulator.cpp b/storage/ndb/src/kernel/vm/Emulator.cpp
deleted file mode 100644
index 6610d88fba0..00000000000
--- a/storage/ndb/src/kernel/vm/Emulator.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "Emulator.hpp"
-#include <FastScheduler.hpp>
-#include <SignalLoggerManager.hpp>
-#include <TransporterRegistry.hpp>
-#include <TimeQueue.hpp>
-
-#include "Configuration.hpp"
-#include "WatchDog.hpp"
-#include "ThreadConfig.hpp"
-#include "SimBlockList.hpp"
-
-#include <NodeState.hpp>
-#include "ndbd_malloc_impl.hpp"
-
-#include <NdbMem.h>
-#include <NdbMutex.h>
-#include <NdbSleep.h>
-
-#include <EventLogger.hpp>
-
-void childExit(int code, Uint32 currentStartPhase);
-void childAbort(int code, Uint32 currentStartPhase);
-
-extern "C" {
- extern void (* ndb_new_handler)();
-}
-extern EventLogger g_eventLogger;
-extern my_bool opt_core;
-// instantiated and updated in NdbcntrMain.cpp
-extern Uint32 g_currentStartPhase;
-
-/**
- * Declare the global variables
- */
-
-#ifndef NO_EMULATED_JAM
-Uint8 theEmulatedJam[EMULATED_JAM_SIZE * 4];
-Uint32 theEmulatedJamIndex = 0;
-Uint32 theEmulatedJamBlockNumber = 0;
-#endif
-
- GlobalData globalData;
-
- TimeQueue globalTimeQueue;
- FastScheduler globalScheduler;
- TransporterRegistry globalTransporterRegistry;
-
-#ifdef VM_TRACE
- SignalLoggerManager globalSignalLoggers;
-#endif
-
-EmulatorData globalEmulatorData;
-NdbMutex * theShutdownMutex = 0;
-int simulate_error_during_shutdown= 0;
-
-EmulatorData::EmulatorData(){
- theConfiguration = 0;
- theWatchDog = 0;
- theThreadConfig = 0;
- theSimBlockList = 0;
- theShutdownMutex = 0;
- m_socket_server = 0;
- m_mem_manager = 0;
-}
-
-void
-ndb_new_handler_impl(){
- ERROR_SET(fatal, NDBD_EXIT_MEMALLOC, "New handler", "");
-}
-
-void
-EmulatorData::create(){
- NdbMem_Create();
-
- theConfiguration = new Configuration();
- theWatchDog = new WatchDog();
- theThreadConfig = new ThreadConfig();
- theSimBlockList = new SimBlockList();
- m_socket_server = new SocketServer();
- m_mem_manager = new Ndbd_mem_manager();
-
- theShutdownMutex = NdbMutex_Create();
-
- ndb_new_handler = ndb_new_handler_impl;
-}
-
-void
-EmulatorData::destroy(){
- if(theConfiguration)
- delete theConfiguration; theConfiguration = 0;
- if(theWatchDog)
- delete theWatchDog; theWatchDog = 0;
- if(theThreadConfig)
- delete theThreadConfig; theThreadConfig = 0;
- if(theSimBlockList)
- delete theSimBlockList; theSimBlockList = 0;
- if(m_socket_server)
- delete m_socket_server; m_socket_server = 0;
- NdbMutex_Destroy(theShutdownMutex);
- if (m_mem_manager)
- delete m_mem_manager; m_mem_manager = 0;
-
- NdbMem_Destroy();
-}
-
-void
-NdbShutdown(NdbShutdownType type,
- NdbRestartType restartType)
-{
- if(type == NST_ErrorInsert){
- type = NST_Restart;
- restartType = (NdbRestartType)
- globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
- if(restartType == NRT_Default){
- type = NST_ErrorHandler;
- globalEmulatorData.theConfiguration->stopOnError(true);
- }
- }
-
- if((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex
- (NdbMutex_Trylock(theShutdownMutex) == 0)){
- globalData.theRestartFlag = perform_stop;
-
- bool restart = false;
-
- if((type != NST_Normal &&
- globalEmulatorData.theConfiguration->stopOnError() == false) ||
- type == NST_Restart) {
-
- restart = true;
- }
-
-
- const char * shutting = "shutting down";
- if(restart){
- shutting = "restarting";
- }
-
- switch(type){
- case NST_Normal:
- g_eventLogger.info("Shutdown initiated");
- break;
- case NST_Watchdog:
- g_eventLogger.info("Watchdog %s system", shutting);
- break;
- case NST_ErrorHandler:
- g_eventLogger.info("Error handler %s system", shutting);
- break;
- case NST_ErrorHandlerSignal:
- g_eventLogger.info("Error handler signal %s system", shutting);
- break;
- case NST_ErrorHandlerStartup:
- g_eventLogger.info("Error handler startup %s system", shutting);
- break;
- case NST_Restart:
- g_eventLogger.info("Restarting system");
- break;
- default:
- g_eventLogger.info("Error handler %s system (unknown type: %u)",
- shutting, (unsigned)type);
- type = NST_ErrorHandler;
- break;
- }
-
- const char * exitAbort = 0;
- if (opt_core)
- exitAbort = "aborting";
- else
- exitAbort = "exiting";
-
- if(type == NST_Watchdog){
- /**
- * Very serious, don't attempt to free, just die!!
- */
- g_eventLogger.info("Watchdog shutdown completed - %s", exitAbort);
- if (opt_core)
- {
- childAbort(-1,g_currentStartPhase);
- }
- else
- {
- childExit(-1,g_currentStartPhase);
- }
- }
-
-#ifndef NDB_WIN32
- if (simulate_error_during_shutdown) {
- kill(getpid(), simulate_error_during_shutdown);
- while(true)
- NdbSleep_MilliSleep(10);
- }
-#endif
-
- globalEmulatorData.theWatchDog->doStop();
-
-#ifdef VM_TRACE
- FILE * outputStream = globalSignalLoggers.setOutputStream(0);
- if(outputStream != 0)
- fclose(outputStream);
-#endif
-
- /**
- * Stop all transporter connection attempts and accepts
- */
- globalEmulatorData.m_socket_server->stopServer();
- globalEmulatorData.m_socket_server->stopSessions();
- globalTransporterRegistry.stop_clients();
-
- /**
- * Stop transporter communication with other nodes
- */
- globalTransporterRegistry.stopSending();
- globalTransporterRegistry.stopReceiving();
-
- /**
- * Remove all transporters
- */
- globalTransporterRegistry.removeAll();
-
-#ifdef VM_TRACE
-#define UNLOAD (type != NST_ErrorHandler && type != NST_Watchdog)
-#else
-#define UNLOAD true
-#endif
- if(UNLOAD){
- globalEmulatorData.theSimBlockList->unload();
- globalEmulatorData.destroy();
- }
-
- if(type != NST_Normal && type != NST_Restart){
- // Signal parent that error occured during startup
- if (type == NST_ErrorHandlerStartup)
- kill(getppid(), SIGUSR1);
- g_eventLogger.info("Error handler shutdown completed - %s", exitAbort);
- if (opt_core)
- {
- childAbort(-1,g_currentStartPhase);
- }
- else
- {
- childExit(-1,g_currentStartPhase);
- }
- }
-
- /**
- * This is a normal restart, depend on angel
- */
- if(type == NST_Restart){
- childExit(restartType,g_currentStartPhase);
- }
-
- g_eventLogger.info("Shutdown completed - exiting");
- } else {
- /**
- * Shutdown is already in progress
- */
-
- /**
- * If this is the watchdog, kill system the hard way
- */
- if (type== NST_Watchdog){
- g_eventLogger.info("Watchdog is killing system the hard way");
-#if defined VM_TRACE
- childAbort(-1,g_currentStartPhase);
-#else
- childExit(-1,g_currentStartPhase);
-#endif
- }
-
- while(true)
- NdbSleep_MilliSleep(10);
- }
-}
-
diff --git a/storage/ndb/src/kernel/vm/Emulator.hpp b/storage/ndb/src/kernel/vm/Emulator.hpp
deleted file mode 100644
index 7168e043b15..00000000000
--- a/storage/ndb/src/kernel/vm/Emulator.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef EMULATOR_H
-#define EMULATOR_H
-
-//===========================================================================
-//
-// .DESCRIPTION
-// This is the main fuction for the AXE VM emulator.
-// It contains some global objects and a run method.
-//
-//===========================================================================
-#include <kernel_types.h>
-#include <TransporterRegistry.hpp>
-
-extern class JobTable globalJobTable;
-extern class TimeQueue globalTimeQueue;
-extern class FastScheduler globalScheduler;
-extern class TransporterRegistry globalTransporterRegistry;
-extern struct GlobalData globalData;
-
-#ifdef VM_TRACE
-extern class SignalLoggerManager globalSignalLoggers;
-#endif
-
-#ifndef NO_EMULATED_JAM
- #define EMULATED_JAM_SIZE 1024
- #define JAM_MASK ((EMULATED_JAM_SIZE * 4) - 1)
-
- extern Uint8 theEmulatedJam[];
- extern Uint32 theEmulatedJamIndex;
- // last block entry, used in dumpJam() if jam contains no block entries
- extern Uint32 theEmulatedJamBlockNumber;
-#else
- const Uint8 theEmulatedJam[]=0;
- const Uint32 theEmulatedJamIndex=0;
-#endif
-
-struct EmulatorData {
- class Configuration * theConfiguration;
- class WatchDog * theWatchDog;
- class ThreadConfig * theThreadConfig;
- class SimBlockList * theSimBlockList;
- class SocketServer * m_socket_server;
- class Ndbd_mem_manager * m_mem_manager;
-
- /**
- * Constructor
- *
- * Sets all the pointers to NULL
- */
- EmulatorData();
-
- /**
- * Create all the objects
- */
- void create();
-
- /**
- * Destroys all the objects
- */
- void destroy();
-};
-
-extern struct EmulatorData globalEmulatorData;
-
-enum NdbShutdownType {
- NST_Normal,
- NST_Watchdog,
- NST_ErrorHandler,
- NST_ErrorHandlerSignal,
- NST_Restart,
- NST_ErrorInsert,
- NST_ErrorHandlerStartup
-};
-
-enum NdbRestartType {
- NRT_Default = 0,
- NRT_NoStart_Restart = 1, // -n
- NRT_DoStart_Restart = 2, //
- NRT_NoStart_InitialStart = 3, // -n -i
- NRT_DoStart_InitialStart = 4 // -i
-};
-
-/**
- * Shutdown/restart Ndb
- *
- * @param type - Type of shutdown/restart
- * @param restartType - Type of restart (only valid if type == NST_Restart)
- */
-void
-NdbShutdown(NdbShutdownType type,
- NdbRestartType restartType = NRT_Default);
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/FastScheduler.cpp b/storage/ndb/src/kernel/vm/FastScheduler.cpp
deleted file mode 100644
index e5fbe0b1242..00000000000
--- a/storage/ndb/src/kernel/vm/FastScheduler.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "FastScheduler.hpp"
-#include "RefConvert.hpp"
-
-#include "Emulator.hpp"
-#include "VMSignal.hpp"
-
-#include <SignalLoggerManager.hpp>
-#include <BlockNumbers.h>
-#include <GlobalSignalNumbers.h>
-#include <signaldata/EventReport.hpp>
-#include "LongSignal.hpp"
-#include <NdbTick.h>
-
-#define MIN_NUMBER_OF_SIG_PER_DO_JOB 64
-#define MAX_NUMBER_OF_SIG_PER_DO_JOB 2048
-#define EXTRA_SIGNALS_PER_DO_JOB 32
-
-FastScheduler::FastScheduler()
-{
- // These constants work for sun only, but they should be initated from
- // Emulator.C as soon as VMTime has been initiated.
- theJobBuffers[0].newBuffer(JBASIZE);
- theJobBuffers[1].newBuffer(JBBSIZE);
- theJobBuffers[2].newBuffer(JBCSIZE);
- theJobBuffers[3].newBuffer(JBDSIZE);
- clear();
-}
-
-FastScheduler::~FastScheduler()
-{
-}
-
-void
-FastScheduler::clear()
-{
- int i;
- // Make sure the restart signals are not sent too early
- // the prio is set back in 'main' using the 'ready' method.
- globalData.highestAvailablePrio = LEVEL_IDLE;
- globalData.sendPackedActivated = 0;
- globalData.activateSendPacked = 0;
- for (i = 0; i < JB_LEVELS; i++){
- theJobBuffers[i].clear();
- }
- globalData.JobCounter = 0;
- globalData.JobLap = 0;
- globalData.loopMax = 32;
- globalData.VMSignals[0].header.theSignalId = 0;
-
- theDoJobTotalCounter = 0;
- theDoJobCallCounter = 0;
-}
-
-void
-FastScheduler::activateSendPacked()
-{
- globalData.sendPackedActivated = 1;
- globalData.activateSendPacked = 0;
- globalData.loopMax = 2048;
-}//FastScheduler::activateSendPacked()
-
-//------------------------------------------------------------------------
-// sendPacked is executed at the end of the loop.
-// To ensure that we don't send any messages before executing all local
-// packed signals we do another turn in the loop (unless we have already
-// executed too many signals in the loop).
-//------------------------------------------------------------------------
-void
-FastScheduler::doJob()
-{
- Uint32 loopCount = 0;
- Uint32 TminLoops = getBOccupancy() + EXTRA_SIGNALS_PER_DO_JOB;
- Uint32 TloopMax = (Uint32)globalData.loopMax;
- if (TminLoops < TloopMax) {
- TloopMax = TminLoops;
- }//if
- if (TloopMax < MIN_NUMBER_OF_SIG_PER_DO_JOB) {
- TloopMax = MIN_NUMBER_OF_SIG_PER_DO_JOB;
- }//if
- register Signal* signal = getVMSignals();
- register Uint32 tHighPrio= globalData.highestAvailablePrio;
- do{
- while ((tHighPrio < LEVEL_IDLE) && (loopCount < TloopMax)) {
- // signal->garbage_register();
- // To ensure we find bugs quickly
- register Uint32 gsnbnr = theJobBuffers[tHighPrio].retrieve(signal);
- register BlockNumber reg_bnr = gsnbnr & 0xFFF;
- register GlobalSignalNumber reg_gsn = gsnbnr >> 16;
- globalData.incrementWatchDogCounter(1);
- if (reg_bnr > 0) {
- Uint32 tJobCounter = globalData.JobCounter;
- Uint32 tJobLap = globalData.JobLap;
- SimulatedBlock* b = globalData.getBlock(reg_bnr);
- theJobPriority[tJobCounter] = (Uint8)tHighPrio;
- globalData.JobCounter = (tJobCounter + 1) & 4095;
- globalData.JobLap = tJobLap + 1;
-
-#ifdef VM_TRACE_TIME
- Uint32 us1, us2;
- Uint64 ms1, ms2;
- NdbTick_CurrentMicrosecond(&ms1, &us1);
- b->m_currentGsn = reg_gsn;
-#endif
-
- getSections(signal->header.m_noOfSections, signal->m_sectionPtr);
-#ifdef VM_TRACE
- {
- if (globalData.testOn) {
- signal->header.theVerId_signalNumber = reg_gsn;
- signal->header.theReceiversBlockNumber = reg_bnr;
-
- globalSignalLoggers.executeSignal(signal->header,
- tHighPrio,
- &signal->theData[0],
- globalData.ownId,
- signal->m_sectionPtr,
- signal->header.m_noOfSections);
- }//if
- }
-#endif
- b->executeFunction(reg_gsn, signal);
- releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
- signal->header.m_noOfSections = 0;
-#ifdef VM_TRACE_TIME
- NdbTick_CurrentMicrosecond(&ms2, &us2);
- Uint64 diff = ms2;
- diff -= ms1;
- diff *= 1000000;
- diff += us2;
- diff -= us1;
- b->addTime(reg_gsn, diff);
-#endif
- tHighPrio = globalData.highestAvailablePrio;
- } else {
- tHighPrio++;
- globalData.highestAvailablePrio = tHighPrio;
- }//if
- loopCount++;
- }//while
- sendPacked();
- tHighPrio = globalData.highestAvailablePrio;
- if(getBOccupancy() > MAX_OCCUPANCY)
- {
- if(loopCount != TloopMax)
- abort();
- assert( loopCount == TloopMax );
- TloopMax += 512;
- }
- } while ((getBOccupancy() > MAX_OCCUPANCY) ||
- ((loopCount < TloopMax) &&
- (tHighPrio < LEVEL_IDLE)));
-
- theDoJobCallCounter ++;
- theDoJobTotalCounter += loopCount;
- if (theDoJobCallCounter == 8192) {
- reportDoJobStatistics(theDoJobTotalCounter >> 13);
- theDoJobCallCounter = 0;
- theDoJobTotalCounter = 0;
- }//if
-
-}//FastScheduler::doJob()
-
-void FastScheduler::sendPacked()
-{
- if (globalData.sendPackedActivated == 1) {
- SimulatedBlock* b_lqh = globalData.getBlock(DBLQH);
- SimulatedBlock* b_tc = globalData.getBlock(DBTC);
- SimulatedBlock* b_tup = globalData.getBlock(DBTUP);
- Signal* signal = getVMSignals();
- b_lqh->executeFunction(GSN_SEND_PACKED, signal);
- b_tc->executeFunction(GSN_SEND_PACKED, signal);
- b_tup->executeFunction(GSN_SEND_PACKED, signal);
- return;
- } else if (globalData.activateSendPacked == 0) {
- return;
- } else {
- activateSendPacked();
- }//if
- return;
-}//FastScheduler::sendPacked()
-
-Uint32
-APZJobBuffer::retrieve(Signal* signal)
-{
- Uint32 tOccupancy = theOccupancy;
- Uint32 myRPtr = rPtr;
- BufferEntry& buf = buffer[myRPtr];
- Uint32 gsnbnr;
- Uint32 cond = (++myRPtr == bufSize) - 1;
- Uint32 tRecBlockNo = buf.header.theReceiversBlockNumber;
-
- if (tOccupancy != 0) {
- if (tRecBlockNo != 0) {
- // Transform protocol to signal.
- rPtr = myRPtr & cond;
- theOccupancy = tOccupancy - 1;
- gsnbnr = buf.header.theVerId_signalNumber << 16 | tRecBlockNo;
-
- Uint32 tSignalId = globalData.theSignalId;
- Uint32 tLength = buf.header.theLength;
- Uint32 tFirstData = buf.theDataRegister[0];
- signal->header = buf.header;
-
- // Recall our signal Id for restart purposes
- buf.header.theSignalId = tSignalId;
- globalData.theSignalId = tSignalId + 1;
-
- Uint32* tDataRegPtr = &buf.theDataRegister[0];
- Uint32* tSigDataPtr = signal->getDataPtrSend();
- *tSigDataPtr = tFirstData;
- tDataRegPtr++;
- tSigDataPtr++;
- Uint32 tLengthCopied = 1;
- while (tLengthCopied < tLength) {
- Uint32 tData0 = tDataRegPtr[0];
- Uint32 tData1 = tDataRegPtr[1];
- Uint32 tData2 = tDataRegPtr[2];
- Uint32 tData3 = tDataRegPtr[3];
-
- tDataRegPtr += 4;
- tLengthCopied += 4;
-
- tSigDataPtr[0] = tData0;
- tSigDataPtr[1] = tData1;
- tSigDataPtr[2] = tData2;
- tSigDataPtr[3] = tData3;
- tSigDataPtr += 4;
- }//while
-
- /**
- * Copy sections references (copy all without if-statements)
- */
- tDataRegPtr = &buf.theDataRegister[tLength];
- SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
- Uint32 tData0 = tDataRegPtr[0];
- Uint32 tData1 = tDataRegPtr[1];
- Uint32 tData2 = tDataRegPtr[2];
-
- tSecPtr[0].i = tData0;
- tSecPtr[1].i = tData1;
- tSecPtr[2].i = tData2;
-
- //---------------------------------------------------------
- // Prefetch of buffer[rPtr] is done here. We prefetch for
- // read both the first cache line and the next 64 byte
- // entry
- //---------------------------------------------------------
- PREFETCH((void*)&buffer[rPtr]);
- PREFETCH((void*)(((char*)&buffer[rPtr]) + 64));
- return gsnbnr;
- } else {
- bnr_error();
- return 0; // Will never come here, simply to keep GCC happy.
- }//if
- } else {
- //------------------------------------------------------------
- // The Job Buffer was empty, signal this by return zero.
- //------------------------------------------------------------
- return 0;
- }//if
-}//APZJobBuffer::retrieve()
-
-void
-APZJobBuffer::signal2buffer(Signal* signal,
- BlockNumber bnr, GlobalSignalNumber gsn,
- BufferEntry& buf)
-{
- Uint32 tSignalId = globalData.theSignalId;
- Uint32 tFirstData = signal->theData[0];
- Uint32 tLength = signal->header.theLength;
- Uint32 tSigId = buf.header.theSignalId;
-
- buf.header = signal->header;
- buf.header.theVerId_signalNumber = gsn;
- buf.header.theReceiversBlockNumber = bnr;
- buf.header.theSendersSignalId = tSignalId - 1;
- buf.header.theSignalId = tSigId;
- buf.theDataRegister[0] = tFirstData;
-
- Uint32 tLengthCopied = 1;
- Uint32* tSigDataPtr = &signal->theData[1];
- Uint32* tDataRegPtr = &buf.theDataRegister[1];
- while (tLengthCopied < tLength) {
- Uint32 tData0 = tSigDataPtr[0];
- Uint32 tData1 = tSigDataPtr[1];
- Uint32 tData2 = tSigDataPtr[2];
- Uint32 tData3 = tSigDataPtr[3];
-
- tLengthCopied += 4;
- tSigDataPtr += 4;
-
- tDataRegPtr[0] = tData0;
- tDataRegPtr[1] = tData1;
- tDataRegPtr[2] = tData2;
- tDataRegPtr[3] = tData3;
- tDataRegPtr += 4;
- }//while
-
- /**
- * Copy sections references (copy all without if-statements)
- */
- tDataRegPtr = &buf.theDataRegister[tLength];
- SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
- Uint32 tData0 = tSecPtr[0].i;
- Uint32 tData1 = tSecPtr[1].i;
- Uint32 tData2 = tSecPtr[2].i;
- tDataRegPtr[0] = tData0;
- tDataRegPtr[1] = tData1;
- tDataRegPtr[2] = tData2;
-}//APZJobBuffer::signal2buffer()
-
-void
-APZJobBuffer::insert(const SignalHeader * const sh,
- const Uint32 * const theData, const Uint32 secPtrI[3]){
- 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;
-
- buf.header = * sh;
- const Uint32 len = buf.header.theLength;
- memcpy(buf.theDataRegister, theData, 4 * len);
- memcpy(&buf.theDataRegister[len], &secPtrI[0], 4 * 3);
- //---------------------------------------------------------
- // Prefetch of buffer[wPtr] is done here. We prefetch for
- // write both the first cache line and the next 64 byte
- // entry
- //---------------------------------------------------------
- WRITEHINT((void*)&buffer[wPtr]);
- WRITEHINT((void*)(((char*)&buffer[wPtr]) + 64));
-
- } else {
- jbuf_error();
- }//if
-}
-APZJobBuffer::APZJobBuffer()
- : bufSize(0), buffer(NULL), memRef(NULL)
-{
- clear();
-}
-
-APZJobBuffer::~APZJobBuffer()
-{
- delete [] buffer;
-}
-
-void
-APZJobBuffer::newBuffer(int 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;
-}
-
-void
-APZJobBuffer::clear()
-{
- rPtr = 0;
- wPtr = 0;
- theOccupancy = 0;
-}
-
-/**
- * Function prototype for print_restart
- *
- * Defined later in this file
- */
-void print_restart(FILE * output, Signal* signal, Uint32 aLevel);
-
-void FastScheduler::dumpSignalMemory(FILE * output)
-{
- SignalT<25> signalT;
- Signal &signal= *(Signal*)&signalT;
- Uint32 ReadPtr[5];
- Uint32 tJob;
- Uint32 tLastJob;
-
- fprintf(output, "\n");
-
- if (globalData.JobLap > 4095) {
- if (globalData.JobCounter != 0)
- tJob = globalData.JobCounter - 1;
- else
- tJob = 4095;
- tLastJob = globalData.JobCounter;
- } else {
- if (globalData.JobCounter == 0)
- return; // No signals sent
- else {
- tJob = globalData.JobCounter - 1;
- tLastJob = 4095;
- }
- }
- ReadPtr[0] = theJobBuffers[0].getReadPtr();
- ReadPtr[1] = theJobBuffers[1].getReadPtr();
- ReadPtr[2] = theJobBuffers[2].getReadPtr();
- ReadPtr[3] = theJobBuffers[3].getReadPtr();
-
- do {
- unsigned char tLevel = theJobPriority[tJob];
- globalData.incrementWatchDogCounter(4);
- if (ReadPtr[tLevel] == 0)
- ReadPtr[tLevel] = theJobBuffers[tLevel].getBufSize() - 1;
- else
- ReadPtr[tLevel]--;
-
- theJobBuffers[tLevel].retrieveDump(&signal, ReadPtr[tLevel]);
- print_restart(output, &signal, tLevel);
-
- if (tJob == 0)
- tJob = 4095;
- else
- tJob--;
-
- } while (tJob != tLastJob);
- fflush(output);
-}
-
-void
-FastScheduler::prio_level_error()
-{
- ERROR_SET(ecError, NDBD_EXIT_WRONG_PRIO_LEVEL,
- "Wrong Priority Level", "FastScheduler.C");
-}
-
-void
-jbuf_error()
-{
- ERROR_SET(ecError, NDBD_EXIT_BLOCK_JBUFCONGESTION,
- "Job Buffer Full", "APZJobBuffer.C");
-}
-
-void
-bnr_error()
-{
- ERROR_SET(ecError, NDBD_EXIT_BLOCK_BNR_ZERO,
- "Block Number Zero", "FastScheduler.C");
-}
-
-void
-print_restart(FILE * output, Signal* signal, Uint32 aLevel)
-{
- fprintf(output, "--------------- Signal ----------------\n");
- SignalLoggerManager::printSignalHeader(output,
- signal->header,
- aLevel,
- globalData.ownId,
- true);
- SignalLoggerManager::printSignalData (output,
- signal->header,
- &signal->theData[0]);
-}
-
-/**
- * This method used to be a Cmvmi member function
- * but is now a "ordinary" function"
- *
- * See TransporterCallback.cpp for explanation
- */
-void
-FastScheduler::reportDoJobStatistics(Uint32 tMeanLoopCount) {
- SignalT<2> signalT;
- Signal &signal= *(Signal*)&signalT;
-
- memset(&signal.header, 0, sizeof(signal.header));
- signal.header.theLength = 2;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, 0);
-
- signal.theData[0] = NDB_LE_JobStatistic;
- signal.theData[1] = tMeanLoopCount;
-
- execute(&signal, JBA, CMVMI, GSN_EVENT_REP);
-}
-
diff --git a/storage/ndb/src/kernel/vm/FastScheduler.hpp b/storage/ndb/src/kernel/vm/FastScheduler.hpp
deleted file mode 100644
index f36b432ed4a..00000000000
--- a/storage/ndb/src/kernel/vm/FastScheduler.hpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef FastScheduler_H
-#define FastScheduler_H
-
-#include <VMSignal.hpp>
-#include <kernel_types.h>
-#include <Prio.hpp>
-#include <SignalLoggerManager.hpp>
-#include <SimulatedBlock.hpp>
-#include <ErrorHandlingMacros.hpp>
-#include <GlobalData.hpp>
-#include <TransporterDefinitions.hpp>
-#include <prefetch.h>
-
-#define MAX_OCCUPANCY 1024
-
-#define JBASIZE 1280 // Jobs which have dead lines to meet use this level
-#define JBBSIZE 4096 // Most jobs use this level
-#define JBCSIZE 64 // Only used by STTOR and STTORRY currently
-#define JBDSIZE 4096 // Time Queue uses this level for storage, not supported
- // as priority level
-void bnr_error();
-void jbuf_error();
-class Signal;
-class Block;
-
-class BufferEntry
-{
-public:
- SignalHeader header;
- Uint32 theDataRegister[25];
-};
-
-class APZJobBuffer
-{
-public:
- APZJobBuffer();
- ~APZJobBuffer();
-
- void newBuffer(int size);
-
- void insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn);
- void insert(const SignalHeader * const sh, const Uint32 * const theData, const Uint32 secPtrI[3]);
- void insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn,
- Uint32 myWPtr);
-
- Uint32 retrieve(Signal *signal);
- void retrieve(Signal *signal, Uint32 myRptr);
-
- /**
- * Used when dumping to trace file
- */
- void retrieveDump(Signal *signal, Uint32 myRptr);
-
- void clear();
- Uint32 getOccupancy() const;
-
- Uint32 getReadPtr() const;
- Uint32 getWritePtr() const;
- Uint32 getBufSize() const;
-
-private:
- void signal2buffer(Signal* signal, BlockNumber bnr,
- GlobalSignalNumber gsn, BufferEntry& buf);
- Uint32 rPtr;
- Uint32 wPtr;
- Uint32 theOccupancy;
- Uint32 bufSize;
- BufferEntry* buffer;
- BufferEntry* memRef;
-};
-
-
-class FastScheduler
-{
-public:
- FastScheduler();
- ~FastScheduler();
-
- void doJob();
- int checkDoJob();
-
- void activateSendPacked();
-
- void execute(Signal* signal,
- Priority prio,
- BlockNumber bnr,
- GlobalSignalNumber gsn);
-
- void execute(const SignalHeader * const sh,
- Uint8 prio, const Uint32 * const theData, const Uint32 secPtr[3]);
-
- void clear();
- Signal* getVMSignals();
-
- void dumpSignalMemory(FILE * output);
- Priority highestAvailablePrio() const;
- Uint32 getBOccupancy() const;
- void sendPacked();
-
- void insertTimeQueue(Signal* aSignal, BlockNumber bnr,
- GlobalSignalNumber gsn, Uint32 aIndex);
- void scheduleTimeQueue(Uint32 aIndex);
-
-private:
- void highestAvailablePrio(Priority prio);
- void reportJob(Priority aPriority);
- void prio_level_error();
-
- Uint32 theDoJobTotalCounter;
- Uint32 theDoJobCallCounter;
- Uint8 theJobPriority[4096];
- APZJobBuffer theJobBuffers[JB_LEVELS];
-
- void reportDoJobStatistics(Uint32 meanLoopCount);
-};
-
-inline
-Uint32
-FastScheduler::getBOccupancy() const {
- return theJobBuffers[JBB].getOccupancy();
-}//FastScheduler::getBOccupancy()
-
-inline
-int
-FastScheduler::checkDoJob()
-{
- /*
- * Job buffer overload protetction
- * If the job buffer B is filled over a certain limit start
- * to execute the signals in the job buffer's
- */
- if (getBOccupancy() < MAX_OCCUPANCY) {
- return 0;
- } else {
- doJob();
- return 1;
- }//if
-}//FastScheduler::checkDoJob()
-
-inline
-void
-FastScheduler::reportJob(Priority aPriority)
-{
- Uint32 tJobCounter = globalData.JobCounter;
- Uint32 tJobLap = globalData.JobLap;
- theJobPriority[tJobCounter] = (Uint8)aPriority;
- globalData.JobCounter = (tJobCounter + 1) & 4095;
- globalData.JobLap = tJobLap + 1;
-}
-
-inline
-Priority
-FastScheduler::highestAvailablePrio() const
-{
- return (Priority)globalData.highestAvailablePrio;
-}
-
-inline
-void
-FastScheduler::highestAvailablePrio(Priority prio)
-{
- globalData.highestAvailablePrio = (Uint32)prio;
-}
-
-inline
-Signal*
-FastScheduler::getVMSignals()
-{
- return &globalData.VMSignals[0];
-}
-
-
-// Inserts of a protocol object into the Job Buffer.
-inline
-void
-FastScheduler::execute(const SignalHeader * const sh, Uint8 prio,
- const Uint32 * const theData, const Uint32 secPtrI[3]){
-#ifdef VM_TRACE
- if (prio >= LEVEL_IDLE)
- prio_level_error();
-#endif
-
- theJobBuffers[prio].insert(sh, theData, secPtrI);
- if (prio < (Uint8)highestAvailablePrio())
- highestAvailablePrio((Priority)prio);
-}
-
-inline
-void
-FastScheduler::execute(Signal* signal, Priority prio,
- BlockNumber bnr, GlobalSignalNumber gsn)
-{
-#ifdef VM_TRACE
- if (prio >= LEVEL_IDLE)
- prio_level_error();
-#endif
- theJobBuffers[prio].insert(signal, bnr, gsn);
- if (prio < highestAvailablePrio())
- highestAvailablePrio(prio);
-}
-
-inline
-void
-FastScheduler::insertTimeQueue(Signal* signal, BlockNumber bnr,
- GlobalSignalNumber gsn, Uint32 aIndex)
-{
- theJobBuffers[3].insert(signal, bnr, gsn, aIndex);
-}
-
-inline
-void
-FastScheduler::scheduleTimeQueue(Uint32 aIndex)
-{
- Signal* signal = getVMSignals();
- theJobBuffers[3].retrieve(signal, aIndex);
- theJobBuffers[0].insert
- (signal,
- (BlockNumber)signal->header.theReceiversBlockNumber,
- (GlobalSignalNumber)signal->header.theVerId_signalNumber);
- if (highestAvailablePrio() > JBA)
- highestAvailablePrio(JBA);
-}
-
-inline
-Uint32
-APZJobBuffer::getWritePtr() const
-{
- return wPtr;
-}
-
-inline
-Uint32
-APZJobBuffer::getReadPtr() const
-{
- return rPtr;
-}
-
-inline
-Uint32
-APZJobBuffer::getOccupancy() const
-{
- return theOccupancy;
-}
-
-inline
-Uint32
-APZJobBuffer::getBufSize() const
-{
- return bufSize;
-}
-
-inline
-void
-APZJobBuffer::retrieve(Signal* signal, Uint32 myRptr)
-{
- register BufferEntry& buf = buffer[myRptr];
-
- buf.header.theSignalId = globalData.theSignalId++;
-
- signal->header = buf.header;
-
- Uint32 *from = (Uint32*) &buf.theDataRegister[0];
- Uint32 *to = (Uint32*) &signal->theData[0];
- Uint32 noOfWords = buf.header.theLength;
- for(; noOfWords; noOfWords--)
- *to++ = *from++;
- // Copy sections references (copy all without if-statements)
- SegmentedSectionPtr * tSecPtr = &signal->m_sectionPtr[0];
- tSecPtr[0].i = from[0];
- tSecPtr[1].i = from[1];
- tSecPtr[2].i = from[2];
- return;
-}
-
-inline
-void
-APZJobBuffer::retrieveDump(Signal* signal, Uint32 myRptr)
-{
- /**
- * Note that signal id is not taken from global data
- */
-
- register BufferEntry& buf = buffer[myRptr];
- signal->header = buf.header;
-
- Uint32 *from = (Uint32*) &buf.theDataRegister[0];
- Uint32 *to = (Uint32*) &signal->theData[0];
- Uint32 noOfWords = buf.header.theLength;
- for(; noOfWords; noOfWords--)
- *to++ = *from++;
- return;
-}
-
-inline
-void
-APZJobBuffer::insert(Signal* signal,
- BlockNumber bnr, GlobalSignalNumber gsn)
-{
- 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;
- signal2buffer(signal, bnr, gsn, buf);
- //---------------------------------------------------------
- // Prefetch of buffer[wPtr] is done here. We prefetch for
- // write both the first cache line and the next 64 byte
- // entry
- //---------------------------------------------------------
- WRITEHINT((void*)&buffer[wPtr]);
- WRITEHINT((void*)(((char*)&buffer[wPtr]) + 64));
- } else {
- jbuf_error();
- }//if
-}
-
-
-inline
-void
-APZJobBuffer::insert(Signal* signal, BlockNumber bnr,
- GlobalSignalNumber gsn, Uint32 myWPtr)
-{
- register BufferEntry& buf = buffer[myWPtr];
- signal2buffer(signal, bnr, gsn, buf);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/GlobalData.hpp b/storage/ndb/src/kernel/vm/GlobalData.hpp
deleted file mode 100644
index daf2469af49..00000000000
--- a/storage/ndb/src/kernel/vm/GlobalData.hpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef GLOBAL_DATA_H
-#define GLOBAL_DATA_H
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-#include "Prio.hpp"
-#include "VMSignal.hpp"
-
-#include <BlockNumbers.h>
-#include <NodeState.hpp>
-#include <NodeInfo.hpp>
-#include "ArrayPool.hpp"
-
-class SimulatedBlock;
-
-enum restartStates {initial_state,
- perform_start,
- system_started,
- perform_stop};
-
-struct GlobalData {
- Uint32 m_restart_seq; //
- NodeVersionInfo m_versionInfo;
- NodeInfo m_nodeInfo[MAX_NODES];
- Signal VMSignals[1]; // Owned by FastScheduler::
-
- Uint64 internalMillisecCounter; // Owned by ThreadConfig::
- Uint32 highestAvailablePrio; // Owned by FastScheduler::
- Uint32 JobCounter; // Owned by FastScheduler
- Uint64 JobLap; // Owned by FastScheduler
- Uint32 loopMax; // Owned by FastScheduler
-
- Uint32 theNextTimerJob; // Owned by TimeQueue::
- Uint32 theCurrentTimer; // Owned by TimeQueue::
- Uint32 theShortTQIndex; // Owned by TimeQueue::
-
- Uint32 theLongTQIndex; // Owned by TimeQueue::
- Uint32 theCountTimer; // Owned by TimeQueue::
- Uint32 theFirstFreeTQIndex; // Owned by TimeQueue::
- Uint32 testOn; // Owned by the Signal Loggers
-
- NodeId ownId; // Own processor id
-
- Uint32 theStartLevel;
- restartStates theRestartFlag;
- Uint32 theSignalId;
-
- Uint32 sendPackedActivated;
- Uint32 activateSendPacked;
-
- GlobalData(){
- theSignalId = 0;
- theStartLevel = NodeState::SL_NOTHING;
- theRestartFlag = perform_start;
- }
- ~GlobalData(){}
-
- void setBlock(BlockNumber blockNo, SimulatedBlock * block);
- SimulatedBlock * getBlock(BlockNumber blockNo);
-
- void incrementWatchDogCounter(Uint32 place);
- const Uint32 * getWatchDogPtr();
-
-private:
- Uint32 watchDog;
- SimulatedBlock* blockTable[NO_OF_BLOCKS]; // Owned by Dispatcher::
-public:
- ArrayPool<GlobalPage> m_global_page_pool;
- ArrayPool<GlobalPage> m_shared_page_pool;
-};
-
-extern GlobalData globalData;
-
-#define GLOBAL_TEST_ON (localTestOn)
-#define GET_GLOBAL_TEST_FLAG bool localTestOn = globalData.testOn
-#define SET_GLOBAL_TEST_ON (globalData.testOn = true)
-#define SET_GLOBAL_TEST_OFF (globalData.testOn = false)
-#define TOGGLE_GLOBAL_TEST_FLAG (globalData.testOn = (globalData.testOn == true ? false : true))
-
-inline
-void
-GlobalData::setBlock(BlockNumber blockNo, SimulatedBlock * block){
- blockNo -= MIN_BLOCK_NO;
- assert((blockTable[blockNo] == 0) || (blockTable[blockNo] == block));
- blockTable[blockNo] = block;
-}
-
-inline
-SimulatedBlock *
-GlobalData::getBlock(BlockNumber blockNo){
- blockNo -= MIN_BLOCK_NO;
- return blockTable[blockNo];
-}
-
-inline
-void
-GlobalData::incrementWatchDogCounter(Uint32 place){
- watchDog = place;
-}
-
-inline
-const Uint32 *
-GlobalData::getWatchDogPtr(){
- return &watchDog;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/KeyDescriptor.hpp b/storage/ndb/src/kernel/vm/KeyDescriptor.hpp
deleted file mode 100644
index 8f2f3590695..00000000000
--- a/storage/ndb/src/kernel/vm/KeyDescriptor.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KEY_DESCRIPTOR_HPP
-#define KEY_DESCRIPTOR_HPP
-
-#include <ndb_types.h>
-#include <ndb_limits.h>
-#include "CArray.hpp"
-
-struct KeyDescriptor
-{
- KeyDescriptor () {
- noOfKeyAttr = hasCharAttr = noOfDistrKeys = noOfVarKeys = 0;
- }
-
- Uint8 noOfKeyAttr;
- Uint8 hasCharAttr;
- Uint8 noOfDistrKeys;
- Uint8 noOfVarKeys;
- struct KeyAttr
- {
- Uint32 attributeDescriptor;
- CHARSET_INFO* charsetInfo;
- } keyAttr[MAX_ATTRIBUTES_IN_INDEX];
-};
-
-extern CArray<KeyDescriptor> g_key_descriptor_pool;
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/KeyTable.hpp b/storage/ndb/src/kernel/vm/KeyTable.hpp
deleted file mode 100644
index 5c26524a861..00000000000
--- a/storage/ndb/src/kernel/vm/KeyTable.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KEY_TABLE_HPP
-#define KEY_TABLE_HPP
-
-#include <DLHashTable.hpp>
-
-/**
- * KeyTable2 is DLHashTable2 with hardcoded Uint32 key named "key".
- */
-template <typename P, typename T>
-class KeyTableImpl : public DLHashTableImpl<P, T> {
-public:
- KeyTableImpl(P & pool) :
- DLHashTableImpl<P, T>(pool) {
- }
-
- bool find(Ptr<T>& ptr, const T& rec) const {
- return DLHashTableImpl<P, T>::find(ptr, rec);
- }
-
- bool find(Ptr<T>& ptr, Uint32 key) const {
- T rec;
- rec.key = key;
- return DLHashTableImpl<P, T>::find(ptr, rec);
- }
-};
-
-// Specializations
-
-template <typename T>
-class KeyTable : public KeyTableImpl<ArrayPool<T>, T>
-{
-public:
- KeyTable(ArrayPool<T> & p) : KeyTableImpl<ArrayPool<T>, T>(p) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/KeyTable2.hpp b/storage/ndb/src/kernel/vm/KeyTable2.hpp
deleted file mode 100644
index d754fddd64f..00000000000
--- a/storage/ndb/src/kernel/vm/KeyTable2.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KEY_TABLE2_HPP
-#define KEY_TABLE2_HPP
-
-#include <DLHashTable2.hpp>
-
-/**
- * KeyTable2 is DLHashTable2 with hardcoded Uint32 key named "key".
- */
-template <class T, class U>
-class KeyTable2 : public DLHashTable2<T, U> {
-public:
- KeyTable2(ArrayPool<U>& pool) :
- DLHashTable2<T, U>(pool) {
- }
-
- bool find(Ptr<T>& ptr, const T& rec) const {
- return DLHashTable2<T, U>::find(ptr, rec);
- }
-
- bool find(Ptr<T>& ptr, Uint32 key) const {
- T rec;
- rec.key = key;
- return DLHashTable2<T, U>::find(ptr, rec);
- }
-};
-
-template <class T, class U>
-class KeyTable2C : public KeyTable2<T, U> {
- Uint32 m_count;
-public:
- KeyTable2C(ArrayPool<U>& pool) :
- KeyTable2<T, U>(pool), m_count(0) {
- }
-
- Uint32 get_count() const { return m_count; }
-
- bool seize(Ptr<T> & ptr) {
- if (KeyTable2<T, U>::seize(ptr))
- {
- m_count ++;
- return true;
- }
- return false;
- }
-
- void add(Ptr<T> & ptr) {
- KeyTable2<T, U>::add(ptr);
- m_count ++;
- }
-
- void remove(Ptr<T> & ptr, const T & key) {
- KeyTable2<T, U>::remove(ptr, key);
- if (ptr.i != RNIL)
- {
- assert(m_count);
- m_count --;
- }
- }
-
- void remove(Uint32 i) {
- KeyTable2<T, U>::remove(i);
- assert(m_count);
- m_count --;
- }
-
- void remove(Ptr<T> & ptr) {
- KeyTable2<T, U>::remove(ptr);
- assert(m_count);
- m_count --;
- }
-
- void removeAll() {
- KeyTable2<T, U>::removeAll();
- m_count = 0;
- }
-
- void release(Ptr<T> & ptr, const T & key) {
- KeyTable2<T, U>::release(ptr, key);
- if (ptr.i != RNIL)
- {
- assert(m_count);
- m_count --;
- }
- }
-
- void release(Uint32 i) {
- KeyTable2<T, U>::release(i);
- assert(m_count);
- m_count --;
- }
-
- void release(Ptr<T> & ptr) {
- KeyTable2<T, U>::release(ptr);
- assert(m_count);
- m_count --;
- }
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/KeyTable2Ref.hpp b/storage/ndb/src/kernel/vm/KeyTable2Ref.hpp
deleted file mode 100644
index 45373550a52..00000000000
--- a/storage/ndb/src/kernel/vm/KeyTable2Ref.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef KEY_TABLE2_REF_HPP
-#define KEY_TABLE2_REF_HPP
-
-#include "KeyTable2.hpp"
-
-/**
- * KeyTable2 is DLHashTable2 with hardcoded Uint32 key named "key".
- */
-template <class T, class U, class V>
-class KeyTable2Ref
-{
- KeyTable2<U, V>& m_ref;
-public:
- KeyTable2Ref(KeyTable2<U, V>& ref) :m_ref(ref) {}
-
- bool find(Ptr<T>& ptr, Uint32 key) const {
- U rec;
- rec.key = key;
- Ptr<U> tmp;
- bool ret = m_ref.find(tmp, rec);
- ptr.i = tmp.i;
- ptr.p = static_cast<T*>(tmp.p);
- return ret;
- }
-
- bool seize(Ptr<T> & ptr) {
- Ptr<U> tmp;
- bool ret = m_ref.seize(tmp);
- ptr.i = tmp.i;
- ptr.p = static_cast<T*>(tmp.p);
- return ret;
- }
-
- void add(Ptr<T> & ptr) {
- Ptr<U> tmp;
- tmp.i = ptr.i;
- tmp.p = static_cast<U*>(ptr.p);
- m_ref.add(tmp);
- }
-
- void release(Ptr<T> & ptr) {
- Ptr<U> tmp;
- tmp.i = ptr.i;
- tmp.p = static_cast<U*>(ptr.p);
- m_ref.release(tmp);
- }
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/LinearPool.hpp b/storage/ndb/src/kernel/vm/LinearPool.hpp
deleted file mode 100644
index 6d9a7b14a2d..00000000000
--- a/storage/ndb/src/kernel/vm/LinearPool.hpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LINEAR_POOL_HPP
-#define LINEAR_POOL_HPP
-
-#include <Bitmask.hpp>
-#include "SuperPool.hpp"
-
-/*
- * LinearPool - indexed record pool
- *
- * LinearPool implements a pool where each record has a 0-based index.
- * Any index value (up to 2^32-1) is allowed. Normal efficient usage is
- * to assign index values in sequence and to re-use any values which
- * have become free. This is default seize/release behaviour.
- *
- * LinearPool has 2 internal RecordPool instances:
- *
- * (a) record pool of T (the template argument class)
- * (b) record pool of "maps" (array of Uint32)
- *
- * The maps translate an index into an i-value in (a). Each map has
- * a level. Level 0 maps point to i-values. Level N+1 maps point to
- * level N maps. There is a unique "root map" at top.
- *
- * This works exactly like numbers in a given base. Each map has base
- * size entries. For implementation convenience the base must be power
- * of 2 between 2^1 and 2^15. It is given by its log2 value (1-15).
- *
- * A position in a map is also called a "digit".
- *
- * There is a doubly linked list of available maps (some free entries)
- * on each level. There is a doubly linked freelist within each map.
- * There is also a bitmask of used entries in each map.
- *
- * Level 0 free entry has space for one record. Level N free entry
- * implies space for base^N records. The implied levels are created and
- * removed on demand. Empty maps are usually removed.
- *
- * Default base is 256 (log2 = 8) which requires maximum 4 levels or
- * digits (similar to ip address).
- *
- * TODO
- *
- * - move most of the inline code to LinearPool.cpp
- * - optimize for common case
- * - add optimized 2-level implementation (?)
- */
-
-#include "SuperPool.hpp"
-
-template <class T, Uint32 LogBase = 8>
-class LinearPool {
- typedef SuperPool::PtrI PtrI;
-
- // Base.
- STATIC_CONST( Base = 1 << LogBase );
-
- // Digit mask.
- STATIC_CONST( DigitMask = Base - 1 );
-
- // Max possible levels (0 to max root level).
- STATIC_CONST( MaxLevels = (32 + LogBase - 1) / LogBase );
-
- // Number of words in map used bit mask.
- STATIC_CONST( BitmaskSize = (Base + 31) / 32 );
-
- // Map.
- struct Map {
- Uint32 m_level;
- Uint32 m_occup; // number of used entries
- Uint32 m_firstfree; // position of first free entry
- PtrI m_parent; // parent map
- Uint32 m_index; // from root to here
- PtrI m_nextavail;
- PtrI m_prevavail;
- Uint32 m_bitmask[BitmaskSize];
- PtrI m_entry[Base];
- };
-
-public:
-
- // Constructor.
- LinearPool(GroupPool& gp);
-
- // Destructor.
- ~LinearPool();
-
- // Update pointer ptr.p according to index value ptr.i.
- void getPtr(Ptr<T>& ptr);
-
- // Allocate record from the pool. Reuses free index if possible.
- bool seize(Ptr<T>& ptr);
-
- // Allocate given index. Like seize but returns -1 if in use.
- int seize_index(Ptr<T>& ptr, Uint32 index);
-
- // Return record to the pool.
- void release(Ptr<T>& ptr);
-
- // Return number of used records (may require 1 page scan).
- Uint32 count();
-
- // Verify (debugging).
- void verify();
-
-private:
-
- // Given index find the bottom map.
- void get_map(Ptr<Map>& map_ptr, Uint32 index);
-
- // Add new root map and increase level
- bool add_root();
-
- // Add new non-root map.
- bool add_map(Ptr<Map>& map_ptr, Ptr<Map> parent_ptr, Uint32 digit);
-
- // Subroutine to initialize map free lists.
- void init_free(Ptr<Map> map_ptr);
-
- // Add entry at given free position.
- void add_entry(Ptr<Map> map_ptr, Uint32 digit, PtrI ptr_i);
-
- // Remove entry and map if it becomes empty.
- void remove_entry(Ptr<Map> map_ptr, Uint32 digit);
-
- // Remove map and all parents which become empty.
- void remove_map(Ptr<Map> map_ptr);
-
- // Add map to available list.
- void add_avail(Ptr<Map> map_ptr);
-
- // Remove map from available list.
- void remove_avail(Ptr<Map> map_ptr);
-
- // Verify available lists
- void verify_avail();
-
- // Verify map (recursive).
- void verify_map(Ptr<Map> map_ptr, Uint32 level, Uint32* count);
-
- RecordPool<T> m_records;
- RecordPool<Map> m_maps;
- Uint32 m_levels; // 0 means empty pool
- PtrI m_root;
- PtrI m_avail[MaxLevels];
-};
-
-template <class T, Uint32 LogBase>
-inline
-LinearPool<T, LogBase>::LinearPool(GroupPool& gp) :
- m_records(gp),
- m_maps(gp),
- m_levels(0),
- m_root(RNIL)
-{
- Uint32 n;
- for (n = 0; n < MaxLevels; n++)
- m_avail[n] = RNIL;
-}
-
-template <class T, Uint32 LogBase>
-inline
-LinearPool<T, LogBase>::~LinearPool()
-{
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::getPtr(Ptr<T>& ptr)
-{
- Uint32 index = ptr.i;
- // get level 0 map
- Ptr<Map> map_ptr;
- get_map(map_ptr, index);
- // get record
- Ptr<T> rec_ptr;
- Uint32 digit = index & DigitMask;
- assert(BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, digit));
- rec_ptr.i = map_ptr.p->m_entry[digit];
- m_records.getPtr(rec_ptr);
- ptr.p = rec_ptr.p;
-}
-
-template <class T, Uint32 LogBase>
-inline bool
-LinearPool<T, LogBase>::seize(Ptr<T>& ptr)
-{
- // look for free list on some level
- Ptr<Map> map_ptr;
- map_ptr.i = RNIL;
- Uint32 n = 0;
- while (n < m_levels) {
- if ((map_ptr.i = m_avail[n]) != RNIL)
- break;
- n++;
- }
- if (map_ptr.i == RNIL) {
- // add new level with available maps
- if (! add_root())
- return false;
- assert(n < m_levels);
- map_ptr.i = m_avail[n];
- }
- m_maps.getPtr(map_ptr);
- // walk down creating missing levels and using an entry on each
- Uint32 digit;
- Ptr<Map> new_ptr;
- new_ptr.i = RNIL;
- while (true) {
- digit = map_ptr.p->m_firstfree;
- if (n == 0)
- break;
- Ptr<Map> child_ptr;
- if (! add_map(child_ptr, map_ptr, digit)) {
- if (new_ptr.i != RNIL)
- remove_map(new_ptr);
- return false;
- }
- new_ptr = child_ptr;
- map_ptr = child_ptr;
- n--;
- }
- // now on level 0
- assert(map_ptr.p->m_level == 0);
- Ptr<T> rec_ptr;
- if (! m_records.seize(rec_ptr)) {
- if (new_ptr.i != RNIL)
- remove_map(new_ptr);
- return false;
- }
- add_entry(map_ptr, digit, rec_ptr.i);
- ptr.i = digit + (map_ptr.p->m_index << LogBase);
- ptr.p = rec_ptr.p;
- return true;
-}
-
-template <class T, Uint32 LogBase>
-inline int
-LinearPool<T, LogBase>::seize_index(Ptr<T>& ptr, Uint32 index)
-{
- // extract all digits at least up to current root level
- Uint32 digits[MaxLevels];
- Uint32 n = 0;
- Uint32 tmp = index;
- do {
- digits[n] = tmp & DigitMask;
- tmp >>= LogBase;
- } while (++n < m_levels || tmp != 0);
- // add any new root levels
- while (n > m_levels) {
- if (! add_root())
- return false;
- }
- // start from root
- Ptr<Map> map_ptr;
- map_ptr.i = m_root;
- m_maps.getPtr(map_ptr);
- // walk down creating or re-using existing levels
- Uint32 digit;
- bool used;
- Ptr<Map> new_ptr;
- new_ptr.i = RNIL;
- while (true) {
- digit = digits[--n];
- used = BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, digit);
- if (n == 0)
- break;
- if (used) {
- map_ptr.i = map_ptr.p->m_entry[digit];
- m_maps.getPtr(map_ptr);
- } else {
- Ptr<Map> child_ptr;
- if (! add_map(child_ptr, map_ptr, digit)) {
- if (new_ptr.i != RNIL)
- remove_map(new_ptr);
- }
- new_ptr = child_ptr;
- map_ptr = child_ptr;
- }
- }
- // now at level 0
- assert(map_ptr.p->m_level == 0);
- Ptr<T> rec_ptr;
- if (used || ! m_records.seize(rec_ptr)) {
- if (new_ptr.i != RNIL)
- remove_map(new_ptr);
- return used ? -1 : false;
- }
- add_entry(map_ptr, digit, rec_ptr.i);
- assert(index == digit + (map_ptr.p->m_index << LogBase));
- ptr.i = index;
- ptr.p = rec_ptr.p;
- return true;
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::release(Ptr<T>& ptr)
-{
- Uint32 index = ptr.i;
- // get level 0 map
- Ptr<Map> map_ptr;
- get_map(map_ptr, index);
- // release record
- Ptr<T> rec_ptr;
- Uint32 digit = index & DigitMask;
- rec_ptr.i = map_ptr.p->m_entry[digit];
- m_records.release(rec_ptr);
- // remove entry
- remove_entry(map_ptr, digit);
- // null pointer
- ptr.i = RNIL;
- ptr.p = 0;
-}
-
-template <class T, Uint32 LogBase>
-inline Uint32
-LinearPool<T, LogBase>::count()
-{
- SuperPool& sp = m_records.m_superPool;
- Uint32 count1 = sp.getRecUseCount(m_records.m_recInfo);
- return count1;
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::verify()
-{
- verify_avail();
- if (m_root == RNIL) {
- assert(m_levels == 0);
- return;
- }
- assert(m_levels != 0);
- Ptr<Map> map_ptr;
- map_ptr.i = m_root;
- m_maps.getPtr(map_ptr);
- Uint32 count1 = count();
- Uint32 count2 = 0;
- verify_map(map_ptr, m_levels - 1, &count2);
- assert(count1 == count2);
-}
-
-// private methods
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::get_map(Ptr<Map>& map_ptr, Uint32 index)
-{
- // root map must exist
- Ptr<Map> tmp_ptr;
- tmp_ptr.i = m_root;
- m_maps.getPtr(tmp_ptr);
- assert(tmp_ptr.p->m_level + 1 == m_levels);
- // extract index digits up to current root level
- Uint32 digits[MaxLevels];
- Uint32 n = 0;
- do {
- digits[n] = index & DigitMask;
- index >>= LogBase;
- } while (++n < m_levels);
- assert(index == 0);
- // walk down indirect levels
- while (--n > 0) {
- tmp_ptr.i = tmp_ptr.p->m_entry[digits[n]];
- m_maps.getPtr(tmp_ptr);
- }
- // level 0 map
- assert(tmp_ptr.p->m_level == 0);
- map_ptr = tmp_ptr;
-}
-
-template <class T, Uint32 LogBase>
-inline bool
-LinearPool<T, LogBase>::add_root()
-{
- // new root
- Ptr<Map> map_ptr;
- if (! m_maps.seize(map_ptr))
- return false;
- Uint32 n = m_levels++;
- assert(n < MaxLevels);
- // set up
- map_ptr.p->m_level = n;
- map_ptr.p->m_parent = RNIL;
- map_ptr.p->m_index = 0;
- init_free(map_ptr);
- // on level > 0 digit 0 points to old root
- if (n > 0) {
- Ptr<Map> old_ptr;
- old_ptr.i = m_root;
- m_maps.getPtr(old_ptr);
- assert(old_ptr.p->m_parent == RNIL);
- old_ptr.p->m_parent = map_ptr.i;
- add_entry(map_ptr, 0, old_ptr.i);
- }
- // set new root
- m_root = map_ptr.i;
- return true;
-}
-
-template <class T, Uint32 LogBase>
-inline bool
-LinearPool<T, LogBase>::add_map(Ptr<Map>& map_ptr, Ptr<Map> parent_ptr, Uint32 digit)
-{
- if (! m_maps.seize(map_ptr))
- return false;
- assert(parent_ptr.p->m_level != 0);
- // set up
- map_ptr.p->m_level = parent_ptr.p->m_level - 1;
- map_ptr.p->m_parent = parent_ptr.i;
- map_ptr.p->m_index = digit + (parent_ptr.p->m_index << LogBase);
- init_free(map_ptr);
- add_entry(parent_ptr, digit, map_ptr.i);
- return true;
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::init_free(Ptr<Map> map_ptr)
-{
- map_ptr.p->m_occup = 0;
- map_ptr.p->m_firstfree = 0;
- // freelist
- Uint32 j;
- Uint16 back = ZNIL;
- for (j = 0; j < Base - 1; j++) {
- map_ptr.p->m_entry[j] = back | ((j + 1) << 16);
- back = j;
- }
- map_ptr.p->m_entry[j] = back | (ZNIL << 16);
- // bitmask
- BitmaskImpl::clear(BitmaskSize, map_ptr.p->m_bitmask);
- // add to available
- add_avail(map_ptr);
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::add_entry(Ptr<Map> map_ptr, Uint32 digit, PtrI ptr_i)
-{
- assert(map_ptr.p->m_occup < Base && digit < Base);
- assert(! BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, digit));
- // unlink from freelist
- Uint32 val = map_ptr.p->m_entry[digit];
- Uint16 back = val & ZNIL;
- Uint16 forw = val >> 16;
- if (back != ZNIL) {
- assert(back < Base);
- map_ptr.p->m_entry[back] &= ZNIL;
- map_ptr.p->m_entry[back] |= (forw << 16);
- }
- if (forw != ZNIL) {
- assert(forw < Base);
- map_ptr.p->m_entry[forw] &= (ZNIL << 16);
- map_ptr.p->m_entry[forw] |= back;
- }
- if (back == ZNIL) {
- map_ptr.p->m_firstfree = forw;
- }
- // set new value
- map_ptr.p->m_entry[digit] = ptr_i;
- map_ptr.p->m_occup++;
- BitmaskImpl::set(BitmaskSize, map_ptr.p->m_bitmask, digit);
- if (map_ptr.p->m_occup == Base)
- remove_avail(map_ptr);
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::remove_entry(Ptr<Map> map_ptr, Uint32 digit)
-{
- assert(map_ptr.p->m_occup != 0 && digit < Base);
- assert(BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, digit));
- // add to freelist
- Uint32 firstfree = map_ptr.p->m_firstfree;
- map_ptr.p->m_entry[digit] = ZNIL | (firstfree << 16);
- if (firstfree != ZNIL) {
- assert(firstfree < Base);
- map_ptr.p->m_entry[firstfree] &= (ZNIL << 16);
- map_ptr.p->m_entry[firstfree] |= digit;
- }
- map_ptr.p->m_firstfree = digit;
- map_ptr.p->m_occup--;
- BitmaskImpl::clear(BitmaskSize, map_ptr.p->m_bitmask, digit);
- if (map_ptr.p->m_occup + 1 == Base)
- add_avail(map_ptr);
- else if (map_ptr.p->m_occup == 0)
- remove_map(map_ptr);
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::remove_map(Ptr<Map> map_ptr)
-{
- assert(map_ptr.p->m_occup == 0);
- remove_avail(map_ptr);
- Ptr<Map> parent_ptr;
- parent_ptr.i = map_ptr.p->m_parent;
- Uint32 digit = map_ptr.p->m_index & DigitMask;
- PtrI map_ptr_i = map_ptr.i;
- m_maps.release(map_ptr);
- if (m_root == map_ptr_i) {
- assert(parent_ptr.i == RNIL);
- Uint32 used = count();
- assert(used == 0);
- m_root = RNIL;
- m_levels = 0;
- }
- if (parent_ptr.i != RNIL) {
- m_maps.getPtr(parent_ptr);
- // remove child entry (recursive)
- remove_entry(parent_ptr, digit);
- }
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::add_avail(Ptr<Map> map_ptr)
-{
- Uint32 n = map_ptr.p->m_level;
- assert(n < m_levels);
- map_ptr.p->m_nextavail = m_avail[n];
- if (map_ptr.p->m_nextavail != RNIL) {
- Ptr<Map> next_ptr;
- next_ptr.i = map_ptr.p->m_nextavail;
- m_maps.getPtr(next_ptr);
- next_ptr.p->m_prevavail = map_ptr.i;
- }
- map_ptr.p->m_prevavail = RNIL;
- m_avail[n] = map_ptr.i;
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::remove_avail(Ptr<Map> map_ptr)
-{
- Uint32 n = map_ptr.p->m_level;
- assert(n < m_levels);
- if (map_ptr.p->m_nextavail != RNIL) {
- Ptr<Map> next_ptr;
- next_ptr.i = map_ptr.p->m_nextavail;
- m_maps.getPtr(next_ptr);
- next_ptr.p->m_prevavail = map_ptr.p->m_prevavail;
- }
- if (map_ptr.p->m_prevavail != RNIL) {
- Ptr<Map> prev_ptr;
- prev_ptr.i = map_ptr.p->m_prevavail;
- m_maps.getPtr(prev_ptr);
- prev_ptr.p->m_nextavail = map_ptr.p->m_nextavail;
- }
- if (map_ptr.p->m_prevavail == RNIL) {
- m_avail[n] = map_ptr.p->m_nextavail;
- }
- map_ptr.p->m_nextavail = RNIL;
- map_ptr.p->m_prevavail = RNIL;
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::verify_avail()
-{
- // check available lists
- for (Uint32 n = 0; n < MaxLevels; n++) {
- Ptr<Map> map_ptr;
- map_ptr.i = m_avail[n];
- Uint32 back = RNIL;
- while (map_ptr.i != RNIL) {
- m_maps.getPtr(map_ptr);
- assert(map_ptr.p->m_occup < Base);
- assert(back == map_ptr.p->m_prevavail);
- back = map_ptr.i;
- map_ptr.i = map_ptr.p->m_nextavail;
- }
- }
-}
-
-template <class T, Uint32 LogBase>
-inline void
-LinearPool<T, LogBase>::verify_map(Ptr<Map> map_ptr, Uint32 level, Uint32* count)
-{
- assert(level < MaxLevels);
- assert(map_ptr.p->m_level == level);
- // check freelist
- {
- Uint32 nused = BitmaskImpl::count(BitmaskSize, map_ptr.p->m_bitmask);
- assert(nused <= Base);
- assert(map_ptr.p->m_occup == nused);
- Uint32 nfree = 0;
- Uint32 j = map_ptr.p->m_firstfree;
- Uint16 back = ZNIL;
- while (j != ZNIL) {
- assert(j < Base);
- assert(! BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, j));
- Uint32 val = map_ptr.p->m_entry[j];
- assert(back == (val & ZNIL));
- back = j;
- j = (val >> 16);
- nfree++;
- }
- assert(nused + nfree == Base);
- }
- // check entries
- {
- for (Uint32 j = 0; j < Base; j++) {
- bool free = ! BitmaskImpl::get(BitmaskSize, map_ptr.p->m_bitmask, j);
- if (free)
- continue;
- if (level != 0) {
- Ptr<Map> child_ptr;
- child_ptr.i = map_ptr.p->m_entry[j];
- m_maps.getPtr(child_ptr);
- assert(child_ptr.p->m_parent == map_ptr.i);
- assert(child_ptr.p->m_index == j + (map_ptr.p->m_index << LogBase));
- verify_map(child_ptr, level - 1, count);
- } else {
- Ptr<T> rec_ptr;
- rec_ptr.i = map_ptr.p->m_entry[j];
- m_records.getPtr(rec_ptr);
- (*count)++;
- }
- }
- }
- // check membership on available list
- {
- Ptr<Map> avail_ptr;
- avail_ptr.i = m_avail[map_ptr.p->m_level];
- bool found = false;
- while (avail_ptr.i != RNIL) {
- if (avail_ptr.i == map_ptr.i) {
- found = true;
- break;
- }
- m_maps.getPtr(avail_ptr);
- avail_ptr.i = avail_ptr.p->m_nextavail;
- }
- assert(found == (map_ptr.p->m_occup < Base));
- }
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/LongSignal.hpp b/storage/ndb/src/kernel/vm/LongSignal.hpp
deleted file mode 100644
index 5f4f9744c45..00000000000
--- a/storage/ndb/src/kernel/vm/LongSignal.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LONG_SIGNAL_HPP
-#define LONG_SIGNAL_HPP
-
-#include "pc.hpp"
-#include <ArrayPool.hpp>
-
-/**
- * Section handling
- */
-struct SectionSegment {
-
- STATIC_CONST( DataLength = NDB_SECTION_SEGMENT_SZ );
-
- Uint32 m_ownerRef;
- Uint32 m_sz;
- Uint32 m_lastSegment;
- union {
- Uint32 m_nextSegment;
- Uint32 nextPool;
- };
- Uint32 theData[DataLength];
-};
-
-/**
- * Pool for SectionSegments
- */
-class SectionSegmentPool : public ArrayPool<SectionSegment> {};
-
-/**
- * And the instance
- */
-extern SectionSegmentPool g_sectionSegmentPool;
-
-/**
- * Function prototypes
- */
-void print(SegmentedSectionPtr ptr, FILE* out);
-void copy(SegmentedSectionPtr dst, Uint32 * src, Uint32 len);
-void copy(Uint32 * dst, SegmentedSectionPtr src);
-bool import(Ptr<SectionSegment> & first, const Uint32 * src, Uint32 len);
-
-extern class SectionSegmentPool g_sectionSegmentPool;
-void getSection(SegmentedSectionPtr & ptr, Uint32 id);
-void linkSegments(Uint32 head, Uint32 tail);
-
-void getSections(Uint32 secCount, SegmentedSectionPtr ptr[3]);
-void releaseSections(Uint32 secCount, SegmentedSectionPtr ptr[3]);
-
-
-#include "DataBuffer.hpp"
-
-template<Uint32 sz>
-void
-append(DataBuffer<sz>& dst, SegmentedSectionPtr ptr, SectionSegmentPool& pool){
- Uint32 len = ptr.sz;
- while(len > SectionSegment::DataLength){
- dst.append(ptr.p->theData, SectionSegment::DataLength);
- ptr.p = pool.getPtr(ptr.p->m_nextSegment);
- len -= SectionSegment::DataLength;
- }
- dst.append(ptr.p->theData, len);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/Makefile.am b/storage/ndb/src/kernel/vm/Makefile.am
deleted file mode 100644
index a862da610bd..00000000000
--- a/storage/ndb/src/kernel/vm/Makefile.am
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-#SUBDIRS = testCopy testDataBuffer testSimplePropertiesSection
-#ifneq ($(USE_EDITLINE), N)
-#DIRS += testLongSig
-#endif
-
-noinst_LIBRARIES = libkernel.a
-
-libkernel_a_SOURCES = \
- SimulatedBlock.cpp \
- FastScheduler.cpp \
- TimeQueue.cpp \
- VMSignal.cpp \
- ThreadConfig.cpp \
- TransporterCallback.cpp \
- Emulator.cpp \
- Configuration.cpp \
- WatchDog.cpp \
- SimplePropertiesSection.cpp \
- SectionReader.cpp \
- Mutex.cpp SafeCounter.cpp \
- Rope.cpp \
- ndbd_malloc.cpp ndbd_malloc_impl.cpp \
- Pool.cpp WOPool.cpp RWPool.cpp \
- DynArr256.cpp
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
-
-windoze-dsp: libkernel.dsp
-
-libkernel.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
-
-EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256
-ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST
-ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp
-ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/strings/libmystrings.a
-
-bench_pool_SOURCES = bench_pool.cpp
-bench_pool_LDFLAGS = @ndb_bin_am_ldflags@\
- libkernel.a ../error/liberror.a \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/strings/libmystrings.a
-
-testDynArr256_CXXFLAGS = -DUNIT_TEST
-testDynArr256_SOURCES = DynArr256.cpp
-testDynArr256_LDFLAGS = @ndb_bin_am_ldflags@ \
- libkernel.a ../error/liberror.a \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/strings/libmystrings.a
-
diff --git a/storage/ndb/src/kernel/vm/Mutex.cpp b/storage/ndb/src/kernel/vm/Mutex.cpp
deleted file mode 100644
index e489386e3df..00000000000
--- a/storage/ndb/src/kernel/vm/Mutex.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include "SimulatedBlock.hpp"
-#include "Mutex.hpp"
-#include <signaldata/UtilLock.hpp>
-
-SimulatedBlock::MutexManager::MutexManager(class SimulatedBlock & block)
- : m_block(block),
- m_activeMutexes(m_mutexPool) {
-}
-
-bool
-SimulatedBlock::MutexManager::setSize(Uint32 maxNoOfActiveMutexes){
- return m_mutexPool.setSize(maxNoOfActiveMutexes);
-}
-
-Uint32
-SimulatedBlock::MutexManager::getSize() const {
- return m_mutexPool.getSize();
-}
-
-bool
-SimulatedBlock::MutexManager::seize(ActiveMutexPtr& ptr){
- return m_activeMutexes.seize(ptr);
-}
-
-void
-SimulatedBlock::MutexManager::release(Uint32 activeMutexPtrI){
- m_activeMutexes.release(activeMutexPtrI);
-}
-
-void
-SimulatedBlock::MutexManager::getPtr(ActiveMutexPtr& ptr){
- m_activeMutexes.getPtr(ptr);
-}
-
-BlockReference
-SimulatedBlock::MutexManager::reference() const {
- return m_block.reference();
-}
-
-void
-SimulatedBlock::MutexManager::progError(int line,
- int err_code,
- const char* extra)
-{
- m_block.progError(line, err_code, extra);
-}
-
-void
-SimulatedBlock::MutexManager::create(Signal* signal, ActiveMutexPtr& ptr){
-
- UtilCreateLockReq * req = (UtilCreateLockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->lockType = UtilCreateLockReq::Mutex;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_CREATE_LOCK_REQ,
- signal,
- UtilCreateLockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_CREATE_LOCK_REQ;
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_REF(Signal* signal){
-
- UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, ref->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == ref->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_CREATE_LOCK_CONF(Signal* signal){
-
- UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, conf->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_CREATE_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == conf->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, 0);
-}
-
-
-void
-SimulatedBlock::MutexManager::destroy(Signal* signal, ActiveMutexPtr& ptr){
-
- UtilDestroyLockReq * req = (UtilDestroyLockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->lockKey = ptr.p->m_mutexKey;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_DESTROY_LOCK_REQ,
- signal,
- UtilDestroyLockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_DESTROY_LOCK_REQ;
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_REF(Signal* signal){
- UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, ref->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == ref->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_DESTORY_LOCK_CONF(Signal* signal){
- UtilDestroyLockConf * conf = (UtilDestroyLockConf*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, conf->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_DESTROY_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == conf->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, 0);
-}
-
-
-void
-SimulatedBlock::MutexManager::lock(Signal* signal, ActiveMutexPtr& ptr){
-
- UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->requestInfo = 0;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_LOCK_REQ,
- signal,
- UtilLockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_LOCK_REQ;
-}
-
-void
-SimulatedBlock::MutexManager::trylock(Signal* signal, ActiveMutexPtr& ptr){
-
- UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->requestInfo = UtilLockReq::TryLock;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_LOCK_REQ,
- signal,
- UtilLockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_LOCK_REQ;
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_LOCK_REF(Signal* signal){
- UtilLockRef * ref = (UtilLockRef*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, ref->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == ref->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_LOCK_CONF(Signal* signal){
- UtilLockConf * conf = (UtilLockConf*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, conf->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == conf->lockId);
-
- ptr.p->m_mutexKey = conf->lockKey;
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, 0);
-}
-
-void
-SimulatedBlock::MutexManager::unlock(Signal* signal, ActiveMutexPtr& ptr){
- UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->lockKey = ptr.p->m_mutexKey;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_UNLOCK_REQ,
- signal,
- UtilUnlockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_UNLOCK_REQ;
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_UNLOCK_REF(Signal* signal){
- UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, ref->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == ref->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
-}
-
-void
-SimulatedBlock::MutexManager::execUTIL_UNLOCK_CONF(Signal* signal){
- UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtr();
- ActiveMutexPtr ptr;
- m_activeMutexes.getPtr(ptr, conf->senderData);
- ndbrequire(ptr.p->m_gsn == GSN_UTIL_UNLOCK_REQ);
- ndbrequire(ptr.p->m_mutexId == conf->lockId);
-
- ptr.p->m_gsn = 0;
- m_block.execute(signal, ptr.p->m_callback, 0);
-}
-
-void
-Mutex::release(SimulatedBlock::MutexManager& mgr,
- Uint32 activePtrI, Uint32 mutexId){
- SimulatedBlock::MutexManager::ActiveMutexPtr ptr;
- ptr.i = activePtrI;
- mgr.getPtr(ptr);
- if(ptr.p->m_gsn == 0 && ptr.p->m_mutexId == mutexId){
- mgr.release(activePtrI);
- return;
- }
-
- if(ptr.p->m_mutexId != mutexId)
- ErrorReporter::handleAssert("MutexHandle::release invalid handle",
- __FILE__, __LINE__);
- ErrorReporter::handleAssert("MutexHandle::release of mutex inuse",
- __FILE__, __LINE__);
-}
-
-void
-Mutex::unlock(){
- if(!m_ptr.isNull()){
- m_mgr.getPtr(m_ptr);
- if(m_ptr.p->m_mutexId == m_mutexId){
- SimulatedBlock::Callback c =
- { &SimulatedBlock::ignoreMutexUnlockCallback, m_ptr.i };
- m_ptr.p->m_callback = c;
- m_mgr.unlock(m_signal, m_ptr);
- m_ptr.setNull(); // Remove reference
- }
- }
-}
-
diff --git a/storage/ndb/src/kernel/vm/Mutex.hpp b/storage/ndb/src/kernel/vm/Mutex.hpp
deleted file mode 100644
index eb45e27f80e..00000000000
--- a/storage/ndb/src/kernel/vm/Mutex.hpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef BLOCK_MUTEX_HPP
-#define BLOCK_MUTEX_HPP
-
-#include "Callback.hpp"
-#include "SimulatedBlock.hpp"
-
-class Mutex;
-
-/**
- * MutexHandle - A "reference" to a mutex
- * - Should be used together with Mutex
- */
-class MutexHandle {
- friend class Mutex;
-public:
- MutexHandle(Uint32 id);
-
- bool isNull() const;
- void release(SimulatedBlock::MutexManager & mgr);
-
-private:
- const Uint32 m_mutexId;
- Uint32 m_activeMutexPtrI;
-};
-
-/**
- * MutexHandle2 - A template-based "reference" to a mutex
- */
-template<Uint32 MutexId>
-class MutexHandle2 {
- friend class Mutex;
-public:
- MutexHandle2();
-
- bool isNull() const;
- void release(SimulatedBlock::MutexManager & mgr);
-
-private:
- Uint32 m_activeMutexPtrI;
-};
-
-/**
- * A mutex - Used together with a MutexHandle to be put on the stack
- */
-class Mutex {
-public:
- Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle &);
-
- template<Uint32 MutexId>
- Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle2<MutexId> &);
-
- ~Mutex();
-
- void release();
- bool isNull() const ;
-
- bool lock(SimulatedBlock::Callback & callback);
- bool trylock(SimulatedBlock::Callback & callback);
- void unlock(SimulatedBlock::Callback & callback);
- void unlock(); // Ignore callback
-
- bool create(SimulatedBlock::Callback & callback);
- bool destroy(SimulatedBlock::Callback & callback);
-
-private:
- Signal* m_signal;
- SimulatedBlock::MutexManager & m_mgr;
- const Uint32 m_mutexId;
- Uint32 & m_srcPtrI;
- SimulatedBlock::MutexManager::ActiveMutexPtr m_ptr;
-
-public:
- static void release(SimulatedBlock::MutexManager&,
- Uint32 activePtrI, Uint32 mutexId);
-};
-
-inline
-MutexHandle::MutexHandle(Uint32 id) : m_mutexId(id) {
- m_activeMutexPtrI = RNIL;
-}
-
-inline
-bool
-MutexHandle::isNull() const {
- return m_activeMutexPtrI == RNIL;
-}
-
-inline
-void
-MutexHandle::release(SimulatedBlock::MutexManager & mgr){
- if(!isNull()){
- Mutex::release(mgr, m_activeMutexPtrI, m_mutexId);
- m_activeMutexPtrI = RNIL;
- }
-}
-
-template<Uint32 MutexId>
-inline
-MutexHandle2<MutexId>::MutexHandle2() {
- m_activeMutexPtrI = RNIL;
-}
-
-template<Uint32 MutexId>
-inline
-bool
-MutexHandle2<MutexId>::isNull() const {
- return m_activeMutexPtrI == RNIL;
-}
-
-
-template<Uint32 MutexId>
-inline
-void
-MutexHandle2<MutexId>::release(SimulatedBlock::MutexManager & mgr){
- if(!isNull()){
- Mutex::release(mgr, m_activeMutexPtrI, MutexId);
- m_activeMutexPtrI = RNIL;
- }
-}
-
-
-inline
-Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
- MutexHandle & mh)
- : m_signal(signal),
- m_mgr(mgr),
- m_mutexId(mh.m_mutexId),
- m_srcPtrI(mh.m_activeMutexPtrI){
-
- m_ptr.i = m_srcPtrI;
-
-}
-
-template<Uint32 MutexId>
-inline
-Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr,
- MutexHandle2<MutexId> & mh)
- : m_signal(signal),
- m_mgr(mgr),
- m_mutexId(MutexId),
- m_srcPtrI(mh.m_activeMutexPtrI){
-
- m_ptr.i = m_srcPtrI;
-
-}
-
-inline
-Mutex::~Mutex(){
- m_srcPtrI = m_ptr.i;
-}
-
-inline
-void
-Mutex::release(){
- if(!m_ptr.isNull()){
- Mutex::release(m_mgr, m_ptr.i, m_mutexId);
- m_ptr.setNull();
- }
-}
-
-inline
-bool
-Mutex::isNull() const {
- return m_ptr.isNull();
-}
-
-inline
-bool
-Mutex::lock(SimulatedBlock::Callback & callback){
- if(m_ptr.isNull()){
- if(m_mgr.seize(m_ptr)){
- m_ptr.p->m_mutexId = m_mutexId;
- m_ptr.p->m_callback = callback;
- m_mgr.lock(m_signal, m_ptr);
- return true;
- }
- return false;
- }
- ErrorReporter::handleAssert("Mutex::lock mutex alreay inuse",
- __FILE__, __LINE__);
- return false;
-}
-
-inline
-bool
-Mutex::trylock(SimulatedBlock::Callback & callback){
- if(m_ptr.isNull()){
- if(m_mgr.seize(m_ptr)){
- m_ptr.p->m_mutexId = m_mutexId;
- m_ptr.p->m_callback = callback;
- m_mgr.lock(m_signal, m_ptr);
- return true;
- }
- return false;
- }
- ErrorReporter::handleAssert("Mutex::trylock mutex alreay inuse",
- __FILE__, __LINE__);
- return false;
-}
-
-inline
-void
-Mutex::unlock(SimulatedBlock::Callback & callback){
- if(!m_ptr.isNull()){
- m_mgr.getPtr(m_ptr);
- if(m_ptr.p->m_mutexId == m_mutexId){
- m_ptr.p->m_callback = callback;
- m_mgr.unlock(m_signal, m_ptr);
- return;
- }
- }
- ErrorReporter::handleAssert("Mutex::unlock invalid mutex",
- __FILE__, __LINE__);
-}
-
-inline
-bool
-Mutex::create(SimulatedBlock::Callback & callback){
- if(m_ptr.isNull()){
- if(m_mgr.seize(m_ptr)){
- m_ptr.p->m_mutexId = m_mutexId;
- m_ptr.p->m_callback = callback;
- m_mgr.create(m_signal, m_ptr);
- return true;
- }
- return false;
- }
- ErrorReporter::handleAssert("Mutex::create mutex alreay inuse",
- __FILE__, __LINE__);
- return false;
-}
-
-inline
-bool
-Mutex::destroy(SimulatedBlock::Callback & callback){
- if(m_ptr.isNull()){
- if(m_mgr.seize(m_ptr)){
- m_ptr.p->m_mutexId = m_mutexId;
- m_ptr.p->m_callback = callback;
- m_mgr.destroy(m_signal, m_ptr);
- return true;
- }
- return false;
- }
- ErrorReporter::handleAssert("Mutex::destroy mutex alreay inuse",
- __FILE__, __LINE__);
- return false;
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/NdbdSuperPool.cpp b/storage/ndb/src/kernel/vm/NdbdSuperPool.cpp
deleted file mode 100644
index b9557d843ab..00000000000
--- a/storage/ndb/src/kernel/vm/NdbdSuperPool.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/* Copyright (c) 2003, 2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "SuperPool.hpp"
-#include "ndbd_malloc_impl.hpp"
-#include "NdbdSuperPool.hpp"
-
-#define PSI (1 << (BMW_2LOG + 2))
-
-struct AllocArea
-{
- AllocArea(AllocArea* next);
-
- Uint16 m_currPage; // 2
- Uint16 m_numPages; // number of pages // 2
- SuperPool::PtrI m_firstPageI; // 4
- void* m_memory; // page-aligned pages // 4/8
- struct AllocArea* m_nextArea; // 4/8
- // tot 16/24
-};
-
-AllocArea::AllocArea(AllocArea* next)
-{
- m_nextArea = next;
- m_firstPageI = RNIL;
- m_currPage = m_numPages = 0;
- m_memory = 0;
-}
-
-NdbdSuperPool::NdbdSuperPool(class Ndbd_mem_manager & mm,
- Uint32 pageSize, Uint32 pageBits) :
- SuperPool(pageSize, pageBits),
- m_mm(mm),
- m_currArea(0), m_firstArea(0)
-{
- m_memRoot = m_mm.get_memroot();
-
- m_shift = Ndbd_mem_manager::ndb_log2((1 << (BMW_2LOG + 2)) / pageSize) - 1;
- m_add = (1 << m_shift) - 1;
-}
-
-NdbdSuperPool::~NdbdSuperPool()
-{
- Uint32 cnt = PSI / sizeof(AllocArea);
- AllocArea* ap = m_firstArea;
- while(ap != 0)
- {
- AllocArea * first = ap;
- for(Uint32 i = 0; i<cnt; i++)
- {
- if (ap->m_numPages)
- {
- m_mm.release(ap->m_memory, ap->m_numPages >> m_shift);
- }
- ap = ap->m_nextArea;
- }
- m_mm.release((void*)first, 1);
- }
-}
-
-bool
-NdbdSuperPool::init_1()
-{
- Uint32 pageCount = (1 << m_pageBits);
- if (m_pageEnt == 0) {
- // allocate page entry array
- Uint32 bytes = pageCount * sizeof(PageEnt);
- m_pageEnt = static_cast<PageEnt*>(malloc(bytes));
- if (m_pageEnt == 0)
- return false;
- for (Uint32 i = 0; i < pageCount; i++)
- new (&m_pageEnt[i]) PageEnt();
- }
- if (m_pageType == 0) {
- // allocate type check array
- Uint32 bytes = pageCount;
- m_pageType = static_cast<Uint8*>(malloc(bytes));
- if (m_pageType == 0)
- return false;
- memset(m_pageType, 0, bytes);
- }
-
- return true;
-}
-
-static
-void
-initAllocAreaPage(AllocArea * p1)
-{
- AllocArea * ap = p1;
- Uint32 cnt = PSI / sizeof(AllocArea);
- for(Uint32 i = 0; i<cnt; i++, ap++)
- {
- new (ap) AllocArea(ap + 1);
- }
-
- (p1 + cnt - 1)->m_nextArea = 0;
-}
-
-bool
-NdbdSuperPool::init_2()
-{
- m_memRoot = m_mm.get_memroot();
-
- Uint32 cnt = 1;
- AllocArea* p1 = (AllocArea*)m_mm.alloc(&cnt, 1);
- if (p1 == 0)
- return false;
-
- initAllocAreaPage(p1);
- m_currArea = p1;
- m_firstArea = p1;
- return true;
-}
-
-SuperPool::PtrI
-NdbdSuperPool::getNewPage()
-{
- AllocArea* ap = m_currArea;
- Uint32 curr = ap->m_currPage;
- Uint32 cnt = ap->m_numPages;
- if (curr == cnt)
- {
- // area is used up
- if (! (ap = allocMem()))
- {
- abort();
- return RNIL;
- }
- curr = ap->m_currPage;
- cnt = ap->m_numPages;
- }
-
- assert(curr < cnt);
- PtrI pageI = ap->m_firstPageI;
- Uint32 recBits = m_recBits;
- Int32 ip = ((Int32)pageI >> recBits) + curr;
- pageI = ip << recBits;
- ap->m_currPage = curr + 1;
- return pageI;
-}
-
-Uint32
-NdbdSuperPool::allocAreaMemory(AllocArea* ap, Uint32 tryPages)
-{
- Uint32 cnt = (tryPages + m_add) >> m_shift;
- void* p1 = m_mm.alloc(&cnt, 1);
- if (p1 == 0)
- {
- abort();
- return 0;
- }
- Uint32 pageI = getPageI(p1);
- ap->m_firstPageI = pageI;
- ap->m_currPage = 0;
- ap->m_memory = p1;
- ap->m_numPages = cnt << m_shift;
- return cnt;
-}
-
-AllocArea*
-NdbdSuperPool::allocArea()
-{
- AllocArea * curr = m_currArea;
- AllocArea * next = curr->m_nextArea;
- if (next == 0)
- {
- Uint32 cnt = 1;
- AllocArea* p1 = (AllocArea*)m_mm.alloc(&cnt, 1);
- if (p1 == 0)
- return 0;
-
- initAllocAreaPage(p1);
-
- m_currArea->m_nextArea = p1;
- return m_currArea = p1;
- }
- else
- {
- m_currArea = m_currArea->m_nextArea;
- return m_currArea;
- }
-}
-
-AllocArea*
-NdbdSuperPool::allocMem()
-{
- // compute number of additional pages needed
- if (m_totPages >= m_maxPages)
- {
- abort();
- return 0;
- }
- Uint32 needPages = (m_totPages == 0 ? m_initPages : m_incrPages);
-
- // add new area
- AllocArea* ap = allocArea();
- if (ap == 0)
- {
- abort();
- return 0;
- }
-
- Uint32 numPages;
- if (!(numPages = allocAreaMemory(ap, needPages)))
- {
- abort();
- return 0;
- }
-
- // update counts
- m_totPages += numPages;
- return ap;
-}
diff --git a/storage/ndb/src/kernel/vm/NdbdSuperPool.hpp b/storage/ndb/src/kernel/vm/NdbdSuperPool.hpp
deleted file mode 100644
index 66765fcebc5..00000000000
--- a/storage/ndb/src/kernel/vm/NdbdSuperPool.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (c) 2003, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDBD_SUPER_POOL_HPP
-#define NDBD_SUPER_POOL_HPP
-
-#include "SuperPool.hpp"
-
-struct AllocArea;
-
-class NdbdSuperPool : public SuperPool
-{
-public:
- NdbdSuperPool(class Ndbd_mem_manager&, Uint32 pageSize, Uint32 pageBits);
-
- // Destructor.
- virtual ~NdbdSuperPool();
-
- // Get new page from current area.
- virtual PtrI getNewPage();
-
- // Call first...on all superpools (uses malloc)
- bool init_1();
-
- // Call second...uses mm
- bool init_2();
-
- virtual bool allocMemory() { return allocMem() != 0; }
-private:
- Uint32 allocAreaMemory(AllocArea*, Uint32 pages);
- AllocArea* allocArea();
- AllocArea* allocMem();
-
- // List of malloc areas.
- Uint32 m_shift, m_add;
- class Ndbd_mem_manager & m_mm;
-
- AllocArea* m_currArea;
- AllocArea* m_firstArea;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/Pool.cpp b/storage/ndb/src/kernel/vm/Pool.cpp
deleted file mode 100644
index 6b4b36a5036..00000000000
--- a/storage/ndb/src/kernel/vm/Pool.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2003, 2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include "Pool.hpp"
-#include "SimulatedBlock.hpp"
-
-void*
-Pool_context::alloc_page(Uint32 type_id, Uint32 *i)
-{
- return m_block->m_ctx.m_mm.alloc_page(type_id, i,
- Ndbd_mem_manager::NDB_ZONE_LO);
-}
-
-void
-Pool_context::release_page(Uint32 type_id, Uint32 i)
-{
- m_block->m_ctx.m_mm.release_page(type_id, i);
-}
-
-void*
-Pool_context::get_memroot()
-{
- return m_block->m_ctx.m_mm.get_memroot();
-}
-
-void
-Pool_context::handleAbort(int err, const char * msg)
-{
- m_block->progError(__LINE__, err, msg);
-}
diff --git a/storage/ndb/src/kernel/vm/Pool.hpp b/storage/ndb/src/kernel/vm/Pool.hpp
deleted file mode 100644
index 47b2e0d8892..00000000000
--- a/storage/ndb/src/kernel/vm/Pool.hpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_POOL_HPP
-#define NDB_POOL_HPP
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-
-/**
- * Type bits
- *
- * Type id is 11 bits record type, and 5 bits resource id
- * -> 2048 different kind of records and 32 different resource groups
- *
- * Resource id is used to handle configuration parameters
- *
- * see blocks/records_types.hpp
- */
-#define RG_BITS 5
-#define RG_MASK ((1 << RG_BITS) - 1)
-#define MAKE_TID(TID,RG) ((TID << RG_BITS) | RG)
-
-/**
- * Page bits
- */
-#define POOL_RECORD_BITS 13
-#define POOL_RECORD_MASK ((1 << POOL_RECORD_BITS) - 1)
-
-/**
- * Record_info
- *
- */
-struct Record_info
-{
- Uint16 m_size;
- Uint16 m_type_id;
- Uint16 m_offset_next_pool;
- Uint16 m_offset_magic;
-};
-
-/**
- * Resource_limit
- */
-struct Resource_limit
-{
- Uint32 m_min;
- Uint32 m_max;
- Uint32 m_curr;
- Uint32 m_resource_id;
-};
-
-struct Pool_context
-{
- Pool_context() {}
- class SimulatedBlock* m_block;
-
- /**
- * Get mem root
- */
- void* get_memroot();
-
- /**
- * Alloc consekutive pages
- *
- * @param i : out : i value of first page
- * @return : pointer to first page (NULL if failed)
- *
- * Will handle resource limit
- */
- void* alloc_page(Uint32 type_id, Uint32 *i);
-
- /**
- * Release pages
- *
- * @param i : in : i value of first page
- * @param p : in : pointer to first page
- */
- void release_page(Uint32 type_id, Uint32 i);
-
- /**
- * Alloc consekutive pages
- *
- * @param cnt : in/out : no of requested pages,
- * return no of allocated (undefined return NULL)
- * out will never be > in
- * @param i : out : i value of first page
- * @param min : in : will never allocate less than min
- * @return : pointer to first page (NULL if failed)
- *
- * Will handle resource limit
- */
- void* alloc_pages(Uint32 type_id, Uint32 *i, Uint32 *cnt, Uint32 min =1);
-
- /**
- * Release pages
- *
- * @param i : in : i value of first page
- * @param p : in : pointer to first page
- * @param cnt : in : no of pages to release
- */
- void release_pages(Uint32 type_id, Uint32 i, Uint32 cnt);
-
- /**
- * Abort
- */
- void handleAbort(int code, const char* msg);
-};
-
-template <typename T>
-struct Ptr
-{
- T * p;
- Uint32 i;
- inline bool isNull() const { return i == RNIL; }
- inline void setNull() { i = RNIL; }
-};
-
-template <typename T>
-struct ConstPtr
-{
- const T * p;
- Uint32 i;
- inline bool isNull() const { return i == RNIL; }
- inline void setNull() { i = RNIL; }
-};
-
-#ifdef XX_DOCUMENTATION_XX
-/**
- * Any pool should implement the following
- */
-struct PoolImpl
-{
- Pool_context m_ctx;
- Record_info m_record_info;
-
- void init(const Record_info& ri, const Pool_context& pc);
- void init(const Record_info& ri, const Pool_context& pc);
-
- bool seize(Ptr<void>&);
- void release(Ptr<void>);
- void * getPtr(Uint32 i);
-};
-#endif
-
-template <typename T, typename P>
-class RecordPool {
-public:
- RecordPool();
- ~RecordPool();
-
- void init(Uint32 type_id, const Pool_context& pc);
- void wo_pool_init(Uint32 type_id, const Pool_context& pc);
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &);
- void getPtr(ConstPtr<T> &) const;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i);
- const T * getConstPtr(Uint32 i) const;
-
- /**
- * Update p & i value for ptr according to <b>i</b> value
- */
- void getPtr(Ptr<T> &, Uint32 i);
- void getPtr(ConstPtr<T> &, Uint32 i) const;
-
- /**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
- bool seize(Ptr<T> &);
-
- /**
- * Return an object to pool
- */
- void release(Uint32 i);
-
- /**
- * Return an object to pool
- */
- void release(Ptr<T>);
-private:
- P m_pool;
-};
-
-template <typename T, typename P>
-inline
-RecordPool<T, P>::RecordPool()
-{
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::init(Uint32 type_id, const Pool_context& pc)
-{
- T tmp;
- const char * off_base = (char*)&tmp;
- const char * off_next = (char*)&tmp.nextPool;
- const char * off_magic = (char*)&tmp.m_magic;
-
- Record_info ri;
- ri.m_size = sizeof(T);
- ri.m_offset_next_pool = Uint32(off_next - off_base);
- ri.m_offset_magic = Uint32(off_magic - off_base);
- ri.m_type_id = type_id;
- m_pool.init(ri, pc);
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::wo_pool_init(Uint32 type_id, const Pool_context& pc)
-{
- T tmp;
- const char * off_base = (char*)&tmp;
- const char * off_magic = (char*)&tmp.m_magic;
-
- Record_info ri;
- ri.m_size = sizeof(T);
- ri.m_offset_next_pool = 0;
- ri.m_offset_magic = Uint32(off_magic - off_base);
- ri.m_type_id = type_id;
- m_pool.init(ri, pc);
-}
-
-template <typename T, typename P>
-inline
-RecordPool<T, P>::~RecordPool()
-{
-}
-
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::getPtr(Ptr<T> & ptr)
-{
- ptr.p = static_cast<T*>(m_pool.getPtr(ptr.i));
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::getPtr(ConstPtr<T> & ptr) const
-{
- ptr.p = static_cast<const T*>(m_pool.getPtr(ptr.i));
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::getPtr(Ptr<T> & ptr, Uint32 i)
-{
- ptr.i = i;
- ptr.p = static_cast<T*>(m_pool.getPtr(ptr.i));
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::getPtr(ConstPtr<T> & ptr, Uint32 i) const
-{
- ptr.i = i;
- ptr.p = static_cast<const T*>(m_pool.getPtr(ptr.i));
-}
-
-template <typename T, typename P>
-inline
-T *
-RecordPool<T, P>::getPtr(Uint32 i)
-{
- return static_cast<T*>(m_pool.getPtr(i));
-}
-
-template <typename T, typename P>
-inline
-const T *
-RecordPool<T, P>::getConstPtr(Uint32 i) const
-{
- return static_cast<const T*>(m_pool.getPtr(i));
-}
-
-template <typename T, typename P>
-inline
-bool
-RecordPool<T, P>::seize(Ptr<T> & ptr)
-{
- Ptr<void> tmp;
- bool ret = m_pool.seize(tmp);
- if(likely(ret))
- {
- ptr.i = tmp.i;
- ptr.p = static_cast<T*>(tmp.p);
- }
- return ret;
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::release(Uint32 i)
-{
- Ptr<void> ptr;
- ptr.i = i;
- ptr.p = m_pool.getPtr(i);
- m_pool.release(ptr);
-}
-
-template <typename T, typename P>
-inline
-void
-RecordPool<T, P>::release(Ptr<T> ptr)
-{
- Ptr<void> tmp;
- tmp.i = ptr.i;
- tmp.p = ptr.p;
- m_pool.release(tmp);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/Prio.hpp b/storage/ndb/src/kernel/vm/Prio.hpp
deleted file mode 100644
index 3cc34a43918..00000000000
--- a/storage/ndb/src/kernel/vm/Prio.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef PRIO_H
-#define PRIO_H
-
-enum JobBufferLevel {
- JBA = 0,
- JBB = 1,
- JBC = 2,
- JBD = 3, LEVEL_IDLE = 3,
- JB_LEVELS,
- ILLEGAL_JB_LEVEL
-};
-
-typedef JobBufferLevel Priority;
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/RWPool.cpp b/storage/ndb/src/kernel/vm/RWPool.cpp
deleted file mode 100644
index a98e2b9b1d1..00000000000
--- a/storage/ndb/src/kernel/vm/RWPool.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "RWPool.hpp"
-#include <ndbd_exit_codes.h>
-#include <NdbOut.hpp>
-
-#define REC_NIL GLOBAL_PAGE_SIZE_WORDS
-
-RWPool::RWPool()
-{
- bzero(this, sizeof(* this));
- m_current_pos = RWPage::RWPAGE_WORDS;
- m_current_first_free = REC_NIL;
- m_first_free_page = RNIL;
-}
-
-void
-RWPool::init(const Record_info& ri, const Pool_context& pc)
-{
- m_ctx = pc;
- m_record_info = ri;
- m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
- m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
- m_record_info.m_offset_next_pool = ((ri.m_offset_next_pool + 3) >> 2);
- m_memroot = (RWPage*)m_ctx.get_memroot();
- ndbout_c("RWPool::init(%x, %d)",ri.m_type_id, m_record_info.m_size);
-}
-
-bool
-RWPool::seize(Ptr<void>& ptr)
-{
- Uint32 pos = m_current_pos;
- Uint32 size = m_record_info.m_size;
- Uint32 off = m_record_info.m_offset_magic;
- RWPage *pageP = m_current_page;
- if (likely(m_current_first_free != REC_NIL))
- {
-seize_free:
- pos = m_current_first_free;
- ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
- ptr.p = pageP->m_data + pos;
- pageP->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
- m_current_ref_count++;
- m_current_first_free = pageP->m_data[pos+m_record_info.m_offset_next_pool];
- return true;
- }
- else if (pos + size < RWPage::RWPAGE_WORDS)
- {
-seize_first:
- ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
- ptr.p = (pageP->m_data + pos);
- pageP->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
- m_current_ref_count++;
- m_current_pos = pos + size;
- return true;
- }
-
- if (m_current_page)
- {
- m_current_page->m_first_free = REC_NIL;
- m_current_page->m_next_page = RNIL;
- m_current_page->m_prev_page = RNIL;
- m_current_page->m_type_id = m_record_info.m_type_id;
- m_current_page->m_ref_count = m_current_ref_count;
- }
-
- if (m_first_free_page != RNIL)
- {
- pageP = m_current_page = m_memroot + m_first_free_page;
- m_current_page_no = m_first_free_page;
- m_current_pos = RWPage::RWPAGE_WORDS;
- m_current_first_free = m_current_page->m_first_free;
- m_first_free_page = m_current_page->m_next_page;
- m_current_ref_count = m_current_page->m_ref_count;
- if (m_first_free_page != RNIL)
- {
- (m_memroot + m_first_free_page)->m_prev_page = RNIL;
- }
- goto seize_free;
- }
-
- m_current_ref_count = 0;
-
- RWPage* page;
- Uint32 page_no = RNIL;
- if ((page = (RWPage*)m_ctx.alloc_page(m_record_info.m_type_id, &page_no)))
- {
- pos = 0;
- m_current_page_no = page_no;
- pageP = m_current_page = page;
- m_current_first_free = REC_NIL;
- page->m_type_id = m_record_info.m_type_id;
- goto seize_first;
- }
-
- m_current_page = 0;
- m_current_page_no = RNIL;
- m_current_pos = RWPage::RWPAGE_WORDS;
- m_current_first_free = REC_NIL;
-
- return false;
-}
-
-void
-RWPool::release(Ptr<void> ptr)
-{
- Uint32 cur_page = m_current_page_no;
- Uint32 ptr_page = ptr.i >> POOL_RECORD_BITS;
- Uint32 *record_ptr = (Uint32*)ptr.p;
- Uint32 magic_val = * (record_ptr + m_record_info.m_offset_magic);
-
- if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
- {
- * (record_ptr + m_record_info.m_offset_magic) = 0;
- if (cur_page == ptr_page)
- {
- * (record_ptr + m_record_info.m_offset_next_pool) = m_current_first_free;
- assert(m_current_ref_count);
- m_current_ref_count--;
- m_current_first_free = ptr.i & POOL_RECORD_MASK;
- return;
- }
-
- // Cache miss on page...
- RWPage* page = m_memroot + ptr_page;
- Uint32 ref_cnt = page->m_ref_count;
- Uint32 ff = page->m_first_free;
-
- * (record_ptr + m_record_info.m_offset_next_pool) = ff;
- page->m_first_free = ptr.i & POOL_RECORD_MASK;
- page->m_ref_count = ref_cnt - 1;
-
- if (ff == REC_NIL)
- {
- /**
- * It was full...add to free page list
- */
- Uint32 ffp = m_first_free_page;
- if (ffp != RNIL)
- {
- RWPage* next = (m_memroot + ffp);
- assert(next->m_prev_page == RNIL);
- next->m_prev_page = ptr_page;
- }
- page->m_next_page = ffp;
- page->m_prev_page = RNIL;
- m_first_free_page = ptr_page;
- return;
- }
- else if(ref_cnt == 1)
- {
- /**
- * It's now empty...release it
- */
- Uint32 prev = page->m_prev_page;
- Uint32 next = page->m_next_page;
- if (prev != RNIL)
- {
- (m_memroot + prev)->m_next_page = next;
- }
- else
- {
- assert(m_first_free_page == ptr_page);
- m_first_free_page = next;
- }
-
- if (next != RNIL)
- {
- (m_memroot + next)->m_prev_page = prev;
- }
- m_ctx.release_page(m_record_info.m_type_id, ptr_page);
- return;
- }
- return;
- }
- handle_invalid_release(ptr);
-}
-
-void
-RWPool::handle_invalid_release(Ptr<void> ptr)
-{
- char buf[255];
-
- Uint32 pos = ptr.i & POOL_RECORD_MASK;
- Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
- Uint32 * record_ptr_p = (Uint32*)ptr.p;
- Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
-
- Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
- snprintf(buf, sizeof(buf),
- "Invalid memory release: ptr (%x %p %p) magic: (%.8x %.8x) memroot: %p page: %x",
- ptr.i, ptr.p, record_ptr_i, magic, m_record_info.m_type_id,
- m_memroot,
- (m_memroot+pageI)->m_type_id);
-
- m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}
-
-void
-RWPool::handle_invalid_get_ptr(Uint32 ptrI)
-{
- char buf[255];
-
- Uint32 pos = ptrI & POOL_RECORD_MASK;
- Uint32 pageI = ptrI >> POOL_RECORD_BITS;
- Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
-
- Uint32 magic = * (record_ptr_i + m_record_info.m_offset_magic);
- snprintf(buf, sizeof(buf),
- "Invalid memory access: ptr (%x %p) magic: (%.8x %.8x) memroot: %p page: %x",
- ptrI, record_ptr_i, magic, m_record_info.m_type_id,
- m_memroot,
- (m_memroot+pageI)->m_type_id);
-
- m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}
diff --git a/storage/ndb/src/kernel/vm/RWPool.hpp b/storage/ndb/src/kernel/vm/RWPool.hpp
deleted file mode 100644
index dfe4c04e644..00000000000
--- a/storage/ndb/src/kernel/vm/RWPool.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef RWPOOL_HPP
-#define RWPOOL_HPP
-
-#include "Pool.hpp"
-
-struct RWPage
-{
- STATIC_CONST( RWPAGE_WORDS = GLOBAL_PAGE_SIZE_WORDS - 4 );
-
- Uint32 m_type_id;
- Uint16 m_first_free;
- Uint16 m_ref_count;
- Uint32 m_next_page;
- Uint32 m_prev_page;
- Uint32 m_data[RWPAGE_WORDS];
-};
-
-/**
- * Read Write Pool
- */
-struct RWPool
-{
- Record_info m_record_info;
- RWPage* m_memroot;
- RWPage* m_current_page;
- Pool_context m_ctx;
- Uint32 m_first_free_page;
- Uint32 m_current_page_no;
- Uint16 m_current_pos;
- Uint16 m_current_first_free;
- Uint16 m_current_ref_count;
-public:
- RWPool();
-
- void init(const Record_info& ri, const Pool_context& pc);
- bool seize(Ptr<void>&);
- void release(Ptr<void>);
- void * getPtr(Uint32 i);
-
-private:
- void handle_invalid_release(Ptr<void>);
- void handle_invalid_get_ptr(Uint32 i);
-};
-
-inline
-void*
-RWPool::getPtr(Uint32 i)
-{
- Uint32 page_no = i >> POOL_RECORD_BITS;
- Uint32 page_idx = i & POOL_RECORD_MASK;
- RWPage * page = m_memroot + page_no;
- Uint32 * record = page->m_data + page_idx;
- Uint32 magic_val = * (record + m_record_info.m_offset_magic);
- if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
- {
- return record;
- }
- handle_invalid_get_ptr(i);
- return 0; /* purify: deadcode */
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/RequestTracker.hpp b/storage/ndb/src/kernel/vm/RequestTracker.hpp
deleted file mode 100644
index 743a90234b1..00000000000
--- a/storage/ndb/src/kernel/vm/RequestTracker.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __REQUEST_TRACKER_HPP
-#define __REQUEST_TRACKER_HPP
-
-#include "SafeCounter.hpp"
-
-class RequestTracker {
-public:
- RequestTracker(){ init(); }
-
- void init() { m_confs.clear(); m_nRefs = 0; }
-
- template<typename SignalClass>
- bool init(SafeCounterManager& mgr,
- NodeReceiverGroup rg, Uint16 GSN, Uint32 senderData)
- {
- init();
- SafeCounter tmp(mgr, m_sc);
- return tmp.init<SignalClass>(rg, GSN, senderData);
- }
-
- bool ignoreRef(SafeCounterManager& mgr, Uint32 nodeId)
- { return m_sc.clearWaitingFor(mgr, nodeId); }
-
- bool reportRef(SafeCounterManager& mgr, Uint32 nodeId)
- { m_nRefs++; return m_sc.clearWaitingFor(mgr, nodeId); }
-
- bool reportConf(SafeCounterManager& mgr, Uint32 nodeId)
- { m_confs.set(nodeId); return m_sc.clearWaitingFor(mgr, nodeId); }
-
- bool hasRef() { return m_nRefs != 0; }
-
- bool hasConf() { return !m_confs.isclear(); }
-
- bool done() { return m_sc.done(); }
-
-private:
- SafeCounterHandle m_sc;
- NodeBitmask m_confs;
- Uint8 m_nRefs;
-};
-
-#endif // __REQUEST_TRACKER_HPP
diff --git a/storage/ndb/src/kernel/vm/Rope.cpp b/storage/ndb/src/kernel/vm/Rope.cpp
deleted file mode 100644
index 9ee48d5fa3e..00000000000
--- a/storage/ndb/src/kernel/vm/Rope.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Copyright (C) 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include "Rope.hpp"
-
-#define DEBUG_ROPE 0
-
-void
-ConstRope::copy(char* buf) const {
- char * ptr = buf;
- if(DEBUG_ROPE)
- ndbout_c("ConstRope::copy() head = [ %d 0x%x 0x%x ]",
- head.used, head.firstItem, head.lastItem);
- Uint32 left = head.used;
- Ptr<Segment> curr;
- curr.i = head.firstItem;
- while(left > 4 * getSegmentSize()){
- thePool.getPtr(curr);
- memcpy(buf, curr.p->data, 4 * getSegmentSize());
- curr.i = curr.p->nextPool;
- left -= 4 * getSegmentSize();
- buf += 4 * getSegmentSize();
- }
- if(left > 0){
- thePool.getPtr(curr);
- memcpy(buf, curr.p->data, left);
- }
-
- if(DEBUG_ROPE)
- ndbout_c("ConstRope::copy()-> %s", ptr);
-}
-
-int
-ConstRope::compare(const char * str, size_t len) const {
- if(DEBUG_ROPE)
- ndbout_c("ConstRope[ %d 0x%x 0x%x ]::compare(%s, %d)",
- head.used, head.firstItem, head.lastItem, str, (int) len);
- Uint32 left = head.used > len ? len : head.used;
- Ptr<Segment> curr;
- curr.i = head.firstItem;
- while(left > 4 * getSegmentSize()){
- thePool.getPtr(curr);
- int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
- if(res != 0){
- if(DEBUG_ROPE)
- ndbout_c("ConstRope::compare(%s, %d, %s) -> %d", str, left,
- (const char*)curr.p->data, res);
- return res;
- }
- curr.i = curr.p->nextPool;
- left -= 4 * getSegmentSize();
- str += 4 * getSegmentSize();
- }
-
- if(left > 0){
- thePool.getPtr(curr);
- int res = memcmp(str, (const char*)curr.p->data, left);
- if(res){
- if(DEBUG_ROPE)
- ndbout_c("ConstRope::compare(%s, %d, %s) -> %d",
- str, left, (const char*)curr.p->data, res);
- return res;
- }
- }
- if(DEBUG_ROPE)
- ndbout_c("ConstRope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
- return head.used > len;
-}
-
-void
-Rope::copy(char* buf) const {
- char * ptr = buf;
- if(DEBUG_ROPE)
- ndbout_c("Rope::copy() head = [ %d 0x%x 0x%x ]",
- head.used, head.firstItem, head.lastItem);
- Uint32 left = head.used;
- Ptr<Segment> curr;
- curr.i = head.firstItem;
- while(left > 4 * getSegmentSize()){
- thePool.getPtr(curr);
- memcpy(buf, curr.p->data, 4 * getSegmentSize());
- curr.i = curr.p->nextPool;
- left -= 4 * getSegmentSize();
- buf += 4 * getSegmentSize();
- }
- if(left > 0){
- thePool.getPtr(curr);
- memcpy(buf, curr.p->data, left);
- }
- if(DEBUG_ROPE)
- ndbout_c("Rope::copy()-> %s", ptr);
-}
-
-int
-Rope::compare(const char * str, size_t len) const {
- if(DEBUG_ROPE)
- ndbout_c("Rope::compare(%s, %d)", str, (int) len);
- Uint32 left = head.used > len ? len : head.used;
- Ptr<Segment> curr;
- curr.i = head.firstItem;
- while(left > 4 * getSegmentSize()){
- thePool.getPtr(curr);
- int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
- if(res != 0){
- if(DEBUG_ROPE)
- ndbout_c("Rope::compare(%s, %d, %s) -> %d", str, (int) len,
- (const char*)curr.p->data, res);
- return res;
- }
-
- curr.i = curr.p->nextPool;
- left -= 4 * getSegmentSize();
- str += 4 * getSegmentSize();
- }
-
- if(left > 0){
- thePool.getPtr(curr);
- int res = memcmp(str, (const char*)curr.p->data, left);
- if(res){
- if(DEBUG_ROPE)
- ndbout_c("Rope::compare(%s, %d) -> %d", str, (int) len, res);
- return res;
- }
- }
- if(DEBUG_ROPE)
- ndbout_c("Rope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
- return head.used > len;
-}
-
-bool
-Rope::assign(const char * s, size_t len, Uint32 hash){
- if(DEBUG_ROPE)
- ndbout_c("Rope::assign(%s, %d, 0x%x)", s, (int) len, hash);
- m_hash = hash;
- head.used = (head.used + 3) / 4;
- release();
- if(append((const Uint32*)s, len >> 2)){
- if(len & 3){
- Uint32 buf = 0;
- const char * src = (const char*)(((Uint32*)s)+(len >> 2));
- char* dst = (char*)&buf;
- size_t left = len & 3;
- while(left){
- * dst ++ = * src++;
- left--;
- }
- if(!append(&buf, 1))
- return false;
- }
- head.used = len;
- if(DEBUG_ROPE)
- ndbout_c("Rope::assign(...) head = [ %d 0x%x 0x%x ]",
- head.used, head.firstItem, head.lastItem);
- return true;
- }
- return false;
-}
-
-void
-Rope::erase(){
- head.used = (head.used + 3) / 4;
- release();
-}
-
-Uint32
-Rope::hash(const char * p, Uint32 len){
- if(DEBUG_ROPE)
- ndbout_c("Rope::hash(%s, %d)", p, len);
- Uint32 h = 0;
- for (; len > 0; len--)
- h = (h << 5) + h + (* p++);
- if(DEBUG_ROPE)
- ndbout_c("Rope::hash(...) -> 0x%x", h);
- return h;
-}
-
diff --git a/storage/ndb/src/kernel/vm/Rope.hpp b/storage/ndb/src/kernel/vm/Rope.hpp
deleted file mode 100644
index d7e3ccc6e53..00000000000
--- a/storage/ndb/src/kernel/vm/Rope.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_ROPE_HPP
-#define NDB_ROPE_HPP
-
-#include "DataBuffer.hpp"
-
-typedef DataBuffer<7> RopeBase;
-typedef DataBuffer<7>::DataBufferPool RopePool;
-
-struct RopeHandle {
- RopeHandle() { m_hash = 0; }
-
- Uint32 m_hash;
- RopeBase::Head m_head;
-
- Uint32 hashValue() const { return m_hash; }
-};
-
-class ConstRope : private RopeBase {
-public:
- ConstRope(RopePool& thePool, const RopeHandle& handle)
- : RopeBase(thePool), src(handle)
- {
- this->head = src.m_head;
- }
-
- ~ConstRope(){
- }
-
- size_t size() const;
- bool empty() const;
-
- void copy(char* buf) const;
-
- int compare(const char * s) const { return compare(s, strlen(s) + 1); }
- int compare(const char *, size_t len) const;
-
-private:
- const RopeHandle & src;
-};
-
-class Rope : private RopeBase {
-public:
- Rope(RopePool& thePool, RopeHandle& handle)
- : RopeBase(thePool), src(handle)
- {
- this->head = src.m_head;
- m_hash = src.m_hash;
- }
-
- ~Rope(){
- src.m_head = this->head;
- src.m_hash = m_hash;
- }
-
- size_t size() const;
- bool empty() const;
-
- void copy(char* buf) const;
-
- int compare(const char * s) const { return compare(s, strlen(s) + 1); }
- int compare(const char *, size_t len) const;
-
- bool assign(const char * s) { return assign(s, strlen(s) + 1);}
- bool assign(const char * s, size_t l) { return assign(s, l, hash(s, l));}
- bool assign(const char *, size_t len, Uint32 hash);
-
- void erase();
-
- static Uint32 hash(const char * str, Uint32 len);
-
-private:
- Uint32 m_hash;
- RopeHandle & src;
-};
-
-inline
-size_t
-Rope::size() const {
- return head.used;
-}
-
-inline
-bool
-Rope::empty() const {
- return head.used == 0;
-}
-
-inline
-size_t
-ConstRope::size() const {
- return head.used;
-}
-
-inline
-bool
-ConstRope::empty() const {
- return head.used == 0;
-}
-
-#endif
-
diff --git a/storage/ndb/src/kernel/vm/SLFifoList.hpp b/storage/ndb/src/kernel/vm/SLFifoList.hpp
deleted file mode 100644
index 4cd370a3129..00000000000
--- a/storage/ndb/src/kernel/vm/SLFifoList.hpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/* Copyright (c) 2003, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SLFIFOLIST_HPP
-#define SLFIFOLIST_HPP
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-#include "Pool.hpp"
-
-/**
- * Template class used for implementing an
- * list of object retreived from a pool
- */
-template <typename P, typename T, typename U = T>
-class SLFifoListImpl
-{
-public:
- /**
- * List head
- */
- struct Head
- {
- Head();
- Uint32 firstItem;
- Uint32 lastItem;
-
-#ifdef VM_TRACE
- bool in_use;
-#endif
-
- inline bool isEmpty() const { return firstItem == RNIL;}
- };
-
- SLFifoListImpl(P & thePool);
-
- bool seizeFirst(Ptr<T> &);
- bool seizeLast(Ptr<T> &);
- bool seize(Ptr<T> & ptr) { return seizeLast(ptr);}
-
- void releaseFirst(Ptr<T> &);
-
- void addFirst(Ptr<T> &);
- void addLast(Ptr<T> &);
-
- void removeFirst(Ptr<T> &);
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const ;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const ;
-
- /**
- * Update ptr to first element in list
- *
- * Return i
- */
- bool first(Ptr<T> &) const ;
-
- /**
- * Update ptr to first element in list
- *
- * Return i
- */
- bool last(Ptr<T> &) const ;
-
- /**
- * Get next element
- *
- * NOTE ptr must be both p & i
- */
- bool next(Ptr<T> &) const ;
-
- /**
- * Check if next exists i.e. this is not last
- *
- * NOTE ptr must be both p & i
- */
- bool hasNext(const Ptr<T> &) const;
-
- inline bool isEmpty() const { return head.firstItem == RNIL;}
-
-protected:
- Head head;
- P & thePool;
-};
-
-template <typename P, typename T, typename U = T>
-class LocalSLFifoListImpl : public SLFifoListImpl<P,T,U>
-{
-public:
- LocalSLFifoListImpl(P & thePool, typename SLFifoListImpl<P,T,U>::Head &_src)
- : SLFifoListImpl<P,T,U>(thePool), src(_src)
- {
- this->head = src;
-#ifdef VM_TRACE
- assert(src.in_use == false);
- src.in_use = true;
-#endif
- }
-
- ~LocalSLFifoListImpl(){
-#ifdef VM_TRACE
- assert(src.in_use == true);
-#endif
- src = this->head;
- }
-private:
- typename SLFifoListImpl<P,T,U>::Head & src;
-};
-
-template <typename P, typename T, typename U>
-inline
-SLFifoListImpl<P,T,U>::SLFifoListImpl(P & _pool):
- thePool(_pool)
-{
-}
-
-template <typename P, typename T, typename U>
-inline
-SLFifoListImpl<P,T,U>::Head::Head()
-{
- firstItem = RNIL;
- lastItem = RNIL;
-#ifdef VM_TRACE
- in_use = false;
-#endif
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::seizeFirst(Ptr<T> & p)
-{
- if (likely(thePool.seize(p)))
- {
- addFirst(p);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::seizeLast(Ptr<T> & p)
-{
- if (likely(thePool.seize(p)))
- {
- addLast(p);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::addFirst(Ptr<T> & p)
-{
- Uint32 first = head.firstItem;
- head.firstItem = p.i;
- if (first == RNIL)
- {
- head.lastItem = p.i;
- }
- p.p->U::nextList = first;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::addLast(Ptr<T> & p)
-{
- T * t = p.p;
- Uint32 last = head.lastItem;
-
- t->U::nextList = RNIL;
- head.lastItem = p.i;
-
- if(last != RNIL)
- {
- T * t2 = thePool.getPtr(last);
- t2->U::nextList = p.i;
- }
- else
- {
- head.firstItem = p.i;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::removeFirst(Ptr<T> & p)
-{
- Uint32 first = head.firstItem;
- Uint32 last = head.lastItem;
- assert(p.i == first);
- if (first != last)
- {
- head.firstItem = p.p->U::nextList;
- }
- else
- {
- head.firstItem = head.lastItem = RNIL;
- }
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::releaseFirst(Ptr<T> & p)
-{
- removeFirst(p);
- thePool.release(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
-{
- p.i = i;
- p.p = thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p) const
-{
- thePool.getPtr(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-T *
-SLFifoListImpl<P,T,U>::getPtr(Uint32 i) const
-{
- return thePool.getPtr(i);
-}
-
-/**
- * Update ptr to first element in list
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::first(Ptr<T> & p) const
-{
- p.i = head.firstItem;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::last(Ptr<T> & p) const
-{
- p.i = head.lastItem;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::next(Ptr<T> & p) const
-{
- p.i = p.p->U::nextList;
- if(p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLFifoListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
-{
- return p.p->U::nextList != RNIL;
-}
-
-// Specializations
-
-template <typename T, typename U = T>
-class SLFifoList : public SLFifoListImpl<ArrayPool<T>, T, U>
-{
-public:
- SLFifoList(ArrayPool<T> & p) : SLFifoListImpl<ArrayPool<T>, T, U>(p) {}
-};
-
-template <typename T, typename U = T>
-class LocalSLFifoList : public LocalSLFifoListImpl<ArrayPool<T>,T,U> {
-public:
- LocalSLFifoList(ArrayPool<T> & p, typename SLFifoList<T,U>::Head & _src)
- : LocalSLFifoListImpl<ArrayPool<T>,T,U>(p, _src) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SLList.hpp b/storage/ndb/src/kernel/vm/SLList.hpp
deleted file mode 100644
index 08ba6898185..00000000000
--- a/storage/ndb/src/kernel/vm/SLList.hpp
+++ /dev/null
@@ -1,402 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SLLIST_HPP
-#define SLLIST_HPP
-
-#include "ArrayPool.hpp"
-#include <NdbOut.hpp>
-
-/**
- * Template class used for implementing an
- * list of object retreived from a pool
- */
-template <typename P, typename T, typename U = T>
-class SLListImpl
-{
-public:
- /**
- * List head
- */
- struct HeadPOD {
- Uint32 firstItem;
- void init() { firstItem = RNIL;}
- };
-
- struct Head : public HeadPOD {
- Head();
- Head& operator= (const HeadPOD& src) {
- this->firstItem = src.firstItem;
- return *this;
- }
- };
-
- SLListImpl(P & thePool);
-
- /**
- * Allocate an object from pool - update Ptr
- *
- * Return i
- */
- bool seize(Ptr<T> &);
-
- /**
- * Allocate object <b>i</b> from pool - update Ptr
- *
- * Return i
- */
- bool seizeId(Ptr<T> &, Uint32 i);
-
- /**
- * Allocate <b>n</b>objects from pool
- *
- * Return i value of first object allocated or RNIL if fails
- */
- bool seizeN(Ptr<T> &, Uint32 n);
-
- /**
- * Return all objects to the pool
- */
- void release();
-
- /**
- * Remove all object from list but don't return to pool
- */
- void remove();
-
- /**
- * Update i & p value according to <b>i</b>
- */
- void getPtr(Ptr<T> &, Uint32 i) const;
-
- /**
- * Update p value for ptr according to i value
- */
- void getPtr(Ptr<T> &) const ;
-
- /**
- * Get pointer for i value
- */
- T * getPtr(Uint32 i) const ;
-
- /**
- * Update ptr to first element in list
- *
- * Return i
- */
- bool first(Ptr<T> &) const ;
-
- /**
- * Get next element
- *
- * NOTE ptr must be both p & i
- */
- bool next(Ptr<T> &) const ;
-
- /**
- * Check if next exists
- *
- * NOTE ptr must be both p & i
- */
- bool hasNext(const Ptr<T> &) const;
-
- /**
- * Add
- */
- void add(Ptr<T> & p){
- p.p->U::nextList = head.firstItem;
- head.firstItem = p.i;
- }
-
- /**
- * Add a list to list
- * @NOTE all elements _must_ be correctly initilized correctly wrt next/prev
- */
- void add(Uint32 first, Ptr<T> & last);
-
- /**
- * Remove object from list
- *
- * @NOTE Does not return it to pool
- */
- bool remove_front(Ptr<T> &);
-
- Uint32 noOfElements() const {
- Uint32 c = 0;
- Uint32 i = head.firstItem;
- while(i != RNIL){
- c++;
- const T * t = thePool.getPtr(i);
- i = t->U::nextList;
- }
- return c;
- }
-
- /**
- * Print
- * (Run operator NdbOut<< on every element)
- */
- void print(NdbOut & out) {
- out << "firstItem = " << head.firstItem << endl;
- Uint32 i = head.firstItem;
- while(i != RNIL){
- T * t = thePool.getPtr(i);
- t->print(out); out << " ";
- i = t->next;
- }
- }
-
- inline bool empty() const { return head.firstItem == RNIL;}
-
-protected:
- Head head;
- P & thePool;
-};
-
-template <typename P, typename T, typename U = T>
-class LocalSLListImpl : public SLListImpl<P, T, U>
-{
-public:
- LocalSLListImpl(P & thePool, typename SLListImpl<P, T, U>::HeadPOD & _src)
- : SLListImpl<P, T, U>(thePool), src(_src)
- {
- this->head = src;
- }
-
- ~LocalSLListImpl(){
- src = this->head;
- }
-private:
- typename SLListImpl<P, T, U>::HeadPOD & src;
-};
-
-template <typename P, typename T, typename U>
-inline
-SLListImpl<P, T, U>::SLListImpl(P & _pool):
- thePool(_pool)
-{
-}
-
-template <typename P, typename T, typename U>
-inline
-SLListImpl<P, T, U>::Head::Head()
-{
- this->init();
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::seize(Ptr<T> & p)
-{
- thePool.seize(p);
- T * t = p.p;
- Uint32 ff = head.firstItem;
- if(p.i != RNIL)
- {
- t->U::nextList = ff;
- head.firstItem = p.i;
- return true;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::seizeId(Ptr<T> & p, Uint32 ir)
-{
- thePool.seizeId(p, ir);
- T * t = p.p;
- Uint32 ff = head.firstItem;
- if(p.i != RNIL)
- {
- t->U::nextList = ff;
- head.firstItem = p.i;
- return true;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::seizeN(Ptr<T> & p, Uint32 n)
-{
- for(Uint32 i = 0; i < n; i++)
- {
- if(seize(p) == RNIL)
- {
- /**
- * Failure
- */
- for(; i > 0; i--)
- {
- p.i = head.firstItem;
- thePool.getPtr(p);
- head.firstItem = p.p->U::nextList;
- thePool.release(p);
- }
- return false;
- }
- }
-
- /**
- * Success
- */
- p.i = head.firstItem;
- p.p = thePool.getPtr(head.firstItem);
-
- return true;
-}
-
-
-template <typename P, typename T, typename U>
-inline
-void
-SLListImpl<P, T, U>::remove()
-{
- head.firstItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::remove_front(Ptr<T> & p)
-{
- p.i = head.firstItem;
- if (p.i != RNIL)
- {
- p.p = thePool.getPtr(p.i);
- head.firstItem = p.p->U::nextList;
- return true;
- }
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLListImpl<P, T, U>::add(Uint32 first, Ptr<T> & last)
-{
- last.p->U::nextList = head.firstItem;
- head.firstItem = first;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLListImpl<P, T, U>::release()
-{
- Ptr<T> ptr;
- Uint32 curr = head.firstItem;
- while(curr != RNIL)
- {
- thePool.getPtr(ptr, curr);
- curr = ptr.p->U::nextList;
- thePool.release(ptr);
- }
- head.firstItem = RNIL;
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLListImpl<P, T, U>::getPtr(Ptr<T> & p, Uint32 i) const
-{
- p.i = i;
- p.p = thePool.getPtr(i);
-}
-
-template <typename P, typename T, typename U>
-inline
-void
-SLListImpl<P, T, U>::getPtr(Ptr<T> & p) const
-{
- thePool.getPtr(p);
-}
-
-template <typename P, typename T, typename U>
-inline
-T *
-SLListImpl<P, T, U>::getPtr(Uint32 i) const
-{
- return thePool.getPtr(i);
-}
-
-/**
- * Update ptr to first element in list
- *
- * Return i
- */
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::first(Ptr<T> & p) const
-{
- Uint32 i = head.firstItem;
- p.i = i;
- if(i != RNIL)
- {
- p.p = thePool.getPtr(i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::next(Ptr<T> & p) const
-{
- Uint32 i = p.p->U::nextList;
- p.i = i;
- if(i != RNIL)
- {
- p.p = thePool.getPtr(i);
- return true;
- }
- p.p = NULL;
- return false;
-}
-
-template <typename P, typename T, typename U>
-inline
-bool
-SLListImpl<P, T, U>::hasNext(const Ptr<T> & p) const
-{
- return p.p->U::nextList != RNIL;
-}
-
-// Specializations
-
-template <typename T, typename U = T>
-class SLList : public SLListImpl<ArrayPool<T>, T, U>
-{
-public:
- SLList(ArrayPool<T> & p) : SLListImpl<ArrayPool<T>, T, U>(p) {}
-};
-
-template <typename T, typename U = T>
-class LocalSLList : public LocalSLListImpl<ArrayPool<T>,T,U> {
-public:
- LocalSLList(ArrayPool<T> & p, typename SLList<T,U>::Head & _src)
- : LocalSLListImpl<ArrayPool<T>,T,U>(p, _src) {}
-};
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SafeCounter.cpp b/storage/ndb/src/kernel/vm/SafeCounter.cpp
deleted file mode 100644
index f01bb4d8f85..00000000000
--- a/storage/ndb/src/kernel/vm/SafeCounter.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include "SimulatedBlock.hpp"
-#include "SafeCounter.hpp"
-#include <signaldata/NodeFailRep.hpp>
-
-SafeCounterManager::SafeCounterManager(class SimulatedBlock & block)
- : m_block(block),
- m_activeCounters(m_counterPool)
-{}
-
-bool
-SafeCounterManager::setSize(Uint32 maxNoOfActiveMutexes, bool exit_on_error) {
- return m_counterPool.setSize(maxNoOfActiveMutexes, false, exit_on_error);
-}
-
-Uint32
-SafeCounterManager::getSize() const {
- return m_counterPool.getSize();
-}
-
-bool
-SafeCounterManager::seize(ActiveCounterPtr& ptr){
- return m_activeCounters.seize(ptr);
-}
-
-void
-SafeCounterManager::release(ActiveCounterPtr& ptr){
- m_activeCounters.release(ptr);
-}
-
-void
-SafeCounterManager::getPtr(ActiveCounterPtr& ptr, Uint32 ptrI){
- m_activeCounters.getPtr(ptr, ptrI);
-}
-
-
-void
-SafeCounterManager::printNODE_FAILREP(){
- ActiveCounterPtr ptr;
-
- NodeBitmask nodes;
- nodes.clear();
- // nodes.bitORC(nodes);
-
- for(m_activeCounters.first(ptr); !ptr.isNull(); m_activeCounters.next(ptr)){
- ActiveCounter::SignalDesc desc = ptr.p->m_signalDesc;
- ndbout_c("theData[desc.m_senderDataOffset=%u] = %u",
- desc.m_senderDataOffset, ptr.p->m_senderData);
- ndbout_c("theData[desc.m_errorCodeOffset=%u] = %u",
- desc.m_errorCodeOffset, desc.m_nodeFailErrorCode);
- Uint32 len = MAX(MAX(desc.m_senderDataOffset, desc.m_errorCodeOffset),
- desc.m_senderRefOffset);
-
- NodeBitmask overlapping = ptr.p->m_nodes;
- Uint32 i = 0;
- while((i = overlapping.find(i)) != NodeBitmask::NotFound){
- ndbout_c(" theData[desc.m_senderRefOffset=%u] = %x",
- desc.m_senderRefOffset, numberToRef(desc.m_block, i));
- ndbout_c(" sendSignal(%x,%u,signal,%u,JBB",
- m_block.reference(), desc.m_gsn, len+1);
- i++;
- }
- }
-}
-
-void
-SafeCounterManager::execNODE_FAILREP(Signal* signal){
- Uint32 * theData = signal->getDataPtrSend();
- ActiveCounterPtr ptr;
- NodeBitmask nodes;
- nodes.assign(NodeBitmask::Size,
- ((const NodeFailRep*)signal->getDataPtr())->theNodes);
-
- for(m_activeCounters.first(ptr); !ptr.isNull(); m_activeCounters.next(ptr)){
- if(nodes.overlaps(ptr.p->m_nodes)){
- ActiveCounter::SignalDesc desc = ptr.p->m_signalDesc;
- theData[desc.m_senderDataOffset] = ptr.p->m_senderData;
- theData[desc.m_errorCodeOffset] = desc.m_nodeFailErrorCode;
- Uint32 len = MAX(MAX(desc.m_senderDataOffset, desc.m_errorCodeOffset),
- desc.m_senderRefOffset);
-
- NodeBitmask overlapping = ptr.p->m_nodes;
- overlapping.bitAND(nodes);
- Uint32 i = 0;
- while((i = overlapping.find(i)) != NodeBitmask::NotFound){
- theData[desc.m_senderRefOffset] = numberToRef(desc.m_block, i);
- m_block.sendSignal(m_block.reference(), desc.m_gsn, signal, len+1,JBB);
- i++;
- }
- }
- }
-}
-
-BlockReference
-SafeCounterManager::reference() const {
- return m_block.reference();
-}
-
-void
-SafeCounterManager::progError(int line, int err_code, const char* extra){
- m_block.progError(line, err_code, extra);
-}
-
-bool
-SafeCounterHandle::clearWaitingFor(SafeCounterManager& mgr, Uint32 nodeId)
-{
- SafeCounterManager::ActiveCounterPtr ptr;
- mgr.getPtr(ptr, m_activeCounterPtrI);
- ptr.p->m_nodes.clear(nodeId);
-
- if (ptr.p->m_nodes.isclear()){
- mgr.release(ptr);
- m_activeCounterPtrI = RNIL;
- return true;
- }
- return false;
-}
-
-SafeCounter::~SafeCounter(){
- bool clear = m_count == 0;
- bool isnull = m_ptr.i == RNIL;
-
- m_activeCounterPtrI = m_ptr.i;
-
- if(clear && isnull)
- return;
-
- if(clear && !isnull){
- m_mgr.release(m_ptr);
- m_activeCounterPtrI = RNIL;
- return;
- }
-
- /**
- * !clear && !isnull
- */
- if(!isnull){
- m_ptr.p->m_nodes = m_nodes;
- return;
- }
-
- ErrorReporter::handleAssert("~SafeCounter:: wo/ init", __FILE__, __LINE__);
-}
diff --git a/storage/ndb/src/kernel/vm/SafeCounter.hpp b/storage/ndb/src/kernel/vm/SafeCounter.hpp
deleted file mode 100644
index 7a917fd4310..00000000000
--- a/storage/ndb/src/kernel/vm/SafeCounter.hpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __SAFE_COUNTER_HPP
-#define __SAFE_COUNTER_HPP
-
-/*************************************************************
- *
- * SafeCounter "automates" three way to node-fais safe protocols
- * for "slave" failures. This is done by registing "fake" signals
- * to be sent in case of nodefailure.
- *
- * init<SignalClass>(..., GSN, senderData);
- *
- * It is implemented so that one can replace SignalCounter with
- * SafeCounter (SignalCounter should probably go away with time)
- * methods:
- * clearWaitingFor(nodeId);
- * done();
- * etc.
- *
- * If included in a new block method
- * SafeCounterManager::execNODE_FAILREP must included in
- * <block>::execNODE_FAILREP
- *
- * the SignalClass must have senderRef, senderData and errorCode
- * and also ErrorCode::NF_FakeErrorREF, implemented
- *
- * SafeCounter consists of 3 parts:
- * SafeCounterManager which keeps track of active "counters"
- * SafeCounterHandle to store "i-value" in your "op record"
- * SafeCounter as a temporary variable only to use on the stack
- * for operation
- *
- */
-
-#include <NodeBitmask.hpp>
-#include "DLList.hpp"
-#include "VMSignal.hpp"
-
-class SimulatedBlock;
-
-/**
- *
- */
-class SafeCounterManager {
- friend class SafeCounter;
- friend class SafeCounterHandle;
- friend class SimulatedBlock;
-public:
- SafeCounterManager(class SimulatedBlock &);
-
- bool setSize(Uint32 maxNoOfActiveMutexes, bool exit_on_error = true);
- Uint32 getSize() const ;
-
- void execNODE_FAILREP(Signal*);
- void printNODE_FAILREP();
-
-private:
- struct ActiveCounter { /** sizeof = 7words = 28bytes */
- public:
- Uint32 m_senderData;
- NodeBitmask m_nodes;
- struct SignalDesc {
- public:
- Uint16 m_gsn;
- Uint16 m_block;
- Uint8 m_senderRefOffset;
- Uint8 m_senderDataOffset;
- Uint8 m_errorCodeOffset;
- Uint8 m_nodeFailErrorCode;
- } m_signalDesc;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- typedef Ptr<ActiveCounter> ActiveCounterPtr;
-
- bool seize(ActiveCounterPtr& ptr);
- void release(ActiveCounterPtr& ptr);
- void getPtr(ActiveCounterPtr& ptr, Uint32 ptrI);
-
- SimulatedBlock & m_block;
- ArrayPool<ActiveCounter> m_counterPool;
- DLList<ActiveCounter> m_activeCounters;
-
- BlockReference reference() const;
- void progError(int line, int err_code, const char* extra = 0);
-};
-
-
-class SafeCounterHandle {
- friend class SafeCounter;
-public:
- SafeCounterHandle();
-
- /**
- * Return if done (no nodes set in bitmask)
- */
- bool clearWaitingFor(SafeCounterManager& mgr, Uint32 nodeId);
-
- bool done() const;
-
-private:
- Uint32 m_activeCounterPtrI;
-};
-
-class SafeCounter {
- friend class SafeCounterManager;
-public:
- SafeCounter(SafeCounterManager&, SafeCounterHandle&);
-
- template<typename SignalClass>
- bool init(Uint16 block, Uint16 GSN, Uint32 senderData);
-
- template<typename SignalClass>
- bool init(NodeReceiverGroup rg, Uint16 GSN, Uint32 senderData);
-
- template<typename SignalClass>
- bool init(NodeReceiverGroup rg, Uint32 senderData);
-
- ~SafeCounter();
-
- void clearWaitingFor();
-
- /**
- * When sending to different node
- */
- void setWaitingFor(Uint32 nodeId);
- bool clearWaitingFor(Uint32 nodeId);
- bool forceClearWaitingFor(Uint32 nodeId);
-
- bool isWaitingFor(Uint32 nodeId) const;
- bool done() const;
-
- const char * getText() const; /* ? needed for, some portability issues */
-
- SafeCounter& operator=(const NdbNodeBitmask&);
- SafeCounter& operator=(const NodeReceiverGroup&);
-private:
- Uint32 m_count;
- NodeBitmask m_nodes;
-
- SafeCounterManager & m_mgr;
- SafeCounterManager::ActiveCounterPtr m_ptr;
-
- Uint32 & m_activeCounterPtrI;
-};
-
-inline
-SafeCounterHandle::SafeCounterHandle(){
- m_activeCounterPtrI = RNIL;
-}
-
-inline
-bool
-SafeCounterHandle::done() const {
- return m_activeCounterPtrI == RNIL;
-}
-
-inline
-SafeCounter::SafeCounter(SafeCounterManager& mgr, SafeCounterHandle& handle)
- : m_mgr(mgr),
- m_activeCounterPtrI(handle.m_activeCounterPtrI)
-{
- m_ptr.i = handle.m_activeCounterPtrI;
- if (m_ptr.i == RNIL) {
- m_nodes.clear();
- m_count = 0;
- } else {
- m_mgr.getPtr(m_ptr, m_ptr.i);
- m_nodes = m_ptr.p->m_nodes;
- m_count = m_nodes.count();
- }
-}
-
-template<typename Ref>
-inline
-bool
-SafeCounter::init(Uint16 block, Uint16 GSN, Uint32 senderData){
-
- SafeCounterManager::ActiveCounter::SignalDesc signalDesc;
- signalDesc.m_gsn = GSN;
- signalDesc.m_block = block;
- signalDesc.m_errorCodeOffset = offsetof(Ref, errorCode) >> 2;
- signalDesc.m_senderRefOffset = offsetof(Ref, senderRef) >> 2;
- signalDesc.m_senderDataOffset = offsetof(Ref, senderData) >> 2;
- signalDesc.m_nodeFailErrorCode = Ref::NF_FakeErrorREF;
- assert(((Uint32)Ref::NF_FakeErrorREF) < 256);
-
- if(m_ptr.i == RNIL){
- SafeCounterManager::ActiveCounterPtr ptr;
- if(m_mgr.seize(ptr)){
- ptr.p->m_senderData = senderData;
- ptr.p->m_signalDesc = signalDesc;
- m_ptr = ptr;
- return true;
- }
- return false;
- }
-
- if(m_count == 0){
- m_ptr.p->m_senderData = senderData;
- m_ptr.p->m_signalDesc = signalDesc;
- return true;
- }
-
- ErrorReporter::handleAssert("SafeCounter::init twice", __FILE__, __LINE__);
- return false;
-}
-
-template<typename Ref>
-inline
-bool
-SafeCounter::init(NodeReceiverGroup rg, Uint16 GSN, Uint32 senderData){
-
- if (init<Ref>(rg.m_block, GSN, senderData))
- {
- m_nodes = rg.m_nodes;
- m_count = m_nodes.count();
- return true;
- }
- return false;
-}
-
-template<typename Ref>
-inline
-bool
-SafeCounter::init(NodeReceiverGroup rg, Uint32 senderData){
-
- if (init<Ref>(rg.m_block, Ref::GSN, senderData))
- {
- m_nodes = rg.m_nodes;
- m_count = m_nodes.count();
- return true;
- }
- return false;
-}
-
-inline
-void
-SafeCounter::setWaitingFor(Uint32 nodeId) {
- if(!m_nodes.get(nodeId)){
- m_nodes.set(nodeId);
- m_count++;
- return;
- }
- ErrorReporter::handleAssert("SafeCounter::set", __FILE__, __LINE__);
-}
-
-inline
-bool
-SafeCounter::isWaitingFor(Uint32 nodeId) const {
- return m_nodes.get(nodeId);
-}
-
-inline
-bool
-SafeCounter::done() const {
- return m_count == 0;
-}
-
-inline
-bool
-SafeCounter::clearWaitingFor(Uint32 nodeId) {
- if(m_count > 0 && m_nodes.get(nodeId)){
- m_count--;
- m_nodes.clear(nodeId);
- return (m_count == 0);
- }
- ErrorReporter::handleAssert("SafeCounter::clear", __FILE__, __LINE__);
- return false;
-}
-
-inline
-void
-SafeCounter::clearWaitingFor(){
- m_count = 0;
- m_nodes.clear();
-}
-
-inline
-bool
-SafeCounter::forceClearWaitingFor(Uint32 nodeId){
- if(isWaitingFor(nodeId)){
- return clearWaitingFor(nodeId);
- }
- return (m_count == 0);
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SectionReader.cpp b/storage/ndb/src/kernel/vm/SectionReader.cpp
deleted file mode 100644
index 7cad2ed51c1..00000000000
--- a/storage/ndb/src/kernel/vm/SectionReader.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <SectionReader.hpp>
-#include <TransporterDefinitions.hpp>
-#include "LongSignal.hpp"
-
-#if 0
- Uint32 m_len;
- class SectionSegmentPool & m_pool;
- class SectionSegment * m_head;
- class SectionSegment * m_currentPos;
-#endif
-
-SectionReader::SectionReader
-(struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool)
- : m_pool(pool)
-{
- if(ptr.p == 0){
- m_pos = 0;
- m_len = 0;
- m_head = 0;
- m_currentSegment = 0;
- } else {
- m_pos = 0;
- m_len = ptr.p->m_sz;
- m_head = ptr.p;
- m_currentSegment = ptr.p;
- }
-}
-
-void
-SectionReader::reset(){
- m_pos = 0;
- m_currentSegment = m_head;
-}
-
-bool
-SectionReader::step(Uint32 len){
- if(m_pos + len >= m_len) {
- m_pos++;
- return false;
- }
- while(len > SectionSegment::DataLength){
- m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
-
- len -= SectionSegment::DataLength;
- m_pos += SectionSegment::DataLength;
- }
-
- Uint32 ind = m_pos % SectionSegment::DataLength;
- while(len > 0){
- len--;
- m_pos++;
-
- ind++;
- if(ind == SectionSegment::DataLength){
- ind = 0;
- m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
- }
- }
- return true;
-}
-
-bool
-SectionReader::getWord(Uint32 * dst){
- if (peekWord(dst)) {
- step(1);
- return true;
- }
- return false;
-}
-
-bool
-SectionReader::peekWord(Uint32 * dst) const {
- if(m_pos < m_len){
- Uint32 ind = m_pos % SectionSegment::DataLength;
- * dst = m_currentSegment->theData[ind];
- return true;
- }
- return false;
-}
-
-bool
-SectionReader::peekWords(Uint32 * dst, Uint32 len) const {
- if(m_pos + len > m_len)
- return false;
-
- Uint32 ind = (m_pos % SectionSegment::DataLength);
- Uint32 left = SectionSegment::DataLength - ind;
- SectionSegment * p = m_currentSegment;
-
- while(len > left){
- memcpy(dst, &p->theData[ind], 4 * left);
- dst += left;
- len -= left;
- ind = 0;
- left = SectionSegment::DataLength;
- p = m_pool.getPtr(p->m_nextSegment);
- }
-
- memcpy(dst, &p->theData[ind], 4 * len);
- return true;
-}
-
-bool
-SectionReader::getWords(Uint32 * dst, Uint32 len){
- if(m_pos + len > m_len)
- return false;
-
- Uint32 ind = (m_pos % SectionSegment::DataLength);
- Uint32 left = SectionSegment::DataLength - ind;
- SectionSegment * p = m_currentSegment;
-
- while(len > left){
- memcpy(dst, &p->theData[ind], 4 * left);
- dst += left;
- len -= left;
- ind = 0;
- left = SectionSegment::DataLength;
- p = m_pool.getPtr(p->m_nextSegment);
- }
-
- memcpy(dst, &p->theData[ind], 4 * len);
-
- m_pos += len;
- m_currentSegment = p;
- return true;
-}
-
diff --git a/storage/ndb/src/kernel/vm/SectionReader.hpp b/storage/ndb/src/kernel/vm/SectionReader.hpp
deleted file mode 100644
index 9e39c3666e3..00000000000
--- a/storage/ndb/src/kernel/vm/SectionReader.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SECTION_READER_HPP
-#define SECTION_READER_HPP
-
-#include <ndb_types.h>
-
-class SectionReader {
-public:
- SectionReader(struct SegmentedSectionPtr &,
- class SectionSegmentPool &);
-
- void reset();
- bool step(Uint32 len);
- bool getWord(Uint32 * dst);
- bool peekWord(Uint32 * dst) const ;
- bool peekWords(Uint32 * dst, Uint32 len) const;
- Uint32 getSize() const;
- bool getWords(Uint32 * dst, Uint32 len);
-
-private:
- Uint32 m_pos;
- Uint32 m_len;
- class SectionSegmentPool & m_pool;
- class SectionSegment * m_head;
- class SectionSegment * m_currentSegment;
-};
-
-inline
-Uint32 SectionReader::getSize() const
-{
- return m_len;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SignalCounter.hpp b/storage/ndb/src/kernel/vm/SignalCounter.hpp
deleted file mode 100644
index 1d451114dff..00000000000
--- a/storage/ndb/src/kernel/vm/SignalCounter.hpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SIGNAL_COUNTER_HPP
-#define SIGNAL_COUNTER_HPP
-
-#include <NodeBitmask.hpp>
-#include <ErrorReporter.hpp>
-
-class SignalCounter {
- friend struct NodeReceiverGroup;
-
-private:
- Uint32 m_count;
- NdbNodeBitmask m_nodes;
-
-public:
- SignalCounter() { clearWaitingFor();}
- void clearWaitingFor();
-
- /**
- * When sending to different node
- */
- void setWaitingFor(Uint32 nodeId);
- void clearWaitingFor(Uint32 nodeId);
- void forceClearWaitingFor(Uint32 nodeId);
-
- bool isWaitingFor(Uint32 nodeId) const;
- bool done() const;
-
- const char * getText() const;
-
- SignalCounter& operator=(const NdbNodeBitmask & bitmask);
- SignalCounter& operator=(const NodeReceiverGroup& rg) {
- return (* this) = rg.m_nodes;
- }
-
- /**
- * When sending to same node
- */
- SignalCounter& operator=(Uint32 count);
- SignalCounter& operator--(int);
- SignalCounter& operator++(int);
- SignalCounter& operator+=(Uint32);
- Uint32 getCount() const;
-};
-
-inline
-void
-SignalCounter::setWaitingFor(Uint32 nodeId) {
- if(!m_nodes.get(nodeId)){
- m_nodes.set(nodeId);
- m_count++;
- return;
- }
- ErrorReporter::handleAssert("SignalCounter::set", __FILE__, __LINE__);
-}
-
-inline
-bool
-SignalCounter::isWaitingFor(Uint32 nodeId) const {
- return m_nodes.get(nodeId);
-}
-
-inline
-bool
-SignalCounter::done() const {
- return m_count == 0;
-}
-
-inline
-Uint32
-SignalCounter::getCount() const {
- return m_count;
-}
-
-inline
-void
-SignalCounter::clearWaitingFor(Uint32 nodeId) {
- if(m_nodes.get(nodeId) && m_count > 0){
- m_count--;
- m_nodes.clear(nodeId);
- return;
- }
- ErrorReporter::handleAssert("SignalCounter::clear", __FILE__, __LINE__);
-}
-
-inline
-void
-SignalCounter::clearWaitingFor(){
- m_count = 0;
- m_nodes.clear();
-}
-
-inline
-void
-SignalCounter::forceClearWaitingFor(Uint32 nodeId){
- if(isWaitingFor(nodeId)){
- clearWaitingFor(nodeId);
- }
-}
-
-inline
-SignalCounter&
-SignalCounter::operator=(Uint32 count){
- m_count = count;
- m_nodes.clear();
- return * this;
-}
-
-inline
-SignalCounter&
-SignalCounter::operator--(int){
- if(m_count > 0){
- m_count--;
- return * this;
- }
- ErrorReporter::handleAssert("SignalCounter::operator--", __FILE__, __LINE__);
- return * this;
-}
-
-inline
-SignalCounter&
-SignalCounter::operator++(int){
- m_count++;
- return * this;
-}
-
-inline
-SignalCounter&
-SignalCounter::operator+=(Uint32 n){
- m_count += n;
- return * this;
-}
-
-inline
-const char *
-SignalCounter::getText() const {
- static char buf[255];
- static char nodes[NodeBitmask::TextLength+1];
- BaseString::snprintf(buf, sizeof(buf), "[SignalCounter: m_count=%d %s]", m_count, m_nodes.getText(nodes));
- return buf;
-}
-
-inline
-SignalCounter&
-SignalCounter::operator=(const NdbNodeBitmask & bitmask){
- m_nodes = bitmask;
- m_count = bitmask.count();
- return * this;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SimBlockList.hpp b/storage/ndb/src/kernel/vm/SimBlockList.hpp
deleted file mode 100644
index 2f4fbac5711..00000000000
--- a/storage/ndb/src/kernel/vm/SimBlockList.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SimBlockList_H
-#define SimBlockList_H
-
-#include <SimulatedBlock.hpp>
-
-class EmulatorData;
-
-class SimBlockList
-{
-public:
- SimBlockList();
- ~SimBlockList();
-
- void load(EmulatorData&);
- void unload();
-private:
- int noOfBlocks;
- SimulatedBlock** theList;
-};
-
-inline
-SimBlockList::SimBlockList(){
- noOfBlocks = 0;
- theList = 0;
-}
-
-inline
-SimBlockList::~SimBlockList(){
- unload();
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp b/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp
deleted file mode 100644
index 77f72d1a5c3..00000000000
--- a/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <SimpleProperties.hpp>
-#include <TransporterDefinitions.hpp>
-#include "LongSignal.hpp"
-
-SimplePropertiesSectionReader::SimplePropertiesSectionReader
-(struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool)
- : m_pool(pool)
-{
- if(ptr.p == 0){
- m_pos = 0;
- m_len = 0;
- m_head = 0;
- m_currentSegment = 0;
- } else {
- m_pos = 0;
- m_len = ptr.p->m_sz;
- m_head = ptr.p;
- m_currentSegment = ptr.p;
- }
- first();
-}
-
-void
-SimplePropertiesSectionReader::reset(){
- m_pos = 0;
- m_currentSegment = m_head;
-}
-
-bool
-SimplePropertiesSectionReader::step(Uint32 len){
- if(m_pos + len >= m_len) {
- m_pos++;
- return false;
- }
- while(len > SectionSegment::DataLength){
- m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
-
- len -= SectionSegment::DataLength;
- m_pos += SectionSegment::DataLength;
- }
-
- Uint32 ind = m_pos % SectionSegment::DataLength;
- while(len > 0){
- len--;
- m_pos++;
-
- ind++;
- if(ind == SectionSegment::DataLength){
- ind = 0;
- m_currentSegment = m_pool.getPtr(m_currentSegment->m_nextSegment);
- }
- }
- return true;
-}
-
-bool
-SimplePropertiesSectionReader::getWord(Uint32 * dst){
- if (peekWord(dst)) {
- step(1);
- return true;
- }
- return false;
-}
-
-bool
-SimplePropertiesSectionReader::peekWord(Uint32 * dst) const {
- if(m_pos < m_len){
- Uint32 ind = m_pos % SectionSegment::DataLength;
- * dst = m_currentSegment->theData[ind];
- return true;
- }
- return false;
-}
-
-bool
-SimplePropertiesSectionReader::peekWords(Uint32 * dst, Uint32 len) const {
- if(m_pos + len > m_len){
- return false;
- }
- Uint32 ind = (m_pos % SectionSegment::DataLength);
- Uint32 left = (SectionSegment::DataLength - ind);
- SectionSegment * p = m_currentSegment;
-
- while(len > left){
- memcpy(dst, &p->theData[ind], 4 * left);
- dst += left;
- len -= left;
- ind = 0;
- left = SectionSegment::DataLength;
- p = m_pool.getPtr(p->m_nextSegment);
- }
-
- memcpy(dst, &p->theData[ind], 4 * len);
- return true;
-}
-
-bool
-SimplePropertiesSectionReader::getWords(Uint32 * dst, Uint32 len){
- if(peekWords(dst, len)){
- step(len);
- return true;
- }
- return false;
-}
-
-SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SectionSegmentPool & pool)
- : m_pool(pool)
-{
- Ptr<SectionSegment> first;
- if(m_pool.seize(first)){
- ;
- } else {
- m_pos = -1;
- m_head = 0;
- m_currentSegment = 0;
- m_prevPtrI = RNIL;
- return;
- }
- m_sz = 0;
- m_pos = 0;
- m_head = first.p;
- m_head->m_lastSegment = first.i;
- m_currentSegment = first.p;
- m_prevPtrI = RNIL;
-}
-
-bool
-SimplePropertiesSectionWriter::reset(){
- if(m_pos >= 0){
- m_pos = 0;
- return true;
- }
- return false;
-}
-
-bool
-SimplePropertiesSectionWriter::putWord(Uint32 val){
- return putWords(&val, 1);
-}
-
-bool
-SimplePropertiesSectionWriter::putWords(const Uint32 * src, Uint32 len){
- Uint32 left = SectionSegment::DataLength - m_pos;
-
- while(len >= left){
- memcpy(&m_currentSegment->theData[m_pos], src, 4 * left);
- Ptr<SectionSegment> next;
- if(m_pool.seize(next)){
-
- m_prevPtrI = m_currentSegment->m_lastSegment;
- m_currentSegment->m_nextSegment = next.i;
- next.p->m_lastSegment = next.i;
- m_currentSegment = next.p;
-
- len -= left;
- src += left;
- m_sz += left;
-
- left = SectionSegment::DataLength;
- m_pos = 0;
- } else {
- abort();
- return false;
- }
- }
-
- memcpy(&m_currentSegment->theData[m_pos], src, 4 * len);
- m_sz += len;
- m_pos += len;
-
- assert(m_pos < (int)SectionSegment::DataLength);
-
- return true;
-}
-
-void
-SimplePropertiesSectionWriter::getPtr(struct SegmentedSectionPtr & dst){
- // Set last ptr and size
- if(m_pos >= 0){
- dst.p = m_head;
- dst.i = m_head->m_lastSegment;
- dst.sz = m_sz;
- m_head->m_sz = m_sz;
- m_head->m_lastSegment = m_currentSegment->m_lastSegment;
-
- if((m_pos % SectionSegment::DataLength) == 0){
- m_pool.release(m_currentSegment->m_lastSegment);
- m_head->m_lastSegment = m_prevPtrI;
- }
-
- m_sz = 0;
- m_pos = -1;
- m_head = m_currentSegment = 0;
- m_prevPtrI = RNIL;
- return ;
- }
- dst.p = 0;
- dst.sz = 0;
- dst.i = RNIL;
-
- m_pool.release(m_head->m_lastSegment);
-
- m_sz = 0;
- m_pos = -1;
- m_head = m_currentSegment = 0;
- m_prevPtrI = RNIL;
-}
diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
deleted file mode 100644
index 6703b3c7fab..00000000000
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
+++ /dev/null
@@ -1,2082 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "SimulatedBlock.hpp"
-#include <NdbOut.hpp>
-#include <GlobalData.hpp>
-#include <Emulator.hpp>
-#include <WatchDog.hpp>
-#include <ErrorHandlingMacros.hpp>
-#include <TimeQueue.hpp>
-#include <TransporterRegistry.hpp>
-#include <SignalLoggerManager.hpp>
-#include <FastScheduler.hpp>
-#include "ndbd_malloc.hpp"
-#include <signaldata/EventReport.hpp>
-#include <signaldata/ContinueFragmented.hpp>
-#include <signaldata/NodeStateSignalData.hpp>
-#include <signaldata/FsRef.hpp>
-#include <signaldata/SignalDroppedRep.hpp>
-#include <DebuggerNames.hpp>
-#include "LongSignal.hpp"
-
-#include <Properties.hpp>
-#include "Configuration.hpp"
-#include <AttributeDescriptor.hpp>
-#include <NdbSqlUtil.hpp>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-#define ljamEntry() jamEntryLine(30000 + __LINE__)
-#define ljam() jamLine(30000 + __LINE__)
-
-//
-// Constructor, Destructor
-//
-SimulatedBlock::SimulatedBlock(BlockNumber blockNumber,
- struct Block_context & ctx)
- : theNodeId(globalData.ownId),
- theNumber(blockNumber),
- theReference(numberToRef(blockNumber, globalData.ownId)),
- m_ctx(ctx),
- m_global_page_pool(globalData.m_global_page_pool),
- m_shared_page_pool(globalData.m_shared_page_pool),
- c_fragmentInfoHash(c_fragmentInfoPool),
- c_linearFragmentSendList(c_fragmentSendPool),
- c_segmentedFragmentSendList(c_fragmentSendPool),
- c_mutexMgr(* this),
- c_counterMgr(* this)
-{
- NewVarRef = 0;
-
- globalData.setBlock(blockNumber, this);
- c_fragmentIdCounter = 1;
- c_fragSenderRunning = false;
-
- Properties tmp;
- const Properties * p = &tmp;
- ndbrequire(p != 0);
-
- Uint32 count = 10;
- char buf[255];
-
- count = 10;
- BaseString::snprintf(buf, 255, "%s.FragmentSendPool", getBlockName(blockNumber));
- if(!p->get(buf, &count))
- p->get("FragmentSendPool", &count);
- c_fragmentSendPool.setSize(count);
-
- count = 10;
- BaseString::snprintf(buf, 255, "%s.FragmentInfoPool", getBlockName(blockNumber));
- if(!p->get(buf, &count))
- p->get("FragmentInfoPool", &count);
- c_fragmentInfoPool.setSize(count);
-
- count = 10;
- BaseString::snprintf(buf, 255, "%s.FragmentInfoHash", getBlockName(blockNumber));
- if(!p->get(buf, &count))
- p->get("FragmentInfoHash", &count);
- c_fragmentInfoHash.setSize(count);
-
- count = 5;
- BaseString::snprintf(buf, 255, "%s.ActiveMutexes", getBlockName(blockNumber));
- if(!p->get(buf, &count))
- p->get("ActiveMutexes", &count);
- c_mutexMgr.setSize(count);
-
- c_counterMgr.setSize(5);
-
-#ifdef VM_TRACE_TIME
- clearTimes();
-#endif
-
- for(GlobalSignalNumber i = 0; i<=MAX_GSN; i++)
- theExecArray[i] = 0;
-
- installSimulatedBlockFunctions();
- UpgradeStartup::installEXEC(this);
-
- CLEAR_ERROR_INSERT_VALUE;
-
-#ifdef VM_TRACE
- m_global_variables = new Ptr<void> * [1];
- m_global_variables[0] = 0;
-#endif
-}
-
-SimulatedBlock::~SimulatedBlock()
-{
- freeBat();
-#ifdef VM_TRACE_TIME
- printTimes(stdout);
-#endif
-
-#ifdef VM_TRACE
- delete [] m_global_variables;
-#endif
-}
-
-void
-SimulatedBlock::installSimulatedBlockFunctions(){
- ExecFunction * a = theExecArray;
- a[GSN_NODE_STATE_REP] = &SimulatedBlock::execNODE_STATE_REP;
- a[GSN_CHANGE_NODE_STATE_REQ] = &SimulatedBlock::execCHANGE_NODE_STATE_REQ;
- a[GSN_NDB_TAMPER] = &SimulatedBlock::execNDB_TAMPER;
- a[GSN_SIGNAL_DROPPED_REP] = &SimulatedBlock::execSIGNAL_DROPPED_REP;
- a[GSN_CONTINUE_FRAGMENTED]= &SimulatedBlock::execCONTINUE_FRAGMENTED;
- a[GSN_UTIL_CREATE_LOCK_REF] = &SimulatedBlock::execUTIL_CREATE_LOCK_REF;
- a[GSN_UTIL_CREATE_LOCK_CONF] = &SimulatedBlock::execUTIL_CREATE_LOCK_CONF;
- a[GSN_UTIL_DESTROY_LOCK_REF] = &SimulatedBlock::execUTIL_DESTORY_LOCK_REF;
- a[GSN_UTIL_DESTROY_LOCK_CONF] = &SimulatedBlock::execUTIL_DESTORY_LOCK_CONF;
- a[GSN_UTIL_LOCK_REF] = &SimulatedBlock::execUTIL_LOCK_REF;
- 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_FSOPENREF] = &SimulatedBlock::execFSOPENREF;
- a[GSN_FSCLOSEREF] = &SimulatedBlock::execFSCLOSEREF;
- a[GSN_FSWRITEREF] = &SimulatedBlock::execFSWRITEREF;
- a[GSN_FSREADREF] = &SimulatedBlock::execFSREADREF;
- a[GSN_FSREMOVEREF] = &SimulatedBlock::execFSREMOVEREF;
- a[GSN_FSSYNCREF] = &SimulatedBlock::execFSSYNCREF;
- a[GSN_FSAPPENDREF] = &SimulatedBlock::execFSAPPENDREF;
- a[GSN_NODE_START_REP] = &SimulatedBlock::execNODE_START_REP;
- a[GSN_API_START_REP] = &SimulatedBlock::execAPI_START_REP;
-}
-
-void
-SimulatedBlock::addRecSignalImpl(GlobalSignalNumber gsn,
- ExecFunction f, bool force){
- if(gsn > MAX_GSN || (!force && theExecArray[gsn] != 0)){
- char errorMsg[255];
- BaseString::snprintf(errorMsg, 255,
- "GSN %d(%d))", gsn, MAX_GSN);
- ERROR_SET(fatal, NDBD_EXIT_ILLEGAL_SIGNAL, errorMsg, errorMsg);
- }
- theExecArray[gsn] = f;
-}
-
-void
-SimulatedBlock::signal_error(Uint32 gsn, Uint32 len, Uint32 recBlockNo,
- const char* filename, int lineno) const
-{
- char objRef[255];
- BaseString::snprintf(objRef, 255, "%s:%d", filename, lineno);
- char probData[255];
- BaseString::snprintf(probData, 255,
- "Signal (GSN: %d, Length: %d, Rec Block No: %d)",
- gsn, len, recBlockNo);
-
- ErrorReporter::handleError(NDBD_EXIT_BLOCK_BNR_ZERO,
- probData,
- objRef);
-}
-
-
-extern class SectionSegmentPool g_sectionSegmentPool;
-
-void
-SimulatedBlock::sendSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jobBuffer) const {
-
- BlockNumber sendBnr = number();
- BlockReference sendBRef = reference();
-
- Uint32 noOfSections = signal->header.m_noOfSections;
- Uint32 recBlock = refToBlock(ref);
- Uint32 recNode = refToNode(ref);
- Uint32 ourProcessor = globalData.ownId;
-
- signal->header.theLength = length;
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = recBlock;
-
- Uint32 tSignalId = signal->header.theSignalId;
-
- if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
- signal_error(gsn, length, recBlock, __FILE__, __LINE__);
- return;
- }//if
-#ifdef VM_TRACE
- if(globalData.testOn){
- Uint16 proc =
- (recNode == 0 ? globalData.ownId : recNode);
- signal->header.theSendersBlockRef = sendBRef;
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- proc,
- signal->m_sectionPtr,
- signal->header.m_noOfSections);
- }
-#endif
-
- if(recNode == ourProcessor || recNode == 0) {
- signal->header.theSendersSignalId = tSignalId;
- signal->header.theSendersBlockRef = sendBRef;
- signal->header.theLength = length;
- globalScheduler.execute(signal, jobBuffer, recBlock,
- gsn);
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = 0;
- return;
- } else {
- // send distributed Signal
- SignalHeader sh;
-
- Uint32 tTrace = signal->getTrace();
-
- sh.theVerId_signalNumber = gsn;
- sh.theReceiversBlockNumber = recBlock;
- sh.theSendersBlockRef = sendBnr;
- sh.theLength = length;
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.m_noOfSections = noOfSections;
- sh.m_fragmentInfo = 0;
-
-#ifdef TRACE_DISTRIBUTED
- ndbout_c("send: %s(%d) to (%s, %d)",
- getSignalName(gsn), gsn, getBlockName(recBlock),
- recNode);
-#endif
- SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
- &signal->theData[0],
- recNode,
- g_sectionSegmentPool,
- signal->m_sectionPtr);
-
- ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
- ::releaseSections(noOfSections, signal->m_sectionPtr);
- signal->header.m_noOfSections = 0;
- }
- return;
-}
-
-void
-SimulatedBlock::sendSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jobBuffer) const {
-
- Uint32 noOfSections = signal->header.m_noOfSections;
- Uint32 tSignalId = signal->header.theSignalId;
- Uint32 tTrace = signal->getTrace();
- Uint32 tFragInf = signal->header.m_fragmentInfo;
-
- Uint32 ourProcessor = globalData.ownId;
- Uint32 recBlock = rg.m_block;
-
- signal->header.theLength = length;
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = recBlock;
- signal->header.theSendersSignalId = tSignalId;
- signal->header.theSendersBlockRef = reference();
-
- if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
- signal_error(gsn, length, recBlock, __FILE__, __LINE__);
- return;
- }//if
-
- SignalHeader sh;
-
- sh.theVerId_signalNumber = gsn;
- sh.theReceiversBlockNumber = recBlock;
- sh.theSendersBlockRef = number();
- sh.theLength = length;
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.m_noOfSections = noOfSections;
- sh.m_fragmentInfo = tFragInf;
-
- /**
- * Check own node
- */
- bool release = true;
- if(rg.m_nodes.get(0) || rg.m_nodes.get(ourProcessor)){
-#ifdef VM_TRACE
- if(globalData.testOn){
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- ourProcessor,
- signal->m_sectionPtr,
- signal->header.m_noOfSections);
- }
-#endif
- globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
-
- rg.m_nodes.clear((Uint32)0);
- rg.m_nodes.clear(ourProcessor);
- release = false;
- }
-
- /**
- * Do the big loop
- */
- Uint32 recNode = 0;
- while(!rg.m_nodes.isclear()){
- recNode = rg.m_nodes.find(recNode + 1);
- rg.m_nodes.clear(recNode);
-#ifdef VM_TRACE
- if(globalData.testOn){
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- recNode,
- signal->m_sectionPtr,
- signal->header.m_noOfSections);
- }
-#endif
-
-#ifdef TRACE_DISTRIBUTED
- ndbout_c("send: %s(%d) to (%s, %d)",
- getSignalName(gsn), gsn, getBlockName(recBlock),
- recNode);
-#endif
-
- SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
- &signal->theData[0],
- recNode,
- g_sectionSegmentPool,
- signal->m_sectionPtr);
- ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
- }
-
- if(release){
- ::releaseSections(noOfSections, signal->m_sectionPtr);
- }
-
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = 0;
-
- return;
-}
-
-bool import(Ptr<SectionSegment> & first, const Uint32 * src, Uint32 len);
-
-void
-SimulatedBlock::sendSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jobBuffer,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections) const {
-
- BlockNumber sendBnr = number();
- BlockReference sendBRef = reference();
-
- Uint32 recBlock = refToBlock(ref);
- Uint32 recNode = refToNode(ref);
- Uint32 ourProcessor = globalData.ownId;
-
- ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
-
- signal->header.theLength = length;
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = recBlock;
- signal->header.m_noOfSections = noOfSections;
-
- Uint32 tSignalId = signal->header.theSignalId;
- Uint32 tFragInfo = signal->header.m_fragmentInfo;
-
- if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
- signal_error(gsn, length, recBlock, __FILE__, __LINE__);
- return;
- }//if
-#ifdef VM_TRACE
- if(globalData.testOn){
- Uint16 proc =
- (recNode == 0 ? globalData.ownId : recNode);
- signal->header.theSendersBlockRef = sendBRef;
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- proc,
- ptr, noOfSections);
- }
-#endif
-
- if(recNode == ourProcessor || recNode == 0) {
- signal->header.theSendersSignalId = tSignalId;
- signal->header.theSendersBlockRef = sendBRef;
-
- /**
- * We have to copy the data
- */
- Ptr<SectionSegment> segptr[3];
- for(Uint32 i = 0; i<noOfSections; i++){
- ndbrequire(import(segptr[i], ptr[i].p, ptr[i].sz));
- signal->m_sectionPtr[i].i = segptr[i].i;
- }
-
- globalScheduler.execute(signal, jobBuffer, recBlock,
- gsn);
- signal->header.m_noOfSections = 0;
- return;
- } else {
- // send distributed Signal
- SignalHeader sh;
-
- Uint32 tTrace = signal->getTrace();
- Uint32 noOfSections = signal->header.m_noOfSections;
-
- sh.theVerId_signalNumber = gsn;
- sh.theReceiversBlockNumber = recBlock;
- sh.theSendersBlockRef = sendBnr;
- sh.theLength = length;
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.m_noOfSections = noOfSections;
- sh.m_fragmentInfo = tFragInfo;
-
-#ifdef TRACE_DISTRIBUTED
- ndbout_c("send: %s(%d) to (%s, %d)",
- getSignalName(gsn), gsn, getBlockName(recBlock),
- recNode);
-#endif
-
- SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
- &signal->theData[0],
- recNode,
- ptr);
- ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
- }
-
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = 0;
- return;
-}
-
-void
-SimulatedBlock::sendSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jobBuffer,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections) const {
-
- Uint32 tSignalId = signal->header.theSignalId;
- Uint32 tTrace = signal->getTrace();
- Uint32 tFragInfo = signal->header.m_fragmentInfo;
-
- Uint32 ourProcessor = globalData.ownId;
- Uint32 recBlock = rg.m_block;
-
- ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
-
- signal->header.theLength = length;
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = recBlock;
- signal->header.theSendersSignalId = tSignalId;
- signal->header.theSendersBlockRef = reference();
- signal->header.m_noOfSections = noOfSections;
-
- if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) {
- signal_error(gsn, length, recBlock, __FILE__, __LINE__);
- return;
- }//if
-
- SignalHeader sh;
- sh.theVerId_signalNumber = gsn;
- sh.theReceiversBlockNumber = recBlock;
- sh.theSendersBlockRef = number();
- sh.theLength = length;
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.m_noOfSections = noOfSections;
- sh.m_fragmentInfo = tFragInfo;
-
- /**
- * Check own node
- */
- if(rg.m_nodes.get(0) || rg.m_nodes.get(ourProcessor)){
-#ifdef VM_TRACE
- if(globalData.testOn){
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- ourProcessor,
- ptr, noOfSections);
- }
-#endif
- /**
- * We have to copy the data
- */
- Ptr<SectionSegment> segptr[3];
- for(Uint32 i = 0; i<noOfSections; i++){
- ndbrequire(import(segptr[i], ptr[i].p, ptr[i].sz));
- signal->m_sectionPtr[i].i = segptr[i].i;
- }
- globalScheduler.execute(signal, jobBuffer, recBlock, gsn);
-
- rg.m_nodes.clear((Uint32)0);
- rg.m_nodes.clear(ourProcessor);
- }
-
- /**
- * Do the big loop
- */
- Uint32 recNode = 0;
- while(!rg.m_nodes.isclear()){
- recNode = rg.m_nodes.find(recNode + 1);
- rg.m_nodes.clear(recNode);
-
-#ifdef VM_TRACE
- if(globalData.testOn){
- globalSignalLoggers.sendSignal(signal->header,
- jobBuffer,
- &signal->theData[0],
- recNode,
- ptr, noOfSections);
- }
-#endif
-
-#ifdef TRACE_DISTRIBUTED
- ndbout_c("send: %s(%d) to (%s, %d)",
- getSignalName(gsn), gsn, getBlockName(recBlock),
- recNode);
-#endif
-
- SendStatus ss = globalTransporterRegistry.prepareSend(&sh, jobBuffer,
- &signal->theData[0],
- recNode,
- ptr);
- ndbrequire(ss == SEND_OK || ss == SEND_BLOCKED || ss == SEND_DISCONNECTED);
- }
-
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = 0;
-
- return;
-}
-
-void
-SimulatedBlock::sendSignalWithDelay(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 delayInMilliSeconds,
- Uint32 length) const {
-
- BlockNumber bnr = refToBlock(ref);
-
- //BlockNumber sendBnr = number();
- BlockReference sendBRef = reference();
-
- if (bnr == 0) {
- bnr_error();
- }//if
-
- signal->header.theLength = length;
- signal->header.theSendersSignalId = signal->header.theSignalId;
- signal->header.theSendersBlockRef = sendBRef;
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = bnr;
-
-#ifdef VM_TRACE
- {
- if(globalData.testOn){
- globalSignalLoggers.sendSignalWithDelay(delayInMilliSeconds,
- signal->header,
- 0,
- &signal->theData[0],
- globalData.ownId,
- signal->m_sectionPtr,
- signal->header.m_noOfSections);
- }
- }
-#endif
- globalTimeQueue.insert(signal, bnr, gsn, delayInMilliSeconds);
-
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = 0;
-
- // befor 2nd parameter to globalTimeQueue.insert
- // (Priority)theSendSig[sigIndex].jobBuffer
-}
-
-void
-SimulatedBlock::releaseSections(Signal* signal){
- ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
- signal->header.m_noOfSections = 0;
-}
-
-class SectionSegmentPool&
-SimulatedBlock::getSectionSegmentPool(){
- return g_sectionSegmentPool;
-}
-
-NewVARIABLE *
-SimulatedBlock::allocateBat(int batSize){
- NewVARIABLE* bat = NewVarRef;
- bat = (NewVARIABLE*)realloc(bat, batSize * sizeof(NewVARIABLE));
- NewVarRef = bat;
- theBATSize = batSize;
- return bat;
-}
-
-void
-SimulatedBlock::freeBat(){
- if(NewVarRef != 0){
- free(NewVarRef);
- NewVarRef = 0;
- }
-}
-
-const NewVARIABLE *
-SimulatedBlock::getBat(Uint16 blockNo){
- SimulatedBlock * sb = globalData.getBlock(blockNo);
- if(sb == 0)
- return 0;
- return sb->NewVarRef;
-}
-
-Uint16
-SimulatedBlock::getBatSize(Uint16 blockNo){
- SimulatedBlock * sb = globalData.getBlock(blockNo);
- if(sb == 0)
- return 0;
- return sb->theBATSize;
-}
-
-void* SimulatedBlock::allocRecord(const char * type, size_t s, size_t n, bool clear, Uint32 paramId)
-{
- return allocRecordAligned(type, s, n, 0, 0, clear, paramId);
-}
-
-void*
-SimulatedBlock::allocRecordAligned(const char * type, size_t s, size_t n, void **unaligned_buffer, Uint32 align, bool clear, Uint32 paramId)
-{
-
- void * p = NULL;
- Uint32 over_alloc = unaligned_buffer ? (align - 1) : 0;
- size_t size = n*s + over_alloc;
- Uint64 real_size = (Uint64)((Uint64)n)*((Uint64)s) + over_alloc;
- refresh_watch_dog(9);
- if (real_size > 0){
-#ifdef VM_TRACE_MEM
- ndbout_c("%s::allocRecord(%s, %u, %u) = %llu bytes",
- getBlockName(number()),
- type,
- s,
- n,
- real_size);
-#endif
- if( real_size == (Uint64)size )
- p = ndbd_malloc(size);
- if (p == NULL){
- char buf1[255];
- char buf2[255];
- struct ndb_mgm_param_info param_info;
- size_t size = sizeof(ndb_mgm_param_info);
-
- if(0 != paramId && 0 == ndb_mgm_get_db_parameter_info(paramId, &param_info, &size)) {
- BaseString::snprintf(buf1, sizeof(buf1), "%s could not allocate memory for parameter %s",
- getBlockName(number()), param_info.m_name);
- } else {
- BaseString::snprintf(buf1, sizeof(buf1), "%s could not allocate memory for %s",
- getBlockName(number()), type);
- }
- BaseString::snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %llu bytes",
- (Uint32)s, (Uint32)n, (Uint64)real_size);
- ERROR_SET(fatal, NDBD_EXIT_MEMALLOC, buf1, buf2);
- }
-
- if(clear){
- char * ptr = (char*)p;
- const Uint32 chunk = 128 * 1024;
- while(size > chunk){
- refresh_watch_dog(9);
- memset(ptr, 0, chunk);
- ptr += chunk;
- size -= chunk;
- }
- refresh_watch_dog(9);
- memset(ptr, 0, size);
- }
- if (unaligned_buffer)
- {
- *unaligned_buffer = p;
- p = (void *)(((UintPtr)p + over_alloc) & ~(UintPtr)(over_alloc));
-#ifdef VM_TRACE
- g_eventLogger.info("'%s' (%u) %llu %llu, alignment correction %u bytes",
- type, align, (Uint64)p, (Uint64)p+n*s,
- (Uint32)((UintPtr)p - (UintPtr)*unaligned_buffer));
-#endif
- }
- }
- return p;
-}
-
-void
-SimulatedBlock::deallocRecord(void ** ptr,
- const char * type, size_t s, size_t n){
- (void)type;
-
- if(* ptr != 0){
- ndbd_free(* ptr, n*s);
- * ptr = 0;
- }
-}
-
-void
-SimulatedBlock::refresh_watch_dog(Uint32 place)
-{
- globalData.incrementWatchDogCounter(place);
-}
-
-void
-SimulatedBlock::update_watch_dog_timer(Uint32 interval)
-{
- extern EmulatorData globalEmulatorData;
- globalEmulatorData.theWatchDog->setCheckInterval(interval);
-}
-
-void
-SimulatedBlock::progError(int line, int err_code, const char* extra) const {
- jamLine(line);
-
- const char *aBlockName = getBlockName(number(), "VM Kernel");
-
- // Pack status of interesting config variables
- // so that we can print them in error.log
- int magicStatus =
- (m_ctx.m_config.stopOnError()<<1) +
- (m_ctx.m_config.getInitialStart()<<2) +
- (m_ctx.m_config.getDaemonMode()<<3);
-
-
- /* Add line number to block name */
- char buf[100];
- BaseString::snprintf(&buf[0], 100, "%s (Line: %d) 0x%.8x",
- aBlockName, line, magicStatus);
-
- ErrorReporter::handleError(err_code, extra, buf);
-
-}
-
-void
-SimulatedBlock::infoEvent(const char * msg, ...) const {
- if(msg == 0)
- return;
-
- Uint32 theData[25];
- theData[0] = NDB_LE_InfoEvent;
- char * buf = (char *)&(theData[1]);
-
- va_list ap;
- va_start(ap, msg);
- BaseString::vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4
- va_end(ap);
-
- int len = strlen(buf) + 1;
- if(len > 96){
- len = 96;
- buf[95] = 0;
- }
-
- /**
- * Init and put it into the job buffer
- */
- SignalHeader sh;
- memset(&sh, 0, sizeof(SignalHeader));
-
- const Signal * signal = globalScheduler.getVMSignals();
- Uint32 tTrace = signal->header.theTrace;
- Uint32 tSignalId = signal->header.theSignalId;
-
- sh.theVerId_signalNumber = GSN_EVENT_REP;
- sh.theReceiversBlockNumber = CMVMI;
- sh.theSendersBlockRef = reference();
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.theLength = ((len+3)/4)+1;
-
- Uint32 secPtrI[3]; // Dummy
- globalScheduler.execute(&sh, JBB, theData, secPtrI);
-}
-
-void
-SimulatedBlock::warningEvent(const char * msg, ...) const {
- if(msg == 0)
- return;
-
- Uint32 theData[25];
- theData[0] = NDB_LE_WarningEvent;
- char * buf = (char *)&(theData[1]);
-
- va_list ap;
- va_start(ap, msg);
- BaseString::vsnprintf(buf, 96, msg, ap); // 96 = 100 - 4
- va_end(ap);
-
- int len = strlen(buf) + 1;
- if(len > 96){
- len = 96;
- buf[95] = 0;
- }
-
- /**
- * Init and put it into the job buffer
- */
- SignalHeader sh;
- memset(&sh, 0, sizeof(SignalHeader));
-
- const Signal * signal = globalScheduler.getVMSignals();
- Uint32 tTrace = signal->header.theTrace;
- Uint32 tSignalId = signal->header.theSignalId;
-
- sh.theVerId_signalNumber = GSN_EVENT_REP;
- sh.theReceiversBlockNumber = CMVMI;
- sh.theSendersBlockRef = reference();
- sh.theTrace = tTrace;
- sh.theSignalId = tSignalId;
- sh.theLength = ((len+3)/4)+1;
-
- Uint32 secPtrI[3]; // Dummy
- globalScheduler.execute(&sh, JBB, theData, secPtrI);
-}
-
-void
-SimulatedBlock::execNODE_STATE_REP(Signal* signal){
- const NodeStateRep * const rep = (NodeStateRep *)&signal->theData[0];
-
- this->theNodeState = rep->nodeState;
-}
-
-void
-SimulatedBlock::execCHANGE_NODE_STATE_REQ(Signal* signal){
- const ChangeNodeStateReq * const req =
- (ChangeNodeStateReq *)&signal->theData[0];
-
- this->theNodeState = req->nodeState;
- const Uint32 senderData = req->senderData;
- const BlockReference senderRef = req->senderRef;
-
- /**
- * Pack return signal
- */
- ChangeNodeStateConf * const conf =
- (ChangeNodeStateConf *)&signal->theData[0];
-
- conf->senderData = senderData;
-
- sendSignal(senderRef, GSN_CHANGE_NODE_STATE_CONF, signal,
- ChangeNodeStateConf::SignalLength, JBB);
-}
-
-void
-SimulatedBlock::execNDB_TAMPER(Signal * signal){
- SET_ERROR_INSERT_VALUE(signal->theData[0]);
-}
-
-void
-SimulatedBlock::execSIGNAL_DROPPED_REP(Signal * signal){
- char msg[64];
- const SignalDroppedRep * const rep = (SignalDroppedRep *)&signal->theData[0];
- snprintf(msg, sizeof(msg), "%s GSN: %u (%u,%u)", getBlockName(number()),
- rep->originalGsn, rep->originalLength,rep->originalSectionCount);
- ErrorReporter::handleError(NDBD_EXIT_OUT_OF_LONG_SIGNAL_MEMORY,
- msg,
- __FILE__,
- NST_ErrorHandler);
-}
-
-void
-SimulatedBlock::execCONTINUE_FRAGMENTED(Signal * signal){
- ljamEntry();
-
- Ptr<FragmentSendInfo> fragPtr;
-
- c_segmentedFragmentSendList.first(fragPtr);
- for(; !fragPtr.isNull();){
- ljam();
- Ptr<FragmentSendInfo> copyPtr = fragPtr;
- c_segmentedFragmentSendList.next(fragPtr);
-
- sendNextSegmentedFragment(signal, * copyPtr.p);
- if(copyPtr.p->m_status == FragmentSendInfo::SendComplete){
- ljam();
- if(copyPtr.p->m_callback.m_callbackFunction != 0) {
- ljam();
- execute(signal, copyPtr.p->m_callback, 0);
- }//if
- c_segmentedFragmentSendList.release(copyPtr);
- }
- }
-
- c_linearFragmentSendList.first(fragPtr);
- for(; !fragPtr.isNull();){
- ljam();
- Ptr<FragmentSendInfo> copyPtr = fragPtr;
- c_linearFragmentSendList.next(fragPtr);
-
- sendNextLinearFragment(signal, * copyPtr.p);
- if(copyPtr.p->m_status == FragmentSendInfo::SendComplete){
- ljam();
- if(copyPtr.p->m_callback.m_callbackFunction != 0) {
- ljam();
- execute(signal, copyPtr.p->m_callback, 0);
- }//if
- c_linearFragmentSendList.release(copyPtr);
- }
- }
-
- if(c_segmentedFragmentSendList.isEmpty() &&
- c_linearFragmentSendList.isEmpty()){
- ljam();
- c_fragSenderRunning = false;
- return;
- }
-
- ContinueFragmented * sig = (ContinueFragmented*)signal->getDataPtrSend();
- sig->line = __LINE__;
- sendSignal(reference(), GSN_CONTINUE_FRAGMENTED, signal, 1, JBB);
-}
-
-void
-SimulatedBlock::execNODE_START_REP(Signal* signal)
-{
-}
-
-void
-SimulatedBlock::execAPI_START_REP(Signal* signal)
-{
-}
-
-#ifdef VM_TRACE_TIME
-void
-SimulatedBlock::clearTimes() {
- for(Uint32 i = 0; i <= MAX_GSN; i++){
- m_timeTrace[i].cnt = 0;
- m_timeTrace[i].sum = 0;
- m_timeTrace[i].sub = 0;
- }
-}
-
-void
-SimulatedBlock::printTimes(FILE * output){
- fprintf(output, "-- %s --\n", getBlockName(number()));
- Uint64 sum = 0;
- for(Uint32 i = 0; i <= MAX_GSN; i++){
- Uint32 n = m_timeTrace[i].cnt;
- if(n != 0){
- double dn = n;
-
- double avg = m_timeTrace[i].sum;
- double avg2 = avg - m_timeTrace[i].sub;
-
- avg /= dn;
- avg2 /= dn;
-
- fprintf(output,
- //name ; cnt ; loc ; acc
- "%s ; #%d ; %dus ; %dus ; %dms\n",
- getSignalName(i), n, (Uint32)avg, (Uint32)avg2,
- (Uint32)((m_timeTrace[i].sum - m_timeTrace[i].sub + 500)/ 1000));
-
- sum += (m_timeTrace[i].sum - m_timeTrace[i].sub);
- }
- }
- sum = (sum + 500)/ 1000;
- fprintf(output, "-- %s : %d --\n", getBlockName(number()), sum);
- fprintf(output, "\n");
- fflush(output);
-}
-
-#endif
-
-void release(SegmentedSectionPtr & ptr);
-
-SimulatedBlock::FragmentInfo::FragmentInfo(Uint32 fragId, Uint32 sender){
- m_fragmentId = fragId;
- m_senderRef = sender;
- m_sectionPtrI[0] = RNIL;
- m_sectionPtrI[1] = RNIL;
- m_sectionPtrI[2] = RNIL;
-}
-
-SimulatedBlock::FragmentSendInfo::FragmentSendInfo()
-{
-}
-
-bool
-SimulatedBlock::assembleFragments(Signal * signal){
- Uint32 sigLen = signal->length() - 1;
- Uint32 fragId = signal->theData[sigLen];
- Uint32 fragInfo = signal->header.m_fragmentInfo;
- Uint32 senderRef = signal->getSendersBlockRef();
-
- if(fragInfo == 0){
- return true;
- }
-
- const Uint32 secs = signal->header.m_noOfSections;
- const Uint32 * const secNos = &signal->theData[sigLen - secs];
-
- if(fragInfo == 1){
- /**
- * First in train
- */
- Ptr<FragmentInfo> fragPtr;
- if(!c_fragmentInfoHash.seize(fragPtr)){
- ndbrequire(false);
- return false;
- }
-
- new (fragPtr.p)FragmentInfo(fragId, senderRef);
- c_fragmentInfoHash.add(fragPtr);
-
- for(Uint32 i = 0; i<secs; i++){
- Uint32 sectionNo = secNos[i];
- ndbassert(sectionNo < 3);
- fragPtr.p->m_sectionPtrI[sectionNo] = signal->m_sectionPtr[i].i;
- }
-
- /**
- * Don't release allocated segments
- */
- signal->header.m_fragmentInfo = 0;
- signal->header.m_noOfSections = 0;
- return false;
- }
-
- FragmentInfo key(fragId, senderRef);
- Ptr<FragmentInfo> fragPtr;
- if(c_fragmentInfoHash.find(fragPtr, key)){
-
- /**
- * FragInfo == 2 or 3
- */
- Uint32 i;
- for(i = 0; i<secs; i++){
- Uint32 sectionNo = secNos[i];
- ndbassert(sectionNo < 3);
- Uint32 sectionPtrI = signal->m_sectionPtr[i].i;
- if(fragPtr.p->m_sectionPtrI[sectionNo] != RNIL){
- linkSegments(fragPtr.p->m_sectionPtrI[sectionNo], sectionPtrI);
- } else {
- fragPtr.p->m_sectionPtrI[sectionNo] = sectionPtrI;
- }
- }
-
- /**
- * fragInfo = 2
- */
- if(fragInfo == 2){
- signal->header.m_fragmentInfo = 0;
- signal->header.m_noOfSections = 0;
- return false;
- }
-
- /**
- * fragInfo = 3
- */
- for(i = 0; i<3; i++){
- Uint32 ptrI = fragPtr.p->m_sectionPtrI[i];
- if(ptrI != RNIL){
- signal->m_sectionPtr[i].i = ptrI;
- } else {
- break;
- }
- }
- signal->setLength(sigLen - i);
- signal->header.m_noOfSections = i;
- signal->header.m_fragmentInfo = 0;
- getSections(i, signal->m_sectionPtr);
-
- c_fragmentInfoHash.release(fragPtr);
- return true;
- }
-
- /**
- * Unable to find fragment
- */
- ndbrequire(false);
- return false;
-}
-
-bool
-SimulatedBlock::sendFirstFragment(FragmentSendInfo & info,
- NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Uint32 messageSize){
-
- info.m_sectionPtr[0].m_segmented.i = RNIL;
- info.m_sectionPtr[1].m_segmented.i = RNIL;
- info.m_sectionPtr[2].m_segmented.i = RNIL;
-
- Uint32 totalSize = 0;
- SectionSegment * p;
- switch(signal->header.m_noOfSections){
- case 3:
- p = signal->m_sectionPtr[2].p;
- info.m_sectionPtr[2].m_segmented.p = p;
- info.m_sectionPtr[2].m_segmented.i = signal->m_sectionPtr[2].i;
- totalSize += p->m_sz;
- case 2:
- p = signal->m_sectionPtr[1].p;
- info.m_sectionPtr[1].m_segmented.p = p;
- info.m_sectionPtr[1].m_segmented.i = signal->m_sectionPtr[1].i;
- totalSize += p->m_sz;
- case 1:
- p = signal->m_sectionPtr[0].p;
- info.m_sectionPtr[0].m_segmented.p = p;
- info.m_sectionPtr[0].m_segmented.i = signal->m_sectionPtr[0].i;
- totalSize += p->m_sz;
- }
-
- if(totalSize <= messageSize + SectionSegment::DataLength){
- /**
- * Send signal directly
- */
- sendSignal(rg, gsn, signal, length, jbuf);
- info.m_status = FragmentSendInfo::SendComplete;
- return true;
- }
-
- /**
- * Consume sections
- */
- signal->header.m_noOfSections = 0;
-
- /**
- * Setup info object
- */
- info.m_status = FragmentSendInfo::SendNotComplete;
- info.m_prio = (Uint8)jbuf;
- info.m_gsn = gsn;
- info.m_fragInfo = 1;
- info.m_messageSize = messageSize;
- info.m_fragmentId = c_fragmentIdCounter++;
- info.m_nodeReceiverGroup = rg;
- info.m_callback.m_callbackFunction = 0;
-
- Ptr<SectionSegment> tmp;
- if(!import(tmp, &signal->theData[0], length)){
- ndbrequire(false);
- return false;
- }
- info.m_theDataSection.p = &tmp.p->theData[0];
- info.m_theDataSection.sz = length;
- tmp.p->theData[length] = tmp.i;
-
- sendNextSegmentedFragment(signal, info);
-
- if(c_fragmentIdCounter == 0){
- /**
- * Fragment id 0 is invalid
- */
- c_fragmentIdCounter = 1;
- }
-
- return true;
-}
-
-#if 0
-#define lsout(x) x
-#else
-#define lsout(x)
-#endif
-
-void
-SimulatedBlock::sendNextSegmentedFragment(Signal* signal,
- FragmentSendInfo & info){
-
- /**
- * Store "theData"
- */
- const Uint32 sigLen = info.m_theDataSection.sz;
- memcpy(&signal->theData[0], info.m_theDataSection.p, 4 * sigLen);
-
- Uint32 sz = 0;
- Uint32 maxSz = info.m_messageSize;
-
- Int32 secNo = 2;
- Uint32 secCount = 0;
- Uint32 * secNos = &signal->theData[sigLen];
-
- enum { Unknown = 0, Full = 1 } loop = Unknown;
- for(; secNo >= 0 && secCount < 3; secNo--){
- Uint32 ptrI = info.m_sectionPtr[secNo].m_segmented.i;
- if(ptrI == RNIL)
- continue;
-
- info.m_sectionPtr[secNo].m_segmented.i = RNIL;
-
- SectionSegment * ptrP = info.m_sectionPtr[secNo].m_segmented.p;
- const Uint32 size = ptrP->m_sz;
-
- signal->m_sectionPtr[secCount].i = ptrI;
- signal->m_sectionPtr[secCount].p = ptrP;
- signal->m_sectionPtr[secCount].sz = size;
- secNos[secCount] = secNo;
- secCount++;
-
- const Uint32 sizeLeft = maxSz - sz;
- if(size <= sizeLeft){
- /**
- * The section fits
- */
- sz += size;
- lsout(ndbout_c("section %d saved as %d", secNo, secCount-1));
- continue;
- }
-
- const Uint32 overflow = size - sizeLeft; // > 0
- if(overflow <= SectionSegment::DataLength){
- /**
- * Only one segment left to send
- * send even if sizeLeft <= size
- */
- lsout(ndbout_c("section %d saved as %d but full over: %d",
- secNo, secCount-1, overflow));
- secNo--;
- break;
- }
-
- // size >= 61
- if(sizeLeft < SectionSegment::DataLength){
- /**
- * Less than one segment left (space)
- * dont bother sending
- */
- secCount--;
- info.m_sectionPtr[secNo].m_segmented.i = ptrI;
- loop = Full;
- lsout(ndbout_c("section %d not saved", secNo));
- break;
- }
-
- /**
- * Split list
- * 1) Find place to split
- * 2) Rewrite header (the part that will be sent)
- * 3) Write new header (for remaining part)
- * 4) Store new header on FragmentSendInfo - record
- */
- // size >= 61 && sizeLeft >= 60
- Uint32 sum = SectionSegment::DataLength;
- Uint32 prevPtrI = ptrI;
- ptrI = ptrP->m_nextSegment;
- const Uint32 fill = sizeLeft - SectionSegment::DataLength;
- while(sum < fill){
- prevPtrI = ptrI;
- ptrP = g_sectionSegmentPool.getPtr(ptrI);
- ptrI = ptrP->m_nextSegment;
- sum += SectionSegment::DataLength;
- }
-
- /**
- * Rewrite header w.r.t size and last
- */
- Uint32 prev = secCount - 1;
- const Uint32 last = signal->m_sectionPtr[prev].p->m_lastSegment;
- signal->m_sectionPtr[prev].p->m_lastSegment = prevPtrI;
- signal->m_sectionPtr[prev].p->m_sz = sum;
- signal->m_sectionPtr[prev].sz = sum;
-
- /**
- * Write "new" list header
- */
- ptrP = g_sectionSegmentPool.getPtr(ptrI);
- ptrP->m_lastSegment = last;
- ptrP->m_sz = size - sum;
-
- /**
- * And store it on info-record
- */
- info.m_sectionPtr[secNo].m_segmented.i = ptrI;
- info.m_sectionPtr[secNo].m_segmented.p = ptrP;
-
- loop = Full;
- lsout(ndbout_c("section %d split into %d", secNo, prev));
- break;
- }
-
- lsout(ndbout_c("loop: %d secNo: %d secCount: %d sz: %d",
- loop, secNo, secCount, sz));
-
- /**
- * Store fragment id
- */
- secNos[secCount] = info.m_fragmentId;
-
- Uint32 fragInfo = info.m_fragInfo;
- info.m_fragInfo = 2;
- switch(loop){
- case Unknown:
- if(secNo >= 0){
- lsout(ndbout_c("Unknown - Full"));
- /**
- * Not finished
- */
- break;
- }
- // Fall through
- lsout(ndbout_c("Unknown - Done"));
- info.m_status = FragmentSendInfo::SendComplete;
- ndbassert(fragInfo == 2);
- fragInfo = 3;
- case Full:
- break;
- }
-
- signal->header.m_fragmentInfo = fragInfo;
- signal->header.m_noOfSections = secCount;
-
- sendSignal(info.m_nodeReceiverGroup,
- info.m_gsn,
- signal,
- sigLen + secCount + 1,
- (JobBufferLevel)info.m_prio);
-
- if(fragInfo == 3){
- /**
- * This is the last signal
- */
- g_sectionSegmentPool.release(info.m_theDataSection.p[sigLen]);
- }
-}
-
-bool
-SimulatedBlock::sendFirstFragment(FragmentSendInfo & info,
- NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Uint32 messageSize){
-
- ::releaseSections(signal->header.m_noOfSections, signal->m_sectionPtr);
- signal->header.m_noOfSections = 0;
-
- info.m_sectionPtr[0].m_linear.p = NULL;
- info.m_sectionPtr[1].m_linear.p = NULL;
- info.m_sectionPtr[2].m_linear.p = NULL;
-
- Uint32 totalSize = 0;
- switch(noOfSections){
- case 3:
- info.m_sectionPtr[2].m_linear = ptr[2];
- totalSize += ptr[2].sz;
- case 2:
- info.m_sectionPtr[1].m_linear = ptr[1];
- totalSize += ptr[1].sz;
- case 1:
- info.m_sectionPtr[0].m_linear = ptr[0];
- totalSize += ptr[0].sz;
- }
-
- if(totalSize <= messageSize + SectionSegment::DataLength){
- /**
- * Send signal directly
- */
- sendSignal(rg, gsn, signal, length, jbuf, ptr, noOfSections);
- info.m_status = FragmentSendInfo::SendComplete;
-
- /**
- * Indicate to sendLinearSignalFragment
- * that we'r already done
- */
- return true;
- }
-
- /**
- * Setup info object
- */
- info.m_status = FragmentSendInfo::SendNotComplete;
- info.m_prio = (Uint8)jbuf;
- info.m_gsn = gsn;
- info.m_messageSize = messageSize;
- info.m_fragInfo = 1;
- info.m_fragmentId = c_fragmentIdCounter++;
- info.m_nodeReceiverGroup = rg;
- info.m_callback.m_callbackFunction = 0;
-
- Ptr<SectionSegment> tmp;
- if(!import(tmp, &signal->theData[0], length)){
- ndbrequire(false);
- return false;
- }
-
- info.m_theDataSection.p = &tmp.p->theData[0];
- info.m_theDataSection.sz = length;
- tmp.p->theData[length] = tmp.i;
-
- sendNextLinearFragment(signal, info);
-
- if(c_fragmentIdCounter == 0){
- /**
- * Fragment id 0 is invalid
- */
- c_fragmentIdCounter = 1;
- }
-
- return true;
-}
-
-void
-SimulatedBlock::sendNextLinearFragment(Signal* signal,
- FragmentSendInfo & info){
-
- /**
- * Store "theData"
- */
- const Uint32 sigLen = info.m_theDataSection.sz;
- memcpy(&signal->theData[0], info.m_theDataSection.p, 4 * sigLen);
-
- Uint32 sz = 0;
- Uint32 maxSz = info.m_messageSize;
-
- Int32 secNo = 2;
- Uint32 secCount = 0;
- Uint32 * secNos = &signal->theData[sigLen];
- LinearSectionPtr signalPtr[3];
-
- enum { Unknown = 0, Full = 2 } loop = Unknown;
- for(; secNo >= 0 && secCount < 3; secNo--){
- Uint32 * ptrP = info.m_sectionPtr[secNo].m_linear.p;
- if(ptrP == NULL)
- continue;
-
- info.m_sectionPtr[secNo].m_linear.p = NULL;
- const Uint32 size = info.m_sectionPtr[secNo].m_linear.sz;
-
- signalPtr[secCount].p = ptrP;
- signalPtr[secCount].sz = size;
- secNos[secCount] = secNo;
- secCount++;
-
- const Uint32 sizeLeft = maxSz - sz;
- if(size <= sizeLeft){
- /**
- * The section fits
- */
- sz += size;
- lsout(ndbout_c("section %d saved as %d", secNo, secCount-1));
- continue;
- }
-
- const Uint32 overflow = size - sizeLeft; // > 0
- if(overflow <= SectionSegment::DataLength){
- /**
- * Only one segment left to send
- * send even if sizeLeft <= size
- */
- lsout(ndbout_c("section %d saved as %d but full over: %d",
- secNo, secCount-1, overflow));
- secNo--;
- break;
- }
-
- // size >= 61
- if(sizeLeft < SectionSegment::DataLength){
- /**
- * Less than one segment left (space)
- * dont bother sending
- */
- secCount--;
- info.m_sectionPtr[secNo].m_linear.p = ptrP;
- loop = Full;
- lsout(ndbout_c("section %d not saved", secNo));
- break;
- }
-
- /**
- * Split list
- * 1) Find place to split
- * 2) Rewrite header (the part that will be sent)
- * 3) Write new header (for remaining part)
- * 4) Store new header on FragmentSendInfo - record
- */
- Uint32 sum = sizeLeft;
- sum /= SectionSegment::DataLength;
- sum *= SectionSegment::DataLength;
-
- /**
- * Rewrite header w.r.t size
- */
- Uint32 prev = secCount - 1;
- signalPtr[prev].sz = sum;
-
- /**
- * Write/store "new" header
- */
- info.m_sectionPtr[secNo].m_linear.p = ptrP + sum;
- info.m_sectionPtr[secNo].m_linear.sz = size - sum;
-
- loop = Full;
- lsout(ndbout_c("section %d split into %d", secNo, prev));
- break;
- }
-
- lsout(ndbout_c("loop: %d secNo: %d secCount: %d sz: %d",
- loop, secNo, secCount, sz));
-
- /**
- * Store fragment id
- */
- secNos[secCount] = info.m_fragmentId;
-
- Uint32 fragInfo = info.m_fragInfo;
- info.m_fragInfo = 2;
- switch(loop){
- case Unknown:
- if(secNo >= 0){
- lsout(ndbout_c("Unknown - Full"));
- /**
- * Not finished
- */
- break;
- }
- // Fall through
- lsout(ndbout_c("Unknown - Done"));
- info.m_status = FragmentSendInfo::SendComplete;
- ndbassert(fragInfo == 2);
- fragInfo = 3;
- case Full:
- break;
- }
-
- signal->header.m_noOfSections = 0;
- signal->header.m_fragmentInfo = fragInfo;
-
- sendSignal(info.m_nodeReceiverGroup,
- info.m_gsn,
- signal,
- sigLen + secCount + 1,
- (JobBufferLevel)info.m_prio,
- signalPtr,
- secCount);
-
- if(fragInfo == 3){
- /**
- * This is the last signal
- */
- g_sectionSegmentPool.release(info.m_theDataSection.p[sigLen]);
- }
-}
-
-void
-SimulatedBlock::sendFragmentedSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Callback & c,
- Uint32 messageSize){
- bool res = true;
- Ptr<FragmentSendInfo> ptr;
- res = c_segmentedFragmentSendList.seize(ptr);
- ndbrequire(res);
-
- res = sendFirstFragment(* ptr.p,
- NodeReceiverGroup(ref),
- gsn,
- signal,
- length,
- jbuf,
- messageSize);
- ndbrequire(res);
-
- if(ptr.p->m_status == FragmentSendInfo::SendComplete){
- c_segmentedFragmentSendList.release(ptr);
- if(c.m_callbackFunction != 0)
- execute(signal, c, 0);
- return;
- }
- ptr.p->m_callback = c;
-
- if(!c_fragSenderRunning){
- c_fragSenderRunning = true;
- ContinueFragmented * sig = (ContinueFragmented*)signal->getDataPtrSend();
- sig->line = __LINE__;
- sendSignal(reference(), GSN_CONTINUE_FRAGMENTED, signal, 1, JBB);
- }
-}
-
-void
-SimulatedBlock::sendFragmentedSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Callback & c,
- Uint32 messageSize){
- bool res = true;
- Ptr<FragmentSendInfo> ptr;
- res = c_segmentedFragmentSendList.seize(ptr);
- ndbrequire(res);
-
- res = sendFirstFragment(* ptr.p,
- rg,
- gsn,
- signal,
- length,
- jbuf,
- messageSize);
- ndbrequire(res);
-
- if(ptr.p->m_status == FragmentSendInfo::SendComplete){
- c_segmentedFragmentSendList.release(ptr);
- if(c.m_callbackFunction != 0)
- execute(signal, c, 0);
- return;
- }
- ptr.p->m_callback = c;
-
- if(!c_fragSenderRunning){
- c_fragSenderRunning = true;
- ContinueFragmented * sig = (ContinueFragmented*)signal->getDataPtrSend();
- sig->line = __LINE__;
- sendSignal(reference(), GSN_CONTINUE_FRAGMENTED, signal, 1, JBB);
- }
-}
-
-SimulatedBlock::Callback SimulatedBlock::TheEmptyCallback = {0, 0};
-void
-SimulatedBlock::TheNULLCallbackFunction(class Signal*, Uint32, Uint32)
-{ abort(); /* should never be called */ }
-SimulatedBlock::Callback SimulatedBlock::TheNULLCallback =
-{ &SimulatedBlock::TheNULLCallbackFunction, 0 };
-
-void
-SimulatedBlock::sendFragmentedSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Callback & c,
- Uint32 messageSize){
- bool res = true;
- Ptr<FragmentSendInfo> tmp;
- res = c_linearFragmentSendList.seize(tmp);
- ndbrequire(res);
-
- res = sendFirstFragment(* tmp.p,
- NodeReceiverGroup(ref),
- gsn,
- signal,
- length,
- jbuf,
- ptr,
- noOfSections,
- messageSize);
- ndbrequire(res);
-
- if(tmp.p->m_status == FragmentSendInfo::SendComplete){
- c_linearFragmentSendList.release(tmp);
- if(c.m_callbackFunction != 0)
- execute(signal, c, 0);
- return;
- }
- tmp.p->m_callback = c;
-
- if(!c_fragSenderRunning){
- c_fragSenderRunning = true;
- ContinueFragmented * sig = (ContinueFragmented*)signal->getDataPtrSend();
- sig->line = __LINE__;
- sendSignal(reference(), GSN_CONTINUE_FRAGMENTED, signal, 1, JBB);
- }
-}
-
-void
-SimulatedBlock::sendFragmentedSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Callback & c,
- Uint32 messageSize){
- bool res = true;
- Ptr<FragmentSendInfo> tmp;
- res = c_linearFragmentSendList.seize(tmp);
- ndbrequire(res);
-
- res = sendFirstFragment(* tmp.p,
- rg,
- gsn,
- signal,
- length,
- jbuf,
- ptr,
- noOfSections,
- messageSize);
- ndbrequire(res);
-
- if(tmp.p->m_status == FragmentSendInfo::SendComplete){
- c_linearFragmentSendList.release(tmp);
- if(c.m_callbackFunction != 0)
- execute(signal, c, 0);
- return;
- }
- tmp.p->m_callback = c;
-
- if(!c_fragSenderRunning){
- c_fragSenderRunning = true;
- ContinueFragmented * sig = (ContinueFragmented*)signal->getDataPtrSend();
- sig->line = __LINE__;
- sendSignal(reference(), GSN_CONTINUE_FRAGMENTED, signal, 1, JBB);
- }
-}
-
-NodeInfo &
-SimulatedBlock::setNodeInfo(NodeId nodeId) {
- ndbrequire(nodeId > 0 && nodeId < MAX_NODES);
- return globalData.m_nodeInfo[nodeId];
-}
-
-void
-SimulatedBlock::execUTIL_CREATE_LOCK_REF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_CREATE_LOCK_REF(signal);
-}
-
-void SimulatedBlock::execUTIL_CREATE_LOCK_CONF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_CREATE_LOCK_CONF(signal);
-}
-
-void SimulatedBlock::execUTIL_DESTORY_LOCK_REF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_DESTORY_LOCK_REF(signal);
-}
-
-void SimulatedBlock::execUTIL_DESTORY_LOCK_CONF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_DESTORY_LOCK_CONF(signal);
-}
-
-void SimulatedBlock::execUTIL_LOCK_REF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_LOCK_REF(signal);
-}
-
-void SimulatedBlock::execUTIL_LOCK_CONF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_LOCK_CONF(signal);
-}
-
-void SimulatedBlock::execUTIL_UNLOCK_REF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_UNLOCK_REF(signal);
-}
-
-void SimulatedBlock::execUTIL_UNLOCK_CONF(Signal* signal){
- ljamEntry();
- c_mutexMgr.execUTIL_UNLOCK_CONF(signal);
-}
-
-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;
- }
-}
-
-void
-SimulatedBlock::fsRefError(Signal* signal, Uint32 line, const char *msg)
-{
- const FsRef *fsRef = (FsRef*)signal->getDataPtr();
- Uint32 errorCode = fsRef->errorCode;
- Uint32 osErrorCode = fsRef->osErrorCode;
- char msg2[100];
-
- sprintf(msg2, "%s: %s. OS errno: %u", getBlockName(number()), msg, osErrorCode);
-
- progError(line, errorCode, msg2);
-}
-
-void
-SimulatedBlock::execFSWRITEREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system write failed");
-}
-
-void
-SimulatedBlock::execFSREADREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system read failed");
-}
-
-void
-SimulatedBlock::execFSCLOSEREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system close failed");
-}
-
-void
-SimulatedBlock::execFSOPENREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system open failed");
-}
-
-void
-SimulatedBlock::execFSREMOVEREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system remove failed");
-}
-
-void
-SimulatedBlock::execFSSYNCREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system sync failed");
-}
-
-void
-SimulatedBlock::execFSAPPENDREF(Signal* signal)
-{
- fsRefError(signal, __LINE__, "File system append failed");
-}
-
-#ifdef VM_TRACE
-void
-SimulatedBlock::clear_global_variables(){
- Ptr<void> ** tmp = m_global_variables;
- while(* tmp != 0){
- (* tmp)->i = RNIL;
- (* tmp)->p = 0;
- tmp++;
- }
-}
-
-void
-SimulatedBlock::init_globals_list(void ** tmp, size_t cnt){
- m_global_variables = new Ptr<void> * [cnt+1];
- for(size_t i = 0; i<cnt; i++){
- m_global_variables[i] = (Ptr<void>*)tmp[i];
- }
- m_global_variables[cnt] = 0;
-}
-
-#endif
-
-#include "KeyDescriptor.hpp"
-
-Uint32
-SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
- Uint32 *dst, Uint32 dstSize,
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const
-{
- const KeyDescriptor * desc = g_key_descriptor_pool.getPtr(tab);
- const Uint32 noOfKeyAttr = desc->noOfKeyAttr;
-
- Uint32 i = 0;
- Uint32 srcPos = 0;
- Uint32 dstPos = 0;
- while (i < noOfKeyAttr)
- {
- const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i];
- Uint32 dstWords =
- xfrm_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo,
- src, srcPos, dst, dstPos, dstSize);
- keyPartLen[i++] = dstWords;
- if (unlikely(dstWords == 0))
- return 0;
- }
-
- if (0)
- {
- for(Uint32 i = 0; i<dstPos; i++)
- {
- printf("%.8x ", dst[i]);
- }
- printf("\n");
- }
- return dstPos;
-}
-
-Uint32
-SimulatedBlock::xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
- const Uint32* src, Uint32 & srcPos,
- Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const
-{
- Uint32 array =
- AttributeDescriptor::getArrayType(attrDesc);
- Uint32 srcBytes =
- AttributeDescriptor::getSizeInBytes(attrDesc);
-
- Uint32 srcWords = ~0;
- Uint32 dstWords = ~0;
- uchar* dstPtr = (uchar*)&dst[dstPos];
- const uchar* srcPtr = (const uchar*)&src[srcPos];
-
- if (cs == NULL)
- {
- jam();
- Uint32 len;
- LINT_INIT(len);
- switch(array){
- case NDB_ARRAYTYPE_SHORT_VAR:
- len = 1 + srcPtr[0];
- break;
- case NDB_ARRAYTYPE_MEDIUM_VAR:
- len = 2 + srcPtr[0] + (srcPtr[1] << 8);
- break;
-#ifndef VM_TRACE
- default:
-#endif
- case NDB_ARRAYTYPE_FIXED:
- len = srcBytes;
- }
- srcWords = (len + 3) >> 2;
- dstWords = srcWords;
- memcpy(dstPtr, srcPtr, dstWords << 2);
-
- if (0)
- {
- ndbout_c("srcPos: %d dstPos: %d len: %d srcWords: %d dstWords: %d",
- srcPos, dstPos, len, srcWords, dstWords);
-
- for(Uint32 i = 0; i<srcWords; i++)
- printf("%.8x ", src[srcPos + i]);
- printf("\n");
- }
- }
- else
- {
- jam();
- Uint32 typeId =
- AttributeDescriptor::getType(attrDesc);
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
- if (unlikely(!ok))
- return 0;
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- /*
- * Varchar end-spaces are ignored in comparisons. To get same hash
- * we blank-pad to maximum length via strnxfrm.
- */
- Uint32 dstLen = xmul * (srcBytes - lb);
- ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
- int n = NdbSqlUtil::strnxfrm_bug7284(cs, dstPtr, dstLen, srcPtr + lb, len);
- if (unlikely(n == -1))
- return 0;
- while ((n & 3) != 0)
- {
- dstPtr[n++] = 0;
- }
- dstWords = (n >> 2);
- srcWords = (lb + len + 3) >> 2;
- }
-
- dstPos += dstWords;
- srcPos += srcWords;
- return dstWords;
-}
-
-Uint32
-SimulatedBlock::create_distr_key(Uint32 tableId,
- Uint32 *data,
- const Uint32
- keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const
-{
- const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tableId);
- const Uint32 noOfKeyAttr = desc->noOfKeyAttr;
- Uint32 noOfDistrKeys = desc->noOfDistrKeys;
-
- Uint32 *src = data;
- Uint32 *dst = data;
- Uint32 i = 0;
- Uint32 dstPos = 0;
-
- if(keyPartLen)
- {
- while (i < noOfKeyAttr && noOfDistrKeys)
- {
- Uint32 attr = desc->keyAttr[i].attributeDescriptor;
- Uint32 len = keyPartLen[i];
- if(AttributeDescriptor::getDKey(attr))
- {
- noOfDistrKeys--;
- memmove(dst+dstPos, src, len << 2);
- dstPos += len;
- }
- src += len;
- i++;
- }
- }
- else
- {
- while (i < noOfKeyAttr && noOfDistrKeys)
- {
- Uint32 attr = desc->keyAttr[i].attributeDescriptor;
- Uint32 len = AttributeDescriptor::getSizeInWords(attr);
- ndbrequire(AttributeDescriptor::getArrayType(attr) == NDB_ARRAYTYPE_FIXED);
- if(AttributeDescriptor::getDKey(attr))
- {
- noOfDistrKeys--;
- memmove(dst+dstPos, src, len << 2);
- dstPos += len;
- }
- src += len;
- i++;
- }
- }
- return dstPos;
-}
-
-CArray<KeyDescriptor> g_key_descriptor_pool;
-
diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
deleted file mode 100644
index ebd07a5bb1a..00000000000
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
+++ /dev/null
@@ -1,824 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SIMULATEDBLOCK_H
-#define SIMULATEDBLOCK_H
-
-#include <NdbTick.h>
-#include <kernel_types.h>
-#include <util/version.h>
-#include <ndb_limits.h>
-
-#include "VMSignal.hpp"
-#include <RefConvert.hpp>
-#include <BlockNumbers.h>
-#include <GlobalSignalNumbers.h>
-
-#include "pc.hpp"
-#include "Pool.hpp"
-#include <NodeInfo.hpp>
-#include <NodeState.hpp>
-#include "GlobalData.hpp"
-#include "LongSignal.hpp"
-#include <SignalLoggerManager.hpp>
-
-#include <ErrorReporter.hpp>
-#include <ErrorHandlingMacros.hpp>
-
-#include "DLList.hpp"
-#include "ArrayPool.hpp"
-#include "DLHashTable.hpp"
-#include "WOPool.hpp"
-#include "RWPool.hpp"
-#include "Callback.hpp"
-#include "SafeCounter.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>
-#include "ndbd_malloc_impl.hpp"
-#include <blocks/record_types.hpp>
-
-/**
- * Something for filesystem access
- */
-struct NewBaseAddrBits /* 32 bits */
-{
- unsigned int q : 4; /* Highest index - 2log */
- /* Strings are treated as 16 bit indexed */
- /* variables with the number of characters in */
- /* index 0, byte 0 */
- unsigned int v : 3; /* Size in bits - 2log */
- unsigned int unused : 25 ;
-};
-
-typedef struct NewVar
-{
- Uint32 * WA;
- Uint32 nrr;
- Uint32 ClusterSize; /* Real Cluster size */
- NewBaseAddrBits bits;
-} NewVARIABLE; /* 128 bits */
-
-struct Block_context
-{
- Block_context(class Configuration& cfg, class Ndbd_mem_manager& mm)
- : m_config(cfg), m_mm(mm) {}
- class Configuration& m_config;
- class Ndbd_mem_manager& m_mm;
-};
-
-class SimulatedBlock {
- friend class TraceLCP;
- friend class SafeCounter;
- friend class SafeCounterManager;
- friend struct UpgradeStartup;
- friend class AsyncFile;
- friend class Pgman;
- friend class Page_cache_client;
- friend class Lgman;
- friend class Logfile_client;
- friend struct Pool_context;
-public:
- friend class BlockComponent;
- virtual ~SimulatedBlock();
-
-protected:
- /**
- * Constructor
- */
- SimulatedBlock(BlockNumber blockNumber,
- struct Block_context & ctx);
-
- /**********************************************************
- * Handling of execFunctions
- */
- typedef void (SimulatedBlock::* ExecFunction)(Signal* signal);
- void addRecSignalImpl(GlobalSignalNumber g, ExecFunction fun, bool f =false);
- void installSimulatedBlockFunctions();
- ExecFunction theExecArray[MAX_GSN+1];
-public:
- /**
- *
- */
- inline void executeFunction(GlobalSignalNumber gsn, Signal* signal);
-public:
- typedef void (SimulatedBlock::* CallbackFunction)(class Signal*,
- Uint32 callbackData,
- Uint32 returnCode);
- struct Callback {
- CallbackFunction m_callbackFunction;
- Uint32 m_callbackData;
- };
-
- virtual const char* get_filename(Uint32 fd) const { return "";}
-protected:
- static Callback TheEmptyCallback;
- void TheNULLCallbackFunction(class Signal*, Uint32, Uint32);
- static Callback TheNULLCallback;
- void execute(Signal* signal, Callback & c, Uint32 returnCode);
-
-
- /**********************************************************
- * Send signal - dialects
- */
-
- void sendSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf ) const ;
-
- void sendSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf ) const ;
-
- void sendSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections) const ;
-
- void sendSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections) const ;
-
- // Send multiple signal with delay. In this VM the jobbufffer level has
- // no effect on on delayed signals
- //
- void sendSignalWithDelay(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 delayInMilliSeconds,
- Uint32 length) const ;
-
- void EXECUTE_DIRECT(Uint32 block,
- Uint32 gsn,
- Signal* signal,
- Uint32 len);
-
- class SectionSegmentPool& getSectionSegmentPool();
- void releaseSections(Signal* signal);
-
- /**********************************************************
- * Fragmented signals
- */
-
- /**
- * Assemble fragments
- *
- * @return true if all fragments has arrived
- * false otherwise
- */
- bool assembleFragments(Signal * signal);
-
- void sendFragmentedSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Callback & = TheEmptyCallback,
- Uint32 messageSize = 240);
-
- void sendFragmentedSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Callback & = TheEmptyCallback,
- Uint32 messageSize = 240);
-
- void sendFragmentedSignal(BlockReference ref,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Callback &,
- Uint32 messageSize = 240);
-
- void sendFragmentedSignal(NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Callback &,
- Uint32 messageSize = 240);
-
- /**********************************************************
- * Fragmented signals structures
- */
-
- /**
- * Struct used when assembling fragmented long signals at receiver side
- */
- struct FragmentInfo {
- FragmentInfo(Uint32 fragId, Uint32 sender);
-
- Uint32 m_senderRef;
- Uint32 m_fragmentId;
- Uint32 m_sectionPtrI[3];
- union {
- Uint32 nextPool;
- Uint32 nextHash;
- };
- Uint32 prevHash;
-
- inline bool equal(FragmentInfo & p) const {
- return m_senderRef == p.m_senderRef && m_fragmentId == p.m_fragmentId;
- }
-
- inline Uint32 hashValue() const {
- return m_senderRef + m_fragmentId ;
- }
- }; // sizeof() = 32 bytes
-
- /**
- * Struct used when sending fragmented signals
- */
- struct FragmentSendInfo {
- FragmentSendInfo();
-
- enum Status {
- SendNotComplete = 0,
- SendComplete = 1
- };
- Uint8 m_status;
- Uint8 m_prio;
- Uint16 m_fragInfo;
- Uint16 m_gsn;
- Uint16 m_messageSize; // Size of each fragment
- Uint32 m_fragmentId;
- union {
- Ptr<struct SectionSegment> m_segmented;
- LinearSectionPtr m_linear;
- } m_sectionPtr[3];
- LinearSectionPtr m_theDataSection;
- NodeReceiverGroup m_nodeReceiverGroup; // 3
- Callback m_callback;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
-
- /**
- * setupFragmentSendInfo
- * Setup a struct to be used with sendSignalFragment
- * Used by sendFragmentedSignal
- */
- bool sendFirstFragment(FragmentSendInfo & info,
- NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections,
- Uint32 messageSize = 240);
-
- bool sendFirstFragment(FragmentSendInfo & info,
- NodeReceiverGroup rg,
- GlobalSignalNumber gsn,
- Signal* signal,
- Uint32 length,
- JobBufferLevel jbuf,
- Uint32 messageSize = 240);
-
- /**
- * Send signal fragment
- *
- * @see sendFragmentedSignal
- */
- void sendNextSegmentedFragment(Signal* signal, FragmentSendInfo & info);
-
- /**
- * Send signal fragment
- *
- * @see sendFragmentedSignal
- */
- void sendNextLinearFragment(Signal* signal, FragmentSendInfo & info);
-
- BlockNumber number() const;
- BlockReference reference() const;
- NodeId getOwnNodeId() const;
-
- /**
- * Refresh Watch Dog in initialising code
- *
- */
- void refresh_watch_dog(Uint32 place = 1);
- void update_watch_dog_timer(Uint32 interval);
-
- /**
- * Prog error
- * This function should be called when this node should be shutdown
- * If the cause of the shutdown is known use extradata to add an
- * errormessage describing the problem
- */
- void progError(int line, int err_code, const char* extradata=NULL) const ;
-private:
- void signal_error(Uint32, Uint32, Uint32, const char*, int) const ;
- const NodeId theNodeId;
- const BlockNumber theNumber;
- const BlockReference theReference;
-
-protected:
- Block_context m_ctx;
- NewVARIABLE* allocateBat(int batSize);
- void freeBat();
- static const NewVARIABLE* getBat (BlockNumber blockNo);
- static Uint16 getBatSize(BlockNumber blockNo);
-
- static BlockReference calcTcBlockRef (NodeId aNode);
- static BlockReference calcLqhBlockRef (NodeId aNode);
- static BlockReference calcAccBlockRef (NodeId aNode);
- static BlockReference calcTupBlockRef (NodeId aNode);
- static BlockReference calcTuxBlockRef (NodeId aNode);
- static BlockReference calcDihBlockRef (NodeId aNode);
- static BlockReference calcQmgrBlockRef (NodeId aNode);
- static BlockReference calcDictBlockRef (NodeId aNode);
- static BlockReference calcNdbCntrBlockRef (NodeId aNode);
- static BlockReference calcTrixBlockRef (NodeId aNode);
- static BlockReference calcBackupBlockRef (NodeId aNode);
- static BlockReference calcSumaBlockRef (NodeId aNode);
-
- static BlockReference calcApiClusterMgrBlockRef (NodeId aNode);
-
- /**
- * allocRecord
- * Allocates memory for the datastructures where ndb keeps the data
- *
- */
- void* allocRecord(const char * type, size_t s, size_t n, bool clear = true, Uint32 paramId = 0);
- void* allocRecordAligned(const char * type, size_t s, size_t n, void **unaligned_buffer, Uint32 align = NDB_O_DIRECT_WRITE_ALIGNMENT, bool clear = true, Uint32 paramId = 0);
-
- /**
- * Deallocate record
- *
- * NOTE: Also resets pointer
- */
- void deallocRecord(void **, const char * type, size_t s, size_t n);
-
- /**
- * General info event (sent to cluster log)
- */
- void infoEvent(const char * msg, ...) const ;
- void warningEvent(const char * msg, ...) const ;
-
- /**
- * Get node state
- */
- const NodeState & getNodeState() const;
-
- /**
- * Get node info
- */
- const NodeInfo & getNodeInfo(NodeId nodeId) const;
- NodeInfo & setNodeInfo(NodeId);
-
- const NodeVersionInfo& getNodeVersionInfo() const;
- NodeVersionInfo& setNodeVersionInfo();
-
- /**********************
- * Xfrm stuff
- */
-
- /**
- * @return length
- */
- Uint32 xfrm_key(Uint32 tab, const Uint32* src,
- Uint32 *dst, Uint32 dstSize,
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const;
-
- Uint32 xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
- const Uint32* src, Uint32 & srcPos,
- Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const;
-
- /**
- *
- */
- Uint32 create_distr_key(Uint32 tableId,
- Uint32 *data,
- const Uint32 keyPaLen[MAX_ATTRIBUTES_IN_INDEX])const;
-
-private:
- NewVARIABLE* NewVarRef; /* New Base Address Table for block */
- Uint16 theBATSize; /* # entries in BAT */
-
-protected:
- ArrayPool<GlobalPage>& m_global_page_pool;
- ArrayPool<GlobalPage>& m_shared_page_pool;
-
-private:
- /**
- * Node state
- */
- NodeState theNodeState;
- void execNDB_TAMPER(Signal * signal);
- void execNODE_STATE_REP(Signal* signal);
- void execCHANGE_NODE_STATE_REQ(Signal* signal);
-
- void execSIGNAL_DROPPED_REP(Signal* signal);
- void execCONTINUE_FRAGMENTED(Signal* signal);
- void execAPI_START_REP(Signal* signal);
- void execNODE_START_REP(Signal* signal);
-
- Uint32 c_fragmentIdCounter;
- ArrayPool<FragmentInfo> c_fragmentInfoPool;
- DLHashTable<FragmentInfo> c_fragmentInfoHash;
-
- bool c_fragSenderRunning;
- ArrayPool<FragmentSendInfo> c_fragmentSendPool;
- DLList<FragmentSendInfo> c_linearFragmentSendList;
- DLList<FragmentSendInfo> c_segmentedFragmentSendList;
-
-public:
- class MutexManager {
- friend class Mutex;
- friend class SimulatedBlock;
- friend class DbUtil;
- public:
- MutexManager(class SimulatedBlock &);
-
- bool setSize(Uint32 maxNoOfActiveMutexes);
- Uint32 getSize() const ; // Get maxNoOfActiveMutexes
-
- private:
- /**
- * core interface
- */
- struct ActiveMutex {
- Uint32 m_gsn; // state
- Uint32 m_mutexId;
- Uint32 m_mutexKey;
- Callback m_callback;
- union {
- Uint32 nextPool;
- Uint32 nextList;
- };
- Uint32 prevList;
- };
- typedef Ptr<ActiveMutex> ActiveMutexPtr;
-
- bool seize(ActiveMutexPtr& ptr);
- void release(Uint32 activeMutexPtrI);
-
- void getPtr(ActiveMutexPtr& ptr);
-
- void create(Signal*, ActiveMutexPtr&);
- void destroy(Signal*, ActiveMutexPtr&);
- void lock(Signal*, ActiveMutexPtr&);
- void trylock(Signal*, ActiveMutexPtr&);
- void unlock(Signal*, ActiveMutexPtr&);
-
- private:
- void execUTIL_CREATE_LOCK_REF(Signal* signal);
- void execUTIL_CREATE_LOCK_CONF(Signal* signal);
- void execUTIL_DESTORY_LOCK_REF(Signal* signal);
- void execUTIL_DESTORY_LOCK_CONF(Signal* signal);
- void execUTIL_LOCK_REF(Signal* signal);
- void execUTIL_LOCK_CONF(Signal* signal);
- void execUTIL_UNLOCK_REF(Signal* signal);
- void execUTIL_UNLOCK_CONF(Signal* signal);
-
- SimulatedBlock & m_block;
- ArrayPool<ActiveMutex> m_mutexPool;
- DLList<ActiveMutex> m_activeMutexes;
-
- BlockReference reference() const;
- void progError(int line, int err_code, const char* extra = 0);
- };
-
- friend class MutexManager;
- MutexManager c_mutexMgr;
-
- void ignoreMutexUnlockCallback(Signal* signal, Uint32 ptrI, Uint32 retVal);
-
- SafeCounterManager c_counterMgr;
-private:
- void execUTIL_CREATE_LOCK_REF(Signal* signal);
- void execUTIL_CREATE_LOCK_CONF(Signal* signal);
- void execUTIL_DESTORY_LOCK_REF(Signal* signal);
- void execUTIL_DESTORY_LOCK_CONF(Signal* signal);
- void execUTIL_LOCK_REF(Signal* signal);
- void execUTIL_LOCK_CONF(Signal* signal);
- void execUTIL_UNLOCK_REF(Signal* signal);
- void execUTIL_UNLOCK_CONF(Signal* signal);
-
-protected:
- void execUPGRADE(Signal* signal);
-
- void fsRefError(Signal* signal, Uint32 line, const char *msg);
- void execFSWRITEREF(Signal* signal);
- void execFSREADREF(Signal* signal);
- void execFSOPENREF(Signal* signal);
- void execFSCLOSEREF(Signal* signal);
- void execFSREMOVEREF(Signal* signal);
- void execFSSYNCREF(Signal* signal);
- void execFSAPPENDREF(Signal* signal);
-
- // Variable for storing inserted errors, see pc.H
- ERROR_INSERT_VARIABLE;
-
-#ifdef VM_TRACE_TIME
-public:
- void clearTimes();
- void printTimes(FILE * output);
- void addTime(Uint32 gsn, Uint64 time);
- void subTime(Uint32 gsn, Uint64 time);
- struct TimeTrace {
- Uint32 cnt;
- Uint64 sum, sub;
- } m_timeTrace[MAX_GSN+1];
- Uint32 m_currentGsn;
-#endif
-
-#ifdef VM_TRACE
- Ptr<void> **m_global_variables;
- void clear_global_variables();
- void init_globals_list(void ** tmp, size_t cnt);
-#endif
-};
-
-inline
-void
-SimulatedBlock::executeFunction(GlobalSignalNumber gsn, Signal* signal){
- ExecFunction f = theExecArray[gsn];
- if(gsn <= MAX_GSN && f != 0){
-#ifdef VM_TRACE
- clear_global_variables();
-#endif
- (this->*f)(signal);
- return;
- }
-
- /**
- * This point only passed if an error has occurred
- */
- char errorMsg[255];
- if (!(gsn <= MAX_GSN)) {
- BaseString::snprintf(errorMsg, 255, "Illegal signal received (GSN %d too high)", gsn);
- ERROR_SET(fatal, NDBD_EXIT_PRGERR, errorMsg, errorMsg);
- }
- if (!(theExecArray[gsn] != 0)) {
- BaseString::snprintf(errorMsg, 255, "Illegal signal received (GSN %d not added)", gsn);
- ERROR_SET(fatal, NDBD_EXIT_PRGERR, errorMsg, errorMsg);
- }
- ndbrequire(false);
-}
-
-inline
-void
-SimulatedBlock::execute(Signal* signal, Callback & c, Uint32 returnCode){
- CallbackFunction fun = c.m_callbackFunction;
- if (fun == TheNULLCallback.m_callbackFunction)
- return;
- ndbrequire(fun != 0);
- c.m_callbackFunction = NULL;
- (this->*fun)(signal, c.m_callbackData, returnCode);
-}
-
-inline
-BlockNumber
-SimulatedBlock::number() const {
- return theNumber;
-}
-
-inline
-BlockReference
-SimulatedBlock::reference() const {
- return theReference;
-}
-
-inline
-NodeId
-SimulatedBlock::getOwnNodeId() const {
- return theNodeId;
-}
-
-inline
-BlockReference
-SimulatedBlock::calcTcBlockRef (NodeId aNodeId){
- return numberToRef(DBTC, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcLqhBlockRef (NodeId aNodeId){
-return numberToRef(DBLQH, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcAccBlockRef (NodeId aNodeId){
- return numberToRef(DBACC, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcTupBlockRef (NodeId aNodeId){
- return numberToRef(DBTUP, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcTuxBlockRef (NodeId aNodeId){
- return numberToRef(DBTUX, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcDihBlockRef (NodeId aNodeId){
- return numberToRef(DBDIH, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcDictBlockRef (NodeId aNodeId){
- return numberToRef(DBDICT, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcQmgrBlockRef (NodeId aNodeId){
- return numberToRef(QMGR, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcNdbCntrBlockRef (NodeId aNodeId){
- return numberToRef(NDBCNTR, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcTrixBlockRef (NodeId aNodeId){
- return numberToRef(TRIX, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcBackupBlockRef (NodeId aNodeId){
- return numberToRef(BACKUP, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcSumaBlockRef (NodeId aNodeId){
- return numberToRef(SUMA, aNodeId);
-}
-
-inline
-BlockReference
-SimulatedBlock::calcApiClusterMgrBlockRef (NodeId aNodeId){
- return numberToRef(API_CLUSTERMGR, aNodeId);
-}
-
-inline
-const NodeState &
-SimulatedBlock::getNodeState() const {
- return theNodeState;
-}
-
-inline
-const NodeInfo &
-SimulatedBlock::getNodeInfo(NodeId nodeId) const {
- ndbrequire(nodeId > 0 && nodeId < MAX_NODES);
- return globalData.m_nodeInfo[nodeId];
-}
-
-inline
-const NodeVersionInfo &
-SimulatedBlock::getNodeVersionInfo() const {
- return globalData.m_versionInfo;
-}
-
-inline
-NodeVersionInfo &
-SimulatedBlock::setNodeVersionInfo() {
- return globalData.m_versionInfo;
-}
-
-inline
-void
-SimulatedBlock::EXECUTE_DIRECT(Uint32 block,
- Uint32 gsn,
- Signal* signal,
- Uint32 len){
- signal->setLength(len);
-#ifdef VM_TRACE
- if(globalData.testOn){
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = block;
- signal->header.theSendersBlockRef = reference();
- globalSignalLoggers.executeDirect(signal->header,
- 0, // in
- &signal->theData[0],
- globalData.ownId);
- }
-#endif
- SimulatedBlock* b = globalData.getBlock(block);
-#ifdef VM_TRACE_TIME
- Uint32 us1, us2;
- Uint64 ms1, ms2;
- NdbTick_CurrentMicrosecond(&ms1, &us1);
- Uint32 tGsn = m_currentGsn;
- b->m_currentGsn = gsn;
-#endif
- b->executeFunction(gsn, signal);
-#ifdef VM_TRACE_TIME
- NdbTick_CurrentMicrosecond(&ms2, &us2);
- Uint64 diff = ms2;
- diff -= ms1;
- diff *= 1000000;
- diff += us2;
- diff -= us1;
- b->addTime(gsn, diff);
- m_currentGsn = tGsn;
- subTime(tGsn, diff);
-#endif
-#ifdef VM_TRACE
- if(globalData.testOn){
- signal->header.theVerId_signalNumber = gsn;
- signal->header.theReceiversBlockNumber = block;
- signal->header.theSendersBlockRef = reference();
- globalSignalLoggers.executeDirect(signal->header,
- 1, // out
- &signal->theData[0],
- globalData.ownId);
- }
-#endif
-}
-
-#ifdef VM_TRACE_TIME
-inline
-void
-SimulatedBlock::addTime(Uint32 gsn, Uint64 time){
- m_timeTrace[gsn].cnt ++;
- m_timeTrace[gsn].sum += time;
-}
-
-inline
-void
-SimulatedBlock::subTime(Uint32 gsn, Uint64 time){
- m_timeTrace[gsn].sub += time;
-}
-#endif
-
-/**
- * Defines for backward compatiblility
- */
-
-#define BLOCK_DEFINES(BLOCK) \
- typedef void (BLOCK::* ExecSignalLocal) (Signal* signal); \
- typedef void (BLOCK::* BlockCallback)(Signal*, Uint32 callb, Uint32 retCode); \
- inline CallbackFunction safe_cast(BlockCallback f){ \
- return static_cast<CallbackFunction>(f); \
- } \
-public:\
-private: \
- void addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force = false)
-
-#define BLOCK_CONSTRUCTOR(BLOCK)
-
-#define BLOCK_FUNCTIONS(BLOCK) \
-void \
-BLOCK::addRecSignal(GlobalSignalNumber gsn, ExecSignalLocal f, bool force){ \
- addRecSignalImpl(gsn, (ExecFunction)f, force);\
-}
-
-#include "Mutex.hpp"
-
-#endif
-
diff --git a/storage/ndb/src/kernel/vm/SuperPool.cpp b/storage/ndb/src/kernel/vm/SuperPool.cpp
deleted file mode 100644
index de391bcab42..00000000000
--- a/storage/ndb/src/kernel/vm/SuperPool.cpp
+++ /dev/null
@@ -1,750 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "SuperPool.hpp"
-
-#define SP_ALIGN(sz, al) (((sz) + (al) - 1) & ~((al) - 1))
-
-// This is used for m_freeRecI when there is no record pool page.
-#define NNIL 0xffffffff
-
-// SuperPool
-
-SuperPool::SuperPool(Uint32 pageSize, Uint32 pageBits) :
- m_pageSize(pageSize),
- m_pageBits(pageBits),
- m_recBits(32 - m_pageBits),
- m_recMask((1 << m_recBits) - 1),
- m_memRoot(0),
- m_pageEnt(0),
- m_pageType(0),
- m_freeList(),
- m_initPages(0),
- m_incrPages(0),
- m_maxPages(0),
- m_totPages(0),
- m_typeCount(0),
- m_groupMinPct(0),
- m_groupMinPages(0),
- m_groupTotPages(0)
-{
- assert(m_pageSize != 0 && (m_pageSize & (m_pageSize - 1)) == 0);
- assert(m_pageBits <= 30);
-}
-
-SuperPool::~SuperPool()
-{
-}
-
-SuperPool::PageEnt::PageEnt() :
- m_pageType(0),
- m_useCount(0),
- m_freeRecI(NNIL),
- m_nextPageI(RNIL),
- m_prevPageI(RNIL)
-{
-}
-
-// page list routines
-
-SuperPool::PageList::PageList() :
- m_headPageI(RNIL),
- m_tailPageI(RNIL),
- m_pageCount(0)
-{
-}
-
-SuperPool::PageList::PageList(PtrI pageI) :
- m_headPageI(pageI),
- m_tailPageI(pageI),
- m_pageCount(1)
-{
- assert(pageI != RNIL);
-}
-
-void
-SuperPool::movePages(PageList& pl1, PageList& pl2)
-{
- PtrI pageI1 = pl1.m_tailPageI;
- PtrI pageI2 = pl2.m_headPageI;
- if (pl1.m_pageCount != 0) {
- assert(pageI1 != RNIL);
- if (pl2.m_pageCount != 0) {
- assert(pageI2 != RNIL);
- PageEnt& pe1 = getPageEnt(pageI1);
- PageEnt& pe2 = getPageEnt(pageI2);
- pe1.m_nextPageI = pageI2;
- pe2.m_prevPageI = pageI1;
- pl1.m_tailPageI = pl2.m_tailPageI;
- pl1.m_pageCount += pl2.m_pageCount;
- } else {
- assert(pageI2 == RNIL);
- }
- } else {
- assert(pageI1 == RNIL);
- pl1 = pl2;
- }
- pl2.m_headPageI = pl2.m_tailPageI = RNIL;
- pl2.m_pageCount = 0;
-}
-
-void
-SuperPool::addHeadPage(PageList& pl, PtrI pageI)
-{
- assert(pageI != RNIL);
- PageEnt& pe = getPageEnt(pageI);
- assert(pe.m_nextPageI == RNIL & pe.m_prevPageI == RNIL);
- PageList pl2(pageI);
- movePages(pl2, pl);
- pl = pl2;
-}
-
-void
-SuperPool::addTailPage(PageList& pl, PtrI pageI)
-{
- assert(pageI != RNIL);
- PageEnt& pe = getPageEnt(pageI);
- assert(pe.m_nextPageI == RNIL & pe.m_prevPageI == RNIL);
- PageList pl2(pageI);
- movePages(pl, pl2);
-}
-
-void
-SuperPool::removePage(PageList& pl, PtrI pageI)
-{
- assert(pageI != RNIL);
- PageEnt& pe = getPageEnt(pageI);
- if (pe.m_nextPageI != RNIL) {
- assert(pl.m_tailPageI != pageI);
- PageEnt& nextPe = getPageEnt(pe.m_nextPageI);
- nextPe.m_prevPageI = pe.m_prevPageI;
- } else {
- assert(pl.m_tailPageI == pageI);
- pl.m_tailPageI = pe.m_prevPageI;
- }
- if (pe.m_prevPageI != RNIL) {
- assert(pl.m_headPageI != pageI);
- PageEnt& prevPe = getPageEnt(pe.m_prevPageI);
- prevPe.m_nextPageI = pe.m_nextPageI;
- } else {
- assert(pl.m_headPageI == pageI);
- pl.m_headPageI = pe.m_nextPageI;
- }
- pe.m_nextPageI = RNIL;
- pe.m_prevPageI = RNIL;
- assert(pl.m_pageCount != 0);
- pl.m_pageCount--;
-}
-
-// reverse mapping
-
-SuperPool::PtrI
-SuperPool::getPageI(void* pageP)
-{
- Uint32 pageSize = m_pageSize;
- Uint32 pageBits = m_pageBits;
- Uint32 recBits = m_recBits;
- void* memRoot = m_memRoot;
- my_ptrdiff_t ipL = (Uint8*)pageP - (Uint8*)memRoot;
- assert(ipL % pageSize == 0);
- ipL /= (Int32)pageSize;
- Int32 ip = (Int32)ipL;
- Int32 lim = 1 << (pageBits - 1);
- if (! (ip == ipL && -lim <= ip && ip < lim && ip != -1)) {
- // page was too distant from memory root
- return RNIL;
- }
- PtrI pageI = ip << recBits;
- assert(pageP == getPageP(pageI));
- return pageI;
-}
-
-// record pool
-
-SuperPool::RecInfo::RecInfo(GroupPool& gp, Uint32 recSize) :
- m_groupPool(gp),
- m_recSize(recSize),
- m_recType(0),
- m_maxPerPage(0),
- m_freeRecI(NNIL),
- m_useCount(0),
- m_pageList(),
- m_hyX(1),
- m_hyY(2)
-{
- SuperPool& sp = gp.m_superPool;
- m_recType = (sp.m_typeCount++ << 1) | 1;
- assert(m_recSize == SP_ALIGN(m_recSize, sizeof(Uint32)));
- { // compute max records per page
- Uint32 n1 = sp.m_pageSize / m_recSize;
- Uint32 b2 = (sp.m_recBits < 16 ? sp.m_recBits : 16);
- Uint32 n2 = (1 << b2) - 1; // last is reserved
- m_maxPerPage = (n1 < n2 ? n1 : n2);
- assert(m_maxPerPage != 0);
- }
-}
-
-Uint32
-SuperPool::getFreeCount(RecInfo& ri, PtrI recI)
-{
- Uint32 n = 0;
- Uint32 recMask = m_recMask;
- Uint32 loopRecI = recI;
- while ((loopRecI & recMask) != recMask) {
- n++;
- void* loopRecP = getRecP(loopRecI, ri);
- loopRecI = *(Uint32*)loopRecP;
- }
- assert(n == (Uint16)n);
- return n;
-}
-
-Uint32
-SuperPool::getRecPageCount(RecInfo& ri)
-{
- Uint32 n = 0;
- for (Uint32 k = 0; k <= 2; k++)
- n += ri.m_pageList[k].m_pageCount;
- if (ri.m_freeRecI != NNIL)
- n += 1;
- return n;
-}
-
-Uint32
-SuperPool::getRecTotCount(RecInfo& ri)
-{
- return ri.m_maxPerPage * getRecPageCount(ri);
-}
-
-Uint32
-SuperPool::getRecUseCount(RecInfo& ri)
-{
- Uint32 n = ri.m_useCount;
- // current page does not keep count
- if (ri.m_freeRecI != NNIL) {
- Uint32 maxPerPage = ri.m_maxPerPage;
- Uint32 freeCount = getFreeCount(ri, ri.m_freeRecI);
- assert(maxPerPage >= freeCount);
- n += maxPerPage - freeCount;
- }
- return n;
-}
-
-// current page
-
-Uint32
-SuperPool::getRecPageList(RecInfo& ri, PageEnt& pe)
-{
- if (pe.m_useCount == 0)
- return 0;
- if (pe.m_useCount < ri.m_maxPerPage)
- return 1;
- if (pe.m_useCount == ri.m_maxPerPage)
- return 2;
- assert(false);
- return ~(Uint32)0;
-}
-
-void
-SuperPool::addCurrPage(RecInfo& ri, PtrI pageI)
-{
- PageEnt& pe = getPageEnt(pageI);
- ri.m_freeRecI = pe.m_freeRecI;
- // remove from right list
- Uint32 k = getRecPageList(ri, pe);
- assert(k != 2);
- removePage(ri.m_pageList[k], pageI);
- assert(ri.m_useCount >= pe.m_useCount);
- ri.m_useCount -= pe.m_useCount;
-}
-
-void
-SuperPool::removeCurrPage(RecInfo& ri)
-{
- Uint32 recMask = m_recMask;
- PtrI pageI = ri.m_freeRecI & ~ m_recMask;
- // update page entry
- PageEnt& pe = getPageEnt(pageI);
- pe.m_freeRecI = ri.m_freeRecI;
- Uint32 maxPerPage = ri.m_maxPerPage;
- Uint32 freeCount = getFreeCount(ri, pe.m_freeRecI);
- assert(maxPerPage >= freeCount);
- pe.m_useCount = maxPerPage - freeCount;
- // add to right list
- Uint32 k = getRecPageList(ri, pe);
- addHeadPage(ri.m_pageList[k], pageI);
- ri.m_useCount += pe.m_useCount;
- ri.m_freeRecI = NNIL;
- if (k == 0) {
- freeRecPages(ri);
- }
-}
-
-// page allocation
-
-bool
-SuperPool::getAvailPage(RecInfo& ri)
-{
- PtrI pageI;
- if ((pageI = ri.m_pageList[1].m_headPageI) != RNIL ||
- (pageI = ri.m_pageList[0].m_headPageI) != RNIL ||
- (pageI = getFreePage(ri)) != RNIL) {
- // the page is in record pool now
- if (ri.m_freeRecI != NNIL)
- removeCurrPage(ri);
- addCurrPage(ri, pageI);
- return true;
- }
- return false;
-}
-
-SuperPool::PtrI
-SuperPool::getFreePage(RecInfo& ri)
-{
- GroupPool& gp = ri.m_groupPool;
- PtrI pageI;
- if ((pageI = getFreePage(gp)) != RNIL) {
- initFreePage(ri, pageI);
- addHeadPage(ri.m_pageList[0], pageI);
- return pageI;
- }
- return RNIL;
-}
-
-SuperPool::PtrI
-SuperPool::getFreePage(GroupPool& gp)
-{
- PtrI pageI;
- if ((pageI = gp.m_freeList.m_headPageI) != RNIL) {
- removePage(gp.m_freeList, pageI);
- return pageI;
- }
- if (gp.m_totPages < getMaxPages(gp) &&
- (pageI = getFreePage()) != RNIL) {
- gp.m_totPages++;
- return pageI;
- }
- return RNIL;
-}
-
-SuperPool::PtrI
-SuperPool::getFreePage()
-{
- PtrI pageI;
- if ((pageI = m_freeList.m_headPageI) != RNIL) {
- removePage(m_freeList, pageI);
- return pageI;
- }
- if ((pageI = getNewPage()) != RNIL) {
- return pageI;
- }
- return RNIL;
-}
-
-void
-SuperPool::initFreePage(RecInfo& ri, PtrI pageI)
-{
- void* pageP = getPageP(pageI);
- // set up free record list
- Uint32 num = ri.m_maxPerPage;
- Uint32 recSize = ri.m_recSize;
- void* recP = (Uint8*)pageP;
- Uint32 irNext = 1;
- while (irNext < num) {
- *(Uint32*)recP = pageI | irNext;
- recP = (Uint8*)recP + recSize;
- irNext++;
- }
- // terminator has all recBits set
- *(Uint32*)recP = pageI | m_recMask;
- // set up new page entry
- PageEnt& pe = getPageEnt(pageI);
- new (&pe) PageEnt();
- pe.m_pageType = ri.m_recType;
- pe.m_freeRecI = pageI | 0;
- pe.m_useCount = 0;
- // set type check byte
- Uint32 ip = pageI >> m_recBits;
- m_pageType[ip] = (ri.m_recType & 0xFF);
-}
-
-// release
-
-void
-SuperPool::releaseNotCurrent(RecInfo& ri, PtrI recI)
-{
- PageEnt& pe = getPageEnt(recI);
- void* recP = getRecP(recI, ri);
- *(Uint32*)recP = pe.m_freeRecI;
- pe.m_freeRecI = recI;
- PtrI pageI = recI & ~ m_recMask;
- Uint32 maxPerPage = ri.m_maxPerPage;
- // move to right list
- Uint32 k1 = getRecPageList(ri, pe);
- assert(pe.m_useCount != 0);
- pe.m_useCount--;
- Uint32 k2 = getRecPageList(ri, pe);
- if (k1 != k2) {
- removePage(ri.m_pageList[k1], pageI);
- addHeadPage(ri.m_pageList[k2], pageI);
- if (k2 == 0) {
- freeRecPages(ri);
- }
- }
- assert(ri.m_useCount != 0);
- ri.m_useCount--;
-}
-
-void
-SuperPool::freeRecPages(RecInfo& ri)
-{
- // ignore current page
- Uint32 useCount = ri.m_useCount;
- Uint32 totCount = 0;
- for (uint32 k = 0; k <= 2; k++)
- totCount += ri.m_pageList[k].m_pageCount;
- totCount *= ri.m_maxPerPage;
- assert(totCount >= useCount);
- if ((totCount - useCount) * ri.m_hyY < useCount * ri.m_hyX)
- return;
- // free all free pages
- GroupPool& gp = ri.m_groupPool;
- Uint32 minPages = getMinPages(gp);
- PageList& pl = ri.m_pageList[0];
- while (pl.m_pageCount != 0) {
- PtrI pageI = pl.m_headPageI;
- removePage(pl, pageI);
- PageEnt& pe = getPageEnt(pageI);
- pe.m_pageType = 0;
- pe.m_freeRecI = NNIL;
- Uint32 ip = pageI >> m_recBits;
- m_pageType[ip] = 0;
- if (gp.m_totPages <= minPages) {
- addHeadPage(gp.m_freeList, pageI);
- } else {
- // return excess to super pool
- addHeadPage(m_freeList, pageI);
- assert(gp.m_totPages != 0);
- gp.m_totPages--;
- }
- }
-}
-
-void
-SuperPool::freeAllRecPages(RecInfo& ri, bool force)
-{
- GroupPool& gp = ri.m_groupPool;
- if (ri.m_freeRecI != NNIL)
- removeCurrPage(ri);
- assert(force || ri.m_useCount == 0);
- for (Uint32 k = 0; k <= 2; k++)
- movePages(gp.m_freeList, ri.m_pageList[k]);
-}
-
-// size parameters
-
-void
-SuperPool::setInitPages(Uint32 initPages)
-{
- m_initPages = initPages;
-}
-
-void
-SuperPool::setIncrPages(Uint32 incrPages)
-{
- m_incrPages = incrPages;
-}
-
-void
-SuperPool::setMaxPages(Uint32 maxPages)
-{
- m_maxPages = maxPages;
-}
-
-Uint32
-SuperPool::getGpMinPages()
-{
- Uint32 minPages = (m_groupMinPct * m_totPages) / 100;
- if (minPages < m_groupMinPages)
- minPages = m_groupMinPages;
- return minPages;
-}
-
-Uint32
-SuperPool::getMinPages(GroupPool& gp)
-{
- Uint32 minPages = (gp.m_minPct * m_totPages) / 100;
- if (minPages < gp.m_minPages)
- minPages = gp.m_minPages;
- return minPages;
-}
-
-Uint32
-SuperPool::getMaxPages(GroupPool& gp)
-{
- Uint32 n1 = getGpMinPages();
- Uint32 n2 = getMinPages(gp);
- assert(n1 >= n2);
- // pages reserved by other groups
- Uint32 n3 = n1 - n2;
- // rest can be claimed
- Uint32 n4 = (m_totPages >= n3 ? m_totPages - n3 : 0);
- return n4;
-}
-
-// debug
-
-void
-SuperPool::verify(RecInfo& ri)
-{
- GroupPool& gp = ri.m_groupPool;
- verifyPageList(m_freeList);
- verifyPageList(gp.m_freeList);
- for (Uint32 k = 0; k <= 2; k++) {
- PageList& pl = ri.m_pageList[k];
- verifyPageList(pl);
- PtrI pageI = pl.m_headPageI;
- while (pageI != RNIL) {
- PageEnt& pe = getPageEnt(pageI);
- assert(pe.m_pageType == ri.m_recType);
- Uint32 maxPerPage = ri.m_maxPerPage;
- Uint32 freeCount = getFreeCount(ri, pe.m_freeRecI);
- assert(maxPerPage >= freeCount);
- Uint32 useCount = maxPerPage - freeCount;
- assert(pe.m_useCount == useCount);
- assert(k != 0 || useCount == 0);
- assert(k != 1 || (useCount != 0 && freeCount != 0));
- assert(k != 2 || freeCount == 0);
- pageI = pe.m_nextPageI;
- }
- }
-}
-
-void
-SuperPool::verifyPageList(PageList& pl)
-{
- Uint32 count = 0;
- PtrI pageI = pl.m_headPageI;
- while (pageI != RNIL) {
- PageEnt& pe = getPageEnt(pageI);
- if (pe.m_prevPageI == RNIL) {
- assert(count == 0);
- } else {
- PageEnt& prevPe = getPageEnt(pe.m_prevPageI);
- assert(prevPe.m_nextPageI == pageI);
- }
- if (pe.m_nextPageI == RNIL) {
- assert(pl.m_tailPageI == pageI);
- } else {
- PageEnt& nextPe = getPageEnt(pe.m_nextPageI);
- assert(nextPe.m_prevPageI == pageI);
- }
- if (pe.m_pageType != 0) {
- assert(pe.m_freeRecI != NNIL);
- PageEnt& pe2 = getPageEnt(pe.m_freeRecI);
- assert(&pe == &pe2);
- } else {
- assert(pe.m_freeRecI == NNIL);
- }
- pageI = pe.m_nextPageI;
- count++;
- }
- assert(pl.m_pageCount == count);
-}
-
-// GroupPool
-
-GroupPool::GroupPool(SuperPool& sp) :
- m_superPool(sp),
- m_minPct(0),
- m_minPages(0),
- m_totPages(0),
- m_freeList()
-{
-}
-
-GroupPool::~GroupPool()
-{
-}
-
-void
-GroupPool::setMinPct(Uint32 minPct)
-{
- SuperPool& sp = m_superPool;
- // subtract any previous value
- assert(sp.m_groupMinPct >= m_minPct);
- sp.m_groupMinPct -= m_minPct;
- // add new value
- sp.m_groupMinPct += minPct;
- m_minPct = minPct;
-}
-
-void
-GroupPool::setMinPages(Uint32 minPages)
-{
- SuperPool& sp = m_superPool;
- // subtract any previous value
- assert(sp.m_groupMinPages >= m_minPages);
- sp.m_groupMinPages -= m_minPages;
- // add new value
- sp.m_groupMinPages += minPages;
- m_minPages = minPages;
-}
-
-// HeapPool
-
-HeapPool::HeapPool(Uint32 pageSize, Uint32 pageBits) :
- SuperPool(pageSize, pageBits),
- m_areaHead(),
- m_currArea(&m_areaHead),
- m_lastArea(&m_areaHead)
-{
-}
-
-HeapPool::~HeapPool()
-{
- free(m_pageEnt);
- free(m_pageType);
- Area* ap;
- while ((ap = m_areaHead.m_nextArea) != 0) {
- m_areaHead.m_nextArea = ap->m_nextArea;
- free(ap->m_memory);
- free(ap);
- }
-}
-
-HeapPool::Area::Area() :
- m_nextArea(0),
- m_firstPageI(RNIL),
- m_currPage(0),
- m_memory(0),
- m_pages(0),
- m_numPages(0)
-{
-}
-
-SuperPool::PtrI
-HeapPool::getNewPage()
-{
- Area* ap = m_currArea;
- if (ap->m_currPage == ap->m_numPages) {
- // area is used up
- if (ap->m_nextArea == 0) {
- if (! allocMemoryImpl())
- return RNIL;
- }
- ap = m_currArea = ap->m_nextArea;
- assert(ap != 0);
- }
- assert(ap->m_currPage < ap->m_numPages);
- PtrI pageI = ap->m_firstPageI;
- Uint32 recBits = m_recBits;
- Int32 ip = (Int32)pageI >> recBits;
- ip += ap->m_currPage;
- pageI = ip << recBits;
- ap->m_currPage++;
- return pageI;
-}
-
-bool
-HeapPool::allocInit()
-{
- Uint32 pageCount = (1 << m_pageBits);
- if (m_pageEnt == 0) {
- // allocate page entry array
- Uint32 bytes = pageCount * sizeof(PageEnt);
- m_pageEnt = static_cast<PageEnt*>(malloc(bytes));
- if (m_pageEnt == 0)
- return false;
- for (Uint32 i = 0; i < pageCount; i++)
- new (&m_pageEnt[i]) PageEnt();
- }
- if (m_pageType == 0) {
- // allocate type check array
- Uint32 bytes = pageCount;
- m_pageType = static_cast<Uint8*>(malloc(bytes));
- if (m_pageType == 0)
- return false;
- memset(m_pageType, 0, bytes);
- }
- return true;
-}
-
-bool
-HeapPool::allocArea(Area* ap, Uint32 tryPages)
-{
- Uint32 pageSize = m_pageSize;
- // one page is usually lost due to alignment
- Uint8* p1 = (Uint8*)malloc(pageSize * (tryPages + 1));
- if (p1 == 0)
- return false;
- // align
- UintPtr n1 = (UintPtr)p1;
- UintPtr n2 = SP_ALIGN(n1, (UintPtr)pageSize);
- Uint8* p2 = p1 + (n2 - n1);
- assert(p2 >= p1 && p2 - p1 < pageSize && (UintPtr)p2 % pageSize == 0);
- // set memory root to first allocated page
- if (m_memRoot == 0)
- m_memRoot = p2;
- // convert to i-value
- Uint32 pageI = getPageI(p2);
- ap->m_firstPageI = pageI;
- ap->m_currPage = 0;
- ap->m_memory = p1;
- ap->m_pages = p2;
- ap->m_numPages = tryPages + (p1 == p2);
- return true;
-}
-
-bool
-HeapPool::allocMemoryImpl()
-{
- if (! allocInit())
- return false;
- // compute number of additional pages needed
- if (m_maxPages <= m_totPages)
- return false;
- Uint32 needPages = (m_totPages == 0 ? m_initPages : m_incrPages);
- if (needPages > m_maxPages - m_totPages)
- needPages = m_maxPages - m_totPages;
- while (needPages != 0) {
- // add new area
- Area* ap = static_cast<Area*>(malloc(sizeof(Area)));
- if (ap == 0)
- return false;
- new (ap) Area();
- m_lastArea->m_nextArea = ap;
- m_lastArea = ap;
- // initial malloc is done in m_incrPages pieces
- Uint32 wantPages = needPages;
- if (m_incrPages != 0 && wantPages > m_incrPages)
- wantPages = m_incrPages;
- Uint32 tryPages = wantPages;
- while (tryPages != 0) {
- if (allocArea(ap, tryPages))
- break;
- tryPages /= 2;
- }
- if (tryPages == 0)
- return false;
- // update counts
- Uint32 numPages = ap->m_numPages;
- m_totPages += numPages;
- needPages = (needPages > numPages ? needPages - numPages : 0);
- }
- return true;
-}
diff --git a/storage/ndb/src/kernel/vm/SuperPool.hpp b/storage/ndb/src/kernel/vm/SuperPool.hpp
deleted file mode 100644
index 8fe4e681452..00000000000
--- a/storage/ndb/src/kernel/vm/SuperPool.hpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/* Copyright (c) 2003, 2005, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SUPER_POOL_HPP
-#define SUPER_POOL_HPP
-
-#include <ndb_global.h>
-
-#include <pc.hpp>
-#include <ErrorReporter.hpp>
-
-/*
- * SuperPool - super pool for record pools (abstract class)
- *
- * Documents: SuperPool GroupPool RecordPool<T>
- *
- * SUPER POOL
- *
- * A "super pool" is a shared pool of pages of fixed size. A "record
- * pool" is a pool of records of fixed size. One super pool instance is
- * used by a number of record pools to allocate their memory. A special
- * case is a "page pool" where a record is a simple page whose size
- * divides super pool page size.
- *
- * A record pool allocates memory in pages. Thus each used page is
- * associated with one record pool and one record type. The records on
- * a page form an array starting at start of page. Thus each record has
- * an index within the page. Any last partial record which does not fit
- * on the page is disregarded.
- *
- * I-VALUE
- *
- * The old "i-p" principle is kept. A reference to a super pool page or
- * record is stored as an "i-value" from which the record pointer "p" is
- * computed. In super pool the i-value is a Uint32 with two parts:
- *
- * - "ip" index of page within super pool (high "pageBits")
- * - "ir" index of record within page (low "recBits")
- *
- * At most 16 recBits are used, the rest are zero.
- *
- * The translation between "ip" and page address is described in next
- * section. Once page address is known, the record address is found
- * from "ir" in the obvious way.
- *
- * One advantage of i-value is that it can be verified. The level of
- * verification can depend on compile options.
- *
- * - "v1" check i-value specifies valid page
- * - "v2" check record type matches page type, see below
- * - "v3" check record is in use
- * - "v4" check unused record is unmodified
- *
- * Another advantage of a 32-bit i-value is that it extends the space of
- * 32-bit addressable records on a 64-bit platform.
- *
- * MEMORY ROOT
- *
- * This super pool requires a "memory root" i.e. a memory address such
- * that the index of a page "ip" satisfies
- *
- * page address = memory root + (signed)ip * page size
- *
- * This is possible on all platforms, provided that the memory root and
- * all pages are either on the heap or on the stack, in order to keep
- * the size of "ip" reasonably small.
- *
- * The cast (signed)ip is done as integer of pageBits bits. "ip" has
- * same sign bit as i-value "i" so (signed)ip = (Int32)i >> recBits.
- *
- * RESERVED I-VALUES
- *
- * RNIL is 0xffffff00 (signed -256). It is used everywhere in NDB as
- * "null pointer" i.e. as an i-value which does not point to a record.
- * In addition the signed values -255 to -1 are reserved for use by the
- * application.
- *
- * An i-value with all "ir" bits set is used as terminator in free
- * record list. Unlike RNIL, it still has valid page bits "ip".
- *
- * Following restrictions avoid hitting the reserved values:
- *
- * - pageBits is <= 30
- * - the maximum "ip" value 2^pageBits-1 (signed -1) is not used
- * - the maximum "ir" value 2^recBits-1 is not used
- *
- * PAGE ENTRIES
- *
- * Each super pool page has a "page entry". It contains:
- *
- * - page type
- * - i-value of first free record on page
- * - page use count, to see if page can be freed
- * - pointers (as i-values) to next and previous page in list
- *
- * Page entry cannot be stored on the page itself since this prevents
- * aligning pages to OS block size and the use of BATs for page pools in
- * NDB. For now the implementation provides an array of page entries
- * with place for all potential (2^pageBits) entries.
- *
- * PAGE TYPE
- *
- * Page type is unique to the record pool using the super pool. It is
- * assigned in record pool constructor. Page type zero means that the
- * page is free i.e. not allocated to a record pool.
- *
- * Each "i-p" conversion checks ("v2") that the record belongs to same
- * pool as the page. This check is much more common than page or record
- * allocation. To make it cache effective, there is a separate page
- * type array. It truncates type to one non-zero byte.
- *
- * GROUP POOL
- *
- * Each record pool belongs to a group. The group specifies minimum
- * size or memory percentage the group must be able to allocate. The
- * sum of the minimum sizes of group pools is normally smaller than
- * super pool size. This provides unclaimed memory which a group can
- * use temporarily to allocate more than its minimum.
- *
- * The record pools within a group compete freely for the available
- * memory within the group.
- *
- * Typical exmaple is group of all metadata pools. The group allows
- * specifying the memory to reserve for metadata, without having to
- * specify number of tables, attributes, indexes, triggers, etc.
- *
- * PAGE LISTS
- *
- * Super pool has free page list. Each group pool uses it to allocate
- * its own free page list. And each record pool within the group uses
- * the group's free list to allocate its pages.
- *
- * A page allocated to a record pool has a use count i.e. number of used
- * records. When use count drops to zero the page can be returned to
- * the group. This is not necessarily done at once.
- *
- * The list of free records in a record pool has two levels. There are
- * available pages (some free) and a singly linked free list within the
- * page. A page allocated to record pool is on one of 4 lists:
- *
- * - free page (all free, available, could be returned to group)
- * - busy page (some free, some used, available)
- * - full page (none free)
- * - current page (list of one), see below
- *
- * Some usage types (temporary pools) may never free records. They pay
- * a small penalty for the extra overhead.
- *
- * RECORD POOL
- *
- * A pool of records which allocates its memory from a super pool
- * instance via a group pool. There are 3 basic operations:
- *
- * - getPtr - translate i-value to pointer-to-record p
- * - seize - allocate record
- * - release - free record
- *
- * CURRENT PAGE
- *
- * getPtr is a fast computation which does not touch the page entry.
- * For seize (and release) there is a small optimization.
- *
- * The "current page" is the page of latest seize. It is unlinked from
- * its normal list and the free record pointer is stored under record
- * pool instance.
- *
- * The page remains current until there is a seize and the page is full.
- * Then the real page entry and its list membership are updated, and
- * a new page is made current.
- *
- * This implies that each (active) record pool allocates at least one
- * page which is never returned to the group.
- *
- * PAGE POLICY
- *
- * A group pool returns its "excess" (above minimum) free pages to the
- * super pool immediately.
- *
- * Allocating a new page to a record pool is expensive due to free list
- * setup. Therefore a record pool should not always return empty pages
- * to the group. Policies:
- *
- * - "pp1" never return empty page to the group
- * - "pp2" always return empty (non-current) page to the group
- * - "pp3" simple hysteresis
- *
- * Last one "pp3" is used. It works as follows:
- *
- * When a page becomes free, check if number of free records exceeds
- * some fixed fraction of all records. If it does, move all free pages
- * to the group. Current page is ignored in the check.
- *
- * TODO
- *
- * Define abstract class SuperAlloc. Make SuperPool a concrete class
- * with SuperAlloc instance in ctor. Replace HeapPool by HeapAlloc.
- */
-
-// Types forward.
-class GroupPool;
-
-class SuperPool {
-public:
- // Type of i-value, used to reference both pages and records.
- typedef Uint32 PtrI;
-
- // Page entry.
- struct PageEnt {
- PageEnt();
- Uint16 m_pageType; // zero if not in record pool
- Uint16 m_useCount; // used records on the page
- PtrI m_freeRecI; // first free record on the page
- PtrI m_nextPageI;
- PtrI m_prevPageI;
- };
-
- // Doubly-linked list of page entries.
- struct PageList {
- PageList();
- PageList(PtrI pageI);
- PtrI m_headPageI;
- PtrI m_tailPageI;
- Uint32 m_pageCount;
- };
-
- // Constructor. Gives page size in bytes (must be power of 2) and
- // number of bits to use for page index "ip" in i-value.
- SuperPool(Uint32 pageSize, Uint32 pageBits);
-
- // Destructor.
- virtual ~SuperPool() = 0;
-
- // Move all pages from second list to end of first list.
- void movePages(PageList& pl1, PageList& pl2);
-
- // Add page to beginning of page list.
- void addHeadPage(PageList& pl, PtrI pageI);
-
- // Add page to end of page list.
- void addTailPage(PageList& pl, PtrI pageI);
-
- // Remove any page from page list.
- void removePage(PageList& pl, PtrI pageI);
-
- // Translate i-value ("ri" ignored) to page entry.
- PageEnt& getPageEnt(PtrI pageI);
-
- // Translate i-value ("ri" ignored) to page address.
- void* getPageP(PtrI pageI);
-
- // Translate page address to i-value. Address must be page-aligned to
- // memory root. Returns RNIL if "ip" range exceeded.
- PtrI getPageI(void* pageP);
-
- // Record pool info.
- struct RecInfo {
- RecInfo(GroupPool& gp, Uint32 recSize);
- GroupPool& m_groupPool;
- Uint32 m_recSize;
- Uint16 m_recType;
- Uint16 m_maxPerPage;
- PtrI m_freeRecI; // first free record on current page
- Uint32 m_useCount; // used records excluding current page
- PageList m_pageList[3]; // 0-free 1-busy 2-full
- Uint16 m_hyX; // hysteresis fraction x/y in "pp3"
- Uint16 m_hyY;
- };
-
- // Translate i-value to record address.
- void* getRecP(PtrI recI, RecInfo& ri);
-
- // Count records on page free list.
- Uint32 getFreeCount(RecInfo& ri, PtrI freeRecPtrI);
-
- // Compute total number of pages in pool.
- Uint32 getRecPageCount(RecInfo& ri);
-
- // Compute total number of records (used or not) in pool.
- Uint32 getRecTotCount(RecInfo& ri);
-
- // Compute total number of used records in pool.
- Uint32 getRecUseCount(RecInfo& ri);
-
- // Compute record pool page list index (0,1,2).
- Uint32 getRecPageList(RecInfo& ri, PageEnt& pe);
-
- // Add current page.
- void addCurrPage(RecInfo& ri, PtrI pageI);
-
- // Remove current page.
- void removeCurrPage(RecInfo& ri);
-
- // Get page with some free records and make it current. Takes head of
- // used or free list, or else gets free page from group pool.
- bool getAvailPage(RecInfo& ri);
-
- // Get free page from group pool and add it to record pool free list.
- // This is an expensive subroutine of getAvailPage(RecInfo&):
- PtrI getFreePage(RecInfo& ri);
-
- // Get free detached (not on list) page from group pool.
- PtrI getFreePage(GroupPool& gp);
-
- // Get free detached page from super pool.
- PtrI getFreePage();
-
- // Get new free detached page from the implementation.
- virtual PtrI getNewPage() = 0;
-
- // Initialize free list etc. Subroutine of getFreePage(RecInfo&).
- void initFreePage(RecInfo& ri, PtrI pageI);
-
- // Release record which is not on current page.
- void releaseNotCurrent(RecInfo& ri, PtrI recI);
-
- // Free pages from record pool according to page policy.
- void freeRecPages(RecInfo& ri);
-
- // Free all pages in record pool.
- void freeAllRecPages(RecInfo& ri, bool force);
-
- // Set pool size parameters in pages. Call allocMemory() for changes
- // (such as extra mallocs) to take effect.
- void setInitPages(Uint32 initPages);
- void setIncrPages(Uint32 incrPages);
- void setMaxPages(Uint32 maxPages);
-
- // Get number of pages reserved by all groups.
- Uint32 getGpMinPages();
-
- // Get number of pages reserved to a group.
- Uint32 getMinPages(GroupPool& gp);
-
- // Get max number of pages a group can try to allocate.
- Uint32 getMaxPages(GroupPool& gp);
-
- // Allocate more memory according to current parameters. Returns
- // false if no new memory was allocated. Otherwise returns true,
- // even if the amount allocated was less than requested.
- virtual bool allocMemory() = 0;
-
- // Debugging.
- void verify(RecInfo& ri);
- void verifyPageList(PageList& pl);
-
- // Super pool parameters.
- const Uint32 m_pageSize;
- const Uint16 m_pageBits;
- const Uint16 m_recBits;
- const Uint32 m_recMask;
- // Implementation must set up these 3 pointers.
- void* m_memRoot;
- PageEnt* m_pageEnt;
- Uint8* m_pageType;
- // Free page list.
- PageList m_freeList;
- // Free pages and sizes.
- Uint32 m_initPages;
- Uint32 m_incrPages;
- Uint32 m_maxPages;
- Uint32 m_totPages;
- Uint32 m_typeCount;
- // Reserved and allocated by group pools.
- Uint32 m_groupMinPct;
- Uint32 m_groupMinPages;
- Uint32 m_groupTotPages;
-};
-
-inline SuperPool::PageEnt&
-SuperPool::getPageEnt(PtrI pageI)
-{
- Uint32 ip = pageI >> m_recBits;
- return m_pageEnt[ip];
-}
-
-inline void*
-SuperPool::getPageP(PtrI ptrI)
-{
- Int32 ip = (Int32)ptrI >> m_recBits;
- return (Uint8*)m_memRoot + ip * (my_ptrdiff_t)m_pageSize;
-}
-
-inline void*
-SuperPool::getRecP(PtrI ptrI, RecInfo& ri)
-{
- Uint32 ip = ptrI >> m_recBits;
- assert(m_pageType[ip] == (ri.m_recType & 0xFF));
- Uint32 ir = ptrI & m_recMask;
- return (Uint8*)getPageP(ptrI) + ir * ri.m_recSize;
-}
-
-/*
- * GroupPool - subset of a super pool pages (concrete class)
- */
-
-class GroupPool {
-public:
- // Types.
- typedef SuperPool::PageList PageList;
-
- // Constructor.
- GroupPool(SuperPool& sp);
-
- // Destructor.
- ~GroupPool();
-
- // Set minimum pct reserved in super pool.
- void setMinPct(Uint32 resPct);
-
- // Set minimum pages reserved in super pool.
- void setMinPages(Uint32 resPages);
-
- SuperPool& m_superPool;
- Uint32 m_minPct;
- Uint32 m_minPages;
- Uint32 m_totPages;
- PageList m_freeList;
-};
-
-/*
- * RecordPool - record pool using one super pool instance (template)
- */
-
-template <class T>
-class RecordPool {
-public:
- // Constructor.
- RecordPool(GroupPool& gp);
-
- // Destructor.
- ~RecordPool();
-
- // Update pointer ptr.p according to i-value ptr.i.
- void getPtr(Ptr<T>& ptr);
-
- // Allocate record from the pool.
- bool seize(Ptr<T>& ptr);
-
- // Return record to the pool.
- void release(Ptr<T>& ptr);
-
- // todo variants of basic methods
-
- // Return all pages to group pool. The force flag is required if
- // there are any used records.
- void freeAllRecPages(bool force);
-
- SuperPool& m_superPool;
- SuperPool::RecInfo m_recInfo;
-};
-
-template <class T>
-inline
-RecordPool<T>::RecordPool(GroupPool& gp) :
- m_superPool(gp.m_superPool),
- m_recInfo(gp, sizeof(T))
-{
-}
-
-template <class T>
-inline
-RecordPool<T>::~RecordPool()
-{
- freeAllRecPages(true);
-}
-
-template <class T>
-inline void
-RecordPool<T>::getPtr(Ptr<T>& ptr)
-{
- void* recP = m_superPool.getRecP(ptr.i, m_recInfo);
- ptr.p = static_cast<T*>(recP);
-}
-
-template <class T>
-inline bool
-RecordPool<T>::seize(Ptr<T>& ptr)
-{
- SuperPool& sp = m_superPool;
- SuperPool::RecInfo& ri = m_recInfo;
- Uint32 recMask = sp.m_recMask;
- // get current page
- if ((ri.m_freeRecI & recMask) != recMask ||
- sp.getAvailPage(ri)) {
- SuperPool::PtrI recI = ri.m_freeRecI;
- void* recP = sp.getRecP(recI, ri);
- ri.m_freeRecI = *(Uint32*)recP;
- ptr.i = recI;
- ptr.p = static_cast<T*>(recP);
- return true;
- }
- ptr.i = RNIL;
- ptr.p = 0;
- return false;
-}
-
-template <class T>
-inline void
-RecordPool<T>::release(Ptr<T>& ptr)
-{
- SuperPool& sp = m_superPool;
- SuperPool::RecInfo& ri = m_recInfo;
- SuperPool::PtrI recI = ptr.i;
- Uint32 recMask = sp.m_recMask;
- // check if current page
- if ((recI & ~recMask) == (ri.m_freeRecI & ~recMask)) {
- void* recP = sp.getRecP(recI, ri);
- *(Uint32*)recP = ri.m_freeRecI;
- ri.m_freeRecI = recI;
- } else {
- sp.releaseNotCurrent(ri, recI);
- }
- ptr.i = RNIL;
- ptr.p = 0;
-}
-
-template <class T>
-inline void
-RecordPool<T>::freeAllRecPages(bool force)
-{
- SuperPool& sp = m_superPool;
- sp.freeAllRecPages(m_recInfo, force);
-}
-
-/*
- * HeapPool - SuperPool on heap (concrete class)
- *
- * A super pool based on malloc with memory root on the heap. This
- * pool type has 2 realistic uses:
- *
- * - a small pool with only initial malloc and pageBits set to match
- * - the big pool from which all heap allocations are done
- *
- * A smart malloc may break "ip" limit by using different VM areas for
- * different sized requests. For this reason malloc is done in units of
- * increment size if possible. Memory root is set to the page-aligned
- * address from first page malloc.
- */
-
-class HeapPool : public SuperPool {
-public:
- // Describes malloc area. The areas are kept in singly linked list.
- // There is a list head and pointers to current and last area.
- struct Area {
- Area();
- Area* m_nextArea;
- PtrI m_firstPageI;
- Uint32 m_currPage;
- void* m_memory; // from malloc
- void* m_pages; // page-aligned pages
- Uint32 m_numPages; // number of pages
- };
-
- // Constructor.
- HeapPool(Uint32 pageSize, Uint32 pageBits);
-
- // Destructor.
- virtual ~HeapPool();
-
- // Get new page from current area.
- virtual PtrI getNewPage();
-
- // Allocate fixed arrays.
- bool allocInit();
-
- // Allocate array of aligned pages.
- bool allocArea(Area* ap, Uint32 tryPages);
-
- // Allocate memory.
- virtual bool allocMemory() { return allocMemoryImpl();}
- bool allocMemoryImpl();
-
- // List of malloc areas.
- Area m_areaHead;
- Area* m_currArea;
- Area* m_lastArea;
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/ThreadConfig.cpp b/storage/ndb/src/kernel/vm/ThreadConfig.cpp
deleted file mode 100644
index e7cfa0e6492..00000000000
--- a/storage/ndb/src/kernel/vm/ThreadConfig.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "ThreadConfig.hpp"
-#include "Emulator.hpp"
-#include "GlobalData.hpp"
-#include "TimeQueue.hpp"
-#include "TransporterRegistry.hpp"
-#include "FastScheduler.hpp"
-#include "pc.hpp"
-
-#include <GlobalSignalNumbers.h>
-#include <BlockNumbers.h>
-
-#include <NdbSleep.h>
-#include <NdbTick.h>
-#include <NdbOut.hpp>
-
-#include <signaldata/StartOrd.hpp>
-
-ThreadConfig::ThreadConfig()
-{
-}
-
-ThreadConfig::~ThreadConfig()
-{
-}
-
-/**
- * For each millisecond that has passed since this function was last called:
- * Scan the job buffer and increment the internalMillisecCounter
- * with 1 to keep track of where we are
- */
-inline
-void
-ThreadConfig::scanTimeQueue()
-{
- unsigned int maxCounter;
- Uint64 currMilliSecond;
- maxCounter = 0;
- currMilliSecond = NdbTick_CurrentMillisecond();
- if (currMilliSecond < globalData.internalMillisecCounter) {
-//--------------------------------------------------------------------
-// This could occur around 2036 or if the operator decides to change
-// time backwards. We cannot know how long time has past since last
-// time and we make a best try with 0 milliseconds.
-//--------------------------------------------------------------------
-#ifdef VM_TRACE
- ndbout << "Time moved backwards with ";
- ndbout << (globalData.internalMillisecCounter - currMilliSecond);
- ndbout << " milliseconds" << endl;
-#endif
- globalData.internalMillisecCounter = currMilliSecond;
- }//if
- if (currMilliSecond > (globalData.internalMillisecCounter + 1500)) {
-//--------------------------------------------------------------------
-// Time has moved forward more than a second. Either it could happen
-// if operator changed the time or if the OS has misbehaved badly.
-// We set the new time to one second from the past.
-//--------------------------------------------------------------------
-#ifdef VM_TRACE
- ndbout << "Time moved forward with ";
- ndbout << (currMilliSecond - globalData.internalMillisecCounter);
- ndbout << " milliseconds" << endl;
-#endif
- globalData.internalMillisecCounter = currMilliSecond - 1000;
- }//if
- while (((currMilliSecond - globalData.internalMillisecCounter) > 0) &&
- (maxCounter < 20)){
- globalData.internalMillisecCounter++;
- maxCounter++;
- globalTimeQueue.scanTable();
- }//while
-}//ThreadConfig::scanTimeQueue()
-
-
-//--------------------------------------------------------------------
-// ipControlLoop -- The main loop of ndb.
-// Handles the scheduling of signal execution and input/output
-// One lap in the loop should take approximately 10 milli seconds
-// If the jobbuffer is empty and the laptime is less than 10 milliseconds
-// at the end of the loop
-// the TransporterRegistry is called in order to sleep on the IO ports
-// waiting for another incoming signal to wake us up.
-// The timeout value in this call is calculated as (10 ms - laptime)
-// This would make ndb use less cpu while improving response time.
-//--------------------------------------------------------------------
-void ThreadConfig::ipControlLoop()
-{
-
-//--------------------------------------------------------------------
-// initialise the counter that keeps track of the current millisecond
-//--------------------------------------------------------------------
- globalData.internalMillisecCounter = NdbTick_CurrentMillisecond();
- Uint32 i = 0;
- while (globalData.theRestartFlag != perform_stop) {
-
- Uint32 timeOutMillis = 0;
- if (LEVEL_IDLE == globalData.highestAvailablePrio) {
-//--------------------------------------------------------------------
-// The buffers are empty, we need to wait for a while until we continue.
-// We cannot wait forever since we can also have timed events.
-//--------------------------------------------------------------------
-//--------------------------------------------------------------------
-// Set the time we will sleep on the sockets before waking up
-// unconditionally to 10 ms. Will never sleep more than 10 milliseconds
-// on a socket.
-//--------------------------------------------------------------------
- timeOutMillis = 10;
- }//if
-//--------------------------------------------------------------------
-// Now it is time to check all interfaces. We will send all buffers
-// plus checking for any received messages.
-//--------------------------------------------------------------------
- if (i++ >= 20) {
- globalTransporterRegistry.update_connections();
- globalData.incrementWatchDogCounter(5);
- i = 0;
- }//if
-
- globalData.incrementWatchDogCounter(6);
- globalTransporterRegistry.performSend();
-
- globalData.incrementWatchDogCounter(7);
- if (globalTransporterRegistry.pollReceive(timeOutMillis)) {
- globalData.incrementWatchDogCounter(8);
- globalTransporterRegistry.performReceive();
- }
-
-//--------------------------------------------------------------------
-// We scan the time queue to see if there are any timed signals that
-// is now ready to be executed.
-//--------------------------------------------------------------------
- globalData.incrementWatchDogCounter(2);
- scanTimeQueue();
-
-//--------------------------------------------------------------------
-// This is where the actual execution of signals occur. We execute
-// until all buffers are empty or until we have executed 2048 signals.
-//--------------------------------------------------------------------
- globalScheduler.doJob();
- }//while
-
- globalData.incrementWatchDogCounter(6);
- globalTransporterRegistry.performSend();
-
-}//ThreadConfig::ipControlLoop()
-
-int
-ThreadConfig::doStart(NodeState::StartLevel startLevel){
-
- SignalHeader sh;
- memset(&sh, 0, sizeof(SignalHeader));
-
- sh.theVerId_signalNumber = GSN_START_ORD;
- sh.theReceiversBlockNumber = CMVMI;
- sh.theSendersBlockRef = 0;
- sh.theTrace = 0;
- sh.theSignalId = 0;
- sh.theLength = StartOrd::SignalLength;
-
- Uint32 theData[25];
- StartOrd * const startOrd = (StartOrd *)&theData[0];
- startOrd->restartInfo = 0;
-
- Uint32 secPtrI[3];
- globalScheduler.execute(&sh, JBA, theData, secPtrI);
- return 0;
-}
-
diff --git a/storage/ndb/src/kernel/vm/ThreadConfig.hpp b/storage/ndb/src/kernel/vm/ThreadConfig.hpp
deleted file mode 100644
index a05cc9c8532..00000000000
--- a/storage/ndb/src/kernel/vm/ThreadConfig.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ThreadConfig_H
-#define ThreadConfig_H
-
-#include <kernel_types.h>
-#include <ErrorReporter.hpp>
-#include <NodeState.hpp>
-
-class IPCConfig;
-
-class ThreadConfig
-{
-public:
- ThreadConfig();
- ~ThreadConfig();
-
- void ipControlLoop();
-
- int doStart(NodeState::StartLevel startLevel);
-private:
-
- void scanTimeQueue();
-};
-#endif // ThreadConfig_H
diff --git a/storage/ndb/src/kernel/vm/TimeQueue.cpp b/storage/ndb/src/kernel/vm/TimeQueue.cpp
deleted file mode 100644
index ad4e4cd1b8a..00000000000
--- a/storage/ndb/src/kernel/vm/TimeQueue.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "TimeQueue.hpp"
-#include <ErrorHandlingMacros.hpp>
-#include <GlobalData.hpp>
-#include <FastScheduler.hpp>
-#include <VMSignal.hpp>
-
-static const int MAX_TIME_QUEUE_VALUE = 32000;
-
-TimeQueue::TimeQueue()
-{
- clear();
-}
-
-TimeQueue::~TimeQueue()
-{
-}
-
-void
-TimeQueue::clear()
-{
- globalData.theNextTimerJob = 65535;
- globalData.theCurrentTimer = 0;
- globalData.theShortTQIndex = 0;
- globalData.theLongTQIndex = 0;
- for (int i = 0; i < MAX_NO_OF_TQ; i++)
- theFreeIndex[i] = i+1;
- theFreeIndex[MAX_NO_OF_TQ - 1] = NULL_TQ_ENTRY;
- globalData.theFirstFreeTQIndex = 0;
-}
-
-void
-TimeQueue::insert(Signal* signal, BlockNumber bnr,
- GlobalSignalNumber gsn, Uint32 delayTime)
-{
- if (delayTime == 0)
- delayTime = 1;
- register Uint32 regCurrentTime = globalData.theCurrentTimer;
- register Uint32 i;
- register Uint32 regSave;
- register TimerEntry newEntry;
-
- newEntry.time_struct.delay_time = regCurrentTime + delayTime;
- newEntry.time_struct.job_index = getIndex();
- regSave = newEntry.copy_struct;
-
- globalScheduler.insertTimeQueue(signal, bnr, gsn,
- newEntry.time_struct.job_index);
-
- if (newEntry.time_struct.delay_time < globalData.theNextTimerJob)
- globalData.theNextTimerJob = newEntry.time_struct.delay_time;
- if (delayTime < 100){
- register Uint32 regShortIndex = globalData.theShortTQIndex;
- if (regShortIndex == 0){
- theShortQueue[0].copy_struct = newEntry.copy_struct;
- } else if (regShortIndex >= MAX_NO_OF_SHORT_TQ - 1) {
- ERROR_SET(ecError, NDBD_EXIT_TIME_QUEUE_SHORT,
- "Too many in Short Time Queue", "TimeQueue.C" );
- } else {
- for (i = 0; i < regShortIndex; i++) {
- if (theShortQueue[i].time_struct.delay_time >
- newEntry.time_struct.delay_time) {
-
- regSave = theShortQueue[i].copy_struct;
- theShortQueue[i].copy_struct = newEntry.copy_struct;
- break;
- }
- }
- if (i == regShortIndex) {
- theShortQueue[regShortIndex].copy_struct = regSave;
- } else {
- for (i++; i < regShortIndex; i++) {
- register Uint32 regTmp = theShortQueue[i].copy_struct;
- theShortQueue[i].copy_struct = regSave;
- regSave = regTmp;
- }
- theShortQueue[regShortIndex].copy_struct = regSave;
- }
- }
- globalData.theShortTQIndex = regShortIndex + 1;
- } else if (delayTime <= (unsigned)MAX_TIME_QUEUE_VALUE) {
- register Uint32 regLongIndex = globalData.theLongTQIndex;
- if (regLongIndex == 0) {
- theLongQueue[0].copy_struct = newEntry.copy_struct;
- } else if (regLongIndex >= MAX_NO_OF_LONG_TQ - 1) {
- ERROR_SET(ecError, NDBD_EXIT_TIME_QUEUE_LONG,
- "Too many in Long Time Queue", "TimeQueue.C" );
- } else {
- for (i = 0; i < regLongIndex; i++) {
- if (theLongQueue[i].time_struct.delay_time >
- newEntry.time_struct.delay_time) {
-
- regSave = theLongQueue[i].copy_struct;
- theLongQueue[i].copy_struct = newEntry.copy_struct;
- break;
- }
- }
- if (i == regLongIndex) {
- theLongQueue[regLongIndex].copy_struct = regSave;
- } else {
- for (i++; i < regLongIndex; i++) {
- register Uint32 regTmp = theLongQueue[i].copy_struct;
- theLongQueue[i].copy_struct = regSave;
- regSave = regTmp;
- }
- theLongQueue[regLongIndex].copy_struct = regSave;
- }
- }
- globalData.theLongTQIndex = regLongIndex + 1;
- } else {
- ERROR_SET(ecError, NDBD_EXIT_TIME_QUEUE_DELAY,
- "Too long delay for Time Queue", "TimeQueue.C" );
- }
-}
-
-// executes the expired signals;
-void
-TimeQueue::scanTable()
-{
- register Uint32 i, j;
-
- globalData.theCurrentTimer++;
- if (globalData.theCurrentTimer == 32000)
- recount_timers();
- if (globalData.theNextTimerJob > globalData.theCurrentTimer)
- return;
- globalData.theNextTimerJob = 65535; // If no more timer jobs
- for (i = 0; i < globalData.theShortTQIndex; i++) {
- if (theShortQueue[i].time_struct.delay_time > globalData.theCurrentTimer){
- break;
- } else {
- releaseIndex((Uint32)theShortQueue[i].time_struct.job_index);
- globalScheduler.scheduleTimeQueue(theShortQueue[i].time_struct.job_index);
- }
- }
- if (i > 0) {
- for (j = i; j < globalData.theShortTQIndex; j++)
- theShortQueue[j - i].copy_struct = theShortQueue[j].copy_struct;
- globalData.theShortTQIndex -= i;
- }
- if (globalData.theShortTQIndex != 0) // If not empty
- globalData.theNextTimerJob = theShortQueue[0].time_struct.delay_time;
- for (i = 0; i < globalData.theLongTQIndex; i++) {
- if (theLongQueue[i].time_struct.delay_time > globalData.theCurrentTimer) {
- break;
- } else {
- releaseIndex((Uint32)theLongQueue[i].time_struct.job_index);
- globalScheduler.scheduleTimeQueue(theLongQueue[i].time_struct.job_index);
- }
- }
- if (i > 0) {
- for (j = i; j < globalData.theLongTQIndex; j++)
- theLongQueue[j - i].copy_struct = theLongQueue[j].copy_struct;
- globalData.theLongTQIndex -= i;
- }
- if (globalData.theLongTQIndex != 0) // If not empty
- if (globalData.theNextTimerJob > theLongQueue[0].time_struct.delay_time)
- globalData.theNextTimerJob = theLongQueue[0].time_struct.delay_time;
-}
-
-void
-TimeQueue::recount_timers()
-{
- Uint32 i;
-
- globalData.theCurrentTimer = 0;
- globalData.theNextTimerJob -= 32000;
-
- for (i = 0; i < globalData.theShortTQIndex; i++)
- theShortQueue[i].time_struct.delay_time -= 32000;
- for (i = 0; i < globalData.theLongTQIndex; i++)
- theLongQueue[i].time_struct.delay_time -= 32000;
-}
-
-Uint32
-TimeQueue::getIndex()
-{
- Uint32 retValue = globalData.theFirstFreeTQIndex;
- globalData.theFirstFreeTQIndex = (Uint32)theFreeIndex[retValue];
- if (retValue >= MAX_NO_OF_TQ)
- ERROR_SET(fatal, NDBD_EXIT_TIME_QUEUE_INDEX,
- "Index out of range", "TimeQueue.C" );
- return retValue;
-}
-
-void
-TimeQueue::releaseIndex(Uint32 aIndex)
-{
- theFreeIndex[aIndex] = globalData.theFirstFreeTQIndex;
- globalData.theFirstFreeTQIndex = aIndex;
-}
-
-
diff --git a/storage/ndb/src/kernel/vm/TimeQueue.hpp b/storage/ndb/src/kernel/vm/TimeQueue.hpp
deleted file mode 100644
index 4c1a32ac3e6..00000000000
--- a/storage/ndb/src/kernel/vm/TimeQueue.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TimeQueue_H
-#define TimeQueue_H
-
-#include <kernel_types.h>
-#include "Prio.hpp"
-
-#define MAX_NO_OF_SHORT_TQ 512
-#define MAX_NO_OF_LONG_TQ 512
-#define MAX_NO_OF_TQ (MAX_NO_OF_SHORT_TQ + MAX_NO_OF_LONG_TQ)
-#define NULL_TQ_ENTRY 65535
-
-class Signal;
-
-struct TimeStruct
-{
- Uint16 delay_time;
- Uint16 job_index;
-};
-
-union TimerEntry
-{
- struct TimeStruct time_struct;
- Uint32 copy_struct;
-};
-
-class TimeQueue
-{
-public:
- TimeQueue();
- ~TimeQueue();
-
- void insert(Signal* signal, BlockNumber bnr,
- GlobalSignalNumber gsn, Uint32 delayTime);
- void clear();
- void scanTable(); // Called once per millisecond
- Uint32 getIndex();
- void releaseIndex(Uint32 aIndex);
- void recount_timers();
-
-private:
- TimerEntry theShortQueue[MAX_NO_OF_SHORT_TQ];
- TimerEntry theLongQueue[MAX_NO_OF_LONG_TQ];
- Uint16 theFreeIndex[MAX_NO_OF_TQ];
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/TransporterCallback.cpp b/storage/ndb/src/kernel/vm/TransporterCallback.cpp
deleted file mode 100644
index 979a8075bdd..00000000000
--- a/storage/ndb/src/kernel/vm/TransporterCallback.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <TransporterCallback.hpp>
-#include <TransporterRegistry.hpp>
-#include <FastScheduler.hpp>
-#include <Emulator.hpp>
-#include <ErrorHandlingMacros.hpp>
-
-#include "LongSignal.hpp"
-
-#include <signaldata/EventReport.hpp>
-#include <signaldata/TestOrd.hpp>
-#include <signaldata/SignalDroppedRep.hpp>
-#include <signaldata/DisconnectRep.hpp>
-
-#include "VMSignal.hpp"
-#include <NdbOut.hpp>
-#include "DataBuffer.hpp"
-
-
-/**
- * The instance
- */
-SectionSegmentPool g_sectionSegmentPool;
-
-struct ConnectionError
-{
- enum TransporterError err;
- const char *text;
-};
-
-static const ConnectionError connectionError[] =
-{
- { TE_NO_ERROR, "No error"},
- { TE_SHM_UNABLE_TO_CREATE_SEGMENT, "Unable to create shared memory segment"},
- { (enum TransporterError) -1, "No connection error message available (please report a bug)"}
-};
-
-const char *lookupConnectionError(Uint32 err)
-{
- int i= 0;
- while ((Uint32)connectionError[i].err != err &&
- connectionError[i].err != -1)
- i++;
- return connectionError[i].text;
-}
-
-bool
-import(Ptr<SectionSegment> & first, const Uint32 * src, Uint32 len){
- /**
- * Dummy data used when setting prev.m_nextSegment for first segment of a
- * section
- */
- Uint32 dummyPrev[4];
-
- first.p = 0;
- if(g_sectionSegmentPool.seize(first)){
- ;
- } else {
- return false;
- }
-
- first.p->m_sz = len;
- first.p->m_ownerRef = 0;
-
- Ptr<SectionSegment> prevPtr = { (SectionSegment *)&dummyPrev[0], 0 };
- Ptr<SectionSegment> currPtr = first;
-
- while(len > SectionSegment::DataLength){
- prevPtr.p->m_nextSegment = currPtr.i;
- memcpy(&currPtr.p->theData[0], src, 4 * SectionSegment::DataLength);
- src += SectionSegment::DataLength;
- len -= SectionSegment::DataLength;
- prevPtr = currPtr;
- if(g_sectionSegmentPool.seize(currPtr)){
- ;
- } else {
- first.p->m_lastSegment = prevPtr.i;
- return false;
- }
- }
-
- first.p->m_lastSegment = currPtr.i;
- currPtr.p->m_nextSegment = RNIL;
- memcpy(&currPtr.p->theData[0], src, 4 * len);
- return true;
-}
-
-void
-linkSegments(Uint32 head, Uint32 tail){
-
- Ptr<SectionSegment> headPtr;
- g_sectionSegmentPool.getPtr(headPtr, head);
-
- Ptr<SectionSegment> tailPtr;
- g_sectionSegmentPool.getPtr(tailPtr, tail);
-
- Ptr<SectionSegment> oldTailPtr;
- g_sectionSegmentPool.getPtr(oldTailPtr, headPtr.p->m_lastSegment);
-
- headPtr.p->m_lastSegment = tailPtr.p->m_lastSegment;
- headPtr.p->m_sz += tailPtr.p->m_sz;
-
- oldTailPtr.p->m_nextSegment = tailPtr.i;
-}
-
-void
-copy(Uint32 * & insertPtr,
- class SectionSegmentPool & thePool, const SegmentedSectionPtr & _ptr){
-
- Uint32 len = _ptr.sz;
- SectionSegment * ptrP = _ptr.p;
-
- while(len > 60){
- memcpy(insertPtr, &ptrP->theData[0], 4 * 60);
- len -= 60;
- insertPtr += 60;
- ptrP = thePool.getPtr(ptrP->m_nextSegment);
- }
- memcpy(insertPtr, &ptrP->theData[0], 4 * len);
- insertPtr += len;
-}
-
-void
-copy(Uint32 * dst, SegmentedSectionPtr src){
- copy(dst, g_sectionSegmentPool, src);
-}
-
-void
-getSections(Uint32 secCount, SegmentedSectionPtr ptr[3]){
- Uint32 tSec0 = ptr[0].i;
- Uint32 tSec1 = ptr[1].i;
- Uint32 tSec2 = ptr[2].i;
- SectionSegment * p;
- switch(secCount){
- case 3:
- p = g_sectionSegmentPool.getPtr(tSec2);
- ptr[2].p = p;
- ptr[2].sz = p->m_sz;
- case 2:
- p = g_sectionSegmentPool.getPtr(tSec1);
- ptr[1].p = p;
- ptr[1].sz = p->m_sz;
- case 1:
- p = g_sectionSegmentPool.getPtr(tSec0);
- ptr[0].p = p;
- ptr[0].sz = p->m_sz;
- case 0:
- return;
- }
- char msg[40];
- sprintf(msg, "secCount=%d", secCount);
- ErrorReporter::handleAssert(msg, __FILE__, __LINE__);
-}
-
-void
-getSection(SegmentedSectionPtr & ptr, Uint32 i){
- ptr.i = i;
- SectionSegment * p = g_sectionSegmentPool.getPtr(i);
- ptr.p = p;
- ptr.sz = p->m_sz;
-}
-
-#define relSz(x) ((x + SectionSegment::DataLength - 1) / SectionSegment::DataLength)
-
-void
-release(SegmentedSectionPtr & ptr){
- g_sectionSegmentPool.releaseList(relSz(ptr.sz),
- ptr.i,
- ptr.p->m_lastSegment);
-}
-
-void
-releaseSections(Uint32 secCount, SegmentedSectionPtr ptr[3]){
- Uint32 tSec0 = ptr[0].i;
- Uint32 tSz0 = ptr[0].sz;
- Uint32 tSec1 = ptr[1].i;
- Uint32 tSz1 = ptr[1].sz;
- Uint32 tSec2 = ptr[2].i;
- Uint32 tSz2 = ptr[2].sz;
- switch(secCount){
- case 3:
- g_sectionSegmentPool.releaseList(relSz(tSz2), tSec2,
- ptr[2].p->m_lastSegment);
- case 2:
- g_sectionSegmentPool.releaseList(relSz(tSz1), tSec1,
- ptr[1].p->m_lastSegment);
- case 1:
- g_sectionSegmentPool.releaseList(relSz(tSz0), tSec0,
- ptr[0].p->m_lastSegment);
- case 0:
- return;
- }
- char msg[40];
- sprintf(msg, "secCount=%d", secCount);
- ErrorReporter::handleAssert(msg, __FILE__, __LINE__);
-}
-
-#include <DebuggerNames.hpp>
-
-void
-execute(void * callbackObj,
- SignalHeader * const header,
- Uint8 prio,
- Uint32 * const theData,
- 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)",
- getSignalName(header->theVerId_signalNumber),
- header->theVerId_signalNumber,
- getBlockName(refToBlock(header->theSendersBlockRef)),
- refToNode(header->theSendersBlockRef));
-#endif
-
- bool ok = true;
- Ptr<SectionSegment> secPtr[3];
- switch(secCount){
- case 3:
- ok &= import(secPtr[2], ptr[2].p, ptr[2].sz);
- case 2:
- ok &= import(secPtr[1], ptr[1].p, ptr[1].sz);
- 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){
- /**
- * Normal path
- */
- secPtrI[0] = secPtr[0].i;
- secPtrI[1] = secPtr[1].i;
- secPtrI[2] = secPtr[2].i;
-
- globalScheduler.execute(header, prio, theData, secPtrI);
- return;
- }
-
- /**
- * Out of memory
- */
- for(Uint32 i = 0; i<secCount; i++){
- if(secPtr[i].p != 0){
- g_sectionSegmentPool.releaseList(relSz(ptr[i].sz), secPtr[i].i,
- secPtr[i].p->m_lastSegment);
- }
- }
- Uint32 gsn = header->theVerId_signalNumber;
- Uint32 len = header->theLength;
- Uint32 newLen= (len > 22 ? 22 : len);
- SignalDroppedRep * rep = (SignalDroppedRep*)theData;
- memmove(rep->originalData, theData, (4 * newLen));
- rep->originalGsn = gsn;
- rep->originalLength = len;
- rep->originalSectionCount = secCount;
- header->theVerId_signalNumber = GSN_SIGNAL_DROPPED_REP;
- header->theLength = newLen + 3;
- header->m_noOfSections = 0;
- globalScheduler.execute(header, prio, theData, secPtrI);
-}
-
-NdbOut &
-operator<<(NdbOut& out, const SectionSegment & ss){
- out << "[ last= " << ss.m_lastSegment << " next= " << ss.nextPool << " ]";
- return out;
-}
-
-void
-print(SectionSegment * s, Uint32 len, FILE* out){
- for(Uint32 i = 0; i<len; i++){
- fprintf(out, "H\'0x%.8x ", s->theData[i]);
- if(((i + 1) % 6) == 0)
- fprintf(out, "\n");
- }
-}
-
-void
-print(SegmentedSectionPtr ptr, FILE* out){
-
- ptr.p = g_sectionSegmentPool.getPtr(ptr.i);
- Uint32 len = ptr.p->m_sz;
-
- fprintf(out, "ptr.i = %d(%p) ptr.sz = %d(%d)\n", ptr.i, ptr.p, len, ptr.sz);
- while(len > SectionSegment::DataLength){
- print(ptr.p, SectionSegment::DataLength, out);
-
- len -= SectionSegment::DataLength;
- fprintf(out, "ptr.i = %d\n", ptr.p->m_nextSegment);
- ptr.p = g_sectionSegmentPool.getPtr(ptr.p->m_nextSegment);
- }
-
- print(ptr.p, len, out);
- fprintf(out, "\n");
-}
-
-int
-checkJobBuffer() {
- /**
- * Check to see if jobbbuffers are starting to get full
- * and if so call doJob
- */
- return globalScheduler.checkDoJob();
-}
-
-void
-reportError(void * callbackObj, NodeId nodeId,
- TransporterError errorCode, const char *info)
-{
-#ifdef DEBUG_TRANSPORTER
- ndbout_c("reportError (%d, 0x%x) %s", nodeId, errorCode, info ? info : "")
-#endif
-
- DBUG_ENTER("reportError");
- DBUG_PRINT("info",("nodeId %d errorCode: 0x%x info: %s",
- nodeId, errorCode, info));
-
- switch (errorCode)
- {
- case TE_SIGNAL_LOST_SEND_BUFFER_FULL:
- {
- char msg[64];
- snprintf(msg, sizeof(msg), "Remote note id %d.%s%s", nodeId,
- info ? " " : "", info ? info : "");
- ErrorReporter::handleError(NDBD_EXIT_SIGNAL_LOST_SEND_BUFFER_FULL,
- msg, __FILE__, NST_ErrorHandler);
- }
- case TE_SIGNAL_LOST:
- {
- char msg[64];
- snprintf(msg, sizeof(msg), "Remote node id %d,%s%s", nodeId,
- info ? " " : "", info ? info : "");
- ErrorReporter::handleError(NDBD_EXIT_SIGNAL_LOST,
- msg, __FILE__, NST_ErrorHandler);
- }
- case TE_SHM_IPC_PERMANENT:
- {
- char msg[128];
- snprintf(msg, sizeof(msg),
- "Remote node id %d.%s%s",
- nodeId, info ? " " : "", info ? info : "");
- ErrorReporter::handleError(NDBD_EXIT_CONNECTION_SETUP_FAILED,
- msg, __FILE__, NST_ErrorHandler);
- }
- default:
- break;
- }
-
- if(errorCode & TE_DO_DISCONNECT){
- reportDisconnect(callbackObj, nodeId, errorCode);
- }
-
- SignalT<3> signalT;
- Signal &signal= *(Signal*)&signalT;
- memset(&signal.header, 0, sizeof(signal.header));
-
-
- if(errorCode & TE_DO_DISCONNECT)
- signal.theData[0] = NDB_LE_TransporterError;
- else
- signal.theData[0] = NDB_LE_TransporterWarning;
-
- signal.theData[1] = nodeId;
- signal.theData[2] = errorCode;
-
- signal.header.theLength = 3;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId);
- globalScheduler.execute(&signal, JBA, CMVMI, GSN_EVENT_REP);
-
- DBUG_VOID_RETURN;
-}
-
-/**
- * Report average send length in bytes (4096 last sends)
- */
-void
-reportSendLen(void * callbackObj,
- NodeId nodeId, Uint32 count, Uint64 bytes){
-
- SignalT<3> signalT;
- Signal &signal= *(Signal*)&signalT;
- memset(&signal.header, 0, sizeof(signal.header));
-
- signal.header.theLength = 3;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId);
- signal.theData[0] = NDB_LE_SendBytesStatistic;
- signal.theData[1] = nodeId;
- signal.theData[2] = (bytes/count);
- globalScheduler.execute(&signal, JBA, CMVMI, GSN_EVENT_REP);
-}
-
-/**
- * Report average receive length in bytes (4096 last receives)
- */
-void
-reportReceiveLen(void * callbackObj,
- NodeId nodeId, Uint32 count, Uint64 bytes){
-
- SignalT<3> signalT;
- Signal &signal= *(Signal*)&signalT;
- memset(&signal.header, 0, sizeof(signal.header));
-
- signal.header.theLength = 3;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId);
- signal.theData[0] = NDB_LE_ReceiveBytesStatistic;
- signal.theData[1] = nodeId;
- signal.theData[2] = (bytes/count);
- globalScheduler.execute(&signal, JBA, CMVMI, GSN_EVENT_REP);
-}
-
-/**
- * Report connection established
- */
-
-void
-reportConnect(void * callbackObj, NodeId nodeId){
-
- SignalT<1> signalT;
- Signal &signal= *(Signal*)&signalT;
- memset(&signal.header, 0, sizeof(signal.header));
-
- signal.header.theLength = 1;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId);
- signal.theData[0] = nodeId;
-
- globalScheduler.execute(&signal, JBA, CMVMI, GSN_CONNECT_REP);
-}
-
-/**
- * Report connection broken
- */
-void
-reportDisconnect(void * callbackObj, NodeId nodeId, Uint32 errNo){
-
- DBUG_ENTER("reportDisconnect");
-
- SignalT<sizeof(DisconnectRep)/4> signalT;
- Signal &signal= *(Signal*)&signalT;
- memset(&signal.header, 0, sizeof(signal.header));
-
- signal.header.theLength = DisconnectRep::SignalLength;
- signal.header.theSendersSignalId = 0;
- signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId);
- signal.header.theTrace = TestOrd::TraceDisconnect;
-
- DisconnectRep * const rep = (DisconnectRep *)&signal.theData[0];
- rep->nodeId = nodeId;
- rep->err = errNo;
-
- globalScheduler.execute(&signal, JBA, CMVMI, GSN_DISCONNECT_REP);
-
- DBUG_VOID_RETURN;
-}
-
-void
-SignalLoggerManager::printSegmentedSection(FILE * output,
- const SignalHeader & sh,
- const SegmentedSectionPtr ptr[3],
- unsigned i)
-{
- fprintf(output, "SECTION %u type=segmented", i);
- if (i >= 3) {
- fprintf(output, " *** invalid ***\n");
- return;
- }
- const Uint32 len = ptr[i].sz;
- SectionSegment * ssp = ptr[i].p;
- Uint32 pos = 0;
- fprintf(output, " size=%u\n", (unsigned)len);
- while (pos < len) {
- if (pos > 0 && pos % SectionSegment::DataLength == 0) {
- ssp = g_sectionSegmentPool.getPtr(ssp->m_nextSegment);
- }
- printDataWord(output, pos, ssp->theData[pos % SectionSegment::DataLength]);
- }
- if (len > 0)
- putc('\n', output);
-}
-
-void
-transporter_recv_from(void * callbackObj, NodeId nodeId){
- globalData.m_nodeInfo[nodeId].m_heartbeat_cnt= 0;
- return;
-}
diff --git a/storage/ndb/src/kernel/vm/VMSignal.cpp b/storage/ndb/src/kernel/vm/VMSignal.cpp
deleted file mode 100644
index 3d6d7ddc8f7..00000000000
--- a/storage/ndb/src/kernel/vm/VMSignal.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "VMSignal.hpp"
-#include <string.h>
-
-Signal::Signal(){
- memset(&header, 0, sizeof(header));
- memset(theData, 0, sizeof(theData));
-}
-
-void
-Signal::garbage_register()
-{
- int i;
- theData[0] = 0x13579135;
- header.theLength = 0x13579135;
- header.theSendersBlockRef = 0x13579135;
- for (i = 1; i < 24; i++)
- theData[i] = 0x13579135;
-}
diff --git a/storage/ndb/src/kernel/vm/VMSignal.hpp b/storage/ndb/src/kernel/vm/VMSignal.hpp
deleted file mode 100644
index ccdcea56463..00000000000
--- a/storage/ndb/src/kernel/vm/VMSignal.hpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef VMSignal_H
-#define VMSignal_H
-
-#include <ndb_global.h>
-#include <ndb_limits.h>
-#include <kernel_types.h>
-
-#include <ErrorReporter.hpp>
-#include <NodeBitmask.hpp>
-
-#include <RefConvert.hpp>
-#include <TransporterDefinitions.hpp>
-
-/**
- * Struct used when sending to multiple blocks
- */
-struct NodeReceiverGroup {
- NodeReceiverGroup();
- NodeReceiverGroup(Uint32 blockRef);
- NodeReceiverGroup(Uint32 blockNo, const NodeBitmask &);
- NodeReceiverGroup(Uint32 blockNo, const class SignalCounter &);
-
- NodeReceiverGroup& operator=(BlockReference ref);
-
- Uint32 m_block;
- NodeBitmask m_nodes;
-};
-
-template <unsigned T> struct SignalT
-{
- SignalHeader header;
- SegmentedSectionPtr m_sectionPtr[3];
- union {
- Uint32 theData[T];
- Uint64 dummyAlign;
- };
-};
-
-/**
- * class used for passing argumentes to blocks
- */
-class Signal {
- friend class SimulatedBlock;
- friend class APZJobBuffer;
- friend class FastScheduler;
-public:
- Signal();
-
- Uint32 getLength() const;
- Uint32 getTrace() const;
- Uint32 getSendersBlockRef() const;
-
- const Uint32* getDataPtr() const ;
- Uint32* getDataPtrSend() ;
-
- void setTrace(Uint32);
-
- Uint32 getNoOfSections() const;
- bool getSection(SegmentedSectionPtr & ptr, Uint32 sectionNo);
- void setSection(SegmentedSectionPtr ptr, Uint32 sectionNo);
-
- /**
- * Old depricated methods...
- */
- Uint32 length() const { return getLength();}
- BlockReference senderBlockRef() const { return getSendersBlockRef();}
-
-private:
- void setLength(Uint32);
-
-public:
-#define VMS_DATA_SIZE \
- (MAX_ATTRIBUTES_IN_TABLE + MAX_TUPLE_SIZE_IN_WORDS + MAX_KEY_SIZE_IN_WORDS)
-
-#if VMS_DATA_SIZE > 8192
-#error "VMSignal buffer is too small"
-#endif
-
- SignalHeader header; // 28 bytes
- SegmentedSectionPtr m_sectionPtr[3];
- union {
- Uint32 theData[8192]; // 8192 32-bit words -> 32K Bytes
- Uint64 dummyAlign;
- };
- void garbage_register();
-};
-
-inline
-Uint32
-Signal::getLength() const {
- return header.theLength;
-}
-
-inline
-Uint32
-Signal::getTrace() const {
- return header.theTrace;
-}
-
-inline
-Uint32
-Signal::getSendersBlockRef() const {
- return header.theSendersBlockRef;
-}
-
-inline
-const Uint32*
-Signal::getDataPtr() const {
- return &theData[0];
-}
-
-inline
-Uint32*
-Signal::getDataPtrSend() {
- return &theData[0];
-}
-
-inline
-void
-Signal::setLength(Uint32 len){
- header.theLength = len;
-}
-
-inline
-void
-Signal::setTrace(Uint32 t){
- header.theTrace = t;
-}
-
-inline
-Uint32
-Signal::getNoOfSections() const {
- return header.m_noOfSections;
-}
-
-inline
-bool
-Signal::getSection(SegmentedSectionPtr & ptr, Uint32 section){
- if(section < header.m_noOfSections){
- ptr = m_sectionPtr[section];
- return true;
- }
- ptr.p = 0;
- return false;
-}
-
-inline
-void
-Signal::setSection(SegmentedSectionPtr ptr, Uint32 sectionNo){
- if(sectionNo != header.m_noOfSections || sectionNo > 2){
- abort();
- }
- m_sectionPtr[sectionNo] = ptr;
- header.m_noOfSections++;
-}
-
-inline
-NodeReceiverGroup::NodeReceiverGroup() : m_block(0){
- m_nodes.clear();
-}
-
-inline
-NodeReceiverGroup::NodeReceiverGroup(Uint32 blockRef){
- m_nodes.clear();
- m_block = refToBlock(blockRef);
- m_nodes.set(refToNode(blockRef));
-}
-
-inline
-NodeReceiverGroup::NodeReceiverGroup(Uint32 blockNo, const NodeBitmask & nodes){
- m_block = blockNo;
- 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){
- m_nodes.clear();
- m_block = refToBlock(blockRef);
- m_nodes.set(refToNode(blockRef));
- return * this;
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/WOPool.cpp b/storage/ndb/src/kernel/vm/WOPool.cpp
deleted file mode 100644
index 359b79c42fe..00000000000
--- a/storage/ndb/src/kernel/vm/WOPool.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "WOPool.hpp"
-#include <ndbd_exit_codes.h>
-#include <NdbOut.hpp>
-
-WOPool::WOPool()
-{
- bzero(this, sizeof(* this));
- m_current_pos = WOPage::WOPAGE_WORDS;
-}
-
-void
-WOPool::init(const Record_info& ri, const Pool_context& pc)
-{
- m_ctx = pc;
- m_record_info = ri;
- m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
- m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
- m_memroot = (WOPage*)m_ctx.get_memroot();
- ndbout_c("WOPool::init(%x, %d)",ri.m_type_id, m_record_info.m_size);
-}
-
-bool
-WOPool::seize_new_page(Ptr<void>& ptr)
-{
- WOPage* page;
- Uint32 page_no = RNIL;
- if ((page = (WOPage*)m_ctx.alloc_page(m_record_info.m_type_id, &page_no)))
- {
- if (m_current_page)
- {
- m_current_page->m_ref_count = m_current_ref_count;
- }
-
- m_current_pos = 0;
- m_current_ref_count = 0;
- m_current_page_no = page_no;
- m_current_page = page;
- page->m_type_id = m_record_info.m_type_id;
- bool ret = seize(ptr);
- assert(ret);
- return true;
- }
- return false;
-}
-
-void
-WOPool::release_not_current(Ptr<void> ptr)
-{
- WOPage* page = (WOPage*)(UintPtr(ptr.p) & ~(GLOBAL_PAGE_SIZE - 1));
- Uint32 cnt = page->m_ref_count;
- Uint32 type = page->m_type_id;
- Uint32 ri_type = m_record_info.m_type_id;
- if (likely(cnt && type == ri_type))
- {
- if (cnt == 1)
- {
- m_ctx.release_page(ri_type, ptr.i >> POOL_RECORD_BITS);
- return;
- }
- page->m_ref_count = cnt - 1;
- return;
- }
-
- handle_inconsistent_release(ptr);
-}
-
-void
-WOPool::handle_invalid_release(Ptr<void> ptr)
-{
- char buf[255];
-
- Uint32 pos = ptr.i & POOL_RECORD_MASK;
- Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
- Uint32 * record_ptr_p = (Uint32*)ptr.p;
- Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
-
- Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
- snprintf(buf, sizeof(buf),
- "Invalid memory release: ptr (%x %p %p) magic: (%.8x %.8x) memroot: %p page: %x",
- ptr.i, ptr.p, record_ptr_i, magic, m_record_info.m_type_id,
- m_memroot,
- (m_memroot+pageI)->m_type_id);
-
- m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}
-
-void
-WOPool::handle_invalid_get_ptr(Uint32 ptrI)
-{
- char buf[255];
-
- Uint32 pos = ptrI & POOL_RECORD_MASK;
- Uint32 pageI = ptrI >> POOL_RECORD_BITS;
- Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
-
- Uint32 magic = * (record_ptr_i + m_record_info.m_offset_magic);
- snprintf(buf, sizeof(buf),
- "Invalid memory access: ptr (%x %p) magic: (%.8x %.8x) memroot: %p page: %x",
- ptrI, record_ptr_i, magic, m_record_info.m_type_id,
- m_memroot,
- (m_memroot+pageI)->m_type_id);
-
- m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}
-
-void
-WOPool::handle_inconsistent_release(Ptr<void> ptr)
-{
- WOPage* page = (WOPage*)(UintPtr(ptr.p) & ~(GLOBAL_PAGE_SIZE - 1));
- Uint32 cnt = page->m_ref_count;
- Uint32 type = page->m_type_id;
- Uint32 ri_type = m_record_info.m_type_id;
-
- char buf[255];
-
- snprintf(buf, sizeof(buf),
- "Memory corruption: ptr (%x %p) page (%d %x %x)",
- ptr.i, ptr.p, cnt, type, ri_type);
-
- m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
-}
diff --git a/storage/ndb/src/kernel/vm/WOPool.hpp b/storage/ndb/src/kernel/vm/WOPool.hpp
deleted file mode 100644
index a9cdef881fb..00000000000
--- a/storage/ndb/src/kernel/vm/WOPool.hpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright (c) 2003, 2006, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef WOPOOL_HPP
-#define WOPOOL_HPP
-
-#include "Pool.hpp"
-
-struct WOPage
-{
- STATIC_CONST( WOPAGE_WORDS = GLOBAL_PAGE_SIZE_WORDS - 2 );
-
- Uint32 m_type_id;
- Uint32 m_ref_count;
- Uint32 m_data[WOPAGE_WORDS];
-};
-
-/**
- * Write Once Pool
- */
-struct WOPool
-{
- Record_info m_record_info;
- WOPage* m_memroot;
- WOPage* m_current_page;
- Pool_context m_ctx;
- Uint32 m_current_page_no;
- Uint16 m_current_pos;
- Uint16 m_current_ref_count;
-public:
- WOPool();
-
- void init(const Record_info& ri, const Pool_context& pc);
- bool seize(Ptr<void>&);
- void release(Ptr<void>);
- void * getPtr(Uint32 i);
-
-private:
- bool seize_new_page(Ptr<void>&);
- void release_not_current(Ptr<void>);
-
- void handle_invalid_release(Ptr<void>);
- void handle_invalid_get_ptr(Uint32 i);
- void handle_inconsistent_release(Ptr<void>);
-};
-
-inline
-bool
-WOPool::seize(Ptr<void>& ptr)
-{
- Uint32 pos = m_current_pos;
- Uint32 size = m_record_info.m_size;
- WOPage *pageP = m_current_page;
- if (likely(pos + size < WOPage::WOPAGE_WORDS))
- {
- ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
- ptr.p = (pageP->m_data + pos);
- pageP->m_data[pos+m_record_info.m_offset_magic] = ~(Uint32)m_record_info.m_type_id;
- m_current_pos = pos + size;
- m_current_ref_count++;
- return true;
- }
-
- return seize_new_page(ptr);
-}
-
-inline
-void
-WOPool::release(Ptr<void> ptr)
-{
- Uint32 cur_page = m_current_page_no;
- Uint32 ptr_page = ptr.i >> POOL_RECORD_BITS;
- Uint32 *magic_ptr = (((Uint32*)ptr.p)+m_record_info.m_offset_magic);
- Uint32 magic_val = *magic_ptr;
-
- if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
- {
- * magic_ptr = 0;
- if (cur_page == ptr_page)
- {
- if (m_current_ref_count == 1)
- {
- m_current_pos = 0;
- }
- m_current_ref_count--;
- return;
- }
- return release_not_current(ptr);
- }
- handle_invalid_release(ptr);
-}
-
-inline
-void*
-WOPool::getPtr(Uint32 i)
-{
- Uint32 page_no = i >> POOL_RECORD_BITS;
- Uint32 page_idx = i & POOL_RECORD_MASK;
- WOPage * page = m_memroot + page_no;
- Uint32 * record = page->m_data + page_idx;
- Uint32 magic_val = * (record + m_record_info.m_offset_magic);
- if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
- {
- return record;
- }
- handle_invalid_get_ptr(i);
- return 0; /* purify: deadcode */
-}
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/WaitQueue.hpp b/storage/ndb/src/kernel/vm/WaitQueue.hpp
deleted file mode 100644
index 732c895ea12..00000000000
--- a/storage/ndb/src/kernel/vm/WaitQueue.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef WAIT_QUEUE_HPP
-#define WAIT_QUEUE_HPP
-
-#include "ArrayPool.hpp"
-#include "SimulatedBlock.hpp"
-
-template <class Block,
- class T,
- void (Block::* Function)(Signal*, Ptr<T>)>
-class WaitQueue {
-public:
- WaitQueue(Block & block, ArrayPool<T>& pool){
- }
-
- void add(Ptr<T>, void (Block::* Callback)(Signal*, Ptr<T>)) {}
- void complete(Ptr<T>) {}
-};
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/WatchDog.cpp b/storage/ndb/src/kernel/vm/WatchDog.cpp
deleted file mode 100644
index fdf45a1803b..00000000000
--- a/storage/ndb/src/kernel/vm/WatchDog.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright (c) 2003-2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-#include <sys/times.h>
-
-#include "WatchDog.hpp"
-#include "GlobalData.hpp"
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-#include <ErrorHandlingMacros.hpp>
-#include <EventLogger.hpp>
-
-#include <NdbTick.h>
-
-extern EventLogger g_eventLogger;
-
-extern "C"
-void*
-runWatchDog(void* w){
- ((WatchDog*)w)->run();
- return NULL;
-}
-
-WatchDog::WatchDog(Uint32 interval) :
- theIPValue(globalData.getWatchDogPtr())
-{
- setCheckInterval(interval);
- theStop = false;
- theThreadPtr = 0;
-}
-
-WatchDog::~WatchDog(){
- doStop();
-}
-
-Uint32
-WatchDog::setCheckInterval(Uint32 interval){
- // An interval of less than 70ms is not acceptable
- return theInterval = (interval < 70 ? 70 : interval);
-}
-
-void
-WatchDog::doStart(){
- theStop = false;
- theThreadPtr = NdbThread_Create(runWatchDog,
- (void**)this,
- 32768,
- "ndb_watchdog",
- NDB_THREAD_PRIO_HIGH);
-}
-
-void
-WatchDog::doStop(){
- void *status;
- theStop = true;
- if(theThreadPtr){
- NdbThread_WaitFor(theThreadPtr, &status);
- NdbThread_Destroy(&theThreadPtr);
- }
-}
-
-const char *get_action(Uint32 IPValue)
-{
- const char *action;
- switch (IPValue) {
- case 1:
- action = "Job Handling";
- break;
- case 2:
- action = "Scanning Timers";
- break;
- case 3:
- action = "External I/O";
- break;
- case 4:
- action = "Print Job Buffers at crash";
- break;
- case 5:
- action = "Checking connections";
- break;
- case 6:
- action = "Performing Send";
- break;
- case 7:
- action = "Polling for Receive";
- break;
- case 8:
- action = "Performing Receive";
- break;
- case 9:
- action = "Allocating memory";
- break;
- default:
- action = "Unknown place";
- break;
- }//switch
- return action;
-}
-
-void
-WatchDog::run()
-{
- unsigned int anIPValue, sleep_time;
- unsigned int oldIPValue = 0;
- unsigned int theIntervalCheck = theInterval;
- struct MicroSecondTimer start_time, last_time, now;
- NdbTick_getMicroTimer(&start_time);
- last_time = start_time;
-
- // WatchDog for the single threaded NDB
- while (!theStop)
- {
- sleep_time= 100;
-
- NdbSleep_MilliSleep(sleep_time);
- if(theStop)
- break;
-
- NdbTick_getMicroTimer(&now);
- if (NdbTick_getMicrosPassed(last_time, now)/1000 > sleep_time*2)
- {
- struct tms my_tms;
- times(&my_tms);
- g_eventLogger.info("Watchdog: User time: %llu System time: %llu",
- (Uint64)my_tms.tms_utime,
- (Uint64)my_tms.tms_stime);
- g_eventLogger.warning("Watchdog: Warning overslept %u ms, expected %u ms.",
- NdbTick_getMicrosPassed(last_time, now)/1000,
- sleep_time);
- }
- last_time = now;
-
- // Verify that the IP thread is not stuck in a loop
- anIPValue = *theIPValue;
- if (anIPValue != 0)
- {
- oldIPValue = anIPValue;
- globalData.incrementWatchDogCounter(0);
- NdbTick_getMicroTimer(&start_time);
- theIntervalCheck = theInterval;
- }
- else
- {
- int warn = 1;
- Uint32 elapsed = NdbTick_getMicrosPassed(start_time, now)/1000;
- /*
- oldIPValue == 9 indicates malloc going on, this can take some time
- so only warn if we pass the watchdog interval
- */
- if (oldIPValue == 9)
- if (elapsed < theIntervalCheck)
- warn = 0;
- else
- theIntervalCheck += theInterval;
-
- if (warn)
- {
- const char *last_stuck_action = get_action(oldIPValue);
- g_eventLogger.warning("Ndb kernel is stuck in: %s", last_stuck_action);
- {
- struct tms my_tms;
- times(&my_tms);
- g_eventLogger.info("Watchdog: User time: %llu System time: %llu",
- (Uint64)my_tms.tms_utime,
- (Uint64)my_tms.tms_stime);
- }
- if (elapsed > 3 * theInterval)
- {
- shutdownSystem(last_stuck_action);
- }
- }
- }
- }
- return;
-}
-
-void
-WatchDog::shutdownSystem(const char *last_stuck_action){
-
- ErrorReporter::handleError(NDBD_EXIT_WATCHDOG_TERMINATE,
- last_stuck_action,
- __FILE__,
- NST_Watchdog);
-}
diff --git a/storage/ndb/src/kernel/vm/WatchDog.hpp b/storage/ndb/src/kernel/vm/WatchDog.hpp
deleted file mode 100644
index f78850f8e86..00000000000
--- a/storage/ndb/src/kernel/vm/WatchDog.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef WatchDog_H
-#define WatchDog_H
-
-#include <kernel_types.h>
-#include <NdbThread.h>
-
-extern "C" void* runWatchDog(void* w);
-
-class WatchDog{
-public:
- WatchDog(Uint32 interval = 3000);
- ~WatchDog();
-
- void doStart();
- void doStop();
-
- Uint32 setCheckInterval(Uint32 interval);
-
-protected:
- /**
- * Thread function
- */
- friend void* runWatchDog(void* w);
-
- /**
- * Thread pointer
- */
- NdbThread* theThreadPtr;
-
-private:
- Uint32 theInterval;
- const Uint32 * theIPValue;
-
- bool theStop;
-
- void run();
- void shutdownSystem(const char *last_stuck_action);
-};
-
-#endif // WatchDog_H
diff --git a/storage/ndb/src/kernel/vm/al_test/Makefile b/storage/ndb/src/kernel/vm/al_test/Makefile
deleted file mode 100644
index a7287a341fd..00000000000
--- a/storage/ndb/src/kernel/vm/al_test/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-include .defs.mk
-
-TYPE := kernel
-
-BIN_TARGET := al_test
-BIN_TARGET_ARCHIVES := portlib
-
-SOURCES = main.cpp
-
-CFLAGS_main.cpp = -DDEBUG
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp b/storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp
deleted file mode 100644
index 3b5304b432c..00000000000
--- a/storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <ndb_global.hpp>
-
-#include <ArrayList.hpp>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-struct A_Listable_Object {
- Uint32 next;
- Uint32 prev;
- char somedata[12];
-
- void print (NdbOut & out) {
- out << "ALO: next = " << next
- << " prev = " << prev << endl;
- }
-};
-
-extern const int x_AL_Next = offsetof(A_Listable_Object, next);
-extern const int x_AL_Prev = offsetof(A_Listable_Object, prev);
-
-NdbOut &
-operator<<(NdbOut & o, A_Listable_Object & a){
- a.print(o);
- return o;
-}
-
-typedef Ptr<A_Listable_Object> A_Listable_ObjectPtr;
-
-#define APool ArrayPool<A_Listable_Object>
-#define AList ArrayList<A_Listable_Object>
-
-APool aGPool;
-AList aGList(aGPool);
-
-class ArrayListTest {
-public:
- static void tryList0(int listSize){
- APool aPool;
- AList aList(aPool);
-
- if(!aPool.setSize(listSize)){
- ndbout << "Failed to do aPool.setSize(" << listSize << ")" << endl;
- return;
- }
-
- int * anArray = new int[listSize];
-
- for(int i = 1; i<listSize; i++){
- int arrayElements = 0;
-
-
- for(int j = 0; j<i; j++){
- A_Listable_ObjectPtr p;
- const int ret = aList.seize(p);
- if(ret == RNIL){
- ndbout << "Failed to seize!!" << endl;
- ndbout << "Have seized " << j
- << " out of " << listSize << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- anArray[arrayElements] = ret;
- arrayElements++;
- }
- assert(aList.noOfElements() == i);
- assert(aPool.noOfFree() == (listSize - i));
- assert(arrayElements == i);
-
- for(int j = 0; j<i; j++){
- aList.release(anArray[j]);
- }
-
- assert(aList.noOfElements() == 0);
- assert(aPool.noOfFree() == listSize);
- }
- }
-
- static void tryList1(int listSize, int iterations){
- APool aPool;
- AList aList(aPool);
-
- if(!aPool.setSize(listSize)){
- ndbout << "Failed to do aPool.setSize(" << listSize << ")" << endl;
- return;
- }
-
- ndbout << "Seizing/Releaseing " << iterations
- << " times over list with " << listSize << " elements" << endl;
-
- int * anArray = new int[listSize];
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- for(int i = 0; i<iterations; i++){
- assert(arrayElements <= listSize);
- const int r = rand() % (10 * listSize);
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aList.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Listable_ObjectPtr p;
- const int ret = aList.seize(p);
- if(ret == RNIL && arrayElements != listSize){
- ndbout << "Failed to seize!!"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << listSize << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= listSize && ret != RNIL){
- ndbout << "Seize did not fail when it should have"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << listSize << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
-
- ndbout << "Seized: " << noOfSeize
- << " Seized with buffer full: " << noFailSeize
- << " Release: " << noOfRelease << " --- ";
- ndbout << "(" << noOfSeize << " + " << noFailSeize << " + " << noOfRelease
- << " = " << (noOfSeize + noFailSeize + noOfRelease) << ")" << endl;
- }
-
- static void tryList2(int size, int iter, int fail){
- APool aPool;
- AList aList(aPool);
-
- if(!aPool.setSize(size)){
- ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
- return;
- }
-
- ndbout << "doing getPtr(i) where i > size(" << size << ") "
- << fail << " times mixed with " << iter
- << " ordinary seize/release" << endl;
-
- int * anArray = new int[size];
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- for(int i = 0; i<iter; i++){
- assert(arrayElements <= size);
- const int r = rand() % (10 * size);
-
- if((i + 1)%(iter/fail) == 0){
- aList.getPtr(size + r);
- continue;
- }
-
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aList.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Listable_ObjectPtr p;
- const int ret = aList.seize(p);
- if(ret == RNIL && arrayElements != size){
- ndbout << "Failed to seize!!"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= size && ret != RNIL){
- ndbout << "Seize did not fail when it should have"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
- }
-
- static void
- tryList3(int size, int fail){
- ndbout << "Failing " << fail << " times " << endl;
-
- for(int i = 0; i<fail; i++){
- APool aPool;
- AList aList(aPool);
-
- if(!aPool.setSize(size)){
- ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
- return;
- }
-
- const int noOfElementsInBufferWhenFail = (i + 1) * (size /(fail + 1));
-
- int * anArray = new int[size];
- for(int i = 0; i<size; i++)
- anArray[i] = i;
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- while(true){
- assert(arrayElements <= size);
- if(arrayElements == noOfElementsInBufferWhenFail){
- ndbout << "++ You should get a ErrorReporter::handle... " << endl;
- aList.release(anArray[arrayElements]);
- ndbout << "++ Inbetween these lines" << endl << endl;
- break;
- }
- const int r = rand() % (10 * size);
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aList.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Listable_ObjectPtr p;
- const int ret = aList.seize(p);
- if(ret == RNIL && arrayElements != size){
- ndbout << "Failed to seize!!" << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= size && ret != RNIL){
- ndbout << "Seize did not fail when it should have" << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
- }
-
- }
-};
diff --git a/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp b/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp
deleted file mode 100644
index 75f97d1ffba..00000000000
--- a/storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include <ndb_global.h>
-
-#include <ArrayList.hpp>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-struct A_Poolable_Object {
- Uint32 next;
- char somedata[12];
-
- void print (NdbOut & out) {
- out << "A_Poolable_Object: next = " << next << endl;
- }
-
-};
-
-
-NdbOut &
-operator<<(NdbOut & o, A_Poolable_Object & a){
- a.print(o);
- return o;
-}
-
-typedef Ptr<A_Poolable_Object> A_Poolable_ObjectPtr;
-#if 1
-#define BPool ArrayPool<A_Poolable_Object>
-#else
-#define BPool ArrayPool(A_Poolable_Object, next)
-#endif
-
-class ArrayPoolTest {
-public:
- static void tryPool1(int poolSize, int iterations){
- BPool aPool;
-
- if(!aPool.setSize(poolSize)){
- ndbout << "Failed to do aPool.setSize(" << poolSize << ")" << endl;
- return;
- }
-
- ndbout << "Seizing/Releaseing " << iterations
- << " times over pool with " << poolSize << " elements" << endl;
-
- int * anArray = new int[poolSize];
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- for(int i = 0; i<iterations; i++){
- if(!((arrayElements <= poolSize) &&
- (aPool.noOfFree() == aPool.noOfFree2()) &&
- (aPool.noOfFree() == (poolSize - arrayElements)))){
- ndbout << "Assertion!!"
- << " iteration=" << i << endl;
- const int f1 = aPool.noOfFree();
- const int f2 = aPool.noOfFree2();
- ndbout << "noOfFree() = " << f1 << endl;
- ndbout << "noOfFree2() = " << f2 << endl;
- ndbout << "poolSize = " << poolSize << endl;
- ndbout << "arrayElemts = " << arrayElements << endl;
- aPool.print(ndbout);
- assert(0);
- }
-
- const int r = rand() % (10 * poolSize);
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aPool.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Poolable_ObjectPtr p;
- const int ret = aPool.seize(p);
- if(ret == RNIL && arrayElements != poolSize){
- ndbout << "Failed to seize!!"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << poolSize << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= poolSize && ret != RNIL){
- ndbout << "Seize did not fail when it should have"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << poolSize << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- memset(p.p, i, sizeof(p.p->somedata));
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
-
- ndbout << "Seized: " << noOfSeize
- << " Seized with buffer full: " << noFailSeize
- << " Release: " << noOfRelease << " --- ";
- ndbout << "(" << noOfSeize << " + " << noFailSeize << " + " << noOfRelease
- << " = " << (noOfSeize + noFailSeize + noOfRelease) << ")" << endl;
- }
-
- static void tryPool2(int size, int iter, int fail){
- BPool aPool;
-
- if(!aPool.setSize(size)){
- ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
- return;
- }
-
- ndbout << "doing getPtr(i) where i > size(" << size << ") "
- << fail << " times mixed with " << iter
- << " ordinary seize/release" << endl;
-
- int * anArray = new int[size];
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- for(int i = 0; i<iter; i++){
- if(!((arrayElements <= size) &&
- (aPool.noOfFree() == aPool.noOfFree2()) &&
- (aPool.noOfFree() == (size - arrayElements)))){
- ndbout << "Assertion!!"
- << " iteration=" << i << endl;
- const int f1 = aPool.noOfFree();
- const int f2 = aPool.noOfFree2();
- ndbout << "noOfFree() = " << f1 << endl;
- ndbout << "noOfFree2() = " << f2 << endl;
- ndbout << "poolSize = " << size << endl;
- ndbout << "arrayElemts = " << arrayElements << endl;
- aPool.print(ndbout);
- assert(0);
- }
- const int r = rand() % (10 * size);
-
- if((i + 1)%(iter/fail) == 0){
- aPool.getPtr(size + r);
- continue;
- }
-
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aPool.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Poolable_ObjectPtr p;
- const int ret = aPool.seize(p);
- if(ret == RNIL && arrayElements != size){
- ndbout << "Failed to seize!!"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= size && ret != RNIL){
- ndbout << "Seize did not fail when it should have"
- << " iteration=" << i << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- memset(p.p, p.i, sizeof(p.p->somedata));
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
- }
-
- static void
- tryPool3(int size, int fail){
- ndbout << "Failing " << fail << " times " << endl;
-
- for(int i = 0; i<fail; i++){
- BPool aPool;
- if(!aPool.setSize(size)){
- ndbout << "Failed to do aPool.setSize(" << size << ")" << endl;
- return;
- }
-
- const int noOfElementsInBufferWhenFail = (i + 1) * (size /(fail + 1));
-
- int * anArray = new int[size];
- for(int i = 0; i<size; i++)
- anArray[i] = i;
- int arrayElements = 0;
-
- int noOfSeize = 0;
- int noFailSeize = 0;
- int noOfRelease = 0;
-
- while(true){
- assert(arrayElements <= size);
- if(arrayElements == noOfElementsInBufferWhenFail){
- ndbout << "++ You should get a ErrorReporter::handle... " << endl;
- aPool.release(anArray[arrayElements]);
- ndbout << "++ Inbetween these lines" << endl << endl;
- break;
- }
- const int r = rand() % (10 * size);
- if(r < (arrayElements - 1)){
- /**
- * Release an element
- */
- noOfRelease++;
- aPool.release(anArray[r]);
- arrayElements--;
- for(int j = r; j<arrayElements; j++)
- anArray[j] = anArray[j+1];
-
- } else {
- /**
- * Seize an element
- */
- A_Poolable_ObjectPtr p;
- const int ret = aPool.seize(p);
- if(ret == RNIL && arrayElements != size){
- ndbout << "Failed to seize!!" << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(arrayElements >= size && ret != RNIL){
- ndbout << "Seize did not fail when it should have" << endl;
- ndbout << "Have seized " << arrayElements
- << " out of " << size << endl;
- ndbout << "Terminating..." << endl;
- abort();
- }
- if(ret != RNIL){
- noOfSeize++;
- anArray[arrayElements] = ret;
- arrayElements++;
- } else {
- noFailSeize++;
- }
- }
- }
- delete []anArray;
- }
-
- }
-};
-
diff --git a/storage/ndb/src/kernel/vm/al_test/main.cpp b/storage/ndb/src/kernel/vm/al_test/main.cpp
deleted file mode 100644
index 5f536031bb1..00000000000
--- a/storage/ndb/src/kernel/vm/al_test/main.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include <ArrayList.hpp>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-#include <NdbMain.h>
-
-#include "arrayListTest.cpp"
-#include "arrayPoolTest.cpp"
-
-NDB_COMMAND(al_test, "al_test", "al_test", "al_test", 65535)
-{
- NdbMem_Create();
- srand(NdbTick_CurrentMillisecond());
-
-#if 1
- ndbout << endl << endl << "-- Testing basic basic seize/release" << endl;
- ArrayListTest::tryList0(10);
-
- ndbout << endl << endl << "-- Testing basic seize/release" << endl;
- ArrayListTest::tryList1(1000, 1000);
-
- ndbout << endl << endl << "-- Testing that seize returns RNIL"
- << endl;
- ArrayListTest::tryList1(10, 1000000);
-
- ndbout << endl << endl << "-- Testing access out of array" << endl;
- ArrayListTest::tryList2(1000, 100000, 5);
-#endif
-
-#if 1
- ndbout << endl << endl << "-- Testing basic seize/release" << endl;
- ArrayPoolTest::tryPool1(1000, 1000);
-
- ndbout << endl << endl << "-- Testing that seize returns RNIL"
- << endl;
- ArrayPoolTest::tryPool1(10, 1000000);
-
- ndbout << endl << endl << "-- Testing access out of array" << endl;
- ArrayPoolTest::tryPool2(1000, 100000, 5);
-
- ndbout << endl << endl << "-- Testing releasing none seized element" << endl;
- ArrayPoolTest::tryPool3(1000, 5);
-#endif
-}
-
-void
-ErrorReporter::handleBlockAssert(int line)
-{
- ndbout << "ErrorReporter::handleAssert activated - "
- << " line= " << line << endl;
- //assert(0);
-}
diff --git a/storage/ndb/src/kernel/vm/bench_pool.cpp b/storage/ndb/src/kernel/vm/bench_pool.cpp
deleted file mode 100644
index 8011bd0f8cd..00000000000
--- a/storage/ndb/src/kernel/vm/bench_pool.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/* Copyright (c) 2003, 2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include "ArrayPool.hpp"
-#include "WOPool.hpp"
-#include "RWPool.hpp"
-#include <NdbTick.h>
-#include "ndbd_malloc_impl.hpp"
-#include "SimulatedBlock.hpp"
-
-#ifdef USE_CALLGRIND
-#include <valgrind/callgrind.h>
-#else
-#define CALLGRIND_TOGGLE_COLLECT()
-#endif
-
-#define T_TEST_AP (1 << 0)
-#define T_TEST_WO (1 << 1)
-#define T_TEST_RW (1 << 2)
-
-#define T_SEIZE (1 << 0)
-#define T_RELEASE (1 << 1)
-#define T_G_RELEASE (1 << 2)
-#define T_R_RELEASE (1 << 3)
-#define T_R_G_RELEASE (1 << 4)
-#define T_MIX (1 << 5)
-#define T_GETPTR (1 << 6)
-#define T_FIFO (1 << 7)
-
-const char *test_names[] = {
- "seize",
- "release",
- "get+rel",
- "r-rel",
- "r-get+rel",
- "mix",
- "getptr",
- "fifo",
- 0
-};
-
-Uint32 pools = ~0;
-Uint32 tests = ~0;
-Uint32 records = ~0;
-Uint32 sizes = 7;
-unsigned int seed;
-Ndbd_mem_manager mm;
-Configuration cfg;
-Block_context ctx(cfg, mm);
-struct BB : public SimulatedBlock
-{
- BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {}
-};
-
-BB block(DBACC, ctx);
-
-template <typename T>
-void
-init(ArrayPool<T> & pool, Uint32 cnt)
-{
- pool.setSize(cnt + 1, true);
-}
-
-template <typename T>
-void
-init(RecordPool<T, WOPool> & pool, Uint32 cnt)
-{
- Pool_context pc;
- pc.m_block = &block;
- pool.wo_pool_init(0x2001, pc);
-}
-
-template <typename T>
-void
-init(RecordPool<T, RWPool> & pool, Uint32 cnt)
-{
- Pool_context pc;
- pc.m_block = &block;
- pool.init(0x2001, pc);
-}
-
-template <typename T, typename R>
-void
-test_pool(R& pool, Uint32 cnt, Uint32 loops)
-{
- Ptr<T> ptr;
- Uint32 *arr = (Uint32*)alloca(cnt * sizeof(Uint32));
- bzero(arr, cnt * sizeof(Uint32));
- if (tests & T_SEIZE)
- {
- Uint64 sum = 0;
- for(Uint32 i = 0; i<loops; i++)
- { // seize
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- assert(b);
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- for(Uint32 j = 0; j<cnt; j++)
- {
- ptr.i = arr[j];
- pool.getPtr(ptr);
- ptr.p->do_stuff();
- pool.release(ptr.i);
- arr[j] = RNIL;
- }
- sum += (stop - start);
- }
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_RELEASE)
- { // release
- Uint64 sum = 0;
- for(Uint32 i = 0; i<loops; i++)
- {
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- }
-
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 j = 0; j<cnt; j++)
- {
- pool.release(arr[j]);
- arr[j] = RNIL;
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- sum += (stop - start);
- }
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_G_RELEASE)
- { // getptr + release
- Uint64 sum = 0;
- for(Uint32 i = 0; i<loops; i++)
- {
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- }
-
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 j = 0; j<cnt; j++)
- {
- pool.getPtr(ptr, arr[j]);
- ptr.p->do_stuff();
- pool.release(ptr);
- arr[j] = RNIL;
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- sum += (stop - start);
- }
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_R_RELEASE)
- { // release reverse
- Uint64 sum = 0;
- for(Uint32 i = 0; i<loops; i++)
- {
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- }
-
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 j = 0; j<cnt; j++)
- {
- pool.release(arr[cnt - j - 1]);
- arr[cnt - j - 1] = RNIL;
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- sum += (stop - start);
- }
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_R_G_RELEASE)
- { // getptr + release
- Uint64 sum = 0;
- for(Uint32 i = 0; i<loops; i++)
- {
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- }
-
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 j = 0; j<cnt; j++)
- {
- pool.getPtr(ptr, arr[cnt - j - 1]);
- ptr.p->do_stuff();
- pool.release(ptr);
- arr[cnt - j - 1] = RNIL;
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- sum += (stop - start);
- }
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_MIX)
- {
- Uint64 sum = 0;
- Uint64 start = NdbTick_CurrentMillisecond();
- Uint32 lseed = seed;
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 i = 0; i<loops * cnt; i++)
- {
- int pos = rand_r(&lseed) % cnt;
- ptr.i = arr[pos];
- if (ptr.i == RNIL)
- {
- pool.seize(ptr);
- arr[pos] = ptr.i;
- assert(ptr.i != RNIL);
- ptr.p->do_stuff();
- }
- else
- {
- pool.getPtr(ptr);
- ptr.p->do_stuff();
- pool.release(ptr);
- arr[pos] = RNIL;
- }
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- for(Uint32 j = 0; j<cnt; j++)
- {
- ptr.i = arr[j];
- if (ptr.i != RNIL)
- {
- pool.getPtr(ptr);
- pool.release(ptr.i);
- }
- arr[j] = RNIL;
- }
-
- sum += (stop - start);
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_GETPTR)
- {
- Uint32 lseed = seed;
- for(Uint32 j = 0; j<cnt; j++)
- {
- bool b = pool.seize(ptr);
- arr[j] = ptr.i;
- ptr.p->do_stuff();
- assert(b);
- }
-
- Uint64 sum = 0;
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 i = 0; i<loops * cnt; i++)
- {
- int pos = rand_r(&lseed) % cnt;
- ptr.i = arr[pos];
- pool.getPtr(ptr);
- ptr.p->do_stuff();
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
-
- for(Uint32 j = 0; j<cnt; j++)
- {
- ptr.i = arr[j];
- pool.getPtr(ptr);
- ptr.p->do_stuff();
- pool.release(ptr.i);
- arr[j] = RNIL;
- }
-
- sum += (stop - start);
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- if (tests & T_FIFO)
- { // fifo
- Uint64 sum = 0;
- Uint64 start = NdbTick_CurrentMillisecond();
- CALLGRIND_TOGGLE_COLLECT();
- for(Uint32 i = 0; i<loops; i++)
- {
- Uint32 head = RNIL;
- Uint32 last = RNIL;
-
- Uint64 sum = 0;
- for(Uint32 j = 0; j<cnt; j++)
- {
- pool.seize(ptr);
- ptr.p->do_stuff();
- ptr.p->m_nextList = RNIL;
- if (head == RNIL)
- {
- head = ptr.i;
- }
- else
- {
- T* t = pool.getPtr(last);
- t->m_nextList = ptr.i;
- }
- last = ptr.i;
- }
-
- while (head != RNIL)
- {
- pool.getPtr(ptr, head);
- ptr.p->do_stuff();
- head = ptr.p->m_nextList;
- pool.release(ptr);
- }
- }
- CALLGRIND_TOGGLE_COLLECT();
- Uint64 stop = NdbTick_CurrentMillisecond();
- sum += (stop - start);
- printf(" ; %lld", sum); fflush(stdout);
- }
-
- ndbout_c("");
-}
-
-template <Uint32 sz>
-struct Rec {
- Uint32 m_data;
- Uint32 m_magic;
- Uint32 nextPool;
- Uint32 m_nextList;
- char m_cdata[sz-16];
-
- void do_stuff() {
- Uint32 sum = 0;
- Uint32 *ptr = (Uint32*)this;
- for(Uint32 i = 0; i<(sz >> 2); i++)
- sum += * ptr ++;
- m_data = sum;
- }
-};
-
-typedef Rec<32> Rec32;
-typedef Rec<36> Rec36;
-typedef Rec<56> Rec56;
-typedef Rec<224> Rec224;
-
-template <typename T>
-void test_ap(Uint32 cnt, Uint32 loop)
-{
- printf("AP ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
- ArrayPool<T> pool;
- init(pool, cnt);
- test_pool<T, ArrayPool<T> >(pool, cnt, loop);
-}
-
-template <typename T>
-void test_rw(Uint32 cnt, Uint32 loop)
-{
- printf("RW ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
- RecordPool<T, RWPool> pool;
- init(pool, cnt);
- test_pool<T, RecordPool<T, RWPool> >(pool, cnt, loop);
-}
-
-template <typename T>
-void test_wo(Uint32 cnt, Uint32 loop)
-{
- printf("WO ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
- RecordPool<T, WOPool> pool;
- init(pool, cnt);
- test_pool<T, RecordPool<T, WOPool> >(pool, cnt, loop);
-}
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-int
-main(int argc, char **argv)
-{
- Uint32 loops = 300000;
- for (Uint32 i = 1 ; i<argc ; i++)
- {
- if (argc > i+1 && strcmp(argv[i], "-pools") == 0)
- {
- pools = 0;
- for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
- {
- char c = argv[i+1][j];
- if (c >= '0' && c <= '9')
- pools |= 1 << (c - '0');
- else
- pools |= 1 << (10 + (c - 'a'));
- }
- }
- else if (argc > i+1 && strcmp(argv[i], "-tests") == 0)
- {
- tests = 0;
- for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
- {
- char c = argv[i+1][j];
- if (c >= '0' && c <= '9')
- tests |= 1 << (c - '0');
- else
- tests |= 1 << (10 + (c - 'a'));
- }
- }
- else if (argc > i+1 && strcmp(argv[i], "-sizes") == 0)
- {
- sizes = 0;
- for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
- {
- char c = argv[i+1][j];
- if (c >= '0' && c <= '9')
- sizes |= 1 << (c - '0');
- else
- sizes |= 1 << (10 + (c - 'a'));
- }
- }
- else if (argc > i+1 && strcmp(argv[i], "-records") == 0)
- {
- records = 0;
- for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
- {
- char c = argv[i+1][j];
- if (c >= '0' && c <= '9')
- records |= 1 << (c - '0');
- else
- records |= 1 << (10 + (c - 'a'));
- }
- }
- else if (argc > i+1 && strcmp(argv[i], "-loop") == 0)
- {
- loops = atoi(argv[i+1]);
- }
- }
-
- Resource_limit rl;
- rl.m_min = 0;
- rl.m_max = 10000;
- rl.m_resource_id = 0;
- mm.set_resource_limit(rl);
- if(!mm.init())
- {
- abort();
- }
-
- seed = time(0);
- Uint32 sz = 0;
- Uint32 cnt = 256;
-
- printf("pool ; rs ; ws");
- for (Uint32 i = 0; test_names[i] && i<31; i++)
- if (tests & (1 << i))
- printf(" ; %s", test_names[i]);
- ndbout_c("");
-
- while(cnt <= 1000000)
- {
- Uint32 loop = 768 * loops / cnt;
- if (sizes & (1 << sz))
- {
- if (records & 1)
- {
- if (pools & T_TEST_AP)
- test_ap<Rec32>(cnt, loop);
- if (pools & T_TEST_WO)
- test_wo<Rec32>(cnt, loop);
- if (pools & T_TEST_RW)
- test_rw<Rec32>(cnt, loop);
- }
- if (records & 2)
- {
- if (pools & T_TEST_AP)
- test_ap<Rec36>(cnt, loop);
- if (pools & T_TEST_WO)
- test_wo<Rec36>(cnt, loop);
- if (pools & T_TEST_RW)
- test_rw<Rec36>(cnt, loop);
- }
- if (records & 4)
- {
- if (pools & T_TEST_AP)
- test_ap<Rec56>(cnt, loop);
- if (pools & T_TEST_WO)
- test_wo<Rec56>(cnt, loop);
- if (pools & T_TEST_RW)
- test_rw<Rec56>(cnt, loop);
- }
- if (records & 8)
- {
- if (pools & T_TEST_AP)
- test_ap<Rec224>(cnt, loop);
- if (pools & T_TEST_WO)
- test_wo<Rec224>(cnt, loop);
- if (pools & T_TEST_RW)
- test_rw<Rec224>(cnt, loop);
- }
- }
-
- cnt += (512 << sz);
- sz++;
- }
-}
-
-Uint32 g_currentStartPhase;
-Uint32 g_start_type;
-NdbNodeBitmask g_nowait_nodes;
-
-void childExit(int code, Uint32 currentStartPhase)
-{
- abort();
-}
-
-void childAbort(int code, Uint32 currentStartPhase)
-{
- abort();
-}
-
-void childReportError(int error)
-{
- abort();
-}
-
-void
-UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
-}
-
-void
-UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){
-}
-
-void
-UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){
-}
-
-void
-UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){
-}
-
-#include <SimBlockList.hpp>
-
-void
-SimBlockList::unload()
-{
-
-}
-
-#define INSTANCE(X) \
-template void test_ap<X>(unsigned, unsigned);\
-template void test_wo<X>(unsigned, unsigned);\
-template void test_rw<X>(unsigned, unsigned);\
-template void test_pool<X, ArrayPool<X> >(ArrayPool<X>&, unsigned, unsigned);\
-template void test_pool<X, RecordPool<X, RWPool> >(RecordPool<X, RWPool>&, unsigned, unsigned); \
-template void test_pool<X, RecordPool<X, WOPool> >(RecordPool<X, WOPool>&, unsigned, unsigned);\
-template void init<X>(ArrayPool<X>&, unsigned);\
-template void init<X>(RecordPool<X, RWPool>&, unsigned);\
-template void init<X>(RecordPool<X, WOPool>&, unsigned)
-
-INSTANCE(Rec32);
-INSTANCE(Rec36);
-INSTANCE(Rec56);
-INSTANCE(Rec224);
-
diff --git a/storage/ndb/src/kernel/vm/mem.txt b/storage/ndb/src/kernel/vm/mem.txt
deleted file mode 100644
index 0ab0ff2a5a9..00000000000
--- a/storage/ndb/src/kernel/vm/mem.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-Structure
-
-Ndbd_mem_allocator
-Handles allocation on 32k blocks
-Provides Buddy allocation of max 8G objects
-
-SuperPool 8k (chunk size 64k)
-GroupPool - Metadata
- DICT::RopePool
-
-GroupPool - Disk operations
- TUP::Page request
- PGMAN::Page request
- LGMAN::Log waiter
- LGMAN::Log syncer
-
-GroupPool - Disk space
- Tsman::Datafile
- Tsman::Tablespace
- Lgman::Undofile
- Lgman::Logfilegroup
- TUP::Extent alloc info
-
-SuperPool 32k
- TUP Undo buffer
- SUMA GCI buffer
- Pgman::PageEntry
-
-Direct Ndbd_mem_allocator
- Pgman::GlobalPage -
- TUP PageMan
- Restore
- Backup
- Lgman::Logbuffer
diff --git a/storage/ndb/src/kernel/vm/ndbd_malloc.cpp b/storage/ndb/src/kernel/vm/ndbd_malloc.cpp
deleted file mode 100644
index 596b30e416b..00000000000
--- a/storage/ndb/src/kernel/vm/ndbd_malloc.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2003, 2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "ndbd_malloc.hpp"
-#include <NdbMem.h>
-
-//#define TRACE_MALLOC
-#ifdef TRACE_MALLOC
-#include <stdio.h>
-#endif
-
-#ifdef TRACE_MALLOC
-static void xxx(size_t size, size_t *s_m, size_t *s_k, size_t *s_b)
-{
- *s_m = size/1024/1024;
- *s_k = (size - *s_m*1024*1024)/1024;
- *s_b = size - *s_m*1024*1024-*s_k*1024;
-}
-#endif
-
-static Uint64 g_allocated_memory;
-void *ndbd_malloc(size_t size)
-{
- void *p = NdbMem_Allocate(size);
- if (p)
- {
- g_allocated_memory += size;
-#ifdef TRACE_MALLOC
- {
- size_t s_m, s_k, s_b;
- xxx(size, &s_m, &s_k, &s_b);
- fprintf(stderr, "%p malloc(%um %uk %ub)", p, s_m, s_k, s_b);
- xxx(g_allocated_memory, &s_m, &s_k, &s_b);
- fprintf(stderr, "\t\ttotal(%um %uk %ub)\n", s_m, s_k, s_b);
- }
-#endif
- }
- return p;
-}
-
-void ndbd_free(void *p, size_t size)
-{
- NdbMem_Free(p);
- if (p)
- {
- g_allocated_memory -= size;
-#ifdef TRACE_MALLOC
- fprintf(stderr, "%p free(%d)\n", p, size);
-#endif
- }
-}
diff --git a/storage/ndb/src/kernel/vm/ndbd_malloc.hpp b/storage/ndb/src/kernel/vm/ndbd_malloc.hpp
deleted file mode 100644
index 52f50daf2ee..00000000000
--- a/storage/ndb/src/kernel/vm/ndbd_malloc.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDBD_MALLOC_H
-#define NDBD_MALLOC_H
-
-/**
- * common memory allocation function for ndbd kernel
- */
-void *ndbd_malloc(size_t size);
-void ndbd_free(void *p, size_t size);
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
deleted file mode 100644
index f96488ada9f..00000000000
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
+++ /dev/null
@@ -1,1016 +0,0 @@
-/* Copyright (c) 2003, 2006-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-#include "ndbd_malloc_impl.hpp"
-#include <ndb_global.h>
-#include <EventLogger.hpp>
-
-#ifndef UNIT_TEST
-extern EventLogger g_eventLogger;
-#else
-extern EventLogger g_eventLogger;
-#endif
-
-static int f_method_idx = 0;
-#ifdef NDBD_MALLOC_METHOD_SBRK
-static const char * f_method = "SMsm";
-#else
-static const char * f_method = "MSms";
-#endif
-#define MAX_CHUNKS 10
-
-#define ZONE_LO 0
-#define ZONE_HI 1
-
-/**
- * POOL_RECORD_BITS == 13 => 32 - 13 = 19 bits for page
- */
-#define ZONE_LO_BOUND (1u << 19)
-
-struct InitChunk
-{
- Uint32 m_cnt;
- Uint32 m_start;
- Alloc_page* m_ptr;
-};
-
-#include <NdbOut.hpp>
-
-static
-bool
-do_malloc(Uint32 pages, InitChunk* chunk)
-{
- pages += 1;
- void * ptr = 0;
- Uint32 sz = pages;
-
-retry:
- char method = f_method[f_method_idx];
- switch(method){
- case 0:
- return false;
- case 'S':
- case 's':
- {
- ptr = 0;
- while (ptr == 0)
- {
- ptr = sbrk(sizeof(Alloc_page) * sz);
-
- if (ptr == (void*)-1)
- {
- if (method == 'S')
- {
- f_method_idx++;
- goto retry;
- }
-
- ptr = 0;
- sz = 1 + (9 * sz) / 10;
- if (pages >= 32 && sz < 32)
- {
- sz = pages;
- f_method_idx++;
- goto retry;
- }
- }
- }
- break;
- }
- case 'M':
- case 'm':
- {
- ptr = 0;
- while (ptr == 0)
- {
- ptr = malloc(sizeof(Alloc_page) * sz);
- if (ptr == 0)
- {
- if (method == 'M')
- {
- f_method_idx++;
- goto retry;
- }
-
- sz = 1 + (9 * sz) / 10;
- if (pages >= 32 && sz < 32)
- {
- f_method_idx++;
- goto retry;
- }
- }
- }
- break;
- }
- default:
- return false;
- }
-
- chunk->m_cnt = sz;
- chunk->m_ptr = (Alloc_page*)ptr;
- const UintPtr align = sizeof(Alloc_page) - 1;
- if (UintPtr(ptr) & align)
- {
- chunk->m_cnt--;
- chunk->m_ptr = (Alloc_page*)((UintPtr(ptr) + align) & ~align);
- }
-
-#ifdef UNIT_TEST
- ndbout_c("do_malloc(%d) -> %p %d", pages, ptr, chunk->m_cnt);
- if (1)
- {
- Uint32 sum = 0;
- Alloc_page* page = chunk->m_ptr;
- for (Uint32 i = 0; i<chunk->m_cnt; i++, page++)
- {
- page->m_data[0*1024] = 0;
- page->m_data[1*1024] = 0;
- page->m_data[2*1024] = 0;
- page->m_data[3*1024] = 0;
- page->m_data[4*1024] = 0;
- page->m_data[5*1024] = 0;
- page->m_data[6*1024] = 0;
- page->m_data[7*1024] = 0;
- }
- }
-#endif
-
- return true;
-}
-
-Uint32
-Ndbd_mem_manager::ndb_log2(Uint32 input)
-{
- input = input | (input >> 8);
- input = input | (input >> 4);
- input = input | (input >> 2);
- input = input | (input >> 1);
- Uint32 output = (input & 0x5555) + ((input >> 1) & 0x5555);
- output = (output & 0x3333) + ((output >> 2) & 0x3333);
- output = output + (output >> 4);
- output = (output & 0xf) + ((output >> 8) & 0xf);
- return output;
-}
-
-Ndbd_mem_manager::Ndbd_mem_manager()
-{
- m_base_page = 0;
- bzero(m_buddy_lists, sizeof(m_buddy_lists));
- bzero(m_resource_limit, sizeof(m_resource_limit));
-
- if (sizeof(Free_page_data) != (4 * (1 << FPD_2LOG)))
- {
- g_eventLogger.error("Invalid build, ndbd_malloc_impl.cpp:%d", __LINE__);
- abort();
- }
-}
-
-/**
- * m_min = reserved
- * m_curr = current
- * m_max = max alloc, 0 = no limit
- */
-
-void
-Ndbd_mem_manager::set_resource_limit(const Resource_limit& rl)
-{
- Uint32 id = rl.m_resource_id;
- assert(id < XX_RL_COUNT);
-
- Uint32 reserve = id ? rl.m_min : 0;
- Uint32 current_reserved = m_resource_limit[0].m_min;
-
- m_resource_limit[id] = rl;
- m_resource_limit[id].m_curr = 0;
- m_resource_limit[0].m_min = current_reserved + reserve;
-}
-
-bool
-Ndbd_mem_manager::get_resource_limit(Uint32 id, Resource_limit& rl) const
-{
- if (id < XX_RL_COUNT)
- {
- rl = m_resource_limit[id];
- return true;
- }
- return false;
-}
-
-static
-inline
-void
-check_resource_limits(Resource_limit* rl)
-{
-#ifdef VM_TRACE
- Uint32 curr = 0;
- Uint32 res_alloc = 0;
- Uint32 shared_alloc = 0;
- Uint32 sumres = 0;
- for (Uint32 i = 1; i<XX_RL_COUNT; i++)
- {
- curr += rl[i].m_curr;
- sumres += rl[i].m_min;
- assert(rl[i].m_max == 0 || rl[i].m_curr <= rl[i].m_max);
- if (rl[i].m_curr > rl[i].m_min)
- {
- shared_alloc += rl[i].m_curr - rl[i].m_min;
- res_alloc += rl[i].m_min;
- }
- else
- {
- res_alloc += rl[i].m_curr;
- }
- }
- assert(curr == rl[0].m_curr);
- assert(res_alloc + shared_alloc == curr);
- assert(res_alloc <= sumres);
- assert(sumres == res_alloc + rl[0].m_min);
- assert(rl[0].m_curr <= rl[0].m_max);
-#endif
-}
-
-
-bool
-Ndbd_mem_manager::init(bool alloc_less_memory)
-{
- assert(m_base_page == 0);
-
- Uint32 pages = 0;
- Uint32 max_page = 0;
- Uint32 reserved = m_resource_limit[0].m_min;
- if (m_resource_limit[0].m_max)
- {
- pages = m_resource_limit[0].m_max;
- }
- else
- {
- pages = m_resource_limit[0].m_min; // reserved
- }
-
- if (m_resource_limit[0].m_min == 0)
- {
- m_resource_limit[0].m_min = pages;
- }
-
- g_eventLogger.info("Ndbd_mem_manager::init(%d) min: %dMb initial: %dMb",
- alloc_less_memory,
- (sizeof(Alloc_page)*m_resource_limit[0].m_min)>>20,
- (sizeof(Alloc_page)*pages)>>20);
-
- if (pages == 0)
- {
- return 0;
- }
-
- /**
- * Do malloc
- */
-
- Uint32 cnt = 0;
- struct InitChunk chunks[MAX_CHUNKS];
- bzero(chunks, sizeof(chunks));
-
- Uint32 allocated = 0;
- while (cnt < MAX_CHUNKS && allocated < pages)
- {
- InitChunk chunk;
- LINT_INIT(chunk.m_start);
-
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
- memset((char*) &chunk, 0 , sizeof(chunk));
-#endif
-
- if (do_malloc(pages - allocated, &chunk))
- {
- Uint32 i = 0;
- for(; i<cnt ; i++)
- {
- if (chunk.m_ptr < chunks[i].m_ptr)
- {
- for (Uint32 j = cnt; j > i; j--)
- chunks[j] = chunks[j-1];
- break;
- }
- }
- cnt++;
- chunks[i] = chunk;
- allocated += chunk.m_cnt;
- }
- else
- {
- break;
- }
- }
-
- if (allocated < m_resource_limit[0].m_min)
- {
- g_eventLogger.
- error("Unable to alloc min memory from OS: min: %lldMb "
- " allocated: %lldMb",
- (Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_min) >> 20,
- (Uint64)(sizeof(Alloc_page)*allocated) >> 20);
- return false;
- }
- else if (allocated < pages)
- {
- g_eventLogger.
- warning("Unable to alloc requested memory from OS: min: %lldMb"
- " requested: %lldMb allocated: %lldMb",
- (Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_min)>>20,
- (Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_max)>>20,
- (Uint64)(sizeof(Alloc_page)*allocated)>>20);
- if (!alloc_less_memory)
- return false;
- }
-
- m_base_page = chunks[0].m_ptr;
-
- for (Uint32 i = 0; i<cnt; i++)
- {
- UintPtr start = UintPtr(chunks[i].m_ptr) - UintPtr(m_base_page);
- start >>= (2 + BMW_2LOG);
- UintPtr last = start + chunks[i].m_cnt;
- chunks[i].m_start = start;
- assert((Uint64(start) >> 32) == 0);
-
- if (last > max_page)
- max_page = last;
- }
-
- m_resource_limit[0].m_resource_id = max_page;
- m_resource_limit[0].m_min = reserved;
- m_resource_limit[0].m_max = 0;
-
- for (Uint32 i = 0; i<cnt; i++)
- {
- grow(chunks[i].m_start, chunks[i].m_cnt);
- }
-
- check_resource_limits(m_resource_limit);
-
- return true;
-}
-
-#include <NdbOut.hpp>
-
-void
-Ndbd_mem_manager::grow(Uint32 start, Uint32 cnt)
-{
- assert(cnt);
- Uint32 start_bmp = start >> BPP_2LOG;
- Uint32 last_bmp = (start + cnt - 1) >> BPP_2LOG;
-
-#if SIZEOF_CHARP == 4
- assert(start_bmp == 0 && last_bmp == 0);
-#endif
-
- if (start_bmp != last_bmp)
- {
- Uint32 tmp = ((start_bmp + 1) << BPP_2LOG) - start;
- grow(start, tmp);
- grow((start_bmp + 1) << BPP_2LOG, cnt - tmp);
- return;
- }
-
- if ((start + cnt) == ((start_bmp + 1) << BPP_2LOG))
- {
- cnt--; // last page is always marked as empty
- }
-
- for (Uint32 i = 0; i<m_used_bitmap_pages.size(); i++)
- if (m_used_bitmap_pages[i] == start_bmp)
- goto found;
-
- if (start != (start_bmp << BPP_2LOG))
- {
-
- ndbout_c("ndbd_malloc_impl.cpp:%d:grow(%d, %d) %d!=%d not using %uMb"
- " - Unable to use due to bitmap pages missaligned!!",
- __LINE__, start, cnt, start, (start_bmp << BPP_2LOG),
- (cnt >> (20 - 15)));
- g_eventLogger.error("ndbd_malloc_impl.cpp:%d:grow(%d, %d) not using %uMb"
- " - Unable to use due to bitmap pages missaligned!!",
- __LINE__, start, cnt,
- (cnt >> (20 - 15)));
-
- dump();
- return;
- }
-
-#ifdef UNIT_TEST
- ndbout_c("creating bitmap page %d", start_bmp);
-#endif
-
- {
- Alloc_page* bmp = m_base_page + start;
- memset(bmp, 0, sizeof(Alloc_page));
- cnt--;
- start++;
- }
- m_used_bitmap_pages.push_back(start_bmp);
-
-found:
- if (cnt)
- {
- m_resource_limit[0].m_curr += cnt;
- m_resource_limit[0].m_max += cnt;
- if (start >= ZONE_LO_BOUND)
- {
- Uint64 mbytes = ((Uint64(cnt) * 32) + 1023) / 1024;
- ndbout_c("Adding %uMb to ZONE_HI (%u,%u)", (Uint32)mbytes, start, cnt);
- release(start, cnt);
- }
- else if (start + cnt <= ZONE_LO_BOUND)
- {
- Uint64 mbytes = ((Uint64(cnt)*32) + 1023) / 1024;
- ndbout_c("Adding %uMb to ZONE_LO (%u,%u)", (Uint32)mbytes, start, cnt);
- release(start, cnt);
- }
- else
- {
- Uint32 cnt0 = ZONE_LO_BOUND - start;
- Uint32 cnt1 = start + cnt - ZONE_LO_BOUND;
- Uint64 mbytes0 = ((Uint64(cnt0)*32) + 1023) / 1024;
- Uint64 mbytes1 = ((Uint64(cnt1)*32) + 1023) / 1024;
- ndbout_c("Adding %uMb to ZONE_LO (split %u,%u)", (Uint32)mbytes0,
- start, cnt0);
- ndbout_c("Adding %uMb to ZONE_HI (split %u,%u)", (Uint32)mbytes1,
- ZONE_LO_BOUND, cnt1);
- release(start, cnt0);
- release(ZONE_LO_BOUND, cnt1);
- }
- }
-}
-
-void
-Ndbd_mem_manager::release(Uint32 start, Uint32 cnt)
-{
- assert(m_resource_limit[0].m_curr >= cnt);
- assert(start);
- m_resource_limit[0].m_curr -= cnt;
-
- set(start, start+cnt-1);
-
- Uint32 zone = start < ZONE_LO_BOUND ? 0 : 1;
- release_impl(zone, start, cnt);
-}
-
-void
-Ndbd_mem_manager::release_impl(Uint32 zone, Uint32 start, Uint32 cnt)
-{
- assert(start);
-
- Uint32 test = check(start-1, start+cnt);
- if (start != ZONE_LO_BOUND && test & 1)
- {
- Free_page_data *fd = get_free_page_data(m_base_page + start - 1,
- start - 1);
- Uint32 sz = fd->m_size;
- Uint32 left = start - sz;
- remove_free_list(zone, left, fd->m_list);
- cnt += sz;
- start = left;
- }
-
- Uint32 right = start + cnt;
- if (right != ZONE_LO_BOUND && test & 2)
- {
- Free_page_data *fd = get_free_page_data(m_base_page+right, right);
- Uint32 sz = fd->m_size;
- remove_free_list(zone, right, fd->m_list);
- cnt += sz;
- }
-
- insert_free_list(zone, start, cnt);
-}
-
-void
-Ndbd_mem_manager::alloc(AllocZone zone,
- Uint32* ret, Uint32 *pages, Uint32 min)
-{
- if (zone == NDB_ZONE_ANY)
- {
- Uint32 save = * pages;
- alloc_impl(ZONE_HI, ret, pages, min);
- if (*pages)
- return;
- * pages = save;
- }
-
- alloc_impl(ZONE_LO, ret, pages, min);
-}
-
-void
-Ndbd_mem_manager::alloc_impl(Uint32 zone,
- Uint32* ret, Uint32 *pages, Uint32 min)
-{
- Int32 i;
- Uint32 start;
- Uint32 cnt = * pages;
- Uint32 list = ndb_log2(cnt - 1);
-
- assert(cnt);
- assert(list <= 16);
-
- for (i = list; i < 16; i++)
- {
- if ((start = m_buddy_lists[zone][i]))
- {
-/* ---------------------------------------------------------------- */
-/* PROPER AMOUNT OF PAGES WERE FOUND. NOW SPLIT THE FOUND */
-/* AREA AND RETURN THE PART NOT NEEDED. */
-/* ---------------------------------------------------------------- */
-
- Uint32 sz = remove_free_list(zone, start, i);
- Uint32 extra = sz - cnt;
- assert(sz >= cnt);
- if (extra)
- {
- insert_free_list(zone, start + cnt, extra);
- clear_and_set(start, start+cnt-1);
- }
- else
- {
- clear(start, start+cnt-1);
- }
- * ret = start;
- assert(m_resource_limit[0].m_curr + cnt <= m_resource_limit[0].m_max);
- return;
- }
- }
-
- /**
- * Could not find in quaranteed list...
- * search in other lists...
- */
-
- Int32 min_list = ndb_log2(min - 1);
- assert((Int32)list >= min_list);
- for (i = list - 1; i >= min_list; i--)
- {
- if ((start = m_buddy_lists[zone][i]))
- {
- Uint32 sz = remove_free_list(zone, start, i);
- Uint32 extra = sz - cnt;
- if (sz > cnt)
- {
- insert_free_list(zone, start + cnt, extra);
- sz -= extra;
- clear_and_set(start, start+sz-1);
- }
- else
- {
- clear(start, start+sz-1);
- }
-
- * ret = start;
- * pages = sz;
- assert(m_resource_limit[0].m_curr + sz <= m_resource_limit[0].m_max);
- return;
- }
- }
- * pages = 0;
-}
-
-void
-Ndbd_mem_manager::insert_free_list(Uint32 zone, Uint32 start, Uint32 size)
-{
- Uint32 list = ndb_log2(size) - 1;
- Uint32 last = start + size - 1;
-
- Uint32 head = m_buddy_lists[zone][list];
- Free_page_data* fd_first = get_free_page_data(m_base_page+start,
- start);
- fd_first->m_list = list;
- fd_first->m_next = head;
- fd_first->m_prev = 0;
- fd_first->m_size = size;
-
- Free_page_data* fd_last = get_free_page_data(m_base_page+last, last);
- fd_last->m_list = list;
- fd_last->m_next = head;
- fd_last->m_prev = 0;
- fd_last->m_size = size;
-
- if (head)
- {
- Free_page_data* fd = get_free_page_data(m_base_page+head, head);
- assert(fd->m_prev == 0);
- assert(fd->m_list == list);
- fd->m_prev = start;
- }
-
- m_buddy_lists[zone][list] = start;
-}
-
-Uint32
-Ndbd_mem_manager::remove_free_list(Uint32 zone, Uint32 start, Uint32 list)
-{
- Free_page_data* fd = get_free_page_data(m_base_page+start, start);
- Uint32 size = fd->m_size;
- Uint32 next = fd->m_next;
- Uint32 prev = fd->m_prev;
- assert(fd->m_list == list);
-
- if (prev)
- {
- assert(m_buddy_lists[zone][list] != start);
- fd = get_free_page_data(m_base_page+prev, prev);
- assert(fd->m_next == start);
- assert(fd->m_list == list);
- fd->m_next = next;
- }
- else
- {
- assert(m_buddy_lists[zone][list] == start);
- m_buddy_lists[zone][list] = next;
- }
-
- if (next)
- {
- fd = get_free_page_data(m_base_page+next, next);
- assert(fd->m_list == list);
- assert(fd->m_prev == start);
- fd->m_prev = prev;
- }
-
- return size;
-}
-
-void
-Ndbd_mem_manager::dump() const
-{
- for (Uint32 zone = 0; zone < 2; zone ++)
- {
- for (Uint32 i = 0; i<16; i++)
- {
- printf(" list: %d - ", i);
- Uint32 head = m_buddy_lists[zone][i];
- while(head)
- {
- Free_page_data* fd = get_free_page_data(m_base_page+head, head);
- printf("[ i: %d prev %d next %d list %d size %d ] ",
- head, fd->m_prev, fd->m_next, fd->m_list, fd->m_size);
- head = fd->m_next;
- }
- printf("EOL\n");
- }
-
- for (Uint32 i = 0; i<XX_RL_COUNT; i++)
- {
- printf("ri: %d min: %d curr: %d max: %d\n",
- i,
- m_resource_limit[i].m_min,
- m_resource_limit[i].m_curr,
- m_resource_limit[i].m_max);
- }
- }
-}
-
-void*
-Ndbd_mem_manager::alloc_page(Uint32 type, Uint32* i, AllocZone zone)
-{
- Uint32 idx = type & RG_MASK;
- assert(idx && idx < XX_RL_COUNT);
- Resource_limit tot = m_resource_limit[0];
- Resource_limit rl = m_resource_limit[idx];
-
- Uint32 cnt = 1;
- Uint32 res0 = (rl.m_curr < rl.m_min) ? 1 : 0;
- Uint32 limit = (rl.m_max == 0 || rl.m_curr < rl.m_max) ? 0 : 1; // Over limit
- Uint32 free = (tot.m_min + tot.m_curr < tot.m_max) ? 1 : 0; // Has free
-
- assert(tot.m_min >= res0);
-
- if (likely(res0 == 1 || (limit == 0 && free == 1)))
- {
- alloc(zone, i, &cnt, 1);
- if (likely(cnt))
- {
- m_resource_limit[0].m_curr = tot.m_curr + cnt;
- m_resource_limit[0].m_min = tot.m_min - res0;
- m_resource_limit[idx].m_curr = rl.m_curr + cnt;
-
- check_resource_limits(m_resource_limit);
- return m_base_page + *i;
- }
- }
-
- return 0;
-}
-
-void
-Ndbd_mem_manager::release_page(Uint32 type, Uint32 i)
-{
- Uint32 idx = type & RG_MASK;
- assert(idx && idx < XX_RL_COUNT);
- Resource_limit tot = m_resource_limit[0];
- Resource_limit rl = m_resource_limit[idx];
-
- Uint32 sub = (rl.m_curr <= rl.m_min) ? 1 : 0; // Over min ?
- release(i, 1);
- m_resource_limit[0].m_curr = tot.m_curr - 1;
- m_resource_limit[0].m_min = tot.m_min + sub;
- m_resource_limit[idx].m_curr = rl.m_curr - 1;
-
- check_resource_limits(m_resource_limit);
-}
-
-void
-Ndbd_mem_manager::alloc_pages(Uint32 type, Uint32* i, Uint32 *cnt, Uint32 min)
-{
- Uint32 idx = type & RG_MASK;
- assert(idx && idx < XX_RL_COUNT);
- Resource_limit tot = m_resource_limit[0];
- Resource_limit rl = m_resource_limit[idx];
-
- Uint32 req = *cnt;
-
- Uint32 max = rl.m_max - rl.m_curr;
- Uint32 res0 = rl.m_min - rl.m_curr;
- Uint32 free_shared = tot.m_max - (tot.m_min + tot.m_curr);
-
- Uint32 res1;
- if (rl.m_curr + req <= rl.m_min)
- {
- // all is reserved...
- res0 = req;
- res1 = 0;
- }
- else
- {
- req = rl.m_max ? max : req;
- res0 = (rl.m_curr > rl.m_min) ? 0 : res0;
- res1 = req - res0;
-
- if (unlikely(res1 > free_shared))
- {
- res1 = free_shared;
- req = res0 + res1;
- }
- }
-
- // req = pages to alloc
- // res0 = portion that is reserved
- // res1 = part that is over reserver
- assert (res0 + res1 == req);
- assert (tot.m_min >= res0);
-
- if (likely(req))
- {
- // Hi order allocations can always use any zone
- alloc(NDB_ZONE_ANY, i, &req, 1);
- * cnt = req;
- if (unlikely(req < res0)) // Got min than what was reserved :-(
- {
- res0 = req;
- }
- assert(tot.m_min >= res0);
- assert(tot.m_curr + req <= tot.m_max);
-
- m_resource_limit[0].m_curr = tot.m_curr + req;
- m_resource_limit[0].m_min = tot.m_min - res0;
- m_resource_limit[idx].m_curr = rl.m_curr + req;
- check_resource_limits(m_resource_limit);
- return ;
- }
- * cnt = req;
- return;
-}
-
-void
-Ndbd_mem_manager::release_pages(Uint32 type, Uint32 i, Uint32 cnt)
-{
- Uint32 idx = type & RG_MASK;
- assert(idx && idx < XX_RL_COUNT);
- Resource_limit tot = m_resource_limit[0];
- Resource_limit rl = m_resource_limit[idx];
-
- release(i, cnt);
-
- Uint32 currnew = rl.m_curr - cnt;
- if (rl.m_curr > rl.m_min)
- {
- if (currnew < rl.m_min)
- {
- m_resource_limit[0].m_min = tot.m_min + (rl.m_min - currnew);
- }
- }
- else
- {
- m_resource_limit[0].m_min = tot.m_min + cnt;
- }
- m_resource_limit[0].m_curr = tot.m_curr - cnt;
- m_resource_limit[idx].m_curr = currnew;
- check_resource_limits(m_resource_limit);
-}
-
-#ifdef UNIT_TEST
-
-#include <Vector.hpp>
-#include <NdbTick.h>
-
-struct Chunk {
- Uint32 pageId;
- Uint32 pageCount;
-};
-
-struct Timer
-{
- Uint64 sum;
- Uint32 cnt;
-
- Timer() { sum = cnt = 0;}
-
- struct timeval st;
-
- void start() {
- gettimeofday(&st, 0);
- }
-
- Uint64 calc_diff() {
- struct timeval st2;
- gettimeofday(&st2, 0);
- Uint64 diff = st2.tv_sec;
- diff -= st.tv_sec;
- diff *= 1000000;
- diff += st2.tv_usec;
- diff -= st.tv_usec;
- return diff;
- }
-
- void stop() {
- add(calc_diff());
- }
-
- void add(Uint64 diff) { sum += diff; cnt++;}
-
- void print(const char * title) const {
- float ps = sum;
- ps /= cnt;
- printf("%s %fus/call %lld %d\n", title, ps, sum, cnt);
- }
-};
-
-int
-main(int argc, char** argv)
-{
- int sz = 1*32768;
- int run_time = 30;
- if (argc > 1)
- sz = 32*atoi(argv[1]);
-
- if (argc > 2)
- run_time = atoi(argv[2]);
-
- char buf[255];
- Timer timer[4];
- printf("Startar modul test av Page Manager %dMb %ds\n",
- (sz >> 5), run_time);
- g_eventLogger.createConsoleHandler();
- g_eventLogger.setCategory("keso");
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_INFO);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_CRITICAL);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_WARNING);
-
-#define DEBUG 0
-
- Ndbd_mem_manager mem;
- Resource_limit rl;
- rl.m_min = 0;
- rl.m_max = sz;
- rl.m_curr = 0;
- rl.m_resource_id = 0;
- mem.set_resource_limit(rl);
- rl.m_min = sz < 16384 ? sz : 16384;
- rl.m_max = 0;
- rl.m_resource_id = 1;
- mem.set_resource_limit(rl);
-
- mem.init();
- mem.dump();
- printf("pid: %d press enter to continue\n", getpid());
- fgets(buf, sizeof(buf), stdin);
- Vector<Chunk> chunks;
- time_t stop = time(0) + run_time;
- for(Uint32 i = 0; time(0) < stop; i++){
- //mem.dump();
-
- // Case
- Uint32 c = (rand() % 100);
- if (c < 50)
- {
- c = 0;
- }
- else if (c < 93)
- {
- c = 1;
- }
- else
- {
- c = 2;
- }
-
- Uint32 alloc = 1 + rand() % 3200;
-
- if(chunks.size() == 0 && c == 0)
- {
- c = 1 + rand() % 2;
- }
-
- if(DEBUG)
- printf("loop=%d ", i);
- switch(c){
- case 0:{ // Release
- const int ch = rand() % chunks.size();
- Chunk chunk = chunks[ch];
- chunks.erase(ch);
- timer[0].start();
- Uint64 start = NdbTick_CurrentMillisecond();
- mem.release(chunk.pageId, chunk.pageCount);
- timer[0].stop();
- if(DEBUG)
- printf(" release %d %d\n", chunk.pageId, chunk.pageCount);
- }
- break;
- case 2: { // Seize(n) - fail
- alloc += sz;
- // Fall through
- }
- case 1: { // Seize(n) (success)
- Chunk chunk;
- chunk.pageCount = alloc;
- if (DEBUG)
- {
- printf(" alloc %d -> ", alloc); fflush(stdout);
- }
- timer[0].start();
- mem.alloc(&chunk.pageId, &chunk.pageCount, 1);
- Uint64 diff = timer[0].calc_diff();
-
- if (DEBUG)
- printf("%d %d", chunk.pageId, chunk.pageCount);
- assert(chunk.pageCount <= alloc);
- if(chunk.pageCount != 0){
- chunks.push_back(chunk);
- if(chunk.pageCount != alloc) {
- timer[2].add(diff);
- if (DEBUG)
- printf(" - Tried to allocate %d - only allocated %d - free: %d",
- alloc, chunk.pageCount, 0);
- }
- else
- {
- timer[1].add(diff);
- }
- } else {
- timer[3].add(diff);
- if (DEBUG)
- printf(" Failed to alloc %d pages with %d pages free",
- alloc, 0);
- }
- if (DEBUG)
- printf("\n");
- }
- break;
- }
- }
- if (!DEBUG)
- while(chunks.size() > 0){
- Chunk chunk = chunks.back();
- mem.release(chunk.pageId, chunk.pageCount);
- chunks.erase(chunks.size() - 1);
- }
-
- const char *title[] = {
- "release ",
- "alloc full",
- "alloc part",
- "alloc fail"
- };
- for(Uint32 i = 0; i<4; i++)
- timer[i].print(title[i]);
-
- mem.dump();
-}
-
-template class Vector<Chunk>;
-
-#endif
-template class Vector<Uint32>;
diff --git a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp b/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
deleted file mode 100644
index e820d1303d3..00000000000
--- a/storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright (c) 2003, 2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDBD_MALLOC_IMPL_H
-#define NDBD_MALLOC_IMPL_H
-
-#include <kernel_types.h>
-#include <Bitmask.hpp>
-#include <assert.h>
-#include "Pool.hpp"
-#include <Vector.hpp>
-
-/**
- * 13 -> 8192 words -> 32768 bytes
- * 18 -> 262144 words -> 1M
- */
-#define BMW_2LOG 13
-#define BITMAP_WORDS (1 << BMW_2LOG)
-
-#define BPP_2LOG (BMW_2LOG + 5)
-#define SPACE_PER_BMP_2LOG ((2 + BMW_2LOG) + BPP_2LOG)
-
-//#define BITMAP_WORDS GLOBAL_PAGE_SIZE_WORDS
-
-struct Alloc_page
-{
- Uint32 m_data[BITMAP_WORDS];
-};
-
-struct Free_page_data
-{
- Uint32 m_list;
- Uint32 m_next;
- Uint32 m_prev;
- Uint32 m_size;
-};
-
-#define FPD_2LOG 2
-
-class Ndbd_mem_manager
-{
-public:
- Ndbd_mem_manager();
-
- void set_resource_limit(const Resource_limit& rl);
- bool get_resource_limit(Uint32 id, Resource_limit& rl) const;
-
- bool init(bool allow_alloc_less_than_requested = true);
- void* get_memroot() const { return (void*)m_base_page;}
-
- void dump() const ;
-
- enum AllocZone
- {
- NDB_ZONE_LO = 0, // Only allocate with page_id < (1 << 13)
- NDB_ZONE_ANY = 1 // Allocate with any page_id
- };
-
- void* alloc_page(Uint32 type, Uint32* i, enum AllocZone);
- void release_page(Uint32 type, Uint32 i);
-
- void alloc_pages(Uint32 type, Uint32* i, Uint32 *cnt, Uint32 min = 1);
- void release_pages(Uint32 type, Uint32 i, Uint32 cnt);
-
- /**
- * Compute 2log of size
- * @note size = 0 -> 0
- * @note size > 65536 -> 16
- */
- static Uint32 ndb_log2(Uint32 size);
-
-private:
- void grow(Uint32 start, Uint32 cnt);
-
-#define XX_RL_COUNT 4
- /**
- * Return pointer to free page data on page
- */
- static Free_page_data* get_free_page_data(Alloc_page*, Uint32 idx);
- Vector<Uint32> m_used_bitmap_pages;
-
- Uint32 m_buddy_lists[2][16];
- Resource_limit m_resource_limit[XX_RL_COUNT]; // RG_COUNT in record_types.hpp
- Alloc_page * m_base_page;
-
- void release_impl(Uint32 zone, Uint32 start, Uint32 cnt);
- void insert_free_list(Uint32 zone, Uint32 start, Uint32 cnt);
- Uint32 remove_free_list(Uint32 zone, Uint32 start, Uint32 list);
-
- void set(Uint32 first, Uint32 last);
- void clear(Uint32 first, Uint32 last);
- void clear_and_set(Uint32 first, Uint32 last);
- Uint32 check(Uint32 first, Uint32 last);
-
- void alloc(AllocZone, Uint32* ret, Uint32 *pages, Uint32 min_requested);
- void alloc_impl(Uint32 zone, Uint32* ret, Uint32 *pages, Uint32 min);
- void release(Uint32 start, Uint32 cnt);
-};
-
-inline
-Free_page_data*
-Ndbd_mem_manager::get_free_page_data(Alloc_page* ptr, Uint32 idx)
-{
- assert(idx & ((1 << BPP_2LOG) - 1));
- assert((idx & ((1 << BPP_2LOG) - 1)) != ((1 << BPP_2LOG) - 1));
-
- return (Free_page_data*)
- (ptr->m_data + ((idx & ((BITMAP_WORDS >> FPD_2LOG) - 1)) << FPD_2LOG));
-}
-
-inline
-void
-Ndbd_mem_manager::set(Uint32 first, Uint32 last)
-{
- Alloc_page * ptr = m_base_page;
-#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
- Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
- assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
- assert(bmp < m_resource_limit[0].m_resource_id);
-
- first -= bmp;
- last -= bmp;
- ptr += bmp;
-#endif
- BitmaskImpl::set(BITMAP_WORDS, ptr->m_data, first);
- BitmaskImpl::set(BITMAP_WORDS, ptr->m_data, last);
-}
-
-inline
-void
-Ndbd_mem_manager::clear(Uint32 first, Uint32 last)
-{
- Alloc_page * ptr = m_base_page;
-#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
- Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
- assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
- assert(bmp < m_resource_limit[0].m_resource_id);
-
- first -= bmp;
- last -= bmp;
- ptr += bmp;
-#endif
- BitmaskImpl::clear(BITMAP_WORDS, ptr->m_data, first);
- BitmaskImpl::clear(BITMAP_WORDS, ptr->m_data, last);
-}
-
-inline
-void
-Ndbd_mem_manager::clear_and_set(Uint32 first, Uint32 last)
-{
- Alloc_page * ptr = m_base_page;
-#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
- Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
- assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
- assert(bmp < m_resource_limit[0].m_resource_id);
-
- first -= bmp;
- last -= bmp;
- ptr += bmp;
-#endif
- BitmaskImpl::clear(BITMAP_WORDS, ptr->m_data, first);
- BitmaskImpl::clear(BITMAP_WORDS, ptr->m_data, last);
- BitmaskImpl::set(BITMAP_WORDS, ptr->m_data, last+1);
-}
-
-inline
-Uint32
-Ndbd_mem_manager::check(Uint32 first, Uint32 last)
-{
- Uint32 ret = 0;
- Alloc_page * ptr = m_base_page;
-#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
- Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
- assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
- assert(bmp < m_resource_limit[0].m_resource_id);
-
- first -= bmp;
- last -= bmp;
- ptr += bmp;
-#endif
- ret |= BitmaskImpl::get(BITMAP_WORDS, ptr->m_data, first) << 0;
- ret |= BitmaskImpl::get(BITMAP_WORDS, ptr->m_data, last) << 1;
- return ret;
-}
-
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/pc.hpp b/storage/ndb/src/kernel/vm/pc.hpp
deleted file mode 100644
index 8be09ca91e4..00000000000
--- a/storage/ndb/src/kernel/vm/pc.hpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Copyright (c) 2003-2006, 2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef PC_H
-#define PC_H
-
-
-#include "Emulator.hpp"
-#include <NdbOut.hpp>
-#include <ndb_limits.h>
-
-#ifdef NO_EMULATED_JAM
-
-#define jam()
-#define jamLine(line)
-#define jamEntry()
-#define jamEntryLine(line)
-
-#else
-#ifdef NDB_WIN32
-
-#define jam() { \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = __LINE__; \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamLine(line) { \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = line; \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamEntry() { \
- theEmulatedJamBlockNumber = number(); \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | __LINE__); \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamEntryLine(line) { \
- theEmulatedJamBlockNumber = number(); \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | (line)); \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-
-#else
-
-#define jam() { \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = __LINE__; \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamLine(line) { \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = line; \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamEntry() { \
- theEmulatedJamBlockNumber = number(); \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | __LINE__); \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-#define jamEntryLine(line) { \
- theEmulatedJamBlockNumber = number(); \
- Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
- *(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = \
- ((theEmulatedJamBlockNumber << 20) | (line)); \
- theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
-
-#endif
-
-#endif
-#ifndef NDB_OPT
-#define ptrCheck(ptr, limit, rec) if (ptr.i < (limit)) ptr.p = &rec[ptr.i]; else ptr.p = NULL
-
-/**
- * Sets the p-value of a ptr-struct to be a pointer to record no i
- * (where i is the i-value of the ptr-struct)
- *
- * @param ptr ptr-struct with a set i-value (the p-value in this gets set)
- * @param limit max no of records in rec
- * @param rec pointer to first record in an array of records
- */
-#define ptrCheckGuardErr(ptr, limit, rec, error) {\
- UintR TxxzLimit; \
- TxxzLimit = (limit); \
- UintR TxxxPtr; \
- TxxxPtr = ptr.i; \
- ptr.p = &rec[TxxxPtr]; \
- if (TxxxPtr < (TxxzLimit)) { \
- ; \
- } else { \
- progError(__LINE__, error, __FILE__); \
- }}
-#define ptrAss(ptr, rec) ptr.p = &rec[ptr.i]
-#define ptrNull(ptr) ptr.p = NULL
-#define ptrGuardErr(ptr, error) if (ptr.p == NULL) \
- progError(__LINE__, error, __FILE__)
-#define arrGuardErr(ind, size, error) if ((ind) >= (size)) \
- progError(__LINE__, error, __FILE__)
-#else
-#define ptrCheck(ptr, limit, rec) ptr.p = &rec[ptr.i]
-#define ptrCheckGuardErr(ptr, limit, rec, error) ptr.p = &rec[ptr.i]
-#define ptrAss(ptr, rec) ptr.p = &rec[ptr.i]
-#define ptrNull(ptr) ptr.p = NULL
-#define ptrGuardErr(ptr, error)
-#define arrGuardErr(ind, size, error)
-#endif
-
-#define ptrCheckGuard(ptr, limit, rec) \
- ptrCheckGuardErr(ptr, limit, rec, NDBD_EXIT_POINTER_NOTINRANGE)
-#define ptrGuard(ptr) ptrGuardErr(ptr, NDBD_EXIT_POINTER_NOTINRANGE)
-#define arrGuard(ind, size) arrGuardErr(ind, size, NDBD_EXIT_INDEX_NOTINRANGE)
-
-// -------- ERROR INSERT MACROS -------
-#ifdef ERROR_INSERT
-#define ERROR_INSERT_VARIABLE UintR cerrorInsert
-#define ERROR_INSERTED(x) (cerrorInsert == (x))
-#define ERROR_INSERTED_CLEAR(x) (cerrorInsert == (x) ? (cerrorInsert = 0, true) : false)
-#define SET_ERROR_INSERT_VALUE(x) cerrorInsert = x
-#define CLEAR_ERROR_INSERT_VALUE cerrorInsert = 0
-#else
-#define ERROR_INSERT_VARIABLE typedef void * cerrorInsert // Will generate compiler error if used
-#define ERROR_INSERTED(x) false
-#define ERROR_INSERTED_CLEAR(x) false
-#define SET_ERROR_INSERT_VALUE(x)
-#define CLEAR_ERROR_INSERT_VALUE
-#endif
-
-/* ------------------------------------------------------------------------- */
-/* COMMONLY USED CONSTANTS. */
-/* ------------------------------------------------------------------------- */
-#define ZFALSE 0
-#define ZTRUE 1
-#define ZSET 1
-#define ZOK 0
-#define ZNOT_OK 1
-#define ZCLOSE_FILE 2
-#define ZNIL 0xffff
-#define Z8NIL 255
-
-/* ------------------------------------------------------------------------- */
-// Number of fragments stored per node. Should be settable on a table basis
-// in future version since small tables want small value and large tables
-// need large value.
-/* ------------------------------------------------------------------------- */
-#define NO_OF_FRAG_PER_NODE 1
-#define MAX_FRAG_PER_NODE 8
-
-/**
-* DIH allocates fragments in chunk for fast find of fragment record.
-* These parameters define chunk size and log of chunk size.
-*/
-#define NO_OF_FRAGS_PER_CHUNK 4
-#define LOG_NO_OF_FRAGS_PER_CHUNK 2
-
-/* ---------------------------------------------------------------- */
-// To avoid synching too big chunks at a time we synch after writing
-// a certain number of data/UNDO pages. (e.g. 2 MBytes).
-/* ---------------------------------------------------------------- */
-#define MAX_REDO_PAGES_WITHOUT_SYNCH 32
-
-/* ------------------------------------------------------------------ */
-// We have these constants to ensure that we can easily change the
-// parallelism of node recovery and the amount of scan
-// operations needed for node recoovery.
-/* ------------------------------------------------------------------ */
-#define MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT 6000
-#define MAGIC_CONSTANT 56
-#define NODE_RECOVERY_SCAN_OP_RECORDS \
- (4 + ((4*MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT)/ \
- ((MAGIC_CONSTANT + 2) * 5)))
-
-#ifdef NO_CHECKPOINT
-#define NO_LCP
-#define NO_GCP
-#endif
-
-/**
- * Ndb kernel blocks assertion handling
- *
- * Two type of assertions:
- * - ndbassert - Only used when compiling VM_TRACE
- * - ndbrequire - Always checked
- *
- * If a ndbassert/ndbrequire fails, the system will
- * shutdown and generate an error log
- *
- *
- * NOTE these may only be used within blocks
- */
-#if defined VM_TRACE
-#define ndbassert(check) \
- if(likely(check)){ \
- } else { \
- progError(__LINE__, NDBD_EXIT_NDBASSERT, __FILE__); \
- }
-#else
-#define ndbassert(check)
-#endif
-
-#define ndbrequireErr(check, error) \
- if(likely(check)){ \
- } else { \
- progError(__LINE__, error, __FILE__); \
- }
-
-#define ndbrequire(check) \
- ndbrequireErr(check, NDBD_EXIT_NDBREQUIRE)
-
-#define CRASH_INSERTION(errorType) \
- if (!ERROR_INSERTED((errorType))) { \
- } else { \
- progError(__LINE__, NDBD_EXIT_ERROR_INSERT, __FILE__); \
- }
-
-#define CRASH_INSERTION2(errorNum, condition) \
- if (!(ERROR_INSERTED(errorNum) && condition)) { \
- } else { \
- progError(__LINE__, NDBD_EXIT_ERROR_INSERT, __FILE__); \
- }
-
-#define MEMCOPY_PAGE(to, from, page_size_in_bytes) \
- memcpy((void*)(to), (void*)(from), (size_t)(page_size_in_bytes));
-#define MEMCOPY_NO_WORDS(to, from, no_of_words) \
- memcpy((to), (void*)(from), (size_t)((no_of_words) << 2));
-
-#endif
diff --git a/storage/ndb/src/kernel/vm/testCopy/Makefile b/storage/ndb/src/kernel/vm/testCopy/Makefile
deleted file mode 100644
index 5abd93eb74f..00000000000
--- a/storage/ndb/src/kernel/vm/testCopy/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include .defs.mk
-
-TYPE := util
-
-BIN_TARGET := testCopy
-
-SOURCES = testCopy.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/vm/testCopy/rr.cpp b/storage/ndb/src/kernel/vm/testCopy/rr.cpp
deleted file mode 100644
index bb0521357ea..00000000000
--- a/storage/ndb/src/kernel/vm/testCopy/rr.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <sched.h>
-
-int
-main(int argc, char * const argv[]){
- struct sched_param p;
- p.sched_priority = 1;
-
- int ret = sched_setscheduler(getpid(), SCHED_RR, &p);
- printf("ref = %d\n", ret);
-
- execv(argv[1], &argv[1]);
- return 0;
-}
diff --git a/storage/ndb/src/kernel/vm/testCopy/testCopy.cpp b/storage/ndb/src/kernel/vm/testCopy/testCopy.cpp
deleted file mode 100644
index ef7f3277174..00000000000
--- a/storage/ndb/src/kernel/vm/testCopy/testCopy.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-#ifdef __NDB_FORTE6
-#define HAND
-bool hand = true;
-#else
-bool hand = false;
-#endif
-
-struct Data7 {
- Uint32 data[7];
-
-#ifdef HAND
- inline Data7& operator=(const Data7 & o){
- Uint32 t0 = o.data[0];
- Uint32 t1 = o.data[1];
- Uint32 t2 = o.data[2];
- Uint32 t3 = o.data[3];
- Uint32 t4 = o.data[4];
- Uint32 t5 = o.data[5];
- Uint32 t6 = o.data[6];
- data[0] = t0;
- data[1] = t1;
- data[2] = t2;
- data[3] = t3;
- data[4] = t4;
- data[5] = t5;
- data[6] = t6;
- return * this;
- }
-#endif
-};
-
-struct Data25 {
- Uint32 data[25];
-};
-
-struct TestSignal {
-
- Data7 head;
- Data25 data;
-};
-
-Uint32 g_time = 3000;
-Uint32 g_count = 8*2048;
-
-TestSignal g_signal;
-TestSignal * g_jobBuffer;
-
-template<Uint32 LEN>
-inline
-void
-MEMCOPY(Uint32 * to, const Uint32 * from){
- Uint32 t0 ;
- Uint32 t1 ;
- Uint32 t2 ;
- Uint32 t3 ;
- Uint32 len = LEN;
- while(len > 4){
- t0 = from[0];
- t1 = from[1];
- t2 = from[2];
- t3 = from[3];
-
- to[0] = t0;
- to[1] = t1;
- to[2] = t2;
- to[3] = t3;
-
-
- to += 4;
- from += 4;
- len -= 4;
- }
-
- //ndbout_c("len = %d", len);
-
- t0 = from[0];
- t1 = from[1];
- t2 = from[2];
- switch(len & 3){
- case 3:
- //ndbout_c("3");
- to[2] = t2;
- case 2:
- //ndbout_c("2");
- to[1] = t1;
- case 1:
- //ndbout_c("1");
- to[0] = t0;
- }
-
-}
-
-inline
-void
-MEMCOPY_NO_WORDS(Uint32 * to, const Uint32 * from, Uint32 len){
- Uint32 t0 ;
- Uint32 t1 ;
- Uint32 t2 ;
- Uint32 t3 ;
- while(len > 4){
- t0 = from[0];
- t1 = from[1];
- t2 = from[2];
- t3 = from[3];
-
- to[0] = t0;
- to[1] = t1;
- to[2] = t2;
- to[3] = t3;
-
-
- to += 4;
- from += 4;
- len -= 4;
- }
-
- //ndbout_c("len = %d", len);
-
- t0 = from[0];
- t1 = from[1];
- t2 = from[2];
- switch(len & 3){
- case 3:
- //ndbout_c("3");
- to[2] = t2;
- case 2:
- //ndbout_c("2");
- to[1] = t1;
- case 1:
- //ndbout_c("1");
- to[0] = t0;
- }
-}
-
-inline
-void
-copy1(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- Uint32 t0 = ts.head.data[0];
- Uint32 t1 = ts.head.data[1];
- Uint32 t2 = ts.head.data[2];
- Uint32 t3 = ts.head.data[3];
- Uint32 t4 = ts.head.data[4];
- Uint32 t5 = ts.head.data[5];
- Uint32 t6 = ts.head.data[6];
-
- dst.head.data[0] = t0;
- dst.head.data[1] = t1;
- dst.head.data[2] = t2;
- dst.head.data[3] = t3;
- dst.head.data[4] = t4;
- dst.head.data[5] = t5;
- dst.head.data[6] = t6;
-}
-
-
-
-inline
-void
-copy2(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- Uint32 t0 = ts.head.data[0];
- Uint32 t1 = ts.head.data[1];
- Uint32 t2 = ts.head.data[2];
- Uint32 t3 = ts.head.data[3];
-
- dst.head.data[0] = t0;
- dst.head.data[1] = t1;
- dst.head.data[2] = t2;
- dst.head.data[3] = t3;
-
- Uint32 t4 = ts.head.data[4];
- Uint32 t5 = ts.head.data[5];
- Uint32 t6 = ts.head.data[6];
-
- dst.head.data[4] = t4;
- dst.head.data[5] = t5;
- dst.head.data[6] = t6;
-}
-
-inline
-void
-copy3(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- dst.head = ts.head;
-}
-
-inline
-void
-copy4(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- memcpy(&dst.head.data[0], &ts.head.data[0], sizeof(Data7));
-}
-
-inline
-void
-copy5(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- MEMCOPY_NO_WORDS(&dst.head.data[0], &ts.head.data[0], 7);
-}
-
-inline
-void
-copy6(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
- MEMCOPY<7>(&dst.head.data[0], &ts.head.data[0]);
-}
-
-inline
-void
-copy7(Uint32 i, TestSignal & ts){
- TestSignal & dst = g_jobBuffer[i];
-
-#if (__GNUC__ >= 3 ) || (__GNUC__ == 2 && __GNUC_MINOR >= 95)
- __builtin_memcpy(&dst.head.data[0], &ts.head.data[0], sizeof(Data7));
-#else
- dst.head = ts.head;
-#endif
-}
-
-template<void (* C)(Uint32 i, TestSignal & ts)>
-int
-doTime(Uint32 ms){
-
- Uint64 ms1, ms2;
- const Uint32 count = g_count;
- for(Uint32 i = 0; i<count; i++)
- C(i, g_signal);
- for(Uint32 i = 0; i<count; i++)
- C(i, g_signal);
-
- Uint32 laps = 0;
-
- ms1 = NdbTick_CurrentMillisecond();
- do {
- for(int j = 100; j>= 0; j--)
- for(Uint32 i = 0; i<count; i++){
- C(i, g_signal);
- }
- ms2 = NdbTick_CurrentMillisecond();
- laps += 100;
- } while((ms2 - ms1) < ms);
-
- return laps;
-}
-
-
-template<void (* C)(Uint32 i, TestSignal & ts)>
-void doCopyLap(Uint32 laps, const char * title){
-
- Uint64 ms1, ms2;
- const Uint32 count = g_count;
- for(Uint32 i = 0; i<count; i++)
- C(i, g_signal);
- laps--;
- for(Uint32 i = 0; i<count; i++)
- C(i, g_signal);
- laps--;
-
- Uint32 div = laps;
-
- ms1 = NdbTick_CurrentMillisecond();
- while(laps > 0){
- for(Uint32 i = 0; i<count; i++){
-#if (__GNUC__ == 3 && __GNUC_MINOR >= 1)
- _builtin_prefetch(&g_jobBuffer[i], 1, 0);
-#endif
- C(i, g_signal);
- }
- laps--;
- }
- ms2 = NdbTick_CurrentMillisecond();
-
- ms2 -= ms1;
- Uint32 diff = ms2;
- ndbout_c("%s : %d laps in %d millis => %d copies/sec",
- title, div, diff, (1000*div*g_count+(diff/2))/diff);
-}
-
-int
-main(int argc, const char ** argv){
-
- if(argc > 1)
- g_count = atoi(argv[1]);
-
- if(argc > 2)
- g_time = atoi(argv[2]);
-
- ndbout_c("Using %d entries => %d kB ",
- g_count,
- g_count * sizeof(TestSignal) / 1024);
- ndbout_c("Testing for %d ms", g_time);
-
- ndbout_c("Using %s copy-constructor",
- (hand ? "hand written" : "compiler generated"));
-
- g_jobBuffer = new TestSignal[g_count + 1];
- for(int i = 0; i<10; i++)
- memset(g_jobBuffer, 0, g_count * sizeof(TestSignal));
-
- int laps = doTime<copy2>(g_time);
- ndbout_c("Laps = %d", laps);
-
- doCopyLap<copy2>(laps, "4 t-variables");
- doCopyLap<copy3>(laps, "copy constr. ");
- doCopyLap<copy1>(laps, "7 t-variables");
- doCopyLap<copy4>(laps, "mem copy ");
- doCopyLap<copy5>(laps, "mem copy hand");
- doCopyLap<copy6>(laps, "mem copy temp");
- doCopyLap<copy7>(laps, "mem copy gcc ");
-
- delete[] g_jobBuffer;
- return 0;
-}
diff --git a/storage/ndb/src/kernel/vm/testDataBuffer/Makefile b/storage/ndb/src/kernel/vm/testDataBuffer/Makefile
deleted file mode 100644
index 693989dfe3c..00000000000
--- a/storage/ndb/src/kernel/vm/testDataBuffer/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include .defs.mk
-
-TYPE := kernel
-
-BIN_TARGET := testKernelDataBuffer
-BIN_TARGET_ARCHIVES := general portlib
-
-SOURCES = testDataBuffer.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp b/storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp
deleted file mode 100644
index 03233f72ff8..00000000000
--- a/storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbTick.h>
-#include <DataBuffer.hpp>
-
-#undef test
-
-struct Buffer {
- Buffer(Uint32 size){ m_sz = size; buffer = new Uint32[m_sz]; m_len = 0;}
- ~Buffer(){ delete [] buffer;}
-
- Uint32 m_sz;
- Uint32 m_len;
- Uint32 * buffer;
-};
-
-inline
-void
-require(bool b){
- if(!b)
- abort();
-}
-
-template<Uint32 sz>
-void
-compare(DataBuffer<sz> & db, Buffer & buf){
- typename DataBuffer<sz>::DataBufferIterator it;
- db.first(it);
- for(Uint32 i = 0; i<buf.m_len; i++){
- if(buf.buffer[i] != * it.data){
- db.print(stdout);
- abort();
- }
- db.next(it);
- }
-
- for(Uint32 i = 0; i<buf.m_len; i++){
- if(!db.position(it, i))
- abort();
- if(buf.buffer[i] != * it.data){
- db.print(stdout);
- abort();
- }
- }
-}
-
-template<Uint32 sz>
-void
-test(Uint32 loops, Uint32 iter){
-
- ndbout_c("DataBuffer<%d> loops=%d iter=%d", sz, loops, iter);
-
- while(loops-- > 0){
- Uint32 size = sz*((10 + (rand() % (10 * sz)) + sz - 1)/sz);
-
- typename DataBuffer<sz>::DataBufferPool thePool;
- typename DataBuffer<sz>::DataBufferIterator it;
- DataBuffer<sz> db(thePool);
-
- thePool.setSize((size + sz - 1) / sz);
- Buffer buf(size);
-
- bool testOverRun = true;
-
- for(Uint32 i = 0; i<iter; i++){
- Uint32 c = (rand() % (testOverRun ? 7 : 4));
- Uint32 free = (size - db.getSize());
- Uint32 alloc = 0;
- if(free == 0){
- c = (testOverRun ? c : 0);
- if(c >= 1 && c <= 3)
- c += 3;
- }
-
- if(free <= 1)
- alloc = 1;
- else
- alloc = 1 + (rand() % (free - 1));
-
- //ndbout_c("iter=%d case=%d free=%d alloc=%d", i, c, free, alloc);
- switch(c){
- case 0: // Release
- db.first(it);
- for(; !it.curr.isNull(); db.next(it))
- * it.data = 0;
-
- db.release();
- buf.m_len = 0;
- break;
- case 1:{ // Append (success)
- for(Uint32 i = 0; i<alloc; i++)
- buf.buffer[buf.m_len + i] = buf.m_len + i;//rand();
-
- require(db.append(&buf.buffer[buf.m_len], alloc));
- buf.m_len += alloc;
- break;
- }
- case 2: { // Seize(1) (success)
- for(Uint32 i = 0; i<alloc; i++){
- buf.buffer[buf.m_len + i] = buf.m_len + i;//rand();
- require(db.seize(1));
- require(db.position(it, db.getSize()-1));
- * it.data = buf.buffer[buf.m_len + i];
- }
- buf.m_len += alloc;
- break;
- }
- case 3: { // Seize(n) (success)
- for(Uint32 i = 0; i<alloc; i++){
- buf.buffer[buf.m_len + i] = buf.m_len + i;//rand();
- }
- Uint32 pos = db.getSize();
- require(db.seize(alloc));
- require(db.position(it, pos));
- for(Uint32 i = 0; i<alloc; i++){
- * it.data = buf.buffer[buf.m_len + i];
- db.next(it);
- }
- buf.m_len += alloc;
- break;
- }
- case 4: { // Append fail
- require(!db.append(buf.buffer, alloc + free));
- require(db.getSize() == 0);
- buf.m_len = 0;
- break;
- }
- case 5: { // Seize(1) - fail
- for(Uint32 i = 0; i<free; i++){
- require(db.seize(1));
- }
-
- require(!db.seize(1));
- require(db.getSize() == 0);
- buf.m_len = 0;
- break;
- }
- case 6: { // Seize(n) - fail
- require(!db.seize(alloc + free));
- require(db.getSize() == 0);
- buf.m_len = 0;
- break;
- }
- }
- compare(db, buf);
- }
- }
-}
-
-int
-main(void){
-
- srand(NdbTick_CurrentMillisecond());
-
-
- test<1>(1000, 1000);
- test<11>(1000, 1000);
- test<15>(1000, 1000);
- test<16>(1000, 1000);
- test<17>(1000, 1000);
-#if 0
-#endif
- return 0;
-}
-
-void
-ErrorReporter::handleAssert(const char * msg, const char * file, int line)
-{
- ndbout << "ErrorReporter::handleAssert activated - "
- << " line= " << line << endl;
- abort();
-}
diff --git a/storage/ndb/src/kernel/vm/testLongSig/Makefile b/storage/ndb/src/kernel/vm/testLongSig/Makefile
deleted file mode 100644
index ecf33dca109..00000000000
--- a/storage/ndb/src/kernel/vm/testLongSig/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include .defs.mk
-
-TYPE := signalsender
-
-BIN_TARGET := testLongSig
-
-SOURCES = testLongSig.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp b/storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp
deleted file mode 100644
index cc5c3286168..00000000000
--- a/storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <editline/editline.h>
-#include <SignalSender.hpp>
-
-void
-print_help(){
- ndbout << "The test menu" << endl;
- ndbout << "1 - Sending of long signals w/ segmented sections" << endl;
- ndbout << "2 - As 1 but using receiver group" << endl;
- ndbout << "3 - Sending of long signals w/ linear sections" << endl;
- ndbout << "4 - As 3 but using receiver group" << endl;
- ndbout << "5 - Sending of manually fragmented signals w/ segmented sections"
- << endl;
- ndbout << "6 - As 5 but using receiver group" << endl;
- ndbout << "7 - Sending of manually fragmented signals w/ linear sections"
- << endl;
- ndbout << "8 - As but using receiver group" << endl;
-
- ndbout << "9 - Sending of CONTINUEB fragmented signals w/ segmented sections"
- << endl;
- ndbout << "10 - As 9 but using receiver group" << endl;
- 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;
- ndbout << "c - Run tests 1 - 12 with variable sizes - 1000k loops" << endl;
-}
-
-void runTest(SignalSender &, Uint32 i, bool verbose);
-
-static
-int
-randRange(Uint32 min, Uint32 max){
- float r = rand();
- float f = (max - min + 1);
- float d = (float)RAND_MAX + 1.0;
- return min + (int)(f * r / d);
-}
-
-static
-int
-randRange(const Uint32 odds[], Uint32 count){
- Uint32 val = randRange((Uint32)0, 100);
-
- Uint32 i = 0;
- Uint32 sum = 0;
- while(sum <= val && i < count){
- sum += odds[i];
- i++;
- }
- return i - 1;
-}
-
-int
-main(void){
-
- srand(NdbTick_CurrentMillisecond());
-#if 0
- for(int i = 0; i<100; i++)
- ndbout_c("randRange(0, 3) = %d", randRange(0, 3));
- return 0;
-#endif
- SignalSender ss;
-
- ndbout << "Connecting...";
- if(!ss.connect(30)){
- ndbout << "failed" << endl << "Exiting" << endl;
- return 0;
- }
- ndbout << "done" << endl;
- ndbout_c("Connected as block=%d node=%d",
- refToBlock(ss.getOwnRef()), refToNode(ss.getOwnRef()));
-
- Uint32 data[25];
- Uint32 sec0[70];
- Uint32 sec1[123];
- Uint32 sec2[10];
-
- data[0] = ss.getOwnRef();
- data[1] = 1;
- data[2] = 76;
- data[3] = 1;
- data[4] = 1;
- data[5] = 70;
- data[6] = 123;
- data[7] = 10;
- const Uint32 theDataLen = 18;
-
- for(Uint32 i = 0; i<70; i++)
- sec0[i] = i;
-
- for(Uint32 i = 0; i<123; i++)
- sec1[i] = 70+i;
-
- for(Uint32 i = 0; i<10; i++)
- sec2[i] = (i + 1)*(i + 1);
-
- SimpleSignal signal1;
- signal1.set(ss, 0, CMVMI, GSN_TESTSIG, theDataLen + 2);
- signal1.header.m_noOfSections = 1;
- signal1.header.m_fragmentInfo = 1;
-
- memcpy(&signal1.theData[0], data, 4 * theDataLen );
- signal1.theData[theDataLen + 0] = 0;
- signal1.theData[theDataLen + 1] = 7; // FragmentId
-
- signal1.ptr[0].sz = 60;
- signal1.ptr[0].p = &sec0[0];
-
- SimpleSignal signal2;
-
- Uint32 idx = 0;
- memcpy(&signal2.theData[0], data, 4 * theDataLen );
- signal2.theData[theDataLen + idx] = 0; idx++;
- signal2.theData[theDataLen + idx] = 1; idx++;
- //signal2.theData[theDataLen + idx] = 2; idx++;
- signal2.theData[theDataLen + idx] = 7; idx++; // FragmentId
-
- signal2.set(ss, 0, CMVMI, GSN_TESTSIG, theDataLen + idx);
- signal2.header.m_fragmentInfo = 3;
- signal2.header.m_noOfSections = idx - 1;
-
- signal2.ptr[0].sz = 10;
- signal2.ptr[0].p = &sec0[60];
-
- signal2.ptr[1].sz = 123;
- signal2.ptr[1].p = &sec1[0];
-
- signal2.ptr[2].sz = 10;
- signal2.ptr[2].p = &sec2[0];
-
- char * buf;
- while((buf = readline("Enter command: "))){
- add_history(buf);
- data[1] = atoi(buf);
- if(strcmp(buf, "r") == 0){
- SimpleSignal * ret1 = ss.waitFor();
- (* ret1).print();
- delete ret1;
- continue;
- }
- if(strcmp(buf, "a") == 0){
- runTest(ss, 10, true);
- print_help();
- continue;
- }
- if(strcmp(buf, "b") == 0){
- runTest(ss, 100, false);
- print_help();
- continue;
- }
- if(strcmp(buf, "c") == 0){
- runTest(ss, 1000000, false);
- print_help();
- continue;
- }
-
- if(data[1] >= 1 && data[1] <= 12){
- Uint32 nodeId = ss.getAliveNode();
- ndbout_c("Sending 2 fragmented to node %d", nodeId);
- ss.sendSignal(nodeId, &signal1);
- ss.sendSignal(nodeId, &signal2);
-
- if(data[1] >= 5){
- continue;
- }
- ndbout_c("Waiting for signal from %d", nodeId);
-
- SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId);
- (* ret1).print();
- Uint32 count = ret1->theData[4] - 1;
- delete ret1;
- while(count > 0){
- ndbout << "Waiting for " << count << " signals... ";
- SimpleSignal * ret1 = ss.waitFor();
- ndbout_c("received from node %d",
- refToNode(ret1->header.theSendersBlockRef));
- (* ret1).print();
- 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();
- }
- }
- ndbout << "Exiting" << endl;
-};
-
-void
-runTest(SignalSender & ss, Uint32 count, bool verbose){
-
- SimpleSignal sig;
- Uint32 sec0[256];
- Uint32 sec1[256];
- Uint32 sec2[256];
- for(Uint32 i = 0; i<256; i++){
- sec0[i] = i;
- sec1[i] = i + i;
- sec2[i] = i * i;
- }
-
- sig.theData[0] = ss.getOwnRef();
- sig.theData[1] = 1; // TestType
- sig.theData[2] = 128; // FragSize
- sig.theData[3] = 0; // Print
- sig.theData[4] = 1; // RetCount
-
- sig.ptr[0].p = &sec0[0];
- sig.ptr[1].p = &sec1[0];
- sig.ptr[2].p = &sec2[0];
-
- for(unsigned loop = 0; loop < count; loop++){
- const Uint32 odds[] = { 5, 40, 30, 25 };
- const Uint32 secs = randRange(odds, 4);
- sig.ptr[0].sz = randRange(1, 256);
- 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;
- unsigned sum = 0;
- for(unsigned i = 0; i<secs; i++){
- const Uint32 sz = sig.ptr[i].sz;
- ndbout << sz << " ";
- min = (min < sz ? min : sz);
- max = (max > sz ? max : sz);
- sum += sz;
- sig.theData[5+i] = sz;
- }
- ndbout_c("] len = %d", len);
- for(int test = 1; test <= 12; test++){
- sig.theData[1] = test;
- Uint32 nodeId = ss.getAliveNode();
- if(verbose){
- ndbout << " Test " << test << " node " << nodeId << "...";
- fflush(stdout);
- }
- SendStatus r = ss.sendSignal(nodeId, &sig);
- assert(r == SEND_OK);
- if(test < 5){
- SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId);
- Uint32 count = ret1->theData[4] - 1;
- delete ret1;
-
- while(count > 0){
- SimpleSignal * ret1 = ss.waitFor();
- delete ret1;
- count--;
- }
- if(verbose)
- ndbout << "done" << endl;
- } else {
- Uint32 nodes = ss.getNoOfConnectedNodes();
- Uint32 sum2 = 0;
- if((test & 1) == 1)
- nodes = 1;
- while(nodes > 0){
- SimpleSignal * ret = ss.waitFor();
- if(ret->header.m_fragmentInfo == 0){
- for(Uint32 i = 0; i<ret->header.m_noOfSections; i++)
- sum2 += ret->ptr[i].sz;
- } else {
- for(Uint32 i = 0; i<ret->header.m_noOfSections; i++)
- if(ret->theData[i] != 3)
- sum2 += ret->ptr[i].sz;
- }
- if(ret->header.m_fragmentInfo == 0 ||
- ret->header.m_fragmentInfo == 3){
- nodes--;
- }
- delete ret;
- }
- if(verbose)
- ndbout_c("done sum=%d sum2=%d", sum, sum2);
- }
- }
- }
-}
diff --git a/storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile b/storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile
deleted file mode 100644
index fb3aea00507..00000000000
--- a/storage/ndb/src/kernel/vm/testSimplePropertiesSection/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include .defs.mk
-
-TYPE := kernel
-
-BIN_TARGET := testSimplePropertiesSection
-BIN_TARGET_ARCHIVES := general portlib
-
-SOURCES = test.cpp ../SimplePropertiesSection.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp b/storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp
deleted file mode 100644
index 5d58d062d97..00000000000
--- a/storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbTick.h>
-#include <TransporterDefinitions.hpp>
-#include <SimpleProperties.hpp>
-#include <LongSignal.hpp>
-
-#undef test
-
-struct Buffer {
- Buffer(Uint32 size){ m_sz = size; buffer = new Uint32[m_sz]; m_len = 0;}
- ~Buffer(){ delete [] buffer;}
-
- Uint32 m_sz;
- Uint32 m_len;
- Uint32 * buffer;
-};
-
-inline
-void
-require(bool b){
- if(!b)
- abort();
-}
-
-#define relSz(x) ((x + SectionSegment::DataLength - 1) / SectionSegment::DataLength)
-
-void
-release(SectionSegmentPool & thePool, SegmentedSectionPtr & ptr){
- const Uint32 sz = relSz(ptr.sz);
- thePool.releaseList(sz,
- ptr.i,
- ptr.p->m_lastSegment);
-}
-
-void
-compare(SimplePropertiesSectionReader & db, Buffer & buf){
-
- {
- bool fail = false;
- db.reset();
- for(Uint32 i = 0; i<buf.m_len; i++){
- Uint32 tmp;
- if(!db.getWord(&tmp)){
- ndbout_c("getWord(...) failed i=%d size=%d", i, buf.m_len);
- abort();
- }
-
- if(tmp != buf.buffer[i]){
- ndbout_c("getWord(...)=%d != buf[%d]=%d size=%d", tmp, i,
- buf.buffer[i], buf.m_len);
- fail = true;
- }
- }
- require(!fail);
- }
-
- {
- db.reset();
- Buffer buf2(buf.m_sz);
- if(!db.getWords(buf2.buffer, buf.m_len))
- abort();
-
- bool fail = false;
- for(Uint32 i = 0; i<buf.m_len; i++){
- if(buf.buffer[i] != buf2.buffer[i]){
- ndbout_c("getWords(...) buf[%d] != buf2[%d] size=%d", i, i, buf.m_len);
- fail = true;
- }
- }
- require(!fail);
- }
-}
-
-
-void
-test(Uint32 sz, Uint32 loops, Uint32 iter){
-
- ndbout_c("SimplePropertiesSection sz=%d loops=%d iter=%d", sz, loops, iter);
-
- while(loops-- > 0){
- Uint32 size = sz*((10 + (rand() % (10 * sz)) + sz - 1)/sz);
-
- Buffer buf(size);
- SectionSegmentPool thePool; thePool.setSize(size);
-
- for(Uint32 i = 0; i<iter; i++){
- Uint32 c = 0 + (rand() % (2));
-
- const Uint32 alloc = 1 + (rand() % (size - 1));
- SegmentedSectionPtr dst;
-
- if(0)
- ndbout_c("size: %d loops: %d iter: %d c=%d alloc=%d",
- size, loops, i, c, alloc);
-
- switch(c){
- case 0:{
- for(Uint32 i = 0; i<alloc; i++)
- buf.buffer[i] = i; //rand();
- buf.m_len = alloc;
-
- SimplePropertiesSectionWriter w(thePool);
- for(Uint32 i = 0; i<alloc; i++){
- w.putWord(buf.buffer[i]);
- }
- w.getPtr(dst);
- break;
- }
- case 1:{
- for(Uint32 i = 0; i<alloc; i++)
- buf.buffer[i] = i; //rand();
- buf.m_len = alloc;
-
- SimplePropertiesSectionWriter w(thePool);
- Uint32 i = 0;
- while(i < alloc){
- Uint32 sz = rand() % (alloc - i + 1);
- w.putWords(&buf.buffer[i], sz);
- i += sz;
- }
- w.getPtr(dst);
- break;
- }
- case 2:{
- break;
- }
- }
- SimplePropertiesSectionReader r(dst, thePool);
- compare(r, buf);
- release(thePool, dst);
- require(thePool.getSize() == thePool.getNoOfFree());
- }
- }
-}
-
-int
-main(void){
-
- srand(NdbTick_CurrentMillisecond());
-
- //test( 1, 1000, 1000);
- test(54, 1000, 1000);
- test(59, 1000, 1000);
- test(60, 1000, 1000);
- test(61, 1000, 1000);
- return 0;
-}
-
-void
-ErrorReporter::handleAssert(const char * msg, const char * file, int line)
-{
- ndbout << "ErrorReporter::handleAssert activated - "
- << " line= " << line << endl;
- abort();
-}
diff --git a/storage/ndb/src/kernel/vm/testSuperPool.cpp b/storage/ndb/src/kernel/vm/testSuperPool.cpp
deleted file mode 100644
index b5f57be1bbe..00000000000
--- a/storage/ndb/src/kernel/vm/testSuperPool.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-#if 0
-make -f Makefile -f - testSuperPool <<'_eof_'
-testSuperPool: testSuperPool.cpp libkernel.a LinearPool.hpp
- $(CXXCOMPILE) -o $@ $@.cpp libkernel.a -L../../common/util/.libs -lgeneral
-_eof_
-exit $?
-#endif
-
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SuperPool.hpp"
-#include "LinearPool.hpp"
-#include <NdbOut.hpp>
-
-template <Uint32 sz>
-struct A {
- Uint32 a[sz];
- void fill() {
- Uint32 c = 0;
- for (Uint32 i = 0; i + 1 < sz; i++) {
- a[i] = random();
- c = (c << 1) ^ a[i];
- }
- a[sz - 1] = c;
- }
- void check() {
- Uint32 c = 0;
- for (Uint32 i = 0; i + 1 < sz; i++) {
- c = (c << 1) ^ a[i];
- }
- assert(a[sz - 1] == c);
- }
-};
-
-static Uint32
-urandom(Uint32 n)
-{
- return (Uint32)random() % n;
-}
-
-static Uint32
-random_coprime(Uint32 n)
-{
- Uint32 prime[] = { 101, 211, 307, 401, 503, 601, 701, 809, 907 };
- Uint32 count = sizeof(prime) / sizeof(prime[0]);
- assert(n != 0);
- while (1) {
- Uint32 i = urandom(count);
- if (n % prime[i] != 0)
- return prime[i];
- }
-}
-
-static int
-cmpPtrI(const void* a, const void* b)
-{
- Ptr<const void> u = *(Ptr<const void>*)a;
- Ptr<const void> v = *(Ptr<const void>*)b;
- return u.i < v.i ? -1 : u.i > v.i ? +1 : 0;
-}
-
-static int
-cmpPtrP(const void* a, const void* b)
-{
- Ptr<const void> u = *(Ptr<const void>*)a;
- Ptr<const void> v = *(Ptr<const void>*)b;
- return u.p < v.p ? -1 : u.p > v.p ? +1 : 0;
-}
-
-static Uint32 loopcount = 3;
-
-template <class T>
-static void
-sp_test(GroupPool& gp)
-{
- SuperPool& sp = gp.m_superPool;
- RecordPool<T> rp(gp);
- assert(gp.m_totPages == gp.m_freeList.m_pageCount);
- SuperPool::RecInfo& ri = rp.m_recInfo;
- Uint32 pageCount = sp.m_totPages;
- Uint32 perPage = rp.m_recInfo.m_maxPerPage;
- Uint32 perPool = perPage * pageCount;
- ndbout << "pages=" << pageCount << " perpage=" << perPage << " perpool=" << perPool << endl;
- Ptr<T>* ptrList = new Ptr<T> [perPool];
- memset(ptrList, 0x1f, perPool * sizeof(Ptr<T>));
- Uint32 verify = 1000;
- Uint32 useCount;
- Uint32 loop;
- for (loop = 0; loop < loopcount; loop++) {
- ndbout << "loop " << loop << endl;
- Uint32 i, j;
- // seize all
- ndbout << "seize all" << endl;
- for (i = 0; i < perPool + 1; i++) {
- if (verify == 0 || urandom(perPool) < verify)
- sp.verify(ri);
- j = i;
- Ptr<T> ptr1 = { 0, RNIL };
- if (! rp.seize(ptr1))
- break;
- ptr1.p->fill();
- ptr1.p->check();
- Ptr<T> ptr2 = { 0, ptr1.i };
- rp.getPtr(ptr2);
- assert(ptr1.i == ptr2.i && ptr1.p == ptr2.p);
- ptrList[j] = ptr1;
- }
- sp.verify(ri);
- ndbout << "seized " << i << endl;
- assert(i == perPool);
- useCount = sp.getRecUseCount(ri);
- assert(useCount == perPool);
- // check duplicates
- ndbout << "check dups" << endl;
- {
- Ptr<T>* ptrList2 = new Ptr<T> [perPool];
- memcpy(ptrList2, ptrList, perPool * sizeof(Ptr<T>));
- qsort(ptrList2, perPool, sizeof(Ptr<T>), cmpPtrI);
- for (i = 1; i < perPool; i++)
- assert(ptrList2[i - 1].i != ptrList2[i].i);
- qsort(ptrList2, perPool, sizeof(Ptr<T>), cmpPtrP);
- for (i = 1; i < perPool; i++)
- assert(ptrList2[i - 1].p != ptrList2[i].p);
- delete [] ptrList2;
- }
- // release all in various orders
- ndbout << "release all" << endl;
- Uint32 coprime = random_coprime(perPool);
- for (i = 0; i < perPool; i++) {
- if (verify == 0 || urandom(perPool) < verify)
- sp.verify(ri);
- switch (loop % 3) {
- case 0: // ascending
- j = i;
- break;
- case 1: // descending
- j = perPool - 1 - i;
- break;
- case 2: // pseudo-random
- j = (coprime * i) % perPool;
- break;
- }
- Ptr<T>& ptr = ptrList[j];
- assert(ptr.i != RNIL && ptr.p != 0);
- ptr.p->check();
- rp.release(ptr);
- assert(ptr.i == RNIL && ptr.p == 0);
- }
- sp.verify(ri);
- useCount = sp.getRecUseCount(ri);
- assert(useCount == 0);
- // seize/release at random
- ndbout << "seize/release at random" << endl;
- for (i = 0; i < loopcount * perPool; i++) {
- if (verify == 0 || urandom(perPool) < verify)
- sp.verify(ri);
- j = urandom(perPool);
- Ptr<T>& ptr = ptrList[j];
- if (ptr.i == RNIL) {
- if (rp.seize(ptr))
- ptr.p->fill();
- } else {
- ptr.p->check();
- rp.release(ptr);
- }
- }
- ndbout << "used " << ri.m_useCount << endl;
- sp.verify(ri);
- // release all
- ndbout << "release all" << endl;
- for (i = 0; i < perPool; i++) {
- if (verify == 0 || urandom(perPool) < verify)
- sp.verify(ri);
- j = i;
- Ptr<T>& ptr = ptrList[j];
- if (ptr.i != RNIL) {
- ptr.p->check();
- rp.release(ptr);
- }
- }
- sp.verify(ri);
- useCount = sp.getRecUseCount(ri);
- assert(useCount == 0);
- }
- // done
- delete [] ptrList;
-}
-
-template <class T>
-static void
-lp_test(GroupPool& gp)
-{
- SuperPool& sp = gp.m_superPool;
- LinearPool<T, 5> lp(gp);
- ndbout << "linear pool test" << endl;
- Ptr<T> ptr;
- Uint32 loop;
- for (loop = 0; loop < loopcount; loop++) {
- int count = 0;
- while (1) {
- bool ret = lp.seize(ptr);
- lp.verify();
- if (! ret)
- break;
- assert(ptr.i == count);
- Ptr<T> ptr2;
- ptr2.i = ptr.i;
- ptr2.p = 0;
- lp.getPtr(ptr2);
- assert(ptr.p == ptr2.p);
- count++;
- }
- assert(count != 0);
- ndbout << "seized " << count << endl;
- switch (loop % 3) {
- case 0:
- {
- int n = 0;
- while (n < count) {
- ptr.i = n;
- lp.release(ptr);
- lp.verify();
- n++;
- }
- ndbout << "released in order" << endl;
- }
- break;
- case 1:
- {
- int n = count;
- while (n > 0) {
- n--;
- ptr.i = n;
- lp.release(ptr);
- lp.verify();
- }
- ndbout << "released in reverse" << endl;
- }
- break;
- default:
- {
- int coprime = random_coprime(count);
- int n = 0;
- while (n < count) {
- int m = (coprime * n) % count;
- ptr.i = m;
- lp.release(ptr);
- lp.verify();
- n++;
- }
- ndbout << "released at random" << endl;
- }
- break;
- }
- { Uint32 cnt = lp.count(); assert(cnt == 0); }
- // seize_index test
- char *used = new char [10 * count];
- memset(used, false, sizeof(used));
- Uint32 i, ns = 0, nr = 0;
- for (i = 0; i < count; i++) {
- Uint32 index = urandom(10 * count);
- if (used[index]) {
- ptr.i = index;
- lp.release(ptr);
- lp.verify();
- nr++;
- } else {
- int i = lp.seize_index(ptr, index);
- assert(i >= 0);
- lp.verify();
- if (i == 0) // no space
- continue;
- assert(ptr.i == index);
- Ptr<T> ptr2;
- ptr2.i = ptr.i;
- ptr2.p = 0;
- lp.getPtr(ptr2);
- assert(ptr.p == ptr2.p);
- ns++;
- }
- used[index] = ! used[index];
- }
- ndbout << "random sparse seize " << ns << " release " << nr << endl;
- nr = 0;
- for (i = 0; i < 10 * count; i++) {
- if (used[i]) {
- ptr.i = i;
- lp.release(ptr);
- lp.verify();
- used[i] = false;
- nr++;
- }
- }
- ndbout << "released " << nr << endl;
- { Uint32 cnt = lp.count(); assert(cnt == 0); }
- }
-}
-
-static Uint32 pageSize = 32768;
-static Uint32 pageBits = 17;
-
-const Uint32 sz1 = 3;
-const Uint32 sz2 = 4;
-const Uint32 sz3 = 53;
-const Uint32 sz4 = 424;
-const Uint32 sz5 = 5353;
-
-typedef A<sz1> T1;
-typedef A<sz2> T2;
-typedef A<sz3> T3;
-typedef A<sz4> T4;
-typedef A<sz5> T5;
-
-template static void sp_test<T1>(GroupPool& sp);
-template static void sp_test<T2>(GroupPool& sp);
-template static void sp_test<T3>(GroupPool& sp);
-template static void sp_test<T4>(GroupPool& sp);
-template static void sp_test<T5>(GroupPool& sp);
-//
-template static void lp_test<T3>(GroupPool& sp);
-
-int
-main(int argc, char** argv)
-{
- if (argc > 1 && strncmp(argv[1], "-l", 2) == 0)
- loopcount = atoi(argv[1] + 2);
- HeapPool sp(pageSize, pageBits);
- sp.setInitPages(7);
- sp.setMaxPages(7);
- if (! sp.allocMemory())
- assert(false);
- GroupPool gp(sp);
- Uint16 s = (Uint16)getpid();
- srandom(s);
- ndbout << "rand " << s << endl;
- int count;
- count = 0;
- while (++count <= 0) { // change to 1 to find new bug
- sp_test<T1>(gp);
- sp_test<T2>(gp);
- sp_test<T3>(gp);
- sp_test<T4>(gp);
- sp_test<T5>(gp);
- }
- count = 0;
- while (++count <= 1) {
- lp_test<T3>(gp);
- }
- return 0;
-}
diff --git a/storage/ndb/src/libndb.ver.in b/storage/ndb/src/libndb.ver.in
deleted file mode 100644
index 6b13a23e883..00000000000
--- a/storage/ndb/src/libndb.ver.in
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2007 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-libndbclient_@NDB_SHARED_LIB_MAJOR_VERSION@ { global: *; };
-
diff --git a/storage/ndb/src/mgmapi/LocalConfig.cpp b/storage/ndb/src/mgmapi/LocalConfig.cpp
deleted file mode 100644
index 3ab32215c79..00000000000
--- a/storage/ndb/src/mgmapi/LocalConfig.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "LocalConfig.hpp"
-#include <NdbEnv.h>
-#include <NdbConfig.h>
-#include <NdbAutoPtr.hpp>
-#include <NdbMem.h>
-
-LocalConfig::LocalConfig(){
- error_line = 0; error_msg[0] = 0;
- _ownNodeId= 0;
-}
-
-bool
-LocalConfig::init(const char *connectString,
- const char *fileName)
-{
- DBUG_ENTER("LocalConfig::init");
- /**
- * Escalation:
- * 1. Check connectString
- * 2. Check given filename
- * 3. Check environment variable NDB_CONNECTSTRING
- * 4. Check Ndb.cfg in NDB_HOME
- * 5. Check Ndb.cfg in cwd
- * 6. Check defaultConnectString
- */
-
- _ownNodeId= 0;
-
- //1. Check connectString
- if(connectString != 0 && connectString[0] != 0){
- if(readConnectString(connectString, "connect string")){
- if (ids.size())
- DBUG_RETURN(true);
- // only nodeid given, continue to find hosts
- } else
- DBUG_RETURN(false);
- }
-
- //2. Check given filename
- if (fileName && strlen(fileName) > 0) {
- bool fopenError;
- if(readFile(fileName, fopenError)){
- DBUG_RETURN(true);
- }
- DBUG_RETURN(false);
- }
-
- //3. Check environment variable
- char buf[255];
- if(NdbEnv_GetEnv("NDB_CONNECTSTRING", buf, sizeof(buf)) &&
- strlen(buf) != 0){
- if(readConnectString(buf, "NDB_CONNECTSTRING")){
- DBUG_RETURN(true);
- }
- DBUG_RETURN(false);
- }
-
- //4. Check Ndb.cfg in NDB_HOME
- {
- bool fopenError;
- char *buf2= NdbConfig_NdbCfgName(1 /*true*/);
- NdbAutoPtr<char> tmp_aptr(buf2);
- if(readFile(buf2, fopenError))
- DBUG_RETURN(true);
- if (!fopenError)
- DBUG_RETURN(false);
- }
-
- //5. Check Ndb.cfg in cwd
- {
- bool fopenError;
- char *buf2= NdbConfig_NdbCfgName(0 /*false*/);
- NdbAutoPtr<char> tmp_aptr(buf2);
- if(readFile(buf2, fopenError))
- DBUG_RETURN(true);
- if (!fopenError)
- DBUG_RETURN(false);
- }
-
- //7. Check
- {
- char buf2[256];
- BaseString::snprintf(buf2, sizeof(buf2), "host=localhost:%s", NDB_PORT);
- if(readConnectString(buf2, "default connect string"))
- DBUG_RETURN(true);
- }
-
- setError(0, "");
-
- DBUG_RETURN(false);
-}
-
-LocalConfig::~LocalConfig(){
-}
-
-void LocalConfig::setError(int lineNumber, const char * _msg) {
- error_line = lineNumber;
- strncpy(error_msg, _msg, sizeof(error_msg));
-}
-
-void LocalConfig::printError() const {
- ndbout << "Configuration error" << endl;
- if (error_line)
- ndbout << "Line: "<< error_line << ", ";
- ndbout << error_msg << endl << endl;
-}
-
-void LocalConfig::printUsage() const {
- ndbout << "This node needs information on how to connect"<<endl
- << "to the NDB Management Server."<<endl
- << "The information can be supplied in one of the following ways:"
- << endl;
-
- ndbout << "1. Put a Ndb.cfg file in the directory where you start"<<endl
- << " the node. "<< endl
- << " Ex: Ndb.cfg" << endl
- << " | host=localhost:"<<NDB_PORT<<endl;
-
- ndbout << "2. Use the environment variable NDB_CONNECTSTRING to "<<endl
- << " provide this information." <<endl
- << " Ex: " << endl
- << " >export NDB_CONNECTSTRING=\"host=localhost:"<<NDB_PORT<<"\""
- <<endl<<endl;
-}
-
-const char *nodeIdTokens[] = {
- "OwnProcessId %i",
- "nodeid=%i",
- 0
-};
-
-const char *hostNameTokens[] = {
- "host://%[^:]:%i",
- "host=%[^:]:%i",
- "mgmd=%[^:]:%i",
- "%[^:^=^ ]:%i",
- "%s %i",
- 0
-};
-
-const char *fileNameTokens[] = {
- "file://%s",
- "file=%s",
- 0
-};
-
-bool
-LocalConfig::parseNodeId(const char * buf){
- for(int i = 0; nodeIdTokens[i] != 0; i++)
- if (sscanf(buf, nodeIdTokens[i], &_ownNodeId) == 1)
- return true;
- return false;
-}
-
-bool
-LocalConfig::parseHostName(const char * buf){
- char tempString[1024];
- char tempString2[1024];
- int port;
- do {
- for(int i = 0; hostNameTokens[i] != 0; i++) {
- if (sscanf(buf, hostNameTokens[i], tempString, &port) == 2) {
- MgmtSrvrId mgmtSrvrId;
- mgmtSrvrId.type = MgmId_TCP;
- mgmtSrvrId.name.assign(tempString);
- mgmtSrvrId.port = port;
- ids.push_back(mgmtSrvrId);
- return true;
- }
- }
- if (buf == tempString2)
- break;
- // try to add default port to see if it works
- snprintf(tempString2, sizeof(tempString2),"%s:%s", buf, NDB_PORT);
- buf= tempString2;
- } while(1);
- return false;
-}
-
-bool
-LocalConfig::parseFileName(const char * buf){
- char tempString[1024];
- for(int i = 0; fileNameTokens[i] != 0; i++) {
- if (sscanf(buf, fileNameTokens[i], tempString) == 1) {
- MgmtSrvrId mgmtSrvrId;
- mgmtSrvrId.type = MgmId_File;
- mgmtSrvrId.name.assign(tempString);
- ids.push_back(mgmtSrvrId);
- return true;
- }
- }
- return false;
-}
-
-bool
-LocalConfig::parseString(const char * connectString, BaseString &err){
- char * for_strtok;
- char * copy = strdup(connectString);
- NdbAutoPtr<char> tmp_aptr(copy);
-
- for (char *tok = strtok_r(copy,";,",&for_strtok); tok != 0;
- tok = strtok_r(NULL, ";,", &for_strtok)) {
- if (tok[0] == '#') continue;
-
- if (!_ownNodeId) // only one nodeid definition allowed
- if (parseNodeId(tok))
- continue;
- if (parseHostName(tok))
- continue;
- if (parseFileName(tok))
- continue;
-
- err.assfmt("Unexpected entry: \"%s\"", tok);
- return false;
- }
-
- return true;
-}
-
-bool LocalConfig::readFile(const char * filename, bool &fopenError)
-{
- char line[1024];
-
- fopenError = false;
-
- FILE * file = fopen(filename, "r");
- if(file == 0){
- BaseString::snprintf(line, sizeof(line),
- "Unable to open local config file: %s", filename);
- setError(0, line);
- fopenError = true;
- return false;
- }
-
- BaseString theString;
-
- while(fgets(line, sizeof(line), file)){
- BaseString tmp(line);
- tmp.trim(" \t\n\r");
- if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
- theString.append(tmp);
- break;
- }
- }
- while (fgets(line, sizeof(line), file)) {
- BaseString tmp(line);
- tmp.trim(" \t\n\r");
- if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
- theString.append(";");
- theString.append(tmp);
- }
- }
-
- BaseString err;
- bool return_value = parseString(theString.c_str(), err);
-
- if (!return_value) {
- BaseString tmp;
- tmp.assfmt("Reading %s: %s", filename, err.c_str());
- setError(0, tmp.c_str());
- }
-
- fclose(file);
- return return_value;
-}
-
-bool
-LocalConfig::readConnectString(const char * connectString,
- const char * info){
- BaseString err;
- bool return_value = parseString(connectString, err);
- if (!return_value) {
- BaseString err2;
- err2.assfmt("Reading %d \"%s\": %s", info, connectString, err.c_str());
- setError(0,err2.c_str());
- }
- return return_value;
-}
-
-char *
-LocalConfig::makeConnectString(char *buf, int sz)
-{
- int p= BaseString::snprintf(buf,sz,"nodeid=%d", _ownNodeId);
- if (p < sz)
- for (unsigned i = 0; i < ids.size(); i++)
- {
- if (ids[i].type != MgmId_TCP)
- continue;
- int new_p= p+BaseString::snprintf(buf+p,sz-p,",%s:%d",
- ids[i].name.c_str(), ids[i].port);
- if (new_p < sz)
- p= new_p;
- else
- {
- buf[p]= 0;
- break;
- }
- }
- buf[sz-1]=0;
- return buf;
-}
-
-template class Vector<MgmtSrvrId>;
diff --git a/storage/ndb/src/mgmapi/LocalConfig.hpp b/storage/ndb/src/mgmapi/LocalConfig.hpp
deleted file mode 100644
index 47816bfa343..00000000000
--- a/storage/ndb/src/mgmapi/LocalConfig.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef LocalConfig_H
-#define LocalConfig_H
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-
-//****************************************************************************
-// Description: The class LocalConfig corresponds to the information possible
-// to give in the local configuration file.
-//*****************************************************************************
-
-enum MgmtSrvrId_Type {
- MgmId_TCP = 0,
- MgmId_File = 1
-};
-
-struct MgmtSrvrId {
- MgmtSrvrId_Type type;
- BaseString name;
- unsigned int port;
-};
-
-struct LocalConfig {
-
- int _ownNodeId;
- Vector<MgmtSrvrId> ids;
-
- int error_line;
- char error_msg[256];
-
- LocalConfig();
- ~LocalConfig();
- bool init(const char *connectString = 0,
- const char *fileName = 0);
-
- void printError() const;
- void printUsage() const;
-
- void setError(int lineNumber, const char * _msg);
- bool readConnectString(const char *, const char *info);
- bool readFile(const char * file, bool &fopenError);
- bool parseLine(char * line, int lineNumber);
-
- bool parseNodeId(const char *buf);
- bool parseHostName(const char *buf);
- bool parseFileName(const char *buf);
- bool parseString(const char *buf, BaseString &err);
- char * makeConnectString(char *buf, int sz);
-};
-
-#endif // LocalConfig_H
-
diff --git a/storage/ndb/src/mgmapi/Makefile.am b/storage/ndb/src/mgmapi/Makefile.am
deleted file mode 100644
index 341563fb7ef..00000000000
--- a/storage/ndb/src/mgmapi/Makefile.am
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2004-2005 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-MYSQLCLUSTERdir= .
-
-noinst_LTLIBRARIES = libmgmapi.la
-
-libmgmapi_la_SOURCES = mgmapi.cpp ndb_logevent.cpp mgmapi_configuration.cpp LocalConfig.cpp ../kernel/error/ndbd_exit_codes.c ../mgmsrv/ConfigInfo.cpp
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/include/mgmapi
-
-DEFS_LOC = -DNDB_MGMAPI -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\"" \
- -DNO_DEBUG_MESSAGES -DNDB_PORT="\"@ndb_port@\""
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_util.mk.am
-
-#ndbtest_PROGRAMS = ndb_test_mgmapi
-
-windoze-dsp: libmgmapi.dsp
-
-libmgmapi.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libmgmapi_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp
deleted file mode 100644
index 9ae066d0f6e..00000000000
--- a/storage/ndb/src/mgmapi/mgmapi.cpp
+++ /dev/null
@@ -1,2866 +0,0 @@
- /* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-
-#include <LocalConfig.hpp>
-#include <NdbAutoPtr.hpp>
-
-#include <NdbSleep.h>
-#include <NdbTCP.h>
-#include <mgmapi.h>
-#include <mgmapi_internal.h>
-#include <mgmapi_debug.h>
-#include "mgmapi_configuration.hpp"
-#include <socket_io.h>
-#include <version.h>
-
-#include <NdbOut.hpp>
-#include <SocketServer.hpp>
-#include <SocketClient.hpp>
-#include <Parser.hpp>
-#include <OutputStream.hpp>
-#include <InputStream.hpp>
-
-#include <base64.h>
-
-#define MGM_CMD(name, fun, desc) \
- { name, \
- 0, \
- ParserRow<ParserDummy>::Cmd, \
- ParserRow<ParserDummy>::String, \
- ParserRow<ParserDummy>::Optional, \
- ParserRow<ParserDummy>::IgnoreMinMax, \
- 0, 0, \
- fun, \
- desc, 0 }
-
-#define MGM_ARG(name, type, opt, desc) \
- { name, \
- 0, \
- ParserRow<ParserDummy>::Arg, \
- ParserRow<ParserDummy>::type, \
- ParserRow<ParserDummy>::opt, \
- ParserRow<ParserDummy>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- desc, 0 }
-
-#define MGM_END() \
- { 0, \
- 0, \
- ParserRow<ParserDummy>::Arg, \
- ParserRow<ParserDummy>::Int, \
- ParserRow<ParserDummy>::Optional, \
- ParserRow<ParserDummy>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-class ParserDummy : private SocketServer::Session
-{
-public:
- ParserDummy(NDB_SOCKET_TYPE sock);
-};
-
-ParserDummy::ParserDummy(NDB_SOCKET_TYPE sock) : SocketServer::Session(sock)
-{
-}
-
-typedef Parser<ParserDummy> Parser_t;
-
-#define NDB_MGM_MAX_ERR_DESC_SIZE 256
-
-struct ndb_mgm_handle {
- int cfg_i;
-
- int connected;
- int last_error;
- int last_error_line;
- char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE];
- unsigned int timeout;
-
- NDB_SOCKET_TYPE socket;
-
- LocalConfig cfg;
-
-#ifdef MGMAPI_LOG
- FILE* logfile;
-#endif
- FILE *errstream;
- char *m_name;
- int mgmd_version_major;
- int mgmd_version_minor;
- int mgmd_version_build;
- char * m_bindaddress;
-};
-
-#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);
- BaseString::vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap);
- va_end(ap);
-}
-
-#define CHECK_HANDLE(handle, ret) \
- if(handle == 0) { \
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_HANDLE, ""); \
- return ret; \
- }
-
-#define CHECK_CONNECTED(handle, ret) \
- if (handle->connected != 1) { \
- SET_ERROR(handle, NDB_MGM_SERVER_NOT_CONNECTED , ""); \
- return ret; \
- }
-
-#define CHECK_REPLY(handle, reply, ret) \
- if(reply == NULL) { \
- if(!handle->last_error) \
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
- return ret; \
- }
-
-#define DBUG_CHECK_REPLY(handle, reply, ret) \
- if (reply == NULL) { \
- if(!handle->last_error) \
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
- DBUG_RETURN(ret); \
- }
-
-#define CHECK_TIMEDOUT(in, out) \
- if(in.timedout() || out.timedout()) \
- SET_ERROR(handle, ETIMEDOUT, \
- "Time out talking to management server");
-
-#define CHECK_TIMEDOUT_RET(h, in, out, ret) \
- if(in.timedout() || out.timedout()) { \
- SET_ERROR(handle, ETIMEDOUT, \
- "Time out talking to management server"); \
- ndb_mgm_disconnect_quiet(h); \
- return ret; \
- }
-
-#define DBUG_CHECK_TIMEDOUT_RET(h, in, out, ret) \
- if(in.timedout() || out.timedout()) { \
- SET_ERROR(handle, ETIMEDOUT, \
- "Time out talking to management server"); \
- ndb_mgm_disconnect_quiet(h); \
- DBUG_RETURN(ret); \
- }
-
-/*****************************************************************************
- * Handles
- *****************************************************************************/
-
-extern "C"
-NdbMgmHandle
-ndb_mgm_create_handle()
-{
- DBUG_ENTER("ndb_mgm_create_handle");
- NdbMgmHandle h =
- (NdbMgmHandle)my_malloc(sizeof(ndb_mgm_handle),MYF(MY_WME));
- h->connected = 0;
- h->last_error = 0;
- h->last_error_line = 0;
- h->socket = NDB_INVALID_SOCKET;
- h->timeout = 60000;
- h->cfg_i = -1;
- h->errstream = stdout;
- h->m_name = 0;
- h->m_bindaddress = 0;
-
- strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE);
-
- new (&(h->cfg)) LocalConfig;
- h->cfg.init(0, 0);
-
-#ifdef MGMAPI_LOG
- h->logfile = 0;
-#endif
-
- h->mgmd_version_major= -1;
- h->mgmd_version_minor= -1;
- h->mgmd_version_build= -1;
-
- DBUG_PRINT("info", ("handle: 0x%lx", (long) h));
- DBUG_RETURN(h);
-}
-
-extern "C"
-void
-ndb_mgm_set_name(NdbMgmHandle handle, const char *name)
-{
- my_free(handle->m_name);
- handle->m_name= my_strdup(name, MYF(MY_WME));
-}
-
-extern "C"
-int
-ndb_mgm_set_connectstring(NdbMgmHandle handle, const char * mgmsrv)
-{
- DBUG_ENTER("ndb_mgm_set_connectstring");
- DBUG_PRINT("info", ("handle: 0x%lx", (long) handle));
- handle->cfg.~LocalConfig();
- new (&(handle->cfg)) LocalConfig;
- if (!handle->cfg.init(mgmsrv, 0) ||
- handle->cfg.ids.size() == 0)
- {
- handle->cfg.~LocalConfig();
- new (&(handle->cfg)) LocalConfig;
- handle->cfg.init(0, 0); /* reset the LocalConfig */
- SET_ERROR(handle, NDB_MGM_ILLEGAL_CONNECT_STRING, mgmsrv ? mgmsrv : "");
- DBUG_RETURN(-1);
- }
- handle->cfg_i= -1;
- DBUG_RETURN(0);
-}
-
-extern "C"
-int
-ndb_mgm_set_bindaddress(NdbMgmHandle handle, const char * arg)
-{
- DBUG_ENTER("ndb_mgm_set_bindaddress");
- if (handle->m_bindaddress)
- free(handle->m_bindaddress);
-
- if (arg)
- handle->m_bindaddress = strdup(arg);
- else
- handle->m_bindaddress = 0;
-
- DBUG_RETURN(0);
-}
-
-/**
- * Destroy a handle
- */
-extern "C"
-void
-ndb_mgm_destroy_handle(NdbMgmHandle * handle)
-{
- DBUG_ENTER("ndb_mgm_destroy_handle");
- if(!handle)
- DBUG_VOID_RETURN;
- DBUG_PRINT("info", ("handle: 0x%lx", (long) (* handle)));
- /**
- * important! only disconnect if connected
- * other code relies on this
- */
- if((* handle)->connected){
- ndb_mgm_disconnect(* handle);
- }
-#ifdef MGMAPI_LOG
- if ((* handle)->logfile != 0){
- fclose((* handle)->logfile);
- (* handle)->logfile = 0;
- }
-#endif
- (*handle)->cfg.~LocalConfig();
- my_free((*handle)->m_name);
- if ((*handle)->m_bindaddress)
- free((*handle)->m_bindaddress);
- my_free(* handle);
- * handle = 0;
- DBUG_VOID_RETURN;
-}
-
-extern "C"
-void
-ndb_mgm_set_error_stream(NdbMgmHandle handle, FILE * file)
-{
- handle->errstream = file;
-}
-
-/*****************************************************************************
- * Error handling
- *****************************************************************************/
-
-/**
- * Get latest error associated with a handle
- */
-extern "C"
-int
-ndb_mgm_get_latest_error(const NdbMgmHandle h)
-{
- return h->last_error;
-}
-
-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)
-{
- return h->last_error_line;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_latest_error_msg(const NdbMgmHandle h)
-{
- for (int i=0; i<ndb_mgm_noOfErrorMsgs; i++) {
- if (ndb_mgm_error_msgs[i].code == h->last_error)
- return ndb_mgm_error_msgs[i].msg;
- }
-
- return "Error"; // Unknown Error message
-}
-
-/*
- * Call an operation, and return the reply
- */
-static const Properties *
-ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
- const char *cmd, const Properties *cmd_args)
-{
- DBUG_ENTER("ndb_mgm_call");
- DBUG_PRINT("enter",("handle->socket: %d, cmd: %s",
- handle->socket, cmd));
- SocketOutputStream out(handle->socket, handle->timeout);
- SocketInputStream in(handle->socket, handle->timeout);
-
- out.println(cmd);
-#ifdef MGMAPI_LOG
- /**
- * Print command to log file
- */
- FileOutputStream f(handle->logfile);
- f.println("OUT: %s", cmd);
-#endif
-
- if(cmd_args != NULL) {
- Properties::Iterator iter(cmd_args);
- const char *name;
- while((name = iter.next()) != NULL) {
- PropertiesType t;
- Uint32 val_i;
- Uint64 val_64;
- BaseString val_s;
-
- cmd_args->getTypeOf(name, &t);
- switch(t) {
- case PropertiesType_Uint32:
- cmd_args->get(name, &val_i);
- out.println("%s: %d", name, val_i);
- break;
- case PropertiesType_Uint64:
- cmd_args->get(name, &val_64);
- out.println("%s: %Ld", name, val_64);
- break;
- case PropertiesType_char:
- cmd_args->get(name, val_s);
- out.println("%s: %s", name, val_s.c_str());
- break;
- case PropertiesType_Properties:
- DBUG_PRINT("info",("Ignoring PropertiesType_Properties."));
- /* Ignore */
- break;
- default:
- DBUG_PRINT("info",("Ignoring PropertiesType: %d.",t));
- }
- }
-#ifdef MGMAPI_LOG
- /**
- * Print arguments to log file
- */
- cmd_args->print(handle->logfile, "OUT: ");
-#endif
- }
- out.println("");
-
- DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
-
- Parser_t::Context ctx;
- ParserDummy session(handle->socket);
- Parser_t parser(command_reply, in, true, true, true);
-
- const Properties* p = parser.parse(ctx, session);
- if (p == NULL){
- if(!ndb_mgm_is_connected(handle)) {
- DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- DBUG_RETURN(NULL);
- }
- else
- {
- DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- if(ctx.m_status==Parser_t::Eof
- || ctx.m_status==Parser_t::NoLine)
- {
- ndb_mgm_disconnect(handle);
- DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- DBUG_RETURN(NULL);
- }
- /**
- * Print some info about why the parser returns NULL
- */
- fprintf(handle->errstream,
- "Error in mgm protocol parser. cmd: >%s< status: %d curr: %s\n",
- cmd, (Uint32)ctx.m_status,
- (ctx.m_currentToken)?ctx.m_currentToken:"NULL");
- DBUG_PRINT("info",("ctx.status: %d, ctx.m_currentToken: %s",
- ctx.m_status, ctx.m_currentToken));
- }
- }
-#ifdef MGMAPI_LOG
- else {
- /**
- * Print reply to log file
- */
- p->print(handle->logfile, "IN: ");
- }
-#endif
-
- if(p && (in.timedout() || out.timedout()))
- delete p;
- DBUG_CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- DBUG_RETURN(p);
-}
-
-/**
- * Returns true if connected
- */
-extern "C"
-int ndb_mgm_is_connected(NdbMgmHandle handle)
-{
- if(!handle)
- return 0;
-
- if(handle->connected)
- {
- if(Ndb_check_socket_hup(handle->socket))
- {
- handle->connected= 0;
- NDB_CLOSE_SOCKET(handle->socket);
- }
- }
- return handle->connected;
-}
-
-extern "C"
-int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds)
-{
- return ndb_mgm_set_timeout(handle, seconds*1000);
- return 0;
-}
-
-extern "C"
-int ndb_mgm_set_timeout(NdbMgmHandle handle, unsigned int timeout_ms)
-{
- if(!handle)
- return -1;
-
- handle->timeout= timeout_ms;
- return 0;
-}
-
-extern "C"
-int ndb_mgm_number_of_mgmd_in_connect_string(NdbMgmHandle handle)
-{
- int count=0;
- Uint32 i;
- LocalConfig &cfg= handle->cfg;
-
- for (i = 0; i < cfg.ids.size(); i++)
- {
- if (cfg.ids[i].type != MgmId_TCP)
- continue;
- count++;
- }
- return count;
-}
-
-/**
- * Connect to a management server
- */
-extern "C"
-int
-ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
- int retry_delay_in_seconds, int verbose)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_connect");
- CHECK_HANDLE(handle, -1);
-
- DBUG_ENTER("ndb_mgm_connect");
-#ifdef MGMAPI_LOG
- /**
- * Open the log file
- */
- char logname[64];
- BaseString::snprintf(logname, 64, "mgmapi.log");
- handle->logfile = fopen(logname, "w");
-#endif
- char buf[1024];
-
- /**
- * Do connect
- */
- LocalConfig &cfg= handle->cfg;
- NDB_SOCKET_TYPE sockfd= NDB_INVALID_SOCKET;
- Uint32 i;
- SocketClient s(0, 0);
- s.set_connect_timeout((handle->timeout+999)/1000);
- if (!s.init())
- {
- fprintf(handle->errstream,
- "Unable to create socket, "
- "while trying to connect with connect string: %s\n",
- cfg.makeConnectString(buf,sizeof(buf)));
-
- setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
- "Unable to create socket, "
- "while trying to connect with connect string: %s\n",
- cfg.makeConnectString(buf,sizeof(buf)));
- DBUG_RETURN(-1);
- }
-
- if (handle->m_bindaddress)
- {
- BaseString::snprintf(buf, sizeof(buf), handle->m_bindaddress);
- unsigned short portno = 0;
- char * port = strchr(buf, ':');
- if (port != 0)
- {
- portno = atoi(port+1);
- * port = 0;
- }
- int err;
- if ((err = s.bind(buf, portno)) != 0)
- {
- fprintf(handle->errstream,
- "Unable to bind local address %s errno: %d, "
- "while trying to connect with connect string: %s\n",
- handle->m_bindaddress, err,
- cfg.makeConnectString(buf,sizeof(buf)));
-
- setError(handle, NDB_MGM_BIND_ADDRESS, __LINE__,
- "Unable to bind local address %s errno: %d, "
- "while trying to connect with connect string: %s\n",
- handle->m_bindaddress, err,
- cfg.makeConnectString(buf,sizeof(buf)));
- DBUG_RETURN(-1);
- }
- }
-
- while (sockfd == NDB_INVALID_SOCKET)
- {
- // do all the mgmt servers
- for (i = 0; i < cfg.ids.size(); i++)
- {
- if (cfg.ids[i].type != MgmId_TCP)
- continue;
- sockfd = s.connect(cfg.ids[i].name.c_str(), cfg.ids[i].port);
- if (sockfd != NDB_INVALID_SOCKET)
- break;
- }
- if (sockfd != NDB_INVALID_SOCKET)
- break;
-#ifndef DBUG_OFF
- {
- DBUG_PRINT("info",("Unable to connect with connect string: %s",
- cfg.makeConnectString(buf,sizeof(buf))));
- }
-#endif
- if (verbose > 0) {
- fprintf(handle->errstream,
- "Unable to connect with connect string: %s\n",
- cfg.makeConnectString(buf,sizeof(buf)));
- verbose= -1;
- }
- if (no_retries == 0) {
- setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
- "Unable to connect with connect string: %s",
- cfg.makeConnectString(buf,sizeof(buf)));
- if (verbose == -2)
- fprintf(handle->errstream, ", failed.\n");
- DBUG_RETURN(-1);
- }
- if (verbose == -1) {
- fprintf(handle->errstream, "Retrying every %d seconds",
- retry_delay_in_seconds);
- if (no_retries > 0)
- fprintf(handle->errstream, ". Attempts left:");
- else
- fprintf(handle->errstream, ", until connected.");
- fflush(handle->errstream);
- verbose= -2;
- }
- if (no_retries > 0) {
- if (verbose == -2) {
- fprintf(handle->errstream, " %d", no_retries);
- fflush(handle->errstream);
- }
- no_retries--;
- }
- NdbSleep_SecSleep(retry_delay_in_seconds);
- }
- if (verbose == -2)
- {
- fprintf(handle->errstream, "\n");
- fflush(handle->errstream);
- }
- handle->cfg_i = i;
-
- handle->socket = sockfd;
- handle->connected = 1;
-
- DBUG_RETURN(0);
-}
-
-/**
- * Only used for low level testing
- * Never to be used by end user.
- * Or anybody who doesn't know exactly what they're doing.
- */
-extern "C"
-int
-ndb_mgm_get_fd(NdbMgmHandle handle)
-{
- return handle->socket;
-}
-
-/**
- * Disconnect from mgm server without error checking
- * Should be used internally only.
- * e.g. on timeout, we leave NdbMgmHandle disconnected
- */
-extern "C"
-int
-ndb_mgm_disconnect_quiet(NdbMgmHandle handle)
-{
- NDB_CLOSE_SOCKET(handle->socket);
- handle->socket = NDB_INVALID_SOCKET;
- handle->connected = 0;
-
- return 0;
-}
-
-/**
- * Disconnect from a mgm server
- */
-extern "C"
-int
-ndb_mgm_disconnect(NdbMgmHandle handle)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_disconnect");
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- return ndb_mgm_disconnect_quiet(handle);
-}
-
-struct ndb_mgm_type_atoi
-{
- const char * str;
- const char * alias;
- enum ndb_mgm_node_type value;
-};
-
-static struct ndb_mgm_type_atoi type_values[] =
-{
- { "NDB", "ndbd", NDB_MGM_NODE_TYPE_NDB},
- { "API", "mysqld", NDB_MGM_NODE_TYPE_API },
- { "MGM", "ndb_mgmd", NDB_MGM_NODE_TYPE_MGM }
-};
-
-const int no_of_type_values = (sizeof(type_values) /
- sizeof(ndb_mgm_type_atoi));
-
-extern "C"
-ndb_mgm_node_type
-ndb_mgm_match_node_type(const char * type)
-{
- if(type == 0)
- return NDB_MGM_NODE_TYPE_UNKNOWN;
-
- for(int i = 0; i<no_of_type_values; i++)
- if(strcmp(type, type_values[i].str) == 0)
- return type_values[i].value;
- else if(strcmp(type, type_values[i].alias) == 0)
- return type_values[i].value;
-
- return NDB_MGM_NODE_TYPE_UNKNOWN;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type)
-{
- for(int i = 0; i<no_of_type_values; i++)
- if(type_values[i].value == type)
- return type_values[i].str;
- return 0;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char** str)
-{
- for(int i = 0; i<no_of_type_values; i++)
- if(type_values[i].value == type)
- {
- if (str)
- *str= type_values[i].str;
- return type_values[i].alias;
- }
- return 0;
-}
-
-struct ndb_mgm_status_atoi {
- const char * str;
- enum ndb_mgm_node_status value;
-};
-
-static struct ndb_mgm_status_atoi status_values[] =
-{
- { "UNKNOWN", NDB_MGM_NODE_STATUS_UNKNOWN },
- { "NO_CONTACT", NDB_MGM_NODE_STATUS_NO_CONTACT },
- { "NOT_STARTED", NDB_MGM_NODE_STATUS_NOT_STARTED },
- { "STARTING", NDB_MGM_NODE_STATUS_STARTING },
- { "STARTED", NDB_MGM_NODE_STATUS_STARTED },
- { "SHUTTING_DOWN", NDB_MGM_NODE_STATUS_SHUTTING_DOWN },
- { "RESTARTING", NDB_MGM_NODE_STATUS_RESTARTING },
- { "SINGLE USER MODE", NDB_MGM_NODE_STATUS_SINGLEUSER }
-};
-
-const int no_of_status_values = (sizeof(status_values) /
- sizeof(ndb_mgm_status_atoi));
-
-extern "C"
-ndb_mgm_node_status
-ndb_mgm_match_node_status(const char * status)
-{
- if(status == 0)
- return NDB_MGM_NODE_STATUS_UNKNOWN;
-
- for(int i = 0; i<no_of_status_values; i++)
- if(strcmp(status, status_values[i].str) == 0)
- return status_values[i].value;
-
- return NDB_MGM_NODE_STATUS_UNKNOWN;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_node_status_string(enum ndb_mgm_node_status status)
-{
- int i;
- for(i = 0; i<no_of_status_values; i++)
- if(status_values[i].value == status)
- return status_values[i].str;
-
- for(i = 0; i<no_of_status_values; i++)
- if(status_values[i].value == NDB_MGM_NODE_STATUS_UNKNOWN)
- return status_values[i].str;
-
- return 0;
-}
-
-static int
-status_ackumulate(struct ndb_mgm_node_state * state,
- const char * field,
- const char * value)
-{
- if(strcmp("type", field) == 0){
- state->node_type = ndb_mgm_match_node_type(value);
- } else if(strcmp("status", field) == 0){
- state->node_status = ndb_mgm_match_node_status(value);
- } else if(strcmp("startphase", field) == 0){
- state->start_phase = atoi(value);
- } else if(strcmp("dynamic_id", field) == 0){
- state->dynamic_id = atoi(value);
- } else if(strcmp("node_group", field) == 0){
- 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 if(strcmp("address", field) == 0){
- strncpy(state->connect_address, value, sizeof(state->connect_address));
- state->connect_address[sizeof(state->connect_address)-1]= 0;
- } else {
- ndbout_c("Unknown field: %s", field);
- }
- return 0;
-}
-
-/**
- * Compare function for qsort() that sorts ndb_mgm_node_state in
- * node_id order
- */
-static int
-cmp_state(const void *_a, const void *_b)
-{
- struct ndb_mgm_node_state *a, *b;
-
- a = (struct ndb_mgm_node_state *)_a;
- b = (struct ndb_mgm_node_state *)_b;
-
- if (a->node_id > b->node_id)
- return 1;
- return -1;
-}
-
-extern "C"
-struct ndb_mgm_cluster_state *
-ndb_mgm_get_status(NdbMgmHandle handle)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_status");
- CHECK_HANDLE(handle, NULL);
- CHECK_CONNECTED(handle, NULL);
-
- SocketOutputStream out(handle->socket, handle->timeout);
- SocketInputStream in(handle->socket, handle->timeout);
-
- out.println("get status");
- out.println("");
-
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
-
- char buf[1024];
- if(!in.gets(buf, sizeof(buf)))
- {
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
- return NULL;
- }
- if(strcmp("node status\n", buf) != 0) {
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- ndbout << in.timedout() << " " << out.timedout() << buf << endl;
- SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
- return NULL;
- }
- if(!in.gets(buf, sizeof(buf)))
- {
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
- return NULL;
- }
-
- BaseString tmp(buf);
- Vector<BaseString> split;
- tmp.split(split, ":");
- if(split.size() != 2){
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
- return NULL;
- }
-
- if(!(split[0].trim() == "nodes")){
- SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
- return NULL;
- }
-
- const int noOfNodes = atoi(split[1].c_str());
-
- ndb_mgm_cluster_state *state = (ndb_mgm_cluster_state*)
- malloc(sizeof(ndb_mgm_cluster_state)+
- noOfNodes*(sizeof(ndb_mgm_node_state)+sizeof("000.000.000.000#")));
-
- if(!state)
- {
- SET_ERROR(handle, NDB_MGM_OUT_OF_MEMORY,
- "Allocating ndb_mgm_cluster_state");
- return NULL;
- }
-
- state->no_of_nodes= noOfNodes;
- ndb_mgm_node_state * ptr = &state->node_states[0];
- int nodeId = 0;
- int i;
- for (i= 0; i < noOfNodes; i++) {
- state->node_states[i].connect_address[0]= 0;
- }
- i = -1; ptr--;
- for(; i<noOfNodes; ){
- if(!in.gets(buf, sizeof(buf)))
- {
- free(state);
- if(in.timedout() || out.timedout())
- SET_ERROR(handle, ETIMEDOUT,
- "Time out talking to management server");
- else
- SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
- "Probably disconnected");
- return NULL;
- }
- tmp.assign(buf);
-
- if(tmp.trim() == ""){
- break;
- }
-
- Vector<BaseString> split2;
- tmp.split(split2, ":.", 4);
- if(split2.size() != 4)
- break;
-
- const int id = atoi(split2[1].c_str());
- if(id != nodeId){
- ptr++;
- i++;
- nodeId = id;
- ptr->node_id = id;
- }
-
- split2[3].trim(" \t\n");
-
- if(status_ackumulate(ptr,split2[2].c_str(), split2[3].c_str()) != 0) {
- break;
- }
- }
-
- if(i+1 != noOfNodes){
- free(state);
- CHECK_TIMEDOUT_RET(handle, in, out, NULL);
- SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
- return NULL;
- }
-
- qsort(state->node_states, state->no_of_nodes, sizeof(state->node_states[0]),
- cmp_state);
- return state;
-}
-
-extern "C"
-int
-ndb_mgm_enter_single_user(NdbMgmHandle handle,
- unsigned int nodeId,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_enter_single_user");
- const ParserRow<ParserDummy> enter_single_reply[] = {
- MGM_CMD("enter single user reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("nodeId", nodeId);
- const Properties *reply;
- reply = ndb_mgm_call(handle, enter_single_reply, "enter single user", &args);
- CHECK_REPLY(handle, reply, -1);
-
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_COULD_NOT_ENTER_SINGLE_USER_MODE,
- result.c_str());
- delete reply;
- return -1;
- }
-
- delete reply;
- return 0;
-}
-
-
-extern "C"
-int
-ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_exit_single_user");
- const ParserRow<ParserDummy> exit_single_reply[] = {
- MGM_CMD("exit single user reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- const Properties *reply;
- reply = ndb_mgm_call(handle, exit_single_reply, "exit single user", 0);
- CHECK_REPLY(handle, reply, -1);
-
- const char * buf;
- reply->get("result", &buf);
- if(strcmp(buf,"Ok")!=0) {
- SET_ERROR(handle, NDB_MGM_COULD_NOT_EXIT_SINGLE_USER_MODE, buf);
- delete reply;
- return -1;
- }
-
- delete reply;
- return 0;
-}
-
-extern "C"
-int
-ndb_mgm_stop(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop");
- return ndb_mgm_stop2(handle, no_of_nodes, node_list, 0);
-}
-
-extern "C"
-int
-ndb_mgm_stop2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
- int abort)
-{
- int disconnect;
- return ndb_mgm_stop3(handle, no_of_nodes, node_list, abort, &disconnect);
-}
-
-
-extern "C"
-int
-ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
- int abort, int *disconnect)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop3");
- const ParserRow<ParserDummy> stop_reply_v1[] = {
- MGM_CMD("stop reply", NULL, ""),
- MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- const ParserRow<ParserDummy> stop_reply_v2[] = {
- MGM_CMD("stop reply", NULL, ""),
- MGM_ARG("stopped", Int, Optional, "No of stopped nodes"),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_ARG("disconnect", Int, Mandatory, "Need to disconnect"),
- MGM_END()
- };
-
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- if(handle->mgmd_version_build==-1)
- {
- char verstr[50];
- if(!ndb_mgm_get_version(handle,
- &(handle->mgmd_version_major),
- &(handle->mgmd_version_minor),
- &(handle->mgmd_version_build),
- sizeof(verstr),
- verstr))
- {
- return -1;
- }
- }
- int use_v2= ((handle->mgmd_version_major==5)
- && (
- (handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
- ||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
- ||(handle->mgmd_version_minor>1)
- )
- )
- || (handle->mgmd_version_major>5);
-
- if(no_of_nodes < -1){
- SET_ERROR(handle, NDB_MGM_ILLEGAL_NUMBER_OF_NODES,
- "Negative number of nodes requested to stop");
- return -1;
- }
-
- Uint32 stoppedNoOfNodes = 0;
- if(no_of_nodes <= 0){
- /**
- * All nodes should be stopped (all or just db)
- */
- Properties args;
- args.put("abort", abort);
- if(use_v2)
- args.put("stop", (no_of_nodes==-1)?"mgm,db":"db");
- const Properties *reply;
- if(use_v2)
- reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args);
- else
- reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
- CHECK_REPLY(handle, reply, -1);
-
- if(!reply->get("stopped", &stoppedNoOfNodes)){
- SET_ERROR(handle, NDB_MGM_STOP_FAILED,
- "Could not get number of stopped nodes from mgm server");
- delete reply;
- return -1;
- }
- if(use_v2)
- reply->get("disconnect", (Uint32*)disconnect);
- else
- *disconnect= 0;
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_STOP_FAILED, result.c_str());
- delete reply;
- return -1;
- }
- delete reply;
- return stoppedNoOfNodes;
- }
-
- /**
- * A list of database nodes should be stopped
- */
- Properties args;
-
- BaseString node_list_str;
- node_list_str.assfmt("%d", node_list[0]);
- for(int node = 1; node < no_of_nodes; node++)
- node_list_str.appfmt(" %d", node_list[node]);
-
- args.put("node", node_list_str.c_str());
- args.put("abort", abort);
-
- const Properties *reply;
- if(use_v2)
- reply = ndb_mgm_call(handle, stop_reply_v2, "stop v2", &args);
- else
- reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
-
- CHECK_REPLY(handle, reply, stoppedNoOfNodes);
- if(!reply->get("stopped", &stoppedNoOfNodes)){
- SET_ERROR(handle, NDB_MGM_STOP_FAILED,
- "Could not get number of stopped nodes from mgm server");
- delete reply;
- return -1;
- }
- if(use_v2)
- reply->get("disconnect", (Uint32*)disconnect);
- else
- *disconnect= 0;
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_STOP_FAILED, result.c_str());
- delete reply;
- return -1;
- }
- delete reply;
- return stoppedNoOfNodes;
-}
-
-extern "C"
-int
-ndb_mgm_restart(NdbMgmHandle handle, int no_of_nodes, const int *node_list)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart");
- return ndb_mgm_restart2(handle, no_of_nodes, node_list, 0, 0, 0);
-}
-
-extern "C"
-int
-ndb_mgm_restart2(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
- int initial, int nostart, int abort)
-{
- int disconnect;
-
- return ndb_mgm_restart3(handle, no_of_nodes, node_list, initial, nostart,
- abort, &disconnect);
-}
-
-extern "C"
-int
-ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
- int initial, int nostart, int abort, int *disconnect)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_restart3");
- Uint32 restarted = 0;
- const ParserRow<ParserDummy> restart_reply_v1[] = {
- MGM_CMD("restart reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
- MGM_END()
- };
- const ParserRow<ParserDummy> restart_reply_v2[] = {
- MGM_CMD("restart reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_ARG("restarted", Int, Optional, "No of restarted nodes"),
- MGM_ARG("disconnect", Int, Optional, "Disconnect to apply"),
- MGM_END()
- };
-
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- if(handle->mgmd_version_build==-1)
- {
- char verstr[50];
- if(!ndb_mgm_get_version(handle,
- &(handle->mgmd_version_major),
- &(handle->mgmd_version_minor),
- &(handle->mgmd_version_build),
- sizeof(verstr),
- verstr))
- {
- return -1;
- }
- }
- int use_v2= ((handle->mgmd_version_major==5)
- && (
- (handle->mgmd_version_minor==0 && handle->mgmd_version_build>=21)
- ||(handle->mgmd_version_minor==1 && handle->mgmd_version_build>=12)
- ||(handle->mgmd_version_minor>1)
- )
- )
- || (handle->mgmd_version_major>5);
-
- if(no_of_nodes < 0){
- SET_ERROR(handle, NDB_MGM_RESTART_FAILED,
- "Restart requested of negative number of nodes");
- return -1;
- }
-
- if(no_of_nodes == 0) {
- Properties args;
- args.put("abort", abort);
- args.put("initialstart", initial);
- args.put("nostart", nostart);
- const Properties *reply;
- const int timeout = handle->timeout;
- handle->timeout= 5*60*1000; // 5 minutes
- reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
- handle->timeout= timeout;
- CHECK_REPLY(handle, reply, -1);
-
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_RESTART_FAILED, result.c_str());
- delete reply;
- return -1;
- }
- if(!reply->get("restarted", &restarted)){
- SET_ERROR(handle, NDB_MGM_RESTART_FAILED,
- "Could not get restarted number of nodes from mgm server");
- delete reply;
- return -1;
- }
- delete reply;
- return restarted;
- }
-
- BaseString node_list_str;
- node_list_str.assfmt("%d", node_list[0]);
- for(int node = 1; node < no_of_nodes; node++)
- node_list_str.appfmt(" %d", node_list[node]);
-
- Properties args;
-
- args.put("node", node_list_str.c_str());
- args.put("abort", abort);
- args.put("initialstart", initial);
- args.put("nostart", nostart);
-
- const Properties *reply;
- const int timeout = handle->timeout;
- handle->timeout= 5*60*1000; // 5 minutes
- if(use_v2)
- reply = ndb_mgm_call(handle, restart_reply_v2, "restart node v2", &args);
- else
- reply = ndb_mgm_call(handle, restart_reply_v1, "restart node", &args);
- handle->timeout= timeout;
- if(reply != NULL) {
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_RESTART_FAILED, result.c_str());
- delete reply;
- return -1;
- }
- reply->get("restarted", &restarted);
- if(use_v2)
- reply->get("disconnect", (Uint32*)disconnect);
- else
- *disconnect= 0;
- delete reply;
- }
-
- return restarted;
-}
-
-static const char *clusterlog_severity_names[]=
- { "enabled", "debug", "info", "warning", "error", "critical", "alert" };
-
-struct ndb_mgm_event_severities
-{
- const char* name;
- enum ndb_mgm_event_severity severity;
-} clusterlog_severities[] = {
- { clusterlog_severity_names[0], NDB_MGM_EVENT_SEVERITY_ON },
- { clusterlog_severity_names[1], NDB_MGM_EVENT_SEVERITY_DEBUG },
- { clusterlog_severity_names[2], NDB_MGM_EVENT_SEVERITY_INFO },
- { clusterlog_severity_names[3], NDB_MGM_EVENT_SEVERITY_WARNING },
- { clusterlog_severity_names[4], NDB_MGM_EVENT_SEVERITY_ERROR },
- { clusterlog_severity_names[5], NDB_MGM_EVENT_SEVERITY_CRITICAL },
- { clusterlog_severity_names[6], NDB_MGM_EVENT_SEVERITY_ALERT },
- { "all", NDB_MGM_EVENT_SEVERITY_ALL },
- { 0, NDB_MGM_ILLEGAL_EVENT_SEVERITY },
-};
-
-extern "C"
-ndb_mgm_event_severity
-ndb_mgm_match_event_severity(const char * name)
-{
- if(name == 0)
- return NDB_MGM_ILLEGAL_EVENT_SEVERITY;
-
- for(int i = 0; clusterlog_severities[i].name !=0 ; i++)
- if(strcasecmp(name, clusterlog_severities[i].name) == 0)
- return clusterlog_severities[i].severity;
-
- return NDB_MGM_ILLEGAL_EVENT_SEVERITY;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_event_severity_string(enum ndb_mgm_event_severity severity)
-{
- int i= (int)severity;
- if (i >= 0 && i < (int)NDB_MGM_EVENT_SEVERITY_ALL)
- return clusterlog_severity_names[i];
- for(i = (int)NDB_MGM_EVENT_SEVERITY_ALL; clusterlog_severities[i].name != 0; i++)
- if(clusterlog_severities[i].severity == severity)
- return clusterlog_severities[i].name;
- return 0;
-}
-
-extern "C"
-int
-ndb_mgm_get_clusterlog_severity_filter(NdbMgmHandle handle,
- struct ndb_mgm_severity* severity,
- unsigned int severity_size)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_severity_filter");
- const ParserRow<ParserDummy> getinfo_reply[] = {
- MGM_CMD("clusterlog", NULL, ""),
- MGM_ARG(clusterlog_severity_names[0], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[1], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[2], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[3], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[4], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[5], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[6], Int, Mandatory, ""),
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- const Properties *reply;
- reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
- CHECK_REPLY(handle, reply, -1);
-
- for(unsigned int i=0; i < severity_size; i++) {
- reply->get(clusterlog_severity_names[severity[i].category], &severity[i].value);
- }
- return severity_size;
-}
-
-extern "C"
-const unsigned int *
-ndb_mgm_get_clusterlog_severity_filter_old(NdbMgmHandle handle)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_severity_filter");
- static unsigned int enabled[(int)NDB_MGM_EVENT_SEVERITY_ALL]=
- {0,0,0,0,0,0,0};
- const ParserRow<ParserDummy> getinfo_reply[] = {
- MGM_CMD("clusterlog", NULL, ""),
- MGM_ARG(clusterlog_severity_names[0], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[1], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[2], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[3], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[4], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[5], Int, Mandatory, ""),
- MGM_ARG(clusterlog_severity_names[6], Int, Mandatory, ""),
- };
- CHECK_HANDLE(handle, NULL);
- CHECK_CONNECTED(handle, NULL);
-
- Properties args;
- const Properties *reply;
- reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
- CHECK_REPLY(handle, reply, NULL);
-
- for(int i=0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) {
- reply->get(clusterlog_severity_names[i], &enabled[i]);
- }
- return enabled;
-}
-
-extern "C"
-int
-ndb_mgm_set_clusterlog_severity_filter(NdbMgmHandle handle,
- enum ndb_mgm_event_severity severity,
- int enable,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR,
- "Executing: ndb_mgm_set_clusterlog_severity_filter");
- const ParserRow<ParserDummy> filter_reply[] = {
- MGM_CMD("set logfilter reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("level", severity);
- args.put("enable", enable);
-
- const Properties *reply;
- reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args);
- CHECK_REPLY(handle, reply, retval);
-
- BaseString result;
- reply->get("result", result);
-
- if (strcmp(result.c_str(), "1") == 0)
- retval = 1;
- else if (strcmp(result.c_str(), "0") == 0)
- retval = 0;
- else
- {
- SET_ERROR(handle, EINVAL, result.c_str());
- }
- delete reply;
- return retval;
-}
-
-struct ndb_mgm_event_categories
-{
- const char* name;
- enum ndb_mgm_event_category category;
-} categories[] = {
- { "STARTUP", NDB_MGM_EVENT_CATEGORY_STARTUP },
- { "SHUTDOWN", NDB_MGM_EVENT_CATEGORY_SHUTDOWN },
- { "STATISTICS", NDB_MGM_EVENT_CATEGORY_STATISTIC },
- { "NODERESTART", NDB_MGM_EVENT_CATEGORY_NODE_RESTART },
- { "CONNECTION", NDB_MGM_EVENT_CATEGORY_CONNECTION },
- { "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT },
- { "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG },
- { "INFO", NDB_MGM_EVENT_CATEGORY_INFO },
- { "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR },
- { "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP },
- { "CONGESTION", NDB_MGM_EVENT_CATEGORY_CONGESTION },
- { 0, NDB_MGM_ILLEGAL_EVENT_CATEGORY }
-};
-
-extern "C"
-ndb_mgm_event_category
-ndb_mgm_match_event_category(const char * status)
-{
- if(status == 0)
- return NDB_MGM_ILLEGAL_EVENT_CATEGORY;
-
- for(int i = 0; categories[i].name !=0 ; i++)
- if(strcmp(status, categories[i].name) == 0)
- return categories[i].category;
-
- return NDB_MGM_ILLEGAL_EVENT_CATEGORY;
-}
-
-extern "C"
-const char *
-ndb_mgm_get_event_category_string(enum ndb_mgm_event_category status)
-{
- int i;
- for(i = 0; categories[i].name != 0; i++)
- if(categories[i].category == status)
- return categories[i].name;
-
- return 0;
-}
-
-static const char *clusterlog_names[]=
- { "startup", "shutdown", "statistics", "checkpoint", "noderestart", "connection", "info", "warning", "error", "congestion", "debug", "backup" };
-
-extern "C"
-int
-ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle,
- struct ndb_mgm_loglevel* loglevel,
- unsigned int loglevel_size)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_loglevel");
- int loglevel_count = loglevel_size;
- const ParserRow<ParserDummy> getloglevel_reply[] = {
- MGM_CMD("get cluster loglevel", NULL, ""),
- MGM_ARG(clusterlog_names[0], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[1], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[2], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[3], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[4], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[5], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[6], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[7], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[8], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[9], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[10], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[11], Int, Mandatory, ""),
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- const Properties *reply;
- reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
- CHECK_REPLY(handle, reply, -1);
-
- for(int i=0; i < loglevel_count; i++) {
- reply->get(clusterlog_names[loglevel[i].category], &loglevel[i].value);
- }
- return loglevel_count;
-}
-
-extern "C"
-const unsigned int *
-ndb_mgm_get_clusterlog_loglevel_old(NdbMgmHandle handle)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_clusterlog_loglevel");
- int loglevel_count = CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1 ;
- static unsigned int loglevel[CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1] = {0,0,0,0,0,0,0,0,0,0,0,0};
- const ParserRow<ParserDummy> getloglevel_reply[] = {
- MGM_CMD("get cluster loglevel", NULL, ""),
- MGM_ARG(clusterlog_names[0], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[1], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[2], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[3], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[4], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[5], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[6], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[7], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[8], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[9], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[10], Int, Mandatory, ""),
- MGM_ARG(clusterlog_names[11], Int, Mandatory, ""),
- };
- CHECK_HANDLE(handle, NULL);
- CHECK_CONNECTED(handle, NULL);
-
- Properties args;
- const Properties *reply;
- reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
- CHECK_REPLY(handle, reply, NULL);
-
- for(int i=0; i < loglevel_count; i++) {
- reply->get(clusterlog_names[i], &loglevel[i]);
- }
- return loglevel;
-}
-
-extern "C"
-int
-ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId,
- enum ndb_mgm_event_category cat,
- int level,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR,
- "Executing: ndb_mgm_set_clusterlog_loglevel");
- const ParserRow<ParserDummy> clusterlog_reply[] = {
- MGM_CMD("set cluster loglevel reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
- args.put("category", cat);
- args.put("level", level);
-
- const Properties *reply;
- reply = ndb_mgm_call(handle, clusterlog_reply,
- "set cluster loglevel", &args);
- CHECK_REPLY(handle, reply, -1);
-
- DBUG_ENTER("ndb_mgm_set_clusterlog_loglevel");
- DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level));
-
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, EINVAL, result.c_str());
- delete reply;
- DBUG_RETURN(-1);
- }
- delete reply;
- DBUG_RETURN(0);
-}
-
-extern "C"
-int
-ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId,
- enum ndb_mgm_event_category category,
- int level,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_set_loglevel_node");
- const ParserRow<ParserDummy> loglevel_reply[] = {
- MGM_CMD("set loglevel reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
- args.put("category", category);
- args.put("level", level);
- const Properties *reply;
- reply = ndb_mgm_call(handle, loglevel_reply, "set loglevel", &args);
- CHECK_REPLY(handle, reply, -1);
-
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, EINVAL, result.c_str());
- delete reply;
- return -1;
- }
-
- delete reply;
- return 0;
-}
-
-int
-ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
- int parsable)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_listen_event");
- const ParserRow<ParserDummy> stat_reply[] = {
- MGM_CMD("listen event", NULL, ""),
- MGM_ARG("result", Int, Mandatory, "Error message"),
- MGM_ARG("msg", String, Optional, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
-
- const char *hostname= ndb_mgm_get_connected_host(handle);
- int port= ndb_mgm_get_connected_port(handle);
- SocketClient s(hostname, port);
- const NDB_SOCKET_TYPE sockfd = s.connect();
- if (sockfd == NDB_INVALID_SOCKET) {
- setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
- "Unable to connect to");
- return -1;
- }
-
- Properties args;
-
- if (parsable)
- args.put("parsable", parsable);
- {
- BaseString tmp;
- for(int i = 0; filter[i] != 0; i += 2){
- tmp.appfmt("%d=%d ", filter[i+1], filter[i]);
- }
- args.put("filter", tmp.c_str());
- }
-
- int tmp = handle->socket;
- handle->socket = sockfd;
-
- const Properties *reply;
- reply = ndb_mgm_call(handle, stat_reply, "listen event", &args);
-
- handle->socket = tmp;
-
- if(reply == NULL) {
- close(sockfd);
- CHECK_REPLY(handle, reply, -1);
- }
- delete reply;
- return sockfd;
-}
-
-extern "C"
-int
-ndb_mgm_listen_event(NdbMgmHandle handle, const int filter[])
-{
- return ndb_mgm_listen_event_internal(handle,filter,0);
-}
-
-extern "C"
-int
-ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, const int * _args,
- int _num_args, struct ndb_mgm_reply* /* reply */)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_dump_state");
- const ParserRow<ParserDummy> dump_state_reply[] = {
- MGM_CMD("dump state reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- char buf[256];
- buf[0] = 0;
- for (int i = 0; i < _num_args; i++){
- unsigned n = strlen(buf);
- if (n + 20 > sizeof(buf)) {
- SET_ERROR(handle, NDB_MGM_USAGE_ERROR, "arguments too long");
- return -1;
- }
- sprintf(buf + n, "%s%d", i ? " " : "", _args[i]);
- }
-
- Properties args;
- args.put("node", nodeId);
- args.put("args", buf);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, dump_state_reply, "dump state", &args);
- CHECK_REPLY(handle, prop, -1);
-
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, EINVAL, result.c_str());
- delete prop;
- return -1;
- }
-
- delete prop;
- return 0;
-}
-
-extern "C"
-int
-ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId,
- struct ndb_mgm_reply* reply)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_signallog");
- const ParserRow<ParserDummy> start_signallog_reply[] = {
- MGM_CMD("start signallog reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle,
- start_signallog_reply,
- "start signallog",
- &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop != NULL) {
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- retval = 0;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- retval = -1;
- }
- delete prop;
- }
-
- return retval;
-}
-
-extern "C"
-int
-ndb_mgm_stop_signallog(NdbMgmHandle handle, int nodeId,
- struct ndb_mgm_reply* reply)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_stop_signallog");
- const ParserRow<ParserDummy> stop_signallog_reply[] = {
- MGM_CMD("stop signallog reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, stop_signallog_reply, "stop signallog", &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop != NULL) {
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- retval = 0;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- retval = -1;
- }
- delete prop;
- }
-
- return retval;
-}
-
-struct ndb_mgm_signal_log_modes
-{
- const char* name;
- enum ndb_mgm_signal_log_mode mode;
-};
-
-extern "C"
-int
-ndb_mgm_log_signals(NdbMgmHandle handle, int nodeId,
- enum ndb_mgm_signal_log_mode mode,
- const char* blockNames,
- struct ndb_mgm_reply* reply)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_log_signals");
- const ParserRow<ParserDummy> stop_signallog_reply[] = {
- MGM_CMD("log signals reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
- args.put("blocks", blockNames);
-
- switch(mode) {
- case NDB_MGM_SIGNAL_LOG_MODE_IN:
- args.put("in", (Uint32)1);
- args.put("out", (Uint32)0);
- break;
- case NDB_MGM_SIGNAL_LOG_MODE_OUT:
- args.put("in", (Uint32)0);
- args.put("out", (Uint32)1);
- break;
- case NDB_MGM_SIGNAL_LOG_MODE_INOUT:
- args.put("in", (Uint32)1);
- args.put("out", (Uint32)1);
- break;
- case NDB_MGM_SIGNAL_LOG_MODE_OFF:
- args.put("in", (Uint32)0);
- args.put("out", (Uint32)0);
- break;
- }
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, stop_signallog_reply, "log signals", &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop != NULL) {
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- retval = 0;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- retval = -1;
- }
- delete prop;
- }
-
- return retval;
-}
-
-extern "C"
-int
-ndb_mgm_set_trace(NdbMgmHandle handle, int nodeId, int traceNumber,
- struct ndb_mgm_reply* reply)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_set_trace");
- const ParserRow<ParserDummy> set_trace_reply[] = {
- MGM_CMD("set trace reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
- args.put("trace", traceNumber);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, set_trace_reply, "set trace", &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop != NULL) {
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- retval = 0;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- retval = -1;
- }
- delete prop;
- }
-
- return retval;
-}
-
-extern "C"
-int
-ndb_mgm_insert_error(NdbMgmHandle handle, int nodeId, int errorCode,
- struct ndb_mgm_reply* reply)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_insert_error");
- const ParserRow<ParserDummy> insert_error_reply[] = {
- MGM_CMD("insert error reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int retval = -1;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("node", nodeId);
- args.put("error", errorCode);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, insert_error_reply, "insert error", &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop != NULL) {
- BaseString result;
- prop->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- retval = 0;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- retval = -1;
- }
- delete prop;
- }
-
- return retval;
-}
-
-extern "C"
-int
-ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start");
- const ParserRow<ParserDummy> start_reply[] = {
- MGM_CMD("start reply", NULL, ""),
- MGM_ARG("started", Int, Optional, "No of started nodes"),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- int started = 0;
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- if(no_of_nodes < 0){
- SET_ERROR(handle, EINVAL, "");
- return -1;
- }
-
- if(no_of_nodes == 0){
- Properties args;
- const Properties *reply;
- reply = ndb_mgm_call(handle, start_reply, "start all", &args);
- CHECK_REPLY(handle, reply, -1);
-
- Uint32 count = 0;
- if(!reply->get("started", &count)){
- delete reply;
- return -1;
- }
- delete reply;
- return count;
- }
-
- for(int node = 0; node < no_of_nodes; node++) {
- Properties args;
- args.put("node", node_list[node]);
-
- const Properties *reply;
- reply = ndb_mgm_call(handle, start_reply, "start", &args);
-
- if(reply != NULL) {
- BaseString result;
- reply->get("result", result);
- if(strcmp(result.c_str(), "Ok") == 0) {
- started++;
- } else {
- SET_ERROR(handle, EINVAL, result.c_str());
- delete reply;
- return -1;
- }
- }
- delete reply;
- }
-
- return started;
-}
-
-/*****************************************************************************
- * Backup
- *****************************************************************************/
-extern "C"
-int
-ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
- unsigned int* _backup_id,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_start_backup");
- const ParserRow<ParserDummy> start_backup_reply[] = {
- MGM_CMD("start backup reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_ARG("id", Int, Optional, "Id of the started backup"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("completed", wait_completed);
- const Properties *reply;
- { // start backup can take some time, set timeout high
- Uint64 old_timeout= handle->timeout;
- if (wait_completed == 2)
- handle->timeout= 48*60*60*1000; // 48 hours
- else if (wait_completed == 1)
- handle->timeout= 10*60*1000; // 10 minutes
- reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
- handle->timeout= old_timeout;
- }
- CHECK_REPLY(handle, reply, -1);
-
- BaseString result;
- reply->get("result", result);
- reply->get("id", _backup_id);
- if(strcmp(result.c_str(), "Ok") != 0) {
- SET_ERROR(handle, NDB_MGM_COULD_NOT_START_BACKUP, result.c_str());
- delete reply;
- return -1;
- }
-
- delete reply;
- return 0;
-}
-
-extern "C"
-int
-ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
- struct ndb_mgm_reply* /*reply*/)
-{
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_abort_backup");
- const ParserRow<ParserDummy> stop_backup_reply[] = {
- MGM_CMD("abort backup reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -1);
-
- Properties args;
- args.put("id", backupId);
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, stop_backup_reply, "abort backup", &args);
- CHECK_REPLY(handle, prop, -1);
-
- const char * buf;
- prop->get("result", &buf);
- if(strcmp(buf,"Ok")!=0) {
- SET_ERROR(handle, NDB_MGM_COULD_NOT_ABORT_BACKUP, buf);
- delete prop;
- return -1;
- }
-
- delete prop;
- return 0;
-}
-
-extern "C"
-struct ndb_mgm_configuration *
-ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
- SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_configuration");
- 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);
- CHECK_REPLY(handle, prop, 0);
-
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n\n", buf);
- break;
- }
-
- buf = "<Unspecified>";
- if(!prop->get("Content-Type", &buf) ||
- strcmp(buf, "ndbconfig/octet-stream") != 0){
- fprintf(handle->errstream, "Unhandled response type: %s\n", buf);
- break;
- }
-
- buf = "<Unspecified>";
- if(!prop->get("Content-Transfer-Encoding", &buf)
- || strcmp(buf, "base64") != 0){
- fprintf(handle->errstream, "Unhandled encoding: %s\n", buf);
- break;
- }
-
- buf = "<Content-Length Unspecified>";
- Uint32 len = 0;
- if(!prop->get("Content-Length", &len)){
- fprintf(handle->errstream, "Invalid response: %s\n\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->timeout,
- &buf64[start], len-start)) < 1){
- delete[] buf64;
- buf64 = 0;
- if(read==0)
- SET_ERROR(handle, ETIMEDOUT, "Timeout reading packed config");
- else
- SET_ERROR(handle, errno, "Error reading packed config");
- ndb_mgm_disconnect_quiet(handle);
- break;
- }
- start += read;
- } while(start < len);
- if(buf64 == 0)
- break;
-
- void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
- const int res = base64_decode(buf64, len-1, tmp_data, NULL);
- delete[] buf64;
- UtilBuffer tmp;
- tmp.append((void *) tmp_data, res);
- free(tmp_data);
- if (res < 0)
- {
- fprintf(handle->errstream, "Failed to decode buffer\n");
- break;
- }
-
- ConfigValuesFactory cvf;
- const int res2 = cvf.unpack(tmp);
- if(!res2){
- fprintf(handle->errstream, "Failed to unpack buffer\n");
- break;
- }
-
- delete prop;
- return (ndb_mgm_configuration*)cvf.getConfigValues();
- } while(0);
-
- delete prop;
- return 0;
-}
-
-extern "C"
-void
-ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg)
-{
- if (cfg) {
- ((ConfigValues *)cfg)->~ConfigValues();
- free((void *)cfg);
- }
-}
-
-extern "C"
-int
-ndb_mgm_set_configuration_nodeid(NdbMgmHandle handle, int nodeid)
-{
- CHECK_HANDLE(handle, -1);
- handle->cfg._ownNodeId= nodeid;
- return 0;
-}
-
-extern "C"
-int
-ndb_mgm_get_configuration_nodeid(NdbMgmHandle handle)
-{
- CHECK_HANDLE(handle, 0);
- return handle->cfg._ownNodeId;
-}
-
-extern "C"
-int ndb_mgm_get_connected_port(NdbMgmHandle handle)
-{
- if (handle->cfg_i >= 0)
- return handle->cfg.ids[handle->cfg_i].port;
- else
- return 0;
-}
-
-extern "C"
-const char *ndb_mgm_get_connected_host(NdbMgmHandle handle)
-{
- if (handle->cfg_i >= 0)
- return handle->cfg.ids[handle->cfg_i].name.c_str();
- else
- return 0;
-}
-
-extern "C"
-const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz)
-{
- return handle->cfg.makeConnectString(buf,buf_sz);
-}
-
-extern "C"
-int
-ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
- int log_event)
-{
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- union { long l; char c[sizeof(long)]; } endian_check;
-
- endian_check.l = 1;
-
- int nodeid= handle->cfg._ownNodeId;
-
- Properties args;
- args.put("version", version);
- args.put("nodetype", nodetype);
- args.put("nodeid", nodeid);
- args.put("user", "mysqld");
- args.put("password", "mysqld");
- args.put("public key", "a public key");
- args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
- if (handle->m_name)
- args.put("name", handle->m_name);
- args.put("log_event", log_event);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("get nodeid reply", NULL, ""),
- MGM_ARG("error_code", Int, Optional, "Error code"),
- MGM_ARG("nodeid", Int, Optional, "Error message"),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
- CHECK_REPLY(handle, prop, -1);
-
- nodeid= -1;
- do {
- const char * buf;
- if (!prop->get("result", &buf) || strcmp(buf, "Ok") != 0)
- {
- const char *hostname= ndb_mgm_get_connected_host(handle);
- unsigned port= ndb_mgm_get_connected_port(handle);
- BaseString err;
- Uint32 error_code= NDB_MGM_ALLOCID_ERROR;
- err.assfmt("Could not alloc node id at %s port %d: %s",
- hostname, port, buf);
- prop->get("error_code", &error_code);
- setError(handle, error_code, __LINE__, err.c_str());
- break;
- }
- Uint32 _nodeid;
- if(!prop->get("nodeid", &_nodeid) != 0){
- fprintf(handle->errstream, "ERROR Message: <nodeid Unspecified>\n");
- break;
- }
- nodeid= _nodeid;
- }while(0);
-
- delete prop;
- return nodeid;
-}
-
-extern "C"
-int
-ndb_mgm_set_int_parameter(NdbMgmHandle handle,
- int node,
- int param,
- unsigned value,
- struct ndb_mgm_reply*){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
- args.put("node", node);
- args.put("param", param);
- args.put("value", value);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("set parameter reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "set parameter", &args);
- CHECK_REPLY(handle, prop, -1);
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- res= 0;
- } while(0);
-
- delete prop;
- return res;
-}
-
-extern "C"
-int
-ndb_mgm_set_int64_parameter(NdbMgmHandle handle,
- int node,
- int param,
- unsigned long long value,
- struct ndb_mgm_reply*){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
- args.put("node", node);
- args.put("param", param);
- args.put("value", value);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("set parameter reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "set parameter", &args);
- CHECK_REPLY(handle, prop, 0);
-
- if(prop == NULL) {
- SET_ERROR(handle, EIO, "Unable set parameter");
- return -1;
- }
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- res= 0;
- } while(0);
-
- delete prop;
- return res;
-}
-
-extern "C"
-int
-ndb_mgm_set_string_parameter(NdbMgmHandle handle,
- int node,
- int param,
- const char * value,
- struct ndb_mgm_reply*){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
- args.put("node", node);
- args.put("parameter", param);
- args.put("value", value);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("set parameter reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "set parameter", &args);
- CHECK_REPLY(handle, prop, 0);
-
- if(prop == NULL) {
- SET_ERROR(handle, EIO, "Unable set parameter");
- return -1;
- }
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- res= 0;
- } while(0);
-
- delete prop;
- return res;
-}
-
-extern "C"
-int
-ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("purge stale sessions reply", NULL, ""),
- MGM_ARG("purged", String, Optional, ""),
- MGM_ARG("result", String, Mandatory, "Error message"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args);
- CHECK_REPLY(handle, prop, -1);
-
- if(prop == NULL) {
- SET_ERROR(handle, EIO, "Unable to purge stale sessions");
- return -1;
- }
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- if (purged) {
- if (prop->get("purged", &buf))
- *purged= strdup(buf);
- else
- *purged= 0;
- }
- res= 0;
- } while(0);
- delete prop;
- return res;
-}
-
-extern "C"
-int
-ndb_mgm_check_connection(NdbMgmHandle handle){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- SocketOutputStream out(handle->socket, handle->timeout);
- SocketInputStream in(handle->socket, handle->timeout);
- char buf[32];
- if (out.println("check connection"))
- goto ndb_mgm_check_connection_error;
-
- if (out.println(""))
- goto ndb_mgm_check_connection_error;
-
- in.gets(buf, sizeof(buf));
- if(strcmp("check connection reply\n", buf))
- goto ndb_mgm_check_connection_error;
-
- in.gets(buf, sizeof(buf));
- if(strcmp("result: Ok\n", buf))
- goto ndb_mgm_check_connection_error;
-
- in.gets(buf, sizeof(buf));
- if(strcmp("\n", buf))
- goto ndb_mgm_check_connection_error;
-
- return 0;
-
-ndb_mgm_check_connection_error:
- ndb_mgm_disconnect(handle);
- return -1;
-}
-
-extern "C"
-int
-ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
- int node1,
- int node2,
- int param,
- int value,
- struct ndb_mgm_reply* mgmreply){
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- DBUG_ENTER("ndb_mgm_set_connection_int_parameter");
-
- Properties args;
- args.put("node1", node1);
- args.put("node2", node2);
- args.put("param", param);
- args.put("value", (Uint32)value);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("set connection parameter reply", NULL, ""),
- MGM_ARG("message", String, Mandatory, "Error Message"),
- MGM_ARG("result", String, Mandatory, "Status Result"),
- MGM_END()
- };
-
- const Properties *prop;
- prop= ndb_mgm_call(handle, reply, "set connection parameter", &args);
- DBUG_CHECK_REPLY(handle, prop, -1);
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- res= 0;
- } while(0);
-
- delete prop;
- DBUG_RETURN(res);
-}
-
-extern "C"
-int
-ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
- int node1,
- int node2,
- int param,
- int *value,
- struct ndb_mgm_reply* mgmreply){
- CHECK_HANDLE(handle, -1);
- CHECK_CONNECTED(handle, -2);
- DBUG_ENTER("ndb_mgm_get_connection_int_parameter");
-
- Properties args;
- args.put("node1", node1);
- args.put("node2", node2);
- args.put("param", param);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("get connection parameter reply", NULL, ""),
- MGM_ARG("value", Int, Mandatory, "Current Value"),
- MGM_ARG("result", String, Mandatory, "Result"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "get connection parameter", &args);
- DBUG_CHECK_REPLY(handle, prop, -3);
-
- int res= -1;
- do {
- const char * buf;
- if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
- fprintf(handle->errstream, "ERROR Message: %s\n", buf);
- break;
- }
- res= 0;
- } while(0);
-
- if(!prop->get("value",(Uint32*)value)){
- fprintf(handle->errstream, "Unable to get value\n");
- res = -4;
- }
-
- delete prop;
- DBUG_RETURN(res);
-}
-
-extern "C"
-NDB_SOCKET_TYPE
-ndb_mgm_convert_to_transporter(NdbMgmHandle *handle)
-{
- NDB_SOCKET_TYPE s;
-
- CHECK_HANDLE((*handle), NDB_INVALID_SOCKET);
- CHECK_CONNECTED((*handle), NDB_INVALID_SOCKET);
-
- (*handle)->connected= 0; // we pretend we're disconnected
- s= (*handle)->socket;
-
- SocketOutputStream s_output(s, (*handle)->timeout);
- s_output.println("transporter connect");
- s_output.println("");
-
- ndb_mgm_destroy_handle(handle); // set connected=0, so won't disconnect
-
- return s;
-}
-
-extern "C"
-Uint32
-ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
-{
- Uint32 nodeid=0;
-
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- DBUG_ENTER("ndb_mgm_get_mgmd_nodeid");
-
- Properties args;
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("get mgmd nodeid reply", NULL, ""),
- MGM_ARG("nodeid", Int, Mandatory, "Node ID"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args);
- DBUG_CHECK_REPLY(handle, prop, 0);
-
- if(!prop->get("nodeid",&nodeid)){
- fprintf(handle->errstream, "Unable to get value\n");
- return 0;
- }
-
- delete prop;
- DBUG_RETURN(nodeid);
-}
-
-extern "C"
-int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
-{
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- DBUG_ENTER("ndb_mgm_report_event");
-
- Properties args;
- args.put("length", length);
- BaseString data_string;
-
- for (int i = 0; i < (int) length; i++)
- data_string.appfmt(" %lu", (ulong) data[i]);
-
- args.put("data", data_string.c_str());
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("report event reply", NULL, ""),
- MGM_ARG("result", String, Mandatory, "Result"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "report event", &args);
- DBUG_CHECK_REPLY(handle, prop, -1);
-
- DBUG_RETURN(0);
-}
-
-extern "C"
-int ndb_mgm_end_session(NdbMgmHandle handle)
-{
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
- DBUG_ENTER("ndb_mgm_end_session");
-
- SocketOutputStream s_output(handle->socket, handle->timeout);
- s_output.println("end session");
- s_output.println("");
-
- SocketInputStream in(handle->socket, handle->timeout);
- char buf[32];
- in.gets(buf, sizeof(buf));
- CHECK_TIMEDOUT_RET(handle, in, s_output, -1);
-
- DBUG_RETURN(0);
-}
-
-extern "C"
-int ndb_mgm_get_version(NdbMgmHandle handle,
- int *major, int *minor, int *build, int len, char* str)
-{
- DBUG_ENTER("ndb_mgm_get_version");
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("version", NULL, ""),
- MGM_ARG("id", Int, Mandatory, "ID"),
- MGM_ARG("major", Int, Mandatory, "Major"),
- MGM_ARG("minor", Int, Mandatory, "Minor"),
- MGM_ARG("string", String, Mandatory, "String"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "get version", &args);
- CHECK_REPLY(handle, prop, 0);
-
- Uint32 id;
- if(!prop->get("id",&id)){
- fprintf(handle->errstream, "Unable to get value\n");
- return 0;
- }
- *build= getBuild(id);
-
- if(!prop->get("major",(Uint32*)major)){
- fprintf(handle->errstream, "Unable to get value\n");
- return 0;
- }
-
- if(!prop->get("minor",(Uint32*)minor)){
- fprintf(handle->errstream, "Unable to get value\n");
- return 0;
- }
-
- BaseString result;
- if(!prop->get("string", result)){
- fprintf(handle->errstream, "Unable to get value\n");
- return 0;
- }
-
- strncpy(str, result.c_str(), len);
-
- delete prop;
- DBUG_RETURN(1);
-}
-
-extern "C"
-Uint64
-ndb_mgm_get_session_id(NdbMgmHandle handle)
-{
- Uint64 session_id=0;
-
- DBUG_ENTER("ndb_mgm_get_session_id");
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("get session id reply", NULL, ""),
- MGM_ARG("id", Int, Mandatory, "Node ID"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "get session id", &args);
- CHECK_REPLY(handle, prop, 0);
-
- if(!prop->get("id",&session_id)){
- fprintf(handle->errstream, "Unable to get session id\n");
- return 0;
- }
-
- delete prop;
- DBUG_RETURN(session_id);
-}
-
-extern "C"
-int
-ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
- struct NdbMgmSession *s, int *len)
-{
- int retval= 0;
- DBUG_ENTER("ndb_mgm_get_session");
- CHECK_HANDLE(handle, 0);
- CHECK_CONNECTED(handle, 0);
-
- Properties args;
- args.put("id", id);
-
- const ParserRow<ParserDummy> reply[]= {
- MGM_CMD("get session reply", NULL, ""),
- MGM_ARG("id", Int, Mandatory, "Node ID"),
- MGM_ARG("m_stopSelf", Int, Optional, "m_stopSelf"),
- MGM_ARG("m_stop", Int, Optional, "stop session"),
- MGM_ARG("nodeid", Int, Optional, "allocated node id"),
- MGM_ARG("parser_buffer_len", Int, Optional, "waiting in buffer"),
- MGM_ARG("parser_status", Int, Optional, "parser status"),
- MGM_END()
- };
-
- const Properties *prop;
- prop = ndb_mgm_call(handle, reply, "get session", &args);
- CHECK_REPLY(handle, prop, 0);
-
- Uint64 r_id;
- int rlen= 0;
-
- if(!prop->get("id",&r_id)){
- fprintf(handle->errstream, "Unable to get session id\n");
- goto err;
- }
-
- s->id= r_id;
- rlen+=sizeof(s->id);
-
- if(prop->get("m_stopSelf",&(s->m_stopSelf)))
- rlen+=sizeof(s->m_stopSelf);
- else
- goto err;
-
- if(prop->get("m_stop",&(s->m_stop)))
- rlen+=sizeof(s->m_stop);
- else
- goto err;
-
- if(prop->get("nodeid",&(s->nodeid)))
- rlen+=sizeof(s->nodeid);
- else
- goto err;
-
- if(prop->get("parser_buffer_len",&(s->parser_buffer_len)))
- {
- rlen+=sizeof(s->parser_buffer_len);
- if(prop->get("parser_status",&(s->parser_status)))
- rlen+=sizeof(s->parser_status);
- }
-
- *len= rlen;
- retval= 1;
-
-err:
- delete prop;
- DBUG_RETURN(retval);
-}
-
-template class Vector<const ParserRow<ParserDummy>*>;
diff --git a/storage/ndb/src/mgmapi/mgmapi_configuration.cpp b/storage/ndb/src/mgmapi/mgmapi_configuration.cpp
deleted file mode 100644
index d5966a4f5a5..00000000000
--- a/storage/ndb/src/mgmapi/mgmapi_configuration.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Copyright (C) 2004-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-#include <ndb_types.h>
-#include <mgmapi.h>
-#include "mgmapi_configuration.hpp"
-#include "../mgmsrv/ConfigInfo.hpp"
-
-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, Uint64 * 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);
-}
-
-/**
- * Retrieve information about parameter
- * @param info : in - pointer to structure allocated by caller
- * @param size : in/out : pointer to int initialized to sizeof(ndb_mgm_param_info)...will be set to bytes set by function on return
-*/
-extern "C"
-int
-ndb_mgm_get_db_parameter_info(Uint32 paramId, struct ndb_mgm_param_info * info, size_t * size) {
- if ( paramId == 0 ) {
- return -1;
- }
-
- ConfigInfo data;
- for (int i = 0; i < data.m_NoOfParams; i++) {
- if (paramId == data.m_ParamInfo[i]._paramId && strcmp("DB", data.m_ParamInfo[i]._section) == 0) {
- size_t tmp = 0;
- if (tmp + sizeof(info->m_id) <= *size)
- {
- info->m_id = data.m_ParamInfo[i]._paramId;
- tmp += sizeof(info->m_id);
- }
-
- if (tmp + sizeof(info->m_name) <= *size)
- {
- info->m_name = data.m_ParamInfo[i]._fname;
- tmp += sizeof(info->m_name);
- }
-
- *size = tmp;
- return 0;
- }
- }
- return -1;
-}
diff --git a/storage/ndb/src/mgmapi/mgmapi_configuration.hpp b/storage/ndb/src/mgmapi/mgmapi_configuration.hpp
deleted file mode 100644
index 4ce74568970..00000000000
--- a/storage/ndb/src/mgmapi/mgmapi_configuration.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#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, Uint64 * value) const ;
- int get(int param, const char ** value) const ;
-
- //
- void reset();
- int enter();
-};
-
-#endif
diff --git a/storage/ndb/src/mgmapi/mgmapi_internal.h b/storage/ndb/src/mgmapi/mgmapi_internal.h
deleted file mode 100644
index 1172bb79ba5..00000000000
--- a/storage/ndb/src/mgmapi/mgmapi_internal.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (c) 2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef MGMAPI_INTERNAL_H
-#define MGMAPI_INTERNAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <NdbTCP.h>
-
- /**
- * Set an integer parameter for a connection
- *
- * @param handle the NDB management handle.
- * @param node1 the node1 id
- * @param node2 the node2 id
- * @param param the parameter (e.g. CFG_CONNECTION_SERVER_PORT)
- * @param value what to set it to
- * @param reply from ndb_mgmd
- */
- int ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
- int node1,
- int node2,
- int param,
- int value,
- struct ndb_mgm_reply* reply);
-
- /**
- * Get an integer parameter for a connection
- *
- * @param handle the NDB management handle.
- * @param node1 the node1 id
- * @param node2 the node2 id
- * @param param the parameter (e.g. CFG_CONNECTION_SERVER_PORT)
- * @param value where to store the retreived value. In the case of
- * error, value is not changed.
- * @param reply from ndb_mgmd
- * @return 0 on success. < 0 on error.
- */
- int ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
- int node1,
- int node2,
- int param,
- int *value,
- struct ndb_mgm_reply* reply);
-
- /**
- * Convert connection to transporter
- * @param handle NDB management handle.
- *
- * @return socket
- *
- * @note the socket is now able to be used as a transporter connection
- */
- NDB_SOCKET_TYPE ndb_mgm_convert_to_transporter(NdbMgmHandle *handle);
-
- int ndb_mgm_disconnect_quiet(NdbMgmHandle handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/storage/ndb/src/mgmapi/ndb_logevent.cpp b/storage/ndb/src/mgmapi/ndb_logevent.cpp
deleted file mode 100644
index 5aeb48440c3..00000000000
--- a/storage/ndb/src/mgmapi/ndb_logevent.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <mgmapi.h>
-
-#include <NdbOut.hpp>
-#include <Properties.hpp>
-#include <socket_io.h>
-#include <InputStream.hpp>
-
-#include <debugger/EventLogger.hpp>
-
-#include "ndb_logevent.hpp"
-
-extern
-int ndb_mgm_listen_event_internal(NdbMgmHandle, const int filter[], int);
-
-struct ndb_logevent_error_msg {
- enum ndb_logevent_handle_error code;
- const char *msg;
-};
-
-struct ndb_logevent_error_msg ndb_logevent_error_messages[]= {
- { NDB_LEH_READ_ERROR, "Read error" },
- { NDB_LEH_MISSING_EVENT_SPECIFIER, "Missing event specifier" },
- { NDB_LEH_UNKNOWN_EVENT_VARIABLE, "Unknown event variable" },
- { NDB_LEH_UNKNOWN_EVENT_TYPE, "Unknown event type" },
- { NDB_LEH_INTERNAL_ERROR, "Unknown internal error" },
- { NDB_LEH_NO_ERROR,0}
-};
-
-struct ndb_logevent_handle {
- NDB_SOCKET_TYPE socket;
- enum ndb_logevent_handle_error m_error;
-};
-
-extern "C"
-NdbLogEventHandle
-ndb_mgm_create_logevent_handle(NdbMgmHandle mh,
- const int filter[])
-{
- int fd= ndb_mgm_listen_event_internal(mh, filter, 1);
-
- if (fd == -1)
- return 0;
-
- NdbLogEventHandle h=
- (NdbLogEventHandle)my_malloc(sizeof(ndb_logevent_handle),MYF(MY_WME));
-
- h->socket= fd;
-
- return h;
-}
-
-extern "C"
-int
-ndb_logevent_get_fd(const NdbLogEventHandle h)
-{
- return h->socket;
-}
-
-extern "C"
-void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h)
-{
- if( !h )
- return;
-
- if ( *h )
- close((*h)->socket);
-
- my_free(* h);
- * h = 0;
-}
-
-#define ROW(a,b,c,d) \
-{ NDB_LE_ ## a, b, c, 0, offsetof(struct ndb_logevent, a.d), \
- sizeof(((struct ndb_logevent *)0)->a.d) }
-
-#define ROW_FN(a,b,c,d,e) \
-{ NDB_LE_ ## a, b, c, e, offsetof(struct ndb_logevent, a.d), \
- sizeof(((struct ndb_logevent *)0)->a.d) }
-
-static int ref_to_node(int ref){
- return ref & 0xFFFF;
-}
-
-struct Ndb_logevent_body_row ndb_logevent_body[]= {
-
- // Connection
- ROW( Connected, "node", 1, node),
-
- ROW( Disconnected, "node", 1, node),
-
- ROW( CommunicationClosed, "node", 1, node),
-
- ROW( CommunicationOpened, "node", 1, node),
-
- ROW( ConnectedApiVersion, "node", 1, node),
- ROW( ConnectedApiVersion, "version", 2, version),
-
- /* CHECKPOINT */
-
- ROW( GlobalCheckpointStarted, "gci", 1, gci),
-
- ROW( GlobalCheckpointCompleted, "gci", 1, gci),
-
- ROW( LocalCheckpointStarted, "lci", 1, lci),
- ROW( LocalCheckpointStarted, "keep_gci", 2, keep_gci),
- ROW( LocalCheckpointStarted, "restore_gci", 3, restore_gci),
-
- ROW( LocalCheckpointCompleted, "lci", 1, lci),
-
- ROW( LCPStoppedInCalcKeepGci, "data", 1, data),
-
- ROW( LCPFragmentCompleted, "node", 1, node),
- ROW( LCPFragmentCompleted, "table_id", 2, table_id),
- ROW( LCPFragmentCompleted, "fragment_id", 3, fragment_id),
-
- ROW( UndoLogBlocked, "acc_count", 1, acc_count),
- ROW( UndoLogBlocked, "tup_count", 2, tup_count),
-
- /* STARTUP */
- ROW( NDBStartStarted, "version", 1, version),
-
- ROW( NDBStartCompleted, "version", 1, version),
-
-// ROW( STTORRYRecieved),
-
- ROW( StartPhaseCompleted, "phase", 1, phase),
- ROW( StartPhaseCompleted, "starttype", 2, starttype),
-
- ROW( CM_REGCONF, "own_id", 1, own_id),
- ROW( CM_REGCONF, "president_id", 2, president_id),
- ROW( CM_REGCONF, "dynamic_id", 3, dynamic_id),
-
- ROW( CM_REGREF, "own_id", 1, own_id),
- ROW( CM_REGREF, "other_id", 2, other_id),
- ROW( CM_REGREF, "cause", 3, cause),
-
- ROW( FIND_NEIGHBOURS, "own_id", 1, own_id),
- ROW( FIND_NEIGHBOURS, "left_id", 3, left_id),
- ROW( FIND_NEIGHBOURS, "right_id", 3, right_id),
- ROW( FIND_NEIGHBOURS, "dynamic_id", 4, dynamic_id),
-
- ROW( NDBStopStarted, "stoptype", 1, stoptype),
-
- ROW( NDBStopCompleted, "action", 1, action),
- ROW( NDBStopCompleted, "signum", 2, signum),
-
- ROW( NDBStopForced, "action", 1, action),
- ROW( NDBStopForced, "signum", 2, signum),
- ROW( NDBStopForced, "error", 3, error),
- ROW( NDBStopForced, "sphase", 4, sphase),
- ROW( NDBStopForced, "extra", 5, extra),
-
-// ROW( NDBStopAborted),
-
- ROW( StartREDOLog, "node", 1, node),
- ROW( StartREDOLog, "keep_gci", 2, keep_gci),
- ROW( StartREDOLog, "completed_gci", 3, completed_gci),
- ROW( StartREDOLog, "restorable_gci", 4, restorable_gci),
-
- ROW( StartLog, "log_part", 1, log_part),
- ROW( StartLog, "start_mb", 2, start_mb),
- ROW( StartLog, "stop_mb", 3, stop_mb),
- ROW( StartLog, "gci", 4, gci),
-
- ROW( UNDORecordsExecuted, "block", 1, block),
- ROW( UNDORecordsExecuted, "data1", 2, data1),
- ROW( UNDORecordsExecuted, "data2", 3, data2),
- ROW( UNDORecordsExecuted, "data3", 4, data3),
- ROW( UNDORecordsExecuted, "data4", 5, data4),
- ROW( UNDORecordsExecuted, "data5", 6, data5),
- ROW( UNDORecordsExecuted, "data6", 7, data6),
- ROW( UNDORecordsExecuted, "data7", 8, data7),
- ROW( UNDORecordsExecuted, "data8", 9, data8),
- ROW( UNDORecordsExecuted, "data9", 10, data9),
- ROW( UNDORecordsExecuted, "data10", 11, data10),
-
- /* NODERESTART */
-// ROW( NR_CopyDict),
-
-// ROW( NR_CopyDistr),
-
- ROW( NR_CopyFragsStarted, "dest_node", 1, dest_node),
-
- ROW( NR_CopyFragDone, "dest_node", 1, dest_node),
- ROW( NR_CopyFragDone, "table_id", 2, table_id),
- ROW( NR_CopyFragDone, "fragment_id", 3, fragment_id),
-
- ROW( NR_CopyFragsCompleted, "dest_node", 1, dest_node),
-
- ROW( NodeFailCompleted, "block", 1, block), /* 0 = all */
- ROW( NodeFailCompleted, "failed_node", 2, failed_node),
- ROW( NodeFailCompleted, "completing_node", 3, completing_node), /* 0 = all */
-
- ROW( NODE_FAILREP, "failed_node", 1, failed_node),
- ROW( NODE_FAILREP, "failure_state", 2, failure_state),
-
- /* TODO */
- ROW( ArbitState, "code", 1, code),
- ROW( ArbitState, "arbit_node", 2, arbit_node),
- ROW( ArbitState, "ticket_0", 3, ticket_0),
- ROW( ArbitState, "ticket_1", 4, ticket_1),
-
- /* TODO */
- ROW( ArbitResult, "code", 1, code),
- ROW( ArbitResult, "arbit_node", 2, arbit_node),
- ROW( ArbitResult, "ticket_0", 3, ticket_0),
- ROW( ArbitResult, "ticket_1", 4, ticket_1),
-
-// ROW( GCP_TakeoverStarted),
-
-// ROW( GCP_TakeoverCompleted),
-
-// ROW( LCP_TakeoverStarted),
-
- ROW( LCP_TakeoverCompleted, "state", 1, state),
-
- /* STATISTIC */
- ROW( TransReportCounters, "trans_count", 1, trans_count),
- ROW( TransReportCounters, "commit_count", 2, commit_count),
- ROW( TransReportCounters, "read_count", 3, read_count),
- ROW( TransReportCounters, "simple_read_count", 4, simple_read_count),
- ROW( TransReportCounters, "write_count", 5, write_count),
- ROW( TransReportCounters, "attrinfo_count", 6, attrinfo_count),
- ROW( TransReportCounters, "conc_op_count", 7, conc_op_count),
- ROW( TransReportCounters, "abort_count", 8, abort_count),
- ROW( TransReportCounters, "scan_count", 9, scan_count),
- ROW( TransReportCounters, "range_scan_count", 10, range_scan_count),
-
- ROW( OperationReportCounters, "ops", 1, ops),
-
- ROW( TableCreated, "table_id", 1, table_id),
-
- ROW( JobStatistic, "mean_loop_count", 1, mean_loop_count),
-
- ROW( SendBytesStatistic, "to_node", 1, to_node),
- ROW( SendBytesStatistic, "mean_sent_bytes", 2, mean_sent_bytes),
-
- ROW( ReceiveBytesStatistic, "from_node", 1, from_node),
- ROW( ReceiveBytesStatistic, "mean_received_bytes", 2, mean_received_bytes),
-
- ROW( MemoryUsage, "gth", 1, gth),
- ROW( MemoryUsage, "page_size_bytes", 2, page_size_bytes),
- ROW( MemoryUsage, "pages_used", 3, pages_used),
- ROW( MemoryUsage, "pages_total", 4, pages_total),
- ROW( MemoryUsage, "block", 5, block),
-
- /* ERROR */
- ROW( TransporterError, "to_node", 1, to_node),
- ROW( TransporterError, "code", 2, code),
-
- ROW( TransporterWarning, "to_node", 1, to_node),
- ROW( TransporterWarning, "code", 2, code),
-
- ROW( MissedHeartbeat, "node", 1, node),
- ROW( MissedHeartbeat, "count", 2, count),
-
- ROW( DeadDueToHeartbeat, "node", 1, node),
-
- /* TODO */
-// ROW( WarningEvent),
-
- /* INFO */
- ROW( SentHeartbeat, "node", 1, node),
-
- ROW( CreateLogBytes, "node", 1, node),
-
- /* TODO */
-// ROW( InfoEvent),
-
- ROW( EventBufferStatus, "usage", 1, usage),
- ROW( EventBufferStatus, "alloc", 2, alloc),
- ROW( EventBufferStatus, "max", 3, max),
- ROW( EventBufferStatus, "apply_gci_l", 4, apply_gci_l),
- ROW( EventBufferStatus, "apply_gci_h", 5, apply_gci_h),
- ROW( EventBufferStatus, "latest_gci_l", 6, latest_gci_l),
- ROW( EventBufferStatus, "latest_gci_h", 7, latest_gci_h),
-
- // Backup
- ROW_FN( BackupStarted, "starting_node", 1, starting_node, ref_to_node),
- ROW( BackupStarted, "backup_id", 2, backup_id),
-
- ROW_FN(BackupFailedToStart,"starting_node",1, starting_node, ref_to_node),
- ROW( BackupFailedToStart, "error", 2, error),
-
- ROW_FN( BackupCompleted, "starting_node", 1, starting_node, ref_to_node),
- ROW( BackupCompleted, "backup_id", 2, backup_id),
- ROW( BackupCompleted, "start_gci", 3, start_gci),
- ROW( BackupCompleted, "stop_gci", 4, stop_gci),
- ROW( BackupCompleted, "n_bytes", 5, n_bytes),
- ROW( BackupCompleted, "n_records", 6, n_records),
- ROW( BackupCompleted, "n_log_bytes", 7, n_log_bytes),
- ROW( BackupCompleted, "n_log_records", 8, n_log_records),
-
- ROW_FN( BackupAborted, "starting_node", 1, starting_node, ref_to_node),
- ROW( BackupAborted, "backup_id", 2, backup_id),
- ROW( BackupAborted, "error", 3, error),
-
- ROW( SingleUser, "type", 1, type),
- ROW( SingleUser, "node_id", 2, node_id),
- { NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0}
-};
-
-struct Ndb_logevent_header_row {
- const char *token; // token to use for text transfer
- int offset; // offset into struct ndb_logevent
- int size;
-};
-
-#define ROW2(a,b) \
-{ a, offsetof(struct ndb_logevent, b), \
- sizeof(((struct ndb_logevent *)0)->b) }
-
-struct Ndb_logevent_header_row ndb_logevent_header[]= {
- ROW2( "type", type),
- ROW2( "time", time),
- ROW2( "source_nodeid", source_nodeid),
- { 0, 0, 0 }
-};
-
-static int
-insert_row(const char * pair, Properties & p){
- BaseString tmp(pair);
-
- tmp.trim(" \t\n\r");
- Vector<BaseString> split;
- tmp.split(split, ":=", 2);
- if(split.size() != 2)
- return -1;
- p.put(split[0].trim().c_str(), split[1].trim().c_str());
-
- return 0;
-}
-
-static
-int memcpy_atoi(void *dst, const char *str, int sz)
-{
- switch (sz)
- {
- case 1:
- {
- Int8 val= atoi(str);
- memcpy(dst,&val,sz);
- return 0;
- }
- case 2:
- {
- Int16 val= atoi(str);
- memcpy(dst,&val,sz);
- return 0;
- }
- case 4:
- {
- Int32 val= atoi(str);
- memcpy(dst,&val,sz);
- return 0;
- }
- case 8:
- {
- Int64 val= atoi(str);
- memcpy(dst,&val,sz);
- return 0;
- }
- default:
- {
- return -1;
- }
- }
-}
-
-extern "C"
-int ndb_logevent_get_next(const NdbLogEventHandle h,
- struct ndb_logevent *dst,
- unsigned timeout_in_milliseconds)
-{
- if (timeout_in_milliseconds == 0)
- {
- int res;
- while ((res = ndb_logevent_get_next(h, dst, 60000))==0);
- return res;
- }
-
- SocketInputStream in(h->socket, timeout_in_milliseconds);
-
- Properties p;
- char buf[256];
-
- /* header */
- while (1) {
- if (in.gets(buf,sizeof(buf)) == 0)
- {
- h->m_error= NDB_LEH_READ_ERROR;
- return -1;
- }
- if ( buf[0] == 0 )
- {
- // timed out
- return 0;
- }
-
- if ( strcmp("log event reply\n", buf) == 0 )
- break;
-
- if ( strcmp("<PING>\n", buf) )
- ndbout_c("skipped: %s", buf);
-
- if(in.timedout())
- return 0;
- }
-
- /* read name-value pairs into properties object */
- while (1)
- {
- if (in.gets(buf,sizeof(buf)) == 0)
- {
- h->m_error= NDB_LEH_READ_ERROR;
- return -1;
- }
- if (in.timedout())
- return 0;
-
- if ( buf[0] == '\n' )
- {
- break;
- }
- if (insert_row(buf,p))
- {
- h->m_error= NDB_LEH_READ_ERROR;
- return -1;
- }
- }
-
- int i;
- const char *val;
-
- dst->type= (enum Ndb_logevent_type)-1;
- /* fill in header info from p*/
- for (i= 0; ndb_logevent_header[i].token; i++)
- {
- if ( p.get(ndb_logevent_header[i].token, &val) == 0 )
- {
- ndbout_c("missing: %s\n", ndb_logevent_header[i].token);
- h->m_error= NDB_LEH_MISSING_EVENT_SPECIFIER;
- return -1;
- }
- if ( memcpy_atoi((char *)dst+ndb_logevent_header[i].offset, val,
- ndb_logevent_header[i].size) )
- {
- h->m_error= NDB_LEH_INTERNAL_ERROR;
- return -1;
- }
- }
-
- Uint32 level;
- LogLevel::EventCategory category;
- Logger::LoggerLevel severity;
- EventLoggerBase::EventTextFunction text_fn;
-
- /* fill in rest of header info event_lookup */
- if (EventLoggerBase::event_lookup(dst->type,category,level,severity,text_fn))
- {
- ndbout_c("unknown type: %d\n", dst->type);
- h->m_error= NDB_LEH_UNKNOWN_EVENT_TYPE;
- return -1;
- }
- dst->category= (enum ndb_mgm_event_category)category;
- dst->severity= (enum ndb_mgm_event_severity)severity;
- dst->level= level;
-
- /* fill in header info from p */
- for (i= 0; ndb_logevent_body[i].token; i++)
- {
- if ( ndb_logevent_body[i].type != dst->type )
- continue;
- if ( p.get(ndb_logevent_body[i].token, &val) == 0 )
- {
- h->m_error= NDB_LEH_UNKNOWN_EVENT_VARIABLE;
- return -1;
- }
- if ( memcpy_atoi((char *)dst+ndb_logevent_body[i].offset, val,
- ndb_logevent_body[i].size) )
- {
- h->m_error= NDB_LEH_INTERNAL_ERROR;
- return -1;
- }
- }
- return 1;
-}
-
-extern "C"
-int ndb_logevent_get_latest_error(const NdbLogEventHandle h)
-{
- return h->m_error;
-}
-
-extern "C"
-const char *ndb_logevent_get_latest_error_msg(const NdbLogEventHandle h)
-{
- for (int i= 0; ndb_logevent_error_messages[i].msg; i++)
- if (ndb_logevent_error_messages[i].code == h->m_error)
- return ndb_logevent_error_messages[i].msg;
- return "<unknown error msg>";
-}
diff --git a/storage/ndb/src/mgmapi/ndb_logevent.hpp b/storage/ndb/src/mgmapi/ndb_logevent.hpp
deleted file mode 100644
index 128747ce639..00000000000
--- a/storage/ndb/src/mgmapi/ndb_logevent.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_LOGEVENT_HPP
-#define NDB_LOGEVENT_HPP
-
-#include <ndb_logevent.h>
-
-struct Ndb_logevent_body_row {
- enum Ndb_logevent_type type; // type
- const char *token; // token to use for text transfer
- int index; // index into theData array
- int (*index_fn)(int); // conversion function on the data array[index]
- int offset; // offset into struct ndb_logevent
- int size; // offset into struct ndb_logevent
-};
-
-extern
-struct Ndb_logevent_body_row ndb_logevent_body[];
-
-#endif
diff --git a/storage/ndb/src/mgmapi/test/Makefile b/storage/ndb/src/mgmapi/test/Makefile
deleted file mode 100644
index c6d3efa6fcc..00000000000
--- a/storage/ndb/src/mgmapi/test/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include .defs.mk
-
-TYPE := mgmapiclient util
-
-BIN_TARGET := testMgmapi
-
-CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon)
-#-I$(NDB_TOP)/include/util -I$(NDB_TOP)/include/portlib
-
-# Source files of non-templated classes (.C files)
-SOURCES = keso.cpp
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/mgmapi/test/keso.c b/storage/ndb/src/mgmapi/test/keso.c
deleted file mode 100644
index d385bcf8451..00000000000
--- a/storage/ndb/src/mgmapi/test/keso.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <mgmapi.h>
-
-#ifdef VM_TRACE
-#include <mgmapi_debug.h>
-#endif
-
-#include <NdbOut.hpp>
-
-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);
-static int testStopSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testSetTrace(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testInsertError(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testDumpState(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-#endif
-static int testFilterClusterLog(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testSetLogLevelClusterLog(NdbMgmHandle h,
- struct ndb_mgm_reply* reply);
-static int testSetLogLevelNode(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testRestartNode(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-static int testGetStatPort(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-
-typedef int (*FUNC)(NdbMgmHandle h, struct ndb_mgm_reply* reply);
-
-struct test_case {
- char name[255];
- FUNC func;
-};
-
-struct test_case test_connect_disconnect[] = {
- {"testConnect", &testConnect},
- {"testDisconnect", &testDisconnect}
-};
-
-struct test_case tests[] = {
- { "testStatus", &testStatus },
- { "testFilterClusterLog", &testFilterClusterLog },
- /*{ "testSetLogLevelClusterLog", &testSetLogLevelClusterLog },*/
- /*{ "testSetLogLevelNode", &testSetLogLevelNode },*/
- { "testRestartNode", &testRestartNode },
- { "testGetStatPort", &testGetStatPort },
-#ifdef VM_TRACE
- { "testLogSignals", &testLogSignals },
- { "testStartSignalLog", &testStartSignalLog },
- { "testStopSignalLog", &testStopSignalLog },
- { "testSetTrace", &testSetTrace },
- { "testDumpState", &testDumpState },
- { "testInsertError", &testInsertError }
-#endif
-};
-
-static int no_of_tests = sizeof(tests) / sizeof(struct test_case);
-static int testFailed = 0;
-
-static const char * g_connect_string = "localhost:2200";
-
-int
-main(int argc, const char** argv){
-
- struct ndb_mgm_reply reply;
- int i = 0;
- NdbMgmHandle h = NULL;
-
- if(argc > 1)
- g_connect_string = argv[1];
-
- ndbout_c("Using connectstring: %s", g_connect_string);
-
- for (i = 0; i < 2; i++) {
- ndbout_c("-- %s --", test_connect_disconnect[i].name);
- if (test_connect_disconnect[i].func(h, &reply) == 0) {
- ndbout_c("-- Passed --");
- } else {
- testFailed++;
- ndbout_c("-- Failed --");
- }
- }
- ndbout_c("-- %d passed, %d failed --", (2 - testFailed), testFailed);
-
-
- h = ndb_mgm_create_handle();
- ndb_mgm_connect(h, g_connect_string);
-
- for (i = 0; i < no_of_tests; i ++) {
- ndbout_c("-- %s --", tests[i].name);
- if (tests[i].func(h, &reply) == 0) {
- ndbout_c("-- Passed --");
- } else {
- testFailed++;
- ndbout_c("-- Failed --");
- ndb_mgm_disconnect(h);
- ndb_mgm_connect(h, g_connect_string);
- }
- }
- ndbout_c("-- %d passed, %d failed --", (no_of_tests - testFailed),
- testFailed);
-
- ndb_mgm_disconnect(h);
-
- return 0;
-}
-
-static
-int testConnect(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- h = ndb_mgm_create_handle();
- if (h != NULL) {
- if (ndb_mgm_connect(h, g_connect_string) == -1) {
- ndbout_c(g_connect_string);
- /*ndbout_c("last_error: %d", h->last_error); */
- return -1;
- } else {
- ndbout_c("Connected to localhost:37123");
- }
-
- } else {
- ndbout_c("Unable to create a NdbMgmHandle...");
- return -1;
- }
-
- return 0;
-}
-
-static
-int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- ndb_mgm_disconnect(h);
-
- return 0;
-}
-
-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);
- if (cluster != NULL) {
- ndbout_c("Number of nodes: %d", cluster->no_of_nodes);
- for (i = 0; i < cluster->no_of_nodes; i++) {
- struct ndb_mgm_node_state state = cluster->node_states[i];
- ndbout_c("NodeId: %d (%s)-- %s", state.node_id,
- ndb_mgm_get_node_type_string(state.node_type),
- ndb_mgm_get_node_status_string(state.node_status));
-
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
- return 0;
-}
-
-
-#ifdef VM_TRACE
-
-static
-int testLogSignals(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_log_signals(h, nodeId, NDB_MGM_SIGNAL_LOG_MODE_INOUT,
- "CMVMI QMGR",
- reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-}
-
-static
-int testStartSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_start_signallog(h, nodeId, reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-}
-
-static
-int testStopSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
-
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_stop_signallog(h, nodeId, reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static
-int testSetTrace(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_set_trace(h, nodeId, 2, reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static
-int testInsertError(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_insert_error(h, nodeId, 9999, reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static
-int testDumpState(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
-
- int rc = 0;
- int nodeId = 0;
- int dump[3];
-
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- dump[0] = 1;
- dump[1] = 2;
- dump[2] = 3;
- rc = ndb_mgm_dump_state(h, nodeId, dump, 3, reply);
-
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-}
-
-#endif
-
-static
-int testFilterClusterLog(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int rc = 0;
-
- rc = ndb_mgm_filter_clusterlog(h, NDB_MGM_CLUSTERLOG_INFO, reply);
- if (rc == -1) {
- ndbout_c("rc = %d", reply->return_code);
- ndbout_c("%s", reply->message);
- return -1;
- }
-
- ndbout_c("%s", reply->message);
-
- rc = ndb_mgm_filter_clusterlog(h, NDB_MGM_CLUSTERLOG_DEBUG, reply);
- if (rc == -1) {
- ndbout_c("rc = %d", reply->return_code);
- ndbout_c("%s", reply->message);
- return -1;
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static
-int testSetLogLevelClusterLog(NdbMgmHandle h,
- struct ndb_mgm_reply* reply) {
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_set_loglevel_clusterlog(h, nodeId,
- NDB_MGM_EVENT_CATEGORY_CHECKPOINT,
- 5,
- reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static
-int testSetLogLevelNode(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
-
- int rc = 0;
- int nodeId = 0;
- struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h);
- if (cluster != NULL) {
- if (cluster->no_of_nodes != 0) {
- nodeId = cluster->node_states[0].node_id;
- }
- free(cluster);
- } else {
- ndbout_c("Unable to get node status.");
- return -1;
- }
-
- rc = ndb_mgm_set_loglevel_node(h, nodeId,
- NDB_MGM_EVENT_CATEGORY_STATISTIC,
- 15,
- reply);
- if (rc != 0) {
- ndbout_c("rc = %d", reply->return_code);
- }
-
- ndbout_c("%s", reply->message);
-
- return rc;
-
-}
-
-static int
-testRestartNode(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
- int restarts = 0;
-
- restarts = ndb_mgm_restart(h, 0, 0); /* Restart all */
- if (restarts == 0) {
- ndbout_c("No nodes restarted...");
- return -1;
- } else {
- ndbout_c("%d nodes restarted...", restarts);
- }
-
- return 0;
-}
-
-static
-int testGetStatPort(NdbMgmHandle h, struct ndb_mgm_reply* reply) {
-
- int rc = 0;
- rc = ndb_mgm_get_stat_port(h, reply);
- if (rc == 0) {
- ndbout_c("stat port %s", reply->message);
- } else {
- ndbout_c("failed");
- }
-
- return rc;
-}
diff --git a/storage/ndb/src/mgmapi/test/mgmSrvApi.cpp b/storage/ndb/src/mgmapi/test/mgmSrvApi.cpp
deleted file mode 100644
index 97bab7780a0..00000000000
--- a/storage/ndb/src/mgmapi/test/mgmSrvApi.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/****************************************************
- * Name:
- * mgmSrvApi.cpp
- *
- * Description:
- * Test the bahaviour of the Management Server
- * API based on the tests specified in the
- * "Test Specification for the Management
- * Server API" document
- *
- *****************************************************/
-#include <ndb_global.h>
-#include "mgmapi.h"
-#include "mgmapi_commands.h"
-#include <NdbMain.h>
-#include <NdbOut.hpp>
-
-/**
- * The pupose of this test program is to
- * verify that the Management Server
- * API is functioning properly, i.e. a handle
- * can be created/destroyed properly, the
- * connection to the NDB nodes is established
- * correctly, and all the errors are handled in
- * a proper way.
- * USE: mgmSrvApi -n -i
- *
- * @param n Number of nodes to crash
- *
- **/
-NDB_COMMAND(mgmSrvApi, "mgmSrvApi", "mgmSrvApi -n <Number of nodes to crash> -i <Node ID to be crashed> -p <IP address:port number>", "Management Server API testing", 65535){
-
- const char *Addr = 0;
- int i;
- int nodesNo = 0; // Number of nodes to crash
- int ndbID = 0; // Node ID to be crashed
-
- i = 1;
- while (argc > 1) {
- if (strcmp(argv[i], "-n") == 0)
- nodesNo = atoi(argv[i+1]);
-
- if (strcmp(argv[i], "-i") == 0)
- ndbID = atoi(argv[i+1]);
-
- if (strcmp(argv[i], "-p") == 0)
- Addr = argv[i+1];
-
- argc -= 1;
- i = i + 1;
- }
-
- /*
- * Create a handle
- */
- ndbout << "Creating handle..." << endl;
- NdbMgmHandle h = ndb_mgm_create_handle();
-
- /*
- * Perfom the connection
- */
- ndbout << "Connecting..." << endl;
- if (ndb_mgm_connect(h, Addr) == -1) {
- ndbout << "Connection to " << Addr << " failed" << endl;
- exit(-1);
- }
-
- /*
- * Get status of a node
- */
- ndbout << "Getting status..." << endl;
-
- struct ndb_mgm_cluster_state * status;
- struct ndb_mgm_node_state * nodes;
-
- status = ndb_mgm_get_status(h);
- nodes = status->node_states;
- if (nodes->node_status == 1) {
- ndbout << "No contact established" << endl;
- // exit(-1);
- }
-
- /*
- * Stop the NDB nodes
- */
- ndbout << "Stopping the node(s)" << endl;
- const int * list;
-
- if (nodesNo == 0) // all nodes stopped by definition
- ndbID = 0;
-
- list = &ndbID;
- if (ndb_mgm_stop(h, nodesNo, list) != 1) {
- ndbout << nodesNo << " NDB node(s) not stopped " << endl;
- }
-
- /*
- * Disconnect from the management server
- */
- ndbout << "Disconnecting..." << endl;
- ndb_mgm_disconnect(h);
-
- /*
- * Destroy the handle
- */
- ndbout << "Destroying the handle..." << endl;
- ndb_mgm_destroy_handle(&h);
-
- return 0;
-}
diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
deleted file mode 100644
index 82795fa8185..00000000000
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp
+++ /dev/null
@@ -1,2744 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_sys.h>
-#include <Vector.hpp>
-#include <mgmapi.h>
-#include <util/BaseString.hpp>
-#include <ndbd_exit_codes.h>
-
-class MgmtSrvr;
-
-/**
- * @class CommandInterpreter
- * @brief Reads command line in management client
- *
- * This class has one public method which reads a command line
- * from a stream. It then interpret that commmand line and calls a suitable
- * method in the MgmtSrvr class which executes the command.
- *
- * For command syntax, see the HELP command.
- */
-class CommandInterpreter {
-public:
- /**
- * Constructor
- * @param mgmtSrvr: Management server to use when executing commands
- */
- CommandInterpreter(const char *, int verbose);
- ~CommandInterpreter();
-
- /**
- * Reads one line from the stream, parse the line to find
- * a command and then calls a suitable method which executes
- * the command.
- *
- * @return true until quit/bye/exit has been typed
- */
- int execute(const char *_line, int _try_reconnect=-1, bool interactive=1, int *error= 0);
-
-private:
- void printError();
- int execute_impl(const char *_line, bool interactive=1);
-
- /**
- * Analyse the command line, after the first token.
- *
- * @param processId: DB process id to send command to or -1 if
- * command will be sent to all DB processes.
- * @param allAfterFirstToken: What the client gave after the
- * first token on the command line
- * @return: 0 if analyseAfterFirstToken succeeds, otherwise -1
- */
- int analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
-
- int executeCommand(Vector<BaseString> &command_list,
- unsigned command_pos,
- int *node_ids, int no_of_nodes);
- /**
- * Parse the block specification part of the LOG* commands,
- * things after LOG*: [BLOCK = {ALL|<blockName>+}]
- *
- * @param allAfterLog: What the client gave after the second token
- * (LOG*) on the command line
- * @param blocks, OUT: ALL or name of all the blocks
- * @return: true if correct syntax, otherwise false
- */
- bool parseBlockSpecification(const char* allAfterLog,
- Vector<const char*>& blocks);
-
- /**
- * A bunch of execute functions: Executes one of the commands
- *
- * @param processId: DB process id to send command to
- * @param parameters: What the client gave after the command name
- * on the command line.
- * For example if complete input from user is: "1 LOGLEVEL 22" then the
- * parameters argument is the string with everything after LOGLEVEL, in
- * this case "22". Each function is responsible to check the parameters
- * argument.
- */
- int executeHelp(char* parameters);
- int executeShow(char* parameters);
- int executePurge(char* parameters);
- int executeConnect(char* parameters, bool interactive);
- int executeShutdown(char* parameters);
- void executeRun(char* parameters);
- void executeInfo(char* parameters);
- void executeClusterLog(char* parameters);
-
-public:
- int executeStop(int processId, const char* parameters, bool all);
- int executeEnterSingleUser(char* parameters);
- int executeExitSingleUser(char* parameters);
- int executeStart(int processId, const char* parameters, bool all);
- int executeRestart(int processId, const char* parameters, bool all);
- int executeLogLevel(int processId, const char* parameters, bool all);
- int executeError(int processId, const char* parameters, bool all);
- int executeLog(int processId, const char* parameters, bool all);
- int executeLogIn(int processId, const char* parameters, bool all);
- int executeLogOut(int processId, const char* parameters, bool all);
- int executeLogOff(int processId, const char* parameters, bool all);
- int executeTestOn(int processId, const char* parameters, bool all);
- int executeTestOff(int processId, const char* parameters, bool all);
- int executeSet(int processId, const char* parameters, bool all);
- int executeGetStat(int processId, const char* parameters, bool all);
- int executeStatus(int processId, const char* parameters, bool all);
- int executeEventReporting(int processId, const char* parameters, bool all);
- int executeDumpState(int processId, const char* parameters, bool all);
- int executeStartBackup(char * parameters, bool interactive);
- int executeAbortBackup(char * parameters);
- int executeStop(Vector<BaseString> &command_list, unsigned command_pos,
- int *node_ids, int no_of_nodes);
- int executeRestart(Vector<BaseString> &command_list, unsigned command_pos,
- int *node_ids, int no_of_nodes);
-
- int executeRep(char* parameters);
-
- void executeCpc(char * parameters);
-
-public:
- bool connect(bool interactive);
- bool disconnect();
-
- /**
- * A execute function definition
- */
-public:
- typedef int (CommandInterpreter::* ExecuteFunction)(int processId,
- const char * param,
- bool all);
-
- struct CommandFunctionPair {
- const char * command;
- ExecuteFunction executeFunction;
- };
-private:
- /**
- *
- */
- int executeForAll(const char * cmd,
- ExecuteFunction fun,
- const char * param);
-
- NdbMgmHandle m_mgmsrv;
- NdbMgmHandle m_mgmsrv2;
- const char *m_constr;
- bool m_connected;
- int m_verbose;
- int try_reconnect;
- int m_error;
- struct NdbThread* m_event_thread;
- NdbMutex *m_print_mutex;
-};
-
-struct event_thread_param {
- NdbMgmHandle *m;
- NdbMutex **p;
-};
-
-NdbMutex* print_mutex;
-
-/*
- * Facade object for CommandInterpreter
- */
-
-#include "ndb_mgmclient.hpp"
-#include "ndb_mgmclient.h"
-
-Ndb_mgmclient::Ndb_mgmclient(const char *host,int verbose)
-{
- m_cmd= new CommandInterpreter(host,verbose);
-}
-Ndb_mgmclient::~Ndb_mgmclient()
-{
- delete m_cmd;
-}
-int Ndb_mgmclient::execute(const char *_line, int _try_reconnect, bool interactive, int *error)
-{
- return m_cmd->execute(_line,_try_reconnect,interactive, error);
-}
-int
-Ndb_mgmclient::disconnect()
-{
- return m_cmd->disconnect();
-}
-
-extern "C" {
- Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string)
- {
- return (Ndb_mgmclient_handle) new Ndb_mgmclient(connect_string);
- }
- int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, char** argv)
- {
- return ((Ndb_mgmclient*)h)->execute(argc, argv, 1);
- }
- int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle h)
- {
- delete (Ndb_mgmclient*)h;
- return 0;
- }
-}
-/*
- * The CommandInterpreter
- */
-
-#include <mgmapi.h>
-#include <mgmapi_debug.h>
-#include <version.h>
-#include <NdbAutoPtr.hpp>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-#include <NdbMem.h>
-#include <EventLogger.hpp>
-#include <signaldata/SetLogLevelOrd.hpp>
-#include "MgmtErrorReporter.hpp"
-#include <Parser.hpp>
-#include <SocketServer.hpp>
-#include <util/InputStream.hpp>
-#include <util/OutputStream.hpp>
-
-int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect, bool interactive, int *error)
-{
- if (argc <= 0)
- return 0;
- BaseString _line(argv[0]);
- for (int i= 1; i < argc; i++)
- {
- _line.appfmt(" %s", argv[i]);
- }
- return m_cmd->execute(_line.c_str(),_try_reconnect, interactive, error);
-}
-
-/*****************************************************************************
- * HELP
- *****************************************************************************/
-static const char* helpText =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help\n"
-"---------------------------------------------------------------------------\n"
-"HELP Print help text\n"
-"HELP COMMAND Print detailed help for COMMAND(e.g. SHOW)\n"
-#ifdef VM_TRACE // DEBUG ONLY
-"HELP DEBUG Help for debug compiled version\n"
-#endif
-"SHOW Print information about cluster\n"
-#if 0
-"SHOW CONFIG Print configuration\n"
-"SHOW PARAMETERS Print configuration parameters\n"
-#endif
-"START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
-" Start backup (default WAIT COMPLETED)\n"
-"ABORT BACKUP <backup id> Abort backup\n"
-"SHUTDOWN Shutdown all processes in cluster\n"
-"CLUSTERLOG ON [<severity>] ... Enable Cluster logging\n"
-"CLUSTERLOG OFF [<severity>] ... Disable Cluster logging\n"
-"CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off\n"
-"CLUSTERLOG INFO Print cluster log information\n"
-"<id> START Start data node (started with -n)\n"
-"<id> RESTART [-n] [-i] [-a] Restart data or management server node\n"
-"<id> STOP [-a] Stop data or management server node\n"
-"ENTER SINGLE USER MODE <id> Enter single user mode\n"
-"EXIT SINGLE USER MODE Exit single user mode\n"
-"<id> STATUS Print status\n"
-"<id> CLUSTERLOG {<category>=<level>}+ Set log level for cluster log\n"
-"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n"
-"CONNECT [<connectstring>] Connect to management server (reconnect if already connected)\n"
-"QUIT Quit management client\n"
-;
-
-static const char* helpTextShow =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for SHOW command\n"
-"---------------------------------------------------------------------------\n"
-"SHOW Print information about cluster\n\n"
-"SHOW Print information about cluster.The status reported is from\n"
-" the perspective of the data nodes. API and Management Server nodes\n"
-" are only reported as connected once the data nodes have started.\n"
-#if 0
-"SHOW CONFIG Print configuration (in initial config file format)\n"
-"SHOW PARAMETERS Print information about configuration parameters\n\n"
-#endif
-;
-
-static const char* helpTextHelp =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for HELP command\n"
-"---------------------------------------------------------------------------\n"
-"HELP List available commands of NDB Cluster Management Client\n\n"
-"HELP List available commands.\n"
-;
-
-static const char* helpTextBackup =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for BACKUP command\n"
-"---------------------------------------------------------------------------\n"
-"BACKUP A backup is a snapshot of the database at a given time. \n"
-" The backup consists of three main parts:\n\n"
-" Metadata: the names and definitions of all database tables. \n"
-" Table records: the data actually stored in the database tables \n"
-" at the time that the backup was made.\n"
-" Transaction log: a sequential record telling how \n"
-" and when data was stored in the database.\n\n"
-" Backups are stored on each data node in the cluster that \n"
-" participates in the backup.\n\n"
-" The cluster log records backup related events (such as \n"
-" backup started, aborted, finished).\n"
-;
-
-static const char* helpTextStartBackup =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for START BACKUP command\n"
-"---------------------------------------------------------------------------\n"
-"START BACKUP Start a cluster backup\n\n"
-"START BACKUP [NOWAIT | WAIT STARTED | WAIT COMPLETED]\n"
-" Start a backup for the cluster.\n"
-" Each backup gets an ID number that is reported to the\n"
-" user. This ID number can help you find the backup on the\n"
-" file system, or ABORT BACKUP if you wish to cancel a \n"
-" running backup.\n\n"
-" NOWAIT \n"
-" Start a cluster backup and return immediately.\n"
-" The management client will return control directly\n"
-" to the user without waiting for the backup\n"
-" to have started.\n"
-" The status of the backup is recorded in the Cluster log.\n"
-" WAIT STARTED\n"
-" Start a cluster backup and return until the backup has\n"
-" started. The management client will wait for the backup \n"
-" to have started before returning control to the user.\n"
-" WAIT COMPLETED\n"
-" Start a cluster backup and return until the backup has\n"
-" completed. The management client will wait for the backup\n"
-" to complete before returning control to the user.\n"
-;
-
-static const char* helpTextAbortBackup =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for ABORT BACKUP command\n"
-"---------------------------------------------------------------------------\n"
-"ABORT BACKUP Abort a cluster backup\n\n"
-"ABORT BACKUP <backup id> \n"
-" Abort a backup that is already in progress.\n"
-" The backup id can be seen in the cluster log or in the\n"
-" output of the START BACKUP command.\n"
-;
-
-static const char* helpTextShutdown =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for SHUTDOWN command\n"
-"---------------------------------------------------------------------------\n"
-"SHUTDOWN Shutdown the cluster\n\n"
-"SHUTDOWN Shutdown the data nodes and management nodes.\n"
-" MySQL Servers and NDBAPI nodes are currently not \n"
-" shut down by issuing this command.\n"
-;
-
-static const char* helpTextClusterlogOn =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CLUSTERLOG ON command\n"
-"---------------------------------------------------------------------------\n"
-"CLUSTERLOG ON Enable Cluster logging\n\n"
-"CLUSTERLOG ON [<severity>] ... \n"
-" Turn the cluster log on.\n"
-" It tells management server which severity levels\n"
-" messages will be logged.\n\n"
-" <severity> can be any one of the following values:\n"
-" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
-;
-
-static const char* helpTextClusterlogOff =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CLUSTERLOG OFF command\n"
-"---------------------------------------------------------------------------\n"
-"CLUSTERLOG OFF Disable Cluster logging\n\n"
-"CLUSTERLOG OFF [<severity>] ... \n"
-" Turn the cluster log off.\n"
-" It tells management server which serverity\n"
-" levels logging will be disabled.\n\n"
-" <severity> can be any one of the following values:\n"
-" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
-;
-
-static const char* helpTextClusterlogToggle =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CLUSTERLOG TOGGLE command\n"
-"---------------------------------------------------------------------------\n"
-"CLUSTERLOG TOGGLE Toggle severity filter on/off\n\n"
-"CLUSTERLOG TOGGLE [<severity>] ... \n"
-" Toggle serverity filter on/off.\n"
-" If a serverity level is already enabled,then it will\n"
-" be disabled after you use the command,vice versa.\n\n"
-" <severity> can be any one of the following values:\n"
-" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
-;
-
-static const char* helpTextClusterlogInfo =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CLUSTERLOG INFO command\n"
-"---------------------------------------------------------------------------\n"
-"CLUSTERLOG INFO Print cluster log information\n\n"
-"CLUSTERLOG INFO Display which severity levels have been enabled,\n"
-" see HELP CLUSTERLOG for list of the severity levels.\n"
-;
-
-static const char* helpTextStart =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for START command\n"
-"---------------------------------------------------------------------------\n"
-"START Start data node (started with -n)\n\n"
-"<id> START Start the data node identified by <id>.\n"
-" Only starts data nodes that have not\n"
-" yet joined the cluster. These are nodes\n"
-" launched or restarted with the -n(--nostart)\n"
-" option.\n\n"
-" It does not launch the ndbd process on a remote\n"
-" machine.\n"
-;
-
-static const char* helpTextRestart =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for RESTART command\n"
-"---------------------------------------------------------------------------\n"
-"RESTART Restart data or management server node\n\n"
-"<id> RESTART [-n] [-i] [-a]\n"
-" Restart the data or management node <id>(or All data nodes).\n\n"
-" -n (--nostart) restarts the node but does not\n"
-" make it join the cluster. Use '<id> START' to\n"
-" join the node to the cluster.\n\n"
-" -i (--initial) perform initial start.\n"
-" This cleans the file system (ndb_<id>_fs)\n"
-" and the node will copy data from another node\n"
-" in the same node group during start up.\n\n"
-" Consult the documentation before using -i.\n\n"
-" INCORRECT USE OF -i WILL CAUSE DATA LOSS!\n"
-" -a Aborts the node, not syncing GCP.\n"
-;
-
-static const char* helpTextStop =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for STOP command\n"
-"---------------------------------------------------------------------------\n"
-"STOP Stop data or management server node\n\n"
-"<id> STOP [-a] Stop the data or management server node <id>.\n\n"
-" ALL STOP will just stop all data nodes.\n\n"
-" If you desire to also shut down management servers,\n"
-" use SHUTDOWN instead.\n"
-" -a Aborts the node, not syncing GCP.\n"
-;
-
-static const char* helpTextEnterSingleUserMode =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for ENTER SINGLE USER MODE command\n"
-"---------------------------------------------------------------------------\n"
-"ENTER SINGLE USER MODE Enter single user mode\n\n"
-"ENTER SINGLE USER MODE <id> \n"
-" Enters single-user mode, whereby only the MySQL Server or NDBAPI\n"
-" node identified by <id> is allowed to access the database. \n"
-;
-
-static const char* helpTextExitSingleUserMode =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for EXIT SINGLE USER MODE command\n"
-"---------------------------------------------------------------------------\n"
-"EXIT SINGLE USER MODE Exit single user mode\n\n"
-"EXIT SINGLE USER MODE \n"
-" Exits single-user mode, allowing all SQL nodes \n"
-" (that is, all running mysqld processes) to access the database. \n"
-;
-
-static const char* helpTextStatus =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for STATUS command\n"
-"---------------------------------------------------------------------------\n"
-"STATUS Print status\n\n"
-"<id> STATUS Displays status information for the data node <id>\n"
-" or for All data nodes. \n\n"
-" e.g.\n"
-" ALL STATUS\n"
-" 1 STATUS\n\n"
-" When a node is starting, the start phase will be\n"
-" listed.\n\n"
-" Start Phase Meaning\n"
-" 1 Clear the cluster file system(ndb_<id>_fs). \n"
-" This stage occurs only when the --initial option \n"
-" has been specified.\n"
-" 2 This stage sets up Cluster connections, establishes \n"
-" inter-node communications and starts Cluster heartbeats.\n"
-" 3 The arbitrator node is elected.\n"
-" 4 Initializes a number of internal cluster variables.\n"
-" 5 For an initial start or initial node restart,\n"
-" the redo log files are created.\n"
-" 6 If this is an initial start, create internal system tables.\n"
-" 7 Update internal variables. \n"
-" 8 In a system restart, rebuild all indexes.\n"
-" 9 Update internal variables. \n"
-" 10 The node can be connected by APIs and can receive events.\n"
-" 11 At this point,event delivery is handed over to\n"
-" the node joining the cluster.\n"
-"(see manual for more information)\n"
-;
-
-static const char* helpTextClusterlog =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CLUSTERLOG command\n"
-"---------------------------------------------------------------------------\n"
-"CLUSTERLOG Set log level for cluster log\n\n"
-" <id> CLUSTERLOG {<category>=<level>}+ \n"
-" Logs <category> events with priority less than \n"
-" or equal to <level> in the cluster log.\n\n"
-" <category> can be any one of the following values:\n"
-" STARTUP, SHUTDOWN, STATISTICS, CHECKPOINT, NODERESTART,\n"
-" CONNECTION, ERROR, INFO, CONGESTION, DEBUG, or BACKUP. \n\n"
-" <level> is represented by one of the numbers \n"
-" from 1 to 15 inclusive, where 1 indicates 'most important' \n"
-" and 15 'least important'.\n\n"
-" <severity> can be any one of the following values:\n"
-" ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG.\n"
-;
-
-
-static const char* helpTextPurgeStaleSessions =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for PURGE STALE SESSIONS command\n"
-"---------------------------------------------------------------------------\n"
-"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n\n"
-"PURGE STALE SESSIONS \n"
-" Running this statement forces all reserved \n"
-" node IDs to be checked; any that are not \n"
-" being used by nodes acutally connected to \n"
-" the cluster are then freed.\n\n"
-" This command is not normally needed, but may be\n"
-" required in some situations where failed nodes \n"
-" cannot rejoin the cluster due to failing to\n"
-" allocate a node id.\n"
-;
-
-static const char* helpTextConnect =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for CONNECT command\n"
-"---------------------------------------------------------------------------\n"
-"CONNECT Connect to management server (reconnect if already connected)\n\n"
-"CONNECT [<connectstring>] \n"
-" Connect to management server.\n"
-" The optional parameter connectstring specifies the \n"
-" connect string to user.\n\n"
-" A connect string may be:\n"
-" mgm-server\n"
-" mgm-server:port\n"
-" mgm1:port,mgm2:port\n"
-" With multiple management servers comma separated.\n"
-" The management client with try to connect to the \n"
-" management servers in the order they are listed.\n\n"
-" If no connect string is specified, the default \n"
-" is used. \n"
-;
-
-static const char* helpTextQuit =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for QUIT command\n"
-"---------------------------------------------------------------------------\n"
-"QUIT Quit management client\n\n"
-"QUIT Terminates the management client. \n"
-;
-
-
-#ifdef VM_TRACE // DEBUG ONLY
-static const char* helpTextDebug =
-"---------------------------------------------------------------------------\n"
-" NDB Cluster -- Management Client -- Help for Debugging (Internal use only)\n"
-"---------------------------------------------------------------------------\n"
-"SHOW PROPERTIES Print config properties object\n"
-"<id> LOGLEVEL {<category>=<level>}+ Set log level\n"
-#ifdef ERROR_INSERT
-"<id> ERROR <errorNo> Inject error into NDB node\n"
-#endif
-"<id> LOG [BLOCK = {ALL|<block>+}] Set logging on in & out signals\n"
-"<id> LOGIN [BLOCK = {ALL|<block>+}] Set logging on in signals\n"
-"<id> LOGOUT [BLOCK = {ALL|<block>+}] Set logging on out signals\n"
-"<id> LOGOFF [BLOCK = {ALL|<block>+}] Unset signal logging\n"
-"<id> TESTON Start signal logging\n"
-"<id> TESTOFF Stop signal logging\n"
-"<id> SET <configParamName> <value> Update configuration variable\n"
-"<id> DUMP <arg> Dump system state to cluster.log\n"
-"<id> GETSTAT Print statistics\n"
-"\n"
-"<id> = ALL | Any database node id\n"
-;
-#endif
-
-struct st_cmd_help {
- const char *cmd;
- const char * help;
-}help_items[]={
- {"SHOW", helpTextShow},
- {"HELP", helpTextHelp},
- {"BACKUP", helpTextBackup},
- {"START BACKUP", helpTextStartBackup},
- {"START BACKUP NOWAIT", helpTextStartBackup},
- {"START BACKUP WAIT STARTED", helpTextStartBackup},
- {"START BACKUP WAIT", helpTextStartBackup},
- {"START BACKUP WAIT COMPLETED", helpTextStartBackup},
- {"ABORT BACKUP", helpTextAbortBackup},
- {"SHUTDOWN", helpTextShutdown},
- {"CLUSTERLOG ON", helpTextClusterlogOn},
- {"CLUSTERLOG OFF", helpTextClusterlogOff},
- {"CLUSTERLOG TOGGLE", helpTextClusterlogToggle},
- {"CLUSTERLOG INFO", helpTextClusterlogInfo},
- {"START", helpTextStart},
- {"RESTART", helpTextRestart},
- {"STOP", helpTextStop},
- {"ENTER SINGLE USER MODE", helpTextEnterSingleUserMode},
- {"EXIT SINGLE USER MODE", helpTextExitSingleUserMode},
- {"STATUS", helpTextStatus},
- {"CLUSTERLOG", helpTextClusterlog},
- {"PURGE STALE SESSIONS", helpTextPurgeStaleSessions},
- {"CONNECT", helpTextConnect},
- {"QUIT", helpTextQuit},
-#ifdef VM_TRACE // DEBUG ONLY
- {"DEBUG", helpTextDebug},
-#endif //VM_TRACE
- {NULL, NULL}
-};
-
-static bool
-convert(const char* s, int& val) {
-
- if (s == NULL)
- return false;
-
- if (strlen(s) == 0)
- return false;
-
- errno = 0;
- char* p;
- long v = strtol(s, &p, 10);
- if (errno != 0)
- return false;
-
- if (p != &s[strlen(s)])
- return false;
-
- val = v;
- return true;
-}
-
-/*
- * Constructor
- */
-CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
- : m_verbose(verbose)
-{
- m_constr= _host;
- m_connected= false;
- m_event_thread= NULL;
- try_reconnect = 0;
- m_print_mutex= NdbMutex_Create();
-}
-
-/*
- * Destructor
- */
-CommandInterpreter::~CommandInterpreter()
-{
- disconnect();
- NdbMutex_Destroy(m_print_mutex);
-}
-
-static bool
-emptyString(const char* s)
-{
- if (s == NULL) {
- return true;
- }
-
- for (unsigned int i = 0; i < strlen(s); ++i) {
- if (! isspace(s[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-void
-CommandInterpreter::printError()
-{
- ndbout_c("* %5d: %s",
- ndb_mgm_get_latest_error(m_mgmsrv),
- ndb_mgm_get_latest_error_msg(m_mgmsrv));
- ndbout_c("* %s", ndb_mgm_get_latest_error_desc(m_mgmsrv));
- if (ndb_mgm_check_connection(m_mgmsrv))
- {
- disconnect();
- }
-}
-
-/*
- * print log event from mgmsrv to console screen
- */
-#define make_uint64(a,b) (((Uint64)(a)) + (((Uint64)(b)) << 32))
-#define Q64(a) make_uint64(event->EVENT.a ## _lo, event->EVENT.a ## _hi)
-#define R event->source_nodeid
-#define Q(a) event->EVENT.a
-#define QVERSION getMajor(Q(version)), getMinor(Q(version)), getBuild(Q(version))
-#define NDB_LE_(a) NDB_LE_ ## a
-static void
-printLogEvent(struct ndb_logevent* event)
-{
- switch (event->type) {
- /**
- * NDB_MGM_EVENT_CATEGORY_BACKUP
- */
-#undef EVENT
-#define EVENT BackupStarted
- case NDB_LE_BackupStarted:
- ndbout_c("Node %u: Backup %d started from node %d",
- R, Q(backup_id), Q(starting_node));
- break;
-#undef EVENT
-#define EVENT BackupFailedToStart
- case NDB_LE_BackupFailedToStart:
- ndbout_c("Node %u: Backup request from %d failed to start. Error: %d",
- R, Q(starting_node), Q(error));
- break;
-#undef EVENT
-#define EVENT BackupCompleted
- case NDB_LE_BackupCompleted:
- ndbout_c("Node %u: Backup %u started from node %u completed\n"
- " StartGCP: %u StopGCP: %u\n"
- " #Records: %u #LogRecords: %u\n"
- " Data: %u bytes Log: %u bytes", R,
- Q(backup_id), Q(starting_node),
- Q(start_gci), Q(stop_gci),
- Q(n_records), Q(n_log_records),
- Q(n_bytes), Q(n_log_bytes));
- break;
-#undef EVENT
-#define EVENT BackupAborted
- case NDB_LE_BackupAborted:
- ndbout_c("Node %u: Backup %d started from %d has been aborted. Error: %d",
- R, Q(backup_id), Q(starting_node), Q(error));
- break;
- /**
- * NDB_MGM_EVENT_CATEGORY_STARTUP
- */
-#undef EVENT
-#define EVENT NDBStartStarted
- case NDB_LE_NDBStartStarted:
- ndbout_c("Node %u: Start initiated (version %d.%d.%d)",
- R, QVERSION);
- break;
-#undef EVENT
-#define EVENT NDBStartCompleted
- case NDB_LE_NDBStartCompleted:
- ndbout_c("Node %u: Started (version %d.%d.%d)",
- R, QVERSION);
- break;
-#undef EVENT
-#define EVENT NDBStopStarted
- case NDB_LE_NDBStopStarted:
- ndbout_c("Node %u: %s shutdown initiated", R,
- (Q(stoptype) == 1 ? "Cluster" : "Node"));
- break;
-#undef EVENT
-#define EVENT NDBStopCompleted
- case NDB_LE_NDBStopCompleted:
- {
- BaseString action_str("");
- BaseString signum_str("");
- getRestartAction(Q(action), action_str);
- if (Q(signum))
- signum_str.appfmt(" Initiated by signal %d.",
- Q(signum));
- ndbout_c("Node %u: Node shutdown completed%s.%s",
- R, action_str.c_str(), signum_str.c_str());
- }
- break;
-#undef EVENT
-#define EVENT NDBStopForced
- case NDB_LE_NDBStopForced:
- {
- BaseString action_str("");
- BaseString reason_str("");
- BaseString sphase_str("");
- int signum = Q(signum);
- int error = Q(error);
- int sphase = Q(sphase);
- int extra = Q(extra);
- getRestartAction(Q(action), action_str);
- if (signum)
- reason_str.appfmt(" Initiated by signal %d.", signum);
- if (error)
- {
- ndbd_exit_classification cl;
- ndbd_exit_status st;
- const char *msg = ndbd_exit_message(error, &cl);
- const char *cl_msg = ndbd_exit_classification_message(cl, &st);
- const char *st_msg = ndbd_exit_status_message(st);
- reason_str.appfmt(" Caused by error %d: \'%s(%s). %s\'.",
- error, msg, cl_msg, st_msg);
- if (extra != 0)
- reason_str.appfmt(" (extra info %d)", extra);
- }
- if (sphase < 255)
- sphase_str.appfmt(" Occured during startphase %u.", sphase);
- ndbout_c("Node %u: Forced node shutdown completed%s.%s%s",
- R, action_str.c_str(), sphase_str.c_str(),
- reason_str.c_str());
- }
- break;
-#undef EVENT
-#define EVENT StopAborted
- case NDB_LE_NDBStopAborted:
- ndbout_c("Node %u: Node shutdown aborted", R);
- break;
- /**
- * default nothing to print
- */
- default:
- break;
- }
-}
-
-//*****************************************************************************
-//*****************************************************************************
-
-static int do_event_thread;
-static void*
-event_thread_run(void* p)
-{
- DBUG_ENTER("event_thread_run");
-
- struct event_thread_param param= *(struct event_thread_param*)p;
- NdbMgmHandle handle= *(param.m);
- NdbMutex* printmutex= *(param.p);
-
- int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
- 1, NDB_MGM_EVENT_CATEGORY_STARTUP,
- 0 };
-
- NdbLogEventHandle log_handle= NULL;
- struct ndb_logevent log_event;
-
- log_handle= ndb_mgm_create_logevent_handle(handle, filter);
- if (log_handle)
- {
- do_event_thread= 1;
- do {
- int res= ndb_logevent_get_next(log_handle, &log_event, 2000);
- if (res > 0)
- {
- Guard g(printmutex);
- printLogEvent(&log_event);
- }
- else if (res < 0)
- break;
- } while(do_event_thread);
- ndb_mgm_destroy_logevent_handle(&log_handle);
- }
- else
- {
- do_event_thread= -1;
- }
-
- DBUG_RETURN(NULL);
-}
-
-bool
-CommandInterpreter::connect(bool interactive)
-{
- DBUG_ENTER("CommandInterpreter::connect");
-
- if(m_connected)
- DBUG_RETURN(m_connected);
-
- m_mgmsrv = ndb_mgm_create_handle();
- if(m_mgmsrv == NULL) {
- ndbout_c("Cannot create handle to management server.");
- exit(-1);
- }
- if (interactive) {
- m_mgmsrv2 = ndb_mgm_create_handle();
- if(m_mgmsrv2 == NULL) {
- ndbout_c("Cannot create 2:nd handle to management server.");
- exit(-1);
- }
- }
-
- if (ndb_mgm_set_connectstring(m_mgmsrv, m_constr))
- {
- printError();
- exit(-1);
- }
-
- if(ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
- DBUG_RETURN(m_connected); // couldn't connect, always false
-
- const char *host= ndb_mgm_get_connected_host(m_mgmsrv);
- unsigned port= ndb_mgm_get_connected_port(m_mgmsrv);
- if (interactive) {
- BaseString constr;
- constr.assfmt("%s:%d",host,port);
- if(!ndb_mgm_set_connectstring(m_mgmsrv2, constr.c_str()) &&
- !ndb_mgm_connect(m_mgmsrv2, try_reconnect-1, 5, 1))
- {
- DBUG_PRINT("info",("2:ndb connected to Management Server ok at: %s:%d",
- host, port));
- assert(m_event_thread == NULL);
- assert(do_event_thread == 0);
- do_event_thread= 0;
- struct event_thread_param p;
- p.m= &m_mgmsrv2;
- p.p= &m_print_mutex;
- m_event_thread = NdbThread_Create(event_thread_run,
- (void**)&p,
- 32768,
- "CommandInterpreted_event_thread",
- NDB_THREAD_PRIO_LOW);
- if (m_event_thread)
- {
- DBUG_PRINT("info",("Thread created ok, waiting for started..."));
- int iter= 1000; // try for 30 seconds
- while(do_event_thread == 0 &&
- iter-- > 0)
- NdbSleep_MilliSleep(30);
- }
- if (m_event_thread == NULL ||
- do_event_thread == 0 ||
- do_event_thread == -1)
- {
- DBUG_PRINT("info",("Warning, event thread startup failed, "
- "degraded printouts as result, errno=%d",
- errno));
- printf("Warning, event thread startup failed, "
- "degraded printouts as result, errno=%d\n", errno);
- do_event_thread= 0;
- if (m_event_thread)
- {
- void *res;
- NdbThread_WaitFor(m_event_thread, &res);
- NdbThread_Destroy(&m_event_thread);
- }
- ndb_mgm_disconnect(m_mgmsrv2);
- }
- }
- else
- {
- DBUG_PRINT("warning",
- ("Could not do 2:nd connect to mgmtserver for event listening"));
- DBUG_PRINT("info", ("code: %d, msg: %s",
- ndb_mgm_get_latest_error(m_mgmsrv2),
- ndb_mgm_get_latest_error_msg(m_mgmsrv2)));
- printf("Warning, event connect failed, degraded printouts as result\n");
- printf("code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(m_mgmsrv2),
- ndb_mgm_get_latest_error_msg(m_mgmsrv2));
- }
- }
- m_connected= true;
- DBUG_PRINT("info",("Connected to Management Server at: %s:%d", host, port));
- if (m_verbose)
- {
- printf("Connected to Management Server at: %s:%d\n",
- host, port);
- }
-
- DBUG_RETURN(m_connected);
-}
-
-bool
-CommandInterpreter::disconnect()
-{
- DBUG_ENTER("CommandInterpreter::disconnect");
-
- if (m_event_thread) {
- void *res;
- do_event_thread= 0;
- NdbThread_WaitFor(m_event_thread, &res);
- NdbThread_Destroy(&m_event_thread);
- m_event_thread= NULL;
- ndb_mgm_destroy_handle(&m_mgmsrv2);
- }
- if (m_connected)
- {
- ndb_mgm_destroy_handle(&m_mgmsrv);
- m_connected= false;
- }
- DBUG_RETURN(true);
-}
-
-//*****************************************************************************
-//*****************************************************************************
-
-int
-CommandInterpreter::execute(const char *_line, int _try_reconnect,
- bool interactive, int *error)
-{
- if (_try_reconnect >= 0)
- try_reconnect=_try_reconnect;
- int result= execute_impl(_line, interactive);
- if (error)
- *error= m_error;
-
- return result;
-}
-
-static void
-invalid_command(const char *cmd)
-{
- ndbout << "Invalid command: " << cmd << endl;
- ndbout << "Type HELP for help." << endl << endl;
-}
-
-int
-CommandInterpreter::execute_impl(const char *_line, bool interactive)
-{
- DBUG_ENTER("CommandInterpreter::execute_impl");
- DBUG_PRINT("enter",("line=\"%s\"",_line));
- m_error= 0;
-
- char * line;
- if(_line == NULL) {
- m_error = -1;
- DBUG_RETURN(false);
- }
- line = my_strdup(_line,MYF(MY_WME));
- My_auto_ptr<char> ptr(line);
-
- int do_continue;
- do {
- do_continue= 0;
- BaseString::trim(line," \t");
- if (line[0] == 0 ||
- line[0] == '#')
- {
- DBUG_RETURN(true);
- }
- // for mysql client compatability remove trailing ';'
- {
- unsigned last= strlen(line)-1;
- if (line[last] == ';')
- {
- line[last]= 0;
- do_continue= 1;
- }
- }
- } while (do_continue);
- // if there is anything in the line proceed
- Vector<BaseString> command_list;
- {
- BaseString tmp(line);
- tmp.split(command_list);
- for (unsigned i= 0; i < command_list.size();)
- command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
- }
- char* firstToken = strtok(line, " ");
- char* allAfterFirstToken = strtok(NULL, "");
-
- if (strcasecmp(firstToken, "HELP") == 0 ||
- strcasecmp(firstToken, "?") == 0) {
- m_error = executeHelp(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "CONNECT") == 0) {
- m_error = executeConnect(allAfterFirstToken, interactive);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "SLEEP") == 0) {
- if (allAfterFirstToken)
- if (sleep(atoi(allAfterFirstToken)) != 0 )
- m_error = -1;
- DBUG_RETURN(true);
- }
- else if((strcasecmp(firstToken, "QUIT") == 0 ||
- strcasecmp(firstToken, "EXIT") == 0 ||
- strcasecmp(firstToken, "BYE") == 0) &&
- allAfterFirstToken == NULL){
- DBUG_RETURN(false);
- }
-
- if (!connect(interactive)){
- m_error = -1;
- DBUG_RETURN(true);
- }
-
- if (ndb_mgm_check_connection(m_mgmsrv))
- {
- disconnect();
- connect(interactive);
- }
-
- if (strcasecmp(firstToken, "SHOW") == 0) {
- Guard g(m_print_mutex);
- m_error = executeShow(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "SHUTDOWN") == 0) {
- m_error= executeShutdown(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "CLUSTERLOG") == 0){
- executeClusterLog(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if(strcasecmp(firstToken, "START") == 0 &&
- allAfterFirstToken != NULL &&
- strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
- m_error= executeStartBackup(allAfterFirstToken, interactive);
- DBUG_RETURN(true);
- }
- else if(strcasecmp(firstToken, "ABORT") == 0 &&
- allAfterFirstToken != NULL &&
- strncasecmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
- m_error = executeAbortBackup(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "PURGE") == 0) {
- m_error = executePurge(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if(strcasecmp(firstToken, "ENTER") == 0 &&
- allAfterFirstToken != NULL &&
- allAfterFirstToken != NULL &&
- strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
- sizeof("SINGLE USER MODE") - 1) == 0){
- m_error = executeEnterSingleUser(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if(strcasecmp(firstToken, "EXIT") == 0 &&
- allAfterFirstToken != NULL &&
- strncasecmp(allAfterFirstToken, "SINGLE USER MODE ",
- sizeof("SINGLE USER MODE") - 1) == 0){
- m_error = executeExitSingleUser(allAfterFirstToken);
- DBUG_RETURN(true);
- }
- else if (strcasecmp(firstToken, "ALL") == 0) {
- m_error = analyseAfterFirstToken(-1, allAfterFirstToken);
- } else {
- /**
- * First tokens should be digits, node ID's
- */
- int node_ids[MAX_NODES];
- unsigned pos;
- for (pos= 0; pos < command_list.size(); pos++)
- {
- int node_id;
- if (convert(command_list[pos].c_str(), node_id))
- {
- if (node_id <= 0 || node_id > MAX_NODES) {
- ndbout << "Invalid node ID: " << command_list[pos].c_str()
- << "." << endl;
- DBUG_RETURN(true);
- }
- node_ids[pos]= node_id;
- continue;
- }
- break;
- }
- int no_of_nodes= pos;
- if (no_of_nodes == 0)
- {
- /* No digit found */
- invalid_command(_line);
- m_error = -1;
- DBUG_RETURN(true);
- }
- if (pos == command_list.size())
- {
- /* No command found */
- invalid_command(_line);
- m_error = -1;
- DBUG_RETURN(true);
- }
- if (no_of_nodes == 1)
- {
- m_error = analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
- DBUG_RETURN(true);
- }
- m_error = executeCommand(command_list, pos, node_ids, no_of_nodes);
- DBUG_RETURN(true);
- }
- DBUG_RETURN(true);
-}
-
-
-/**
- * List of commands used as second command argument
- */
-static const CommandInterpreter::CommandFunctionPair commands[] = {
- { "START", &CommandInterpreter::executeStart }
- ,{ "RESTART", &CommandInterpreter::executeRestart }
- ,{ "STOP", &CommandInterpreter::executeStop }
- ,{ "STATUS", &CommandInterpreter::executeStatus }
- ,{ "LOGLEVEL", &CommandInterpreter::executeLogLevel }
- ,{ "CLUSTERLOG", &CommandInterpreter::executeEventReporting }
-#ifdef ERROR_INSERT
- ,{ "ERROR", &CommandInterpreter::executeError }
-#endif
- ,{ "LOG", &CommandInterpreter::executeLog }
- ,{ "LOGIN", &CommandInterpreter::executeLogIn }
- ,{ "LOGOUT", &CommandInterpreter::executeLogOut }
- ,{ "LOGOFF", &CommandInterpreter::executeLogOff }
- ,{ "TESTON", &CommandInterpreter::executeTestOn }
- ,{ "TESTOFF", &CommandInterpreter::executeTestOff }
- ,{ "SET", &CommandInterpreter::executeSet }
- ,{ "GETSTAT", &CommandInterpreter::executeGetStat }
- ,{ "DUMP", &CommandInterpreter::executeDumpState }
-};
-
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::analyseAfterFirstToken(int processId,
- char* allAfterFirstToken) {
-
- int retval = 0;
- if (emptyString(allAfterFirstToken)) {
- ndbout << "Expected a command after "
- << ((processId == -1) ? "ALL." : "node ID.") << endl;
- return -1;
- }
-
- char* secondToken = strtok(allAfterFirstToken, " ");
- char* allAfterSecondToken = strtok(NULL, "\0");
-
- const int tmpSize = sizeof(commands)/sizeof(CommandFunctionPair);
- ExecuteFunction fun = 0;
- const char * command = 0;
- for(int i = 0; i<tmpSize; i++){
- if(strcasecmp(secondToken, commands[i].command) == 0){
- fun = commands[i].executeFunction;
- command = commands[i].command;
- break;
- }
- }
-
- if(fun == 0){
- invalid_command(secondToken);
- return -1;
- }
-
- if(processId == -1){
- retval = executeForAll(command, fun, allAfterSecondToken);
- } else {
- retval = (this->*fun)(processId, allAfterSecondToken, false);
- }
- ndbout << endl;
- return retval;
-}
-
-int
-CommandInterpreter::executeCommand(Vector<BaseString> &command_list,
- unsigned command_pos,
- int *node_ids, int no_of_nodes)
-{
- const char *cmd= command_list[command_pos].c_str();
- int retval = 0;
-
- if (strcasecmp("STOP", cmd) == 0)
- {
- retval = executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
- return retval;
- }
- if (strcasecmp("RESTART", cmd) == 0)
- {
- retval = executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
- return retval;
- }
- ndbout_c("Invalid command: '%s' after multi node id list. "
- "Expected STOP or RESTART.", cmd);
- return -1;
-}
-
-/**
- * Get next nodeid larger than the give node_id. node_id will be
- * set to the next node_id in the list. node_id should be set
- * to 0 (zero) on the first call.
- *
- * @param handle the NDB management handle
- * @param node_id last node_id retreived, 0 at first call
- * @param type type of node to look for
- * @return 1 if a node was found, 0 if no more node exist
- */
-static
-int
-get_next_nodeid(struct ndb_mgm_cluster_state *cl,
- int *node_id,
- enum ndb_mgm_node_type type)
-{
- int i;
-
- if(cl == NULL)
- return 0;
-
- i=0;
- while((i < cl->no_of_nodes)) {
- if((*node_id < cl->node_states[i].node_id) &&
- (cl->node_states[i].node_type == type)) {
-
- if(i >= cl->no_of_nodes)
- return 0;
-
- *node_id = cl->node_states[i].node_id;
- return 1;
- }
- i++;
- }
-
- return 0;
-}
-
-int
-CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
- const char * allAfterSecondToken)
-{
- int nodeId = 0;
- int retval = 0;
-
- if(strcasecmp(cmd, "STOP") == 0) {
- ndbout_c("Executing STOP on all nodes.");
- retval = (this->*fun)(nodeId, allAfterSecondToken, true);
- } else if(strcasecmp(cmd, "RESTART") == 0) {
- ndbout_c("Executing RESTART on all nodes.");
- ndbout_c("Starting shutdown. This may take a while. Please wait...");
- retval = (this->*fun)(nodeId, allAfterSecondToken, true);
- ndbout_c("Trying to start all nodes of system.");
- ndbout_c("Use ALL STATUS to see the system start-up phases.");
- } else {
- Guard g(m_print_mutex);
- struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv);
- if(cl == 0){
- ndbout_c("Unable get status from management server");
- printError();
- return -1;
- }
- NdbAutoPtr<char> ap1((char*)cl);
- while(get_next_nodeid(cl, &nodeId, NDB_MGM_NODE_TYPE_NDB))
- retval = (this->*fun)(nodeId, allAfterSecondToken, true);
- }
- return retval;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-bool
-CommandInterpreter::parseBlockSpecification(const char* allAfterLog,
- Vector<const char*>& blocks)
-{
- // Parse: [BLOCK = {ALL|<blockName>+}]
-
- if (emptyString(allAfterLog)) {
- return true;
- }
-
- // Copy allAfterLog since strtok will modify it
- char* newAllAfterLog = my_strdup(allAfterLog,MYF(MY_WME));
- My_auto_ptr<char> ap1(newAllAfterLog);
- char* firstTokenAfterLog = strtok(newAllAfterLog, " ");
- for (unsigned int i = 0; i < strlen(firstTokenAfterLog); ++i) {
- firstTokenAfterLog[i] = toupper(firstTokenAfterLog[i]);
- }
-
- if (strcasecmp(firstTokenAfterLog, "BLOCK") != 0) {
- ndbout << "Unexpected value: " << firstTokenAfterLog
- << ". Expected BLOCK." << endl;
- return false;
- }
-
- char* allAfterFirstToken = strtok(NULL, "\0");
- if (emptyString(allAfterFirstToken)) {
- ndbout << "Expected =." << endl;
- return false;
- }
-
- char* secondTokenAfterLog = strtok(allAfterFirstToken, " ");
- if (strcasecmp(secondTokenAfterLog, "=") != 0) {
- ndbout << "Unexpected value: " << secondTokenAfterLog
- << ". Expected =." << endl;
- return false;
- }
-
- char* blockName = strtok(NULL, " ");
- bool all = false;
- if (blockName != NULL && (strcasecmp(blockName, "ALL") == 0)) {
- all = true;
- }
- while (blockName != NULL) {
- blocks.push_back(strdup(blockName));
- blockName = strtok(NULL, " ");
- }
-
- if (blocks.size() == 0) {
- ndbout << "No block specified." << endl;
- return false;
- }
- if (blocks.size() > 1 && all) {
- // More than "ALL" specified
- ndbout << "Nothing expected after ALL." << endl;
- return false;
- }
-
- return true;
-}
-
-
-
-/*****************************************************************************
- * HELP
- *****************************************************************************/
-int
-CommandInterpreter::executeHelp(char* parameters)
-{
- if (emptyString(parameters)) {
- ndbout << helpText;
-
- ndbout << endl
- << "<severity> = "
- << "ALERT | CRITICAL | ERROR | WARNING | INFO | DEBUG"
- << endl;
-
- ndbout << "<category> = ";
- for(int i = CFG_MIN_LOGLEVEL; i <= CFG_MAX_LOGLEVEL; i++){
- const char *str= ndb_mgm_get_event_category_string((ndb_mgm_event_category)i);
- if (str) {
- if (i != CFG_MIN_LOGLEVEL)
- ndbout << " | ";
- ndbout << str;
- }
- }
- ndbout << endl;
-
- ndbout << "<level> = " << "0 - 15" << endl;
- ndbout << "<id> = " << "ALL | Any database node id" << endl;
- ndbout << endl;
- ndbout << "For detailed help on COMMAND, use HELP COMMAND." << endl;
- } else {
- int i = 0;
- for (i = 0; help_items[i].cmd != NULL; i++)
- {
- if (strcasecmp(parameters, help_items[i].cmd) == 0)
- {
- ndbout << help_items[i].help;
- break;
- }
- }
- if (help_items[i].cmd == NULL){
- ndbout << "No help for " << parameters << " available" << endl;
- return -1;
- }
- }
- return 0;
-}
-
-
-/*****************************************************************************
- * SHUTDOWN
- *****************************************************************************/
-
-int
-CommandInterpreter::executeShutdown(char* parameters)
-{
- ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
- if(state == NULL) {
- ndbout_c("Could not get status");
- printError();
- return 1;
- }
- NdbAutoPtr<char> ap1((char*)state);
-
- int result = 0;
- int need_disconnect;
- result = ndb_mgm_stop3(m_mgmsrv, -1, 0, 0, &need_disconnect);
- if (result < 0) {
- ndbout << "Shutdown of NDB Cluster node(s) failed." << endl;
- printError();
- return result;
- }
-
- ndbout << result << " NDB Cluster node(s) have shutdown." << endl;
-
- if(need_disconnect) {
- ndbout << "Disconnecting to allow management server to shutdown."
- << endl;
- disconnect();
- }
- return 0;
-}
-
-/*****************************************************************************
- * SHOW
- *****************************************************************************/
-
-
-static
-const char *status_string(ndb_mgm_node_status status)
-{
- switch(status){
- case NDB_MGM_NODE_STATUS_NO_CONTACT:
- return "not connected";
- case NDB_MGM_NODE_STATUS_NOT_STARTED:
- return "not started";
- case NDB_MGM_NODE_STATUS_STARTING:
- return "starting";
- case NDB_MGM_NODE_STATUS_STARTED:
- return "started";
- case NDB_MGM_NODE_STATUS_SHUTTING_DOWN:
- return "shutting down";
- case NDB_MGM_NODE_STATUS_RESTARTING:
- return "restarting";
- case NDB_MGM_NODE_STATUS_SINGLEUSER:
- return "single user mode";
- default:
- return "unknown state";
- }
-}
-
-static void
-print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it,
- const char *proc_name, int no_proc, ndb_mgm_node_type type,
- int master_id)
-{
- int i;
- ndbout << "[" << proc_name
- << "(" << ndb_mgm_get_node_type_string(type) << ")]\t"
- << no_proc << " node(s)" << endl;
- for(i=0; i < state->no_of_nodes; i++) {
- struct ndb_mgm_node_state *node_state= &(state->node_states[i]);
- if(node_state->node_type == type) {
- int node_id= node_state->node_id;
- ndbout << "id=" << node_id;
- if(node_state->version != 0) {
- const char *hostname= node_state->connect_address;
- if (hostname == 0
- || strlen(hostname) == 0
- || strcasecmp(hostname,"0.0.0.0") == 0)
- ndbout << " ";
- else
- ndbout << "\t@" << hostname;
- ndbout << " (Version: "
- << getMajor(node_state->version) << "."
- << getMinor(node_state->version) << "."
- << getBuild(node_state->version);
- if (type == NDB_MGM_NODE_TYPE_NDB) {
- if (node_state->node_status != NDB_MGM_NODE_STATUS_STARTED) {
- ndbout << ", " << status_string(node_state->node_status);
- }
- if (node_state->node_group >= 0) {
- ndbout << ", Nodegroup: " << node_state->node_group;
- if (master_id && node_state->dynamic_id == master_id)
- ndbout << ", Master";
- }
- }
- ndbout << ")" << endl;
- } else {
- ndb_mgm_first(it);
- if(ndb_mgm_find(it, CFG_NODE_ID, node_id) == 0){
- const char *config_hostname= 0;
- ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &config_hostname);
- if (config_hostname == 0 || config_hostname[0] == 0)
- config_hostname= "any host";
- ndbout_c(" (not connected, accepting connect from %s)",
- config_hostname);
- }
- else
- {
- ndbout_c("Unable to find node with id: %d", node_id);
- }
- }
- }
- }
- ndbout << endl;
-}
-
-int
-CommandInterpreter::executePurge(char* parameters)
-{
- int command_ok= 0;
- do {
- if (emptyString(parameters))
- break;
- char* firstToken = strtok(parameters, " ");
- char* nextToken = strtok(NULL, " \0");
- if (strcasecmp(firstToken,"STALE") == 0 &&
- nextToken &&
- strcasecmp(nextToken, "SESSIONS") == 0) {
- command_ok= 1;
- break;
- }
- } while(0);
-
- if (!command_ok) {
- ndbout_c("Unexpected command, expected: PURGE STALE SESSIONS");
- return -1;
- }
-
- char *str;
-
- if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) {
- ndbout_c("Command failed");
- return -1;
- }
- if (str) {
- ndbout_c("Purged sessions with node id's: %s", str);
- free(str);
- }
- else
- {
- ndbout_c("No sessions purged");
- }
- return 0;
-}
-
-int
-CommandInterpreter::executeShow(char* parameters)
-{
- int i;
- if (emptyString(parameters)) {
- ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
- if(state == NULL) {
- ndbout_c("Could not get status");
- printError();
- return -1;
- }
- NdbAutoPtr<char> ap1((char*)state);
-
- ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_mgmsrv,0);
- if(conf == 0){
- ndbout_c("Could not get configuration");
- printError();
- return -1;
- }
-
- ndb_mgm_configuration_iterator * it;
- it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE);
-
- if(it == 0){
- ndbout_c("Unable to create config iterator");
- ndb_mgm_destroy_configuration(conf);
- return -1;
- }
- NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
-
- int
- master_id= 0,
- ndb_nodes= 0,
- api_nodes= 0,
- mgm_nodes= 0;
-
- for(i=0; i < state->no_of_nodes; i++) {
- if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_NDB &&
- state->node_states[i].version != 0){
- master_id= state->node_states[i].dynamic_id;
- break;
- }
- }
-
- for(i=0; i < state->no_of_nodes; i++) {
- switch(state->node_states[i].node_type) {
- case NDB_MGM_NODE_TYPE_API:
- api_nodes++;
- break;
- case NDB_MGM_NODE_TYPE_NDB:
- if (state->node_states[i].dynamic_id &&
- state->node_states[i].dynamic_id < master_id)
- master_id= state->node_states[i].dynamic_id;
- ndb_nodes++;
- break;
- case NDB_MGM_NODE_TYPE_MGM:
- mgm_nodes++;
- break;
- case NDB_MGM_NODE_TYPE_UNKNOWN:
- ndbout << "Error: Unknown Node Type" << endl;
- return -1;
- case NDB_MGM_NODE_TYPE_MAX:
- break; /* purify: deadcode */
- }
- }
-
- ndbout << "Cluster Configuration" << endl
- << "---------------------" << endl;
- print_nodes(state, it, "ndbd", ndb_nodes, NDB_MGM_NODE_TYPE_NDB, master_id);
- print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0);
- print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0);
- // ndbout << helpTextShow;
- ndb_mgm_destroy_configuration(conf);
- return 0;
- } else if (strcasecmp(parameters, "PROPERTIES") == 0 ||
- strcasecmp(parameters, "PROP") == 0) {
- ndbout << "SHOW PROPERTIES is not yet implemented." << endl;
- // ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */
- } else if (strcasecmp(parameters, "CONFIGURATION") == 0 ||
- strcasecmp(parameters, "CONFIG") == 0){
- ndbout << "SHOW CONFIGURATION is not yet implemented." << endl;
- //nbout << "_mgmtSrvr.getConfig()->printConfigFile();" << endl; /* XXX */
- } else if (strcasecmp(parameters, "PARAMETERS") == 0 ||
- strcasecmp(parameters, "PARAMS") == 0 ||
- strcasecmp(parameters, "PARAM") == 0) {
- ndbout << "SHOW PARAMETERS is not yet implemented." << endl;
- // ndbout << "_mgmtSrvr.getConfig()->getConfigInfo()->print();"
- // << endl; /* XXX */
- } else {
- ndbout << "Invalid argument." << endl;
- return -1;
- }
- return 0;
-}
-
-int
-CommandInterpreter::executeConnect(char* parameters, bool interactive)
-{
- BaseString *basestring = NULL;
-
- disconnect();
- if (!emptyString(parameters)) {
- basestring= new BaseString(parameters);
- m_constr= basestring->trim().c_str();
- }
- if ( connect(interactive) == false ){
- return -1;
- }
- if (basestring != NULL)
- delete basestring;
-
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-void
-CommandInterpreter::executeClusterLog(char* parameters)
-{
- DBUG_ENTER("CommandInterpreter::executeClusterLog");
- int i;
- if (emptyString(parameters))
- {
- ndbout << "Missing argument." << endl;
- m_error = -1;
- DBUG_VOID_RETURN;
- }
-
- enum ndb_mgm_event_severity severity = NDB_MGM_EVENT_SEVERITY_ALL;
-
- char * tmpString = my_strdup(parameters,MYF(MY_WME));
- My_auto_ptr<char> ap1(tmpString);
- char * tmpPtr = 0;
- char * item = strtok_r(tmpString, " ", &tmpPtr);
- int enable;
-
- ndb_mgm_severity enabled[NDB_MGM_EVENT_SEVERITY_ALL] =
- {{NDB_MGM_EVENT_SEVERITY_ON,0},
- {NDB_MGM_EVENT_SEVERITY_DEBUG,0},
- {NDB_MGM_EVENT_SEVERITY_INFO,0},
- {NDB_MGM_EVENT_SEVERITY_WARNING,0},
- {NDB_MGM_EVENT_SEVERITY_ERROR,0},
- {NDB_MGM_EVENT_SEVERITY_CRITICAL,0},
- {NDB_MGM_EVENT_SEVERITY_ALERT,0}};
- ndb_mgm_get_clusterlog_severity_filter(m_mgmsrv, &enabled[0], NDB_MGM_EVENT_SEVERITY_ALL);
- if(enabled == NULL) {
- ndbout << "Couldn't get status" << endl;
- printError();
- m_error = -1;
- DBUG_VOID_RETURN;
- }
-
- /********************
- * CLUSTERLOG INFO
- ********************/
- if (strcasecmp(item, "INFO") == 0) {
- DBUG_PRINT("info",("INFO"));
- if(enabled[0].value == 0)
- {
- ndbout << "Cluster logging is disabled." << endl;
- m_error = 0;
- DBUG_VOID_RETURN;
- }
-#if 0
- for(i = 0; i<DB_MGM_EVENT_SEVERITY_ALL;i++)
- printf("enabled[%d] = %d\n", i, enabled[i].value);
-#endif
- ndbout << "Severities enabled: ";
- for(i = 1; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) {
- const char *str= ndb_mgm_get_event_severity_string(enabled[i].category);
- if (str == 0)
- {
- DBUG_ASSERT(false);
- continue;
- }
- if(enabled[i].value)
- ndbout << BaseString(str).ndb_toupper() << " ";
- }
- ndbout << endl;
- m_error = 0;
- DBUG_VOID_RETURN;
-
- }
- else if (strcasecmp(item, "FILTER") == 0 ||
- strcasecmp(item, "TOGGLE") == 0)
- {
- DBUG_PRINT("info",("TOGGLE"));
- enable= -1;
- }
- else if (strcasecmp(item, "OFF") == 0)
- {
- DBUG_PRINT("info",("OFF"));
- enable= 0;
- } else if (strcasecmp(item, "ON") == 0) {
- DBUG_PRINT("info",("ON"));
- enable= 1;
- } else {
- ndbout << "Invalid argument." << endl;
- m_error = -1;
- DBUG_VOID_RETURN;
- }
-
- int res_enable;
- item = strtok_r(NULL, " ", &tmpPtr);
- if (item == NULL) {
- res_enable=
- ndb_mgm_set_clusterlog_severity_filter(m_mgmsrv,
- NDB_MGM_EVENT_SEVERITY_ON,
- enable, NULL);
- if (res_enable < 0)
- {
- ndbout << "Couldn't set filter" << endl;
- printError();
- m_error = -1;
- DBUG_VOID_RETURN;
- }
- ndbout << "Cluster logging is " << (res_enable ? "enabled.":"disabled") << endl;
- m_error = 0;
- DBUG_VOID_RETURN;
- }
-
- do {
- severity= NDB_MGM_ILLEGAL_EVENT_SEVERITY;
- if (strcasecmp(item, "ALL") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_ALL;
- } else if (strcasecmp(item, "ALERT") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_ALERT;
- } else if (strcasecmp(item, "CRITICAL") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_CRITICAL;
- } else if (strcasecmp(item, "ERROR") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_ERROR;
- } else if (strcasecmp(item, "WARNING") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_WARNING;
- } else if (strcasecmp(item, "INFO") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_INFO;
- } else if (strcasecmp(item, "DEBUG") == 0) {
- severity = NDB_MGM_EVENT_SEVERITY_DEBUG;
- } else if (strcasecmp(item, "OFF") == 0 ||
- strcasecmp(item, "ON") == 0) {
- if (enable < 0) // only makes sense with toggle
- severity = NDB_MGM_EVENT_SEVERITY_ON;
- }
- if (severity == NDB_MGM_ILLEGAL_EVENT_SEVERITY) {
- ndbout << "Invalid severity level: " << item << endl;
- m_error = -1;
- DBUG_VOID_RETURN;
- }
-
- res_enable= ndb_mgm_set_clusterlog_severity_filter(m_mgmsrv, severity,
- enable, NULL);
- if (res_enable < 0)
- {
- ndbout << "Couldn't set filter" << endl;
- printError();
- m_error = -1;
- DBUG_VOID_RETURN;
- }
- ndbout << BaseString(item).ndb_toupper().c_str() << " " << (res_enable ? "enabled":"disabled") << endl;
-
- item = strtok_r(NULL, " ", &tmpPtr);
- } while(item != NULL);
-
- m_error = 0;
- DBUG_VOID_RETURN;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-
-int
-CommandInterpreter::executeStop(int processId, const char *parameters,
- bool all)
-{
- int retval = 0;
-
- Vector<BaseString> command_list;
- if (parameters)
- {
- BaseString tmp(parameters);
- tmp.split(command_list);
- for (unsigned i= 0; i < command_list.size();)
- command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
- }
- if (all)
- retval = executeStop(command_list, 0, 0, 0);
- else
- retval = executeStop(command_list, 0, &processId, 1);
-
- return retval;
-}
-
-int
-CommandInterpreter::executeStop(Vector<BaseString> &command_list,
- unsigned command_pos,
- int *node_ids, int no_of_nodes)
-{
- int need_disconnect;
- int abort= 0;
- int retval = 0;
-
- for (; command_pos < command_list.size(); command_pos++)
- {
- const char *item= command_list[command_pos].c_str();
- if (strcasecmp(item, "-A") == 0)
- {
- abort= 1;
- continue;
- }
- ndbout_c("Invalid option: %s. Expecting -A after STOP",
- item);
- return -1;
- }
-
- int result= ndb_mgm_stop3(m_mgmsrv, no_of_nodes, node_ids, abort,
- &need_disconnect);
- if (result < 0)
- {
- ndbout_c("Shutdown failed.");
- printError();
- retval = -1;
- }
- else
- {
- if (node_ids == 0)
- ndbout_c("NDB Cluster has shutdown.");
- else
- {
- ndbout << "Node";
- for (int i= 0; i < no_of_nodes; i++)
- ndbout << " " << node_ids[i];
- ndbout_c(" has shutdown.");
- }
- }
-
- if(need_disconnect)
- {
- ndbout << "Disconnecting to allow Management Server to shutdown" << endl;
- disconnect();
- }
-
- return retval;
-}
-
-int
-CommandInterpreter::executeEnterSingleUser(char* parameters)
-{
- strtok(parameters, " ");
- struct ndb_mgm_reply reply;
- char* id = strtok(NULL, " ");
- id = strtok(NULL, " ");
- id = strtok(NULL, "\0");
- int nodeId = -1;
- if(id == 0 || sscanf(id, "%d", &nodeId) != 1){
- ndbout_c("Invalid arguments: expected <NodeId>");
- ndbout_c("Use SHOW to see what API nodes are configured");
- return -1;
- }
- int result = ndb_mgm_enter_single_user(m_mgmsrv, nodeId, &reply);
-
- if (result != 0) {
- ndbout_c("Entering single user mode for node %d failed", nodeId);
- printError();
- return -1;
- } else {
- ndbout_c("Single user mode entered");
- ndbout_c("Access is granted for API node %d only.", nodeId);
- }
- return 0;
-}
-
-int
-CommandInterpreter::executeExitSingleUser(char* parameters)
-{
- int result = ndb_mgm_exit_single_user(m_mgmsrv, 0);
- if (result != 0) {
- ndbout_c("Exiting single user mode failed.");
- printError();
- return -1;
- } else {
- ndbout_c("Exiting single user mode in progress.");
- ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
- return 0;
- }
-}
-
-int
-CommandInterpreter::executeStart(int processId, const char* parameters,
- bool all)
-{
- int result;
- int retval = 0;
- if(all) {
- result = ndb_mgm_start(m_mgmsrv, 0, 0);
- } else {
- result = ndb_mgm_start(m_mgmsrv, 1, &processId);
- }
-
- if (result <= 0) {
- ndbout << "Start failed." << endl;
- printError();
- retval = -1;
- } else
- {
- if(all)
- ndbout_c("NDB Cluster is being started.");
- else
- ndbout_c("Database node %d is being started.", processId);
- }
- return retval;
-}
-
-int
-CommandInterpreter::executeRestart(int processId, const char* parameters,
- bool all)
-{
- Vector<BaseString> command_list;
- int retval = 0;
-
- if (parameters)
- {
- BaseString tmp(parameters);
- tmp.split(command_list);
- for (unsigned i= 0; i < command_list.size();)
- command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
- }
- if (all)
- retval = executeRestart(command_list, 0, 0, 0);
- else
- retval = executeRestart(command_list, 0, &processId, 1);
-
- return retval;
-}
-
-int
-CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
- unsigned command_pos,
- int *node_ids, int no_of_nodes)
-{
- int result;
- int retval = 0;
- int nostart= 0;
- int initialstart= 0;
- int abort= 0;
- int need_disconnect= 0;
-
- for (; command_pos < command_list.size(); command_pos++)
- {
- const char *item= command_list[command_pos].c_str();
- if (strcasecmp(item, "-N") == 0)
- {
- nostart= 1;
- continue;
- }
- if (strcasecmp(item, "-I") == 0)
- {
- initialstart= 1;
- continue;
- }
- if (strcasecmp(item, "-A") == 0)
- {
- abort= 1;
- continue;
- }
- ndbout_c("Invalid option: %s. Expecting -A,-N or -I after RESTART",
- item);
- return -1;
- }
-
- if (nostart)
- ndbout_c("Shutting down nodes with \"-n, no start\" option, to subsequently start the nodes.");
-
- result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids,
- initialstart, nostart, abort, &need_disconnect);
-
- if (result <= 0) {
- ndbout_c("Restart failed.");
- printError();
- retval = -1;
- }
- else
- {
- if (node_ids == 0)
- ndbout_c("NDB Cluster is being restarted.");
- else
- {
- ndbout << "Node";
- for (int i= 0; i < no_of_nodes; i++)
- ndbout << " " << node_ids[i];
- ndbout_c(" is being restarted");
- }
- if(need_disconnect)
- disconnect();
- }
- return retval;
-}
-
-int
-CommandInterpreter::executeDumpState(int processId, const char* parameters,
- bool all)
-{
- if(emptyString(parameters)){
- ndbout << "Expected argument" << endl;
- return -1;
- }
-
- Uint32 no = 0;
- int pars[25];
-
- char * tmpString = my_strdup(parameters,MYF(MY_WME));
- My_auto_ptr<char> ap1(tmpString);
- char * tmpPtr = 0;
- char * item = strtok_r(tmpString, " ", &tmpPtr);
- while(item != NULL){
- if (0x0 <= strtoll(item, NULL, 0) && strtoll(item, NULL, 0) <= 0xffffffff){
- pars[no] = strtoll(item, NULL, 0);
- } else {
- ndbout << "Illegal value in argument to signal." << endl
- << "(Value must be between 0 and 0xffffffff.)"
- << endl;
- return -1;
- }
- no++;
- item = strtok_r(NULL, " ", &tmpPtr);
- }
- ndbout << "Sending dump signal with data:" << endl;
- for (Uint32 i=0; i<no; i++) {
- ndbout.setHexFormat(1) << pars[i] << " ";
- if (!(i+1 & 0x3)) ndbout << endl;
- }
-
- struct ndb_mgm_reply reply;
- return ndb_mgm_dump_state(m_mgmsrv, processId, pars, no, &reply);
-}
-
-int
-CommandInterpreter::executeStatus(int processId,
- const char* parameters, bool all)
-{
- if (! emptyString(parameters)) {
- ndbout_c("No parameters expected to this command.");
- return -1;
- }
-
- ndb_mgm_node_status status;
- Uint32 startPhase, version;
-
- struct ndb_mgm_cluster_state *cl;
- cl = ndb_mgm_get_status(m_mgmsrv);
- if(cl == NULL) {
- ndbout_c("Cannot get status of node %d.", processId);
- printError();
- return -1;
- }
- NdbAutoPtr<char> ap1((char*)cl);
-
- int i = 0;
- while((i < cl->no_of_nodes) && cl->node_states[i].node_id != processId)
- i++;
- if(cl->node_states[i].node_id != processId) {
- ndbout << processId << ": Node not found" << endl;
- return -1;
- }
- if (cl->node_states[i].node_type != NDB_MGM_NODE_TYPE_NDB){
- if (cl->node_states[i].version != 0){
- version = cl->node_states[i].version;
- ndbout << "Node "<< cl->node_states[i].node_id <<": connected" ;
- ndbout_c(" (Version %d.%d.%d)",
- getMajor(version) ,
- getMinor(version),
- getBuild(version));
-
- }else
- ndbout << "Node "<< cl->node_states[i].node_id <<": not connected" << endl;
- return 0;
- }
- status = cl->node_states[i].node_status;
- startPhase = cl->node_states[i].start_phase;
- version = cl->node_states[i].version;
-
- ndbout << "Node " << processId << ": " << status_string(status);
- switch(status){
- case NDB_MGM_NODE_STATUS_STARTING:
- ndbout << " (Phase " << startPhase << ")";
- break;
- case NDB_MGM_NODE_STATUS_SHUTTING_DOWN:
- ndbout << " (Phase " << startPhase << ")";
- break;
- default:
- break;
- }
- if(status != NDB_MGM_NODE_STATUS_NO_CONTACT)
- ndbout_c(" (Version %d.%d.%d)",
- getMajor(version) ,
- getMinor(version),
- getBuild(version));
- else
- ndbout << endl;
-
- return 0;
-}
-
-
-//*****************************************************************************
-//*****************************************************************************
-
-int
-CommandInterpreter::executeLogLevel(int processId, const char* parameters,
- bool all)
-{
- (void) all;
- if (emptyString(parameters)) {
- ndbout << "Expected argument" << endl;
- return -1;
- }
- BaseString tmp(parameters);
- Vector<BaseString> spec;
- tmp.split(spec, "=");
- if(spec.size() != 2){
- ndbout << "Invalid loglevel specification: " << parameters << endl;
- return -1;
- }
-
- spec[0].trim().ndb_toupper();
- int category = ndb_mgm_match_event_category(spec[0].c_str());
- if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){
- category = atoi(spec[0].c_str());
- if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
- category > NDB_MGM_MAX_EVENT_CATEGORY){
- ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl;
- return -1;
- }
- }
-
- int level = atoi(spec[1].c_str());
- if(level < 0 || level > 15){
- ndbout << "Invalid level: " << spec[1].c_str() << endl;
- return -1;
- }
-
- ndbout << "Executing LOGLEVEL on node " << processId << flush;
-
- struct ndb_mgm_reply reply;
- int result;
- result = ndb_mgm_set_loglevel_node(m_mgmsrv,
- processId,
- (ndb_mgm_event_category)category,
- level,
- &reply);
-
- if (result < 0) {
- ndbout_c(" failed.");
- printError();
- return -1;
- } else {
- ndbout_c(" OK!");
- }
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int CommandInterpreter::executeError(int processId,
- const char* parameters, bool /* all */)
-{
- int retval = 0;
- if (emptyString(parameters)) {
- ndbout << "Missing error number." << endl;
- return -1;
- }
-
- // Copy parameters since strtok will modify it
- char* newpar = my_strdup(parameters,MYF(MY_WME));
- My_auto_ptr<char> ap1(newpar);
- char* firstParameter = strtok(newpar, " ");
-
- int errorNo;
- if (! convert(firstParameter, errorNo)) {
- ndbout << "Expected an integer." << endl;
- return -1;
- }
-
- char* allAfterFirstParameter = strtok(NULL, "\0");
- if (! emptyString(allAfterFirstParameter)) {
- ndbout << "Nothing expected after error number." << endl;
- return -1;
- }
-
- retval = ndb_mgm_insert_error(m_mgmsrv, processId, errorNo, NULL);
- return retval;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-
-int
-CommandInterpreter::executeLog(int processId,
- const char* parameters, bool all)
-{
- struct ndb_mgm_reply reply;
- Vector<const char *> blocks;
- if (! parseBlockSpecification(parameters, blocks)) {
- return -1;
- }
- int len=1;
- Uint32 i;
- for(i=0; i<blocks.size(); i++) {
- len += strlen(blocks[i]) + 1;
- }
- char * blockNames = (char*)my_malloc(len,MYF(MY_WME));
- My_auto_ptr<char> ap1(blockNames);
-
- blockNames[0] = 0;
- for(i=0; i<blocks.size(); i++) {
- strcat(blockNames, blocks[i]);
- strcat(blockNames, "|");
- }
-
- int result = ndb_mgm_log_signals(m_mgmsrv,
- processId,
- NDB_MGM_SIGNAL_LOG_MODE_INOUT,
- blockNames,
- &reply);
- if (result != 0) {
- ndbout_c("Execute LOG on node %d failed.", processId);
- printError();
- return -1;
- }
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogIn(int /* processId */,
- const char* parameters, bool /* all */)
-{
- ndbout << "Command LOGIN not implemented." << endl;
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogOut(int /*processId*/,
- const char* parameters, bool /*all*/)
-{
- ndbout << "Command LOGOUT not implemented." << endl;
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeLogOff(int /*processId*/,
- const char* parameters, bool /*all*/)
-{
- ndbout << "Command LOGOFF not implemented." << endl;
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeTestOn(int processId,
- const char* parameters, bool /*all*/)
-{
- if (! emptyString(parameters)) {
- ndbout << "No parameters expected to this command." << endl;
- return -1;
- }
- struct ndb_mgm_reply reply;
- int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply);
- if (result != 0) {
- ndbout_c("Execute TESTON failed.");
- printError();
- return -1;
- }
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeTestOff(int processId,
- const char* parameters, bool /*all*/)
-{
- if (! emptyString(parameters)) {
- ndbout << "No parameters expected to this command." << endl;
- return -1;
- }
- struct ndb_mgm_reply reply;
- int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply);
- if (result != 0) {
- ndbout_c("Execute TESTOFF failed.");
- printError();
- return -1;
- }
- return 0;
-}
-
-
-//*****************************************************************************
-//*****************************************************************************
-int
-CommandInterpreter::executeSet(int /*processId*/,
- const char* parameters, bool /*all*/)
-{
- if (emptyString(parameters)) {
- ndbout << "Missing parameter name." << endl;
- return -1;
- }
-#if 0
- // Copy parameters since strtok will modify it
- char* newpar = my_strdup(parameters,MYF(MY_WME));
- My_auto_ptr<char> ap1(newpar);
- char* configParameterName = strtok(newpar, " ");
-
- char* allAfterParameterName = strtok(NULL, "\0");
- if (emptyString(allAfterParameterName)) {
- ndbout << "Missing parameter value." << endl;
- return;
- }
-
- char* value = strtok(allAfterParameterName, " ");
-
- char* allAfterValue = strtok(NULL, "\0");
- if (! emptyString(allAfterValue)) {
- ndbout << "Nothing expected after parameter value." << endl;
- return;
- }
-
- bool configBackupFileUpdated;
- bool configPrimaryFileUpdated;
-
- // TODO The handling of the primary and backup config files should be
- // analysed further.
- // How it should be handled if only the backup is possible to write.
-
- int result = _mgmtSrvr.updateConfigParam(processId, configParameterName,
- value, configBackupFileUpdated,
- configPrimaryFileUpdated);
- if (result == 0) {
- if (configBackupFileUpdated && configPrimaryFileUpdated) {
- ndbout << "The configuration is updated." << endl;
- }
- else if (configBackupFileUpdated && !configPrimaryFileUpdated) {
- ndbout << "The configuration is updated but it was only possible "
- << "to update the backup configuration file, not the primary."
- << endl;
- }
- else {
- assert(false);
- }
- }
- else {
- ndbout << get_error_text(result) << endl;
- if (configBackupFileUpdated && configPrimaryFileUpdated) {
- ndbout << "The configuration files are however updated and "
- << "the value will be used next time the process is restarted."
- << endl;
- }
- else if (configBackupFileUpdated && !configPrimaryFileUpdated) {
- ndbout << "It was only possible to update the backup "
- << "configuration file, not the primary." << endl;
- }
- else if (!configBackupFileUpdated && !configPrimaryFileUpdated) {
- ndbout << "The configuration files are not updated." << endl;
- }
- else {
- // The primary is not tried to write if the write of backup file fails
- abort();
- }
- }
-#endif
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-int CommandInterpreter::executeGetStat(int /*processId*/,
- const char* parameters, bool /*all*/)
-{
- if (! emptyString(parameters)) {
- ndbout << "No parameters expected to this command." << endl;
- return -1;
- }
-
-#if 0
- MgmtSrvr::Statistics statistics;
- int result = _mgmtSrvr.getStatistics(processId, statistics);
- if (result != 0) {
- ndbout << get_error_text(result) << endl;
- return;
- }
-#endif
- // Print statistic...
- /*
- ndbout << "Number of GETSTAT commands: "
- << statistics._test1 << endl;
- */
- return 0;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-
-int
-CommandInterpreter::executeEventReporting(int processId,
- const char* parameters,
- bool all)
-{
- int retval = 0;
- if (emptyString(parameters)) {
- ndbout << "Expected argument" << endl;
- return -1;
- }
- BaseString tmp(parameters);
- Vector<BaseString> specs;
- tmp.split(specs, " ");
-
- for (int i=0; i < (int) specs.size(); i++)
- {
- Vector<BaseString> spec;
- specs[i].split(spec, "=");
- if(spec.size() != 2){
- ndbout << "Invalid loglevel specification: " << specs[i] << endl;
- continue;
- }
-
- spec[0].trim().ndb_toupper();
- int category = ndb_mgm_match_event_category(spec[0].c_str());
- if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){
- if(!convert(spec[0].c_str(), category) ||
- category < NDB_MGM_MIN_EVENT_CATEGORY ||
- category > NDB_MGM_MAX_EVENT_CATEGORY){
- ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl;
- continue;
- }
- }
-
- int level;
- if (!convert(spec[1].c_str(),level))
- {
- ndbout << "Invalid level: " << spec[1].c_str() << endl;
- continue;
- }
-
- ndbout << "Executing CLUSTERLOG " << spec[0] << "=" << spec[1]
- << " on node " << processId << flush;
-
- struct ndb_mgm_reply reply;
- int result;
- result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv,
- processId,
- (ndb_mgm_event_category)category,
- level,
- &reply);
-
- if (result != 0) {
- ndbout_c(" failed.");
- printError();
- retval = -1;
- } else {
- ndbout_c(" OK!");
- }
- }
- return retval;
-}
-
-
-/*****************************************************************************
- * Backup
- *****************************************************************************/
-int
-CommandInterpreter::executeStartBackup(char* parameters, bool interactive)
-{
- struct ndb_mgm_reply reply;
- unsigned int backupId;
-
- Vector<BaseString> args;
- {
- BaseString(parameters).split(args);
- for (unsigned i= 0; i < args.size(); i++)
- if (args[i].length() == 0)
- args.erase(i--);
- else
- args[i].ndb_toupper();
- }
- int sz= args.size();
-
- int result;
- int flags = 2;
- if (sz == 2 && args[1] == "NOWAIT")
- {
- flags = 0;
- }
- else if (sz == 1 || (sz == 3 && args[1] == "WAIT" && args[2] == "COMPLETED"))
- {
- flags = 2;
- ndbout_c("Waiting for completed, this may take several minutes");
- }
- else if (sz == 3 && args[1] == "WAIT" && args[2] == "STARTED")
- {
- ndbout_c("Waiting for started, this may take several minutes");
- flags = 1;
- }
- else
- {
- invalid_command(parameters);
- return -1;
- }
-
- NdbLogEventHandle log_handle= NULL;
- struct ndb_logevent log_event;
- if (flags == 2 && !interactive)
- {
- int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0, 0 };
- log_handle = ndb_mgm_create_logevent_handle(m_mgmsrv, filter);
- if (!log_handle)
- {
- ndbout << "Initializing start of backup failed" << endl;
- printError();
- return -1;
- }
- }
- result = ndb_mgm_start_backup(m_mgmsrv, flags, &backupId, &reply);
-
- if (result != 0) {
- ndbout << "Backup failed" << endl;
- printError();
-
- if (log_handle)
- ndb_mgm_destroy_logevent_handle(&log_handle);
- return result;
- }
-
- /**
- * If interactive, event listner thread is already running
- */
- if (log_handle && !interactive)
- {
- int count = 0;
- int retry = 0;
- int res;
- do {
- if ((res= ndb_logevent_get_next(log_handle, &log_event, 60000)) > 0)
- {
- int print = 0;
- switch (log_event.type) {
- case NDB_LE_BackupStarted:
- if (log_event.BackupStarted.backup_id == backupId)
- print = 1;
- break;
- case NDB_LE_BackupCompleted:
- if (log_event.BackupCompleted.backup_id == backupId)
- print = 1;
- break;
- case NDB_LE_BackupAborted:
- if (log_event.BackupAborted.backup_id == backupId)
- print = 1;
- break;
- default:
- break;
- }
- if (print)
- {
- Guard g(m_print_mutex);
- printLogEvent(&log_event);
- count++;
- }
- }
- else
- {
- retry++;
- }
- } while(res >= 0 && count < 2 && retry < 3);
-
- if (retry >= 3)
- ndbout << "get backup event failed for " << retry << " times" << endl;
-
- ndb_mgm_destroy_logevent_handle(&log_handle);
- }
-
- return 0;
-}
-
-int
-CommandInterpreter::executeAbortBackup(char* parameters)
-{
- int bid = -1;
- struct ndb_mgm_reply reply;
- if (emptyString(parameters))
- goto executeAbortBackupError1;
-
- {
- strtok(parameters, " ");
- char* id = strtok(NULL, "\0");
- if(id == 0 || sscanf(id, "%d", &bid) != 1)
- goto executeAbortBackupError1;
- }
- {
- int result= ndb_mgm_abort_backup(m_mgmsrv, bid, &reply);
- if (result != 0) {
- ndbout << "Abort of backup " << bid << " failed" << endl;
- printError();
- return -1;
- } else {
- ndbout << "Abort of backup " << bid << " ordered" << endl;
- }
- }
- return 0;
- executeAbortBackupError1:
- ndbout << "Invalid arguments: expected <BackupId>" << endl;
- return -1;
-}
-
-template class Vector<char const*>;
diff --git a/storage/ndb/src/mgmclient/Makefile.am b/storage/ndb/src/mgmclient/Makefile.am
deleted file mode 100644
index 4d42d73bace..00000000000
--- a/storage/ndb/src/mgmclient/Makefile.am
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2004 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-noinst_LTLIBRARIES = libndbmgmclient.la
-ndbtools_PROGRAMS = ndb_mgm
-
-libndbmgmclient_la_SOURCES = CommandInterpreter.cpp
-libndbmgmclient_la_LIBADD = ../mgmapi/libmgmapi.la \
- ../common/logger/liblogger.la \
- ../common/portlib/libportlib.la \
- ../common/util/libgeneral.la \
- ../common/portlib/libportlib.la \
- ../common/debugger/libtrace.la
-
-
-ndb_mgm_SOURCES = main.cpp
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-
-INCLUDES += -I$(top_srcdir)/storage/ndb/include/mgmapi \
- -I$(top_srcdir)/storage/ndb/src/common/mgmcommon
-
-LDADD_LOC = $(noinst_LTLIBRARIES) \
- ../common/portlib/libportlib.la \
- @readline_link@ \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a \
- @TERMCAP_LIB@ @NDB_SCI_LIBS@
-
-ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
-
-windoze-dsp: ndb_mgm.dsp libndbmgmclient.dsp
-
-ndb_mgm.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-prg.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbtools_PROGRAMS)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgm_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
-
-libndbmgmclient.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbmgmclient_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB
diff --git a/storage/ndb/src/mgmclient/main.cpp b/storage/ndb/src/mgmclient/main.cpp
deleted file mode 100644
index 4622152de82..00000000000
--- a/storage/ndb/src/mgmclient/main.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_opts.h>
-
-// copied from mysql.cc to get readline
-extern "C" {
-#if defined( __WIN__)
-#include <conio.h>
-#else
-#include <readline/readline.h>
-extern "C" int add_history(const char *command); /* From readline directory */
-extern "C" int read_history(const char *command);
-extern "C" int write_history(const char *command);
-#define HAVE_READLINE
-#endif
-}
-
-#include <NdbMain.h>
-#include <NdbHost.h>
-#include <BaseString.hpp>
-#include <NdbOut.hpp>
-#include <mgmapi.h>
-#include <ndb_version.h>
-
-#include "ndb_mgmclient.hpp"
-
-const char *progname = "ndb_mgm";
-const char *load_default_groups[]= { "mysql_cluster","ndb_mgm",0 };
-
-
-static Ndb_mgmclient* com;
-
-extern "C"
-void
-handler(int sig)
-{
- DBUG_ENTER("handler");
- switch(sig){
- case SIGPIPE:
- /**
- * Will happen when connection to mgmsrv is broken
- * Reset connected flag
- */
- com->disconnect();
- break;
- }
- DBUG_VOID_RETURN;
-}
-
-NDB_STD_OPTS_VARS;
-
-static const char default_prompt[]= "ndb_mgm> ";
-static unsigned _try_reconnect;
-static const char *prompt= default_prompt;
-static char *opt_execute_str= 0;
-
-static struct my_option my_long_options[] =
-{
- NDB_STD_OPTS("ndb_mgm"),
- { "execute", 'e',
- "execute command and exit",
- &opt_execute_str, &opt_execute_str, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "try-reconnect", 't',
- "Specify number of tries for connecting to ndb_mgmd (0 = infinite)",
- &_try_reconnect, &_try_reconnect, 0,
- GET_UINT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-static void short_usage_sub(void)
-{
- printf("Usage: %s [OPTIONS] [hostname [port]]\n", my_progname);
-}
-static void usage()
-{
- short_usage_sub();
- ndb_std_print_version();
- print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
- puts("");
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
-
-static int
-read_and_execute(int _try_reconnect)
-{
- static char *line_read = (char *)NULL;
-
- /* If the buffer has already been allocated, return the memory
- to the free pool. */
- if (line_read)
- {
- free (line_read);
- line_read = (char *)NULL;
- }
-#ifdef HAVE_READLINE
- /* Get a line from the user. */
- line_read = readline (prompt);
- /* If the line has any text in it, save it on the history. */
- if (line_read && *line_read)
- add_history (line_read);
-#else
- static char linebuffer[254];
- fputs(prompt, stdout);
- linebuffer[sizeof(linebuffer)-1]=0;
- line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
- if (line_read == linebuffer) {
- char *q=linebuffer;
- while (*q > 31) q++;
- *q=0;
- line_read= strdup(linebuffer);
- }
-#endif
- return com->execute(line_read, _try_reconnect, 1);
-}
-
-int main(int argc, char** argv){
- NDB_INIT(argv[0]);
-
- load_defaults("my",load_default_groups,&argc,&argv);
- int ho_error;
-#ifndef DBUG_OFF
- opt_debug= "d:t:O,/tmp/ndb_mgm.trace";
-#endif
- if ((ho_error=handle_options(&argc, &argv, my_long_options,
- ndb_std_get_one_option)))
- exit(ho_error);
-
- char buf[MAXHOSTNAMELEN+10];
- if(argc == 1) {
- BaseString::snprintf(buf, sizeof(buf), "%s", argv[0]);
- opt_connect_str= buf;
- } else if (argc >= 2) {
- BaseString::snprintf(buf, sizeof(buf), "%s:%s", argv[0], argv[1]);
- opt_connect_str= buf;
- }
-
- if (!isatty(0) || opt_execute_str)
- {
- prompt= 0;
- }
-
- signal(SIGPIPE, handler);
- com = new Ndb_mgmclient(opt_connect_str,1);
- int ret= 0;
- BaseString histfile;
- if (!opt_execute_str)
- {
-#ifdef HAVE_READLINE
- char *histfile_env= getenv("NDB_MGM_HISTFILE");
- if (histfile_env)
- histfile.assign(histfile_env,strlen(histfile_env));
- else if(getenv("HOME"))
- {
- histfile.assign(getenv("HOME"),strlen(getenv("HOME")));
- histfile.append("/.ndb_mgm_history");
- }
- if (histfile.length())
- read_history(histfile.c_str());
-#endif
-
- ndbout << "-- NDB Cluster -- Management Client --" << endl;
- while(read_and_execute(_try_reconnect));
-
-#ifdef HAVE_READLINE
- if (histfile.length())
- {
- BaseString histfile_tmp;
- histfile_tmp.assign(histfile);
- histfile_tmp.append(".TMP");
- if(!write_history(histfile_tmp.c_str()))
- my_rename(histfile_tmp.c_str(), histfile.c_str(), MYF(MY_WME));
- }
-#endif
- }
- else
- {
- com->execute(opt_execute_str,_try_reconnect, 0, &ret);
- }
- delete com;
-
- ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
- return ret;
-}
-
diff --git a/storage/ndb/src/mgmclient/ndb_mgmclient.h b/storage/ndb/src/mgmclient/ndb_mgmclient.h
deleted file mode 100644
index f34297f3cab..00000000000
--- a/storage/ndb/src/mgmclient/ndb_mgmclient.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Ndb_mgmclient_h
-#define Ndb_mgmclient_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void* Ndb_mgmclient_handle;
-Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string);
-int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, char** argv);
-int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* Ndb_mgmclient_h */
diff --git a/storage/ndb/src/mgmclient/ndb_mgmclient.hpp b/storage/ndb/src/mgmclient/ndb_mgmclient.hpp
deleted file mode 100644
index e53443a2033..00000000000
--- a/storage/ndb/src/mgmclient/ndb_mgmclient.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Ndb_mgmclient_hpp
-#define Ndb_mgmclient_hpp
-
-class CommandInterpreter;
-class Ndb_mgmclient
-{
-public:
- Ndb_mgmclient(const char*,int verbose=0);
- ~Ndb_mgmclient();
- int execute(const char *_line, int _try_reconnect=-1, bool interactive=1, int *error= 0);
- int execute(int argc, char** argv, int _try_reconnect=-1, bool interactive=1, int *error= 0);
- int disconnect();
-private:
- CommandInterpreter *m_cmd;
-};
-
-#endif // Ndb_mgmclient_hpp
diff --git a/storage/ndb/src/mgmclient/test_cpcd/Makefile b/storage/ndb/src/mgmclient/test_cpcd/Makefile
deleted file mode 100644
index 4ced10cfc59..00000000000
--- a/storage/ndb/src/mgmclient/test_cpcd/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := test_cpcd
-BIN_TARGET_LIBS := general
-
-
-# Source files of non-templated classes (.cpp files)
-SOURCES = test_cpcd.cpp ../CpcClient.cpp
-
-CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \
- -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon)
-
-include $(NDB_TOP)/Epilogue.mk
-
-
diff --git a/storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp b/storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp
deleted file mode 100644
index 2580a5729e5..00000000000
--- a/storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include "../CpcClient.hpp"
-#include <Vector.hpp>
-
-SimpleCpcClient g_client("localhost", 1234);
-Vector<SimpleCpcClient::Process> g_procs;
-
-void define();
-void start(SimpleCpcClient::Process & p);
-void stop(SimpleCpcClient::Process & p);
-void undefine(SimpleCpcClient::Process & p);
-void list();
-SimpleCpcClient::Process* find(int id);
-
-#define ABORT() {ndbout_c("ABORT"); while(true); abort();}
-
-int name = 0;
-
-int
-main(void){
-
- g_client.connect();
-
- srand(time(0));
- for(int i = 0; i<1000; i++){
- int sz = g_procs.size();
- int test = rand() % 100;
- if(sz == 0 || test < 10){
- define();
- continue;
- }
-
- list();
-
- int proc = rand() % g_procs.size();
- SimpleCpcClient::Process & p = g_procs[proc];
- if(p.m_status == "running" && test > 50){
- ndbout_c("undefine %d: %s (running)", p.m_id, p.m_name.c_str());
- undefine(p);
- g_procs.erase(proc);
- continue;
- }
- if(p.m_status == "running" && test <= 50){
- ndbout_c("stop %d: %s(running)", p.m_id, p.m_name.c_str());
- stop(p);
- continue;
- }
- if(p.m_status == "stopped" && test > 50){
- ndbout_c("undefine %d: %s(stopped)", p.m_id, p.m_name.c_str());
- undefine(p);
- g_procs.erase(proc);
- continue;
- }
- if(p.m_status == "stopped" && test <= 50){
- ndbout_c("start %d %s(stopped)", p.m_id, p.m_name.c_str());
- start(p);
- continue;
- }
- ndbout_c("Unknown: %s", p.m_status.c_str());
- }
-}
-
-void define(){
- SimpleCpcClient::Process m_proc;
- m_proc.m_id = -1;
- m_proc.m_type = "temporary";
- m_proc.m_owner = "atrt";
- m_proc.m_group = "group";
- //m_proc.m_cwd
- //m_proc.m_env
- //proc.m_proc.m_stdout = "log.out";
- //proc.m_proc.m_stderr = "2>&1";
- //proc.m_proc.m_runas = proc.m_host->m_user;
- m_proc.m_ulimit = "c:unlimited";
- if((rand() & 15) >= 0){
- m_proc.m_name.assfmt("%d-%d-%s", getpid(), name++, "sleep");
- m_proc.m_path.assign("/bin/sleep");
- m_proc.m_args = "600";
- } else {
- m_proc.m_name.assfmt("%d-%d-%s", getpid(), name++, "test.sh");
- m_proc.m_path.assign("/home/jonas/run/cpcd/test.sh");
- m_proc.m_args = "600";
- }
- g_procs.push_back(m_proc);
-
- Properties reply;
- if(g_client.define_process(g_procs.back(), reply) != 0){
- ndbout_c("define %s -> ERR", m_proc.m_name.c_str());
- reply.print();
- ABORT();
- }
- ndbout_c("define %s -> %d", m_proc.m_name.c_str(), m_proc.m_id);
-}
-
-void start(SimpleCpcClient::Process & p){
- Properties reply;
- if(g_client.start_process(p.m_id, reply) != 0){
- reply.print();
- ABORT();
- }
-}
-
-void stop(SimpleCpcClient::Process & p){
- Properties reply;
- if(g_client.stop_process(p.m_id, reply) != 0){
- reply.print();
- ABORT();
- }
-}
-
-void undefine(SimpleCpcClient::Process & p){
- Properties reply;
- if(g_client.undefine_process(p.m_id, reply) != 0){
- reply.print();
- ABORT();
- }
-}
-
-void list(){
- Properties reply;
- Vector<SimpleCpcClient::Process> procs;
- if(g_client.list_processes(procs, reply) != 0){
- reply.print();
- ABORT();
- }
-
- for(Uint32 i = 0; i<procs.size(); i++){
- SimpleCpcClient::Process * p = find(procs[i].m_id);
- if(p != 0){
- p->m_status = procs[i].m_status;
- }
- }
-}
-SimpleCpcClient::Process* find(int id){
- for(Uint32 i = 0; i<g_procs.size(); i++){
- if(g_procs[i].m_id == id)
- return &g_procs[i];
- }
- return 0;
-}
diff --git a/storage/ndb/src/mgmsrv/Config.cpp b/storage/ndb/src/mgmsrv/Config.cpp
deleted file mode 100644
index f7461375d0f..00000000000
--- a/storage/ndb/src/mgmsrv/Config.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "Config.hpp"
-#include <ctype.h>
-#include <string.h>
-#include "MgmtErrorReporter.hpp"
-#include <Properties.hpp>
-
-//*****************************************************************************
-// Ctor / Dtor
-//*****************************************************************************
-
-Config::Config() {
- m_oldConfig = 0;
- m_configValues = 0;
-}
-
-Config::~Config() {
- if(m_configValues != 0){
- free(m_configValues);
- }
-
- if(m_oldConfig != 0)
- delete m_oldConfig;
-}
-
-/*****************************************************************************/
-
-void
-Config::printAllNameValuePairs(NdbOut &out,
- const Properties *prop,
- const char* s) const {
- Properties::Iterator it(prop);
- 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(!section->contains(n))
- continue;
- if (m_info.getStatus(section, n) == ConfigInfo::CI_INTERNAL)
- continue;
- if (m_info.getStatus(section, n) == ConfigInfo::CI_DEPRICATED)
- continue;
- if (m_info.getStatus(section, n) == ConfigInfo::CI_NOTIMPLEMENTED)
- continue;
-
- out << n << ": ";
-
- switch (m_info.getType(section, n)) {
- case ConfigInfo::CI_INT:
- MGM_REQUIRE(prop->get(n, &int_value));
- out << int_value;
- break;
-
- case ConfigInfo::CI_INT64:
- MGM_REQUIRE(prop->get(n, &int_64));
- out << int_64;
- break;
-
- case ConfigInfo::CI_BOOL:
- MGM_REQUIRE(prop->get(n, &int_value));
- if (int_value) {
- out << "Y";
- } else {
- out << "N";
- }
- break;
- case ConfigInfo::CI_STRING:
- MGM_REQUIRE(prop->get(n, &str_value));
- out << str_value;
- break;
- case ConfigInfo::CI_SECTION:
- out << "SECTION";
- break;
- }
- out << endl;
- }
-}
-
-/*****************************************************************************/
-
-void Config::printConfigFile(NdbOut &out) const {
-#if 0
- Uint32 noOfNodes, noOfConnections, noOfComputers;
- MGM_REQUIRE(get("NoOfNodes", &noOfNodes));
- MGM_REQUIRE(get("NoOfConnections", &noOfConnections));
- MGM_REQUIRE(get("NoOfComputers", &noOfComputers));
-
- out <<
- "######################################################################" <<
- endl <<
- "#" << endl <<
- "# NDB Cluster System configuration" << endl <<
- "#" << endl <<
- "######################################################################" <<
- endl <<
- "# No of nodes (DB, API or MGM): " << noOfNodes << endl <<
- "# No of connections: " << noOfConnections << endl <<
- "######################################################################" <<
- endl;
-
- /**************************
- * Print COMPUTER configs *
- **************************/
- const char * name;
- Properties::Iterator it(this);
- for(name = it.first(); name != NULL; name = it.next()){
- if(strncasecmp("Computer_", name, 9) == 0){
-
- const Properties *prop;
- out << endl << "[COMPUTER]" << endl;
- MGM_REQUIRE(get(name, &prop));
- printAllNameValuePairs(out, prop, "COMPUTER");
-
- out << endl <<
- "###################################################################" <<
- endl;
-
- } else if(strncasecmp("Node_", name, 5) == 0){
- /**********************
- * Print NODE configs *
- **********************/
- const Properties *prop;
- const char *s;
-
- MGM_REQUIRE(get(name, &prop));
- MGM_REQUIRE(prop->get("Type", &s));
- out << endl << "[" << s << "]" << endl;
- printAllNameValuePairs(out, prop, s);
-
- out << endl <<
- "###################################################################" <<
- endl;
- } else if(strncasecmp("Connection_", name, 11) == 0){
- /****************************
- * Print CONNECTION configs *
- ****************************/
- const Properties *prop;
- const char *s;
-
- MGM_REQUIRE(get(name, &prop));
- MGM_REQUIRE(prop->get("Type", &s));
- out << endl << "[" << s << "]" << endl;
- printAllNameValuePairs(out, prop, s);
-
- out << endl <<
- "###################################################################" <<
- endl;
- } else if(strncasecmp("SYSTEM", name, strlen("SYSTEM")) == 0) {
- /************************
- * Print SYSTEM configs *
- ************************/
- const Properties *prop;
-
- MGM_REQUIRE(get(name, &prop));
- out << endl << "[SYSTEM]" << endl;
- printAllNameValuePairs(out, prop, "SYSTEM");
-
- out << endl <<
- "###################################################################" <<
- endl;
- }
- }
-#endif
-}
diff --git a/storage/ndb/src/mgmsrv/Config.hpp b/storage/ndb/src/mgmsrv/Config.hpp
deleted file mode 100644
index 31ebd7f219f..00000000000
--- a/storage/ndb/src/mgmsrv/Config.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef Config_H
-#define Config_H
-
-#include <LogLevel.hpp>
-
-#include <kernel_types.h>
-
-#include <NdbOut.hpp>
-#include <ndb_limits.h>
-#include <Properties.hpp>
-#include <ConfigInfo.hpp>
-
-class ConfigInfo;
-
-/**
- * @class Config
- * @brief Cluster Configuration (corresponds to initial configuration file)
- *
- * Contains all cluster configuration parameters.
- *
- * The information includes all configurable parameters for a NDB cluster:
- * - DB, API and MGM nodes with all their properties,
- * - Connections between nodes and computers the nodes will execute on.
- *
- * The following categories (sections) of configuration parameters exists:
- * - COMPUTER, DB, MGM, API, TCP, SCI, SHM
- *
- */
-
-class Config {
-public:
- /**
- * Constructor which loads the object with an Properties object
- */
- Config();
- virtual ~Config();
-
- /**
- * Prints the configuration in configfile format
- */
- void printConfigFile(NdbOut &out = ndbout) const;
- void printConfigFile(OutputStream &out) const {
- NdbOut ndb(out);
- printConfigFile(ndb);
- }
-
- /**
- * Info
- */
- const ConfigInfo * getConfigInfo() const { return &m_info;}
-private:
- ConfigInfo m_info;
-
- void printAllNameValuePairs(NdbOut &out,
- const Properties *prop,
- const char* section) const;
-
- /**
- * Information about parameters (min, max values etc)
- */
-public:
- Properties * m_oldConfig;
- struct ndb_mgm_configuration * m_configValues;
-};
-
-#endif // Config_H
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
deleted file mode 100644
index 10dd8bd34c6..00000000000
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp
+++ /dev/null
@@ -1,3827 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#ifndef NDB_MGMAPI
-#include <ndb_opt_defaults.h>
-
-#include <NdbTCP.h>
-#include "ConfigInfo.hpp"
-#include <mgmapi_config_parameters.h>
-#include <ndb_limits.h>
-#include "InitConfigFileParser.hpp"
-#include <m_string.h>
-
-extern my_bool opt_ndb_shm;
-extern my_bool opt_core;
-
-#else
-#include "ConfigInfo.hpp"
-#include <mgmapi_config_parameters.h>
-#endif /* NDB_MGMAPI */
-
-#define MAX_LINE_LENGTH 255
-#define KEY_INTERNAL 0
-#define MAX_INT_RNIL 0xfffffeff
-#define MAX_PORT_NO 65535
-
-#define _STR_VALUE(x) #x
-#define STR_VALUE(x) _STR_VALUE(x)
-
-/****************************************************************************
- * Section names
- ****************************************************************************/
-
-#define DB_TOKEN_PRINT "ndbd(DB)"
-#define MGM_TOKEN_PRINT "ndb_mgmd(MGM)"
-#define API_TOKEN_PRINT "mysqld(API)"
-
-#define DB_TOKEN "DB"
-#define MGM_TOKEN "MGM"
-#define API_TOKEN "API"
-
-#ifndef NDB_MGMAPI
-const ConfigInfo::AliasPair
-ConfigInfo::m_sectionNameAliases[]={
- {API_TOKEN, "MYSQLD"},
- {DB_TOKEN, "NDBD"},
- {MGM_TOKEN, "NDB_MGMD"},
- {0, 0}
-};
-
-const char*
-ConfigInfo::m_sectionNames[]={
- "SYSTEM",
- "COMPUTER",
-
- DB_TOKEN,
- MGM_TOKEN,
- API_TOKEN,
-
- "TCP",
- "SCI",
- "SHM"
-};
-const int ConfigInfo::m_noOfSectionNames =
-sizeof(m_sectionNames)/sizeof(char*);
-
-
-/****************************************************************************
- * Section Rules declarations
- ****************************************************************************/
-static bool transformComputer(InitConfigFileParser::Context & ctx, const char *);
-static bool transformSystem(InitConfigFileParser::Context & ctx, const char *);
-static bool transformNode(InitConfigFileParser::Context & ctx, const char *);
-static bool checkConnectionSupport(InitConfigFileParser::Context & ctx, const char *);
-static bool transformConnection(InitConfigFileParser::Context & ctx, const char *);
-static bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *);
-static bool checkMandatory(InitConfigFileParser::Context & ctx, const char *);
-static bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *);
-static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *);
-static bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *);
-static bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *);
-static bool checkTCPConstraints(InitConfigFileParser::Context &, const char *);
-static bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data);
-static bool fixHostname(InitConfigFileParser::Context & ctx, const char * data);
-static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data);
-static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *);
-static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *);
-static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data);
-static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data);
-static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data);
-static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data);
-
-const ConfigInfo::SectionRule
-ConfigInfo::m_SectionRules[] = {
- { "SYSTEM", transformSystem, 0 },
- { "COMPUTER", transformComputer, 0 },
-
- { DB_TOKEN, transformNode, 0 },
- { API_TOKEN, transformNode, 0 },
- { MGM_TOKEN, transformNode, 0 },
-
- { MGM_TOKEN, fixShmUniqueId, 0 },
-
- { "TCP", checkConnectionSupport, 0 },
- { "SHM", checkConnectionSupport, 0 },
- { "SCI", checkConnectionSupport, 0 },
-
- { "TCP", transformConnection, 0 },
- { "SHM", transformConnection, 0 },
- { "SCI", transformConnection, 0 },
-
- { DB_TOKEN, fixNodeHostname, 0 },
- { API_TOKEN, fixNodeHostname, 0 },
- { MGM_TOKEN, fixNodeHostname, 0 },
-
- { "TCP", fixNodeId, "NodeId1" },
- { "TCP", fixNodeId, "NodeId2" },
- { "SHM", fixNodeId, "NodeId1" },
- { "SHM", fixNodeId, "NodeId2" },
- { "SCI", fixNodeId, "NodeId1" },
- { "SCI", fixNodeId, "NodeId2" },
-
- { "TCP", fixHostname, "HostName1" },
- { "TCP", fixHostname, "HostName2" },
- { "SHM", fixHostname, "HostName1" },
- { "SHM", fixHostname, "HostName2" },
- { "SCI", fixHostname, "HostName1" },
- { "SCI", fixHostname, "HostName2" },
- { "SHM", fixHostname, "HostName1" },
- { "SHM", fixHostname, "HostName2" },
-
- { "TCP", fixPortNumber, 0 }, // has to come after fixHostName
- { "SHM", fixPortNumber, 0 }, // has to come after fixHostName
- { "SCI", fixPortNumber, 0 }, // has to come after fixHostName
-
- { "*", applyDefaultValues, "user" },
- { "*", fixDepricated, 0 },
- { "*", applyDefaultValues, "system" },
-
- { "SHM", fixShmKey, 0 }, // has to come after apply default values
-
- { DB_TOKEN, checkLocalhostHostnameMix, 0 },
- { API_TOKEN, checkLocalhostHostnameMix, 0 },
- { MGM_TOKEN, checkLocalhostHostnameMix, 0 },
-
- { DB_TOKEN, fixFileSystemPath, 0 },
- { DB_TOKEN, fixBackupDataDir, 0 },
-
- { DB_TOKEN, checkDbConstraints, 0 },
-
- { "TCP", checkConnectionConstraints, 0 },
- { "SHM", checkConnectionConstraints, 0 },
- { "SCI", checkConnectionConstraints, 0 },
-
- { "TCP", checkTCPConstraints, "HostName1" },
- { "TCP", checkTCPConstraints, "HostName2" },
- { "SCI", checkTCPConstraints, "HostName1" },
- { "SCI", checkTCPConstraints, "HostName2" },
- { "SHM", checkTCPConstraints, "HostName1" },
- { "SHM", checkTCPConstraints, "HostName2" },
-
- { "*", checkMandatory, 0 },
-
- { DB_TOKEN, saveInConfigValues, 0 },
- { API_TOKEN, saveInConfigValues, 0 },
- { MGM_TOKEN, saveInConfigValues, 0 },
-
- { "TCP", saveInConfigValues, 0 },
- { "SHM", saveInConfigValues, 0 },
- { "SCI", saveInConfigValues, 0 }
-};
-const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
-
-/****************************************************************************
- * Config Rules declarations
- ****************************************************************************/
-static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data);
-static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data);
-static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data);
-static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data);
-
-const ConfigInfo::ConfigRule
-ConfigInfo::m_ConfigRules[] = {
- { sanity_checks, 0 },
- { add_node_connections, 0 },
- { set_connection_priorities, 0 },
- { check_node_vs_replicas, 0 },
- { 0, 0 }
-};
-
-struct DepricationTransform {
- const char * m_section;
- const char * m_oldName;
- const char * m_newName;
- double m_add;
- double m_mul;
-};
-
-static
-const DepricationTransform f_deprication[] = {
- { DB_TOKEN, "Discless", "Diskless", 0, 1 },
- { DB_TOKEN, "Id", "NodeId", 0, 1 },
- { API_TOKEN, "Id", "NodeId", 0, 1 },
- { MGM_TOKEN, "Id", "NodeId", 0, 1 },
- { 0, 0, 0, 0, 0}
-};
-#endif /* NDB_MGMAPI */
-
-/**
- * The default constructors create objects with suitable values for the
- * configuration parameters.
- *
- * Some are however given the value MANDATORY which means that the value
- * must be specified in the configuration file.
- *
- * Min and max values are also given for some parameters.
- * - Attr1: Name in file (initial config file)
- * - Attr2: Name in prop (properties object)
- * - Attr3: Name of Section (in init config file)
- * - Attr4: Updateable
- * - Attr5: Type of parameter (INT or BOOL)
- * - Attr6: Default Value (number only)
- * - Attr7: Min value
- * - Attr8: Max value
- *
- * Parameter constraints are coded in file Config.cpp.
- *
- * *******************************************************************
- * Parameters used under development should be marked "NOTIMPLEMENTED"
- * *******************************************************************
- */
-
-const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
-
- /****************************************************************************
- * COMPUTER
- ***************************************************************************/
- {
- KEY_INTERNAL,
- "COMPUTER",
- "COMPUTER",
- "Computer section",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_SECTION,
- 0,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "Id",
- "COMPUTER",
- "Name of computer",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "HostName",
- "COMPUTER",
- "Hostname of computer (e.g. mysql.com)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "ByteOrder",
- "COMPUTER",
- 0,
- ConfigInfo::CI_DEPRICATED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0,
- 0 },
-
- /****************************************************************************
- * SYSTEM
- ***************************************************************************/
- {
- CFG_SECTION_SYSTEM,
- "SYSTEM",
- "SYSTEM",
- "System section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)CFG_SECTION_SYSTEM,
- 0, 0 },
-
- {
- CFG_SYS_NAME,
- "Name",
- "SYSTEM",
- "Name of system (NDB Cluster)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- CFG_SYS_PRIMARY_MGM_NODE,
- "PrimaryMGMNode",
- "SYSTEM",
- "Node id of Primary "MGM_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_SYS_CONFIG_GENERATION,
- "ConfigGenerationNumber",
- "SYSTEM",
- "Configuration generation number",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- /***************************************************************************
- * DB
- ***************************************************************************/
- {
- CFG_SECTION_NODE,
- DB_TOKEN,
- DB_TOKEN,
- "Node section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)NODE_TYPE_DB,
- 0, 0
- },
-
- {
- CFG_NODE_HOST,
- "HostName",
- DB_TOKEN,
- "Name of computer for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- "localhost",
- 0, 0 },
-
- {
- CFG_NODE_SYSTEM,
- "System",
- DB_TOKEN,
- "Name of system for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "Id",
- DB_TOKEN,
- "",
- ConfigInfo::CI_DEPRICATED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_DATA_NODE_ID) },
-
- {
- CFG_NODE_ID,
- "NodeId",
- DB_TOKEN,
- "Number identifying the database node ("DB_TOKEN_PRINT")",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_DATA_NODE_ID) },
-
- {
- KEY_INTERNAL,
- "ServerPort",
- DB_TOKEN,
- "Port used to setup transporter",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "1",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- CFG_DB_NO_REPLICAS,
- "NoOfReplicas",
- DB_TOKEN,
- "Number of copies of all data in the database (1-4)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- "4" },
-
- {
- CFG_DB_NO_ATTRIBUTES,
- "MaxNoOfAttributes",
- DB_TOKEN,
- "Total number of attributes stored in database. I.e. sum over all tables",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1000",
- "32",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_TABLES,
- "MaxNoOfTables",
- DB_TOKEN,
- "Total number of tables stored in the database",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "128",
- "8",
- STR_VALUE(MAX_TABLES) },
-
- {
- CFG_DB_NO_ORDERED_INDEXES,
- "MaxNoOfOrderedIndexes",
- DB_TOKEN,
- "Total number of ordered indexes that can be defined in the system",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "128",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_UNIQUE_HASH_INDEXES,
- "MaxNoOfUniqueHashIndexes",
- DB_TOKEN,
- "Total number of unique hash indexes that can be defined in the system",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "64",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_INDEXES,
- "MaxNoOfIndexes",
- DB_TOKEN,
- "Total number of indexes that can be defined in the system",
- ConfigInfo::CI_DEPRICATED,
- false,
- ConfigInfo::CI_INT,
- "128",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_INDEX_OPS,
- "MaxNoOfConcurrentIndexOperations",
- DB_TOKEN,
- "Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "8K",
- "0",
- STR_VALUE(MAX_INT_RNIL)
- },
-
- {
- CFG_DB_NO_TRIGGERS,
- "MaxNoOfTriggers",
- DB_TOKEN,
- "Total number of triggers that can be defined in the system",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "768",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_TRIGGER_OPS,
- "MaxNoOfFiredTriggers",
- DB_TOKEN,
- "Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "4000",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- KEY_INTERNAL,
- "ExecuteOnComputer",
- DB_TOKEN,
- "String referencing an earlier defined COMPUTER",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_DB_NO_SAVE_MSGS,
- "MaxNoOfSavedMessages",
- DB_TOKEN,
- "Max number of error messages in error log and max number of trace files",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "25",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_MEMLOCK,
- "LockPagesInMainMemory",
- DB_TOKEN,
- "If set to yes, then NDB Cluster data will not be swapped out to disk",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "2" },
-
- {
- CFG_DB_WATCHDOG_INTERVAL,
- "TimeBetweenWatchDogCheck",
- DB_TOKEN,
- "Time between execution checks inside a database node",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "6000",
- "70",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_WATCHDOG_INTERVAL_INITIAL,
- "TimeBetweenWatchDogCheckInitial",
- DB_TOKEN,
- "Time between execution checks inside a database node in the early start phases when memory is allocated",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "6000",
- "70",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_STOP_ON_ERROR,
- "StopOnError",
- DB_TOKEN,
- "If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_BOOL,
- "true",
- "false",
- "true" },
-
- {
- CFG_DB_STOP_ON_ERROR_INSERT,
- "RestartOnErrorInsert",
- DB_TOKEN,
- "See src/kernel/vm/Emulator.hpp NdbRestartType for details",
- ConfigInfo::CI_INTERNAL,
- true,
- ConfigInfo::CI_INT,
- "2",
- "0",
- "4" },
-
- {
- CFG_DB_NO_OPS,
- "MaxNoOfConcurrentOperations",
- DB_TOKEN,
- "Max number of operation records in transaction coordinator",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "32k",
- "32",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_LOCAL_OPS,
- "MaxNoOfLocalOperations",
- DB_TOKEN,
- "Max number of operation records defined in the local storage node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "32",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_LOCAL_SCANS,
- "MaxNoOfLocalScans",
- DB_TOKEN,
- "Max number of fragment scans in parallel in the local storage node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "32",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BATCH_SIZE,
- "BatchSizePerLocalScan",
- DB_TOKEN,
- "Used to calculate the number of lock records for scan with hold lock",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- STR_VALUE(DEF_BATCH_SIZE),
- "1",
- STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
-
- {
- CFG_DB_NO_TRANSACTIONS,
- "MaxNoOfConcurrentTransactions",
- DB_TOKEN,
- "Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "4096",
- "32",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_NO_SCANS,
- "MaxNoOfConcurrentScans",
- DB_TOKEN,
- "Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "256",
- "2",
- "500" },
-
- {
- CFG_DB_TRANS_BUFFER_MEM,
- "TransactionBufferMemory",
- DB_TOKEN,
- "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1M",
- "1K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_INDEX_MEM,
- "IndexMemory",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT64,
- "18M",
- "1M",
- "1024G" },
-
- {
- CFG_DB_DATA_MEM,
- "DataMemory",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT64,
- "80M",
- "1M",
- "1024G" },
-
- {
- CFG_DB_UNDO_INDEX_BUFFER,
- "UndoIndexBuffer",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "2M",
- "1M",
- STR_VALUE(MAX_INT_RNIL)},
-
- {
- CFG_DB_UNDO_DATA_BUFFER,
- "UndoDataBuffer",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "16M",
- "1M",
- STR_VALUE(MAX_INT_RNIL)},
-
- {
- CFG_DB_REDO_BUFFER,
- "RedoBuffer",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "8M",
- "1M",
- STR_VALUE(MAX_INT_RNIL)},
-
- {
- CFG_DB_LONG_SIGNAL_BUFFER,
- "LongMessageBuffer",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1M",
- "512k",
- STR_VALUE(MAX_INT_RNIL)},
-
- {
- CFG_DB_DISK_PAGE_BUFFER_MEMORY,
- "DiskPageBufferMemory",
- DB_TOKEN,
- "Number bytes on each "DB_TOKEN_PRINT" node allocated for disk page buffer cache",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT64,
- "64M",
- "4M",
- "1024G" },
-
- {
- CFG_DB_SGA,
- "SharedGlobalMemory",
- DB_TOKEN,
- "Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT64,
- "20M",
- "0",
- "65536G" }, // 32k pages * 32-bit i value
-
- {
- CFG_DB_START_PARTIAL_TIMEOUT,
- "StartPartialTimeout",
- DB_TOKEN,
- "Time to wait before trying to start wo/ all nodes. 0=Wait forever",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "30000",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_START_PARTITION_TIMEOUT,
- "StartPartitionedTimeout",
- DB_TOKEN,
- "Time to wait before trying to start partitioned. 0=Wait forever",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "60000",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_START_FAILURE_TIMEOUT,
- "StartFailureTimeout",
- DB_TOKEN,
- "Time to wait before terminating. 0=Wait forever",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_HEARTBEAT_INTERVAL,
- "HeartbeatIntervalDbDb",
- DB_TOKEN,
- "Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "1500",
- "10",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_API_HEARTBEAT_INTERVAL,
- "HeartbeatIntervalDbApi",
- DB_TOKEN,
- "Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "1500",
- "100",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_LCP_INTERVAL,
- "TimeBetweenLocalCheckpoints",
- DB_TOKEN,
- "Time between taking snapshots of the database (expressed in 2log of bytes)",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "20",
- "0",
- "31" },
-
- {
- CFG_DB_GCP_INTERVAL,
- "TimeBetweenGlobalCheckpoints",
- DB_TOKEN,
- "Time between doing group commit of transactions to disk",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "2000",
- "10",
- "32000" },
-
- {
- CFG_DB_NO_REDOLOG_FILES,
- "NoOfFragmentLogFiles",
- DB_TOKEN,
- "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "16",
- "3",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_REDOLOG_FILE_SIZE,
- "FragmentLogFileSize",
- DB_TOKEN,
- "Size of each Redo log file",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "16M",
- "4M",
- "1G" },
-
- {
- CFG_DB_MAX_OPEN_FILES,
- "MaxNoOfOpenFiles",
- DB_TOKEN,
- "Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "20",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_INITIAL_OPEN_FILES,
- "InitialNoOfOpenFiles",
- DB_TOKEN,
- "Initial number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "27",
- "20",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_TRANSACTION_CHECK_INTERVAL,
- "TimeBetweenInactiveTransactionAbortCheck",
- DB_TOKEN,
- "Time between inactive transaction checks",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "1000",
- "1000",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_TRANSACTION_INACTIVE_TIMEOUT,
- "TransactionInactiveTimeout",
- DB_TOKEN,
- "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::CI_USED,
- true,
- ConfigInfo::CI_INT,
- STR_VALUE(MAX_INT_RNIL),
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
- "TransactionDeadlockDetectionTimeout",
- DB_TOKEN,
- "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::CI_USED,
- true,
- ConfigInfo::CI_INT,
- "1200",
- "50",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_LCP_DISC_PAGES_TUP_SR,
- "NoOfDiskPagesToDiskDuringRestartTUP",
- DB_TOKEN,
- "DiskCheckpointSpeedSr",
- ConfigInfo::CI_DEPRICATED,
- true,
- ConfigInfo::CI_INT,
- "40",
- "1",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_LCP_DISC_PAGES_TUP,
- "NoOfDiskPagesToDiskAfterRestartTUP",
- DB_TOKEN,
- "DiskCheckpointSpeed",
- ConfigInfo::CI_DEPRICATED,
- true,
- ConfigInfo::CI_INT,
- "40",
- "1",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_LCP_DISC_PAGES_ACC_SR,
- "NoOfDiskPagesToDiskDuringRestartACC",
- DB_TOKEN,
- "DiskCheckpointSpeedSr",
- ConfigInfo::CI_DEPRICATED,
- true,
- ConfigInfo::CI_INT,
- "20",
- "1",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_LCP_DISC_PAGES_ACC,
- "NoOfDiskPagesToDiskAfterRestartACC",
- DB_TOKEN,
- "DiskCheckpointSpeed",
- ConfigInfo::CI_DEPRICATED,
- true,
- ConfigInfo::CI_INT,
- "20",
- "1",
- STR_VALUE(MAX_INT_RNIL) },
-
-
- {
- CFG_DB_DISCLESS,
- "Diskless",
- DB_TOKEN,
- "Run wo/ disk",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true"},
-
- {
- KEY_INTERNAL,
- "Discless",
- DB_TOKEN,
- "Diskless",
- ConfigInfo::CI_DEPRICATED,
- true,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true"},
-
-
-
- {
- CFG_DB_ARBIT_TIMEOUT,
- "ArbitrationTimeout",
- DB_TOKEN,
- "Max time (milliseconds) database partion waits for arbitration signal",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "3000",
- "10",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_NODE_DATADIR,
- "DataDir",
- DB_TOKEN,
- "Data directory for this node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MYSQLCLUSTERDIR,
- 0, 0 },
-
- {
- CFG_DB_FILESYSTEM_PATH,
- "FileSystemPath",
- DB_TOKEN,
- "Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_LOGLEVEL_STARTUP,
- "LogLevelStartup",
- DB_TOKEN,
- "Node startup info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_SHUTDOWN,
- "LogLevelShutdown",
- DB_TOKEN,
- "Node shutdown info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_STATISTICS,
- "LogLevelStatistic",
- DB_TOKEN,
- "Transaction, operation, transporter info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_CHECKPOINT,
- "LogLevelCheckpoint",
- DB_TOKEN,
- "Local and Global checkpoint info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_NODERESTART,
- "LogLevelNodeRestart",
- DB_TOKEN,
- "Node restart, node failure info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_CONNECTION,
- "LogLevelConnection",
- DB_TOKEN,
- "Node connect/disconnect info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_CONGESTION,
- "LogLevelCongestion",
- DB_TOKEN,
- "Congestion info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_ERROR,
- "LogLevelError",
- DB_TOKEN,
- "Transporter, heartbeat errors printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- {
- CFG_LOGLEVEL_INFO,
- "LogLevelInfo",
- DB_TOKEN,
- "Heartbeat and log info printed on stdout",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "15" },
-
- /**
- * Backup
- */
- {
- CFG_DB_PARALLEL_BACKUPS,
- "ParallelBackups",
- DB_TOKEN,
- "Maximum number of parallel backups",
- ConfigInfo::CI_NOTIMPLEMENTED,
- false,
- ConfigInfo::CI_INT,
- "1",
- "1",
- "1" },
-
- {
- CFG_DB_BACKUP_DATADIR,
- "BackupDataDir",
- DB_TOKEN,
- "Path to where to store backups",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_DB_DISK_SYNCH_SIZE,
- "DiskSyncSize",
- DB_TOKEN,
- "Data written to a file before a synch is forced",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "4M",
- "32k",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_CHECKPOINT_SPEED,
- "DiskCheckpointSpeed",
- DB_TOKEN,
- "Bytes per second allowed to be written by checkpoint",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "10M",
- "1M",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_CHECKPOINT_SPEED_SR,
- "DiskCheckpointSpeedInRestart",
- DB_TOKEN,
- "Bytes per second allowed to be written by checkpoint during restart",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "100M",
- "1M",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BACKUP_MEM,
- "BackupMemory",
- DB_TOKEN,
- "Total memory allocated for backups per node (in bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "4M", // sum of BackupDataBufferSize and BackupLogBufferSize
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BACKUP_DATA_BUFFER_MEM,
- "BackupDataBufferSize",
- DB_TOKEN,
- "Default size of databuffer for a backup (in bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "2M", // remember to change BackupMemory
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BACKUP_LOG_BUFFER_MEM,
- "BackupLogBufferSize",
- DB_TOKEN,
- "Default size of logbuffer for a backup (in bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "2M", // remember to change BackupMemory
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BACKUP_WRITE_SIZE,
- "BackupWriteSize",
- DB_TOKEN,
- "Default size of filesystem writes made by backup (in bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "32K",
- "2K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_BACKUP_MAX_WRITE_SIZE,
- "BackupMaxWriteSize",
- DB_TOKEN,
- "Max size of filesystem writes made by backup (in bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "256K",
- "2K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_STRING_MEMORY,
- "StringMemory",
- DB_TOKEN,
- "Default size of string memory (0 -> 5% of max 1-100 -> %of max, >100 -> actual bytes)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_MAX_ALLOCATE,
- "MaxAllocate",
- DB_TOKEN,
- "Maximum size of allocation to use when allocating memory for tables",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "32M",
- "1M",
- "1G" },
-
- {
- CFG_DB_MEMREPORT_FREQUENCY,
- "MemReportFrequency",
- DB_TOKEN,
- "Frequency of mem reports in seconds, 0 = only when passing %-limits",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_DB_O_DIRECT,
- "ODirect",
- DB_TOKEN,
- "Use O_DIRECT file write/read when possible",
- ConfigInfo::CI_USED,
- true,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true"},
-
- /***************************************************************************
- * API
- ***************************************************************************/
- {
- CFG_SECTION_NODE,
- API_TOKEN,
- API_TOKEN,
- "Node section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)NODE_TYPE_API,
- 0, 0
- },
-
- {
- CFG_NODE_HOST,
- "HostName",
- API_TOKEN,
- "Name of computer for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- "",
- 0, 0 },
-
- {
- CFG_NODE_SYSTEM,
- "System",
- API_TOKEN,
- "Name of system for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "Id",
- API_TOKEN,
- "",
- ConfigInfo::CI_DEPRICATED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_NODES_ID) },
-
- {
- CFG_NODE_ID,
- "NodeId",
- API_TOKEN,
- "Number identifying application node ("API_TOKEN_PRINT")",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_NODES_ID) },
-
- {
- KEY_INTERNAL,
- "ExecuteOnComputer",
- API_TOKEN,
- "String referencing an earlier defined COMPUTER",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_NODE_ARBIT_RANK,
- "ArbitrationRank",
- API_TOKEN,
- "If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- "2" },
-
- {
- CFG_NODE_ARBIT_DELAY,
- "ArbitrationDelay",
- API_TOKEN,
- "When asked to arbitrate, arbitrator waits this long before voting (msec)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_MAX_SCAN_BATCH_SIZE,
- "MaxScanBatchSize",
- "API",
- "The maximum collective batch size for one scan",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- STR_VALUE(MAX_SCAN_BATCH_SIZE),
- "32k",
- "16M" },
-
- {
- CFG_BATCH_BYTE_SIZE,
- "BatchByteSize",
- "API",
- "The default batch size in bytes",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- STR_VALUE(SCAN_BATCH_SIZE),
- "1k",
- "1M" },
-
- {
- CFG_BATCH_SIZE,
- "BatchSize",
- "API",
- "The default batch size in number of records",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- STR_VALUE(DEF_BATCH_SIZE),
- "1",
- STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
-
- /****************************************************************************
- * MGM
- ***************************************************************************/
- {
- CFG_SECTION_NODE,
- MGM_TOKEN,
- MGM_TOKEN,
- "Node section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)NODE_TYPE_MGM,
- 0, 0
- },
-
- {
- CFG_NODE_HOST,
- "HostName",
- MGM_TOKEN,
- "Name of computer for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- "",
- 0, 0 },
-
- {
- CFG_NODE_DATADIR,
- "DataDir",
- MGM_TOKEN,
- "Data directory for this node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MYSQLCLUSTERDIR,
- 0, 0 },
-
- {
- CFG_NODE_SYSTEM,
- "System",
- MGM_TOKEN,
- "Name of system for this node",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "Id",
- MGM_TOKEN,
- "",
- ConfigInfo::CI_DEPRICATED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_NODES_ID) },
-
- {
- CFG_NODE_ID,
- "NodeId",
- MGM_TOKEN,
- "Number identifying the management server node ("MGM_TOKEN_PRINT")",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1",
- STR_VALUE(MAX_NODES_ID) },
-
- {
- CFG_LOG_DESTINATION,
- "LogDestination",
- MGM_TOKEN,
- "String describing where logmessages are sent",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- 0,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "ExecuteOnComputer",
- MGM_TOKEN,
- "String referencing an earlier defined COMPUTER",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- 0,
- 0, 0 },
-
- {
- KEY_INTERNAL,
- "MaxNoOfSavedEvents",
- MGM_TOKEN,
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "100",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_MGM_PORT,
- "PortNumber",
- MGM_TOKEN,
- "Port number to give commands to/fetch configurations from management server",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- NDB_PORT,
- "0",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- KEY_INTERNAL,
- "PortNumberStats",
- MGM_TOKEN,
- "Port number used to get statistical information from a management server",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "0",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- CFG_NODE_ARBIT_RANK,
- "ArbitrationRank",
- MGM_TOKEN,
- "If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1",
- "0",
- "2" },
-
- {
- CFG_NODE_ARBIT_DELAY,
- "ArbitrationDelay",
- MGM_TOKEN,
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- /****************************************************************************
- * TCP
- ***************************************************************************/
- {
- CFG_SECTION_CONNECTION,
- "TCP",
- "TCP",
- "Connection section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)CONNECTION_TYPE_TCP,
- 0, 0
- },
-
- {
- CFG_CONNECTION_HOSTNAME_1,
- "HostName1",
- "TCP",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_HOSTNAME_2,
- "HostName2",
- "TCP",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_1,
- "NodeId1",
- "TCP",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_2,
- "NodeId2",
- "TCP",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- CFG_CONNECTION_GROUP,
- "Group",
- "TCP",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "55",
- "0", "200" },
-
- {
- CFG_CONNECTION_NODE_ID_SERVER,
- "NodeIdServer",
- "TCP",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1", "63" },
-
- {
- CFG_CONNECTION_SEND_SIGNAL_ID,
- "SendSignalId",
- "TCP",
- "Sends id in each signal. Used in trace files.",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "true",
- "false",
- "true" },
-
-
- {
- CFG_CONNECTION_CHECKSUM,
- "Checksum",
- "TCP",
- "If checksum is enabled, all signals between nodes are checked for errors",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true" },
-
- {
- CFG_CONNECTION_SERVER_PORT,
- "PortNumber",
- "TCP",
- "Port used for this transporter",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "0",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- CFG_TCP_SEND_BUFFER_SIZE,
- "SendBufferMemory",
- "TCP",
- "Bytes of buffer for signals sent from this node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "256K",
- "64K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_TCP_RECEIVE_BUFFER_SIZE,
- "ReceiveBufferMemory",
- "TCP",
- "Bytes of buffer for signals received by this node",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "64K",
- "16K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_TCP_PROXY,
- "Proxy",
- "TCP",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_1_SYSTEM,
- "NodeId1_System",
- "TCP",
- "System for node 1 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_2_SYSTEM,
- "NodeId2_System",
- "TCP",
- "System for node 2 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
-
- /****************************************************************************
- * SHM
- ***************************************************************************/
- {
- CFG_SECTION_CONNECTION,
- "SHM",
- "SHM",
- "Connection section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)CONNECTION_TYPE_SHM,
- 0, 0 },
-
- {
- CFG_CONNECTION_HOSTNAME_1,
- "HostName1",
- "SHM",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_HOSTNAME_2,
- "HostName2",
- "SHM",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_SERVER_PORT,
- "PortNumber",
- "SHM",
- "Port used for this transporter",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "0",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- CFG_SHM_SIGNUM,
- "Signum",
- "SHM",
- "Signum to be used for signalling",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_NODE_1,
- "NodeId1",
- "SHM",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_2,
- "NodeId2",
- "SHM",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- 0, 0 },
-
- {
- CFG_CONNECTION_GROUP,
- "Group",
- "SHM",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "35",
- "0", "200" },
-
- {
- CFG_CONNECTION_NODE_ID_SERVER,
- "NodeIdServer",
- "SHM",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1", "63" },
-
- {
- CFG_CONNECTION_SEND_SIGNAL_ID,
- "SendSignalId",
- "SHM",
- "Sends id in each signal. Used in trace files.",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true" },
-
-
- {
- CFG_CONNECTION_CHECKSUM,
- "Checksum",
- "SHM",
- "If checksum is enabled, all signals between nodes are checked for errors",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "true",
- "false",
- "true" },
-
- {
- CFG_SHM_KEY,
- "ShmKey",
- "SHM",
- "A shared memory key",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- UNDEFINED,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_SHM_BUFFER_MEM,
- "ShmSize",
- "SHM",
- "Size of shared memory segment",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1M",
- "64K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_NODE_1_SYSTEM,
- "NodeId1_System",
- "SHM",
- "System for node 1 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_2_SYSTEM,
- "NodeId2_System",
- "SHM",
- "System for node 2 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- /****************************************************************************
- * SCI
- ***************************************************************************/
- {
- CFG_SECTION_CONNECTION,
- "SCI",
- "SCI",
- "Connection section",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_SECTION,
- (const char *)CONNECTION_TYPE_SCI,
- 0, 0
- },
-
- {
- CFG_CONNECTION_NODE_1,
- "NodeId1",
- "SCI",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_NODE_2,
- "NodeId2",
- "SCI",
- "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_STRING,
- MANDATORY,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_GROUP,
- "Group",
- "SCI",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "15",
- "0", "200" },
-
- {
- CFG_CONNECTION_NODE_ID_SERVER,
- "NodeIdServer",
- "SCI",
- "",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "1", "63" },
-
- {
- CFG_CONNECTION_HOSTNAME_1,
- "HostName1",
- "SCI",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_HOSTNAME_2,
- "HostName2",
- "SCI",
- "Name/IP of computer on one side of the connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_SERVER_PORT,
- "PortNumber",
- "SCI",
- "Port used for this transporter",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "0",
- STR_VALUE(MAX_PORT_NO) },
-
- {
- CFG_SCI_HOST1_ID_0,
- "Host1SciId0",
- "SCI",
- "SCI-node id for adapter 0 on Host1 (a computer can have two adapters)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_SCI_HOST1_ID_1,
- "Host1SciId1",
- "SCI",
- "SCI-node id for adapter 1 on Host1 (a computer can have two adapters)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_SCI_HOST2_ID_0,
- "Host2SciId0",
- "SCI",
- "SCI-node id for adapter 0 on Host2 (a computer can have two adapters)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- MANDATORY,
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_SCI_HOST2_ID_1,
- "Host2SciId1",
- "SCI",
- "SCI-node id for adapter 1 on Host2 (a computer can have two adapters)",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "0",
- "0",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_SEND_SIGNAL_ID,
- "SendSignalId",
- "SCI",
- "Sends id in each signal. Used in trace files.",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "true",
- "false",
- "true" },
-
- {
- CFG_CONNECTION_CHECKSUM,
- "Checksum",
- "SCI",
- "If checksum is enabled, all signals between nodes are checked for errors",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_BOOL,
- "false",
- "false",
- "true" },
-
- {
- CFG_SCI_SEND_LIMIT,
- "SendLimit",
- "SCI",
- "Transporter send buffer contents are sent when this no of bytes is buffered",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "8K",
- "128",
- "32K" },
-
- {
- CFG_SCI_BUFFER_MEM,
- "SharedBufferSize",
- "SCI",
- "Size of shared memory segment",
- ConfigInfo::CI_USED,
- false,
- ConfigInfo::CI_INT,
- "1M",
- "64K",
- STR_VALUE(MAX_INT_RNIL) },
-
- {
- CFG_CONNECTION_NODE_1_SYSTEM,
- "NodeId1_System",
- "SCI",
- "System for node 1 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 },
-
- {
- CFG_CONNECTION_NODE_2_SYSTEM,
- "NodeId2_System",
- "SCI",
- "System for node 2 in connection",
- ConfigInfo::CI_INTERNAL,
- false,
- ConfigInfo::CI_STRING,
- UNDEFINED,
- 0, 0 }
-};
-
-const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo);
-
-#ifndef NDB_MGMAPI
-/****************************************************************************
- * Ctor
- ****************************************************************************/
-static void require(bool v)
-{
- if(!v)
- {
- if (opt_core)
- abort();
- else
- exit(-1);
- }
-}
-
-ConfigInfo::ConfigInfo()
- : m_info(true), m_systemDefaults(true)
-{
- int i;
- Properties *section;
- const Properties *oldpinfo;
-
- for (i=0; i<m_NoOfParams; i++) {
- const ParamInfo & param = m_ParamInfo[i];
- Uint64 default_uint64;
- bool default_bool;
-
- // Create new section if it did not exist
- if (!m_info.getCopy(param._section, &section)) {
- Properties newsection(true);
- m_info.put(param._section, &newsection);
-
- // Get copy of section
- m_info.getCopy(param._section, &section);
- }
-
- // Create pinfo (parameter info) entry
- Properties pinfo(true);
- pinfo.put("Id", param._paramId);
- pinfo.put("Fname", param._fname);
- pinfo.put("Description", param._description);
- pinfo.put("Updateable", param._updateable);
- pinfo.put("Type", param._type);
- pinfo.put("Status", param._status);
-
- if(param._default == MANDATORY){
- pinfo.put("Mandatory", (Uint32)1);
- }
-
- switch (param._type) {
- case CI_BOOL:
- {
- bool tmp_bool;
- require(InitConfigFileParser::convertStringToBool(param._min, tmp_bool));
- pinfo.put64("Min", tmp_bool);
- require(InitConfigFileParser::convertStringToBool(param._max, tmp_bool));
- pinfo.put64("Max", tmp_bool);
- break;
- }
- case CI_INT:
- case CI_INT64:
- {
- Uint64 tmp_uint64;
- require(InitConfigFileParser::convertStringToUint64(param._min, tmp_uint64));
- pinfo.put64("Min", tmp_uint64);
- require(InitConfigFileParser::convertStringToUint64(param._max, tmp_uint64));
- pinfo.put64("Max", tmp_uint64);
- break;
- }
- case CI_SECTION:
- pinfo.put("SectionType", (Uint32)UintPtr(param._default));
- break;
- case CI_STRING:
- break;
- }
-
- // Check that pinfo is really new
- if (section->get(param._fname, &oldpinfo)) {
- ndbout << "Error: Parameter " << param._fname
- << " defined twice in section " << param._section
- << "." << endl;
- require(false);
- }
-
- // Add new pinfo to section
- section->put(param._fname, &pinfo);
-
- // Replace section with modified section
- m_info.put(param._section, section, true);
- delete section;
-
- if(param._type != ConfigInfo::CI_SECTION){
- Properties * p;
- if(!m_systemDefaults.getCopy(param._section, &p)){
- p = new Properties(true);
- }
- if(param._default != UNDEFINED &&
- param._default != MANDATORY){
- switch (param._type)
- {
- case CI_SECTION:
- break;
- case CI_STRING:
- require(p->put(param._fname, param._default));
- break;
- case CI_BOOL:
- {
- require(InitConfigFileParser::convertStringToBool(param._default, default_bool));
- require(p->put(param._fname, default_bool));
- break;
- }
- case CI_INT:
- case CI_INT64:
- {
- require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64));
- require(p->put(param._fname, default_uint64));
- break;
- }
- }
- }
- require(m_systemDefaults.put(param._section, p, true));
- delete p;
- }
- }
-
- for (i=0; i<m_NoOfParams; i++) {
- if(m_ParamInfo[i]._section == NULL){
- ndbout << "Check that each entry has a section failed." << endl;
- ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl;
- ndbout << "Edit file " << __FILE__ << "." << endl;
- require(false);
- }
-
- if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION)
- continue;
-
- const Properties * p = getInfo(m_ParamInfo[i]._section);
- if (!p || !p->contains(m_ParamInfo[i]._fname)) {
- ndbout << "Check that each pname has an fname failed." << endl;
- ndbout << "Parameter \"" << m_ParamInfo[i]._fname
- << "\" does not exist in section \""
- << m_ParamInfo[i]._section << "\"." << endl;
- ndbout << "Edit file " << __FILE__ << "." << endl;
- require(false);
- }
- }
-}
-
-/****************************************************************************
- * Getters
- ****************************************************************************/
-inline void warning(const char * src, const char * arg){
- ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl;
- require(false);
-}
-
-const Properties *
-ConfigInfo::getInfo(const char * section) const {
- const Properties * p;
- if(!m_info.get(section, &p)){
- return 0;
- // warning("getInfo", section);
- }
- return p;
-}
-
-const Properties *
-ConfigInfo::getDefaults(const char * section) const {
- const Properties * p;
- if(!m_systemDefaults.get(section, &p)){
- return 0;
- //warning("getDefaults", section);
- }
- return p;
-}
-
-static
-Uint64
-getInfoInt(const Properties * section,
- const char* fname, const char * type){
- Uint32 val32;
- const Properties * p;
- 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 0;
-}
-
-static
-const char *
-getInfoString(const Properties * section,
- const char* fname, const char * type){
- const char* val;
- const Properties * p;
- if (section->get(fname, &p) && p->get(type, &val)) {
- return val;
- }
- warning(type, fname);
- return val;
-}
-
-Uint64
-ConfigInfo::getMax(const Properties * section, const char* fname) const {
- return getInfoInt(section, fname, "Max");
-}
-
-Uint64
-ConfigInfo::getMin(const Properties * section, const char* fname) const {
- return getInfoInt(section, fname, "Min");
-}
-
-Uint64
-ConfigInfo::getDefault(const Properties * section, const char* fname) const {
- return getInfoInt(section, fname, "Default");
-}
-
-const char*
-ConfigInfo::getDescription(const Properties * section,
- const char* fname) const {
- return getInfoString(section, fname, "Description");
-}
-
-bool
-ConfigInfo::isSection(const char * section) const {
- for (int i = 0; i<m_noOfSectionNames; i++) {
- if(!strcasecmp(section, m_sectionNames[i])) return true;
- }
- return false;
-}
-
-const char*
-ConfigInfo::nameToAlias(const char * name) {
- for (int i = 0; m_sectionNameAliases[i].name != 0; i++)
- if(!strcasecmp(name, m_sectionNameAliases[i].name))
- return m_sectionNameAliases[i].alias;
- return 0;
-}
-
-const char*
-ConfigInfo::getAlias(const char * section) {
- for (int i = 0; m_sectionNameAliases[i].name != 0; i++)
- if(!strcasecmp(section, m_sectionNameAliases[i].alias))
- return m_sectionNameAliases[i].name;
- return 0;
-}
-
-bool
-ConfigInfo::verify(const Properties * section, const char* fname,
- Uint64 value) const {
- Uint64 min, max;
-
- min = getInfoInt(section, fname, "Min");
- max = getInfoInt(section, fname, "Max");
- if(min > max){
- warning("verify", fname);
- }
- if (value >= min && value <= max)
- return true;
- else
- return false;
-}
-
-ConfigInfo::Type
-ConfigInfo::getType(const Properties * section, const char* fname) const {
- return (ConfigInfo::Type) getInfoInt(section, fname, "Type");
-}
-
-ConfigInfo::Status
-ConfigInfo::getStatus(const Properties * section, const char* fname) const {
- return (ConfigInfo::Status) getInfoInt(section, fname, "Status");
-}
-
-/****************************************************************************
- * Printers
- ****************************************************************************/
-
-void ConfigInfo::print() const {
- Properties::Iterator it(&m_info);
- for (const char* n = it.first(); n != NULL; n = it.next()) {
- print(n);
- }
-}
-
-void ConfigInfo::print(const char* section) const {
- ndbout << "****** " << section << " ******" << endl << endl;
- const Properties * sec = getInfo(section);
- Properties::Iterator it(sec);
- for (const char* n = it.first(); n != NULL; n = it.next()) {
- // Skip entries with different F- and P-names
- if (getStatus(sec, n) == ConfigInfo::CI_INTERNAL) continue;
- if (getStatus(sec, n) == ConfigInfo::CI_DEPRICATED) continue;
- if (getStatus(sec, n) == ConfigInfo::CI_NOTIMPLEMENTED) continue;
- print(sec, n);
- }
-}
-
-void ConfigInfo::print(const Properties * section,
- const char* parameter) const {
- ndbout << parameter;
- // ndbout << getDescription(section, parameter) << endl;
- switch (getType(section, parameter)) {
- case ConfigInfo::CI_BOOL:
- ndbout << " (Boolean value)" << endl;
- ndbout << getDescription(section, parameter) << endl;
- if (getDefault(section, parameter) == false) {
- ndbout << "Default: N (Legal values: Y, N)" << endl;
- } else if (getDefault(section, parameter) == true) {
- ndbout << "Default: Y (Legal values: Y, N)" << endl;
- } else if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
- ndbout << "MANDATORY (Legal values: Y, N)" << endl;
- } else {
- ndbout << "UNKNOWN" << endl;
- }
- ndbout << endl;
- break;
-
- case ConfigInfo::CI_INT:
- case ConfigInfo::CI_INT64:
- ndbout << " (Non-negative Integer)" << endl;
- ndbout << getDescription(section, parameter) << endl;
- if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
- ndbout << "MANDATORY (";
- } else if (getDefault(section, parameter) == (UintPtr)UNDEFINED) {
- ndbout << "UNDEFINED (";
- } else {
- ndbout << "Default: " << getDefault(section, parameter) << " (";
- }
- ndbout << "Min: " << getMin(section, parameter) << ", ";
- ndbout << "Max: " << getMax(section, parameter) << ")" << endl;
- ndbout << endl;
- break;
-
- case ConfigInfo::CI_STRING:
- ndbout << " (String)" << endl;
- ndbout << getDescription(section, parameter) << endl;
- if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
- ndbout << "MANDATORY" << endl;
- } else {
- ndbout << "No default value" << endl;
- }
- ndbout << endl;
- break;
- case ConfigInfo::CI_SECTION:
- break;
- }
-}
-
-/****************************************************************************
- * Section Rules
- ****************************************************************************/
-
-/**
- * Node rule: Add "Type" and update "NoOfNodes"
- */
-bool
-transformNode(InitConfigFileParser::Context & ctx, const char * data){
-
- Uint32 id, line;
- if(!ctx.m_currentSection->get("NodeId", &id) && !ctx.m_currentSection->get("Id", &id)){
- Uint32 nextNodeId= 1;
- ctx.m_userProperties.get("NextNodeId", &nextNodeId);
- id= nextNodeId;
- while (ctx.m_userProperties.get("AllocatedNodeId_", id, &line))
- id++;
- if (id != nextNodeId)
- {
- fprintf(stderr,"Cluster configuration warning line %d: "
- "Could not use next node id %d for section [%s], "
- "using next unused node id %d.\n",
- ctx.m_sectionLineno, nextNodeId, ctx.fname, id);
- }
- ctx.m_currentSection->put("NodeId", id);
- } else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) {
- ctx.reportError("Duplicate nodeid in section "
- "[%s] starting at line: %d. Previously used on line %d.",
- ctx.fname, ctx.m_sectionLineno, line);
- return false;
- }
-
- if(id >= MAX_NODES)
- {
- ctx.reportError("too many nodes configured, only up to %d nodes supported.",
- MAX_NODES);
- return false;
- }
-
- // next node id _always_ next numbers after last used id
- ctx.m_userProperties.put("NextNodeId", id+1, true);
-
- ctx.m_userProperties.put("AllocatedNodeId_", id, ctx.m_sectionLineno);
- BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id);
-
- ctx.m_currentSection->put("Type", ctx.fname);
-
- Uint32 nodes = 0;
- ctx.m_userProperties.get("NoOfNodes", &nodes);
- ctx.m_userProperties.put("NoOfNodes", ++nodes, true);
-
- /**
- * Update count (per type)
- */
- nodes = 0;
- ctx.m_userProperties.get(ctx.fname, &nodes);
- ctx.m_userProperties.put(ctx.fname, ++nodes, true);
-
- return true;
-}
-
-static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data)
-{
- DBUG_ENTER("checkLocalhostHostnameMix");
- const char * hostname= 0;
- ctx.m_currentSection->get("HostName", &hostname);
- if (hostname == 0 || hostname[0] == 0)
- DBUG_RETURN(true);
-
- Uint32 localhost_used= 0;
- if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){
- localhost_used= 1;
- ctx.m_userProperties.put("$computer-localhost-used", localhost_used);
- if(!ctx.m_userProperties.get("$computer-localhost", &hostname))
- DBUG_RETURN(true);
- } else {
- ctx.m_userProperties.get("$computer-localhost-used", &localhost_used);
- ctx.m_userProperties.put("$computer-localhost", hostname);
- }
-
- if (localhost_used) {
- ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal",
- hostname);
- DBUG_RETURN(false);
- }
-
- DBUG_RETURN(true);
-}
-
-bool
-fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data)
-{
- const char * hostname;
- DBUG_ENTER("fixNodeHostname");
-
- if (ctx.m_currentSection->get("HostName", &hostname))
- DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
-
- const char * compId;
- if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId))
- DBUG_RETURN(true);
-
- const Properties * computer;
- char tmp[255];
- BaseString::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);
- DBUG_RETURN(false);
- }
-
- if(!computer->get("HostName", &hostname)){
- ctx.reportError("HostName missing in [COMPUTER] (Id: %d) "
- " - [%s] starting at line: %d",
- compId, ctx.fname, ctx.m_sectionLineno);
- DBUG_RETURN(false);
- }
-
- require(ctx.m_currentSection->put("HostName", hostname));
- DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
-}
-
-bool
-fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){
- DBUG_ENTER("fixFileSystemPath");
-
- const char * path;
- if (ctx.m_currentSection->get("FileSystemPath", &path))
- DBUG_RETURN(true);
-
- if (ctx.m_currentSection->get("DataDir", &path)) {
- require(ctx.m_currentSection->put("FileSystemPath", path));
- DBUG_RETURN(true);
- }
-
- require(false);
- DBUG_RETURN(false);
-}
-
-bool
-fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){
-
- const char * path;
- if (ctx.m_currentSection->get("BackupDataDir", &path))
- return true;
-
- if (ctx.m_currentSection->get("FileSystemPath", &path)) {
- require(ctx.m_currentSection->put("BackupDataDir", path));
- return true;
- }
-
- require(false);
- return false;
-}
-
-/**
- * Connection rule: Check support of connection
- */
-bool
-checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data)
-{
- int error= 0;
- if (strcasecmp("TCP",ctx.fname) == 0)
- {
- // always enabled
- }
- else if (strcasecmp("SHM",ctx.fname) == 0)
- {
-#ifndef NDB_SHM_TRANSPORTER
- error= 1;
-#endif
- }
- else if (strcasecmp("SCI",ctx.fname) == 0)
- {
-#ifndef NDB_SCI_TRANSPORTER
- error= 1;
-#endif
- }
-
- if (error)
- {
- ctx.reportError("Binary not compiled with this connection support, "
- "[%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- return true;
-}
-
-/**
- * Connection rule: Update "NoOfConnections"
- */
-bool
-transformConnection(InitConfigFileParser::Context & ctx, const char * data)
-{
- Uint32 connections = 0;
- ctx.m_userProperties.get("NoOfConnections", &connections);
- BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections);
- ctx.m_userProperties.put("NoOfConnections", ++connections, true);
-
- ctx.m_currentSection->put("Type", ctx.fname);
- return true;
-}
-
-/**
- * System rule: Just add it
- */
-bool
-transformSystem(InitConfigFileParser::Context & ctx, const char * data){
-
- const char * name;
- if(!ctx.m_currentSection->get("Name", &name)){
- ctx.reportError("Mandatory parameter Name missing from section "
- "[%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- ndbout << "transformSystem " << name << endl;
-
- BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name);
-
- return true;
-}
-
-/**
- * Computer rule: Update "NoOfComputers", add "Type"
- */
-bool
-transformComputer(InitConfigFileParser::Context & ctx, const char * data){
- const char * id;
- if(!ctx.m_currentSection->get("Id", &id)){
- ctx.reportError("Mandatory parameter Id missing from section "
- "[%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id);
-
- Uint32 computers = 0;
- ctx.m_userProperties.get("NoOfComputers", &computers);
- ctx.m_userProperties.put("NoOfComputers", ++computers, true);
-
- const char * hostname = 0;
- ctx.m_currentSection->get("HostName", &hostname);
- if(!hostname){
- return true;
- }
-
- return checkLocalhostHostnameMix(ctx,0);
-}
-
-/**
- * Apply default values
- */
-void
-applyDefaultValues(InitConfigFileParser::Context & ctx,
- const Properties * defaults)
-{
- DBUG_ENTER("applyDefaultValues");
- if(defaults != NULL){
- Properties::Iterator it(defaults);
-
- for(const char * name = it.first(); name != NULL; name = it.next()){
- (void) 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::CI_INT:
- case ConfigInfo::CI_BOOL:{
- Uint32 val = 0;
- ::require(defaults->get(name, &val));
- ctx.m_currentSection->put(name, val);
- DBUG_PRINT("info",("%s=%d #default",name,val));
- break;
- }
- case ConfigInfo::CI_INT64:{
- Uint64 val = 0;
- ::require(defaults->get(name, &val));
- ctx.m_currentSection->put64(name, val);
- DBUG_PRINT("info",("%s=%lld #default",name,val));
- break;
- }
- case ConfigInfo::CI_STRING:{
- const char * val;
- ::require(defaults->get(name, &val));
- ctx.m_currentSection->put(name, val);
- DBUG_PRINT("info",("%s=%s #default",name,val));
- break;
- }
- case ConfigInfo::CI_SECTION:
- break;
- }
- }
-#ifndef DBUG_OFF
- else
- {
- switch (ctx.m_info->getType(ctx.m_currentInfo, name)){
- case ConfigInfo::CI_INT:
- case ConfigInfo::CI_BOOL:{
- Uint32 val = 0;
- ::require(ctx.m_currentSection->get(name, &val));
- DBUG_PRINT("info",("%s=%d",name,val));
- break;
- }
- case ConfigInfo::CI_INT64:{
- Uint64 val = 0;
- ::require(ctx.m_currentSection->get(name, &val));
- DBUG_PRINT("info",("%s=%lld",name,val));
- break;
- }
- case ConfigInfo::CI_STRING:{
- const char * val;
- ::require(ctx.m_currentSection->get(name, &val));
- DBUG_PRINT("info",("%s=%s",name,val));
- break;
- }
- case ConfigInfo::CI_SECTION:
- break;
- }
- }
-#endif
- }
- }
- DBUG_VOID_RETURN;
-}
-
-bool
-applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){
-
- 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;
-}
-
-/**
- * Check that a section contains all MANDATORY parameters
- */
-bool
-checkMandatory(InitConfigFileParser::Context & ctx, const char * data){
-
- Properties::Iterator it(ctx.m_currentInfo);
- for(const char * name = it.first(); name != NULL; name = it.next()){
- const Properties * info = NULL;
- ::require(ctx.m_currentInfo->get(name, &info));
- Uint32 val;
- if(info->get("Mandatory", &val)){
- const char * fname;
- ::require(info->get("Fname", &fname));
- 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);
- return false;
- }
- }
- }
- return true;
-}
-
-/**
- * Connection rule: Fix node id
- *
- * Transform a string "NodeidX" (e.g. "uppsala.32")
- * into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala").
- */
-static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data)
-{
- char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")];
- char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")];
- const char* nodeId;
- if(!ctx.m_currentSection->get(buf, &nodeId))
- {
- ctx.reportError("Mandatory parameter %s missing from section"
- "[%s] starting at line: %d",
- buf, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- char tmpLine[MAX_LINE_LENGTH];
- strncpy(tmpLine, nodeId, MAX_LINE_LENGTH);
- char* token1 = strtok(tmpLine, ".");
- char* token2 = strtok(NULL, ".");
- Uint32 id;
-
- if(!token1)
- {
- ctx.reportError("Value for mandatory parameter %s missing from section "
- "[%s] starting at line: %d",
- buf, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- if (token2 == NULL) { // Only a number given
- errno = 0;
- char* p;
- id = strtol(token1, &p, 10);
- if (errno != 0 || id <= 0x0 || id > MAX_NODES)
- {
- ctx.reportError("Illegal value for mandatory parameter %s from section "
- "[%s] starting at line: %d",
- buf, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- require(ctx.m_currentSection->put(buf, id, true));
- } else { // A pair given (e.g. "uppsala.32")
- errno = 0;
- char* p;
- id = strtol(token2, &p, 10);
- if (errno != 0 || id <= 0x0 || id > MAX_NODES)
- {
- ctx.reportError("Illegal value for mandatory parameter %s from section "
- "[%s] starting at line: %d",
- buf, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- require(ctx.m_currentSection->put(buf, id, true));
- require(ctx.m_currentSection->put(sysbuf, token1));
- }
- return true;
-}
-
-/**
- * Connection rule: Fix hostname
- *
- * Unless Hostname is not already specified, do steps:
- * -# Via Connection's NodeId lookup Node
- * -# Via Node's ExecuteOnComputer lookup Hostname
- * -# Add HostName to Connection
- */
-static bool
-fixHostname(InitConfigFileParser::Context & ctx, const char * data){
-
- char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")];
- char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("HostNam")];
-
- if(!ctx.m_currentSection->contains(data)){
- Uint32 id = 0;
- require(ctx.m_currentSection->get(buf, &id));
-
- const Properties * node;
- if(!ctx.m_config->get("Node", id, &node))
- {
- ctx.reportError("Unknown node: \"%d\" specified in connection "
- "[%s] starting at line: %d",
- id, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- const char * hostname;
- require(node->get("HostName", &hostname));
- require(ctx.m_currentSection->put(data, hostname));
- }
- return true;
-}
-
-/**
- * Connection rule: Fix port number (using a port number adder)
- */
-static bool
-fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
-
- DBUG_ENTER("fixPortNumber");
-
- Uint32 id1, id2;
- const char *hostName1;
- const char *hostName2;
- require(ctx.m_currentSection->get("NodeId1", &id1));
- require(ctx.m_currentSection->get("NodeId2", &id2));
- require(ctx.m_currentSection->get("HostName1", &hostName1));
- require(ctx.m_currentSection->get("HostName2", &hostName2));
- DBUG_PRINT("info",("NodeId1=%d HostName1=\"%s\"",id1,hostName1));
- DBUG_PRINT("info",("NodeId2=%d HostName2=\"%s\"",id2,hostName2));
-
- const Properties *node1, *node2;
- require(ctx.m_config->get("Node", id1, &node1));
- require(ctx.m_config->get("Node", id2, &node2));
-
- const char *type1, *type2;
- require(node1->get("Type", &type1));
- require(node2->get("Type", &type2));
-
- /* add NodeIdServer info */
- {
- Uint32 nodeIdServer = id1 < id2 ? id1 : id2;
- if(strcmp(type1, API_TOKEN) == 0 || strcmp(type2, MGM_TOKEN) == 0)
- nodeIdServer = id2;
- else if(strcmp(type2, API_TOKEN) == 0 || strcmp(type1, MGM_TOKEN) == 0)
- nodeIdServer = id1;
- ctx.m_currentSection->put("NodeIdServer", nodeIdServer);
-
- if (id2 == nodeIdServer) {
- {
- const char *tmp= hostName1;
- hostName1= hostName2;
- hostName2= tmp;
- }
- {
- Uint32 tmp= id1;
- id1= id2;
- id2= tmp;
- }
- {
- const Properties *tmp= node1;
- node1= node2;
- node2= tmp;
- }
- {
- const char *tmp= type1;
- type1= type2;
- type2= tmp;
- }
- }
- }
-
- BaseString hostname(hostName1);
-
- if (hostname.c_str()[0] == 0) {
- ctx.reportError("Hostname required on nodeid %d since it will "
- "act as server.", id1);
- DBUG_RETURN(false);
- }
-
- Uint32 port= 0;
- if(strcmp(type1, MGM_TOKEN)==0)
- node1->get("PortNumber",&port);
- else if(strcmp(type2, MGM_TOKEN)==0)
- node2->get("PortNumber",&port);
-
- if (!port &&
- !node1->get("ServerPort", &port) &&
- !ctx.m_userProperties.get("ServerPort_", id1, &port))
- {
- Uint32 base= 0;
- /*
- * If the connection doesn't involve an mgm server,
- * and a default port number has been set, behave the old
- * way of allocating port numbers for transporters.
- */
- if(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base))
- {
- Uint32 adder= 0;
- {
- BaseString server_port_adder(hostname);
- server_port_adder.append("_ServerPortAdder");
- ctx.m_userProperties.get(server_port_adder.c_str(), &adder);
- ctx.m_userProperties.put(server_port_adder.c_str(), adder+1, true);
- }
-
- if (!ctx.m_userProperties.get("ServerPortBase", &base)){
- if(!(ctx.m_userDefaults &&
- ctx.m_userDefaults->get("PortNumber", &base)) &&
- !ctx.m_systemDefaults->get("PortNumber", &base)) {
- base= strtoll(NDB_TCP_BASE_PORT,0,0);
- }
- ctx.m_userProperties.put("ServerPortBase", base);
- }
-
- port= base + adder;
- ctx.m_userProperties.put("ServerPort_", id1, port);
- }
- }
-
- if(ctx.m_currentSection->contains("PortNumber")) {
- ndbout << "PortNumber should no longer be specificied "
- << "per connection, please remove from config. "
- << "Will be changed to " << port << endl;
- ctx.m_currentSection->put("PortNumber", port, true);
- }
- else
- {
- ctx.m_currentSection->put("PortNumber", port);
- }
-
- DBUG_PRINT("info", ("connection %d-%d port %d host %s",
- id1, id2, port, hostname.c_str()));
-
- DBUG_RETURN(true);
-}
-
-static bool
-fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data)
-{
- DBUG_ENTER("fixShmUniqueId");
- Uint32 nodes= 0;
- ctx.m_userProperties.get(ctx.fname, &nodes);
- if (nodes == 1) // first management server
- {
- Uint32 portno= atoi(NDB_PORT);
- ctx.m_currentSection->get("PortNumber", &portno);
- ctx.m_userProperties.put("ShmUniqueId", portno);
- }
- DBUG_RETURN(true);
-}
-
-static
-bool
-fixShmKey(InitConfigFileParser::Context & ctx, const char *)
-{
- DBUG_ENTER("fixShmKey");
- {
- static int last_signum= -1;
- Uint32 signum;
- if(!ctx.m_currentSection->get("Signum", &signum))
- {
- signum= OPT_NDB_SHM_SIGNUM_DEFAULT;
- if (signum <= 0)
- {
- ctx.reportError("Unable to set default parameter for [SHM]Signum"
- " please specify [SHM DEFAULT]Signum");
- return false;
- }
- ctx.m_currentSection->put("Signum", signum);
- DBUG_PRINT("info",("Added Signum=%u", signum));
- }
- if ( last_signum != (int)signum && last_signum >= 0 )
- {
- ctx.reportError("All shared memory transporters must have same [SHM]Signum defined."
- " Use [SHM DEFAULT]Signum");
- return false;
- }
- last_signum= (int)signum;
- }
- {
- Uint32 id1= 0, id2= 0, key= 0;
- require(ctx.m_currentSection->get("NodeId1", &id1));
- require(ctx.m_currentSection->get("NodeId2", &id2));
- if(!ctx.m_currentSection->get("ShmKey", &key))
- {
- require(ctx.m_userProperties.get("ShmUniqueId", &key));
- key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1);
- ctx.m_currentSection->put("ShmKey", key);
- DBUG_PRINT("info",("Added ShmKey=0x%x", key));
- }
- }
- DBUG_RETURN(true);
-}
-
-/**
- * DB Node rule: Check various constraints
- */
-static bool
-checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){
-
- Uint32 t1 = 0, t2 = 0;
- ctx.m_currentSection->get("MaxNoOfConcurrentOperations", &t1);
- ctx.m_currentSection->get("MaxNoOfConcurrentTransactions", &t2);
-
- if (t1 < t2) {
- ctx.reportError("MaxNoOfConcurrentOperations must be greater than "
- "MaxNoOfConcurrentTransactions - [%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- Uint32 replicas = 0, otherReplicas;
- ctx.m_currentSection->get("NoOfReplicas", &replicas);
- if(ctx.m_userProperties.get("NoOfReplicas", &otherReplicas)){
- if(replicas != otherReplicas){
- ctx.reportError("NoOfReplicas defined differently on different nodes"
- " - [%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- } else {
- ctx.m_userProperties.put("NoOfReplicas", replicas);
- }
-
- /**
- * In kernel, will calculate the MaxNoOfMeataTables use the following sum:
- * Uint32 noOfMetaTables = noOfTables + noOfOrderedIndexes +
- * noOfUniqueHashIndexes + 2
- * 2 is the number of the SysTables.
- * So must check that the sum does't exceed the max value of Uint32.
- */
- Uint32 noOfTables = 0,
- noOfOrderedIndexes = 0,
- noOfUniqueHashIndexes = 0;
- ctx.m_currentSection->get("MaxNoOfTables", &noOfTables);
- ctx.m_currentSection->get("MaxNoOfOrderedIndexes", &noOfOrderedIndexes);
- ctx.m_currentSection->get("MaxNoOfUniqueHashIndexes", &noOfUniqueHashIndexes);
-
- Uint64 sum= (Uint64)noOfTables + noOfOrderedIndexes + noOfUniqueHashIndexes;
-
- if (sum > ((Uint32)~0 - 2)) {
- ctx.reportError("The sum of MaxNoOfTables, MaxNoOfOrderedIndexes and"
- " MaxNoOfUniqueHashIndexes must not exceed %u - [%s]"
- " starting at line: %d",
- ((Uint32)~0 - 2), ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- return true;
-}
-
-/**
- * Connection rule: Check varius constraints
- */
-static bool
-checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){
-
- Uint32 id1 = 0, id2 = 0;
- ctx.m_currentSection->get("NodeId1", &id1);
- ctx.m_currentSection->get("NodeId2", &id2);
-
- if(id1 == id2){
- ctx.reportError("Illegal connection from node to itself"
- " - [%s] starting at line: %d",
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- const Properties * node1;
- if(!ctx.m_config->get("Node", id1, &node1)){
- ctx.reportError("Connection refering to undefined node: %d"
- " - [%s] starting at line: %d",
- id1, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- const Properties * node2;
- if(!ctx.m_config->get("Node", id2, &node2)){
- ctx.reportError("Connection refering to undefined node: %d"
- " - [%s] starting at line: %d",
- id2, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- const char * type1;
- const char * type2;
- require(node1->get("Type", &type1));
- require(node2->get("Type", &type2));
-
- /**
- * Report error if the following are true
- * -# None of the nodes is of type DB
- * -# Not both of them are MGMs
- */
- if((strcmp(type1, DB_TOKEN) != 0 && strcmp(type2, DB_TOKEN) != 0) &&
- !(strcmp(type1, MGM_TOKEN) == 0 && strcmp(type2, MGM_TOKEN) == 0))
- {
- ctx.reportError("Invalid connection between node %d (%s) and node %d (%s)"
- " - [%s] starting at line: %d",
- id1, type1, id2, type2,
- ctx.fname, ctx.m_sectionLineno);
- return false;
- }
-
- return true;
-}
-
-static bool
-checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){
-
- const char * host;
- struct in_addr addr;
- if(ctx.m_currentSection->get(data, &host) && strlen(host) &&
- Ndb_getInAddr(&addr, host)){
- ctx.reportError("Unable to lookup/illegal hostname %s"
- " - [%s] starting at line: %d",
- host, ctx.fname, ctx.m_sectionLineno);
- return false;
- }
- 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::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){
- ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl;
- 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)((Int64)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::CI_INT || newType == ConfigInfo::CI_BOOL){
- require(dst.put(newName, (Uint32)newVal));
- } else if(newType == ConfigInfo::CI_INT64) {
- require(dst.put64(newName, newVal));
- }
- return true;
-}
-
-static bool
-fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
- const char * name;
- /**
- * Transform old values to new values
- * Transform new values to old values (backward compatible)
- */
- Properties tmp(true);
- Properties::Iterator it(ctx.m_currentSection);
- for (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(strcasecmp(name, p->m_oldName) == 0){
- if(!transform(ctx, tmp, name, p->m_newName, add, mul)){
- return false;
- }
- } else if(strcasecmp(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 (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:
- ::require(false);
- }
- }
- return true;
-}
-
-extern int g_print_full_config;
-
-static bool
-saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
- const Properties * sec;
- if(!ctx.m_currentInfo->get(ctx.fname, &sec)){
- require(false);
- 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("SectionType", &typeVal));
-
- if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){
- ndbout_c("skipping section %s", ctx.fname);
- break;
- }
-
- if (g_print_full_config)
- {
- const char *alias= ConfigInfo::nameToAlias(ctx.fname);
- printf("[%s]\n", alias ? alias : ctx.fname);
- }
-
- 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;
-
- 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);
- if (g_print_full_config)
- printf("%s=%u\n", n, val);
- break;
- }
- case PropertiesType_Uint64:{
- Uint64 val;
- require(ctx.m_currentSection->get(n, &val));
- ok = ctx.m_configValues.put64(id, val);
- if (g_print_full_config)
- printf("%s=%llu\n", n, val);
- break;
- }
- case PropertiesType_char:{
- const char * val;
- require(ctx.m_currentSection->get(n, &val));
- ok = ctx.m_configValues.put(id, val);
- if (g_print_full_config)
- printf("%s=%s\n", n, val);
- break;
- }
- default:
- require(false);
- }
- require(ok);
- }
- ctx.m_configValues.closeSection();
- } while(0);
- return true;
-}
-
-static bool
-sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data)
-{
- Uint32 db_nodes = 0;
- Uint32 mgm_nodes = 0;
- Uint32 api_nodes = 0;
- if (!ctx.m_userProperties.get("DB", &db_nodes)) {
- ctx.reportError("At least one database node (ndbd) should be defined in config file");
- return false;
- }
- if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) {
- ctx.reportError("At least one management server node (ndb_mgmd) should be defined in config file");
- return false;
- }
- if (!ctx.m_userProperties.get("API", &api_nodes)) {
- ctx.reportError("At least one application node (for the mysqld) should be defined in config file");
- return false;
- }
- return true;
-}
-
-static void
-add_a_connection(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- Uint32 nodeId1, Uint32 nodeId2, bool use_shm)
-{
- ConfigInfo::ConfigRuleSection s;
- const char *hostname1= 0, *hostname2= 0;
- const Properties *tmp;
-
- require(ctx.m_config->get("Node", nodeId1, &tmp));
- tmp->get("HostName", &hostname1);
-
- require(ctx.m_config->get("Node", nodeId2, &tmp));
- tmp->get("HostName", &hostname2);
-
- char buf[16];
- s.m_sectionData= new Properties(true);
- BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1);
- s.m_sectionData->put("NodeId1", buf);
- BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2);
- s.m_sectionData->put("NodeId2", buf);
-
- if (use_shm &&
- hostname1 && hostname1[0] &&
- hostname2 && hostname2[0] &&
- strcmp(hostname1,hostname2) == 0)
- {
- s.m_sectionType= BaseString("SHM");
- DBUG_PRINT("info",("adding SHM connection %d %d",nodeId1,nodeId2));
- }
- else
- {
- s.m_sectionType= BaseString("TCP");
- DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2));
- }
-
- sections.push_back(s);
-}
-
-static bool
-add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data)
-{
- DBUG_ENTER("add_node_connections");
- Uint32 i;
- Properties * props= ctx.m_config;
- Properties p_connections(true);
- Properties p_connections2(true);
-
- for (i = 0;; i++){
- const Properties * tmp;
- Uint32 nodeId1, nodeId2;
-
- if(!props->get("Connection", i, &tmp)) break;
-
- if(!tmp->get("NodeId1", &nodeId1)) continue;
- p_connections.put("", nodeId1, nodeId1);
- if(!tmp->get("NodeId2", &nodeId2)) continue;
- p_connections.put("", nodeId2, nodeId2);
-
- p_connections2.put("", nodeId1 + nodeId2<<16, nodeId1);
- p_connections2.put("", nodeId2 + nodeId1<<16, nodeId2);
- }
-
- Uint32 nNodes;
- ctx.m_userProperties.get("NoOfNodes", &nNodes);
-
- Properties p_db_nodes(true);
- Properties p_api_nodes(true);
- Properties p_mgm_nodes(true);
-
- Uint32 i_db= 0, i_api= 0, i_mgm= 0, n;
- for (i= 0, n= 0; n < nNodes; i++){
- const Properties * tmp;
- if(!props->get("Node", i, &tmp)) continue;
- n++;
-
- const char * type;
- if(!tmp->get("Type", &type)) continue;
-
- if (strcmp(type,DB_TOKEN) == 0)
- p_db_nodes.put("", i_db++, i);
- else if (strcmp(type,API_TOKEN) == 0)
- p_api_nodes.put("", i_api++, i);
- else if (strcmp(type,MGM_TOKEN) == 0)
- p_mgm_nodes.put("", i_mgm++, i);
- }
-
- Uint32 nodeId1, nodeId2, dummy;
-
- for (i= 0; p_db_nodes.get("", i, &nodeId1); i++){
- for (Uint32 j= i+1;; j++){
- if(!p_db_nodes.get("", j, &nodeId2)) break;
- if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) {
- add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm);
- }
- }
- }
-
- for (i= 0; p_api_nodes.get("", i, &nodeId1); i++){
- if(!p_connections.get("", nodeId1, &dummy)) {
- for (Uint32 j= 0;; j++){
- if(!p_db_nodes.get("", j, &nodeId2)) break;
- add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm);
- }
- }
- }
-
- for (i= 0; p_mgm_nodes.get("", i, &nodeId1); i++){
- if(!p_connections.get("", nodeId1, &dummy)) {
- for (Uint32 j= 0;; j++){
- if(!p_db_nodes.get("", j, &nodeId2)) break;
- add_a_connection(sections,ctx,nodeId1,nodeId2,0);
- }
- }
- }
-
- DBUG_RETURN(true);
-}
-
-static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data)
-{
- DBUG_ENTER("set_connection_priorities");
- DBUG_RETURN(true);
-}
-
-static bool
-check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
- struct InitConfigFileParser::Context &ctx,
- const char * rule_data)
-{
- Uint32 db_nodes= 0;
- Uint32 replicas= 0;
- Uint32 db_host_count= 0;
- bool with_arbitration_rank= false;
- ctx.m_userProperties.get(DB_TOKEN, &db_nodes);
- ctx.m_userProperties.get("NoOfReplicas", &replicas);
- if((db_nodes % replicas) != 0){
- ctx.reportError("Invalid no of db nodes wrt no of replicas.\n"
- "No of nodes must be dividable with no or replicas");
- return false;
- }
- // check that node groups and arbitrators are ok
- // just issue warning if not
- if(replicas > 1){
- Properties * props= ctx.m_config;
- Properties p_db_hosts(true); // store hosts which db nodes run on
- Properties p_arbitrators(true); // store hosts which arbitrators run on
- // arbitrator should not run together with db node on same host
- Uint32 i, n, group= 0, i_group= 0;
- Uint32 n_nodes;
- BaseString node_group_warning, arbitration_warning;
- const char *arbit_warn_fmt=
- "\n arbitrator with id %d and db node with id %d on same host %s";
- const char *arbit_warn_fmt2=
- "\n arbitrator with id %d has no hostname specified";
-
- ctx.m_userProperties.get("NoOfNodes", &n_nodes);
- for (i= 0, n= 0; n < n_nodes; i++){
- const Properties * tmp;
- if(!props->get("Node", i, &tmp)) continue;
- n++;
-
- const char * type;
- if(!tmp->get("Type", &type)) continue;
-
- const char* host= 0;
- tmp->get("HostName", &host);
-
- if (strcmp(type,DB_TOKEN) == 0)
- {
- {
- Uint32 ii;
- if (!p_db_hosts.get(host,&ii))
- db_host_count++;
- p_db_hosts.put(host,i);
- if (p_arbitrators.get(host,&ii))
- {
- arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host);
- p_arbitrators.remove(host); // only one warning per db node
- }
- }
- {
- unsigned j;
- BaseString str, str2;
- str.assfmt("#group%d_",group);
- p_db_hosts.put(str.c_str(),i_group,host);
- str2.assfmt("##group%d_",group);
- p_db_hosts.put(str2.c_str(),i_group,i);
- for (j= 0; j < i_group; j++)
- {
- const char *other_host;
- p_db_hosts.get(str.c_str(),j,&other_host);
- if (strcmp(host,other_host) == 0) {
- unsigned int other_i, c= 0;
- p_db_hosts.get(str2.c_str(),j,&other_i);
- p_db_hosts.get(str.c_str(),&c);
- if (c == 0) // first warning in this node group
- node_group_warning.appfmt(" Node group %d", group);
- c|= 1 << j;
- p_db_hosts.put(str.c_str(),c);
- node_group_warning.appfmt(",\n db node with id %d and id %d "
- "on same host %s", other_i, i, host);
- }
- }
- i_group++;
- DBUG_ASSERT(i_group <= replicas);
- if (i_group == replicas)
- {
- unsigned c= 0;
- p_db_hosts.get(str.c_str(),&c);
- if (c+1 == (1u << (replicas-1))) // all nodes on same machine
- node_group_warning.append(".\n Host failure will "
- "cause complete cluster shutdown.");
- else if (c > 0)
- node_group_warning.append(".\n Host failure may "
- "cause complete cluster shutdown.");
- group++;
- i_group= 0;
- }
- }
- }
- else if (strcmp(type,API_TOKEN) == 0 ||
- strcmp(type,MGM_TOKEN) == 0)
- {
- Uint32 rank;
- if(tmp->get("ArbitrationRank", &rank) && rank > 0)
- {
- with_arbitration_rank = true; //check whether MGM or API node configured with rank >0
- if(host && host[0] != 0)
- {
- Uint32 ii;
- p_arbitrators.put(host,i);
- if (p_db_hosts.get(host,&ii))
- {
- arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
- }
- }
- else
- {
- arbitration_warning.appfmt(arbit_warn_fmt2, i);
- }
- }
- }
- }
- if (db_host_count > 1 && node_group_warning.length() > 0)
- ctx.reportWarning("Cluster configuration warning:\n%s",node_group_warning.c_str());
- if (!with_arbitration_rank)
- {
- ctx.reportWarning("Cluster configuration warning:"
- "\n Neither %s nor %s nodes are configured with arbitrator,"
- "\n may cause complete cluster shutdown in case of host failure.",
- MGM_TOKEN, API_TOKEN);
- }
- if (db_host_count > 1 && arbitration_warning.length() > 0)
- ctx.reportWarning("Cluster configuration warning:%s%s",arbitration_warning.c_str(),
- "\n Running arbitrator on the same host as a database node may"
- "\n cause complete cluster shutdown in case of host failure.");
- }
- return true;
-}
-
-template class Vector<ConfigInfo::ConfigRuleSection>;
-#endif /* NDB_MGMAPI */
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.hpp b/storage/ndb/src/mgmsrv/ConfigInfo.hpp
deleted file mode 100644
index e1ecb7d7965..00000000000
--- a/storage/ndb/src/mgmsrv/ConfigInfo.hpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ConfigInfo_H
-#define ConfigInfo_H
-
-#ifndef NDB_MGMAPI
-#include <kernel_types.h>
-#include <Properties.hpp>
-#include <ndb_limits.h>
-#include <NdbOut.hpp>
-#include "InitConfigFileParser.hpp"
-#endif /* NDB_MGMAPI */
-
-/**
- * A MANDATORY parameters must be specified in the config file
- * An UNDEFINED parameter may or may not be specified in the config file
- */
-
-// Default value for mandatory params.
-#define MANDATORY ((char*)~(UintPtr)0)
-// Default value for undefined params.
-#define UNDEFINED ((char*) 0)
-
-/**
- * @class ConfigInfo
- * @brief Metainformation about ALL cluster configuration parameters
- *
- * Use the getters to find out metainformation about parameters.
- */
-class ConfigInfo {
-public:
- enum Type { CI_BOOL, CI_INT, CI_INT64, CI_STRING, CI_SECTION };
- enum Status { CI_USED, ///< Active
- CI_DEPRICATED, ///< Can be, but shouldn't
- CI_NOTIMPLEMENTED, ///< Is ignored.
- CI_INTERNAL ///< Not configurable by the user
- };
-
- /**
- * Entry for one configuration parameter
- */
- struct ParamInfo {
- Uint32 _paramId;
- const char* _fname;
- const char* _section;
- const char* _description;
- Status _status;
- bool _updateable;
- Type _type;
- const char* _default;
- const char* _min;
- const char* _max;
- };
-
-#ifndef NDB_MGMAPI
- struct AliasPair{
- const char * name;
- const char * alias;
- };
-
- /**
- * Entry for one section rule
- */
- struct SectionRule {
- const char * m_section;
- bool (* m_sectionRule)(struct InitConfigFileParser::Context &,
- const char * m_ruleData);
- const char * m_ruleData;
- };
-
- /**
- * Entry for config rule
- */
- struct ConfigRuleSection {
- BaseString m_sectionType;
- Properties * m_sectionData;
- };
-
- struct ConfigRule {
- bool (* m_configRule)(Vector<ConfigRuleSection>&,
- struct InitConfigFileParser::Context &,
- const char * m_ruleData);
- const char * m_ruleData;
- };
-
- ConfigInfo();
-
- /**
- * Checks if the suggested value is valid for the suggested parameter
- * (i.e. if it is >= than min and <= than max).
- *
- * @param section Init Config file section name
- * @param fname Name of parameter
- * @param value Value to check
- * @return true if parameter value is valid.
- *
- * @note Result is not defined if section/name are wrong!
- */
- bool verify(const Properties* secti, const char* fname, Uint64 value) const;
- static const char* nameToAlias(const char*);
- static const char* getAlias(const char*);
- bool isSection(const char*) 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;
- 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;
-
- void print() const;
- void print(const char* section) const;
- void print(const Properties * section, const char* parameter) const;
-
-private:
- Properties m_info;
- Properties m_systemDefaults;
-
- static const AliasPair m_sectionNameAliases[];
- static const char* m_sectionNames[];
- static const int m_noOfSectionNames;
-#endif /* NDB_MGMAPI */
-
-public:
- static const ParamInfo m_ParamInfo[];
- static const int m_NoOfParams;
-
-#ifndef NDB_MGMAPI
- static const SectionRule m_SectionRules[];
- static const ConfigRule m_ConfigRules[];
- static const int m_NoOfRules;
-#endif /* NDB_MGMAPI */
-};
-
-#endif // ConfigInfo_H
diff --git a/storage/ndb/src/mgmsrv/ERROR_codes.txt b/storage/ndb/src/mgmsrv/ERROR_codes.txt
deleted file mode 100644
index 44a6047c05e..00000000000
--- a/storage/ndb/src/mgmsrv/ERROR_codes.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Next Session 10
-Next Global 10001
-
-
-#define MGM_ERROR_MAX_INJECT_SESSION_ONLY 10000
-Errors < 10000 are per-session only - in MgmApiSession.
-
-Others are for the whole mgm server.
-
-Error 0 is no error
-
-TIMEOUTS
---------
-
-num where type testing
-
-1 get config sleep begin
-2 get config sleep middle parsable
-3 get config mangle halfway through encoded properties
-
-4 end session sleep before reply
-
-5 node status sleep before reply
-6 node status sleep during parsable reply
-7 node status sleep after parsable, before status reply
-8 node status sleep partway through status reporting
-9 node status sleep end of status printing
-
-10000 events PING no ping don't send pings to event listeners
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
deleted file mode 100644
index c44cb37880a..00000000000
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ /dev/null
@@ -1,953 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-#include "InitConfigFileParser.hpp"
-#include "Config.hpp"
-#include "MgmtErrorReporter.hpp"
-#include <NdbOut.hpp>
-#include "ConfigInfo.hpp"
-#include <m_string.h>
-
-const int MAX_LINE_LENGTH = 1024; // Max length of line of text in config file
-static void trim(char *);
-
-static void require(bool v) { if(!v) abort();}
-
-//****************************************************************************
-// Ctor / Dtor
-//****************************************************************************
-InitConfigFileParser::InitConfigFileParser(FILE * out)
-{
- m_info = new ConfigInfo();
- m_errstream = out ? out : stdout;
-}
-
-InitConfigFileParser::~InitConfigFileParser() {
- delete m_info;
-}
-
-//****************************************************************************
-// Read Config File
-//****************************************************************************
-InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out)
- : m_userProperties(true), m_configValues(1000, 20) {
-
- m_config = new Properties(true);
- m_defaults = new Properties(true);
- m_errstream = out;
-}
-
-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){
- fprintf(m_errstream, "Error opening file: %s\n", filename);
- return 0;
- }
-
- Config * ret = parseConfig(file);
- fclose(file);
- return ret;
-}
-
-Config *
-InitConfigFileParser::parseConfig(FILE * file) {
-
- char line[MAX_LINE_LENGTH];
-
- Context ctx(m_info, m_errstream);
- ctx.m_lineno = 0;
- ctx.m_currentSection = 0;
-
- /*************
- * Open file *
- *************/
- if (file == NULL) {
- return 0;
- }
-
- /***********************
- * While lines to read *
- ***********************/
- while (fgets(line, MAX_LINE_LENGTH, file)) {
- ctx.m_lineno++;
-
- trim(line);
-
- if (isEmptyLine(line)) // Skip if line is empty or comment
- continue;
-
- // End with NULL instead of newline
- if (line[strlen(line)-1] == '\n')
- line[strlen(line)-1] = '\0';
-
- /********************************
- * 1. Parse new default section *
- ********************************/
- if (char* section = parseDefaultSectionHeader(line)) {
- if(!storeSection(ctx)){
- free(section);
- ctx.reportError("Could not store previous default section "
- "of configuration file.");
- return 0;
- }
- BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section); free(section);
- ctx.type = InitConfigFileParser::DefaultSection;
- ctx.m_sectionLineno = ctx.m_lineno;
- ctx.m_currentSection = new Properties(true);
- ctx.m_userDefaults = NULL;
- require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
- require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
- continue;
- }
-
- /************************
- * 2. Parse new section *
- ************************/
- if (char* section = parseSectionHeader(line)) {
- if(!storeSection(ctx)){
- free(section);
- ctx.reportError("Could not store previous section "
- "of configuration file.");
- return 0;
- }
- BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section);
- free(section);
- ctx.type = InitConfigFileParser::Section;
- ctx.m_sectionLineno = ctx.m_lineno;
- ctx.m_currentSection = new Properties(true);
- ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
- require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
- require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
- continue;
- }
-
- /****************************
- * 3. Parse name-value pair *
- ****************************/
- if (!parseNameValuePair(ctx, line)) {
- ctx.reportError("Could not parse name-value pair in config file.");
- 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 0;
- }
-
- return run_config_rules(ctx);
-}
-
-Config*
-InitConfigFileParser::run_config_rules(Context& ctx)
-{
- for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){
- ctx.type = InitConfigFileParser::Undefined;
- ctx.m_currentSection = 0;
- ctx.m_userDefaults = 0;
- ctx.m_currentInfo = 0;
- ctx.m_systemDefaults = 0;
-
- Vector<ConfigInfo::ConfigRuleSection> tmp;
- if(!(* ConfigInfo::m_ConfigRules[i].m_configRule)(tmp, ctx,
- ConfigInfo::m_ConfigRules[i].m_ruleData))
- return 0;
-
- for(size_t j = 0; j<tmp.size(); j++){
- BaseString::snprintf(ctx.fname, sizeof(ctx.fname), tmp[j].m_sectionType.c_str());
- ctx.type = InitConfigFileParser::Section;
- ctx.m_currentSection = tmp[j].m_sectionData;
- ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
- require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
- require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
- if(!storeSection(ctx))
- return 0;
- }
- }
-
- Uint32 nConnections = 0;
- Uint32 nComputers = 0;
- Uint32 nNodes = 0;
- Uint32 nExtConnections = 0;
- const char * system = "?";
- ctx.m_userProperties.get("NoOfConnections", &nConnections);
- ctx.m_userProperties.get("NoOfComputers", &nComputers);
- ctx.m_userProperties.get("NoOfNodes", &nNodes);
- ctx.m_userProperties.get("ExtNoOfConnections", &nExtConnections);
- ctx.m_userProperties.get("ExtSystem", &system);
- ctx.m_config->put("NoOfConnections", nConnections);
- ctx.m_config->put("NoOfComputers", nComputers);
- ctx.m_config->put("NoOfNodes", nNodes);
-
- char tmpLine[MAX_LINE_LENGTH];
- BaseString::snprintf(tmpLine, MAX_LINE_LENGTH,
- "EXTERNAL SYSTEM_%s:NoOfConnections", system);
- ctx.m_config->put(tmpLine, nExtConnections);
-
- 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;
-}
-
-//****************************************************************************
-// Parse Name-Value Pair
-//****************************************************************************
-
-bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
-{
- if (ctx.m_currentSection == NULL){
- ctx.reportError("Value specified outside section");
- return false;
- }
-
- // *************************************
- // Split string at first occurrence of
- // '=' or ':'
- // *************************************
-
- Vector<BaseString> tmp_string_split;
- if (BaseString(line).split(tmp_string_split,
- "=:", 2) != 2)
- {
- ctx.reportError("Parse error");
- return false;
- }
-
- // *************************************
- // Remove all after #
- // *************************************
-
- Vector<BaseString> tmp_string_split2;
- tmp_string_split[1].split(tmp_string_split2,
- "#", 2);
- tmp_string_split[1]=tmp_string_split2[0];
-
- // *************************************
- // Remove leading and trailing chars
- // *************************************
- {
- for (int i = 0; i < 2; i++)
- tmp_string_split[i].trim("\r\n \t");
- }
-
- // *************************************
- // First in split is fname
- // *************************************
-
- const char *fname= tmp_string_split[0].c_str();
-
- if (!ctx.m_currentInfo->contains(fname)) {
- ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname);
- return false;
- }
- ConfigInfo::Status status = m_info->getStatus(ctx.m_currentInfo, fname);
- if (status == ConfigInfo::CI_NOTIMPLEMENTED) {
- ctx.reportWarning("[%s] %s not yet implemented", ctx.fname, fname);
- }
- if (status == ConfigInfo::CI_DEPRICATED) {
- const char * desc = m_info->getDescription(ctx.m_currentInfo, fname);
- if(desc && desc[0]){
- ctx.reportWarning("[%s] %s is depricated, use %s instead",
- ctx.fname, fname, desc);
- } else if (desc == 0){
- ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname);
- }
- }
-
- // ***********************
- // Store name-value pair
- // ***********************
-
- return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str());
-}
-
-
-//****************************************************************************
-// STORE NAME-VALUE pair in properties section
-//****************************************************************************
-
-bool
-InitConfigFileParser::storeNameValuePair(Context& ctx,
- const char* fname,
- const char* value) {
-
- const char * pname = fname;
-
- if (ctx.m_currentSection->contains(pname)) {
- ctx.reportError("[%s] Parameter %s specified twice", ctx.fname, fname);
- return false;
- }
-
- // ***********************
- // Store name-value pair
- // ***********************
-
- const ConfigInfo::Type type = m_info->getType(ctx.m_currentInfo, fname);
- switch(type){
- case ConfigInfo::CI_BOOL: {
- bool value_bool;
- if (!convertStringToBool(value, value_bool)) {
- ctx.reportError("Illegal boolean value for parameter %s", fname);
- return false;
- }
- MGM_REQUIRE(ctx.m_currentSection->put(pname, value_bool));
- break;
- }
- case ConfigInfo::CI_INT:
- case ConfigInfo::CI_INT64:{
- Uint64 value_int;
- if (!convertStringToUint64(value, value_int)) {
- ctx.reportError("Illegal integer value for parameter %s", fname);
- return false;
- }
- if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) {
- ctx.reportError("Illegal value %s for parameter %s.\n"
- "Legal values are between %Lu and %Lu", value, fname,
- m_info->getMin(ctx.m_currentInfo, fname),
- m_info->getMax(ctx.m_currentInfo, fname));
- return false;
- }
- if(type == ConfigInfo::CI_INT){
- MGM_REQUIRE(ctx.m_currentSection->put(pname, (Uint32)value_int));
- } else {
- MGM_REQUIRE(ctx.m_currentSection->put64(pname, value_int));
- }
- break;
- }
- case ConfigInfo::CI_STRING:
- MGM_REQUIRE(ctx.m_currentSection->put(pname, value));
- break;
- case ConfigInfo::CI_SECTION:
- abort();
- }
- return true;
-}
-
-//****************************************************************************
-// Is Empty Line
-//****************************************************************************
-
-bool InitConfigFileParser::isEmptyLine(const char* line) const {
- int i;
-
- // Check if it is a comment line
- if (line[0] == '#') return true;
-
- // Check if it is a line with only spaces
- for (i = 0; i < MAX_LINE_LENGTH && line[i] != '\n' && line[i] != '\0'; i++) {
- if (line[i] != ' ' && line[i] != '\t') return false;
- }
- return true;
-}
-
-//****************************************************************************
-// Convert String to Int
-//****************************************************************************
-bool InitConfigFileParser::convertStringToUint64(const char* s,
- Uint64& val,
- Uint32 log10base) {
- if (s == NULL)
- return false;
- if (strlen(s) == 0)
- return false;
-
- errno = 0;
- char* p;
- Int64 v = strtoll(s, &p, log10base);
- if (errno != 0)
- return false;
-
- long mul = 0;
- if (p != &s[strlen(s)]){
- char * tmp = strdup(p);
- trim(tmp);
- switch(tmp[0]){
- case 'k':
- case 'K':
- mul = 10;
- break;
- case 'M':
- mul = 20;
- break;
- case 'G':
- mul = 30;
- break;
- default:
- free(tmp);
- return false;
- }
- free(tmp);
- }
-
- val = (v << mul);
- return true;
-}
-
-bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) {
- if (s == NULL) return false;
- if (strlen(s) == 0) return false;
-
- 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, "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, "0")) {
- val = false;
- return true;
- }
-
- return false; // Failure to convert
-}
-
-//****************************************************************************
-// Parse Section Header
-//****************************************************************************
-static void
-trim(char * str){
- int len = strlen(str);
- for(len--;
- (str[len] == '\r' || str[len] == '\n' ||
- str[len] == ' ' || str[len] == '\t') &&
- len > 0;
- len--)
- str[len] = 0;
-
- int pos = 0;
- while(str[pos] == ' ' || str[pos] == '\t')
- pos++;
-
- if(str[pos] == '\"' && str[len] == '\"') {
- pos++;
- str[len] = 0;
- len--;
- }
-
- memmove(str, &str[pos], len - pos + 2);
-}
-
-char*
-InitConfigFileParser::parseSectionHeader(const char* line) const {
- char * tmp = strdup(line);
-
- if(tmp[0] != '['){
- free(tmp);
- return NULL;
- }
-
- if(tmp[strlen(tmp)-1] != ']'){
- free(tmp);
- return NULL;
- }
- tmp[strlen(tmp)-1] = 0;
-
- tmp[0] = ' ';
- trim(tmp);
-
- // Get the correct header name if an alias
- {
- const char *tmp_alias= m_info->getAlias(tmp);
- if (tmp_alias) {
- free(tmp);
- tmp= strdup(tmp_alias);
- }
- }
-
- // Lookup token among sections
- if(!m_info->isSection(tmp)) {
- free(tmp);
- return NULL;
- }
- if(m_info->getInfo(tmp)) return tmp;
-
- free(tmp);
- return NULL;
-}
-
-//****************************************************************************
-// Parse Default Section Header
-//****************************************************************************
-
-char*
-InitConfigFileParser::parseDefaultSectionHeader(const char* line) const {
- static char token1[MAX_LINE_LENGTH], token2[MAX_LINE_LENGTH];
-
- int no = sscanf(line, "[%120[A-Z_a-z] %120[A-Z_a-z]]", token1, token2);
-
- // Not correct no of tokens
- if (no != 2) return NULL;
-
- // Not correct keyword at end
- if (!strcasecmp(token2, "DEFAULT") == 0) return NULL;
-
- const char *token1_alias= m_info->getAlias(token1);
- if (token1_alias == 0)
- token1_alias= token1;
-
- if(m_info->getInfo(token1_alias)){
- return strdup(token1_alias);
- }
-
- // Did not find section
- return NULL;
-}
-
-const Properties *
-InitConfigFileParser::getSection(const char * name, const Properties * src){
- const Properties * p;
- if(src && src->get(name, &p))
- return p;
-
- return 0;
-}
-
-//****************************************************************************
-// STORE section
-//****************************************************************************
-bool
-InitConfigFileParser::storeSection(Context& ctx){
- if(ctx.m_currentSection == NULL)
- return true;
- for(int i = strlen(ctx.fname) - 1; i>=0; i--){
- ctx.fname[i] = toupper(ctx.fname[i]);
- }
- BaseString::snprintf(ctx.pname, sizeof(ctx.pname), ctx.fname);
- char buf[255];
- if(ctx.type == InitConfigFileParser::Section)
- BaseString::snprintf(buf, sizeof(buf), "%s", ctx.fname);
- if(ctx.type == InitConfigFileParser::DefaultSection)
- BaseString::snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname);
- BaseString::snprintf(ctx.fname, sizeof(ctx.fname), buf);
- 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 &&
- !ctx.m_defaults->put(ctx.pname, ctx.m_currentSection))
- {
- ctx.reportError("Duplicate default section not allowed");
- return false;
- }
- if(ctx.type == InitConfigFileParser::Section)
- require(ctx.m_config->put(ctx.pname, ctx.m_currentSection));
- delete ctx.m_currentSection; ctx.m_currentSection = NULL;
- return true;
-}
-
-void
-InitConfigFileParser::Context::reportError(const char * fmt, ...){
- va_list ap;
- char buf[1000];
-
- va_start(ap, fmt);
- if (fmt != 0)
- BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- va_end(ap);
- fprintf(m_errstream, "Error line %d: %s\n",
- m_lineno, buf);
-
- //m_currentSection->print();
-}
-
-void
-InitConfigFileParser::Context::reportWarning(const char * fmt, ...){
- va_list ap;
- char buf[1000];
-
- va_start(ap, fmt);
- if (fmt != 0)
- BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- va_end(ap);
- fprintf(m_errstream, "Warning line %d: %s\n",
- m_lineno, buf);
-}
-
-#include <my_sys.h>
-#include <my_getopt.h>
-
-static int order = 1;
-static
-my_bool
-parse_mycnf_opt(int, const struct my_option * opt, char * value)
-{
- long *app_type= (long*) &opt->app_type;
- if(opt->comment)
- (*app_type)++;
- else
- *app_type = order++;
- return 0;
-}
-
-bool
-InitConfigFileParser::store_in_properties(Vector<struct my_option>& options,
- InitConfigFileParser::Context& ctx,
- const char * name)
-{
- for(unsigned i = 0; i<options.size(); i++)
- {
- if(options[i].comment &&
- options[i].app_type &&
- strcmp(options[i].comment, name) == 0)
- {
- Uint64 value_int;
- switch(options[i].var_type){
- case GET_INT:
- value_int = *(Uint32*)options[i].value;
- break;
- case GET_LL:
- value_int = *(Uint64*)options[i].value;
- break;
- case GET_STR:
- ctx.m_currentSection->put(options[i].name, *(char**)options[i].value);
- continue;
- default:
- abort();
- }
-
- const char * fname = options[i].name;
- if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) {
- ctx.reportError("Illegal value %lld for parameter %s.\n"
- "Legal values are between %Lu and %Lu",
- value_int, fname,
- m_info->getMin(ctx.m_currentInfo, fname),
- m_info->getMax(ctx.m_currentInfo, fname));
- return false;
- }
-
- ConfigInfo::Status status = m_info->getStatus(ctx.m_currentInfo, fname);
- if (status == ConfigInfo::CI_DEPRICATED) {
- const char * desc = m_info->getDescription(ctx.m_currentInfo, fname);
- if(desc && desc[0]){
- ctx.reportWarning("[%s] %s is depricated, use %s instead",
- ctx.fname, fname, desc);
- } else if (desc == 0){
- ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname);
- }
- }
-
- if (options[i].var_type == GET_INT)
- ctx.m_currentSection->put(options[i].name, (Uint32)value_int);
- else
- ctx.m_currentSection->put64(options[i].name, value_int);
- }
- }
- return true;
-}
-
-bool
-InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options,
- InitConfigFileParser::Context& ctx,
- const char * name)
-{
- strcpy(ctx.fname, name);
- ctx.type = InitConfigFileParser::DefaultSection;
- ctx.m_currentSection = new Properties(true);
- ctx.m_userDefaults = NULL;
- require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
- require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
- if(store_in_properties(options, ctx, name))
- return storeSection(ctx);
- return false;
-}
-
-static
-int
-load_defaults(Vector<struct my_option>& options, const char* groups[])
-{
- int argc = 1;
- const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 };
- BaseString file;
- BaseString extra_file;
- BaseString group_suffix;
-
- const char *save_file = my_defaults_file;
- const char *save_extra_file = my_defaults_extra_file;
- const char *save_group_suffix = my_defaults_group_suffix;
-
- if (my_defaults_file)
- {
- file.assfmt("--defaults-file=%s", my_defaults_file);
- argv[argc++] = file.c_str();
- }
-
- if (my_defaults_extra_file)
- {
- extra_file.assfmt("--defaults-extra-file=%s", my_defaults_extra_file);
- argv[argc++] = extra_file.c_str();
- }
-
- if (my_defaults_group_suffix)
- {
- group_suffix.assfmt("--defaults-group-suffix=%s",
- my_defaults_group_suffix);
- argv[argc++] = group_suffix.c_str();
- }
-
- char ** tmp = (char**)argv;
- int ret = load_defaults("my", groups, &argc, &tmp);
-
- my_defaults_file = save_file;
- my_defaults_extra_file = save_extra_file;
- my_defaults_group_suffix = save_group_suffix;
-
- if (ret == 0)
- {
- return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt);
- }
-
- return ret;
-}
-
-bool
-InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options,
- InitConfigFileParser::Context& ctx,
- const char * name,
- const char *groups[])
-{
- unsigned i;
- Vector<struct my_option> copy;
- for(i = 0; i<options.size(); i++)
- {
- if(options[i].comment && strcmp(options[i].comment, name) == 0)
- {
- options[i].app_type = 0;
- copy.push_back(options[i]);
- }
- }
-
- struct my_option end;
- bzero(&end, sizeof(end));
- copy.push_back(end);
-
- if (load_defaults(copy, groups))
- return false;
-
- return store_in_properties(copy, ctx, name);
-}
-
-Config *
-InitConfigFileParser::parse_mycnf()
-{
- int i;
- Config * res = 0;
- Vector<struct my_option> options;
- for(i = 0; i<ConfigInfo::m_NoOfParams; i++)
- {
- {
- struct my_option opt;
- bzero(&opt, sizeof(opt));
- const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i];
- switch(param._type){
- case ConfigInfo::CI_BOOL:
- opt.value = (uchar **)malloc(sizeof(int));
- opt.var_type = GET_INT;
- break;
- case ConfigInfo::CI_INT:
- opt.value = (uchar**)malloc(sizeof(int));
- opt.var_type = GET_INT;
- break;
- case ConfigInfo::CI_INT64:
- opt.value = (uchar**)malloc(sizeof(Int64));
- opt.var_type = GET_LL;
- break;
- case ConfigInfo::CI_STRING:
- opt.value = (uchar**)malloc(sizeof(char *));
- opt.var_type = GET_STR;
- break;
- default:
- continue;
- }
- opt.name = param._fname;
- opt.id = 256;
- opt.app_type = 0;
- opt.arg_type = REQUIRED_ARG;
- opt.comment = param._section;
- options.push_back(opt);
- }
- }
-
- struct my_option *ndbd, *ndb_mgmd, *mysqld, *api;
-
- /**
- * Add ndbd, ndb_mgmd, api/mysqld
- */
- Uint32 idx = options.size();
- {
- struct my_option opt;
- bzero(&opt, sizeof(opt));
- opt.name = "ndbd";
- opt.id = 256;
- opt.value = (uchar**)malloc(sizeof(char*));
- opt.var_type = GET_STR;
- opt.arg_type = REQUIRED_ARG;
- options.push_back(opt);
-
- opt.name = "ndb_mgmd";
- opt.id = 256;
- opt.value = (uchar**)malloc(sizeof(char*));
- opt.var_type = GET_STR;
- opt.arg_type = REQUIRED_ARG;
- options.push_back(opt);
-
- opt.name = "mysqld";
- opt.id = 256;
- opt.value = (uchar**)malloc(sizeof(char*));
- opt.var_type = GET_STR;
- opt.arg_type = REQUIRED_ARG;
- options.push_back(opt);
-
- opt.name = "ndbapi";
- opt.id = 256;
- opt.value = (uchar**)malloc(sizeof(char*));
- opt.var_type = GET_STR;
- opt.arg_type = REQUIRED_ARG;
- options.push_back(opt);
-
- bzero(&opt, sizeof(opt));
- options.push_back(opt);
-
- ndbd = &options[idx];
- ndb_mgmd = &options[idx+1];
- mysqld = &options[idx+2];
- api = &options[idx+3];
- }
-
- Context ctx(m_info, m_errstream);
- const char *groups[]= { "cluster_config", 0 };
- if (load_defaults(options, groups))
- goto end;
-
- ctx.m_lineno = 0;
- if(!handle_mycnf_defaults(options, ctx, "DB"))
- goto end;
- if(!handle_mycnf_defaults(options, ctx, "API"))
- goto end;
- if(!handle_mycnf_defaults(options, ctx, "MGM"))
- goto end;
- if(!handle_mycnf_defaults(options, ctx, "TCP"))
- goto end;
- if(!handle_mycnf_defaults(options, ctx, "SHM"))
- goto end;
- if(!handle_mycnf_defaults(options, ctx, "SCI"))
- goto end;
-
- {
- struct sect { struct my_option* src; const char * name; } sections[] =
- {
- { ndb_mgmd, "MGM" }
- ,{ ndbd, "DB" }
- ,{ mysqld, "API" }
- ,{ api, "API" }
- ,{ 0, 0 }, { 0, 0 }
- };
-
- for(i = 0; sections[i].src; i++)
- {
- for(int j = i + 1; sections[j].src; j++)
- {
- if (sections[j].src->app_type < sections[i].src->app_type)
- {
- sect swap = sections[i];
- sections[i] = sections[j];
- sections[j] = swap;
- }
- }
- }
-
- ctx.type = InitConfigFileParser::Section;
- ctx.m_sectionLineno = ctx.m_lineno;
- for(i = 0; sections[i].src; i++)
- {
- if (sections[i].src->app_type)
- {
- strcpy(ctx.fname, sections[i].name);
- BaseString str(*(char**)sections[i].src->value);
- Vector<BaseString> list;
- str.split(list, ",");
-
- const char * defaults_groups[] = { 0, 0, 0 };
- for(unsigned j = 0; j<list.size(); j++)
- {
- BaseString group_idx;
- BaseString group_host;
- group_idx.assfmt("%s.%s.%d", groups[0],
- sections[i].src->name, j + 1);
- group_host.assfmt("%s.%s.%s", groups[0],
- sections[i].src->name, list[j].c_str());
- defaults_groups[0] = group_idx.c_str();
- if(list[j].length())
- defaults_groups[1] = group_host.c_str();
- else
- defaults_groups[1] = 0;
-
- ctx.m_currentSection = new Properties(true);
- ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
- require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
- require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0);
- ctx.m_currentSection->put("HostName", list[j].c_str());
- if(!load_mycnf_groups(options, ctx, sections[i].name,
- defaults_groups))
- goto end;
-
- if(!storeSection(ctx))
- goto end;
- }
- }
- }
- }
-
- res = run_config_rules(ctx);
-
-end:
- for(i = 0; options[i].name; i++)
- free(options[i].value);
-
- return res;
-}
-
-template class Vector<struct my_option>;
-
-/*
- See include/my_getopt.h for the declaration of struct my_option
-*/
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
deleted file mode 100644
index 19ceafafda7..00000000000
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef InitConfigFileParser_H
-#define InitConfigFileParser_H
-
-#include <ndb_global.h>
-
-#include <Properties.hpp>
-#include <ConfigValues.hpp>
-
-class Config;
-class ConfigInfo;
-
-/**
- * @class InitConfigFileParser
- * @brief Reads initial config file and returns Config object
- *
- * 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 {
- FILE * m_errstream;
-public:
- /**
- * Constructor
- */
- InitConfigFileParser(FILE * errstream = stdout);
- ~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);
- Config * parse_mycnf();
-
- /**
- * Parser context struct
- */
- enum ContextSectionType { Undefined, Section, DefaultSection };
-
- /**
- * Context = Which section in init config file we are currently parsing
- */
- struct Context {
- Context(const ConfigInfo *, FILE * out);
- ~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
- Uint32 m_lineno; ///< Current line no in config file
- Uint32 m_sectionLineno; ///< Where did current section start
-
- const ConfigInfo * m_info; // The config info
- 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
- const Properties * m_systemDefaults; // The syst. defaults for this section
- const Properties * m_currentInfo; // The "info" for this section
-
- Properties m_userProperties; // User properties (temporary values)
- ConfigValuesFactory m_configValues; //
-
- public:
- FILE * m_errstream;
- void reportError(const char * msg, ...);
- void reportWarning(const char * msg, ...);
- };
-
- static bool convertStringToUint64(const char* s, Uint64& val, Uint32 log10base = 0);
- static bool convertStringToBool(const char* s, bool& val);
-
-private:
- /**
- * Check if line only contains space/comments
- * @param line: The line to check
- * @return true if spaces/comments only, false otherwise
- */
- bool isEmptyLine(const char* line) const;
-
- /**
- * Checks if line contains a section header
- * @param line: String to search
- * @return section header if matching some section header, NULL otherwise
- */
- char* parseSectionHeader(const char* line) const;
-
- /**
- * Checks if line contains a default header
- * @param line: String to search
- * @return section header if matching some section header, NULL otherwise
- */
- char* parseDefaultSectionHeader(const char* line) const;
-
- bool parseNameValuePair(Context&, const char* line);
- bool storeNameValuePair(Context&, const char* fname, const char* value);
-
- bool storeSection(Context&);
-
- const Properties* getSection(const char * name, const Properties* src);
-
- /**
- * Information about parameters (min, max values etc)
- */
- ConfigInfo* m_info;
-
- bool handle_mycnf_defaults(Vector<struct my_option>& options,
- InitConfigFileParser::Context& ctx,
- const char * name);
-
- bool load_mycnf_groups(Vector<struct my_option> & options,
- InitConfigFileParser::Context& ctx,
- const char * name,
- const char *groups[]);
-
- bool store_in_properties(Vector<struct my_option>& options,
- InitConfigFileParser::Context& ctx,
- const char * name);
-
- Config* run_config_rules(Context& ctx);
-};
-
-#endif // InitConfigFileParser_H
diff --git a/storage/ndb/src/mgmsrv/Makefile.am b/storage/ndb/src/mgmsrv/Makefile.am
deleted file mode 100644
index 48524061d66..00000000000
--- a/storage/ndb/src/mgmsrv/Makefile.am
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2004-2006 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-MYSQLDATAdir = $(localstatedir)
-MYSQLSHAREdir = $(pkgdatadir)
-MYSQLBASEdir= $(prefix)
-#MYSQLCLUSTERdir= $(prefix)/mysql-cluster
-MYSQLCLUSTERdir= .
-
-ndbbin_PROGRAMS = ndb_mgmd
-
-ndb_mgmd_SOURCES = \
- MgmtSrvr.cpp \
- MgmtSrvrGeneralSignalHandling.cpp \
- main.cpp \
- Services.cpp \
- convertStrToInt.cpp \
- SignalQueue.cpp \
- MgmtSrvrConfig.cpp \
- ConfigInfo.cpp \
- InitConfigFileParser.cpp \
- Config.cpp
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/ndbapi \
- -I$(top_srcdir)/storage/ndb/src/mgmapi \
- -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \
- -I$(top_srcdir)/storage/ndb/src/mgmclient
-
-LDADD_LOC = $(top_builddir)/storage/ndb/src/mgmclient/CommandInterpreter.lo \
- $(top_builddir)/storage/ndb/src/libndbclient.la \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a \
- @readline_link@ \
- @NDB_SCI_LIBS@ \
- @TERMCAP_LIB@
-
-DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
- -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\""
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-
-ndb_mgmd_LDFLAGS = @ndb_bin_am_ldflags@
-
-windoze-dsp: ndb_mgmd.dsp
-
-ndb_mgmd.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-prg.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
deleted file mode 100644
index 6a9377bdd73..00000000000
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ /dev/null
@@ -1,3017 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-
-#include "MgmtSrvr.hpp"
-#include "MgmtErrorReporter.hpp"
-#include "ndb_mgmd_error.h"
-#include <ConfigRetriever.hpp>
-
-#include <NdbOut.hpp>
-#include <NdbApiSignal.hpp>
-#include <kernel_types.h>
-#include <RefConvert.hpp>
-#include <BlockNumbers.h>
-#include <GlobalSignalNumbers.h>
-#include <signaldata/TestOrd.hpp>
-#include <signaldata/TamperOrd.hpp>
-#include <signaldata/StartOrd.hpp>
-#include <signaldata/ApiVersion.hpp>
-#include <signaldata/ResumeReq.hpp>
-#include <signaldata/SetLogLevelOrd.hpp>
-#include <signaldata/EventSubscribeReq.hpp>
-#include <signaldata/EventReport.hpp>
-#include <signaldata/DumpStateOrd.hpp>
-#include <signaldata/BackupSignalData.hpp>
-#include <signaldata/ManagementServer.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/AllocNodeId.hpp>
-#include <NdbSleep.h>
-#include <EventLogger.hpp>
-#include <DebuggerNames.hpp>
-#include <ndb_version.h>
-
-#include <SocketServer.hpp>
-#include <NdbConfig.h>
-
-#include <NdbAutoPtr.hpp>
-
-#include <ndberror.h>
-
-#include <mgmapi.h>
-#include <mgmapi_configuration.hpp>
-#include <mgmapi_config_parameters.h>
-#include <m_string.h>
-
-#include <SignalSender.hpp>
-
-//#define MGM_SRV_DEBUG
-#ifdef MGM_SRV_DEBUG
-#define DEBUG(x) do ndbout << x << endl; while(0)
-#else
-#define DEBUG(x)
-#endif
-
-int g_errorInsert;
-#define ERROR_INSERTED(x) (g_errorInsert == x)
-
-#define INIT_SIGNAL_SENDER(ss,nodeId) \
- SignalSender ss(theFacade); \
- ss.lock(); /* lock will be released on exit */ \
- {\
- int result = okToSendTo(nodeId, true);\
- if (result != 0) {\
- return result;\
- }\
- }
-
-extern int g_no_nodeid_checks;
-extern my_bool opt_core;
-
-static void require(bool v)
-{
- if(!v)
- {
- if (opt_core)
- abort();
- else
- exit(-1);
- }
-}
-
-void *
-MgmtSrvr::logLevelThread_C(void* m)
-{
- MgmtSrvr *mgm = (MgmtSrvr*)m;
- mgm->logLevelThreadRun();
- return 0;
-}
-
-extern EventLogger g_eventLogger;
-
-#ifdef NOT_USED
-static NdbOut&
-operator<<(NdbOut& out, const LogLevel & ll)
-{
- out << "[LogLevel: ";
- for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
- out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
- out << "]";
- return out;
-}
-#endif
-
-void
-MgmtSrvr::logLevelThreadRun()
-{
- while (!_isStopThread)
- {
- Vector<NodeId> failed_started_nodes;
- Vector<EventSubscribeReq> failed_log_level_requests;
-
- /**
- * Handle started nodes
- */
- m_started_nodes.lock();
- if (m_started_nodes.size() > 0)
- {
- // calculate max log level
- EventSubscribeReq req;
- {
- LogLevel tmp;
- m_event_listner.lock();
- for(int i = m_event_listner.m_clients.size() - 1; i >= 0; i--)
- tmp.set_max(m_event_listner[i].m_logLevel);
- m_event_listner.unlock();
- req = tmp;
- }
- req.blockRef = _ownReference;
- while (m_started_nodes.size() > 0)
- {
- Uint32 node = m_started_nodes[0];
- m_started_nodes.erase(0, false);
- m_started_nodes.unlock();
-
- if (setEventReportingLevelImpl(node, req))
- {
- failed_started_nodes.push_back(node);
- }
- else
- {
- SetLogLevelOrd ord;
- ord = m_nodeLogLevel[node];
- setNodeLogLevelImpl(node, ord);
- }
- m_started_nodes.lock();
- }
- }
- m_started_nodes.unlock();
-
- m_log_level_requests.lock();
- while (m_log_level_requests.size() > 0)
- {
- EventSubscribeReq req = m_log_level_requests[0];
- m_log_level_requests.erase(0, false);
- m_log_level_requests.unlock();
-
- if(req.blockRef == 0)
- {
- req.blockRef = _ownReference;
- if (setEventReportingLevelImpl(0, req))
- {
- failed_log_level_requests.push_back(req);
- }
- }
- else
- {
- SetLogLevelOrd ord;
- ord = req;
- if (setNodeLogLevelImpl(req.blockRef, ord))
- {
- failed_log_level_requests.push_back(req);
- }
- }
- m_log_level_requests.lock();
- }
- m_log_level_requests.unlock();
-
- if(!ERROR_INSERTED(10000))
- m_event_listner.check_listeners();
-
- Uint32 sleeptime = _logLevelThreadSleep;
- if (failed_started_nodes.size())
- {
- m_started_nodes.lock();
- for (Uint32 i = 0; i<failed_started_nodes.size(); i++)
- m_started_nodes.push_back(failed_started_nodes[i], false);
- m_started_nodes.unlock();
- failed_started_nodes.clear();
- sleeptime = 100;
- }
-
- if (failed_log_level_requests.size())
- {
- m_log_level_requests.lock();
- for (Uint32 i = 0; i<failed_log_level_requests.size(); i++)
- m_log_level_requests.push_back(failed_log_level_requests[i], false);
- m_log_level_requests.unlock();
- failed_log_level_requests.clear();
- sleeptime = 100;
- }
-
- NdbSleep_MilliSleep(sleeptime);
- }
-}
-
-void
-MgmtSrvr::startEventLog()
-{
- NdbMutex_Lock(m_configMutex);
-
- g_eventLogger.setCategory("MgmSrvr");
-
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
-
- if(iter.find(CFG_NODE_ID, _ownNodeId) != 0){
- NdbMutex_Unlock(m_configMutex);
- return;
- }
-
- const char * tmp;
- char errStr[100];
- int err= 0;
- BaseString logdest;
- char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId);
- NdbAutoPtr<char> tmp_aptr(clusterLog);
-
- if(iter.get(CFG_LOG_DESTINATION, &tmp) == 0){
- logdest.assign(tmp);
- }
- NdbMutex_Unlock(m_configMutex);
-
- if(logdest.length() == 0 || logdest == "") {
- logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
- clusterLog);
- }
- errStr[0]='\0';
- if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) {
- ndbout << "Warning: could not add log destination \""
- << logdest.c_str() << "\". Reason: ";
- if(err)
- ndbout << strerror(err);
- if(err && errStr[0]!='\0')
- ndbout << ", ";
- if(errStr[0]!='\0')
- ndbout << errStr;
- ndbout << endl;
- }
-}
-
-void
-MgmtSrvr::stopEventLog()
-{
- g_eventLogger.close();
-}
-
-bool
-MgmtSrvr::setEventLogFilter(int severity, int enable)
-{
- Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
- if (enable > 0) {
- g_eventLogger.enable(level);
- } else if (enable == 0) {
- g_eventLogger.disable(level);
- } else if (g_eventLogger.isEnable(level)) {
- g_eventLogger.disable(level);
- } else {
- g_eventLogger.enable(level);
- }
- return g_eventLogger.isEnable(level);
-}
-
-bool
-MgmtSrvr::isEventLogFilterEnabled(int severity)
-{
- return g_eventLogger.isEnable((Logger::LoggerLevel)severity);
-}
-
-int MgmtSrvr::translateStopRef(Uint32 errCode)
-{
- switch(errCode){
- case StopRef::NodeShutdownInProgress:
- return NODE_SHUTDOWN_IN_PROGESS;
- break;
- case StopRef::SystemShutdownInProgress:
- return SYSTEM_SHUTDOWN_IN_PROGRESS;
- break;
- case StopRef::NodeShutdownWouldCauseSystemCrash:
- return NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH;
- break;
- case StopRef::UnsupportedNodeShutdown:
- return UNSUPPORTED_NODE_SHUTDOWN;
- break;
- }
- return 4999;
-}
-
-int
-MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const
-{
- int count = 0;
- NodeId nodeId = 0;
-
- while (getNextNodeId(&nodeId, type)) {
- count++;
- }
- return count;
-}
-
-int
-MgmtSrvr::getPort() const
-{
- if(NdbMutex_Lock(m_configMutex))
- return 0;
-
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
-
- if(iter.find(CFG_NODE_ID, getOwnNodeId()) != 0){
- ndbout << "Could not retrieve configuration for Node "
- << getOwnNodeId() << " in config file." << endl
- << "Have you set correct NodeId for this node?" << endl;
- NdbMutex_Unlock(m_configMutex);
- return 0;
- }
-
- unsigned type;
- if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0 ||
- type != NODE_TYPE_MGM){
- ndbout << "Local node id " << getOwnNodeId()
- << " is not defined as management server" << endl
- << "Have you set correct NodeId for this node?" << endl;
- NdbMutex_Unlock(m_configMutex);
- return 0;
- }
-
- Uint32 port = 0;
- if(iter.get(CFG_MGM_PORT, &port) != 0){
- ndbout << "Could not find PortNumber in the configuration file." << endl;
- NdbMutex_Unlock(m_configMutex);
- return 0;
- }
-
- NdbMutex_Unlock(m_configMutex);
-
- return port;
-}
-
-/* Constructor */
-int MgmtSrvr::init()
-{
- if ( _ownNodeId > 0)
- return 0;
- return -1;
-}
-
-MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
- const char *config_filename,
- const char *connect_string) :
- _blockNumber(1), // Hard coded block number since it makes it easy to send
- // signals to other management servers.
- m_socket_server(socket_server),
- _ownReference(0),
- theSignalIdleList(NULL),
- theWaitState(WAIT_SUBSCRIBE_CONF),
- m_local_mgm_handle(0),
- m_event_listner(this),
- m_master_node(0)
-{
-
- DBUG_ENTER("MgmtSrvr::MgmtSrvr");
-
- _ownNodeId= 0;
-
- _config = NULL;
-
- _isStopThread = false;
- _logLevelThread = NULL;
- _logLevelThreadSleep = 500;
-
- theFacade = 0;
-
- m_newConfig = NULL;
- if (config_filename)
- m_configFilename.assign(config_filename);
-
- m_nextConfigGenerationNumber = 0;
-
- m_config_retriever= new ConfigRetriever(connect_string,
- NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
- // if connect_string explicitly given or
- // no config filename is given then
- // first try to allocate nodeid from another management server
- if ((connect_string || config_filename == NULL) &&
- (m_config_retriever->do_connect(0,0,0) == 0))
- {
- int tmp_nodeid= 0;
- tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
- if (tmp_nodeid == 0)
- {
- ndbout_c(m_config_retriever->getErrorString());
- require(false);
- }
- // read config from other managent server
- _config= fetchConfig();
- if (_config == 0)
- {
- ndbout << m_config_retriever->getErrorString() << endl;
- require(false);
- }
- _ownNodeId= tmp_nodeid;
- }
-
- if (_ownNodeId == 0)
- {
- // read config locally
- _config= readConfig();
- if (_config == 0) {
- if (config_filename != NULL)
- ndbout << "Invalid configuration file: " << config_filename << endl;
- else
- ndbout << "Invalid configuration file" << endl;
- exit(-1);
- }
- }
-
- theMgmtWaitForResponseCondPtr = NdbCondition_Create();
-
- m_configMutex = NdbMutex_Create();
-
- /**
- * Fill the nodeTypes array
- */
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- nodeTypes[i] = (enum ndb_mgm_node_type)-1;
- m_connect_address[i].s_addr= 0;
- }
-
- {
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
-
- for(iter.first(); iter.valid(); iter.next()){
- unsigned type, id;
- if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0)
- continue;
-
- if(iter.get(CFG_NODE_ID, &id) != 0)
- continue;
-
- MGM_REQUIRE(id < MAX_NODES);
-
- 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;
- default:
- break;
- }
- }
- }
-
- _props = NULL;
- BaseString error_string;
-
- if ((m_node_id_mutex = NdbMutex_Create()) == 0)
- {
- ndbout << "mutex creation failed line = " << __LINE__ << endl;
- require(false);
- }
-
- if (_ownNodeId == 0) // we did not get node id from other server
- {
- NodeId tmp= m_config_retriever->get_configuration_nodeid();
- int error_code;
-
- if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
- 0, 0, error_code, error_string)){
- ndbout << "Unable to obtain requested nodeid: "
- << error_string.c_str() << endl;
- require(false);
- }
- _ownNodeId = tmp;
- }
-
- {
- DBUG_PRINT("info", ("verifyConfig"));
- if (!m_config_retriever->verifyConfig(_config->m_configValues,
- _ownNodeId))
- {
- ndbout << m_config_retriever->getErrorString() << endl;
- require(false);
- }
- }
-
- // Setup clusterlog as client[0] in m_event_listner
- {
- Ndb_mgmd_event_service::Event_listener se;
- se.m_socket = NDB_INVALID_SOCKET;
- for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){
- se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7);
- }
- se.m_logLevel.setLogLevel(LogLevel::llError, 15);
- se.m_logLevel.setLogLevel(LogLevel::llConnection, 8);
- se.m_logLevel.setLogLevel(LogLevel::llBackup, 15);
- m_event_listner.m_clients.push_back(se);
- m_event_listner.m_logLevel = se.m_logLevel;
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-//****************************************************************************
-//****************************************************************************
-bool
-MgmtSrvr::check_start()
-{
- if (_config == 0) {
- DEBUG("MgmtSrvr.cpp: _config is NULL.");
- return false;
- }
-
- return true;
-}
-
-bool
-MgmtSrvr::start(BaseString &error_string)
-{
- int mgm_connect_result;
-
- DBUG_ENTER("MgmtSrvr::start");
- if (_props == NULL) {
- if (!check_start()) {
- error_string.append("MgmtSrvr.cpp: check_start() failed.");
- DBUG_RETURN(false);
- }
- }
- theFacade= new TransporterFacade();
-
- if(theFacade == 0) {
- DEBUG("MgmtSrvr.cpp: theFacade is NULL.");
- error_string.append("MgmtSrvr.cpp: theFacade is NULL.");
- DBUG_RETURN(false);
- }
- if ( theFacade->start_instance
- (_ownNodeId, (ndb_mgm_configuration*)_config->m_configValues) < 0) {
- DEBUG("MgmtSrvr.cpp: TransporterFacade::start_instance < 0.");
- DBUG_RETURN(false);
- }
-
- MGM_REQUIRE(_blockNumber == 1);
-
- // Register ourself at TransporterFacade to be able to receive signals
- // and to be notified when a database process has died.
- _blockNumber = theFacade->open(this,
- signalReceivedNotification,
- nodeStatusNotification);
-
- if(_blockNumber == -1){
- DEBUG("MgmtSrvr.cpp: _blockNumber is -1.");
- error_string.append("MgmtSrvr.cpp: _blockNumber is -1.");
- theFacade->stop_instance();
- theFacade = 0;
- DBUG_RETURN(false);
- }
-
- if((mgm_connect_result= connect_to_self()) < 0)
- {
- ndbout_c("Unable to connect to our own ndb_mgmd (Error %d)",
- mgm_connect_result);
- ndbout_c("This is probably a bug.");
- }
-
- /*
- set api reg req frequency quite high:
-
- 100 ms interval to make sure we have fairly up-to-date
- info from the nodes. This to make sure that this info
- is not dependent on heart beat settings in the
- configuration
- */
- theFacade->theClusterMgr->set_max_api_reg_req_interval(100);
-
- TransporterRegistry *reg = theFacade->get_registry();
- for(unsigned int i=0;i<reg->m_transporter_interface.size();i++) {
- BaseString msg;
- DBUG_PRINT("info",("Setting dynamic port %d->%d : %d",
- reg->get_localNodeId(),
- reg->m_transporter_interface[i].m_remote_nodeId,
- reg->m_transporter_interface[i].m_s_service_port
- )
- );
- int res = setConnectionDbParameter((int)reg->get_localNodeId(),
- (int)reg->m_transporter_interface[i]
- .m_remote_nodeId,
- (int)CFG_CONNECTION_SERVER_PORT,
- reg->m_transporter_interface[i]
- .m_s_service_port,
- msg);
- DBUG_PRINT("info",("Set result: %d: %s",res,msg.c_str()));
- }
-
- _ownReference = numberToRef(_blockNumber, _ownNodeId);
-
- startEventLog();
- // Set the initial confirmation count for subscribe requests confirm
- // from NDB nodes in the cluster.
- //
- // Loglevel thread
- _logLevelThread = NdbThread_Create(logLevelThread_C,
- (void**)this,
- 32768,
- "MgmtSrvr_Loglevel",
- NDB_THREAD_PRIO_LOW);
-
- DBUG_RETURN(true);
-}
-
-
-//****************************************************************************
-//****************************************************************************
-MgmtSrvr::~MgmtSrvr()
-{
- if(theFacade != 0){
- theFacade->stop_instance();
- delete theFacade;
- theFacade = 0;
- }
-
- stopEventLog();
-
- NdbMutex_Destroy(m_node_id_mutex);
- NdbCondition_Destroy(theMgmtWaitForResponseCondPtr);
- NdbMutex_Destroy(m_configMutex);
-
- if(m_newConfig != NULL)
- free(m_newConfig);
-
- if(_config != NULL)
- delete _config;
-
- // End set log level thread
- void* res = 0;
- _isStopThread = true;
-
- if (_logLevelThread != NULL) {
- NdbThread_WaitFor(_logLevelThread, &res);
- NdbThread_Destroy(&_logLevelThread);
- }
-
- if (m_config_retriever)
- delete m_config_retriever;
-}
-
-//****************************************************************************
-//****************************************************************************
-
-int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
-{
- if(nodeId == 0 || getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
- return WRONG_PROCESS_TYPE;
- // Check if we have contact with it
- if(unCond){
- if(theFacade->theClusterMgr->getNodeInfo(nodeId).m_api_reg_conf)
- return 0;
- }
- else if (theFacade->get_node_alive(nodeId) == true)
- return 0;
- return NO_CONTACT_WITH_PROCESS;
-}
-
-void report_unknown_signal(SimpleSignal *signal)
-{
- g_eventLogger.error("Unknown signal received. SignalNumber: "
- "%i from (%d, %x)",
- signal->readSignalNumber(),
- refToNode(signal->header.theSendersBlockRef),
- refToBlock(signal->header.theSendersBlockRef));
-}
-
-/*****************************************************************************
- * Starting and stopping database nodes
- ****************************************************************************/
-
-int
-MgmtSrvr::start(int nodeId)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- SimpleSignal ssig;
- StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
- startOrd->restartInfo = 0;
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-/*****************************************************************************
- * Version handling
- *****************************************************************************/
-
-int
-MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
-{
- version= 0;
- if (getOwnNodeId() == nodeId)
- {
- /**
- * If we're inquiring about our own node id,
- * We know what version we are (version implies connected for mgm)
- * but would like to find out from elsewhere what address they're using
- * to connect to us. This means that secondary mgm servers
- * can list ip addresses for mgm servers.
- *
- * If we don't get an address (i.e. no db nodes),
- * we get the address from the configuration.
- */
- sendVersionReq(nodeId, version, address);
- version= NDB_VERSION;
- if(!*address)
- {
- ndb_mgm_configuration_iterator
- iter(*_config->m_configValues, CFG_SECTION_NODE);
- unsigned tmp= 0;
- for(iter.first();iter.valid();iter.next())
- {
- if(iter.get(CFG_NODE_ID, &tmp)) require(false);
- if((unsigned)nodeId!=tmp)
- continue;
- if(iter.get(CFG_NODE_HOST, address)) require(false);
- break;
- }
- }
- }
- else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
- {
- ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
- if(node.connected)
- version= node.m_info.m_version;
- *address= get_connect_address(nodeId);
- }
- else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
- {
- return sendVersionReq(nodeId, version, address);
- }
-
- return 0;
-}
-
-int
-MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
-{
- SignalSender ss(theFacade);
- ss.lock();
-
- SimpleSignal ssig;
- ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
- req->senderRef = ss.getOwnRef();
- req->nodeId = v_nodeId;
- ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
- ApiVersionReq::SignalLength);
-
- int do_send = 1;
- NodeId nodeId;
-
- while (1)
- {
- if (do_send)
- {
- bool next;
- nodeId = 0;
-
- while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- okToSendTo(nodeId, true) != 0);
-
- const ClusterMgr::Node &node=
- theFacade->theClusterMgr->getNodeInfo(nodeId);
- if(next && node.m_state.startLevel != NodeState::SL_STARTED)
- {
- NodeId tmp=nodeId;
- while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- okToSendTo(nodeId, true) != 0);
- if(!next)
- nodeId= tmp;
- }
-
- if(!next) return NO_CONTACT_WITH_DB_NODES;
-
- if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
- return SEND_OR_RECEIVE_FAILED;
- }
- do_send = 0;
- }
-
- SimpleSignal *signal = ss.waitFor();
-
- int gsn = signal->readSignalNumber();
- switch (gsn) {
- case GSN_API_VERSION_CONF: {
- const ApiVersionConf * const conf =
- CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
- assert((int) conf->nodeId == v_nodeId);
- version = conf->version;
- struct in_addr in;
- in.s_addr= conf->inet_addr;
- *address= inet_ntoa(in);
- return 0;
- }
- case GSN_NF_COMPLETEREP:{
- const NFCompleteRep * const rep =
- CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
- if (rep->failedNodeId == nodeId)
- do_send = 1; // retry with other node
- continue;
- }
- case GSN_NODE_FAILREP:{
- const NodeFailRep * const rep =
- CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
- if (NodeBitmask::get(rep->theNodes,nodeId))
- do_send = 1; // retry with other node
- continue;
- }
- default:
- report_unknown_signal(signal);
- return SEND_OR_RECEIVE_FAILED;
- }
- break;
- } // while(1)
-
- return 0;
-}
-
-int MgmtSrvr::sendStopMgmd(NodeId nodeId,
- bool abort,
- bool stop,
- bool restart,
- bool nostart,
- bool initialStart)
-{
- const char* hostname;
- Uint32 port;
- BaseString connect_string;
-
- {
- Guard g(m_configMutex);
- {
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
-
- if(iter.first()) return SEND_OR_RECEIVE_FAILED;
- if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
- if(iter.get(CFG_NODE_HOST, &hostname)) return SEND_OR_RECEIVE_FAILED;
- }
- {
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
-
- if(iter.first()) return SEND_OR_RECEIVE_FAILED;
- if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
- if(iter.get(CFG_MGM_PORT, &port)) return SEND_OR_RECEIVE_FAILED;
- }
- if( strlen(hostname) == 0 )
- return SEND_OR_RECEIVE_FAILED;
- }
- connect_string.assfmt("%s:%u",hostname,port);
-
- DBUG_PRINT("info",("connect string: %s",connect_string.c_str()));
-
- NdbMgmHandle h= ndb_mgm_create_handle();
- if ( h && connect_string.length() > 0 )
- {
- ndb_mgm_set_connectstring(h,connect_string.c_str());
- if(ndb_mgm_connect(h,1,0,0))
- {
- DBUG_PRINT("info",("failed ndb_mgm_connect"));
- return SEND_OR_RECEIVE_FAILED;
- }
- if(!restart)
- {
- if(ndb_mgm_stop(h, 1, (const int*)&nodeId) < 0)
- {
- return SEND_OR_RECEIVE_FAILED;
- }
- }
- else
- {
- int nodes[1];
- nodes[0]= (int)nodeId;
- if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0)
- {
- return SEND_OR_RECEIVE_FAILED;
- }
- }
- }
- ndb_mgm_destroy_handle(&h);
-
- return 0;
-}
-
-/*
- * Common method for handeling all STOP_REQ signalling that
- * is used by Stopping, Restarting and Single user commands
- *
- * In the event that we need to stop a mgmd, we create a mgm
- * client connection to that mgmd and stop it that way.
- * This allows us to stop mgm servers when there isn't any real
- * distributed communication up.
- *
- * node_ids.size()==0 means to stop all DB nodes.
- * MGM nodes will *NOT* be stopped.
- *
- * If we work out we should be stopping or restarting ourselves,
- * we return <0 in stopSelf for restart, >0 for stop
- * and 0 for do nothing.
- */
-
-int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
- NodeBitmask &stoppedNodes,
- Uint32 singleUserNodeId,
- bool abort,
- bool stop,
- bool restart,
- bool nostart,
- bool initialStart,
- int* stopSelf)
-{
- int error = 0;
- DBUG_ENTER("MgmtSrvr::sendSTOP_REQ");
- DBUG_PRINT("enter", ("no of nodes: %d singleUseNodeId: %d "
- "abort: %d stop: %d restart: %d "
- "nostart: %d initialStart: %d",
- node_ids.size(), singleUserNodeId,
- abort, stop, restart, nostart, initialStart));
-
- stoppedNodes.clear();
-
- SignalSender ss(theFacade);
- ss.lock(); // lock will be released on exit
-
- SimpleSignal ssig;
- StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
- ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
- NdbNodeBitmask notstarted;
- for (Uint32 i = 0; i<node_ids.size(); i++)
- {
- Uint32 nodeId = node_ids[i];
- ClusterMgr::Node node = theFacade->theClusterMgr->getNodeInfo(nodeId);
- if (node.m_state.startLevel != NodeState::SL_STARTED)
- notstarted.set(nodeId);
- }
-
- stopReq->requestInfo = 0;
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = ss.getOwnRef();
- if (singleUserNodeId)
- {
- stopReq->singleuser = 1;
- stopReq->singleUserApi = singleUserNodeId;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, false);
- }
- else
- {
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, stop);
- StopReq::setPerformRestart(stopReq->requestInfo, restart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- StopReq::setInitialStart(stopReq->requestInfo, initialStart);
- }
-
- // send the signals
- NodeBitmask nodes;
- NodeId nodeId= 0;
- int use_master_node= 0;
- int do_send= 0;
- *stopSelf= 0;
- NdbNodeBitmask nodes_to_stop;
- {
- for (unsigned i= 0; i < node_ids.size(); i++)
- {
- nodeId= node_ids[i];
- ndbout << "asked to stop " << nodeId << endl;
-
- if ((getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM)
- &&(getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB))
- return WRONG_PROCESS_TYPE;
-
- if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM)
- nodes_to_stop.set(nodeId);
- else if (nodeId != getOwnNodeId())
- {
- error= sendStopMgmd(nodeId, abort, stop, restart,
- nostart, initialStart);
- if (error == 0)
- stoppedNodes.set(nodeId);
- }
- else
- {
- ndbout << "which is me" << endl;
- *stopSelf= (restart)? -1 : 1;
- stoppedNodes.set(nodeId);
- }
- }
- }
- int no_of_nodes_to_stop= nodes_to_stop.count();
- if (node_ids.size())
- {
- if (no_of_nodes_to_stop)
- {
- do_send= 1;
- if (no_of_nodes_to_stop == 1)
- {
- nodeId= nodes_to_stop.find(0);
- }
- else // multi node stop, send to master
- {
- use_master_node= 1;
- nodes_to_stop.copyto(NdbNodeBitmask::Size, stopReq->nodes);
- StopReq::setStopNodes(stopReq->requestInfo, 1);
- }
- }
- }
- else
- {
- nodeId= 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
- {
- if(okToSendTo(nodeId, true) == 0)
- {
- SendStatus result = ss.sendSignal(nodeId, &ssig);
- if (result == SEND_OK)
- nodes.set(nodeId);
- }
- }
- }
-
- // now wait for the replies
- while (!nodes.isclear() || do_send)
- {
- if (do_send)
- {
- int r;
- assert(nodes.count() == 0);
- if (use_master_node)
- nodeId= m_master_node;
- if ((r= okToSendTo(nodeId, true)) != 0)
- {
- bool next;
- if (!use_master_node)
- DBUG_RETURN(r);
- m_master_node= nodeId= 0;
- while((next= getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- (r= okToSendTo(nodeId, true)) != 0);
- if (!next)
- DBUG_RETURN(NO_CONTACT_WITH_DB_NODES);
- }
- if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
- DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
- nodes.set(nodeId);
- do_send= 0;
- }
- SimpleSignal *signal = ss.waitFor();
- int gsn = signal->readSignalNumber();
- switch (gsn) {
- case GSN_STOP_REF:{
- const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
- const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
-#ifdef VM_TRACE
- ndbout_c("Node %d refused stop", nodeId);
-#endif
- assert(nodes.get(nodeId));
- nodes.clear(nodeId);
- if (ref->errorCode == StopRef::MultiNodeShutdownNotMaster)
- {
- assert(use_master_node);
- m_master_node= ref->masterNodeId;
- do_send= 1;
- continue;
- }
- error = translateStopRef(ref->errorCode);
- break;
- }
- case GSN_STOP_CONF:{
-#ifdef NOT_USED
- const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
-#endif
- const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
-#ifdef VM_TRACE
- ndbout_c("Node %d single user mode", nodeId);
-#endif
- assert(nodes.get(nodeId));
- if (singleUserNodeId != 0)
- {
- stoppedNodes.set(nodeId);
- }
- else
- {
- assert(no_of_nodes_to_stop > 1);
- stoppedNodes.bitOR(nodes_to_stop);
- }
- nodes.clear(nodeId);
- break;
- }
- case GSN_NF_COMPLETEREP:{
- const NFCompleteRep * const rep =
- CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
-#ifdef VM_TRACE
- ndbout_c("sendSTOP_REQ Node %d fail completed", rep->failedNodeId);
-#endif
- nodes.clear(rep->failedNodeId); // clear the failed node
- if (singleUserNodeId == 0)
- stoppedNodes.set(rep->failedNodeId);
- break;
- }
- case GSN_NODE_FAILREP:{
- const NodeFailRep * const rep =
- CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
- NdbNodeBitmask mask;
- mask.assign(NdbNodeBitmask::Size, rep->theNodes);
- mask.bitAND(notstarted);
- nodes.bitANDC(mask);
-
- if (singleUserNodeId == 0)
- stoppedNodes.bitOR(mask);
- break;
- }
- default:
- report_unknown_signal(signal);
-#ifdef VM_TRACE
- ndbout_c("Unknown signal %d", gsn);
-#endif
- DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
- }
- }
- if (error && *stopSelf)
- {
- *stopSelf= 0;
- }
- DBUG_RETURN(error);
-}
-
-/*
- * Stop one nodes
- */
-
-int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids,
- int *stopCount, bool abort, int* stopSelf)
-{
- if (!abort)
- {
- NodeId nodeId = 0;
- ClusterMgr::Node node;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
- {
- node = theFacade->theClusterMgr->getNodeInfo(nodeId);
- if((node.m_state.startLevel != NodeState::SL_STARTED) &&
- (node.m_state.startLevel != NodeState::SL_NOTHING))
- return OPERATION_NOT_ALLOWED_START_STOP;
- }
- }
- NodeBitmask nodes;
- int ret= sendSTOP_REQ(node_ids,
- nodes,
- 0,
- abort,
- false,
- false,
- false,
- false,
- stopSelf);
- if (stopCount)
- *stopCount= nodes.count();
- return ret;
-}
-
-int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf)
-{
- NodeId nodeId = 0;
- int error;
-
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
- {
- if(nodeId==getOwnNodeId())
- continue;
- error= sendStopMgmd(nodeId, abort, true, false,
- false, false);
- if (error == 0)
- *stopCount++;
- }
-
- *stopSelf= 1;
- *stopCount++;
-
- return 0;
-}
-
-/*
- * Perform DB nodes shutdown.
- * MGM servers are left in their current state
- */
-
-int MgmtSrvr::shutdownDB(int * stopCount, bool abort)
-{
- NodeBitmask nodes;
- Vector<NodeId> node_ids;
-
- int tmp;
-
- int ret = sendSTOP_REQ(node_ids,
- nodes,
- 0,
- abort,
- true,
- false,
- false,
- false,
- &tmp);
- if (stopCount)
- *stopCount = nodes.count();
- return ret;
-}
-
-/*
- * Enter single user mode on all live nodes
- */
-
-int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
-{
- if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
- return NODE_NOT_API_NODE;
- NodeId nodeId = 0;
- ClusterMgr::Node node;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
- {
- node = theFacade->theClusterMgr->getNodeInfo(nodeId);
- if((node.m_state.startLevel != NodeState::SL_STARTED) &&
- (node.m_state.startLevel != NodeState::SL_NOTHING))
- return OPERATION_NOT_ALLOWED_START_STOP;
- }
- NodeBitmask nodes;
- Vector<NodeId> node_ids;
- int stopSelf;
- int ret = sendSTOP_REQ(node_ids,
- nodes,
- singleUserNodeId,
- false,
- false,
- false,
- false,
- false,
- &stopSelf);
- if (stopCount)
- *stopCount = nodes.count();
- return ret;
-}
-
-/*
- * Perform node restart
- */
-
-int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids,
- int * stopCount, bool nostart,
- bool initialStart, bool abort,
- int *stopSelf)
-{
- NodeBitmask nodes;
- int ret= sendSTOP_REQ(node_ids,
- nodes,
- 0,
- abort,
- false,
- true,
- true,
- initialStart,
- stopSelf);
-
- if (ret)
- return ret;
-
- if (stopCount)
- *stopCount = nodes.count();
-
- // start up the nodes again
- int waitTime = 12000;
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
- for (unsigned i = 0; i < node_ids.size(); i++)
- {
- NodeId nodeId= node_ids[i];
- enum ndb_mgm_node_status s;
- s = NDB_MGM_NODE_STATUS_NO_CONTACT;
-#ifdef VM_TRACE
- ndbout_c("Waiting for %d not started", nodeId);
-#endif
- while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0)
- {
- Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
- Uint32 connectCount = 0;
- bool system;
- const char *address;
- status(nodeId, &s, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount, &address);
- NdbSleep_MilliSleep(100);
- waitTime = (maxTime - NdbTick_CurrentMillisecond());
- }
- }
-
- if (nostart)
- return 0;
-
- for (unsigned i = 0; i < node_ids.size(); i++)
- {
- (void) start(node_ids[i]);
- }
- return 0;
-}
-
-/*
- * Perform restart of all DB nodes
- */
-
-int MgmtSrvr::restartDB(bool nostart, bool initialStart,
- bool abort, int * stopCount)
-{
- NodeBitmask nodes;
- Vector<NodeId> node_ids;
- int tmp;
-
- int ret = sendSTOP_REQ(node_ids,
- nodes,
- 0,
- abort,
- true,
- true,
- true,
- initialStart,
- &tmp);
-
- if (ret)
- return ret;
-
- if (stopCount)
- *stopCount = nodes.count();
-
-#ifdef VM_TRACE
- ndbout_c("Stopped %d nodes", nodes.count());
-#endif
- /**
- * Here all nodes were correctly stopped,
- * so we wait for all nodes to be contactable
- */
- int waitTime = 12000;
- NodeId nodeId = 0;
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
-
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
- if (!nodes.get(nodeId))
- continue;
- enum ndb_mgm_node_status s;
- s = NDB_MGM_NODE_STATUS_NO_CONTACT;
-#ifdef VM_TRACE
- ndbout_c("Waiting for %d not started", nodeId);
-#endif
- while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
- Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
- Uint32 connectCount = 0;
- bool system;
- const char *address;
- status(nodeId, &s, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount, &address);
- NdbSleep_MilliSleep(100);
- waitTime = (maxTime - NdbTick_CurrentMillisecond());
- }
- }
-
- if(nostart)
- return 0;
-
- /**
- * Now we start all database nodes (i.e. we make them non-idle)
- * We ignore the result we get from the start command.
- */
- nodeId = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
- if (!nodes.get(nodeId))
- continue;
- int result;
- result = start(nodeId);
- DEBUG("Starting node " << nodeId << " with result " << result);
- /**
- * Errors from this call are deliberately ignored.
- * Maybe the user only wanted to restart a subset of the nodes.
- * It is also easy for the user to check which nodes have
- * started and which nodes have not.
- */
- }
-
- return 0;
-}
-
-int
-MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
-{
- NodeId nodeId = 0;
- int count = 0;
-
- SignalSender ss(theFacade);
- ss.lock(); // lock will be released on exit
-
- SimpleSignal ssig;
- ResumeReq* const resumeReq =
- CAST_PTR(ResumeReq, ssig.getDataPtrSend());
- ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
- ResumeReq::SignalLength);
- resumeReq->senderData = 12;
- resumeReq->senderRef = ss.getOwnRef();
-
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
- SendStatus result = ss.sendSignal(nodeId, &ssig);
- if (result == SEND_OK)
- count++;
- }
- }
-
- if(stopCount != 0)
- * stopCount = count;
-
- return 0;
-}
-
-/*****************************************************************************
- * Status
- ****************************************************************************/
-
-#include <ClusterMgr.hpp>
-
-void
-MgmtSrvr::updateStatus()
-{
- theFacade->theClusterMgr->forceHB();
-}
-
-int
-MgmtSrvr::status(int nodeId,
- ndb_mgm_node_status * _status,
- Uint32 * version,
- Uint32 * _phase,
- bool * _system,
- Uint32 * dynamic,
- Uint32 * nodegroup,
- Uint32 * connectCount,
- const char **address)
-{
- if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
- versionNode(nodeId, *version, address);
- } else {
- *address= get_connect_address(nodeId);
- }
-
- const ClusterMgr::Node node =
- theFacade->theClusterMgr->getNodeInfo(nodeId);
-
- if(!node.connected){
- * _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
- return 0;
- }
-
- if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
- * version = node.m_info.m_version;
- }
-
- * 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;
- * _phase = 0;
- return 0;
- break;
- case NodeState::SL_STARTING:
- * _status = NDB_MGM_NODE_STATUS_STARTING;
- * _phase = node.m_state.starting.startPhase;
- return 0;
- break;
- case NodeState::SL_STARTED:
- * _status = NDB_MGM_NODE_STATUS_STARTED;
- * _phase = 0;
- return 0;
- break;
- case NodeState::SL_STOPPING_1:
- * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
- * _phase = 1;
- * _system = node.m_state.stopping.systemShutdown != 0;
- return 0;
- break;
- case NodeState::SL_STOPPING_2:
- * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
- * _phase = 2;
- * _system = node.m_state.stopping.systemShutdown != 0;
- return 0;
- break;
- case NodeState::SL_STOPPING_3:
- * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
- * _phase = 3;
- * _system = node.m_state.stopping.systemShutdown != 0;
- return 0;
- break;
- case NodeState::SL_STOPPING_4:
- * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
- * _phase = 4;
- * _system = node.m_state.stopping.systemShutdown != 0;
- return 0;
- break;
- case NodeState::SL_SINGLEUSER:
- * _status = NDB_MGM_NODE_STATUS_SINGLEUSER;
- * _phase = 0;
- return 0;
- break;
- default:
- * _status = NDB_MGM_NODE_STATUS_UNKNOWN;
- * _phase = 0;
- return 0;
- }
-
- return -1;
-}
-
-int
-MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
- const EventSubscribeReq& ll)
-{
- SignalSender ss(theFacade);
- NdbNodeBitmask nodes;
- nodes.clear();
- while (1)
- {
- Uint32 nodeId, max;
- ss.lock();
- SimpleSignal ssig;
- EventSubscribeReq * dst =
- CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
- EventSubscribeReq::SignalLength);
- *dst = ll;
-
- if (nodeId_arg == 0)
- {
- // all nodes
- nodeId = 1;
- max = MAX_NDB_NODES;
- }
- else
- {
- // only one node
- max = nodeId = nodeId_arg;
- }
- // first make sure nodes are sendable
- for(; nodeId <= max; nodeId++)
- {
- if (nodeTypes[nodeId] != NODE_TYPE_DB)
- continue;
- if (okToSendTo(nodeId, true))
- {
- if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false)
- {
- // node not connected we can safely skip this one
- continue;
- }
- // api_reg_conf not recevied yet, need to retry
- return SEND_OR_RECEIVE_FAILED;
- }
- }
-
- if (nodeId_arg == 0)
- {
- // all nodes
- nodeId = 1;
- max = MAX_NDB_NODES;
- }
- else
- {
- // only one node
- max = nodeId = nodeId_arg;
- }
- // now send to all sendable nodes nodes
- // note, lock is held, so states have not changed
- for(; (Uint32) nodeId <= max; nodeId++)
- {
- if (nodeTypes[nodeId] != NODE_TYPE_DB)
- continue;
- if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false)
- continue; // node is not connected, skip
- if (ss.sendSignal(nodeId, &ssig) == SEND_OK)
- nodes.set(nodeId);
- else if (max == nodeId)
- {
- return SEND_OR_RECEIVE_FAILED;
- }
- }
- break;
- }
-
- if (nodes.isclear())
- {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- int error = 0;
- while (!nodes.isclear())
- {
- Uint32 nodeId;
- SimpleSignal *signal = ss.waitFor();
- int gsn = signal->readSignalNumber();
- nodeId = refToNode(signal->header.theSendersBlockRef);
- switch (gsn) {
- case GSN_EVENT_SUBSCRIBE_CONF:{
- nodes.clear(nodeId);
- break;
- }
- case GSN_EVENT_SUBSCRIBE_REF:{
- nodes.clear(nodeId);
- error = 1;
- break;
- }
- // Since sending okToSend(true),
- // there is no guarantee that NF_COMPLETEREP will come
- // i.e listen also to NODE_FAILREP
- case GSN_NODE_FAILREP: {
- const NodeFailRep * const rep =
- CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
- NdbNodeBitmask mask;
- mask.assign(NdbNodeBitmask::Size, rep->theNodes);
- nodes.bitANDC(mask);
- break;
- }
-
- case GSN_NF_COMPLETEREP:{
- const NFCompleteRep * const rep =
- CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
- nodes.clear(rep->failedNodeId);
- break;
- }
- default:
- report_unknown_signal(signal);
- return SEND_OR_RECEIVE_FAILED;
- }
- }
- if (error)
- return SEND_OR_RECEIVE_FAILED;
- return 0;
-}
-
-//****************************************************************************
-//****************************************************************************
-int
-MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
- SetLogLevelOrd::SignalLength);
- SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
- *dst = ll;
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-//****************************************************************************
-//****************************************************************************
-
-int
-MgmtSrvr::insertError(int nodeId, int errorNo)
-{
- int block;
-
- if (errorNo < 0) {
- return INVALID_ERROR_NUMBER;
- }
-
- SignalSender ss(theFacade);
- ss.lock(); /* lock will be released on exit */
-
- if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
- {
- block= CMVMI;
- }
- else if(nodeId == _ownNodeId)
- {
- g_errorInsert= errorNo;
- return 0;
- }
- else if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
- block= _blockNumber;
- else
- return WRONG_PROCESS_TYPE;
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, block, GSN_TAMPER_ORD,
- TamperOrd::SignalLength);
- TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
- tamperOrd->errorNo = errorNo;
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-
-
-//****************************************************************************
-//****************************************************************************
-
-int
-MgmtSrvr::setTraceNo(int nodeId, int traceNo)
-{
- if (traceNo < 0) {
- return INVALID_TRACE_NUMBER;
- }
-
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
- testOrd->clear();
- // Assume TRACE command causes toggling. Not really defined... ? TODO
- testOrd->setTraceCommand(TestOrd::Toggle,
- (TestOrd::TraceSpecification)traceNo);
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-//****************************************************************************
-//****************************************************************************
-
-int
-MgmtSrvr::getBlockNumber(const BaseString &blockName)
-{
- short bno = getBlockNo(blockName.c_str());
- if(bno != 0)
- return bno;
- return -1;
-}
-
-//****************************************************************************
-//****************************************************************************
-
-int
-MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
- const Vector<BaseString>& blocks)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- // Convert from MgmtSrvr format...
-
- TestOrd::Command command;
- if (mode == Off) {
- command = TestOrd::Off;
- }
- else {
- command = TestOrd::On;
- }
-
- TestOrd::SignalLoggerSpecification logSpec;
- switch (mode) {
- case In:
- logSpec = TestOrd::InputSignals;
- break;
- case Out:
- logSpec = TestOrd::OutputSignals;
- break;
- case InOut:
- logSpec = TestOrd::InputOutputSignals;
- break;
- case Off:
- // In MgmtSrvr interface it's just possible to switch off all logging, both
- // "in" and "out" (this should probably be changed).
- logSpec = TestOrd::InputOutputSignals;
- break;
- default:
- ndbout_c("Unexpected value %d, MgmtSrvr::setSignalLoggingMode, line %d",
- (unsigned)mode, __LINE__);
- assert(false);
- return -1;
- }
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
- testOrd->clear();
-
- if (blocks.size() == 0 || blocks[0] == "ALL") {
- // Logg command for all blocks
- testOrd->addSignalLoggerCommand(command, logSpec);
- } else {
- for(unsigned i = 0; i < blocks.size(); i++){
- int blockNumber = getBlockNumber(blocks[i]);
- if (blockNumber == -1) {
- return INVALID_BLOCK_NAME;
- }
- testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
- } // for
- } // else
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-/*****************************************************************************
- * Signal tracing
- *****************************************************************************/
-int MgmtSrvr::startSignalTracing(int nodeId)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
- testOrd->clear();
- testOrd->setTestCommand(TestOrd::On);
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-int
-MgmtSrvr::stopSignalTracing(int nodeId)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- SimpleSignal ssig;
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
- testOrd->clear();
- testOrd->setTestCommand(TestOrd::Off);
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-
-/*****************************************************************************
- * Dump state
- *****************************************************************************/
-
-int
-MgmtSrvr::dumpState(int nodeId, const char* args)
-{
- // Convert the space separeted args
- // string to an int array
- Uint32 args_array[25];
- Uint32 numArgs = 0;
-
- char buf[10];
- int b = 0;
- memset(buf, 0, 10);
- for (size_t i = 0; i <= strlen(args); i++){
- if (args[i] == ' ' || args[i] == 0){
- args_array[numArgs] = atoi(buf);
- numArgs++;
- memset(buf, 0, 10);
- b = 0;
- } else {
- buf[b] = args[i];
- b++;
- }
- }
-
- return dumpState(nodeId, args_array, numArgs);
-}
-
-int
-MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
-{
- INIT_SIGNAL_SENDER(ss,nodeId);
-
- const Uint32 len = no > 25 ? 25 : no;
-
- SimpleSignal ssig;
- DumpStateOrd * const dumpOrd =
- CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
- ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
- for(Uint32 i = 0; i<25; i++){
- if (i < len)
- dumpOrd->args[i] = args[i];
- else
- dumpOrd->args[i] = 0;
- }
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-
-//****************************************************************************
-//****************************************************************************
-
-const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz)
-{
- ndb_error_string(errorCode, buf, buf_sz);
- buf[buf_sz-1]= 0;
- return buf;
-}
-
-void
-MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
-{
- // The way of handling a received signal is taken from the Ndb class.
- int gsn = signal->readSignalNumber();
-
- switch (gsn) {
- case GSN_EVENT_SUBSCRIBE_CONF:
- break;
- case GSN_EVENT_SUBSCRIBE_REF:
- break;
- case GSN_EVENT_REP:
- {
- eventReport(signal->getDataPtr());
- break;
- }
-
- case GSN_NF_COMPLETEREP:
- break;
- case GSN_NODE_FAILREP:
- break;
-
- case GSN_TAMPER_ORD:
- ndbout << "TAMPER ORD" << endl;
- break;
-
- default:
- g_eventLogger.error("Unknown signal received. SignalNumber: "
- "%i from (%d, %x)",
- gsn,
- refToNode(signal->theSendersBlockRef),
- refToBlock(signal->theSendersBlockRef));
- }
-
- if (theWaitState == NO_WAIT) {
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- }
-}
-
-void
-MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
-{
- DBUG_ENTER("MgmtSrvr::handleStatus");
- Uint32 theData[25];
- EventReport *rep = (EventReport *)theData;
-
- theData[1] = nodeId;
- if (alive) {
- if (nodeTypes[nodeId] == NODE_TYPE_DB)
- {
- m_started_nodes.push_back(nodeId);
- }
- rep->setEventType(NDB_LE_Connected);
- } else {
- rep->setEventType(NDB_LE_Disconnected);
- if(nfComplete)
- {
- DBUG_VOID_RETURN;
- }
- }
- rep->setNodeId(_ownNodeId);
- eventReport(theData);
- DBUG_VOID_RETURN;
-}
-
-//****************************************************************************
-//****************************************************************************
-
-void
-MgmtSrvr::signalReceivedNotification(void* mgmtSrvr,
- NdbApiSignal* signal,
- LinearSectionPtr ptr[3])
-{
- ((MgmtSrvr*)mgmtSrvr)->handleReceivedSignal(signal);
-}
-
-
-//****************************************************************************
-//****************************************************************************
-void
-MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId,
- bool alive, bool nfComplete)
-{
- DBUG_ENTER("MgmtSrvr::nodeStatusNotification");
- DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete));
- ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive, nfComplete);
- DBUG_VOID_RETURN;
-}
-
-enum ndb_mgm_node_type
-MgmtSrvr::getNodeType(NodeId nodeId) const
-{
- if(nodeId >= MAX_NODES)
- return (enum ndb_mgm_node_type)-1;
-
- return nodeTypes[nodeId];
-}
-
-const char *MgmtSrvr::get_connect_address(Uint32 node_id)
-{
- if (m_connect_address[node_id].s_addr == 0 &&
- theFacade && theFacade->theTransporterRegistry &&
- theFacade->theClusterMgr &&
- getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB)
- {
- const ClusterMgr::Node &node=
- theFacade->theClusterMgr->getNodeInfo(node_id);
- if (node.connected)
- {
- m_connect_address[node_id]=
- theFacade->theTransporterRegistry->get_connect_address(node_id);
- }
- }
- return inet_ntoa(m_connect_address[node_id]);
-}
-
-void
-MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const
-{
- if (theFacade && theFacade->theClusterMgr)
- {
- for(Uint32 i = 0; i < MAX_NODES; i++)
- {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB)
- {
- const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i);
- connected_nodes.bitOR(node.m_state.m_connected_nodes);
- }
- }
- }
-}
-
-int
-MgmtSrvr::alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type)
-{
- SignalSender ss(theFacade);
- ss.lock(); // lock will be released on exit
-
- SimpleSignal ssig;
- AllocNodeIdReq* req = CAST_PTR(AllocNodeIdReq, ssig.getDataPtrSend());
- ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_ALLOC_NODEID_REQ,
- AllocNodeIdReq::SignalLength);
-
- req->senderRef = ss.getOwnRef();
- req->senderData = 19;
- req->nodeId = free_node_id;
- req->nodeType = type;
-
- int do_send = 1;
- NodeId nodeId = 0;
- while (1)
- {
- if (nodeId == 0)
- {
- bool next;
- while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- theFacade->get_node_alive(nodeId) == false);
- if (!next)
- return NO_CONTACT_WITH_DB_NODES;
- do_send = 1;
- }
- if (do_send)
- {
- if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
- return SEND_OR_RECEIVE_FAILED;
- }
- do_send = 0;
- }
-
- SimpleSignal *signal = ss.waitFor();
-
- int gsn = signal->readSignalNumber();
- switch (gsn) {
- case GSN_ALLOC_NODEID_CONF:
- {
-#ifdef NOT_USED
- const AllocNodeIdConf * const conf =
- CAST_CONSTPTR(AllocNodeIdConf, signal->getDataPtr());
-#endif
- return 0;
- }
- case GSN_ALLOC_NODEID_REF:
- {
- const AllocNodeIdRef * const ref =
- CAST_CONSTPTR(AllocNodeIdRef, signal->getDataPtr());
- if (ref->errorCode == AllocNodeIdRef::NotMaster ||
- ref->errorCode == AllocNodeIdRef::Busy ||
- ref->errorCode == AllocNodeIdRef::NodeFailureHandlingNotCompleted)
- {
- do_send = 1;
- nodeId = refToNode(ref->masterRef);
- if (!theFacade->get_node_alive(nodeId))
- nodeId = 0;
- if (ref->errorCode != AllocNodeIdRef::NotMaster)
- {
- /* sleep for a while (100ms) before retrying */
- NdbSleep_MilliSleep(100);
- }
- continue;
- }
- return ref->errorCode;
- }
- case GSN_NF_COMPLETEREP:
- {
- const NFCompleteRep * const rep =
- CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
-#ifdef VM_TRACE
- ndbout_c("Node %d fail completed", rep->failedNodeId);
-#endif
- if (rep->failedNodeId == nodeId)
- {
- do_send = 1;
- nodeId = 0;
- }
- continue;
- }
- case GSN_NODE_FAILREP:{
- // ignore NF_COMPLETEREP will come
- continue;
- }
- default:
- report_unknown_signal(signal);
- return SEND_OR_RECEIVE_FAILED;
- }
- }
- return 0;
-}
-
-bool
-MgmtSrvr::alloc_node_id(NodeId * nodeId,
- enum ndb_mgm_node_type type,
- struct sockaddr *client_addr,
- SOCKET_SIZE_TYPE *client_addr_len,
- int &error_code, BaseString &error_string,
- int log_event)
-{
- DBUG_ENTER("MgmtSrvr::alloc_node_id");
- DBUG_PRINT("enter", ("nodeid: %d type: %d client_addr: 0x%ld",
- *nodeId, type, (long) client_addr));
- if (g_no_nodeid_checks) {
- if (*nodeId == 0) {
- error_string.appfmt("no-nodeid-checks set in management server.\n"
- "node id must be set explicitly in connectstring");
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- DBUG_RETURN(false);
- }
- DBUG_RETURN(true);
- }
- Guard g(m_node_id_mutex);
- int no_mgm= 0;
- NodeBitmask connected_nodes(m_reserved_nodes);
- get_connected_nodes(connected_nodes);
- {
- for(Uint32 i = 0; i < MAX_NODES; i++)
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM)
- no_mgm++;
- }
- bool found_matching_id= false;
- bool found_matching_type= false;
- bool found_free_node= false;
- unsigned id_found= 0;
- const char *config_hostname= 0;
- struct in_addr config_addr= {0};
- int r_config_addr= -1;
- unsigned type_c= 0;
-
- if(NdbMutex_Lock(m_configMutex))
- {
- // should not happen
- error_string.appfmt("unable to lock configuration mutex");
- error_code = NDB_MGM_ALLOCID_ERROR;
- DBUG_RETURN(false);
- }
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
- for(iter.first(); iter.valid(); iter.next()) {
- unsigned tmp= 0;
- if(iter.get(CFG_NODE_ID, &tmp)) require(false);
- if (*nodeId && *nodeId != tmp)
- continue;
- found_matching_id= true;
- if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false);
- if(type_c != (unsigned)type)
- continue;
- found_matching_type= true;
- if (connected_nodes.get(tmp))
- continue;
- found_free_node= true;
- if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false);
- if (config_hostname && config_hostname[0] == 0)
- config_hostname= 0;
- else if (client_addr) {
- // check hostname compatability
- const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr);
- if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0
- || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) {
- struct in_addr tmp_addr;
- if(Ndb_getInAddr(&tmp_addr, "localhost") != 0
- || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) {
- // not localhost
-#if 0
- ndbout << "MgmtSrvr::getFreeNodeId compare failed for \""
- << config_hostname
- << "\" id=" << tmp << endl;
-#endif
- continue;
- }
- // connecting through localhost
- // check if config_hostname is local
- if (!SocketServer::tryBind(0,config_hostname)) {
- continue;
- }
- }
- } else { // client_addr == 0
- if (!SocketServer::tryBind(0,config_hostname)) {
- continue;
- }
- }
- if (*nodeId != 0 ||
- type != NDB_MGM_NODE_TYPE_MGM ||
- no_mgm == 1) { // any match is ok
-
- if (config_hostname == 0 &&
- *nodeId == 0 &&
- type != NDB_MGM_NODE_TYPE_MGM)
- {
- if (!id_found) // only set if not set earlier
- id_found= tmp;
- continue; /* continue looking for a nodeid with specified
- * hostname
- */
- }
- assert(id_found == 0);
- id_found= tmp;
- break;
- }
- if (id_found) { // mgmt server may only have one match
- error_string.appfmt("Ambiguous node id's %d and %d.\n"
- "Suggest specifying node id in connectstring,\n"
- "or specifying unique host names in config file.",
- id_found, tmp);
- NdbMutex_Unlock(m_configMutex);
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- DBUG_RETURN(false);
- }
- if (config_hostname == 0) {
- error_string.appfmt("Ambiguity for node id %d.\n"
- "Suggest specifying node id in connectstring,\n"
- "or specifying unique host names in config file,\n"
- "or specifying just one mgmt server in config file.",
- tmp);
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- DBUG_RETURN(false);
- }
- id_found= tmp; // mgmt server matched, check for more matches
- }
- NdbMutex_Unlock(m_configMutex);
-
- if (id_found && client_addr != 0)
- {
- int res = alloc_node_id_req(id_found, type);
- unsigned save_id_found = id_found;
- switch (res)
- {
- case 0:
- // ok continue
- break;
- case NO_CONTACT_WITH_DB_NODES:
- // ok continue
- break;
- default:
- // something wrong
- id_found = 0;
- break;
-
- }
- if (id_found == 0)
- {
- char buf[128];
- ndb_error_string(res, buf, sizeof(buf));
- error_string.appfmt("Cluster refused allocation of id %d. Error: %d (%s).",
- save_id_found, res, buf);
- g_eventLogger.warning("Cluster refused allocation of id %d. "
- "Connection from ip %s. "
- "Returned error string \"%s\"", save_id_found,
- inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr),
- error_string.c_str());
- DBUG_RETURN(false);
- }
- }
-
- if (id_found)
- {
- *nodeId= id_found;
- DBUG_PRINT("info", ("allocating node id %d",*nodeId));
- {
- int r= 0;
- if (client_addr)
- m_connect_address[id_found]=
- ((struct sockaddr_in *)client_addr)->sin_addr;
- else if (config_hostname)
- r= Ndb_getInAddr(&(m_connect_address[id_found]), config_hostname);
- else {
- char name[256];
- r= gethostname(name, sizeof(name));
- if (r == 0) {
- name[sizeof(name)-1]= 0;
- r= Ndb_getInAddr(&(m_connect_address[id_found]), name);
- }
- }
- if (r)
- m_connect_address[id_found].s_addr= 0;
- }
- m_reserved_nodes.set(id_found);
- if (theFacade && id_found != theFacade->ownId())
- {
- /**
- * Make sure we're ready to accept connections from this node
- */
- theFacade->lock_mutex();
- theFacade->doConnect(id_found);
- theFacade->unlock_mutex();
- }
-
- char tmp_str[128];
- m_reserved_nodes.getText(tmp_str);
- g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, "
- "m_reserved_nodes %s.",
- id_found, get_connect_address(id_found), tmp_str);
- DBUG_RETURN(true);
- }
-
- if (found_matching_type && !found_free_node) {
- // we have a temporary error which might be due to that
- // we have got the latest connect status from db-nodes. Force update.
- updateStatus();
- }
-
- BaseString type_string, type_c_string;
- {
- const char *alias, *str;
- alias= ndb_mgm_get_node_type_alias_string(type, &str);
- type_string.assfmt("%s(%s)", alias, str);
- alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c,
- &str);
- type_c_string.assfmt("%s(%s)", alias, str);
- }
-
- if (*nodeId == 0)
- {
- if (found_matching_id)
- {
- if (found_matching_type)
- {
- if (found_free_node)
- {
- error_string.appfmt("Connection done from wrong host ip %s.",
- (client_addr)?
- inet_ntoa(((struct sockaddr_in *)
- (client_addr))->sin_addr):"");
- error_code = NDB_MGM_ALLOCID_ERROR;
- }
- else
- {
- error_string.appfmt("No free node id found for %s.",
- type_string.c_str());
- error_code = NDB_MGM_ALLOCID_ERROR;
- }
- }
- else
- {
- error_string.appfmt("No %s node defined in config file.",
- type_string.c_str());
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- }
- }
- else
- {
- error_string.append("No nodes defined in config file.");
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- }
- }
- else
- {
- if (found_matching_id)
- {
- if (found_matching_type)
- {
- if (found_free_node)
- {
- // have to split these into two since inet_ntoa overwrites itself
- error_string.appfmt("Connection with id %d done from wrong host ip %s,",
- *nodeId, inet_ntoa(((struct sockaddr_in *)
- (client_addr))->sin_addr));
- error_string.appfmt(" expected %s(%s).", config_hostname,
- r_config_addr ?
- "lookup failed" : inet_ntoa(config_addr));
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- }
- else
- {
- error_string.appfmt("Id %d already allocated by another node.",
- *nodeId);
- error_code = NDB_MGM_ALLOCID_ERROR;
- }
- }
- else
- {
- error_string.appfmt("Id %d configured as %s, connect attempted as %s.",
- *nodeId, type_c_string.c_str(),
- type_string.c_str());
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- }
- }
- else
- {
- error_string.appfmt("No node defined with id=%d in config file.",
- *nodeId);
- error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
- }
- }
-
- if (log_event || error_code == NDB_MGM_ALLOCID_CONFIG_MISMATCH)
- {
- g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s."
- " Returned error string \"%s\"",
- *nodeId,
- client_addr != 0
- ? inet_ntoa(((struct sockaddr_in *)
- (client_addr))->sin_addr)
- : "<none>",
- error_string.c_str());
-
- NodeBitmask connected_nodes2;
- get_connected_nodes(connected_nodes2);
- BaseString tmp_connected, tmp_not_connected;
- for(Uint32 i = 0; i < MAX_NODES; i++)
- {
- if (connected_nodes2.get(i))
- {
- if (!m_reserved_nodes.get(i))
- tmp_connected.appfmt(" %d", i);
- }
- else if (m_reserved_nodes.get(i))
- {
- tmp_not_connected.appfmt(" %d", i);
- }
- }
- if (tmp_connected.length() > 0)
- g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved",
- tmp_connected.c_str());
- if (tmp_not_connected.length() > 0)
- g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved",
- tmp_not_connected.c_str());
- }
- DBUG_RETURN(false);
-}
-
-bool
-MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const
-{
- NodeId tmp = * nodeId;
-
- tmp++;
- while(nodeTypes[tmp] != type && tmp < MAX_NODES)
- tmp++;
-
- if(tmp == MAX_NODES){
- return false;
- }
-
- * nodeId = tmp;
- return true;
-}
-
-#include "Services.hpp"
-
-void
-MgmtSrvr::eventReport(const Uint32 * theData)
-{
- const EventReport * const eventReport = (EventReport *)&theData[0];
-
- NodeId nodeId = eventReport->getNodeId();
- Ndb_logevent_type type = eventReport->getEventType();
- // Log event
- g_eventLogger.log(type, theData, nodeId,
- &m_event_listner[0].m_logLevel);
- m_event_listner.log(type, theData, nodeId);
-}
-
-/***************************************************************************
- * Backup
- ***************************************************************************/
-
-int
-MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
-{
- SignalSender ss(theFacade);
- ss.lock(); // lock will be released on exit
-
- NodeId nodeId = m_master_node;
- if (okToSendTo(nodeId, false) != 0)
- {
- bool next;
- nodeId = m_master_node = 0;
- while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- okToSendTo(nodeId, false) != 0);
- if(!next)
- return NO_CONTACT_WITH_DB_NODES;
- }
-
- SimpleSignal ssig;
- BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
- ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
- BackupReq::SignalLength);
-
- req->senderData = 19;
- req->backupDataLen = 0;
- assert(waitCompleted < 3);
- req->flags = waitCompleted & 0x3;
-
- BackupEvent event;
- int do_send = 1;
- while (1) {
- if (do_send)
- {
- if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
- return SEND_OR_RECEIVE_FAILED;
- }
- if (waitCompleted == 0)
- return 0;
- do_send = 0;
- }
- SimpleSignal *signal = ss.waitFor();
-
- int gsn = signal->readSignalNumber();
- switch (gsn) {
- case GSN_BACKUP_CONF:{
- const BackupConf * const conf =
- CAST_CONSTPTR(BackupConf, signal->getDataPtr());
- event.Event = BackupEvent::BackupStarted;
- event.Started.BackupId = conf->backupId;
- event.Nodes = conf->nodes;
-#ifdef VM_TRACE
- ndbout_c("Backup(%d) master is %d", conf->backupId,
- refToNode(signal->header.theSendersBlockRef));
-#endif
- backupId = conf->backupId;
- if (waitCompleted == 1)
- return 0;
- // wait for next signal
- break;
- }
- case GSN_BACKUP_COMPLETE_REP:{
- const BackupCompleteRep * const rep =
- CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr());
-#ifdef VM_TRACE
- ndbout_c("Backup(%d) completed", rep->backupId);
-#endif
- event.Event = BackupEvent::BackupCompleted;
- event.Completed.BackupId = rep->backupId;
-
- event.Completed.NoOfBytes = rep->noOfBytesLow;
- event.Completed.NoOfLogBytes = rep->noOfLogBytes;
- event.Completed.NoOfRecords = rep->noOfRecordsLow;
- event.Completed.NoOfLogRecords = rep->noOfLogRecords;
- event.Completed.stopGCP = rep->stopGCP;
- event.Completed.startGCP = rep->startGCP;
- event.Nodes = rep->nodes;
-
- if (signal->header.theLength >= BackupCompleteRep::SignalLength)
- {
- event.Completed.NoOfBytes += ((Uint64)rep->noOfBytesHigh) << 32;
- event.Completed.NoOfRecords += ((Uint64)rep->noOfRecordsHigh) << 32;
- }
-
- backupId = rep->backupId;
- return 0;
- }
- case GSN_BACKUP_REF:{
- const BackupRef * const ref =
- CAST_CONSTPTR(BackupRef, signal->getDataPtr());
- if(ref->errorCode == BackupRef::IAmNotMaster){
- m_master_node = nodeId = refToNode(ref->masterRef);
-#ifdef VM_TRACE
- ndbout_c("I'm not master resending to %d", nodeId);
-#endif
- do_send = 1; // try again
- if (!theFacade->get_node_alive(nodeId))
- m_master_node = nodeId = 0;
- continue;
- }
- event.Event = BackupEvent::BackupFailedToStart;
- event.FailedToStart.ErrorCode = ref->errorCode;
- return ref->errorCode;
- }
- case GSN_BACKUP_ABORT_REP:{
- const BackupAbortRep * const rep =
- CAST_CONSTPTR(BackupAbortRep, signal->getDataPtr());
- event.Event = BackupEvent::BackupAborted;
- event.Aborted.Reason = rep->reason;
- event.Aborted.BackupId = rep->backupId;
- event.Aborted.ErrorCode = rep->reason;
-#ifdef VM_TRACE
- ndbout_c("Backup %d aborted", rep->backupId);
-#endif
- return rep->reason;
- }
- case GSN_NF_COMPLETEREP:{
- const NFCompleteRep * const rep =
- CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
-#ifdef VM_TRACE
- ndbout_c("Node %d fail completed", rep->failedNodeId);
-#endif
- if (rep->failedNodeId == nodeId ||
- waitCompleted == 1)
- return 1326;
- // wait for next signal
- // master node will report aborted backup
- break;
- }
- case GSN_NODE_FAILREP:{
- const NodeFailRep * const rep =
- CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
- if (NodeBitmask::get(rep->theNodes,nodeId) ||
- waitCompleted == 1)
- return 1326;
- // wait for next signal
- // master node will report aborted backup
- break;
- }
- default:
- report_unknown_signal(signal);
- return SEND_OR_RECEIVE_FAILED;
- }
- }
-}
-
-int
-MgmtSrvr::abortBackup(Uint32 backupId)
-{
- SignalSender ss(theFacade);
- ss.lock(); // lock will be released on exit
-
- bool next;
- NodeId nodeId = 0;
- while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
- theFacade->get_node_alive(nodeId) == false);
-
- if(!next){
- return NO_CONTACT_WITH_DB_NODES;
- }
-
- SimpleSignal ssig;
-
- AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
- ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
- AbortBackupOrd::SignalLength);
-
- ord->requestType = AbortBackupOrd::ClientAbort;
- ord->senderData = 19;
- ord->backupId = backupId;
-
- return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
-}
-
-
-MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
- : m_mgmsrv(m)
-{
- m_reserved_nodes.clear();
- m_alloc_timeout= 0;
-}
-
-MgmtSrvr::Allocated_resources::~Allocated_resources()
-{
- Guard g(m_mgmsrv.m_node_id_mutex);
- if (!m_reserved_nodes.isclear()) {
- m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes);
- // node has been reserved, force update signal to ndb nodes
- m_mgmsrv.updateStatus();
-
- char tmp_str[128];
- m_mgmsrv.m_reserved_nodes.getText(tmp_str);
- g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
- get_nodeid(), tmp_str);
- }
-}
-
-void
-MgmtSrvr::Allocated_resources::reserve_node(NodeId id, NDB_TICKS timeout)
-{
- m_reserved_nodes.set(id);
- m_alloc_timeout= NdbTick_CurrentMillisecond() + timeout;
-}
-
-bool
-MgmtSrvr::Allocated_resources::is_timed_out(NDB_TICKS tick)
-{
- if (m_alloc_timeout && tick > m_alloc_timeout)
- {
- g_eventLogger.info("Mgmt server state: nodeid %d timed out.",
- get_nodeid());
- return true;
- }
- return false;
-}
-
-NodeId
-MgmtSrvr::Allocated_resources::get_nodeid() const
-{
- for(Uint32 i = 0; i < MAX_NODES; i++)
- {
- if (m_reserved_nodes.get(i))
- return i;
- }
- return 0;
-}
-
-int
-MgmtSrvr::setDbParameter(int node, int param, const char * value,
- BaseString& msg){
-
- if(NdbMutex_Lock(m_configMutex))
- return -1;
-
- /**
- * Check parameter
- */
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_NODE);
- if(iter.first() != 0){
- msg.assign("Unable to find node section (iter.first())");
- NdbMutex_Unlock(m_configMutex);
- return -1;
- }
-
- Uint32 type = NODE_TYPE_DB + 1;
- if(node != 0){
- if(iter.find(CFG_NODE_ID, node) != 0){
- msg.assign("Unable to find node (iter.find())");
- NdbMutex_Unlock(m_configMutex);
- return -1;
- }
- if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
- msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
- NdbMutex_Unlock(m_configMutex);
- return -1;
- }
- } else {
- do {
- if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
- msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
- NdbMutex_Unlock(m_configMutex);
- return -1;
- }
- if(type == NODE_TYPE_DB)
- break;
- } while(iter.next() == 0);
- }
-
- if(type != NODE_TYPE_DB){
- msg.assfmt("Invalid node type or no such node (%d %d)",
- type, NODE_TYPE_DB);
- NdbMutex_Unlock(m_configMutex);
- return -1;
- }
-
- int p_type;
- unsigned val_32;
- Uint64 val_64;
- const char * val_char;
- do {
- p_type = 0;
- if(iter.get(param, &val_32) == 0){
- val_32 = atoi(value);
- break;
- }
-
- p_type++;
- if(iter.get(param, &val_64) == 0){
- val_64 = strtoll(value, 0, 10);
- break;
- }
- p_type++;
- if(iter.get(param, &val_char) == 0){
- val_char = value;
- break;
- }
- msg.assign("Could not get parameter");
- NdbMutex_Unlock(m_configMutex);
- return -1;
- } while(0);
-
- bool res = false;
- do {
- int ret = iter.get(CFG_TYPE_OF_SECTION, &type);
- assert(ret == 0);
-
- if(type != NODE_TYPE_DB)
- continue;
-
- Uint32 node;
- ret = iter.get(CFG_NODE_ID, &node);
- assert(ret == 0);
-
- ConfigValues::Iterator i2(_config->m_configValues->m_config,
- iter.m_config);
- switch(p_type){
- case 0:
- res = i2.set(param, val_32);
- ndbout_c("Updating node %d param: %d to %d", node, param, val_32);
- break;
- case 1:
- res = i2.set(param, val_64);
- ndbout_c("Updating node %d param: %d to %u", node, param, val_32);
- break;
- case 2:
- res = i2.set(param, val_char);
- ndbout_c("Updating node %d param: %d to %s", node, param, val_char);
- break;
- default:
- require(false);
- }
- assert(res);
- } while(node == 0 && iter.next() == 0);
-
- msg.assign("Success");
- NdbMutex_Unlock(m_configMutex);
- return 0;
-}
-int
-MgmtSrvr::setConnectionDbParameter(int node1,
- int node2,
- int param,
- int value,
- BaseString& msg){
- Uint32 current_value,new_value;
-
- DBUG_ENTER("MgmtSrvr::setConnectionDbParameter");
-
- if(NdbMutex_Lock(m_configMutex))
- {
- DBUG_RETURN(-1);
- }
-
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_CONNECTION);
-
- if(iter.first() != 0){
- msg.assign("Unable to find connection section (iter.first())");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-1);
- }
-
- for(;iter.valid();iter.next()) {
- Uint32 n1,n2;
- iter.get(CFG_CONNECTION_NODE_1, &n1);
- iter.get(CFG_CONNECTION_NODE_2, &n2);
- if((n1 == (unsigned)node1 && n2 == (unsigned)node2)
- || (n1 == (unsigned)node2 && n2 == (unsigned)node1))
- break;
- }
- if(!iter.valid()) {
- msg.assign("Unable to find connection between nodes");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-2);
- }
-
- if(iter.get(param, &current_value) != 0) {
- msg.assign("Unable to get current value of parameter");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-3);
- }
-
- ConfigValues::Iterator i2(_config->m_configValues->m_config,
- iter.m_config);
-
- if(i2.set(param, (unsigned)value) == false) {
- msg.assign("Unable to set new value of parameter");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-4);
- }
-
- if(iter.get(param, &new_value) != 0) {
- msg.assign("Unable to get parameter after setting it.");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-5);
- }
-
- msg.assfmt("%u -> %u",current_value,new_value);
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(1);
-}
-
-
-int
-MgmtSrvr::getConnectionDbParameter(int node1,
- int node2,
- int param,
- int *value,
- BaseString& msg){
- DBUG_ENTER("MgmtSrvr::getConnectionDbParameter");
-
- if(NdbMutex_Lock(m_configMutex))
- {
- DBUG_RETURN(-1);
- }
-
- ndb_mgm_configuration_iterator
- iter(* _config->m_configValues, CFG_SECTION_CONNECTION);
-
- if(iter.first() != 0){
- msg.assign("Unable to find connection section (iter.first())");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-1);
- }
-
- for(;iter.valid();iter.next()) {
- Uint32 n1=0,n2=0;
- iter.get(CFG_CONNECTION_NODE_1, &n1);
- iter.get(CFG_CONNECTION_NODE_2, &n2);
- if((n1 == (unsigned)node1 && n2 == (unsigned)node2)
- || (n1 == (unsigned)node2 && n2 == (unsigned)node1))
- break;
- }
- if(!iter.valid()) {
- msg.assign("Unable to find connection between nodes");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-1);
- }
-
- if(iter.get(param, (Uint32*)value) != 0) {
- msg.assign("Unable to get current value of parameter");
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(-1);
- }
-
- msg.assfmt("%d",*value);
- NdbMutex_Unlock(m_configMutex);
- DBUG_RETURN(1);
-}
-
-void MgmtSrvr::transporter_connect(NDB_SOCKET_TYPE sockfd)
-{
- if (theFacade->get_registry()->connect_server(sockfd))
- {
- /**
- * Force an update_connections() so that the
- * ClusterMgr and TransporterFacade is up to date
- * with the new connection.
- * Important for correct node id reservation handling
- */
- NdbMutex_Lock(theFacade->theMutexPtr);
- theFacade->get_registry()->update_connections();
- NdbMutex_Unlock(theFacade->theMutexPtr);
- }
-}
-
-int MgmtSrvr::connect_to_self(void)
-{
- int r= 0;
- m_local_mgm_handle= ndb_mgm_create_handle();
- snprintf(m_local_mgm_connect_string,sizeof(m_local_mgm_connect_string),
- "localhost:%u",getPort());
- ndb_mgm_set_connectstring(m_local_mgm_handle, m_local_mgm_connect_string);
-
- if((r= ndb_mgm_connect(m_local_mgm_handle, 0, 0, 0)) < 0)
- {
- ndb_mgm_destroy_handle(&m_local_mgm_handle);
- return r;
- }
- // TransporterRegistry now owns this NdbMgmHandle and will destroy it.
- theFacade->get_registry()->set_mgm_handle(m_local_mgm_handle);
-
- return 0;
-}
-
-template class MutexVector<unsigned short>;
-template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
-template class Vector<EventSubscribeReq>;
-template class MutexVector<EventSubscribeReq>;
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
deleted file mode 100644
index 255a3e962ea..00000000000
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ /dev/null
@@ -1,648 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef MgmtSrvr_H
-#define MgmtSrvr_H
-
-#include <kernel_types.h>
-#include "Config.hpp"
-#include <NdbCondition.h>
-#include <mgmapi.h>
-
-#include <NdbTCP.h>
-#include <ConfigRetriever.hpp>
-#include <Vector.hpp>
-#include <NodeBitmask.hpp>
-#include <signaldata/ManagementServer.hpp>
-#include <ndb_version.h>
-#include <EventLogger.hpp>
-#include <signaldata/EventSubscribeReq.hpp>
-
-#include <SignalSender.hpp>
-
-/**
- * @desc Block number for Management server.
- * @todo This should probably be somewhere else. I don't know where atm.
- */
-#define MGMSRV 1
-
-#define MGM_ERROR_MAX_INJECT_SESSION_ONLY 10000
-
-extern int g_errorInsert;
-
-class ConfigInfoServer;
-class NdbApiSignal;
-class Config;
-class SetLogLevelOrd;
-class SocketServer;
-
-class Ndb_mgmd_event_service : public EventLoggerBase
-{
- friend class MgmtSrvr;
-public:
- struct Event_listener : public EventLoggerBase {
- Event_listener() {}
- NDB_SOCKET_TYPE m_socket;
- Uint32 m_parsable;
- };
-
-private:
- class MgmtSrvr * m_mgmsrv;
- MutexVector<Event_listener> m_clients;
-public:
- Ndb_mgmd_event_service(class MgmtSrvr * m) : m_clients(5) {
- m_mgmsrv = m;
- }
-
- void add_listener(const Event_listener&);
- void check_listeners();
- void update_max_log_level(const LogLevel&);
- void update_log_level(const LogLevel&);
-
- void log(int eventType, const Uint32* theData, NodeId nodeId);
-
- void stop_sessions();
-
- Event_listener& operator[](unsigned i) { return m_clients[i]; }
- const Event_listener& operator[](unsigned i) const { return m_clients[i]; }
- void lock() { m_clients.lock(); }
- void unlock(){ m_clients.unlock(); }
-};
-
-/**
- * @class MgmtSrvr
- * @brief Main class for the management server.
- *
- * It has one interface to be used by a local client.
- * With the methods it's possible to send different kind of commands to
- * DB processes, as log level, set trace number etc.
- *
- * A MgmtSrvr creates a ConfigInfoServer which serves request on TCP sockets.
- * The requests come typical from DB and API processes which want
- * to fetch its configuration parameters. The MgmtSrvr knows about the
- * configuration by reading a configuration file.
- *
- * The MgmtSrvr class corresponds in some ways to the Ndb class in API.
- * It creates a TransporterFacade, receives signals and defines signals
- * to send and receive.
- */
-class MgmtSrvr {
-
-public:
- // some compilers need all of this
- class Allocated_resources;
- friend class Allocated_resources;
- class Allocated_resources {
- public:
- Allocated_resources(class MgmtSrvr &m);
- ~Allocated_resources();
- // methods to reserve/allocate resources which
- // will be freed when running destructor
- void reserve_node(NodeId id, NDB_TICKS timeout);
- bool is_timed_out(NDB_TICKS tick);
- bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId); }
- bool is_reserved(NodeBitmask mask) { return !mask.bitAND(m_reserved_nodes).isclear(); }
- bool isclear() { return m_reserved_nodes.isclear(); }
- NodeId get_nodeid() const;
- private:
- MgmtSrvr &m_mgmsrv;
- NodeBitmask m_reserved_nodes;
- NDB_TICKS m_alloc_timeout;
- };
- NdbMutex *m_node_id_mutex;
-
- /**
- * Start/initate the event log.
- */
- void startEventLog();
-
- /**
- * Stop the event log.
- */
- void stopEventLog();
-
- /**
- * Enable/disable eventlog log levels/severities.
- *
- * @param serverity the log level/serverity.
- * @return true if the severity was enabled.
- */
- bool setEventLogFilter(int severity, int enable);
-
- /**
- * Returns true if the log level/severity is enabled.
- *
- * @param severity the severity level.
- */
- bool isEventLogFilterEnabled(int severity);
-
- /**
- * This enum specifies the different signal loggig modes possible to set
- * with the setSignalLoggingMode method.
- */
- enum LogMode {In, Out, InOut, Off};
-
- /* Constructor */
-
- MgmtSrvr(SocketServer *socket_server,
- const char *config_filename, /* Where to save config */
- const char *connect_string);
- int init();
- NodeId getOwnNodeId() const {return _ownNodeId;};
-
- /**
- * Read (initial) config file, create TransporterFacade,
- * define signals, create ConfigInfoServer.
- * @return true if succeeded, otherwise false
- */
- bool check_start(); // may be run before start to check that some things are ok
- bool start(BaseString &error_string);
-
- ~MgmtSrvr();
-
- /**
- * Get status on a node.
- * address may point to a common area (e.g. from inet_addr)
- * There is no gaurentee that it is preserved across calls.
- * Copy the string if you are not going to use it immediately.
- */
- int status(int nodeId,
- ndb_mgm_node_status * status,
- Uint32 * version,
- Uint32 * phase,
- bool * systemShutdown,
- Uint32 * dynamicId,
- Uint32 * nodeGroup,
- Uint32 * connectCount,
- const char **address);
-
- // All the functions below may return any of this error codes:
- // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE,
- // COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED
-
- /**
- * Save a configuration to permanent storage
- */
- int saveConfig(const Config *);
-
- /**
- * Save the running configuration
- */
- int saveConfig() {
- return saveConfig(_config);
- };
-
- /**
- * Read configuration from file, or from another MGM server
- */
- Config *readConfig();
-
- /**
- * Fetch configuration from another MGM server
- */
- Config *fetchConfig();
-
- /**
- * Stop a node
- *
- * @param processId: Id of the DB process to stop
- * @return 0 if succeeded, otherwise: as stated above, plus:
- */
- int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort,
- int *stopSelf);
-
- int shutdownMGM(int *stopCount, bool abort, int *stopSelf);
-
- /**
- * shutdown the DB nodes
- */
- int shutdownDB(int * cnt = 0, bool abort = false);
-
- /**
- * print version info about a node
- *
- * @param processId: Id of the DB process to stop
- * @return 0 if succeeded, otherwise: as stated above, plus:
- */
- int versionNode(int nodeId, Uint32 &version, const char **address);
-
- /**
- * Maintenance on the system
- */
- int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0);
-
-
- /**
- * Resume from maintenance on the system
- */
- int exitSingleUser(int * cnt = 0, bool abort = false);
-
- /**
- * Start DB process.
- * @param processId: Id of the DB process to start
- * @return 0 if succeeded, otherwise: as stated above, plus:
- */
- int start(int processId);
-
- /**
- * Restart nodes
- * @param processId: Id of the DB process to start
- */
- int restartNodes(const Vector<NodeId> &node_ids,
- int *stopCount, bool nostart,
- bool initialStart, bool abort, int *stopSelf);
-
- /**
- * Restart all DB nodes
- */
- int restartDB(bool nostart, bool initialStart,
- bool abort = false,
- int * stopCount = 0);
-
- struct BackupEvent {
- enum Event {
- BackupStarted = 1,
- BackupFailedToStart = 2,
- BackupCompleted = 3,
- BackupAborted = 4
- } Event;
-
- NdbNodeBitmask Nodes;
- union {
- struct {
- Uint32 BackupId;
- } Started ;
- struct {
- Uint32 ErrorCode;
- } FailedToStart ;
- struct {
- Uint64 NoOfBytes;
- Uint64 NoOfRecords;
- Uint32 BackupId;
- Uint32 NoOfLogBytes;
- Uint32 NoOfLogRecords;
- Uint32 startGCP;
- Uint32 stopGCP;
- } Completed ;
- struct {
- Uint32 BackupId;
- Uint32 Reason;
- Uint32 ErrorCode;
- } Aborted ;
- };
- };
-
- /**
- * Backup functionallity
- */
- int startBackup(Uint32& backupId, int waitCompleted= 2);
- int abortBackup(Uint32 backupId);
- int performBackup(Uint32* backupId);
-
- //**************************************************************************
- // Description: Set event report level for a DB process
- // Parameters:
- // processId: Id of the DB process
- // level: Event report level
- // isResend: Flag to indicate for resending log levels during node restart
- // Returns: 0 if succeeded, otherwise: as stated above, plus:
- // INVALID_LEVEL
- //**************************************************************************
-
- int setEventReportingLevelImpl(int processId, const EventSubscribeReq& ll);
- int setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll);
-
- /**
- * Insert an error in a DB process.
- * @param processId: Id of the DB process
- * @param errorNo: The error number. > 0.
- * @return 0 if succeeded, otherwise: as stated above, plus:
- * INVALID_ERROR_NUMBER
- */
- int insertError(int processId, int errorNo);
-
-
-
- int setTraceNo(int processId, int traceNo);
- //**************************************************************************
- // Description: Set trace number in a DB process.
- // Parameters:
- // processId: Id of the DB process
- // trace: Trace number
- // Returns: 0 if succeeded, otherwise: as stated above, plus:
- // INVALID_TRACE_NUMBER
- //**************************************************************************
-
-
- int setSignalLoggingMode(int processId, LogMode mode,
- const Vector<BaseString> &blocks);
-
- int setSignalLoggingMode(int processId, LogMode mode,
- BaseString &block) {
- Vector<BaseString> v;
- v.push_back(block);
- return setSignalLoggingMode(processId, mode, v);
- }
- //**************************************************************************
- // Description: Set signal logging mode for blocks in a DB process.
- // Parameters:
- // processId: Id of the DB process
- // mode: The log mode
- // blocks: Which blocks to be affected (container of strings)
- // Returns: 0 if succeeded, otherwise: as stated above, plus:
- // INVALID_BLOCK_NAME
- //**************************************************************************
-
-
- int startSignalTracing(int processId);
- //**************************************************************************
- // Description: Start signal tracing for a DB process.
- // Parameters:
- // processId: Id of the DB process
- // Returns: 0 if succeeded, otherwise: as stated above.
- //**************************************************************************
-
-
- int stopSignalTracing(int processId);
- //**************************************************************************
- // Description: Stop signal tracing for a DB process.
- // Parameters:
- // processId: Id of the DB process
- // Returns: 0 if succeeded, otherwise: as stated above.
- //**************************************************************************
-
- /**
- * Dump State
- */
- int dumpState(int processId, const Uint32 args[], Uint32 argNo);
- int dumpState(int processId, const char* args);
-
- /**
- * Get next node id (node id gt that _nodeId)
- * of specified type and save it in _nodeId
- *
- * @return false if none found
- */
- bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
- bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type,
- struct sockaddr *client_addr,
- SOCKET_SIZE_TYPE *client_addr_len,
- int &error_code, BaseString &error_string,
- int log_event = 1);
-
- /**
- *
- */
- enum ndb_mgm_node_type getNodeType(NodeId) const;
-
- /**
- * Get error text
- *
- * @param errorCode: Error code to get a match error text for.
- * @return The error text.
- */
- const char* getErrorText(int errorCode, char *buf, int buf_sz);
-
- /**
- * Get configuration
- */
- const Config * getConfig() const;
-
- /**
- * Returns the node count for the specified node type.
- *
- * @param type The node type.
- * @return The number of nodes of the specified type.
- */
- int getNodeCount(enum ndb_mgm_node_type type) const;
-
- /**
- * Returns the port number.
- * @return port number.
- */
- int getPort() const;
-
- int setDbParameter(int node, int parameter, const char * value, BaseString&);
- int setConnectionDbParameter(int node1, int node2, int param, int value,
- BaseString& msg);
- int getConnectionDbParameter(int node1, int node2, int param,
- int *value, BaseString& msg);
-
- int connect_to_self(void);
-
- void transporter_connect(NDB_SOCKET_TYPE sockfd);
-
- ConfigRetriever *get_config_retriever() { return m_config_retriever; };
-
- const char *get_connect_address(Uint32 node_id);
- void get_connected_nodes(NodeBitmask &connected_nodes) const;
- SocketServer *get_socket_server() { return m_socket_server; }
-
- void updateStatus();
-
- //**************************************************************************
-private:
- //**************************************************************************
-
- int sendStopMgmd(NodeId nodeId,
- bool abort,
- bool stop,
- bool restart,
- bool nostart,
- bool initialStart);
-
- int sendSTOP_REQ(const Vector<NodeId> &node_ids,
- NodeBitmask &stoppedNodes,
- Uint32 singleUserNodeId,
- bool abort,
- bool stop,
- bool restart,
- bool nostart,
- bool initialStart,
- int *stopSelf);
-
- /**
- * Check if it is possible to send a signal to a (DB) process
- *
- * @param processId: Id of the process to send to
- * @return 0 OK, 1 process dead, 2 API or MGMT process, 3 not configured
- */
- int okToSendTo(NodeId nodeId, bool unCond = false);
-
- /**
- * Get block number for a block
- *
- * @param blockName: Block to get number for
- * @return -1 if block not found, otherwise block number
- */
- int getBlockNumber(const BaseString &blockName);
-
- int alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type);
- //**************************************************************************
-
- int _blockNumber;
- NodeId _ownNodeId;
- SocketServer *m_socket_server;
-
- BlockReference _ownReference;
- NdbMutex *m_configMutex;
- const Config * _config;
- Config * m_newConfig;
- BaseString m_configFilename;
- Uint32 m_nextConfigGenerationNumber;
-
- NodeBitmask m_reserved_nodes;
- struct in_addr m_connect_address[MAX_NODES];
-
- //**************************************************************************
- // Specific signal handling methods
- //**************************************************************************
-
- static void defineSignals(int blockNumber);
- //**************************************************************************
- // Description: Define all signals to be sent or received for a block
- // Parameters:
- // blockNumber: The block number send/receive
- // Returns: -
- //**************************************************************************
-
- void handleReceivedSignal(NdbApiSignal* signal);
- //**************************************************************************
- // Description: This method is called from "another" thread when a signal
- // is received. If expect the received signal and succeed to handle it
- // we signal with a condition variable to the waiting
- // thread (receiveOptimisedResponse) that the signal has arrived.
- // Parameters:
- // signal: The recieved signal
- // Returns: -
- //**************************************************************************
-
- void handleStatus(NodeId nodeId, bool alive, bool nfComplete);
- //**************************************************************************
- // Description: Handle the death of a process
- // Parameters:
- // processId: Id of the dead process.
- // Returns: -
- //**************************************************************************
-
- //**************************************************************************
- // Specific signal handling data
- //**************************************************************************
-
-
- //**************************************************************************
- //**************************************************************************
- // General signal handling methods
- // This functions are more or less copied from the Ndb class.
-
-
- /**
- * WaitSignalType defines states where each state define a set of signals
- * we accept to receive.
- * The state is set after we have sent a signal.
- * When a signal arrives we first check current state (handleReceivedSignal)
- * to verify that we expect the arrived signal.
- * It's only then we are in state accepting the arrived signal
- * we handle the signal.
- */
- enum WaitSignalType {
- NO_WAIT, // We don't expect to receive any signal
- WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation
- };
-
- /**
- * This function is called from "outside" of MgmtSrvr
- * when a signal is sent to MgmtSrvr.
- * @param mgmtSrvr: The MgmtSrvr object which shall recieve the signal.
- * @param signal: The received signal.
- */
- static void signalReceivedNotification(void* mgmtSrvr,
- NdbApiSignal* signal,
- struct LinearSectionPtr ptr[3]);
-
- /**
- * Called from "outside" of MgmtSrvr when a DB process has died.
- * @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich
- * shall receive the notification.
- * @param processId: Id of the dead process.
- */
- static void nodeStatusNotification(void* mgmSrv, Uint32 nodeId,
- bool alive, bool nfCompleted);
-
- /**
- * An event from <i>nodeId</i> has arrived
- */
- void eventReport(const Uint32 * theData);
-
-
- //**************************************************************************
- //**************************************************************************
- // General signal handling data
-
- STATIC_CONST( WAIT_FOR_RESPONSE_TIMEOUT = 300000 ); // Milliseconds
- // Max time to wait for a signal to arrive
-
- NdbApiSignal* theSignalIdleList;
- // List of unused signals
-
- Uint32 theWaitNode;
- WaitSignalType theWaitState;
- // State denoting a set of signals we accept to recieve.
-
- NdbCondition* theMgmtWaitForResponseCondPtr;
- // Condition variable used when we wait for a signal to arrive/a
- // signal arrives.
- // We wait in receiveOptimisedResponse and signal in handleReceivedSignal.
-
- NdbMgmHandle m_local_mgm_handle;
- char m_local_mgm_connect_string[20];
- class TransporterFacade * theFacade;
-
- int sendVersionReq( int processId, Uint32 &version, const char **address);
- int translateStopRef(Uint32 errCode);
-
- bool _isStopThread;
- int _logLevelThreadSleep;
- MutexVector<NodeId> m_started_nodes;
- MutexVector<EventSubscribeReq> m_log_level_requests;
- LogLevel m_nodeLogLevel[MAX_NODES];
- enum ndb_mgm_node_type nodeTypes[MAX_NODES];
- friend class MgmApiSession;
- friend class Ndb_mgmd_event_service;
- Ndb_mgmd_event_service m_event_listner;
-
- NodeId m_master_node;
-
- /**
- * Handles the thread wich upon a 'Node is started' event will
- * set the node's previous loglevel settings.
- */
- struct NdbThread* _logLevelThread;
- static void *logLevelThread_C(void *);
- void logLevelThreadRun();
-
- Config *_props;
-
- ConfigRetriever *m_config_retriever;
-};
-
-inline
-const Config *
-MgmtSrvr::getConfig() const {
- return _config;
-}
-
-#endif // MgmtSrvr_H
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
deleted file mode 100644
index eee317d780b..00000000000
--- a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <signaldata/TestOrd.hpp>
-#include <OutputStream.hpp>
-
-#include "MgmtSrvr.hpp"
-#include "SignalQueue.hpp"
-#include <InitConfigFileParser.hpp>
-#include <ConfigRetriever.hpp>
-#include <ndb_version.h>
-
-/**
- * Save a configuration to the running configuration file
- */
-int
-MgmtSrvr::saveConfig(const Config *conf) {
- BaseString newfile;
- newfile.appfmt("%s.new", m_configFilename.c_str());
-
- /* Open and write to the new config file */
- FILE *f = fopen(newfile.c_str(), "w");
- if(f == NULL) {
- /** @todo Send something apropriate to the log */
- return -1;
- }
- FileOutputStream stream(f);
- conf->printConfigFile(stream);
-
- fclose(f);
-
- /* Rename file to real name */
- rename(newfile.c_str(), m_configFilename.c_str());
-
- return 0;
-}
-
-Config *
-MgmtSrvr::readConfig() {
- Config *conf;
- InitConfigFileParser parser;
- if (m_configFilename.length())
- {
- conf = parser.parseConfig(m_configFilename.c_str());
- }
- else
- {
- ndbout_c("Reading cluster configuration using my.cnf");
- conf = parser.parse_mycnf();
- }
- return conf;
-}
-
-Config *
-MgmtSrvr::fetchConfig() {
- struct ndb_mgm_configuration * tmp = m_config_retriever->getConfig();
- if(tmp != 0){
- Config * conf = new Config();
- conf->m_configValues = tmp;
- return conf;
- }
- return 0;
-}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
deleted file mode 100644
index e80d5b3dcab..00000000000
--- a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//******************************************************************************
-// General signal handling methods
-// All implementations stolen from the Ndb class.
-// Some kind of reuse should be preferred.
-//******************************************************************************
-
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
deleted file mode 100644
index 3b8e08cf4dd..00000000000
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ /dev/null
@@ -1,1818 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ctype.h>
-
-#include <uucode.h>
-#include <socket_io.h>
-#include <util/version.h>
-#include <mgmapi.h>
-#include <EventLogger.hpp>
-#include <signaldata/SetLogLevelOrd.hpp>
-#include <LogLevel.hpp>
-#include <BaseString.hpp>
-
-#include <ConfigValues.hpp>
-#include <mgmapi_configuration.hpp>
-#include <Vector.hpp>
-#include "Services.hpp"
-#include "../mgmapi/ndb_logevent.hpp"
-
-#include <base64.h>
-#include <ndberror.h>
-
-extern bool g_StopServer;
-extern bool g_RestartServer;
-extern EventLogger g_eventLogger;
-
-static const unsigned int MAX_READ_TIMEOUT = 1000 ;
-static const unsigned int MAX_WRITE_TIMEOUT = 100 ;
-
-/**
- const char * name;
- const char * realName;
- const Type type;
- const ArgType argType;
- const ArgRequired argRequired;
- const ArgMinMax argMinMax;
- const int minVal;
- const int maxVal;
- void (T::* function)(const class Properties & args);
- const char * description;
-*/
-
-#define MGM_CMD(name, fun, desc) \
- { name, \
- 0, \
- ParserRow<MgmApiSession>::Cmd, \
- ParserRow<MgmApiSession>::String, \
- ParserRow<MgmApiSession>::Optional, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- 0, 0, \
- fun, \
- desc, 0 }
-
-#define MGM_ARG(name, type, opt, desc) \
- { name, \
- 0, \
- ParserRow<MgmApiSession>::Arg, \
- ParserRow<MgmApiSession>::type, \
- ParserRow<MgmApiSession>::opt, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- desc, 0 }
-
-#define MGM_ARG2(name, type, opt, min, max, desc) \
- { name, \
- 0, \
- ParserRow<MgmApiSession>::Arg, \
- ParserRow<MgmApiSession>::type, \
- ParserRow<MgmApiSession>::opt, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- min, max, \
- 0, \
- desc, 0 }
-
-#define MGM_END() \
- { 0, \
- 0, \
- ParserRow<MgmApiSession>::Arg, \
- ParserRow<MgmApiSession>::Int, \
- ParserRow<MgmApiSession>::Optional, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-#define MGM_CMD_ALIAS(name, realName, fun) \
- { name, \
- realName, \
- ParserRow<MgmApiSession>::CmdAlias, \
- ParserRow<MgmApiSession>::Int, \
- ParserRow<MgmApiSession>::Optional, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-#define MGM_ARG_ALIAS(name, realName, fun) \
- { name, \
- realName, \
- ParserRow<MgmApiSession>::ArgAlias, \
- ParserRow<MgmApiSession>::Int, \
- ParserRow<MgmApiSession>::Optional, \
- ParserRow<MgmApiSession>::IgnoreMinMax, \
- 0, 0, \
- 0, \
- 0, 0 }
-
-const
-ParserRow<MgmApiSession> commands[] = {
- MGM_CMD("get config", &MgmApiSession::getConfig, ""),
- MGM_ARG("version", Int, Mandatory, "Configuration version number"),
- MGM_ARG("node", Int, Optional, "Node ID"),
-
- MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""),
- MGM_ARG("version", Int, Mandatory, "Configuration version number"),
- MGM_ARG("nodetype", Int, Mandatory, "Node type"),
- MGM_ARG("transporter", String, Optional, "Transporter type"),
- MGM_ARG("nodeid", Int, Optional, "Node ID"),
- MGM_ARG("user", String, Mandatory, "Password"),
- MGM_ARG("password", String, Mandatory, "Password"),
- MGM_ARG("public key", String, Mandatory, "Public key"),
- MGM_ARG("endian", String, Optional, "Endianness"),
- MGM_ARG("name", String, Optional, "Name of connection"),
- MGM_ARG("timeout", Int, Optional, "Timeout in seconds"),
- MGM_ARG("log_event", Int, Optional, "Log failure in cluster log"),
-
- MGM_CMD("get version", &MgmApiSession::getVersion, ""),
-
- MGM_CMD("get status", &MgmApiSession::getStatus, ""),
-
- MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""),
- MGM_CMD("get cluster loglevel", &MgmApiSession::getClusterLogLevel, ""),
-
- MGM_CMD("restart node", &MgmApiSession::restart_v1, ""),
- MGM_ARG("node", String, Mandatory, "Nodes to restart"),
- MGM_ARG("initialstart", Int, Optional, "Initial start"),
- MGM_ARG("nostart", Int, Optional, "No start"),
- MGM_ARG("abort", Int, Optional, "Abort"),
-
- MGM_CMD("restart node v2", &MgmApiSession::restart_v2, ""),
- MGM_ARG("node", String, Mandatory, "Nodes to restart"),
- MGM_ARG("initialstart", Int, Optional, "Initial start"),
- MGM_ARG("nostart", Int, Optional, "No start"),
- MGM_ARG("abort", Int, Optional, "Abort"),
-
- MGM_CMD("restart all", &MgmApiSession::restartAll, ""),
- MGM_ARG("initialstart", Int, Optional, "Initial start"),
- MGM_ARG("nostart", Int, Optional, "No start"),
- MGM_ARG("abort", Int, Optional, "Abort"),
-
- MGM_CMD("insert error", &MgmApiSession::insertError, ""),
- MGM_ARG("node", Int, Mandatory, "Node to receive error"),
- MGM_ARG("error", Int, Mandatory, "Errorcode to insert"),
-
- MGM_CMD("set trace", &MgmApiSession::setTrace, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
- MGM_ARG("trace", Int, Mandatory, "Trace number"),
-
- MGM_CMD("log signals", &MgmApiSession::logSignals, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
- MGM_ARG("blocks", String, Mandatory, "Blocks (space separated)"),
- MGM_ARG("in", Int, Mandatory, "Log input signals"),
- MGM_ARG("out", Int, Mandatory, "Log output signals"),
-
- MGM_CMD("start signallog", &MgmApiSession::startSignalLog, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
-
- MGM_CMD("stop signallog", &MgmApiSession::stopSignalLog, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
-
- MGM_CMD("dump state", &MgmApiSession::dumpState, ""),
- MGM_ARG("node", Int, Mandatory ,"Node"),
- MGM_ARG("args", String, Mandatory, "Args(space separated int's)"),
-
- MGM_CMD("start backup", &MgmApiSession::startBackup, ""),
- MGM_ARG("completed", Int, Optional ,"Wait until completed"),
-
- MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""),
- MGM_ARG("id", Int, Mandatory, "Backup id"),
-
- MGM_CMD("stop", &MgmApiSession::stop_v1, ""),
- MGM_ARG("node", String, Mandatory, "Node"),
- MGM_ARG("abort", Int, Mandatory, "Node"),
-
- MGM_CMD("stop v2", &MgmApiSession::stop_v2, ""),
- MGM_ARG("node", String, Mandatory, "Node"),
- MGM_ARG("abort", Int, Mandatory, "Node"),
-
- MGM_CMD("stop all", &MgmApiSession::stopAll, ""),
- MGM_ARG("abort", Int, Mandatory, "Node"),
- MGM_ARG("stop", String, Optional, "MGM/DB or both"),
-
- MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""),
- MGM_ARG("nodeId", Int, Mandatory, "Node"),
-
- MGM_CMD("exit single user", &MgmApiSession::exitSingleUser, ""),
-
-
- MGM_CMD("start", &MgmApiSession::start, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
-
- MGM_CMD("start all", &MgmApiSession::startAll, ""),
-
- MGM_CMD("bye", &MgmApiSession::bye, ""),
-
- MGM_CMD("end session", &MgmApiSession::endSession, ""),
-
- MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
- MGM_ARG("category", Int, Mandatory, "Event category"),
- MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
-
- MGM_CMD("set cluster loglevel", &MgmApiSession::setClusterLogLevel, ""),
- MGM_ARG("node", Int, Mandatory, "Node"),
- MGM_ARG("category", Int, Mandatory, "Event category"),
- MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
-
- MGM_CMD("set logfilter", &MgmApiSession::setLogFilter, ""),
- MGM_ARG("level", Int, Mandatory, "Severety level"),
- MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
-
- MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
- MGM_ARG("node", String, Mandatory, "Node"),
- MGM_ARG("parameter", String, Mandatory, "Parameter"),
- MGM_ARG("value", String, Mandatory, "Value"),
-
- MGM_CMD("set connection parameter",
- &MgmApiSession::setConnectionParameter, ""),
- MGM_ARG("node1", String, Mandatory, "Node1 ID"),
- MGM_ARG("node2", String, Mandatory, "Node2 ID"),
- MGM_ARG("param", String, Mandatory, "Parameter"),
- MGM_ARG("value", String, Mandatory, "Value"),
-
- MGM_CMD("get connection parameter",
- &MgmApiSession::getConnectionParameter, ""),
- MGM_ARG("node1", String, Mandatory, "Node1 ID"),
- MGM_ARG("node2", String, Mandatory, "Node2 ID"),
- MGM_ARG("param", String, Mandatory, "Parameter"),
-
- MGM_CMD("listen event", &MgmApiSession::listen_event, ""),
- MGM_ARG("node", Int, Optional, "Node"),
- MGM_ARG("parsable", Int, Optional, "Parsable"),
- MGM_ARG("filter", String, Mandatory, "Event category"),
-
- MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""),
-
- MGM_CMD("check connection", &MgmApiSession::check_connection, ""),
-
- MGM_CMD("transporter connect", &MgmApiSession::transporter_connect, ""),
-
- MGM_CMD("get mgmd nodeid", &MgmApiSession::get_mgmd_nodeid, ""),
-
- MGM_CMD("report event", &MgmApiSession::report_event, ""),
- MGM_ARG("length", Int, Mandatory, "Length"),
- MGM_ARG("data", String, Mandatory, "Data"),
-
- MGM_CMD("list sessions", &MgmApiSession::listSessions, ""),
-
- MGM_CMD("get session id", &MgmApiSession::getSessionId, ""),
-
- MGM_CMD("get session", &MgmApiSession::getSession, ""),
- MGM_ARG("id", Int, Mandatory, "SessionID"),
-
- MGM_END()
-};
-
-struct PurgeStruct
-{
- NodeBitmask free_nodes;/* free nodes as reported
- * by ndbd in apiRegReqConf
- */
- BaseString *str;
- NDB_TICKS tick;
-};
-
-#define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x)
-
-#define SLEEP_ERROR_INSERTED(x) if(ERROR_INSERTED(x)){NdbSleep_SecSleep(10);}
-
-MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id)
- : SocketServer::Session(sock), m_mgmsrv(mgm)
-{
- DBUG_ENTER("MgmApiSession::MgmApiSession");
- m_input = new SocketInputStream(sock, 30000);
- m_output = new SocketOutputStream(sock, 30000);
- m_parser = new Parser_t(commands, *m_input, true, true, true);
- m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
- m_stopSelf= 0;
- m_ctx= NULL;
- m_session_id= session_id;
- m_mutex= NdbMutex_Create();
- m_errorInsert= 0;
- DBUG_VOID_RETURN;
-}
-
-MgmApiSession::~MgmApiSession()
-{
- DBUG_ENTER("MgmApiSession::~MgmApiSession");
- if (m_input)
- delete m_input;
- if (m_output)
- delete m_output;
- if (m_parser)
- delete m_parser;
- if (m_allocated_resources)
- delete m_allocated_resources;
- if(m_socket != NDB_INVALID_SOCKET)
- {
- NDB_CLOSE_SOCKET(m_socket);
- m_socket= NDB_INVALID_SOCKET;
- }
- if(m_stopSelf < 0)
- g_RestartServer= true;
- if(m_stopSelf)
- g_StopServer= true;
- NdbMutex_Destroy(m_mutex);
- DBUG_VOID_RETURN;
-}
-
-void
-MgmApiSession::runSession()
-{
- DBUG_ENTER("MgmApiSession::runSession");
-
- Parser_t::Context ctx;
- ctx.m_mutex= m_mutex;
- m_ctx= &ctx;
- bool stop= false;
- while(!stop) {
- NdbMutex_Lock(m_mutex);
-
- m_input->reset_timeout();
- m_output->reset_timeout();
-
- m_parser->run(ctx, *this);
-
- if(ctx.m_currentToken == 0)
- {
- NdbMutex_Unlock(m_mutex);
- break;
- }
-
- switch(ctx.m_status) {
- case Parser_t::UnknownCommand:
- break;
- default:
- break;
- }
-
- stop= m_stop;
- NdbMutex_Unlock(m_mutex);
- };
-
- NdbMutex_Lock(m_mutex);
- m_ctx= NULL;
- if(m_socket != NDB_INVALID_SOCKET)
- {
- NDB_CLOSE_SOCKET(m_socket);
- m_socket= NDB_INVALID_SOCKET;
- }
- NdbMutex_Unlock(m_mutex);
- DBUG_VOID_RETURN;
-}
-
-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::get_nodeid(Parser_t::Context &,
- const class Properties &args)
-{
- const char *cmd= "get nodeid reply";
- Uint32 version, nodeid= 0, nodetype= 0xff;
- Uint32 timeout= 20; // default seconds timeout
- const char * transporter;
- const char * user;
- const char * password;
- const char * public_key;
- const char * endian= NULL;
- const char * name= NULL;
- Uint32 log_event= 1;
- bool log_event_version;
- union { long l; char c[sizeof(long)]; } endian_check;
-
- args.get("version", &version);
- args.get("nodetype", &nodetype);
- args.get("transporter", &transporter);
- args.get("nodeid", &nodeid);
- args.get("user", &user);
- args.get("password", &password);
- args.get("public key", &public_key);
- args.get("endian", &endian);
- args.get("name", &name);
- args.get("timeout", &timeout);
- /* for backwards compatability keep track if client uses new protocol */
- log_event_version= args.get("log_event", &log_event);
-
- endian_check.l = 1;
- if(endian
- && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) {
- m_output->println(cmd);
- m_output->println("result: Node does not have the same endianness as the management server.");
- m_output->println("");
- return;
- }
-
- bool compatible;
- switch (nodetype) {
- case NODE_TYPE_MGM:
- case NODE_TYPE_API:
- compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
- break;
- case NODE_TYPE_DB:
- compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
- break;
- default:
- m_output->println(cmd);
- m_output->println("result: unknown nodetype %d", nodetype);
- m_output->println("");
- return;
- }
-
- struct sockaddr_in addr;
- SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
- if (r != 0 ) {
- m_output->println(cmd);
- m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
- m_output->println("");
- return;
- }
-
- NodeId tmp= nodeid;
- if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
- BaseString error_string;
- int error_code;
- NDB_TICKS tick= 0;
- /* only report error on second attempt as not to clog the cluster log */
- while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
- (struct sockaddr*)&addr, &addrlen,
- error_code, error_string,
- tick == 0 ? 0 : log_event))
- {
- /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
- if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH)
- {
- // attempt to free any timed out reservations
- tick= NdbTick_CurrentMillisecond();
- struct PurgeStruct ps;
- m_mgmsrv.get_connected_nodes(ps.free_nodes);
- // invert connected_nodes to get free nodes
- ps.free_nodes.bitXORC(NodeBitmask());
- ps.str= 0;
- ps.tick= tick;
- m_mgmsrv.get_socket_server()->
- foreachSession(stop_session_if_timed_out,&ps);
- m_mgmsrv.get_socket_server()->checkSessions();
- error_string = "";
- continue;
- }
- const char *alias;
- const char *str;
- alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
- nodetype, &str);
- m_output->println(cmd);
- m_output->println("result: %s", error_string.c_str());
- /* only use error_code protocol if client knows about it */
- if (log_event_version)
- m_output->println("error_code: %d", error_code);
- m_output->println("");
- return;
- }
- }
-
-#if 0
- if (!compatible){
- m_output->println(cmd);
- m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
- NDB_VERSION, version);
- m_output->println("");
- return;
- }
-#endif
-
- m_output->println(cmd);
- m_output->println("nodeid: %u", tmp);
- m_output->println("result: Ok");
- m_output->println("");
- m_allocated_resources->reserve_node(tmp, timeout*1000);
-
- if (name)
- g_eventLogger.info("Node %d: %s", tmp, name);
-
- return;
-}
-
-void
-MgmApiSession::getConfig(Parser_t::Context &,
- const class Properties &args)
-{
- Uint32 version, node = 0;
-
- args.get("version", &version);
- args.get("node", &node);
-
- const Config *conf = m_mgmsrv.getConfig();
- if(conf == NULL) {
- m_output->println("get config reply");
- m_output->println("result: Could not fetch configuration");
- m_output->println("");
- return;
- }
-
- 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;
- }
- }
-
- NdbMutex_Lock(m_mgmsrv.m_configMutex);
- const ConfigValues * cfg = &conf->m_configValues->m_config;
-
- UtilBuffer src;
- cfg->pack(src);
- NdbMutex_Unlock(m_mgmsrv.m_configMutex);
-
- char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
- (void) base64_encode(src.get_data(), src.length(), tmp_str);
-
- SLEEP_ERROR_INSERTED(1);
-
- m_output->println("get config reply");
- m_output->println("result: Ok");
- m_output->println("Content-Length: %d", strlen(tmp_str));
- m_output->println("Content-Type: ndbconfig/octet-stream");
- SLEEP_ERROR_INSERTED(2);
- m_output->println("Content-Transfer-Encoding: base64");
- m_output->println("");
- if(ERROR_INSERTED(3))
- {
- int l= strlen(tmp_str);
- tmp_str[l/2]='\0';
- m_output->println(tmp_str);
- NdbSleep_SecSleep(10);
- }
- m_output->println(tmp_str);
-
- free(tmp_str);
- return;
-}
-
-void
-MgmApiSession::insertError(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node = 0, error = 0;
- int result= 0;
-
- args.get("node", &node);
- args.get("error", &error);
-
- if(node==m_mgmsrv.getOwnNodeId()
- && error < MGM_ERROR_MAX_INJECT_SESSION_ONLY)
- {
- m_errorInsert= error;
- if(error==0)
- g_errorInsert= error;
- }
- else
- {
- result= m_mgmsrv.insertError(node, error);
- }
-
- m_output->println("insert error reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::setTrace(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node = 0, trace = 0;
-
- args.get("node", &node);
- args.get("trace", &trace);
-
- int result = m_mgmsrv.setTraceNo(node, trace);
-
- m_output->println("set trace reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::getVersion(Parser<MgmApiSession>::Context &,
- Properties const &) {
- m_output->println("version");
- m_output->println("id: %d", NDB_VERSION);
- m_output->println("major: %d", getMajor(NDB_VERSION));
- m_output->println("minor: %d", getMinor(NDB_VERSION));
- m_output->println("string: %s", NDB_VERSION_STRING);
- m_output->println("");
-}
-
-void
-MgmApiSession::startBackup(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- DBUG_ENTER("MgmApiSession::startBackup");
- unsigned backupId;
- Uint32 completed= 2;
- int result;
-
- args.get("completed", &completed);
-
- result = m_mgmsrv.startBackup(backupId, completed);
-
- m_output->println("start backup reply");
- if(result != 0)
- {
- m_output->println("result: %s", get_error_text(result));
- }
- else{
- m_output->println("result: Ok");
- if (completed)
- m_output->println("id: %d", backupId);
- }
- m_output->println("");
- DBUG_VOID_RETURN;
-}
-
-void
-MgmApiSession::abortBackup(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 id = 0;
-
- args.get("id", &id);
-
- int result = m_mgmsrv.abortBackup(id);
-
- m_output->println("abort backup reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-/*****************************************************************************/
-
-void
-MgmApiSession::dumpState(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node;
- BaseString args_str;
-
- args.get("node", &node);
- args.get("args", args_str);
-
- int result = m_mgmsrv.dumpState(node, args_str.c_str());
- m_output->println("dump state reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-
-void
-MgmApiSession::bye(Parser<MgmApiSession>::Context &,
- Properties const &) {
- m_stop = true;
-}
-
-void
-MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
- Properties const &) {
- if(m_allocated_resources)
- delete m_allocated_resources;
-
- m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
-
- SLEEP_ERROR_INSERTED(4);
- m_output->println("end session reply");
-}
-
-void
-MgmApiSession::getClusterLogLevel(Parser<MgmApiSession>::Context & , Properties const &) {
- const char* names[] = { "startup",
- "shutdown",
- "statistics",
- "checkpoint",
- "noderestart",
- "connection",
- "info",
- "warning",
- "error",
- "congestion",
- "debug",
- "backup" };
-
- int loglevel_count = (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1) ;
- LogLevel::EventCategory category;
-
- m_output->println("get cluster loglevel");
- for(int i = 0; i < loglevel_count; i++) {
- category = (LogLevel::EventCategory) i;
- m_output->println("%s: %d", names[i], m_mgmsrv.m_event_listner[0].m_logLevel.getLogLevel(category));
- }
- m_output->println("");
-}
-
-void
-MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- const char *reply= "set cluster loglevel reply";
- Uint32 node, level, cat;
- BaseString errorString;
- DBUG_ENTER("MgmApiSession::setClusterLogLevel");
- args.get("node", &node);
- args.get("category", &cat);
- args.get("level", &level);
-
- DBUG_PRINT("enter",("node=%d, category=%d, level=%d", node, cat, level));
-
- if(level > NDB_MGM_MAX_LOGLEVEL) {
- m_output->println(reply);
- m_output->println("result: Invalid loglevel %d", level);
- m_output->println("");
- DBUG_VOID_RETURN;
- }
-
- LogLevel::EventCategory category=
- (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
-
- m_mgmsrv.m_event_listner.lock();
- if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level))
- {
- m_output->println(reply);
- m_output->println("result: Invalid category %d", category);
- m_output->println("");
- m_mgmsrv.m_event_listner.unlock();
- DBUG_VOID_RETURN;
- }
- m_mgmsrv.m_event_listner.unlock();
-
- {
- LogLevel tmp;
- m_mgmsrv.m_event_listner.update_max_log_level(tmp);
- }
-
- m_output->println(reply);
- m_output->println("result: Ok");
- m_output->println("");
- DBUG_VOID_RETURN;
-}
-
-void
-MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node = 0, level = 0, cat;
- BaseString errorString;
- SetLogLevelOrd logLevel;
- logLevel.clear();
- args.get("node", &node);
- args.get("category", &cat);
- args.get("level", &level);
-
- if(level > NDB_MGM_MAX_LOGLEVEL) {
- m_output->println("set loglevel reply");
- m_output->println("result: Invalid loglevel", errorString.c_str());
- m_output->println("");
- return;
- }
-
- LogLevel::EventCategory category=
- (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
-
- {
- LogLevel ll;
- ll.setLogLevel(category,level);
- m_mgmsrv.m_event_listner.update_max_log_level(ll);
- }
-
- m_output->println("set loglevel reply");
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node;
-
- args.get("node", &node);
-
- int result = m_mgmsrv.stopSignalTracing(node);
-
- m_output->println("stop signallog");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::restart_v1(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- restart(args,1);
-}
-
-void
-MgmApiSession::restart_v2(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- restart(args,2);
-}
-
-void
-MgmApiSession::restart(Properties const &args, int version) {
- Uint32
- nostart = 0,
- initialstart = 0,
- abort = 0;
- char *nodes_str;
- Vector<NodeId> nodes;
-
- args.get("initialstart", &initialstart);
- args.get("nostart", &nostart);
- args.get("abort", &abort);
- args.get("node", (const char **)&nodes_str);
-
- char *p, *last;
- for((p = strtok_r(nodes_str, " ", &last));
- p;
- (p = strtok_r(NULL, " ", &last))) {
- nodes.push_back(atoi(p));
- }
-
- int restarted = 0;
- int result= m_mgmsrv.restartNodes(nodes,
- &restarted,
- nostart != 0,
- initialstart != 0,
- abort != 0,
- &m_stopSelf);
-
- m_output->println("restart reply");
- if(result != 0){
- m_output->println("result: %d-%s", result, get_error_text(result));
- } else
- m_output->println("result: Ok");
- m_output->println("restarted: %d", restarted);
- if(version>1)
- m_output->println("disconnect: %d", (m_stopSelf)?1:0);
- m_output->println("");
-}
-
-void
-MgmApiSession::restartAll(Parser<MgmApiSession>::Context &,
- Properties const &args)
-{
- Uint32 nostart = 0;
- Uint32 initialstart = 0;
- Uint32 abort = 0;
-
- args.get("initialstart", &initialstart);
- args.get("abort", &abort);
- args.get("nostart", &nostart);
-
- int count = 0;
- int result = m_mgmsrv.restartDB(nostart, initialstart, abort, &count);
-
- m_output->println("restart reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("restarted: %d", count);
- m_output->println("");
-}
-
-static void
-printNodeStatus(OutputStream *output,
- MgmtSrvr &mgmsrv,
- enum ndb_mgm_node_type type) {
- NodeId nodeId = 0;
- while(mgmsrv.getNextNodeId(&nodeId, type)) {
- enum ndb_mgm_node_status status;
- Uint32 startPhase = 0,
- version = 0,
- dynamicId = 0,
- nodeGroup = 0,
- connectCount = 0;
- bool system;
- const char *address= NULL;
- mgmsrv.status(nodeId, &status, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount,
- &address);
- output->println("node.%d.type: %s",
- nodeId,
- ndb_mgm_get_node_type_string(type));
- output->println("node.%d.status: %s",
- nodeId,
- ndb_mgm_get_node_status_string(status));
- output->println("node.%d.version: %d", nodeId, version);
- 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);
- output->println("node.%d.address: %s", nodeId, address ? address : "");
- }
-
-}
-
-void
-MgmApiSession::getStatus(Parser<MgmApiSession>::Context &,
- Properties const &) {
- int noOfNodes = 0;
-
- NodeId nodeId = 0;
- while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- noOfNodes++;
- }
- nodeId = 0;
- while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_API)){
- noOfNodes++;
- }
- nodeId = 0;
- while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){
- noOfNodes++;
- }
- SLEEP_ERROR_INSERTED(5);
- m_output->println("node status");
- SLEEP_ERROR_INSERTED(6);
- m_output->println("nodes: %d", noOfNodes);
- m_mgmsrv.updateStatus();
- SLEEP_ERROR_INSERTED(7);
- printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB);
- printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM);
- SLEEP_ERROR_INSERTED(8);
- printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API);
- SLEEP_ERROR_INSERTED(9);
-
- nodeId = 0;
-
- m_output->println("");
-}
-
-void
-MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &,
- Properties const &) {
- const char* names[] = { "enabled",
- "debug",
- "info",
- "warning",
- "error",
- "critical",
- "alert" };
-
- m_output->println("clusterlog");
- for(int i = 0; i < 7; i++) {
- m_output->println("%s: %d",
- names[i], m_mgmsrv.isEventLogFilterEnabled(i));
- }
- m_output->println("");
-}
-
-void
-MgmApiSession::stop_v1(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- stop(args,1);
-}
-
-void
-MgmApiSession::stop_v2(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- stop(args,2);
-}
-
-void
-MgmApiSession::stop(Properties const &args, int version) {
- Uint32 abort;
- char *nodes_str;
- Vector<NodeId> nodes;
-
- args.get("node", (const char **)&nodes_str);
- if(nodes_str == NULL)
- {
- m_output->println("stop reply");
- m_output->println("result: empty node list");
- m_output->println("");
- return;
- }
- args.get("abort", &abort);
-
- char *p, *last;
- for((p = strtok_r(nodes_str, " ", &last));
- p;
- (p = strtok_r(NULL, " ", &last))) {
- nodes.push_back(atoi(p));
- }
-
- int stopped= 0;
- int result= 0;
- if (nodes.size())
- result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0, &m_stopSelf);
-
- m_output->println("stop reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("stopped: %d", stopped);
- if(version>1)
- m_output->println("disconnect: %d", (m_stopSelf)?1:0);
- m_output->println("");
-}
-
-void
-MgmApiSession::stopAll(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- int stopped[2] = {0,0};
- Uint32 abort;
- args.get("abort", &abort);
-
- BaseString stop;
- const char* tostop= "db";
- int ver=1;
- if (args.get("stop", stop))
- {
- tostop= stop.c_str();
- ver= 2;
- }
-
- int result= 0;
- if(strstr(tostop,"db"))
- result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0);
- if(!result && strstr(tostop,"mgm"))
- result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf);
-
- m_output->println("stop reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("stopped: %d", stopped[0]+stopped[1]);
- if(ver >1)
- m_output->println("disconnect: %d", (m_stopSelf)?1:0);
- m_output->println("");
-}
-
-void
-MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- int stopped = 0;
- Uint32 nodeId = 0;
- int result= 0;
- args.get("nodeId", &nodeId);
-
- result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
- m_output->println("enter single user reply");
- if(result != 0) {
- m_output->println("result: %s", get_error_text(result));
- }
- else {
- m_output->println("result: Ok");
- }
- m_output->println("");
-}
-
-void
-MgmApiSession::exitSingleUser(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- int stopped = 0;
- int result = m_mgmsrv.exitSingleUser(&stopped, false);
- m_output->println("exit single user reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-
-void
-MgmApiSession::startSignalLog(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node;
-
- args.get("node", &node);
-
- int result = m_mgmsrv.startSignalTracing(node);
-
- m_output->println("start signallog reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::logSignals(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node = 0, in = 0, out = 0;
- // BaseString blocks;
- BaseString blockList;
- char * blockName;
- args.get("node", &node);
- args.get("in", &in);
- args.get("out", &out);
- args.get("blocks", blockList);
- // fast fix - pekka
- char buf[200];
- BaseString::snprintf(buf, 200, "%s", blockList.c_str());
- Vector<BaseString> blocks;
-
- blockName=strtok(buf,"|");
- while( blockName != NULL)
- {
- blocks.push_back(blockName);
- blockName=strtok(NULL,"|");
- }
-
-
- if(in > 1 || out > 1)
- return; /* Invalid arguments */
-
- const MgmtSrvr::LogMode modes[] = {
- MgmtSrvr::Off,
- MgmtSrvr::Out,
- MgmtSrvr::In,
- MgmtSrvr::InOut,
- };
- MgmtSrvr::LogMode mode = modes[in<<1 | out];
-
- int result = m_mgmsrv.setSignalLoggingMode(node, mode, blocks);
-
- m_output->println("log signals reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::start(Parser<MgmApiSession>::Context &,
- Properties const &args) {
- Uint32 node;
-
- args.get("node", &node);
-
- int result = m_mgmsrv.start(node);
-
- m_output->println("start reply");
- if(result != 0)
- m_output->println("result: %s", get_error_text(result));
- else
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::startAll(Parser<MgmApiSession>::Context &,
- Properties const &) {
- NodeId node = 0;
- int started = 0;
-
- while(m_mgmsrv.getNextNodeId(&node, NDB_MGM_NODE_TYPE_NDB))
- if(m_mgmsrv.start(node) == 0)
- started++;
-
- m_output->println("start reply");
- m_output->println("result: Ok");
- m_output->println("started: %d", started);
- m_output->println("");
-}
-
-void
-MgmApiSession::setLogFilter(Parser_t::Context &ctx,
- const class Properties &args) {
- Uint32 severity;
- Uint32 enable;
-
- args.get("level", &severity);
- args.get("enable", &enable);
-
- int result = m_mgmsrv.setEventLogFilter(severity, enable);
-
- m_output->println("set logfilter reply");
- m_output->println("result: %d", result);
- m_output->println("");
-}
-
-#ifdef NOT_USED
-
-static NdbOut&
-operator<<(NdbOut& out, const LogLevel & ll)
-{
- out << "[LogLevel: ";
- for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
- out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
- out << "]";
- return out;
-}
-#endif
-
-void
-Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId){
-
- Uint32 threshold;
- LogLevel::EventCategory cat;
- Logger::LoggerLevel severity;
- EventLoggerBase::EventTextFunction textF;
- int i, n;
- DBUG_ENTER("Ndb_mgmd_event_service::log");
- DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
-
- if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF))
- DBUG_VOID_RETURN;
-
- char m_text[512];
- EventLogger::getText(m_text, sizeof(m_text),
- textF, theData, nodeId);
-
- BaseString str("log event reply\n");
- str.appfmt("type=%d\n", eventType);
- str.appfmt("time=%d\n", 0);
- str.appfmt("source_nodeid=%d\n", nodeId);
- for (i= 0; ndb_logevent_body[i].token; i++)
- {
- if ( ndb_logevent_body[i].type != eventType)
- continue;
- int val= theData[ndb_logevent_body[i].index];
- if (ndb_logevent_body[i].index_fn)
- val= (*(ndb_logevent_body[i].index_fn))(val);
- str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val);
- if(strcmp(ndb_logevent_body[i].token,"error") == 0)
- {
- int m_text_len= strlen(m_text);
- if(sizeof(m_text)-m_text_len-3 > 0)
- {
- BaseString::snprintf(m_text+m_text_len, 4 , " - ");
- ndb_error_string(val, m_text+(m_text_len+3), sizeof(m_text)-m_text_len-3);
- }
- }
- }
-
- Vector<NDB_SOCKET_TYPE> copy;
- m_clients.lock();
- for(i = m_clients.size() - 1; i >= 0; i--)
- {
- if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat))
- {
- if(m_clients[i].m_socket==NDB_INVALID_SOCKET)
- continue;
-
- SocketOutputStream out(m_clients[i].m_socket);
-
- int r;
- if (m_clients[i].m_parsable)
- r= out.println(str.c_str());
- else
- r= out.println(m_text);
-
- if (r<0)
- {
- copy.push_back(m_clients[i].m_socket);
- m_clients.erase(i, false);
- }
- }
- }
- m_clients.unlock();
-
- if ((n= (int)copy.size()))
- {
- for(i= 0; i < n; i++)
- NDB_CLOSE_SOCKET(copy[i]);
-
- LogLevel tmp; tmp.clear();
- m_clients.lock();
- for(i= m_clients.size() - 1; i >= 0; i--)
- tmp.set_max(m_clients[i].m_logLevel);
- m_clients.unlock();
- update_log_level(tmp);
- }
- DBUG_VOID_RETURN;
-}
-
-void
-Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level)
-{
- LogLevel tmp = log_level;
- m_clients.lock();
- for(int i = m_clients.size() - 1; i >= 0; i--)
- tmp.set_max(m_clients[i].m_logLevel);
- m_clients.unlock();
- update_log_level(tmp);
-}
-
-void
-Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp)
-{
- m_logLevel = tmp;
- EventSubscribeReq req;
- req = tmp;
- // send update to all nodes
- req.blockRef = 0;
- m_mgmsrv->m_log_level_requests.push_back(req);
-}
-
-void
-Ndb_mgmd_event_service::check_listeners()
-{
- int i, n= 0;
- DBUG_ENTER("Ndb_mgmd_event_service::check_listeners");
- m_clients.lock();
- for(i= m_clients.size() - 1; i >= 0; i--)
- {
- if(m_clients[i].m_socket==NDB_INVALID_SOCKET)
- continue;
-
- SocketOutputStream out(m_clients[i].m_socket);
-
- DBUG_PRINT("info",("%d %d",i,m_clients[i].m_socket));
-
- if(out.println("<PING>") < 0)
- {
- NDB_CLOSE_SOCKET(m_clients[i].m_socket);
- m_clients.erase(i, false);
- n=1;
- }
- }
- if (n)
- {
- LogLevel tmp; tmp.clear();
- for(i= m_clients.size() - 1; i >= 0; i--)
- tmp.set_max(m_clients[i].m_logLevel);
- update_log_level(tmp);
- }
- m_clients.unlock();
- DBUG_VOID_RETURN;
-}
-
-void
-Ndb_mgmd_event_service::add_listener(const Event_listener& client)
-{
- DBUG_ENTER("Ndb_mgmd_event_service::add_listener");
- DBUG_PRINT("enter",("client.m_socket: %d", client.m_socket));
-
- check_listeners();
-
- m_clients.push_back(client);
- update_max_log_level(client.m_logLevel);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Ndb_mgmd_event_service::stop_sessions(){
- m_clients.lock();
- for(int i = m_clients.size() - 1; i >= 0; i--){
- if(m_clients[i].m_socket != NDB_INVALID_SOCKET){
- NDB_CLOSE_SOCKET(m_clients[i].m_socket);
- m_clients.erase(i);
- }
- }
- m_clients.unlock();
-}
-
-void
-MgmApiSession::setParameter(Parser_t::Context &,
- Properties const &args) {
- BaseString node, param, value;
- args.get("node", node);
- args.get("parameter", param);
- args.get("value", value);
-
- BaseString result;
- int ret = m_mgmsrv.setDbParameter(atoi(node.c_str()),
- atoi(param.c_str()),
- value.c_str(),
- result);
-
- m_output->println("set parameter reply");
- m_output->println("message: %s", result.c_str());
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::setConnectionParameter(Parser_t::Context &ctx,
- Properties const &args) {
- BaseString node1, node2, param, value;
- args.get("node1", node1);
- args.get("node2", node2);
- args.get("param", param);
- args.get("value", value);
-
- BaseString result;
- int ret = m_mgmsrv.setConnectionDbParameter(atoi(node1.c_str()),
- atoi(node2.c_str()),
- atoi(param.c_str()),
- atoi(value.c_str()),
- result);
-
- m_output->println("set connection parameter reply");
- m_output->println("message: %s", result.c_str());
- m_output->println("result: %s", (ret>0)?"Ok":"Failed");
- m_output->println("");
-}
-
-void
-MgmApiSession::getConnectionParameter(Parser_t::Context &ctx,
- Properties const &args) {
- BaseString node1, node2, param;
- int value = 0;
-
- args.get("node1", node1);
- args.get("node2", node2);
- args.get("param", param);
-
- BaseString result;
- int ret = m_mgmsrv.getConnectionDbParameter(atoi(node1.c_str()),
- atoi(node2.c_str()),
- atoi(param.c_str()),
- &value,
- result);
-
- m_output->println("get connection parameter reply");
- m_output->println("value: %d", value);
- m_output->println("result: %s", (ret>0)?"Ok":result.c_str());
- m_output->println("");
-}
-
-void
-MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
- Properties const & args) {
- Uint32 parsable= 0;
- BaseString node, param, value;
- args.get("node", node);
- args.get("filter", param);
- args.get("parsable", &parsable);
-
- int result = 0;
- BaseString msg;
-
- Ndb_mgmd_event_service::Event_listener le;
- le.m_parsable = parsable;
- le.m_socket = m_socket;
-
- Vector<BaseString> list;
- param.trim();
- param.split(list, " ,");
- for(size_t i = 0; i<list.size(); i++){
- Vector<BaseString> spec;
- list[i].trim();
- list[i].split(spec, "=:");
- if(spec.size() != 2){
- msg.appfmt("Invalid filter specification: >%s< >%s< %d",
- param.c_str(), list[i].c_str(), spec.size());
- result = -1;
- goto done;
- }
-
- spec[0].trim().ndb_toupper();
- int category = ndb_mgm_match_event_category(spec[0].c_str());
- if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){
- category = atoi(spec[0].c_str());
- if(category < NDB_MGM_MIN_EVENT_CATEGORY ||
- category > NDB_MGM_MAX_EVENT_CATEGORY){
- msg.appfmt("Unknown category: >%s<", spec[0].c_str());
- result = -1;
- goto done;
- }
- }
-
- int level = atoi(spec[1].c_str());
- if(level < 0 || level > NDB_MGM_MAX_LOGLEVEL){
- msg.appfmt("Invalid level: >%s<", spec[1].c_str());
- result = -1;
- goto done;
- }
- category -= CFG_MIN_LOGLEVEL;
- le.m_logLevel.setLogLevel((LogLevel::EventCategory)category, level);
- }
-
- if(list.size() == 0){
- msg.appfmt("Empty filter specification");
- result = -1;
- goto done;
- }
-
-done:
- m_output->println("listen event");
- m_output->println("result: %d", result);
- if(result != 0)
- m_output->println("msg: %s", msg.c_str());
- m_output->println("");
-
- if(result==0)
- {
- m_mgmsrv.m_event_listner.add_listener(le);
- m_stop = true;
- m_socket = NDB_INVALID_SOCKET;
- }
-}
-
-void
-MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *data)
-{
- MgmApiSession *s= (MgmApiSession *)_s;
- struct PurgeStruct &ps= *(struct PurgeStruct *)data;
- if (s->m_allocated_resources->is_reserved(ps.free_nodes))
- {
- if (ps.str)
- ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid());
- s->stopSession();
- }
-}
-
-void
-MgmApiSession::stop_session_if_timed_out(SocketServer::Session *_s, void *data)
-{
- MgmApiSession *s= (MgmApiSession *)_s;
- struct PurgeStruct &ps= *(struct PurgeStruct *)data;
- if (s->m_allocated_resources->is_reserved(ps.free_nodes) &&
- s->m_allocated_resources->is_timed_out(ps.tick))
- {
- s->stopSession();
- }
-}
-
-void
-MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx,
- const class Properties &args)
-{
- struct PurgeStruct ps;
- BaseString str;
- ps.str = &str;
-
- m_mgmsrv.get_connected_nodes(ps.free_nodes);
- ps.free_nodes.bitXORC(NodeBitmask()); // invert connected_nodes to get free nodes
-
- m_mgmsrv.get_socket_server()->foreachSession(stop_session_if_not_connected,&ps);
- m_mgmsrv.get_socket_server()->checkSessions();
-
- m_output->println("purge stale sessions reply");
- if (str.length() > 0)
- m_output->println("purged:%s",str.c_str());
- m_output->println("result: Ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::check_connection(Parser_t::Context &ctx,
- const class Properties &args)
-{
- SLEEP_ERROR_INSERTED(1);
- m_output->println("check connection reply");
- SLEEP_ERROR_INSERTED(2);
- m_output->println("result: Ok");
- SLEEP_ERROR_INSERTED(3);
- m_output->println("");
-}
-
-void
-MgmApiSession::transporter_connect(Parser_t::Context &ctx,
- Properties const &args)
-{
- m_mgmsrv.transporter_connect(m_socket);
-
- m_stop= true;
- m_stopped= true; // force a stop (no closing socket)
- m_socket= NDB_INVALID_SOCKET; // so nobody closes it
-}
-
-void
-MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx,
- Properties const &args)
-{
- m_output->println("get mgmd nodeid reply");
- m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId());
- SLEEP_ERROR_INSERTED(1);
-
- m_output->println("");
-}
-
-void
-MgmApiSession::report_event(Parser_t::Context &ctx,
- Properties const &args)
-{
- Uint32 length;
- const char *data_string;
- Uint32 data[25];
-
- args.get("length", &length);
- args.get("data", &data_string);
-
- BaseString tmp(data_string);
- Vector<BaseString> item;
- tmp.split(item, " ");
- for (int i = 0; (Uint32) i < length ; i++)
- {
- sscanf(item[i].c_str(), "%u", data+i);
- }
-
- m_mgmsrv.eventReport(data);
- m_output->println("report event reply");
- m_output->println("result: ok");
- m_output->println("");
-}
-
-void
-MgmApiSession::list_session(SocketServer::Session *_s, void *data)
-{
- MgmApiSession *s= (MgmApiSession *)_s;
- MgmApiSession *lister= (MgmApiSession*) data;
-
- if(s!=lister)
- NdbMutex_Lock(s->m_mutex);
-
- Uint64 id= s->m_session_id;
- lister->m_output->println("session: %llu",id);
- lister->m_output->println("session.%llu.m_stopSelf: %d",id,s->m_stopSelf);
- lister->m_output->println("session.%llu.m_stop: %d",id,s->m_stop);
- lister->m_output->println("session.%llu.allocated.nodeid: %d",id,s->m_allocated_resources->get_nodeid());
- if(s->m_ctx)
- {
- int l= strlen(s->m_ctx->m_tokenBuffer);
- char *buf= (char*) malloc(2*l+1);
- char *b= buf;
- for(int i=0; i<l;i++)
- if(s->m_ctx->m_tokenBuffer[i]=='\n')
- {
- *b++='\\';
- *b++='n';
- }
- else
- {
- *b++= s->m_ctx->m_tokenBuffer[i];
- }
- *b= '\0';
-
- lister->m_output->println("session.%llu.parser.buffer.len: %u",id,l);
- lister->m_output->println("session.%llu.parser.buffer: %s",id,buf);
- lister->m_output->println("session.%llu.parser.status: %d",id,s->m_ctx->m_status);
-
- free(buf);
- }
-
- if(s!=lister)
- NdbMutex_Unlock(s->m_mutex);
-}
-
-void
-MgmApiSession::listSessions(Parser_t::Context &ctx,
- Properties const &args) {
- m_mgmsrv.get_socket_server()->foreachSession(list_session,(void*)this);
-
- m_output->println("");
-}
-
-void
-MgmApiSession::getSessionId(Parser_t::Context &ctx,
- Properties const &args) {
- m_output->println("get session id reply");
- m_output->println("id: %llu",m_session_id);
- m_output->println("");
-}
-
-struct get_session_param {
- MgmApiSession *l;
- Uint64 id;
- int found;
-};
-
-void
-MgmApiSession::get_session(SocketServer::Session *_s, void *data)
-{
- struct get_session_param *p= (struct get_session_param*)data;
- MgmApiSession *s= (MgmApiSession *)_s;
-
- if(s!=p->l)
- NdbMutex_Lock(s->m_mutex);
-
- if(p->id != s->m_session_id)
- {
- if(s!=p->l)
- NdbMutex_Unlock(s->m_mutex);
- return;
- }
-
- p->found= true;
- p->l->m_output->println("id: %llu",s->m_session_id);
- p->l->m_output->println("m_stopSelf: %d",s->m_stopSelf);
- p->l->m_output->println("m_stop: %d",s->m_stop);
- p->l->m_output->println("nodeid: %d",s->m_allocated_resources->get_nodeid());
- if(s->m_ctx)
- {
- int l= strlen(s->m_ctx->m_tokenBuffer);
- p->l->m_output->println("parser_buffer_len: %u",l);
- p->l->m_output->println("parser_status: %d",s->m_ctx->m_status);
- }
-
- if(s!=p->l)
- NdbMutex_Unlock(s->m_mutex);
-}
-
-void
-MgmApiSession::getSession(Parser_t::Context &ctx,
- Properties const &args) {
- Uint64 id;
- struct get_session_param p;
-
- args.get("id", &id);
-
- p.l= this;
- p.id= id;
- p.found= false;
-
- m_output->println("get session reply");
- m_mgmsrv.get_socket_server()->foreachSession(get_session,(void*)&p);
-
- if(p.found==false)
- m_output->println("id: 0");
-
- m_output->println("");
-}
-
-template class MutexVector<int>;
-template class Vector<ParserRow<MgmApiSession> const*>;
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
deleted file mode 100644
index 6020ac60f4f..00000000000
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef MGMAPI_SERVICE_HPP
-#define MGMAPI_SERVICE_HPP
-
-#include <SocketServer.hpp>
-#include <NdbSleep.h>
-#include <Parser.hpp>
-#include <OutputStream.hpp>
-#include <InputStream.hpp>
-
-#include "MgmtSrvr.hpp"
-
-class MgmApiSession : public SocketServer::Session
-{
- static void stop_session_if_timed_out(SocketServer::Session *_s, void *data);
- static void stop_session_if_not_connected(SocketServer::Session *_s, void *data);
- static void list_session(SocketServer::Session *_s, void *data);
- static void get_session(SocketServer::Session *_s, void *data);
-private:
- typedef Parser<MgmApiSession> Parser_t;
-
- class MgmtSrvr & m_mgmsrv;
- InputStream *m_input;
- OutputStream *m_output;
- Parser_t *m_parser;
- MgmtSrvr::Allocated_resources *m_allocated_resources;
- char m_err_str[1024];
- int m_stopSelf; // -1 is restart, 0 do nothing, 1 stop
- NdbMutex *m_mutex;
-
- // for listing sessions and other fun:
- Parser_t::Context *m_ctx;
- Uint64 m_session_id;
-
- int m_errorInsert;
-
- const char *get_error_text(int err_no)
- { return m_mgmsrv.getErrorText(err_no, m_err_str, sizeof(m_err_str)); }
-
-public:
- MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id);
- virtual ~MgmApiSession();
- void runSession();
-
- void getConfig(Parser_t::Context &ctx, const class Properties &args);
-
- void get_nodeid(Parser_t::Context &ctx, const class Properties &args);
- void getVersion(Parser_t::Context &ctx, const class Properties &args);
- void getStatus(Parser_t::Context &ctx, const class Properties &args);
- void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args);
- void restart(const class Properties &args, int version);
- void restart_v1(Parser_t::Context &ctx, const class Properties &args);
- void restart_v2(Parser_t::Context &ctx, const class Properties &args);
- void restartAll(Parser_t::Context &ctx, const class Properties &args);
- void insertError(Parser_t::Context &ctx, const class Properties &args);
- void setTrace(Parser_t::Context &ctx, const class Properties &args);
- void logSignals(Parser_t::Context &ctx, const class Properties &args);
- void startSignalLog(Parser_t::Context &ctx, const class Properties &args);
- void stopSignalLog(Parser_t::Context &ctx, const class Properties &args);
- void dumpState(Parser_t::Context &ctx, const class Properties &args);
- void startBackup(Parser_t::Context &ctx, const class Properties &args);
- void abortBackup(Parser_t::Context &ctx, const class Properties &args);
- void enterSingleUser(Parser_t::Context &ctx, const class Properties &args);
- void exitSingleUser(Parser_t::Context &ctx, const class Properties &args);
- void stop_v1(Parser_t::Context &ctx, const class Properties &args);
- void stop_v2(Parser_t::Context &ctx, const class Properties &args);
- void stop(const class Properties &args, int version);
- void stopAll(Parser_t::Context &ctx, const class Properties &args);
- void start(Parser_t::Context &ctx, const class Properties &args);
- void startAll(Parser_t::Context &ctx, const class Properties &args);
- void bye(Parser_t::Context &ctx, const class Properties &args);
- void endSession(Parser_t::Context &ctx, const class Properties &args);
- void setLogLevel(Parser_t::Context &ctx, const class Properties &args);
- void getClusterLogLevel(Parser_t::Context &ctx,
- const class Properties &args);
- void setClusterLogLevel(Parser_t::Context &ctx,
- const class Properties &args);
- void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
-
- void setParameter(Parser_t::Context &ctx, const class Properties &args);
- void setConnectionParameter(Parser_t::Context &ctx,
- const class Properties &args);
- void getConnectionParameter(Parser_t::Context &ctx,
- Properties const &args);
-
- void listen_event(Parser_t::Context &ctx, const class Properties &args);
-
- void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args);
- void check_connection(Parser_t::Context &ctx, const class Properties &args);
-
- void transporter_connect(Parser_t::Context &ctx, Properties const &args);
-
- void get_mgmd_nodeid(Parser_t::Context &ctx, Properties const &args);
-
- void report_event(Parser_t::Context &ctx, Properties const &args);
-
- void listSessions(Parser_t::Context &ctx, Properties const &args);
-
- void getSessionId(Parser_t::Context &ctx, Properties const &args);
- void getSession(Parser_t::Context &ctx, Properties const &args);
-};
-
-class MgmApiService : public SocketServer::Service {
- class MgmtSrvr * m_mgmsrv;
- Uint64 m_next_session_id; // Protected by m_sessions mutex it SocketServer
-public:
- MgmApiService(){
- m_mgmsrv = 0;
- m_next_session_id= 1;
- }
-
- void setMgm(class MgmtSrvr * mgmsrv){
- m_mgmsrv = mgmsrv;
- }
-
- SocketServer::Session * newSession(NDB_SOCKET_TYPE socket){
- return new MgmApiSession(* m_mgmsrv, socket, m_next_session_id++);
- }
-};
-
-#endif
diff --git a/storage/ndb/src/mgmsrv/SignalQueue.cpp b/storage/ndb/src/mgmsrv/SignalQueue.cpp
deleted file mode 100644
index a8b993d2760..00000000000
--- a/storage/ndb/src/mgmsrv/SignalQueue.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "SignalQueue.hpp"
-
-SignalQueue::SignalQueue() {
- m_mutex = NdbMutex_Create();
- m_cond = NdbCondition_Create();
- m_signalQueueHead = NULL;
-}
-
-SignalQueue::~SignalQueue() {
- {
- Guard g(m_mutex);
- while(m_signalQueueHead != NULL)
- delete pop();
- }
- NdbMutex_Destroy(m_mutex);
- m_mutex = NULL;
- NdbCondition_Destroy(m_cond);
- m_cond = NULL;
-}
-
-NdbApiSignal *
-SignalQueue::pop() {
- NdbApiSignal *ret;
-
- if(m_signalQueueHead == NULL)
- return NULL;
-
- ret = m_signalQueueHead->signal;
-
- QueueEntry *old = m_signalQueueHead;
- m_signalQueueHead = m_signalQueueHead->next;
-
- delete old;
-
- return ret;
-}
-
-void
-SignalQueue::receive(void *me, NdbApiSignal *signal) {
- SignalQueue *q = (SignalQueue *)me;
- q->receive(signal);
-}
-
-void
-SignalQueue::receive(NdbApiSignal *signal) {
- QueueEntry *n = new QueueEntry();
- n->signal = signal;
- n->next = NULL;
-
- Guard guard(m_mutex);
-
- if(m_signalQueueHead == NULL) {
- m_signalQueueHead = n;
- NdbCondition_Broadcast(m_cond);
- return;
- }
-
- QueueEntry *cur = m_signalQueueHead;
-
- while(cur->next != NULL)
- cur = cur->next;
-
- cur->next = n;
-
- NdbCondition_Broadcast(m_cond);
-}
-
-NdbApiSignal *
-SignalQueue::waitFor(int gsn, NodeId nodeid, Uint32 timeout) {
- Guard g(m_mutex);
-
- if(m_signalQueueHead == NULL)
- NdbCondition_WaitTimeout(m_cond, m_mutex, timeout);
-
- if(m_signalQueueHead == NULL)
- return NULL;
-
- if(gsn != 0 &&
- m_signalQueueHead->signal->readSignalNumber() != gsn)
- return NULL;
-
- if(nodeid != 0 &&
- refToNode(m_signalQueueHead->signal->theSendersBlockRef) != nodeid)
- return NULL;
-
- return pop();
-}
diff --git a/storage/ndb/src/mgmsrv/SignalQueue.hpp b/storage/ndb/src/mgmsrv/SignalQueue.hpp
deleted file mode 100644
index e73bb25daab..00000000000
--- a/storage/ndb/src/mgmsrv/SignalQueue.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef __SIGNALQUEUE_HPP_INCLUDED__
-#define __SIGNALQUEUE_HPP_INCLUDED__
-
-#include <NdbApiSignal.hpp>
-#include <NdbMutex.h>
-#include <NdbCondition.h>
-#include <Vector.hpp>
-
-/* XXX Look for an already existing definition */
-#define DEFAULT_TIMEOUT 5000
-
-class SignalQueue {
-public:
- typedef void (* SignalHandler)(void *obj, int gsn, NdbApiSignal *signal);
-
- SignalQueue();
- ~SignalQueue();
-
- /**
- * Static wrapper making it possible to call receive without knowing the
- * type of the receiver
- */
- static void receive(void *me, NdbApiSignal *signal);
-
- /**
- * Enqueues a signal, and notifies any thread waiting for signals.
- */
- void receive(NdbApiSignal *signal);
-
- NdbApiSignal *waitFor(int gsn,
- NodeId nodeid = 0,
- Uint32 timeout = DEFAULT_TIMEOUT);
- template<class T> bool waitFor(Vector<T> &t,
- T **handler,
- NdbApiSignal **signal,
- Uint32 timeout = DEFAULT_TIMEOUT);
-private:
- NdbMutex *m_mutex; /* Locks all data in SignalQueue */
- NdbCondition *m_cond; /* Notifies about new signal in the queue */
-
- /**
- * Returns the last recently received signal. Must be called with
- * m_mutex locked.
- * The caller takes responsibility for deleting the returned object.
- *
- * @returns NULL if failed, or a received signal
- */
- NdbApiSignal *pop();
-
- class QueueEntry {
- public:
- NdbApiSignal *signal;
- QueueEntry *next;
- };
- QueueEntry *m_signalQueueHead; /** Head of the queue.
- * New entries added on the tail
- */
-};
-
-template<class T> bool
-SignalQueue::waitFor(Vector<T> &t,
- T **handler,
- NdbApiSignal **signal,
- Uint32 timeout) {
- Guard g(m_mutex);
-
- if(m_signalQueueHead == NULL)
- NdbCondition_WaitTimeout(m_cond, m_mutex, timeout);
-
- if(m_signalQueueHead == NULL)
- return false;
-
- for(size_t i = 0; i < t.size(); i++) {
- if(t[i].check(m_signalQueueHead->signal)) {
- * handler = &t[i];
- * signal = pop();
- return true;
- }
- }
-
- return false;
-}
-
-#endif /* !__SIGNALQUEUE_HPP_INCLUDED__ */
diff --git a/storage/ndb/src/mgmsrv/convertStrToInt.cpp b/storage/ndb/src/mgmsrv/convertStrToInt.cpp
deleted file mode 100644
index 1ca0eeb8da7..00000000000
--- a/storage/ndb/src/mgmsrv/convertStrToInt.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-
-bool convert(const char* s, int& val) {
-
- if (s == NULL) {
- return false;
- }
-
- if (strlen(s) == 0) {
- return false;
- }
-
- errno = 0;
- char* p;
- long v = strtol(s, &p, 10);
- if (errno != 0) {
- return false;
- }
- if (p != &s[strlen(s)]) {
- return false;
- }
-
- val = v;
- return true;
-}
-
-
diff --git a/storage/ndb/src/mgmsrv/convertStrToInt.hpp b/storage/ndb/src/mgmsrv/convertStrToInt.hpp
deleted file mode 100644
index dd144705da9..00000000000
--- a/storage/ndb/src/mgmsrv/convertStrToInt.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-//******************************************************************************
-// Description:
-//
-// Author: Peter Lind
-//******************************************************************************
-
-extern bool convert(const char* s, int& val);
-
-
diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp
deleted file mode 100644
index 7cf286db969..00000000000
--- a/storage/ndb/src/mgmsrv/main.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_opts.h>
-
-#include "MgmtSrvr.hpp"
-#include "EventLogger.hpp"
-#include <Config.hpp>
-#include "InitConfigFileParser.hpp"
-#include <SocketServer.hpp>
-#include "Services.hpp"
-#include <version.h>
-#include <kernel_types.h>
-#include <Properties.hpp>
-#include <NdbOut.hpp>
-#include <NdbMain.h>
-#include <NdbDaemon.h>
-#include <NdbConfig.h>
-#include <NdbHost.h>
-#include <ndb_version.h>
-#include <ConfigRetriever.hpp>
-#include <mgmapi_config_parameters.h>
-
-#include <NdbAutoPtr.hpp>
-
-#include <ndb_mgmclient.hpp>
-
-#undef DEBUG
-#define DEBUG(x) ndbout << x << endl;
-
-const char progname[] = "mgmtsrvr";
-const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
-
-// copied from mysql.cc to get readline
-extern "C" {
-#if defined( __WIN__)
-#include <conio.h>
-#else
-#include <readline/readline.h>
-extern "C" int add_history(const char *command); /* From readline directory */
-#define HAVE_READLINE
-#endif
-}
-
-static int
-read_and_execute(Ndb_mgmclient* com, const char * prompt, int _try_reconnect)
-{
- static char *line_read = (char *)NULL;
-
- /* If the buffer has already been allocated, return the memory
- to the free pool. */
- if (line_read)
- {
- free (line_read);
- line_read = (char *)NULL;
- }
-#ifdef HAVE_READLINE
- /* Get a line from the user. */
- line_read = readline (prompt);
- /* If the line has any text in it, save it on the history. */
- if (line_read && *line_read)
- add_history (line_read);
-#else
- static char linebuffer[254];
- fputs(prompt, stdout);
- linebuffer[sizeof(linebuffer)-1]=0;
- line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
- if (line_read == linebuffer) {
- char *q=linebuffer;
- while (*q > 31) q++;
- *q=0;
- line_read= strdup(linebuffer);
- }
-#endif
- return com->execute(line_read,_try_reconnect);
-}
-
-/**
- * @struct MgmGlobals
- * @brief Global Variables used in the management server
- *****************************************************************************/
-
-/** Command line arguments */
-static int opt_daemon; // NOT bool, bool need not be int
-static int opt_non_interactive;
-static int opt_interactive;
-static const char * opt_config_filename= 0;
-static int opt_mycnf = 0;
-
-struct MgmGlobals {
- MgmGlobals();
- ~MgmGlobals();
-
- /** Stuff found in environment or in local config */
- NodeId localNodeId;
- bool use_specific_ip;
- char * interface_name;
- short unsigned int port;
-
- /** The Mgmt Server */
- MgmtSrvr * mgmObject;
-
- /** The Socket Server */
- SocketServer * socketServer;
-};
-
-int g_no_nodeid_checks= 0;
-int g_print_full_config;
-static MgmGlobals *glob= 0;
-
-/******************************************************************************
- * Function prototypes
- ******************************************************************************/
-/**
- * Global variables
- */
-bool g_StopServer;
-bool g_RestartServer;
-extern EventLogger g_eventLogger;
-
-enum ndb_mgmd_options {
- OPT_INTERACTIVE = NDB_STD_OPTIONS_LAST,
- OPT_NO_NODEID_CHECKS,
- OPT_NO_DAEMON
-};
-NDB_STD_OPTS_VARS;
-
-static struct my_option my_long_options[] =
-{
- NDB_STD_OPTS("ndb_mgmd"),
- { "config-file", 'f', "Specify cluster configuration file",
- &opt_config_filename, &opt_config_filename, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "print-full-config", 'P', "Print full config and exit",
- &g_print_full_config, &g_print_full_config, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)",
- &opt_daemon, &opt_daemon, 0,
- GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
- { "interactive", OPT_INTERACTIVE,
- "Run interactive. Not supported but provided for testing purposes",
- &opt_interactive, &opt_interactive, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "no-nodeid-checks", OPT_NO_NODEID_CHECKS,
- "Do not provide any node id checks",
- &g_no_nodeid_checks, &g_no_nodeid_checks, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "nodaemon", OPT_NO_DAEMON,
- "Don't run as daemon, but don't read from stdin",
- &opt_non_interactive, &opt_non_interactive, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { "mycnf", 256,
- "Read cluster config from my.cnf",
- &opt_mycnf, &opt_mycnf, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
-
-static void short_usage_sub(void)
-{
- printf("Usage: %s [OPTIONS]\n", my_progname);
-}
-static void usage()
-{
- short_usage_sub();
- ndb_std_print_version();
- print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
- puts("");
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
-}
-
-/*
- * MAIN
- */
-int main(int argc, char** argv)
-{
-
- NDB_INIT(argv[0]);
-
- load_defaults("my",load_default_groups,&argc,&argv);
-
- int ho_error;
-#ifndef DBUG_OFF
- opt_debug= "d:t:O,/tmp/ndb_mgmd.trace";
-#endif
- if ((ho_error=handle_options(&argc, &argv, my_long_options,
- ndb_std_get_one_option)))
- exit(ho_error);
-
-start:
- glob= new MgmGlobals;
-
- if (opt_interactive ||
- opt_non_interactive ||
- g_print_full_config) {
- opt_daemon= 0;
- }
-
- if (opt_mycnf && opt_config_filename)
- {
- ndbout_c("Both --mycnf and -f is not supported");
- return 0;
- }
-
- if (opt_mycnf == 0 && opt_config_filename == 0)
- {
- struct stat buf;
- if (stat("config.ini", &buf) != -1)
- opt_config_filename = "config.ini";
- }
-
- glob->socketServer = new SocketServer();
-
- MgmApiService * mapi = new MgmApiService();
-
- glob->mgmObject = new MgmtSrvr(glob->socketServer,
- opt_config_filename,
- opt_connect_str);
-
- if (g_print_full_config)
- goto the_end;
-
- if (glob->mgmObject->init())
- goto error_end;
-
- my_setwd(NdbConfig_get_path(0), MYF(0));
-
- glob->localNodeId= glob->mgmObject->getOwnNodeId();
- if (glob->localNodeId == 0) {
- goto error_end;
- }
-
- glob->port= glob->mgmObject->getPort();
-
- if (glob->port == 0)
- goto error_end;
-
- glob->interface_name = 0;
- glob->use_specific_ip = false;
-
- if(!glob->use_specific_ip){
- int count= 5; // no of retries for tryBind
- while(!glob->socketServer->tryBind(glob->port, glob->interface_name)){
- if (--count > 0) {
- NdbSleep_MilliSleep(1000);
- continue;
- }
- ndbout_c("Unable to setup port: %s:%d!\n"
- "Please check if the port is already used,\n"
- "(perhaps a ndb_mgmd is already running),\n"
- "and if you are executing on the correct computer",
- (glob->interface_name ? glob->interface_name : "*"), glob->port);
- goto error_end;
- }
- free(glob->interface_name);
- glob->interface_name = 0;
- }
-
- if(!glob->socketServer->setup(mapi, &glob->port, glob->interface_name))
- {
- ndbout_c("Unable to setup management port: %d!\n"
- "Please check if the port is already used,\n"
- "(perhaps a ndb_mgmd is already running),\n"
- "and if you are executing on the correct computer",
- glob->port);
- delete mapi;
- goto error_end;
- }
-
- if(!glob->mgmObject->check_start()){
- ndbout_c("Unable to check start management server.");
- ndbout_c("Probably caused by illegal initial configuration file.");
- goto error_end;
- }
-
- if (opt_daemon) {
- // Become a daemon
- char *lockfile= NdbConfig_PidFileName(glob->localNodeId);
- char *logfile= NdbConfig_StdoutFileName(glob->localNodeId);
- NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
-
- if (NdbDaemon_Make(lockfile, logfile, 0) == -1) {
- ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
- return 1;
- }
- }
-
-#ifndef NDB_WIN32
- signal(SIGPIPE, SIG_IGN);
-#endif
- {
- BaseString error_string;
- if(!glob->mgmObject->start(error_string)){
- ndbout_c("Unable to start management server.");
- ndbout_c("Probably caused by illegal initial configuration file.");
- ndbout_c(error_string.c_str());
- goto error_end;
- }
- }
-
- //glob->mgmObject->saveConfig();
- mapi->setMgm(glob->mgmObject);
-
- char msg[256];
- BaseString::snprintf(msg, sizeof(msg),
- "NDB Cluster Management Server. %s", NDB_VERSION_STRING);
- ndbout_c(msg);
- g_eventLogger.info(msg);
-
- BaseString::snprintf(msg, 256, "Id: %d, Command port: %d",
- glob->localNodeId, glob->port);
- ndbout_c(msg);
- g_eventLogger.info(msg);
-
- g_StopServer = false;
- g_RestartServer= false;
- glob->socketServer->startServer();
-
- if(opt_interactive) {
- BaseString con_str;
- if(glob->interface_name)
- con_str.appfmt("host=%s:%d", glob->interface_name, glob->port);
- else
- con_str.appfmt("localhost:%d", glob->port);
- Ndb_mgmclient com(con_str.c_str(), 1);
- while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1));
- } else
- {
- while(g_StopServer != true)
- NdbSleep_MilliSleep(500);
- }
-
- if(g_RestartServer)
- g_eventLogger.info("Restarting server...");
- else
- g_eventLogger.info("Shutting down server...");
- glob->socketServer->stopServer();
- // We disconnect from the ConfigRetreiver mgmd when we delete glob below
- glob->socketServer->stopSessions(true);
- g_eventLogger.info("Shutdown complete");
- the_end:
- delete glob;
- if(g_RestartServer)
- goto start;
- ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
- return 0;
- error_end:
- delete glob;
- ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
- return 1;
-}
-
-MgmGlobals::MgmGlobals(){
- // Default values
- port = 0;
- interface_name = 0;
- socketServer = 0;
- mgmObject = 0;
-}
-
-MgmGlobals::~MgmGlobals(){
- if (socketServer)
- delete socketServer;
- if (mgmObject)
- delete mgmObject;
- if (interface_name)
- free(interface_name);
-}
diff --git a/storage/ndb/src/mgmsrv/mkconfig/Makefile b/storage/ndb/src/mgmsrv/mkconfig/Makefile
deleted file mode 100644
index 43574eefbd1..00000000000
--- a/storage/ndb/src/mgmsrv/mkconfig/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-BIN_TARGET := mkconfig
-BIN_TARGET_ARCHIVES := logger trace mgmsrvcommon portlib general
-
-SOURCES := mkconfig.cpp
-
-CCFLAGS_LOC += -I.. -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon)
-CFLAGS_mkconfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi)
-
-include $(NDB_TOP)/Epilogue.mk
diff --git a/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp
deleted file mode 100644
index 90e179e7f4f..00000000000
--- a/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <ndb_version.h>
-#include <mgmapi_configuration.hpp>
-
-#include <NdbMain.h>
-#include <Properties.hpp>
-
-#include "InitConfigFileParser.hpp"
-#include <Config.hpp>
-
-void usage(const char * prg){
- ndbout << "Usage " << prg << ": <Init config> <Binary file>" << endl;
-
-}
-
-NDB_COMMAND(mkconfig,
- "mkconfig", "mkconfig",
- "Make a binary configuration from a config file", 16384){
- ndb_init();
- if(argc < 3){
- usage(argv[0]);
- return 0;
- }
-
- InitConfigFileParser parser;
- Config* _cp;
-
- if ((_cp = parser.parseConfig(argv[1])) == 0)
- return false;
-
- ConfigValues* cp = &_cp->m_configValues->m_config;
- Uint32 sz = cp->getPackedSize();
- UtilBuffer buf;
- if(!cp->pack(buf))
- return -1;
-
- FILE * f = fopen(argv[2], "w");
- if(fwrite(buf.get_data(), 1, buf.length(), f) != sz){
- fclose(f);
- unlink(argv[2]);
- return -1;
- }
- fclose(f);
- return 0;
-}
diff --git a/storage/ndb/src/mgmsrv/ndb_mgmd_error.h b/storage/ndb/src/mgmsrv/ndb_mgmd_error.h
deleted file mode 100644
index 61302ea6945..00000000000
--- a/storage/ndb/src/mgmsrv/ndb_mgmd_error.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (C) 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_MGMD_ERROR_H
-#define NDB_MGMD_ERROR_H
-
-#define NO_CONTACT_WITH_PROCESS 5000
-#define WRONG_PROCESS_TYPE 5002
-#define SEND_OR_RECEIVE_FAILED 5005
-#define INVALID_ERROR_NUMBER 5007
-#define INVALID_TRACE_NUMBER 5008
-#define INVALID_BLOCK_NAME 5010
-#define NODE_SHUTDOWN_IN_PROGESS 5026
-#define SYSTEM_SHUTDOWN_IN_PROGRESS 5027
-#define NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH 5028
-#define NO_CONTACT_WITH_DB_NODES 5030
-#define UNSUPPORTED_NODE_SHUTDOWN 5031
-#define NODE_NOT_API_NODE 5062
-#define OPERATION_NOT_ALLOWED_START_STOP 5063
-
-#endif
diff --git a/storage/ndb/src/ndbapi/API.hpp b/storage/ndb/src/ndbapi/API.hpp
deleted file mode 100644
index 250f6499fa6..00000000000
--- a/storage/ndb/src/ndbapi/API.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef API_H
-#define API_H
-
-#include <BlockNumbers.h>
-#include <GlobalSignalNumbers.h>
-#include <RefConvert.hpp>
-#include "NdbImpl.hpp"
-#include "NdbDictionaryImpl.hpp"
-
-#endif
diff --git a/storage/ndb/src/ndbapi/ClusterMgr.cpp b/storage/ndb/src/ndbapi/ClusterMgr.cpp
deleted file mode 100644
index 123c18cbcc6..00000000000
--- a/storage/ndb/src/ndbapi/ClusterMgr.cpp
+++ /dev/null
@@ -1,909 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-#include <ndb_limits.h>
-#include <util/version.h>
-
-#include "TransporterFacade.hpp"
-#include "ClusterMgr.hpp"
-#include <IPCConfig.hpp>
-#include "NdbApiSignal.hpp"
-#include "API.hpp"
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-
-#include <signaldata/NodeFailRep.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/ApiRegSignalData.hpp>
-
-#include <mgmapi.h>
-#include <mgmapi_configuration.hpp>
-#include <mgmapi_config_parameters.h>
-
-int global_flag_skip_invalidate_cache = 0;
-//#define DEBUG_REG
-
-// Just a C wrapper for threadMain
-extern "C"
-void*
-runClusterMgr_C(void * me)
-{
- ((ClusterMgr*) me)->threadMain();
-
- return NULL;
-}
-
-extern "C" {
- void ndbSetOwnVersion();
-}
-ClusterMgr::ClusterMgr(TransporterFacade & _facade):
- theStop(0),
- theFacade(_facade)
-{
- DBUG_ENTER("ClusterMgr::ClusterMgr");
- ndbSetOwnVersion();
- clusterMgrThreadMutex = NdbMutex_Create();
- waitForHBCond= NdbCondition_Create();
- waitingForHB= false;
- m_max_api_reg_req_interval= 0xFFFFFFFF; // MAX_INT
- noOfAliveNodes= 0;
- noOfConnectedNodes= 0;
- theClusterMgrThread= 0;
- m_connect_count = 0;
- m_cluster_state = CS_waiting_for_clean_cache;
- DBUG_VOID_RETURN;
-}
-
-ClusterMgr::~ClusterMgr()
-{
- DBUG_ENTER("ClusterMgr::~ClusterMgr");
- doStop();
- NdbCondition_Destroy(waitForHBCond);
- NdbMutex_Destroy(clusterMgrThreadMutex);
- DBUG_VOID_RETURN;
-}
-
-void
-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;
- ndbout << "--------------------------------------" << endl;
- ndbout_c("ClusterMgr: Node %d defined as %s", tmp, config.getNodeType(tmp));
-#endif
-
- 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;
- break;
- case NODE_TYPE_API:
- theNodes[tmp].m_info.m_type = NodeInfo::API;
- break;
- case NODE_TYPE_MGM:
- theNodes[tmp].m_info.m_type = NodeInfo::MGM;
- break;
- default:
- type = type;
-#if 0
- ndbout_c("ClusterMgr: Unknown node type: %d", type);
-#endif
- }
- }
-}
-
-void
-ClusterMgr::startThread() {
- NdbMutex_Lock(clusterMgrThreadMutex);
-
- theStop = 0;
-
- theClusterMgrThread = NdbThread_Create(runClusterMgr_C,
- (void**)this,
- 32768,
- "ndb_clustermgr",
- NDB_THREAD_PRIO_LOW);
- NdbMutex_Unlock(clusterMgrThreadMutex);
-}
-
-void
-ClusterMgr::doStop( ){
- DBUG_ENTER("ClusterMgr::doStop");
- NdbMutex_Lock(clusterMgrThreadMutex);
- if(theStop){
- NdbMutex_Unlock(clusterMgrThreadMutex);
- DBUG_VOID_RETURN;
- }
- void *status;
- theStop = 1;
- if (theClusterMgrThread) {
- NdbThread_WaitFor(theClusterMgrThread, &status);
- NdbThread_Destroy(&theClusterMgrThread);
- }
- NdbMutex_Unlock(clusterMgrThreadMutex);
- DBUG_VOID_RETURN;
-}
-
-void
-ClusterMgr::forceHB()
-{
- theFacade.lock_mutex();
-
- if(waitingForHB)
- {
- NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000);
- theFacade.unlock_mutex();
- return;
- }
-
- waitingForHB= true;
-
- NodeBitmask ndb_nodes;
- ndb_nodes.clear();
- waitForHBFromNodes.clear();
- for(Uint32 i = 0; i < MAX_NODES; i++)
- {
- if(!theNodes[i].defined)
- continue;
- if(theNodes[i].m_info.m_type == NodeInfo::DB)
- {
- ndb_nodes.set(i);
- const ClusterMgr::Node &node= getNodeInfo(i);
- waitForHBFromNodes.bitOR(node.m_state.m_connected_nodes);
- }
- }
- waitForHBFromNodes.bitAND(ndb_nodes);
-
-#ifdef DEBUG_REG
- char buf[128];
- ndbout << "Waiting for HB from " << waitForHBFromNodes.getText(buf) << endl;
-#endif
- NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
-
- signal.theVerId_signalNumber = GSN_API_REGREQ;
- signal.theReceiversBlockNumber = QMGR;
- signal.theTrace = 0;
- signal.theLength = ApiRegReq::SignalLength;
-
- ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
- req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
- req->version = NDB_VERSION;
-
- int nodeId= 0;
- for(int i=0;
- (int) NodeBitmask::NotFound != (nodeId= waitForHBFromNodes.find(i));
- i= nodeId+1)
- {
-#ifdef DEBUG_REG
- ndbout << "FORCE HB to " << nodeId << endl;
-#endif
- theFacade.sendSignalUnCond(&signal, nodeId);
- }
-
- /* Wait for nodes to reply - if any heartbeats was sent */
- if (!waitForHBFromNodes.isclear())
- NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000);
-
- waitingForHB= false;
-#ifdef DEBUG_REG
- ndbout << "Still waiting for HB from " << waitForHBFromNodes.getText(buf) << endl;
-#endif
- theFacade.unlock_mutex();
-}
-
-void
-ClusterMgr::threadMain( ){
- NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
-
- signal.theVerId_signalNumber = GSN_API_REGREQ;
- signal.theReceiversBlockNumber = QMGR;
- signal.theTrace = 0;
- signal.theLength = ApiRegReq::SignalLength;
-
- ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
- req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
- req->version = NDB_VERSION;
-
-
- Uint32 timeSlept = 100;
- Uint64 now = NdbTick_CurrentMillisecond();
-
- while(!theStop){
- /**
- * Start of Secure area for use of Transporter
- */
- if (m_cluster_state == CS_waiting_for_clean_cache)
- {
- theFacade.m_globalDictCache.lock();
- unsigned sz= theFacade.m_globalDictCache.get_size();
- theFacade.m_globalDictCache.unlock();
- if (sz)
- goto next;
- m_cluster_state = CS_waiting_for_first_connect;
- }
-
- theFacade.lock_mutex();
- for (int i = 1; i < MAX_NDB_NODES; i++){
- /**
- * Send register request (heartbeat) to all available nodes
- * at specified timing intervals
- */
- const NodeId nodeId = i;
- Node & theNode = theNodes[nodeId];
-
- if (!theNode.defined)
- continue;
-
- if (theNode.connected == false){
- theFacade.doConnect(nodeId);
- continue;
- }
-
- if (!theNode.compatible){
- continue;
- }
-
- theNode.hbCounter += timeSlept;
- if (theNode.hbCounter >= m_max_api_reg_req_interval ||
- theNode.hbCounter >= theNode.hbFrequency) {
- /**
- * It is now time to send a new Heartbeat
- */
- if (theNode.hbCounter >= theNode.hbFrequency) {
- theNode.m_info.m_heartbeat_cnt++;
- theNode.hbCounter = 0;
- }
-
-#ifdef DEBUG_REG
- ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId);
-#endif
- theFacade.sendSignalUnCond(&signal, nodeId);
- }//if
-
- if (theNode.m_info.m_heartbeat_cnt == 4 && theNode.hbFrequency > 0){
- reportNodeFailed(i);
- }//if
- }
-
- /**
- * End of secure area. Let other threads in
- */
- theFacade.unlock_mutex();
-
-next:
- // Sleep for 100 ms between each Registration Heartbeat
- Uint64 before = now;
- NdbSleep_MilliSleep(100);
- now = NdbTick_CurrentMillisecond();
- timeSlept = (now - before);
- }
-}
-
-#if 0
-void
-ClusterMgr::showState(NodeId nodeId){
- ndbout << "-- ClusterMgr - NodeId = " << nodeId << endl;
- ndbout << "theNodeList = " << theNodeList[nodeId] << endl;
- ndbout << "theNodeState = " << theNodeState[nodeId] << endl;
- ndbout << "theNodeCount = " << theNodeCount[nodeId] << endl;
- ndbout << "theNodeStopDelay = " << theNodeStopDelay[nodeId] << endl;
- ndbout << "theNodeSendDelay = " << theNodeSendDelay[nodeId] << endl;
-}
-#endif
-
-ClusterMgr::Node::Node()
- : m_state(NodeState::SL_NOTHING) {
- compatible = nfCompleteRep = true;
- connected = defined = m_alive = m_api_reg_conf = false;
- m_state.m_connected_nodes.clear();
-}
-
-/******************************************************************************
- * API_REGREQ and friends
- ******************************************************************************/
-
-void
-ClusterMgr::execAPI_REGREQ(const Uint32 * theData){
- const ApiRegReq * const apiRegReq = (ApiRegReq *)&theData[0];
- const NodeId nodeId = refToNode(apiRegReq->ref);
-
-#ifdef DEBUG_REG
- ndbout_c("ClusterMgr: Recd API_REGREQ from node %d", nodeId);
-#endif
-
- assert(nodeId > 0 && nodeId < MAX_NODES);
-
- Node & node = theNodes[nodeId];
- assert(node.defined == true);
- assert(node.connected == true);
-
- if(node.m_info.m_version != apiRegReq->version){
- node.m_info.m_version = apiRegReq->version;
-
- if (getMajor(node.m_info.m_version) < getMajor(NDB_VERSION) ||
- getMinor(node.m_info.m_version) < getMinor(NDB_VERSION)) {
- node.compatible = false;
- } else {
- node.compatible = true;
- }
- }
-
- NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
- signal.theVerId_signalNumber = GSN_API_REGCONF;
- signal.theReceiversBlockNumber = API_CLUSTERMGR;
- signal.theTrace = 0;
- signal.theLength = ApiRegConf::SignalLength;
-
- ApiRegConf * const conf = CAST_PTR(ApiRegConf, signal.getDataPtrSend());
- conf->qmgrRef = numberToRef(API_CLUSTERMGR, theFacade.ownId());
- conf->version = NDB_VERSION;
- conf->apiHeartbeatFrequency = node.hbFrequency;
- theFacade.sendSignalUnCond(&signal, nodeId);
-}
-
-void
-ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
- const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
- const NodeId nodeId = refToNode(apiRegConf->qmgrRef);
-
-#ifdef DEBUG_REG
- ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
-#endif
-
- assert(nodeId > 0 && nodeId < MAX_NODES);
-
- Node & node = theNodes[nodeId];
- assert(node.defined == true);
- assert(node.connected == true);
-
- if(node.m_info.m_version != apiRegConf->version){
- node.m_info.m_version = apiRegConf->version;
- if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM)
- node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
- node.m_info.m_version);
- else
- node.compatible = ndbCompatible_api_ndb(NDB_VERSION,
- node.m_info.m_version);
- }
-
- node.m_api_reg_conf = true;
-
- node.m_state = apiRegConf->nodeState;
- if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
- node.m_state.getSingleUserMode())){
- set_node_alive(node, true);
- } else {
- set_node_alive(node, false);
- }//if
- node.m_info.m_heartbeat_cnt = 0;
- node.hbCounter = 0;
-
- if(waitingForHB)
- {
- waitForHBFromNodes.clear(nodeId);
-
- if(waitForHBFromNodes.isclear())
- {
- waitingForHB= false;
- NdbCondition_Broadcast(waitForHBCond);
- }
- }
- node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;
-}
-
-void
-ClusterMgr::execAPI_REGREF(const Uint32 * theData){
-
- ApiRegRef * ref = (ApiRegRef*)theData;
-
- const NodeId nodeId = refToNode(ref->ref);
-
- assert(nodeId > 0 && nodeId < MAX_NODES);
-
- Node & node = theNodes[nodeId];
- assert(node.connected == true);
- assert(node.defined == true);
-
- node.compatible = false;
- set_node_alive(node, false);
- node.m_state = NodeState::SL_NOTHING;
- node.m_info.m_version = ref->version;
-
- switch(ref->errorCode){
- case ApiRegRef::WrongType:
- ndbout_c("Node %d reports that this node should be a NDB node", nodeId);
- abort();
- case ApiRegRef::UnsupportedVersion:
- default:
- break;
- }
-
- waitForHBFromNodes.clear(nodeId);
- if(waitForHBFromNodes.isclear())
- NdbCondition_Signal(waitForHBCond);
-}
-
-void
-ClusterMgr::execNODE_FAILREP(const Uint32 * theData){
- NodeFailRep * const nodeFail = (NodeFailRep *)&theData[0];
- for(int i = 1; i<MAX_NODES; i++){
- if(NodeBitmask::get(nodeFail->theNodes, i)){
- reportNodeFailed(i);
- }
- }
-}
-
-void
-ClusterMgr::execNF_COMPLETEREP(const Uint32 * theData){
- NFCompleteRep * const nfComp = (NFCompleteRep *)theData;
-
- const NodeId nodeId = nfComp->failedNodeId;
- assert(nodeId > 0 && nodeId < MAX_NODES);
-
- theFacade.ReportNodeFailureComplete(nodeId);
- theNodes[nodeId].nfCompleteRep = true;
-}
-
-void
-ClusterMgr::reportConnected(NodeId nodeId){
- DBUG_ENTER("ClusterMgr::reportConnected");
- DBUG_PRINT("info", ("nodeId: %u", nodeId));
- /**
- * Ensure that we are sending heartbeat every 100 ms
- * until we have got the first reply from NDB providing
- * us with the real time-out period to use.
- */
- assert(nodeId > 0 && nodeId < MAX_NODES);
-
- noOfConnectedNodes++;
-
- Node & theNode = theNodes[nodeId];
- theNode.connected = true;
- theNode.m_info.m_heartbeat_cnt = 0;
- theNode.hbCounter = 0;
-
- /**
- * make sure the node itself is marked connected even
- * if first API_REGCONF has not arrived
- */
- theNode.m_state.m_connected_nodes.set(nodeId);
- theNode.hbFrequency = 0;
- theNode.m_info.m_version = 0;
- theNode.compatible = true;
- theNode.nfCompleteRep = true;
- theNode.m_state.startLevel = NodeState::SL_NOTHING;
-
- theFacade.ReportNodeAlive(nodeId);
- DBUG_VOID_RETURN;
-}
-
-void
-ClusterMgr::reportDisconnected(NodeId nodeId){
- assert(nodeId > 0 && nodeId < MAX_NODES);
- assert(noOfConnectedNodes > 0);
-
- noOfConnectedNodes--;
- theNodes[nodeId].connected = false;
- theNodes[nodeId].m_api_reg_conf = false;
- theNodes[nodeId].m_state.m_connected_nodes.clear();
-
- reportNodeFailed(nodeId, true);
-}
-
-void
-ClusterMgr::reportNodeFailed(NodeId nodeId, bool disconnect){
-
- Node & theNode = theNodes[nodeId];
-
- set_node_alive(theNode, false);
- theNode.m_info.m_connectCount ++;
-
- if(theNode.connected)
- {
- theFacade.doDisconnect(nodeId);
- }
-
- const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING);
- theNode.m_state.startLevel = NodeState::SL_NOTHING;
-
- if(disconnect || report)
- {
- theFacade.ReportNodeDead(nodeId);
- }
-
- theNode.nfCompleteRep = false;
- if(noOfAliveNodes == 0)
- {
- if (!global_flag_skip_invalidate_cache)
- {
- theFacade.m_globalDictCache.lock();
- theFacade.m_globalDictCache.invalidate_all();
- theFacade.m_globalDictCache.unlock();
- m_connect_count ++;
- m_cluster_state = CS_waiting_for_clean_cache;
- }
- NFCompleteRep rep;
- for(Uint32 i = 1; i<MAX_NODES; i++){
- if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){
- rep.failedNodeId = i;
- execNF_COMPLETEREP((Uint32*)&rep);
- }
- }
- }
-}
-
-/******************************************************************************
- * Arbitrator
- ******************************************************************************/
-ArbitMgr::ArbitMgr(TransporterFacade & _fac)
- : theFacade(_fac)
-{
- DBUG_ENTER("ArbitMgr::ArbitMgr");
-
- theThreadMutex = NdbMutex_Create();
- theInputCond = NdbCondition_Create();
- theInputMutex = NdbMutex_Create();
-
- theRank = 0;
- theDelay = 0;
- theThread = 0;
-
- theInputTimeout = 0;
- theInputFull = false;
- memset(&theInputFull, 0, sizeof(theInputFull));
- theState = StateInit;
-
- memset(&theStartReq, 0, sizeof(theStartReq));
- memset(&theChooseReq1, 0, sizeof(theChooseReq1));
- memset(&theChooseReq2, 0, sizeof(theChooseReq2));
- memset(&theStopOrd, 0, sizeof(theStopOrd));
-
- DBUG_VOID_RETURN;
-}
-
-ArbitMgr::~ArbitMgr()
-{
- DBUG_ENTER("ArbitMgr::~ArbitMgr");
- NdbMutex_Destroy(theThreadMutex);
- NdbCondition_Destroy(theInputCond);
- NdbMutex_Destroy(theInputMutex);
- DBUG_VOID_RETURN;
-}
-
-// Start arbitrator thread. This is kernel request.
-// First stop any previous thread since it is a left-over
-// which was never used and which now has wrong ticket.
-void
-ArbitMgr::doStart(const Uint32* theData)
-{
- ArbitSignal aSignal;
- NdbMutex_Lock(theThreadMutex);
- if (theThread != NULL) {
- aSignal.init(GSN_ARBIT_STOPORD, NULL);
- aSignal.data.code = StopRestart;
- sendSignalToThread(aSignal);
- void* value;
- NdbThread_WaitFor(theThread, &value);
- NdbThread_Destroy(&theThread);
- theState = StateInit;
- theInputFull = false;
- }
- aSignal.init(GSN_ARBIT_STARTREQ, theData);
- sendSignalToThread(aSignal);
- theThread = NdbThread_Create(
- runArbitMgr_C, (void**)this, 32768, "ndb_arbitmgr",
- NDB_THREAD_PRIO_HIGH);
- NdbMutex_Unlock(theThreadMutex);
-}
-
-// The "choose me" signal from a candidate.
-void
-ArbitMgr::doChoose(const Uint32* theData)
-{
- ArbitSignal aSignal;
- aSignal.init(GSN_ARBIT_CHOOSEREQ, theData);
- sendSignalToThread(aSignal);
-}
-
-// Stop arbitrator thread via stop signal from the kernel
-// or when exiting API program.
-void
-ArbitMgr::doStop(const Uint32* theData)
-{
- DBUG_ENTER("ArbitMgr::doStop");
- ArbitSignal aSignal;
- NdbMutex_Lock(theThreadMutex);
- if (theThread != NULL) {
- aSignal.init(GSN_ARBIT_STOPORD, theData);
- if (theData == 0) {
- aSignal.data.code = StopExit;
- } else {
- aSignal.data.code = StopRequest;
- }
- sendSignalToThread(aSignal);
- void* value;
- NdbThread_WaitFor(theThread, &value);
- NdbThread_Destroy(&theThread);
- theState = StateInit;
- }
- NdbMutex_Unlock(theThreadMutex);
- DBUG_VOID_RETURN;
-}
-
-// private methods
-
-extern "C"
-void*
-runArbitMgr_C(void* me)
-{
- ((ArbitMgr*) me)->threadMain();
- return NULL;
-}
-
-void
-ArbitMgr::sendSignalToThread(ArbitSignal& aSignal)
-{
-#ifdef DEBUG_ARBIT
- char buf[17] = "";
- ndbout << "arbit recv: ";
- ndbout << " gsn=" << aSignal.gsn;
- ndbout << " send=" << aSignal.data.sender;
- ndbout << " code=" << aSignal.data.code;
- ndbout << " node=" << aSignal.data.node;
- ndbout << " ticket=" << aSignal.data.ticket.getText(buf, sizeof(buf));
- ndbout << " mask=" << aSignal.data.mask.getText(buf, sizeof(buf));
- ndbout << endl;
-#endif
- aSignal.setTimestamp(); // signal arrival time
- NdbMutex_Lock(theInputMutex);
- while (theInputFull) {
- NdbCondition_WaitTimeout(theInputCond, theInputMutex, 1000);
- }
- theInputBuffer = aSignal;
- theInputFull = true;
- NdbCondition_Signal(theInputCond);
- NdbMutex_Unlock(theInputMutex);
-}
-
-void
-ArbitMgr::threadMain()
-{
- ArbitSignal aSignal;
- aSignal = theInputBuffer;
- threadStart(aSignal);
- bool stop = false;
- while (! stop) {
- NdbMutex_Lock(theInputMutex);
- while (! theInputFull) {
- NdbCondition_WaitTimeout(theInputCond, theInputMutex, theInputTimeout);
- threadTimeout();
- }
- aSignal = theInputBuffer;
- theInputFull = false;
- NdbCondition_Signal(theInputCond);
- NdbMutex_Unlock(theInputMutex);
- switch (aSignal.gsn) {
- case GSN_ARBIT_CHOOSEREQ:
- threadChoose(aSignal);
- break;
- case GSN_ARBIT_STOPORD:
- stop = true;
- break;
- }
- }
- threadStop(aSignal);
-}
-
-// handle events in the thread
-
-void
-ArbitMgr::threadStart(ArbitSignal& aSignal)
-{
- theStartReq = aSignal;
- sendStartConf(theStartReq, ArbitCode::ApiStart);
- theState = StateStarted;
- theInputTimeout = 1000;
-}
-
-void
-ArbitMgr::threadChoose(ArbitSignal& aSignal)
-{
- switch (theState) {
- case StateStarted: // first REQ
- if (! theStartReq.data.match(aSignal.data)) {
- sendChooseRef(aSignal, ArbitCode::ErrTicket);
- break;
- }
- theChooseReq1 = aSignal;
- if (theDelay == 0) {
- sendChooseConf(aSignal, ArbitCode::WinChoose);
- theState = StateFinished;
- theInputTimeout = 1000;
- break;
- }
- theState = StateChoose1;
- theInputTimeout = 1;
- return;
- case StateChoose1: // second REQ within Delay
- if (! theStartReq.data.match(aSignal.data)) {
- sendChooseRef(aSignal, ArbitCode::ErrTicket);
- break;
- }
- theChooseReq2 = aSignal;
- theState = StateChoose2;
- theInputTimeout = 1;
- return;
- case StateChoose2: // too many REQs - refuse all
- if (! theStartReq.data.match(aSignal.data)) {
- sendChooseRef(aSignal, ArbitCode::ErrTicket);
- break;
- }
- sendChooseRef(theChooseReq1, ArbitCode::ErrToomany);
- sendChooseRef(theChooseReq2, ArbitCode::ErrToomany);
- sendChooseRef(aSignal, ArbitCode::ErrToomany);
- theState = StateFinished;
- theInputTimeout = 1000;
- return;
- default:
- sendChooseRef(aSignal, ArbitCode::ErrState);
- break;
- }
-}
-
-void
-ArbitMgr::threadTimeout()
-{
- switch (theState) {
- case StateStarted:
- break;
- case StateChoose1:
- if (theChooseReq1.getTimediff() < theDelay)
- break;
- sendChooseConf(theChooseReq1, ArbitCode::WinChoose);
- theState = StateFinished;
- theInputTimeout = 1000;
- break;
- case StateChoose2:
- sendChooseConf(theChooseReq1, ArbitCode::WinChoose);
- sendChooseConf(theChooseReq2, ArbitCode::LoseChoose);
- theState = StateFinished;
- theInputTimeout = 1000;
- break;
- default:
- break;
- }
-}
-
-void
-ArbitMgr::threadStop(ArbitSignal& aSignal)
-{
- switch (aSignal.data.code) {
- case StopExit:
- switch (theState) {
- case StateStarted:
- sendStopRep(theStartReq, 0);
- break;
- case StateChoose1: // just in time
- sendChooseConf(theChooseReq1, ArbitCode::WinChoose);
- break;
- case StateChoose2:
- sendChooseConf(theChooseReq1, ArbitCode::WinChoose);
- sendChooseConf(theChooseReq2, ArbitCode::LoseChoose);
- break;
- case StateInit:
- case StateFinished:
- //??
- break;
- }
- break;
- case StopRequest:
- break;
- case StopRestart:
- break;
- }
-}
-
-// output routines
-
-void
-ArbitMgr::sendStartConf(ArbitSignal& aSignal, Uint32 code)
-{
- ArbitSignal copySignal = aSignal;
- copySignal.gsn = GSN_ARBIT_STARTCONF;
- copySignal.data.code = code;
- sendSignalToQmgr(copySignal);
-}
-
-void
-ArbitMgr::sendChooseConf(ArbitSignal& aSignal, Uint32 code)
-{
- ArbitSignal copySignal = aSignal;
- copySignal.gsn = GSN_ARBIT_CHOOSECONF;
- copySignal.data.code = code;
- sendSignalToQmgr(copySignal);
-}
-
-void
-ArbitMgr::sendChooseRef(ArbitSignal& aSignal, Uint32 code)
-{
- ArbitSignal copySignal = aSignal;
- copySignal.gsn = GSN_ARBIT_CHOOSEREF;
- copySignal.data.code = code;
- sendSignalToQmgr(copySignal);
-}
-
-void
-ArbitMgr::sendStopRep(ArbitSignal& aSignal, Uint32 code)
-{
- ArbitSignal copySignal = aSignal;
- copySignal.gsn = GSN_ARBIT_STOPREP;
- copySignal.data.code = code;
- sendSignalToQmgr(copySignal);
-}
-
-/**
- * Send signal to QMGR. The input includes signal number and
- * signal data. The signal data is normally a copy of a received
- * signal so it contains expected arbitrator node id and ticket.
- * The sender in signal data is the QMGR node id.
- */
-void
-ArbitMgr::sendSignalToQmgr(ArbitSignal& aSignal)
-{
- NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
-
- signal.theVerId_signalNumber = aSignal.gsn;
- signal.theReceiversBlockNumber = QMGR;
- signal.theTrace = 0;
- signal.theLength = ArbitSignalData::SignalLength;
-
- ArbitSignalData* sd = CAST_PTR(ArbitSignalData, signal.getDataPtrSend());
-
- sd->sender = numberToRef(API_CLUSTERMGR, theFacade.ownId());
- sd->code = aSignal.data.code;
- sd->node = aSignal.data.node;
- sd->ticket = aSignal.data.ticket;
- sd->mask = aSignal.data.mask;
-
-#ifdef DEBUG_ARBIT
- char buf[17] = "";
- ndbout << "arbit send: ";
- ndbout << " gsn=" << aSignal.gsn;
- ndbout << " recv=" << aSignal.data.sender;
- ndbout << " code=" << aSignal.data.code;
- ndbout << " node=" << aSignal.data.node;
- ndbout << " ticket=" << aSignal.data.ticket.getText(buf, sizeof(buf));
- ndbout << " mask=" << aSignal.data.mask.getText(buf, sizeof(buf));
- ndbout << endl;
-#endif
-
- theFacade.lock_mutex();
- theFacade.sendSignalUnCond(&signal, aSignal.data.sender);
- theFacade.unlock_mutex();
-}
-
diff --git a/storage/ndb/src/ndbapi/ClusterMgr.hpp b/storage/ndb/src/ndbapi/ClusterMgr.hpp
deleted file mode 100644
index e0c8e50236a..00000000000
--- a/storage/ndb/src/ndbapi/ClusterMgr.hpp
+++ /dev/null
@@ -1,259 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef ClusterMgr_H
-#define ClusterMgr_H
-
-#include "API.hpp"
-#include <ndb_limits.h>
-#include <NdbThread.h>
-#include <NdbMutex.h>
-#include <NdbCondition.h>
-#include <signaldata/ArbitSignalData.hpp>
-#include <signaldata/NodeStateSignalData.hpp>
-#include <NodeInfo.hpp>
-#include <NodeState.hpp>
-
-extern "C" void* runClusterMgr_C(void * me);
-
-
-/**
- * @class ClusterMgr
- */
-class ClusterMgr {
- friend void* runClusterMgr_C(void * me);
- friend void execute(void *, struct SignalHeader * const,
- Uint8, Uint32 * const, LinearSectionPtr ptr[3]);
-public:
- ClusterMgr(class TransporterFacade &);
- ~ClusterMgr();
- void init(struct ndb_mgm_configuration_iterator & config);
-
- void reportConnected(NodeId nodeId);
- void reportDisconnected(NodeId nodeId);
-
- bool checkUpgradeCompatability(Uint32 nodeVersion);
-
- void doStop();
- void startThread();
-
- void forceHB();
- void set_max_api_reg_req_interval(unsigned int millisec) { m_max_api_reg_req_interval = millisec; }
-
-private:
- void threadMain();
-
- int theStop;
- class TransporterFacade & theFacade;
-
-public:
- enum Cluster_state {
- CS_waiting_for_clean_cache = 0,
- CS_waiting_for_first_connect,
- CS_connected
- };
- struct Node {
- Node();
- bool defined;
- bool connected; // Transporter connected
- bool compatible; // Version is compatible
- bool nfCompleteRep; // NF Complete Rep has arrived
- bool m_alive; // Node is alive
- bool m_api_reg_conf;// API_REGCONF has arrived
-
- NodeInfo m_info;
- NodeState m_state;
-
- /**
- * Heartbeat stuff
- */
- Uint32 hbFrequency; // Heartbeat frequence
- Uint32 hbCounter; // # milliseconds passed since last hb sent
- };
-
- const Node & getNodeInfo(NodeId) const;
- Uint32 getNoOfConnectedNodes() const;
- bool isClusterAlive() const;
- void hb_received(NodeId);
-
- Uint32 m_connect_count;
-private:
- Uint32 m_max_api_reg_req_interval;
- Uint32 noOfAliveNodes;
- Uint32 noOfConnectedNodes;
- Node theNodes[MAX_NODES];
- NdbThread* theClusterMgrThread;
-
- NodeBitmask waitForHBFromNodes; // used in forcing HBs
- NdbCondition* waitForHBCond;
- bool waitingForHB;
-
- enum Cluster_state m_cluster_state;
- /**
- * Used for controlling start/stop of the thread
- */
- NdbMutex* clusterMgrThreadMutex;
-
- void showState(NodeId nodeId);
- void reportNodeFailed(NodeId nodeId, bool disconnect = false);
-
- /**
- * Signals received
- */
- void execAPI_REGREQ (const Uint32 * theData);
- void execAPI_REGCONF (const Uint32 * theData);
- void execAPI_REGREF (const Uint32 * theData);
- void execNODE_FAILREP (const Uint32 * theData);
- void execNF_COMPLETEREP(const Uint32 * theData);
-
- inline void set_node_alive(Node& node, bool alive){
- if(node.m_alive && !alive)
- {
- assert(noOfAliveNodes);
- noOfAliveNodes--;
- }
- else if(!node.m_alive && alive)
- {
- noOfAliveNodes++;
- }
- node.m_alive = alive;
- }
-};
-
-inline
-const ClusterMgr::Node &
-ClusterMgr::getNodeInfo(NodeId nodeId) const {
- return theNodes[nodeId];
-}
-
-inline
-Uint32
-ClusterMgr::getNoOfConnectedNodes() const {
- return noOfConnectedNodes;
-}
-
-inline
-bool
-ClusterMgr::isClusterAlive() const {
- return noOfAliveNodes != 0;
-}
-inline
-void
-ClusterMgr::hb_received(NodeId nodeId) {
- theNodes[nodeId].m_info.m_heartbeat_cnt= 0;
-}
-
-/*****************************************************************************/
-
-/**
- * @class ArbitMgr
- * Arbitration manager. Runs in separate thread.
- * Started only by a request from the kernel.
- */
-
-extern "C" void* runArbitMgr_C(void* me);
-
-class ArbitMgr
-{
-public:
- ArbitMgr(class TransporterFacade &);
- ~ArbitMgr();
-
- inline void setRank(unsigned n) { theRank = n; }
- inline void setDelay(unsigned n) { theDelay = n; }
-
- void doStart(const Uint32* theData);
- void doChoose(const Uint32* theData);
- void doStop(const Uint32* theData);
-
- friend void* runArbitMgr_C(void* me);
-
-private:
- class TransporterFacade & theFacade;
- unsigned theRank;
- unsigned theDelay;
-
- void threadMain();
- NdbThread* theThread;
- NdbMutex* theThreadMutex; // not really needed
-
- struct ArbitSignal {
- GlobalSignalNumber gsn;
- ArbitSignalData data;
- NDB_TICKS timestamp;
-
- ArbitSignal() {}
-
- inline void init(GlobalSignalNumber aGsn, const Uint32* aData) {
- gsn = aGsn;
- if (aData != NULL)
- memcpy(&data, aData, sizeof(data));
- else
- memset(&data, 0, sizeof(data));
- }
-
- inline void setTimestamp() {
- timestamp = NdbTick_CurrentMillisecond();
- }
-
- inline NDB_TICKS getTimediff() {
- NDB_TICKS now = NdbTick_CurrentMillisecond();
- return now < timestamp ? 0 : now - timestamp;
- }
- };
-
- NdbMutex* theInputMutex;
- NdbCondition* theInputCond;
- int theInputTimeout;
- bool theInputFull; // the predicate
- ArbitSignal theInputBuffer; // shared buffer
-
- void sendSignalToThread(ArbitSignal& aSignal);
-
- enum State { // thread states
- StateInit,
- StateStarted, // thread started
- StateChoose1, // received one valid REQ
- StateChoose2, // received two valid REQs
- StateFinished // finished one way or other
- };
- State theState;
-
- enum Stop { // stop code in ArbitSignal.data.code
- StopExit = 1, // at API exit
- StopRequest = 2, // request from kernel
- StopRestart = 3 // stop before restart
- };
-
- void threadStart(ArbitSignal& aSignal); // handle thread events
- void threadChoose(ArbitSignal& aSignal);
- void threadTimeout();
- void threadStop(ArbitSignal& aSignal);
-
- ArbitSignal theStartReq;
- ArbitSignal theChooseReq1;
- ArbitSignal theChooseReq2;
- ArbitSignal theStopOrd;
-
- void sendStartConf(ArbitSignal& aSignal, Uint32);
- void sendChooseRef(ArbitSignal& aSignal, Uint32);
- void sendChooseConf(ArbitSignal& aSignal, Uint32);
- void sendStopRep(ArbitSignal& aSignal, Uint32);
-
- void sendSignalToQmgr(ArbitSignal& aSignal);
-};
-
-#endif
diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp
deleted file mode 100644
index 44f258526b3..00000000000
--- a/storage/ndb/src/ndbapi/DictCache.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "DictCache.hpp"
-#include "NdbDictionaryImpl.hpp"
-#include <NdbTick.h>
-#include <NdbCondition.h>
-#include <NdbSleep.h>
-
-static NdbTableImpl * f_invalid_table = 0;
-static NdbTableImpl * f_altered_table = 0;
-
-static int ndb_dict_cache_count = 0;
-
-Ndb_local_table_info *
-Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz)
-{
- assert(! is_ndb_blob_table(table_impl));
- Uint32 tot_size= sizeof(Ndb_local_table_info) - sizeof(Uint64)
- + ((sz+7) & ~7); // round to Uint64
- void *data= malloc(tot_size);
- if (data == 0)
- return 0;
- memset(data, 0, tot_size);
- new (data) Ndb_local_table_info(table_impl);
- return (Ndb_local_table_info *) data;
-}
-
-void Ndb_local_table_info::destroy(Ndb_local_table_info *info)
-{
- free((void *)info);
-}
-
-Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
-{
- assert(! is_ndb_blob_table(table_impl));
- m_table_impl= table_impl;
- m_tuple_id_range.reset();
-}
-
-Ndb_local_table_info::~Ndb_local_table_info()
-{
-}
-
-LocalDictCache::LocalDictCache(){
- m_tableHash.createHashTable();
-}
-
-LocalDictCache::~LocalDictCache(){
- m_tableHash.releaseHashTable();
-}
-
-Ndb_local_table_info *
-LocalDictCache::get(const char * name){
- ASSERT_NOT_MYSQLD;
- assert(! is_ndb_blob_table(name));
- const Uint32 len = strlen(name);
- return m_tableHash.getData(name, len);
-}
-
-void
-LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){
- ASSERT_NOT_MYSQLD;
- assert(! is_ndb_blob_table(name));
- const Uint32 id = tab_info->m_table_impl->m_id;
- m_tableHash.insertKey(name, strlen(name), id, tab_info);
-}
-
-void
-LocalDictCache::drop(const char * name){
- ASSERT_NOT_MYSQLD;
- assert(! is_ndb_blob_table(name));
- Ndb_local_table_info *info= m_tableHash.deleteKey(name, strlen(name));
- DBUG_ASSERT(info != 0);
- Ndb_local_table_info::destroy(info);
-}
-
-/*****************************************************************
- * Global cache
- */
-GlobalDictCache::GlobalDictCache(){
- DBUG_ENTER("GlobalDictCache::GlobalDictCache");
- m_tableHash.createHashTable();
- m_waitForTableCondition = NdbCondition_Create();
- if (f_invalid_table == NULL)
- f_invalid_table = new NdbTableImpl();
- if (f_altered_table == NULL)
- f_altered_table = new NdbTableImpl();
- ndb_dict_cache_count++;
- DBUG_VOID_RETURN;
-}
-
-GlobalDictCache::~GlobalDictCache(){
- DBUG_ENTER("GlobalDictCache::~GlobalDictCache");
- if (--ndb_dict_cache_count == 0)
- {
- if (f_invalid_table)
- {
- delete f_invalid_table;
- f_invalid_table = 0;
- }
- if (f_altered_table)
- {
- delete f_altered_table;
- f_altered_table = 0;
- }
- }
- NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
- while(curr != 0){
- Vector<TableVersion> * vers = curr->theData;
- const unsigned sz = vers->size();
- for(unsigned i = 0; i<sz ; i++){
- TableVersion tv= (*vers)[i];
- DBUG_PRINT(" ", ("vers[%d]: ver: %d, refCount: %d, status: %d",
- i, tv.m_version, tv.m_refCount, tv.m_status));
- if(tv.m_impl != 0)
- {
- DBUG_PRINT(" ", ("m_impl: internalname: %s",
- tv.m_impl->m_internalName.c_str()));
- delete (* vers)[i].m_impl;
- }
- }
- delete curr->theData;
- curr->theData= NULL;
- curr = m_tableHash.getNext(curr);
- }
- m_tableHash.releaseHashTable();
- NdbCondition_Destroy(m_waitForTableCondition);
- DBUG_VOID_RETURN;
-}
-
-void GlobalDictCache::printCache()
-{
- DBUG_ENTER("GlobalDictCache::printCache");
- NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
- while(curr != 0){
- DBUG_PRINT("curr", ("len: %d, hash: %d, lk: %d, str: %s",
- curr->len, curr->hash, curr->localkey1,
- (char*) curr->str));
- if (curr->theData){
- Vector<TableVersion> * vers = curr->theData;
- const unsigned sz = vers->size();
- for(unsigned i = 0; i<sz ; i++){
- TableVersion tv= (*vers)[i];
- DBUG_PRINT(" ", ("impl: %p vers[%d]: ver: %d, refCount: %d, status: %d",
- tv.m_impl, i, tv.m_version, tv.m_refCount, tv.m_status));
- if(tv.m_impl != 0)
- {
- DBUG_PRINT(" ", ("m_impl: internalname: %s",
- tv.m_impl->m_internalName.c_str()));
- }
- }
- }
- else
- {
- DBUG_PRINT(" ", ("NULL"));
- }
- curr = m_tableHash.getNext(curr);
- }
- DBUG_VOID_RETURN;
-}
-
-NdbTableImpl *
-GlobalDictCache::get(const char * name, int *error)
-{
- DBUG_ENTER("GlobalDictCache::get");
- DBUG_PRINT("enter", ("name: %s", name));
- assert(! is_ndb_blob_table(name));
-
- const Uint32 len = strlen(name);
- Vector<TableVersion> * versions = 0;
- versions = m_tableHash.getData(name, len);
- if(versions == 0){
- versions = new Vector<TableVersion>(2);
- if (versions == NULL)
- {
- *error = -1;
- DBUG_RETURN(0);
- }
- m_tableHash.insertKey(name, len, 0, versions);
- }
-
- int waitTime = 100;
-
- bool retreive = false;
- while(versions->size() > 0 && !retreive){
- TableVersion * ver = & versions->back();
- switch(ver->m_status){
- case OK:
- if (ver->m_impl->m_status == NdbDictionary::Object::Invalid)
- {
- ver->m_status = DROPPED;
- retreive = true; // Break loop
- if (ver->m_refCount == 0)
- {
- delete ver->m_impl;
- versions->erase(versions->size() - 1);
- }
- break;
- }
- ver->m_refCount++;
- DBUG_PRINT("info", ("Table OK tab: %p version=%x.%x refCount=%u",
- ver->m_impl,
- ver->m_impl->m_version & 0xFFFFFF,
- ver->m_impl->m_version >> 24,
- ver->m_refCount));
- DBUG_RETURN(ver->m_impl);
- case DROPPED:
- retreive = true; // Break loop
- break;
- case RETREIVING:
- DBUG_PRINT("info", ("Wait for retrieving thread"));
- NdbCondition_WaitTimeout(m_waitForTableCondition, m_mutex, waitTime);
- continue;
- }
- }
-
- /**
- * Create new...
- */
- TableVersion tmp;
- tmp.m_version = 0;
- tmp.m_impl = 0;
- tmp.m_status = RETREIVING;
- tmp.m_refCount = 1; // The one retreiving it
- if (versions->push_back(tmp))
- {
- *error = -1;
- DBUG_RETURN(0);
- }
- DBUG_PRINT("info", ("No table found"));
- DBUG_RETURN(0);
-}
-
-NdbTableImpl *
-GlobalDictCache::put(const char * name, NdbTableImpl * tab)
-{
- DBUG_ENTER("GlobalDictCache::put");
- DBUG_PRINT("enter", ("tab: %p name: %s, internal_name: %s version: %x.%x",
- tab, name,
- tab ? tab->m_internalName.c_str() : "tab NULL",
- tab ? tab->m_version & 0xFFFFFF : 0,
- tab ? tab->m_version >> 24 : 0));
- assert(! is_ndb_blob_table(name));
-
- const Uint32 len = strlen(name);
- Vector<TableVersion> * vers = m_tableHash.getData(name, len);
- if(vers == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- const Uint32 sz = vers->size();
- if(sz == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- TableVersion & ver = vers->back();
- if(ver.m_status != RETREIVING ||
- !(ver.m_impl == 0 ||
- ver.m_impl == f_invalid_table || ver.m_impl == f_altered_table) ||
- ver.m_version != 0 ||
- ver.m_refCount == 0){
- abort();
- }
-
- if(tab == 0)
- {
- DBUG_PRINT("info", ("No table found in db"));
- vers->erase(sz - 1);
- }
- else if (ver.m_impl == 0) {
- DBUG_PRINT("info", ("Table OK"));
- ver.m_impl = tab;
- ver.m_version = tab->m_version;
- ver.m_status = OK;
- }
- else if (ver.m_impl == f_invalid_table)
- {
- DBUG_PRINT("info", ("Table DROPPED invalid"));
- ver.m_impl = tab;
- ver.m_version = tab->m_version;
- ver.m_status = DROPPED;
- ver.m_impl->m_status = NdbDictionary::Object::Invalid;
- }
- else if(ver.m_impl == f_altered_table)
- {
- DBUG_PRINT("info", ("Table DROPPED altered"));
- ver.m_impl = tab;
- ver.m_version = tab->m_version;
- ver.m_status = DROPPED;
- ver.m_impl->m_status = NdbDictionary::Object::Altered;
- }
- else
- {
- abort();
- }
- NdbCondition_Broadcast(m_waitForTableCondition);
- DBUG_RETURN(tab);
-}
-
-unsigned
-GlobalDictCache::get_size()
-{
- NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
- int sz = 0;
- while(curr != 0){
- sz += curr->theData->size();
- curr = m_tableHash.getNext(curr);
- }
- if (sz)
- {
- printCache();
- }
- return sz;
-}
-
-void
-GlobalDictCache::invalidate_all()
-{
- DBUG_ENTER("GlobalDictCache::invalidate_all");
- NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
- while(curr != 0){
- Vector<TableVersion> * vers = curr->theData;
- if (vers->size())
- {
- TableVersion * ver = & vers->back();
- if (ver->m_status != RETREIVING)
- {
- ver->m_impl->m_status = NdbDictionary::Object::Invalid;
- ver->m_status = DROPPED;
- if (ver->m_refCount == 0)
- {
- delete ver->m_impl;
- vers->erase(vers->size() - 1);
- }
- }
- }
- curr = m_tableHash.getNext(curr);
- }
- DBUG_VOID_RETURN;
-}
-
-void
-GlobalDictCache::release(NdbTableImpl * tab, int invalidate)
-{
- DBUG_ENTER("GlobalDictCache::release");
- DBUG_PRINT("enter", ("tab: %p internal_name: %s",
- tab, tab->m_internalName.c_str()));
- assert(! is_ndb_blob_table(tab));
-
- unsigned i;
- const Uint32 len = strlen(tab->m_internalName.c_str());
- Vector<TableVersion> * vers =
- m_tableHash.getData(tab->m_internalName.c_str(), len);
- if(vers == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- const Uint32 sz = vers->size();
- if(sz == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- for(i = 0; i < sz; i++){
- TableVersion & ver = (* vers)[i];
- if(ver.m_impl == tab){
- if(ver.m_refCount == 0 || ver.m_status == RETREIVING ||
- ver.m_version != tab->m_version){
- DBUG_PRINT("info", ("Releasing with refCount=%d status=%d impl=%p",
- ver.m_refCount, ver.m_status, ver.m_impl));
- break;
- }
-
- ver.m_refCount--;
- if (ver.m_impl->m_status == NdbDictionary::Object::Invalid || invalidate)
- {
- ver.m_impl->m_status = NdbDictionary::Object::Invalid;
- ver.m_status = DROPPED;
- }
- if (ver.m_refCount == 0 && ver.m_status == DROPPED)
- {
- DBUG_PRINT("info", ("refCount is zero, deleting m_impl"));
- delete ver.m_impl;
- vers->erase(i);
- }
- DBUG_VOID_RETURN;
- }
- }
-
- for(i = 0; i<sz; i++){
- TableVersion & ver = (* vers)[i];
- ndbout_c("%d: version: %d refCount: %d status: %d impl: %p",
- i, ver.m_version, ver.m_refCount,
- ver.m_status, ver.m_impl);
- }
-
- abort();
-}
-
-void
-GlobalDictCache::alter_table_rep(const char * name,
- Uint32 tableId,
- Uint32 tableVersion,
- bool altered)
-{
- DBUG_ENTER("GlobalDictCache::alter_table_rep");
- assert(! is_ndb_blob_table(name));
- const Uint32 len = strlen(name);
- Vector<TableVersion> * vers =
- m_tableHash.getData(name, len);
-
- if(vers == 0)
- {
- DBUG_VOID_RETURN;
- }
-
- const Uint32 sz = vers->size();
- if(sz == 0)
- {
- DBUG_VOID_RETURN;
- }
-
- for(Uint32 i = 0; i < sz; i++)
- {
- TableVersion & ver = (* vers)[i];
- if(ver.m_version == tableVersion && ver.m_impl &&
- (Uint32) ver.m_impl->m_id == tableId)
- {
- ver.m_status = DROPPED;
- ver.m_impl->m_status = altered ?
- NdbDictionary::Object::Altered : NdbDictionary::Object::Invalid;
- if (ver.m_refCount == 0)
- {
- delete ver.m_impl;
- vers->erase(i);
- }
- DBUG_VOID_RETURN;
- }
-
- if(i == sz - 1 && ver.m_status == RETREIVING)
- {
- ver.m_impl = altered ? f_altered_table : f_invalid_table;
- DBUG_VOID_RETURN;
- }
- }
- DBUG_VOID_RETURN;
-}
-
-template class Vector<GlobalDictCache::TableVersion>;
diff --git a/storage/ndb/src/ndbapi/DictCache.hpp b/storage/ndb/src/ndbapi/DictCache.hpp
deleted file mode 100644
index 8839358185d..00000000000
--- a/storage/ndb/src/ndbapi/DictCache.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef DictCache_H
-#define DictCache_H
-
-#include <ndb_types.h>
-#include <kernel_types.h>
-#include <NdbError.hpp>
-#include <BaseString.hpp>
-#include <Vector.hpp>
-#include <UtilBuffer.hpp>
-#include <NdbDictionary.hpp>
-#include <Ndb.hpp>
-#include <NdbCondition.h>
-#include "NdbLinHash.hpp"
-
-class Ndb_local_table_info {
-public:
- static Ndb_local_table_info *create(NdbTableImpl *table_impl, Uint32 sz=0);
- static void destroy(Ndb_local_table_info *);
- NdbTableImpl *m_table_impl;
-
- // range of cached tuple ids per thread
- Ndb::TupleIdRange m_tuple_id_range;
-
- Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
-private:
- Ndb_local_table_info(NdbTableImpl *table_impl);
- ~Ndb_local_table_info();
-};
-
-/**
- * A non thread safe dict cache
- */
-class LocalDictCache {
-public:
- LocalDictCache();
- ~LocalDictCache();
-
- Ndb_local_table_info * get(const char * name);
-
- void put(const char * name, Ndb_local_table_info *);
- void drop(const char * name);
-
- NdbLinHash<Ndb_local_table_info> m_tableHash; // On name
-};
-
-/**
- * A thread safe dict cache
- */
-class GlobalDictCache : public NdbLockable {
-public:
- GlobalDictCache();
- ~GlobalDictCache();
-
- NdbTableImpl * get(NdbTableImpl *tab);
- NdbTableImpl * get(const char * name, int *error);
-
- NdbTableImpl* put(const char * name, NdbTableImpl *);
- void release(NdbTableImpl *, int invalidate = 0);
-
- void alter_table_rep(const char * name,
- Uint32 tableId, Uint32 tableVersion, bool altered);
-
- unsigned get_size();
- void invalidate_all();
-public:
- enum Status {
- OK = 0,
- DROPPED = 1,
- RETREIVING = 2
- };
-
-private:
- void printCache();
-
- struct TableVersion {
- Uint32 m_version;
- Uint32 m_refCount;
- NdbTableImpl * m_impl;
- Status m_status;
- };
-
- NdbLinHash<Vector<TableVersion> > m_tableHash;
- NdbCondition * m_waitForTableCondition;
-};
-
-#endif
-
-
diff --git a/storage/ndb/src/ndbapi/Makefile.am b/storage/ndb/src/ndbapi/Makefile.am
deleted file mode 100644
index 07c09a0f515..00000000000
--- a/storage/ndb/src/ndbapi/Makefile.am
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2004-2006 MySQL AB
-# Use is subject to license terms
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-#SUBDIRS = signal-sender
-
-noinst_PROGRAMS = ndberror_check
-
-ndberror_check_SOURCES = ndberror_check.c
-
-noinst_LTLIBRARIES = libndbapi.la
-
-libndbapi_la_SOURCES = \
- TransporterFacade.cpp \
- ClusterMgr.cpp \
- Ndb.cpp \
- NdbPoolImpl.cpp \
- NdbPool.cpp \
- Ndblist.cpp \
- Ndbif.cpp \
- Ndbinit.cpp \
- Ndberr.cpp \
- ndberror.c \
- NdbErrorOut.cpp \
- NdbTransaction.cpp \
- NdbTransactionScan.cpp \
- NdbOperation.cpp \
- NdbOperationSearch.cpp \
- NdbOperationScan.cpp \
- NdbOperationInt.cpp \
- NdbOperationDefine.cpp \
- NdbOperationExec.cpp \
- NdbScanOperation.cpp NdbScanFilter.cpp \
- NdbIndexOperation.cpp \
- NdbEventOperation.cpp \
- NdbEventOperationImpl.cpp \
- NdbApiSignal.cpp \
- NdbRecAttr.cpp \
- NdbUtil.cpp \
- NdbReceiver.cpp \
- NdbDictionary.cpp \
- NdbDictionaryImpl.cpp \
- DictCache.cpp \
- ndb_cluster_connection.cpp \
- NdbBlob.cpp \
- NdbIndexStat.cpp \
- SignalSender.cpp \
- ObjectMap.cpp
-
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
-
-# Ndbapi cannot handle -O3
-NDB_CXXFLAGS_RELEASE_LOC = -O2
-
-include $(top_srcdir)/storage/ndb/config/common.mk.am
-include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
-
-ndberror_check_LDFLAGS = \
- $(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/mysys/libmysys.a \
- $(top_builddir)/strings/libmystrings.a
-
-windoze-dsp: libndbapi.dsp
-
-libndbapi.dsp: Makefile \
- $(top_srcdir)/storage/ndb/config/win-lib.am \
- $(top_srcdir)/storage/ndb/config/win-name \
- $(top_srcdir)/storage/ndb/config/win-includes \
- $(top_srcdir)/storage/ndb/config/win-sources \
- $(top_srcdir)/storage/ndb/config/win-libraries
- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbapi_la_SOURCES)
- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp
deleted file mode 100644
index 005fa2633aa..00000000000
--- a/storage/ndb/src/ndbapi/Ndb.cpp
+++ /dev/null
@@ -1,1920 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-
-
-/*****************************************************************************
-Name: Ndb.cpp
-******************************************************************************/
-
-#include <ndb_global.h>
-
-
-#include "NdbApiSignal.hpp"
-#include "NdbImpl.hpp"
-#include <NdbOperation.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbEventOperation.hpp>
-#include <NdbEventOperationImpl.hpp>
-#include <NdbRecAttr.hpp>
-#include <md5_hash.hpp>
-#include <NdbSleep.h>
-#include <NdbOut.hpp>
-#include <ndb_limits.h>
-#include "API.hpp"
-#include <NdbEnv.h>
-#include <BaseString.hpp>
-#include <NdbSqlUtil.hpp>
-
-/****************************************************************************
-void connect();
-
-Connect to any node which has no connection at the moment.
-****************************************************************************/
-NdbTransaction* Ndb::doConnect(Uint32 tConNode)
-{
- Uint32 tNode;
- Uint32 tAnyAlive = 0;
- int TretCode= 0;
-
- DBUG_ENTER("Ndb::doConnect");
-
- if (tConNode != 0) {
- TretCode = NDB_connect(tConNode);
- if ((TretCode == 1) || (TretCode == 2)) {
-//****************************************************************************
-// We have connections now to the desired node. Return
-//****************************************************************************
- DBUG_RETURN(getConnectedNdbTransaction(tConNode));
- } else if (TretCode < 0) {
- DBUG_RETURN(NULL);
- } else if (TretCode != 0) {
- tAnyAlive = 1;
- }//if
- }//if
-//****************************************************************************
-// We will connect to any node. Make sure that we have connections to all
-// nodes.
-//****************************************************************************
- if (theImpl->m_optimized_node_selection)
- {
- Ndb_cluster_connection_node_iter &node_iter=
- theImpl->m_node_iter;
- theImpl->m_ndb_cluster_connection.init_get_next_node(node_iter);
- while ((tNode= theImpl->m_ndb_cluster_connection.get_next_node(node_iter)))
- {
- TretCode= NDB_connect(tNode);
- if ((TretCode == 1) ||
- (TretCode == 2))
- {
-//****************************************************************************
-// We have connections now to the desired node. Return
-//****************************************************************************
- DBUG_RETURN(getConnectedNdbTransaction(tNode));
- } else if (TretCode < 0) {
- DBUG_RETURN(NULL);
- } else if (TretCode != 0) {
- tAnyAlive= 1;
- }//if
- DBUG_PRINT("info",("tried node %d, TretCode %d, error code %d, %s",
- tNode, TretCode, getNdbError().code,
- getNdbError().message));
- }
- }
- else // just do a regular round robin
- {
- Uint32 tNoOfDbNodes= theImpl->theNoOfDBnodes;
- Uint32 &theCurrentConnectIndex= theImpl->theCurrentConnectIndex;
- UintR Tcount = 0;
- do {
- theCurrentConnectIndex++;
- if (theCurrentConnectIndex >= tNoOfDbNodes)
- theCurrentConnectIndex = 0;
-
- Tcount++;
- tNode= theImpl->theDBnodes[theCurrentConnectIndex];
- TretCode= NDB_connect(tNode);
- if ((TretCode == 1) ||
- (TretCode == 2))
- {
-//****************************************************************************
-// We have connections now to the desired node. Return
-//****************************************************************************
- DBUG_RETURN(getConnectedNdbTransaction(tNode));
- } else if (TretCode < 0) {
- DBUG_RETURN(NULL);
- } else if (TretCode != 0) {
- tAnyAlive= 1;
- }//if
- DBUG_PRINT("info",("tried node %d TretCode %d", tNode, TretCode));
- } while (Tcount < tNoOfDbNodes);
- }
-//****************************************************************************
-// We were unable to find a free connection. If no node alive we will report
-// error code for cluster failure otherwise connection failure.
-//****************************************************************************
- if (tAnyAlive == 1) {
-#ifdef VM_TRACE
- ndbout << "TretCode = " << TretCode << endl;
-#endif
- theError.code = 4006;
- } else {
- theError.code = 4009;
- }//if
- DBUG_RETURN(NULL);
-}
-
-int
-Ndb::NDB_connect(Uint32 tNode)
-{
-//****************************************************************************
-// We will perform seize of a transaction record in DBTC in the specified node.
-//***************************************************************************
-
- int tReturnCode;
- TransporterFacade *tp = theImpl->m_transporter_facade;
-
- DBUG_ENTER("Ndb::NDB_connect");
-
- bool nodeAvail = tp->get_node_alive(tNode);
- if(nodeAvail == false){
- DBUG_RETURN(0);
- }
-
- NdbTransaction * tConArray = theConnectionArray[tNode];
- if (tConArray != NULL) {
- DBUG_RETURN(2);
- }
-
- NdbTransaction * tNdbCon = getNdbCon(); // Get free connection object.
- if (tNdbCon == NULL) {
- DBUG_RETURN(4);
- }//if
- NdbApiSignal* tSignal = getSignal(); // Get signal object
- if (tSignal == NULL) {
- releaseNdbCon(tNdbCon);
- DBUG_RETURN(4);
- }//if
- if (tSignal->setSignal(GSN_TCSEIZEREQ) == -1) {
- releaseNdbCon(tNdbCon);
- releaseSignal(tSignal);
- DBUG_RETURN(4);
- }//if
- tSignal->setData(tNdbCon->ptr2int(), 1);
-//************************************************
-// Set connection pointer as NdbTransaction object
-//************************************************
- tSignal->setData(theMyRef, 2); // Set my block reference
- tNdbCon->Status(NdbTransaction::Connecting); // Set status to connecting
- Uint32 nodeSequence;
- tReturnCode= sendRecSignal(tNode, WAIT_TC_SEIZE, tSignal,
- 0, &nodeSequence);
- releaseSignal(tSignal);
- if ((tReturnCode == 0) && (tNdbCon->Status() == NdbTransaction::Connected)) {
- //************************************************
- // Send and receive was successful
- //************************************************
- NdbTransaction* tPrevFirst = theConnectionArray[tNode];
- tNdbCon->setConnectedNodeId(tNode, nodeSequence);
-
- tNdbCon->setMyBlockReference(theMyRef);
- theConnectionArray[tNode] = tNdbCon;
- tNdbCon->theNext = tPrevFirst;
- DBUG_RETURN(1);
- } else {
- releaseNdbCon(tNdbCon);
-//****************************************************************************
-// Unsuccessful connect is indicated by 3.
-//****************************************************************************
- DBUG_PRINT("info",
- ("unsuccessful connect tReturnCode %d, tNdbCon->Status() %d",
- tReturnCode, tNdbCon->Status()));
- if (theError.code == 299 || // single user mode
- theError.code == 281 ) // cluster shutdown in progress
- {
- // no need to retry with other node
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(3);
- }//if
-}//Ndb::NDB_connect()
-
-NdbTransaction *
-Ndb::getConnectedNdbTransaction(Uint32 nodeId){
- NdbTransaction* next = theConnectionArray[nodeId];
- theConnectionArray[nodeId] = next->theNext;
- next->theNext = NULL;
-
- return next;
-}//Ndb::getConnectedNdbTransaction()
-
-/*****************************************************************************
-disconnect();
-
-Remark: Disconnect all connections to the database.
-*****************************************************************************/
-void
-Ndb::doDisconnect()
-{
- DBUG_ENTER("Ndb::doDisconnect");
- NdbTransaction* tNdbCon;
- CHECK_STATUS_MACRO_VOID;
-
- Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes;
- Uint8 *theDBnodes= theImpl->theDBnodes;
- DBUG_PRINT("info", ("theNoOfDBnodes=%d", tNoOfDbNodes));
- UintR i;
- for (i = 0; i < tNoOfDbNodes; i++) {
- Uint32 tNode = theDBnodes[i];
- tNdbCon = theConnectionArray[tNode];
- while (tNdbCon != NULL) {
- NdbTransaction* tmpNdbCon = tNdbCon;
- tNdbCon = tNdbCon->theNext;
- releaseConnectToNdb(tmpNdbCon);
- }//while
- }//for
- tNdbCon = theTransactionList;
- while (tNdbCon != NULL) {
- NdbTransaction* tmpNdbCon = tNdbCon;
- tNdbCon = tNdbCon->theNext;
- releaseConnectToNdb(tmpNdbCon);
- }//while
- DBUG_VOID_RETURN;
-}//Ndb::disconnect()
-
-/*****************************************************************************
-int waitUntilReady(int timeout);
-
-Return Value: Returns 0 if the Ndb is ready within timeout seconds.
- Returns -1 otherwise.
-Remark: Waits until a node has status != 0
-*****************************************************************************/
-int
-Ndb::waitUntilReady(int timeout)
-{
- DBUG_ENTER("Ndb::waitUntilReady");
- int secondsCounter = 0;
- int milliCounter = 0;
-
- if (theInitState != Initialised) {
- // Ndb::init is not called
- theError.code = 4256;
- DBUG_RETURN(-1);
- }
-
- while (theNode == 0) {
- if (secondsCounter >= timeout)
- {
- theError.code = 4269;
- DBUG_RETURN(-1);
- }
- NdbSleep_MilliSleep(100);
- milliCounter += 100;
- if (milliCounter >= 1000) {
- secondsCounter++;
- milliCounter = 0;
- }//if
- }
-
- if (theImpl->m_ndb_cluster_connection.wait_until_ready
- (timeout-secondsCounter,30) < 0)
- {
- theError.code = 4009;
- DBUG_RETURN(-1);
- }
-
- DBUG_RETURN(0);
-}
-
-/*****************************************************************************
-NdbTransaction* startTransaction();
-
-Return Value: Returns a pointer to a connection object.
- Return NULL otherwise.
-Remark: Start transaction. Synchronous.
-*****************************************************************************/
-int
-Ndb::computeHash(Uint32 *retval,
- const NdbDictionary::Table *table,
- const struct Key_part_ptr * keyData,
- void* buf, Uint32 bufLen)
-{
- Uint32 j = 0;
- Uint32 sumlen = 0; // Needed len
- const NdbTableImpl* impl = &NdbTableImpl::getImpl(*table);
- const NdbColumnImpl* const * cols = impl->m_columns.getBase();
- Uint32 len;
- char* pos;
-
- Uint32 colcnt = impl->m_columns.size();
- Uint32 parts = impl->m_noOfDistributionKeys;
- if (parts == 0)
- {
- parts = impl->m_noOfKeys;
- }
-
- for (Uint32 i = 0; i<parts; i++)
- {
- if (unlikely(keyData[i].ptr == 0))
- goto enullptr;
- }
-
- if (unlikely(keyData[parts].ptr != 0))
- goto emissingnullptr;
-
- const NdbColumnImpl* partcols[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
- for (Uint32 i = 0; i<colcnt && j < parts; i++)
- {
- if (cols[i]->m_distributionKey)
- {
- // wl3717_todo
- // char allowed now as dist key so this case should be tested
- partcols[j++] = cols[i];
- }
- }
-
- for (Uint32 i = 0; i<parts; i++)
- {
- Uint32 lb, len;
- if (unlikely(!NdbSqlUtil::get_var_length(partcols[i]->m_type,
- keyData[i].ptr,
- keyData[i].len,
- lb, len)))
- goto emalformedkey;
-
- if (unlikely(keyData[i].len < (lb + len)))
- goto elentosmall;
-
- Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
-
- if (unlikely(lb == 0 && keyData[i].len != maxlen))
- goto emalformedkey;
-
- if (partcols[i]->m_cs)
- {
- Uint32 xmul = partcols[i]->m_cs->strxfrm_multiply;
- xmul = xmul ? xmul : 1;
- len = xmul * (maxlen - lb);
- }
-
- len = (lb + len + 3) & ~(Uint32)3;
- sumlen += len;
-
- }
-
- if (buf)
- {
- UintPtr org = UintPtr(buf);
- UintPtr use = (org + 7) & ~(UintPtr)7;
-
- buf = (void*)use;
- bufLen -= (use - org);
-
- if (unlikely(sumlen > bufLen))
- goto ebuftosmall;
- }
- else
- {
- buf = malloc(sumlen);
- if (unlikely(buf == 0))
- goto enomem;
- bufLen = 0;
- assert((UintPtr(buf) & 7) == 0);
- }
-
- pos = (char*)buf;
- for (Uint32 i = 0; i<parts; i++)
- {
- Uint32 lb, len;
- NdbSqlUtil::get_var_length(partcols[i]->m_type,
- keyData[i].ptr, keyData[i].len, lb, len);
- CHARSET_INFO* cs;
- if ((cs = partcols[i]->m_cs))
- {
- Uint32 xmul = cs->strxfrm_multiply;
- if (xmul == 0)
- xmul = 1;
- /*
- * Varchar end-spaces are ignored in comparisons. To get same hash
- * we blank-pad to maximum length via strnxfrm.
- */
- Uint32 maxlen = (partcols[i]->m_attrSize * partcols[i]->m_arraySize);
- Uint32 dstLen = xmul * (maxlen - lb);
- int n = NdbSqlUtil::strnxfrm_bug7284(cs,
- (unsigned char*)pos,
- dstLen,
- ((unsigned char*)keyData[i].ptr)+lb,
- len);
-
- if (unlikely(n == -1))
- goto emalformedstring;
-
- while ((n & 3) != 0)
- {
- pos[n++] = 0;
- }
- pos += n;
- }
- else
- {
- len += lb;
- memcpy(pos, keyData[i].ptr, len);
- while (len & 3)
- {
- * (pos + len++) = 0;
- }
- pos += len;
- }
- }
- len = UintPtr(pos) - UintPtr(buf);
- assert((len & 3) == 0);
-
- Uint32 values[4];
- md5_hash(values, (const Uint64*)buf, len >> 2);
-
- if (retval)
- {
- * retval = values[1];
- }
-
- if (bufLen == 0)
- free(buf);
-
- return 0;
-
-enullptr:
- return 4316;
-
-emissingnullptr:
- return 4276;
-
-elentosmall:
- return 4277;
-
-ebuftosmall:
- return 4278;
-
-emalformedstring:
- if (bufLen == 0)
- free(buf);
-
- return 4279;
-
-emalformedkey:
- return 4280;
-
-enomem:
- return 4000;
-}
-
-NdbTransaction*
-Ndb::startTransaction(const NdbDictionary::Table *table,
- const char * keyData, Uint32 keyLen)
-{
- DBUG_ENTER("Ndb::startTransaction");
-
- if (theInitState == Initialised) {
- theError.code = 0;
- checkFailedNode();
- /**
- * If the user supplied key data
- * We will make a qualified quess to which node is the primary for the
- * the fragment and contact that node
- */
- Uint32 nodeId;
- NdbTableImpl* impl;
- if(table != 0 && keyData != 0 && (impl= &NdbTableImpl::getImpl(*table)))
- {
- Uint32 hashValue;
- {
- Uint32 buf[4];
- if((UintPtr(keyData) & 7) == 0 && (keyLen & 3) == 0)
- {
- md5_hash(buf, (const Uint64*)keyData, keyLen >> 2);
- }
- else
- {
- Uint64 tmp[1000];
- tmp[keyLen/8] = 0;
- memcpy(tmp, keyData, keyLen);
- md5_hash(buf, tmp, (keyLen+3) >> 2);
- }
- hashValue= buf[1];
- }
- const Uint16 *nodes;
- Uint32 cnt= impl->get_nodes(hashValue, &nodes);
- if(cnt)
- nodeId= nodes[0];
- else
- nodeId= 0;
- } else {
- nodeId = 0;
- }//if
-
- {
- NdbTransaction *trans= startTransactionLocal(0, nodeId);
- DBUG_PRINT("exit",("start trans: 0x%lx transid: 0x%lx",
- (long) trans,
- (long) (trans ? trans->getTransactionId() : 0)));
- DBUG_RETURN(trans);
- }
- } else {
- DBUG_RETURN(NULL);
- }//if
-}//Ndb::startTransaction()
-
-/*****************************************************************************
-NdbTransaction* hupp(NdbTransaction* pBuddyTrans);
-
-Return Value: Returns a pointer to a connection object.
- Connected to the same node as pBuddyTrans
- and also using the same transction id
-Remark: Start transaction. Synchronous.
-*****************************************************************************/
-NdbTransaction*
-Ndb::hupp(NdbTransaction* pBuddyTrans)
-{
- DBUG_ENTER("Ndb::hupp");
-
- DBUG_PRINT("enter", ("trans: 0x%lx", (long) pBuddyTrans));
-
- Uint32 aPriority = 0;
- if (pBuddyTrans == NULL){
- DBUG_RETURN(startTransaction());
- }
-
- if (theInitState == Initialised) {
- theError.code = 0;
- checkFailedNode();
-
- Uint32 nodeId = pBuddyTrans->getConnectedNodeId();
- NdbTransaction* pCon = startTransactionLocal(aPriority, nodeId);
- if(pCon == NULL)
- DBUG_RETURN(NULL);
-
- if (pCon->getConnectedNodeId() != nodeId){
- // We could not get a connection to the desired node
- // release the connection and return NULL
- closeTransaction(pCon);
- theError.code = 4006;
- DBUG_RETURN(NULL);
- }
- pCon->setTransactionId(pBuddyTrans->getTransactionId());
- pCon->setBuddyConPtr((Uint32)pBuddyTrans->getTC_ConnectPtr());
- DBUG_PRINT("exit", ("hupp trans: 0x%lx transid: 0x%lx",
- (long) pCon,
- (long) (pCon ? pCon->getTransactionId() : 0)));
- DBUG_RETURN(pCon);
- } else {
- DBUG_RETURN(NULL);
- }//if
-}//Ndb::hupp()
-
-NdbTransaction*
-Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId)
-{
-#ifdef VM_TRACE
- char buf[255];
- const char* val = NdbEnv_GetEnv("NDB_TRANSACTION_NODE_ID", buf, 255);
- if(val != 0){
- nodeId = atoi(val);
- }
-#endif
-
- DBUG_ENTER("Ndb::startTransactionLocal");
- DBUG_PRINT("enter", ("nodeid: %d", nodeId));
-
- if(unlikely(theRemainingStartTransactions == 0))
- {
- theError.code = 4006;
- DBUG_RETURN(0);
- }
-
- NdbTransaction* tConnection;
- Uint64 tFirstTransId = theFirstTransId;
- tConnection = doConnect(nodeId);
- if (tConnection == NULL) {
- DBUG_RETURN(NULL);
- }//if
-
- theRemainingStartTransactions--;
- NdbTransaction* tConNext = theTransactionList;
- if (tConnection->init())
- {
- theError.code = tConnection->theError.code;
- DBUG_RETURN(NULL);
- }
- theTransactionList = tConnection; // into a transaction list.
- tConnection->next(tConNext); // Add the active connection object
- tConnection->setTransactionId(tFirstTransId);
- tConnection->thePriority = aPriority;
- if ((tFirstTransId & 0xFFFFFFFF) == 0xFFFFFFFF) {
- //---------------------------------------------------
-// Transaction id rolling round. We will start from
-// consecutive identity 0 again.
-//---------------------------------------------------
- theFirstTransId = ((tFirstTransId >> 32) << 32);
- } else {
- theFirstTransId = tFirstTransId + 1;
- }//if
-#ifdef VM_TRACE
- if (tConnection->theListState != NdbTransaction::NotInList) {
- printState("startTransactionLocal %x", tConnection);
- abort();
- }
-#endif
- DBUG_RETURN(tConnection);
-}//Ndb::startTransactionLocal()
-
-/*****************************************************************************
-void closeTransaction(NdbTransaction* aConnection);
-
-Parameters: aConnection: the connection used in the transaction.
-Remark: Close transaction by releasing the connection and all operations.
-*****************************************************************************/
-void
-Ndb::closeTransaction(NdbTransaction* aConnection)
-{
- DBUG_ENTER("Ndb::closeTransaction");
- NdbTransaction* tCon;
- NdbTransaction* tPreviousCon;
-
- if (aConnection == NULL) {
-//-----------------------------------------------------
-// closeTransaction called on NULL pointer, destructive
-// application behaviour.
-//-----------------------------------------------------
-#ifdef VM_TRACE
- printf("NULL into closeTransaction\n");
-#endif
- DBUG_VOID_RETURN;
- }//if
- CHECK_STATUS_MACRO_VOID;
-
- tCon = theTransactionList;
- theRemainingStartTransactions++;
-
- DBUG_PRINT("info",("close trans: 0x%lx transid: 0x%lx",
- (long) aConnection,
- (long) aConnection->getTransactionId()));
- DBUG_PRINT("info",("magic number: 0x%x TCConPtr: 0x%x theMyRef: 0x%x 0x%x",
- aConnection->theMagicNumber, aConnection->theTCConPtr,
- aConnection->theMyRef, getReference()));
-
- if (aConnection == tCon) { // Remove the active connection object
- 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 NdbTransaction leads
- * to reuse. And TC crashes when the API tries to reuse it to
- * something else...
- */
-#ifdef VM_TRACE
- printf("Scan timeout:ed NdbTransaction-> "
- "not returning it-> memory leak\n");
-#endif
- DBUG_VOID_RETURN;
- }
-
-#ifdef VM_TRACE
- printf("Non-existing transaction into closeTransaction\n");
- abort();
-#endif
- DBUG_VOID_RETURN;
- }//if
- tPreviousCon = tCon;
- tCon = tCon->next();
- }//while
- tPreviousCon->next(tCon->next());
- }//if
-
- aConnection->release();
-
- if(aConnection->theError.code == 4008){
- /**
- * Something timed-out, returning the NdbTransaction leads
- * to reuse. And TC crashes when the API tries to reuse it to
- * something else...
- */
-#ifdef VM_TRACE
- printf("Con timeout:ed NdbTransaction-> not returning it-> memory leak\n");
-#endif
- DBUG_VOID_RETURN;
- }
-
- if (aConnection->theReleaseOnClose == false) {
- /**
- * Put it back in idle list for that node
- */
- Uint32 nodeId = aConnection->getConnectedNodeId();
- aConnection->theNext = theConnectionArray[nodeId];
- theConnectionArray[nodeId] = aConnection;
- DBUG_VOID_RETURN;
- } else {
- aConnection->theReleaseOnClose = false;
- releaseNdbCon(aConnection);
- }//if
- DBUG_VOID_RETURN;
-}//Ndb::closeTransaction()
-
-/*****************************************************************************
-int* NdbTamper(int aAction, int aNode);
-
-Parameters: aAction Specifies what action to be taken
- 1: Lock global checkpointing Can only be sent to master DIH, Parameter aNode ignored.
- 2: UnLock global checkpointing Can only be sent to master DIH, Parameter aNode ignored.
- 3: Crash node
-
- aNode Specifies which node the action will be taken
- -1: Master DIH
- 0-16: Nodnumber
-
-Return Value: -1 Error .
-
-Remark: Sends a signal to DIH.
-*****************************************************************************/
-int
-Ndb::NdbTamper(TamperType aAction, int aNode)
-{
- NdbTransaction* tNdbConn;
- NdbApiSignal tSignal(theMyRef);
- int tNode;
- int tAction;
- int ret_code;
-
-#ifdef CUSTOMER_RELEASE
- return -1;
-#else
- DBUG_ENTER("Ndb::NdbTamper");
- CHECK_STATUS_MACRO;
- checkFailedNode();
-
- theRestartGCI = 0;
- switch (aAction) {
-// Translate enum to integer. This is done because the SCI layer
-// expects integers.
- case LockGlbChp:
- tAction = 1;
- break;
- case UnlockGlbChp:
- tAction = 2;
- break;
- case CrashNode:
- tAction = 3;
- break;
- case ReadRestartGCI:
- tAction = 4;
- break;
- default:
- theError.code = 4102;
- DBUG_RETURN(-1);
- }
-
- tNdbConn = getNdbCon(); // Get free connection object
- if (tNdbConn == NULL) {
- theError.code = 4000;
- DBUG_RETURN(-1);
- }
- tSignal.setSignal(GSN_DIHNDBTAMPER);
- tSignal.setData (tAction, 1);
- tSignal.setData(tNdbConn->ptr2int(),2);
- tSignal.setData(theMyRef,3); // Set return block reference
- tNdbConn->Status(NdbTransaction::Connecting); // Set status to connecting
- TransporterFacade *tp = theImpl->m_transporter_facade;
- if (tAction == 3) {
- tp->lock_mutex();
- tp->sendSignal(&tSignal, aNode);
- tp->unlock_mutex();
- releaseNdbCon(tNdbConn);
- } else if ( (tAction == 2) || (tAction == 1) ) {
- tp->lock_mutex();
- tNode = tp->get_an_alive_node();
- if (tNode == 0) {
- theError.code = 4002;
- releaseNdbCon(tNdbConn);
- DBUG_RETURN(-1);
- }//if
- ret_code = tp->sendSignal(&tSignal,aNode);
- tp->unlock_mutex();
- releaseNdbCon(tNdbConn);
- DBUG_RETURN(ret_code);
- } else {
- do {
- tp->lock_mutex();
- // Start protected area
- tNode = tp->get_an_alive_node();
- tp->unlock_mutex();
- // End protected area
- if (tNode == 0) {
- theError.code = 4009;
- releaseNdbCon(tNdbConn);
- DBUG_RETURN(-1);
- }//if
- ret_code = sendRecSignal(tNode, WAIT_NDB_TAMPER, &tSignal, 0);
- if (ret_code == 0) {
- if (tNdbConn->Status() != NdbTransaction::Connected) {
- theRestartGCI = 0;
- }//if
- releaseNdbCon(tNdbConn);
- DBUG_RETURN(theRestartGCI);
- } else if ((ret_code == -5) || (ret_code == -2)) {
- TRACE_DEBUG("Continue DIHNDBTAMPER when node failed/stopping");
- } else {
- DBUG_RETURN(-1);
- }//if
- } while (1);
- }
- DBUG_RETURN(0);
-#endif
-}
-#if 0
-/****************************************************************************
-NdbSchemaCon* startSchemaTransaction();
-
-Return Value: Returns a pointer to a schema connection object.
- Return NULL otherwise.
-Remark: Start schema transaction. Synchronous.
-****************************************************************************/
-NdbSchemaCon*
-Ndb::startSchemaTransaction()
-{
- NdbSchemaCon* tSchemaCon;
- if (theSchemaConToNdbList != NULL) {
- theError.code = 4321;
- return NULL;
- }//if
- tSchemaCon = new NdbSchemaCon(this);
- if (tSchemaCon == NULL) {
- theError.code = 4000;
- return NULL;
- }//if
- theSchemaConToNdbList = tSchemaCon;
- return tSchemaCon;
-}
-/*****************************************************************************
-void closeSchemaTransaction(NdbSchemaCon* aSchemaCon);
-
-Parameters: aSchemaCon: the schemacon used in the transaction.
-Remark: Close transaction by releasing the schemacon and all schemaop.
-*****************************************************************************/
-void
-Ndb::closeSchemaTransaction(NdbSchemaCon* aSchemaCon)
-{
- if (theSchemaConToNdbList != aSchemaCon) {
- abort();
- return;
- }//if
- aSchemaCon->release();
- delete aSchemaCon;
- theSchemaConToNdbList = NULL;
- return;
-}//Ndb::closeSchemaTransaction()
-#endif
-
-/*****************************************************************************
-void RestartGCI(int aRestartGCI);
-
-Remark: Set theRestartGCI on the NDB object
-*****************************************************************************/
-void
-Ndb::RestartGCI(int aRestartGCI)
-{
- theRestartGCI = aRestartGCI;
-}
-
-/****************************************************************************
-int getBlockNumber(void);
-
-Remark:
-****************************************************************************/
-int
-Ndb::getBlockNumber()
-{
- return theNdbBlockNumber;
-}
-
-NdbDictionary::Dictionary *
-Ndb::getDictionary() const {
- return theDictionary;
-}
-
-/****************************************************************************
-int getNodeId();
-
-Remark:
-****************************************************************************/
-int
-Ndb::getNodeId()
-{
- return theNode;
-}
-
-/****************************************************************************
-Uint64 getAutoIncrementValue( const char* aTableName,
- Uint64 & autoValue,
- Uint32 cacheSize,
- Uint64 step,
- Uint64 start);
-
-Parameters: aTableName (IN) : The table name.
- autoValue (OUT) : Returns new autoincrement value
- cacheSize (IN) : Prefetch this many values
- step (IN) : Specifies the step between the
- autoincrement values.
- start (IN) : Start value for first value
-Returns: 0 if succesful, -1 if error encountered
-Remark: Returns a new autoincrement value to the application.
- The autoincrement values can be increased by steps
- (default 1) and a number of values can be prefetched
- by specifying cacheSize (default 10).
-****************************************************************************/
-int
-Ndb::getAutoIncrementValue(const char* aTableName,
- Uint64 & autoValue, Uint32 cacheSize,
- Uint64 step, Uint64 start)
-{
- DBUG_ENTER("Ndb::getAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- BaseString internal_tabname(internalize_table_name(aTableName));
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- const NdbTableImpl* table = info->m_table_impl;
- TupleIdRange & range = info->m_tuple_id_range;
- if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong) autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & autoValue, Uint32 cacheSize,
- Uint64 step, Uint64 start)
-{
- DBUG_ENTER("Ndb::getAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
- const BaseString& internal_tabname = table->m_internalName;
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- TupleIdRange & range = info->m_tuple_id_range;
- if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable,
- TupleIdRange & range, Uint64 & autoValue,
- Uint32 cacheSize, Uint64 step, Uint64 start)
-{
- DBUG_ENTER("Ndb::getAutoIncrementValue");
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
-
- if (getTupleIdFromNdb(table, range, autoValue, cacheSize, step, start) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::getTupleIdFromNdb(const NdbTableImpl* table,
- TupleIdRange & range, Uint64 & tupleId,
- Uint32 cacheSize, Uint64 step, Uint64 start)
-{
-/*
- Returns a new TupleId to the application.
- The TupleId comes from SYSTAB_0 where SYSKEY_0 = TableId.
- It is initialized to (TableId << 48) + 1 in NdbcntrMain.cpp.
- In most cases step= start= 1, in which case we get:
- 1,2,3,4,5,...
- If step=10 and start=5 and first number is 1, we get:
- 5,15,25,35,...
-*/
- DBUG_ENTER("Ndb::getTupleIdFromNdb");
- /*
- Check if the next value can be taken from the pre-fetched
- sequence.
- */
- if (range.m_first_tuple_id != range.m_last_tuple_id &&
- range.m_first_tuple_id + step <= range.m_last_tuple_id)
- {
- assert(range.m_first_tuple_id < range.m_last_tuple_id);
- range.m_first_tuple_id += step;
- tupleId = range.m_first_tuple_id;
- DBUG_PRINT("info", ("Next cached value %lu", (ulong) tupleId));
- }
- else
- {
- /*
- If start value is greater than step it is ignored
- */
- Uint64 offset = (start > step) ? 1 : start;
-
- /*
- Pre-fetch a number of values depending on cacheSize
- */
- if (cacheSize == 0)
- cacheSize = 1;
-
- DBUG_PRINT("info", ("reading %u values from database", (uint)cacheSize));
- /*
- * reserve next cacheSize entries in db. adds cacheSize to NEXTID
- * and returns first tupleId in the new range. If tupleId's are
- * incremented in steps then multiply the cacheSize with step size.
- */
- Uint64 opValue = cacheSize * step;
-
- if (opTupleIdOnNdb(table, range, opValue, 0) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("Next value fetched from database %lu", (ulong) opValue));
- DBUG_PRINT("info", ("Increasing %lu by offset %lu, increment is %lu", (ulong) (ulong) opValue, (ulong) offset, (ulong) step));
- Uint64 current, next;
- Uint64 div = ((Uint64) (opValue + step - offset)) / step;
- next = div * step + offset;
- current = (next < step) ? next : next - step;
- tupleId = (opValue <= current) ? current : next;
- DBUG_PRINT("info", ("Returning %lu", (ulong) tupleId));
- range.m_first_tuple_id = tupleId;
- }
- DBUG_RETURN(0);
-}
-
-/****************************************************************************
-int readAutoIncrementValue( const char* aTableName,
- Uint64 & autoValue);
-
-Parameters: aTableName (IN) : The table name.
- autoValue (OUT) : The current autoincrement value
-Returns: 0 if succesful, -1 if error encountered
-Remark: Returns the current autoincrement value to the application.
-****************************************************************************/
-int
-Ndb::readAutoIncrementValue(const char* aTableName,
- Uint64 & autoValue)
-{
- DBUG_ENTER("Ndb::readAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- BaseString internal_tabname(internalize_table_name(aTableName));
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- const NdbTableImpl* table = info->m_table_impl;
- TupleIdRange & range = info->m_tuple_id_range;
- if (readTupleIdFromNdb(table, range, autoValue) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 & autoValue)
-{
- DBUG_ENTER("Ndb::readAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
- const BaseString& internal_tabname = table->m_internalName;
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- TupleIdRange & range = info->m_tuple_id_range;
- if (readTupleIdFromNdb(table, range, autoValue) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
- TupleIdRange & range, Uint64 & autoValue)
-{
- DBUG_ENTER("Ndb::readAutoIncrementValue");
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
-
- if (readTupleIdFromNdb(table, range, autoValue) == -1)
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
- DBUG_RETURN(0);
-}
-
-int
-Ndb::readTupleIdFromNdb(const NdbTableImpl* table,
- TupleIdRange & range, Uint64 & tupleId)
-{
- DBUG_ENTER("Ndb::readTupleIdFromNdb");
- if (range.m_first_tuple_id != range.m_last_tuple_id)
- {
- assert(range.m_first_tuple_id < range.m_last_tuple_id);
- tupleId = range.m_first_tuple_id + 1;
- }
- else
- {
- /*
- * peek at NEXTID. does not reserve it so the value is valid
- * only if no other transactions are allowed.
- */
- Uint64 opValue = 0;
- if (opTupleIdOnNdb(table, range, opValue, 3) == -1)
- DBUG_RETURN(-1);
- tupleId = opValue;
- }
- DBUG_RETURN(0);
-}
-
-/****************************************************************************
-int setAutoIncrementValue( const char* aTableName,
- Uint64 autoValue,
- bool modify);
-
-Parameters: aTableName (IN) : The table name.
- autoValue (IN) : The new autoincrement value
- modify (IN) : Modify existing value (not initialization)
-Returns: 0 if succesful, -1 if error encountered
-Remark: Sets a new autoincrement value for the application.
-****************************************************************************/
-int
-Ndb::setAutoIncrementValue(const char* aTableName,
- Uint64 autoValue, bool modify)
-{
- DBUG_ENTER("Ndb::setAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- BaseString internal_tabname(internalize_table_name(aTableName));
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- const NdbTableImpl* table = info->m_table_impl;
- TupleIdRange & range = info->m_tuple_id_range;
- if (setTupleIdInNdb(table, range, autoValue, modify) == -1)
- DBUG_RETURN(-1);
- DBUG_RETURN(0);
-}
-
-int
-Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
- Uint64 autoValue, bool modify)
-{
- DBUG_ENTER("Ndb::setAutoIncrementValue");
- ASSERT_NOT_MYSQLD;
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
- const BaseString& internal_tabname = table->m_internalName;
-
- Ndb_local_table_info *info=
- theDictionary->get_local_table_info(internal_tabname);
- if (info == 0) {
- theError.code = theDictionary->getNdbError().code;
- DBUG_RETURN(-1);
- }
- TupleIdRange & range = info->m_tuple_id_range;
- if (setTupleIdInNdb(table, range, autoValue, modify) == -1)
- DBUG_RETURN(-1);
- DBUG_RETURN(0);
-}
-
-int
-Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
- TupleIdRange & range, Uint64 autoValue,
- bool modify)
-{
- DBUG_ENTER("Ndb::setAutoIncrementValue");
- assert(aTable != 0);
- const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable);
-
- if (setTupleIdInNdb(table, range, autoValue, modify) == -1)
- DBUG_RETURN(-1);
- DBUG_RETURN(0);
-}
-
-int
-Ndb::setTupleIdInNdb(const NdbTableImpl* table,
- TupleIdRange & range, Uint64 tupleId, bool modify)
-{
- DBUG_ENTER("Ndb::setTupleIdInNdb");
- if (modify)
- {
- if (checkTupleIdInNdb(range, tupleId))
- {
- if (range.m_first_tuple_id != range.m_last_tuple_id)
- {
- assert(range.m_first_tuple_id < range.m_last_tuple_id);
- if (tupleId <= range.m_first_tuple_id + 1)
- DBUG_RETURN(0);
- if (tupleId <= range.m_last_tuple_id)
- {
- range.m_first_tuple_id = tupleId - 1;
- DBUG_PRINT("info",
- ("Setting next auto increment cached value to %lu",
- (ulong)tupleId));
- DBUG_RETURN(0);
- }
- }
- /*
- * if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
- * tupleId and set cached range to first = last = tupleId - 1.
- */
- if (opTupleIdOnNdb(table, range, tupleId, 2) == -1)
- DBUG_RETURN(-1);
- }
- }
- else
- {
- /*
- * update NEXTID to given value. reset cached range.
- */
- if (opTupleIdOnNdb(table, range, tupleId, 1) == -1)
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-int Ndb::initAutoIncrement()
-{
- if (m_sys_tab_0)
- return 0;
-
- BaseString currentDb(getDatabaseName());
- BaseString currentSchema(getDatabaseSchemaName());
-
- setDatabaseName("sys");
- setDatabaseSchemaName("def");
-
- m_sys_tab_0 = theDictionary->getTableGlobal("SYSTAB_0");
-
- // Restore current name space
- setDatabaseName(currentDb.c_str());
- setDatabaseSchemaName(currentSchema.c_str());
-
- if (m_sys_tab_0 == NULL) {
- assert(theDictionary->m_error.code != 0);
- theError.code = theDictionary->m_error.code;
- return -1;
- }
-
- return 0;
-}
-
-bool
-Ndb::checkUpdateAutoIncrementValue(TupleIdRange & range, Uint64 autoValue)
-{
- return(checkTupleIdInNdb(range, autoValue) != 0);
-}
-
-int
-Ndb::checkTupleIdInNdb(TupleIdRange & range, Uint64 tupleId)
-{
- DBUG_ENTER("Ndb::checkTupleIdIndNdb");
- if ((range.m_first_tuple_id != ~(Uint64)0) &&
- (range.m_first_tuple_id > tupleId))
- {
- /*
- * If we have ever cached a value in this object and this cached
- * value is larger than the value we're trying to set then we
- * need not check with the real value in the SYSTAB_0 table.
- */
- DBUG_RETURN(0);
- }
- if (range.m_highest_seen > tupleId)
- {
- /*
- * Although we've never cached any higher value we have read
- * a higher value and again it isn't necessary to change the
- * auto increment value.
- */
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-
-int
-Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
- TupleIdRange & range, Uint64 & opValue, Uint32 op)
-{
- DBUG_ENTER("Ndb::opTupleIdOnNdb");
- Uint32 aTableId = table->m_id;
- DBUG_PRINT("enter", ("table: %u value: %lu op: %u",
- aTableId, (ulong) opValue, op));
-
- NdbTransaction* tConnection = NULL;
- NdbOperation* tOperation = NULL;
- Uint64 tValue;
- NdbRecAttr* tRecAttrResult;
-
- CHECK_STATUS_MACRO;
-
- if (initAutoIncrement() == -1)
- goto error_handler;
-
- tConnection = this->startTransaction();
- if (tConnection == NULL)
- goto error_handler;
-
- tOperation = tConnection->getNdbOperation(m_sys_tab_0);
- if (tOperation == NULL)
- goto error_handler;
-
- switch (op)
- {
- case 0:
- tOperation->interpretedUpdateTuple();
- tOperation->equal("SYSKEY_0", aTableId);
- tOperation->incValue("NEXTID", opValue);
- tRecAttrResult = tOperation->getValue("NEXTID");
-
- if (tConnection->execute( NdbTransaction::Commit ) == -1 )
- goto error_handler;
-
- tValue = tRecAttrResult->u_64_value();
-
- range.m_first_tuple_id = tValue - opValue;
- range.m_last_tuple_id = tValue - 1;
- opValue = range.m_first_tuple_id; // out
- break;
- case 1:
- // create on first use
- tOperation->writeTuple();
- tOperation->equal("SYSKEY_0", aTableId );
- tOperation->setValue("NEXTID", opValue);
-
- if (tConnection->execute( NdbTransaction::Commit ) == -1 )
- goto error_handler;
-
- range.reset();
- break;
- case 2:
- tOperation->interpretedUpdateTuple();
- tOperation->equal("SYSKEY_0", aTableId );
- tOperation->load_const_u64(1, opValue);
- tOperation->read_attr("NEXTID", 2);
- // compare NEXTID >= opValue
- tOperation->branch_le(2, 1, 0);
- tOperation->write_attr("NEXTID", 1);
- tOperation->interpret_exit_ok();
- tOperation->def_label(0);
- tOperation->interpret_exit_ok();
- tRecAttrResult = tOperation->getValue("NEXTID");
- if (tConnection->execute( NdbTransaction::Commit ) == -1)
- {
- goto error_handler;
- }
- else
- {
- range.m_highest_seen = tRecAttrResult->u_64_value();
- DBUG_PRINT("info",
- ("Setting next auto increment value (db) to %lu",
- (ulong) opValue));
- range.m_first_tuple_id = range.m_last_tuple_id = opValue - 1;
- }
- break;
- case 3:
- tOperation->readTuple();
- tOperation->equal("SYSKEY_0", aTableId );
- tRecAttrResult = tOperation->getValue("NEXTID");
- if (tConnection->execute( NdbTransaction::Commit ) == -1 )
- goto error_handler;
- range.m_highest_seen = opValue = tRecAttrResult->u_64_value(); // out
- break;
- default:
- goto error_handler;
- }
-
- this->closeTransaction(tConnection);
-
- DBUG_RETURN(0);
-
-error_handler:
- DBUG_PRINT("error", ("ndb=%d con=%d op=%d",
- theError.code,
- tConnection != NULL ? tConnection->theError.code : -1,
- tOperation != NULL ? tOperation->theError.code : -1));
-
- if (theError.code == 0 && tConnection != NULL)
- theError.code = tConnection->theError.code;
- if (theError.code == 0 && tOperation != NULL)
- theError.code = tOperation->theError.code;
- DBUG_ASSERT(theError.code != 0);
-
- NdbError savedError;
- savedError = theError;
-
- if (tConnection != NULL)
- this->closeTransaction(tConnection);
-
- theError = savedError;
-
- DBUG_RETURN(-1);
-}
-
-Uint32
-convertEndian(Uint32 Data)
-{
-#ifdef WORDS_BIGENDIAN
- Uint32 t1, t2, t3, t4;
- t4 = (Data >> 24) & 255;
- t3 = (Data >> 16) & 255;
- t4 = t4 + (t3 << 8);
- t2 = (Data >> 8) & 255;
- t4 = t4 + (t2 << 16);
- t1 = Data & 255;
- t4 = t4 + (t1 << 24);
- return t4;
-#else
- return Data;
-#endif
-}
-
-// <internal>
-Ndb_cluster_connection &
-Ndb::get_ndb_cluster_connection()
-{
- return theImpl->m_ndb_cluster_connection;
-}
-
-const char * Ndb::getCatalogName() const
-{
- return theImpl->m_dbname.c_str();
-}
-
-int Ndb::setCatalogName(const char * a_catalog_name)
-{
- // TODO can table_name_separator be escaped?
- if (a_catalog_name && ! strchr(a_catalog_name, table_name_separator)) {
- if (!theImpl->m_dbname.assign(a_catalog_name) ||
- theImpl->update_prefix())
- {
- theError.code = 4000;
- return -1;
- }
- }
- return 0;
-}
-
-const char * Ndb::getSchemaName() const
-{
- return theImpl->m_schemaname.c_str();
-}
-
-int Ndb::setSchemaName(const char * a_schema_name)
-{
- // TODO can table_name_separator be escaped?
- if (a_schema_name && ! strchr(a_schema_name, table_name_separator)) {
- if (!theImpl->m_schemaname.assign(a_schema_name) ||
- theImpl->update_prefix())
- {
- theError.code = 4000;
- return -1;
- }
- }
- return 0;
-}
-// </internal>
-
-const char * Ndb::getDatabaseName() const
-{
- return getCatalogName();
-}
-
-int Ndb::setDatabaseName(const char * a_catalog_name)
-{
- return setCatalogName(a_catalog_name);
-}
-
-const char * Ndb::getDatabaseSchemaName() const
-{
- return getSchemaName();
-}
-
-int Ndb::setDatabaseSchemaName(const char * a_schema_name)
-{
- return setSchemaName(a_schema_name);
-}
-
-int Ndb::setDatabaseAndSchemaName(const NdbDictionary::Table* t)
-{
- const char* s0 = t->m_impl.m_internalName.c_str();
- const char* s1 = strchr(s0, table_name_separator);
- if (s1 && s1 != s0) {
- const char* s2 = strchr(s1 + 1, table_name_separator);
- if (s2 && s2 != s1 + 1) {
- char buf[NAME_LEN + 1];
- if (s1 - s0 <= NAME_LEN && s2 - (s1 + 1) <= NAME_LEN) {
- sprintf(buf, "%.*s", (int) (s1 - s0), s0);
- setDatabaseName(buf);
- sprintf(buf, "%.*s", (int) (s2 - (s1 + 1)), s1 + 1);
- setDatabaseSchemaName(buf);
- return 0;
- }
- }
- }
- return -1;
-}
-
-bool Ndb::usingFullyQualifiedNames()
-{
- return fullyQualifiedNames;
-}
-
-const char *
-Ndb::externalizeTableName(const char * internalTableName, bool fullyQualifiedNames)
-{
- if (fullyQualifiedNames) {
- register const char *ptr = internalTableName;
-
- // Skip database name
- while (*ptr && *ptr++ != table_name_separator)
- ;
- // Skip schema name
- while (*ptr && *ptr++ != table_name_separator)
- ;
- return ptr;
- }
- else
- return internalTableName;
-}
-
-const char *
-Ndb::externalizeTableName(const char * internalTableName)
-{
- return externalizeTableName(internalTableName, usingFullyQualifiedNames());
-}
-
-const char *
-Ndb::externalizeIndexName(const char * internalIndexName, bool fullyQualifiedNames)
-{
- if (fullyQualifiedNames) {
- register const char *ptr = internalIndexName;
-
- // Scan name from the end
- while (*ptr++)
- ;
- ptr--; // strend
- while (ptr >= internalIndexName && *ptr != table_name_separator)
- ptr--;
-
- return ptr + 1;
- }
- else
- return internalIndexName;
-}
-
-const char *
-Ndb::externalizeIndexName(const char * internalIndexName)
-{
- return externalizeIndexName(internalIndexName, usingFullyQualifiedNames());
-}
-
-
-const BaseString
-Ndb::internalize_table_name(const char *external_name) const
-{
- BaseString ret;
- DBUG_ENTER("internalize_table_name");
- DBUG_PRINT("enter", ("external_name: %s", external_name));
-
- if (fullyQualifiedNames)
- {
- /* Internal table name format <db>/<schema>/<table>
- <db>/<schema>/ is already available in m_prefix
- so just concat the two strings
- */
-#ifdef VM_TRACE
- // verify that m_prefix looks like abc/def/
- const char* s0 = theImpl->m_prefix.c_str();
- const char* s1 = s0 ? strchr(s0, table_name_separator) : 0;
- const char* s2 = s1 ? strchr(s1 + 1, table_name_separator) : 0;
- assert(s1 && s1 != s0 && s2 && s2 != s1 + 1 && *(s2 + 1) == 0);
-#endif
- ret.assfmt("%s%s",
- theImpl->m_prefix.c_str(),
- external_name);
- }
- else
- ret.assign(external_name);
-
- DBUG_PRINT("exit", ("internal_name: %s", ret.c_str()));
- DBUG_RETURN(ret);
-}
-
-const BaseString
-Ndb::old_internalize_index_name(const NdbTableImpl * table,
- const char * external_name) const
-{
- BaseString ret;
- DBUG_ENTER("old_internalize_index_name");
- DBUG_PRINT("enter", ("external_name: %s, table_id: %d",
- external_name, table ? table->m_id : ~0));
- if (!table)
- {
- DBUG_PRINT("error", ("!table"));
- DBUG_RETURN(ret);
- }
-
- if (fullyQualifiedNames)
- {
- /* Internal index name format <db>/<schema>/<tabid>/<table> */
- ret.assfmt("%s%d%c%s",
- theImpl->m_prefix.c_str(),
- table->m_id,
- table_name_separator,
- external_name);
- }
- else
- ret.assign(external_name);
-
- DBUG_PRINT("exit", ("internal_name: %s", ret.c_str()));
- DBUG_RETURN(ret);
-}
-
-const BaseString
-Ndb::internalize_index_name(const NdbTableImpl * table,
- const char * external_name) const
-{
- BaseString ret;
- DBUG_ENTER("internalize_index_name");
- DBUG_PRINT("enter", ("external_name: %s, table_id: %d",
- external_name, table ? table->m_id : ~0));
- if (!table)
- {
- DBUG_PRINT("error", ("!table"));
- DBUG_RETURN(ret);
- }
-
- if (fullyQualifiedNames)
- {
- /* Internal index name format sys/def/<tabid>/<table> */
- ret.assfmt("%s%d%c%s",
- theImpl->m_systemPrefix.c_str(),
- table->m_id,
- table_name_separator,
- external_name);
- }
- else
- ret.assign(external_name);
-
- DBUG_PRINT("exit", ("internal_name: %s", ret.c_str()));
- DBUG_RETURN(ret);
-}
-
-
-const BaseString
-Ndb::getDatabaseFromInternalName(const char * internalName)
-{
- char * databaseName = new char[strlen(internalName) + 1];
- if (databaseName == NULL)
- {
- errno = ENOMEM;
- return BaseString(NULL);
- }
- strcpy(databaseName, internalName);
- register char *ptr = databaseName;
-
- /* Scan name for the first table_name_separator */
- while (*ptr && *ptr != table_name_separator)
- ptr++;
- *ptr = '\0';
- BaseString ret = BaseString(databaseName);
- delete [] databaseName;
- return ret;
-}
-
-const BaseString
-Ndb::getSchemaFromInternalName(const char * internalName)
-{
- char * schemaName = new char[strlen(internalName)];
- if (schemaName == NULL)
- {
- errno = ENOMEM;
- return BaseString(NULL);
- }
- register const char *ptr1 = internalName;
-
- /* Scan name for the second table_name_separator */
- while (*ptr1 && *ptr1 != table_name_separator)
- ptr1++;
- strcpy(schemaName, ptr1 + 1);
- register char *ptr = schemaName;
- while (*ptr && *ptr != table_name_separator)
- ptr++;
- *ptr = '\0';
- BaseString ret = BaseString(schemaName);
- delete [] schemaName;
- return ret;
-}
-
-// ToDo set event buffer size
-NdbEventOperation* Ndb::createEventOperation(const char* eventName)
-{
- DBUG_ENTER("Ndb::createEventOperation");
- NdbEventOperation* tOp= theEventBuffer->createEventOperation(eventName,
- theError);
- if (tOp)
- {
- // keep track of all event operations
- NdbEventOperationImpl *op=
- NdbEventBuffer::getEventOperationImpl(tOp);
- op->m_next= theImpl->m_ev_op;
- op->m_prev= 0;
- theImpl->m_ev_op= op;
- if (op->m_next)
- op->m_next->m_prev= op;
- }
-
- DBUG_RETURN(tOp);
-}
-
-int Ndb::dropEventOperation(NdbEventOperation* tOp)
-{
- DBUG_ENTER("Ndb::dropEventOperation");
- DBUG_PRINT("info", ("name: %s", tOp->getEvent()->getTable()->getName()));
- // remove it from list
- NdbEventOperationImpl *op=
- NdbEventBuffer::getEventOperationImpl(tOp);
- if (op->m_next)
- op->m_next->m_prev= op->m_prev;
- if (op->m_prev)
- op->m_prev->m_next= op->m_next;
- else
- theImpl->m_ev_op= op->m_next;
-
- DBUG_PRINT("info", ("first: %s",
- theImpl->m_ev_op ? theImpl->m_ev_op->getEvent()->getTable()->getName() : "<empty>"));
- assert(theImpl->m_ev_op == 0 || theImpl->m_ev_op->m_prev == 0);
-
- theEventBuffer->dropEventOperation(tOp);
- DBUG_RETURN(0);
-}
-
-NdbEventOperation *Ndb::getEventOperation(NdbEventOperation* tOp)
-{
- NdbEventOperationImpl *op;
- if (tOp)
- op= NdbEventBuffer::getEventOperationImpl(tOp)->m_next;
- else
- op= theImpl->m_ev_op;
- if (op)
- return op->m_facade;
- return 0;
-}
-
-int
-Ndb::pollEvents(int aMillisecondNumber, Uint64 *latestGCI)
-{
- return theEventBuffer->pollEvents(aMillisecondNumber, latestGCI);
-}
-
-int
-Ndb::flushIncompleteEvents(Uint64 gci)
-{
- return theEventBuffer->flushIncompleteEvents(gci);
-}
-
-NdbEventOperation *Ndb::nextEvent()
-{
- return theEventBuffer->nextEvent();
-}
-
-const NdbEventOperation*
-Ndb::getGCIEventOperations(Uint32* iter, Uint32* event_types)
-{
- NdbEventOperationImpl* op =
- theEventBuffer->getGCIEventOperations(iter, event_types);
- if (op != NULL)
- return op->m_facade;
- return NULL;
-}
-
-Uint64 Ndb::getLatestGCI()
-{
- return theEventBuffer->getLatestGCI();
-}
-
-void Ndb::setReportThreshEventGCISlip(unsigned thresh)
-{
- if (theEventBuffer->m_free_thresh != thresh)
- {
- theEventBuffer->m_free_thresh= thresh;
- theEventBuffer->m_min_free_thresh= thresh;
- theEventBuffer->m_max_free_thresh= 100;
- }
-}
-
-void Ndb::setReportThreshEventFreeMem(unsigned thresh)
-{
- if (theEventBuffer->m_free_thresh != thresh)
- {
- theEventBuffer->m_free_thresh= thresh;
- theEventBuffer->m_min_free_thresh= thresh;
- theEventBuffer->m_max_free_thresh= 100;
- }
-}
-
-#ifdef VM_TRACE
-#include <NdbMutex.h>
-extern NdbMutex *ndb_print_state_mutex;
-
-static bool
-checkdups(NdbTransaction** list, unsigned no)
-{
- for (unsigned i = 0; i < no; i++)
- for (unsigned j = i + 1; j < no; j++)
- if (list[i] == list[j])
- return true;
- return false;
-}
-void
-Ndb::printState(const char* fmt, ...)
-{
- char buf[200];
- va_list ap;
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- NdbMutex_Lock(ndb_print_state_mutex);
- bool dups = false;
- unsigned i;
- ndbout << buf << " ndb=" << hex << (void*)this << endl;
- for (unsigned n = 0; n < MAX_NDB_NODES; n++) {
- NdbTransaction* con = theConnectionArray[n];
- if (con != 0) {
- ndbout << "conn " << n << ":" << endl;
- while (con != 0) {
- con->printState();
- con = con->theNext;
- }
- }
- }
- ndbout << "prepared: " << theNoOfPreparedTransactions<< endl;
- if (checkdups(thePreparedTransactionsArray, theNoOfPreparedTransactions)) {
- ndbout << "!! DUPS !!" << endl;
- dups = true;
- }
- for (i = 0; i < theNoOfPreparedTransactions; i++)
- thePreparedTransactionsArray[i]->printState();
- ndbout << "sent: " << theNoOfSentTransactions<< endl;
- if (checkdups(theSentTransactionsArray, theNoOfSentTransactions)) {
- ndbout << "!! DUPS !!" << endl;
- dups = true;
- }
- for (i = 0; i < theNoOfSentTransactions; i++)
- theSentTransactionsArray[i]->printState();
- ndbout << "completed: " << theNoOfCompletedTransactions<< endl;
- if (checkdups(theCompletedTransactionsArray, theNoOfCompletedTransactions)) {
- ndbout << "!! DUPS !!" << endl;
- dups = true;
- }
- for (i = 0; i < theNoOfCompletedTransactions; i++)
- theCompletedTransactionsArray[i]->printState();
- NdbMutex_Unlock(ndb_print_state_mutex);
-}
-#endif
-
-
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.cpp b/storage/ndb/src/ndbapi/NdbApiSignal.cpp
deleted file mode 100644
index 89873f22d32..00000000000
--- a/storage/ndb/src/ndbapi/NdbApiSignal.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include "API.hpp"
-#include "NdbApiSignal.hpp"
-
-/**
- * The following include includes
- * definitions directly from the kernel
- *
- * Definitions that is shared between kernel and the API
- */
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/TestOrd.hpp>
-#include <signaldata/CreateIndx.hpp>
-#include <signaldata/DropIndx.hpp>
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/IndxKeyInfo.hpp>
-#include <signaldata/IndxAttrInfo.hpp>
-#include <signaldata/TcHbRep.hpp>
-#include <signaldata/ScanTab.hpp>
-
-#include <NdbOut.hpp>
-
-/******************************************************************************
-NdbApiSignal();
-
-Return Value: None
-Remark: Creates a NdbApiSignal object.
-******************************************************************************/
-NdbApiSignal::NdbApiSignal(BlockReference ref)
-{
- theVerId_signalNumber = 0; // 4 bit ver id - 16 bit gsn
- theReceiversBlockNumber = 0; // Only 16 bit blocknum
- theSendersBlockRef = refToBlock(ref);
- theLength = 0;
- theSendersSignalId = 0;
- theSignalId = 0;
- theTrace = 0;
- m_noOfSections = 0;
- m_fragmentInfo = 0;
- for (int i = 0; i < 25; i++)
- theData[i] = 0x13579753;
-
- setDataPtr(&theData[0]);
- theNextSignal = 0;
-}
-
-NdbApiSignal::NdbApiSignal(Ndb* ndb)
-{
- BlockReference ref = ndb->theMyRef;
- theVerId_signalNumber = 0; // 4 bit ver id - 16 bit gsn
- theReceiversBlockNumber = 0; // Only 16 bit blocknum
- theSendersBlockRef = refToBlock(ref);
- theLength = 0;
- theSendersSignalId = 0;
- theSignalId = 0;
- theTrace = 0;
- m_noOfSections = 0;
- m_fragmentInfo = 0;
- for (int i = 0; i < 25; i++)
- theData[i] = 0x13579753;
-
- setDataPtr(&theData[0]);
- theNextSignal = 0;
-}
-
-/**
- * Copy constructor
- */
-NdbApiSignal::NdbApiSignal(const NdbApiSignal &src) {
- copyFrom(&src);
-}
-/******************************************************************************
-~NdbApiSignal();
-
-Return Value: None
-Remark: Delete a NdbApiSignal object.
-******************************************************************************/
-NdbApiSignal::~NdbApiSignal()
-{
-}
-/******************************************************************************
-int setSignal(NdbSignalType aNdbSignalType);
-
-Return Value: Return 0 : setSignal was successful.
- Return tErrorCode In all other case.
-Parameters: aNdbSignalType: Type of signal.
-Remark: Set signal header and allocate 128 byte.
-******************************************************************************/
-int
-NdbApiSignal::setSignal(int aNdbSignalType)
-{
- theSendersSignalId = 0;
- switch (aNdbSignalType)
- {
- case GSN_DIHNDBTAMPER:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBDIH;
- theVerId_signalNumber = GSN_DIHNDBTAMPER;
- theLength = 3;
- }
- break;
-
- case GSN_TCSEIZEREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TCSEIZEREQ;
- theLength = 2;
- }
- break;
-
- case GSN_TCKEYREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TCKEYREQ;
- theLength = TcKeyReq::SignalLength;
- }
- break;
-
- case GSN_TCRELEASEREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TCRELEASEREQ;
- theLength = 3;
- }
- break;
-
- case GSN_ATTRINFO:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_ATTRINFO;
- theLength = AttrInfo::MaxSignalLength;
- }
- break;
-
- case GSN_KEYINFO:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_KEYINFO;
- theLength = KeyInfo::MaxSignalLength;
- }
- break;
-
- case GSN_TCROLLBACKREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TCROLLBACKREQ;
- theLength = 3;
- }
- break;
-
- case GSN_TC_HBREP:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TC_HBREP;
- theLength = TcHbRep::SignalLength;
- }
- break;
-
- case GSN_TC_COMMITREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TC_COMMITREQ;
- theLength = 3;
- }
- break;
-
- case GSN_SCAN_TABREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_SCAN_TABREQ;
- theLength = ScanTabReq::StaticLength;
- }
- break;
-
- case GSN_SCAN_NEXTREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_SCAN_NEXTREQ;
- theLength = ScanNextReq::SignalLength;
- }
- break;
-
- case GSN_CREATE_INDX_REQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBDICT;
- theVerId_signalNumber = GSN_CREATE_INDX_REQ;
- theLength = CreateIndxReq::SignalLength;
- }
- break;
-
- case GSN_DROP_INDX_REQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBDICT;
- theVerId_signalNumber = GSN_DROP_INDX_REQ;
- theLength = DropIndxReq::SignalLength;
- }
- break;
-
- case GSN_TCINDXREQ:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_TCINDXREQ;
- theLength = TcKeyReq::SignalLength;
- }
- break;
-
- case GSN_INDXKEYINFO:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_INDXKEYINFO;
- theLength = IndxKeyInfo::MaxSignalLength;
- }
- break;
-
- case GSN_INDXATTRINFO:
- {
- theTrace = TestOrd::TraceAPI;
- theReceiversBlockNumber = DBTC;
- theVerId_signalNumber = GSN_INDXATTRINFO;
- theLength = IndxAttrInfo::MaxSignalLength;
- }
- break;
-
- default:
- {
- return -1;
- }
- }
- return 0;
-}
-
-void
-NdbApiSignal::set(Uint8 trace,
- Uint16 receiversBlockNumber,
- Uint16 signalNumber,
- Uint32 length){
-
- theTrace = trace;
- theReceiversBlockNumber = receiversBlockNumber;
- theVerId_signalNumber = signalNumber;
- theLength = length;
-}
-
-void
-NdbApiSignal::copyFrom(const NdbApiSignal * src){
- theVerId_signalNumber = src->theVerId_signalNumber;
- theReceiversBlockNumber = src->theReceiversBlockNumber;
- theSendersBlockRef = src->theSendersBlockRef;
- theLength = src->theLength;
- theTrace = src->theTrace;
-
- Uint32 * dstData = getDataPtrSend();
- const Uint32 * srcData = src->getDataPtr();
- for (Uint32 i = 0; i < theLength; i++)
- dstData[i] = srcData[i];
-
- setDataPtr(dstData);
-
- /**
- * NOTE that theSignalId is used as data ptr
- * and should not be copied
- * NOTE that theSendersSignalId is used as next pointer
- * and should not be copied
- */
-}
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.hpp b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
deleted file mode 100644
index e28a246b934..00000000000
--- a/storage/ndb/src/ndbapi/NdbApiSignal.hpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/**********************************************************************
- * Name: NdbApiSignal.H
- * Include:
- * Link:
- * Author: UABMNST Mona Natterkvist UAB/B/SD
- * Date: 97----
- * Version: 0.1
- * Description: Interface between TIS and NDB
- * Documentation:
- * Adjust: 971204 UABMNST First version.
- * Adjust: 000705 QABANAB Changes in Protocol2
- * Comment:
- *****************************************************************************/
-#ifndef NdbApiSignal_H
-#define NdbApiSignal_H
-
-#include <kernel_types.h>
-#include "TransporterFacade.hpp"
-#include <TransporterDefinitions.hpp>
-#include "Ndb.hpp"
-
-#define CAST_PTR(X,Y) static_cast<X*>(static_cast<void*>(Y))
-#define CAST_CONSTPTR(X,Y) static_cast<const X*>(static_cast<const void*>(Y))
-
-/**
- * A NdbApiSignal : public SignalHeader
- *
- * Stores the address to theData in theSignalId
- */
-class NdbApiSignal : public SignalHeader
- {
-public:
- NdbApiSignal(Ndb* ndb);
- NdbApiSignal(BlockReference ref);
- NdbApiSignal(const NdbApiSignal &);
- NdbApiSignal(const SignalHeader &header)
- : SignalHeader(header), theNextSignal(0), theRealData(0) {};
- ~NdbApiSignal();
-
- void set(Uint8 trace,
- Uint16 receiversBlockNumber,
- Uint16 signalNumber,
- Uint32 length);
-
-
- void setData(Uint32 aWord, Uint32 aDataNo);
- Uint32 readData(Uint32 aDataNo) const; // Read word in signal
-
- int setSignal(int NdbSignalType); // Set signal header
- int readSignalNumber(); // Read signal number
- Uint32 getLength() const;
- void setLength(Uint32 aLength);
- void next(NdbApiSignal* anApiSignal);
- NdbApiSignal* next();
-
- const Uint32 * getDataPtr() const;
- Uint32 * getDataPtrSend();
-
- NodeId get_sender_node();
-
- /**
- * Fragmentation
- */
- bool isFirstFragment() const { return m_fragmentInfo <= 1;}
- bool isLastFragment() const {
- return m_fragmentInfo == 0 || m_fragmentInfo == 3;
- }
-
- Uint32 getFragmentId() const {
- return (m_fragmentInfo == 0 ? 0 : getDataPtr()[theLength - 1]);
- }
-
-private:
- friend void execute(void * callbackObj,
- struct SignalHeader * const header,
- Uint8 prio, Uint32 * const theData,
- LinearSectionPtr ptr[3]);
-
- void setDataPtr(Uint32 *);
-
- friend class NdbTransaction;
- friend class NdbScanReceiver;
- friend class Table;
- void copyFrom(const NdbApiSignal * src);
-
- /**
- * Only used when creating a signal in the api
- */
- Uint32 theData[25];
- NdbApiSignal *theNextSignal;
- Uint32 *theRealData;
-};
-/**********************************************************************
-NodeId get_sender_node
-Remark: Get the node id of the sender
-***********************************************************************/
-inline
-NodeId
-NdbApiSignal::get_sender_node()
-{
- return refToNode(theSendersBlockRef);
-}
-
-/**********************************************************************
-void getLength
-Remark: Get the length of the signal.
-******************************************************************************/
-inline
-Uint32
-NdbApiSignal::getLength() const{
- return theLength;
-}
-
-/**********************************************************************
-void setLength
-Parameters: aLength: Signal length
-Remark: Set the length in the signal.
-******************************************************************************/
-inline
-void
-NdbApiSignal::setLength(Uint32 aLength){
- theLength = aLength;
-}
-
-/**********************************************************************
-void next(NdbApiSignal* aSignal);
-
-Parameters: aSignal: Signal object.
-Remark: Insert signal rear in a linked list.
-*****************************************************************************/
-inline
-void
-NdbApiSignal::next(NdbApiSignal* aSignal){
- theNextSignal = aSignal;
-}
-/**********************************************************************
-NdbApiSignal* next();
-
-Return Value: Return theNext signal object if the next was successful.
- Return NULL: In all other case.
-Remark: Read the theNext in signal.
-*****************************************************************************/
-inline
-NdbApiSignal*
-NdbApiSignal::next(){
- return theNextSignal;
-}
-/**********************************************************************
-int readSignalNo();
-
-Return Value: Return the signalNumber.
-Remark: Read signal number
-*****************************************************************************/
-inline
-int
-NdbApiSignal::readSignalNumber()
-{
- return (int)theVerId_signalNumber;
-}
-/**********************************************************************
-Uint32 readData(Uint32 aDataNo);
-
-Return Value: Return Data word in a signal.
- Return -1: In all other case.
- aDataNo: Data number in signal.
-Remark: Return the dataWord information in a signal for a dataNo.
-******************************************************************************/
-inline
-Uint32
-NdbApiSignal::readData(Uint32 aDataNo) const {
- return getDataPtr()[aDataNo-1];
-}
-/**********************************************************************
-int setData(Uint32 aWord, int aDataNo);
-
-Return Value: Return 0 : setData was successful.
- Return -1: In all other case.
-Parameters: aWord: Data word.
- aDataNo: Data number in signal.
-Remark: Set Data word in signal 1 - 25
-******************************************************************************/
-inline
-void
-NdbApiSignal::setData(Uint32 aWord, Uint32 aDataNo){
- getDataPtrSend()[aDataNo -1] = aWord;
-}
-
-/**
- * Return pointer to data structure
- */
-inline
-const Uint32 *
-NdbApiSignal::getDataPtr() const {
- return theRealData;
-}
-
-inline
-Uint32 *
-NdbApiSignal::getDataPtrSend(){
- return (Uint32*)&theData[0];
-}
-
-inline
-void
-NdbApiSignal::setDataPtr(Uint32 * ptr){
- theRealData = ptr;
-}
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp
deleted file mode 100644
index 60b38e6b593..00000000000
--- a/storage/ndb/src/ndbapi/NdbBlob.cpp
+++ /dev/null
@@ -1,2029 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <Ndb.hpp>
-#include <NdbDictionaryImpl.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbOperation.hpp>
-#include <NdbIndexOperation.hpp>
-#include <NdbRecAttr.hpp>
-#include <NdbBlob.hpp>
-#include "NdbBlobImpl.hpp"
-#include <NdbScanOperation.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <NdbEventOperationImpl.hpp>
-
-/*
- * Reading index table directly (as a table) is faster but there are
- * bugs or limitations. Keep the code and make possible to choose.
- */
-static const bool g_ndb_blob_ok_to_read_index_table = false;
-
-// get state
-
-NdbBlob::State
-NdbBlob::getState()
-{
- return theState;
-}
-
-void
-NdbBlob::getVersion(int& version)
-{
- version = theEventBlobVersion;
-}
-
-// set state (inline)
-
-inline void
-NdbBlob::setState(State newState)
-{
- DBUG_ENTER("NdbBlob::setState");
- DBUG_PRINT("info", ("this=%p newState=%u", this, newState));
- theState = newState;
- DBUG_VOID_RETURN;
-}
-
-// define blob table
-
-int
-NdbBlob::getBlobTableName(char* btname, Ndb* anNdb, const char* tableName, const char* columnName)
-{
- DBUG_ENTER("NdbBlob::getBlobTableName");
- NdbTableImpl* t = anNdb->theDictionary->m_impl.getTable(tableName);
- if (t == NULL)
- DBUG_RETURN(-1);
- NdbColumnImpl* c = t->getColumn(columnName);
- if (c == NULL)
- DBUG_RETURN(-1);
- getBlobTableName(btname, t, c);
- DBUG_RETURN(0);
-}
-
-void
-NdbBlob::getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c)
-{
- DBUG_ENTER("NdbBlob::getBlobTableName");
- assert(t != 0 && c != 0 && c->getBlobType() && c->getPartSize() != 0);
- memset(btname, 0, NdbBlobImpl::BlobTableNameSize);
- sprintf(btname, "NDB$BLOB_%d_%d", (int)t->m_id, (int)c->m_column_no);
- DBUG_PRINT("info", ("blob table name: %s", btname));
- DBUG_VOID_RETURN;
-}
-
-void
-NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
-{
- DBUG_ENTER("NdbBlob::getBlobTable");
- char btname[NdbBlobImpl::BlobTableNameSize];
- getBlobTableName(btname, t, c);
- bt.setName(btname);
- bt.setLogging(t->getLogging());
- /*
- BLOB tables use the same fragmentation as the original table
- but may change the fragment type if it is UserDefined since it
- must be hash based so that the kernel can handle it on its own.
- It also uses the same tablespaces and it never uses any range or
- list arrays.
- */
- bt.m_primaryTableId = t->m_id;
- bt.m_fd.clear();
- bt.m_ts.clear();
- bt.m_range.clear();
- bt.setFragmentCount(t->getFragmentCount());
- bt.m_tablespace_id = t->m_tablespace_id;
- bt.m_tablespace_version = t->m_tablespace_version;
- switch (t->getFragmentType())
- {
- case NdbDictionary::Object::FragAllSmall:
- case NdbDictionary::Object::FragAllMedium:
- case NdbDictionary::Object::FragAllLarge:
- case NdbDictionary::Object::FragSingle:
- bt.setFragmentType(t->getFragmentType());
- break;
- case NdbDictionary::Object::DistrKeyLin:
- case NdbDictionary::Object::DistrKeyHash:
- bt.setFragmentType(t->getFragmentType());
- break;
- case NdbDictionary::Object::UserDefined:
- bt.setFragmentType(NdbDictionary::Object::DistrKeyHash);
- break;
- default:
- DBUG_ASSERT(0);
- break;
- }
- DBUG_PRINT("info",
- ("Create BLOB table with primary table = %u and Fragment Type = %u",
- bt.m_primaryTableId, (uint)bt.getFragmentType()));
- { NdbDictionary::Column bc("PK");
- bc.setType(NdbDictionary::Column::Unsigned);
- assert(t->m_keyLenInWords != 0);
- bc.setLength(t->m_keyLenInWords);
- bc.setPrimaryKey(true);
- bc.setDistributionKey(true);
- bt.addColumn(bc);
- }
- { NdbDictionary::Column bc("DIST");
- bc.setType(NdbDictionary::Column::Unsigned);
- bc.setPrimaryKey(true);
- bc.setDistributionKey(true);
- bt.addColumn(bc);
- }
- { NdbDictionary::Column bc("PART");
- bc.setType(NdbDictionary::Column::Unsigned);
- bc.setPrimaryKey(true);
- bc.setDistributionKey(false);
- bt.addColumn(bc);
- }
- { NdbDictionary::Column bc("DATA");
- switch (c->m_type) {
- case NdbDictionary::Column::Blob:
- bc.setType(NdbDictionary::Column::Binary);
- break;
- case NdbDictionary::Column::Text:
- bc.setType(NdbDictionary::Column::Char);
- break;
- default:
- assert(false);
- break;
- }
- bc.setLength(c->getPartSize());
- bc.setStorageType(c->getStorageType());
- bt.addColumn(bc);
- }
- DBUG_VOID_RETURN;
-}
-
-int
-NdbBlob::getBlobEventName(char* bename, Ndb* anNdb, const char* eventName, const char* columnName)
-{
- NdbEventImpl* e = anNdb->theDictionary->m_impl.getEvent(eventName);
- if (e == NULL)
- return -1;
- NdbColumnImpl* c = e->m_tableImpl->getColumn(columnName);
- if (c == NULL)
- return -1;
- getBlobEventName(bename, e, c);
- delete e; // it is from new NdbEventImpl
- return 0;
-}
-
-void
-NdbBlob::getBlobEventName(char* bename, const NdbEventImpl* e, const NdbColumnImpl* c)
-{
- // XXX events should have object id
- snprintf(bename, MAX_TAB_NAME_SIZE, "NDB$BLOBEVENT_%s_%d", e->m_name.c_str(), (int)c->m_column_no);
-}
-
-void
-NdbBlob::getBlobEvent(NdbEventImpl& be, const NdbEventImpl* e, const NdbColumnImpl* c)
-{
- DBUG_ENTER("NdbBlob::getBlobEvent");
- // blob table
- assert(c->m_blobTable != NULL);
- const NdbTableImpl& bt = *c->m_blobTable;
- // blob event name
- char bename[MAX_TAB_NAME_SIZE+1];
- getBlobEventName(bename, e, c);
- bename[sizeof(bename)-1]= 0;
- be.setName(bename);
- be.setTable(bt);
- // simple assigments
- be.mi_type = e->mi_type;
- be.m_dur = e->m_dur;
- be.m_mergeEvents = e->m_mergeEvents;
- // report unchanged data
- // not really needed now since UPD is DEL o INS and we subscribe to all
- be.setReport(NdbDictionary::Event::ER_ALL);
- // columns PK - DIST - PART - DATA
- { const NdbColumnImpl* bc = bt.getColumn((Uint32)0);
- be.addColumn(*bc);
- }
- { const NdbColumnImpl* bc = bt.getColumn((Uint32)1);
- be.addColumn(*bc);
- }
- { const NdbColumnImpl* bc = bt.getColumn((Uint32)2);
- be.addColumn(*bc);
- }
- { const NdbColumnImpl* bc = bt.getColumn((Uint32)3);
- be.addColumn(*bc);
- }
- DBUG_VOID_RETURN;
-}
-
-// initialization
-
-NdbBlob::NdbBlob(Ndb*)
-{
- init();
-}
-
-void
-NdbBlob::init()
-{
- theState = Idle;
- theEventBlobVersion = -1;
- theNdb = NULL;
- theNdbCon = NULL;
- theNdbOp = NULL;
- theEventOp = NULL;
- theBlobEventOp = NULL;
- theBlobEventPkRecAttr = NULL;
- theBlobEventDistRecAttr = NULL;
- theBlobEventPartRecAttr = NULL;
- theBlobEventDataRecAttr = NULL;
- theTable = NULL;
- theAccessTable = NULL;
- theBlobTable = NULL;
- theColumn = NULL;
- theFillChar = 0;
- theInlineSize = 0;
- thePartSize = 0;
- theStripeSize = 0;
- theGetFlag = false;
- theGetBuf = NULL;
- theSetFlag = false;
- theSetBuf = NULL;
- theGetSetBytes = 0;
- thePendingBlobOps = 0;
- theActiveHook = NULL;
- theActiveHookArg = NULL;
- theHead = NULL;
- theInlineData = NULL;
- theHeadInlineRecAttr = NULL;
- theHeadInlineReadOp = NULL;
- theHeadInlineUpdateFlag = false;
- theNullFlag = -1;
- theLength = 0;
- thePos = 0;
- theNext = NULL;
-}
-
-void
-NdbBlob::release()
-{
- setState(Idle);
-}
-
-// buffers
-
-NdbBlob::Buf::Buf() :
- data(NULL),
- size(0),
- maxsize(0)
-{
-}
-
-NdbBlob::Buf::~Buf()
-{
- delete [] data;
-}
-
-void
-NdbBlob::Buf::alloc(unsigned n)
-{
- size = n;
- if (maxsize < n) {
- delete [] data;
- // align to Uint64
- if (n % 8 != 0)
- n += 8 - n % 8;
- data = new char [n];
- maxsize = n;
- }
-#ifdef VM_TRACE
- memset(data, 'X', maxsize);
-#endif
-}
-
-void
-NdbBlob::Buf::zerorest()
-{
- assert(size <= maxsize);
- memset(data + size, 0, maxsize - size);
-}
-
-void
-NdbBlob::Buf::copyfrom(const NdbBlob::Buf& src)
-{
- size = src.size;
- memcpy(data, src.data, size);
-}
-
-// classify operations (inline)
-
-inline bool
-NdbBlob::isTableOp()
-{
- return theTable == theAccessTable;
-}
-
-inline bool
-NdbBlob::isIndexOp()
-{
- return theTable != theAccessTable;
-}
-
-inline bool
-NdbBlob::isKeyOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::InsertRequest ||
- theNdbOp->theOperationType == NdbOperation::UpdateRequest ||
- theNdbOp->theOperationType == NdbOperation::WriteRequest ||
- theNdbOp->theOperationType == NdbOperation::ReadRequest ||
- theNdbOp->theOperationType == NdbOperation::ReadExclusive ||
- theNdbOp->theOperationType == NdbOperation::DeleteRequest;
-}
-
-inline bool
-NdbBlob::isReadOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::ReadRequest ||
- theNdbOp->theOperationType == NdbOperation::ReadExclusive;
-}
-
-inline bool
-NdbBlob::isInsertOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::InsertRequest;
-}
-
-inline bool
-NdbBlob::isUpdateOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::UpdateRequest;
-}
-
-inline bool
-NdbBlob::isWriteOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::WriteRequest;
-}
-
-inline bool
-NdbBlob::isDeleteOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::DeleteRequest;
-}
-
-inline bool
-NdbBlob::isScanOp()
-{
- return
- theNdbOp->theOperationType == NdbOperation::OpenScanRequest ||
- theNdbOp->theOperationType == NdbOperation::OpenRangeScanRequest;
-}
-
-inline bool
-NdbBlob::isReadOnlyOp()
-{
- return ! (
- theNdbOp->theOperationType == NdbOperation::InsertRequest ||
- theNdbOp->theOperationType == NdbOperation::UpdateRequest ||
- theNdbOp->theOperationType == NdbOperation::WriteRequest
- );
-}
-
-inline bool
-NdbBlob::isTakeOverOp()
-{
- return
- TcKeyReq::getTakeOverScanFlag(theNdbOp->theScanInfo);
-}
-
-// computations (inline)
-
-inline Uint32
-NdbBlob::getPartNumber(Uint64 pos)
-{
- assert(thePartSize != 0 && pos >= theInlineSize);
- return (pos - theInlineSize) / thePartSize;
-}
-
-inline Uint32
-NdbBlob::getPartCount()
-{
- if (theLength <= theInlineSize)
- return 0;
- return 1 + getPartNumber(theLength - 1);
-}
-
-inline Uint32
-NdbBlob::getDistKey(Uint32 part)
-{
- assert(theStripeSize != 0);
- return (part / theStripeSize) % theStripeSize;
-}
-
-// pack/unpack table/index key XXX support routines, shortcuts
-
-int
-NdbBlob::packKeyValue(const NdbTableImpl* aTable, const Buf& srcBuf)
-{
- DBUG_ENTER("NdbBlob::packKeyValue");
- const Uint32* data = (const Uint32*)srcBuf.data;
- unsigned pos = 0;
- Uint32* pack_data = (Uint32*)thePackKeyBuf.data;
- unsigned pack_pos = 0;
- for (unsigned i = 0; i < aTable->m_columns.size(); i++) {
- NdbColumnImpl* c = aTable->m_columns[i];
- assert(c != NULL);
- if (c->m_pk) {
- unsigned len = c->m_attrSize * c->m_arraySize;
- Uint32 pack_len;
- bool ok = c->get_var_length(&data[pos], pack_len);
- if (! ok) {
- setErrorCode(NdbBlobImpl::ErrCorruptPK);
- DBUG_RETURN(-1);
- }
- memcpy(&pack_data[pack_pos], &data[pos], pack_len);
- while (pack_len % 4 != 0) {
- char* p = (char*)&pack_data[pack_pos] + pack_len++;
- *p = 0;
- }
- pos += (len + 3) / 4;
- pack_pos += pack_len / 4;
- }
- }
- assert(4 * pos == srcBuf.size);
- assert(4 * pack_pos <= thePackKeyBuf.maxsize);
- thePackKeyBuf.size = 4 * pack_pos;
- thePackKeyBuf.zerorest();
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::unpackKeyValue(const NdbTableImpl* aTable, Buf& dstBuf)
-{
- DBUG_ENTER("NdbBlob::unpackKeyValue");
- Uint32* data = (Uint32*)dstBuf.data;
- unsigned pos = 0;
- const Uint32* pack_data = (const Uint32*)thePackKeyBuf.data;
- unsigned pack_pos = 0;
- for (unsigned i = 0; i < aTable->m_columns.size(); i++) {
- NdbColumnImpl* c = aTable->m_columns[i];
- assert(c != NULL);
- if (c->m_pk) {
- unsigned len = c->m_attrSize * c->m_arraySize;
- Uint32 pack_len;
- bool ok = c->get_var_length(&pack_data[pack_pos], pack_len);
- if (! ok) {
- setErrorCode(NdbBlobImpl::ErrCorruptPK);
- DBUG_RETURN(-1);
- }
- memcpy(&data[pos], &pack_data[pack_pos], pack_len);
- while (pack_len % 4 != 0) {
- char* p = (char*)&data[pos] + pack_len++;
- *p = 0;
- }
- pos += (len + 3) / 4;
- pack_pos += pack_len / 4;
- }
- }
- assert(4 * pos == dstBuf.size);
- assert(4 * pack_pos == thePackKeyBuf.size);
- DBUG_RETURN(0);
-}
-
-// getters and setters
-
-int
-NdbBlob::getTableKeyValue(NdbOperation* anOp)
-{
- DBUG_ENTER("NdbBlob::getTableKeyValue");
- Uint32* data = (Uint32*)theKeyBuf.data;
- unsigned pos = 0;
- for (unsigned i = 0; i < theTable->m_columns.size(); i++) {
- NdbColumnImpl* c = theTable->m_columns[i];
- assert(c != NULL);
- if (c->m_pk) {
- unsigned len = c->m_attrSize * c->m_arraySize;
- if (anOp->getValue_impl(c, (char*)&data[pos]) == NULL) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- // odd bytes receive no data and must be zeroed
- while (len % 4 != 0) {
- char* p = (char*)&data[pos] + len++;
- *p = 0;
- }
- pos += len / 4;
- }
- }
- assert(pos == theKeyBuf.size / 4);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setTableKeyValue(NdbOperation* anOp)
-{
- DBUG_ENTER("NdbBlob::setTableKeyValue");
- DBUG_DUMP("info", (uchar*) theKeyBuf.data, 4 * theTable->m_keyLenInWords);
- const Uint32* data = (const Uint32*)theKeyBuf.data;
- const unsigned columns = theTable->m_columns.size();
- unsigned pos = 0;
- for (unsigned i = 0; i < columns; i++) {
- NdbColumnImpl* c = theTable->m_columns[i];
- assert(c != NULL);
- if (c->m_pk) {
- unsigned len = c->m_attrSize * c->m_arraySize;
- if (anOp->equal_impl(c, (const char*)&data[pos]) == -1) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- pos += (len + 3) / 4;
- }
- }
- if (theNdbOp->theDistrKeyIndicator_)
- anOp->setPartitionId(theNdbOp->getPartitionId());
- assert(pos == theKeyBuf.size / 4);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setAccessKeyValue(NdbOperation* anOp)
-{
- DBUG_ENTER("NdbBlob::setAccessKeyValue");
- DBUG_DUMP("info", (uchar*) theAccessKeyBuf.data,
- 4 * theAccessTable->m_keyLenInWords);
- const Uint32* data = (const Uint32*)theAccessKeyBuf.data;
- const unsigned columns = theAccessTable->m_columns.size();
- unsigned pos = 0;
- for (unsigned i = 0; i < columns; i++) {
- NdbColumnImpl* c = theAccessTable->m_columns[i];
- assert(c != NULL);
- if (c->m_pk) {
- unsigned len = c->m_attrSize * c->m_arraySize;
- if (anOp->equal_impl(c, (const char*)&data[pos]) == -1) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- pos += (len + 3) / 4;
- }
- }
- assert(pos == theAccessKeyBuf.size / 4);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
-{
- DBUG_ENTER("NdbBlob::setPartKeyValue");
- DBUG_PRINT("info", ("dist=%u part=%u packkey=", getDistKey(part), part));
- DBUG_DUMP("info", (uchar*) thePackKeyBuf.data, 4 * thePackKeyBuf.size);
- // TODO use attr ids after compatibility with 4.1.7 not needed
- if (anOp->equal("PK", thePackKeyBuf.data) == -1 ||
- anOp->equal("DIST", getDistKey(part)) == -1 ||
- anOp->equal("PART", part) == -1) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::getHeadInlineValue(NdbOperation* anOp)
-{
- DBUG_ENTER("NdbBlob::getHeadInlineValue");
- theHeadInlineRecAttr = anOp->getValue_impl(theColumn, theHeadInlineBuf.data);
- if (theHeadInlineRecAttr == NULL) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- /*
- * If we get no data from this op then the operation is aborted
- * one way or other. Following hack in 5.0 makes sure we don't read
- * garbage. The proper fix exists only in version >= 5.1.
- */
- theHead->length = 0;
- DBUG_RETURN(0);
-}
-
-void
-NdbBlob::getHeadFromRecAttr()
-{
- DBUG_ENTER("NdbBlob::getHeadFromRecAttr");
- assert(theHeadInlineRecAttr != NULL);
- theNullFlag = theHeadInlineRecAttr->isNULL();
- assert(theEventBlobVersion >= 0 || theNullFlag != -1);
- theLength = ! theNullFlag ? theHead->length : 0;
- DBUG_PRINT("info", ("theNullFlag=%d theLength=%llu",
- theNullFlag, theLength));
- DBUG_VOID_RETURN;
-}
-
-int
-NdbBlob::setHeadInlineValue(NdbOperation* anOp)
-{
- DBUG_ENTER("NdbBlob::setHeadInlineValue");
- theHead->length = theLength;
- if (theLength < theInlineSize)
- memset(theInlineData + theLength, 0, theInlineSize - theLength);
- assert(theNullFlag != -1);
- const char* aValue = theNullFlag ? 0 : theHeadInlineBuf.data;
- if (anOp->setValue(theColumn, aValue) == -1) {
- setErrorCode(anOp);
- DBUG_RETURN(-1);
- }
- theHeadInlineUpdateFlag = false;
- DBUG_RETURN(0);
-}
-
-// getValue/setValue
-
-int
-NdbBlob::getValue(void* data, Uint32 bytes)
-{
- DBUG_ENTER("NdbBlob::getValue");
- DBUG_PRINT("info", ("data=%p bytes=%u", data, bytes));
- if (! isReadOp() && ! isScanOp()) {
- setErrorCode(NdbBlobImpl::ErrCompat);
- DBUG_RETURN(-1);
- }
- if (theGetFlag || theState != Prepared) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- if (data == NULL && bytes != 0) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- theGetFlag = true;
- theGetBuf = static_cast<char*>(data);
- theGetSetBytes = bytes;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setValue(const void* data, Uint32 bytes)
-{
- DBUG_ENTER("NdbBlob::setValue");
- DBUG_PRINT("info", ("data=%p bytes=%u", data, bytes));
- if (isReadOnlyOp()) {
- setErrorCode(NdbBlobImpl::ErrCompat);
- DBUG_RETURN(-1);
- }
- if (theSetFlag || theState != Prepared) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- if (data == NULL && bytes != 0) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- theSetFlag = true;
- theSetBuf = static_cast<const char*>(data);
- theGetSetBytes = bytes;
- if (isInsertOp()) {
- // write inline part now
- if (theSetBuf != NULL) {
- Uint32 n = theGetSetBytes;
- if (n > theInlineSize)
- n = theInlineSize;
- assert(thePos == 0);
- if (writeDataPrivate(theSetBuf, n) == -1)
- DBUG_RETURN(-1);
- } else {
- theNullFlag = true;
- theLength = 0;
- }
- if (setHeadInlineValue(theNdbOp) == -1)
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-// activation hook
-
-int
-NdbBlob::setActiveHook(ActiveHook activeHook, void* arg)
-{
- DBUG_ENTER("NdbBlob::setActiveHook");
- DBUG_PRINT("info", ("hook=%p arg=%p", (void*)activeHook, arg));
- if (theState != Prepared) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- theActiveHook = activeHook;
- theActiveHookArg = arg;
- DBUG_RETURN(0);
-}
-
-// misc operations
-
-int
-NdbBlob::getDefined(int& isNull) // deprecated
-{
- DBUG_ENTER("NdbBlob::getDefined");
- if (theState == Prepared && theSetFlag) {
- isNull = (theSetBuf == NULL);
- DBUG_RETURN(0);
- }
- isNull = theNullFlag;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::getNull(bool& isNull) // deprecated
-{
- DBUG_ENTER("NdbBlob::getNull");
- if (theState == Prepared && theSetFlag) {
- isNull = (theSetBuf == NULL);
- DBUG_RETURN(0);
- }
- if (theNullFlag == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- isNull = theNullFlag;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::getNull(int& isNull)
-{
- DBUG_ENTER("NdbBlob::getNull");
- if (theState == Prepared && theSetFlag) {
- isNull = (theSetBuf == NULL);
- DBUG_RETURN(0);
- }
- isNull = theNullFlag;
- if (isNull == -1 && theEventBlobVersion == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- DBUG_PRINT("info", ("isNull=%d", isNull));
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setNull()
-{
- DBUG_ENTER("NdbBlob::setNull");
- if (isReadOnlyOp()) {
- setErrorCode(NdbBlobImpl::ErrCompat);
- DBUG_RETURN(-1);
- }
- if (theNullFlag == -1) {
- if (theState == Prepared) {
- DBUG_RETURN(setValue(0, 0));
- }
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- if (theNullFlag)
- DBUG_RETURN(0);
- if (deleteParts(0, getPartCount()) == -1)
- DBUG_RETURN(-1);
- theNullFlag = true;
- theLength = 0;
- theHeadInlineUpdateFlag = true;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::getLength(Uint64& len)
-{
- DBUG_ENTER("NdbBlob::getLength");
- if (theState == Prepared && theSetFlag) {
- len = theGetSetBytes;
- DBUG_RETURN(0);
- }
- if (theNullFlag == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- len = theLength;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::truncate(Uint64 length)
-{
- DBUG_ENTER("NdbBlob::truncate");
- DBUG_PRINT("info", ("length=%llu", length));
- if (isReadOnlyOp()) {
- setErrorCode(NdbBlobImpl::ErrCompat);
- DBUG_RETURN(-1);
- }
- if (theNullFlag == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- if (theLength > length) {
- if (length > theInlineSize) {
- Uint32 part1 = getPartNumber(length - 1);
- Uint32 part2 = getPartNumber(theLength - 1);
- assert(part2 >= part1);
- if (part2 > part1 && deleteParts(part1 + 1, part2 - part1) == -1)
- DBUG_RETURN(-1);
- } else {
- if (deleteParts(0, getPartCount()) == -1)
- DBUG_RETURN(-1);
- }
- theLength = length;
- theHeadInlineUpdateFlag = true;
- if (thePos > length)
- thePos = length;
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::getPos(Uint64& pos)
-{
- DBUG_ENTER("NdbBlob::getPos");
- if (theNullFlag == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- pos = thePos;
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::setPos(Uint64 pos)
-{
- DBUG_ENTER("NdbBlob::setPos");
- DBUG_PRINT("info", ("pos=%llu", pos));
- if (theNullFlag == -1) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- if (pos > theLength) {
- setErrorCode(NdbBlobImpl::ErrSeek);
- DBUG_RETURN(-1);
- }
- thePos = pos;
- DBUG_RETURN(0);
-}
-
-// read/write
-
-int
-NdbBlob::readData(void* data, Uint32& bytes)
-{
- DBUG_ENTER("NdbBlob::readData");
- if (theState != Active) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- char* buf = static_cast<char*>(data);
- int ret = readDataPrivate(buf, bytes);
- DBUG_RETURN(ret);
-}
-
-int
-NdbBlob::readDataPrivate(char* buf, Uint32& bytes)
-{
- DBUG_ENTER("NdbBlob::readDataPrivate");
- DBUG_PRINT("info", ("bytes=%u", bytes));
- assert(thePos <= theLength);
- Uint64 pos = thePos;
- if (bytes > theLength - pos)
- bytes = theLength - pos;
- Uint32 len = bytes;
- if (len > 0) {
- // inline part
- if (pos < theInlineSize) {
- Uint32 n = theInlineSize - pos;
- if (n > len)
- n = len;
- memcpy(buf, theInlineData + pos, n);
- pos += n;
- buf += n;
- len -= n;
- }
- }
- if (len > 0 && thePartSize == 0) {
- setErrorCode(NdbBlobImpl::ErrSeek);
- DBUG_RETURN(-1);
- }
- if (len > 0) {
- assert(pos >= theInlineSize);
- Uint32 off = (pos - theInlineSize) % thePartSize;
- // partial first block
- if (off != 0) {
- DBUG_PRINT("info", ("partial first block pos=%llu len=%u", pos, len));
- Uint32 part = (pos - theInlineSize) / thePartSize;
- if (readParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- // need result now
- if (executePendingBlobReads() == -1)
- DBUG_RETURN(-1);
- Uint32 n = thePartSize - off;
- if (n > len)
- n = len;
- memcpy(buf, thePartBuf.data + off, n);
- pos += n;
- buf += n;
- len -= n;
- }
- }
- if (len > 0) {
- assert((pos - theInlineSize) % thePartSize == 0);
- // complete blocks in the middle
- if (len >= thePartSize) {
- Uint32 part = (pos - theInlineSize) / thePartSize;
- Uint32 count = len / thePartSize;
- if (readParts(buf, part, count) == -1)
- DBUG_RETURN(-1);
- Uint32 n = thePartSize * count;
- pos += n;
- buf += n;
- len -= n;
- }
- }
- if (len > 0) {
- // partial last block
- DBUG_PRINT("info", ("partial last block pos=%llu len=%u", pos, len));
- assert((pos - theInlineSize) % thePartSize == 0 && len < thePartSize);
- Uint32 part = (pos - theInlineSize) / thePartSize;
- if (readParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- // need result now
- if (executePendingBlobReads() == -1)
- DBUG_RETURN(-1);
- memcpy(buf, thePartBuf.data, len);
- Uint32 n = len;
- pos += n;
- buf += n;
- len -= n;
- }
- assert(len == 0);
- thePos = pos;
- assert(thePos <= theLength);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::writeData(const void* data, Uint32 bytes)
-{
- DBUG_ENTER("NdbBlob::writeData");
- if (isReadOnlyOp()) {
- setErrorCode(NdbBlobImpl::ErrCompat);
- DBUG_RETURN(-1);
- }
- if (theState != Active) {
- setErrorCode(NdbBlobImpl::ErrState);
- DBUG_RETURN(-1);
- }
- const char* buf = static_cast<const char*>(data);
- int ret = writeDataPrivate(buf, bytes);
- DBUG_RETURN(ret);
-}
-
-int
-NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
-{
- DBUG_ENTER("NdbBlob::writeDataPrivate");
- DBUG_PRINT("info", ("bytes=%u", bytes));
- assert(thePos <= theLength);
- Uint64 pos = thePos;
- Uint32 len = bytes;
- // any write makes blob not NULL
- if (theNullFlag) {
- theNullFlag = false;
- theHeadInlineUpdateFlag = true;
- }
- if (len > 0) {
- // inline part
- if (pos < theInlineSize) {
- Uint32 n = theInlineSize - pos;
- if (n > len)
- n = len;
- memcpy(theInlineData + pos, buf, n);
- theHeadInlineUpdateFlag = true;
- pos += n;
- buf += n;
- len -= n;
- }
- }
- if (len > 0 && thePartSize == 0) {
- setErrorCode(NdbBlobImpl::ErrSeek);
- DBUG_RETURN(-1);
- }
- if (len > 0) {
- assert(pos >= theInlineSize);
- Uint32 off = (pos - theInlineSize) % thePartSize;
- // partial first block
- if (off != 0) {
- DBUG_PRINT("info", ("partial first block pos=%llu len=%u", pos, len));
- // flush writes to guarantee correct read
- if (executePendingBlobWrites() == -1)
- DBUG_RETURN(-1);
- Uint32 part = (pos - theInlineSize) / thePartSize;
- if (readParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- // need result now
- if (executePendingBlobReads() == -1)
- DBUG_RETURN(-1);
- Uint32 n = thePartSize - off;
- if (n > len) {
- /* If we are adding data at the end, fill rest of part. */
- if (pos + len >= theLength)
- memset(thePartBuf.data + off + len, theFillChar, n - len);
- n = len;
- }
- memcpy(thePartBuf.data + off, buf, n);
- if (updateParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- pos += n;
- buf += n;
- len -= n;
- }
- }
- if (len > 0) {
- assert((pos - theInlineSize) % thePartSize == 0);
- // complete blocks in the middle
- if (len >= thePartSize) {
- Uint32 part = (pos - theInlineSize) / thePartSize;
- Uint32 count = len / thePartSize;
- for (unsigned i = 0; i < count; i++) {
- if (part + i < getPartCount()) {
- if (updateParts(buf, part + i, 1) == -1)
- DBUG_RETURN(-1);
- } else {
- if (insertParts(buf, part + i, 1) == -1)
- DBUG_RETURN(-1);
- }
- Uint32 n = thePartSize;
- pos += n;
- buf += n;
- len -= n;
- }
- }
- }
- if (len > 0) {
- // partial last block
- DBUG_PRINT("info", ("partial last block pos=%llu len=%u", pos, len));
- assert((pos - theInlineSize) % thePartSize == 0 && len < thePartSize);
- Uint32 part = (pos - theInlineSize) / thePartSize;
- if (theLength > pos + len) {
- // flush writes to guarantee correct read
- if (executePendingBlobWrites() == -1)
- DBUG_RETURN(-1);
- if (readParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- // need result now
- if (executePendingBlobReads() == -1)
- DBUG_RETURN(-1);
- memcpy(thePartBuf.data, buf, len);
- if (updateParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- } else {
- memcpy(thePartBuf.data, buf, len);
- memset(thePartBuf.data + len, theFillChar, thePartSize - len);
- if (part < getPartCount()) {
- if (updateParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- } else {
- if (insertParts(thePartBuf.data, part, 1) == -1)
- DBUG_RETURN(-1);
- }
- }
- Uint32 n = len;
- pos += n;
- buf += n;
- len -= n;
- }
- assert(len == 0);
- if (theLength < pos) {
- theLength = pos;
- theHeadInlineUpdateFlag = true;
- }
- thePos = pos;
- assert(thePos <= theLength);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::readParts");
- DBUG_PRINT("info", ("part=%u count=%u", part, count));
- int ret;
- if (theEventBlobVersion == -1)
- ret = readTableParts(buf, part, count);
- else
- ret = readEventParts(buf, part, count);
- DBUG_RETURN(ret);
-}
-
-int
-NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::readTableParts");
- Uint32 n = 0;
- while (n < count) {
- NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
- if (tOp == NULL ||
- /*
- * This was committedRead() before. However lock on main
- * table tuple does not fully protect blob parts since DBTUP
- * commits each tuple separately.
- */
- tOp->readTuple(NdbOperation::LM_SimpleRead) == -1 ||
- setPartKeyValue(tOp, part + n) == -1 ||
- tOp->getValue((Uint32)3, buf) == NULL) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- buf += thePartSize;
- n++;
- thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
- theNdbCon->thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::readEventParts(char* buf, Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::readEventParts");
- int ret = theEventOp->readBlobParts(buf, this, part, count);
- if (ret != 0) {
- setErrorCode(theEventOp);
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::insertParts");
- DBUG_PRINT("info", ("part=%u count=%u", part, count));
- Uint32 n = 0;
- while (n < count) {
- NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
- if (tOp == NULL ||
- tOp->insertTuple() == -1 ||
- setPartKeyValue(tOp, part + n) == -1 ||
- tOp->setValue((Uint32)3, buf) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- buf += thePartSize;
- n++;
- thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
- theNdbCon->thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::updateParts");
- DBUG_PRINT("info", ("part=%u count=%u", part, count));
- Uint32 n = 0;
- while (n < count) {
- NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
- if (tOp == NULL ||
- tOp->updateTuple() == -1 ||
- setPartKeyValue(tOp, part + n) == -1 ||
- tOp->setValue((Uint32)3, buf) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- buf += thePartSize;
- n++;
- thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
- theNdbCon->thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::deleteParts(Uint32 part, Uint32 count)
-{
- DBUG_ENTER("NdbBlob::deleteParts");
- DBUG_PRINT("info", ("part=%u count=%u", part, count));
- Uint32 n = 0;
- while (n < count) {
- NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
- if (tOp == NULL ||
- tOp->deleteTuple() == -1 ||
- setPartKeyValue(tOp, part + n) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- n++;
- thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
- theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
- }
- DBUG_RETURN(0);
-}
-
-/*
- * Number of blob parts not known. Used to check for race condition
- * when writeTuple is used for insert. Deletes all parts found.
- */
-int
-NdbBlob::deletePartsUnknown(Uint32 part)
-{
- DBUG_ENTER("NdbBlob::deletePartsUnknown");
- DBUG_PRINT("info", ("part=%u count=all", part));
- if (thePartSize == 0) // tinyblob
- DBUG_RETURN(0);
- static const unsigned maxbat = 256;
- static const unsigned minbat = 1;
- unsigned bat = minbat;
- NdbOperation* tOpList[maxbat];
- Uint32 count = 0;
- while (true) {
- Uint32 n;
- n = 0;
- while (n < bat) {
- NdbOperation*& tOp = tOpList[n]; // ref
- tOp = theNdbCon->getNdbOperation(theBlobTable);
- if (tOp == NULL ||
- tOp->deleteTuple() == -1 ||
- setPartKeyValue(tOp, part + count + n) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption= NdbOperation::AO_IgnoreError;
- tOp->m_noErrorPropagation = true;
- n++;
- }
- DBUG_PRINT("info", ("bat=%u", bat));
- if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1)
- DBUG_RETURN(-1);
- n = 0;
- while (n < bat) {
- NdbOperation* tOp = tOpList[n];
- if (tOp->theError.code != 0) {
- if (tOp->theError.code != 626) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- // first non-existent part
- DBUG_PRINT("info", ("count=%u", count));
- DBUG_RETURN(0);
- }
- n++;
- count++;
- }
- bat *= 4;
- if (bat > maxbat)
- bat = maxbat;
- }
-}
-
-// pending ops
-
-int
-NdbBlob::executePendingBlobReads()
-{
- DBUG_ENTER("NdbBlob::executePendingBlobReads");
- Uint8 flags = (1 << NdbOperation::ReadRequest);
- if (thePendingBlobOps & flags) {
- if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1)
- DBUG_RETURN(-1);
- thePendingBlobOps = 0;
- theNdbCon->thePendingBlobOps = 0;
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::executePendingBlobWrites()
-{
- DBUG_ENTER("NdbBlob::executePendingBlobWrites");
- Uint8 flags = 0xFF & ~(1 << NdbOperation::ReadRequest);
- if (thePendingBlobOps & flags) {
- if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1)
- DBUG_RETURN(-1);
- thePendingBlobOps = 0;
- theNdbCon->thePendingBlobOps = 0;
- }
- DBUG_RETURN(0);
-}
-
-// callbacks
-
-int
-NdbBlob::invokeActiveHook()
-{
- DBUG_ENTER("NdbBlob::invokeActiveHook");
- assert(theState == Active && theActiveHook != NULL);
- int ret = (*theActiveHook)(this, theActiveHookArg);
- if (ret != 0) {
- // no error is set on blob level
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-// blob handle maintenance
-
-/*
- * Prepare blob handle linked to an operation. Checks blob table.
- * Allocates buffers. For key operation fetches key data from signal
- * data. For read operation adds read of head+inline.
- */
-int
-NdbBlob::atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn)
-{
- DBUG_ENTER("NdbBlob::atPrepare");
- DBUG_PRINT("info", ("this=%p op=%p con=%p", this, anOp, aCon));
- assert(theState == Idle);
- // ndb api stuff
- theNdb = anOp->theNdb;
- theNdbCon = aCon; // for scan, this is the real transaction (m_transConnection)
- theNdbOp = anOp;
- theTable = anOp->m_currentTable;
- theAccessTable = anOp->m_accessTable;
- theColumn = aColumn;
- // prepare blob column and table
- if (prepareColumn() == -1)
- DBUG_RETURN(-1);
- // extra buffers
- theAccessKeyBuf.alloc(theAccessTable->m_keyLenInWords << 2);
- theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize);
- // handle different operation types
- bool supportedOp = false;
- if (isKeyOp()) {
- if (isTableOp()) {
- // get table key
- Uint32* data = (Uint32*)thePackKeyBuf.data;
- Uint32 size = theTable->m_keyLenInWords; // in-out
- if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- thePackKeyBuf.size = 4 * size;
- thePackKeyBuf.zerorest();
- if (unpackKeyValue(theTable, theKeyBuf) == -1)
- DBUG_RETURN(-1);
- }
- if (isIndexOp()) {
- // get index key
- Uint32* data = (Uint32*)thePackKeyBuf.data;
- Uint32 size = theAccessTable->m_keyLenInWords; // in-out
- if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- thePackKeyBuf.size = 4 * size;
- thePackKeyBuf.zerorest();
- if (unpackKeyValue(theAccessTable, theAccessKeyBuf) == -1)
- DBUG_RETURN(-1);
- }
- if (isReadOp()) {
- // upgrade lock mode
- if (theNdbOp->theLockMode == NdbOperation::LM_CommittedRead)
- theNdbOp->setReadLockMode(NdbOperation::LM_Read);
- // add read of head+inline in this op
- if (getHeadInlineValue(theNdbOp) == -1)
- DBUG_RETURN(-1);
- }
- if (isInsertOp()) {
- // becomes NULL unless set before execute
- theNullFlag = true;
- theLength = 0;
- }
- if (isWriteOp()) {
- // becomes NULL unless set before execute
- theNullFlag = true;
- theLength = 0;
- theHeadInlineUpdateFlag = true;
- }
- supportedOp = true;
- }
- if (isScanOp()) {
- // upgrade lock mode
- if (theNdbOp->theLockMode == NdbOperation::LM_CommittedRead)
- theNdbOp->setReadLockMode(NdbOperation::LM_Read);
- // add read of head+inline in this op
- if (getHeadInlineValue(theNdbOp) == -1)
- DBUG_RETURN(-1);
- supportedOp = true;
- }
- if (! supportedOp) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- setState(Prepared);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::atPrepare(NdbEventOperationImpl* anOp, NdbEventOperationImpl* aBlobOp, const NdbColumnImpl* aColumn, int version)
-{
- DBUG_ENTER("NdbBlob::atPrepare [event]");
- DBUG_PRINT("info", ("this=%p op=%p", this, anOp));
- assert(theState == Idle);
- assert(version == 0 || version == 1);
- theEventBlobVersion = version;
- // ndb api stuff
- theNdb = anOp->m_ndb;
- theEventOp = anOp;
- theBlobEventOp = aBlobOp;
- theTable = anOp->m_eventImpl->m_tableImpl;
- theAccessTable = theTable;
- theColumn = aColumn;
- // prepare blob column and table
- if (prepareColumn() == -1)
- DBUG_RETURN(-1);
- // tinyblob sanity
- assert((theBlobEventOp == NULL) == (theBlobTable == NULL));
- // extra buffers
- theBlobEventDataBuf.alloc(thePartSize);
- // prepare receive of head+inline
- theHeadInlineRecAttr = theEventOp->getValue(aColumn, theHeadInlineBuf.data, version);
- if (theHeadInlineRecAttr == NULL) {
- setErrorCode(theEventOp);
- DBUG_RETURN(-1);
- }
- // prepare receive of blob part
- if (theBlobEventOp != NULL) {
- if ((theBlobEventPkRecAttr =
- theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)0),
- thePackKeyBuf.data, version)) == NULL ||
- (theBlobEventDistRecAttr =
- theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)1),
- (char*)0, version)) == NULL ||
- (theBlobEventPartRecAttr =
- theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)2),
- (char*)&thePartNumber, version)) == NULL ||
- (theBlobEventDataRecAttr =
- theBlobEventOp->getValue(theBlobTable->getColumn((Uint32)3),
- theBlobEventDataBuf.data, version)) == NULL) {
- setErrorCode(theBlobEventOp);
- DBUG_RETURN(-1);
- }
- }
- setState(Prepared);
- DBUG_RETURN(0);
-}
-
-int
-NdbBlob::prepareColumn()
-{
- DBUG_ENTER("prepareColumn");
- NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
- switch (theColumn->getType()) {
- case NdbDictionary::Column::Blob:
- partType = NdbDictionary::Column::Binary;
- theFillChar = 0x0;
- break;
- case NdbDictionary::Column::Text:
- partType = NdbDictionary::Column::Char;
- theFillChar = 0x20;
- break;
- default:
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- // sizes
- theInlineSize = theColumn->getInlineSize();
- thePartSize = theColumn->getPartSize();
- theStripeSize = theColumn->getStripeSize();
- // sanity check
- assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head));
- assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) + theInlineSize);
- if (thePartSize > 0) {
- const NdbTableImpl* bt = NULL;
- const NdbColumnImpl* bc = NULL;
- if (theStripeSize == 0 ||
- (bt = theColumn->m_blobTable) == NULL ||
- (bc = bt->getColumn("DATA")) == NULL ||
- bc->getType() != partType ||
- bc->getLength() != (int)thePartSize) {
- setErrorCode(NdbBlobImpl::ErrTable);
- DBUG_RETURN(-1);
- }
- // blob table
- theBlobTable = &NdbTableImpl::getImpl(*bt);
- }
- // these buffers are always used
- theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
- theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
- theHead = (Head*)theHeadInlineBuf.data;
- theInlineData = theHeadInlineBuf.data + sizeof(Head);
- thePartBuf.alloc(thePartSize);
- DBUG_RETURN(0);
-}
-
-/*
- * Before execute of prepared operation. May add new operations before
- * this one. May ask that this operation and all before it (a "batch")
- * is executed immediately in no-commit mode. In this case remaining
- * prepared operations are saved in a separate list. They are added
- * back after postExecute.
- */
-int
-NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
-{
- DBUG_ENTER("NdbBlob::preExecute");
- DBUG_PRINT("info", ("this=%p op=%p con=%p", this, theNdbOp, theNdbCon));
- if (theState == Invalid)
- DBUG_RETURN(-1);
- assert(theState == Prepared);
- // handle different operation types
- assert(isKeyOp());
- if (isReadOp()) {
- if (theGetFlag && theGetSetBytes > theInlineSize) {
- // need blob head before proceeding
- batch = true;
- }
- }
- if (isInsertOp()) {
- if (theSetFlag && theGetSetBytes > theInlineSize) {
- // add ops to write rest of a setValue
- assert(theSetBuf != NULL);
- const char* buf = theSetBuf + theInlineSize;
- Uint32 bytes = theGetSetBytes - theInlineSize;
- assert(thePos == theInlineSize);
- if (writeDataPrivate(buf, bytes) == -1)
- DBUG_RETURN(-1);
- if (theHeadInlineUpdateFlag) {
- // add an operation to update head+inline
- NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
- if (tOp == NULL ||
- tOp->updateTuple() == -1 ||
- setTableKeyValue(tOp) == -1 ||
- setHeadInlineValue(tOp) == -1) {
- setErrorCode(NdbBlobImpl::ErrAbort);
- DBUG_RETURN(-1);
- }
- DBUG_PRINT("info", ("add op to update head+inline"));
- }
- }
- }
- if (isTableOp()) {
- if (isUpdateOp() || isWriteOp() || isDeleteOp()) {
- // add operation before this one to read head+inline
- NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp);
- /*
- * If main op is from take over scan lock, the added read is done
- * as committed read:
- *
- * In normal transactional case, the row is locked by us and
- * committed read returns same as normal read.
- *
- * In current TRUNCATE TABLE, the deleting trans is committed in
- * batches and then restarted with new trans id. A normal read
- * would hang on the scan delete lock and then fail.
- */
- NdbOperation::LockMode lockMode =
- ! isTakeOverOp() ?
- NdbOperation::LM_Read : NdbOperation::LM_CommittedRead;
- if (tOp == NULL ||
- tOp->readTuple(lockMode) == -1 ||
- setTableKeyValue(tOp) == -1 ||
- getHeadInlineValue(tOp) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- if (isWriteOp()) {
- tOp->m_abortOption = NdbOperation::AO_IgnoreError;
- tOp->m_noErrorPropagation = true;
- }
- theHeadInlineReadOp = tOp;
- // execute immediately
- batch = true;
- DBUG_PRINT("info", ("add op before to read head+inline"));
- }
- }
- if (isIndexOp()) {
- // add op before this one to read table key
- NdbBlob* tFirstBlob = theNdbOp->theBlobList;
- if (this == tFirstBlob) {
- // first blob does it for all
- if (g_ndb_blob_ok_to_read_index_table) {
- Uint32 pkAttrId = theAccessTable->getNoOfColumns() - 1;
- NdbOperation* tOp = theNdbCon->getNdbOperation(theAccessTable, theNdbOp);
- if (tOp == NULL ||
- tOp->readTuple() == -1 ||
- setAccessKeyValue(tOp) == -1 ||
- tOp->getValue(pkAttrId, thePackKeyBuf.data) == NULL) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- } else {
- NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
- if (tOp == NULL ||
- tOp->readTuple() == -1 ||
- setAccessKeyValue(tOp) == -1 ||
- getTableKeyValue(tOp) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- }
- }
- DBUG_PRINT("info", ("added op before to read table key"));
- if (isUpdateOp() || isDeleteOp()) {
- // add op before this one to read head+inline via index
- NdbIndexOperation* tOp = theNdbCon->getNdbIndexOperation(theAccessTable->m_index, theTable, theNdbOp);
- if (tOp == NULL ||
- tOp->readTuple() == -1 ||
- setAccessKeyValue(tOp) == -1 ||
- getHeadInlineValue(tOp) == -1) {
- setErrorCode(tOp);
- DBUG_RETURN(-1);
- }
- if (isWriteOp()) {
- tOp->m_abortOption = NdbOperation::AO_IgnoreError;
- tOp->m_noErrorPropagation = true;
- }
- theHeadInlineReadOp = tOp;
- // execute immediately
- batch = true;
- DBUG_PRINT("info", ("added index op before to read head+inline"));
- }
- if (isWriteOp()) {
- // XXX until IgnoreError fixed for index op
- batch = true;
- }
- }
- if (isWriteOp()) {
- if (theSetFlag) {
- // write head+inline now
- theNullFlag = true;
- theLength = 0;
- if (theSetBuf != NULL) {
- Uint32 n = theGetSetBytes;
- if (n > theInlineSize)
- n = theInlineSize;
- assert(thePos == 0);
- if (writeDataPrivate(theSetBuf, n) == -1)
- DBUG_RETURN(-1);
- }
- if (setHeadInlineValue(theNdbOp) == -1)
- DBUG_RETURN(-1);
- // the read op before us may overwrite
- theHeadInlineCopyBuf.copyfrom(theHeadInlineBuf);
- }
- }
- if (theActiveHook != NULL) {
- // need blob head for callback
- batch = true;
- }
- DBUG_PRINT("info", ("batch=%u", batch));
- DBUG_RETURN(0);
-}
-
-/*
- * After execute, for any operation. If already Active, this routine
- * has been done previously. Operations which requested a no-commit
- * batch can add new operations after this one. They are added before
- * any remaining prepared operations.
- */
-int
-NdbBlob::postExecute(NdbTransaction::ExecType anExecType)
-{
- DBUG_ENTER("NdbBlob::postExecute");
- DBUG_PRINT("info", ("this=%p op=%p con=%p anExecType=%u", this, theNdbOp, theNdbCon, anExecType));
- if (theState == Invalid)
- DBUG_RETURN(-1);
- if (theState == Active) {
- setState(anExecType == NdbTransaction::NoCommit ? Active : Closed);
- DBUG_PRINT("info", ("skip active"));
- DBUG_RETURN(0);
- }
- assert(theState == Prepared);
- setState(anExecType == NdbTransaction::NoCommit ? Active : Closed);
- assert(isKeyOp());
- if (isIndexOp()) {
- NdbBlob* tFirstBlob = theNdbOp->theBlobList;
- if (this == tFirstBlob) {
- packKeyValue(theTable, theKeyBuf);
- } else {
- // copy key from first blob
- theKeyBuf.copyfrom(tFirstBlob->theKeyBuf);
- thePackKeyBuf.copyfrom(tFirstBlob->thePackKeyBuf);
- thePackKeyBuf.zerorest();
- }
- }
- if (isReadOp()) {
- getHeadFromRecAttr();
- if (setPos(0) == -1)
- DBUG_RETURN(-1);
- if (theGetFlag) {
- assert(theGetSetBytes == 0 || theGetBuf != 0);
- assert(theGetSetBytes <= theInlineSize ||
- anExecType == NdbTransaction::NoCommit);
- Uint32 bytes = theGetSetBytes;
- if (readDataPrivate(theGetBuf, bytes) == -1)
- DBUG_RETURN(-1);
- }
- }
- if (isUpdateOp()) {
- assert(anExecType == NdbTransaction::NoCommit);
- getHeadFromRecAttr();
- if (theSetFlag) {
- // setValue overwrites everything
- if (theSetBuf != NULL) {
- if (truncate(0) == -1)
- DBUG_RETURN(-1);
- assert(thePos == 0);
- if (writeDataPrivate(theSetBuf, theGetSetBytes) == -1)
- DBUG_RETURN(-1);
- } else {
- if (setNull() == -1)
- DBUG_RETURN(-1);
- }
- }
- }
- if (isWriteOp() && isTableOp()) {
- assert(anExecType == NdbTransaction::NoCommit);
- if (theHeadInlineReadOp->theError.code == 0) {
- int tNullFlag = theNullFlag;
- Uint64 tLength = theLength;
- Uint64 tPos = thePos;
- getHeadFromRecAttr();
- DBUG_PRINT("info", ("tuple found"));
- if (truncate(0) == -1)
- DBUG_RETURN(-1);
- // restore previous head+inline
- theHeadInlineBuf.copyfrom(theHeadInlineCopyBuf);
- theNullFlag = tNullFlag;
- theLength = tLength;
- thePos = tPos;
- } else {
- if (theHeadInlineReadOp->theError.code != 626) {
- setErrorCode(theHeadInlineReadOp);
- DBUG_RETURN(-1);
- }
- DBUG_PRINT("info", ("tuple not found"));
- /*
- * Read found no tuple but it is possible that a tuple was
- * created after the read by another transaction. Delete all
- * blob parts which may exist.
- */
- if (deletePartsUnknown(0) == -1)
- DBUG_RETURN(-1);
- }
- if (theSetFlag && theGetSetBytes > theInlineSize) {
- assert(theSetBuf != NULL);
- const char* buf = theSetBuf + theInlineSize;
- Uint32 bytes = theGetSetBytes - theInlineSize;
- assert(thePos == theInlineSize);
- if (writeDataPrivate(buf, bytes) == -1)
- DBUG_RETURN(-1);
- }
- }
- if (isWriteOp() && isIndexOp()) {
- // XXX until IgnoreError fixed for index op
- if (deletePartsUnknown(0) == -1)
- DBUG_RETURN(-1);
- if (theSetFlag && theGetSetBytes > theInlineSize) {
- assert(theSetBuf != NULL);
- const char* buf = theSetBuf + theInlineSize;
- Uint32 bytes = theGetSetBytes - theInlineSize;
- assert(thePos == theInlineSize);
- if (writeDataPrivate(buf, bytes) == -1)
- DBUG_RETURN(-1);
- }
- }
- if (isDeleteOp()) {
- assert(anExecType == NdbTransaction::NoCommit);
- getHeadFromRecAttr();
- if (deleteParts(0, getPartCount()) == -1)
- DBUG_RETURN(-1);
- }
- setState(anExecType == NdbTransaction::NoCommit ? Active : Closed);
- // activation callback
- if (theActiveHook != NULL) {
- if (invokeActiveHook() == -1)
- DBUG_RETURN(-1);
- }
- if (anExecType == NdbTransaction::NoCommit && theHeadInlineUpdateFlag) {
- NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
- if (tOp == NULL ||
- tOp->updateTuple() == -1 ||
- setTableKeyValue(tOp) == -1 ||
- setHeadInlineValue(tOp) == -1) {
- setErrorCode(NdbBlobImpl::ErrAbort);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- DBUG_PRINT("info", ("added op to update head+inline"));
- }
- DBUG_RETURN(0);
-}
-
-/*
- * Before commit of completed operation. For write add operation to
- * update head+inline.
- */
-int
-NdbBlob::preCommit()
-{
- DBUG_ENTER("NdbBlob::preCommit");
- DBUG_PRINT("info", ("this=%p op=%p con=%p", this, theNdbOp, theNdbCon));
- if (theState == Invalid)
- DBUG_RETURN(-1);
- assert(theState == Active);
- assert(isKeyOp());
- if (isInsertOp() || isUpdateOp() || isWriteOp()) {
- if (theHeadInlineUpdateFlag) {
- // add an operation to update head+inline
- NdbOperation* tOp = theNdbCon->getNdbOperation(theTable);
- if (tOp == NULL ||
- tOp->updateTuple() == -1 ||
- setTableKeyValue(tOp) == -1 ||
- setHeadInlineValue(tOp) == -1) {
- setErrorCode(NdbBlobImpl::ErrAbort);
- DBUG_RETURN(-1);
- }
- tOp->m_abortOption = NdbOperation::AbortOnError;
- DBUG_PRINT("info", ("added op to update head+inline"));
- }
- }
- DBUG_RETURN(0);
-}
-
-/*
- * After next scan result. Handle like read op above.
- */
-int
-NdbBlob::atNextResult()
-{
- DBUG_ENTER("NdbBlob::atNextResult");
- DBUG_PRINT("info", ("this=%p op=%p con=%p", this, theNdbOp, theNdbCon));
- if (theState == Invalid)
- DBUG_RETURN(-1);
- assert(isScanOp());
- // get primary key
- { NdbScanOperation* tScanOp = (NdbScanOperation*)theNdbOp;
- Uint32* data = (Uint32*)thePackKeyBuf.data;
- unsigned size = theTable->m_keyLenInWords; // in-out
- if (tScanOp->getKeyFromKEYINFO20(data, size) == -1) {
- setErrorCode(NdbBlobImpl::ErrUsage);
- DBUG_RETURN(-1);
- }
- thePackKeyBuf.size = 4 * size;
- thePackKeyBuf.zerorest();
- if (unpackKeyValue(theTable, theKeyBuf) == -1)
- DBUG_RETURN(-1);
- }
- getHeadFromRecAttr();
- if (setPos(0) == -1)
- DBUG_RETURN(-1);
- if (theGetFlag) {
- assert(theGetSetBytes == 0 || theGetBuf != 0);
- Uint32 bytes = theGetSetBytes;
- if (readDataPrivate(theGetBuf, bytes) == -1)
- DBUG_RETURN(-1);
- }
- setState(Active);
- // activation callback
- if (theActiveHook != NULL) {
- if (invokeActiveHook() == -1)
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
-
-/*
- * After next event on main table.
- */
-int
-NdbBlob::atNextEvent()
-{
- DBUG_ENTER("NdbBlob::atNextEvent");
- Uint32 optype =
- SubTableData::getOperation(theEventOp->m_data_item->sdata->requestInfo);
- DBUG_PRINT("info", ("this=%p op=%p blob op=%p version=%d optype=%u", this, theEventOp, theBlobEventOp, theEventBlobVersion, optype));
- if (theState == Invalid)
- DBUG_RETURN(-1);
- assert(theEventBlobVersion >= 0);
- if (optype >= NdbDictionary::Event::_TE_FIRST_NON_DATA_EVENT)
- DBUG_RETURN(0);
- getHeadFromRecAttr();
- if (theNullFlag == -1) // value not defined
- DBUG_RETURN(0);
- if (setPos(0) == -1)
- DBUG_RETURN(-1);
- setState(Active);
- DBUG_RETURN(0);
-}
-
-// misc
-
-const NdbDictionary::Column*
-NdbBlob::getColumn()
-{
- return theColumn;
-}
-
-// errors
-
-void
-NdbBlob::setErrorCode(int anErrorCode, bool invalidFlag)
-{
- DBUG_ENTER("NdbBlob::setErrorCode");
- DBUG_PRINT("info", ("this=%p code=%u", this, anErrorCode));
- theError.code = anErrorCode;
- // conditionally copy error to operation level
- if (theNdbOp != NULL && theNdbOp->theError.code == 0)
- theNdbOp->setErrorCode(theError.code);
- if (invalidFlag)
- setState(Invalid);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag)
-{
- int code = 0;
- if (anOp != NULL && (code = anOp->theError.code) != 0)
- ;
- else if ((code = theNdbCon->theError.code) != 0)
- ;
- else if ((code = theNdb->theError.code) != 0)
- ;
- else
- code = NdbBlobImpl::ErrUnknown;
- setErrorCode(code, invalidFlag);
-}
-
-void
-NdbBlob::setErrorCode(NdbTransaction* aCon, bool invalidFlag)
-{
- int code = 0;
- if (theNdbCon != NULL && (code = theNdbCon->theError.code) != 0)
- ;
- else if ((code = theNdb->theError.code) != 0)
- ;
- else
- code = NdbBlobImpl::ErrUnknown;
- setErrorCode(code, invalidFlag);
-}
-
-void
-NdbBlob::setErrorCode(NdbEventOperationImpl* anOp, bool invalidFlag)
-{
- int code = 0;
- if ((code = anOp->m_error.code) != 0)
- ;
- else
- code = NdbBlobImpl::ErrUnknown;
- setErrorCode(code, invalidFlag);
-}
-
-// info about all blobs in this operation
-
-NdbBlob*
-NdbBlob::blobsFirstBlob()
-{
- return theNdbOp->theBlobList;
-}
-
-NdbBlob*
-NdbBlob::blobsNextBlob()
-{
- return theNext;
-}
-
-// debug
-
-#ifdef VM_TRACE
-inline int
-NdbBlob::getOperationType() const
-{
- return theNdbOp != NULL ? theNdbOp->theOperationType : -1;
-}
-
-NdbOut&
-operator<<(NdbOut& out, const NdbBlob& blob)
-{
- ndbout << dec << "o=" << blob.getOperationType();
- ndbout << dec << " s=" << (Uint32) blob.theState;
- ndbout << dec << " n=" << blob.theNullFlag;;
- ndbout << dec << " l=" << blob.theLength;
- ndbout << dec << " p=" << blob.thePos;
- ndbout << dec << " u=" << (Uint32)blob.theHeadInlineUpdateFlag;
- ndbout << dec << " g=" << (Uint32)blob.theGetSetBytes;
- return out;
-}
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbBlobImpl.hpp b/storage/ndb/src/ndbapi/NdbBlobImpl.hpp
deleted file mode 100644
index d250e176c11..00000000000
--- a/storage/ndb/src/ndbapi/NdbBlobImpl.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NdbBlobImpl_H
-#define NdbBlobImpl_H
-
-class NdbBlobImpl {
-public:
- STATIC_CONST( BlobTableNameSize = 40 );
- // "Invalid blob attributes or invalid blob parts table"
- STATIC_CONST( ErrTable = 4263 );
- // "Invalid usage of blob attribute"
- STATIC_CONST( ErrUsage = 4264 );
- // "The blob method is not valid in current blob state"
- STATIC_CONST( ErrState = 4265 );
- // "Invalid blob seek position"
- STATIC_CONST( ErrSeek = 4266 );
- // "Corrupted blob value"
- STATIC_CONST( ErrCorrupt = 4267 );
- // "Error in blob head update forced rollback of transaction"
- STATIC_CONST( ErrAbort = 4268 );
- // "Unknown blob error"
- STATIC_CONST( ErrUnknown = 4270 );
- // "Corrupted main table PK in blob operation"
- STATIC_CONST( ErrCorruptPK = 4274 );
- // "The blob method is incompatible with operation type or lock mode"
- STATIC_CONST( ErrCompat = 4275 );
-};
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp
deleted file mode 100644
index 318cfb8cced..00000000000
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp
+++ /dev/null
@@ -1,2047 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <NdbDictionary.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <NdbOut.hpp>
-
-NdbDictionary::ObjectId::ObjectId()
- : m_impl(* new NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined))
-{
-}
-
-NdbDictionary::ObjectId::~ObjectId()
-{
- NdbDictObjectImpl * tmp = &m_impl;
- delete tmp;
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::ObjectId::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::ObjectId::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::ObjectId::getObjectId() const {
- return m_impl.m_id;
-}
-
-/*****************************************************************
- * Column facade
- */
-NdbDictionary::Column::Column(const char * name)
- : m_impl(* new NdbColumnImpl(* this))
-{
- setName(name);
-}
-
-NdbDictionary::Column::Column(const NdbDictionary::Column & org)
- : m_impl(* new NdbColumnImpl(* this))
-{
- m_impl = org.m_impl;
-}
-
-NdbDictionary::Column::Column(NdbColumnImpl& impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Column::~Column(){
- NdbColumnImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-NdbDictionary::Column&
-NdbDictionary::Column::operator=(const NdbDictionary::Column& column)
-{
- m_impl = column.m_impl;
-
- return *this;
-}
-
-int
-NdbDictionary::Column::setName(const char * name){
- return !m_impl.m_name.assign(name);
-}
-
-const char*
-NdbDictionary::Column::getName() const {
- return m_impl.m_name.c_str();
-}
-
-void
-NdbDictionary::Column::setType(Type t){
- m_impl.init(t);
-}
-
-NdbDictionary::Column::Type
-NdbDictionary::Column::getType() const {
- return m_impl.m_type;
-}
-
-void
-NdbDictionary::Column::setPrecision(int val){
- m_impl.m_precision = val;
-}
-
-int
-NdbDictionary::Column::getPrecision() const {
- return m_impl.m_precision;
-}
-
-void
-NdbDictionary::Column::setScale(int val){
- m_impl.m_scale = val;
-}
-
-int
-NdbDictionary::Column::getScale() const{
- return m_impl.m_scale;
-}
-
-void
-NdbDictionary::Column::setLength(int length){
- m_impl.m_length = length;
-}
-
-int
-NdbDictionary::Column::getLength() const{
- return m_impl.m_length;
-}
-
-void
-NdbDictionary::Column::setInlineSize(int size)
-{
- m_impl.m_precision = size;
-}
-
-void
-NdbDictionary::Column::setCharset(CHARSET_INFO* cs)
-{
- m_impl.m_cs = cs;
-}
-
-CHARSET_INFO*
-NdbDictionary::Column::getCharset() const
-{
- return m_impl.m_cs;
-}
-
-int
-NdbDictionary::Column::getInlineSize() const
-{
- return m_impl.m_precision;
-}
-
-void
-NdbDictionary::Column::setPartSize(int size)
-{
- m_impl.m_scale = size;
-}
-
-int
-NdbDictionary::Column::getPartSize() const
-{
- return m_impl.m_scale;
-}
-
-void
-NdbDictionary::Column::setStripeSize(int size)
-{
- m_impl.m_length = size;
-}
-
-int
-NdbDictionary::Column::getStripeSize() const
-{
- return m_impl.m_length;
-}
-
-int
-NdbDictionary::Column::getSize() const{
- return m_impl.m_attrSize;
-}
-
-void
-NdbDictionary::Column::setNullable(bool val){
- m_impl.m_nullable = val;
-}
-
-bool
-NdbDictionary::Column::getNullable() const {
- return m_impl.m_nullable;
-}
-
-void
-NdbDictionary::Column::setPrimaryKey(bool val){
- m_impl.m_pk = val;
-}
-
-bool
-NdbDictionary::Column::getPrimaryKey() const {
- return m_impl.m_pk;
-}
-
-void
-NdbDictionary::Column::setPartitionKey(bool val){
- m_impl.m_distributionKey = val;
-}
-
-bool
-NdbDictionary::Column::getPartitionKey() const{
- return m_impl.m_distributionKey;
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Column::getBlobTable() const {
- NdbTableImpl * t = m_impl.m_blobTable;
- if (t)
- return t->m_facade;
- return 0;
-}
-
-void
-NdbDictionary::Column::setAutoIncrement(bool val){
- m_impl.m_autoIncrement = val;
-}
-
-bool
-NdbDictionary::Column::getAutoIncrement() const {
- return m_impl.m_autoIncrement;
-}
-
-void
-NdbDictionary::Column::setAutoIncrementInitialValue(Uint64 val){
- m_impl.m_autoIncrementInitialValue = val;
-}
-
-int
-NdbDictionary::Column::setDefaultValue(const char* defaultValue)
-{
- return !m_impl.m_defaultValue.assign(defaultValue);
-}
-
-const char*
-NdbDictionary::Column::getDefaultValue() const
-{
- return m_impl.m_defaultValue.c_str();
-}
-
-int
-NdbDictionary::Column::getColumnNo() const {
- return m_impl.m_column_no;
-}
-
-int
-NdbDictionary::Column::getAttrId() const {
- return m_impl.m_attrId;;
-}
-
-bool
-NdbDictionary::Column::equal(const NdbDictionary::Column & col) const {
- return m_impl.equal(col.m_impl);
-}
-
-int
-NdbDictionary::Column::getSizeInBytes() const
-{
- return m_impl.m_attrSize * m_impl.m_arraySize;
-}
-
-void
-NdbDictionary::Column::setArrayType(ArrayType type)
-{
- m_impl.m_arrayType = type;
-}
-
-NdbDictionary::Column::ArrayType
-NdbDictionary::Column::getArrayType() const
-{
- return (ArrayType)m_impl.m_arrayType;
-}
-
-void
-NdbDictionary::Column::setStorageType(StorageType type)
-{
- m_impl.m_storageType = type;
-}
-
-NdbDictionary::Column::StorageType
-NdbDictionary::Column::getStorageType() const
-{
- return (StorageType)m_impl.m_storageType;
-}
-
-/*****************************************************************
- * Table facade
- */
-NdbDictionary::Table::Table(const char * name)
- : m_impl(* new NdbTableImpl(* this))
-{
- setName(name);
-}
-
-NdbDictionary::Table::Table(const NdbDictionary::Table & org)
- : Object(org), m_impl(* new NdbTableImpl(* this))
-{
- m_impl.assign(org.m_impl);
-}
-
-NdbDictionary::Table::Table(NdbTableImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Table::~Table(){
- NdbTableImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-NdbDictionary::Table&
-NdbDictionary::Table::operator=(const NdbDictionary::Table& table)
-{
- m_impl.assign(table.m_impl);
-
- m_impl.m_facade = this;
- return *this;
-}
-
-int
-NdbDictionary::Table::setName(const char * name){
- return m_impl.setName(name);
-}
-
-const char *
-NdbDictionary::Table::getName() const {
- return m_impl.getName();
-}
-
-const char *
-NdbDictionary::Table::getMysqlName() const {
- return m_impl.getMysqlName();
-}
-
-int
-NdbDictionary::Table::getTableId() const {
- return m_impl.m_id;
-}
-
-int
-NdbDictionary::Table::addColumn(const Column & c){
- NdbColumnImpl* col = new NdbColumnImpl;
- if (col == NULL)
- {
- errno = ENOMEM;
- return -1;
- }
- (* col) = NdbColumnImpl::getImpl(c);
- if (m_impl.m_columns.push_back(col))
- {
- return -1;
- }
- if (m_impl.buildColumnHash())
- {
- return -1;
- }
- return 0;
-}
-
-const NdbDictionary::Column*
-NdbDictionary::Table::getColumn(const char * name) const {
- return m_impl.getColumn(name);
-}
-
-const NdbDictionary::Column*
-NdbDictionary::Table::getColumn(const int attrId) const {
- return m_impl.getColumn(attrId);
-}
-
-NdbDictionary::Column*
-NdbDictionary::Table::getColumn(const char * name)
-{
- return m_impl.getColumn(name);
-}
-
-NdbDictionary::Column*
-NdbDictionary::Table::getColumn(const int attrId)
-{
- return m_impl.getColumn(attrId);
-}
-
-void
-NdbDictionary::Table::setLogging(bool val){
- m_impl.m_logging = val;
-}
-
-bool
-NdbDictionary::Table::getLogging() const {
- return m_impl.m_logging;
-}
-
-void
-NdbDictionary::Table::setFragmentType(FragmentType ft){
- m_impl.m_fragmentType = ft;
-}
-
-NdbDictionary::Object::FragmentType
-NdbDictionary::Table::getFragmentType() const {
- return m_impl.m_fragmentType;
-}
-
-void
-NdbDictionary::Table::setKValue(int kValue){
- m_impl.m_kvalue = kValue;
-}
-
-int
-NdbDictionary::Table::getKValue() const {
- return m_impl.m_kvalue;
-}
-
-void
-NdbDictionary::Table::setMinLoadFactor(int lf){
- m_impl.m_minLoadFactor = lf;
-}
-
-int
-NdbDictionary::Table::getMinLoadFactor() const {
- return m_impl.m_minLoadFactor;
-}
-
-void
-NdbDictionary::Table::setMaxLoadFactor(int lf){
- m_impl.m_maxLoadFactor = lf;
-}
-
-int
-NdbDictionary::Table::getMaxLoadFactor() const {
- return m_impl.m_maxLoadFactor;
-}
-
-int
-NdbDictionary::Table::getNoOfColumns() const {
- return m_impl.m_columns.size();
-}
-
-int
-NdbDictionary::Table::getNoOfPrimaryKeys() const {
- return m_impl.m_noOfKeys;
-}
-
-void
-NdbDictionary::Table::setMaxRows(Uint64 maxRows)
-{
- m_impl.m_max_rows = maxRows;
-}
-
-Uint64
-NdbDictionary::Table::getMaxRows() const
-{
- return m_impl.m_max_rows;
-}
-
-void
-NdbDictionary::Table::setMinRows(Uint64 minRows)
-{
- m_impl.m_min_rows = minRows;
-}
-
-Uint64
-NdbDictionary::Table::getMinRows() const
-{
- return m_impl.m_min_rows;
-}
-
-void
-NdbDictionary::Table::setDefaultNoPartitionsFlag(Uint32 flag)
-{
- m_impl.m_default_no_part_flag = flag;;
-}
-
-Uint32
-NdbDictionary::Table::getDefaultNoPartitionsFlag() const
-{
- return m_impl.m_default_no_part_flag;
-}
-
-const char*
-NdbDictionary::Table::getPrimaryKey(int no) const {
- int count = 0;
- for (unsigned i = 0; i < m_impl.m_columns.size(); i++) {
- if (m_impl.m_columns[i]->m_pk) {
- if (count++ == no)
- return m_impl.m_columns[i]->m_name.c_str();
- }
- }
- return 0;
-}
-
-const void*
-NdbDictionary::Table::getFrmData() const {
- return m_impl.getFrmData();
-}
-
-Uint32
-NdbDictionary::Table::getFrmLength() const {
- return m_impl.getFrmLength();
-}
-
-enum NdbDictionary::Table::SingleUserMode
-NdbDictionary::Table::getSingleUserMode() const
-{
- return (enum SingleUserMode)m_impl.m_single_user_mode;
-}
-
-void
-NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMode mode)
-{
- m_impl.m_single_user_mode = (Uint8)mode;
-}
-
-int
-NdbDictionary::Table::setTablespaceNames(const void *data, Uint32 len)
-{
- return m_impl.setTablespaceNames(data, len);
-}
-
-const void*
-NdbDictionary::Table::getTablespaceNames()
-{
- return m_impl.getTablespaceNames();
-}
-
-Uint32
-NdbDictionary::Table::getTablespaceNamesLen() const
-{
- return m_impl.getTablespaceNamesLen();
-}
-
-void
-NdbDictionary::Table::setLinearFlag(Uint32 flag)
-{
- m_impl.m_linear_flag = flag;
-}
-
-bool
-NdbDictionary::Table::getLinearFlag() const
-{
- return m_impl.m_linear_flag;
-}
-
-void
-NdbDictionary::Table::setFragmentCount(Uint32 count)
-{
- m_impl.setFragmentCount(count);
-}
-
-Uint32
-NdbDictionary::Table::getFragmentCount() const
-{
- return m_impl.getFragmentCount();
-}
-
-int
-NdbDictionary::Table::setFrm(const void* data, Uint32 len){
- return m_impl.setFrm(data, len);
-}
-
-const void*
-NdbDictionary::Table::getFragmentData() const {
- return m_impl.getFragmentData();
-}
-
-Uint32
-NdbDictionary::Table::getFragmentDataLen() const {
- return m_impl.getFragmentDataLen();
-}
-
-int
-NdbDictionary::Table::setFragmentData(const void* data, Uint32 len)
-{
- return m_impl.setFragmentData(data, len);
-}
-
-const void*
-NdbDictionary::Table::getTablespaceData() const {
- return m_impl.getTablespaceData();
-}
-
-Uint32
-NdbDictionary::Table::getTablespaceDataLen() const {
- return m_impl.getTablespaceDataLen();
-}
-
-int
-NdbDictionary::Table::setTablespaceData(const void* data, Uint32 len)
-{
- return m_impl.setTablespaceData(data, len);
-}
-
-const void*
-NdbDictionary::Table::getRangeListData() const {
- return m_impl.getRangeListData();
-}
-
-Uint32
-NdbDictionary::Table::getRangeListDataLen() const {
- return m_impl.getRangeListDataLen();
-}
-
-int
-NdbDictionary::Table::setRangeListData(const void* data, Uint32 len)
-{
- return m_impl.setRangeListData(data, len);
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Table::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-void
-NdbDictionary::Table::setStatusInvalid() const {
- m_impl.m_status = NdbDictionary::Object::Invalid;
-}
-
-int
-NdbDictionary::Table::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::Table::getObjectId() const {
- return m_impl.m_id;
-}
-
-bool
-NdbDictionary::Table::equal(const NdbDictionary::Table & col) const {
- return m_impl.equal(col.m_impl);
-}
-
-int
-NdbDictionary::Table::getRowSizeInBytes() const {
- int sz = 0;
- for(int i = 0; i<getNoOfColumns(); i++){
- const NdbDictionary::Column * c = getColumn(i);
- sz += (c->getSizeInBytes()+ 3) / 4;
- }
- return sz * 4;
-}
-
-int
-NdbDictionary::Table::getReplicaCount() const {
- return m_impl.m_replicaCount;
-}
-
-bool
-NdbDictionary::Table::getTemporary() {
- return m_impl.m_temporary;
-}
-
-void
-NdbDictionary::Table::setTemporary(bool val) {
- m_impl.m_temporary = val;
-}
-
-int
-NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const {
- const NdbDictionary::Table * pTab =
- pNdb->getDictionary()->getTable(getName());
- if(pTab != 0 && equal(* pTab))
- return 0;
- if(pTab != 0 && !equal(* pTab))
- return -1;
- return pNdb->getDictionary()->createTable(* this);
-}
-
-bool
-NdbDictionary::Table::getTablespace(Uint32 *id, Uint32 *version) const
-{
- if (m_impl.m_tablespace_id == RNIL)
- return false;
- if (id)
- *id= m_impl.m_tablespace_id;
- if (version)
- *version= m_impl.m_version;
- return true;
-}
-
-const char *
-NdbDictionary::Table::getTablespaceName() const
-{
- return m_impl.m_tablespace_name.c_str();
-}
-
-int
-NdbDictionary::Table::setTablespaceName(const char * name){
- m_impl.m_tablespace_id = ~0;
- m_impl.m_tablespace_version = ~0;
- return !m_impl.m_tablespace_name.assign(name);
-}
-
-int
-NdbDictionary::Table::setTablespace(const NdbDictionary::Tablespace & ts){
- m_impl.m_tablespace_id = NdbTablespaceImpl::getImpl(ts).m_id;
- m_impl.m_tablespace_version = ts.getObjectVersion();
- return !m_impl.m_tablespace_name.assign(ts.getName());
-}
-
-void
-NdbDictionary::Table::setRowChecksumIndicator(bool val){
- m_impl.m_row_checksum = val;
-}
-
-bool
-NdbDictionary::Table::getRowChecksumIndicator() const {
- return m_impl.m_row_checksum;
-}
-
-void
-NdbDictionary::Table::setRowGCIIndicator(bool val){
- m_impl.m_row_gci = val;
-}
-
-bool
-NdbDictionary::Table::getRowGCIIndicator() const {
- return m_impl.m_row_gci;
-}
-
-void
-NdbDictionary::Table::setForceVarPart(bool val){
- m_impl.m_force_var_part = val;
-}
-
-bool
-NdbDictionary::Table::getForceVarPart() const {
- return m_impl.m_force_var_part;
-}
-
-int
-NdbDictionary::Table::aggregate(NdbError& error)
-{
- return m_impl.aggregate(error);
-}
-
-int
-NdbDictionary::Table::validate(NdbError& error)
-{
- return m_impl.validate(error);
-}
-
-
-/*****************************************************************
- * Index facade
- */
-
-NdbDictionary::Index::Index(const char * name)
- : m_impl(* new NdbIndexImpl(* this))
-{
- setName(name);
-}
-
-NdbDictionary::Index::Index(NdbIndexImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Index::~Index(){
- NdbIndexImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-int
-NdbDictionary::Index::setName(const char * name){
- return m_impl.setName(name);
-}
-
-const char *
-NdbDictionary::Index::getName() const {
- return m_impl.getName();
-}
-
-int
-NdbDictionary::Index::setTable(const char * table){
- return m_impl.setTable(table);
-}
-
-const char *
-NdbDictionary::Index::getTable() const {
- return m_impl.getTable();
-}
-
-unsigned
-NdbDictionary::Index::getNoOfColumns() const {
- return m_impl.m_columns.size();
-}
-
-int
-NdbDictionary::Index::getNoOfIndexColumns() const {
- return m_impl.m_columns.size();
-}
-
-const NdbDictionary::Column *
-NdbDictionary::Index::getColumn(unsigned no) const {
- if(no < m_impl.m_columns.size())
- return m_impl.m_columns[no];
- return NULL;
-}
-
-const char *
-NdbDictionary::Index::getIndexColumn(int no) const {
- const NdbDictionary::Column* col = getColumn(no);
-
- if (col)
- return col->getName();
- else
- return NULL;
-}
-
-int
-NdbDictionary::Index::addColumn(const Column & c){
- NdbColumnImpl* col = new NdbColumnImpl;
- if (col == NULL)
- {
- errno = ENOMEM;
- return -1;
- }
- (* col) = NdbColumnImpl::getImpl(c);
- if (m_impl.m_columns.push_back(col))
- {
- return -1;
- }
- return 0;
-}
-
-int
-NdbDictionary::Index::addColumnName(const char * name){
- const Column c(name);
- return addColumn(c);
-}
-
-int
-NdbDictionary::Index::addIndexColumn(const char * name){
- const Column c(name);
- return addColumn(c);
-}
-
-int
-NdbDictionary::Index::addColumnNames(unsigned noOfNames, const char ** names){
- for(unsigned i = 0; i < noOfNames; i++) {
- const Column c(names[i]);
- if (addColumn(c))
- {
- return -1;
- }
- }
- return 0;
-}
-
-int
-NdbDictionary::Index::addIndexColumns(int noOfNames, const char ** names){
- for(int i = 0; i < noOfNames; i++) {
- const Column c(names[i]);
- if (addColumn(c))
- {
- return -1;
- }
- }
- return 0;
-}
-
-void
-NdbDictionary::Index::setType(NdbDictionary::Index::Type t){
- m_impl.m_type = (NdbDictionary::Object::Type)t;
-}
-
-NdbDictionary::Index::Type
-NdbDictionary::Index::getType() const {
- return (NdbDictionary::Index::Type)m_impl.m_type;
-}
-
-void
-NdbDictionary::Index::setLogging(bool val){
- m_impl.m_logging = val;
-}
-
-bool
-NdbDictionary::Index::getTemporary(){
- return m_impl.m_temporary;
-}
-
-void
-NdbDictionary::Index::setTemporary(bool val){
- m_impl.m_temporary = val;
-}
-
-bool
-NdbDictionary::Index::getLogging() const {
- return m_impl.m_logging;
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Index::getObjectStatus() const {
- return m_impl.m_table->m_status;
-}
-
-int
-NdbDictionary::Index::getObjectVersion() const {
- return m_impl.m_table->m_version;
-}
-
-int
-NdbDictionary::Index::getObjectId() const {
- return m_impl.m_table->m_id;
-}
-
-
-/*****************************************************************
- * Event facade
- */
-NdbDictionary::Event::Event(const char * name)
- : m_impl(* new NdbEventImpl(* this))
-{
- setName(name);
-}
-
-NdbDictionary::Event::Event(const char * name, const Table& table)
- : m_impl(* new NdbEventImpl(* this))
-{
- setName(name);
- setTable(table);
-}
-
-NdbDictionary::Event::Event(NdbEventImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Event::~Event()
-{
- NdbEventImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-int
-NdbDictionary::Event::setName(const char * name)
-{
- return m_impl.setName(name);
-}
-
-const char *
-NdbDictionary::Event::getName() const
-{
- return m_impl.getName();
-}
-
-void
-NdbDictionary::Event::setTable(const Table& table)
-{
- m_impl.setTable(table);
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Event::getTable() const
-{
- return m_impl.getTable();
-}
-
-int
-NdbDictionary::Event::setTable(const char * table)
-{
- return m_impl.setTable(table);
-}
-
-const char*
-NdbDictionary::Event::getTableName() const
-{
- return m_impl.getTableName();
-}
-
-void
-NdbDictionary::Event::addTableEvent(const TableEvent t)
-{
- m_impl.addTableEvent(t);
-}
-
-bool
-NdbDictionary::Event::getTableEvent(const TableEvent t) const
-{
- return m_impl.getTableEvent(t);
-}
-
-void
-NdbDictionary::Event::setDurability(EventDurability d)
-{
- m_impl.setDurability(d);
-}
-
-NdbDictionary::Event::EventDurability
-NdbDictionary::Event::getDurability() const
-{
- return m_impl.getDurability();
-}
-
-void
-NdbDictionary::Event::setReport(EventReport r)
-{
- m_impl.setReport(r);
-}
-
-NdbDictionary::Event::EventReport
-NdbDictionary::Event::getReport() const
-{
- return m_impl.getReport();
-}
-
-void
-NdbDictionary::Event::addColumn(const Column & c){
- NdbColumnImpl* col = new NdbColumnImpl;
- (* col) = NdbColumnImpl::getImpl(c);
- m_impl.m_columns.push_back(col);
-}
-
-void
-NdbDictionary::Event::addEventColumn(unsigned attrId)
-{
- m_impl.m_attrIds.push_back(attrId);
-}
-
-void
-NdbDictionary::Event::addEventColumn(const char * name)
-{
- const Column c(name);
- addColumn(c);
-}
-
-void
-NdbDictionary::Event::addEventColumns(int n, const char ** names)
-{
- for (int i = 0; i < n; i++)
- addEventColumn(names[i]);
-}
-
-int NdbDictionary::Event::getNoOfEventColumns() const
-{
- return m_impl.getNoOfEventColumns();
-}
-
-const NdbDictionary::Column *
-NdbDictionary::Event::getEventColumn(unsigned no) const
-{
- return m_impl.getEventColumn(no);
-}
-
-void NdbDictionary::Event::mergeEvents(bool flag)
-{
- m_impl.m_mergeEvents = flag;
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Event::getObjectStatus() const
-{
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::Event::getObjectVersion() const
-{
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::Event::getObjectId() const {
- return m_impl.m_id;
-}
-
-void NdbDictionary::Event::print()
-{
- m_impl.print();
-}
-
-/*****************************************************************
- * Tablespace facade
- */
-NdbDictionary::Tablespace::Tablespace()
- : m_impl(* new NdbTablespaceImpl(* this))
-{
-}
-
-NdbDictionary::Tablespace::Tablespace(NdbTablespaceImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Tablespace::Tablespace(const NdbDictionary::Tablespace & org)
- : Object(org), m_impl(* new NdbTablespaceImpl(* this))
-{
- m_impl.assign(org.m_impl);
-}
-
-NdbDictionary::Tablespace::~Tablespace(){
- NdbTablespaceImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-void
-NdbDictionary::Tablespace::setName(const char * name){
- m_impl.m_name.assign(name);
-}
-
-const char *
-NdbDictionary::Tablespace::getName() const {
- return m_impl.m_name.c_str();
-}
-
-void
-NdbDictionary::Tablespace::setAutoGrowSpecification
-(const NdbDictionary::AutoGrowSpecification& spec){
- m_impl.m_grow_spec = spec;
-}
-const NdbDictionary::AutoGrowSpecification&
-NdbDictionary::Tablespace::getAutoGrowSpecification() const {
- return m_impl.m_grow_spec;
-}
-
-void
-NdbDictionary::Tablespace::setExtentSize(Uint32 sz){
- m_impl.m_extent_size = sz;
-}
-
-Uint32
-NdbDictionary::Tablespace::getExtentSize() const {
- return m_impl.m_extent_size;
-}
-
-void
-NdbDictionary::Tablespace::setDefaultLogfileGroup(const char * name){
- m_impl.m_logfile_group_id = ~0;
- m_impl.m_logfile_group_version = ~0;
- m_impl.m_logfile_group_name.assign(name);
-}
-
-void
-NdbDictionary::Tablespace::setDefaultLogfileGroup
-(const NdbDictionary::LogfileGroup & lg){
- m_impl.m_logfile_group_id = NdbLogfileGroupImpl::getImpl(lg).m_id;
- m_impl.m_logfile_group_version = lg.getObjectVersion();
- m_impl.m_logfile_group_name.assign(lg.getName());
-}
-
-const char *
-NdbDictionary::Tablespace::getDefaultLogfileGroup() const {
- return m_impl.m_logfile_group_name.c_str();
-}
-
-Uint32
-NdbDictionary::Tablespace::getDefaultLogfileGroupId() const {
- return m_impl.m_logfile_group_id;
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Tablespace::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::Tablespace::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::Tablespace::getObjectId() const {
- return m_impl.m_id;
-}
-
-/*****************************************************************
- * LogfileGroup facade
- */
-NdbDictionary::LogfileGroup::LogfileGroup()
- : m_impl(* new NdbLogfileGroupImpl(* this))
-{
-}
-
-NdbDictionary::LogfileGroup::LogfileGroup(NdbLogfileGroupImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::LogfileGroup::LogfileGroup(const NdbDictionary::LogfileGroup & org)
- : Object(org), m_impl(* new NdbLogfileGroupImpl(* this))
-{
- m_impl.assign(org.m_impl);
-}
-
-NdbDictionary::LogfileGroup::~LogfileGroup(){
- NdbLogfileGroupImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-void
-NdbDictionary::LogfileGroup::setName(const char * name){
- m_impl.m_name.assign(name);
-}
-
-const char *
-NdbDictionary::LogfileGroup::getName() const {
- return m_impl.m_name.c_str();
-}
-
-void
-NdbDictionary::LogfileGroup::setUndoBufferSize(Uint32 sz){
- m_impl.m_undo_buffer_size = sz;
-}
-
-Uint32
-NdbDictionary::LogfileGroup::getUndoBufferSize() const {
- return m_impl.m_undo_buffer_size;
-}
-
-void
-NdbDictionary::LogfileGroup::setAutoGrowSpecification
-(const NdbDictionary::AutoGrowSpecification& spec){
- m_impl.m_grow_spec = spec;
-}
-const NdbDictionary::AutoGrowSpecification&
-NdbDictionary::LogfileGroup::getAutoGrowSpecification() const {
- return m_impl.m_grow_spec;
-}
-
-Uint64 NdbDictionary::LogfileGroup::getUndoFreeWords() const {
- return m_impl.m_undo_free_words;
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::LogfileGroup::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::LogfileGroup::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::LogfileGroup::getObjectId() const {
- return m_impl.m_id;
-}
-
-/*****************************************************************
- * Datafile facade
- */
-NdbDictionary::Datafile::Datafile()
- : m_impl(* new NdbDatafileImpl(* this))
-{
-}
-
-NdbDictionary::Datafile::Datafile(NdbDatafileImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Datafile::Datafile(const NdbDictionary::Datafile & org)
- : Object(org), m_impl(* new NdbDatafileImpl(* this))
-{
- m_impl.assign(org.m_impl);
-}
-
-NdbDictionary::Datafile::~Datafile(){
- NdbDatafileImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-void
-NdbDictionary::Datafile::setPath(const char * path){
- m_impl.m_path.assign(path);
-}
-
-const char *
-NdbDictionary::Datafile::getPath() const {
- return m_impl.m_path.c_str();
-}
-
-void
-NdbDictionary::Datafile::setSize(Uint64 sz){
- m_impl.m_size = sz;
-}
-
-Uint64
-NdbDictionary::Datafile::getSize() const {
- return m_impl.m_size;
-}
-
-Uint64
-NdbDictionary::Datafile::getFree() const {
- return m_impl.m_free;
-}
-
-int
-NdbDictionary::Datafile::setTablespace(const char * tablespace){
- m_impl.m_filegroup_id = ~0;
- m_impl.m_filegroup_version = ~0;
- return !m_impl.m_filegroup_name.assign(tablespace);
-}
-
-int
-NdbDictionary::Datafile::setTablespace(const NdbDictionary::Tablespace & ts){
- m_impl.m_filegroup_id = NdbTablespaceImpl::getImpl(ts).m_id;
- m_impl.m_filegroup_version = ts.getObjectVersion();
- return !m_impl.m_filegroup_name.assign(ts.getName());
-}
-
-const char *
-NdbDictionary::Datafile::getTablespace() const {
- return m_impl.m_filegroup_name.c_str();
-}
-
-void
-NdbDictionary::Datafile::getTablespaceId(NdbDictionary::ObjectId* dst) const
-{
- if (dst)
- {
- NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
- NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
- }
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Datafile::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::Datafile::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::Datafile::getObjectId() const {
- return m_impl.m_id;
-}
-
-/*****************************************************************
- * Undofile facade
- */
-NdbDictionary::Undofile::Undofile()
- : m_impl(* new NdbUndofileImpl(* this))
-{
-}
-
-NdbDictionary::Undofile::Undofile(NdbUndofileImpl & impl)
- : m_impl(impl)
-{
-}
-
-NdbDictionary::Undofile::Undofile(const NdbDictionary::Undofile & org)
- : Object(org), m_impl(* new NdbUndofileImpl(* this))
-{
- m_impl.assign(org.m_impl);
-}
-
-NdbDictionary::Undofile::~Undofile(){
- NdbUndofileImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-void
-NdbDictionary::Undofile::setPath(const char * path){
- m_impl.m_path.assign(path);
-}
-
-const char *
-NdbDictionary::Undofile::getPath() const {
- return m_impl.m_path.c_str();
-}
-
-void
-NdbDictionary::Undofile::setSize(Uint64 sz){
- m_impl.m_size = sz;
-}
-
-Uint64
-NdbDictionary::Undofile::getSize() const {
- return m_impl.m_size;
-}
-
-void
-NdbDictionary::Undofile::setLogfileGroup(const char * logfileGroup){
- m_impl.m_filegroup_id = ~0;
- m_impl.m_filegroup_version = ~0;
- m_impl.m_filegroup_name.assign(logfileGroup);
-}
-
-void
-NdbDictionary::Undofile::setLogfileGroup
-(const NdbDictionary::LogfileGroup & ts){
- m_impl.m_filegroup_id = NdbLogfileGroupImpl::getImpl(ts).m_id;
- m_impl.m_filegroup_version = ts.getObjectVersion();
- m_impl.m_filegroup_name.assign(ts.getName());
-}
-
-const char *
-NdbDictionary::Undofile::getLogfileGroup() const {
- return m_impl.m_filegroup_name.c_str();
-}
-
-void
-NdbDictionary::Undofile::getLogfileGroupId(NdbDictionary::ObjectId * dst)const
-{
- if (dst)
- {
- NdbDictObjectImpl::getImpl(* dst).m_id = m_impl.m_filegroup_id;
- NdbDictObjectImpl::getImpl(* dst).m_version = m_impl.m_filegroup_version;
- }
-}
-
-NdbDictionary::Object::Status
-NdbDictionary::Undofile::getObjectStatus() const {
- return m_impl.m_status;
-}
-
-int
-NdbDictionary::Undofile::getObjectVersion() const {
- return m_impl.m_version;
-}
-
-int
-NdbDictionary::Undofile::getObjectId() const {
- return m_impl.m_id;
-}
-
-/*****************************************************************
- * Dictionary facade
- */
-NdbDictionary::Dictionary::Dictionary(Ndb & ndb)
- : m_impl(* new NdbDictionaryImpl(ndb, *this))
-{
-}
-
-NdbDictionary::Dictionary::Dictionary(NdbDictionaryImpl & impl)
- : m_impl(impl)
-{
-}
-NdbDictionary::Dictionary::~Dictionary(){
- NdbDictionaryImpl * tmp = &m_impl;
- if(this != tmp){
- delete tmp;
- }
-}
-
-int
-NdbDictionary::Dictionary::createTable(const Table & t)
-{
- DBUG_ENTER("NdbDictionary::Dictionary::createTable");
- DBUG_RETURN(m_impl.createTable(NdbTableImpl::getImpl(t)));
-}
-
-int
-NdbDictionary::Dictionary::dropTable(Table & t){
- return m_impl.dropTable(NdbTableImpl::getImpl(t));
-}
-
-int
-NdbDictionary::Dictionary::dropTableGlobal(const Table & t){
- return m_impl.dropTableGlobal(NdbTableImpl::getImpl(t));
-}
-
-int
-NdbDictionary::Dictionary::dropTable(const char * name){
- return m_impl.dropTable(name);
-}
-
-int
-NdbDictionary::Dictionary::alterTable(const Table & t){
- return m_impl.alterTable(NdbTableImpl::getImpl(t));
-}
-
-int
-NdbDictionary::Dictionary::alterTableGlobal(const Table & f,
- const Table & t)
-{
- return m_impl.alterTableGlobal(NdbTableImpl::getImpl(f),
- NdbTableImpl::getImpl(t));
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getTable(const char * name, void **data) const
-{
- NdbTableImpl * t = m_impl.getTable(name, data);
- if(t)
- return t->m_facade;
- return 0;
-}
-
-const NdbDictionary::Index *
-NdbDictionary::Dictionary::getIndexGlobal(const char * indexName,
- const Table &ndbtab) const
-{
- NdbIndexImpl * i = m_impl.getIndexGlobal(indexName,
- NdbTableImpl::getImpl(ndbtab));
- if(i)
- return i->m_facade;
- return 0;
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getTableGlobal(const char * name) const
-{
- NdbTableImpl * t = m_impl.getTableGlobal(name);
- if(t)
- return t->m_facade;
- return 0;
-}
-
-int
-NdbDictionary::Dictionary::removeIndexGlobal(const Index &ndbidx,
- int invalidate) const
-{
- return m_impl.releaseIndexGlobal(NdbIndexImpl::getImpl(ndbidx), invalidate);
-}
-
-int
-NdbDictionary::Dictionary::removeTableGlobal(const Table &ndbtab,
- int invalidate) const
-{
- return m_impl.releaseTableGlobal(NdbTableImpl::getImpl(ndbtab), invalidate);
-}
-
-void NdbDictionary::Dictionary::putTable(const NdbDictionary::Table * table)
-{
- NdbDictionary::Table *copy_table = new NdbDictionary::Table;
- *copy_table = *table;
- m_impl.putTable(&NdbTableImpl::getImpl(*copy_table));
-}
-
-void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz)
-{
- m_impl.m_local_table_data_size= sz;
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getTable(const char * name) const
-{
- return getTable(name, 0);
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getBlobTable(const NdbDictionary::Table* table,
- const char* col_name)
-{
- const NdbDictionary::Column* col = table->getColumn(col_name);
- if (col == NULL) {
- m_impl.m_error.code = 4318;
- return NULL;
- }
- return getBlobTable(table, col->getColumnNo());
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getBlobTable(const NdbDictionary::Table* table,
- Uint32 col_no)
-{
- return m_impl.getBlobTable(NdbTableImpl::getImpl(*table), col_no);
-}
-
-void
-NdbDictionary::Dictionary::invalidateTable(const char * name){
- DBUG_ENTER("NdbDictionaryImpl::invalidateTable");
- NdbTableImpl * t = m_impl.getTable(name);
- if(t)
- m_impl.invalidateObject(* t);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictionary::Dictionary::invalidateTable(const Table *table){
- NdbTableImpl &t = NdbTableImpl::getImpl(*table);
- m_impl.invalidateObject(t);
-}
-
-void
-NdbDictionary::Dictionary::removeCachedTable(const char * name){
- NdbTableImpl * t = m_impl.getTable(name);
- if(t)
- m_impl.removeCachedObject(* t);
-}
-
-void
-NdbDictionary::Dictionary::removeCachedTable(const Table *table){
- NdbTableImpl &t = NdbTableImpl::getImpl(*table);
- m_impl.removeCachedObject(t);
-}
-
-int
-NdbDictionary::Dictionary::createIndex(const Index & ind)
-{
- return m_impl.createIndex(NdbIndexImpl::getImpl(ind));
-}
-
-int
-NdbDictionary::Dictionary::createIndex(const Index & ind, const Table & tab)
-{
- return m_impl.createIndex(NdbIndexImpl::getImpl(ind),
- NdbTableImpl::getImpl(tab));
-}
-
-int
-NdbDictionary::Dictionary::dropIndex(const char * indexName,
- const char * tableName)
-{
- return m_impl.dropIndex(indexName, tableName);
-}
-
-int
-NdbDictionary::Dictionary::dropIndexGlobal(const Index &ind)
-{
- return m_impl.dropIndexGlobal(NdbIndexImpl::getImpl(ind));
-}
-
-const NdbDictionary::Index *
-NdbDictionary::Dictionary::getIndex(const char * indexName,
- const char * tableName) const
-{
- NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
- if(i)
- return i->m_facade;
- return 0;
-}
-
-void
-NdbDictionary::Dictionary::invalidateIndex(const Index *index){
- DBUG_ENTER("NdbDictionary::Dictionary::invalidateIndex");
- NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
- assert(i.m_table != 0);
- m_impl.invalidateObject(* i.m_table);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictionary::Dictionary::invalidateIndex(const char * indexName,
- const char * tableName){
- DBUG_ENTER("NdbDictionaryImpl::invalidateIndex");
- NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
- if(i) {
- assert(i->m_table != 0);
- m_impl.invalidateObject(* i->m_table);
- }
- DBUG_VOID_RETURN;
-}
-
-int
-NdbDictionary::Dictionary::forceGCPWait()
-{
- return m_impl.forceGCPWait();
-}
-
-void
-NdbDictionary::Dictionary::removeCachedIndex(const Index *index){
- DBUG_ENTER("NdbDictionary::Dictionary::removeCachedIndex");
- NdbIndexImpl &i = NdbIndexImpl::getImpl(*index);
- assert(i.m_table != 0);
- m_impl.removeCachedObject(* i.m_table);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictionary::Dictionary::removeCachedIndex(const char * indexName,
- const char * tableName){
- NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
- if(i) {
- assert(i->m_table != 0);
- m_impl.removeCachedObject(* i->m_table);
- }
-}
-
-const NdbDictionary::Table *
-NdbDictionary::Dictionary::getIndexTable(const char * indexName,
- const char * tableName) const
-{
- NdbIndexImpl * i = m_impl.getIndex(indexName, tableName);
- NdbTableImpl * t = m_impl.getTable(tableName);
- if(i && t) {
- NdbTableImpl * it = m_impl.getIndexTable(i, t);
- return it->m_facade;
- }
- return 0;
-}
-
-
-int
-NdbDictionary::Dictionary::createEvent(const Event & ev)
-{
- return m_impl.createEvent(NdbEventImpl::getImpl(ev));
-}
-
-int
-NdbDictionary::Dictionary::dropEvent(const char * eventName)
-{
- return m_impl.dropEvent(eventName);
-}
-
-const NdbDictionary::Event *
-NdbDictionary::Dictionary::getEvent(const char * eventName)
-{
- NdbEventImpl * t = m_impl.getEvent(eventName);
- if(t)
- return t->m_facade;
- return 0;
-}
-
-int
-NdbDictionary::Dictionary::listObjects(List& list, Object::Type type)
-{
- return m_impl.listObjects(list, type);
-}
-
-int
-NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) const
-{
- return m_impl.listObjects(list, type);
-}
-
-int
-NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName)
-{
- const NdbDictionary::Table* tab= getTable(tableName);
- if(tab == 0)
- {
- return -1;
- }
- return m_impl.listIndexes(list, tab->getTableId());
-}
-
-int
-NdbDictionary::Dictionary::listIndexes(List& list,
- const char * tableName) const
-{
- const NdbDictionary::Table* tab= getTable(tableName);
- if(tab == 0)
- {
- return -1;
- }
- return m_impl.listIndexes(list, tab->getTableId());
-}
-
-int
-NdbDictionary::Dictionary::listIndexes(List& list,
- const NdbDictionary::Table &table) const
-{
- return m_impl.listIndexes(list, table.getTableId());
-}
-
-
-const struct NdbError &
-NdbDictionary::Dictionary::getNdbError() const {
- return m_impl.getNdbError();
-}
-
-// printers
-
-NdbOut&
-operator<<(NdbOut& out, const NdbDictionary::Column& col)
-{
- const CHARSET_INFO *cs = col.getCharset();
- const char *csname = cs ? cs->name : "?";
- out << col.getName() << " ";
- switch (col.getType()) {
- case NdbDictionary::Column::Tinyint:
- out << "Tinyint";
- break;
- case NdbDictionary::Column::Tinyunsigned:
- out << "Tinyunsigned";
- break;
- case NdbDictionary::Column::Smallint:
- out << "Smallint";
- break;
- case NdbDictionary::Column::Smallunsigned:
- out << "Smallunsigned";
- break;
- case NdbDictionary::Column::Mediumint:
- out << "Mediumint";
- break;
- case NdbDictionary::Column::Mediumunsigned:
- out << "Mediumunsigned";
- break;
- case NdbDictionary::Column::Int:
- out << "Int";
- break;
- case NdbDictionary::Column::Unsigned:
- out << "Unsigned";
- break;
- case NdbDictionary::Column::Bigint:
- out << "Bigint";
- break;
- case NdbDictionary::Column::Bigunsigned:
- out << "Bigunsigned";
- break;
- case NdbDictionary::Column::Float:
- out << "Float";
- break;
- case NdbDictionary::Column::Double:
- out << "Double";
- break;
- case NdbDictionary::Column::Olddecimal:
- out << "Olddecimal(" << col.getPrecision() << "," << col.getScale() << ")";
- break;
- case NdbDictionary::Column::Olddecimalunsigned:
- out << "Olddecimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
- break;
- case NdbDictionary::Column::Decimal:
- out << "Decimal(" << col.getPrecision() << "," << col.getScale() << ")";
- break;
- case NdbDictionary::Column::Decimalunsigned:
- out << "Decimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")";
- break;
- case NdbDictionary::Column::Char:
- out << "Char(" << col.getLength() << ";" << csname << ")";
- break;
- case NdbDictionary::Column::Varchar:
- out << "Varchar(" << col.getLength() << ";" << csname << ")";
- break;
- case NdbDictionary::Column::Binary:
- out << "Binary(" << col.getLength() << ")";
- break;
- case NdbDictionary::Column::Varbinary:
- out << "Varbinary(" << col.getLength() << ")";
- break;
- case NdbDictionary::Column::Datetime:
- out << "Datetime";
- break;
- case NdbDictionary::Column::Date:
- out << "Date";
- break;
- case NdbDictionary::Column::Blob:
- out << "Blob(" << col.getInlineSize() << "," << col.getPartSize()
- << ";" << col.getStripeSize() << ")";
- break;
- case NdbDictionary::Column::Text:
- out << "Text(" << col.getInlineSize() << "," << col.getPartSize()
- << ";" << col.getStripeSize() << ";" << csname << ")";
- break;
- case NdbDictionary::Column::Time:
- out << "Time";
- break;
- case NdbDictionary::Column::Year:
- out << "Year";
- break;
- case NdbDictionary::Column::Timestamp:
- out << "Timestamp";
- break;
- case NdbDictionary::Column::Undefined:
- out << "Undefined";
- break;
- case NdbDictionary::Column::Bit:
- out << "Bit(" << col.getLength() << ")";
- break;
- case NdbDictionary::Column::Longvarchar:
- out << "Longvarchar(" << col.getLength() << ";" << csname << ")";
- break;
- case NdbDictionary::Column::Longvarbinary:
- out << "Longvarbinary(" << col.getLength() << ")";
- break;
- default:
- out << "Type" << (Uint32)col.getType();
- break;
- }
- // show unusual (non-MySQL) array size
- if (col.getLength() != 1) {
- switch (col.getType()) {
- case NdbDictionary::Column::Char:
- case NdbDictionary::Column::Varchar:
- case NdbDictionary::Column::Binary:
- case NdbDictionary::Column::Varbinary:
- case NdbDictionary::Column::Blob:
- case NdbDictionary::Column::Text:
- case NdbDictionary::Column::Bit:
- case NdbDictionary::Column::Longvarchar:
- case NdbDictionary::Column::Longvarbinary:
- break;
- default:
- out << " [" << col.getLength() << "]";
- break;
- }
- }
-
- if (col.getPrimaryKey())
- out << " PRIMARY KEY";
- else if (! col.getNullable())
- out << " NOT NULL";
- else
- out << " NULL";
-
- if(col.getDistributionKey())
- out << " DISTRIBUTION KEY";
-
- switch (col.getArrayType()) {
- case NDB_ARRAYTYPE_FIXED:
- out << " AT=FIXED";
- break;
- case NDB_ARRAYTYPE_SHORT_VAR:
- out << " AT=SHORT_VAR";
- break;
- case NDB_ARRAYTYPE_MEDIUM_VAR:
- out << " AT=MEDIUM_VAR";
- break;
- default:
- out << " AT=" << (int)col.getArrayType() << "?";
- break;
- }
-
- switch (col.getStorageType()) {
- case NDB_STORAGETYPE_MEMORY:
- out << " ST=MEMORY";
- break;
- case NDB_STORAGETYPE_DISK:
- out << " ST=DISK";
- break;
- default:
- out << " ST=" << (int)col.getStorageType() << "?";
- break;
- }
-
- return out;
-}
-
-int
-NdbDictionary::Dictionary::createLogfileGroup(const LogfileGroup & lg,
- ObjectId * obj)
-{
- return m_impl.createLogfileGroup(NdbLogfileGroupImpl::getImpl(lg),
- obj ?
- & NdbDictObjectImpl::getImpl(* obj) : 0);
-}
-
-int
-NdbDictionary::Dictionary::dropLogfileGroup(const LogfileGroup & lg)
-{
- return m_impl.dropLogfileGroup(NdbLogfileGroupImpl::getImpl(lg));
-}
-
-NdbDictionary::LogfileGroup
-NdbDictionary::Dictionary::getLogfileGroup(const char * name)
-{
- NdbDictionary::LogfileGroup tmp;
- m_impl.m_receiver.get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
- NdbDictionary::Object::LogfileGroup, name);
- return tmp;
-}
-
-int
-NdbDictionary::Dictionary::createTablespace(const Tablespace & lg,
- ObjectId * obj)
-{
- return m_impl.createTablespace(NdbTablespaceImpl::getImpl(lg),
- obj ?
- & NdbDictObjectImpl::getImpl(* obj) : 0);
-}
-
-int
-NdbDictionary::Dictionary::dropTablespace(const Tablespace & lg)
-{
- return m_impl.dropTablespace(NdbTablespaceImpl::getImpl(lg));
-}
-
-NdbDictionary::Tablespace
-NdbDictionary::Dictionary::getTablespace(const char * name)
-{
- NdbDictionary::Tablespace tmp;
- m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
- NdbDictionary::Object::Tablespace, name);
- return tmp;
-}
-
-NdbDictionary::Tablespace
-NdbDictionary::Dictionary::getTablespace(Uint32 tablespaceId)
-{
- NdbDictionary::Tablespace tmp;
- m_impl.m_receiver.get_filegroup(NdbTablespaceImpl::getImpl(tmp),
- NdbDictionary::Object::Tablespace,
- tablespaceId);
- return tmp;
-}
-
-int
-NdbDictionary::Dictionary::createDatafile(const Datafile & df,
- bool force,
- ObjectId * obj)
-{
- return m_impl.createDatafile(NdbDatafileImpl::getImpl(df),
- force,
- obj ? & NdbDictObjectImpl::getImpl(* obj) : 0);
-}
-
-int
-NdbDictionary::Dictionary::dropDatafile(const Datafile& df)
-{
- return m_impl.dropDatafile(NdbDatafileImpl::getImpl(df));
-}
-
-NdbDictionary::Datafile
-NdbDictionary::Dictionary::getDatafile(Uint32 node, const char * path)
-{
- NdbDictionary::Datafile tmp;
- m_impl.m_receiver.get_file(NdbDatafileImpl::getImpl(tmp),
- NdbDictionary::Object::Datafile,
- node ? (int)node : -1, path);
- return tmp;
-}
-
-int
-NdbDictionary::Dictionary::createUndofile(const Undofile & df,
- bool force,
- ObjectId * obj)
-{
- return m_impl.createUndofile(NdbUndofileImpl::getImpl(df),
- force,
- obj ? & NdbDictObjectImpl::getImpl(* obj) : 0);
-}
-
-int
-NdbDictionary::Dictionary::dropUndofile(const Undofile& df)
-{
- return m_impl.dropUndofile(NdbUndofileImpl::getImpl(df));
-}
-
-NdbDictionary::Undofile
-NdbDictionary::Dictionary::getUndofile(Uint32 node, const char * path)
-{
- NdbDictionary::Undofile tmp;
- m_impl.m_receiver.get_file(NdbUndofileImpl::getImpl(tmp),
- NdbDictionary::Object::Undofile,
- node ? (int)node : -1, path);
- return tmp;
-}
-
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
deleted file mode 100644
index d9b00a68f6b..00000000000
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ /dev/null
@@ -1,5319 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "NdbDictionaryImpl.hpp"
-#include "API.hpp"
-#include <NdbOut.hpp>
-#include "NdbApiSignal.hpp"
-#include "TransporterFacade.hpp"
-#include <signaldata/GetTabInfo.hpp>
-#include <signaldata/DictTabInfo.hpp>
-#include <signaldata/CreateTable.hpp>
-#include <signaldata/CreateIndx.hpp>
-#include <signaldata/CreateEvnt.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <signaldata/DropTable.hpp>
-#include <signaldata/AlterTable.hpp>
-#include <signaldata/DropIndx.hpp>
-#include <signaldata/ListTables.hpp>
-#include <signaldata/DropFilegroup.hpp>
-#include <signaldata/CreateFilegroup.hpp>
-#include <signaldata/WaitGCP.hpp>
-#include <SimpleProperties.hpp>
-#include <Bitmask.hpp>
-#include <AttributeList.hpp>
-#include <NdbEventOperation.hpp>
-#include "NdbEventOperationImpl.hpp"
-#include <NdbBlob.hpp>
-#include "NdbBlobImpl.hpp"
-#include <AttributeHeader.hpp>
-#include <my_sys.h>
-#include <NdbEnv.h>
-#include <NdbMem.h>
-#include <util/version.h>
-#include <NdbSleep.h>
-
-#define DEBUG_PRINT 0
-#define INCOMPATIBLE_VERSION -2
-
-#define DICT_WAITFOR_TIMEOUT (7*24*60*60*1000)
-
-#define ERR_RETURN(a,b) \
-{\
- DBUG_PRINT("exit", ("error %d return %d", (a).code, b));\
- DBUG_RETURN(b);\
-}
-
-int ndb_dictionary_is_mysqld = 0;
-
-bool
-is_ndb_blob_table(const char* name, Uint32* ptab_id, Uint32* pcol_no)
-{
- return DictTabInfo::isBlobTableName(name, ptab_id, pcol_no);
-}
-
-bool
-is_ndb_blob_table(const NdbTableImpl* t)
-{
- return is_ndb_blob_table(t->m_internalName.c_str());
-}
-
-//#define EVENT_DEBUG
-
-/**
- * Column
- */
-NdbColumnImpl::NdbColumnImpl()
- : NdbDictionary::Column(* this), m_attrId(-1), m_facade(this)
-{
- DBUG_ENTER("NdbColumnImpl::NdbColumnImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
- : NdbDictionary::Column(* this), m_attrId(-1), m_facade(&f)
-{
- DBUG_ENTER("NdbColumnImpl::NdbColumnImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-NdbColumnImpl&
-NdbColumnImpl::operator=(const NdbColumnImpl& col)
-{
- DBUG_ENTER("NdbColumnImpl::operator=");
- DBUG_PRINT("info", ("this: %p &col: %p", this, &col));
- m_attrId = col.m_attrId;
- m_name = col.m_name;
- m_type = col.m_type;
- m_precision = col.m_precision;
- m_cs = col.m_cs;
- m_scale = col.m_scale;
- m_length = col.m_length;
- m_pk = col.m_pk;
- m_distributionKey = col.m_distributionKey;
- m_nullable = col.m_nullable;
- m_autoIncrement = col.m_autoIncrement;
- m_autoIncrementInitialValue = col.m_autoIncrementInitialValue;
- m_defaultValue = col.m_defaultValue;
- m_attrSize = col.m_attrSize;
- m_arraySize = col.m_arraySize;
- m_arrayType = col.m_arrayType;
- m_storageType = col.m_storageType;
- m_keyInfoPos = col.m_keyInfoPos;
- if (col.m_blobTable == NULL)
- m_blobTable = NULL;
- else {
- if (m_blobTable == NULL)
- m_blobTable = new NdbTableImpl();
- m_blobTable->assign(*col.m_blobTable);
- }
- m_column_no = col.m_column_no;
- // Do not copy m_facade !!
-
- DBUG_RETURN(*this);
-}
-
-void
-NdbColumnImpl::init(Type t)
-{
- // do not use default_charset_info as it may not be initialized yet
- // use binary collation until NDB tests can handle charsets
- CHARSET_INFO* default_cs = &my_charset_bin;
- m_type = t;
- switch (m_type) {
- case Tinyint:
- case Tinyunsigned:
- case Smallint:
- case Smallunsigned:
- case Mediumint:
- case Mediumunsigned:
- case Int:
- case Unsigned:
- case Bigint:
- case Bigunsigned:
- case Float:
- case Double:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Olddecimal:
- case Olddecimalunsigned:
- case Decimal:
- case Decimalunsigned:
- m_precision = 10;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Char:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = default_cs;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Varchar:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = default_cs;
- m_arrayType = NDB_ARRAYTYPE_SHORT_VAR;
- break;
- case Binary:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Varbinary:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_SHORT_VAR;
- break;
- case Datetime:
- case Date:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Blob:
- m_precision = 256;
- m_scale = 8000;
- m_length = 4;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Text:
- m_precision = 256;
- m_scale = 8000;
- m_length = 4;
- m_cs = default_cs;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Time:
- case Year:
- case Timestamp:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Bit:
- m_precision = 0;
- m_scale = 0;
- m_length = 1;
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_FIXED;
- break;
- case Longvarchar:
- m_precision = 0;
- m_scale = 0;
- m_length = 1; // legal
- m_cs = default_cs;
- m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
- break;
- case Longvarbinary:
- m_precision = 0;
- m_scale = 0;
- m_length = 1; // legal
- m_cs = NULL;
- m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
- break;
- default:
- case Undefined:
- assert(false);
- break;
- }
- m_pk = false;
- m_nullable = false;
- m_distributionKey = false;
- m_keyInfoPos = 0;
- // next 2 are set at run time
- m_attrSize = 0;
- m_arraySize = 0;
- m_autoIncrement = false;
- m_autoIncrementInitialValue = 1;
- m_blobTable = NULL;
- m_storageType = NDB_STORAGETYPE_MEMORY;
-#ifdef VM_TRACE
- if(NdbEnv_GetEnv("NDB_DEFAULT_DISK", (char *)0, 0))
- m_storageType = NDB_STORAGETYPE_DISK;
-#endif
-}
-
-NdbColumnImpl::~NdbColumnImpl()
-{
- DBUG_ENTER("NdbColumnImpl::~NdbColumnImpl");
- DBUG_PRINT("info", ("this: %p", this));
- if (m_blobTable != NULL)
- delete m_blobTable;
- m_blobTable = NULL;
- DBUG_VOID_RETURN;
-}
-
-bool
-NdbColumnImpl::equal(const NdbColumnImpl& col) const
-{
- DBUG_ENTER("NdbColumnImpl::equal");
- DBUG_PRINT("info", ("this: %p &col: %p", this, &col));
- if(strcmp(m_name.c_str(), col.m_name.c_str()) != 0){
- DBUG_RETURN(false);
- }
- if(m_type != col.m_type){
- DBUG_RETURN(false);
- }
- if(m_pk != col.m_pk){
- DBUG_RETURN(false);
- }
- if(m_nullable != col.m_nullable){
- DBUG_RETURN(false);
- }
- if (m_pk) {
- if (m_distributionKey != col.m_distributionKey) {
- DBUG_RETURN(false);
- }
- }
- if (m_precision != col.m_precision ||
- m_scale != col.m_scale ||
- m_length != col.m_length ||
- m_cs != col.m_cs) {
- DBUG_RETURN(false);
- }
- if (m_autoIncrement != col.m_autoIncrement){
- DBUG_RETURN(false);
- }
- if(strcmp(m_defaultValue.c_str(), col.m_defaultValue.c_str()) != 0){
- DBUG_RETURN(false);
- }
-
- if (m_arrayType != col.m_arrayType || m_storageType != col.m_storageType){
- DBUG_RETURN(false);
- }
-
- DBUG_RETURN(true);
-}
-
-NdbDictionary::Column *
-NdbColumnImpl::create_pseudo(const char * name){
- NdbDictionary::Column * col = new NdbDictionary::Column();
- col->setName(name);
- if(!strcmp(name, "NDB$FRAGMENT")){
- col->setType(NdbDictionary::Column::Unsigned);
- col->m_impl.m_attrId = AttributeHeader::FRAGMENT;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$FRAGMENT_FIXED_MEMORY")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::FRAGMENT_FIXED_MEMORY;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$FRAGMENT_VARSIZED_MEMORY")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::FRAGMENT_VARSIZED_MEMORY;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$ROW_COUNT")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::ROW_COUNT;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$COMMIT_COUNT")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$ROW_SIZE")){
- col->setType(NdbDictionary::Column::Unsigned);
- col->m_impl.m_attrId = AttributeHeader::ROW_SIZE;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$RANGE_NO")){
- col->setType(NdbDictionary::Column::Unsigned);
- col->m_impl.m_attrId = AttributeHeader::RANGE_NO;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$DISK_REF")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::DISK_REF;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$RECORDS_IN_RANGE")){
- col->setType(NdbDictionary::Column::Unsigned);
- col->m_impl.m_attrId = AttributeHeader::RECORDS_IN_RANGE;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 4;
- } else if(!strcmp(name, "NDB$ROWID")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::ROWID;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 2;
- } else if(!strcmp(name, "NDB$ROW_GCI")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::ROW_GCI;
- col->m_impl.m_attrSize = 8;
- col->m_impl.m_arraySize = 1;
- col->m_impl.m_nullable = true;
- } else if(!strcmp(name, "NDB$ANY_VALUE")){
- col->setType(NdbDictionary::Column::Unsigned);
- col->m_impl.m_attrId = AttributeHeader::ANY_VALUE;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$COPY_ROWID")){
- col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::COPY_ROWID;
- col->m_impl.m_attrSize = 4;
- col->m_impl.m_arraySize = 2;
- } else {
- abort();
- }
- col->m_impl.m_storageType = NDB_STORAGETYPE_MEMORY;
- return col;
-}
-
-/**
- * NdbTableImpl
- */
-
-NdbTableImpl::NdbTableImpl()
- : NdbDictionary::Table(* this),
- NdbDictObjectImpl(NdbDictionary::Object::UserTable), m_facade(this)
-{
- DBUG_ENTER("NdbTableImpl::NdbTableImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-NdbTableImpl::NdbTableImpl(NdbDictionary::Table & f)
- : NdbDictionary::Table(* this),
- NdbDictObjectImpl(NdbDictionary::Object::UserTable), m_facade(&f)
-{
- DBUG_ENTER("NdbTableImpl::NdbTableImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-NdbTableImpl::~NdbTableImpl()
-{
- DBUG_ENTER("NdbTableImpl::~NdbTableImpl");
- DBUG_PRINT("info", ("this: %p", this));
- if (m_index != 0) {
- delete m_index;
- m_index = 0;
- }
- for (unsigned i = 0; i < m_columns.size(); i++)
- delete m_columns[i];
- DBUG_VOID_RETURN;
-}
-
-void
-NdbTableImpl::init(){
- m_changeMask= 0;
- m_id= RNIL;
- m_version = ~0;
- m_status = NdbDictionary::Object::Invalid;
- m_type = NdbDictionary::Object::TypeUndefined;
- m_primaryTableId= RNIL;
- m_internalName.clear();
- m_externalName.clear();
- m_newExternalName.clear();
- m_mysqlName.clear();
- m_frm.clear();
- m_newFrm.clear();
- m_ts_name.clear();
- m_new_ts_name.clear();
- m_ts.clear();
- m_new_ts.clear();
- m_fd.clear();
- m_new_fd.clear();
- m_range.clear();
- m_new_range.clear();
- m_fragmentType= NdbDictionary::Object::FragAllSmall;
- m_hashValueMask= 0;
- m_hashpointerValue= 0;
- m_linear_flag= true;
- m_primaryTable.clear();
- m_default_no_part_flag = 1;
- m_logging= true;
- m_temporary = false;
- m_row_gci = true;
- m_row_checksum = true;
- m_force_var_part = false;
- m_kvalue= 6;
- m_minLoadFactor= 78;
- m_maxLoadFactor= 80;
- m_keyLenInWords= 0;
- m_fragmentCount= 0;
- m_index= NULL;
- m_indexType= NdbDictionary::Object::TypeUndefined;
- m_noOfKeys= 0;
- m_noOfDistributionKeys= 0;
- m_noOfBlobs= 0;
- m_replicaCount= 0;
- m_min_rows = 0;
- m_max_rows = 0;
- m_tablespace_name.clear();
- m_tablespace_id = ~0;
- m_tablespace_version = ~0;
- m_single_user_mode = 0;
-}
-
-bool
-NdbTableImpl::equal(const NdbTableImpl& obj) const
-{
- DBUG_ENTER("NdbTableImpl::equal");
- if ((m_internalName.c_str() == NULL) ||
- (strcmp(m_internalName.c_str(), "") == 0) ||
- (obj.m_internalName.c_str() == NULL) ||
- (strcmp(obj.m_internalName.c_str(), "") == 0))
- {
- // Shallow equal
- if(strcmp(getName(), obj.getName()) != 0)
- {
- DBUG_PRINT("info",("name %s != %s",getName(),obj.getName()));
- DBUG_RETURN(false);
- }
- }
- else
- {
- // Deep equal
- if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0)
- {
- DBUG_PRINT("info",("m_internalName %s != %s",
- m_internalName.c_str(),obj.m_internalName.c_str()));
- DBUG_RETURN(false);
- }
- }
- if (m_frm.length() != obj.m_frm.length() ||
- (memcmp(m_frm.get_data(), obj.m_frm.get_data(), m_frm.length())))
- {
- DBUG_PRINT("info",("m_frm not equal"));
- DBUG_RETURN(false);
- }
- if (m_fd.length() != obj.m_fd.length() ||
- (memcmp(m_fd.get_data(), obj.m_fd.get_data(), m_fd.length())))
- {
- DBUG_PRINT("info",("m_fd not equal"));
- DBUG_RETURN(false);
- }
- if (m_ts.length() != obj.m_ts.length() ||
- (memcmp(m_ts.get_data(), obj.m_ts.get_data(), m_ts.length())))
- {
- DBUG_PRINT("info",("m_ts not equal"));
- DBUG_RETURN(false);
- }
- if (m_range.length() != obj.m_range.length() ||
- (memcmp(m_range.get_data(), obj.m_range.get_data(), m_range.length())))
- {
- DBUG_PRINT("info",("m_range not equal"));
- DBUG_RETURN(false);
- }
- if(m_fragmentType != obj.m_fragmentType)
- {
- DBUG_PRINT("info",("m_fragmentType %d != %d",m_fragmentType,
- obj.m_fragmentType));
- DBUG_RETURN(false);
- }
- if(m_columns.size() != obj.m_columns.size())
- {
- DBUG_PRINT("info",("m_columns.size %d != %d",m_columns.size(),
- obj.m_columns.size()));
- DBUG_RETURN(false);
- }
-
- for(unsigned i = 0; i<obj.m_columns.size(); i++)
- {
- if(!m_columns[i]->equal(* obj.m_columns[i]))
- {
- DBUG_PRINT("info",("m_columns [%d] != [%d]",i,i));
- DBUG_RETURN(false);
- }
- }
-
- if(m_linear_flag != obj.m_linear_flag)
- {
- DBUG_PRINT("info",("m_linear_flag %d != %d",m_linear_flag,
- obj.m_linear_flag));
- DBUG_RETURN(false);
- }
-
- if(m_max_rows != obj.m_max_rows)
- {
- DBUG_PRINT("info",("m_max_rows %d != %d",(int32)m_max_rows,
- (int32)obj.m_max_rows));
- DBUG_RETURN(false);
- }
-
- if(m_default_no_part_flag != obj.m_default_no_part_flag)
- {
- DBUG_PRINT("info",("m_default_no_part_flag %d != %d",m_default_no_part_flag,
- obj.m_default_no_part_flag));
- DBUG_RETURN(false);
- }
-
- if(m_logging != obj.m_logging)
- {
- DBUG_PRINT("info",("m_logging %d != %d",m_logging,obj.m_logging));
- DBUG_RETURN(false);
- }
-
- if(m_temporary != obj.m_temporary)
- {
- DBUG_PRINT("info",("m_temporary %d != %d",m_temporary,obj.m_temporary));
- DBUG_RETURN(false);
- }
-
- if(m_row_gci != obj.m_row_gci)
- {
- DBUG_PRINT("info",("m_row_gci %d != %d",m_row_gci,obj.m_row_gci));
- DBUG_RETURN(false);
- }
-
- if(m_row_checksum != obj.m_row_checksum)
- {
- DBUG_PRINT("info",("m_row_checksum %d != %d",m_row_checksum,
- obj.m_row_checksum));
- DBUG_RETURN(false);
- }
-
- if(m_kvalue != obj.m_kvalue)
- {
- DBUG_PRINT("info",("m_kvalue %d != %d",m_kvalue,obj.m_kvalue));
- DBUG_RETURN(false);
- }
-
- if(m_minLoadFactor != obj.m_minLoadFactor)
- {
- DBUG_PRINT("info",("m_minLoadFactor %d != %d",m_minLoadFactor,
- obj.m_minLoadFactor));
- DBUG_RETURN(false);
- }
-
- if(m_maxLoadFactor != obj.m_maxLoadFactor)
- {
- DBUG_PRINT("info",("m_maxLoadFactor %d != %d",m_maxLoadFactor,
- obj.m_maxLoadFactor));
- DBUG_RETURN(false);
- }
-
- if(m_tablespace_id != obj.m_tablespace_id)
- {
- DBUG_PRINT("info",("m_tablespace_id %d != %d",m_tablespace_id,
- obj.m_tablespace_id));
- DBUG_RETURN(false);
- }
-
- if(m_tablespace_version != obj.m_tablespace_version)
- {
- DBUG_PRINT("info",("m_tablespace_version %d != %d",m_tablespace_version,
- obj.m_tablespace_version));
- DBUG_RETURN(false);
- }
-
- if(m_id != obj.m_id)
- {
- DBUG_PRINT("info",("m_id %d != %d",m_id,obj.m_id));
- DBUG_RETURN(false);
- }
-
- if(m_version != obj.m_version)
- {
- DBUG_PRINT("info",("m_version %d != %d",m_version,obj.m_version));
- DBUG_RETURN(false);
- }
-
- if(m_type != obj.m_type)
- {
- DBUG_PRINT("info",("m_type %d != %d",m_type,obj.m_type));
- DBUG_RETURN(false);
- }
-
- if (m_type == NdbDictionary::Object::UniqueHashIndex ||
- m_type == NdbDictionary::Object::OrderedIndex)
- {
- if(m_primaryTableId != obj.m_primaryTableId)
- {
- DBUG_PRINT("info",("m_primaryTableId %d != %d",m_primaryTableId,
- obj.m_primaryTableId));
- DBUG_RETURN(false);
- }
- if (m_indexType != obj.m_indexType)
- {
- DBUG_PRINT("info",("m_indexType %d != %d",m_indexType,obj.m_indexType));
- DBUG_RETURN(false);
- }
- if(strcmp(m_primaryTable.c_str(), obj.m_primaryTable.c_str()) != 0)
- {
- DBUG_PRINT("info",("m_primaryTable %s != %s",
- m_primaryTable.c_str(),obj.m_primaryTable.c_str()));
- DBUG_RETURN(false);
- }
- }
-
- if(m_single_user_mode != obj.m_single_user_mode)
- {
- DBUG_PRINT("info",("m_single_user_mode %d != %d",
- (int32)m_single_user_mode,
- (int32)obj.m_single_user_mode));
- DBUG_RETURN(false);
- }
-
- DBUG_RETURN(true);
-}
-
-int
-NdbTableImpl::assign(const NdbTableImpl& org)
-{
- DBUG_ENTER("NdbColumnImpl::assign");
- DBUG_PRINT("info", ("this: %p &org: %p", this, &org));
- /* m_changeMask intentionally not copied */
- m_primaryTableId = org.m_primaryTableId;
- if (!m_internalName.assign(org.m_internalName) ||
- updateMysqlName())
- {
- return -1;
- }
- // If the name has been explicitly set, use that name
- // otherwise use the fetched name
- if (!org.m_newExternalName.empty())
- m_externalName.assign(org.m_newExternalName);
- else
- m_externalName.assign(org.m_externalName);
- m_frm.assign(org.m_frm.get_data(), org.m_frm.length());
- m_ts_name.assign(org.m_ts_name.get_data(), org.m_ts_name.length());
- m_new_ts_name.assign(org.m_new_ts_name.get_data(),
- org.m_new_ts_name.length());
- m_ts.assign(org.m_ts.get_data(), org.m_ts.length());
- m_new_ts.assign(org.m_new_ts.get_data(), org.m_new_ts.length());
- m_fd.assign(org.m_fd.get_data(), org.m_fd.length());
- m_new_fd.assign(org.m_new_fd.get_data(), org.m_new_fd.length());
- m_range.assign(org.m_range.get_data(), org.m_range.length());
- m_new_range.assign(org.m_new_range.get_data(), org.m_new_range.length());
-
- m_fragmentType = org.m_fragmentType;
- /*
- m_columnHashMask, m_columnHash, m_hashValueMask, m_hashpointerValue
- is state calculated by computeAggregates and buildColumnHash
- */
- unsigned i;
- for(i = 0; i < m_columns.size(); i++)
- {
- delete m_columns[i];
- }
- m_columns.clear();
- for(i = 0; i < org.m_columns.size(); i++)
- {
- NdbColumnImpl * col = new NdbColumnImpl();
- if (col == NULL)
- {
- errno = ENOMEM;
- return -1;
- }
- const NdbColumnImpl * iorg = org.m_columns[i];
- (* col) = (* iorg);
- if (m_columns.push_back(col))
- {
- delete col;
- return -1;
- }
- }
-
- m_fragments = org.m_fragments;
-
- m_linear_flag = org.m_linear_flag;
- m_max_rows = org.m_max_rows;
- m_default_no_part_flag = org.m_default_no_part_flag;
- m_logging = org.m_logging;
- m_temporary = org.m_temporary;
- m_row_gci = org.m_row_gci;
- m_row_checksum = org.m_row_checksum;
- m_force_var_part = org.m_force_var_part;
- m_kvalue = org.m_kvalue;
- m_minLoadFactor = org.m_minLoadFactor;
- m_maxLoadFactor = org.m_maxLoadFactor;
- m_keyLenInWords = org.m_keyLenInWords;
- m_fragmentCount = org.m_fragmentCount;
-
- m_single_user_mode = org.m_single_user_mode;
-
- if (m_index != 0)
- delete m_index;
- m_index = org.m_index;
-
- m_primaryTable = org.m_primaryTable;
- m_indexType = org.m_indexType;
-
- m_noOfKeys = org.m_noOfKeys;
- m_noOfDistributionKeys = org.m_noOfDistributionKeys;
- m_noOfBlobs = org.m_noOfBlobs;
- m_replicaCount = org.m_replicaCount;
-
- m_id = org.m_id;
- m_version = org.m_version;
- m_status = org.m_status;
-
- m_max_rows = org.m_max_rows;
- m_min_rows = org.m_min_rows;
-
- m_tablespace_name = org.m_tablespace_name;
- m_tablespace_id= org.m_tablespace_id;
- m_tablespace_version = org.m_tablespace_version;
- DBUG_RETURN(0);
-}
-
-int NdbTableImpl::setName(const char * name)
-{
- return !m_newExternalName.assign(name);
-}
-
-const char *
-NdbTableImpl::getName() const
-{
- if (m_newExternalName.empty())
- return m_externalName.c_str();
- else
- return m_newExternalName.c_str();
-}
-
-void
-NdbTableImpl::computeAggregates()
-{
- m_noOfKeys = 0;
- m_keyLenInWords = 0;
- m_noOfDistributionKeys = 0;
- m_noOfBlobs = 0;
- m_noOfDiskColumns = 0;
- Uint32 i, n;
- for (i = 0; i < m_columns.size(); i++) {
- NdbColumnImpl* col = m_columns[i];
- if (col->m_pk) {
- m_noOfKeys++;
- m_keyLenInWords += (col->m_attrSize * col->m_arraySize + 3) / 4;
- }
- if (col->m_distributionKey)
- m_noOfDistributionKeys++; // XXX check PK
-
- if (col->getBlobType())
- m_noOfBlobs++;
-
- if (col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
- m_noOfDiskColumns++;
-
- col->m_keyInfoPos = ~0;
- }
- if (m_noOfDistributionKeys == m_noOfKeys) {
- // all is none!
- m_noOfDistributionKeys = 0;
- }
-
- if (m_noOfDistributionKeys == 0)
- {
- // none is all!
- for (i = 0, n = m_noOfKeys; n != 0; i++) {
- NdbColumnImpl* col = m_columns[i];
- if (col->m_pk) {
- col->m_distributionKey = true;
- n--;
- }
- }
- }
-
- Uint32 keyInfoPos = 0;
- for (i = 0, n = m_noOfKeys; n != 0; i++) {
- NdbColumnImpl* col = m_columns[i];
- if (col->m_pk) {
- col->m_keyInfoPos = keyInfoPos++;
- n--;
- }
- }
-}
-
-// TODO add error checks
-// TODO use these internally at create and retrieve
-int
-NdbTableImpl::aggregate(NdbError& error)
-{
- computeAggregates();
- return 0;
-}
-int
-NdbTableImpl::validate(NdbError& error)
-{
- if (aggregate(error) == -1)
- return -1;
- return 0;
-}
-
-const void*
-NdbTableImpl::getTablespaceNames() const
-{
- if (m_new_ts_name.empty())
- return m_ts_name.get_data();
- else
- return m_new_ts_name.get_data();
-}
-
-Uint32
-NdbTableImpl::getTablespaceNamesLen() const
-{
- if (m_new_ts_name.empty())
- return m_ts_name.length();
- else
- return m_new_ts_name.length();
-}
-
-int NdbTableImpl::setTablespaceNames(const void *data, Uint32 len)
-{
- return !m_new_ts_name.assign(data, len);
-}
-
-void NdbTableImpl::setFragmentCount(Uint32 count)
-{
- m_fragmentCount= count;
-}
-
-Uint32 NdbTableImpl::getFragmentCount() const
-{
- return m_fragmentCount;
-}
-
-int NdbTableImpl::setFrm(const void* data, Uint32 len)
-{
- return m_newFrm.assign(data, len);
-}
-
-const void *
-NdbTableImpl::getFrmData() const
-{
- if (m_newFrm.empty())
- return m_frm.get_data();
- else
- return m_newFrm.get_data();
-}
-
-Uint32
-NdbTableImpl::getFrmLength() const
-{
- if (m_newFrm.empty())
- return m_frm.length();
- else
- return m_newFrm.length();
-}
-
-int NdbTableImpl::setFragmentData(const void* data, Uint32 len)
-{
- return m_new_fd.assign(data, len);
-}
-
-const void *
-NdbTableImpl::getFragmentData() const
-{
- if (m_new_fd.empty())
- return m_fd.get_data();
- else
- return m_new_fd.get_data();
-}
-
-Uint32
-NdbTableImpl::getFragmentDataLen() const
-{
- if (m_new_fd.empty())
- return m_fd.length();
- else
- return m_new_fd.length();
-}
-
-int NdbTableImpl::setTablespaceData(const void* data, Uint32 len)
-{
- return !m_new_ts.assign(data, len);
-}
-
-const void *
-NdbTableImpl::getTablespaceData() const
-{
- if (m_new_ts.empty())
- return m_ts.get_data();
- else
- return m_new_ts.get_data();
-}
-
-Uint32
-NdbTableImpl::getTablespaceDataLen() const
-{
- if (m_new_ts.empty())
- return m_ts.length();
- else
- return m_new_ts.length();
-}
-
-int NdbTableImpl::setRangeListData(const void* data, Uint32 len)
-{
- return m_new_range.assign(data, len);
-}
-
-const void *
-NdbTableImpl::getRangeListData() const
-{
- if (m_new_range.empty())
- return m_range.get_data();
- else
- return m_new_range.get_data();
-}
-
-Uint32
-NdbTableImpl::getRangeListDataLen() const
-{
- if (m_new_range.empty())
- return m_range.length();
- else
- return m_new_range.length();
-}
-
-int
-NdbTableImpl::updateMysqlName()
-{
- Vector<BaseString> v;
- if (m_internalName.split(v,"/") == 3)
- {
- return !m_mysqlName.assfmt("%s/%s",v[0].c_str(),v[2].c_str());
- }
- return !m_mysqlName.assign("");
-}
-
-int
-NdbTableImpl::buildColumnHash(){
- const Uint32 size = m_columns.size();
- int i;
- for(i = 31; i >= 0; i--){
- if(((1 << i) & size) != 0){
- m_columnHashMask = (1 << (i + 1)) - 1;
- break;
- }
- }
-
- Vector<Uint32> hashValues;
- Vector<Vector<Uint32> > chains;
- if (chains.fill(size, hashValues))
- {
- return -1;
- }
- for(i = 0; i< (int) size; i++){
- Uint32 hv = Hash(m_columns[i]->getName()) & 0xFFFE;
- Uint32 bucket = hv & m_columnHashMask;
- bucket = (bucket < size ? bucket : bucket - size);
- assert(bucket < size);
- if (hashValues.push_back(hv) ||
- chains[bucket].push_back(i))
- {
- return -1;
- }
- }
-
- m_columnHash.clear();
- Uint32 tmp = 1;
- if (m_columnHash.fill((unsigned)size-1, tmp)) // Default no chaining
- {
- return -1;
- }
-
- Uint32 pos = 0; // In overflow vector
- for(i = 0; i< (int) size; i++){
- Uint32 sz = chains[i].size();
- if(sz == 1){
- Uint32 col = chains[i][0];
- Uint32 hv = hashValues[col];
- Uint32 bucket = hv & m_columnHashMask;
- bucket = (bucket < size ? bucket : bucket - size);
- m_columnHash[bucket] = (col << 16) | hv | 1;
- } else if(sz > 1){
- Uint32 col = chains[i][0];
- Uint32 hv = hashValues[col];
- Uint32 bucket = hv & m_columnHashMask;
- bucket = (bucket < size ? bucket : bucket - size);
- m_columnHash[bucket] = (sz << 16) | (((size - bucket) + pos) << 1);
- for(size_t j = 0; j<sz; j++, pos++){
- Uint32 col = chains[i][j];
- Uint32 hv = hashValues[col];
- if (m_columnHash.push_back((col << 16) | hv))
- {
- return -1;
- }
- }
- }
- }
-
- if (m_columnHash.push_back(0)) // Overflow when looping in end of array
- {
- return -1;
- }
-
-#if 0
- for(size_t i = 0; i<m_columnHash.size(); i++){
- Uint32 tmp = m_columnHash[i];
- int col = -1;
- if(i < size && (tmp & 1) == 1){
- col = (tmp >> 16);
- } else if(i >= size){
- col = (tmp >> 16);
- }
- ndbout_c("m_columnHash[%d] %s = %x",
- i, col > 0 ? m_columns[col]->getName() : "" , m_columnHash[i]);
- }
-#endif
- return 0;
-}
-
-Uint32
-NdbTableImpl::get_nodes(Uint32 hashValue, const Uint16 ** nodes) const
-{
- Uint32 fragmentId;
- if(m_replicaCount == 0)
- return 0;
- switch (m_fragmentType)
- {
- case NdbDictionary::Object::FragAllSmall:
- case NdbDictionary::Object::FragAllMedium:
- case NdbDictionary::Object::FragAllLarge:
- case NdbDictionary::Object::FragSingle:
- case NdbDictionary::Object::DistrKeyLin:
- {
- fragmentId = hashValue & m_hashValueMask;
- if(fragmentId < m_hashpointerValue)
- fragmentId = hashValue & ((m_hashValueMask << 1) + 1);
- break;
- }
- case NdbDictionary::Object::DistrKeyHash:
- {
- fragmentId = hashValue % m_fragmentCount;
- break;
- }
- default:
- return 0;
- }
- Uint32 pos = fragmentId * m_replicaCount;
- if (pos + m_replicaCount <= m_fragments.size())
- {
- *nodes = m_fragments.getBase()+pos;
- return m_replicaCount;
- }
- return 0;
-}
-
-int
-NdbDictionary::Table::checkColumns(const Uint32* map, Uint32 len) const
-{
- int ret = 0;
- Uint32 colCnt = m_impl.m_columns.size();
- if (map == 0)
- {
- ret |= 1;
- ret |= (m_impl.m_noOfDiskColumns) ? 2 : 0;
- ret |= (colCnt > m_impl.m_noOfDiskColumns) ? 4 : 0;
- return ret;
- }
-
- NdbColumnImpl** cols = m_impl.m_columns.getBase();
- const char * ptr = reinterpret_cast<const char*>(map);
- const char * end = ptr + len;
- Uint32 no = 0;
- while (ptr < end)
- {
- Uint32 val = (Uint32)* ptr;
- Uint32 idx = 1;
- for (Uint32 i = 0; i<8; i++)
- {
- if (val & idx)
- {
- if (cols[no]->getPrimaryKey())
- ret |= 1;
- else
- {
- if (cols[no]->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
- ret |= 2;
- else
- ret |= 4;
- }
- }
- no ++;
- idx *= 2;
- if (no == colCnt)
- return ret;
- }
-
- ptr++;
- }
- return ret;
-}
-
-
-
-/**
- * NdbIndexImpl
- */
-
-NdbIndexImpl::NdbIndexImpl() :
- NdbDictionary::Index(* this),
- NdbDictObjectImpl(NdbDictionary::Object::OrderedIndex), m_facade(this)
-{
- init();
-}
-
-NdbIndexImpl::NdbIndexImpl(NdbDictionary::Index & f) :
- NdbDictionary::Index(* this),
- NdbDictObjectImpl(NdbDictionary::Object::OrderedIndex), m_facade(&f)
-{
- init();
-}
-
-void NdbIndexImpl::init()
-{
- m_id= RNIL;
- m_type= NdbDictionary::Object::TypeUndefined;
- m_logging= true;
- m_temporary= false;
- m_table= NULL;
-}
-
-NdbIndexImpl::~NdbIndexImpl(){
- for (unsigned i = 0; i < m_columns.size(); i++)
- delete m_columns[i];
-}
-
-int NdbIndexImpl::setName(const char * name)
-{
- return !m_externalName.assign(name);
-}
-
-const char *
-NdbIndexImpl::getName() const
-{
- return m_externalName.c_str();
-}
-
-int
-NdbIndexImpl::setTable(const char * table)
-{
- return !m_tableName.assign(table);
-}
-
-const char *
-NdbIndexImpl::getTable() const
-{
- return m_tableName.c_str();
-}
-
-const NdbTableImpl *
-NdbIndexImpl::getIndexTable() const
-{
- return m_table;
-}
-
-/**
- * NdbEventImpl
- */
-
-NdbEventImpl::NdbEventImpl() :
- NdbDictionary::Event(* this),
- NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined), m_facade(this)
-{
- DBUG_ENTER("NdbEventImpl::NdbEventImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-NdbEventImpl::NdbEventImpl(NdbDictionary::Event & f) :
- NdbDictionary::Event(* this),
- NdbDictObjectImpl(NdbDictionary::Object::TypeUndefined), m_facade(&f)
-{
- DBUG_ENTER("NdbEventImpl::NdbEventImpl");
- DBUG_PRINT("info", ("this: %p", this));
- init();
- DBUG_VOID_RETURN;
-}
-
-void NdbEventImpl::init()
-{
- m_eventId= RNIL;
- m_eventKey= RNIL;
- mi_type= 0;
- m_dur= NdbDictionary::Event::ED_UNDEFINED;
- m_mergeEvents = false;
- m_tableImpl= NULL;
- m_rep= NdbDictionary::Event::ER_UPDATED;
-}
-
-NdbEventImpl::~NdbEventImpl()
-{
- DBUG_ENTER("NdbEventImpl::~NdbEventImpl");
- DBUG_PRINT("info", ("this: %p", this));
- for (unsigned i = 0; i < m_columns.size(); i++)
- delete m_columns[i];
- if (m_tableImpl)
- delete m_tableImpl;
- DBUG_VOID_RETURN;
-}
-
-int NdbEventImpl::setName(const char * name)
-{
- return !m_name.assign(name);
-}
-
-const char *NdbEventImpl::getName() const
-{
- return m_name.c_str();
-}
-
-int
-NdbEventImpl::setTable(const NdbDictionary::Table& table)
-{
- setTable(&NdbTableImpl::getImpl(table));
- return !m_tableName.assign(m_tableImpl->getName());
-}
-
-void
-NdbEventImpl::setTable(NdbTableImpl *tableImpl)
-{
- DBUG_ENTER("NdbEventImpl::setTable");
- DBUG_PRINT("info", ("this: %p tableImpl: %p", this, tableImpl));
- DBUG_ASSERT(tableImpl->m_status != NdbDictionary::Object::Invalid);
- if (!m_tableImpl)
- m_tableImpl = new NdbTableImpl();
- // Copy table, since event might be accessed from different threads
- m_tableImpl->assign(*tableImpl);
- DBUG_VOID_RETURN;
-}
-
-const NdbDictionary::Table *
-NdbEventImpl::getTable() const
-{
- if (m_tableImpl)
- return m_tableImpl->m_facade;
- else
- return NULL;
-}
-
-int
-NdbEventImpl::setTable(const char * table)
-{
- return !m_tableName.assign(table);
-}
-
-const char *
-NdbEventImpl::getTableName() const
-{
- return m_tableName.c_str();
-}
-
-void
-NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDictionary::Event::TE_ALL)
-{
- mi_type |= (unsigned)t;
-}
-
-bool
-NdbEventImpl::getTableEvent(const NdbDictionary::Event::TableEvent t) const
-{
- return (mi_type & (unsigned)t) == (unsigned)t;
-}
-
-void
-NdbEventImpl::setDurability(NdbDictionary::Event::EventDurability d)
-{
- m_dur = d;
-}
-
-NdbDictionary::Event::EventDurability
-NdbEventImpl::getDurability() const
-{
- return m_dur;
-}
-
-void
-NdbEventImpl::setReport(NdbDictionary::Event::EventReport r)
-{
- m_rep = r;
-}
-
-NdbDictionary::Event::EventReport
-NdbEventImpl::getReport() const
-{
- return m_rep;
-}
-
-int NdbEventImpl::getNoOfEventColumns() const
-{
- return m_attrIds.size() + m_columns.size();
-}
-
-const NdbDictionary::Column *
-NdbEventImpl::getEventColumn(unsigned no) const
-{
- if (m_columns.size())
- {
- if (no < m_columns.size())
- {
- return m_columns[no];
- }
- }
- else if (m_attrIds.size())
- {
- if (no < m_attrIds.size())
- {
- NdbTableImpl* tab= m_tableImpl;
- if (tab == 0)
- return 0;
- return tab->getColumn(m_attrIds[no]);
- }
- }
- return 0;
-}
-
-/**
- * NdbDictionaryImpl
- */
-
-NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb)
- : NdbDictionary::Dictionary(* this),
- m_facade(this),
- m_receiver(m_error),
- m_ndb(ndb)
-{
- m_globalHash = 0;
- m_local_table_data_size= 0;
-}
-
-NdbDictionaryImpl::NdbDictionaryImpl(Ndb &ndb,
- NdbDictionary::Dictionary & f)
- : NdbDictionary::Dictionary(* this),
- m_facade(&f),
- m_receiver(m_error),
- m_ndb(ndb)
-{
- m_globalHash = 0;
- m_local_table_data_size= 0;
-}
-
-NdbDictionaryImpl::~NdbDictionaryImpl()
-{
- NdbElement_t<Ndb_local_table_info> * curr = m_localHash.m_tableHash.getNext(0);
- if(m_globalHash){
- while(curr != 0){
- m_globalHash->lock();
- m_globalHash->release(curr->theData->m_table_impl);
- Ndb_local_table_info::destroy(curr->theData);
- m_globalHash->unlock();
-
- curr = m_localHash.m_tableHash.getNext(curr);
- }
- } else {
- assert(curr == 0);
- }
-}
-
-NdbTableImpl *
-NdbDictionaryImpl::fetchGlobalTableImplRef(const GlobalCacheInitObject &obj)
-{
- DBUG_ENTER("fetchGlobalTableImplRef");
- NdbTableImpl *impl;
- int error= 0;
-
- m_globalHash->lock();
- impl = m_globalHash->get(obj.m_name.c_str(), &error);
- m_globalHash->unlock();
-
- if (impl == 0){
- if (error == 0)
- impl = m_receiver.getTable(obj.m_name.c_str(),
- m_ndb.usingFullyQualifiedNames());
- else
- m_error.code = 4000;
- if (impl != 0 && obj.init(*impl))
- {
- delete impl;
- impl = 0;
- }
- m_globalHash->lock();
- m_globalHash->put(obj.m_name.c_str(), impl);
- m_globalHash->unlock();
- }
-
- DBUG_RETURN(impl);
-}
-
-void
-NdbDictionaryImpl::putTable(NdbTableImpl *impl)
-{
- NdbTableImpl *old;
-
- int ret = getBlobTables(*impl);
- int error = 0;
- assert(ret == 0);
-
- m_globalHash->lock();
- if ((old= m_globalHash->get(impl->m_internalName.c_str(), &error)))
- {
- m_globalHash->alter_table_rep(old->m_internalName.c_str(),
- impl->m_id,
- impl->m_version,
- FALSE);
- }
- m_globalHash->put(impl->m_internalName.c_str(), impl);
- m_globalHash->unlock();
- Ndb_local_table_info *info=
- Ndb_local_table_info::create(impl, m_local_table_data_size);
-
- m_localHash.put(impl->m_internalName.c_str(), info);
-}
-
-int
-NdbDictionaryImpl::getBlobTables(NdbTableImpl &t)
-{
- unsigned n= t.m_noOfBlobs;
- DBUG_ENTER("NdbDictionaryImpl::addBlobTables");
- // optimized for blob column being the last one
- // and not looking for more than one if not neccessary
- for (unsigned i = t.m_columns.size(); i > 0 && n > 0;) {
- i--;
- NdbColumnImpl & c = *t.m_columns[i];
- if (! c.getBlobType() || c.getPartSize() == 0)
- continue;
- n--;
- // retrieve blob table def from DICT - by-pass cache
- char btname[NdbBlobImpl::BlobTableNameSize];
- NdbBlob::getBlobTableName(btname, &t, &c);
- BaseString btname_internal = m_ndb.internalize_table_name(btname);
- NdbTableImpl* bt =
- m_receiver.getTable(btname_internal, m_ndb.usingFullyQualifiedNames());
- if (bt == NULL)
- DBUG_RETURN(-1);
-
- // TODO check primary id/version when returned by DICT
-
- // the blob column owns the blob table
- assert(c.m_blobTable == NULL);
- c.m_blobTable = bt;
- }
- DBUG_RETURN(0);
-}
-
-NdbTableImpl*
-NdbDictionaryImpl::getBlobTable(const NdbTableImpl& tab, uint col_no)
-{
- if (col_no < tab.m_columns.size()) {
- NdbColumnImpl* col = tab.m_columns[col_no];
- if (col != NULL) {
- NdbTableImpl* bt = col->m_blobTable;
- if (bt != NULL)
- return bt;
- else
- m_error.code = 4273; // No blob table..
- } else
- m_error.code = 4249; // Invalid table..
- } else
- m_error.code = 4318; // Invalid attribute..
- return NULL;
-}
-
-NdbTableImpl*
-NdbDictionaryImpl::getBlobTable(uint tab_id, uint col_no)
-{
- DBUG_ENTER("NdbDictionaryImpl::getBlobTable");
- DBUG_PRINT("enter", ("tab_id: %u col_no %u", tab_id, col_no));
-
- NdbTableImpl* tab = m_receiver.getTable(tab_id,
- m_ndb.usingFullyQualifiedNames());
- if (tab == NULL)
- DBUG_RETURN(NULL);
- Ndb_local_table_info* info =
- get_local_table_info(tab->m_internalName);
- delete tab;
- if (info == NULL)
- DBUG_RETURN(NULL);
- NdbTableImpl* bt = getBlobTable(*info->m_table_impl, col_no);
- DBUG_RETURN(bt);
-}
-
-#if 0
-bool
-NdbDictionaryImpl::setTransporter(class TransporterFacade * tf)
-{
- if(tf != 0){
- m_globalHash = &tf->m_globalDictCache;
- return m_receiver.setTransporter(tf);
- }
-
- return false;
-}
-#endif
-
-bool
-NdbDictionaryImpl::setTransporter(class Ndb* ndb,
- class TransporterFacade * tf)
-{
- m_globalHash = &tf->m_globalDictCache;
- if(m_receiver.setTransporter(ndb, tf)){
- return true;
- }
- return false;
-}
-
-NdbTableImpl *
-NdbDictionaryImpl::getIndexTable(NdbIndexImpl * index,
- NdbTableImpl * table)
-{
- const char *current_db= m_ndb.getDatabaseName();
- NdbTableImpl *index_table;
- const BaseString internalName(
- m_ndb.internalize_index_name(table, index->getName()));
- // Get index table in system database
- m_ndb.setDatabaseName(NDB_SYSTEM_DATABASE);
- index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
- m_ndb.setDatabaseName(current_db);
- if (!index_table)
- {
- // Index table not found
- // Try geting index table in current database (old format)
- index_table= getTable(m_ndb.externalizeTableName(internalName.c_str()));
- }
- return index_table;
-}
-
-#if 0
-bool
-NdbDictInterface::setTransporter(class TransporterFacade * tf)
-{
- if(tf == 0)
- return false;
-
- Guard g(tf->theMutexPtr);
-
- m_blockNumber = tf->open(this,
- execSignal,
- execNodeStatus);
-
- if ( m_blockNumber == -1 ) {
- m_error.code= 4105;
- return false; // no more free blocknumbers
- }//if
- Uint32 theNode = tf->ownId();
- m_reference = numberToRef(m_blockNumber, theNode);
- m_transporter = tf;
- m_waiter.m_mutex = tf->theMutexPtr;
-
- return true;
-}
-#endif
-
-bool
-NdbDictInterface::setTransporter(class Ndb* ndb, class TransporterFacade * tf)
-{
- m_reference = ndb->getReference();
- m_transporter = tf;
- m_waiter.m_mutex = tf->theMutexPtr;
-
- return true;
-}
-
-NdbDictInterface::~NdbDictInterface()
-{
-}
-
-void
-NdbDictInterface::execSignal(void* dictImpl,
- class NdbApiSignal* signal,
- class LinearSectionPtr ptr[3])
-{
- NdbDictInterface * tmp = (NdbDictInterface*)dictImpl;
-
- const Uint32 gsn = signal->readSignalNumber();
- switch(gsn){
- case GSN_GET_TABINFOREF:
- tmp->execGET_TABINFO_REF(signal, ptr);
- break;
- case GSN_GET_TABINFO_CONF:
- tmp->execGET_TABINFO_CONF(signal, ptr);
- break;
- case GSN_CREATE_TABLE_REF:
- tmp->execCREATE_TABLE_REF(signal, ptr);
- break;
- case GSN_CREATE_TABLE_CONF:
- tmp->execCREATE_TABLE_CONF(signal, ptr);
- break;
- case GSN_DROP_TABLE_REF:
- tmp->execDROP_TABLE_REF(signal, ptr);
- break;
- case GSN_DROP_TABLE_CONF:
- tmp->execDROP_TABLE_CONF(signal, ptr);
- break;
- case GSN_ALTER_TABLE_REF:
- tmp->execALTER_TABLE_REF(signal, ptr);
- break;
- case GSN_ALTER_TABLE_CONF:
- tmp->execALTER_TABLE_CONF(signal, ptr);
- break;
- case GSN_CREATE_INDX_REF:
- tmp->execCREATE_INDX_REF(signal, ptr);
- break;
- case GSN_CREATE_INDX_CONF:
- tmp->execCREATE_INDX_CONF(signal, ptr);
- break;
- case GSN_DROP_INDX_REF:
- tmp->execDROP_INDX_REF(signal, ptr);
- break;
- case GSN_DROP_INDX_CONF:
- tmp->execDROP_INDX_CONF(signal, ptr);
- break;
- case GSN_CREATE_EVNT_REF:
- tmp->execCREATE_EVNT_REF(signal, ptr);
- break;
- case GSN_CREATE_EVNT_CONF:
- tmp->execCREATE_EVNT_CONF(signal, ptr);
- break;
- case GSN_SUB_START_CONF:
- tmp->execSUB_START_CONF(signal, ptr);
- break;
- case GSN_SUB_START_REF:
- tmp->execSUB_START_REF(signal, ptr);
- break;
- case GSN_SUB_STOP_CONF:
- tmp->execSUB_STOP_CONF(signal, ptr);
- break;
- case GSN_SUB_STOP_REF:
- tmp->execSUB_STOP_REF(signal, ptr);
- break;
- case GSN_DROP_EVNT_REF:
- tmp->execDROP_EVNT_REF(signal, ptr);
- break;
- case GSN_DROP_EVNT_CONF:
- tmp->execDROP_EVNT_CONF(signal, ptr);
- break;
- case GSN_LIST_TABLES_CONF:
- tmp->execLIST_TABLES_CONF(signal, ptr);
- break;
- case GSN_CREATE_FILEGROUP_REF:
- tmp->execCREATE_FILEGROUP_REF(signal, ptr);
- break;
- case GSN_CREATE_FILEGROUP_CONF:
- tmp->execCREATE_FILEGROUP_CONF(signal, ptr);
- break;
- case GSN_CREATE_FILE_REF:
- tmp->execCREATE_FILE_REF(signal, ptr);
- break;
- case GSN_CREATE_FILE_CONF:
- tmp->execCREATE_FILE_CONF(signal, ptr);
- break;
- case GSN_DROP_FILEGROUP_REF:
- tmp->execDROP_FILEGROUP_REF(signal, ptr);
- break;
- case GSN_DROP_FILEGROUP_CONF:
- tmp->execDROP_FILEGROUP_CONF(signal, ptr);
- break;
- case GSN_DROP_FILE_REF:
- tmp->execDROP_FILE_REF(signal, ptr);
- break;
- case GSN_DROP_FILE_CONF:
- tmp->execDROP_FILE_CONF(signal, ptr);
- break;
- case GSN_WAIT_GCP_CONF:
- tmp->execWAIT_GCP_CONF(signal, ptr);
- break;
- case GSN_WAIT_GCP_REF:
- tmp->execWAIT_GCP_REF(signal, ptr);
- break;
- default:
- abort();
- }
-}
-
-void
-NdbDictInterface::execNodeStatus(void* dictImpl, Uint32 aNode,
- bool alive, bool nfCompleted)
-{
- NdbDictInterface * tmp = (NdbDictInterface*)dictImpl;
-
- if(!alive && !nfCompleted){
- return;
- }
-
- if (!alive && nfCompleted){
- tmp->m_waiter.nodeFail(aNode);
- }
-}
-
-int
-NdbDictInterface::dictSignal(NdbApiSignal* sig,
- LinearSectionPtr ptr[3], int secs,
- int node_specification,
- WaitSignalType wst,
- int timeout, Uint32 RETRIES,
- const int *errcodes, int temporaryMask)
-{
- DBUG_ENTER("NdbDictInterface::dictSignal");
- DBUG_PRINT("enter", ("useMasterNodeId: %d", node_specification));
-
- int sleep = 50;
- int mod = 5;
-
- for(Uint32 i = 0; i<RETRIES; i++)
- {
- if (i > 0)
- NdbSleep_MilliSleep(sleep + 10 * (rand() % mod));
- if (i == RETRIES / 2)
- {
- mod = 10;
- }
- if (i == 3*RETRIES/4)
- {
- sleep = 100;
- }
-
- m_buffer.clear();
-
- // Protected area
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(m_transporter, &m_waiter, refToBlock(m_reference));
- Uint32 node;
- switch(node_specification){
- case 0:
- node = (m_transporter->get_node_alive(m_masterNodeId) ? m_masterNodeId :
- (m_masterNodeId = m_transporter->get_an_alive_node()));
- break;
- case -1:
- node = m_transporter->get_an_alive_node();
- break;
- default:
- node = node_specification;
- }
- DBUG_PRINT("info", ("node %d", node));
- if(node == 0){
- m_error.code= 4009;
- DBUG_RETURN(-1);
- }
- int res = (ptr ?
- m_transporter->sendFragmentedSignal(sig, node, ptr, secs):
- m_transporter->sendSignal(sig, node));
- if(res != 0){
- DBUG_PRINT("info", ("dictSignal failed to send signal"));
- m_error.code = 4007;
- continue;
- }
-
- m_error.code= 0;
- int ret_val= poll_guard.wait_n_unlock(timeout, node, wst);
- // End of Protected area
-
- if(ret_val == 0 && m_error.code == 0){
- // Normal return
- DBUG_RETURN(0);
- }
-
- /**
- * Handle error codes
- */
- if(ret_val == -2) //WAIT_NODE_FAILURE
- {
- m_error.code = 4013;
- continue;
- }
- if(m_waiter.m_state == WST_WAIT_TIMEOUT)
- {
- DBUG_PRINT("info", ("dictSignal caught time-out"));
- m_error.code = 4008;
- DBUG_RETURN(-1);
- }
-
- if ( temporaryMask == -1)
- {
- const NdbError &error= getNdbError();
- if (error.status == NdbError::TemporaryError)
- continue;
- }
- else if ( (temporaryMask & m_error.code) != 0 ) {
- continue;
- }
- DBUG_PRINT("info", ("dictSignal caught error= %d", m_error.code));
-
- if(m_error.code && errcodes)
- {
- int j;
- for(j = 0; errcodes[j] ; j++){
- if(m_error.code == errcodes[j]){
- break;
- }
- }
- if(errcodes[j]) // Accepted error code
- continue;
- }
- break;
- }
- DBUG_RETURN(-1);
-}
-
-/*
- Get dictionary information for a table using table id as reference
-
- DESCRIPTION
- Sends a GET_TABINFOREQ signal containing the table id
- */
-NdbTableImpl *
-NdbDictInterface::getTable(int tableId, bool fullyQualifiedNames)
-{
- NdbApiSignal tSignal(m_reference);
- GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
-
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestType =
- GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
- req->tableId = tableId;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
- tSignal.theLength = GetTabInfoReq::SignalLength;
-
- return getTable(&tSignal, 0, 0, fullyQualifiedNames);
-}
-
-/*
- Get dictionary information for a table using table name as the reference
-
- DESCRIPTION
- Send GET_TABINFOREQ signal with the table name in the first
- long section part
-*/
-
-NdbTableImpl *
-NdbDictInterface::getTable(const BaseString& name, bool fullyQualifiedNames)
-{
- NdbApiSignal tSignal(m_reference);
- GetTabInfoReq* const req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
-
- const Uint32 namelen= name.length() + 1; // NULL terminated
- const Uint32 namelen_words= (namelen + 3) >> 2; // Size in words
-
- req->senderRef= m_reference;
- req->senderData= 0;
- req->requestType=
- GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
- req->tableNameLen= namelen;
- tSignal.theReceiversBlockNumber= DBDICT;
- tSignal.theVerId_signalNumber= GSN_GET_TABINFOREQ;
- tSignal.theLength= GetTabInfoReq::SignalLength;
-
- // Copy name to m_buffer to get a word sized buffer
- m_buffer.clear();
- if (m_buffer.grow(namelen_words*4+4) ||
- m_buffer.append(name.c_str(), namelen))
- {
- m_error.code= 4000;
- return NULL;
- }
-
-#ifndef IGNORE_VALGRIND_WARNINGS
- Uint32 pad = 0;
- if (m_buffer.append(&pad, 4))
- {
- m_error.code= 4000;
- return NULL;
- }
-#endif
-
- LinearSectionPtr ptr[1];
- ptr[0].p= (Uint32*)m_buffer.get_data();
- ptr[0].sz= namelen_words;
-
- return getTable(&tSignal, ptr, 1, fullyQualifiedNames);
-}
-
-
-NdbTableImpl *
-NdbDictInterface::getTable(class NdbApiSignal * signal,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections, bool fullyQualifiedNames)
-{
- int errCodes[] = {GetTabInfoRef::Busy, 0 };
- int r = dictSignal(signal, ptr, noOfSections,
- -1, // any node
- WAIT_GET_TAB_INFO_REQ,
- DICT_WAITFOR_TIMEOUT, 100, errCodes);
-
- if (r)
- return 0;
-
- NdbTableImpl * rt = 0;
- m_error.code = parseTableInfo(&rt,
- (Uint32*)m_buffer.get_data(),
- m_buffer.length() / 4,
- fullyQualifiedNames);
- if(rt)
- {
- if (rt->buildColumnHash())
- {
- m_error.code = 4000;
- delete rt;
- return NULL;
- }
- }
-
- return rt;
-}
-
-void
-NdbDictInterface::execGET_TABINFO_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const GetTabInfoConf* conf = CAST_CONSTPTR(GetTabInfoConf, signal->getDataPtr());
- const Uint32 i = GetTabInfoConf::DICT_TAB_INFO;
- if(signal->isFirstFragment()){
- m_fragmentId = signal->getFragmentId();
- if (m_buffer.grow(4 * conf->totalLen))
- {
- m_error.code= 4000;
- goto end;
- }
- } else {
- if(m_fragmentId != signal->getFragmentId()){
- abort();
- }
- }
-
- if (m_buffer.append(ptr[i].p, 4 * ptr[i].sz))
- {
- m_error.code= 4000;
- }
-end:
- if(!signal->isLastFragment()){
- return;
- }
-
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execGET_TABINFO_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef,
- signal->getDataPtr());
-
- m_error.code= ref->errorCode;
- m_waiter.signal(NO_WAIT);
-}
-
-/*****************************************************************
- * Pack/Unpack tables
- */
-struct ApiKernelMapping {
- Int32 kernelConstant;
- Int32 apiConstant;
-};
-
-Uint32
-getApiConstant(Int32 kernelConstant, const ApiKernelMapping map[], Uint32 def)
-{
- int i = 0;
- while(map[i].kernelConstant != kernelConstant){
- if(map[i].kernelConstant == -1 &&
- map[i].apiConstant == -1){
- return def;
- }
- i++;
- }
- return map[i].apiConstant;
-}
-
-Uint32
-getKernelConstant(Int32 apiConstant, const ApiKernelMapping map[], Uint32 def)
-{
- int i = 0;
- while(map[i].apiConstant != apiConstant){
- if(map[i].kernelConstant == -1 &&
- map[i].apiConstant == -1){
- return def;
- }
- i++;
- }
- return map[i].kernelConstant;
-}
-
-static const
-ApiKernelMapping
-fragmentTypeMapping[] = {
- { DictTabInfo::AllNodesSmallTable, NdbDictionary::Object::FragAllSmall },
- { DictTabInfo::AllNodesMediumTable, NdbDictionary::Object::FragAllMedium },
- { DictTabInfo::AllNodesLargeTable, NdbDictionary::Object::FragAllLarge },
- { DictTabInfo::SingleFragment, NdbDictionary::Object::FragSingle },
- { DictTabInfo::DistrKeyHash, NdbDictionary::Object::DistrKeyHash },
- { DictTabInfo::DistrKeyLin, NdbDictionary::Object::DistrKeyLin },
- { DictTabInfo::UserDefined, NdbDictionary::Object::UserDefined },
- { -1, -1 }
-};
-
-static const
-ApiKernelMapping
-objectTypeMapping[] = {
- { DictTabInfo::SystemTable, NdbDictionary::Object::SystemTable },
- { DictTabInfo::UserTable, NdbDictionary::Object::UserTable },
- { DictTabInfo::UniqueHashIndex, NdbDictionary::Object::UniqueHashIndex },
- { DictTabInfo::OrderedIndex, NdbDictionary::Object::OrderedIndex },
- { DictTabInfo::HashIndexTrigger, NdbDictionary::Object::HashIndexTrigger },
- { DictTabInfo::IndexTrigger, NdbDictionary::Object::IndexTrigger },
- { DictTabInfo::SubscriptionTrigger,NdbDictionary::Object::SubscriptionTrigger },
- { DictTabInfo::ReadOnlyConstraint ,NdbDictionary::Object::ReadOnlyConstraint },
- { DictTabInfo::Tablespace, NdbDictionary::Object::Tablespace },
- { DictTabInfo::LogfileGroup, NdbDictionary::Object::LogfileGroup },
- { DictTabInfo::Datafile, NdbDictionary::Object::Datafile },
- { DictTabInfo::Undofile, NdbDictionary::Object::Undofile },
- { -1, -1 }
-};
-
-static const
-ApiKernelMapping
-objectStateMapping[] = {
- { DictTabInfo::StateOffline, NdbDictionary::Object::StateOffline },
- { DictTabInfo::StateBuilding, NdbDictionary::Object::StateBuilding },
- { DictTabInfo::StateDropping, NdbDictionary::Object::StateDropping },
- { DictTabInfo::StateOnline, NdbDictionary::Object::StateOnline },
- { DictTabInfo::StateBackup, NdbDictionary::Object::StateBackup },
- { DictTabInfo::StateBroken, NdbDictionary::Object::StateBroken },
- { -1, -1 }
-};
-
-static const
-ApiKernelMapping
-objectStoreMapping[] = {
- { DictTabInfo::StoreNotLogged, NdbDictionary::Object::StoreNotLogged },
- { DictTabInfo::StorePermanent, NdbDictionary::Object::StorePermanent },
- { -1, -1 }
-};
-
-static const
-ApiKernelMapping
-indexTypeMapping[] = {
- { DictTabInfo::UniqueHashIndex, NdbDictionary::Index::UniqueHashIndex },
- { DictTabInfo::OrderedIndex, NdbDictionary::Index::OrderedIndex },
- { -1, -1 }
-};
-
-int
-NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
- const Uint32 * data, Uint32 len,
- bool fullyQualifiedNames,
- Uint32 version)
-{
- SimplePropertiesLinearReader it(data, len);
- DictTabInfo::Table *tableDesc;
- SimpleProperties::UnpackStatus s;
- DBUG_ENTER("NdbDictInterface::parseTableInfo");
-
- tableDesc = (DictTabInfo::Table*)NdbMem_Allocate(sizeof(DictTabInfo::Table));
- if (!tableDesc)
- {
- DBUG_RETURN(4000);
- }
- tableDesc->init();
- s = SimpleProperties::unpack(it, tableDesc,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize,
- true, true);
-
- if(s != SimpleProperties::Break){
- NdbMem_Free((void*)tableDesc);
- DBUG_RETURN(703);
- }
- const char * internalName = tableDesc->TableName;
- const char * externalName = Ndb::externalizeTableName(internalName, fullyQualifiedNames);
-
- NdbTableImpl * impl = new NdbTableImpl();
- impl->m_id = tableDesc->TableId;
- impl->m_version = tableDesc->TableVersion;
- impl->m_status = NdbDictionary::Object::Retrieved;
- if (!impl->m_internalName.assign(internalName) ||
- impl->updateMysqlName() ||
- !impl->m_externalName.assign(externalName) ||
- impl->m_frm.assign(tableDesc->FrmData, tableDesc->FrmLen) ||
- impl->m_fd.assign(tableDesc->FragmentData, tableDesc->FragmentDataLen) ||
- impl->m_range.assign(tableDesc->RangeListData, tableDesc->RangeListDataLen))
- {
- DBUG_RETURN(4000);
- }
- impl->m_fragmentCount = tableDesc->FragmentCount;
-
- /*
- We specifically don't get tablespace data and range/list arrays here
- since those are known by the MySQL Server through analysing the
- frm file.
- Fragment Data contains the real node group mapping and the fragment
- identities used for each fragment. At the moment we have no need for
- this.
- Frm file is needed for autodiscovery.
- */
-
- impl->m_fragmentType = (NdbDictionary::Object::FragmentType)
- getApiConstant(tableDesc->FragmentType,
- fragmentTypeMapping,
- (Uint32)NdbDictionary::Object::FragUndefined);
-
- Uint64 max_rows = ((Uint64)tableDesc->MaxRowsHigh) << 32;
- max_rows += tableDesc->MaxRowsLow;
- impl->m_max_rows = max_rows;
- Uint64 min_rows = ((Uint64)tableDesc->MinRowsHigh) << 32;
- min_rows += tableDesc->MinRowsLow;
- impl->m_min_rows = min_rows;
- impl->m_default_no_part_flag = tableDesc->DefaultNoPartFlag;
- impl->m_linear_flag = tableDesc->LinearHashFlag;
- impl->m_logging = tableDesc->TableLoggedFlag;
- impl->m_temporary = tableDesc->TableTemporaryFlag;
- impl->m_row_gci = tableDesc->RowGCIFlag;
- impl->m_row_checksum = tableDesc->RowChecksumFlag;
- impl->m_force_var_part = tableDesc->ForceVarPartFlag;
- impl->m_kvalue = tableDesc->TableKValue;
- impl->m_minLoadFactor = tableDesc->MinLoadFactor;
- impl->m_maxLoadFactor = tableDesc->MaxLoadFactor;
- impl->m_single_user_mode = tableDesc->SingleUserMode;
-
- impl->m_indexType = (NdbDictionary::Object::Type)
- getApiConstant(tableDesc->TableType,
- indexTypeMapping,
- NdbDictionary::Object::TypeUndefined);
-
- if(impl->m_indexType == NdbDictionary::Object::TypeUndefined){
- } else {
- const char * externalPrimary =
- Ndb::externalizeTableName(tableDesc->PrimaryTable, fullyQualifiedNames);
- if (!impl->m_primaryTable.assign(externalPrimary))
- {
- DBUG_RETURN(4000);
- }
- }
-
- Uint32 i;
- for(i = 0; i < tableDesc->NoOfAttributes; i++) {
- DictTabInfo::Attribute attrDesc; attrDesc.init();
- s = SimpleProperties::unpack(it,
- &attrDesc,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize,
- true, true);
- if(s != SimpleProperties::Break){
- delete impl;
- NdbMem_Free((void*)tableDesc);
- DBUG_RETURN(703);
- }
-
- NdbColumnImpl * col = new NdbColumnImpl();
- col->m_attrId = attrDesc.AttributeId;
- col->setName(attrDesc.AttributeName);
-
- // check type and compute attribute size and array size
- if (! attrDesc.translateExtType()) {
- delete col;
- delete impl;
- NdbMem_Free((void*)tableDesc);
- DBUG_RETURN(703);
- }
- col->m_type = (NdbDictionary::Column::Type)attrDesc.AttributeExtType;
- col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF);
- col->m_scale = attrDesc.AttributeExtScale;
- col->m_length = attrDesc.AttributeExtLength;
- // charset in upper half of precision
- unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16);
- // charset is defined exactly for char types
- if (col->getCharType() != (cs_number != 0)) {
- delete col;
- delete impl;
- NdbMem_Free((void*)tableDesc);
- DBUG_RETURN(703);
- }
- if (col->getCharType()) {
- col->m_cs = get_charset(cs_number, MYF(0));
- if (col->m_cs == NULL) {
- delete col;
- delete impl;
- NdbMem_Free((void*)tableDesc);
- DBUG_RETURN(743);
- }
- }
- col->m_attrSize = (1 << attrDesc.AttributeSize) / 8;
- col->m_arraySize = attrDesc.AttributeArraySize;
- col->m_arrayType = attrDesc.AttributeArrayType;
- if(attrDesc.AttributeSize == 0)
- {
- col->m_attrSize = 4;
- col->m_arraySize = (attrDesc.AttributeArraySize + 31) >> 5;
- }
- col->m_storageType = attrDesc.AttributeStorageType;
-
- col->m_pk = attrDesc.AttributeKeyFlag;
- col->m_distributionKey = (attrDesc.AttributeDKey != 0);
- col->m_nullable = attrDesc.AttributeNullableFlag;
- col->m_autoIncrement = (attrDesc.AttributeAutoIncrement != 0);
- col->m_autoIncrementInitialValue = ~0;
- if (!col->m_defaultValue.assign(attrDesc.AttributeDefaultValue))
- {
- delete col;
- delete impl;
- DBUG_RETURN(4000);
- }
-
- col->m_column_no = impl->m_columns.size();
- impl->m_columns.push_back(col);
- it.next();
- }
-
- impl->computeAggregates();
-
- if(tableDesc->ReplicaDataLen > 0)
- {
- Uint16 replicaCount = ntohs(tableDesc->ReplicaData[0]);
- Uint16 fragCount = ntohs(tableDesc->ReplicaData[1]);
-
- impl->m_replicaCount = replicaCount;
- impl->m_fragmentCount = fragCount;
- DBUG_PRINT("info", ("replicaCount=%x , fragCount=%x",replicaCount,fragCount));
- Uint32 pos = 2;
- for(i = 0; i < (Uint32) fragCount;i++)
- {
- pos++; // skip logpart
- for (Uint32 j = 0; j<(Uint32)replicaCount; j++)
- {
- if (impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[pos++])))
- {
- delete impl;
- DBUG_RETURN(4000);
- }
- }
- }
-
- Uint32 topBit = (1 << 31);
- for(; topBit && !(fragCount & topBit); ){
- topBit >>= 1;
- }
- impl->m_hashValueMask = topBit - 1;
- impl->m_hashpointerValue = fragCount - (impl->m_hashValueMask + 1);
- }
- else
- {
- impl->m_fragmentCount = tableDesc->FragmentCount;
- impl->m_replicaCount = 0;
- impl->m_hashValueMask = 0;
- impl->m_hashpointerValue = 0;
- }
-
- impl->m_tablespace_id = tableDesc->TablespaceId;
- impl->m_tablespace_version = tableDesc->TablespaceVersion;
-
- * ret = impl;
-
- NdbMem_Free((void*)tableDesc);
- if (version < MAKE_VERSION(5,1,3))
- {
- ;
- }
- else
- {
- DBUG_ASSERT(impl->m_fragmentCount > 0);
- }
- DBUG_RETURN(0);
-}
-
-/*****************************************************************
- * Create table and alter table
- */
-int
-NdbDictionaryImpl::createTable(NdbTableImpl &t)
-{
- DBUG_ENTER("NdbDictionaryImpl::createTable");
-
-
- bool autoIncrement = false;
- Uint64 initialValue = 0;
- for (Uint32 i = 0; i < t.m_columns.size(); i++) {
- const NdbColumnImpl* c = t.m_columns[i];
- assert(c != NULL);
- if (c->m_autoIncrement) {
- if (autoIncrement) {
- m_error.code = 4335;
- DBUG_RETURN(-1);
- }
- autoIncrement = true;
- initialValue = c->m_autoIncrementInitialValue;
- }
- }
-
- // if the new name has not been set, use the copied name
- if (t.m_newExternalName.empty())
- {
- if (!t.m_newExternalName.assign(t.m_externalName))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- }
- // create table
- if (m_receiver.createTable(m_ndb, t) != 0)
- DBUG_RETURN(-1);
- Uint32* data = (Uint32*)m_receiver.m_buffer.get_data();
- t.m_id = data[0];
- t.m_version = data[1];
-
- // update table def from DICT - by-pass cache
- NdbTableImpl* t2 =
- m_receiver.getTable(t.m_internalName, m_ndb.usingFullyQualifiedNames());
-
- // check if we got back same table
- if (t2 == NULL) {
- DBUG_PRINT("info", ("table %s dropped by another thread",
- t.m_internalName.c_str()));
- m_error.code = 283;
- DBUG_RETURN(-1);
- }
- if (t.m_id != t2->m_id || t.m_version != t2->m_version) {
- DBUG_PRINT("info", ("table %s re-created by another thread",
- t.m_internalName.c_str()));
- m_error.code = 283;
- delete t2;
- DBUG_RETURN(-1);
- }
-
- // auto-increment - use "t" because initial value is not in DICT
- {
- if (autoIncrement) {
- // XXX unlikely race condition - t.m_id may no longer be same table
- // the tuple id range is not used on input
- Ndb::TupleIdRange range;
- if (m_ndb.setTupleIdInNdb(&t, range, initialValue, false) == -1) {
- assert(m_ndb.theError.code != 0);
- m_error.code = m_ndb.theError.code;
- delete t2;
- DBUG_RETURN(-1);
- }
- }
- }
-
- // blob tables - use "t2" to get values set by kernel
- if (t2->m_noOfBlobs != 0 && createBlobTables(t, *t2) != 0) {
- int save_code = m_error.code;
- (void)dropTableGlobal(*t2);
- m_error.code = save_code;
- delete t2;
- DBUG_RETURN(-1);
- }
-
- // not entered in cache
- delete t2;
- DBUG_RETURN(0);
-}
-
-int
-NdbDictionaryImpl::createBlobTables(NdbTableImpl& orig, NdbTableImpl &t)
-{
- DBUG_ENTER("NdbDictionaryImpl::createBlobTables");
- for (unsigned i = 0; i < t.m_columns.size(); i++) {
- NdbColumnImpl & c = *t.m_columns[i];
- if (! c.getBlobType() || c.getPartSize() == 0)
- continue;
- NdbTableImpl bt;
- NdbBlob::getBlobTable(bt, &t, &c);
- NdbDictionary::Column::StorageType
- d = NdbDictionary::Column::StorageTypeDisk;
- if (orig.m_columns[i]->getStorageType() == d)
- bt.getColumn("DATA")->setStorageType(d);
- if (createTable(bt) != 0) {
- DBUG_RETURN(-1);
- }
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbDictInterface::createTable(Ndb & ndb,
- NdbTableImpl & impl)
-{
- DBUG_ENTER("NdbDictInterface::createTable");
- DBUG_RETURN(createOrAlterTable(ndb, impl, false));
-}
-
-int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
-{
- BaseString internalName(impl.m_internalName);
- const char * originalInternalName = internalName.c_str();
-
- DBUG_ENTER("NdbDictionaryImpl::alterTable");
- Ndb_local_table_info * local = 0;
- if((local= get_local_table_info(originalInternalName)) == 0)
- {
- m_error.code = 709;
- DBUG_RETURN(-1);
- }
-
- // Alter the table
- int ret = alterTableGlobal(*local->m_table_impl, impl);
- if(ret == 0)
- {
- m_globalHash->lock();
- m_globalHash->release(local->m_table_impl, 1);
- m_globalHash->unlock();
- m_localHash.drop(originalInternalName);
- }
- DBUG_RETURN(ret);
-}
-
-int NdbDictionaryImpl::alterTableGlobal(NdbTableImpl &old_impl,
- NdbTableImpl &impl)
-{
- DBUG_ENTER("NdbDictionaryImpl::alterTableGlobal");
- // Alter the table
- int ret = m_receiver.alterTable(m_ndb, impl);
- old_impl.m_status = NdbDictionary::Object::Invalid;
- if(ret == 0){
- DBUG_RETURN(ret);
- }
- ERR_RETURN(getNdbError(), ret);
-}
-
-int
-NdbDictInterface::alterTable(Ndb & ndb,
- NdbTableImpl & impl)
-{
- DBUG_ENTER("NdbDictInterface::alterTable");
- DBUG_RETURN(createOrAlterTable(ndb, impl, true));
-}
-
-int
-NdbDictInterface::createOrAlterTable(Ndb & ndb,
- NdbTableImpl & impl,
- bool alter)
-{
- unsigned i, err;
- char *ts_names[MAX_NDB_PARTITIONS];
- DBUG_ENTER("NdbDictInterface::createOrAlterTable");
-
- impl.computeAggregates();
-
- if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){
- m_error.code= 4317;
- DBUG_RETURN(-1);
- }
- unsigned sz = impl.m_columns.size();
- if (sz > NDB_MAX_ATTRIBUTES_IN_TABLE){
- m_error.code= 4318;
- DBUG_RETURN(-1);
- }
-
- // Check if any changes for alter table
-
- // Name change
- if (!impl.m_newExternalName.empty()) {
- if (alter)
- {
- AlterTableReq::setNameFlag(impl.m_changeMask, true);
- }
- if (!impl.m_externalName.assign(impl.m_newExternalName))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_newExternalName.clear();
- }
- // Definition change (frm)
- if (!impl.m_newFrm.empty())
- {
- if (alter)
- {
- AlterTableReq::setFrmFlag(impl.m_changeMask, true);
- }
- if (impl.m_frm.assign(impl.m_newFrm.get_data(), impl.m_newFrm.length()))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_newFrm.clear();
- }
- // Change FragmentData (fragment identity, state, tablespace id)
- if (!impl.m_new_fd.empty())
- {
- if (alter)
- {
- AlterTableReq::setFragDataFlag(impl.m_changeMask, true);
- }
- if (impl.m_fd.assign(impl.m_new_fd.get_data(), impl.m_new_fd.length()))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_new_fd.clear();
- }
- // Change Tablespace Name Data
- if (!impl.m_new_ts_name.empty())
- {
- if (alter)
- {
- AlterTableReq::setTsNameFlag(impl.m_changeMask, true);
- }
- if (impl.m_ts_name.assign(impl.m_new_ts_name.get_data(),
- impl.m_new_ts_name.length()))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_new_ts_name.clear();
- }
- // Change Range/List Data
- if (!impl.m_new_range.empty())
- {
- if (alter)
- {
- AlterTableReq::setRangeListFlag(impl.m_changeMask, true);
- }
- if (impl.m_range.assign(impl.m_new_range.get_data(),
- impl.m_new_range.length()))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_new_range.clear();
- }
- // Change Tablespace Data
- if (!impl.m_new_ts.empty())
- {
- if (alter)
- {
- AlterTableReq::setTsFlag(impl.m_changeMask, true);
- }
- if (impl.m_ts.assign(impl.m_new_ts.get_data(),
- impl.m_new_ts.length()))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.m_new_ts.clear();
- }
-
-
- /*
- TODO RONM: Here I need to insert checks for fragment array and
- range or list array
- */
-
- //validate();
- //aggregate();
-
- const BaseString internalName(
- ndb.internalize_table_name(impl.m_externalName.c_str()));
- if (!impl.m_internalName.assign(internalName))
- {
- m_error.code= 4000;
- DBUG_RETURN(-1);
- }
- impl.updateMysqlName();
- DictTabInfo::Table *tmpTab;
-
- tmpTab = (DictTabInfo::Table*)NdbMem_Allocate(sizeof(DictTabInfo::Table));
- if (!tmpTab)
- {
- m_error.code = 4000;
- DBUG_RETURN(-1);
- }
- tmpTab->init();
- BaseString::snprintf(tmpTab->TableName,
- sizeof(tmpTab->TableName),
- internalName.c_str());
-
- Uint32 distKeys= 0;
- for(i = 0; i<sz; i++) {
- const NdbColumnImpl * col = impl.m_columns[i];
- if (col == NULL) {
- m_error.code = 4272;
- NdbMem_Free((void*)tmpTab);
- DBUG_RETURN(-1);
- }
- if (col->m_distributionKey)
- {
- distKeys++;
- }
- }
- if (distKeys == impl.m_noOfKeys)
- distKeys= 0;
- impl.m_noOfDistributionKeys= distKeys;
-
-
- // Check max length of frm data
- if (impl.m_frm.length() > MAX_FRM_DATA_SIZE){
- m_error.code= 1229;
- NdbMem_Free((void*)tmpTab);
- DBUG_RETURN(-1);
- }
- /*
- TODO RONM: This needs to change to dynamic arrays instead
- Frm Data, FragmentData, TablespaceData, RangeListData, TsNameData
- */
- tmpTab->FrmLen = impl.m_frm.length();
- memcpy(tmpTab->FrmData, impl.m_frm.get_data(), impl.m_frm.length());
-
- tmpTab->FragmentDataLen = impl.m_fd.length();
- memcpy(tmpTab->FragmentData, impl.m_fd.get_data(), impl.m_fd.length());
-
- tmpTab->TablespaceDataLen = impl.m_ts.length();
- memcpy(tmpTab->TablespaceData, impl.m_ts.get_data(), impl.m_ts.length());
-
- tmpTab->RangeListDataLen = impl.m_range.length();
- memcpy(tmpTab->RangeListData, impl.m_range.get_data(),
- impl.m_range.length());
-
- memcpy(ts_names, impl.m_ts_name.get_data(),
- impl.m_ts_name.length());
-
- tmpTab->FragmentCount= impl.m_fragmentCount;
- tmpTab->TableLoggedFlag = impl.m_logging;
- tmpTab->TableTemporaryFlag = impl.m_temporary;
- tmpTab->RowGCIFlag = impl.m_row_gci;
- tmpTab->RowChecksumFlag = impl.m_row_checksum;
- tmpTab->TableKValue = impl.m_kvalue;
- tmpTab->MinLoadFactor = impl.m_minLoadFactor;
- tmpTab->MaxLoadFactor = impl.m_maxLoadFactor;
- tmpTab->TableType = DictTabInfo::UserTable;
- tmpTab->PrimaryTableId = impl.m_primaryTableId;
- tmpTab->NoOfAttributes = sz;
- tmpTab->MaxRowsHigh = (Uint32)(impl.m_max_rows >> 32);
- tmpTab->MaxRowsLow = (Uint32)(impl.m_max_rows & 0xFFFFFFFF);
- tmpTab->MinRowsHigh = (Uint32)(impl.m_min_rows >> 32);
- tmpTab->MinRowsLow = (Uint32)(impl.m_min_rows & 0xFFFFFFFF);
- tmpTab->DefaultNoPartFlag = impl.m_default_no_part_flag;
- tmpTab->LinearHashFlag = impl.m_linear_flag;
- tmpTab->SingleUserMode = impl.m_single_user_mode;
- tmpTab->ForceVarPartFlag = impl.m_force_var_part;
-
- if (impl.m_ts_name.length())
- {
- char **ts_name_ptr= (char**)ts_names;
- i= 0;
- do
- {
- NdbTablespaceImpl tmp;
- if (*ts_name_ptr)
- {
- if(get_filegroup(tmp, NdbDictionary::Object::Tablespace,
- (const char*)*ts_name_ptr) == 0)
- {
- tmpTab->TablespaceData[2*i] = tmp.m_id;
- tmpTab->TablespaceData[2*i + 1] = tmp.m_version;
- }
- else
- {
- NdbMem_Free((void*)tmpTab);
- DBUG_RETURN(-1);
- }
- }
- else
- {
- /*
- No tablespace used, set tablespace id to NULL
- */
- tmpTab->TablespaceData[2*i] = RNIL;
- tmpTab->TablespaceData[2*i + 1] = 0;
- }
- ts_name_ptr++;
- } while (++i < tmpTab->FragmentCount);
- tmpTab->TablespaceDataLen= 4*i;
- }
-
- tmpTab->FragmentType = getKernelConstant(impl.m_fragmentType,
- fragmentTypeMapping,
- DictTabInfo::AllNodesSmallTable);
- tmpTab->TableVersion = rand();
-
- const char *tablespace_name= impl.m_tablespace_name.c_str();
-loop:
- if(impl.m_tablespace_id != ~(Uint32)0)
- {
- tmpTab->TablespaceId = impl.m_tablespace_id;
- tmpTab->TablespaceVersion = impl.m_tablespace_version;
- }
- else if(strlen(tablespace_name))
- {
- NdbTablespaceImpl tmp;
- if(get_filegroup(tmp, NdbDictionary::Object::Tablespace,
- tablespace_name) == 0)
- {
- tmpTab->TablespaceId = tmp.m_id;
- tmpTab->TablespaceVersion = tmp.m_version;
- }
- else
- {
- // error set by get filegroup
- if (m_error.code == 723)
- m_error.code = 755;
-
- NdbMem_Free((void*)tmpTab);
- DBUG_RETURN(-1);
- }
- }
- else
- {
- for(i = 0; i<sz; i++)
- {
- if(impl.m_columns[i]->m_storageType == NDB_STORAGETYPE_DISK)
- {
- tablespace_name = "DEFAULT-TS";
- goto loop;
- }
- }
- }
-
- UtilBufferWriter w(m_buffer);
- SimpleProperties::UnpackStatus s;
- s = SimpleProperties::pack(w,
- tmpTab,
- DictTabInfo::TableMapping,
- DictTabInfo::TableMappingSize, true);
-
- if(s != SimpleProperties::Eof){
- abort();
- }
- NdbMem_Free((void*)tmpTab);
-
- DBUG_PRINT("info",("impl.m_noOfDistributionKeys: %d impl.m_noOfKeys: %d distKeys: %d",
- impl.m_noOfDistributionKeys, impl.m_noOfKeys, distKeys));
- if (distKeys == impl.m_noOfKeys)
- distKeys= 0;
- impl.m_noOfDistributionKeys= distKeys;
-
- for(i = 0; i<sz; i++){
- const NdbColumnImpl * col = impl.m_columns[i];
- if(col == 0)
- continue;
-
- DBUG_PRINT("info",("column: %s(%d) col->m_distributionKey: %d",
- col->m_name.c_str(), i, col->m_distributionKey));
- DictTabInfo::Attribute tmpAttr; tmpAttr.init();
- BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName),
- col->m_name.c_str());
- tmpAttr.AttributeId = col->m_attrId;
- tmpAttr.AttributeKeyFlag = col->m_pk;
- tmpAttr.AttributeNullableFlag = col->m_nullable;
- tmpAttr.AttributeDKey = distKeys ? col->m_distributionKey : 0;
-
- tmpAttr.AttributeExtType = (Uint32)col->m_type;
- tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF);
- tmpAttr.AttributeExtScale = col->m_scale;
- tmpAttr.AttributeExtLength = col->m_length;
- if(col->m_storageType == NDB_STORAGETYPE_DISK)
- tmpAttr.AttributeArrayType = NDB_ARRAYTYPE_FIXED;
- else
- tmpAttr.AttributeArrayType = col->m_arrayType;
-
- if(col->m_pk)
- tmpAttr.AttributeStorageType = NDB_STORAGETYPE_MEMORY;
- else
- tmpAttr.AttributeStorageType = col->m_storageType;
-
- if(col->getBlobType())
- tmpAttr.AttributeStorageType = NDB_STORAGETYPE_MEMORY;
-
- // check type and compute attribute size and array size
- if (! tmpAttr.translateExtType()) {
- m_error.code= 703;
- DBUG_RETURN(-1);
- }
- // charset is defined exactly for char types
- if (col->getCharType() != (col->m_cs != NULL)) {
- m_error.code= 703;
- DBUG_RETURN(-1);
- }
- // primary key type check
- if (col->m_pk &&
- (err = NdbSqlUtil::check_column_for_pk(col->m_type, col->m_cs)))
- {
- m_error.code= err;
- DBUG_RETURN(-1);
- }
- // distribution key not supported for Char attribute
- if (distKeys && col->m_distributionKey && col->m_cs != NULL) {
- // we can allow this for non-var char where strxfrm does nothing
- if (col->m_type == NdbDictionary::Column::Char &&
- (col->m_cs->state & MY_CS_BINSORT))
- ;
- else {
- m_error.code= 745;
- DBUG_RETURN(-1);
- }
- }
- // charset in upper half of precision
- if (col->getCharType()) {
- tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16);
- }
-
- tmpAttr.AttributeAutoIncrement = col->m_autoIncrement;
- BaseString::snprintf(tmpAttr.AttributeDefaultValue,
- sizeof(tmpAttr.AttributeDefaultValue),
- col->m_defaultValue.c_str());
- s = SimpleProperties::pack(w,
- &tmpAttr,
- DictTabInfo::AttributeMapping,
- DictTabInfo::AttributeMappingSize, true);
- w.add(DictTabInfo::AttributeEnd, 1);
- }
-
- int ret;
-
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = m_buffer.length() / 4;
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- if (alter) {
- tSignal.theVerId_signalNumber = GSN_ALTER_TABLE_REQ;
- tSignal.theLength = AlterTableReq::SignalLength;
-
- AlterTableReq * req = CAST_PTR(AlterTableReq, tSignal.getDataPtrSend());
-
- req->senderRef = m_reference;
- req->senderData = 0;
- req->changeMask = impl.m_changeMask;
- req->tableId = impl.m_id;
- req->tableVersion = impl.m_version;;
-
- int errCodes[] = { AlterTableRef::NotMaster, AlterTableRef::Busy, 0 };
- ret = dictSignal(&tSignal, ptr, 1,
- 0, // master
- WAIT_ALTER_TAB_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- errCodes);
-
- if(m_error.code == AlterTableRef::InvalidTableVersion) {
- // Clear caches and try again
- DBUG_RETURN(INCOMPATIBLE_VERSION);
- }
- } else {
- tSignal.theVerId_signalNumber = GSN_CREATE_TABLE_REQ;
- tSignal.theLength = CreateTableReq::SignalLength;
-
- CreateTableReq * req = CAST_PTR(CreateTableReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- int errCodes[] = { CreateTableRef::Busy, CreateTableRef::NotMaster, 0 };
- ret = dictSignal(&tSignal, ptr, 1,
- 0, // master node
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- errCodes);
- }
-
- DBUG_RETURN(ret);
-}
-
-void
-NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const CreateTableConf* const conf=
- CAST_CONSTPTR(CreateTableConf, signal->getDataPtr());
- m_buffer.grow(4 * 2); // 2 words
- Uint32* data = (Uint32*)m_buffer.get_data();
- data[0] = conf->tableId;
- data[1] = conf->tableVersion;
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execCREATE_TABLE_REF(NdbApiSignal * sig,
- LinearSectionPtr ptr[3])
-{
- const CreateTableRef* ref = CAST_CONSTPTR(CreateTableRef, sig->getDataPtr());
- m_error.code= ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execALTER_TABLE_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execALTER_TABLE_REF(NdbApiSignal * sig,
- LinearSectionPtr ptr[3])
-{
- const AlterTableRef * ref = CAST_CONSTPTR(AlterTableRef, sig->getDataPtr());
- m_error.code= ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-/*****************************************************************
- * Drop table
- */
-int
-NdbDictionaryImpl::dropTable(const char * name)
-{
- DBUG_ENTER("NdbDictionaryImpl::dropTable");
- DBUG_PRINT("enter",("name: %s", name));
- ASSERT_NOT_MYSQLD;
- NdbTableImpl * tab = getTable(name);
- if(tab == 0){
- DBUG_RETURN(-1);
- }
- int ret = dropTable(* tab);
- // If table stored in cache is incompatible with the one in the kernel
- // we must clear the cache and try again
- if (ret == INCOMPATIBLE_VERSION) {
- const BaseString internalTableName(m_ndb.internalize_table_name(name));
- DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName.c_str()));
- m_localHash.drop(internalTableName.c_str());
- m_globalHash->lock();
- m_globalHash->release(tab, 1);
- m_globalHash->unlock();
- DBUG_RETURN(dropTable(name));
- }
-
- DBUG_RETURN(ret);
-}
-
-int
-NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
-{
- int res;
- const char * name = impl.getName();
- if(impl.m_status == NdbDictionary::Object::New){
- return dropTable(name);
- }
-
- if (impl.m_indexType != NdbDictionary::Object::TypeUndefined)
- {
- m_receiver.m_error.code= 1228;
- return -1;
- }
-
- List list;
- if ((res = listIndexes(list, impl.m_id)) == -1){
- return -1;
- }
- for (unsigned i = 0; i < list.count; i++) {
- const List::Element& element = list.elements[i];
- if ((res = dropIndex(element.name, name)) == -1)
- {
- return -1;
- }
- }
-
- if (impl.m_noOfBlobs != 0) {
- if (dropBlobTables(impl) != 0){
- return -1;
- }
- }
-
- int ret = m_receiver.dropTable(impl);
- if(ret == 0 || m_error.code == 709 || m_error.code == 723){
- const char * internalTableName = impl.m_internalName.c_str();
-
-
- m_localHash.drop(internalTableName);
- m_globalHash->lock();
- m_globalHash->release(&impl, 1);
- m_globalHash->unlock();
-
- return 0;
- }
-
- return ret;
-}
-
-int
-NdbDictionaryImpl::dropTableGlobal(NdbTableImpl & impl)
-{
- int res;
- DBUG_ENTER("NdbDictionaryImpl::dropTableGlobal");
- DBUG_ASSERT(impl.m_status != NdbDictionary::Object::New);
- DBUG_ASSERT(impl.m_indexType == NdbDictionary::Object::TypeUndefined);
-
- List list;
- if ((res = listIndexes(list, impl.m_id)) == -1){
- ERR_RETURN(getNdbError(), -1);
- }
- for (unsigned i = 0; i < list.count; i++) {
- const List::Element& element = list.elements[i];
- NdbIndexImpl *idx= getIndexGlobal(element.name, impl);
- if (idx == NULL)
- {
- ERR_RETURN(getNdbError(), -1);
- }
- if ((res = dropIndexGlobal(*idx)) == -1)
- {
- releaseIndexGlobal(*idx, 1);
- ERR_RETURN(getNdbError(), -1);
- }
- releaseIndexGlobal(*idx, 1);
- }
-
- if (impl.m_noOfBlobs != 0) {
- if (dropBlobTables(impl) != 0){
- ERR_RETURN(getNdbError(), -1);
- }
- }
-
- int ret = m_receiver.dropTable(impl);
- impl.m_status = NdbDictionary::Object::Invalid;
- if(ret == 0 || m_error.code == 709 || m_error.code == 723)
- {
- DBUG_RETURN(0);
- }
-
- ERR_RETURN(getNdbError(), ret);
-}
-
-int
-NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t)
-{
- DBUG_ENTER("NdbDictionaryImpl::dropBlobTables");
- for (unsigned i = 0; i < t.m_columns.size(); i++) {
- NdbColumnImpl & c = *t.m_columns[i];
- if (! c.getBlobType() || c.getPartSize() == 0)
- continue;
- NdbTableImpl* bt = c.m_blobTable;
- if (bt == NULL) {
- DBUG_PRINT("info", ("col %s: blob table pointer is NULL",
- c.m_name.c_str()));
- continue; // "force" mode on
- }
- // drop directly - by-pass cache
- int ret = m_receiver.dropTable(*c.m_blobTable);
- if (ret != 0) {
- DBUG_PRINT("info", ("col %s: blob table %s: error %d",
- c.m_name.c_str(), bt->m_internalName.c_str(), m_error.code));
- if (! (ret == 709 || ret == 723)) // "force" mode on
- ERR_RETURN(getNdbError(), -1);
- }
- // leave c.m_blobTable defined
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbDictInterface::dropTable(const NdbTableImpl & impl)
-{
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_DROP_TABLE_REQ;
- tSignal.theLength = DropTableReq::SignalLength;
-
- DropTableReq * req = CAST_PTR(DropTableReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->tableId = impl.m_id;
- req->tableVersion = impl.m_version;
-
- int errCodes[] =
- { DropTableRef::NoDropTableRecordAvailable,
- DropTableRef::NotMaster,
- DropTableRef::Busy, 0 };
- int r = dictSignal(&tSignal, 0, 0,
- 0, // master
- WAIT_DROP_TAB_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- errCodes);
- if(m_error.code == DropTableRef::InvalidTableVersion) {
- // Clear caches and try again
- return INCOMPATIBLE_VERSION;
- }
- return r;
-}
-
-void
-NdbDictInterface::execDROP_TABLE_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execDROP_TABLE_CONF");
- //DropTableConf* const conf = CAST_CONSTPTR(DropTableConf, signal->getDataPtr());
-
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execDROP_TABLE_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execDROP_TABLE_REF");
- const DropTableRef* ref = CAST_CONSTPTR(DropTableRef, signal->getDataPtr());
- m_error.code= ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-int
-NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
-{
- const char * internalTableName = impl.m_internalName.c_str();
- DBUG_ENTER("NdbDictionaryImpl::invalidateObject");
- DBUG_PRINT("enter", ("internal_name: %s", internalTableName));
-
- m_localHash.drop(internalTableName);
- m_globalHash->lock();
- m_globalHash->release(&impl, 1);
- m_globalHash->unlock();
- DBUG_RETURN(0);
-}
-
-int
-NdbDictionaryImpl::removeCachedObject(NdbTableImpl & impl)
-{
- const char * internalTableName = impl.m_internalName.c_str();
- DBUG_ENTER("NdbDictionaryImpl::removeCachedObject");
- DBUG_PRINT("enter", ("internal_name: %s", internalTableName));
-
- m_localHash.drop(internalTableName);
- m_globalHash->lock();
- m_globalHash->release(&impl);
- m_globalHash->unlock();
- DBUG_RETURN(0);
-}
-
-int
-NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst,
- NdbTableImpl* tab,
- const NdbTableImpl* prim)
-{
- DBUG_ENTER("NdbDictInterface::create_index_obj_from_table");
- NdbIndexImpl *idx = new NdbIndexImpl();
- if (idx == NULL)
- {
- errno = ENOMEM;
- return -1;
- }
- idx->m_version = tab->m_version;
- idx->m_status = tab->m_status;
- idx->m_id = tab->m_id;
- if (!idx->m_externalName.assign(tab->getName()) ||
- !idx->m_tableName.assign(prim->m_externalName))
- {
- delete idx;
- errno = ENOMEM;
- return -1;
- }
- NdbDictionary::Object::Type type = idx->m_type = tab->m_indexType;
- idx->m_logging = tab->m_logging;
- idx->m_temporary = tab->m_temporary;
- // skip last attribute (NDB$PK or NDB$TNODE)
-
- const Uint32 distKeys = prim->m_noOfDistributionKeys;
- Uint32 keyCount = (distKeys ? distKeys : prim->m_noOfKeys);
-
- unsigned i;
- for(i = 0; i+1<tab->m_columns.size(); i++){
- NdbColumnImpl* org = tab->m_columns[i];
-
- NdbColumnImpl* col = new NdbColumnImpl;
- if (col == NULL)
- {
- errno = ENOMEM;
- delete idx;
- return -1;
- }
- // Copy column definition
- *col = * org;
- if (idx->m_columns.push_back(col))
- {
- delete col;
- delete idx;
- return -1;
- }
-
- /**
- * reverse map
- */
- const NdbColumnImpl* primCol = prim->getColumn(col->getName());
- int key_id = primCol->getColumnNo();
- int fill = -1;
- idx->m_key_ids.fill(key_id, fill);
- idx->m_key_ids[key_id] = i;
- col->m_keyInfoPos = key_id;
-
- if(type == NdbDictionary::Object::OrderedIndex &&
- (primCol->m_distributionKey ||
- (distKeys == 0 && primCol->getPrimaryKey())))
- {
- keyCount--;
- org->m_distributionKey = 1;
- }
- }
-
- if(keyCount == 0)
- {
- tab->m_noOfDistributionKeys = (distKeys ? distKeys : prim->m_noOfKeys);
- }
- else
- {
- for(i = 0; i+1<tab->m_columns.size(); i++)
- tab->m_columns[i]->m_distributionKey = 0;
- }
-
- idx->m_table_id = prim->getObjectId();
- idx->m_table_version = prim->getObjectVersion();
-
- * dst = idx;
- DBUG_PRINT("exit", ("m_id: %d m_version: %d", idx->m_id, idx->m_version));
- DBUG_RETURN(0);
-}
-
-/*****************************************************************
- * Create index
- */
-int
-NdbDictionaryImpl::createIndex(NdbIndexImpl &ix)
-{
- ASSERT_NOT_MYSQLD;
- NdbTableImpl* tab = getTable(ix.getTable());
- if(tab == 0){
- m_error.code = 4249;
- return -1;
- }
-
- return m_receiver.createIndex(m_ndb, ix, * tab);
-}
-
-int
-NdbDictionaryImpl::createIndex(NdbIndexImpl &ix, NdbTableImpl &tab)
-{
- return m_receiver.createIndex(m_ndb, ix, tab);
-}
-
-int
-NdbDictInterface::createIndex(Ndb & ndb,
- const NdbIndexImpl & impl,
- const NdbTableImpl & table)
-{
- //validate();
- //aggregate();
- unsigned i, err;
- UtilBufferWriter w(m_buffer);
- const size_t len = strlen(impl.m_externalName.c_str()) + 1;
- if(len > MAX_TAB_NAME_SIZE) {
- m_error.code = 4241;
- return -1;
- }
- const BaseString internalName(
- ndb.internalize_index_name(&table, impl.getName()));
- w.add(DictTabInfo::TableName, internalName.c_str());
- w.add(DictTabInfo::TableLoggedFlag, impl.m_logging);
- w.add(DictTabInfo::TableTemporaryFlag, impl.m_temporary);
-
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_CREATE_INDX_REQ;
- tSignal.theLength = CreateIndxReq::SignalLength;
-
- CreateIndxReq * const req = CAST_PTR(CreateIndxReq, tSignal.getDataPtrSend());
-
- req->setUserRef(m_reference);
- req->setConnectionPtr(0);
- req->setRequestType(CreateIndxReq::RT_USER);
-
- Uint32 it = getKernelConstant(impl.m_type,
- indexTypeMapping,
- DictTabInfo::UndefTableType);
-
- if(it == DictTabInfo::UndefTableType){
- m_error.code = 4250;
- return -1;
- }
- req->setIndexType((DictTabInfo::TableType) it);
-
- req->setTableId(table.m_id);
- req->setOnline(true);
- AttributeList attributeList;
- attributeList.sz = impl.m_columns.size();
- for(i = 0; i<attributeList.sz; i++){
- const NdbColumnImpl* col =
- table.getColumn(impl.m_columns[i]->m_name.c_str());
- if(col == 0){
- m_error.code = 4247;
- return -1;
- }
- // Copy column definition XXX must be wrong, overwrites
- *impl.m_columns[i] = *col;
-
- // index key type check
- if (it == DictTabInfo::UniqueHashIndex &&
- (err = NdbSqlUtil::check_column_for_hash_index(col->m_type, col->m_cs))
- ||
- it == DictTabInfo::OrderedIndex &&
- (err = NdbSqlUtil::check_column_for_ordered_index(col->m_type, col->m_cs)))
- {
- m_error.code = err;
- return -1;
- }
- // API uses external column number to talk to DICT
- attributeList.id[i] = col->m_column_no;
- }
- LinearSectionPtr ptr[2];
- ptr[0].p = (Uint32*)&attributeList;
- ptr[0].sz = 1 + attributeList.sz;
- ptr[1].p = (Uint32*)m_buffer.get_data();
- ptr[1].sz = m_buffer.length() >> 2; //BUG?
-
- int errCodes[] = { CreateIndxRef::Busy, CreateIndxRef::NotMaster, 0 };
- return dictSignal(&tSignal, ptr, 2,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- errCodes);
-}
-
-void
-NdbDictInterface::execCREATE_INDX_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execCREATE_INDX_REF(NdbApiSignal * sig,
- LinearSectionPtr ptr[3])
-{
- const CreateIndxRef* ref = CAST_CONSTPTR(CreateIndxRef, sig->getDataPtr());
- m_error.code = ref->getErrorCode();
- if(m_error.code == ref->NotMaster)
- m_masterNodeId= ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-/*****************************************************************
- * Drop index
- */
-int
-NdbDictionaryImpl::dropIndex(const char * indexName,
- const char * tableName)
-{
- ASSERT_NOT_MYSQLD;
- NdbIndexImpl * idx = getIndex(indexName, tableName);
- if (idx == 0) {
- m_error.code = 4243;
- return -1;
- }
- int ret = dropIndex(*idx, tableName);
- // If index stored in cache is incompatible with the one in the kernel
- // we must clear the cache and try again
- if (ret == INCOMPATIBLE_VERSION) {
- const BaseString internalIndexName((tableName)
- ?
- m_ndb.internalize_index_name(getTable(tableName), indexName)
- :
- m_ndb.internalize_table_name(indexName)); // Index is also a table
-
- m_localHash.drop(internalIndexName.c_str());
- m_globalHash->lock();
- m_globalHash->release(idx->m_table, 1);
- m_globalHash->unlock();
- return dropIndex(indexName, tableName);
- }
-
- return ret;
-}
-
-int
-NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
-{
- const char * indexName = impl.getName();
- if (tableName || m_ndb.usingFullyQualifiedNames()) {
- NdbTableImpl * timpl = impl.m_table;
-
- if (timpl == 0) {
- m_error.code = 709;
- return -1;
- }
-
- const BaseString internalIndexName((tableName)
- ?
- m_ndb.internalize_index_name(getTable(tableName), indexName)
- :
- m_ndb.internalize_table_name(indexName)); // Index is also a table
-
- if(impl.m_status == NdbDictionary::Object::New){
- return dropIndex(indexName, tableName);
- }
-
- int ret= dropIndexGlobal(impl);
- if (ret == 0)
- {
- m_globalHash->lock();
- m_globalHash->release(impl.m_table, 1);
- m_globalHash->unlock();
- m_localHash.drop(internalIndexName.c_str());
- }
- return ret;
- }
-
- m_error.code = 4243;
- return -1;
-}
-
-int
-NdbDictionaryImpl::dropIndexGlobal(NdbIndexImpl & impl)
-{
- DBUG_ENTER("NdbDictionaryImpl::dropIndexGlobal");
- int ret = m_receiver.dropIndex(impl, *impl.m_table);
- impl.m_status = NdbDictionary::Object::Invalid;
- if(ret == 0)
- {
- DBUG_RETURN(0);
- }
- ERR_RETURN(getNdbError(), ret);
-}
-
-int
-NdbDictInterface::dropIndex(const NdbIndexImpl & impl,
- const NdbTableImpl & timpl)
-{
- DBUG_ENTER("NdbDictInterface::dropIndex");
- DBUG_PRINT("enter", ("indexId: %d indexVersion: %d",
- timpl.m_id, timpl.m_version));
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_DROP_INDX_REQ;
- tSignal.theLength = DropIndxReq::SignalLength;
-
- DropIndxReq * const req = CAST_PTR(DropIndxReq, tSignal.getDataPtrSend());
- req->setUserRef(m_reference);
- req->setConnectionPtr(0);
- req->setRequestType(DropIndxReq::RT_USER);
- req->setTableId(~0); // DICT overwrites
- req->setIndexId(timpl.m_id);
- req->setIndexVersion(timpl.m_version);
-
- int errCodes[] = { DropIndxRef::Busy, DropIndxRef::NotMaster, 0 };
- int r = dictSignal(&tSignal, 0, 0,
- 0, // master
- WAIT_DROP_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- errCodes);
- if(m_error.code == DropIndxRef::InvalidIndexVersion) {
- // Clear caches and try again
- ERR_RETURN(m_error, INCOMPATIBLE_VERSION);
- }
- ERR_RETURN(m_error, r);
-}
-
-void
-NdbDictInterface::execDROP_INDX_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execDROP_INDX_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const DropIndxRef* ref = CAST_CONSTPTR(DropIndxRef, signal->getDataPtr());
- m_error.code = ref->getErrorCode();
- if(m_error.code == ref->NotMaster)
- m_masterNodeId= ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-/*****************************************************************
- * Create event
- */
-
-int
-NdbDictionaryImpl::createEvent(NdbEventImpl & evnt)
-{
- DBUG_ENTER("NdbDictionaryImpl::createEvent");
- int i;
- NdbTableImpl* tab= evnt.m_tableImpl;
- if (tab == 0)
- {
- tab= getTable(evnt.getTableName());
- if(tab == 0){
- DBUG_PRINT("info",("NdbDictionaryImpl::createEvent: table not found: %s",
- evnt.getTableName()));
- ERR_RETURN(getNdbError(), -1);
- }
- evnt.setTable(tab);
- }
-
- DBUG_PRINT("info",("Table: id: %d version: %d", tab->m_id, tab->m_version));
-
- NdbTableImpl &table = *evnt.m_tableImpl;
-
- int attributeList_sz = evnt.m_attrIds.size();
-
- for (i = 0; i < attributeList_sz; i++) {
- NdbColumnImpl *col_impl = table.getColumn(evnt.m_attrIds[i]);
- if (col_impl) {
- evnt.m_facade->addColumn(*(col_impl->m_facade));
- } else {
- ndbout_c("Attr id %u in table %s not found", evnt.m_attrIds[i],
- evnt.getTableName());
- m_error.code= 4713;
- ERR_RETURN(getNdbError(), -1);
- }
- }
-
- evnt.m_attrIds.clear();
-
- attributeList_sz = evnt.m_columns.size();
-
- DBUG_PRINT("info",("Event on tableId=%d, tableVersion=%d, event name %s, no of columns %d",
- table.m_id, table.m_version,
- evnt.m_name.c_str(),
- evnt.m_columns.size()));
-
- int pk_count = 0;
- evnt.m_attrListBitmask.clear();
-
- for(i = 0; i<attributeList_sz; i++){
- const NdbColumnImpl* col =
- table.getColumn(evnt.m_columns[i]->m_name.c_str());
- if(col == 0){
- m_error.code= 4247;
- ERR_RETURN(getNdbError(), -1);
- }
- // Copy column definition
- *evnt.m_columns[i] = *col;
-
- if(col->m_pk){
- pk_count++;
- }
-
- evnt.m_attrListBitmask.set(col->m_attrId);
- }
-
- // Sort index attributes according to primary table (using insertion sort)
- for(i = 1; i < attributeList_sz; i++) {
- NdbColumnImpl* temp = evnt.m_columns[i];
- unsigned int j = i;
- while((j > 0) && (evnt.m_columns[j - 1]->m_attrId > temp->m_attrId)) {
- evnt.m_columns[j] = evnt.m_columns[j - 1];
- j--;
- }
- evnt.m_columns[j] = temp;
- }
- // Check for illegal duplicate attributes
- for(i = 1; i<attributeList_sz; i++) {
- if (evnt.m_columns[i-1]->m_attrId == evnt.m_columns[i]->m_attrId) {
- m_error.code= 4258;
- ERR_RETURN(getNdbError(), -1);
- }
- }
-
-#ifdef EVENT_DEBUG
- char buf[128] = {0};
- evnt.m_attrListBitmask.getText(buf);
- ndbout_c("createEvent: mask = %s", buf);
-#endif
-
- // NdbDictInterface m_receiver;
- if (m_receiver.createEvent(m_ndb, evnt, 0 /* getFlag unset */) != 0)
- ERR_RETURN(getNdbError(), -1);
-
- // Create blob events
- if (evnt.m_mergeEvents && createBlobEvents(evnt) != 0) {
- int save_code = m_error.code;
- (void)dropEvent(evnt.m_name.c_str());
- m_error.code = save_code;
- ERR_RETURN(getNdbError(), -1);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbDictionaryImpl::createBlobEvents(NdbEventImpl& evnt)
-{
- DBUG_ENTER("NdbDictionaryImpl::createBlobEvents");
- NdbTableImpl& t = *evnt.m_tableImpl;
- Uint32 n = t.m_noOfBlobs;
- Uint32 i;
- for (i = 0; i < evnt.m_columns.size() && n > 0; i++) {
- NdbColumnImpl & c = *evnt.m_columns[i];
- if (! c.getBlobType() || c.getPartSize() == 0)
- continue;
- n--;
- NdbEventImpl blob_evnt;
- NdbBlob::getBlobEvent(blob_evnt, &evnt, &c);
- if (createEvent(blob_evnt) != 0)
- ERR_RETURN(getNdbError(), -1);
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbDictInterface::createEvent(class Ndb & ndb,
- NdbEventImpl & evnt,
- int getFlag)
-{
- DBUG_ENTER("NdbDictInterface::createEvent");
- DBUG_PRINT("enter",("getFlag=%d",getFlag));
-
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_CREATE_EVNT_REQ;
- if (getFlag)
- tSignal.theLength = CreateEvntReq::SignalLengthGet;
- else
- tSignal.theLength = CreateEvntReq::SignalLengthCreate;
-
- CreateEvntReq * const req = CAST_PTR(CreateEvntReq, tSignal.getDataPtrSend());
-
- req->setUserRef(m_reference);
- req->setUserData(0);
-
- if (getFlag) {
- // getting event from Dictionary
- req->setRequestType(CreateEvntReq::RT_USER_GET);
- } else {
- DBUG_PRINT("info",("tableId: %u tableVersion: %u",
- evnt.m_tableImpl->m_id,
- evnt.m_tableImpl->m_version));
- // creating event in Dictionary
- req->setRequestType(CreateEvntReq::RT_USER_CREATE);
- req->setTableId(evnt.m_tableImpl->m_id);
- req->setTableVersion(evnt.m_tableImpl->m_version);
- req->setAttrListBitmask(evnt.m_attrListBitmask);
- req->setEventType(evnt.mi_type);
- req->clearFlags();
- if (evnt.m_rep & NdbDictionary::Event::ER_ALL)
- req->setReportAll();
- if (evnt.m_rep & NdbDictionary::Event::ER_SUBSCRIBE)
- req->setReportSubscribe();
- }
-
- UtilBufferWriter w(m_buffer);
-
- const size_t len = strlen(evnt.m_name.c_str()) + 1;
- if(len > MAX_TAB_NAME_SIZE) {
- m_error.code= 4241;
- ERR_RETURN(getNdbError(), -1);
- }
-
- w.add(SimpleProperties::StringValue, evnt.m_name.c_str());
-
- if (getFlag == 0)
- {
- const BaseString internal_tabname(
- ndb.internalize_table_name(evnt.m_tableName.c_str()));
- w.add(SimpleProperties::StringValue,
- internal_tabname.c_str());
- }
-
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = (m_buffer.length()+3) >> 2;
-
- int ret = dictSignal(&tSignal,ptr, 1,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- 0, -1);
-
- if (ret) {
- ERR_RETURN(getNdbError(), ret);
- }
-
- char *dataPtr = (char *)m_buffer.get_data();
- unsigned int lenCreateEvntConf = *((unsigned int *)dataPtr);
- dataPtr += sizeof(lenCreateEvntConf);
- CreateEvntConf const * evntConf = (CreateEvntConf *)dataPtr;
- dataPtr += lenCreateEvntConf;
-
- // NdbEventImpl *evntImpl = (NdbEventImpl *)evntConf->getUserData();
-
- evnt.m_eventId = evntConf->getEventId();
- evnt.m_eventKey = evntConf->getEventKey();
- evnt.m_table_id = evntConf->getTableId();
- evnt.m_table_version = evntConf->getTableVersion();
-
- if (getFlag) {
- evnt.m_attrListBitmask = evntConf->getAttrListBitmask();
- evnt.mi_type = evntConf->getEventType();
- evnt.setTable(dataPtr);
- } else {
- if ((Uint32) evnt.m_tableImpl->m_id != evntConf->getTableId() ||
- evnt.m_tableImpl->m_version != evntConf->getTableVersion() ||
- //evnt.m_attrListBitmask != evntConf->getAttrListBitmask() ||
- evnt.mi_type != evntConf->getEventType()) {
- ndbout_c("ERROR*************");
- ERR_RETURN(getNdbError(), 1);
- }
- }
-
- DBUG_RETURN(0);
-}
-
-int
-NdbDictionaryImpl::executeSubscribeEvent(NdbEventOperationImpl & ev_op)
-{
- // NdbDictInterface m_receiver;
- return m_receiver.executeSubscribeEvent(m_ndb, ev_op);
-}
-
-int
-NdbDictInterface::executeSubscribeEvent(class Ndb & ndb,
- NdbEventOperationImpl & ev_op)
-{
- DBUG_ENTER("NdbDictInterface::executeSubscribeEvent");
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_SUB_START_REQ;
- tSignal.theLength = SubStartReq::SignalLength2;
-
- SubStartReq * req = CAST_PTR(SubStartReq, tSignal.getDataPtrSend());
-
- req->subscriptionId = ev_op.m_eventImpl->m_eventId;
- req->subscriptionKey = ev_op.m_eventImpl->m_eventKey;
- req->part = SubscriptionData::TableData;
- req->subscriberData = ev_op.m_oid;
- req->subscriberRef = m_reference;
-
- DBUG_PRINT("info",("GSN_SUB_START_REQ subscriptionId=%d,subscriptionKey=%d,"
- "subscriberData=%d",req->subscriptionId,
- req->subscriptionKey,req->subscriberData));
-
- DBUG_RETURN(dictSignal(&tSignal,NULL,0,
- 0 /*use masternode id*/,
- WAIT_CREATE_INDX_REQ /*WAIT_CREATE_EVNT_REQ*/,
- -1, 100,
- 0, -1));
-}
-
-int
-NdbDictionaryImpl::stopSubscribeEvent(NdbEventOperationImpl & ev_op)
-{
- // NdbDictInterface m_receiver;
- return m_receiver.stopSubscribeEvent(m_ndb, ev_op);
-}
-
-int
-NdbDictInterface::stopSubscribeEvent(class Ndb & ndb,
- NdbEventOperationImpl & ev_op)
-{
- DBUG_ENTER("NdbDictInterface::stopSubscribeEvent");
-
- NdbApiSignal tSignal(m_reference);
- // tSignal.theReceiversBlockNumber = SUMA;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_SUB_STOP_REQ;
- tSignal.theLength = SubStopReq::SignalLength;
-
- SubStopReq * req = CAST_PTR(SubStopReq, tSignal.getDataPtrSend());
-
- req->subscriptionId = ev_op.m_eventImpl->m_eventId;
- req->subscriptionKey = ev_op.m_eventImpl->m_eventKey;
- req->subscriberData = ev_op.m_oid;
- req->part = (Uint32) SubscriptionData::TableData;
- req->subscriberRef = m_reference;
-
- DBUG_PRINT("info",("GSN_SUB_STOP_REQ subscriptionId=%d,subscriptionKey=%d,"
- "subscriberData=%d",req->subscriptionId,
- req->subscriptionKey,req->subscriberData));
-
- DBUG_RETURN(dictSignal(&tSignal,NULL,0,
- 0 /*use masternode id*/,
- WAIT_CREATE_INDX_REQ /*WAIT_SUB_STOP__REQ*/,
- -1, 100,
- 0, -1));
-}
-
-NdbEventImpl *
-NdbDictionaryImpl::getEvent(const char * eventName, NdbTableImpl* tab)
-{
- DBUG_ENTER("NdbDictionaryImpl::getEvent");
- DBUG_PRINT("enter",("eventName= %s", eventName));
-
- NdbEventImpl *ev = new NdbEventImpl();
- if (ev == NULL) {
- DBUG_RETURN(NULL);
- }
-
- ev->setName(eventName);
-
- int ret = m_receiver.createEvent(m_ndb, *ev, 1 /* getFlag set */);
-
- if (ret) {
- delete ev;
- DBUG_RETURN(NULL);
- }
-
- // We only have the table name with internal name
- DBUG_PRINT("info",("table %s", ev->getTableName()));
- if (tab == NULL)
- {
- tab= fetchGlobalTableImplRef(InitTable(this, ev->getTableName()));
- if (tab == 0)
- {
- DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
- delete ev;
- DBUG_RETURN(NULL);
- }
- if ((tab->m_status != NdbDictionary::Object::Retrieved) ||
- ((Uint32) tab->m_id != ev->m_table_id) ||
- (table_version_major(tab->m_version) !=
- table_version_major(ev->m_table_version)))
- {
- DBUG_PRINT("info", ("mismatch on verison in cache"));
- releaseTableGlobal(*tab, 1);
- tab= fetchGlobalTableImplRef(InitTable(this, ev->getTableName()));
- if (tab == 0)
- {
- DBUG_PRINT("error",("unable to find table %s", ev->getTableName()));
- delete ev;
- DBUG_RETURN(NULL);
- }
- }
- ev->setTable(tab);
- releaseTableGlobal(*tab, 0);
- }
- else
- ev->setTable(tab);
- tab = 0;
-
- ev->setTable(m_ndb.externalizeTableName(ev->getTableName()));
- // get the columns from the attrListBitmask
- NdbTableImpl &table = *ev->m_tableImpl;
- AttributeMask & mask = ev->m_attrListBitmask;
- unsigned attributeList_sz = mask.count();
-
- DBUG_PRINT("info",("Table: id: %d version: %d",
- table.m_id, table.m_version));
-
- if ((Uint32) table.m_id != ev->m_table_id ||
- table_version_major(table.m_version) !=
- table_version_major(ev->m_table_version))
- {
- m_error.code = 241;
- delete ev;
- DBUG_RETURN(NULL);
- }
-#ifndef DBUG_OFF
- char buf[128] = {0};
- mask.getText(buf);
- DBUG_PRINT("info",("attributeList_sz= %d, mask= %s",
- attributeList_sz, buf));
-#endif
-
-
- if ( attributeList_sz > (uint) table.getNoOfColumns() )
- {
- m_error.code = 241;
- DBUG_PRINT("error",("Invalid version, too many columns"));
- delete ev;
- DBUG_RETURN(NULL);
- }
-
- assert( (int)attributeList_sz <= table.getNoOfColumns() );
- for(unsigned id= 0; ev->m_columns.size() < attributeList_sz; id++) {
- if ( id >= (uint) table.getNoOfColumns())
- {
- m_error.code = 241;
- DBUG_PRINT("error",("Invalid version, column %d out of range", id));
- delete ev;
- DBUG_RETURN(NULL);
- }
- if (!mask.get(id))
- continue;
-
- const NdbColumnImpl* col = table.getColumn(id);
- DBUG_PRINT("info",("column %d %s", id, col->getName()));
- NdbColumnImpl* new_col = new NdbColumnImpl;
- // Copy column definition
- *new_col = *col;
- ev->m_columns.push_back(new_col);
- }
- DBUG_RETURN(ev);
-}
-
-// ev is main event and has been retrieved previously
-NdbEventImpl *
-NdbDictionaryImpl::getBlobEvent(const NdbEventImpl& ev, uint col_no)
-{
- DBUG_ENTER("NdbDictionaryImpl::getBlobEvent");
- DBUG_PRINT("enter", ("ev=%s col=%u", ev.m_name.c_str(), col_no));
-
- NdbTableImpl* tab = ev.m_tableImpl;
- assert(tab != NULL && col_no < tab->m_columns.size());
- NdbColumnImpl* col = tab->m_columns[col_no];
- assert(col != NULL && col->getBlobType() && col->getPartSize() != 0);
- NdbTableImpl* blob_tab = col->m_blobTable;
- assert(blob_tab != NULL);
- char bename[MAX_TAB_NAME_SIZE];
- NdbBlob::getBlobEventName(bename, &ev, col);
-
- NdbEventImpl* blob_ev = getEvent(bename, blob_tab);
- DBUG_RETURN(blob_ev);
-}
-
-void
-NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_CONF");
-
- m_buffer.clear();
- unsigned int len = signal->getLength() << 2;
- m_buffer.append((char *)&len, sizeof(len));
- m_buffer.append(signal->getDataPtr(), len);
-
- if (signal->m_noOfSections > 0) {
- m_buffer.append((char *)ptr[0].p, strlen((char *)ptr[0].p)+1);
- }
-
- const CreateEvntConf * const createEvntConf=
- CAST_CONSTPTR(CreateEvntConf, signal->getDataPtr());
-
- Uint32 subscriptionId = createEvntConf->getEventId();
- Uint32 subscriptionKey = createEvntConf->getEventKey();
-
- DBUG_PRINT("info",("nodeid=%d,subscriptionId=%d,subscriptionKey=%d",
- refToNode(signal->theSendersBlockRef),
- subscriptionId,subscriptionKey));
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execCREATE_EVNT_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_REF");
-
- const CreateEvntRef* const ref=
- CAST_CONSTPTR(CreateEvntRef, signal->getDataPtr());
- m_error.code= ref->getErrorCode();
- DBUG_PRINT("error",("error=%d,line=%d,node=%d",ref->getErrorCode(),
- ref->getErrorLine(),ref->getErrorNode()));
- if (m_error.code == CreateEvntRef::NotMaster)
- m_masterNodeId = ref->getMasterNode();
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execSUB_STOP_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execSUB_STOP_CONF");
- const SubStopConf * const subStopConf=
- CAST_CONSTPTR(SubStopConf, signal->getDataPtr());
-
- Uint32 subscriptionId = subStopConf->subscriptionId;
- Uint32 subscriptionKey = subStopConf->subscriptionKey;
- Uint32 subscriberData = subStopConf->subscriberData;
-
- DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
- subscriptionId,subscriptionKey,subscriberData));
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execSUB_STOP_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execSUB_STOP_REF");
- const SubStopRef * const subStopRef=
- CAST_CONSTPTR(SubStopRef, signal->getDataPtr());
-
- Uint32 subscriptionId = subStopRef->subscriptionId;
- Uint32 subscriptionKey = subStopRef->subscriptionKey;
- Uint32 subscriberData = subStopRef->subscriberData;
- m_error.code= subStopRef->errorCode;
-
- DBUG_PRINT("error",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d,error=%d",
- subscriptionId,subscriptionKey,subscriberData,m_error.code));
- if (m_error.code == SubStopRef::NotMaster)
- m_masterNodeId = subStopRef->m_masterNodeId;
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execSUB_START_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execSUB_START_CONF");
- const SubStartConf * const subStartConf=
- CAST_CONSTPTR(SubStartConf, signal->getDataPtr());
-
- Uint32 subscriptionId = subStartConf->subscriptionId;
- Uint32 subscriptionKey = subStartConf->subscriptionKey;
- SubscriptionData::Part part =
- (SubscriptionData::Part)subStartConf->part;
- Uint32 subscriberData = subStartConf->subscriberData;
-
- switch(part) {
- case SubscriptionData::MetaData: {
- DBUG_PRINT("error",("SubscriptionData::MetaData"));
- m_error.code= 1;
- break;
- }
- case SubscriptionData::TableData: {
- DBUG_PRINT("info",("SubscriptionData::TableData"));
- break;
- }
- default: {
- DBUG_PRINT("error",("wrong data"));
- m_error.code= 2;
- break;
- }
- }
- DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
- subscriptionId,subscriptionKey,subscriberData));
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execSUB_START_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execSUB_START_REF");
- const SubStartRef * const subStartRef=
- CAST_CONSTPTR(SubStartRef, signal->getDataPtr());
- m_error.code= subStartRef->errorCode;
- if (m_error.code == SubStartRef::NotMaster)
- m_masterNodeId = subStartRef->m_masterNodeId;
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-/*****************************************************************
- * Drop event
- */
-int
-NdbDictionaryImpl::dropEvent(const char * eventName)
-{
- DBUG_ENTER("NdbDictionaryImpl::dropEvent");
- DBUG_PRINT("info", ("name=%s", eventName));
-
- NdbEventImpl *evnt = getEvent(eventName); // allocated
- if (evnt == NULL) {
- if (m_error.code != 723 && // no such table
- m_error.code != 241) // invalid table
- DBUG_RETURN(-1);
- DBUG_PRINT("info", ("no table err=%d, drop by name alone", m_error.code));
- evnt = new NdbEventImpl();
- evnt->setName(eventName);
- }
- int ret = dropEvent(*evnt);
- delete evnt;
- DBUG_RETURN(ret);
-}
-
-int
-NdbDictionaryImpl::dropEvent(const NdbEventImpl& evnt)
-{
- if (dropBlobEvents(evnt) != 0)
- return -1;
- if (m_receiver.dropEvent(evnt) != 0)
- return -1;
- return 0;
-}
-
-int
-NdbDictionaryImpl::dropBlobEvents(const NdbEventImpl& evnt)
-{
- DBUG_ENTER("NdbDictionaryImpl::dropBlobEvents");
- if (evnt.m_tableImpl != 0) {
- const NdbTableImpl& t = *evnt.m_tableImpl;
- Uint32 n = t.m_noOfBlobs;
- Uint32 i;
- for (i = 0; i < evnt.m_columns.size() && n > 0; i++) {
- const NdbColumnImpl& c = *evnt.m_columns[i];
- if (! c.getBlobType() || c.getPartSize() == 0)
- continue;
- n--;
- NdbEventImpl* blob_evnt = getBlobEvent(evnt, i);
- if (blob_evnt == NULL)
- continue;
- (void)dropEvent(*blob_evnt);
- delete blob_evnt;
- }
- } else {
- // loop over MAX_ATTRIBUTES_IN_TABLE ...
- Uint32 i;
- DBUG_PRINT("info", ("missing table definition, looping over "
- "MAX_ATTRIBUTES_IN_TABLE(%d)",
- MAX_ATTRIBUTES_IN_TABLE));
- for (i = 0; i < MAX_ATTRIBUTES_IN_TABLE; i++) {
- char bename[MAX_TAB_NAME_SIZE];
- // XXX should get name from NdbBlob
- sprintf(bename, "NDB$BLOBEVENT_%s_%u", evnt.getName(), i);
- NdbEventImpl* bevnt = new NdbEventImpl();
- bevnt->setName(bename);
- (void)m_receiver.dropEvent(*bevnt);
- delete bevnt;
- }
- }
- DBUG_RETURN(0);
-}
-
-int
-NdbDictInterface::dropEvent(const NdbEventImpl &evnt)
-{
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_DROP_EVNT_REQ;
- tSignal.theLength = DropEvntReq::SignalLength;
-
- DropEvntReq * const req = CAST_PTR(DropEvntReq, tSignal.getDataPtrSend());
-
- req->setUserRef(m_reference);
- req->setUserData(0);
-
- UtilBufferWriter w(m_buffer);
-
- w.add(SimpleProperties::StringValue, evnt.m_name.c_str());
-
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = (m_buffer.length()+3) >> 2;
-
- return dictSignal(&tSignal,ptr, 1,
- 0 /*use masternode id*/,
- WAIT_CREATE_INDX_REQ,
- -1, 100,
- 0, -1);
-}
-
-void
-NdbDictInterface::execDROP_EVNT_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execDROP_EVNT_CONF");
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbDictInterface::execDROP_EVNT_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbDictInterface::execDROP_EVNT_REF");
- const DropEvntRef* const ref=
- CAST_CONSTPTR(DropEvntRef, signal->getDataPtr());
- m_error.code= ref->getErrorCode();
-
- DBUG_PRINT("info",("ErrorCode=%u Errorline=%u ErrorNode=%u",
- ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode()));
- if (m_error.code == DropEvntRef::NotMaster)
- m_masterNodeId = ref->getMasterNode();
- m_waiter.signal(NO_WAIT);
- DBUG_VOID_RETURN;
-}
-
-/*****************************************************************
- * List objects or indexes
- */
-int
-NdbDictionaryImpl::listObjects(List& list, NdbDictionary::Object::Type type)
-{
- ListTablesReq req;
- req.requestData = 0;
- req.setTableType(getKernelConstant(type, objectTypeMapping, 0));
- req.setListNames(true);
- return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames());
-}
-
-int
-NdbDictionaryImpl::listIndexes(List& list, Uint32 indexId)
-{
- ListTablesReq req;
- req.requestData = 0;
- req.setTableId(indexId);
- req.setListNames(true);
- req.setListIndexes(true);
- return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames());
-}
-
-int
-NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list,
- Uint32 requestData, bool fullyQualifiedNames)
-{
- NdbApiSignal tSignal(m_reference);
- ListTablesReq* const req = CAST_PTR(ListTablesReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestData = requestData;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_LIST_TABLES_REQ;
- tSignal.theLength = ListTablesReq::SignalLength;
- if (listObjects(&tSignal) != 0)
- return -1;
- // count
- const Uint32* data = (const Uint32*)m_buffer.get_data();
- const unsigned length = m_buffer.length() / 4;
- list.count = 0;
- bool ok = true;
- unsigned pos, count;
- pos = count = 0;
- while (pos < length) {
- // table id - name length - name
- pos++;
- if (pos >= length) {
- ok = false;
- break;
- }
- Uint32 n = (data[pos++] + 3) >> 2;
- pos += n;
- if (pos > length) {
- ok = false;
- break;
- }
- count++;
- }
- if (! ok) {
- // bad signal data
- m_error.code= 4213;
- return -1;
- }
- list.count = count;
- list.elements = new NdbDictionary::Dictionary::List::Element[count];
- pos = count = 0;
- while (pos < length) {
- NdbDictionary::Dictionary::List::Element& element = list.elements[count];
- Uint32 d = data[pos++];
- element.id = ListTablesConf::getTableId(d);
- element.type = (NdbDictionary::Object::Type)
- getApiConstant(ListTablesConf::getTableType(d), objectTypeMapping, 0);
- element.state = (NdbDictionary::Object::State)
- getApiConstant(ListTablesConf::getTableState(d), objectStateMapping, 0);
- element.store = (NdbDictionary::Object::Store)
- getApiConstant(ListTablesConf::getTableStore(d), objectStoreMapping, 0);
- element.temp = ListTablesConf::getTableTemp(d);
- // table or index name
- Uint32 n = (data[pos++] + 3) >> 2;
- BaseString databaseName;
- BaseString schemaName;
- BaseString objectName;
- if (!databaseName || !schemaName || !objectName)
- {
- m_error.code= 4000;
- return -1;
- }
- if ((element.type == NdbDictionary::Object::UniqueHashIndex) ||
- (element.type == NdbDictionary::Object::OrderedIndex)) {
- char * indexName = new char[n << 2];
- if (indexName == NULL)
- {
- m_error.code= 4000;
- return -1;
- }
- memcpy(indexName, &data[pos], n << 2);
- if (!(databaseName = Ndb::getDatabaseFromInternalName(indexName)) ||
- !(schemaName = Ndb::getSchemaFromInternalName(indexName)))
- {
- delete [] indexName;
- m_error.code= 4000;
- return -1;
- }
- objectName = BaseString(Ndb::externalizeIndexName(indexName, fullyQualifiedNames));
- delete [] indexName;
- } else if ((element.type == NdbDictionary::Object::SystemTable) ||
- (element.type == NdbDictionary::Object::UserTable)) {
- char * tableName = new char[n << 2];
- if (tableName == NULL)
- {
- m_error.code= 4000;
- return -1;
- }
- memcpy(tableName, &data[pos], n << 2);
- if (!(databaseName = Ndb::getDatabaseFromInternalName(tableName)) ||
- !(schemaName = Ndb::getSchemaFromInternalName(tableName)))
- {
- delete [] tableName;
- m_error.code= 4000;
- return -1;
- }
- objectName = BaseString(Ndb::externalizeTableName(tableName, fullyQualifiedNames));
- delete [] tableName;
- }
- else {
- char * otherName = new char[n << 2];
- if (otherName == NULL)
- {
- m_error.code= 4000;
- return -1;
- }
- memcpy(otherName, &data[pos], n << 2);
- if (!(objectName = BaseString(otherName)))
- {
- m_error.code= 4000;
- return -1;
- }
- delete [] otherName;
- }
- if (!(element.database = new char[databaseName.length() + 1]) ||
- !(element.schema = new char[schemaName.length() + 1]) ||
- !(element.name = new char[objectName.length() + 1]))
- {
- m_error.code= 4000;
- return -1;
- }
- strcpy(element.database, databaseName.c_str());
- strcpy(element.schema, schemaName.c_str());
- strcpy(element.name, objectName.c_str());
- pos += n;
- count++;
- }
- return 0;
-}
-
-int
-NdbDictInterface::listObjects(NdbApiSignal* signal)
-{
- const Uint32 RETRIES = 100;
- for (Uint32 i = 0; i < RETRIES; i++) {
- m_buffer.clear();
- // begin protected
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(m_transporter, &m_waiter, refToBlock(m_reference));
- Uint16 aNodeId = m_transporter->get_an_alive_node();
- if (aNodeId == 0) {
- m_error.code= 4009;
- return -1;
- }
- if (m_transporter->sendSignal(signal, aNodeId) != 0) {
- continue;
- }
- m_error.code= 0;
- int ret_val= poll_guard.wait_n_unlock(DICT_WAITFOR_TIMEOUT,
- aNodeId, WAIT_LIST_TABLES_CONF);
- // end protected
- if (ret_val == 0 && m_error.code == 0)
- return 0;
- if (ret_val == -2) //WAIT_NODE_FAILURE
- continue;
- return -1;
- }
- return -1;
-}
-
-void
-NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal,
- LinearSectionPtr ptr[3])
-{
- const unsigned off = ListTablesConf::HeaderLength;
- const unsigned len = (signal->getLength() - off);
- if (m_buffer.append(signal->getDataPtr() + off, len << 2))
- {
- m_error.code= 4000;
- }
- if (signal->getLength() < ListTablesConf::SignalLength) {
- // last signal has less than full length
- m_waiter.signal(NO_WAIT);
- }
-}
-
-int
-NdbDictionaryImpl::forceGCPWait()
-{
- return m_receiver.forceGCPWait();
-}
-
-int
-NdbDictInterface::forceGCPWait()
-{
- NdbApiSignal tSignal(m_reference);
- WaitGCPReq* const req = CAST_PTR(WaitGCPReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestType = WaitGCPReq::CompleteForceStart;
- tSignal.theReceiversBlockNumber = DBDIH;
- tSignal.theVerId_signalNumber = GSN_WAIT_GCP_REQ;
- tSignal.theLength = WaitGCPReq::SignalLength;
-
- const Uint32 RETRIES = 100;
- for (Uint32 i = 0; i < RETRIES; i++)
- {
- m_transporter->lock_mutex();
- Uint16 aNodeId = m_transporter->get_an_alive_node();
- if (aNodeId == 0) {
- m_error.code= 4009;
- m_transporter->unlock_mutex();
- return -1;
- }
- if (m_transporter->sendSignal(&tSignal, aNodeId) != 0) {
- m_transporter->unlock_mutex();
- continue;
- }
- m_error.code= 0;
- m_waiter.m_node = aNodeId;
- m_waiter.m_state = WAIT_LIST_TABLES_CONF;
- m_waiter.wait(DICT_WAITFOR_TIMEOUT);
- m_transporter->unlock_mutex();
- return 0;
- }
- return -1;
-}
-
-void
-NdbDictInterface::execWAIT_GCP_CONF(NdbApiSignal* signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execWAIT_GCP_REF(NdbApiSignal* signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-NdbFilegroupImpl::NdbFilegroupImpl(NdbDictionary::Object::Type t)
- : NdbDictObjectImpl(t)
-{
- m_extent_size = 0;
- m_undo_buffer_size = 0;
- m_logfile_group_id = ~0;
- m_logfile_group_version = ~0;
-}
-
-NdbTablespaceImpl::NdbTablespaceImpl() :
- NdbDictionary::Tablespace(* this),
- NdbFilegroupImpl(NdbDictionary::Object::Tablespace), m_facade(this)
-{
-}
-
-NdbTablespaceImpl::NdbTablespaceImpl(NdbDictionary::Tablespace & f) :
- NdbDictionary::Tablespace(* this),
- NdbFilegroupImpl(NdbDictionary::Object::Tablespace), m_facade(&f)
-{
-}
-
-NdbTablespaceImpl::~NdbTablespaceImpl(){
-}
-
-int
-NdbTablespaceImpl::assign(const NdbTablespaceImpl& org)
-{
- m_id = org.m_id;
- m_version = org.m_version;
- m_status = org.m_status;
- m_type = org.m_type;
-
- if (!m_name.assign(org.m_name))
- return -1;
- m_grow_spec = org.m_grow_spec;
- m_extent_size = org.m_extent_size;
- m_undo_free_words = org.m_undo_free_words;
- m_logfile_group_id = org.m_logfile_group_id;
- m_logfile_group_version = org.m_logfile_group_version;
- if (!m_logfile_group_name.assign(org.m_logfile_group_name))
- return -1;
- m_undo_free_words = org.m_undo_free_words;
- return 0;
-}
-
-NdbLogfileGroupImpl::NdbLogfileGroupImpl() :
- NdbDictionary::LogfileGroup(* this),
- NdbFilegroupImpl(NdbDictionary::Object::LogfileGroup), m_facade(this)
-{
-}
-
-NdbLogfileGroupImpl::NdbLogfileGroupImpl(NdbDictionary::LogfileGroup & f) :
- NdbDictionary::LogfileGroup(* this),
- NdbFilegroupImpl(NdbDictionary::Object::LogfileGroup), m_facade(&f)
-{
-}
-
-NdbLogfileGroupImpl::~NdbLogfileGroupImpl(){
-}
-
-int
-NdbLogfileGroupImpl::assign(const NdbLogfileGroupImpl& org)
-{
- m_id = org.m_id;
- m_version = org.m_version;
- m_status = org.m_status;
- m_type = org.m_type;
-
- if (!m_name.assign(org.m_name))
- return -1;
- m_grow_spec = org.m_grow_spec;
- m_extent_size = org.m_extent_size;
- m_undo_free_words = org.m_undo_free_words;
- m_logfile_group_id = org.m_logfile_group_id;
- m_logfile_group_version = org.m_logfile_group_version;
- if (!m_logfile_group_name.assign(org.m_logfile_group_name))
- return -1;
- m_undo_free_words = org.m_undo_free_words;
- return 0;
-}
-
-NdbFileImpl::NdbFileImpl(NdbDictionary::Object::Type t)
- : NdbDictObjectImpl(t)
-{
- m_size = 0;
- m_free = 0;
- m_filegroup_id = ~0;
- m_filegroup_version = ~0;
-}
-
-NdbDatafileImpl::NdbDatafileImpl() :
- NdbDictionary::Datafile(* this),
- NdbFileImpl(NdbDictionary::Object::Datafile), m_facade(this)
-{
-}
-
-NdbDatafileImpl::NdbDatafileImpl(NdbDictionary::Datafile & f) :
- NdbDictionary::Datafile(* this),
- NdbFileImpl(NdbDictionary::Object::Datafile), m_facade(&f)
-{
-}
-
-NdbDatafileImpl::~NdbDatafileImpl(){
-}
-
-int
-NdbDatafileImpl::assign(const NdbDatafileImpl& org)
-{
- m_id = org.m_id;
- m_version = org.m_version;
- m_status = org.m_status;
- m_type = org.m_type;
-
- m_size = org.m_size;
- m_free = org.m_free;
- m_filegroup_id = org.m_filegroup_id;
- m_filegroup_version = org.m_filegroup_version;
- if (!m_path.assign(org.m_path) ||
- !m_filegroup_name.assign(org.m_filegroup_name))
- return -1;
- return 0;
-}
-
-NdbUndofileImpl::NdbUndofileImpl() :
- NdbDictionary::Undofile(* this),
- NdbFileImpl(NdbDictionary::Object::Undofile), m_facade(this)
-{
-}
-
-NdbUndofileImpl::NdbUndofileImpl(NdbDictionary::Undofile & f) :
- NdbDictionary::Undofile(* this),
- NdbFileImpl(NdbDictionary::Object::Undofile), m_facade(&f)
-{
-}
-
-NdbUndofileImpl::~NdbUndofileImpl(){
-}
-
-int
-NdbUndofileImpl::assign(const NdbUndofileImpl& org)
-{
- m_id = org.m_id;
- m_version = org.m_version;
- m_status = org.m_status;
- m_type = org.m_type;
-
- m_size = org.m_size;
- m_free = org.m_free;
- m_filegroup_id = org.m_filegroup_id;
- m_filegroup_version = org.m_filegroup_version;
- if (!m_path.assign(org.m_path) ||
- !m_filegroup_name.assign(org.m_filegroup_name))
- return 4000;
- return 0;
-}
-
-int
-NdbDictionaryImpl::createDatafile(const NdbDatafileImpl & file,
- bool force,
- NdbDictObjectImpl* obj)
-
-{
- DBUG_ENTER("NdbDictionaryImpl::createDatafile");
- NdbFilegroupImpl tmp(NdbDictionary::Object::Tablespace);
- if(file.m_filegroup_version != ~(Uint32)0){
- tmp.m_id = file.m_filegroup_id;
- tmp.m_version = file.m_filegroup_version;
- DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
- }
-
-
- if(m_receiver.get_filegroup(tmp, NdbDictionary::Object::Tablespace,
- file.m_filegroup_name.c_str()) == 0){
- DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
- }
- DBUG_RETURN(-1);
-}
-
-int
-NdbDictionaryImpl::dropDatafile(const NdbDatafileImpl & file){
- return m_receiver.drop_file(file);
-}
-
-int
-NdbDictionaryImpl::createUndofile(const NdbUndofileImpl & file,
- bool force,
- NdbDictObjectImpl* obj)
-{
- DBUG_ENTER("NdbDictionaryImpl::createUndofile");
- NdbFilegroupImpl tmp(NdbDictionary::Object::LogfileGroup);
- if(file.m_filegroup_version != ~(Uint32)0){
- tmp.m_id = file.m_filegroup_id;
- tmp.m_version = file.m_filegroup_version;
- DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
- }
-
-
- if(m_receiver.get_filegroup(tmp, NdbDictionary::Object::LogfileGroup,
- file.m_filegroup_name.c_str()) == 0){
- DBUG_RETURN(m_receiver.create_file(file, tmp, force, obj));
- }
- DBUG_PRINT("info", ("Failed to find filegroup"));
- DBUG_RETURN(-1);
-}
-
-int
-NdbDictionaryImpl::dropUndofile(const NdbUndofileImpl & file)
-{
- return m_receiver.drop_file(file);
-}
-
-int
-NdbDictionaryImpl::createTablespace(const NdbTablespaceImpl & fg,
- NdbDictObjectImpl* obj)
-{
- return m_receiver.create_filegroup(fg, obj);
-}
-
-int
-NdbDictionaryImpl::dropTablespace(const NdbTablespaceImpl & fg)
-{
- return m_receiver.drop_filegroup(fg);
-}
-
-int
-NdbDictionaryImpl::createLogfileGroup(const NdbLogfileGroupImpl & fg,
- NdbDictObjectImpl* obj)
-{
- return m_receiver.create_filegroup(fg, obj);
-}
-
-int
-NdbDictionaryImpl::dropLogfileGroup(const NdbLogfileGroupImpl & fg)
-{
- return m_receiver.drop_filegroup(fg);
-}
-
-int
-NdbDictInterface::create_file(const NdbFileImpl & file,
- const NdbFilegroupImpl & group,
- bool overwrite,
- NdbDictObjectImpl* obj)
-{
- DBUG_ENTER("NdbDictInterface::create_file");
- UtilBufferWriter w(m_buffer);
- DictFilegroupInfo::File f; f.init();
- snprintf(f.FileName, sizeof(f.FileName), file.m_path.c_str());
- f.FileType = file.m_type;
- f.FilegroupId = group.m_id;
- f.FilegroupVersion = group.m_version;
- f.FileSizeHi = (file.m_size >> 32);
- f.FileSizeLo = (file.m_size & 0xFFFFFFFF);
-
- SimpleProperties::UnpackStatus s;
- s = SimpleProperties::pack(w,
- &f,
- DictFilegroupInfo::FileMapping,
- DictFilegroupInfo::FileMappingSize, true);
-
- if(s != SimpleProperties::Eof){
- abort();
- }
-
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_CREATE_FILE_REQ;
- tSignal.theLength = CreateFileReq::SignalLength;
-
- CreateFileReq* req = CAST_PTR(CreateFileReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->objType = file.m_type;
- req->requestInfo = 0;
- if (overwrite)
- req->requestInfo |= CreateFileReq::ForceCreateFile;
-
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = m_buffer.length() / 4;
-
- int err[] = { CreateFileRef::Busy, CreateFileRef::NotMaster, 0};
- /*
- Send signal without time-out since creating files can take a very long
- time if the file is very big.
- */
- int ret = dictSignal(&tSignal, ptr, 1,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- -1, 100,
- err);
-
- if (ret == 0 && obj)
- {
- Uint32* data = (Uint32*)m_buffer.get_data();
- obj->m_id = data[0];
- obj->m_version = data[1];
- }
-
- DBUG_RETURN(ret);
-}
-
-void
-NdbDictInterface::execCREATE_FILE_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const CreateFileConf* conf=
- CAST_CONSTPTR(CreateFileConf, signal->getDataPtr());
- m_buffer.grow(4 * 2); // 2 words
- Uint32* data = (Uint32*)m_buffer.get_data();
- data[0] = conf->fileId;
- data[1] = conf->fileVersion;
-
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execCREATE_FILE_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const CreateFileRef* ref =
- CAST_CONSTPTR(CreateFileRef, signal->getDataPtr());
- m_error.code = ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-int
-NdbDictInterface::drop_file(const NdbFileImpl & file)
-{
- DBUG_ENTER("NdbDictInterface::drop_file");
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_DROP_FILE_REQ;
- tSignal.theLength = DropFileReq::SignalLength;
-
- DropFileReq* req = CAST_PTR(DropFileReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->file_id = file.m_id;
- req->file_version = file.m_version;
-
- int err[] = { DropFileRef::Busy, DropFileRef::NotMaster, 0};
- DBUG_RETURN(dictSignal(&tSignal, 0, 0,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- err));
-}
-
-void
-NdbDictInterface::execDROP_FILE_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execDROP_FILE_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const DropFileRef* ref =
- CAST_CONSTPTR(DropFileRef, signal->getDataPtr());
- m_error.code = ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-int
-NdbDictInterface::create_filegroup(const NdbFilegroupImpl & group,
- NdbDictObjectImpl* obj)
-{
- DBUG_ENTER("NdbDictInterface::create_filegroup");
- UtilBufferWriter w(m_buffer);
- DictFilegroupInfo::Filegroup fg; fg.init();
- snprintf(fg.FilegroupName, sizeof(fg.FilegroupName), group.m_name.c_str());
- switch(group.m_type){
- case NdbDictionary::Object::Tablespace:
- {
- fg.FilegroupType = DictTabInfo::Tablespace;
- //fg.TS_DataGrow = group.m_grow_spec;
- fg.TS_ExtentSize = group.m_extent_size;
-
- if(group.m_logfile_group_version != ~(Uint32)0)
- {
- fg.TS_LogfileGroupId = group.m_logfile_group_id;
- fg.TS_LogfileGroupVersion = group.m_logfile_group_version;
- }
- else
- {
- NdbLogfileGroupImpl tmp;
- if(get_filegroup(tmp, NdbDictionary::Object::LogfileGroup,
- group.m_logfile_group_name.c_str()) == 0)
- {
- fg.TS_LogfileGroupId = tmp.m_id;
- fg.TS_LogfileGroupVersion = tmp.m_version;
- }
- else // error set by get filegroup
- {
- DBUG_RETURN(-1);
- }
- }
- }
- break;
- case NdbDictionary::Object::LogfileGroup:
- fg.LF_UndoBufferSize = group.m_undo_buffer_size;
- fg.FilegroupType = DictTabInfo::LogfileGroup;
- //fg.LF_UndoGrow = group.m_grow_spec;
- break;
- default:
- abort();
- DBUG_RETURN(-1);
- };
-
- SimpleProperties::UnpackStatus s;
- s = SimpleProperties::pack(w,
- &fg,
- DictFilegroupInfo::Mapping,
- DictFilegroupInfo::MappingSize, true);
-
- if(s != SimpleProperties::Eof){
- abort();
- }
-
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_CREATE_FILEGROUP_REQ;
- tSignal.theLength = CreateFilegroupReq::SignalLength;
-
- CreateFilegroupReq* req =
- CAST_PTR(CreateFilegroupReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->objType = fg.FilegroupType;
-
- LinearSectionPtr ptr[3];
- ptr[0].p = (Uint32*)m_buffer.get_data();
- ptr[0].sz = m_buffer.length() / 4;
-
- int err[] = { CreateFilegroupRef::Busy, CreateFilegroupRef::NotMaster, 0};
- int ret = dictSignal(&tSignal, ptr, 1,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- err);
-
- if (ret == 0 && obj)
- {
- Uint32* data = (Uint32*)m_buffer.get_data();
- obj->m_id = data[0];
- obj->m_version = data[1];
- }
-
- DBUG_RETURN(ret);
-}
-
-void
-NdbDictInterface::execCREATE_FILEGROUP_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const CreateFilegroupConf* conf=
- CAST_CONSTPTR(CreateFilegroupConf, signal->getDataPtr());
- m_buffer.grow(4 * 2); // 2 words
- Uint32* data = (Uint32*)m_buffer.get_data();
- data[0] = conf->filegroupId;
- data[1] = conf->filegroupVersion;
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execCREATE_FILEGROUP_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const CreateFilegroupRef* ref =
- CAST_CONSTPTR(CreateFilegroupRef, signal->getDataPtr());
- m_error.code = ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-int
-NdbDictInterface::drop_filegroup(const NdbFilegroupImpl & group)
-{
- DBUG_ENTER("NdbDictInterface::drop_filegroup");
- NdbApiSignal tSignal(m_reference);
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_DROP_FILEGROUP_REQ;
- tSignal.theLength = DropFilegroupReq::SignalLength;
-
- DropFilegroupReq* req = CAST_PTR(DropFilegroupReq, tSignal.getDataPtrSend());
- req->senderRef = m_reference;
- req->senderData = 0;
- req->filegroup_id = group.m_id;
- req->filegroup_version = group.m_version;
-
- int err[] = { DropFilegroupRef::Busy, DropFilegroupRef::NotMaster, 0};
- DBUG_RETURN(dictSignal(&tSignal, 0, 0,
- 0, // master
- WAIT_CREATE_INDX_REQ,
- DICT_WAITFOR_TIMEOUT, 100,
- err));
-}
-
-void
-NdbDictInterface::execDROP_FILEGROUP_CONF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- m_waiter.signal(NO_WAIT);
-}
-
-void
-NdbDictInterface::execDROP_FILEGROUP_REF(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- const DropFilegroupRef* ref =
- CAST_CONSTPTR(DropFilegroupRef, signal->getDataPtr());
- m_error.code = ref->errorCode;
- m_masterNodeId = ref->masterNodeId;
- m_waiter.signal(NO_WAIT);
-}
-
-
-int
-NdbDictInterface::get_filegroup(NdbFilegroupImpl & dst,
- NdbDictionary::Object::Type type,
- const char * name){
- DBUG_ENTER("NdbDictInterface::get_filegroup");
- NdbApiSignal tSignal(m_reference);
- GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
-
- size_t strLen = strlen(name) + 1;
-
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestType =
- GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
- req->tableNameLen = strLen;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
- tSignal.theLength = GetTabInfoReq::SignalLength;
-
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)name;
- ptr[0].sz = (strLen + 3)/4;
-
-#ifndef IGNORE_VALGRIND_WARNINGS
- if (strLen & 3)
- {
- Uint32 pad = 0;
- m_buffer.clear();
- m_buffer.append(name, strLen);
- m_buffer.append(&pad, 4);
- ptr[0].p = (Uint32*)m_buffer.get_data();
- }
-#endif
-
- int r = dictSignal(&tSignal, ptr, 1,
- -1, // any node
- WAIT_GET_TAB_INFO_REQ,
- DICT_WAITFOR_TIMEOUT, 100);
- if (r)
- {
- dst.m_id = -1;
- dst.m_version = ~0;
-
- DBUG_PRINT("info", ("get_filegroup failed dictSignal"));
- DBUG_RETURN(-1);
- }
-
- m_error.code = parseFilegroupInfo(dst,
- (Uint32*)m_buffer.get_data(),
- m_buffer.length() / 4);
-
- if(m_error.code)
- {
- DBUG_PRINT("info", ("get_filegroup failed parseFilegroupInfo %d",
- m_error.code));
- DBUG_RETURN(m_error.code);
- }
-
- if(dst.m_type == NdbDictionary::Object::Tablespace)
- {
- NdbDictionary::LogfileGroup tmp;
- get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
- NdbDictionary::Object::LogfileGroup,
- dst.m_logfile_group_id);
- if (!dst.m_logfile_group_name.assign(tmp.getName()))
- DBUG_RETURN(m_error.code = 4000);
- }
-
- if(dst.m_type == type)
- {
- DBUG_RETURN(0);
- }
- DBUG_PRINT("info", ("get_filegroup failed no such filegroup"));
- DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
-}
-
-int
-NdbDictInterface::parseFilegroupInfo(NdbFilegroupImpl &dst,
- const Uint32 * data, Uint32 len)
-
-{
- SimplePropertiesLinearReader it(data, len);
-
- SimpleProperties::UnpackStatus status;
- DictFilegroupInfo::Filegroup fg; fg.init();
- status = SimpleProperties::unpack(it, &fg,
- DictFilegroupInfo::Mapping,
- DictFilegroupInfo::MappingSize,
- true, true);
-
- if(status != SimpleProperties::Eof){
- return CreateFilegroupRef::InvalidFormat;
- }
-
- dst.m_id = fg.FilegroupId;
- dst.m_version = fg.FilegroupVersion;
- dst.m_type = (NdbDictionary::Object::Type)fg.FilegroupType;
- dst.m_status = NdbDictionary::Object::Retrieved;
-
- if (!dst.m_name.assign(fg.FilegroupName))
- return 4000;
- dst.m_extent_size = fg.TS_ExtentSize;
- dst.m_undo_buffer_size = fg.LF_UndoBufferSize;
- dst.m_logfile_group_id = fg.TS_LogfileGroupId;
- dst.m_logfile_group_version = fg.TS_LogfileGroupVersion;
- dst.m_undo_free_words= ((Uint64)fg.LF_UndoFreeWordsHi << 32)
- | (fg.LF_UndoFreeWordsLo);
-
- return 0;
-}
-
-int
-NdbDictInterface::get_filegroup(NdbFilegroupImpl & dst,
- NdbDictionary::Object::Type type,
- Uint32 id){
- DBUG_ENTER("NdbDictInterface::get_filegroup");
- NdbApiSignal tSignal(m_reference);
- GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
-
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestType =
- GetTabInfoReq::RequestById | GetTabInfoReq::LongSignalConf;
- req->tableId = id;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
- tSignal.theLength = GetTabInfoReq::SignalLength;
-
- int r = dictSignal(&tSignal, NULL, 1,
- -1, // any node
- WAIT_GET_TAB_INFO_REQ,
- DICT_WAITFOR_TIMEOUT, 100);
- if (r)
- {
- DBUG_PRINT("info", ("get_filegroup failed dictSignal"));
- DBUG_RETURN(-1);
- }
-
- m_error.code = parseFilegroupInfo(dst,
- (Uint32*)m_buffer.get_data(),
- m_buffer.length() / 4);
-
- if(m_error.code)
- {
- DBUG_PRINT("info", ("get_filegroup failed parseFilegroupInfo %d",
- m_error.code));
- DBUG_RETURN(m_error.code);
- }
-
- if(dst.m_type == type)
- {
- DBUG_RETURN(0);
- }
- DBUG_PRINT("info", ("get_filegroup failed no such filegroup"));
- DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
-}
-
-int
-NdbDictInterface::get_file(NdbFileImpl & dst,
- NdbDictionary::Object::Type type,
- int node,
- const char * name){
- DBUG_ENTER("NdbDictInterface::get_file");
- NdbApiSignal tSignal(m_reference);
- GetTabInfoReq * req = CAST_PTR(GetTabInfoReq, tSignal.getDataPtrSend());
-
- size_t strLen = strlen(name) + 1;
-
- req->senderRef = m_reference;
- req->senderData = 0;
- req->requestType =
- GetTabInfoReq::RequestByName | GetTabInfoReq::LongSignalConf;
- req->tableNameLen = strLen;
- tSignal.theReceiversBlockNumber = DBDICT;
- tSignal.theVerId_signalNumber = GSN_GET_TABINFOREQ;
- tSignal.theLength = GetTabInfoReq::SignalLength;
-
- LinearSectionPtr ptr[1];
- ptr[0].p = (Uint32*)name;
- ptr[0].sz = (strLen + 3)/4;
-
-#ifndef IGNORE_VALGRIND_WARNINGS
- if (strLen & 3)
- {
- Uint32 pad = 0;
- m_buffer.clear();
- m_buffer.append(name, strLen);
- m_buffer.append(&pad, 4);
- ptr[0].p = (Uint32*)m_buffer.get_data();
- }
-#endif
-
- int r = dictSignal(&tSignal, ptr, 1,
- node,
- WAIT_GET_TAB_INFO_REQ,
- DICT_WAITFOR_TIMEOUT, 100);
- if (r)
- {
- DBUG_PRINT("info", ("get_file failed dictSignal"));
- DBUG_RETURN(-1);
- }
-
- m_error.code = parseFileInfo(dst,
- (Uint32*)m_buffer.get_data(),
- m_buffer.length() / 4);
-
- if(m_error.code)
- {
- DBUG_PRINT("info", ("get_file failed parseFileInfo %d",
- m_error.code));
- DBUG_RETURN(m_error.code);
- }
-
- if(dst.m_type == NdbDictionary::Object::Undofile)
- {
- NdbDictionary::LogfileGroup tmp;
- get_filegroup(NdbLogfileGroupImpl::getImpl(tmp),
- NdbDictionary::Object::LogfileGroup,
- dst.m_filegroup_id);
- if (!dst.m_filegroup_name.assign(tmp.getName()))
- DBUG_RETURN(m_error.code = 4000);
- }
- else if(dst.m_type == NdbDictionary::Object::Datafile)
- {
- NdbDictionary::Tablespace tmp;
- get_filegroup(NdbTablespaceImpl::getImpl(tmp),
- NdbDictionary::Object::Tablespace,
- dst.m_filegroup_id);
- if (!dst.m_filegroup_name.assign(tmp.getName()))
- DBUG_RETURN(m_error.code = 4000);
- dst.m_free *= tmp.getExtentSize();
- }
- else
- dst.m_filegroup_name.assign("Not Yet Implemented");
-
- if(dst.m_type == type)
- {
- DBUG_RETURN(0);
- }
- DBUG_PRINT("info", ("get_file failed no such file"));
- DBUG_RETURN(m_error.code = GetTabInfoRef::TableNotDefined);
-}
-
-int
-NdbDictInterface::parseFileInfo(NdbFileImpl &dst,
- const Uint32 * data, Uint32 len)
-{
- SimplePropertiesLinearReader it(data, len);
-
- SimpleProperties::UnpackStatus status;
- DictFilegroupInfo::File f; f.init();
- status = SimpleProperties::unpack(it, &f,
- DictFilegroupInfo::FileMapping,
- DictFilegroupInfo::FileMappingSize,
- true, true);
-
- if(status != SimpleProperties::Eof){
- return CreateFilegroupRef::InvalidFormat;
- }
-
- dst.m_type= (NdbDictionary::Object::Type)f.FileType;
- dst.m_id= f.FileId;
- dst.m_version = f.FileVersion;
-
- dst.m_size= ((Uint64)f.FileSizeHi << 32) | (f.FileSizeLo);
- if (!dst.m_path.assign(f.FileName))
- return 4000;
-
- dst.m_filegroup_id= f.FilegroupId;
- dst.m_filegroup_version= f.FilegroupVersion;
- dst.m_free= f.FileFreeExtents;
- return 0;
-}
-
-template class Vector<int>;
-template class Vector<Uint16>;
-template class Vector<Uint32>;
-template class Vector<Vector<Uint32> >;
-template class Vector<NdbTableImpl*>;
-template class Vector<NdbColumnImpl*>;
-
-const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT = 0;
-const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_FIXED_MEMORY = 0;
-const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY = 0;
-const NdbDictionary::Column * NdbDictionary::Column::ROW_COUNT = 0;
-const NdbDictionary::Column * NdbDictionary::Column::COMMIT_COUNT = 0;
-const NdbDictionary::Column * NdbDictionary::Column::ROW_SIZE = 0;
-const NdbDictionary::Column * NdbDictionary::Column::RANGE_NO = 0;
-const NdbDictionary::Column * NdbDictionary::Column::DISK_REF = 0;
-const NdbDictionary::Column * NdbDictionary::Column::RECORDS_IN_RANGE = 0;
-const NdbDictionary::Column * NdbDictionary::Column::ROWID = 0;
-const NdbDictionary::Column * NdbDictionary::Column::ROW_GCI = 0;
-const NdbDictionary::Column * NdbDictionary::Column::ANY_VALUE = 0;
-const NdbDictionary::Column * NdbDictionary::Column::COPY_ROWID = 0;
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
deleted file mode 100644
index e3cf3488ce7..00000000000
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ /dev/null
@@ -1,1221 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NdbDictionaryImpl_H
-#define NdbDictionaryImpl_H
-
-#include <ndb_types.h>
-#include <kernel_types.h>
-#include <NdbError.hpp>
-#include <BaseString.hpp>
-#include <Vector.hpp>
-#include <UtilBuffer.hpp>
-#include <NdbDictionary.hpp>
-#include <Bitmask.hpp>
-#include <AttributeList.hpp>
-#include <Ndb.hpp>
-#include "NdbWaiter.hpp"
-#include "DictCache.hpp"
-
-bool
-is_ndb_blob_table(const char* name, Uint32* ptab_id = 0, Uint32* pcol_no = 0);
-bool
-is_ndb_blob_table(const class NdbTableImpl* t);
-
-extern int ndb_dictionary_is_mysqld;
-#define ASSERT_NOT_MYSQLD assert(ndb_dictionary_is_mysqld == 0)
-
-class NdbDictObjectImpl {
-public:
- int m_id;
- Uint32 m_version;
- NdbDictionary::Object::Type m_type;
- NdbDictionary::Object::Status m_status;
-
- bool change();
-
- static NdbDictObjectImpl & getImpl(NdbDictionary::ObjectId & t) {
- return t.m_impl;
- }
- static const NdbDictObjectImpl & getImpl(const NdbDictionary::ObjectId & t){
- return t.m_impl;
- }
-
-protected:
- friend class NdbDictionary::ObjectId;
-
- NdbDictObjectImpl(NdbDictionary::Object::Type type) :
- m_type(type),
- m_status(NdbDictionary::Object::New) {
- m_id = -1;
- }
-};
-
-/**
- * Column
- */
-class NdbColumnImpl : public NdbDictionary::Column {
-public:
- NdbColumnImpl();
- NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor
- ~NdbColumnImpl();
- NdbColumnImpl& operator=(const NdbColumnImpl&);
- void init(Type t = Unsigned);
-
- int m_attrId;
- BaseString m_name;
- NdbDictionary::Column::Type m_type;
- int m_precision;
- int m_scale;
- int m_length;
- int m_column_no;
- CHARSET_INFO * m_cs; // not const in MySQL
-
- bool m_pk;
- bool m_distributionKey;
- bool m_nullable;
- bool m_autoIncrement;
- Uint64 m_autoIncrementInitialValue;
- BaseString m_defaultValue;
- NdbTableImpl * m_blobTable;
-
- /**
- * Internal types and sizes, and aggregates
- */
- Uint32 m_attrSize; // element size (size when arraySize==1)
- Uint32 m_arraySize; // length or maxlength+1/2 for Var* types
- Uint32 m_arrayType; // NDB_ARRAYTYPE_FIXED or _VAR
- Uint32 m_storageType; // NDB_STORAGETYPE_MEMORY or _DISK
- /*
- * NdbTableImpl: if m_pk, 0-based index of key in m_attrId order
- * NdbIndexImpl: m_column_no of primary table column
- */
- Uint32 m_keyInfoPos;
- // TODO: use bits in attr desc 2
- bool getInterpretableType() const ;
- bool getCharType() const;
- bool getStringType() const;
- bool getBlobType() const;
-
- /**
- * Equality/assign
- */
- bool equal(const NdbColumnImpl&) const;
-
- static NdbColumnImpl & getImpl(NdbDictionary::Column & t);
- static const NdbColumnImpl & getImpl(const NdbDictionary::Column & t);
- NdbDictionary::Column * m_facade;
-
- static NdbDictionary::Column * create_pseudo(const char *);
-
- // Get total length in bytes, used by NdbOperation
- bool get_var_length(const void* value, Uint32& len) const;
-};
-
-class NdbTableImpl : public NdbDictionary::Table, public NdbDictObjectImpl {
-public:
- NdbTableImpl();
- NdbTableImpl(NdbDictionary::Table &);
- ~NdbTableImpl();
-
- void init();
- int setName(const char * name);
- const char * getName() const;
- void setFragmentCount(Uint32 count);
- Uint32 getFragmentCount() const;
- int setFrm(const void* data, Uint32 len);
- const void * getFrmData() const;
- Uint32 getFrmLength() const;
- int setFragmentData(const void* data, Uint32 len);
- const void * getFragmentData() const;
- Uint32 getFragmentDataLen() const;
- int setTablespaceNames(const void* data, Uint32 len);
- Uint32 getTablespaceNamesLen() const;
- const void * getTablespaceNames() const;
- int setTablespaceData(const void* data, Uint32 len);
- const void * getTablespaceData() const;
- Uint32 getTablespaceDataLen() const;
- int setRangeListData(const void* data, Uint32 len);
- const void * getRangeListData() const;
- Uint32 getRangeListDataLen() const;
-
- const char * getMysqlName() const;
- int updateMysqlName();
-
- int aggregate(NdbError& error);
- int validate(NdbError& error);
-
- Uint32 m_changeMask;
- Uint32 m_primaryTableId;
- BaseString m_internalName;
- BaseString m_externalName;
- BaseString m_mysqlName;
- BaseString m_newExternalName; // Used for alter table
- UtilBuffer m_frm;
- UtilBuffer m_newFrm; // Used for alter table
- UtilBuffer m_ts_name; //Tablespace Names
- UtilBuffer m_new_ts_name; //Tablespace Names
- UtilBuffer m_ts; //TablespaceData
- UtilBuffer m_new_ts; //TablespaceData
- UtilBuffer m_fd; //FragmentData
- UtilBuffer m_new_fd; //FragmentData
- UtilBuffer m_range; //Range Or List Array
- UtilBuffer m_new_range; //Range Or List Array
- NdbDictionary::Object::FragmentType m_fragmentType;
-
- /**
- *
- */
- Uint32 m_columnHashMask;
- Vector<Uint32> m_columnHash;
- Vector<NdbColumnImpl *> m_columns;
- void computeAggregates();
- int buildColumnHash();
-
- /**
- * Fragment info
- */
- Uint32 m_hashValueMask;
- Uint32 m_hashpointerValue;
- Vector<Uint16> m_fragments;
-
- Uint64 m_max_rows;
- Uint64 m_min_rows;
- Uint32 m_default_no_part_flag;
- bool m_linear_flag;
- bool m_logging;
- bool m_temporary;
- bool m_row_gci;
- bool m_row_checksum;
- bool m_force_var_part;
- int m_kvalue;
- int m_minLoadFactor;
- int m_maxLoadFactor;
- Uint16 m_keyLenInWords;
- Uint16 m_fragmentCount;
- Uint8 m_single_user_mode;
-
- NdbIndexImpl * m_index;
- NdbColumnImpl * getColumn(unsigned attrId);
- NdbColumnImpl * getColumn(const char * name);
- const NdbColumnImpl * getColumn(unsigned attrId) const;
- const NdbColumnImpl * getColumn(const char * name) const;
-
- /**
- * Index only stuff
- */
- BaseString m_primaryTable;
- NdbDictionary::Object::Type m_indexType;
-
- /**
- * Aggregates
- */
- Uint8 m_noOfKeys;
- // if all pk = dk then this is zero!
- Uint8 m_noOfDistributionKeys;
- Uint8 m_noOfBlobs;
- Uint8 m_noOfDiskColumns;
- Uint8 m_replicaCount;
-
- /**
- * Equality/assign
- */
- bool equal(const NdbTableImpl&) const;
- int assign(const NdbTableImpl&);
-
- static NdbTableImpl & getImpl(NdbDictionary::Table & t);
- static NdbTableImpl & getImpl(const NdbDictionary::Table & t);
- NdbDictionary::Table * m_facade;
-
- /**
- * Return count
- */
- Uint32 get_nodes(Uint32 hashValue, const Uint16** nodes) const ;
-
- /**
- * Disk stuff
- */
- BaseString m_tablespace_name;
- Uint32 m_tablespace_id;
- Uint32 m_tablespace_version;
-};
-
-class NdbIndexImpl : public NdbDictionary::Index, public NdbDictObjectImpl {
-public:
- NdbIndexImpl();
- NdbIndexImpl(NdbDictionary::Index &);
- ~NdbIndexImpl();
-
- void init();
- int setName(const char * name);
- const char * getName() const;
- int setTable(const char * table);
- const char * getTable() const;
- const NdbTableImpl * getIndexTable() const;
-
- BaseString m_internalName;
- BaseString m_externalName;
- BaseString m_tableName;
- Uint32 m_table_id;
- Uint32 m_table_version;
- Vector<NdbColumnImpl *> m_columns;
- Vector<int> m_key_ids;
-
- bool m_logging;
- bool m_temporary;
-
- NdbTableImpl * m_table;
-
- static NdbIndexImpl & getImpl(NdbDictionary::Index & t);
- static NdbIndexImpl & getImpl(const NdbDictionary::Index & t);
- NdbDictionary::Index * m_facade;
-};
-
-class NdbEventImpl : public NdbDictionary::Event, public NdbDictObjectImpl {
- friend class NdbDictInterface;
- friend class NdbDictionaryImpl;
- friend class NdbEventOperation;
- friend class NdbEventOperationImpl;
- friend class NdbEventBuffer;
- friend class EventBufData_hash;
- friend class NdbBlob;
-public:
- NdbEventImpl();
- NdbEventImpl(NdbDictionary::Event &);
- ~NdbEventImpl();
-
- void init();
- int setName(const char * name);
- const char * getName() const;
- int setTable(const NdbDictionary::Table& table);
- const NdbDictionary::Table * getTable() const;
- int setTable(const char * table);
- const char * getTableName() const;
- void addTableEvent(const NdbDictionary::Event::TableEvent t);
- bool getTableEvent(const NdbDictionary::Event::TableEvent t) const;
- void setDurability(NdbDictionary::Event::EventDurability d);
- NdbDictionary::Event::EventDurability getDurability() const;
- void setReport(NdbDictionary::Event::EventReport r);
- NdbDictionary::Event::EventReport getReport() const;
- int getNoOfEventColumns() const;
- const NdbDictionary::Column * getEventColumn(unsigned no) const;
-
- void print() {
- ndbout_c("NdbEventImpl: id=%d, key=%d",
- m_eventId,
- m_eventKey);
- };
-
- Uint32 m_eventId;
- Uint32 m_eventKey;
- AttributeMask m_attrListBitmask;
- Uint32 m_table_id;
- Uint32 m_table_version;
- BaseString m_name;
- Uint32 mi_type;
- NdbDictionary::Event::EventDurability m_dur;
- NdbDictionary::Event::EventReport m_rep;
- bool m_mergeEvents;
-
- BaseString m_tableName;
- Vector<NdbColumnImpl *> m_columns;
- Vector<unsigned> m_attrIds;
-
- static NdbEventImpl & getImpl(NdbDictionary::Event & t);
- static NdbEventImpl & getImpl(const NdbDictionary::Event & t);
- NdbDictionary::Event * m_facade;
-private:
- NdbTableImpl *m_tableImpl;
- void setTable(NdbTableImpl *tableImpl);
-};
-
-struct NdbFilegroupImpl : public NdbDictObjectImpl {
- NdbFilegroupImpl(NdbDictionary::Object::Type t);
-
- BaseString m_name;
- NdbDictionary::AutoGrowSpecification m_grow_spec;
-
- union {
- Uint32 m_extent_size;
- Uint32 m_undo_buffer_size;
- };
-
- BaseString m_logfile_group_name;
- Uint32 m_logfile_group_id;
- Uint32 m_logfile_group_version;
- Uint64 m_undo_free_words;
-};
-
-class NdbTablespaceImpl : public NdbDictionary::Tablespace,
- public NdbFilegroupImpl {
-public:
- NdbTablespaceImpl();
- NdbTablespaceImpl(NdbDictionary::Tablespace &);
- ~NdbTablespaceImpl();
-
- int assign(const NdbTablespaceImpl&);
-
- static NdbTablespaceImpl & getImpl(NdbDictionary::Tablespace & t);
- static const NdbTablespaceImpl & getImpl(const NdbDictionary::Tablespace &);
- NdbDictionary::Tablespace * m_facade;
-};
-
-class NdbLogfileGroupImpl : public NdbDictionary::LogfileGroup,
- public NdbFilegroupImpl {
-public:
- NdbLogfileGroupImpl();
- NdbLogfileGroupImpl(NdbDictionary::LogfileGroup &);
- ~NdbLogfileGroupImpl();
-
- int assign(const NdbLogfileGroupImpl&);
-
- static NdbLogfileGroupImpl & getImpl(NdbDictionary::LogfileGroup & t);
- static const NdbLogfileGroupImpl& getImpl(const
- NdbDictionary::LogfileGroup&);
- NdbDictionary::LogfileGroup * m_facade;
-};
-
-struct NdbFileImpl : public NdbDictObjectImpl {
- NdbFileImpl(NdbDictionary::Object::Type t);
-
- Uint64 m_size;
- Uint64 m_free;
- BaseString m_path;
- BaseString m_filegroup_name;
- Uint32 m_filegroup_id;
- Uint32 m_filegroup_version;
-};
-
-class NdbDatafileImpl : public NdbDictionary::Datafile, public NdbFileImpl {
-public:
- NdbDatafileImpl();
- NdbDatafileImpl(NdbDictionary::Datafile &);
- ~NdbDatafileImpl();
-
- int assign(const NdbDatafileImpl&);
-
- static NdbDatafileImpl & getImpl(NdbDictionary::Datafile & t);
- static const NdbDatafileImpl & getImpl(const NdbDictionary::Datafile & t);
- NdbDictionary::Datafile * m_facade;
-};
-
-class NdbUndofileImpl : public NdbDictionary::Undofile, public NdbFileImpl {
-public:
- NdbUndofileImpl();
- NdbUndofileImpl(NdbDictionary::Undofile &);
- ~NdbUndofileImpl();
-
- int assign(const NdbUndofileImpl&);
-
- static NdbUndofileImpl & getImpl(NdbDictionary::Undofile & t);
- static const NdbUndofileImpl & getImpl(const NdbDictionary::Undofile & t);
- NdbDictionary::Undofile * m_facade;
-};
-
-class NdbDictInterface {
-public:
- NdbDictInterface(NdbError& err) : m_error(err) {
- m_reference = 0;
- m_masterNodeId = 0;
- m_transporter= NULL;
- }
- ~NdbDictInterface();
-
- bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
- bool setTransporter(class TransporterFacade * tf);
-
- // To abstract the stuff thats made in all create/drop/lists below
- int dictSignal(NdbApiSignal* signal, LinearSectionPtr ptr[3], int secs,
- int nodeId, // -1 any, 0 = master, >1 = specified
- WaitSignalType wst,
- int timeout, Uint32 RETRIES,
- const int *errcodes = 0, int temporaryMask = 0);
-
- int createOrAlterTable(class Ndb & ndb, NdbTableImpl &, bool alter);
-
- int createTable(class Ndb & ndb, NdbTableImpl &);
- int alterTable(class Ndb & ndb, NdbTableImpl &);
- int dropTable(const NdbTableImpl &);
-
- int createIndex(class Ndb & ndb, const NdbIndexImpl &, const NdbTableImpl &);
- int dropIndex(const NdbIndexImpl &, const NdbTableImpl &);
-
- int createEvent(class Ndb & ndb, NdbEventImpl &, int getFlag);
- int dropEvent(const NdbEventImpl &);
- int dropEvent(NdbApiSignal* signal, LinearSectionPtr ptr[3], int noLSP);
-
- int executeSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
- int stopSubscribeEvent(class Ndb & ndb, NdbEventOperationImpl &);
-
- int listObjects(NdbDictionary::Dictionary::List& list, Uint32 requestData, bool fullyQualifiedNames);
- int listObjects(NdbApiSignal* signal);
-
- NdbTableImpl * getTable(int tableId, bool fullyQualifiedNames);
- NdbTableImpl * getTable(const BaseString& name, bool fullyQualifiedNames);
- NdbTableImpl * getTable(class NdbApiSignal * signal,
- LinearSectionPtr ptr[3],
- Uint32 noOfSections, bool fullyQualifiedNames);
-
- int forceGCPWait();
-
- static int parseTableInfo(NdbTableImpl ** dst,
- const Uint32 * data, Uint32 len,
- bool fullyQualifiedNames,
- Uint32 version= 0xFFFFFFFF);
-
- static int parseFileInfo(NdbFileImpl &dst,
- const Uint32 * data, Uint32 len);
-
- static int parseFilegroupInfo(NdbFilegroupImpl &dst,
- const Uint32 * data, Uint32 len);
-
- int create_file(const NdbFileImpl &, const NdbFilegroupImpl&,
- bool overwrite, NdbDictObjectImpl*);
- int drop_file(const NdbFileImpl &);
- int create_filegroup(const NdbFilegroupImpl &, NdbDictObjectImpl*);
- int drop_filegroup(const NdbFilegroupImpl &);
-
- int get_filegroup(NdbFilegroupImpl&, NdbDictionary::Object::Type, Uint32);
- int get_filegroup(NdbFilegroupImpl&,NdbDictionary::Object::Type,const char*);
- int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, int);
- int get_file(NdbFileImpl&, NdbDictionary::Object::Type, int, const char *);
-
- static int create_index_obj_from_table(NdbIndexImpl ** dst,
- NdbTableImpl* index_table,
- const NdbTableImpl* primary_table);
-
- const NdbError &getNdbError() const;
- NdbError & m_error;
-private:
- Uint32 m_reference;
- Uint32 m_masterNodeId;
-
- NdbWaiter m_waiter;
- class TransporterFacade * m_transporter;
-
- friend class Ndb;
- friend class NdbDictionaryImpl;
- static void execSignal(void* dictImpl,
- class NdbApiSignal* signal,
- struct LinearSectionPtr ptr[3]);
-
- static void execNodeStatus(void* dictImpl, Uint32,
- bool alive, bool nfCompleted);
-
- void execGET_TABINFO_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execGET_TABINFO_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execALTER_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execALTER_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execCREATE_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_INDX_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_INDX_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execCREATE_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execSUB_START_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execSUB_START_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execSUB_STOP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execSUB_STOP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_EVNT_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_EVNT_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execDROP_TABLE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_TABLE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execLIST_TABLES_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execCREATE_FILE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_FILE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execCREATE_FILEGROUP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execCREATE_FILEGROUP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execDROP_FILE_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_FILE_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execDROP_FILEGROUP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execDROP_FILEGROUP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- void execWAIT_GCP_CONF(NdbApiSignal *, LinearSectionPtr ptr[3]);
- void execWAIT_GCP_REF(NdbApiSignal *, LinearSectionPtr ptr[3]);
-
- Uint32 m_fragmentId;
- UtilBuffer m_buffer;
-};
-
-class NdbDictionaryImpl;
-class GlobalCacheInitObject
-{
-public:
- NdbDictionaryImpl *m_dict;
- const BaseString &m_name;
- GlobalCacheInitObject(NdbDictionaryImpl *dict,
- const BaseString &name) :
- m_dict(dict),
- m_name(name)
- {}
- virtual ~GlobalCacheInitObject() {}
- virtual int init(NdbTableImpl &tab) const = 0;
-};
-
-class NdbDictionaryImpl : public NdbDictionary::Dictionary {
-public:
- NdbDictionaryImpl(Ndb &ndb);
- NdbDictionaryImpl(Ndb &ndb, NdbDictionary::Dictionary & f);
- ~NdbDictionaryImpl();
-
- bool setTransporter(class Ndb * ndb, class TransporterFacade * tf);
- bool setTransporter(class TransporterFacade * tf);
-
- int createTable(NdbTableImpl &t);
- int createBlobTables(NdbTableImpl& org, NdbTableImpl& created);
- int alterTable(NdbTableImpl &t);
- int dropTable(const char * name);
- int dropTable(NdbTableImpl &);
- int dropBlobTables(NdbTableImpl &);
- int invalidateObject(NdbTableImpl &);
- int removeCachedObject(NdbTableImpl &);
-
- int createIndex(NdbIndexImpl &ix);
- int createIndex(NdbIndexImpl &ix, NdbTableImpl & tab);
- int dropIndex(const char * indexName,
- const char * tableName);
- int dropIndex(NdbIndexImpl &, const char * tableName);
- NdbTableImpl * getIndexTable(NdbIndexImpl * index,
- NdbTableImpl * table);
-
- int createEvent(NdbEventImpl &);
- int createBlobEvents(NdbEventImpl &);
- int dropEvent(const char * eventName);
- int dropEvent(const NdbEventImpl &);
- int dropBlobEvents(const NdbEventImpl &);
-
- int executeSubscribeEvent(NdbEventOperationImpl &);
- int stopSubscribeEvent(NdbEventOperationImpl &);
-
- int forceGCPWait();
-
- int listObjects(List& list, NdbDictionary::Object::Type type);
- int listIndexes(List& list, Uint32 indexId);
-
- NdbTableImpl * getTableGlobal(const char * tableName);
- NdbIndexImpl * getIndexGlobal(const char * indexName,
- NdbTableImpl &ndbtab);
- int alterTableGlobal(NdbTableImpl &orig_impl, NdbTableImpl &impl);
- int dropTableGlobal(NdbTableImpl &);
- int dropIndexGlobal(NdbIndexImpl & impl);
- int releaseTableGlobal(NdbTableImpl & impl, int invalidate);
- int releaseIndexGlobal(NdbIndexImpl & impl, int invalidate);
-
- NdbTableImpl * getTable(const char * tableName, void **data= 0);
- NdbTableImpl * getBlobTable(const NdbTableImpl&, uint col_no);
- NdbTableImpl * getBlobTable(uint tab_id, uint col_no);
- void putTable(NdbTableImpl *impl);
- int getBlobTables(NdbTableImpl &);
- Ndb_local_table_info*
- get_local_table_info(const BaseString& internalTableName);
- NdbIndexImpl * getIndex(const char * indexName,
- const char * tableName);
- NdbIndexImpl * getIndex(const char * indexName, const NdbTableImpl& prim);
- NdbEventImpl * getEvent(const char * eventName, NdbTableImpl* = NULL);
- NdbEventImpl * getBlobEvent(const NdbEventImpl& ev, uint col_no);
- NdbEventImpl * getEventImpl(const char * internalName);
-
- int createDatafile(const NdbDatafileImpl &, bool force, NdbDictObjectImpl*);
- int dropDatafile(const NdbDatafileImpl &);
- int createUndofile(const NdbUndofileImpl &, bool force, NdbDictObjectImpl*);
- int dropUndofile(const NdbUndofileImpl &);
-
- int createTablespace(const NdbTablespaceImpl &, NdbDictObjectImpl*);
- int dropTablespace(const NdbTablespaceImpl &);
-
- int createLogfileGroup(const NdbLogfileGroupImpl &, NdbDictObjectImpl*);
- int dropLogfileGroup(const NdbLogfileGroupImpl &);
-
- const NdbError & getNdbError() const;
- NdbError m_error;
- Uint32 m_local_table_data_size;
-
- LocalDictCache m_localHash;
- GlobalDictCache * m_globalHash;
-
- static NdbDictionaryImpl & getImpl(NdbDictionary::Dictionary & t);
- static const NdbDictionaryImpl & getImpl(const NdbDictionary::Dictionary &t);
- NdbDictionary::Dictionary * m_facade;
-
- NdbDictInterface m_receiver;
- Ndb & m_ndb;
-
- NdbIndexImpl* getIndexImpl(const char * externalName,
- const BaseString& internalName,
- NdbTableImpl &tab,
- NdbTableImpl &prim);
- NdbIndexImpl * getIndexImpl(const char * name,
- const BaseString& internalName);
-private:
- NdbTableImpl * fetchGlobalTableImplRef(const GlobalCacheInitObject &obj);
-};
-
-inline
-NdbEventImpl &
-NdbEventImpl::getImpl(const NdbDictionary::Event & t){
- return t.m_impl;
-}
-
-inline
-NdbEventImpl &
-NdbEventImpl::getImpl(NdbDictionary::Event & t){
- return t.m_impl;
-}
-
-inline
-NdbColumnImpl &
-NdbColumnImpl::getImpl(NdbDictionary::Column & t){
- return t.m_impl;
-}
-
-inline
-const NdbColumnImpl &
-NdbColumnImpl::getImpl(const NdbDictionary::Column & t){
- return t.m_impl;
-}
-
-inline
-bool
-NdbColumnImpl::getInterpretableType() const {
- return (m_type == NdbDictionary::Column::Unsigned ||
- m_type == NdbDictionary::Column::Bigunsigned);
-}
-
-inline
-bool
-NdbColumnImpl::getCharType() const {
- return (m_type == NdbDictionary::Column::Char ||
- m_type == NdbDictionary::Column::Varchar ||
- m_type == NdbDictionary::Column::Text ||
- m_type == NdbDictionary::Column::Longvarchar);
-}
-
-inline
-bool
-NdbColumnImpl::getStringType() const {
- return (m_type == NdbDictionary::Column::Char ||
- m_type == NdbDictionary::Column::Varchar ||
- m_type == NdbDictionary::Column::Longvarchar ||
- m_type == NdbDictionary::Column::Binary ||
- m_type == NdbDictionary::Column::Varbinary ||
- m_type == NdbDictionary::Column::Longvarbinary);
-}
-
-inline
-bool
-NdbColumnImpl::getBlobType() const {
- return (m_type == NdbDictionary::Column::Blob ||
- m_type == NdbDictionary::Column::Text);
-}
-
-inline
-bool
-NdbColumnImpl::get_var_length(const void* value, Uint32& len) const
-{
- Uint32 max_len = m_attrSize * m_arraySize;
- switch (m_arrayType) {
- case NDB_ARRAYTYPE_SHORT_VAR:
- len = 1 + *((Uint8*)value);
- break;
- case NDB_ARRAYTYPE_MEDIUM_VAR:
- len = 2 + uint2korr((char*)value);
- break;
- default:
- len = max_len;
- return true;
- }
- return (len <= max_len);
-}
-
-inline
-NdbTableImpl &
-NdbTableImpl::getImpl(NdbDictionary::Table & t){
- return t.m_impl;
-}
-
-inline
-NdbTableImpl &
-NdbTableImpl::getImpl(const NdbDictionary::Table & t){
- return t.m_impl;
-}
-
-inline
-NdbColumnImpl *
-NdbTableImpl::getColumn(unsigned attrId){
- if(m_columns.size() > attrId){
- return m_columns[attrId];
- }
- return 0;
-}
-
-inline
-const char *
-NdbTableImpl::getMysqlName() const
-{
- return m_mysqlName.c_str();
-}
-
-inline
-Uint32
-Hash( const char* str ){
- Uint32 h = 0;
- Uint32 len = strlen(str);
- while(len >= 4){
- h = (h << 5) + h + str[0];
- h = (h << 5) + h + str[1];
- h = (h << 5) + h + str[2];
- h = (h << 5) + h + str[3];
- len -= 4;
- str += 4;
- }
-
- switch(len){
- case 3:
- h = (h << 5) + h + *str++;
- case 2:
- h = (h << 5) + h + *str++;
- case 1:
- h = (h << 5) + h + *str++;
- }
- return h + h;
-}
-
-
-inline
-NdbColumnImpl *
-NdbTableImpl::getColumn(const char * name){
-
- Uint32 sz = m_columns.size();
- NdbColumnImpl** cols = m_columns.getBase();
- const Uint32 * hashtable = m_columnHash.getBase();
-
- if(sz > 5 && false){
- Uint32 hashValue = Hash(name) & 0xFFFE;
- Uint32 bucket = hashValue & m_columnHashMask;
- bucket = (bucket < sz ? bucket : bucket - sz);
- hashtable += bucket;
- Uint32 tmp = * hashtable;
- if((tmp & 1) == 1 ){ // No chaining
- sz = 1;
- } else {
- sz = (tmp >> 16);
- hashtable += (tmp & 0xFFFE) >> 1;
- tmp = * hashtable;
- }
- do {
- if(hashValue == (tmp & 0xFFFE)){
- NdbColumnImpl* col = cols[tmp >> 16];
- if(strncmp(name, col->m_name.c_str(), col->m_name.length()) == 0){
- return col;
- }
- }
- hashtable++;
- tmp = * hashtable;
- } while(--sz > 0);
-#if 0
- Uint32 dir = m_columnHash[bucket];
- Uint32 pos = bucket + ((dir & 0xFFFE) >> 1);
- Uint32 cnt = dir >> 16;
- ndbout_c("col: %s hv: %x bucket: %d dir: %x pos: %d cnt: %d tmp: %d -> 0",
- name, hashValue, bucket, dir, pos, cnt, tmp);
-#endif
- return 0;
- } else {
- for(Uint32 i = 0; i<sz; i++){
- NdbColumnImpl* col = * cols++;
- if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
- return col;
- }
- }
- return 0;
-}
-
-inline
-const NdbColumnImpl *
-NdbTableImpl::getColumn(unsigned attrId) const {
- if(m_columns.size() > attrId){
- return m_columns[attrId];
- }
- return 0;
-}
-
-inline
-const NdbColumnImpl *
-NdbTableImpl::getColumn(const char * name) const {
- Uint32 sz = m_columns.size();
- NdbColumnImpl* const * cols = m_columns.getBase();
- for(Uint32 i = 0; i<sz; i++, cols++){
- NdbColumnImpl* col = * cols;
- if(col != 0 && strcmp(name, col->m_name.c_str()) == 0)
- return col;
- }
- return 0;
-}
-
-inline
-NdbIndexImpl &
-NdbIndexImpl::getImpl(NdbDictionary::Index & t){
- return t.m_impl;
-}
-
-inline
-NdbIndexImpl &
-NdbIndexImpl::getImpl(const NdbDictionary::Index & t){
- return t.m_impl;
-}
-
-inline
-NdbDictionaryImpl &
-NdbDictionaryImpl::getImpl(NdbDictionary::Dictionary & t){
- return t.m_impl;
-}
-
-inline
-const NdbDictionaryImpl &
-NdbDictionaryImpl::getImpl(const NdbDictionary::Dictionary & t){
- return t.m_impl;
-}
-
-/*****************************************************************
- * Inline:d getters
- */
-
-class InitTable : public GlobalCacheInitObject
-{
-public:
- InitTable(NdbDictionaryImpl *dict,
- const BaseString &name) :
- GlobalCacheInitObject(dict, name)
- {}
- int init(NdbTableImpl &tab) const
- {
- return m_dict->getBlobTables(tab);
- }
-};
-
-inline
-NdbTableImpl *
-NdbDictionaryImpl::getTableGlobal(const char * table_name)
-{
- const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
- return fetchGlobalTableImplRef(InitTable(this, internal_tabname));
-}
-
-inline
-NdbTableImpl *
-NdbDictionaryImpl::getTable(const char * table_name, void **data)
-{
- DBUG_ENTER("NdbDictionaryImpl::getTable");
- DBUG_PRINT("enter", ("table: %s", table_name));
-
- if (unlikely(strchr(table_name, '$') != 0)) {
- Uint32 tab_id, col_no;
- if (is_ndb_blob_table(table_name, &tab_id, &col_no)) {
- NdbTableImpl* t = getBlobTable(tab_id, col_no);
- DBUG_RETURN(t);
- }
- }
-
- const BaseString internal_tabname(m_ndb.internalize_table_name(table_name));
- Ndb_local_table_info *info=
- get_local_table_info(internal_tabname);
- if (info == 0)
- DBUG_RETURN(0);
- if (data)
- *data= info->m_local_data;
- DBUG_RETURN(info->m_table_impl);
-}
-
-inline
-Ndb_local_table_info *
-NdbDictionaryImpl::get_local_table_info(const BaseString& internalTableName)
-{
- DBUG_ENTER("NdbDictionaryImpl::get_local_table_info");
- DBUG_PRINT("enter", ("table: %s", internalTableName.c_str()));
-
- Ndb_local_table_info *info= m_localHash.get(internalTableName.c_str());
- if (info == 0)
- {
- NdbTableImpl *tab=
- fetchGlobalTableImplRef(InitTable(this, internalTableName));
- if (tab)
- {
- info= Ndb_local_table_info::create(tab, m_local_table_data_size);
- if (info)
- {
- m_localHash.put(internalTableName.c_str(), info);
- }
- }
- }
- DBUG_RETURN(info); // autoincrement already initialized
-}
-
-class InitIndex : public GlobalCacheInitObject
-{
-public:
- const char *m_index_name;
- const NdbTableImpl &m_prim;
-
- InitIndex(const BaseString &internal_indexname,
- const char *index_name,
- const NdbTableImpl &prim) :
- GlobalCacheInitObject(0, internal_indexname),
- m_index_name(index_name),
- m_prim(prim)
- {}
-
- int init(NdbTableImpl &tab) const {
- DBUG_ENTER("InitIndex::init");
- DBUG_ASSERT(tab.m_indexType != NdbDictionary::Object::TypeUndefined);
- /**
- * Create index impl
- */
- NdbIndexImpl* idx;
- if(NdbDictInterface::create_index_obj_from_table(&idx, &tab, &m_prim) == 0)
- {
- idx->m_table = &tab;
- if (!idx->m_externalName.assign(m_index_name) ||
- !idx->m_internalName.assign(m_name))
- DBUG_RETURN(4000);
- tab.m_index = idx;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
- }
-};
-
-inline
-NdbIndexImpl *
-NdbDictionaryImpl::getIndexGlobal(const char * index_name,
- NdbTableImpl &ndbtab)
-{
- DBUG_ENTER("NdbDictionaryImpl::getIndexGlobal");
- const BaseString
- internal_indexname(m_ndb.internalize_index_name(&ndbtab, index_name));
- int retry= 2;
-
- while (retry)
- {
- NdbTableImpl *tab=
- fetchGlobalTableImplRef(InitIndex(internal_indexname,
- index_name, ndbtab));
- if (tab)
- {
- // tab->m_index sould be set. otherwise tab == 0
- NdbIndexImpl *idx= tab->m_index;
- if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
- idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
- {
- releaseIndexGlobal(*idx, 1);
- retry--;
- continue;
- }
- DBUG_RETURN(idx);
- }
- break;
- }
- {
- // Index not found, try old format
- const BaseString
- old_internal_indexname(m_ndb.old_internalize_index_name(&ndbtab,
- index_name));
- retry= 2;
- while (retry)
- {
- NdbTableImpl *tab=
- fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
- index_name, ndbtab));
- if (tab)
- {
- // tab->m_index sould be set. otherwise tab == 0
- NdbIndexImpl *idx= tab->m_index;
- if (idx->m_table_id != (unsigned)ndbtab.getObjectId() ||
- idx->m_table_version != (unsigned)ndbtab.getObjectVersion())
- {
- releaseIndexGlobal(*idx, 1);
- retry--;
- continue;
- }
- DBUG_RETURN(idx);
- }
- break;
- }
- }
- m_error.code= 4243;
- DBUG_RETURN(0);
-}
-
-inline int
-NdbDictionaryImpl::releaseTableGlobal(NdbTableImpl & impl, int invalidate)
-{
- DBUG_ENTER("NdbDictionaryImpl::releaseTableGlobal");
- DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
- m_globalHash->lock();
- m_globalHash->release(&impl, invalidate);
- m_globalHash->unlock();
- DBUG_RETURN(0);
-}
-
-inline int
-NdbDictionaryImpl::releaseIndexGlobal(NdbIndexImpl & impl, int invalidate)
-{
- DBUG_ENTER("NdbDictionaryImpl::releaseIndexGlobal");
- DBUG_PRINT("enter", ("internal_name: %s", impl.m_internalName.c_str()));
- m_globalHash->lock();
- m_globalHash->release(impl.m_table, invalidate);
- m_globalHash->unlock();
- DBUG_RETURN(0);
-}
-
-inline
-NdbIndexImpl *
-NdbDictionaryImpl::getIndex(const char * index_name,
- const char * table_name)
-{
- if (table_name == 0)
- {
- assert(0);
- m_error.code= 4243;
- return 0;
- }
-
-
- NdbTableImpl* prim = getTable(table_name);
- if (prim == 0)
- {
- m_error.code= 4243;
- return 0;
- }
-
- return getIndex(index_name, *prim);
-}
-
-inline
-NdbIndexImpl *
-NdbDictionaryImpl::getIndex(const char* index_name,
- const NdbTableImpl& prim)
-{
-
- const BaseString
- internal_indexname(m_ndb.internalize_index_name(&prim, index_name));
-
- Ndb_local_table_info *info= m_localHash.get(internal_indexname.c_str());
- NdbTableImpl *tab;
- if (info == 0)
- {
- tab= fetchGlobalTableImplRef(InitIndex(internal_indexname,
- index_name,
- prim));
- if (!tab)
- goto retry;
-
- info= Ndb_local_table_info::create(tab, 0);
- if (!info)
- goto retry;
- m_localHash.put(internal_indexname.c_str(), info);
- }
- else
- tab= info->m_table_impl;
-
- return tab->m_index;
-
-retry:
- // Index not found, try fetching it from current database
- const BaseString
- old_internal_indexname(m_ndb.old_internalize_index_name(&prim, index_name));
-
- info= m_localHash.get(old_internal_indexname.c_str());
- if (info == 0)
- {
- tab= fetchGlobalTableImplRef(InitIndex(old_internal_indexname,
- index_name,
- prim));
- if (!tab)
- goto err;
-
- info= Ndb_local_table_info::create(tab, 0);
- if (!info)
- goto err;
- m_localHash.put(old_internal_indexname.c_str(), info);
- }
- else
- tab= info->m_table_impl;
-
- return tab->m_index;
-
-err:
- m_error.code= 4243;
- return 0;
-}
-
-inline
-NdbTablespaceImpl &
-NdbTablespaceImpl::getImpl(NdbDictionary::Tablespace & t){
- return t.m_impl;
-}
-
-inline
-const NdbTablespaceImpl &
-NdbTablespaceImpl::getImpl(const NdbDictionary::Tablespace & t){
- return t.m_impl;
-}
-
-inline
-NdbLogfileGroupImpl &
-NdbLogfileGroupImpl::getImpl(NdbDictionary::LogfileGroup & t){
- return t.m_impl;
-}
-
-inline
-const NdbLogfileGroupImpl &
-NdbLogfileGroupImpl::getImpl(const NdbDictionary::LogfileGroup & t){
- return t.m_impl;
-}
-
-inline
-NdbDatafileImpl &
-NdbDatafileImpl::getImpl(NdbDictionary::Datafile & t){
- return t.m_impl;
-}
-
-inline
-const NdbDatafileImpl &
-NdbDatafileImpl::getImpl(const NdbDictionary::Datafile & t){
- return t.m_impl;
-}
-
-inline
-NdbUndofileImpl &
-NdbUndofileImpl::getImpl(NdbDictionary::Undofile & t){
- return t.m_impl;
-}
-
-inline
-const NdbUndofileImpl &
-NdbUndofileImpl::getImpl(const NdbDictionary::Undofile & t){
- return t.m_impl;
-}
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbErrorOut.cpp b/storage/ndb/src/ndbapi/NdbErrorOut.cpp
deleted file mode 100644
index efd5eb211c7..00000000000
--- a/storage/ndb/src/ndbapi/NdbErrorOut.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <NdbOut.hpp>
-
-#include <NdbError.hpp>
-
-/**
- * operators
- */
-NdbOut &
-operator<<(NdbOut & out, const NdbError & error){
- if(error.message != 0)
- out << error.code << ": " << error.message;
- else
- out << error.code << ": ";
- return out;
-}
-
-NdbOut &
-operator<<(NdbOut & out, const NdbError::Status & status){
- return out << ndberror_status_message((ndberror_status)status);
-}
-
-NdbOut &
-operator<<(NdbOut & out, const NdbError::Classification & classification){
- return out << ndberror_classification_message((ndberror_classification)classification);
-}
-
diff --git a/storage/ndb/src/ndbapi/NdbEventOperation.cpp b/storage/ndb/src/ndbapi/NdbEventOperation.cpp
deleted file mode 100644
index 4ba295534b4..00000000000
--- a/storage/ndb/src/ndbapi/NdbEventOperation.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB, 2010 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <Ndb.hpp>
-#include <NdbError.hpp>
-#include <portlib/NdbMem.h>
-#include "NdbEventOperationImpl.hpp"
-#include "NdbDictionaryImpl.hpp"
-
-NdbEventOperation::NdbEventOperation(Ndb *theNdb,const char* eventName)
- : m_impl(* new NdbEventOperationImpl(*this,theNdb,eventName))
-{
-}
-
-NdbEventOperation::~NdbEventOperation()
-{
- NdbEventOperationImpl * tmp = &m_impl;
- if (this != tmp)
- delete tmp;
-}
-
-NdbEventOperation::State NdbEventOperation::getState()
-{
- return m_impl.getState();
-}
-
-void NdbEventOperation::mergeEvents(bool flag)
-{
- m_impl.m_mergeEvents = flag;
-}
-
-NdbRecAttr *
-NdbEventOperation::getValue(const char *colName, char *aValue)
-{
- return m_impl.getValue(colName, aValue, 0);
-}
-
-NdbRecAttr *
-NdbEventOperation::getPreValue(const char *colName, char *aValue)
-{
- return m_impl.getValue(colName, aValue, 1);
-}
-
-NdbBlob *
-NdbEventOperation::getBlobHandle(const char *colName)
-{
- return m_impl.getBlobHandle(colName, 0);
-}
-
-NdbBlob *
-NdbEventOperation::getPreBlobHandle(const char *colName)
-{
- return m_impl.getBlobHandle(colName, 1);
-}
-
-int
-NdbEventOperation::execute()
-{
- return m_impl.execute();
-}
-
-int
-NdbEventOperation::isOverrun() const
-{
- return 0; // ToDo
-}
-
-bool
-NdbEventOperation::isConsistent() const
-{
- return true;
-}
-
-void
-NdbEventOperation::clearError()
-{
- m_impl.m_has_error= 0;
-}
-
-int
-NdbEventOperation::hasError() const
-{
- return m_impl.m_has_error;
-}
-
-bool NdbEventOperation::tableNameChanged() const
-{
- return m_impl.tableNameChanged();
-}
-
-bool NdbEventOperation::tableFrmChanged() const
-{
- return m_impl.tableFrmChanged();
-}
-
-bool NdbEventOperation::tableFragmentationChanged() const
-{
- return m_impl.tableFragmentationChanged();
-}
-
-bool NdbEventOperation::tableRangeListChanged() const
-{
- return m_impl.tableRangeListChanged();
-}
-
-Uint64
-NdbEventOperation::getGCI() const
-{
- return m_impl.getGCI();
-}
-
-Uint32
-NdbEventOperation::getAnyValue() const
-{
- return m_impl.getAnyValue();
-}
-
-Uint64
-NdbEventOperation::getLatestGCI() const
-{
- return m_impl.getLatestGCI();
-}
-
-NdbDictionary::Event::TableEvent
-NdbEventOperation::getEventType() const
-{
- return m_impl.getEventType();
-}
-
-void
-NdbEventOperation::print()
-{
- m_impl.print();
-}
-
-/*
- * Internal for the mysql server
- */
-const NdbDictionary::Table *NdbEventOperation::getTable() const
-{
- return m_impl.m_eventImpl->m_tableImpl->m_facade;
-}
-const NdbDictionary::Event *NdbEventOperation::getEvent() const
-{
- return m_impl.m_eventImpl->m_facade;
-}
-const NdbRecAttr* NdbEventOperation::getFirstPkAttr() const
-{
- return m_impl.theFirstPkAttrs[0];
-}
-const NdbRecAttr* NdbEventOperation::getFirstPkPreAttr() const
-{
- return m_impl.theFirstPkAttrs[1];
-}
-const NdbRecAttr* NdbEventOperation::getFirstDataAttr() const
-{
- return m_impl.theFirstDataAttrs[0];
-}
-const NdbRecAttr* NdbEventOperation::getFirstDataPreAttr() const
-{
- return m_impl.theFirstDataAttrs[1];
-}
-/*
-bool NdbEventOperation::validateTable(NdbDictionary::Table &table) const
-{
- DBUG_ENTER("NdbEventOperation::validateTable");
- bool res = true;
- if (table.getObjectVersion() != m_impl.m_eventImpl->m_tableVersion)
- {
- DBUG_PRINT("info",("invalid version"));
- res= false;
- }
- DBUG_RETURN(res);
-}
-*/
-void NdbEventOperation::setCustomData(void * data)
-{
- m_impl.m_custom_data= data;
-}
-void * NdbEventOperation::getCustomData() const
-{
- return m_impl.m_custom_data;
-}
-
-int NdbEventOperation::getReqNodeId() const
-{
- return SubTableData::getReqNodeId(m_impl.m_data_item->sdata->requestInfo);
-}
-
-int NdbEventOperation::getNdbdNodeId() const
-{
- return SubTableData::getNdbdNodeId(m_impl.m_data_item->sdata->requestInfo);
-}
-
-/*
- * Private members
- */
-
-NdbEventOperation::NdbEventOperation(NdbEventOperationImpl& impl)
- : m_impl(impl) {}
-
-const struct NdbError &
-NdbEventOperation::getNdbError() const {
- return m_impl.getNdbError();
-}
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
deleted file mode 100644
index 0c6f3acc144..00000000000
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ /dev/null
@@ -1,3007 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB, 2010 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <kernel_types.h>
-
-#include "NdbDictionaryImpl.hpp"
-#include "API.hpp"
-#include <NdbOut.hpp>
-#include "NdbApiSignal.hpp"
-#include "TransporterFacade.hpp"
-#include <signaldata/CreateEvnt.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <SimpleProperties.hpp>
-#include <Bitmask.hpp>
-#include <AttributeHeader.hpp>
-#include <AttributeList.hpp>
-#include <NdbError.hpp>
-#include <BaseString.hpp>
-#include <UtilBuffer.hpp>
-#include <NdbDictionary.hpp>
-#include <Ndb.hpp>
-#include "NdbImpl.hpp"
-#include "DictCache.hpp"
-#include <portlib/NdbMem.h>
-#include <NdbRecAttr.hpp>
-#include <NdbBlob.hpp>
-#include <NdbEventOperation.hpp>
-#include "NdbEventOperationImpl.hpp"
-#include <signaldata/AlterTable.hpp>
-#include "ndb_internal.hpp"
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-static Gci_container_pod g_empty_gci_container;
-static const Uint32 ACTIVE_GCI_DIRECTORY_SIZE = 4;
-static const Uint32 ACTIVE_GCI_MASK = ACTIVE_GCI_DIRECTORY_SIZE - 1;
-
-#if defined(VM_TRACE) && defined(NOT_USED)
-static void
-print_std(const SubTableData * sdata, LinearSectionPtr ptr[3])
-{
- printf("addr=%p gci=%d op=%d\n", (void*)sdata, sdata->gci,
- SubTableData::getOperation(sdata->requestInfo));
- for (int i = 0; i <= 2; i++) {
- printf("sec=%d addr=%p sz=%d\n", i, (void*)ptr[i].p, ptr[i].sz);
- for (int j = 0; (uint) j < ptr[i].sz; j++)
- printf("%08x ", ptr[i].p[j]);
- printf("\n");
- }
-}
-#endif
-
-// EventBufData
-
-Uint32
-EventBufData::get_blob_part_no() const
-{
- assert(ptr[0].sz > 2);
- Uint32 pos = AttributeHeader(ptr[0].p[0]).getDataSize() +
- AttributeHeader(ptr[0].p[1]).getDataSize();
- Uint32 no = ptr[1].p[pos];
- return no;
-}
-
-void
-EventBufData::add_part_size(Uint32 & full_count, Uint32 & full_sz) const
-{
- Uint32 tmp_count = 0;
- Uint32 tmp_sz = 0;
- const EventBufData* data2 = m_next_blob;
- while (data2 != 0) {
- tmp_count++;
- tmp_sz += data2->sz;
- const EventBufData* data3 = data2->m_next;
- while (data3 != 0) {
- tmp_count++;
- tmp_sz += data3->sz;
- data3 = data3->m_next;
- }
- data2 = data2->m_next_blob;
- }
- full_count += tmp_count;
- full_sz += tmp_sz;
-}
-
-/*
- * Class NdbEventOperationImpl
- *
- *
- */
-
-// todo handle several ndb objects
-// todo free allocated data when closing NdbEventBuffer
-
-NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &f,
- Ndb *theNdb,
- const char* eventName) :
- NdbEventOperation(*this),
- m_facade(&f),
- m_ndb(theNdb),
- m_state(EO_ERROR),
- m_oid(~(Uint32)0)
-{
- DBUG_ENTER("NdbEventOperationImpl::NdbEventOperationImpl");
-
- assert(m_ndb != NULL);
- NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
- assert(myDict != NULL);
-
- const NdbDictionary::Event *myEvnt = myDict->getEvent(eventName);
- if (!myEvnt)
- {
- m_error.code= myDict->getNdbError().code;
- DBUG_VOID_RETURN;
- }
-
- init(myEvnt->m_impl);
- DBUG_VOID_RETURN;
-}
-
-NdbEventOperationImpl::NdbEventOperationImpl(Ndb *theNdb,
- NdbEventImpl& evnt) :
- NdbEventOperation(*this),
- m_facade(this),
- m_ndb(theNdb),
- m_state(EO_ERROR),
- m_oid(~(Uint32)0)
-{
- DBUG_ENTER("NdbEventOperationImpl::NdbEventOperationImpl [evnt]");
- init(evnt);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbEventOperationImpl::init(NdbEventImpl& evnt)
-{
- DBUG_ENTER("NdbEventOperationImpl::init");
-
- m_magic_number = 0;
- mi_type = 0;
- m_change_mask = 0;
-#ifdef VM_TRACE
- m_data_done_count = 0;
- m_data_count = 0;
-#endif
- m_next = 0;
- m_prev = 0;
-
- m_eventId = 0;
- theFirstPkAttrs[0] = NULL;
- theCurrentPkAttrs[0] = NULL;
- theFirstPkAttrs[1] = NULL;
- theCurrentPkAttrs[1] = NULL;
- theFirstDataAttrs[0] = NULL;
- theCurrentDataAttrs[0] = NULL;
- theFirstDataAttrs[1] = NULL;
- theCurrentDataAttrs[1] = NULL;
-
- theBlobList = NULL;
- theBlobOpList = NULL;
- theMainOp = NULL;
-
- m_data_item= NULL;
- m_eventImpl = NULL;
-
- m_custom_data= 0;
- m_has_error= 1;
-
- // we should lookup id in Dictionary, TODO
- // also make sure we only have one listener on each event
-
- m_eventImpl = &evnt;
-
- m_eventId = m_eventImpl->m_eventId;
-
- m_oid= m_ndb->theImpl->theNdbObjectIdMap.map(this);
-
- m_state= EO_CREATED;
-
- m_node_bit_mask.clear();
-#ifdef ndb_event_stores_merge_events_flag
- m_mergeEvents = m_eventImpl->m_mergeEvents;
-#else
- m_mergeEvents = false;
-#endif
- m_ref_count = 0;
- DBUG_PRINT("info", ("m_ref_count = 0 for op: 0x%lx", (long) this));
-
- m_has_error= 0;
-
- DBUG_PRINT("exit",("this: 0x%lx oid: %u", (long) this, m_oid));
- DBUG_VOID_RETURN;
-}
-
-NdbEventOperationImpl::~NdbEventOperationImpl()
-{
- DBUG_ENTER("NdbEventOperationImpl::~NdbEventOperationImpl");
- m_magic_number= 0;
-
- if (m_oid == ~(Uint32)0)
- DBUG_VOID_RETURN;
-
- stop();
-
- if (theMainOp == NULL)
- {
- NdbEventOperationImpl* tBlobOp = theBlobOpList;
- while (tBlobOp != NULL)
- {
- NdbEventOperationImpl *op = tBlobOp;
- tBlobOp = tBlobOp->m_next;
- delete op;
- }
- }
-
- m_ndb->theImpl->theNdbObjectIdMap.unmap(m_oid, this);
- DBUG_PRINT("exit",("this: %p/%p oid: %u main: %p",
- this, m_facade, m_oid, theMainOp));
-
- if (m_eventImpl)
- {
- delete m_eventImpl->m_facade;
- m_eventImpl= 0;
- }
-
- DBUG_VOID_RETURN;
-}
-
-NdbEventOperation::State
-NdbEventOperationImpl::getState()
-{
- return m_state;
-}
-
-NdbRecAttr*
-NdbEventOperationImpl::getValue(const char *colName, char *aValue, int n)
-{
- DBUG_ENTER("NdbEventOperationImpl::getValue");
- if (m_state != EO_CREATED) {
- ndbout_c("NdbEventOperationImpl::getValue may only be called between "
- "instantiation and execute()");
- DBUG_RETURN(NULL);
- }
-
- NdbColumnImpl *tAttrInfo = m_eventImpl->m_tableImpl->getColumn(colName);
-
- if (tAttrInfo == NULL) {
- ndbout_c("NdbEventOperationImpl::getValue attribute %s not found",colName);
- DBUG_RETURN(NULL);
- }
-
- DBUG_RETURN(NdbEventOperationImpl::getValue(tAttrInfo, aValue, n));
-}
-
-NdbRecAttr*
-NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, int n)
-{
- DBUG_ENTER("NdbEventOperationImpl::getValue");
- // Insert Attribute Id into ATTRINFO part.
-
- NdbRecAttr **theFirstAttr;
- NdbRecAttr **theCurrentAttr;
-
- if (tAttrInfo->getPrimaryKey())
- {
- theFirstAttr = &theFirstPkAttrs[n];
- theCurrentAttr = &theCurrentPkAttrs[n];
- }
- else
- {
- theFirstAttr = &theFirstDataAttrs[n];
- theCurrentAttr = &theCurrentDataAttrs[n];
- }
-
- /************************************************************************
- * Get a Receive Attribute object and link it into the operation object.
- ************************************************************************/
- NdbRecAttr *tAttr = m_ndb->getRecAttr();
- if (tAttr == NULL) {
- exit(-1);
- //setErrorCodeAbort(4000);
- DBUG_RETURN(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 (tAttr->setup(tAttrInfo, aValue)) {
- //setErrorCodeAbort(4000);
- m_ndb->releaseRecAttr(tAttr);
- exit(-1);
- DBUG_RETURN(NULL);
- }
- //theErrorLine++;
-
- tAttr->setUNDEFINED();
-
- // We want to keep the list sorted to make data insertion easier later
-
- if (*theFirstAttr == NULL) {
- *theFirstAttr = tAttr;
- *theCurrentAttr = tAttr;
- tAttr->next(NULL);
- } else {
- Uint32 tAttrId = tAttrInfo->m_attrId;
- if (tAttrId > (*theCurrentAttr)->attrId()) { // right order
- (*theCurrentAttr)->next(tAttr);
- tAttr->next(NULL);
- *theCurrentAttr = tAttr;
- } else if ((*theFirstAttr)->next() == NULL || // only one in list
- (*theFirstAttr)->attrId() > tAttrId) {// or first
- tAttr->next(*theFirstAttr);
- *theFirstAttr = tAttr;
- } else { // at least 2 in list and not first and not last
- NdbRecAttr *p = *theFirstAttr;
- NdbRecAttr *p_next = p->next();
- while (tAttrId > p_next->attrId()) {
- p = p_next;
- p_next = p->next();
- }
- if (tAttrId == p_next->attrId()) { // Using same attribute twice
- tAttr->release(); // do I need to do this?
- m_ndb->releaseRecAttr(tAttr);
- exit(-1);
- DBUG_RETURN(NULL);
- }
- // this is it, between p and p_next
- p->next(tAttr);
- tAttr->next(p_next);
- }
- }
- DBUG_RETURN(tAttr);
-}
-
-NdbBlob*
-NdbEventOperationImpl::getBlobHandle(const char *colName, int n)
-{
- DBUG_ENTER("NdbEventOperationImpl::getBlobHandle (colName)");
-
- assert(m_mergeEvents);
-
- if (m_state != EO_CREATED) {
- ndbout_c("NdbEventOperationImpl::getBlobHandle may only be called between "
- "instantiation and execute()");
- DBUG_RETURN(NULL);
- }
-
- NdbColumnImpl *tAttrInfo = m_eventImpl->m_tableImpl->getColumn(colName);
-
- if (tAttrInfo == NULL) {
- ndbout_c("NdbEventOperationImpl::getBlobHandle attribute %s not found",colName);
- DBUG_RETURN(NULL);
- }
-
- NdbBlob* bh = getBlobHandle(tAttrInfo, n);
- DBUG_RETURN(bh);
-}
-
-NdbBlob*
-NdbEventOperationImpl::getBlobHandle(const NdbColumnImpl *tAttrInfo, int n)
-{
- DBUG_ENTER("NdbEventOperationImpl::getBlobHandle");
- DBUG_PRINT("info", ("attr=%s post/pre=%d", tAttrInfo->m_name.c_str(), n));
-
- // as in NdbOperation, create only one instance
- NdbBlob* tBlob = theBlobList;
- NdbBlob* tLastBlob = NULL;
- while (tBlob != NULL) {
- if (tBlob->theColumn == tAttrInfo && tBlob->theEventBlobVersion == n)
- DBUG_RETURN(tBlob);
- tLastBlob = tBlob;
- tBlob = tBlob->theNext;
- }
-
- NdbEventOperationImpl* tBlobOp = NULL;
-
- const bool is_tinyblob = (tAttrInfo->getPartSize() == 0);
- assert(is_tinyblob == (tAttrInfo->m_blobTable == NULL));
-
- if (! is_tinyblob) {
- // blob event name
- char bename[MAX_TAB_NAME_SIZE];
- NdbBlob::getBlobEventName(bename, m_eventImpl, tAttrInfo);
-
- // find blob event op if any (it serves both post and pre handles)
- tBlobOp = theBlobOpList;
- NdbEventOperationImpl* tLastBlopOp = NULL;
- while (tBlobOp != NULL) {
- if (strcmp(tBlobOp->m_eventImpl->m_name.c_str(), bename) == 0) {
- break;
- }
- tLastBlopOp = tBlobOp;
- tBlobOp = tBlobOp->m_next;
- }
-
- DBUG_PRINT("info", ("%s blob event op for %s",
- tBlobOp ? " reuse" : " create", bename));
-
- // create blob event op if not found
- if (tBlobOp == NULL) {
- // get blob event
- NdbDictionaryImpl& dict =
- NdbDictionaryImpl::getImpl(*m_ndb->getDictionary());
- NdbEventImpl* blobEvnt =
- dict.getBlobEvent(*this->m_eventImpl, tAttrInfo->m_column_no);
- if (blobEvnt == NULL) {
- m_error.code = dict.m_error.code;
- DBUG_RETURN(NULL);
- }
-
- // create blob event operation
- tBlobOp =
- m_ndb->theEventBuffer->createEventOperationImpl(*blobEvnt, m_error);
- if (tBlobOp == NULL)
- DBUG_RETURN(NULL);
-
- // pointer to main table op
- tBlobOp->theMainOp = this;
- tBlobOp->m_mergeEvents = m_mergeEvents;
-
- // to hide blob op it is linked under main op, not under m_ndb
- if (tLastBlopOp == NULL)
- theBlobOpList = tBlobOp;
- else
- tLastBlopOp->m_next = tBlobOp;
- tBlobOp->m_next = NULL;
- }
- }
-
- tBlob = m_ndb->getNdbBlob();
- if (tBlob == NULL) {
- m_error.code = m_ndb->getNdbError().code;
- DBUG_RETURN(NULL);
- }
-
- // calls getValue on inline and blob part
- if (tBlob->atPrepare(this, tBlobOp, tAttrInfo, n) == -1) {
- m_error.code = tBlob->getNdbError().code;
- m_ndb->releaseNdbBlob(tBlob);
- DBUG_RETURN(NULL);
- }
-
- // add to list end
- if (tLastBlob == NULL)
- theBlobList = tBlob;
- else
- tLastBlob->theNext = tBlob;
- tBlob->theNext = NULL;
- DBUG_RETURN(tBlob);
-}
-
-int
-NdbEventOperationImpl::readBlobParts(char* buf, NdbBlob* blob,
- Uint32 part, Uint32 count)
-{
- DBUG_ENTER_EVENT("NdbEventOperationImpl::readBlobParts");
- DBUG_PRINT_EVENT("info", ("part=%u count=%u post/pre=%d",
- part, count, blob->theEventBlobVersion));
-
- NdbEventOperationImpl* blob_op = blob->theBlobEventOp;
-
- EventBufData* main_data = m_data_item;
- DBUG_PRINT_EVENT("info", ("main_data=%p", main_data));
- assert(main_data != NULL);
-
- // search for blob parts list head
- EventBufData* head;
- assert(m_data_item != NULL);
- head = m_data_item->m_next_blob;
- while (head != NULL)
- {
- if (head->m_event_op == blob_op)
- {
- DBUG_PRINT_EVENT("info", ("found blob parts head %p", head));
- break;
- }
- head = head->m_next_blob;
- }
-
- Uint32 nparts = 0;
- EventBufData* data = head;
- // XXX optimize using part no ordering
- while (data != NULL)
- {
- /*
- * Hack part no directly out of buffer since it is not returned
- * in pre data (PK buglet). For part data use receive_event().
- * This means extra copy.
- */
- blob_op->m_data_item = data;
- int r = blob_op->receive_event();
- assert(r > 0);
- Uint32 no = data->get_blob_part_no();
- Uint32 sz = blob->thePartSize;
- const char* src = blob->theBlobEventDataBuf.data;
-
- DBUG_PRINT_EVENT("info", ("part_data=%p part no=%u part sz=%u", data, no, sz));
-
- if (part <= no && no < part + count)
- {
- DBUG_PRINT_EVENT("info", ("part within read range"));
- memcpy(buf + (no - part) * sz, src, sz);
- nparts++;
- }
- else
- {
- DBUG_PRINT_EVENT("info", ("part outside read range"));
- }
- data = data->m_next;
- }
- assert(nparts == count);
-
- DBUG_RETURN_EVENT(0);
-}
-
-int
-NdbEventOperationImpl::execute()
-{
- DBUG_ENTER("NdbEventOperationImpl::execute");
- m_ndb->theEventBuffer->add_drop_lock();
- int r = execute_nolock();
- m_ndb->theEventBuffer->add_drop_unlock();
- DBUG_RETURN(r);
-}
-
-int
-NdbEventOperationImpl::execute_nolock()
-{
- DBUG_ENTER("NdbEventOperationImpl::execute_nolock");
- DBUG_PRINT("info", ("this=%p type=%s", this, !theMainOp ? "main" : "blob"));
-
- NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
- if (!myDict) {
- m_error.code= m_ndb->getNdbError().code;
- DBUG_RETURN(-1);
- }
-
- if (theFirstPkAttrs[0] == NULL &&
- theFirstDataAttrs[0] == NULL) { // defaults to get all
- }
-
- m_magic_number= NDB_EVENT_OP_MAGIC_NUMBER;
- m_state= EO_EXECUTING;
- mi_type= m_eventImpl->mi_type;
- m_ndb->theEventBuffer->add_op();
- // add kernel reference
- // removed on TE_STOP, TE_CLUSTER_FAILURE, or error below
- m_ref_count++;
- m_node_bit_mask.set(0u);
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", m_ref_count, this));
- int r= NdbDictionaryImpl::getImpl(*myDict).executeSubscribeEvent(*this);
- if (r == 0) {
- if (theMainOp == NULL) {
- DBUG_PRINT("info", ("execute blob ops"));
- NdbEventOperationImpl* blob_op = theBlobOpList;
- while (blob_op != NULL) {
- r = blob_op->execute_nolock();
- if (r != 0) {
- // since main op is running and possibly some blob ops as well
- // we can't just reset the main op. Instead return with error,
- // main op (and blob ops) will be cleaned up when user calls
- // dropEventOperation
- m_error.code= myDict->getNdbError().code;
- DBUG_RETURN(r);
- }
- // add blob reference to main op
- // removed by TE_STOP or TE_CLUSTER_FAILURE
- m_ref_count++;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", m_ref_count, this));
- blob_op = blob_op->m_next;
- }
- }
- if (r == 0)
- {
- DBUG_RETURN(0);
- }
- }
- // Error
- // remove kernel reference
- // added above
- m_ref_count--;
- m_node_bit_mask.clear(0u);
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", m_ref_count, this));
- m_state= EO_ERROR;
- mi_type= 0;
- m_magic_number= 0;
- m_error.code= myDict->getNdbError().code;
- m_ndb->theEventBuffer->remove_op();
- DBUG_RETURN(r);
-}
-
-int
-NdbEventOperationImpl::stop()
-{
- DBUG_ENTER("NdbEventOperationImpl::stop");
- int i;
-
- for (i=0 ; i<2; i++) {
- NdbRecAttr *p = theFirstPkAttrs[i];
- while (p) {
- NdbRecAttr *p_next = p->next();
- m_ndb->releaseRecAttr(p);
- p = p_next;
- }
- theFirstPkAttrs[i]= 0;
- }
- for (i=0 ; i<2; i++) {
- NdbRecAttr *p = theFirstDataAttrs[i];
- while (p) {
- NdbRecAttr *p_next = p->next();
- m_ndb->releaseRecAttr(p);
- p = p_next;
- }
- theFirstDataAttrs[i]= 0;
- }
-
- if (m_state != EO_EXECUTING)
- {
- DBUG_RETURN(-1);
- }
-
- NdbDictionary::Dictionary *myDict = m_ndb->getDictionary();
- if (!myDict) {
- m_error.code= m_ndb->getNdbError().code;
- DBUG_RETURN(-1);
- }
-
- m_ndb->theEventBuffer->add_drop_lock();
- int r= NdbDictionaryImpl::getImpl(*myDict).stopSubscribeEvent(*this);
- m_ndb->theEventBuffer->remove_op();
- m_state= EO_DROPPED;
- mi_type= 0;
- if (r == 0) {
- m_ndb->theEventBuffer->add_drop_unlock();
- DBUG_RETURN(0);
- }
- //Error
- m_error.code= NdbDictionaryImpl::getImpl(*myDict).m_error.code;
- m_state= EO_ERROR;
- m_ndb->theEventBuffer->add_drop_unlock();
- DBUG_RETURN(r);
-}
-
-bool NdbEventOperationImpl::tableNameChanged() const
-{
- return (bool)AlterTableReq::getNameFlag(m_change_mask);
-}
-
-bool NdbEventOperationImpl::tableFrmChanged() const
-{
- return (bool)AlterTableReq::getFrmFlag(m_change_mask);
-}
-
-bool NdbEventOperationImpl::tableFragmentationChanged() const
-{
- return (bool)AlterTableReq::getFragDataFlag(m_change_mask);
-}
-
-bool NdbEventOperationImpl::tableRangeListChanged() const
-{
- return (bool)AlterTableReq::getRangeListFlag(m_change_mask);
-}
-
-Uint64
-NdbEventOperationImpl::getGCI()
-{
- return m_data_item->sdata->gci;
-}
-
-Uint32
-NdbEventOperationImpl::getAnyValue() const
-{
- return m_data_item->sdata->anyValue;
-}
-
-Uint64
-NdbEventOperationImpl::getLatestGCI()
-{
- return m_ndb->theEventBuffer->getLatestGCI();
-}
-
-bool
-NdbEventOperationImpl::execSUB_TABLE_DATA(NdbApiSignal * signal,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("NdbEventOperationImpl::execSUB_TABLE_DATA");
- const SubTableData * const sdata=
- CAST_CONSTPTR(SubTableData, signal->getDataPtr());
-
- if(signal->isFirstFragment()){
- m_fragmentId = signal->getFragmentId();
- m_buffer.grow(4 * sdata->totalLen);
- } else {
- if(m_fragmentId != signal->getFragmentId()){
- abort();
- }
- }
- const Uint32 i = SubTableData::DICT_TAB_INFO;
- DBUG_PRINT("info", ("Accumulated %u bytes for fragment %u",
- 4 * ptr[i].sz, m_fragmentId));
- m_buffer.append(ptr[i].p, 4 * ptr[i].sz);
-
- if(!signal->isLastFragment()){
- DBUG_RETURN(FALSE);
- }
-
- DBUG_RETURN(TRUE);
-}
-
-
-int
-NdbEventOperationImpl::receive_event()
-{
- Uint32 operation=
- SubTableData::getOperation(m_data_item->sdata->requestInfo);
- if (unlikely(operation >= NdbDictionary::Event::_TE_FIRST_NON_DATA_EVENT))
- {
- DBUG_ENTER("NdbEventOperationImpl::receive_event");
- DBUG_PRINT("info",("sdata->operation %u this: %p", operation, this));
- if (operation == NdbDictionary::Event::_TE_ALTER)
- {
- // Parse the new table definition and
- // create a table object
- NdbError error;
- NdbDictInterface dif(error);
- NdbTableImpl *at;
- m_change_mask = m_data_item->sdata->changeMask;
- error.code = dif.parseTableInfo(&at,
- (Uint32*)m_buffer.get_data(),
- m_buffer.length() / 4,
- true);
- m_buffer.clear();
- if (unlikely(!at))
- {
- DBUG_PRINT("info", ("Failed to parse DictTabInfo error %u",
- error.code));
- ndbout_c("Failed to parse DictTabInfo error %u", error.code);
- DBUG_RETURN(1);
- }
- at->buildColumnHash();
-
- NdbTableImpl *tmp_table_impl= m_eventImpl->m_tableImpl;
- m_eventImpl->m_tableImpl = at;
-
- DBUG_PRINT("info", ("switching table impl 0x%lx -> 0x%lx",
- (long) tmp_table_impl, (long) at));
-
- // change the rec attrs to refer to the new table object
- int i;
- for (i = 0; i < 2; i++)
- {
- NdbRecAttr *p = theFirstPkAttrs[i];
- while (p)
- {
- int no = p->getColumn()->getColumnNo();
- NdbColumnImpl *tAttrInfo = at->getColumn(no);
- DBUG_PRINT("info", ("rec_attr: 0x%lx "
- "switching column impl 0x%lx -> 0x%lx",
- (long) p, (long) p->m_column, (long) tAttrInfo));
- p->m_column = tAttrInfo;
- p = p->next();
- }
- }
- for (i = 0; i < 2; i++)
- {
- NdbRecAttr *p = theFirstDataAttrs[i];
- while (p)
- {
- int no = p->getColumn()->getColumnNo();
- NdbColumnImpl *tAttrInfo = at->getColumn(no);
- DBUG_PRINT("info", ("rec_attr: 0x%lx "
- "switching column impl 0x%lx -> 0x%lx",
- (long) p, (long) p->m_column, (long) tAttrInfo));
- p->m_column = tAttrInfo;
- p = p->next();
- }
- }
- // change the blobHandle's to refer to the new table object.
- NdbBlob *p = theBlobList;
- while (p)
- {
- int no = p->getColumn()->getColumnNo();
- NdbColumnImpl *tAttrInfo = at->getColumn(no);
- DBUG_PRINT("info", ("blob_handle: 0x%lx "
- "switching column impl 0x%lx -> 0x%lx",
- (long) p, (long) p->theColumn, (long) tAttrInfo));
- p->theColumn = tAttrInfo;
- p = p->next();
- }
- if (tmp_table_impl)
- delete tmp_table_impl;
- }
- DBUG_RETURN(1);
- }
-
- DBUG_ENTER_EVENT("NdbEventOperationImpl::receive_event");
- DBUG_PRINT_EVENT("info",("sdata->operation %u this: %p", operation, this));
- // now move the data into the RecAttrs
-
- int is_update= operation == NdbDictionary::Event::_TE_UPDATE;
-
- Uint32 *aAttrPtr = m_data_item->ptr[0].p;
- Uint32 *aAttrEndPtr = aAttrPtr + m_data_item->ptr[0].sz;
- Uint32 *aDataPtr = m_data_item->ptr[1].p;
-
- DBUG_DUMP_EVENT("after",(char*)m_data_item->ptr[1].p, m_data_item->ptr[1].sz*4);
- DBUG_DUMP_EVENT("before",(char*)m_data_item->ptr[2].p, m_data_item->ptr[2].sz*4);
-
- // copy data into the RecAttr's
- // we assume that the respective attribute lists are sorted
-
- // first the pk's
- {
- NdbRecAttr *tAttr= theFirstPkAttrs[0];
- NdbRecAttr *tAttr1= theFirstPkAttrs[1];
- while(tAttr)
- {
- assert(aAttrPtr < aAttrEndPtr);
- unsigned tDataSz= AttributeHeader(*aAttrPtr).getByteSize();
- assert(tAttr->attrId() ==
- AttributeHeader(*aAttrPtr).getAttributeId());
- receive_data(tAttr, aDataPtr, tDataSz);
- if (is_update)
- receive_data(tAttr1, aDataPtr, tDataSz);
- else
- tAttr1->setUNDEFINED(); // do not leave unspecified
- tAttr1= tAttr1->next();
- // next
- aAttrPtr++;
- aDataPtr+= (tDataSz + 3) >> 2;
- tAttr= tAttr->next();
- }
- }
-
- NdbRecAttr *tWorkingRecAttr = theFirstDataAttrs[0];
-
- Uint32 tRecAttrId;
- Uint32 tAttrId;
- Uint32 tDataSz;
- int hasSomeData=0;
- while ((aAttrPtr < aAttrEndPtr) && (tWorkingRecAttr != NULL)) {
- tRecAttrId = tWorkingRecAttr->attrId();
- tAttrId = AttributeHeader(*aAttrPtr).getAttributeId();
- tDataSz = AttributeHeader(*aAttrPtr).getByteSize();
-
- while (tAttrId > tRecAttrId) {
- DBUG_PRINT_EVENT("info",("undef [%u] %u 0x%x [%u] 0x%x",
- tAttrId, tDataSz, *aDataPtr, tRecAttrId, aDataPtr));
- tWorkingRecAttr->setUNDEFINED();
- tWorkingRecAttr = tWorkingRecAttr->next();
- if (tWorkingRecAttr == NULL)
- break;
- tRecAttrId = tWorkingRecAttr->attrId();
- }
- if (tWorkingRecAttr == NULL)
- break;
-
- if (tAttrId == tRecAttrId) {
- hasSomeData++;
-
- DBUG_PRINT_EVENT("info",("set [%u] %u 0x%x [%u] 0x%x",
- tAttrId, tDataSz, *aDataPtr, tRecAttrId, aDataPtr));
-
- receive_data(tWorkingRecAttr, aDataPtr, tDataSz);
- tWorkingRecAttr = tWorkingRecAttr->next();
- }
- aAttrPtr++;
- aDataPtr += (tDataSz + 3) >> 2;
- }
-
- while (tWorkingRecAttr != NULL) {
- tRecAttrId = tWorkingRecAttr->attrId();
- //printf("set undefined [%u] %u %u [%u]\n",
- // tAttrId, tDataSz, *aDataPtr, tRecAttrId);
- tWorkingRecAttr->setUNDEFINED();
- tWorkingRecAttr = tWorkingRecAttr->next();
- }
-
- tWorkingRecAttr = theFirstDataAttrs[1];
- aDataPtr = m_data_item->ptr[2].p;
- Uint32 *aDataEndPtr = aDataPtr + m_data_item->ptr[2].sz;
- while ((aDataPtr < aDataEndPtr) && (tWorkingRecAttr != NULL)) {
- tRecAttrId = tWorkingRecAttr->attrId();
- tAttrId = AttributeHeader(*aDataPtr).getAttributeId();
- tDataSz = AttributeHeader(*aDataPtr).getByteSize();
- aDataPtr++;
- while (tAttrId > tRecAttrId) {
- tWorkingRecAttr->setUNDEFINED();
- tWorkingRecAttr = tWorkingRecAttr->next();
- if (tWorkingRecAttr == NULL)
- break;
- tRecAttrId = tWorkingRecAttr->attrId();
- }
- if (tWorkingRecAttr == NULL)
- break;
- if (tAttrId == tRecAttrId) {
- assert(!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey());
- hasSomeData++;
-
- receive_data(tWorkingRecAttr, aDataPtr, tDataSz);
- tWorkingRecAttr = tWorkingRecAttr->next();
- }
- aDataPtr += (tDataSz + 3) >> 2;
- }
- while (tWorkingRecAttr != NULL) {
- tWorkingRecAttr->setUNDEFINED();
- tWorkingRecAttr = tWorkingRecAttr->next();
- }
-
- if (hasSomeData || !is_update)
- {
- DBUG_RETURN_EVENT(1);
- }
-
- DBUG_RETURN_EVENT(0);
-}
-
-NdbDictionary::Event::TableEvent
-NdbEventOperationImpl::getEventType()
-{
- return (NdbDictionary::Event::TableEvent)
- (1 << SubTableData::getOperation(m_data_item->sdata->requestInfo));
-}
-
-
-
-void
-NdbEventOperationImpl::print()
-{
- int i;
- ndbout << "EventId " << m_eventId << "\n";
-
- for (i = 0; i < 2; i++) {
- NdbRecAttr *p = theFirstPkAttrs[i];
- ndbout << " %u " << i;
- while (p) {
- ndbout << " : " << p->attrId() << " = " << *p;
- p = p->next();
- }
- ndbout << "\n";
- }
- for (i = 0; i < 2; i++) {
- NdbRecAttr *p = theFirstDataAttrs[i];
- ndbout << " %u " << i;
- while (p) {
- ndbout << " : " << p->attrId() << " = " << *p;
- p = p->next();
- }
- ndbout << "\n";
- }
-}
-
-void
-NdbEventOperationImpl::printAll()
-{
- Uint32 *aAttrPtr = m_data_item->ptr[0].p;
- Uint32 *aAttrEndPtr = aAttrPtr + m_data_item->ptr[0].sz;
- Uint32 *aDataPtr = m_data_item->ptr[1].p;
-
- //tRecAttr->setup(tAttrInfo, aValue)) {
-
- Uint32 tAttrId;
- Uint32 tDataSz;
- for (; aAttrPtr < aAttrEndPtr; ) {
- tAttrId = AttributeHeader(*aAttrPtr).getAttributeId();
- tDataSz = AttributeHeader(*aAttrPtr).getDataSize();
-
- aAttrPtr++;
- aDataPtr += tDataSz;
- }
-}
-
-/*
- * Class NdbEventBuffer
- * Each Ndb object has a Object.
- */
-
-
-NdbEventBuffer::NdbEventBuffer(Ndb *ndb) :
- m_system_nodes(ndb->theImpl->theNoOfDBnodes),
- m_ndb(ndb),
- m_latestGCI(0), m_latest_complete_GCI(0),
- m_total_alloc(0),
- m_free_thresh(10),
- m_min_free_thresh(10),
- m_max_free_thresh(100),
- m_gci_slip_thresh(3),
- m_dropped_ev_op(0),
- m_active_op_count(0),
- m_add_drop_mutex(0)
-{
-#ifdef VM_TRACE
- m_latest_command= "NdbEventBuffer::NdbEventBuffer";
- m_flush_gci = 0;
-#endif
-
- if ((p_cond = NdbCondition_Create()) == NULL) {
- ndbout_c("NdbEventHandle: NdbCondition_Create() failed");
- exit(-1);
- }
- m_mutex= ndb->theImpl->theWaiter.m_mutex;
- // ToDo set event buffer size
- // pre allocate event data array
- m_sz= 0;
-#ifdef VM_TRACE
- m_free_data_count= 0;
-#endif
- m_free_data= 0;
- m_free_data_sz= 0;
-
- // get reference to mutex managed by current connection
- m_add_drop_mutex=
- m_ndb->theImpl->m_ndb_cluster_connection.m_event_add_drop_mutex;
-
- // initialize lists
- bzero(&g_empty_gci_container, sizeof(Gci_container));
- init_gci_containers();
-}
-
-NdbEventBuffer::~NdbEventBuffer()
-{
- // todo lock? what if receive thread writes here?
- NdbEventOperationImpl* op= m_dropped_ev_op;
- while ((op = m_dropped_ev_op))
- {
- m_dropped_ev_op = m_dropped_ev_op->m_next;
- delete op->m_facade;
- }
-
- unsigned j;
- Uint32 sz= m_active_gci.size();
- Gci_container* array = (Gci_container*)m_active_gci.getBase();
- for(j = 0; j < sz; j++)
- {
- array[j].~Gci_container();
- }
-
- for (j= 0; j < m_allocated_data.size(); j++)
- {
- unsigned sz= m_allocated_data[j]->sz;
- EventBufData *data= m_allocated_data[j]->data;
- EventBufData *end_data= data+sz;
- for (; data < end_data; data++)
- {
- if (data->sdata)
- NdbMem_Free(data->sdata);
- }
- NdbMem_Free((char*)m_allocated_data[j]);
- }
-
- NdbCondition_Destroy(p_cond);
-}
-
-void
-NdbEventBuffer::add_op()
-{
- if(m_active_op_count == 0)
- {
- init_gci_containers();
- }
- m_active_op_count++;
-}
-
-void
-NdbEventBuffer::remove_op()
-{
- m_active_op_count--;
-}
-
-void
-NdbEventBuffer::init_gci_containers()
-{
- bzero(&m_complete_data, sizeof(m_complete_data));
- m_latest_complete_GCI = m_latestGCI = 0;
- m_active_gci.clear();
- m_active_gci.fill(2 * ACTIVE_GCI_DIRECTORY_SIZE - 1, g_empty_gci_container);
-}
-
-int NdbEventBuffer::expand(unsigned sz)
-{
- unsigned alloc_size=
- sizeof(EventBufData_chunk) +(sz-1)*sizeof(EventBufData);
- EventBufData_chunk *chunk_data=
- (EventBufData_chunk *)NdbMem_Allocate(alloc_size);
-
- chunk_data->sz= sz;
- m_allocated_data.push_back(chunk_data);
-
- EventBufData *data= chunk_data->data;
- EventBufData *end_data= data+sz;
- EventBufData *last_data= m_free_data;
-
- bzero((void*)data, sz*sizeof(EventBufData));
- for (; data < end_data; data++)
- {
- data->m_next= last_data;
- last_data= data;
- }
- m_free_data= last_data;
-
- m_sz+= sz;
-#ifdef VM_TRACE
- m_free_data_count+= sz;
-#endif
- return 0;
-}
-
-int
-NdbEventBuffer::pollEvents(int aMillisecondNumber, Uint64 *latestGCI)
-{
- int ret= 1;
-#ifdef VM_TRACE
- const char *m_latest_command_save= m_latest_command;
- m_latest_command= "NdbEventBuffer::pollEvents";
-#endif
-
- NdbMutex_Lock(m_mutex);
- NdbEventOperationImpl *ev_op= move_data();
- if (unlikely(ev_op == 0 && aMillisecondNumber))
- {
- NdbCondition_WaitTimeout(p_cond, m_mutex, aMillisecondNumber);
- ev_op= move_data();
- if (unlikely(ev_op == 0))
- ret= 0;
- }
- if (latestGCI)
- *latestGCI= m_latestGCI;
-#ifdef VM_TRACE
- if (ev_op)
- {
- // m_mutex is locked
- // update event ops data counters
- ev_op->m_data_count-= ev_op->m_data_done_count;
- ev_op->m_data_done_count= 0;
- }
- m_latest_command= m_latest_command_save;
-#endif
- NdbMutex_Unlock(m_mutex); // we have moved the data
- return ret;
-}
-
-int
-NdbEventBuffer::flushIncompleteEvents(Uint64 gci)
-{
- /**
- * Find min complete gci
- */
- // called by user thread, so we need to lock the data
- lock();
- Uint32 i;
- Uint32 sz= m_active_gci.size();
- Gci_container* array = (Gci_container*)m_active_gci.getBase();
- for(i = 0; i < sz; i++)
- {
- Gci_container* tmp = array + i;
- if (tmp->m_gci && tmp->m_gci < gci)
- {
- // we have found an old not-completed gci, remove it
- ndbout_c("ndb: flushing incomplete epoch %lld (<%lld)", tmp->m_gci, gci);
- if(!tmp->m_data.is_empty())
- {
- free_list(tmp->m_data);
- }
- tmp->~Gci_container();
- bzero(tmp, sizeof(Gci_container));
- }
- }
-#ifdef VM_TRACE
- m_flush_gci = gci;
-#endif
- unlock();
- return 0;
-}
-
-NdbEventOperation *
-NdbEventBuffer::nextEvent()
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::nextEvent");
-#ifdef VM_TRACE
- const char *m_latest_command_save= m_latest_command;
-#endif
-
- if (m_used_data.m_count > 1024)
- {
-#ifdef VM_TRACE
- m_latest_command= "NdbEventBuffer::nextEvent (lock)";
-#endif
- NdbMutex_Lock(m_mutex);
- // return m_used_data to m_free_data
- free_list(m_used_data);
-
- NdbMutex_Unlock(m_mutex);
- }
-#ifdef VM_TRACE
- m_latest_command= "NdbEventBuffer::nextEvent";
-#endif
-
- EventBufData *data;
- while ((data= m_available_data.m_head))
- {
- NdbEventOperationImpl *op= data->m_event_op;
- DBUG_PRINT_EVENT("info", ("available data=%p op=%p", data, op));
-
- /*
- * If merge is on, blob part sub-events must not be seen on this level.
- * If merge is not on, there are no blob part sub-events.
- */
- assert(op->theMainOp == NULL);
-
- // set NdbEventOperation data
- op->m_data_item= data;
-
- // remove item from m_available_data and return size
- Uint32 full_count, full_sz;
- m_available_data.remove_first(full_count, full_sz);
-
- // add it to used list
- m_used_data.append_used_data(data, full_count, full_sz);
-
-#ifdef VM_TRACE
- op->m_data_done_count++;
-#endif
-
- int r= op->receive_event();
- if (r > 0)
- {
- if (op->m_state == NdbEventOperation::EO_EXECUTING)
- {
-#ifdef VM_TRACE
- m_latest_command= m_latest_command_save;
-#endif
- NdbBlob* tBlob = op->theBlobList;
- while (tBlob != NULL)
- {
- (void)tBlob->atNextEvent();
- tBlob = tBlob->theNext;
- }
- EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
- while (gci_ops && op->getGCI() > gci_ops->m_gci)
- {
- // moved to next gci, check if any references have been
- // released when completing the last gci
- deleteUsedEventOperations();
- gci_ops = m_available_data.next_gci_ops();
- }
- assert(gci_ops && (op->getGCI() == gci_ops->m_gci));
- // to return TE_NUL it should be made into data event
- if (SubTableData::getOperation(data->sdata->requestInfo) ==
- NdbDictionary::Event::_TE_NUL)
- {
- DBUG_PRINT_EVENT("info", ("skip _TE_NUL"));
- continue;
- }
- DBUG_RETURN_EVENT(op->m_facade);
- }
- // the next event belonged to an event op that is no
- // longer valid, skip to next
- continue;
- }
-#ifdef VM_TRACE
- m_latest_command= m_latest_command_save;
-#endif
- }
- m_error.code= 0;
-#ifdef VM_TRACE
- m_latest_command= m_latest_command_save;
-#endif
-
- // free all "per gci unique" collected operations
- // completed gci, check if any references have been
- // released when completing the gci
- EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
- while (gci_ops)
- {
- deleteUsedEventOperations();
- gci_ops = m_available_data.next_gci_ops();
- }
- DBUG_RETURN_EVENT(0);
-}
-
-NdbEventOperationImpl*
-NdbEventBuffer::getGCIEventOperations(Uint32* iter, Uint32* event_types)
-{
- DBUG_ENTER("NdbEventBuffer::getGCIEventOperations");
- EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
- if (*iter < gci_ops->m_gci_op_count)
- {
- EventBufData_list::Gci_op g = gci_ops->m_gci_op_list[(*iter)++];
- if (event_types != NULL)
- *event_types = g.event_types;
- DBUG_PRINT("info", ("gci: %u g.op: 0x%lx g.event_types: 0x%lx",
- (unsigned)gci_ops->m_gci, (long) g.op,
- (long) g.event_types));
- DBUG_RETURN(g.op);
- }
- DBUG_RETURN(NULL);
-}
-
-void
-NdbEventBuffer::deleteUsedEventOperations()
-{
- Uint32 iter= 0;
- const NdbEventOperation *op_f;
- while ((op_f= getGCIEventOperations(&iter, NULL)) != NULL)
- {
- NdbEventOperationImpl *op = &op_f->m_impl;
- DBUG_ASSERT(op->m_ref_count > 0);
- // remove gci reference
- // added in inserDataL
- op->m_ref_count--;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", op->m_ref_count, op));
- if (op->m_ref_count == 0)
- {
- DBUG_PRINT("info", ("deleting op: %p", op));
- DBUG_ASSERT(op->m_node_bit_mask.isclear());
- if (op->m_next)
- op->m_next->m_prev = op->m_prev;
- if (op->m_prev)
- op->m_prev->m_next = op->m_next;
- else
- m_dropped_ev_op = op->m_next;
- delete op->m_facade;
- }
- }
-}
-
-static
-NdbOut&
-operator<<(NdbOut& out, const Gci_container& gci)
-{
- out << "[ GCI: " << gci.m_gci
- << " state: " << hex << gci.m_state
- << " head: " << hex << gci.m_data.m_head
- << " tail: " << hex << gci.m_data.m_tail
-#ifdef VM_TRACE
- << " cnt: " << dec << gci.m_data.m_count
-#endif
- << " gcp: " << dec << gci.m_gcp_complete_rep_count
- << "]";
- return out;
-}
-
-#ifdef VM_TRACE
-static
-NdbOut&
-operator<<(NdbOut& out, const Gci_container_pod& gci)
-{
- Gci_container* ptr = (Gci_container*)&gci;
- out << *ptr;
- return out;
-}
-#endif
-
-static
-Gci_container*
-find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci
-#ifdef VM_TRACE
- ,Uint64 flush_gci
-#endif
- )
-{
- Uint32 pos = (gci & ACTIVE_GCI_MASK);
- Gci_container *bucket= ((Gci_container*)active->getBase()) + pos;
-
- if(gci > bucket->m_gci)
- {
- Gci_container* move;
- Uint32 move_pos = pos + ACTIVE_GCI_DIRECTORY_SIZE;
- do
- {
- active->fill(move_pos, g_empty_gci_container);
- // Needs to recomputed after fill
- bucket = ((Gci_container*)active->getBase()) + pos;
- move = ((Gci_container*)active->getBase()) + move_pos;
- if(move->m_gcp_complete_rep_count == 0)
- {
- memcpy(move, bucket, sizeof(Gci_container));
- bzero(bucket, sizeof(Gci_container));
- bucket->m_gci = gci;
- bucket->m_gcp_complete_rep_count = ~(Uint32)0;
-#ifdef VM_TRACE
- if (gci < flush_gci)
- {
- ndbout_c("received old gci %llu < flush gci %llu", gci, flush_gci);
- assert(false);
- }
-#endif
- return bucket;
- }
- move_pos += ACTIVE_GCI_DIRECTORY_SIZE;
- } while(true);
- }
- else /** gci < bucket->m_gci */
- {
- Uint32 size = active->size() - ACTIVE_GCI_DIRECTORY_SIZE;
- do
- {
- pos += ACTIVE_GCI_DIRECTORY_SIZE;
- bucket += ACTIVE_GCI_DIRECTORY_SIZE;
-
- if(bucket->m_gci == gci)
- {
-#ifdef VM_TRACE
- if (gci < flush_gci)
- {
- ndbout_c("received old gci %llu < flush gci %llu", gci, flush_gci);
- assert(false);
- }
-#endif
- return bucket;
- }
-
- } while(pos < size);
-
- return 0;
- }
-}
-
-inline
-Gci_container*
-find_bucket(Vector<Gci_container_pod> * active, Uint64 gci
-#ifdef VM_TRACE
- ,Uint64 flush_gci
-#endif
- )
-{
- Uint32 pos = (gci & ACTIVE_GCI_MASK);
- Gci_container *bucket= ((Gci_container*)active->getBase()) + pos;
- if(likely(gci == bucket->m_gci))
- return bucket;
-
- return find_bucket_chained(active,gci
-#ifdef VM_TRACE
- , flush_gci
-#endif
- );
-}
-
-static
-void
-crash_on_invalid_SUB_GCP_COMPLETE_REP(const Gci_container* bucket,
- const SubGcpCompleteRep * const rep,
- Uint32 nodes)
-{
- Uint32 old_cnt = bucket->m_gcp_complete_rep_count;
-
- ndbout_c("INVALID SUB_GCP_COMPLETE_REP");
- ndbout_c("gci: %d", rep->gci);
- ndbout_c("sender: %x", rep->senderRef);
- ndbout_c("count: %d", rep->gcp_complete_rep_count);
- ndbout_c("bucket count: %u", old_cnt);
- ndbout_c("nodes: %u", nodes);
- abort();
-}
-
-void
-NdbEventBuffer::execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep)
-{
- if (unlikely(m_active_op_count == 0))
- {
- return;
- }
-
- DBUG_ENTER_EVENT("NdbEventBuffer::execSUB_GCP_COMPLETE_REP");
-
- const Uint64 gci= rep->gci;
- const Uint32 cnt= rep->gcp_complete_rep_count;
-
- Gci_container *bucket = find_bucket(&m_active_gci, gci
-#ifdef VM_TRACE
- , m_flush_gci
-#endif
- );
- Uint32 idx = bucket - (Gci_container*)m_active_gci.getBase();
- if (unlikely(bucket == 0))
- {
- /**
- * Already completed GCI...
- * Possible in case of resend during NF handling
- */
-#ifdef VM_TRACE
- ndbout << "bucket == 0, gci:" << gci
- << " complete: " << m_complete_data << endl;
- for(Uint32 i = 0; i<m_active_gci.size(); i++)
- {
- ndbout << i << " - " << m_active_gci[i] << endl;
- }
-#endif
- DBUG_VOID_RETURN_EVENT;
- }
-
- Uint32 old_cnt = bucket->m_gcp_complete_rep_count;
- if(unlikely(old_cnt == ~(Uint32)0))
- {
- old_cnt = m_system_nodes;
- }
-
- //assert(old_cnt >= cnt);
- if (unlikely(! (old_cnt >= cnt)))
- {
- crash_on_invalid_SUB_GCP_COMPLETE_REP(bucket, rep, m_system_nodes);
- }
- bucket->m_gcp_complete_rep_count = old_cnt - cnt;
-
- if(old_cnt == cnt)
- {
- if(likely(gci == m_latestGCI + 1 || m_latestGCI == 0))
- {
- m_latestGCI = m_complete_data.m_gci = gci; // before reportStatus
- if(!bucket->m_data.is_empty())
- {
-#ifdef VM_TRACE
- assert(bucket->m_data.m_count);
-#endif
- m_complete_data.m_data.append_list(&bucket->m_data, gci);
- }
- reportStatus();
- bzero(bucket, sizeof(Gci_container));
- if (likely(idx < ACTIVE_GCI_DIRECTORY_SIZE))
- {
- /**
- * Only "prepare" next GCI if we're in
- * the first 4 highest GCI's...else
- * this is somekind of "late" GCI...
- * which is only initialized to 0
- *
- * This to make sure we dont get several buckets with same GCI
- */
- bucket->m_gci = gci + ACTIVE_GCI_DIRECTORY_SIZE;
- bucket->m_gcp_complete_rep_count = m_system_nodes;
- }
-
- if(unlikely(m_latest_complete_GCI > gci))
- {
- complete_outof_order_gcis();
- }
-
- // signal that somethings happened
-
- NdbCondition_Signal(p_cond);
- }
- else
- {
- /** out of order something */
- ndbout_c("out of order bucket: %d gci: %ld m_latestGCI: %ld",
- (int) (bucket-(Gci_container*)m_active_gci.getBase()),
- (long) gci, (long) m_latestGCI);
- bucket->m_state = Gci_container::GC_COMPLETE;
- bucket->m_gcp_complete_rep_count = 1; // Prevent from being reused
- m_latest_complete_GCI = gci;
- }
- }
-
- DBUG_VOID_RETURN_EVENT;
-}
-
-void
-NdbEventBuffer::complete_outof_order_gcis()
-{
- Uint64 start_gci = m_latestGCI + 1;
- Uint64 stop_gci = m_latest_complete_GCI;
-
- const Uint32 size = m_active_gci.size();
- Gci_container* array= (Gci_container*)m_active_gci.getBase();
-
- ndbout_c("complete_outof_order_gcis");
- for(Uint32 i = 0; i<size; i++)
- {
- ndbout << i << " - " << array[i] << endl;
- }
-
- for(; start_gci <= stop_gci; start_gci++)
- {
- /**
- * Find gci
- */
- Uint32 i;
- Gci_container* bucket= 0;
- for(i = 0; i<size; i++)
- {
- Gci_container* tmp = array + i;
- if(tmp->m_gci == start_gci && tmp->m_state == Gci_container::GC_COMPLETE)
- {
- bucket= tmp;
- break;
- }
- }
- if(bucket == 0)
- {
- break;
- }
-
- printf("complete_outof_order_gcis - completing %lld", start_gci);
- if(!bucket->m_data.is_empty())
- {
-#ifdef VM_TRACE
- assert(bucket->m_data.m_count);
-#endif
- m_complete_data.m_data.append_list(&bucket->m_data, start_gci);
-#ifdef VM_TRACE
- ndbout_c(" moved %ld rows -> %ld", (long) bucket->m_data.m_count,
- (long) m_complete_data.m_data.m_count);
-#else
- ndbout_c(" ");
-#endif
- }
- bzero(bucket, sizeof(Gci_container));
- if(i < ACTIVE_GCI_DIRECTORY_SIZE)
- {
- bucket->m_gci = start_gci + ACTIVE_GCI_DIRECTORY_SIZE;
- bucket->m_gcp_complete_rep_count = m_system_nodes;
- }
-
- m_latestGCI = m_complete_data.m_gci = start_gci;
- }
-
- ndbout_c("complete_outof_order_gcis: m_latestGCI: %lld", m_latestGCI);
-}
-
-void
-NdbEventBuffer::insert_event(NdbEventOperationImpl* impl,
- SubTableData &data,
- LinearSectionPtr *ptr,
- Uint32 &oid_ref)
-{
- NdbEventOperationImpl *dropped_ev_op = m_dropped_ev_op;
- DBUG_PRINT("info", ("gci: %u", data.gci));
- do
- {
- do
- {
- if (impl->m_node_bit_mask.get(0u))
- {
- oid_ref = impl->m_oid;
- insertDataL(impl, &data, ptr);
- }
- NdbEventOperationImpl* blob_op = impl->theBlobOpList;
- while (blob_op != NULL)
- {
- if (blob_op->m_node_bit_mask.get(0u))
- {
- oid_ref = blob_op->m_oid;
- insertDataL(blob_op, &data, ptr);
- }
- blob_op = blob_op->m_next;
- }
- } while((impl = impl->m_next));
- impl = dropped_ev_op;
- dropped_ev_op = NULL;
- } while (impl);
-}
-
-
-void
-NdbEventBuffer::report_node_connected(Uint32 node_id)
-{
- NdbEventOperation* op= m_ndb->getEventOperation(0);
- if (op == 0)
- return;
-
- DBUG_ENTER("NdbEventBuffer::report_node_connected");
- SubTableData data;
- LinearSectionPtr ptr[3];
- bzero(&data, sizeof(data));
- bzero(ptr, sizeof(ptr));
-
- data.tableId = ~0;
- data.requestInfo = 0;
- SubTableData::setOperation(data.requestInfo,
- NdbDictionary::Event::_TE_ACTIVE);
- SubTableData::setReqNodeId(data.requestInfo, node_id);
- SubTableData::setNdbdNodeId(data.requestInfo, node_id);
- data.logType = SubTableData::LOG;
- data.gci = m_latestGCI + 1;
- /**
- * Insert this event for each operation
- */
- // no need to lock()/unlock(), receive thread calls this
- insert_event(&op->m_impl, data, ptr, data.senderData);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbEventBuffer::report_node_failure(Uint32 node_id)
-{
- NdbEventOperation* op= m_ndb->getEventOperation(0);
- if (op == 0)
- return;
-
- DBUG_ENTER("NdbEventBuffer::report_node_failure");
- SubTableData data;
- LinearSectionPtr ptr[3];
- bzero(&data, sizeof(data));
- bzero(ptr, sizeof(ptr));
-
- data.tableId = ~0;
- data.requestInfo = 0;
- SubTableData::setOperation(data.requestInfo,
- NdbDictionary::Event::_TE_NODE_FAILURE);
- SubTableData::setReqNodeId(data.requestInfo, node_id);
- SubTableData::setNdbdNodeId(data.requestInfo, node_id);
- data.logType = SubTableData::LOG;
- data.gci = m_latestGCI + 1;
- /**
- * Insert this event for each operation
- */
- // no need to lock()/unlock(), receive thread calls this
- insert_event(&op->m_impl, data, ptr, data.senderData);
- DBUG_VOID_RETURN;
-}
-
-void
-NdbEventBuffer::completeClusterFailed()
-{
- NdbEventOperation* op= m_ndb->getEventOperation(0);
- if (op == 0)
- return;
-
- DBUG_ENTER("NdbEventBuffer::completeClusterFailed");
- SubTableData data;
- LinearSectionPtr ptr[3];
- bzero(&data, sizeof(data));
- bzero(ptr, sizeof(ptr));
-
- data.tableId = ~0;
- data.requestInfo = 0;
- SubTableData::setOperation(data.requestInfo,
- NdbDictionary::Event::_TE_CLUSTER_FAILURE);
- data.logType = SubTableData::LOG;
- data.gci = m_latestGCI + 1;
-
-#ifdef VM_TRACE
- m_flush_gci = 0;
-#endif
-
- /**
- * Insert this event for each operation
- */
- // no need to lock()/unlock(), receive thread calls this
- insert_event(&op->m_impl, data, ptr, data.senderData);
-
- /**
- * Release all GCI's with m_gci > gci
- */
- Uint32 i;
- Uint32 sz= m_active_gci.size();
- Uint64 gci= data.gci;
- Gci_container* bucket = 0;
- Gci_container* array = (Gci_container*)m_active_gci.getBase();
- for(i = 0; i < sz; i++)
- {
- Gci_container* tmp = array + i;
- if (tmp->m_gci > gci)
- {
- if(!tmp->m_data.is_empty())
- {
- free_list(tmp->m_data);
- }
- tmp->~Gci_container();
- bzero(tmp, sizeof(Gci_container));
- }
- else if (tmp->m_gcp_complete_rep_count)
- {
- if (tmp->m_gci == gci)
- {
- bucket= tmp;
- continue;
- }
- // we have found an old not-completed gci
- // something is wrong, assert in debug, but try so salvage
- // in release
- ndbout_c("out of order bucket detected at cluster disconnect, "
- "data.gci: %u. tmp->m_gci: %u",
- (unsigned)data.gci, (unsigned)tmp->m_gci);
- assert(false);
- if(!tmp->m_data.is_empty())
- {
- free_list(tmp->m_data);
- }
- tmp->~Gci_container();
- bzero(tmp, sizeof(Gci_container));
- }
- }
-
- if (bucket == 0)
- {
- // no bucket to complete
- DBUG_VOID_RETURN;
- }
-
- const Uint32 cnt= bucket->m_gcp_complete_rep_count = 1;
- bucket->m_gci = gci;
- bucket->m_gcp_complete_rep_count = cnt;
-
- /**
- * And finally complete this GCI
- */
- SubGcpCompleteRep rep;
- rep.gci= gci;
- rep.gcp_complete_rep_count= cnt;
- execSUB_GCP_COMPLETE_REP(&rep);
-
- DBUG_VOID_RETURN;
-}
-
-Uint64
-NdbEventBuffer::getLatestGCI()
-{
- return m_latestGCI;
-}
-
-int
-NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
- const SubTableData * const sdata,
- LinearSectionPtr ptr[3])
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::insertDataL");
- const Uint32 ri = sdata->requestInfo;
- const Uint32 operation = SubTableData::getOperation(ri);
- Uint64 gci= sdata->gci;
- const bool is_data_event =
- operation < NdbDictionary::Event::_TE_FIRST_NON_DATA_EVENT;
-
- if (!is_data_event)
- {
- switch (operation)
- {
- case NdbDictionary::Event::_TE_NODE_FAILURE:
- DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
- op->m_node_bit_mask.clear(SubTableData::getNdbdNodeId(ri));
- DBUG_PRINT("info",
- ("_TE_NODE_FAILURE: m_ref_count: %u for op: %p id: %u",
- op->m_ref_count, op, SubTableData::getNdbdNodeId(ri)));
- break;
- case NdbDictionary::Event::_TE_ACTIVE:
- DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
- op->m_node_bit_mask.set(SubTableData::getNdbdNodeId(ri));
- // internal event, do not relay to user
- DBUG_PRINT("info",
- ("_TE_ACTIVE: m_ref_count: %u for op: %p id: %u",
- op->m_ref_count, op, SubTableData::getNdbdNodeId(ri)));
- DBUG_RETURN_EVENT(0);
- break;
- case NdbDictionary::Event::_TE_CLUSTER_FAILURE:
- DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
- op->m_node_bit_mask.clear();
- DBUG_ASSERT(op->m_ref_count > 0);
- // remove kernel reference
- // added in execute_nolock
- op->m_ref_count--;
- DBUG_PRINT("info", ("_TE_CLUSTER_FAILURE: m_ref_count: %u for op: %p",
- op->m_ref_count, op));
- if (op->theMainOp)
- {
- DBUG_ASSERT(op->m_ref_count == 0);
- DBUG_ASSERT(op->theMainOp->m_ref_count > 0);
- // remove blob reference in main op
- // added in execute_no_lock
- op->theMainOp->m_ref_count--;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p",
- op->theMainOp->m_ref_count, op->theMainOp));
- }
- break;
- case NdbDictionary::Event::_TE_STOP:
- DBUG_ASSERT(op->m_node_bit_mask.get(0u) != 0);
- op->m_node_bit_mask.clear(0u);
- op->m_node_bit_mask.clear(SubTableData::getNdbdNodeId(ri));
- if (op->m_node_bit_mask.isclear())
- {
- DBUG_ASSERT(op->m_ref_count > 0);
- // remove kernel reference
- // added in execute_no_lock
- op->m_ref_count--;
- DBUG_PRINT("info", ("_TE_STOP: m_ref_count: %u for op: %p",
- op->m_ref_count, op));
- if (op->theMainOp)
- {
- DBUG_ASSERT(op->m_ref_count == 0);
- DBUG_ASSERT(op->theMainOp->m_ref_count > 0);
- // remove blob reference in main op
- // added in execute_no_lock
- op->theMainOp->m_ref_count--;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p",
- op->theMainOp->m_ref_count, op->theMainOp));
- }
- }
- else
- {
- op->m_node_bit_mask.set(0u);
- }
- break;
- default:
- break;
- }
- }
-
- if ( likely((Uint32)op->mi_type & (1 << operation)))
- {
- Gci_container* bucket= find_bucket(&m_active_gci, gci
-#ifdef VM_TRACE
- , m_flush_gci
-#endif
- );
-
- DBUG_PRINT_EVENT("info", ("data insertion in eventId %d", op->m_eventId));
- DBUG_PRINT_EVENT("info", ("gci=%d tab=%d op=%d node=%d",
- sdata->gci, sdata->tableId,
- SubTableData::getOperation(sdata->requestInfo),
- SubTableData::getReqNodeId(sdata->requestInfo)));
-
- if (unlikely(bucket == 0))
- {
- /**
- * Already completed GCI...
- * Possible in case of resend during NF handling
- */
- DBUG_RETURN_EVENT(0);
- }
-
- const bool is_blob_event = (op->theMainOp != NULL);
- const bool use_hash = op->m_mergeEvents && is_data_event;
-
- if (! is_data_event && is_blob_event)
- {
- // currently subscribed to but not used
- DBUG_PRINT_EVENT("info", ("ignore non-data event on blob table"));
- DBUG_RETURN_EVENT(0);
- }
-
- // find position in bucket hash table
- EventBufData* data = 0;
- EventBufData_hash::Pos hpos;
- if (use_hash)
- {
- bucket->m_data_hash.search(hpos, op, ptr);
- data = hpos.data;
- }
-
- if (data == 0)
- {
- // allocate new result buffer
- data = alloc_data();
- if (unlikely(data == 0))
- {
- op->m_has_error = 2;
- DBUG_RETURN_EVENT(-1);
- }
- if (unlikely(copy_data(sdata, ptr, data, NULL)))
- {
- op->m_has_error = 3;
- DBUG_RETURN_EVENT(-1);
- }
- data->m_event_op = op;
- if (! is_blob_event || ! is_data_event)
- {
- bucket->m_data.append_data(data);
- }
- else
- {
- // find or create main event for this blob event
- EventBufData_hash::Pos main_hpos;
- int ret = get_main_data(bucket, main_hpos, data);
- if (ret == -1)
- {
- op->m_has_error = 4;
- DBUG_RETURN_EVENT(-1);
- }
- EventBufData* main_data = main_hpos.data;
- if (ret != 0) // main event was created
- {
- main_data->m_event_op = op->theMainOp;
- bucket->m_data.append_data(main_data);
- if (use_hash)
- {
- main_data->m_pkhash = main_hpos.pkhash;
- bucket->m_data_hash.append(main_hpos, main_data);
- }
- }
- // link blob event under main event
- add_blob_data(bucket, main_data, data);
- }
- if (use_hash)
- {
- data->m_pkhash = hpos.pkhash;
- bucket->m_data_hash.append(hpos, data);
- }
-#ifdef VM_TRACE
- op->m_data_count++;
-#endif
- }
- else
- {
- // event with same op, PK found, merge into old buffer
- if (unlikely(merge_data(sdata, ptr, data, & bucket->m_data.m_sz)))
- {
- op->m_has_error = 3;
- DBUG_RETURN_EVENT(-1);
- }
- // merge is on so we do not report blob part events
- if (! is_blob_event) {
- // report actual operation and the composite
- // there is no way to "fix" the flags for a composite op
- // since the flags represent multiple ops on multiple PKs
- // XXX fix by doing merge at end of epoch (extra mem cost)
- {
- EventBufData_list::Gci_op g = { op, (1 << operation) };
- bucket->m_data.add_gci_op(g);
- }
- {
- EventBufData_list::Gci_op
- g = { op,
- (1 << SubTableData::getOperation(data->sdata->requestInfo))};
- bucket->m_data.add_gci_op(g);
- }
- }
- }
-#ifdef NDB_EVENT_VERIFY_SIZE
- verify_size(bucket->m_data);
-#endif
- DBUG_RETURN_EVENT(0);
- }
-
-#ifdef VM_TRACE
- if ((Uint32)op->m_eventImpl->mi_type & (1 << operation))
- {
- DBUG_PRINT_EVENT("info",("Data arrived before ready eventId", op->m_eventId));
- DBUG_RETURN_EVENT(0);
- }
- else {
- DBUG_PRINT_EVENT("info",("skipped"));
- DBUG_RETURN_EVENT(0);
- }
-#else
- DBUG_RETURN_EVENT(0);
-#endif
-}
-
-// allocate EventBufData
-EventBufData*
-NdbEventBuffer::alloc_data()
-{
- DBUG_ENTER_EVENT("alloc_data");
- EventBufData* data = m_free_data;
-
- if (unlikely(data == 0))
- {
-#ifdef VM_TRACE
- assert(m_free_data_count == 0);
- assert(m_free_data_sz == 0);
-#endif
- expand(4000);
- reportStatus();
-
- data = m_free_data;
- if (unlikely(data == 0))
- {
-#ifdef VM_TRACE
- printf("m_latest_command: %s\n", m_latest_command);
- printf("no free data, m_latestGCI %lld\n",
- m_latestGCI);
- printf("m_free_data_count %d\n", m_free_data_count);
- printf("m_available_data_count %d first gci %d last gci %d\n",
- m_available_data.m_count,
- m_available_data.m_head ? m_available_data.m_head->sdata->gci : 0,
- m_available_data.m_tail ? m_available_data.m_tail->sdata->gci : 0);
- printf("m_used_data_count %d\n", m_used_data.m_count);
-#endif
- DBUG_RETURN_EVENT(0); // TODO handle this, overrun, or, skip?
- }
- }
-
- // remove data from free list
- if (data->m_next_blob == 0)
- m_free_data = data->m_next;
- else {
- EventBufData* data2 = data->m_next_blob;
- if (data2->m_next == 0) {
- data->m_next_blob = data2->m_next_blob;
- data = data2;
- } else {
- EventBufData* data3 = data2->m_next;
- data2->m_next = data3->m_next;
- data = data3;
- }
- }
- data->m_next = 0;
- data->m_next_blob = 0;
-#ifdef VM_TRACE
- m_free_data_count--;
- assert(m_free_data_sz >= data->sz);
-#endif
- m_free_data_sz -= data->sz;
- DBUG_RETURN_EVENT(data);
-}
-
-// allocate initial or bigger memory area in EventBufData
-// takes sizes from given ptr and sets up data->ptr
-int
-NdbEventBuffer::alloc_mem(EventBufData* data,
- LinearSectionPtr ptr[3],
- Uint32 * change_sz)
-{
- DBUG_ENTER("NdbEventBuffer::alloc_mem");
- DBUG_PRINT("info", ("ptr sz %u + %u + %u", ptr[0].sz, ptr[1].sz, ptr[2].sz));
- const Uint32 min_alloc_size = 128;
-
- Uint32 sz4 = (sizeof(SubTableData) + 3) >> 2;
- Uint32 alloc_size = (sz4 + ptr[0].sz + ptr[1].sz + ptr[2].sz) << 2;
- if (alloc_size < min_alloc_size)
- alloc_size = min_alloc_size;
-
- if (data->sz < alloc_size)
- {
- Uint32 add_sz = alloc_size - data->sz;
-
- NdbMem_Free((char*)data->memory);
- assert(m_total_alloc >= data->sz);
- data->memory = 0;
- data->sz = 0;
-
- data->memory = (Uint32*)NdbMem_Allocate(alloc_size);
- if (data->memory == 0)
- {
- m_total_alloc -= data->sz;
- DBUG_RETURN(-1);
- }
- data->sz = alloc_size;
- m_total_alloc += add_sz;
-
- if (change_sz != NULL)
- *change_sz += add_sz;
- }
-
- Uint32* memptr = data->memory;
- memptr += sz4;
- int i;
- for (i = 0; i <= 2; i++)
- {
- data->ptr[i].p = memptr;
- data->ptr[i].sz = ptr[i].sz;
- memptr += ptr[i].sz;
- }
-
- DBUG_RETURN(0);
-}
-
-void
-NdbEventBuffer::dealloc_mem(EventBufData* data,
- Uint32 * change_sz)
-{
- NdbMem_Free((char*)data->memory);
- assert(m_total_alloc >= data->sz);
- m_total_alloc -= data->sz;
- if (change_sz != NULL) {
- assert(*change_sz >= data->sz);
- *change_sz -= data->sz;
- }
- data->memory = 0;
- data->sz = 0;
-}
-
-int
-NdbEventBuffer::copy_data(const SubTableData * const sdata,
- LinearSectionPtr ptr[3],
- EventBufData* data,
- Uint32 * change_sz)
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::copy_data");
-
- if (alloc_mem(data, ptr, change_sz) != 0)
- DBUG_RETURN_EVENT(-1);
- memcpy(data->sdata, sdata, sizeof(SubTableData));
- int i;
- for (i = 0; i <= 2; i++)
- memcpy(data->ptr[i].p, ptr[i].p, ptr[i].sz << 2);
- DBUG_RETURN_EVENT(0);
-}
-
-static struct Ev_t {
- enum {
- enum_INS = NdbDictionary::Event::_TE_INSERT,
- enum_DEL = NdbDictionary::Event::_TE_DELETE,
- enum_UPD = NdbDictionary::Event::_TE_UPDATE,
- enum_NUL = NdbDictionary::Event::_TE_NUL,
- enum_IDM = 254, // idempotent op possibly allowed on NF
- enum_ERR = 255 // always impossible
- };
- int t1, t2, t3;
-} ev_t[] = {
- { Ev_t::enum_INS, Ev_t::enum_INS, Ev_t::enum_IDM },
- { Ev_t::enum_INS, Ev_t::enum_DEL, Ev_t::enum_NUL }, //ok
- { Ev_t::enum_INS, Ev_t::enum_UPD, Ev_t::enum_INS }, //ok
- { Ev_t::enum_DEL, Ev_t::enum_INS, Ev_t::enum_UPD }, //ok
- { Ev_t::enum_DEL, Ev_t::enum_DEL, Ev_t::enum_IDM },
- { Ev_t::enum_DEL, Ev_t::enum_UPD, Ev_t::enum_ERR },
- { Ev_t::enum_UPD, Ev_t::enum_INS, Ev_t::enum_ERR },
- { Ev_t::enum_UPD, Ev_t::enum_DEL, Ev_t::enum_DEL }, //ok
- { Ev_t::enum_UPD, Ev_t::enum_UPD, Ev_t::enum_UPD } //ok
-};
-
-/*
- * | INS | DEL | UPD
- * 0 | pk ah + all ah | pk ah | pk ah + new ah
- * 1 | pk ad + all ad | old pk ad | new pk ad + new ad
- * 2 | empty | old non-pk ah+ad | old ah+ad
- */
-
-static AttributeHeader
-copy_head(Uint32& i1, Uint32* p1, Uint32& i2, const Uint32* p2,
- Uint32 flags)
-{
- AttributeHeader ah(p2[i2]);
- bool do_copy = (flags & 1);
- if (do_copy)
- p1[i1] = p2[i2];
- i1++;
- i2++;
- return ah;
-}
-
-static void
-copy_attr(AttributeHeader ah,
- Uint32& j1, Uint32* p1, Uint32& j2, const Uint32* p2,
- Uint32 flags)
-{
- bool do_copy = (flags & 1);
- bool with_head = (flags & 2);
- Uint32 n = with_head + ah.getDataSize();
- if (do_copy)
- {
- Uint32 k;
- for (k = 0; k < n; k++)
- p1[j1 + k] = p2[j2 + k];
- }
- j1 += n;
- j2 += n;
-}
-
-int
-NdbEventBuffer::merge_data(const SubTableData * const sdata,
- LinearSectionPtr ptr2[3],
- EventBufData* data,
- Uint32 * change_sz)
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::merge_data");
-
- Uint32 nkey = data->m_event_op->m_eventImpl->m_tableImpl->m_noOfKeys;
-
- int t1 = SubTableData::getOperation(data->sdata->requestInfo);
- int t2 = SubTableData::getOperation(sdata->requestInfo);
- if (t1 == Ev_t::enum_NUL)
- DBUG_RETURN_EVENT(copy_data(sdata, ptr2, data, change_sz));
-
- Ev_t* tp = 0;
- int i;
- for (i = 0; (uint) i < sizeof(ev_t)/sizeof(ev_t[0]); i++) {
- if (ev_t[i].t1 == t1 && ev_t[i].t2 == t2) {
- tp = &ev_t[i];
- break;
- }
- }
- assert(tp != 0 && tp->t3 != Ev_t::enum_ERR);
-
- if (tp->t3 == Ev_t::enum_IDM) {
- LinearSectionPtr (&ptr1)[3] = data->ptr;
-
- /*
- * TODO
- * - can get data in INS ptr2[2] which is supposed to be empty
- * - can get extra data in DEL ptr2[2]
- * - why does DBUG_PRINT not work in this file ???
- *
- * replication + bug#19872 can ignore this since merge is on
- * only for tables with explicit PK and before data is not used
- */
- const int maxsec = 1; // ignore section 2
-
- int i;
- for (i = 0; i <= maxsec; i++) {
- if (ptr1[i].sz != ptr2[i].sz ||
- memcmp(ptr1[i].p, ptr2[i].p, ptr1[i].sz << 2) != 0) {
- DBUG_PRINT("info", ("idempotent op %d*%d data differs in sec %d",
- tp->t1, tp->t2, i));
- assert(false);
- DBUG_RETURN_EVENT(-1);
- }
- }
- DBUG_PRINT("info", ("idempotent op %d*%d data ok", tp->t1, tp->t2));
- DBUG_RETURN_EVENT(0);
- }
-
- // TODO: use old data items, avoid malloc/free on each merge
-
- // save old data
- EventBufData olddata = *data;
- data->memory = 0;
- data->sz = 0;
-
- // compose ptr1 o ptr2 = ptr
- LinearSectionPtr (&ptr1)[3] = olddata.ptr;
- LinearSectionPtr (&ptr)[3] = data->ptr;
-
- // loop twice where first loop only sets sizes
- int loop;
- int result = 0;
- for (loop = 0; loop <= 1; loop++)
- {
- if (loop == 1)
- {
- if (alloc_mem(data, ptr, change_sz) != 0)
- {
- result = -1;
- goto end;
- }
- *data->sdata = *sdata;
- SubTableData::setOperation(data->sdata->requestInfo, tp->t3);
- }
-
- ptr[0].sz = ptr[1].sz = ptr[2].sz = 0;
-
- // copy pk from new version
- {
- AttributeHeader ah;
- Uint32 i = 0;
- Uint32 j = 0;
- Uint32 i2 = 0;
- Uint32 j2 = 0;
- while (i < nkey)
- {
- ah = copy_head(i, ptr[0].p, i2, ptr2[0].p, loop);
- copy_attr(ah, j, ptr[1].p, j2, ptr2[1].p, loop);
- }
- ptr[0].sz = i;
- ptr[1].sz = j;
- }
-
- // merge after values, new version overrides
- if (tp->t3 != Ev_t::enum_DEL)
- {
- AttributeHeader ah;
- Uint32 i = ptr[0].sz;
- Uint32 j = ptr[1].sz;
- Uint32 i1 = 0;
- Uint32 j1 = 0;
- Uint32 i2 = nkey;
- Uint32 j2 = ptr[1].sz;
- while (i1 < nkey)
- {
- j1 += AttributeHeader(ptr1[0].p[i1++]).getDataSize();
- }
- while (1)
- {
- bool b1 = (i1 < ptr1[0].sz);
- bool b2 = (i2 < ptr2[0].sz);
- if (b1 && b2)
- {
- Uint32 id1 = AttributeHeader(ptr1[0].p[i1]).getAttributeId();
- Uint32 id2 = AttributeHeader(ptr2[0].p[i2]).getAttributeId();
- if (id1 < id2)
- b2 = false;
- else if (id1 > id2)
- b1 = false;
- else
- {
- j1 += AttributeHeader(ptr1[0].p[i1++]).getDataSize();
- b1 = false;
- }
- }
- if (b1)
- {
- ah = copy_head(i, ptr[0].p, i1, ptr1[0].p, loop);
- copy_attr(ah, j, ptr[1].p, j1, ptr1[1].p, loop);
- }
- else if (b2)
- {
- ah = copy_head(i, ptr[0].p, i2, ptr2[0].p, loop);
- copy_attr(ah, j, ptr[1].p, j2, ptr2[1].p, loop);
- }
- else
- break;
- }
- ptr[0].sz = i;
- ptr[1].sz = j;
- }
-
- // merge before values, old version overrides
- if (tp->t3 != Ev_t::enum_INS)
- {
- AttributeHeader ah;
- Uint32 k = 0;
- Uint32 k1 = 0;
- Uint32 k2 = 0;
- while (1)
- {
- bool b1 = (k1 < ptr1[2].sz);
- bool b2 = (k2 < ptr2[2].sz);
- if (b1 && b2)
- {
- Uint32 id1 = AttributeHeader(ptr1[2].p[k1]).getAttributeId();
- Uint32 id2 = AttributeHeader(ptr2[2].p[k2]).getAttributeId();
- if (id1 < id2)
- b2 = false;
- else if (id1 > id2)
- b1 = false;
- else
- {
- k2 += 1 + AttributeHeader(ptr2[2].p[k2]).getDataSize();
- b2 = false;
- }
- }
- if (b1)
- {
- ah = AttributeHeader(ptr1[2].p[k1]);
- copy_attr(ah, k, ptr[2].p, k1, ptr1[2].p, loop | 2);
- }
- else if (b2)
- {
- ah = AttributeHeader(ptr2[2].p[k2]);
- copy_attr(ah, k, ptr[2].p, k2, ptr2[2].p, loop | 2);
- }
- else
- break;
- }
- ptr[2].sz = k;
- }
- }
-
-end:
- dealloc_mem(&olddata, change_sz);
- DBUG_RETURN_EVENT(result);
-}
-
-/*
- * Given blob part event, find main table event on inline part. It
- * should exist (force in TUP) but may arrive later. If so, create
- * NUL event on main table. The real event replaces it later.
- */
-
-// write attribute headers for concatened PK
-static void
-split_concatenated_pk(const NdbTableImpl* t, Uint32* ah_buffer,
- const Uint32* pk_buffer, Uint32 pk_sz)
-{
- Uint32 sz = 0; // words parsed so far
- Uint32 n; // pk attr count
- Uint32 i;
- for (i = n = 0; i < t->m_columns.size() && n < t->m_noOfKeys; i++)
- {
- const NdbColumnImpl* c = t->getColumn(i);
- assert(c != NULL);
- if (! c->m_pk)
- continue;
-
- assert(sz < pk_sz);
- Uint32 bytesize = c->m_attrSize * c->m_arraySize;
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(c->m_type, &pk_buffer[sz], bytesize,
- lb, len);
- assert(ok);
-
- AttributeHeader ah(i, lb + len);
- ah_buffer[n++] = ah.m_value;
- sz += ah.getDataSize();
- }
- assert(n == t->m_noOfKeys && sz <= pk_sz);
-}
-
-int
-NdbEventBuffer::get_main_data(Gci_container* bucket,
- EventBufData_hash::Pos& hpos,
- EventBufData* blob_data)
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::get_main_data");
-
- NdbEventOperationImpl* main_op = blob_data->m_event_op->theMainOp;
- assert(main_op != NULL);
- const NdbTableImpl* mainTable = main_op->m_eventImpl->m_tableImpl;
-
- // create LinearSectionPtr for main table key
- LinearSectionPtr ptr[3];
- Uint32 ah_buffer[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
- ptr[0].sz = mainTable->m_noOfKeys;
- ptr[0].p = ah_buffer;
- ptr[1].sz = AttributeHeader(blob_data->ptr[0].p[0]).getDataSize();
- ptr[1].p = blob_data->ptr[1].p;
- ptr[2].sz = 0;
- ptr[2].p = 0;
- split_concatenated_pk(mainTable, ptr[0].p, ptr[1].p, ptr[1].sz);
-
- DBUG_DUMP_EVENT("ah", (char*)ptr[0].p, ptr[0].sz << 2);
- DBUG_DUMP_EVENT("pk", (char*)ptr[1].p, ptr[1].sz << 2);
-
- // search for main event buffer
- bucket->m_data_hash.search(hpos, main_op, ptr);
- if (hpos.data != NULL)
- DBUG_RETURN_EVENT(0);
-
- // not found, create a place-holder
- EventBufData* main_data = alloc_data();
- if (main_data == NULL)
- DBUG_RETURN_EVENT(-1);
- SubTableData sdata = *blob_data->sdata;
- sdata.tableId = main_op->m_eventImpl->m_tableImpl->m_id;
- SubTableData::setOperation(sdata.requestInfo, NdbDictionary::Event::_TE_NUL);
- if (copy_data(&sdata, ptr, main_data, NULL) != 0)
- DBUG_RETURN_EVENT(-1);
- hpos.data = main_data;
-
- DBUG_RETURN_EVENT(1);
-}
-
-void
-NdbEventBuffer::add_blob_data(Gci_container* bucket,
- EventBufData* main_data,
- EventBufData* blob_data)
-{
- DBUG_ENTER_EVENT("NdbEventBuffer::add_blob_data");
- DBUG_PRINT_EVENT("info", ("main_data=%p blob_data=%p", main_data, blob_data));
- EventBufData* head;
- head = main_data->m_next_blob;
- while (head != NULL)
- {
- if (head->m_event_op == blob_data->m_event_op)
- break;
- head = head->m_next_blob;
- }
- if (head == NULL)
- {
- head = blob_data;
- head->m_next_blob = main_data->m_next_blob;
- main_data->m_next_blob = head;
- }
- else
- {
- blob_data->m_next = head->m_next;
- head->m_next = blob_data;
- }
- // adjust data list size
- bucket->m_data.m_count += 1;
- bucket->m_data.m_sz += blob_data->sz;
- DBUG_VOID_RETURN_EVENT;
-}
-
-NdbEventOperationImpl *
-NdbEventBuffer::move_data()
-{
- // handle received data
- if (!m_complete_data.m_data.is_empty())
- {
- // move this list to last in m_available_data
- m_available_data.append_list(&m_complete_data.m_data, 0);
-
- bzero(&m_complete_data, sizeof(m_complete_data));
- }
-
- // handle used data
- if (!m_used_data.is_empty())
- {
- // return m_used_data to m_free_data
- free_list(m_used_data);
- }
- if (!m_available_data.is_empty())
- {
- DBUG_ENTER_EVENT("NdbEventBuffer::move_data");
-#ifdef VM_TRACE
- DBUG_PRINT_EVENT("exit",("m_available_data_count %u", m_available_data.m_count));
-#endif
- DBUG_RETURN_EVENT(m_available_data.m_head->m_event_op);
- }
- return 0;
-}
-
-void
-NdbEventBuffer::free_list(EventBufData_list &list)
-{
-#ifdef NDB_EVENT_VERIFY_SIZE
- verify_size(list);
-#endif
- // return list to m_free_data
- list.m_tail->m_next= m_free_data;
- m_free_data= list.m_head;
-#ifdef VM_TRACE
- m_free_data_count+= list.m_count;
-#endif
- m_free_data_sz+= list.m_sz;
-
- list.m_head = list.m_tail = NULL;
- list.m_count = list.m_sz = 0;
-}
-
-void EventBufData_list::append_list(EventBufData_list *list, Uint64 gci)
-{
-#ifdef NDB_EVENT_VERIFY_SIZE
- NdbEventBuffer::verify_size(*list);
-#endif
- move_gci_ops(list, gci);
-
- if (m_tail)
- m_tail->m_next= list->m_head;
- else
- m_head= list->m_head;
- m_tail= list->m_tail;
- m_count+= list->m_count;
- m_sz+= list->m_sz;
-}
-
-void
-EventBufData_list::add_gci_op(Gci_op g)
-{
- DBUG_ENTER_EVENT("EventBufData_list::add_gci_op");
- DBUG_PRINT_EVENT("info", ("p.op: %p g.event_types: %x", g.op, g.event_types));
- assert(g.op != NULL && g.op->theMainOp == NULL); // as in nextEvent
- Uint32 i;
- for (i = 0; i < m_gci_op_count; i++) {
- if (m_gci_op_list[i].op == g.op)
- break;
- }
- if (i < m_gci_op_count) {
- m_gci_op_list[i].event_types |= g.event_types;
- } else {
- if (m_gci_op_count == m_gci_op_alloc) {
- Uint32 n = 1 + 2 * m_gci_op_alloc;
- Gci_op* old_list = m_gci_op_list;
- m_gci_op_list = new Gci_op [n];
- if (m_gci_op_alloc != 0) {
- Uint32 bytes = m_gci_op_alloc * sizeof(Gci_op);
- memcpy(m_gci_op_list, old_list, bytes);
- DBUG_PRINT_EVENT("info", ("this: %p delete m_gci_op_list: %p",
- this, old_list));
- delete [] old_list;
- }
- else
- assert(old_list == 0);
- DBUG_PRINT_EVENT("info", ("this: %p new m_gci_op_list: %p",
- this, m_gci_op_list));
- m_gci_op_alloc = n;
- }
- assert(m_gci_op_count < m_gci_op_alloc);
-#ifndef DBUG_OFF
- i = m_gci_op_count;
-#endif
- // add gci reference
- // removed in deleteUsedOperations
- g.op->m_ref_count++;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", g.op->m_ref_count, g.op));
- m_gci_op_list[m_gci_op_count++] = g;
- }
- DBUG_PRINT_EVENT("exit", ("m_gci_op_list[%u].event_types: %x", i, m_gci_op_list[i].event_types));
- DBUG_VOID_RETURN_EVENT;
-}
-
-void
-EventBufData_list::move_gci_ops(EventBufData_list *list, Uint64 gci)
-{
- DBUG_ENTER_EVENT("EventBufData_list::move_gci_ops");
- DBUG_PRINT_EVENT("info", ("this: %p list: %p gci: %llu",
- this, list, gci));
- assert(!m_is_not_multi_list);
- if (!list->m_is_not_multi_list)
- {
- assert(gci == 0);
- if (m_gci_ops_list_tail)
- m_gci_ops_list_tail->m_next = list->m_gci_ops_list;
- else
- {
- m_gci_ops_list = list->m_gci_ops_list;
- }
- m_gci_ops_list_tail = list->m_gci_ops_list_tail;
- goto end;
- }
- {
- Gci_ops *new_gci_ops = new Gci_ops;
- DBUG_PRINT_EVENT("info", ("this: %p m_gci_op_list: %p",
- new_gci_ops, list->m_gci_op_list));
- if (m_gci_ops_list_tail)
- m_gci_ops_list_tail->m_next = new_gci_ops;
- else
- {
- assert(m_gci_ops_list == 0);
- m_gci_ops_list = new_gci_ops;
- }
- m_gci_ops_list_tail = new_gci_ops;
-
- new_gci_ops->m_gci_op_list = list->m_gci_op_list;
- new_gci_ops->m_gci_op_count = list->m_gci_op_count;
- new_gci_ops->m_gci = gci;
- new_gci_ops->m_next = 0;
- }
-end:
- list->m_gci_op_list = 0;
- list->m_gci_ops_list_tail = 0;
- list->m_gci_op_alloc = 0;
- DBUG_VOID_RETURN_EVENT;
-}
-
-NdbEventOperation*
-NdbEventBuffer::createEventOperation(const char* eventName,
- NdbError &theError)
-{
- DBUG_ENTER("NdbEventBuffer::createEventOperation");
- NdbEventOperation* tOp= new NdbEventOperation(m_ndb, eventName);
- if (tOp == 0)
- {
- theError.code= 4000;
- DBUG_RETURN(NULL);
- }
- if (tOp->getState() != NdbEventOperation::EO_CREATED) {
- theError.code= tOp->getNdbError().code;
- delete tOp;
- DBUG_RETURN(NULL);
- }
- // add user reference
- // removed in dropEventOperation
- getEventOperationImpl(tOp)->m_ref_count = 1;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p",
- getEventOperationImpl(tOp)->m_ref_count, getEventOperationImpl(tOp)));
- DBUG_RETURN(tOp);
-}
-
-NdbEventOperationImpl*
-NdbEventBuffer::createEventOperationImpl(NdbEventImpl& evnt,
- NdbError &theError)
-{
- DBUG_ENTER("NdbEventBuffer::createEventOperationImpl");
- NdbEventOperationImpl* tOp= new NdbEventOperationImpl(m_ndb, evnt);
- if (tOp == 0)
- {
- theError.code= 4000;
- DBUG_RETURN(NULL);
- }
- if (tOp->getState() != NdbEventOperation::EO_CREATED) {
- theError.code= tOp->getNdbError().code;
- delete tOp;
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(tOp);
-}
-
-void
-NdbEventBuffer::dropEventOperation(NdbEventOperation* tOp)
-{
- DBUG_ENTER("NdbEventBuffer::dropEventOperation");
- NdbEventOperationImpl* op= getEventOperationImpl(tOp);
-
- op->stop();
- // stop blob event ops
- if (op->theMainOp == NULL)
- {
- NdbEventOperationImpl* tBlobOp = op->theBlobOpList;
- while (tBlobOp != NULL)
- {
- tBlobOp->stop();
- tBlobOp = tBlobOp->m_next;
- }
-
- // release blob handles now, further access is user error
- while (op->theBlobList != NULL)
- {
- NdbBlob* tBlob = op->theBlobList;
- op->theBlobList = tBlob->theNext;
- m_ndb->releaseNdbBlob(tBlob);
- }
- }
-
- DBUG_ASSERT(op->m_ref_count > 0);
- // remove user reference
- // added in createEventOperation
- // user error to use reference after this
- op->m_ref_count--;
- DBUG_PRINT("info", ("m_ref_count: %u for op: %p", op->m_ref_count, op));
- if (op->m_ref_count == 0)
- {
- DBUG_PRINT("info", ("deleting op: %p", op));
- DBUG_ASSERT(op->m_node_bit_mask.isclear());
- delete op->m_facade;
- }
- else
- {
- op->m_next= m_dropped_ev_op;
- op->m_prev= 0;
- if (m_dropped_ev_op)
- m_dropped_ev_op->m_prev= op;
- m_dropped_ev_op= op;
- }
- DBUG_VOID_RETURN;
-}
-
-void
-NdbEventBuffer::reportStatus()
-{
- EventBufData *apply_buf= m_available_data.m_head;
- Uint64 apply_gci, latest_gci= m_latestGCI;
- if (apply_buf == 0)
- apply_buf= m_complete_data.m_data.m_head;
- if (apply_buf)
- apply_gci= apply_buf->sdata->gci;
- else
- apply_gci= latest_gci;
-
- if (100*(Uint64)m_free_data_sz < m_min_free_thresh*(Uint64)m_total_alloc &&
- m_total_alloc > 1024*1024)
- {
- /* report less free buffer than m_free_thresh,
- next report when more free than 2 * m_free_thresh
- */
- m_min_free_thresh= 0;
- m_max_free_thresh= 2 * m_free_thresh;
- goto send_report;
- }
-
- if (100*(Uint64)m_free_data_sz > m_max_free_thresh*(Uint64)m_total_alloc &&
- m_total_alloc > 1024*1024)
- {
- /* report more free than 2 * m_free_thresh
- next report when less free than m_free_thresh
- */
- m_min_free_thresh= m_free_thresh;
- m_max_free_thresh= 100;
- goto send_report;
- }
- if (latest_gci-apply_gci >= m_gci_slip_thresh)
- {
- goto send_report;
- }
- return;
-
-send_report:
- Uint32 data[8];
- data[0]= NDB_LE_EventBufferStatus;
- data[1]= m_total_alloc-m_free_data_sz;
- data[2]= m_total_alloc;
- data[3]= 0;
- data[4]= apply_gci & ~(Uint32)0;
- data[5]= apply_gci >> 32;
- data[6]= latest_gci & ~(Uint32)0;
- data[7]= latest_gci >> 32;
- Ndb_internal::send_event_report(m_ndb, data,8);
-#ifdef VM_TRACE
- assert(m_total_alloc >= m_free_data_sz);
-#endif
-}
-
-#ifdef VM_TRACE
-void
-NdbEventBuffer::verify_size(const EventBufData* data, Uint32 count, Uint32 sz)
-{
- Uint32 tmp_count = 0;
- Uint32 tmp_sz = 0;
- while (data != 0) {
- Uint32 full_count, full_sz;
- data->get_full_size(full_count, full_sz);
- tmp_count += full_count;
- tmp_sz += full_sz;
- data = data->m_next;
- }
- assert(tmp_count == count);
- assert(tmp_sz == sz);
-}
-void
-NdbEventBuffer::verify_size(const EventBufData_list & list)
-{
- verify_size(list.m_head, list.m_count, list.m_sz);
-}
-#endif
-
-// hash table routines
-
-// could optimize the all-fixed case
-Uint32
-EventBufData_hash::getpkhash(NdbEventOperationImpl* op, LinearSectionPtr ptr[3])
-{
- DBUG_ENTER_EVENT("EventBufData_hash::getpkhash");
- DBUG_DUMP_EVENT("ah", (char*)ptr[0].p, ptr[0].sz << 2);
- DBUG_DUMP_EVENT("pk", (char*)ptr[1].p, ptr[1].sz << 2);
-
- const NdbTableImpl* tab = op->m_eventImpl->m_tableImpl;
-
- // in all cases ptr[0] = pk ah.. ptr[1] = pk ad..
- // for pk update (to equivalent pk) post/pre values give same hash
- Uint32 nkey = tab->m_noOfKeys;
- assert(nkey != 0 && nkey <= ptr[0].sz);
- const Uint32* hptr = ptr[0].p;
- const uchar* dptr = (uchar*)ptr[1].p;
-
- // hash registers
- ulong nr1 = 0;
- ulong nr2 = 0;
- while (nkey-- != 0)
- {
- AttributeHeader ah(*hptr++);
- Uint32 bytesize = ah.getByteSize();
- assert(dptr + bytesize <= (uchar*)(ptr[1].p + ptr[1].sz));
-
- Uint32 i = ah.getAttributeId();
- const NdbColumnImpl* col = tab->getColumn(i);
- assert(col != 0);
-
- Uint32 lb, len;
- bool ok = NdbSqlUtil::get_var_length(col->m_type, dptr, bytesize, lb, len);
- assert(ok);
-
- CHARSET_INFO* cs = col->m_cs ? col->m_cs : &my_charset_bin;
- (*cs->coll->hash_sort)(cs, dptr + lb, len, &nr1, &nr2);
- dptr += ((bytesize + 3) / 4) * 4;
- }
- DBUG_PRINT_EVENT("info", ("hash result=%08x", nr1));
- DBUG_RETURN_EVENT(nr1);
-}
-
-bool
-EventBufData_hash::getpkequal(NdbEventOperationImpl* op, LinearSectionPtr ptr1[3], LinearSectionPtr ptr2[3])
-{
- DBUG_ENTER_EVENT("EventBufData_hash::getpkequal");
- DBUG_DUMP_EVENT("ah1", (char*)ptr1[0].p, ptr1[0].sz << 2);
- DBUG_DUMP_EVENT("pk1", (char*)ptr1[1].p, ptr1[1].sz << 2);
- DBUG_DUMP_EVENT("ah2", (char*)ptr2[0].p, ptr2[0].sz << 2);
- DBUG_DUMP_EVENT("pk2", (char*)ptr2[1].p, ptr2[1].sz << 2);
-
- const NdbTableImpl* tab = op->m_eventImpl->m_tableImpl;
-
- Uint32 nkey = tab->m_noOfKeys;
- assert(nkey != 0 && nkey <= ptr1[0].sz && nkey <= ptr2[0].sz);
- const Uint32* hptr1 = ptr1[0].p;
- const Uint32* hptr2 = ptr2[0].p;
- const uchar* dptr1 = (uchar*)ptr1[1].p;
- const uchar* dptr2 = (uchar*)ptr2[1].p;
-
- bool equal = true;
-
- while (nkey-- != 0)
- {
- AttributeHeader ah1(*hptr1++);
- AttributeHeader ah2(*hptr2++);
- // sizes can differ on update of varchar endspace
- Uint32 bytesize1 = ah1.getByteSize();
- Uint32 bytesize2 = ah2.getByteSize();
- assert(dptr1 + bytesize1 <= (uchar*)(ptr1[1].p + ptr1[1].sz));
- assert(dptr2 + bytesize2 <= (uchar*)(ptr2[1].p + ptr2[1].sz));
-
- assert(ah1.getAttributeId() == ah2.getAttributeId());
- Uint32 i = ah1.getAttributeId();
- const NdbColumnImpl* col = tab->getColumn(i);
- assert(col != 0);
-
- Uint32 lb1, len1;
- bool ok1 = NdbSqlUtil::get_var_length(col->m_type, dptr1, bytesize1, lb1, len1);
- Uint32 lb2, len2;
- bool ok2 = NdbSqlUtil::get_var_length(col->m_type, dptr2, bytesize2, lb2, len2);
- assert(ok1 && ok2 && lb1 == lb2);
-
- CHARSET_INFO* cs = col->m_cs ? col->m_cs : &my_charset_bin;
- int res = (cs->coll->strnncollsp)(cs, dptr1 + lb1, len1, dptr2 + lb2, len2, false);
- if (res != 0)
- {
- equal = false;
- break;
- }
- dptr1 += ((bytesize1 + 3) / 4) * 4;
- dptr2 += ((bytesize2 + 3) / 4) * 4;
- }
-
- DBUG_PRINT_EVENT("info", ("equal=%s", equal ? "true" : "false"));
- DBUG_RETURN_EVENT(equal);
-}
-
-void
-EventBufData_hash::search(Pos& hpos, NdbEventOperationImpl* op, LinearSectionPtr ptr[3])
-{
- DBUG_ENTER_EVENT("EventBufData_hash::search");
- Uint32 pkhash = getpkhash(op, ptr);
- Uint32 index = (op->m_oid ^ pkhash) % GCI_EVENT_HASH_SIZE;
- EventBufData* data = m_hash[index];
- while (data != 0)
- {
- if (data->m_event_op == op &&
- data->m_pkhash == pkhash &&
- getpkequal(op, data->ptr, ptr))
- break;
- data = data->m_next_hash;
- }
- hpos.index = index;
- hpos.data = data;
- hpos.pkhash = pkhash;
- DBUG_PRINT_EVENT("info", ("search result=%p", data));
- DBUG_VOID_RETURN_EVENT;
-}
-
-template class Vector<Gci_container_pod>;
-template class Vector<NdbEventBuffer::EventBufData_chunk*>;
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
deleted file mode 100644
index 1c80c5f9df1..00000000000
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
+++ /dev/null
@@ -1,655 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB, 2010 Sun Microsystems, Inc.
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NdbEventOperationImpl_H
-#define NdbEventOperationImpl_H
-
-#include <NdbEventOperation.hpp>
-#include <signaldata/SumaImpl.hpp>
-#include <transporter/TransporterDefinitions.hpp>
-#include <NdbRecAttr.hpp>
-#include <AttributeHeader.hpp>
-#include <UtilBuffer.hpp>
-
-#define NDB_EVENT_OP_MAGIC_NUMBER 0xA9F301B4
-//#define EVENT_DEBUG
-#ifdef EVENT_DEBUG
-#define DBUG_ENTER_EVENT(A) DBUG_ENTER(A)
-#define DBUG_RETURN_EVENT(A) DBUG_RETURN(A)
-#define DBUG_VOID_RETURN_EVENT DBUG_VOID_RETURN
-#define DBUG_PRINT_EVENT(A,B) DBUG_PRINT(A,B)
-#define DBUG_DUMP_EVENT(A,B,C) DBUG_DUMP(A,B,C)
-#else
-#define DBUG_ENTER_EVENT(A)
-#define DBUG_RETURN_EVENT(A) return(A)
-#define DBUG_VOID_RETURN_EVENT return
-#define DBUG_PRINT_EVENT(A,B)
-#define DBUG_DUMP_EVENT(A,B,C)
-#endif
-
-#undef NDB_EVENT_VERIFY_SIZE
-#ifdef VM_TRACE
-// not much effect on performance, leave on
-#define NDB_EVENT_VERIFY_SIZE
-#endif
-
-class NdbEventOperationImpl;
-
-struct EventBufData
-{
- union {
- SubTableData *sdata;
- Uint32 *memory;
- };
- LinearSectionPtr ptr[3];
- unsigned sz;
- NdbEventOperationImpl *m_event_op;
-
- /*
- * Blobs are stored in blob list (m_next_blob) where each entry
- * is list of parts (m_next). TODO order by part number
- *
- * Processed data (m_used_data, m_free_data) keeps the old blob
- * list intact. It is reconsumed when new data items are needed.
- *
- * Data item lists keep track of item count and sum(sz) and
- * these include both main items and blob parts.
- */
-
- EventBufData *m_next; // Next wrt to global order or Next blob part
- EventBufData *m_next_blob; // First part in next blob
-
- EventBufData *m_next_hash; // Next in per-GCI hash
- Uint32 m_pkhash; // PK hash (without op) for fast compare
-
- EventBufData() {}
-
- // Get blob part number from blob data
- Uint32 get_blob_part_no() const;
-
- /*
- * Main item does not include summary of parts (space / performance
- * tradeoff). The summary is needed when moving single data item.
- * It is not needed when moving entire list.
- */
- void get_full_size(Uint32 & full_count, Uint32 & full_sz) const {
- full_count = 1;
- full_sz = sz;
- if (m_next_blob != 0)
- add_part_size(full_count, full_sz);
- }
- void add_part_size(Uint32 & full_count, Uint32 & full_sz) const;
-};
-
-class EventBufData_list
-{
-public:
- EventBufData_list();
- ~EventBufData_list();
-
- // remove first and return its size
- void remove_first(Uint32 & full_count, Uint32 & full_sz);
- // for remove+append avoid double call to get_full_size()
- void append_used_data(EventBufData *data, Uint32 full_count, Uint32 full_sz);
- // append data and insert data but ignore Gci_op list
- void append_used_data(EventBufData *data);
- // append data and insert data into Gci_op list with add_gci_op
- void append_data(EventBufData *data);
- // append list to another, will call move_gci_ops
- void append_list(EventBufData_list *list, Uint64 gci);
-
- int is_empty();
-
- EventBufData *m_head, *m_tail;
- Uint32 m_count;
- Uint32 m_sz;
-
- /*
- distinct ops per gci (assume no hash needed)
-
- list may be in 2 versions
-
- 1. single list with on gci only
- - one linear array
- Gci_op *m_gci_op_list;
- Uint32 m_gci_op_count;
- Uint32 m_gci_op_alloc != 0;
-
- 2. multi list with several gcis
- - linked list of gci's
- - one linear array per gci
- Gci_ops *m_gci_ops_list;
- Gci_ops *m_gci_ops_list_tail;
- Uint32 m_is_not_multi_list == 0;
-
- */
- struct Gci_op // 1 + 2
- {
- NdbEventOperationImpl* op;
- Uint32 event_types;
- };
- struct Gci_ops // 2
- {
- Uint64 m_gci;
- Gci_op *m_gci_op_list;
- Gci_ops *m_next;
- Uint32 m_gci_op_count;
- };
- union
- {
- Gci_op *m_gci_op_list; // 1
- Gci_ops *m_gci_ops_list; // 2
- };
- union
- {
- Uint32 m_gci_op_count; // 1
- Gci_ops *m_gci_ops_list_tail;// 2
- };
- union
- {
- Uint32 m_gci_op_alloc; // 1
- Uint32 m_is_not_multi_list; // 2
- };
- Gci_ops *first_gci_ops();
- Gci_ops *next_gci_ops();
- // case 1 above; add Gci_op to single list
- void add_gci_op(Gci_op g);
-private:
- // case 2 above; move single list or multi list from
- // one list to another
- void move_gci_ops(EventBufData_list *list, Uint64 gci);
-};
-
-inline
-EventBufData_list::EventBufData_list()
- : m_head(0), m_tail(0),
- m_count(0),
- m_sz(0),
- m_gci_op_list(NULL),
- m_gci_ops_list_tail(0),
- m_gci_op_alloc(0)
-{
- DBUG_ENTER_EVENT("EventBufData_list::EventBufData_list");
- DBUG_PRINT_EVENT("info", ("this: %p", this));
- DBUG_VOID_RETURN_EVENT;
-}
-
-inline
-EventBufData_list::~EventBufData_list()
-{
- DBUG_ENTER_EVENT("EventBufData_list::~EventBufData_list");
- DBUG_PRINT_EVENT("info", ("this: %p m_is_not_multi_list: %u",
- this, m_is_not_multi_list));
- if (m_is_not_multi_list)
- {
- DBUG_PRINT_EVENT("info", ("delete m_gci_op_list: %p", m_gci_op_list));
- delete [] m_gci_op_list;
- }
- else
- {
- Gci_ops *op = first_gci_ops();
- while (op)
- op = next_gci_ops();
- }
- DBUG_VOID_RETURN_EVENT;
-}
-
-inline
-int EventBufData_list::is_empty()
-{
- return m_head == 0;
-}
-
-inline
-void EventBufData_list::remove_first(Uint32 & full_count, Uint32 & full_sz)
-{
- m_head->get_full_size(full_count, full_sz);
-#ifdef VM_TRACE
- assert(m_count >= full_count);
- assert(m_sz >= full_sz);
-#endif
- m_count -= full_count;
- m_sz -= full_sz;
- m_head = m_head->m_next;
- if (m_head == 0)
- m_tail = 0;
-}
-
-inline
-void EventBufData_list::append_used_data(EventBufData *data, Uint32 full_count, Uint32 full_sz)
-{
- data->m_next = 0;
- if (m_tail)
- m_tail->m_next = data;
- else
- {
-#ifdef VM_TRACE
- assert(m_head == 0);
- assert(m_count == 0);
- assert(m_sz == 0);
-#endif
- m_head = data;
- }
- m_tail = data;
-
- m_count += full_count;
- m_sz += full_sz;
-}
-
-inline
-void EventBufData_list::append_used_data(EventBufData *data)
-{
- Uint32 full_count, full_sz;
- data->get_full_size(full_count, full_sz);
- append_used_data(data, full_count, full_sz);
-}
-
-inline
-void EventBufData_list::append_data(EventBufData *data)
-{
- Gci_op g = { data->m_event_op,
- 1 << SubTableData::getOperation(data->sdata->requestInfo) };
- add_gci_op(g);
-
- append_used_data(data);
-}
-
-inline EventBufData_list::Gci_ops *
-EventBufData_list::first_gci_ops()
-{
- assert(!m_is_not_multi_list);
- return m_gci_ops_list;
-}
-
-inline EventBufData_list::Gci_ops *
-EventBufData_list::next_gci_ops()
-{
- assert(!m_is_not_multi_list);
- Gci_ops *first = m_gci_ops_list;
- m_gci_ops_list = first->m_next;
- if (first->m_gci_op_list)
- {
- DBUG_PRINT_EVENT("info", ("this: %p delete m_gci_op_list: %p",
- this, first->m_gci_op_list));
- delete [] first->m_gci_op_list;
- }
- delete first;
- if (m_gci_ops_list == 0)
- m_gci_ops_list_tail = 0;
- return m_gci_ops_list;
-}
-
-// GCI bucket has also a hash over data, with key event op, table PK.
-// It can only be appended to and is invalid after remove_first().
-class EventBufData_hash
-{
-public:
- struct Pos { // search result
- Uint32 index; // index into hash array
- EventBufData* data; // non-zero if found
- Uint32 pkhash; // PK hash
- };
-
- static Uint32 getpkhash(NdbEventOperationImpl* op, LinearSectionPtr ptr[3]);
- static bool getpkequal(NdbEventOperationImpl* op, LinearSectionPtr ptr1[3], LinearSectionPtr ptr2[3]);
-
- void search(Pos& hpos, NdbEventOperationImpl* op, LinearSectionPtr ptr[3]);
- void append(Pos& hpos, EventBufData* data);
-
- enum { GCI_EVENT_HASH_SIZE = 101 };
- EventBufData* m_hash[GCI_EVENT_HASH_SIZE];
-};
-
-inline
-void EventBufData_hash::append(Pos& hpos, EventBufData* data)
-{
- data->m_next_hash = m_hash[hpos.index];
- m_hash[hpos.index] = data;
-}
-
-struct Gci_container
-{
- enum State
- {
- GC_COMPLETE = 0x1 // GCI is complete, but waiting for out of order
- };
-
- Uint32 m_state;
- Uint32 m_gcp_complete_rep_count; // Remaining SUB_GCP_COMPLETE_REP until done
- Uint64 m_gci; // GCI
- EventBufData_list m_data;
- EventBufData_hash m_data_hash;
-};
-
-struct Gci_container_pod
-{
- char data[sizeof(Gci_container)];
-};
-
-class NdbEventOperationImpl : public NdbEventOperation {
-public:
- NdbEventOperationImpl(NdbEventOperation &f,
- Ndb *theNdb,
- const char* eventName);
- NdbEventOperationImpl(Ndb *theNdb,
- NdbEventImpl& evnt);
- void init(NdbEventImpl& evnt);
- NdbEventOperationImpl(NdbEventOperationImpl&); //unimplemented
- NdbEventOperationImpl& operator=(const NdbEventOperationImpl&); //unimplemented
- ~NdbEventOperationImpl();
-
- NdbEventOperation::State getState();
-
- int execute();
- int execute_nolock();
- int stop();
- NdbRecAttr *getValue(const char *colName, char *aValue, int n);
- NdbRecAttr *getValue(const NdbColumnImpl *, char *aValue, int n);
- NdbBlob *getBlobHandle(const char *colName, int n);
- NdbBlob *getBlobHandle(const NdbColumnImpl *, int n);
- int readBlobParts(char* buf, NdbBlob* blob, Uint32 part, Uint32 count);
- int receive_event();
- bool tableNameChanged() const;
- bool tableFrmChanged() const;
- bool tableFragmentationChanged() const;
- bool tableRangeListChanged() const;
- Uint64 getGCI();
- Uint32 getAnyValue() const;
- Uint64 getLatestGCI();
- bool execSUB_TABLE_DATA(NdbApiSignal * signal,
- LinearSectionPtr ptr[3]);
-
- NdbDictionary::Event::TableEvent getEventType();
-
- void print();
- void printAll();
-
- NdbEventOperation *m_facade;
- Uint32 m_magic_number;
-
- const NdbError & getNdbError() const;
- NdbError m_error;
-
- Ndb *m_ndb;
- NdbEventImpl *m_eventImpl;
-
- NdbRecAttr *theFirstPkAttrs[2];
- NdbRecAttr *theCurrentPkAttrs[2];
- NdbRecAttr *theFirstDataAttrs[2];
- NdbRecAttr *theCurrentDataAttrs[2];
-
- NdbBlob* theBlobList;
- NdbEventOperationImpl* theBlobOpList; // in main op, list of blob ops
- NdbEventOperationImpl* theMainOp; // in blob op, the main op
-
- NdbEventOperation::State m_state; /* note connection to mi_type */
- Uint32 mi_type; /* should be == 0 if m_state != EO_EXECUTING
- * else same as in EventImpl
- */
- Uint32 m_eventId;
- Uint32 m_oid;
-
- /*
- m_node_bit_mask keeps track of which ndb nodes have reference to
- an event op
-
- - add - TE_ACTIVE
- - remove - TE_STOP, TE_NODE_FAILURE, TE_CLUSTER_FAILURE
-
- TE_NODE_FAILURE and TE_CLUSTER_FAILURE are created as events
- and added to all event ops listed as active or pending delete
- in m_dropped_ev_op using insertDataL, includeing the blob
- event ops referenced by a regular event op.
- - NdbEventBuffer::report_node_failure
- - NdbEventBuffer::completeClusterFailed
-
- TE_ACTIVE is sent from the kernel on initial execute/start of the
- event op, but is also internally generetad on node connect like
- TE_NODE_FAILURE and TE_CLUSTER_FAILURE
- - NdbEventBuffer::report_node_connected
-
- when m_node_bit_mask becomes clear, the kernel reference is
- removed from m_ref_count
-
- node id 0 is used to denote that cluster has a reference
- */
-
- Bitmask<(unsigned int)_NDB_NODE_BITMASK_SIZE> m_node_bit_mask;
-
- /*
- m_ref_count keeps track of outstanding references to an event
- operation impl object. To make sure that the object is not
- deleted too early.
-
- If on dropEventOperation there are still references to an
- object it is queued for delete in NdbEventBuffer::m_dropped_ev_op
-
- the following references exists for a _non_ blob event op:
- * user reference
- - add - NdbEventBuffer::createEventOperation
- - remove - NdbEventBuffer::dropEventOperation
- * kernel reference
- - add - execute_nolock
- - remove - TE_STOP, TE_CLUSTER_FAILURE
- * blob reference
- - add - execute_nolock on blob event
- - remove - TE_STOP, TE_CLUSTER_FAILURE on blob event
- * gci reference
- - add - insertDataL/add_gci_op
- - remove - NdbEventBuffer::deleteUsedEventOperations
-
- the following references exists for a blob event op:
- * kernel reference
- - add - execute_nolock
- - remove - TE_STOP, TE_CLUSTER_FAILURE
- */
-
- int m_ref_count;
- bool m_mergeEvents;
-
- EventBufData *m_data_item;
-
- void *m_custom_data;
- int m_has_error;
-
- Uint32 m_fragmentId;
- UtilBuffer m_buffer;
-
- // Bit mask for what has changed in a table (for TE_ALTER event)
- Uint32 m_change_mask;
-
-#ifdef VM_TRACE
- Uint32 m_data_done_count;
- Uint32 m_data_count;
-#endif
-
- // managed by the ndb object
- NdbEventOperationImpl *m_next;
- NdbEventOperationImpl *m_prev;
-private:
- void receive_data(NdbRecAttr *r, const Uint32 *data, Uint32 sz);
-};
-
-class NdbEventBuffer {
-public:
- NdbEventBuffer(Ndb*);
- ~NdbEventBuffer();
-
- const Uint32 &m_system_nodes;
- Vector<Gci_container_pod> m_active_gci;
- NdbEventOperation *createEventOperation(const char* eventName,
- NdbError &);
- NdbEventOperationImpl *createEventOperationImpl(NdbEventImpl& evnt,
- NdbError &);
- void dropEventOperation(NdbEventOperation *);
- static NdbEventOperationImpl* getEventOperationImpl(NdbEventOperation* tOp);
-
- void add_drop_lock() { NdbMutex_Lock(m_add_drop_mutex); }
- void add_drop_unlock() { NdbMutex_Unlock(m_add_drop_mutex); }
- void lock() { NdbMutex_Lock(m_mutex); }
- void unlock() { NdbMutex_Unlock(m_mutex); }
-
- void add_op();
- void remove_op();
- void init_gci_containers();
-
- // accessed from the "receive thread"
- int insertDataL(NdbEventOperationImpl *op,
- const SubTableData * const sdata,
- LinearSectionPtr ptr[3]);
- void execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep);
- void complete_outof_order_gcis();
-
- void report_node_connected(Uint32 node_id);
- void report_node_failure(Uint32 node_id);
- void completeClusterFailed();
-
- // used by user thread
- Uint64 getLatestGCI();
- Uint32 getEventId(int bufferId);
-
- int pollEvents(int aMillisecondNumber, Uint64 *latestGCI= 0);
- int flushIncompleteEvents(Uint64 gci);
- NdbEventOperation *nextEvent();
- NdbEventOperationImpl* getGCIEventOperations(Uint32* iter,
- Uint32* event_types);
- void deleteUsedEventOperations();
-
- NdbEventOperationImpl *move_data();
-
- // routines to copy/merge events
- EventBufData* alloc_data();
- int alloc_mem(EventBufData* data,
- LinearSectionPtr ptr[3],
- Uint32 * change_sz);
- void dealloc_mem(EventBufData* data,
- Uint32 * change_sz);
- int copy_data(const SubTableData * const sdata,
- LinearSectionPtr ptr[3],
- EventBufData* data,
- Uint32 * change_sz);
- int merge_data(const SubTableData * const sdata,
- LinearSectionPtr ptr[3],
- EventBufData* data,
- Uint32 * change_sz);
- int get_main_data(Gci_container* bucket,
- EventBufData_hash::Pos& hpos,
- EventBufData* blob_data);
- void add_blob_data(Gci_container* bucket,
- EventBufData* main_data,
- EventBufData* blob_data);
-
- void free_list(EventBufData_list &list);
-
- void reportStatus();
-
- // Global Mutex used for some things
- static NdbMutex *p_add_drop_mutex;
-
-#ifdef VM_TRACE
- const char *m_latest_command;
- Uint64 m_flush_gci;
-#endif
-
- Ndb *m_ndb;
- Uint64 m_latestGCI; // latest "handover" GCI
- Uint64 m_latest_complete_GCI; // latest complete GCI (in case of outof order)
-
- NdbMutex *m_mutex;
- struct NdbCondition *p_cond;
-
- // receive thread
- Gci_container m_complete_data;
- EventBufData *m_free_data;
-#ifdef VM_TRACE
- Uint32 m_free_data_count;
-#endif
- Uint32 m_free_data_sz;
-
- // user thread
- EventBufData_list m_available_data;
- EventBufData_list m_used_data;
-
- unsigned m_total_alloc; // total allocated memory
-
- // threshholds to report status
- unsigned m_free_thresh, m_min_free_thresh, m_max_free_thresh;
- unsigned m_gci_slip_thresh;
-
- NdbError m_error;
-
-#ifdef VM_TRACE
- static void verify_size(const EventBufData* data, Uint32 count, Uint32 sz);
- static void verify_size(const EventBufData_list & list);
-#endif
-
-private:
- void insert_event(NdbEventOperationImpl* impl,
- SubTableData &data,
- LinearSectionPtr *ptr,
- Uint32 &oid_ref);
-
- int expand(unsigned sz);
-
- // all allocated data
- struct EventBufData_chunk
- {
- unsigned sz;
- EventBufData data[1];
- };
- Vector<EventBufData_chunk *> m_allocated_data;
- unsigned m_sz;
-
- /*
- dropped event operations (dropEventOperation) that have not yet
- been deleted because of outstanding m_ref_count
-
- check for delete is done on occations when the ref_count may have
- changed by calling deleteUsedEventOperations:
- - nextEvent - each time the user has completed processing a gci
- */
- NdbEventOperationImpl *m_dropped_ev_op;
-
- Uint32 m_active_op_count;
- NdbMutex *m_add_drop_mutex;
-};
-
-inline
-NdbEventOperationImpl*
-NdbEventBuffer::getEventOperationImpl(NdbEventOperation* tOp)
-{
- return &tOp->m_impl;
-}
-
-inline void
-NdbEventOperationImpl::receive_data(NdbRecAttr *r,
- const Uint32 *data,
- Uint32 sz)
-{
- r->receive_data(data,sz);
-#if 0
- if (sz)
- {
- assert((r->attrSize() * r->arraySize() + 3) >> 2 == sz);
- r->theNULLind= 0;
- memcpy(r->aRef(), data, 4 * sz);
- return;
- }
- r->theNULLind= 1;
-#endif
-}
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbImpl.hpp b/storage/ndb/src/ndbapi/NdbImpl.hpp
deleted file mode 100644
index 0792c0e271f..00000000000
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_IMPL_HPP
-#define NDB_IMPL_HPP
-
-#include <ndb_global.h>
-#include <Ndb.hpp>
-#include <NdbOut.hpp>
-#include <NdbError.hpp>
-#include <NdbCondition.h>
-#include <NdbReceiver.hpp>
-#include <NdbOperation.hpp>
-#include <kernel/ndb_limits.h>
-
-#include <NdbTick.h>
-
-#include "ndb_cluster_connection_impl.hpp"
-#include "NdbDictionaryImpl.hpp"
-#include "ObjectMap.hpp"
-
-template <class T>
-struct Ndb_free_list_t
-{
- Ndb_free_list_t();
- ~Ndb_free_list_t();
-
- int fill(Ndb*, Uint32 cnt);
- T* seize(Ndb*);
- void release(T*);
- void clear();
- Uint32 get_sizeof() const { return sizeof(T); }
- T * m_free_list;
- Uint32 m_alloc_cnt, m_free_cnt;
-};
-
-/**
- * Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
- */
-class NdbImpl {
-public:
- NdbImpl(Ndb_cluster_connection *, Ndb&);
- ~NdbImpl();
-
- int send_event_report(Uint32 *data, Uint32 length);
-
- Ndb &m_ndb;
-
- Ndb_cluster_connection_impl &m_ndb_cluster_connection;
- TransporterFacade *m_transporter_facade;
-
- NdbDictionaryImpl m_dictionary;
-
- // Ensure good distribution of connects
- Uint32 theCurrentConnectIndex;
- Ndb_cluster_connection_node_iter m_node_iter;
-
- NdbObjectIdMap theNdbObjectIdMap;
-
- Uint32 theNoOfDBnodes; // The number of DB nodes
- Uint8 theDBnodes[MAX_NDB_NODES]; // The node number of the DB nodes
-
- // 1 indicates to release all connections to node
- Uint32 the_release_ind[MAX_NDB_NODES];
-
- NdbWaiter theWaiter;
-
- NdbEventOperationImpl *m_ev_op;
-
- int m_optimized_node_selection;
-
- BaseString m_dbname; // Database name
- BaseString m_schemaname; // Schema name
-
- BaseString m_prefix; // Buffer for preformatted internal name <db>/<schema>/
-
- int update_prefix()
- {
- if (!m_prefix.assfmt("%s%c%s%c", m_dbname.c_str(), table_name_separator,
- m_schemaname.c_str(), table_name_separator))
- {
- return -1;
- }
- return 0;
- }
-
-/*
- We need this friend accessor function to work around a HP compiler problem,
- where template class friends are not working.
-*/
- static inline void setNdbError(Ndb &ndb,int code){
- ndb.theError.code = code;
- return;
- }
-
- BaseString m_systemPrefix; // Buffer for preformatted for <sys>/<def>/
-
- /**
- * NOTE free lists must be _after_ theNdbObjectIdMap take
- * assure that destructors are run in correct order
- * NOTE these has to be in this specific order to make destructor run in
- * correct order
- */
- Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;
- Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
- Ndb_free_list_t<NdbLabel> theLabelList;
- Ndb_free_list_t<NdbBranch> theBranchList;
- Ndb_free_list_t<NdbSubroutine> theSubroutineList;
- Ndb_free_list_t<NdbCall> theCallList;
- Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
- Ndb_free_list_t<NdbReceiver> theScanList;
- Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
- Ndb_free_list_t<NdbOperation> theOpIdleList;
- Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
- Ndb_free_list_t<NdbTransaction> theConIdleList;
-};
-
-#ifdef VM_TRACE
-#define TRACE_DEBUG(x) ndbout << x << endl;
-#else
-#define TRACE_DEBUG(x)
-#endif
-
-#define CHECK_STATUS_MACRO \
- {if (checkInitState() == -1) { theError.code = 4100; DBUG_RETURN(-1);}}
-#define CHECK_STATUS_MACRO_VOID \
- {if (checkInitState() == -1) { theError.code = 4100; DBUG_VOID_RETURN;}}
-#define CHECK_STATUS_MACRO_ZERO \
- {if (checkInitState() == -1) { theError.code = 4100; DBUG_RETURN(0);}}
-#define CHECK_STATUS_MACRO_NULL \
- {if (checkInitState() == -1) { theError.code = 4100; DBUG_RETURN(NULL);}}
-
-inline
-void *
-Ndb::int2void(Uint32 val){
- return theImpl->theNdbObjectIdMap.getObject(val);
-}
-
-inline
-NdbReceiver *
-Ndb::void2rec(void* val){
- return (NdbReceiver*)val;
-}
-
-inline
-NdbTransaction *
-Ndb::void2con(void* val){
- return (NdbTransaction*)val;
-}
-
-inline
-NdbOperation*
-Ndb::void2rec_op(void* val){
- return (NdbOperation*)(void2rec(val)->getOwner());
-}
-
-inline
-NdbIndexOperation*
-Ndb::void2rec_iop(void* val){
- return (NdbIndexOperation*)(void2rec(val)->getOwner());
-}
-
-inline
-NdbTransaction *
-NdbReceiver::getTransaction(){
- return ((NdbOperation*)m_owner)->theNdbCon;
-}
-
-
-inline
-int
-Ndb::checkInitState()
-{
- theError.code = 0;
-
- if (theInitState != Initialised)
- return -1;
- return 0;
-}
-
-Uint32 convertEndian(Uint32 Data);
-
-enum LockMode {
- Read,
- Update,
- Insert,
- Delete
-};
-
-template<class T>
-inline
-Ndb_free_list_t<T>::Ndb_free_list_t()
-{
- m_free_list= 0;
- m_alloc_cnt= m_free_cnt= 0;
-}
-
-template<class T>
-inline
-Ndb_free_list_t<T>::~Ndb_free_list_t()
-{
- clear();
-}
-
-template<class T>
-inline
-int
-Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
-{
- if (m_free_list == 0)
- {
- m_free_cnt++;
- m_alloc_cnt++;
- m_free_list = new T(ndb);
- if (m_free_list == 0)
- {
- NdbImpl::setNdbError(*ndb, 4000);
- assert(false);
- return -1;
- }
- }
- while(m_alloc_cnt < cnt)
- {
- T* obj= new T(ndb);
- if(obj == 0)
- {
- NdbImpl::setNdbError(*ndb, 4000);
- assert(false);
- return -1;
- }
- obj->next(m_free_list);
- m_free_cnt++;
- m_alloc_cnt++;
- m_free_list = obj;
- }
- return 0;
-}
-
-template<class T>
-inline
-T*
-Ndb_free_list_t<T>::seize(Ndb* ndb)
-{
- T* tmp = m_free_list;
- if (tmp)
- {
- m_free_list = (T*)tmp->next();
- tmp->next(NULL);
- m_free_cnt--;
- return tmp;
- }
-
- if((tmp = new T(ndb)))
- {
- m_alloc_cnt++;
- }
- else
- {
- NdbImpl::setNdbError(*ndb, 4000);
- assert(false);
- }
- return tmp;
-}
-
-template<class T>
-inline
-void
-Ndb_free_list_t<T>::release(T* obj)
-{
- obj->next(m_free_list);
- m_free_list = obj;
- m_free_cnt++;
-}
-
-
-template<class T>
-inline
-void
-Ndb_free_list_t<T>::clear()
-{
- T* obj = m_free_list;
- while(obj)
- {
- T* curr = obj;
- obj = (T*)obj->next();
- delete curr;
- m_alloc_cnt--;
- }
-}
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbIndexOperation.cpp b/storage/ndb/src/ndbapi/NdbIndexOperation.cpp
deleted file mode 100644
index d85639ac55f..00000000000
--- a/storage/ndb/src/ndbapi/NdbIndexOperation.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbIndexOperation.hpp>
-#include <Ndb.hpp>
-#include <NdbTransaction.hpp>
-#include "NdbApiSignal.hpp"
-#include <AttributeHeader.hpp>
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/IndxKeyInfo.hpp>
-#include <signaldata/IndxAttrInfo.hpp>
-
-NdbIndexOperation::NdbIndexOperation(Ndb* aNdb) :
- NdbOperation(aNdb, NdbOperation::UniqueIndexAccess),
- m_theIndex(NULL)
-{
- m_tcReqGSN = GSN_TCINDXREQ;
- m_attrInfoGSN = GSN_INDXATTRINFO;
- m_keyInfoGSN = GSN_INDXKEYINFO;
-
- /**
- * Change receiver type
- */
- theReceiver.init(NdbReceiver::NDB_INDEX_OPERATION, this);
-}
-
-NdbIndexOperation::~NdbIndexOperation()
-{
-}
-
-/*****************************************************************************
- * int indxInit();
- *
- * Return Value: Return 0 : init was successful.
- * Return -1: In all other case.
- * Remark: Initiates operation record after allocation.
- *****************************************************************************/
-int
-NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
- const NdbTableImpl * aTable,
- NdbTransaction* myConnection)
-{
- NdbOperation::init(aTable, myConnection);
-
- switch (anIndex->m_type) {
- case(NdbDictionary::Index::UniqueHashIndex):
- break;
- case(NdbDictionary::Index::Undefined):
- case(NdbDictionary::Index::OrderedIndex):
- setErrorCodeAbort(4003);
- return -1;
- default:
- DBUG_ASSERT(0);
- break;
- }
- m_theIndex = anIndex;
- m_accessTable = anIndex->m_table;
- theNoOfTupKeyLeft = m_accessTable->getNoOfPrimaryKeys();
- return 0;
-}
-
-int NdbIndexOperation::readTuple(NdbOperation::LockMode lm)
-{
- switch(lm) {
- case LM_Read:
- return readTuple();
- break;
- case LM_Exclusive:
- return readTupleExclusive();
- break;
- case LM_CommittedRead:
- return readTuple();
- break;
- case LM_SimpleRead:
- return readTuple();
- break;
- default:
- return -1;
- };
-}
-
-int NdbIndexOperation::insertTuple()
-{
- setErrorCode(4200);
- return -1;
-}
-
-int NdbIndexOperation::readTuple()
-{
- // First check that index is unique
-
- return NdbOperation::readTuple();
-}
-
-int NdbIndexOperation::readTupleExclusive()
-{
- // First check that index is unique
-
- return NdbOperation::readTupleExclusive();
-}
-
-int NdbIndexOperation::simpleRead()
-{
- // First check that index is unique
-
- return NdbOperation::readTuple();
-}
-
-int NdbIndexOperation::dirtyRead()
-{
- // First check that index is unique
-
- return NdbOperation::readTuple();
-}
-
-int NdbIndexOperation::committedRead()
-{
- // First check that index is unique
-
- return NdbOperation::readTuple();
-}
-
-int NdbIndexOperation::updateTuple()
-{
- // First check that index is unique
-
- return NdbOperation::updateTuple();
-}
-
-int NdbIndexOperation::deleteTuple()
-{
- // First check that index is unique
-
- return NdbOperation::deleteTuple();
-}
-
-int NdbIndexOperation::dirtyUpdate()
-{
- // First check that index is unique
-
- return NdbOperation::dirtyUpdate();
-}
-
-int NdbIndexOperation::interpretedUpdateTuple()
-{
- // First check that index is unique
-
- return NdbOperation::interpretedUpdateTuple();
-}
-
-int NdbIndexOperation::interpretedDeleteTuple()
-{
- // First check that index is unique
-
- return NdbOperation::interpretedDeleteTuple();
-}
-
-const NdbDictionary::Index*
-NdbIndexOperation::getIndex() const
-{
- return m_theIndex;
-}
-
-/***************************************************************************
-int receiveTCINDXREF( NdbApiSignal* aSignal)
-
-Return Value: Return 0 : send was succesful.
- Return -1: In all other case.
-Parameters: aSignal: the signal object that contains the TCINDXREF signal from TC.
-Remark: Handles the reception of the TCKEYREF signal.
-***************************************************************************/
-int
-NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal)
-{
- return receiveTCKEYREF(aSignal);
-}//NdbIndexOperation::receiveTCINDXREF()
diff --git a/storage/ndb/src/ndbapi/NdbIndexStat.cpp b/storage/ndb/src/ndbapi/NdbIndexStat.cpp
deleted file mode 100644
index 79bb5a495b5..00000000000
--- a/storage/ndb/src/ndbapi/NdbIndexStat.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <AttributeHeader.hpp>
-#include <NdbSqlUtil.hpp>
-#include <NdbIndexStat.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbIndexScanOperation.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <my_sys.h>
-
-NdbIndexStat::NdbIndexStat(const NdbDictionary::Index* index) :
- m_index(index->m_impl),
- m_cache(NULL)
-{
-}
-
-NdbIndexStat::~NdbIndexStat()
-{
- delete [] m_cache;
- m_cache = NULL;
-}
-
-int
-NdbIndexStat::alloc_cache(Uint32 entries)
-{
- delete [] m_cache;
- m_cache = NULL;
- if (entries == 0) {
- return 0;
- }
- Uint32 i;
- Uint32 keysize = 0;
- for (i = 0; i < m_index.m_columns.size(); i++) {
- NdbColumnImpl* c = m_index.m_columns[i];
- keysize += 2; // counting extra headers
- keysize += (c->m_attrSize * c->m_arraySize + 3 ) / 4;
- }
- Uint32 areasize = entries * (PointerSize + EntrySize + keysize);
- if (areasize > (1 << 16))
- areasize = (1 << 16);
- Uint32 cachesize = 2 * areasize;
- m_cache = new Uint32 [cachesize];
- if (m_cache == NULL) {
- set_error(4000);
- return -1;
- }
- m_areasize = areasize;
- m_seq = 0;
- Uint32 idir;
- for (idir = 0; idir <= 1; idir++) {
- Area& a = m_area[idir];
- a.m_data = &m_cache[idir * areasize];
- a.m_offset = a.m_data - &m_cache[0];
- a.m_free = areasize;
- a.m_entries = 0;
- a.m_idir = idir;
- a.pad1 = 0;
- }
-#ifdef VM_TRACE
- memset(&m_cache[0], 0x3f, cachesize << 2);
-#endif
- return 0;
-}
-
-#ifndef VM_TRACE
-#define stat_verify()
-#else
-void
-NdbIndexStat::stat_verify()
-{
- Uint32 idir;
- for (idir = 0; idir <= 1; idir++) {
- Uint32 i;
- const Area& a = m_area[idir];
- assert(a.m_offset == idir * m_areasize);
- assert(a.m_data == &m_cache[a.m_offset]);
- Uint32 pointerwords = PointerSize * a.m_entries;
- Uint32 entrywords = 0;
- for (i = 0; i < a.m_entries; i++) {
- const Pointer& p = a.get_pointer(i);
- const Entry& e = a.get_entry(i);
- assert(a.get_pos(e) == p.m_pos);
- entrywords += EntrySize + e.m_keylen;
- }
- assert(a.m_free <= m_areasize);
- assert(pointerwords + a.m_free + entrywords == m_areasize);
- Uint32 off = pointerwords + a.m_free;
- for (i = 0; i < a.m_entries; i++) {
- assert(off < m_areasize);
- const Entry& e = *(const Entry*)&a.m_data[off];
- off += EntrySize + e.m_keylen;
- }
- assert(off == m_areasize);
- for (i = 0; i < a.m_entries; i++) {
- const Entry& e = a.get_entry(i);
- const Uint32* entrykey = (const Uint32*)&e + EntrySize;
- Uint32 n = 0;
- while (n + 2 <= e.m_keylen) {
- Uint32 t = entrykey[n++];
- assert(t == 2 * idir || t == 2 * idir + 1 || t == 4);
- AttributeHeader ah = *(const AttributeHeader*)&entrykey[n++];
- n += ah.getDataSize();
- }
- assert(n == e.m_keylen);
- }
- for (i = 0; i + 1 < a.m_entries; i++) {
- const Entry& e1 = a.get_entry(i);
- const Entry& e2 = a.get_entry(i + 1);
- const Uint32* entrykey1 = (const Uint32*)&e1 + EntrySize;
- const Uint32* entrykey2 = (const Uint32*)&e2 + EntrySize;
- int ret = stat_cmpkey(a, entrykey1, e1.m_keylen, entrykey2, e2.m_keylen);
- assert(ret == -1);
- }
- }
-}
-#endif
-
-// compare keys
-int
-NdbIndexStat::stat_cmpkey(const Area& a, const Uint32* key1, Uint32 keylen1, const Uint32* key2, Uint32 keylen2)
-{
- const Uint32 idir = a.m_idir;
- const int jdir = 1 - 2 * int(idir);
- Uint32 i1 = 0, i2 = 0;
- Uint32 t1 = 4, t2 = 4; //BoundEQ
- int ret = 0;
- Uint32 k = 0;
- while (k < m_index.m_columns.size()) {
- NdbColumnImpl* c = m_index.m_columns[k];
- Uint32 n = c->m_attrSize * c->m_arraySize;
- // absence of keypart is treated specially
- bool havekp1 = (i1 + 2 <= keylen1);
- bool havekp2 = (i2 + 2 <= keylen2);
- AttributeHeader ah1;
- AttributeHeader ah2;
- if (havekp1) {
- t1 = key1[i1++];
- assert(t1 == 2 * idir || t1 == 2 * idir + 1 || t1 == 4);
- ah1 = *(const AttributeHeader*)&key1[i1++];
- }
- if (havekp2) {
- t2 = key2[i2++];
- assert(t2 == 2 * idir || t2 == 2 * idir + 1 || t2 == 4);
- ah2 = *(const AttributeHeader*)&key2[i2++];
- }
- if (havekp1) {
- if (havekp2) {
- if (! ah1.isNULL()) {
- if (! ah2.isNULL()) {
- const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(c->m_type);
- ret = (*sqlType.m_cmp)(c->m_cs, &key1[i1], n, &key2[i2], n, true);
- if (ret != 0)
- break;
- } else {
- ret = +1;
- break;
- }
- } else if (! ah2.isNULL()) {
- ret = -1;
- break;
- }
- } else {
- ret = +jdir;
- break;
- }
- } else {
- if (havekp2) {
- ret = -jdir;
- break;
- } else {
- // no more keyparts on either side
- break;
- }
- }
- i1 += ah1.getDataSize();
- i2 += ah2.getDataSize();
- k++;
- }
- if (ret == 0) {
- // strict bound is greater as start key and less as end key
- int s1 = t1 & 1;
- int s2 = t2 & 1;
- ret = (s1 - s2) * jdir;
- }
- return ret;
-}
-
-// find first key >= given key
-int
-NdbIndexStat::stat_search(const Area& a, const Uint32* key, Uint32 keylen, Uint32* idx, bool* match)
-{
- // points at minus/plus infinity
- int lo = -1;
- int hi = a.m_entries;
- // loop invariant: key(lo) < key < key(hi)
- while (hi - lo > 1) {
- // observe lo < j < hi
- int j = (hi + lo) / 2;
- Entry& e = a.get_entry(j);
- const Uint32* key2 = (Uint32*)&e + EntrySize;
- Uint32 keylen2 = e.m_keylen;
- int ret = stat_cmpkey(a, key, keylen, key2, keylen2);
- // observe the loop invariant if ret != 0
- if (ret < 0)
- hi = j;
- else if (ret > 0)
- lo = j;
- else {
- *idx = j;
- *match = true;
- return 0;
- }
- }
- // hi - lo == 1 and key(lo) < key < key(hi)
- *idx = hi;
- *match = false;
- return 0;
-}
-
-// find oldest entry
-int
-NdbIndexStat::stat_oldest(const Area& a)
-{
- Uint32 i, k= 0, m;
- bool found = false;
- m = ~(Uint32)0; // shut up incorrect CC warning
- for (i = 0; i < a.m_entries; i++) {
- Pointer& p = a.get_pointer(i);
- Uint32 m2 = m_seq >= p.m_seq ? m_seq - p.m_seq : p.m_seq - m_seq;
- if (! found || m < m2) {
- m = m2;
- k = i;
- found = true;
- }
- }
- assert(found);
- return k;
-}
-
-// delete entry
-int
-NdbIndexStat::stat_delete(Area& a, Uint32 k)
-{
- Uint32 i;
- NdbIndexStat::Entry& e = a.get_entry(k);
- Uint32 entrylen = EntrySize + e.m_keylen;
- Uint32 pos = a.get_pos(e);
- // adjust pointers to entries after
- for (i = 0; i < a.m_entries; i++) {
- Pointer& p = a.get_pointer(i);
- if (p.m_pos < pos) {
- p.m_pos += entrylen;
- }
- }
- // compact entry area
- unsigned firstpos = a.get_firstpos();
- for (i = pos; i > firstpos; i--) {
- a.m_data[i + entrylen - 1] = a.m_data[i - 1];
- }
- // compact pointer area
- for (i = k; i + 1 < a.m_entries; i++) {
- NdbIndexStat::Pointer& p = a.get_pointer(i);
- NdbIndexStat::Pointer& q = a.get_pointer(i + 1);
- p = q;
- }
- a.m_free += PointerSize + entrylen;
- a.m_entries--;
- stat_verify();
- return 0;
-}
-
-// update or insert stat values
-int
-NdbIndexStat::stat_update(const Uint32* key1, Uint32 keylen1, const Uint32* key2, Uint32 keylen2, const float pct[2])
-{
- const Uint32* const key[2] = { key1, key2 };
- const Uint32 keylen[2] = { keylen1, keylen2 };
- Uint32 idir;
- for (idir = 0; idir <= 1; idir++) {
- Area& a = m_area[idir];
- Uint32 k;
- bool match;
- stat_search(a, key[idir], keylen[idir], &k, &match);
- Uint16 seq = m_seq++;
- if (match) {
- // update old entry
- NdbIndexStat::Pointer& p = a.get_pointer(k);
- NdbIndexStat::Entry& e = a.get_entry(k);
- e.m_pct = pct[idir];
- p.m_seq = seq;
- } else {
- Uint32 entrylen = NdbIndexStat::EntrySize + keylen[idir];
- Uint32 need = NdbIndexStat::PointerSize + entrylen;
- while (need > a.m_free) {
- Uint32 j = stat_oldest(a);
- if (j < k)
- k--;
- stat_delete(a, j);
- }
- // insert pointer
- Uint32 i;
- for (i = a.m_entries; i > k; i--) {
- NdbIndexStat::Pointer& p1 = a.get_pointer(i);
- NdbIndexStat::Pointer& p2 = a.get_pointer(i - 1);
- p1 = p2;
- }
- NdbIndexStat::Pointer& p = a.get_pointer(k);
- // insert entry
- Uint32 firstpos = a.get_firstpos();
- p.m_pos = firstpos - entrylen;
- NdbIndexStat::Entry& e = a.get_entry(k);
- e.m_pct = pct[idir];
- e.m_keylen = keylen[idir];
- Uint32* entrykey = (Uint32*)&e + EntrySize;
- for (i = 0; i < keylen[idir]; i++) {
- entrykey[i] = key[idir][i];
- }
- p.m_seq = seq;
- // total
- a.m_free -= PointerSize + entrylen;
- a.m_entries++;
- }
- }
- stat_verify();
- return 0;
-}
-
-int
-NdbIndexStat::stat_select(const Uint32* key1, Uint32 keylen1, const Uint32* key2, Uint32 keylen2, float pct[2])
-{
- const Uint32* const key[2] = { key1, key2 };
- const Uint32 keylen[2] = { keylen1, keylen2 };
- Uint32 idir;
- for (idir = 0; idir <= 1; idir++) {
- Area& a = m_area[idir];
- Uint32 k;
- bool match;
- stat_search(a, key[idir], keylen[idir], &k, &match);
- if (match) {
- NdbIndexStat::Entry& e = a.get_entry(k);
- pct[idir] = e.m_pct;
- } else if (k == 0) {
- NdbIndexStat::Entry& e = a.get_entry(k);
- if (idir == 0)
- pct[idir] = e.m_pct / 2;
- else
- pct[idir] = e.m_pct + (1 - e.m_pct) / 2;
- } else if (k == a.m_entries) {
- NdbIndexStat::Entry& e = a.get_entry(k - 1);
- if (idir == 0)
- pct[idir] = e.m_pct + (1 - e.m_pct) / 2;
- else
- pct[idir] = e.m_pct / 2;
- } else {
- NdbIndexStat::Entry& e1 = a.get_entry(k - 1);
- NdbIndexStat::Entry& e2 = a.get_entry(k);
- pct[idir] = (e1.m_pct + e2.m_pct) / 2;
- }
- }
- return 0;
-}
-
-int
-NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOperation* op, Uint64 table_rows, Uint64* count, int flags)
-{
- DBUG_ENTER("NdbIndexStat::records_in_range");
- Uint64 rows;
- Uint32 key1[1000], keylen1;
- Uint32 key2[1000], keylen2;
-
- if (m_cache == NULL)
- flags |= RR_UseDb | RR_NoUpdate;
- else if (m_area[0].m_entries == 0 || m_area[1].m_entries == 0)
- flags |= RR_UseDb;
-
- if ((flags & (RR_UseDb | RR_NoUpdate)) != RR_UseDb | RR_NoUpdate) {
- // get start and end key - assume bound is ordered, wellformed
- Uint32 bound[1000];
- Uint32 boundlen = op->getKeyFromSCANTABREQ(bound, 1000);
-
- keylen1 = keylen2 = 0;
- Uint32 n = 0;
- while (n < boundlen) {
- Uint32 t = bound[n];
- AttributeHeader ah(bound[n + 1]);
- Uint32 sz = 2 + ah.getDataSize();
- t &= 0xFFFF; // may contain length
- assert(t <= 4);
- bound[n] = t;
- if (t == 0 || t == 1 || t == 4) {
- memcpy(&key1[keylen1], &bound[n], sz << 2);
- keylen1 += sz;
- }
- if (t == 2 || t == 3 || t == 4) {
- memcpy(&key2[keylen2], &bound[n], sz << 2);
- keylen2 += sz;
- }
- n += sz;
- }
- }
-
- if (flags & RR_UseDb) {
- Uint32 out[4] = { 0, 0, 0, 0 }; // rows, in, before, after
- float tot[4] = { 0, 0, 0, 0 }; // totals of above
- int cnt, ret;
- bool forceSend = true;
- NdbTransaction* trans = op->m_transConnection;
- if (op->interpret_exit_last_row() == -1 ||
- op->getValue(NdbDictionary::Column::RECORDS_IN_RANGE, (char*)out) == 0) {
- m_error = op->getNdbError();
- DBUG_PRINT("error", ("op:%d", op->getNdbError().code));
- DBUG_RETURN(-1);
- }
- if (trans->execute(NdbTransaction::NoCommit,
- NdbOperation::AbortOnError, forceSend) == -1) {
- m_error = trans->getNdbError();
- DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
- op->getNdbError().code));
- DBUG_RETURN(-1);
- }
- cnt = 0;
- while ((ret = op->nextResult(true, forceSend)) == 0) {
- DBUG_PRINT("info", ("frag rows=%u in=%u before=%u after=%u [error=%d]",
- out[0], out[1], out[2], out[3],
- (int)(out[1] + out[2] + out[3]) - (int)out[0]));
- unsigned i;
- for (i = 0; i < 4; i++)
- tot[i] += (float)out[i];
- cnt++;
- }
- if (ret == -1) {
- m_error = op->getNdbError();
- DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
- op->getNdbError().code));
- DBUG_RETURN(-1);
- }
- op->close(forceSend);
- rows = (Uint64)tot[1];
- if (cnt != 0 && ! (flags & RR_NoUpdate)) {
- float pct[2];
- pct[0] = 100 * tot[2] / tot[0];
- pct[1] = 100 * tot[3] / tot[0];
- DBUG_PRINT("info", ("update stat pct"
- " before=%.2f after=%.2f",
- pct[0], pct[1]));
- stat_update(key1, keylen1, key2, keylen2, pct);
- }
- } else {
- float pct[2];
- stat_select(key1, keylen1, key2, keylen2, pct);
- float diff = 100.0 - (pct[0] + pct[1]);
- float trows = (float)table_rows;
- DBUG_PRINT("info", ("select stat pct"
- " before=%.2f after=%.2f in=%.2f table_rows=%.2f",
- pct[0], pct[1], diff, trows));
- rows = 0;
- if (diff >= 0)
- rows = (Uint64)(diff * trows / 100);
- if (rows == 0)
- rows = 1;
- }
-
- *count = rows;
- DBUG_PRINT("value", ("rows=%llu flags=%o", rows, flags));
- DBUG_RETURN(0);
-}
-
-void
-NdbIndexStat::set_error(int code)
-{
- m_error.code = code;
-}
-
-const NdbError&
-NdbIndexStat::getNdbError() const
-{
- return m_error;
-}
diff --git a/storage/ndb/src/ndbapi/NdbLinHash.hpp b/storage/ndb/src/ndbapi/NdbLinHash.hpp
deleted file mode 100644
index e3db91de400..00000000000
--- a/storage/ndb/src/ndbapi/NdbLinHash.hpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NdbLinHash_H
-#define NdbLinHash_H
-
-#include <ndb_types.h>
-
-#define SEGMENTSIZE 64
-#define SEGMENTLOGSIZE 6
-#define DIRECTORYSIZE 64
-#define DIRINDEX(adress) ((adress) >> SEGMENTLOGSIZE)
-#define SEGINDEX(adress) ((adress) & (SEGMENTSIZE-1))
-
-#if !defined(MAXLOADFCTR)
-#define MAXLOADFCTR 2
-#endif
-#if !defined(MINLOADFCTR)
-#define MINLOADFCTR (MAXLOADFCTR/2)
-#endif
-
-template<class C>
-class NdbElement_t {
-public:
- NdbElement_t();
- ~NdbElement_t();
-
- Uint32 len;
- Uint32 hash;
- Uint32 localkey1;
- Uint32 *str;
- NdbElement_t<C> *next;
- C* theData;
-private:
- NdbElement_t(const NdbElement_t<C> & aElement_t);
- NdbElement_t & operator = (const NdbElement_t<C> & aElement_t);
-};
-
-
-template <class C>
-class NdbLinHash {
-public:
- NdbLinHash();
- ~NdbLinHash();
- void createHashTable(void);
- void releaseHashTable(void);
-
- int insertKey(const char * str, Uint32 len, Uint32 lkey1, C* data);
- C *deleteKey(const char * str, Uint32 len);
-
- C* getData(const char *, Uint32);
- Uint32* getKey(const char *, Uint32);
-
- void shrinkTable(void);
- void expandHashTable(void);
-
- Uint32 Hash(const char *str, Uint32 len);
- Uint32 Hash(Uint32 h);
-
- NdbElement_t<C> * getNext(NdbElement_t<C> * curr);
-
-private:
- void getBucket(Uint32 hash, int * dirindex, int * segindex);
-
- struct Segment_t {
- NdbElement_t<C> * elements[SEGMENTSIZE];
- };
-
- Uint32 p; /*bucket to be split*/
- Uint32 max; /*max is the upper bound*/
- Int32 slack; /*number of insertions before splits*/
- Segment_t * directory[DIRECTORYSIZE];
-
- NdbLinHash(const NdbLinHash<C> & aLinHash);
- NdbLinHash<C> & operator = (const NdbLinHash<C> & aLinHash);
-};
-
-// All template methods must be inline
-
-template <class C>
-inline
-NdbLinHash<C>::NdbLinHash() {
-}
-
-template <class C>
-inline
-NdbLinHash<C>::NdbLinHash(const NdbLinHash<C>& aLinHash)
-{
-}
-
-template <class C>
-inline
-NdbLinHash<C>::~NdbLinHash()
-{
-}
-
-template <class C>
-inline
-Uint32
-NdbLinHash<C>::Hash( const char* str, Uint32 len )
-{
- Uint32 h = 0;
- while(len >= 4){
- h = (h << 5) + h + str[0];
- h = (h << 5) + h + str[1];
- h = (h << 5) + h + str[2];
- h = (h << 5) + h + str[3];
- len -= 4;
- str += 4;
- }
-
- while(len > 0){
- h = (h << 5) + h + *str++;
- len--;
- }
- return h;
-}
-
-template <class C>
-inline
-Uint32
-NdbLinHash<C>::Hash( Uint32 h ){
- return h;
-}
-
-template <class C>
-inline
-NdbElement_t<C>::NdbElement_t() :
- len(0),
- hash(0),
- localkey1(0),
- str(NULL),
- next(NULL),
- theData(NULL)
-{
-}
-
-template <class C>
-inline
-NdbElement_t<C>::~NdbElement_t()
-{
- delete []str;
-}
-
-
-/* Initialize the hashtable HASH_T */
-template <class C>
-inline
-void
-NdbLinHash<C>::createHashTable() {
- p = 0;
- max = SEGMENTSIZE - 1;
- slack = SEGMENTSIZE * MAXLOADFCTR;
- directory[0] = new Segment_t();
- int i;
-
- /* The first segment cleared before used */
- for(i = 0; i < SEGMENTSIZE; i++ )
- directory[0]->elements[i] = 0;
-
- /* clear the rest of the directory */
- for(i = 1; i < DIRECTORYSIZE; i++)
- directory[i] = 0;
-}
-
-template <class C>
-inline
-void
-NdbLinHash<C>::getBucket(Uint32 hash, int * dir, int * seg){
- Uint32 adress = hash & max;
- if(adress < p)
- adress = hash & (2 * max + 1);
-
- * dir = DIRINDEX(adress);
- * seg = SEGINDEX(adress);
-}
-
-template <class C>
-inline
-Int32
-NdbLinHash<C>::insertKey( const char* str, Uint32 len, Uint32 lkey1, C* data )
-{
- const Uint32 hash = Hash(str, len);
- int dir, seg;
- getBucket(hash, &dir, &seg);
-
- NdbElement_t<C> **chainp = &directory[dir]->elements[seg];
-
- /**
- * Check if the string already are in the hash table
- * chain=chainp will copy the contents of HASH_T into chain
- */
- NdbElement_t<C> * oldChain = 0;
- NdbElement_t<C> * chain;
- for(chain = *chainp; chain != 0; chain = chain->next){
- if(chain->len == len && !memcmp(chain->str, str, len))
- return -1; /* Element already exists */
- else
- oldChain = chain;
- }
-
- /* New entry */
- chain = new NdbElement_t<C>();
- chain->len = len;
- chain->hash = hash;
- chain->localkey1 = lkey1;
- chain->next = 0;
- chain->theData = data;
- len++; // Null terminated
- chain->str = new Uint32[((len + 3) >> 2)];
- memcpy( &chain->str[0], str, len);
- if (oldChain != 0)
- oldChain->next = chain;
- else
- *chainp = chain;
-
-#if 0
- if(--(slack) < 0)
- expandHashTable();
-#endif
-
- return chain->localkey1;
-}
-
-
-template <class C>
-inline
-Uint32*
-NdbLinHash<C>::getKey( const char* str, Uint32 len )
-{
- const Uint32 tHash = Hash(str, len);
- int dir, seg;
- getBucket(tHash, &dir, &seg);
-
- NdbElement_t<C> ** keyp = &directory[dir]->elements[seg];
-
- /*Check if the string are in the hash table*/
- for(NdbElement_t<C> * key = *keyp; key != 0; key = key->next ) {
- if(key->len == len && !memcmp(key->str, str, len)) {
- return &key->localkey1;
- }
- }
- return NULL ; /* The key was not found */
-}
-
-template <class C>
-inline
-C*
-NdbLinHash<C>::getData( const char* str, Uint32 len ){
-
- const Uint32 tHash = Hash(str, len);
- int dir, seg;
- getBucket(tHash, &dir, &seg);
-
- NdbElement_t<C> ** keyp = &directory[dir]->elements[seg];
-
- /*Check if the string are in the hash table*/
- for(NdbElement_t<C> * key = *keyp; key != 0; key = key->next ) {
- if(key->len == len && !memcmp(key->str, str, len)) {
- return key->theData;
- }
- }
- return NULL ; /* The key was not found */
-}
-
-template <class C>
-inline
-C *
-NdbLinHash<C>::deleteKey ( const char* str, Uint32 len){
- const Uint32 hash = Hash(str, len);
- int dir, seg;
- getBucket(hash, &dir, &seg);
-
- NdbElement_t<C> *oldChain = 0;
- NdbElement_t<C> **chainp = &directory[dir]->elements[seg];
- for(NdbElement_t<C> * chain = *chainp; chain != 0; chain = chain->next){
- if(chain->len == len && !memcmp(chain->str, str, len)){
- C *data= chain->theData;
- if (oldChain == 0) {
- * chainp = chain->next;
- } else {
- oldChain->next = chain->next;
- }
- delete chain;
- return data;
- } else {
- oldChain = chain;
- }
- }
- return 0; /* Element doesn't exist */
-}
-
-template <class C>
-inline
-void
-NdbLinHash<C>::releaseHashTable( void ){
- NdbElement_t<C>* tNextElement;
- NdbElement_t<C>* tElement;
-
- //Traverse the whole directory structure
- for(int countd = 0; countd < DIRECTORYSIZE;countd++ ){
- if (directory[countd] != 0) {
- //Traverse whole hashtable
- for(int counts = 0; counts < SEGMENTSIZE; counts++ )
- if (directory[countd]->elements[counts] != 0) {
- tElement = directory[countd]->elements[counts];
- //Delete all elements even those who is linked
- do {
- tNextElement = tElement->next;
- delete tElement;
- tElement = tNextElement;
- } while (tNextElement != 0);
- }
- delete directory[countd];
- }
- }
-}
-
-template <class C>
-inline
-void
-NdbLinHash<C>::shrinkTable( void )
-{
- Segment_t *lastseg;
- NdbElement_t<C> **chainp;
- Uint32 oldlast = p + max;
-
- if( oldlast == 0 )
- return;
-
- // Adjust the state variables.
- if( p == 0 ) {
- max >>= 1;
- p = max;
- }
- else
- --(p);
-
- // Update slack after shrink.
-
- slack -= MAXLOADFCTR;
-
- // Insert the chain oldlast at the end of chain p.
-
- chainp = &directory[DIRINDEX(p)]->elements[SEGINDEX(p)];
- while( *chainp != 0 ) {
- chainp = &((*chainp)->next);
- lastseg = directory[DIRINDEX(oldlast)];
- *chainp = lastseg->elements[SEGINDEX(oldlast)];
-
- // If necessary free last segment.
- if( SEGINDEX(oldlast) == 0)
- delete lastseg;
- }
-}
-
-template <class C>
-inline
-void
-NdbLinHash<C>::expandHashTable( void )
-{
-
- NdbElement_t<C> **oldbucketp, *chain, *headofold, *headofnew, *next;
- Uint32 maxp = max + 1;
- Uint32 newadress = maxp + p;
-
-
- // Still room in the adress space?
- if( newadress >= DIRECTORYSIZE * SEGMENTSIZE ) {
- return;
- }
-
- // If necessary, create a new segment.
- if( SEGINDEX(newadress) == 0 )
- directory[DIRINDEX(newadress)] = new Segment_t();
-
- // Locate the old (to be split) bucket.
- oldbucketp = &directory[DIRINDEX(p)]->elements[SEGINDEX(p)];
-
- // Adjust the state variables.
- p++;
- if( p > max ) {
- max = 2 *max + 1;
- p = 0;
- }
-
- // Update slack after expandation.
- slack += MAXLOADFCTR;
-
- // Relocate records to the new bucket.
- headofold = 0;
- headofnew = 0;
-
- for( chain = *oldbucketp; chain != 0; chain = next ) {
- next = chain->next;
- if( chain->hash & maxp ) {
- chain->next = headofnew;
- headofnew = chain;
- }
- else {
- chain->next = headofold;
- headofold = chain;
- }
- }
- *oldbucketp = headofold;
- directory[DIRINDEX(newadress)]->elements[SEGINDEX(newadress)] = headofnew;
-}
-
-template <class C>
-inline
-NdbElement_t<C> *
-NdbLinHash<C>::getNext(NdbElement_t<C> * curr){
- if(curr != 0 && curr->next != 0)
- return curr->next;
-
- int dir = 0, seg = 0;
- int counts;
- if(curr != 0)
- {
- getBucket(curr->hash, &dir, &seg);
- counts = seg + 1;
- }
- else
- {
- counts = 0;
- }
-
- for(int countd = dir; countd < DIRECTORYSIZE;countd++ ){
- if (directory[countd] != 0) {
- for(; counts < SEGMENTSIZE; counts++ ){
- if (directory[countd]->elements[counts] != 0) {
- return directory[countd]->elements[counts];
- }
- }
- }
- counts = 0;
- }
-
- return 0;
-}
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbOperation.cpp b/storage/ndb/src/ndbapi/NdbOperation.cpp
deleted file mode 100644
index 521f393e525..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperation.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbTransaction.hpp>
-#include <NdbOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include "NdbRecAttr.hpp"
-#include "NdbUtil.hpp"
-#include "NdbBlob.hpp"
-#include "ndbapi_limits.h"
-#include <signaldata/TcKeyReq.hpp>
-#include "NdbDictionaryImpl.hpp"
-
-#include "API.hpp"
-#include <NdbOut.hpp>
-
-
-/******************************************************************************
- * NdbOperation(Ndb* aNdb, Table* aTable);
- *
- * Return Value: None
- * Parameters: aNdb: Pointers to the Ndb object.
- * aTable: Pointers to the Table object
- * Remark: Creat an object of NdbOperation.
- ****************************************************************************/
-NdbOperation::NdbOperation(Ndb* aNdb, NdbOperation::Type aType) :
- m_type(aType),
- theReceiver(aNdb),
- theErrorLine(0),
- theNdb(aNdb),
- //theTable(aTable),
- theNdbCon(NULL),
- theNext(NULL),
- theTCREQ(NULL),
- theFirstATTRINFO(NULL),
- theCurrentATTRINFO(NULL),
- theTotalCurrAI_Len(0),
- theAI_LenInCurrAI(0),
- theLastKEYINFO(NULL),
-
- theFirstLabel(NULL),
- theLastLabel(NULL),
- theFirstBranch(NULL),
- theLastBranch(NULL),
- theFirstCall(NULL),
- theLastCall(NULL),
- theFirstSubroutine(NULL),
- theLastSubroutine(NULL),
- theNoOfLabels(0),
- theNoOfSubroutines(0),
-
- m_currentTable(NULL), //theTableId(0xFFFF),
- m_accessTable(NULL), //theAccessTableId(0xFFFF),
- //theSchemaVersion(0),
- theTotalNrOfKeyWordInSignal(8),
- theTupKeyLen(0),
- theNoOfTupKeyLeft(0),
- theOperationType(NotDefined),
- theStatus(Init),
- theMagicNumber(0xFE11D0),
- theScanInfo(0),
- m_tcReqGSN(GSN_TCKEYREQ),
- m_keyInfoGSN(GSN_KEYINFO),
- m_attrInfoGSN(GSN_ATTRINFO),
- theBlobList(NULL),
- m_abortOption(-1),
- m_noErrorPropagation(false)
-{
- theReceiver.init(NdbReceiver::NDB_OPERATION, this);
- theError.code = 0;
-}
-/*****************************************************************************
- * ~NdbOperation();
- *
- * Remark: Delete tables for connection pointers (id).
- *****************************************************************************/
-NdbOperation::~NdbOperation( )
-{
-}
-/******************************************************************************
- *void setErrorCode(int anErrorCode);
- *
- * Remark: Set an Error Code on operation and
- * on connection set an error status.
- *****************************************************************************/
-void
-NdbOperation::setErrorCode(int anErrorCode)
-{
- theError.code = anErrorCode;
- theNdbCon->theErrorLine = theErrorLine;
- theNdbCon->theErrorOperation = this;
- if (!(m_abortOption == AO_IgnoreError && m_noErrorPropagation))
- theNdbCon->setOperationErrorCode(anErrorCode);
-}
-
-/******************************************************************************
- * void setErrorCodeAbort(int anErrorCode);
- *
- * Remark: Set an Error Code on operation and on connection set
- * an error status.
- *****************************************************************************/
-void
-NdbOperation::setErrorCodeAbort(int anErrorCode)
-{
- theError.code = anErrorCode;
- theNdbCon->theErrorLine = theErrorLine;
- theNdbCon->theErrorOperation = this;
- // ignore m_noErrorPropagation
- theNdbCon->setOperationErrorCodeAbort(anErrorCode);
-}
-
-/*****************************************************************************
- * int init();
- *
- * Return Value: Return 0 : init was successful.
- * Return -1: In all other case.
- * Remark: Initiates operation record after allocation.
- *****************************************************************************/
-
-int
-NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){
- NdbApiSignal* tSignal;
- theStatus = Init;
- theError.code = 0;
- theErrorLine = 1;
- m_currentTable = m_accessTable = tab;
-
- 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] = 0;
-
- theFirstATTRINFO = NULL;
- theCurrentATTRINFO = NULL;
- theLastKEYINFO = NULL;
-
-
- theTupKeyLen = 0;
- theNoOfTupKeyLeft = tab->getNoOfPrimaryKeys();
-
- theTotalCurrAI_Len = 0;
- theAI_LenInCurrAI = 0;
- theStartIndicator = 0;
- theCommitIndicator = 0;
- theSimpleIndicator = 0;
- theDirtyIndicator = 0;
- theInterpretIndicator = 0;
- theDistrKeyIndicator_ = 0;
- theScanInfo = 0;
- theTotalNrOfKeyWordInSignal = 8;
- theMagicNumber = 0xABCDEF01;
- theBlobList = NULL;
- m_abortOption = -1;
- m_noErrorPropagation = false;
- m_no_disk_flag = 1;
-
- tSignal = theNdb->getSignal();
- if (tSignal == NULL)
- {
- setErrorCode(4000);
- return -1;
- }
- theTCREQ = tSignal;
- theTCREQ->setSignal(m_tcReqGSN);
-
- theAI_LenInCurrAI = 20;
- TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
- tcKeyReq->scanInfo = 0;
- theKEYINFOptr = &tcKeyReq->keyInfo[0];
- theATTRINFOptr = &tcKeyReq->attrInfo[0];
- if (theReceiver.init(NdbReceiver::NDB_OPERATION, this))
- {
- // theReceiver sets the error code of its owner
- return -1;
- }
- return 0;
-}
-
-
-/******************************************************************************
- * void release();
- *
- * Remark: Release all objects connected to the operation object.
- *****************************************************************************/
-void
-NdbOperation::release()
-{
- NdbApiSignal* tSignal;
- NdbApiSignal* tSaveSignal;
- NdbBranch* tBranch;
- NdbBranch* tSaveBranch;
- NdbLabel* tLabel;
- NdbLabel* tSaveLabel;
- NdbCall* tCall;
- NdbCall* tSaveCall;
- NdbSubroutine* tSubroutine;
- NdbSubroutine* tSaveSubroutine;
- NdbBlob* tBlob;
- NdbBlob* tSaveBlob;
-
- tSignal = theTCREQ;
- while (tSignal != NULL)
- {
- tSaveSignal = tSignal;
- tSignal = tSignal->next();
- theNdb->releaseSignal(tSaveSignal);
- }
- theTCREQ = NULL;
- theLastKEYINFO = NULL;
-
- tSignal = theFirstATTRINFO;
- while (tSignal != NULL)
- {
- tSaveSignal = tSignal;
- tSignal = tSignal->next();
- theNdb->releaseSignal(tSaveSignal);
- }
- theFirstATTRINFO = NULL;
- theCurrentATTRINFO = NULL;
-
- if (theInterpretIndicator == 1)
- {
- tBranch = theFirstBranch;
- while (tBranch != NULL)
- {
- tSaveBranch = tBranch;
- tBranch = tBranch->theNext;
- theNdb->releaseNdbBranch(tSaveBranch);
- }
- tLabel = theFirstLabel;
- while (tLabel != NULL)
- {
- tSaveLabel = tLabel;
- tLabel = tLabel->theNext;
- theNdb->releaseNdbLabel(tSaveLabel);
- }
- tCall = theFirstCall;
- while (tCall != NULL)
- {
- tSaveCall = tCall;
- tCall = tCall->theNext;
- theNdb->releaseNdbCall(tSaveCall);
- }
- tSubroutine = theFirstSubroutine;
- while (tSubroutine != NULL)
- {
- tSaveSubroutine = tSubroutine;
- tSubroutine = tSubroutine->theNext;
- theNdb->releaseNdbSubroutine(tSaveSubroutine);
- }
- }
- tBlob = theBlobList;
- while (tBlob != NULL)
- {
- tSaveBlob = tBlob;
- tBlob = tBlob->theNext;
- theNdb->releaseNdbBlob(tSaveBlob);
- }
- theBlobList = NULL;
- theReceiver.release();
-}
-
-NdbRecAttr*
-NdbOperation::getValue(const char* anAttrName, char* aValue)
-{
- return getValue_impl(m_currentTable->getColumn(anAttrName), aValue);
-}
-
-NdbRecAttr*
-NdbOperation::getValue(Uint32 anAttrId, char* aValue)
-{
- return getValue_impl(m_currentTable->getColumn(anAttrId), aValue);
-}
-
-NdbRecAttr*
-NdbOperation::getValue(const NdbDictionary::Column* col, char* aValue)
-{
- return getValue_impl(&NdbColumnImpl::getImpl(*col), aValue);
-}
-
-int
-NdbOperation::equal(const char* anAttrName, const char* aValuePassed)
-{
- return equal_impl(m_accessTable->getColumn(anAttrName), aValuePassed);
-}
-
-int
-NdbOperation::equal(Uint32 anAttrId, const char* aValuePassed)
-{
- return equal_impl(m_accessTable->getColumn(anAttrId), aValuePassed);
-}
-
-int
-NdbOperation::setValue(const char* anAttrName, const char* aValuePassed)
-{
- return setValue(m_currentTable->getColumn(anAttrName), aValuePassed);
-}
-
-
-int
-NdbOperation::setValue(Uint32 anAttrId, const char* aValuePassed)
-{
- return setValue(m_currentTable->getColumn(anAttrId), aValuePassed);
-}
-
-NdbBlob*
-NdbOperation::getBlobHandle(const char* anAttrName)
-{
- const NdbColumnImpl* col = m_currentTable->getColumn(anAttrName);
- if (col == NULL)
- {
- setErrorCode(4004);
- return NULL;
- }
- else
- {
- return getBlobHandle(theNdbCon, col);
- }
-}
-
-NdbBlob*
-NdbOperation::getBlobHandle(Uint32 anAttrId)
-{
- const NdbColumnImpl* col = m_currentTable->getColumn(anAttrId);
- if (col == NULL)
- {
- setErrorCode(4004);
- return NULL;
- }
- else
- {
- return getBlobHandle(theNdbCon, col);
- }
-}
-
-int
-NdbOperation::incValue(const char* anAttrName, Uint32 aValue)
-{
- return incValue(m_currentTable->getColumn(anAttrName), aValue);
-}
-
-int
-NdbOperation::incValue(const char* anAttrName, Uint64 aValue)
-{
- return incValue(m_currentTable->getColumn(anAttrName), aValue);
-}
-
-int
-NdbOperation::incValue(Uint32 anAttrId, Uint32 aValue)
-{
- return incValue(m_currentTable->getColumn(anAttrId), aValue);
-}
-
-int
-NdbOperation::incValue(Uint32 anAttrId, Uint64 aValue)
-{
- return incValue(m_currentTable->getColumn(anAttrId), aValue);
-}
-
-int
-NdbOperation::subValue( const char* anAttrName, Uint32 aValue)
-{
- return subValue(m_currentTable->getColumn(anAttrName), aValue);
-}
-
-int
-NdbOperation::subValue( const char* anAttrName, Uint64 aValue)
-{
- return subValue(m_currentTable->getColumn(anAttrName), aValue);
-}
-
-int
-NdbOperation::subValue(Uint32 anAttrId, Uint32 aValue)
-{
- return subValue(m_currentTable->getColumn(anAttrId), aValue);
-}
-
-int
-NdbOperation::subValue(Uint32 anAttrId, Uint64 aValue)
-{
- return subValue(m_currentTable->getColumn(anAttrId), aValue);
-}
-
-int
-NdbOperation::read_attr(const char* anAttrName, Uint32 RegDest)
-{
- return read_attr(m_currentTable->getColumn(anAttrName), RegDest);
-}
-
-int
-NdbOperation::read_attr(Uint32 anAttrId, Uint32 RegDest)
-{
- return read_attr(m_currentTable->getColumn(anAttrId), RegDest);
-}
-
-int
-NdbOperation::write_attr(const char* anAttrName, Uint32 RegDest)
-{
- return write_attr(m_currentTable->getColumn(anAttrName), RegDest);
-}
-
-int
-NdbOperation::write_attr(Uint32 anAttrId, Uint32 RegDest)
-{
- return write_attr(m_currentTable->getColumn(anAttrId), RegDest);
-}
-
-const char*
-NdbOperation::getTableName() const
-{
- return m_currentTable->m_externalName.c_str();
-}
-
-const NdbDictionary::Table*
-NdbOperation::getTable() const
-{
- return m_currentTable;
-}
-
-NdbTransaction*
-NdbOperation::getNdbTransaction()
-{
- return theNdbCon;
-}
diff --git a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp
deleted file mode 100644
index b70d66260b0..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp
+++ /dev/null
@@ -1,795 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbTransaction.hpp>
-#include <Ndb.hpp>
-#include <NdbRecAttr.hpp>
-#include "NdbUtil.hpp"
-#include "NdbOut.hpp"
-#include "NdbImpl.hpp"
-#include <NdbIndexScanOperation.hpp>
-#include <NdbBlob.hpp>
-
-#include <Interpreter.hpp>
-
-#include <AttributeHeader.hpp>
-#include <signaldata/TcKeyReq.hpp>
-
-/*****************************************************************************
- * int insertTuple();
- *****************************************************************************/
-int
-NdbOperation::insertTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- theOperationType = InsertRequest;
- tNdbCon->theSimpleState = 0;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Exclusive;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::insertTuple()
-/******************************************************************************
- * int updateTuple();
- *****************************************************************************/
-int
-NdbOperation::updateTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = UpdateRequest;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Exclusive;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::updateTuple()
-/*****************************************************************************
- * int writeTuple();
- *****************************************************************************/
-int
-NdbOperation::writeTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = WriteRequest;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Exclusive;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::writeTuple()
-/*****************************************************************************
- * int deleteTuple();
- *****************************************************************************/
-int
-NdbOperation::deleteTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = DeleteRequest;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Exclusive;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::deleteTuple()
-
-/******************************************************************************
- * int readTuple();
- *****************************************************************************/
-int
-NdbOperation::readTuple(NdbOperation::LockMode lm)
-{
- switch(lm) {
- case LM_Read:
- return readTuple();
- break;
- case LM_Exclusive:
- return readTupleExclusive();
- break;
- case LM_CommittedRead:
- return committedRead();
- break;
- case LM_SimpleRead:
- return simpleRead();
- default:
- return -1;
- };
-}
-/******************************************************************************
- * int readTuple();
- *****************************************************************************/
-int
-NdbOperation::readTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = ReadRequest;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Read;
- m_abortOption = AO_IgnoreError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::readTuple()
-
-/******************************************************************************
- * int readTupleExclusive();
- *****************************************************************************/
-int
-NdbOperation::readTupleExclusive()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = ReadExclusive;
- theErrorLine = tErrorLine++;
- theLockMode = LM_Exclusive;
- m_abortOption = AO_IgnoreError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::readTupleExclusive()
-
-/*****************************************************************************
- * int simpleRead();
- *****************************************************************************/
-int
-NdbOperation::simpleRead()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- theOperationType = ReadRequest;
- theSimpleIndicator = 1;
- theDirtyIndicator = 0;
- theErrorLine = tErrorLine++;
- theLockMode = LM_SimpleRead;
- m_abortOption = AO_IgnoreError;
- tNdbCon->theSimpleState = 0;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::simpleRead()
-
-/*****************************************************************************
- * int dirtyRead();
- *****************************************************************************/
-int
-NdbOperation::dirtyRead()
-{
- return committedRead();
-}//NdbOperation::dirtyRead()
-
-/*****************************************************************************
- * int committedRead();
- *****************************************************************************/
-int
-NdbOperation::committedRead()
-{
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- theOperationType = ReadRequest;
- theSimpleIndicator = 1;
- theDirtyIndicator = 1;
- theErrorLine = tErrorLine++;
- theLockMode = LM_CommittedRead;
- m_abortOption = AO_IgnoreError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::committedRead()
-
-/*****************************************************************************
- * int dirtyUpdate();
- ****************************************************************************/
-int
-NdbOperation::dirtyUpdate()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- theOperationType = UpdateRequest;
- tNdbCon->theSimpleState = 0;
- theSimpleIndicator = 1;
- theDirtyIndicator = 1;
- theErrorLine = tErrorLine++;
- theLockMode = LM_CommittedRead;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::dirtyUpdate()
-
-/******************************************************************************
- * int dirtyWrite();
- *****************************************************************************/
-int
-NdbOperation::dirtyWrite()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- theOperationType = WriteRequest;
- tNdbCon->theSimpleState = 0;
- theSimpleIndicator = 1;
- theDirtyIndicator = 1;
- theErrorLine = tErrorLine++;
- theLockMode = LM_CommittedRead;
- m_abortOption = AbortOnError;
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::dirtyWrite()
-
-/******************************************************************************
- * int interpretedUpdateTuple();
- ****************************************************************************/
-int
-NdbOperation::interpretedUpdateTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = UpdateRequest;
- theAI_LenInCurrAI = 25;
- theLockMode = LM_Exclusive;
- theErrorLine = tErrorLine++;
- m_abortOption = AbortOnError;
- initInterpreter();
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::interpretedUpdateTuple()
-
-/*****************************************************************************
- * int interpretedDeleteTuple();
- *****************************************************************************/
-int
-NdbOperation::interpretedDeleteTuple()
-{
- NdbTransaction* tNdbCon = theNdbCon;
- int tErrorLine = theErrorLine;
- if (theStatus == Init) {
- theStatus = OperationDefined;
- tNdbCon->theSimpleState = 0;
- theOperationType = DeleteRequest;
-
- theErrorLine = tErrorLine++;
- theAI_LenInCurrAI = 25;
- theLockMode = LM_Exclusive;
- m_abortOption = AbortOnError;
- initInterpreter();
- return 0;
- } else {
- setErrorCode(4200);
- return -1;
- }//if
-}//NdbOperation::interpretedDeleteTuple()
-
-void
-NdbOperation::setReadLockMode(LockMode lockMode)
-{
- /* We only support changing lock mode for read operations at this time. */
- assert(theOperationType == ReadRequest || theOperationType == ReadExclusive);
- switch (lockMode) {
- case LM_CommittedRead: /* TODO, check theNdbCon->theSimpleState */
- theOperationType= ReadRequest;
- theSimpleIndicator= 1;
- theDirtyIndicator= 1;
- break;
- case LM_SimpleRead: /* TODO, check theNdbCon->theSimpleState */
- theOperationType= ReadRequest;
- theSimpleIndicator= 1;
- theDirtyIndicator= 0;
- break;
- case LM_Read:
- theNdbCon->theSimpleState= 0;
- theOperationType= ReadRequest;
- theSimpleIndicator= 0;
- theDirtyIndicator= 0;
- break;
- case LM_Exclusive:
- theNdbCon->theSimpleState= 0;
- theOperationType= ReadExclusive;
- theSimpleIndicator= 0;
- theDirtyIndicator= 0;
- break;
- default:
- /* Not supported / invalid. */
- assert(false);
- }
- theLockMode= lockMode;
-}
-
-
-/******************************************************************************
- * int getValue(AttrInfo* tAttrInfo, char* aRef )
- *
- * Return Value Return 0 : GetValue was successful.
- * Return -1: In all other case.
- * Parameters: tAttrInfo : Attribute object of the retrieved attribute
- * value.
- * Remark: Define an attribute to retrieve in query.
- *****************************************************************************/
-NdbRecAttr*
-NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue)
-{
- NdbRecAttr* tRecAttr;
- if ((tAttrInfo != NULL) &&
- (theStatus != Init)){
- m_no_disk_flag &= (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
- if (theStatus != GetValue) {
- if (theInterpretIndicator == 1) {
- if (theStatus == FinalGetValue) {
- ; // Simply continue with getValue
- } else if (theStatus == ExecInterpretedValue) {
- if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
- return NULL;
- theInterpretedSize = theTotalCurrAI_Len -
- (theInitialReadSize + 5);
- } else if (theStatus == SetValueInterpreted) {
- theFinalUpdateSize = theTotalCurrAI_Len -
- (theInitialReadSize + theInterpretedSize + 5);
- } else {
- setErrorCodeAbort(4230);
- return NULL;
- }//if
- // MASV - How would execution come here?
- theStatus = FinalGetValue;
- } else {
- setErrorCodeAbort(4230);
- return NULL;
- }//if
- }//if
- AttributeHeader ah(tAttrInfo->m_attrId, 0);
- if (insertATTRINFO(ah.m_value) != -1) {
- // Insert Attribute Id into ATTRINFO part.
-
- /************************************************************************
- * 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;
- }
- } else {
- return NULL;
- }//if insertATTRINFO failure
- } else {
- if (tAttrInfo == NULL) {
- setErrorCodeAbort(4004);
- return NULL;
- }//if
- }//if
- setErrorCodeAbort(4200);
- return NULL;
-}
-
-/*****************************************************************************
- * int setValue(AttrInfo* tAttrInfo, char* aValue, Uint32 len)
- *
- * Return Value: Return 0 : SetValue was succesful.
- * Return -1: In all other case.
- * Parameters: tAttrInfo : Attribute object where the attribute
- * info exists.
- * aValue : Reference to the variable with the new value.
- * len : Length of the value
- * Remark: Define a attribute to set in a query.
-******************************************************************************/
-int
-NdbOperation::setValue( const NdbColumnImpl* tAttrInfo,
- const char* aValuePassed)
-{
- DBUG_ENTER("NdbOperation::setValue");
- DBUG_PRINT("enter", ("col: %s op:%d val: 0x%lx",
- tAttrInfo->m_name.c_str(), theOperationType,
- (long) aValuePassed));
-
- int tReturnCode;
- Uint32 tAttrId;
- Uint32 tData;
- Uint32 tempData[2000];
- OperationType tOpType = theOperationType;
- OperationStatus tStatus = theStatus;
-
-
- if ((tOpType == UpdateRequest) ||
- (tOpType == WriteRequest)) {
- if (theInterpretIndicator == 0) {
- if (tStatus == SetValue) {
- ;
- } else {
- setErrorCodeAbort(4234);
- DBUG_RETURN(-1);
- }//if
- } else {
- if (tStatus == GetValue) {
- theInitialReadSize = theTotalCurrAI_Len - 5;
- } else if (tStatus == ExecInterpretedValue) {
- //--------------------------------------------------------------------
- // We insert an exit from interpretation since we are now starting
- // to set values in the tuple by setValue.
- //--------------------------------------------------------------------
- if (insertATTRINFO(Interpreter::EXIT_OK) == -1){
- DBUG_RETURN(-1);
- }
- theInterpretedSize = theTotalCurrAI_Len -
- (theInitialReadSize + 5);
- } else if (tStatus == SetValueInterpreted) {
- ; // Simply continue adding new setValue
- } else {
- //--------------------------------------------------------------------
- // setValue used in the wrong context. Application coding error.
- //-------------------------------------------------------------------
- setErrorCodeAbort(4234); //Wrong error code
- DBUG_RETURN(-1);
- }//if
- theStatus = SetValueInterpreted;
- }//if
- } else if (tOpType == InsertRequest) {
- if ((theStatus != SetValue) && (theStatus != OperationDefined)) {
- setErrorCodeAbort(4234);
- DBUG_RETURN(-1);
- }//if
- } else if (tOpType == ReadRequest || tOpType == ReadExclusive) {
- setErrorCodeAbort(4504);
- DBUG_RETURN(-1);
- } else if (tOpType == DeleteRequest) {
- setErrorCodeAbort(4504);
- DBUG_RETURN(-1);
- } else if (tOpType == OpenScanRequest || tOpType == OpenRangeScanRequest) {
- setErrorCodeAbort(4228);
- DBUG_RETURN(-1);
- } else {
- //---------------------------------------------------------------------
- // setValue with undefined operation type.
- // Probably application coding error.
- //---------------------------------------------------------------------
- setErrorCodeAbort(4108);
- DBUG_RETURN(-1);
- }//if
- if (tAttrInfo == NULL) {
- setErrorCodeAbort(4004);
- DBUG_RETURN(-1);
- }//if
- if (tAttrInfo->m_pk) {
- if (theOperationType == InsertRequest) {
- DBUG_RETURN(equal_impl(tAttrInfo, aValuePassed));
- } else {
- setErrorCodeAbort(4202);
- DBUG_RETURN(-1);
- }//if
- }//if
-
- // Insert Attribute Id into ATTRINFO part.
- tAttrId = tAttrInfo->m_attrId;
- m_no_disk_flag &= (tAttrInfo->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
- const char *aValue = aValuePassed;
- if (aValue == NULL) {
- if (tAttrInfo->m_nullable) {
- AttributeHeader ah(tAttrId, 0);
- ah.setNULL();
- insertATTRINFO(ah.m_value);
- // Insert Attribute Id with the value
- // NULL into ATTRINFO part.
- DBUG_RETURN(0);
- } else {
- /***********************************************************************
- * Setting a NULL value on a NOT NULL attribute is not allowed.
- **********************************************************************/
- setErrorCodeAbort(4203);
- DBUG_RETURN(-1);
- }//if
- }//if
-
- Uint32 len;
- if (! tAttrInfo->get_var_length(aValue, len)) {
- setErrorCodeAbort(4209);
- DBUG_RETURN(-1);
- }
-
- const Uint32 sizeInBytes = len;
- const Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ;
-
- const int attributeSize = sizeInBytes;
- const int slack = sizeInBytes & 3;
-
- if (((UintPtr)aValue & 3) != 0 || (slack != 0)){
- memcpy(&tempData[0], aValue, attributeSize);
- aValue = (char*)&tempData[0];
- if(slack != 0) {
- char * tmp = (char*)&tempData[0];
- memset(&tmp[attributeSize], 0, (4 - slack));
- }//if
- }//if
-
- // Excluding bits in last word
- const Uint32 sizeInWords = sizeInBytes / 4;
- AttributeHeader ah(tAttrId, sizeInBytes);
- insertATTRINFO( ah.m_value );
-
- /***********************************************************************
- * Check if the pointer of the value passed is aligned on a 4 byte boundary.
- * If so only assign the pointer to the internal variable aValue.
- * If it is not aligned then we start by copying the value to tempData and
- * use this as aValue instead.
- *************************************************************************/
-
- tReturnCode = insertATTRINFOloop((Uint32*)aValue, sizeInWords);
- if (tReturnCode == -1) {
- DBUG_RETURN(tReturnCode);
- }//if
- if (bitsInLastWord != 0) {
- tData = *(Uint32*)(aValue + sizeInWords*4);
- tData = convertEndian(tData);
- tData = tData & ((1 << bitsInLastWord) - 1);
- tData = convertEndian(tData);
- tReturnCode = insertATTRINFO(tData);
- if (tReturnCode == -1) {
- DBUG_RETURN(tReturnCode);
- }//if
- }//if
- theErrorLine++;
- DBUG_RETURN(0);
-}//NdbOperation::setValue()
-
-
-int
-NdbOperation::setAnyValue(Uint32 any_value)
-{
- const NdbColumnImpl* impl =
- &NdbColumnImpl::getImpl(* NdbDictionary::Column::ANY_VALUE);
- OperationType tOpType = theOperationType;
-
- switch(tOpType){
- case DeleteRequest:{
- Uint32 ah;
- AttributeHeader::init(&ah, AttributeHeader::ANY_VALUE, 4);
- if (insertATTRINFO(ah) != -1 && insertATTRINFO(any_value) != -1 )
- {
- return 0;
- }
- }
- default:
- return setValue(impl, (const char *)&any_value);
- }
-
- setErrorCodeAbort(4000);
- return -1;
-}
-
-
-NdbBlob*
-NdbOperation::getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* tAttrInfo)
-{
- NdbBlob* tBlob = theBlobList;
- NdbBlob* tLastBlob = NULL;
- while (tBlob != NULL) {
- if (tBlob->theColumn == tAttrInfo)
- return tBlob;
- tLastBlob = tBlob;
- tBlob = tBlob->theNext;
- }
- tBlob = theNdb->getNdbBlob();
- if (tBlob == NULL)
- return NULL;
- if (tBlob->atPrepare(aCon, this, tAttrInfo) == -1) {
- theNdb->releaseNdbBlob(tBlob);
- return NULL;
- }
- if (tLastBlob == NULL)
- theBlobList = tBlob;
- else
- tLastBlob->theNext = tBlob;
- tBlob->theNext = NULL;
- theNdbCon->theBlobFlag = true;
- return tBlob;
-}
-
-/****************************************************************************
- * int insertATTRINFO( Uint32 aData );
- *
- * Return Value: Return 0 : insertATTRINFO was succesful.
- * Return -1: In all other case.
- * Parameters: aData: the data to insert into ATTRINFO.
- * Remark: Puts the the data into either TCKEYREQ signal or
- * ATTRINFO signal.
- *****************************************************************************/
-int
-NdbOperation::insertATTRINFO( Uint32 aData )
-{
- NdbApiSignal* tSignal;
- register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
- register Uint32* tAttrPtr = theATTRINFOptr;
- register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
-
- if (tAI_LenInCurrAI >= 25) {
- Ndb* tNdb = theNdb;
- NdbApiSignal* tFirstAttrinfo = theFirstATTRINFO;
- tAI_LenInCurrAI = 3;
- tSignal = tNdb->getSignal();
- if (tSignal != NULL) {
- tSignal->setSignal(m_attrInfoGSN);
- tAttrPtr = &tSignal->getDataPtrSend()[3];
- if (tFirstAttrinfo == NULL) {
- tSignal->next(NULL);
- theFirstATTRINFO = tSignal;
- theCurrentATTRINFO = tSignal;
- } else {
- NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
- tSignal->next(NULL);
- theCurrentATTRINFO = tSignal;
- tCurrentAttrinfoBeforeUpdate->next(tSignal);
- }//if
- } else {
- goto insertATTRINFO_error1;
- }//if
- }//if
- *tAttrPtr = aData;
- tAttrPtr++;
- tTotCurrAILen++;
- tAI_LenInCurrAI++;
- theTotalCurrAI_Len = tTotCurrAILen;
- theAI_LenInCurrAI = tAI_LenInCurrAI;
- theATTRINFOptr = tAttrPtr;
- return 0;
-
-insertATTRINFO_error1:
- setErrorCodeAbort(4000);
- return -1;
-
-}//NdbOperation::insertATTRINFO()
-
-/*****************************************************************************
- * int insertATTRINFOloop(Uint32* aDataPtr, Uint32 aLength );
- *
- * Return Value: Return 0 : insertATTRINFO was succesful.
- * Return -1: In all other case.
- * Parameters: aDataPtr: Pointer to the data to insert into ATTRINFO.
- * aLength: Length of data to be copied
- * Remark: Puts the the data into either TCKEYREQ signal or
- * ATTRINFO signal.
- *****************************************************************************/
-int
-NdbOperation::insertATTRINFOloop(register const Uint32* aDataPtr,
- register Uint32 aLength)
-{
- NdbApiSignal* tSignal;
- register Uint32 tAI_LenInCurrAI = theAI_LenInCurrAI;
- register Uint32 tTotCurrAILen = theTotalCurrAI_Len;
- register Uint32* tAttrPtr = theATTRINFOptr;
- Ndb* tNdb = theNdb;
-
- while (aLength > 0) {
- if (tAI_LenInCurrAI >= 25) {
- NdbApiSignal* tFirstAttrinfo = theFirstATTRINFO;
- tAI_LenInCurrAI = 3;
- tSignal = tNdb->getSignal();
- if (tSignal != NULL) {
- tSignal->setSignal(m_attrInfoGSN);
- tAttrPtr = &tSignal->getDataPtrSend()[3];
- if (tFirstAttrinfo == NULL) {
- tSignal->next(NULL);
- theFirstATTRINFO = tSignal;
- theCurrentATTRINFO = tSignal;
- } else {
- NdbApiSignal* tCurrentAttrinfoBeforeUpdate = theCurrentATTRINFO;
- tSignal->next(NULL);
- theCurrentATTRINFO = tSignal;
- tCurrentAttrinfoBeforeUpdate->next(tSignal);
- }//if
- } else {
- goto insertATTRINFO_error1;
- }//if
- }//if
- {
- register Uint32 tData = *aDataPtr;
- aDataPtr++;
- aLength--;
- tAI_LenInCurrAI++;
- *tAttrPtr = tData;
- tAttrPtr++;
- tTotCurrAILen++;
- }
- }//while
- theATTRINFOptr = tAttrPtr;
- theTotalCurrAI_Len = tTotCurrAILen;
- theAI_LenInCurrAI = tAI_LenInCurrAI;
- return 0;
-
-insertATTRINFO_error1:
- setErrorCodeAbort(4000);
- return -1;
-
-}//NdbOperation::insertATTRINFOloop()
-
-NdbOperation::AbortOption
-NdbOperation::getAbortOption() const
-{
- return (AbortOption)m_abortOption;
-}
-
-int
-NdbOperation::setAbortOption(AbortOption ao)
-{
- switch(ao)
- {
- case AO_IgnoreError:
- case AbortOnError:
- m_abortOption= ao;
- return 0;
- default:
- return -1;
- }
-}
diff --git a/storage/ndb/src/ndbapi/NdbOperationExec.cpp b/storage/ndb/src/ndbapi/NdbOperationExec.cpp
deleted file mode 100644
index 113313a462b..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbOperation.hpp>
-#include <NdbTransaction.hpp>
-#include "NdbApiSignal.hpp"
-#include <Ndb.hpp>
-#include <NdbRecAttr.hpp>
-#include "NdbUtil.hpp"
-
-#include "Interpreter.hpp"
-#include <AttributeHeader.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/TcKeyRef.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/ScanTab.hpp>
-
-#include <ndb_version.h>
-
-#include "API.hpp"
-#include <NdbOut.hpp>
-
-
-
-void
-NdbOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag)
-{
- TcKeyReq * const req = CAST_PTR(TcKeyReq, signal->getDataPtrSend());
- TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);
-}
-
-/******************************************************************************
-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 TCKEYREQ signal and optional KEYINFO and ATTRINFO
- signals.
-******************************************************************************/
-int
-NdbOperation::doSend(int aNodeId, Uint32 lastFlag)
-{
- int tReturnCode;
- int tSignalCount = 0;
- assert(theTCREQ != NULL);
- setLastFlag(theTCREQ, lastFlag);
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
- tReturnCode = tp->sendSignal(theTCREQ, aNodeId);
- tSignalCount++;
- if (tReturnCode == -1) {
- return -1;
- }
- NdbApiSignal *tSignal = theTCREQ->next();
- while (tSignal != NULL) {
- NdbApiSignal* tnextSignal = tSignal->next();
- tReturnCode = tp->sendSignal(tSignal, aNodeId);
- tSignal = tnextSignal;
- if (tReturnCode == -1) {
- return -1;
- }
- tSignalCount++;
- }//while
- tSignal = theFirstATTRINFO;
- while (tSignal != NULL) {
- NdbApiSignal* tnextSignal = tSignal->next();
- tReturnCode = tp->sendSignal(tSignal, aNodeId);
- tSignal = tnextSignal;
- if (tReturnCode == -1) {
- return -1;
- }
- tSignalCount++;
- }//while
- theNdbCon->OpSent();
- return tSignalCount;
-}//NdbOperation::doSend()
-
-/***************************************************************************
-int prepareSend(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 data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.
-***************************************************************************/
-int
-NdbOperation::prepareSend(Uint32 aTC_ConnectPtr,
- Uint64 aTransId,
- AbortOption ao)
-{
- Uint32 tTransId1, tTransId2;
- Uint32 tReqInfo;
- Uint8 tInterpretInd = theInterpretIndicator;
- Uint8 tDirtyIndicator = theDirtyIndicator;
- Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
- theErrorLine = 0;
-
- if (tInterpretInd != 1) {
- OperationType tOpType = theOperationType;
- OperationStatus tStatus = theStatus;
- if ((tOpType == UpdateRequest) ||
- (tOpType == InsertRequest) ||
- (tOpType == WriteRequest)) {
- if (tStatus != SetValue) {
- setErrorCodeAbort(4116);
- return -1;
- }//if
- } else if ((tOpType == ReadRequest) || (tOpType == ReadExclusive) ||
- (tOpType == DeleteRequest)) {
- if (tStatus != GetValue) {
- setErrorCodeAbort(4116);
- return -1;
- }
- else if(unlikely(tDirtyIndicator && tTotalCurrAI_Len == 0))
- {
- getValue(NdbDictionary::Column::FRAGMENT);
- tTotalCurrAI_Len = theTotalCurrAI_Len;
- assert(theTotalCurrAI_Len);
- }
- } else {
- setErrorCodeAbort(4005);
- return -1;
- }//if
- } else {
- if (prepareSendInterpreted() == -1) {
- return -1;
- }//if
- tTotalCurrAI_Len = theTotalCurrAI_Len;
- }//if
-
-//-------------------------------------------------------------
-// We start by filling in the first 9 unconditional words of the
-// TCKEYREQ signal.
-//-------------------------------------------------------------
- TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
-
- Uint32 tTableId = m_accessTable->m_id;
- Uint32 tSchemaVersion = m_accessTable->m_version;
-
- tcKeyReq->apiConnectPtr = aTC_ConnectPtr;
- tcKeyReq->apiOperationPtr = ptr2int();
- // Check if too much attrinfo have been defined
- if (tTotalCurrAI_Len > TcKeyReq::MaxTotalAttrInfo){
- setErrorCodeAbort(4257);
- return -1;
- }
- Uint32 TattrLen = 0;
- tcKeyReq->setAttrinfoLen(TattrLen, tTotalCurrAI_Len);
- tcKeyReq->setAPIVersion(TattrLen, NDB_VERSION);
- tcKeyReq->attrLen = TattrLen;
-
- tcKeyReq->tableId = tTableId;
- tcKeyReq->tableSchemaVersion = tSchemaVersion;
- tTransId1 = (Uint32) aTransId;
- tTransId2 = (Uint32) (aTransId >> 32);
-
- Uint8 tSimpleIndicator = theSimpleIndicator;
- Uint8 tCommitIndicator = theCommitIndicator;
- Uint8 tStartIndicator = theStartIndicator;
- Uint8 tInterpretIndicator = theInterpretIndicator;
- Uint8 tNoDisk = m_no_disk_flag;
-
- /**
- * A dirty read, can not abort the transaction
- */
- Uint8 tReadInd = (theOperationType == ReadRequest);
- Uint8 tDirtyState = tReadInd & tDirtyIndicator;
-
- tcKeyReq->transId1 = tTransId1;
- tcKeyReq->transId2 = tTransId2;
-
- tReqInfo = 0;
- if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) {
- tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len);
- } else {
- tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo);
- }//if
-
- tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator);
- tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator);
- tcKeyReq->setStartFlag(tReqInfo, tStartIndicator);
- tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator);
- tcKeyReq->setNoDiskFlag(tReqInfo, tNoDisk);
-
- OperationType tOperationType = theOperationType;
- Uint32 tTupKeyLen = theTupKeyLen;
- Uint8 abortOption = (ao == DefaultAbortOption) ? (Uint8) m_abortOption : (Uint8) ao;
-
- tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
- tcKeyReq->setOperationType(tReqInfo, tOperationType);
- tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen);
-
- // A dirty read is always ignore error
- abortOption = tDirtyState ? (Uint8) AO_IgnoreError : (Uint8) abortOption;
- tcKeyReq->setAbortOption(tReqInfo, abortOption);
- m_abortOption = abortOption;
-
- Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
- Uint8 tScanIndicator = theScanInfo & 1;
-
- tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
- tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator);
-
- tcKeyReq->requestInfo = tReqInfo;
-
-//-------------------------------------------------------------
-// The next step is to fill in the upto three conditional words.
-//-------------------------------------------------------------
- Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo;
- Uint32 tDistrGHIndex = tScanIndicator;
- Uint32 tDistrKeyIndex = tDistrGHIndex;
-
- Uint32 tScanInfo = theScanInfo;
- Uint32 tDistrKey = theDistributionKey;
-
- tOptionalDataPtr[0] = tScanInfo;
- tOptionalDataPtr[tDistrKeyIndex] = tDistrKey;
-
-//-------------------------------------------------------------
-// The next is step is to compress the key data part of the
-// TCKEYREQ signal.
-//-------------------------------------------------------------
- Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator;
- Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex];
- Uint32 Tdata1 = tcKeyReq->keyInfo[0];
- Uint32 Tdata2 = tcKeyReq->keyInfo[1];
- Uint32 Tdata3 = tcKeyReq->keyInfo[2];
- Uint32 Tdata4 = tcKeyReq->keyInfo[3];
- Uint32 Tdata5;
-
- tKeyDataPtr[0] = Tdata1;
- tKeyDataPtr[1] = Tdata2;
- tKeyDataPtr[2] = Tdata3;
- tKeyDataPtr[3] = Tdata4;
- if (tTupKeyLen > 4) {
- Tdata1 = tcKeyReq->keyInfo[4];
- Tdata2 = tcKeyReq->keyInfo[5];
- Tdata3 = tcKeyReq->keyInfo[6];
- Tdata4 = tcKeyReq->keyInfo[7];
-
- tKeyDataPtr[4] = Tdata1;
- tKeyDataPtr[5] = Tdata2;
- tKeyDataPtr[6] = Tdata3;
- tKeyDataPtr[7] = Tdata4;
- }//if
-//-------------------------------------------------------------
-// Finally we also compress the ATTRINFO part of the signal.
-// We optimise by using the if-statement for sending KEYINFO
-// signals to calculating the new Attrinfo Index.
-//-------------------------------------------------------------
- Uint32 tAttrInfoIndex;
-
- if (tTupKeyLen > TcKeyReq::MaxKeyInfo) {
- /**
- * Set transid, TC connect ptr and length in the KEYINFO signals
- */
- NdbApiSignal* tSignal = theTCREQ->next();
- Uint32 remainingKey = tTupKeyLen - TcKeyReq::MaxKeyInfo;
- do {
- Uint32* tSigDataPtr = tSignal->getDataPtrSend();
- NdbApiSignal* tnextSignal = tSignal->next();
- tSigDataPtr[0] = aTC_ConnectPtr;
- tSigDataPtr[1] = tTransId1;
- tSigDataPtr[2] = tTransId2;
- if (remainingKey > KeyInfo::DataLength) {
- // The signal is full
- tSignal->setLength(KeyInfo::MaxSignalLength);
- remainingKey -= KeyInfo::DataLength;
- }
- else {
- // Last signal
- tSignal->setLength(KeyInfo::HeaderLength + remainingKey);
- remainingKey = 0;
- }
- tSignal = tnextSignal;
- } while (tSignal != NULL);
- tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo;
- } else {
- tAttrInfoIndex = tKeyIndex + tTupKeyLen;
- }//if
-
-//-------------------------------------------------------------
-// Perform the Attrinfo packing in the TCKEYREQ signal started
-// above.
-//-------------------------------------------------------------
- Uint32* tAIDataPtr = &tOptionalDataPtr[tAttrInfoIndex];
- Tdata1 = tcKeyReq->attrInfo[0];
- Tdata2 = tcKeyReq->attrInfo[1];
- Tdata3 = tcKeyReq->attrInfo[2];
- Tdata4 = tcKeyReq->attrInfo[3];
- Tdata5 = tcKeyReq->attrInfo[4];
-
- theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) +
- tAttrInfoIndex + TcKeyReq::StaticLength);
-
- tAIDataPtr[0] = Tdata1;
- tAIDataPtr[1] = Tdata2;
- tAIDataPtr[2] = Tdata3;
- tAIDataPtr[3] = Tdata4;
- tAIDataPtr[4] = Tdata5;
-
-/***************************************************
-* Send the ATTRINFO signals.
-***************************************************/
- if (tTotalCurrAI_Len > 5) {
- // Set the last signal's length.
- NdbApiSignal* tSignal = theFirstATTRINFO;
- theCurrentATTRINFO->setLength(theAI_LenInCurrAI);
- do {
- Uint32* tSigDataPtr = tSignal->getDataPtrSend();
- NdbApiSignal* tnextSignal = tSignal->next();
- tSigDataPtr[0] = aTC_ConnectPtr;
- tSigDataPtr[1] = tTransId1;
- tSigDataPtr[2] = tTransId2;
- tSignal = tnextSignal;
- } while (tSignal != NULL);
- }//if
- theStatus = WaitResponse;
- theReceiver.prepareSend();
- return 0;
-}//NdbOperation::prepareSend()
-
-/***************************************************************************
-int prepareSendInterpreted()
-
-Make preparations to send an interpreted operation.
-Return Value: Return 0 : succesful.
- Return -1: In all other case.
-***************************************************************************/
-int
-NdbOperation::prepareSendInterpreted()
-{
- Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
- Uint32 tInitReadSize = theInitialReadSize;
- if (theStatus == ExecInterpretedValue) {
- if (insertATTRINFO(Interpreter::EXIT_OK) != -1) {
-//-------------------------------------------------------------------------
-// Since we read the total length before inserting the last entry in the
-// signals we need to add one to the total length.
-//-------------------------------------------------------------------------
-
- theInterpretedSize = (tTotalCurrAI_Len + 1) -
- (tInitReadSize + 5);
-
- } else {
- return -1;
- }//if
- } else if (theStatus == FinalGetValue) {
-
- theFinalReadSize = tTotalCurrAI_Len -
- (tInitReadSize + theInterpretedSize + theFinalUpdateSize + 5);
-
- } else if (theStatus == SetValueInterpreted) {
-
- theFinalUpdateSize = tTotalCurrAI_Len -
- (tInitReadSize + theInterpretedSize + 5);
-
- } else if (theStatus == SubroutineEnd) {
-
- theSubroutineSize = tTotalCurrAI_Len -
- (tInitReadSize + theInterpretedSize +
- theFinalUpdateSize + theFinalReadSize + 5);
-
- } else if (theStatus == GetValue) {
- theInitialReadSize = tTotalCurrAI_Len - 5;
- } else {
- setErrorCodeAbort(4116);
- return -1;
- }
-
- while (theFirstBranch != NULL) {
- Uint32 tRelAddress;
- Uint32 tLabelAddress = 0;
- int tAddress = -1;
- NdbBranch* tNdbBranch = theFirstBranch;
- Uint32 tBranchLabel = tNdbBranch->theBranchLabel;
- NdbLabel* tNdbLabel = theFirstLabel;
- if (tBranchLabel >= theNoOfLabels) {
- setErrorCodeAbort(4221);
- return -1;
- }//if
-
- // Find the label address
- while (tNdbLabel != NULL) {
- for(tLabelAddress = 0; tLabelAddress<16; tLabelAddress++){
- const Uint32 labelNo = tNdbLabel->theLabelNo[tLabelAddress];
- if(tBranchLabel == labelNo){
- tAddress = tNdbLabel->theLabelAddress[tLabelAddress];
- break;
- }
- }
-
- if(tAddress != -1)
- break;
- tNdbLabel = tNdbLabel->theNext;
- }//while
- if (tAddress == -1) {
-//-------------------------------------------------------------------------
-// We were unable to find any label which the branch refers to. This means
-// that the application have not programmed the interpreter program correctly.
-//-------------------------------------------------------------------------
- setErrorCodeAbort(4222);
- return -1;
- }//if
- if (tNdbLabel->theSubroutine[tLabelAddress] != tNdbBranch->theSubroutine) {
- setErrorCodeAbort(4224);
- return -1;
- }//if
- // Now it is time to update the signal data with the relative branch jump.
- if (tAddress < int(tNdbBranch->theBranchAddress)) {
- tRelAddress = (tNdbBranch->theBranchAddress - tAddress) << 16;
-
- // Indicate backward jump direction
- tRelAddress = tRelAddress + (1 << 31);
-
- } else if (tAddress > int(tNdbBranch->theBranchAddress)) {
- tRelAddress = (tAddress - tNdbBranch->theBranchAddress) << 16;
- } else {
- setErrorCodeAbort(4223);
- return -1;
- }//if
- NdbApiSignal* tSignal = tNdbBranch->theSignal;
- Uint32 tReadData = tSignal->readData(tNdbBranch->theSignalAddress);
- tSignal->setData((tRelAddress + tReadData), tNdbBranch->theSignalAddress);
-
- theFirstBranch = theFirstBranch->theNext;
- theNdb->releaseNdbBranch(tNdbBranch);
- }//while
-
- while (theFirstCall != NULL) {
- Uint32 tSubroutineCount = 0;
- int tAddress = -1;
- NdbSubroutine* tNdbSubroutine;
- NdbCall* tNdbCall = theFirstCall;
- if (tNdbCall->theSubroutine >= theNoOfSubroutines) {
- setErrorCodeAbort(4221);
- return -1;
- }//if
-// Find the subroutine address
- tNdbSubroutine = theFirstSubroutine;
- while (tNdbSubroutine != NULL) {
- tSubroutineCount += 16;
- if (tNdbCall->theSubroutine < tSubroutineCount) {
-// Subroutine Found
- Uint32 tSubroutineAddress = tNdbCall->theSubroutine - (tSubroutineCount - 16);
- tAddress = tNdbSubroutine->theSubroutineAddress[tSubroutineAddress];
- break;
- }//if
- tNdbSubroutine = tNdbSubroutine->theNext;
- }//while
- if (tAddress == -1) {
- setErrorCodeAbort(4222);
- return -1;
- }//if
-// Now it is time to update the signal data with the relative branch jump.
- NdbApiSignal* tSignal = tNdbCall->theSignal;
- Uint32 tReadData = tSignal->readData(tNdbCall->theSignalAddress);
- tSignal->setData(((tAddress << 16) + tReadData), tNdbCall->theSignalAddress);
-
- theFirstCall = theFirstCall->theNext;
- theNdb->releaseNdbCall(tNdbCall);
- }//while
-
- Uint32 tInitialReadSize = theInitialReadSize;
- Uint32 tInterpretedSize = theInterpretedSize;
- Uint32 tFinalUpdateSize = theFinalUpdateSize;
- Uint32 tFinalReadSize = theFinalReadSize;
- Uint32 tSubroutineSize = theSubroutineSize;
- if (theOperationType != OpenScanRequest &&
- theOperationType != OpenRangeScanRequest) {
- TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
-
- tcKeyReq->attrInfo[0] = tInitialReadSize;
- tcKeyReq->attrInfo[1] = tInterpretedSize;
- tcKeyReq->attrInfo[2] = tFinalUpdateSize;
- tcKeyReq->attrInfo[3] = tFinalReadSize;
- tcKeyReq->attrInfo[4] = tSubroutineSize;
- } else {
- // If a scan is defined we use the first ATTRINFO instead of TCKEYREQ.
- theFirstATTRINFO->setData(tInitialReadSize, 4);
- theFirstATTRINFO->setData(tInterpretedSize, 5);
- theFirstATTRINFO->setData(tFinalUpdateSize, 6);
- theFirstATTRINFO->setData(tFinalReadSize, 7);
- theFirstATTRINFO->setData(tSubroutineSize, 8);
- }//if
- theReceiver.prepareSend();
- return 0;
-}//NdbOperation::prepareSendInterpreted()
-
-int
-NdbOperation::checkState_TransId(NdbApiSignal* aSignal)
-{
- Uint64 tRecTransId, tCurrTransId;
- Uint32 tTmp1, tTmp2;
-
- if (theStatus != WaitResponse) {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- return -1;
- }//if
-
- tTmp1 = aSignal->readData(2);
- tTmp2 = aSignal->readData(3);
-
- tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
- tCurrTransId = theNdbCon->getTransactionId();
- if (tCurrTransId != tRecTransId) {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- return -1;
- }//if
- return 0;
-}//NdbOperation::checkState_TransId()
-
-/***************************************************************************
-int receiveTCKEYREF( NdbApiSignal* aSignal)
-
-Return Value: Return 0 : send was succesful.
- Return -1: In all other case.
-Parameters: aSignal: the signal object that contains the TCKEYREF signal from TC.
-Remark: Handles the reception of the TCKEYREF signal.
-***************************************************************************/
-int
-NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
-{
- if (checkState_TransId(aSignal) == -1) {
- return -1;
- }//if
-
- setErrorCode(aSignal->readData(4));
- if (aSignal->getLength() == TcKeyRef::SignalLength)
- {
- // Signal may contain additional error data
- theError.details = (char *) aSignal->readData(5);
- }
-
- theStatus = Finished;
- theReceiver.m_received_result_length = ~0;
-
- // not dirty read
- if(! (theOperationType == ReadRequest && theDirtyIndicator))
- {
- theNdbCon->OpCompleteFailure(this);
- return -1;
- }
-
- /**
- * If TCKEYCONF has arrived
- * op has completed (maybe trans has completed)
- */
- if(theReceiver.m_expected_result_length)
- {
- return theNdbCon->OpCompleteFailure(this);
- }
-
- return -1;
-}
diff --git a/storage/ndb/src/ndbapi/NdbOperationInt.cpp b/storage/ndb/src/ndbapi/NdbOperationInt.cpp
deleted file mode 100644
index 165712b6c06..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperationInt.cpp
+++ /dev/null
@@ -1,1187 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbTransaction.hpp>
-#include <Ndb.hpp>
-#include <NdbRecAttr.hpp>
-#include "NdbUtil.hpp"
-#include "Interpreter.hpp"
-#include <NdbIndexScanOperation.hpp>
-
-#ifdef VM_TRACE
-#include <NdbEnv.h>
-#define INT_DEBUG(x) \
- { const char* tmp = NdbEnv_GetEnv("INT_DEBUG", (char*)0, 0); \
- if (tmp != 0 && strlen(tmp) != 0) { ndbout << "INT:"; ndbout_c x; } }
-#else
-#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)
-{
- if ((theInterpretIndicator == 1)) {
- if ((tNdbColumnImpl == NULL) ||
- (theOperationType == OpenScanRequest ||
- theOperationType == OpenRangeScanRequest))
- goto inc_check_error1;
- if ((tNdbColumnImpl->getInterpretableType() != true) ||
- (tNdbColumnImpl->m_pk != false) ||
- (tNdbColumnImpl->m_nullable))
- goto inc_check_error2;
- if (theStatus == ExecInterpretedValue) {
- ; // Simply continue with interpretation
- } else if (theStatus == GetValue) {
- theInitialReadSize = theTotalCurrAI_Len - 5;
- theStatus = ExecInterpretedValue;
- } else if (theStatus == SubroutineExec) {
- ; // Simply continue with interpretation
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- m_no_disk_flag &=
- (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
- return tNdbColumnImpl->m_attrId;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-
- inc_check_error1:
- if (theOperationType == OpenScanRequest ||
- theOperationType == OpenRangeScanRequest) {
- setErrorCodeAbort(4228);
- return -1;
- }
- setErrorCodeAbort(4004);
- return -1;
-
- inc_check_error2:
- if (tNdbColumnImpl->m_pk){
- setErrorCodeAbort(4202);
- return -1;
- }//if
- if (!tNdbColumnImpl->getInterpretableType()){
- setErrorCodeAbort(4217);
- return -1;
- }//if
- if (tNdbColumnImpl->m_nullable){
- setErrorCodeAbort(4218);
- return -1;
- }//if
- setErrorCodeAbort(4219);
- return -1;
-}
-
-int
-NdbOperation::write_attrCheck(const NdbColumnImpl* tNdbColumnImpl)
-{
- if ((theInterpretIndicator == 1)) {
- if ((tNdbColumnImpl == NULL) ||
- (theOperationType == OpenScanRequest ||
- theOperationType == OpenRangeScanRequest))
- goto write_attr_check_error1;
- if ((tNdbColumnImpl->getInterpretableType() == false) ||
- (tNdbColumnImpl->m_pk))
- goto write_attr_check_error2;
- if (theStatus == ExecInterpretedValue) {
- ; // Simply continue with interpretation
- } else if (theStatus == SubroutineExec) {
- ; // Simply continue with interpretation
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- m_no_disk_flag &=
- (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
- return tNdbColumnImpl->m_attrId;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-
-write_attr_check_error1:
- if (theOperationType == OpenScanRequest ||
- theOperationType == OpenRangeScanRequest) {
- setErrorCodeAbort(4228);
- return -1;
- }
- setErrorCodeAbort(4004);
- return -1;
-
-write_attr_check_error2:
- if (tNdbColumnImpl->m_pk) {
- setErrorCodeAbort(4202);
- return -1;
- }//if
- if (tNdbColumnImpl->getInterpretableType() == false){
- setErrorCodeAbort(4217);
- return -1;
- }//if
- setErrorCodeAbort(4219);
- return -1;
-}
-
-int
-NdbOperation::read_attrCheck(const NdbColumnImpl* tNdbColumnImpl)
-{
- if ((theInterpretIndicator == 1)) {
- if (tNdbColumnImpl == NULL)
- goto read_attr_check_error1;
- if (tNdbColumnImpl->getInterpretableType() == false)
- goto read_attr_check_error2;
- if (theStatus == ExecInterpretedValue) {
- ; // Simply continue with interpretation
- } else if (theStatus == GetValue) {
- theInitialReadSize = theTotalCurrAI_Len - 5;
- theStatus = ExecInterpretedValue;
- } else if (theStatus == SubroutineExec) {
- ; // Simply continue with interpretation
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- m_no_disk_flag &=
- (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
- return tNdbColumnImpl->m_attrId;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-
- read_attr_check_error1:
- setErrorCodeAbort(4004);
- return -1;
-
- read_attr_check_error2:
- if (tNdbColumnImpl->getInterpretableType() == false)
- setErrorCodeAbort(4217);
- else
- setErrorCodeAbort(4219);
- return -1;
-
-}
-
-int
-NdbOperation::initial_interpreterCheck()
-{
- if ((theInterpretIndicator == 1)) {
- if (theStatus == ExecInterpretedValue) {
- return 0; // Simply continue with interpretation
- } else if (theStatus == GetValue) {
- theInitialReadSize = theTotalCurrAI_Len - 5;
- theStatus = ExecInterpretedValue;
- return 0;
- } else if (theStatus == SubroutineExec) {
- return 0; // Simply continue with interpretation
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- return 0;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-}
-
-int
-NdbOperation::labelCheck()
-{
- if ((theInterpretIndicator == 1)) {
- if (theStatus == ExecInterpretedValue) {
- return 0; // Simply continue with interpretation
- } else if (theStatus == GetValue) {
- theInitialReadSize = theTotalCurrAI_Len - 5;
- theStatus = ExecInterpretedValue;
- return 0;
- } else if (theStatus == SubroutineExec) {
- return 0; // Simply continue with interpretation
- } else if (theStatus == SubroutineEnd) {
- theStatus = SubroutineExec;
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- return 0;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-}
-
-int
-NdbOperation::intermediate_interpreterCheck()
-{
- if ((theInterpretIndicator == 1)) {
- if (theStatus == ExecInterpretedValue) {
- return 0; // Simply continue with interpretation
- } else if (theStatus == SubroutineExec) {
- return 0; // Simply continue with interpretation
- } else {
- setErrorCodeAbort(4231);
- return -1;
- }
- return 0;
- } else {
- if (theNdbCon->theCommitStatus == NdbTransaction::Started)
- setErrorCodeAbort(4200);
- }
- return -1;
-}
-
-/*****************************************************************************
- * int incValue(const char* anAttrName, char* aValue, Uint32 aValue)
- *
- * Return Value: Return 0 : incValue was succesful.
- * Return -1: In all other case.
- * Parameters: anAttrName : Attribute name where the attribute value
- * will be save.
- * aValue : The constant to increment the attribute value with.
- *****************************************************************************/
-int
-NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue)
-{
- INT_DEBUG(("incValue32 %d %u", tNdbColumnImpl->m_attrId, aValue));
- int tAttrId;
-
- tAttrId = incCheck(tNdbColumnImpl);
- if (tAttrId == -1)
- goto incValue_error1;
-
-// Load Attribute into register 6
-
- if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
- goto incValue_error1;
-// Load aValue into register 7
- if (aValue < 65536)
- {
- if (insertATTRINFO(Interpreter::LoadConst16(7, aValue)) == -1)
- goto incValue_error1;
- } else {
- if (insertATTRINFO(Interpreter::LoadConst32(7)) == -1)
- goto incValue_error1;
- if (insertATTRINFO(aValue) == -1)
- goto incValue_error1;
- }
- // Add register 6 and 7 and put result in register 7
-
- if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1)
- goto incValue_error1;
- if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
- goto incValue_error1;
-
- theErrorLine++;
- return 0;
-
-incValue_error1:
- return -1;
-}
-
-/*****************************************************************************
- * int subValue(const char* anAttrName, char* aValue, Uint32 aValue)
- *
- * Return Value: Return 0 : incValue was succesful.
- * Return -1: In all other case.
- * Parameters: anAttrName : Attribute name where the attribute value
- * will be save.
- * aValue : The constant to increment the attribute value with.
-******************************************************************************/
-int
-NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue)
-{
- INT_DEBUG(("subValue32 %d %u", tNdbColumnImpl->m_attrId, aValue));
- int tAttrId;
-
- tAttrId = incCheck(tNdbColumnImpl);
- if (tAttrId == -1)
- goto subValue_error1;
-
-// Load Attribute into register 6
-
- if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
- goto subValue_error1;
-// Load aValue into register 7
- if (aValue < 65536)
- {
- if (insertATTRINFO( Interpreter::LoadConst16(7, aValue)) == -1)
- goto subValue_error1;
- } else {
- if (insertATTRINFO( Interpreter::LoadConst32(7)) == -1)
- goto subValue_error1;
- if (insertATTRINFO(aValue) == -1)
- goto subValue_error1;
- }
- // Subtract register 6 and 7 and put result in register 7
-
- if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1)
- goto subValue_error1;
- if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
- goto subValue_error1;
-
- theErrorLine++;
- return 0;
-
- subValue_error1:
- return -1;
-}
-
-/******************************************************************************
- * int incValue(const char* anAttrName, char* aValue, Uint64 aValue)
- *
- * Return Value: Return 0 : incValue was succesful.
- * Return -1: In all other case.
- * Parameters: anAttrName : Attribute name where the attribute value will
- * be save.
- * aValue : The constant to increment the attribute value with.
- *****************************************************************************/
-int
-NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue)
-{
- INT_DEBUG(("incValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue));
- int tAttrId;
-
- tAttrId = incCheck(tNdbColumnImpl);
- if (tAttrId == -1)
- goto incValue_error1;
-
-// Load Attribute into register 6
-
- if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1)
- goto incValue_error1;
-// Load aValue into register 7
- if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1)
- goto incValue_error1;
- if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1)
- goto incValue_error1;
- // Add register 6 and 7 and put result in register 7
- if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1)
- goto incValue_error1;
- if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
- goto incValue_error1;
-
- theErrorLine++;
- return 0;
-
-incValue_error1:
- return -1;
-}
-
-/*****************************************************************************
- * int subValue(const char* anAttrName, char* aValue, Uint64 aValue)
- *
- * Return Value: Return 0 : incValue was succesful.
- * Return -1: In all other case.
- * Parameters: anAttrName : Attribute name where the attribute value will
- * be save.
- * aValue : The constant to increment the attribute value with.
-******************************************************************************/
-int
-NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue)
-{
- INT_DEBUG(("subValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue));
- int tAttrId;
-
- tAttrId = incCheck(tNdbColumnImpl);
- if (tAttrId == -1)
- goto subValue_error1;
-
-// Load Attribute into register 6
-
- if (insertATTRINFO( Interpreter::Read(6, tAttrId)) == -1)
- goto subValue_error1;
-// Load aValue into register 7
- if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1)
- goto subValue_error1;
- if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1)
- goto subValue_error1;
-// Subtract register 6 and 7 and put result in register 7
- if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1)
- goto subValue_error1;
- if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1)
- goto subValue_error1;
-
- theErrorLine++;
- return 0;
-
-subValue_error1:
- return -1;
-}
-
-/*****************************************************************************
- * int NdbOperation::def_label()
- *****************************************************************************/
-int
-NdbOperation::def_label(int tLabelNo)
-{
- INT_DEBUG(("def_label %d", tLabelNo));
- Uint32 tLabelIndex;
- if (labelCheck() == -1)
- return -1;
-
- tLabelIndex = theNoOfLabels - ((theNoOfLabels >> 4) << 4);
- if (tLabelIndex == 0)
- {
- NdbLabel* tNdbLabel = theNdb->getNdbLabel();
- if (tNdbLabel == NULL)
- {
- setErrorCodeAbort(4000);
- return -1;
- }
- if (theFirstLabel == NULL)
- theFirstLabel = tNdbLabel;
- else
- theLastLabel->theNext = tNdbLabel;
-
- theLastLabel = tNdbLabel;
- tNdbLabel->theNext = NULL;
- }
-
- /**
- * Here we set the address that the label should point to (jump address),
- * the first 5 words are excluded since they are length specifications and
- * not part of the data.
- * We need to add 1 to the current ATTRINFO length since the last inserted
- * item is not where we want to jump to.
- * Later on we will update the branch items with this address, this is done in
- * the NdbOperation::prepareSendInterpreted method.
- */
-
- theLastLabel->theLabelNo[tLabelIndex] = tLabelNo;
- theLastLabel->theLabelAddress[tLabelIndex] = (theTotalCurrAI_Len + 1) - (theInitialReadSize + 5);
- theLastLabel->theSubroutine[tLabelIndex] = theNoOfSubroutines;
- theNoOfLabels++;
- theErrorLine++;
- return (theNoOfLabels - 1);
-}
-
-/************************************************************************************************
-int NdbOperation::def_subroutine()
-
-************************************************************************************************/
-int
-NdbOperation::def_subroutine(int tSubNo)
-{
- INT_DEBUG(("def_subroutine %d", tSubNo));
- Uint32 tSubroutineIndex;
-
- if (theInterpretIndicator != 1)
- {
- setErrorCodeAbort(4200);
- return -1;
- }
-
- if (int(theNoOfSubroutines) != tSubNo)
- {
- setErrorCodeAbort(4227);
- return -1;
- }
- if (theStatus == FinalGetValue)
- {
- theFinalReadSize = theTotalCurrAI_Len -
- (theInitialReadSize + theInterpretedSize +
- theFinalUpdateSize + 5);
-
- } else if (theStatus == SubroutineEnd)
- {
- ; // Correct Status, last call was ret_sub()
- } else if (theStatus == ExecInterpretedValue)
- {
- if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
- return -1;
- theInterpretedSize = theTotalCurrAI_Len - (theInitialReadSize + 5);
- } else if (theStatus == SetValueInterpreted)
- {
- theFinalUpdateSize = theTotalCurrAI_Len -
- (theInitialReadSize + theInterpretedSize + 5);
-
- } else if (theStatus == GetValue)
- {
-
- theInitialReadSize = theTotalCurrAI_Len - 5;
-
- } else
- {
- setErrorCodeAbort(4200);
- return -1;
- }
- theStatus = SubroutineExec;
- tSubroutineIndex = theNoOfSubroutines - ((theNoOfSubroutines >> 4) << 4);
- if (tSubroutineIndex == 0)
- {
- NdbSubroutine* tNdbSubroutine = theNdb->getNdbSubroutine();
- if (tNdbSubroutine == NULL)
- {
- setErrorCodeAbort(4000);
- return -1;
- }
- if (theFirstSubroutine == NULL)
- theFirstSubroutine = tNdbSubroutine;
- else
- theLastSubroutine->theNext = tNdbSubroutine;
-
- theLastSubroutine = tNdbSubroutine;
- tNdbSubroutine->theNext = NULL;
- }
- theLastSubroutine->theSubroutineAddress[tSubroutineIndex] = theTotalCurrAI_Len -
- (theInitialReadSize + theInterpretedSize +
- theFinalUpdateSize + theFinalReadSize);
- theNoOfSubroutines++;
- theErrorLine++;
- return (theNoOfSubroutines - 1);
-}
-
-/************************************************************************************************
-int NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
-
-************************************************************************************************/
-int
-NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
-{
- INT_DEBUG(("add_reg %u %u %u", RegSource1, RegSource2, RegDest));
- if (intermediate_interpreterCheck() == -1)
- return -1;
-
- if (RegSource1 >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (RegSource2 >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (RegDest >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (insertATTRINFO( Interpreter::Add(RegDest, RegSource1, RegSource2)) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
-
-************************************************************************************************/
-int
-NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest)
-{
- INT_DEBUG(("sub_reg %u %u %u", RegSource1, RegSource2, RegDest));
- if (intermediate_interpreterCheck() == -1)
- return -1;
-
- if (RegSource1 >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (RegSource2 >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (RegDest >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (insertATTRINFO( Interpreter::Sub(RegDest, RegSource1, RegSource2)) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant)
-
-************************************************************************************************/
-int
-NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant)
-{
- INT_DEBUG(("load_const_u32 %u %u", RegDest, Constant));
- if (initial_interpreterCheck() == -1)
- goto l_u32_error1;
- if (RegDest >= 8)
- goto l_u32_error2;
- if (insertATTRINFO( Interpreter::LoadConst32(RegDest)) == -1)
- goto l_u32_error1;
- if (insertATTRINFO(Constant) == -1)
- goto l_u32_error1;
- theErrorLine++;
- return 0;
-
- l_u32_error1:
- return -1;
-
- l_u32_error2:
- setErrorCodeAbort(4229);
- return -1;
-}
-
-/************************************************************************************************
-int NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant)
-
-************************************************************************************************/
-int
-NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant)
-{
- INT_DEBUG(("load_const_u64 %u %llu", RegDest, Constant));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (RegDest >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
-
- // 64 bit value
- if (insertATTRINFO( Interpreter::LoadConst64(RegDest)) == -1)
- return -1;
- if (insertATTRINFOloop((Uint32*)&Constant, 2) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::load_const_null(Uint32 RegDest)
-
-************************************************************************************************/
-int
-NdbOperation::load_const_null(Uint32 RegDest)
-{
- INT_DEBUG(("load_const_null %u", RegDest));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (RegDest >= 8)
- {
- setErrorCodeAbort(4229);
- return -1;
- }
- if (insertATTRINFO( Interpreter::LOAD_CONST_NULL) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::read_attr(const char* anAttrName, Uint32 RegDest)
-
-************************************************************************************************/
-int
-NdbOperation::read_attr(const NdbColumnImpl* anAttrObject, Uint32 RegDest)
-{
- INT_DEBUG(("read_attr %d %u", anAttrObject->m_attrId, RegDest));
- if (initial_interpreterCheck() == -1)
- return -1;
-
- int tAttrId = read_attrCheck(anAttrObject);
- if (tAttrId == -1)
- goto read_attr_error1;
- if (RegDest >= 8)
- goto read_attr_error2;
- if (insertATTRINFO( Interpreter::Read(tAttrId, RegDest)) != -1) {
- return 0;
- theErrorLine++;
- }//if
- return -1;
-
-read_attr_error1:
- return -1;
-
-read_attr_error2:
- setErrorCodeAbort(4229);
- return -1;
-}
-
-/************************************************************************************************
-int NdbOperation::write_attr(const char* anAttrName, Uint32 RegSource)
-
-************************************************************************************************/
-int
-NdbOperation::write_attr(const NdbColumnImpl* anAttrObject, Uint32 RegSource)
-{
- INT_DEBUG(("write_attr %d %u", anAttrObject->m_attrId, RegSource));
- int tAttrId = write_attrCheck(anAttrObject);
- if (tAttrId == -1)
- return -1;
- if (insertATTRINFO( Interpreter::Write(tAttrId, RegSource)) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::branch_reg_reg(Uint32 type,
- Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- if (intermediate_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO(Interpreter::Branch(type, RegLvalue, RegRvalue)) == -1)
- return -1;
- if (insertBranch(Label) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::branch_ge(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_ge %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_GE_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_gt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_gt %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_GT_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_le(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_le %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_LE_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_lt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_lt %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_LT_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_eq(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_eq %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_EQ_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_ne(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_ne %u %u %u", RegLvalue, RegRvalue, Label));
- return branch_reg_reg(Interpreter::BRANCH_NE_REG_REG,
- RegLvalue, RegRvalue, Label);
-}
-
-int
-NdbOperation::branch_ne_null(Uint32 RegLvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_ne_null %u %u", RegLvalue, Label));
- if (intermediate_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_NE_NULL) == -1)
- return -1;
- if (insertBranch(Label) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::branch_eq_null(Uint32 RegLvalue, Uint32 Label)
-{
- INT_DEBUG(("branch_eq_null %u %u", RegLvalue, Label));
- if (intermediate_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_EQ_NULL) == -1)
- return -1;
- if (insertBranch(Label) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::branch_label(Uint32 Label)
-{
- INT_DEBUG(("branch_label %u", Label));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO(Interpreter::BRANCH) == -1)
- return -1;
- if (insertBranch(Label) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::interpret_exit_ok()
-
-************************************************************************************************/
-int
-NdbOperation::interpret_exit_ok()
-{
- INT_DEBUG(("interpret_exit_ok"));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO(Interpreter::EXIT_OK) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::interpret_exit_last_row()
-{
- INT_DEBUG(("interpret_exit_last_row"));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO(Interpreter::EXIT_OK_LAST) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-/************************************************************************************************
-int NdbOperation::interpret_exit_nok(Uint32 ErrorCode)
-
-************************************************************************************************/
-int
-NdbOperation::interpret_exit_nok(Uint32 ErrorCode)
-{
- INT_DEBUG(("interpret_exit_nok %u", ErrorCode));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::interpret_exit_nok()
-{
- INT_DEBUG(("interpret_exit_nok"));
- Uint32 ErrorCode = 899;
-
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::call_sub(Uint32 Subroutine)
-{
- INT_DEBUG(("call_sub %u", Subroutine));
- if (initial_interpreterCheck() == -1)
- return -1;
- if (insertATTRINFO( (Subroutine << 16) + Interpreter::CALL) == -1)
- return -1;
- if (insertCall(Subroutine) == -1)
- return -1;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::ret_sub()
-{
- INT_DEBUG(("ret_sub"));
- if (theInterpretIndicator != 1)
- {
- setErrorCodeAbort(4200);
- return -1;
- }
- if (theStatus == SubroutineExec)
- {
- ; // Simply continue with interpretation
- } else
- {
- setErrorCodeAbort(4200);
- return -1;
- }
- if (insertATTRINFO(Interpreter::RETURN) == -1)
- return -1;
- theStatus = SubroutineEnd;
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::insertBranch(Uint32 aLabel)
-{
- Uint32 tAddress;
- NdbBranch* tBranch = theNdb->getNdbBranch();
- if (tBranch == NULL)
- goto insertBranch_error1;
- if (theFirstBranch == NULL)
- theFirstBranch = tBranch;
- else
- theLastBranch->theNext = tBranch;
- theLastBranch = tBranch;
- if (theNoOfSubroutines == 0)
- tAddress = theTotalCurrAI_Len -
- (theInitialReadSize + 5);
- else
- tAddress = theTotalCurrAI_Len -
- (theInitialReadSize + theInterpretedSize +
- theFinalUpdateSize + theFinalReadSize + 5);
-
- tBranch->theBranchAddress = tAddress;
- tBranch->theSignal = theCurrentATTRINFO;
- tBranch->theSignalAddress = theAI_LenInCurrAI; // + 1; theAI_LenInCurrAI has already been updated in
- tBranch->theSubroutine = theNoOfSubroutines; // insertATTRINFO which was done before insertBranch!!
- tBranch->theBranchLabel = aLabel;
- return 0;
-
-insertBranch_error1:
- setErrorCodeAbort(4000);
- return -1;
-}
-
-int
-NdbOperation::insertCall(Uint32 aCall)
-{
- NdbCall* tCall = theNdb->getNdbCall();
- if (tCall == NULL)
- {
- setErrorCodeAbort(4000);
- return -1;
- }
- if (theFirstCall == NULL)
- theFirstCall = tCall;
- else
- theLastCall->theNext = tCall;
- theLastCall = tCall;
-
- tCall->theSignal = theCurrentATTRINFO;
- tCall->theSignalAddress = theAI_LenInCurrAI;
- tCall->theSubroutine = aCall;
- return 0;
-}
-
-int
-NdbOperation::branch_col(Uint32 type,
- Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
-
- DBUG_ENTER("NdbOperation::branch_col");
- DBUG_PRINT("enter", ("type: %u col:%u val: 0x%lx len: %u label: %u",
- type, ColId, (long) val, len, Label));
- if (val != NULL)
- DBUG_DUMP("value", (uchar*)val, len);
-
- if (initial_interpreterCheck() == -1)
- DBUG_RETURN(-1);
-
- Interpreter::BinaryCondition c = (Interpreter::BinaryCondition)type;
-
- const NdbColumnImpl * col =
- m_currentTable->getColumn(ColId);
-
- if(col == 0){
- abort();
- }
-
- if (val == NULL)
- len = 0;
- else {
- if (! col->getStringType()) {
- // prevent assert in NdbSqlUtil on length error
- Uint32 sizeInBytes = col->m_attrSize * col->m_arraySize;
- if (len != 0 && len != sizeInBytes)
- {
- setErrorCodeAbort(4209);
- DBUG_RETURN(-1);
- }
- len = sizeInBytes;
- }
- }
-
- m_no_disk_flag &= (col->m_storageType == NDB_STORAGETYPE_DISK ? 0:1);
-
- Uint32 tempData[2000];
- if (((UintPtr)val & 3) != 0) {
- memcpy(tempData, val, len);
- val = tempData;
- }
-
- if (insertATTRINFO(Interpreter::BranchCol(c, 0, 0, false)) == -1)
- DBUG_RETURN(-1);
-
- if (insertBranch(Label) == -1)
- DBUG_RETURN(-1);
-
- if (insertATTRINFO(Interpreter::BranchCol_2(col->m_attrId, len)))
- DBUG_RETURN(-1);
-
- Uint32 len2 = Interpreter::mod4(len);
- if(len2 == len){
- insertATTRINFOloop((Uint32*)val, len2 >> 2);
- } else {
- len2 -= 4;
- insertATTRINFOloop((Uint32*)val, len2 >> 2);
- Uint32 tmp = 0;
- for (Uint32 i = 0; i < len-len2; i++) {
- char* p = (char*)&tmp;
- p[i] = ((char*)val)[len2+i];
- }
- insertATTRINFO(tmp);
- }
-
- theErrorLine++;
- DBUG_RETURN(0);
-}
-
-int
-NdbOperation::branch_col_eq(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_eq %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::EQ, ColId, val, len, nopad, Label);
-}
-
-int
-NdbOperation::branch_col_ne(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_ne %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::NE, ColId, val, len, nopad, Label);
-}
-int
-NdbOperation::branch_col_lt(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_lt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::LT, ColId, val, len, nopad, Label);
-}
-int
-NdbOperation::branch_col_le(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_le %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::LE, ColId, val, len, nopad, Label);
-}
-int
-NdbOperation::branch_col_gt(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_gt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::GT, ColId, val, len, nopad, Label);
-}
-
-int
-NdbOperation::branch_col_ge(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_ge %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::GE, ColId, val, len, nopad, Label);
-}
-
-int
-NdbOperation::branch_col_like(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_like %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::LIKE, ColId, val, len, nopad, Label);
-}
-
-int
-NdbOperation::branch_col_notlike(Uint32 ColId, const void * val, Uint32 len,
- bool nopad, Uint32 Label){
- INT_DEBUG(("branch_col_notlike %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len,
- nopad, Label));
- return branch_col(Interpreter::NOT_LIKE, ColId, val, len, nopad, Label);
-}
-
-int
-NdbOperation::branch_col_null(Uint32 type, Uint32 ColId, Uint32 Label){
-
- if (initial_interpreterCheck() == -1)
- return -1;
-
- if (insertATTRINFO(type) == -1)
- return -1;
-
- if (insertBranch(Label) == -1)
- return -1;
-
- Uint32 attrId=
- NdbColumnImpl::getImpl(* m_currentTable->getColumn(ColId)).m_attrId;
-
- if (insertATTRINFO(Interpreter::BranchCol_2(attrId)))
- return -1;
-
- theErrorLine++;
- return 0;
-}
-
-int
-NdbOperation::branch_col_eq_null(Uint32 ColId, Uint32 Label){
-
- INT_DEBUG(("branch_col_eq_null %u -> %u", ColId, Label));
- return branch_col_null(Interpreter::BRANCH_ATTR_EQ_NULL, ColId, Label);
-}
-
-int
-NdbOperation::branch_col_ne_null(Uint32 ColId, Uint32 Label){
-
- INT_DEBUG(("branch_col_ne_null %u -> %u", ColId, Label));
- return branch_col_null(Interpreter::BRANCH_ATTR_NE_NULL, ColId, Label);
-}
-
diff --git a/storage/ndb/src/ndbapi/NdbOperationScan.cpp b/storage/ndb/src/ndbapi/NdbOperationScan.cpp
deleted file mode 100644
index 3b796dfa83d..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperationScan.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
diff --git a/storage/ndb/src/ndbapi/NdbOperationSearch.cpp b/storage/ndb/src/ndbapi/NdbOperationSearch.cpp
deleted file mode 100644
index b332bfb6cc7..00000000000
--- a/storage/ndb/src/ndbapi/NdbOperationSearch.cpp
+++ /dev/null
@@ -1,646 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-/******************************************************************************
-Name: NdbOperationSearch.C
-Include:
-Link:
-Author: UABMNST Mona Natterkvist UAB/B/SD
-Date: 970829
-Version: 0.1
-Description: Interface between TIS and NDB
-Documentation:
-Adjust: 971022 UABMNST First version.
- 971206 UABRONM
- *****************************************************************************/
-#include "API.hpp"
-
-#include <NdbOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbTransaction.hpp>
-#include <Ndb.hpp>
-#include "NdbImpl.hpp"
-#include <NdbOut.hpp>
-
-#include <AttributeHeader.hpp>
-#include <signaldata/TcKeyReq.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <md5_hash.hpp>
-
-/******************************************************************************
-CondIdType equal(const char* anAttrName, char* aValue, Uint32 aVarKeylen);
-
-Return Value Return 0 : Equal was successful.
- Return -1: In all other case.
-Parameters: anAttrName : Attribute name for search condition..
- aValue : Referense to the search value.
- aVariableKeylen : The length of key in bytes
-Remark: Defines search condition with equality anAttrName.
-******************************************************************************/
-int
-NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
- const char* aValuePassed)
-{
- DBUG_ENTER("NdbOperation::equal_impl");
- DBUG_PRINT("enter", ("col: %s op: %d val: 0x%lx",
- tAttrInfo->m_name.c_str(), theOperationType,
- (long) aValuePassed));
-
- const char* aValue = aValuePassed;
- Uint64 tempData[512];
-
- if ((theStatus == OperationDefined) &&
- (aValue != NULL) &&
- (tAttrInfo != NULL )) {
-/******************************************************************************
- * Start by checking that the attribute is a tuple key.
- * This value is also the word order in the tuple key of this
- * tuple key attribute.
- * Then check that this tuple key has not already been defined.
- * Finally check if all tuple key attributes have been defined. If
- * this is true then set Operation state to tuple key defined.
- *****************************************************************************/
-
- /*
- * For each call theTupleKeyDefined stores 3 items:
- *
- * [0] = m_column_no (external column id)
- * [1] = 1-based index of first word of accumulating keyinfo
- * [2] = number of words of keyinfo
- *
- * This is used to re-order keyinfo if not in m_attrId order.
- *
- * Note: No point to "clean up" this code. The upcoming
- * record-based ndb api makes it obsolete.
- */
-
- Uint32 tAttrId = tAttrInfo->m_column_no; // not m_attrId;
- Uint32 i = 0;
- if (tAttrInfo->m_pk) {
- Uint32 tKeyDefined = theTupleKeyDefined[0][2];
- Uint32 tKeyAttrId = theTupleKeyDefined[0][0];
- do {
- if (tKeyDefined == false) {
- goto keyEntryFound;
- } else {
- if (tKeyAttrId != tAttrId) {
- /******************************************************************
- * We read the key defined variable in advance.
- * It could potentially read outside its area when
- * i = MAXNROFTUPLEKEY - 1,
- * it is not a problem as long as the variable
- * theTupleKeyDefined is defined
- * in the middle of the object.
- * Reading wrong data and not using it causes no problems.
- *****************************************************************/
- i++;
- tKeyAttrId = theTupleKeyDefined[i][0];
- tKeyDefined = theTupleKeyDefined[i][2];
- continue;
- } else {
- goto equal_error2;
- }//if
- }//if
- } while (i < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY);
- goto equal_error2;
- } else {
- goto equal_error1;
- }
- /*************************************************************************
- * Now it is time to retrieve the tuple key data from the pointer supplied
- * by the application.
- * We have to retrieve the size of the attribute in words and bits.
- *************************************************************************/
- keyEntryFound:
- Uint32 sizeInBytes;
- if (! tAttrInfo->get_var_length(aValue, sizeInBytes)) {
- setErrorCodeAbort(4209);
- DBUG_RETURN(-1);
- }
-
- Uint32 tKeyInfoPosition =
- i == 0 ? 1 : theTupleKeyDefined[i-1][1] + theTupleKeyDefined[i-1][2];
- theTupleKeyDefined[i][0] = tAttrId;
- theTupleKeyDefined[i][1] = tKeyInfoPosition;
- theTupleKeyDefined[i][2] = (sizeInBytes + 3) / 4;
-
- {
- /************************************************************************
- * Check if the pointer of the value passed is aligned on a 4 byte
- * boundary. If so only assign the pointer to the internal variable
- * aValue. If it is not aligned then we start by copying the value to
- * tempData and use this as aValue instead.
- ***********************************************************************/
- const bool tDistrKey = tAttrInfo->m_distributionKey;
- const int attributeSize = sizeInBytes;
- const int slack = sizeInBytes & 3;
- const int align = UintPtr(aValue) & 7;
-
- if (((align & 3) != 0) || (slack != 0) || (tDistrKey && (align != 0)))
- {
- ((Uint32*)tempData)[attributeSize >> 2] = 0;
- memcpy(&tempData[0], aValue, attributeSize);
- aValue = (char*)&tempData[0];
- }//if
- }
-
- Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word
- theTupKeyLen += totalSizeInWords;
-#if 0
- else {
- /************************************************************************
- * The attribute is a variable array. We need to use the length parameter
- * to know the size of this attribute in the key information and
- * variable area. A key is however not allowed to be larger than 4
- * kBytes and this is checked for variable array attributes
- * used as keys.
- ************************************************************************/
- Uint32 tMaxVariableKeyLenInWord = (MAXTUPLEKEYLENOFATTERIBUTEINWORD -
- tKeyInfoPosition);
- tAttrSizeInBits = aVariableKeyLen << 3;
- tAttrSizeInWords = tAttrSizeInBits >> 5;
- tAttrBitsInLastWord = tAttrSizeInBits - (tAttrSizeInWords << 5);
- tAttrLenInWords = ((tAttrSizeInBits + 31) >> 5);
- if (tAttrLenInWords > tMaxVariableKeyLenInWord) {
- setErrorCodeAbort(4207);
- return -1;
- }//if
- theTupKeyLen = theTupKeyLen + tAttrLenInWords;
- }//if
-#endif
-
- /**************************************************************************
- * If the operation is an insert request and the attribute is stored then
- * we also set the value in the stored part through putting the
- * information in the ATTRINFO signals.
- *************************************************************************/
- OperationType tOpType = theOperationType;
- if ((tOpType == InsertRequest) ||
- (tOpType == WriteRequest)) {
- Uint32 ahValue;
-
- if(m_accessTable == m_currentTable) {
- AttributeHeader::init(&ahValue, tAttrInfo->m_attrId, sizeInBytes);
- } else {
- assert(tOpType == WriteRequest && m_accessTable->m_index);
- // use attrId of primary table column
- int column_no_current_table =
- m_accessTable->m_index->m_columns[tAttrId]->m_keyInfoPos;
- int attr_id_current_table =
- m_currentTable->m_columns[column_no_current_table]->m_attrId;
- AttributeHeader::init(&ahValue, attr_id_current_table, sizeInBytes);
- }
-
- insertATTRINFO( ahValue );
- insertATTRINFOloop((Uint32*)aValue, totalSizeInWords);
- }//if
-
- /**************************************************************************
- * Store the Key information in the TCKEYREQ and KEYINFO signals.
- *************************************************************************/
- if (insertKEYINFO(aValue, tKeyInfoPosition, totalSizeInWords) != -1) {
- /************************************************************************
- * Add one to number of tuple key attributes defined.
- * If all have been defined then set the operation state to indicate
- * that tuple key is defined.
- * Thereby no more search conditions are allowed in this version.
- ***********************************************************************/
- Uint32 tNoKeysDef = theNoOfTupKeyLeft - 1;
- Uint32 tErrorLine = theErrorLine;
- unsigned char tInterpretInd = theInterpretIndicator;
- theNoOfTupKeyLeft = tNoKeysDef;
- tErrorLine++;
- theErrorLine = tErrorLine;
-
- if (tNoKeysDef == 0) {
-
- // re-order keyinfo if not entered in order
- if (m_accessTable->m_noOfKeys != 1) {
- for (Uint32 i = 0; i < m_accessTable->m_noOfKeys; i++) {
- Uint32 k = theTupleKeyDefined[i][0]; // column_no
- if (m_accessTable->m_columns[k]->m_keyInfoPos != i) {
- DBUG_PRINT("info", ("key disorder at %d", i));
- reorderKEYINFO();
- break;
- }
- }
- }
-
- if (tOpType == UpdateRequest) {
- if (tInterpretInd == 1) {
- theStatus = GetValue;
- } else {
- theStatus = SetValue;
- }//if
- DBUG_RETURN(0);
- } else if ((tOpType == ReadRequest) || (tOpType == DeleteRequest) ||
- (tOpType == ReadExclusive)) {
- theStatus = GetValue;
- // create blob handles automatically
- if (tOpType == DeleteRequest && m_currentTable->m_noOfBlobs != 0) {
- for (unsigned i = 0; i < m_currentTable->m_columns.size(); i++) {
- NdbColumnImpl* c = m_currentTable->m_columns[i];
- assert(c != 0);
- if (c->getBlobType()) {
- if (getBlobHandle(theNdbCon, c) == NULL)
- DBUG_RETURN(-1);
- }
- }
- }
- DBUG_RETURN(0);
- } else if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) {
- theStatus = SetValue;
- DBUG_RETURN(0);
- } else {
- setErrorCodeAbort(4005);
- DBUG_RETURN(-1);
- }//if
- DBUG_RETURN(0);
- }//if
- } else {
- DBUG_RETURN(-1);
- }//if
- DBUG_RETURN(0);
- }
-
- if (aValue == NULL) {
- // NULL value in primary key
- setErrorCodeAbort(4505);
- DBUG_RETURN(-1);
- }//if
-
- if ( tAttrInfo == NULL ) {
- // Attribute name not found in table
- setErrorCodeAbort(4004);
- DBUG_RETURN(-1);
- }//if
-
- if (theStatus == GetValue || theStatus == SetValue){
- // All pk's defined
- setErrorCodeAbort(4225);
- DBUG_RETURN(-1);
- }//if
-
- ndbout_c("theStatus: %d", theStatus);
-
- // If we come here, set a general errorcode
- // and exit
- setErrorCodeAbort(4200);
- DBUG_RETURN(-1);
-
- equal_error1:
- setErrorCodeAbort(4205);
- DBUG_RETURN(-1);
-
- equal_error2:
- setErrorCodeAbort(4206);
- DBUG_RETURN(-1);
-}
-
-/******************************************************************************
- * int insertKEYINFO(const char* aValue, aStartPosition,
- * anAttrSizeInWords, Uint32 anAttrBitsInLastWord);
- *
- * Return Value: Return 0 : insertKEYINFO was succesful.
- * Return -1: In all other case.
- * Parameters: aValue: the data to insert into KEYINFO.
- * aStartPosition : Start position for Tuplekey in
- * KEYINFO (TCKEYREQ).
- * aKeyLenInByte : Length of tuplekey or part of tuplekey
- * anAttrBitsInLastWord : Nr of bits in last word.
- * Remark: Puts the the data into either TCKEYREQ signal
- * or KEYINFO signal.
- *****************************************************************************/
-int
-NdbOperation::insertKEYINFO(const char* aValue,
- register Uint32 aStartPosition,
- register Uint32 anAttrSizeInWords)
-{
- NdbApiSignal* tSignal;
- NdbApiSignal* tCurrentKEYINFO;
- //register NdbApiSignal* tTCREQ = theTCREQ;
- register Uint32 tAttrPos;
- Uint32 tPosition;
- Uint32 tEndPos;
- Uint32 tPos;
- Uint32 signalCounter;
-
-/*****************************************************************************
- * Calculate the end position of the attribute in the key information. *
- * Since the first attribute starts at position one we need to subtract *
- * one to get the correct end position. *
- * We must also remember the last word with only partial information. *
- *****************************************************************************/
- tEndPos = aStartPosition + anAttrSizeInWords - 1;
-
- if ((tEndPos < 9)) {
- register Uint32 tkeyData = *(Uint32*)aValue;
- //TcKeyReq* tcKeyReq = CAST_PTR(TcKeyReq, tTCREQ->getDataPtrSend());
- register Uint32* tDataPtr = (Uint32*)aValue;
- tAttrPos = 1;
- register Uint32* tkeyDataPtr = theKEYINFOptr + aStartPosition - 1;
- // (Uint32*)&tcKeyReq->keyInfo[aStartPosition - 1];
- do {
- tDataPtr++;
- *tkeyDataPtr = tkeyData;
- if (tAttrPos < anAttrSizeInWords) {
- ;
- } else {
- return 0;
- }//if
- tkeyData = *tDataPtr;
- tkeyDataPtr++;
- tAttrPos++;
- } while (1);
- return 0;
- }//if
-/*****************************************************************************
- * Allocate all the KEYINFO signals needed for this key before starting *
- * to fill the signals with data. This simplifies error handling and *
- * avoids duplication of code. *
- *****************************************************************************/
- tAttrPos = 0;
- signalCounter = 1;
- while(tEndPos > theTotalNrOfKeyWordInSignal)
- {
- tSignal = theNdb->getSignal();
- if (tSignal == NULL)
- {
- setErrorCodeAbort(4000);
- return -1;
- }
- if (tSignal->setSignal(m_keyInfoGSN) == -1)
- {
- setErrorCodeAbort(4001);
- return -1;
- }
- if (theTCREQ->next() != NULL)
- theLastKEYINFO->next(tSignal);
- else
- theTCREQ->next(tSignal);
-
- theLastKEYINFO = tSignal;
- theLastKEYINFO->next(NULL);
- theTotalNrOfKeyWordInSignal += 20;
- }
-
-/*****************************************************************************
- * Change to variable tPosition for more appropriate naming of rest of *
- * the code. We must set up current KEYINFO already here if the last *
- * word is a word which is set at LastWordLabel and at the same time *
- * this is the first word in a KEYINFO signal. *
- *****************************************************************************/
- tPosition = aStartPosition;
- tCurrentKEYINFO = theTCREQ->next();
-
-/*****************************************************************************
- * Start by filling up Key information in the 8 words allocated in the *
- * TC[KEY/INDX]REQ signal. *
- *****************************************************************************/
- while (tPosition < 9)
- {
- theKEYINFOptr[tPosition-1] = * (Uint32*)(aValue + (tAttrPos << 2));
- tAttrPos++;
- if (anAttrSizeInWords == tAttrPos)
- goto LastWordLabel;
- tPosition++;
- }
-
-/*****************************************************************************
- * We must set up the start position of the writing of Key information *
- * before we start the writing of KEYINFO signals. If the start is not *
- * the first word of the first KEYINFO signals then we must step forward*
- * to the proper KEYINFO signal and set the signalCounter properly. *
- * signalCounter is set to the actual position in the signal ( = 4 for *
- * first key word in KEYINFO signal. *
- *****************************************************************************/
- tPos = 8;
- while ((tPosition - tPos) > 20)
- {
- tCurrentKEYINFO = tCurrentKEYINFO->next();
- tPos += 20;
- }
- signalCounter = tPosition - tPos + 3;
-
-/*****************************************************************************
- * The loop that actually fills in the Key information into the KEYINFO *
- * signals. Can be optimised by writing larger chunks than 4 bytes at a *
- * time. *
- *****************************************************************************/
- do
- {
- if (signalCounter > 23)
- {
- tCurrentKEYINFO = tCurrentKEYINFO->next();
- signalCounter = 4;
- }
- tCurrentKEYINFO->setData(*(Uint32*)(aValue + (tAttrPos << 2)),
- signalCounter);
- tAttrPos++;
- if (anAttrSizeInWords == tAttrPos)
- goto LastWordLabel;
- tPosition++;
- signalCounter++;
- } while (1);
-
-LastWordLabel:
- return 0;
-}
-
-void
-NdbOperation::reorderKEYINFO()
-{
- Uint32 data[4000];
- Uint32 size = 4000;
- getKeyFromTCREQ(data, size);
- Uint32 pos = 1;
- Uint32 k;
- for (k = 0; k < m_accessTable->m_noOfKeys; k++) {
- Uint32 i;
- for (i = 0; i < m_accessTable->m_columns.size(); i++) {
- NdbColumnImpl* col = m_accessTable->m_columns[i];
- if (col->m_pk && col->m_keyInfoPos == k) {
- Uint32 j;
- for (j = 0; j < m_accessTable->m_noOfKeys; j++) {
- if (theTupleKeyDefined[j][0] == i) {
- Uint32 off = theTupleKeyDefined[j][1] - 1;
- Uint32 len = theTupleKeyDefined[j][2];
- assert(off < 4000 && off + len <= 4000);
- int ret = insertKEYINFO((char*)&data[off], pos, len);
- assert(ret == 0);
- pos += len;
- break;
- }
- }
- assert(j < m_accessTable->m_columns.size());
- break;
- }
- }
- assert(i < m_accessTable->m_columns.size());
- }
-}
-
-int
-NdbOperation::getKeyFromTCREQ(Uint32* data, Uint32 & size)
-{
- assert(size >= theTupKeyLen && theTupKeyLen > 0);
- size = theTupKeyLen;
- unsigned pos = 0;
- while (pos < 8 && pos < size) {
- data[pos] = theKEYINFOptr[pos];
- pos++;
- }
- NdbApiSignal* tSignal = theTCREQ->next();
- unsigned n = 0;
- while (pos < size) {
- if (n == 20) {
- tSignal = tSignal->next();
- n = 0;
- }
- data[pos++] = tSignal->getDataPtrSend()[3 + n++];
- }
- return 0;
-}
-
-int
-NdbOperation::handle_distribution_key(const Uint64* value, Uint32 len)
-{
- if(theDistrKeyIndicator_ == 1 ||
- (theNoOfTupKeyLeft > 0 && m_accessTable->m_noOfDistributionKeys > 1))
- {
- return 0;
- }
-
- if(m_accessTable->m_noOfDistributionKeys == 1)
- {
- setPartitionHash(value, len);
- }
- else if(theTCREQ->readSignalNumber() == GSN_TCKEYREQ)
- {
- // No support for combined distribution key and scan
-
- /**
- * Copy distribution key to linear memory
- */
- NdbColumnImpl* const * cols = m_accessTable->m_columns.getBase();
- Uint64 tmp[1000];
-
- Uint32 chunk = 8;
- Uint32* dst = (Uint32*)tmp;
- NdbApiSignal* tSignal = theTCREQ;
- Uint32* src = ((TcKeyReq*)tSignal->getDataPtrSend())->keyInfo;
- if(tSignal->readSignalNumber() == GSN_SCAN_TABREQ)
- {
- tSignal = tSignal->next();
- src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
- chunk = KeyInfo::DataLength;
- }
-
- for(unsigned i = m_accessTable->m_columns.size(); i>0; cols++, i--)
- {
- if (!(* cols)->getPrimaryKey())
- continue;
-
- NdbColumnImpl* tAttrInfo = * cols;
- Uint32 sizeInBytes;
- switch(tAttrInfo->m_arrayType){
- default:
- case NDB_ARRAYTYPE_FIXED:
- sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
- break;
- case NDB_ARRAYTYPE_SHORT_VAR:
- sizeInBytes = 1 + *(char*)src;
- break;
- case NDB_ARRAYTYPE_MEDIUM_VAR:
- sizeInBytes = 2 + uint2korr((char*)src);
- break;
- }
-
- Uint32 currLen = (sizeInBytes + 3) >> 2;
- if (tAttrInfo->getDistributionKey())
- {
- while (currLen >= chunk)
- {
- memcpy(dst, src, 4*chunk);
- dst += chunk;
- tSignal = tSignal->next();
- src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
- currLen -= chunk;
- chunk = KeyInfo::DataLength;
- }
-
- memcpy(dst, src, 4*currLen);
- dst += currLen;
- src += currLen;
- chunk -= currLen;
- }
- else
- {
- while (currLen >= chunk)
- {
- tSignal = tSignal->next();
- src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
- currLen -= chunk;
- chunk = KeyInfo::DataLength;
- }
-
- src += currLen;
- chunk -= currLen;
- }
- }
- setPartitionHash(tmp, dst - (Uint32*)tmp);
- }
- return 0;
-}
-
-void
-NdbOperation::setPartitionHash(Uint32 value)
-{
- union {
- Uint32 tmp32;
- Uint64 tmp64;
- };
-
- tmp32 = value;
- setPartitionHash(&tmp64, 1);
-}
-
-void
-NdbOperation::setPartitionHash(const Uint64* value, Uint32 len)
-{
- Uint32 buf[4];
- md5_hash(buf, value, len);
- setPartitionId(buf[1]);
-}
-
-void
-NdbOperation::setPartitionId(Uint32 value)
-{
- theDistributionKey = value;
- theDistrKeyIndicator_ = 1;
- DBUG_PRINT("info", ("NdbOperation::setPartitionId: %u",
- theDistributionKey));
-}
-
-Uint32
-NdbOperation::getPartitionId() const
-{
- DBUG_PRINT("info", ("NdbOperation::getPartitionId: %u ind=%d",
- theDistributionKey, theDistrKeyIndicator_));
- return theDistributionKey;
-}
diff --git a/storage/ndb/src/ndbapi/NdbPool.cpp b/storage/ndb/src/ndbapi/NdbPool.cpp
deleted file mode 100644
index 9e5254469bd..00000000000
--- a/storage/ndb/src/ndbapi/NdbPool.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <Ndb.hpp>
-#include "NdbPoolImpl.hpp"
-#include <NdbPool.hpp>
-
-static NdbPool* m_pool = 0;
-
-bool
-create_instance(Ndb_cluster_connection* cc,
- Uint32 max_ndb_objects,
- Uint32 no_conn_obj,
- Uint32 init_no_ndb_objects)
-{
- if (m_pool != NULL) {
- return false;
- }
- m_pool = NdbPool::create_instance(cc,
- max_ndb_objects,
- no_conn_obj,
- init_no_ndb_objects);
- if (m_pool == NULL) {
- return false;
- }
- return true;
-}
-
-void
-drop_instance()
-{
- if (m_pool == NULL) {
- return;
- }
- NdbPool::drop_instance();
- m_pool = NULL;
-}
-
-Ndb*
-get_ndb_object(Uint32 &hint_id,
- const char* a_catalog_name,
- const char* a_schema_name)
-{
- if (m_pool == NULL) {
- return NULL;
- }
- return m_pool->get_ndb_object(hint_id, a_catalog_name, a_schema_name);
-}
-
-void
-return_ndb_object(Ndb* returned_object, Uint32 id)
-{
- if (m_pool == NULL) {
- return;
- }
- m_pool->return_ndb_object(returned_object, id);
-}
-
diff --git a/storage/ndb/src/ndbapi/NdbPoolImpl.cpp b/storage/ndb/src/ndbapi/NdbPoolImpl.cpp
deleted file mode 100644
index d921a78fa58..00000000000
--- a/storage/ndb/src/ndbapi/NdbPoolImpl.cpp
+++ /dev/null
@@ -1,528 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "NdbPoolImpl.hpp"
-
-NdbMutex *NdbPool::pool_mutex = NULL;
-NdbPool *the_pool = NULL;
-
-NdbPool*
-NdbPool::create_instance(Ndb_cluster_connection* cc,
- Uint32 max_ndb_obj,
- Uint32 no_conn_obj,
- Uint32 init_no_ndb_objects)
-{
- if (!initPoolMutex()) {
- return NULL;
- }
- NdbMutex_Lock(pool_mutex);
- NdbPool* a_pool;
- if (the_pool != NULL) {
- a_pool = NULL;
- } else {
- the_pool = new NdbPool(cc, max_ndb_obj, no_conn_obj);
- if (!the_pool->init(init_no_ndb_objects)) {
- delete the_pool;
- the_pool = NULL;
- }
- a_pool = the_pool;
- }
- NdbMutex* temp = pool_mutex;
- if (a_pool == NULL) {
- pool_mutex = NULL;
- }
- NdbMutex_Unlock(pool_mutex);
- if (a_pool == NULL) {
- NdbMutex_Destroy(temp);
- }
- return a_pool;
-}
-
-void
-NdbPool::drop_instance()
-{
- if (pool_mutex == NULL) {
- return;
- }
- NdbMutex_Lock(pool_mutex);
- the_pool->release_all();
- delete the_pool;
- the_pool = NULL;
- NdbMutex* temp = pool_mutex;
- NdbMutex_Unlock(temp);
- NdbMutex_Destroy(temp);
-}
-
-bool
-NdbPool::initPoolMutex()
-{
- bool ret_result = false;
- if (pool_mutex == NULL) {
- pool_mutex = NdbMutex_Create();
- ret_result = ((pool_mutex == NULL) ? false : true);
- }
- return ret_result;
-}
-
-NdbPool::NdbPool(Ndb_cluster_connection* cc,
- Uint32 max_no_objects,
- Uint32 no_conn_objects)
-{
- if (no_conn_objects > 1024) {
- no_conn_objects = 1024;
- }
- if (max_no_objects > MAX_NDB_OBJECTS) {
- max_no_objects = MAX_NDB_OBJECTS;
- } else if (max_no_objects == 0) {
- max_no_objects = 1;
- }
- m_max_ndb_objects = max_no_objects;
- m_no_of_conn_objects = no_conn_objects;
- m_no_of_objects = 0;
- m_waiting = 0;
- m_pool_reference = NULL;
- m_hash_entry = NULL;
- m_first_free = NULL_POOL;
- m_first_not_in_use = NULL_POOL;
- m_last_free = NULL_POOL;
- input_pool_cond = NULL;
- output_pool_cond = NULL;
- m_output_queue = 0;
- m_input_queue = 0;
- m_signal_count = 0;
- m_cluster_connection = cc;
-}
-
-NdbPool::~NdbPool()
-{
- NdbCondition_Destroy(input_pool_cond);
- NdbCondition_Destroy(output_pool_cond);
-}
-
-void
-NdbPool::release_all()
-{
- int i;
- for (i = 0; i < m_max_ndb_objects + 1; i++) {
- if (m_pool_reference[i].ndb_reference != NULL) {
- assert(m_pool_reference[i].in_use);
- assert(m_pool_reference[i].free_entry);
- delete m_pool_reference[i].ndb_reference;
- }
- }
- delete [] m_pool_reference;
- delete [] m_hash_entry;
- m_pool_reference = NULL;
- m_hash_entry = NULL;
-}
-
-bool
-NdbPool::init(Uint32 init_no_objects)
-{
- bool ret_result = false;
- int i;
- do {
- input_pool_cond = NdbCondition_Create();
- output_pool_cond = NdbCondition_Create();
- if (input_pool_cond == NULL || output_pool_cond == NULL) {
- break;
- }
- if (init_no_objects > m_max_ndb_objects) {
- init_no_objects = m_max_ndb_objects;
- }
- if (init_no_objects == 0) {
- init_no_objects = 1;
- }
- m_pool_reference = new NdbPool::POOL_STRUCT[m_max_ndb_objects + 1];
- m_hash_entry = new Uint8[POOL_HASH_TABLE_SIZE];
-
- if ((m_pool_reference == NULL) || (m_hash_entry == NULL)) {
- delete [] m_pool_reference;
- delete [] m_hash_entry;
- break;
- }
- for (i = 0; i < m_max_ndb_objects + 1; i++) {
- m_pool_reference[i].ndb_reference = NULL;
- m_pool_reference[i].in_use = false;
- m_pool_reference[i].next_free_object = i+1;
- m_pool_reference[i].prev_free_object = i-1;
- m_pool_reference[i].next_db_object = NULL_POOL;
- m_pool_reference[i].prev_db_object = NULL_POOL;
- }
- for (i = 0; i < POOL_HASH_TABLE_SIZE; i++) {
- m_hash_entry[i] = NULL_HASH;
- }
- m_pool_reference[m_max_ndb_objects].next_free_object = NULL_POOL;
- m_pool_reference[1].prev_free_object = NULL_POOL;
- m_first_not_in_use = 1;
- m_no_of_objects = init_no_objects;
- for (i = init_no_objects; i > 0 ; i--) {
- Uint32 fake_id;
- if (!allocate_ndb(fake_id, (const char*)NULL, (const char*)NULL)) {
- release_all();
- break;
- }
- }
- ret_result = true;
- break;
- } while (1);
- return ret_result;
-}
-
-/*
-Get an Ndb object.
-Input:
-hint_id: 0 = no hint, otherwise a hint of which Ndb object the thread
- used the last time.
-a_db_name: NULL = don't check for database specific Ndb object, otherwise
- a hint of which database is preferred.
-Output:
-hint_id: Returns id of Ndb object returned
-Return value: Ndb object pointer
-*/
-Ndb*
-NdbPool::get_ndb_object(Uint32 &hint_id,
- const char* a_catalog_name,
- const char* a_schema_name)
-{
- Ndb* ret_ndb = NULL;
- Uint32 hash_entry = compute_hash(a_schema_name);
- NdbMutex_Lock(pool_mutex);
- while (1) {
- /*
- We start by checking if we can use the hinted Ndb object.
- */
- if ((ret_ndb = get_hint_ndb(hint_id, hash_entry)) != NULL) {
- break;
- }
- /*
- The hinted Ndb object was not free. We need to allocate another object.
- We start by checking for a free Ndb object connected to the same database.
- */
- if (a_schema_name && (ret_ndb = get_db_hash(hint_id,
- hash_entry,
- a_catalog_name,
- a_schema_name))) {
- break;
- }
- /*
- No Ndb object connected to the preferred database was found.
- We look for a free Ndb object in general.
- */
- if ((ret_ndb = get_free_list(hint_id, hash_entry)) != NULL) {
- break;
- }
- /*
- No free Ndb object was found. If we haven't allocated objects up until the
- maximum number yet then we can allocate a new Ndb object here.
- */
- if (m_no_of_objects < m_max_ndb_objects) {
- if (allocate_ndb(hint_id, a_catalog_name, a_schema_name)) {
- assert((ret_ndb = get_hint_ndb(hint_id, hash_entry)) != NULL);
- break;
- }
- }
- /*
- We need to wait until an Ndb object becomes
- available.
- */
- if ((ret_ndb = wait_free_ndb(hint_id)) != NULL) {
- break;
- }
- /*
- Not even after waiting were we able to get hold of an Ndb object. We
- return NULL to indicate this problem.
- */
- ret_ndb = NULL;
- break;
- }
- NdbMutex_Unlock(pool_mutex);
- if (ret_ndb != NULL) {
- /*
- We need to set the catalog and schema name of the Ndb object before
- returning it to the caller.
- */
- ret_ndb->setCatalogName(a_catalog_name);
- ret_ndb->setSchemaName(a_schema_name);
- }
- return ret_ndb;
-}
-
-void
-NdbPool::return_ndb_object(Ndb* returned_ndb, Uint32 id)
-{
- NdbMutex_Lock(pool_mutex);
- assert(id <= m_max_ndb_objects);
- assert(id != 0);
- assert(returned_ndb == m_pool_reference[id].ndb_reference);
- bool wait_cond = m_waiting;
- if (wait_cond) {
- NdbCondition* pool_cond;
- if (m_signal_count > 0) {
- pool_cond = output_pool_cond;
- m_signal_count--;
- } else {
- pool_cond = input_pool_cond;
- }
- add_wait_list(id);
- NdbMutex_Unlock(pool_mutex);
- NdbCondition_Signal(pool_cond);
- } else {
- add_free_list(id);
- add_db_hash(id);
- NdbMutex_Unlock(pool_mutex);
- }
-}
-
-bool
-NdbPool::allocate_ndb(Uint32 &id,
- const char* a_catalog_name,
- const char* a_schema_name)
-{
- Ndb* a_ndb;
- if (m_first_not_in_use == NULL_POOL) {
- return false;
- }
- if (a_schema_name) {
- a_ndb = new Ndb(m_cluster_connection, a_schema_name, a_catalog_name);
- } else {
- a_ndb = new Ndb(m_cluster_connection, "");
- }
- if (a_ndb == NULL) {
- return false;
- }
- a_ndb->init(m_no_of_conn_objects);
- m_no_of_objects++;
-
- id = m_first_not_in_use;
- Uint32 allocated_id = m_first_not_in_use;
- m_first_not_in_use = m_pool_reference[allocated_id].next_free_object;
-
- m_pool_reference[allocated_id].ndb_reference = a_ndb;
- m_pool_reference[allocated_id].in_use = true;
- m_pool_reference[allocated_id].free_entry = false;
-
- add_free_list(allocated_id);
- add_db_hash(allocated_id);
- return true;
-}
-
-void
-NdbPool::add_free_list(Uint32 id)
-{
- assert(!m_pool_reference[id].free_entry);
- assert(m_pool_reference[id].in_use);
- m_pool_reference[id].free_entry = true;
- m_pool_reference[id].next_free_object = m_first_free;
- m_pool_reference[id].prev_free_object = (Uint8)NULL_POOL;
- m_first_free = (Uint8)id;
- if (m_last_free == (Uint8)NULL_POOL) {
- m_last_free = (Uint8)id;
- }
-}
-
-void
-NdbPool::add_db_hash(Uint32 id)
-{
- Ndb* t_ndb = m_pool_reference[id].ndb_reference;
- const char* schema_name = t_ndb->getSchemaName();
- Uint32 hash_entry = compute_hash(schema_name);
- Uint8 next_db_entry = m_hash_entry[hash_entry];
- m_pool_reference[id].next_db_object = next_db_entry;
- m_pool_reference[id].prev_db_object = (Uint8)NULL_HASH;
- m_hash_entry[hash_entry] = (Uint8)id;
-}
-
-Ndb*
-NdbPool::get_free_list(Uint32 &id, Uint32 hash_entry)
-{
- if (m_first_free == NULL_POOL) {
- return NULL;
- }
- id = m_first_free;
- Ndb* ret_ndb = get_hint_ndb(m_first_free, hash_entry);
- assert(ret_ndb != NULL);
- return ret_ndb;
-}
-
-Ndb*
-NdbPool::get_db_hash(Uint32 &id,
- Uint32 hash_entry,
- const char *a_catalog_name,
- const char *a_schema_name)
-{
- Uint32 entry_id = m_hash_entry[hash_entry];
- bool found = false;
- while (entry_id != NULL_HASH) {
- Ndb* t_ndb = m_pool_reference[entry_id].ndb_reference;
- const char *a_ndb_catalog_name = t_ndb->getCatalogName();
- if (strcmp(a_catalog_name, a_ndb_catalog_name) == 0) {
- const char *a_ndb_schema_name = t_ndb->getSchemaName();
- if (strcmp(a_schema_name, a_ndb_schema_name) == 0) {
- found = true;
- break;
- }
- }
- entry_id = m_pool_reference[entry_id].next_db_object;
- }
- if (found) {
- id = entry_id;
- Ndb* ret_ndb = get_hint_ndb(entry_id, hash_entry);
- assert(ret_ndb != NULL);
- return ret_ndb;
- }
- return NULL;
-}
-
-Ndb*
-NdbPool::get_hint_ndb(Uint32 hint_id, Uint32 hash_entry)
-{
- Ndb* ret_ndb = NULL;
- do {
- if ((hint_id != 0) &&
- (hint_id <= m_max_ndb_objects) &&
- (m_pool_reference[hint_id].in_use) &&
- (m_pool_reference[hint_id].free_entry)) {
- ret_ndb = m_pool_reference[hint_id].ndb_reference;
- if (ret_ndb != NULL) {
- break;
- } else {
- assert(false);
- }
- }
- return NULL;
- } while (1);
- /*
- This is where we remove the entry from the free list and from the db hash
- table.
- */
- remove_free_list(hint_id);
- remove_db_hash(hint_id, hash_entry);
- return ret_ndb;
-}
-
-void
-NdbPool::remove_free_list(Uint32 id)
-{
- Uint8 next_free_entry = m_pool_reference[id].next_free_object;
- Uint8 prev_free_entry = m_pool_reference[id].prev_free_object;
- if (prev_free_entry == (Uint8)NULL_POOL) {
- m_first_free = next_free_entry;
- } else {
- m_pool_reference[prev_free_entry].next_free_object = next_free_entry;
- }
- if (next_free_entry == (Uint8)NULL_POOL) {
- m_last_free = prev_free_entry;
- } else {
- m_pool_reference[next_free_entry].prev_free_object = prev_free_entry;
- }
- m_pool_reference[id].next_free_object = NULL_POOL;
- m_pool_reference[id].prev_free_object = NULL_POOL;
- m_pool_reference[id].free_entry = false;
-}
-
-void
-NdbPool::remove_db_hash(Uint32 id, Uint32 hash_entry)
-{
- Uint8 next_free_entry = m_pool_reference[id].next_db_object;
- Uint8 prev_free_entry = m_pool_reference[id].prev_db_object;
- if (prev_free_entry == (Uint8)NULL_HASH) {
- m_hash_entry[hash_entry] = next_free_entry;
- } else {
- m_pool_reference[prev_free_entry].next_db_object = next_free_entry;
- }
- if (next_free_entry == (Uint8)NULL_HASH) {
- ;
- } else {
- m_pool_reference[next_free_entry].prev_db_object = prev_free_entry;
- }
- m_pool_reference[id].next_db_object = NULL_HASH;
- m_pool_reference[id].prev_db_object = NULL_HASH;
-}
-
-Uint32
-NdbPool::compute_hash(const char *a_schema_name)
-{
- Uint32 len = strlen(a_schema_name);
- Uint32 h = 147;
- for (Uint32 i = 0; i < len; i++) {
- Uint32 c = a_schema_name[i];
- h = (h << 5) + h + c;
- }
- h &= (POOL_HASH_TABLE_SIZE - 1);
- return h;
-}
-
-Ndb*
-NdbPool::wait_free_ndb(Uint32 &id)
-{
- int res;
- int time_out = 3500;
- do {
- NdbCondition* tmp = input_pool_cond;
- m_waiting++;
- m_input_queue++;
- time_out -= 500;
- res = NdbCondition_WaitTimeout(input_pool_cond, pool_mutex, time_out);
- if (tmp == input_pool_cond) {
- m_input_queue--;
- } else {
- m_output_queue--;
- if (m_output_queue == 0) {
- switch_condition_queue();
- }
- }
- m_waiting--;
- } while (res == 0 && m_first_wait == NULL_POOL);
- if (res != 0 && m_first_wait == NULL_POOL) {
- return NULL;
- }
- id = m_first_wait;
- remove_wait_list();
- assert(m_waiting != 0 || m_first_wait == NULL_POOL);
- return m_pool_reference[id].ndb_reference;
-}
-
-void
-NdbPool::remove_wait_list()
-{
- Uint32 id = m_first_wait;
- m_first_wait = m_pool_reference[id].next_free_object;
- m_pool_reference[id].next_free_object = NULL_POOL;
- m_pool_reference[id].prev_free_object = NULL_POOL;
- m_pool_reference[id].free_entry = false;
-}
-
-void
-NdbPool::add_wait_list(Uint32 id)
-{
- m_pool_reference[id].next_free_object = m_first_wait;
- m_first_wait = id;
-}
-
-void
-NdbPool::switch_condition_queue()
-{
- m_signal_count = m_input_queue;
- Uint8 move_queue = m_input_queue;
- m_input_queue = m_output_queue;
- m_output_queue = move_queue;
-
- NdbCondition* move_cond = input_pool_cond;
- input_pool_cond = output_pool_cond;
- output_pool_cond = move_cond;
-}
-
diff --git a/storage/ndb/src/ndbapi/NdbPoolImpl.hpp b/storage/ndb/src/ndbapi/NdbPoolImpl.hpp
deleted file mode 100644
index 5764ac5871b..00000000000
--- a/storage/ndb/src/ndbapi/NdbPoolImpl.hpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/**
- @section ndbPool Pooling of NDB objects
- This class implements pooling of NDB objects to support MySQL, ODBC and
- any application with a great number of threads.
-
- The general idea is to let the NdbPool class administer all Ndb objects.
- When a thread needs a Ndb object it request a Ndb object from the Pool.
- This interface contains some hints to ensure that the proper Ndb object
- is returned.
-
- The object contains an array of references to all Ndb objects together with
- an indication of whether the object is free or not.
-
- The idea is that the thread should keep track of the Ndb object it used the
- last time. If this object is still free it will simply get this object
- back. If the number of threads do not exceed the number of Ndb objects this
- will always be successful. In certain situations the number of threads will
- be much greater than the number of Ndb objects. In this situation the Pool
- will attempt to provide an object that is attached to the same schema
- as the thread is connected to. If this is not possible it will attempt to
- get any free Ndb object. If not even this is possible the Pool will wait
- until an Ndb object becomes free. If an Ndb object becomes available in
- time it will deliver this Ndb object. In the worst case the call will
- time-out and return NULL to indicate no free Ndb object was found in time.
-
- The implementation uses an array of structs which contain a reference to a
- Ndb object, whether it is in use currently and a number of references to
- set up linked lists of
- 1) Free objects on a schema
- 2) Free objects in LIFO order
-
- Usage:
- The class is a singleton.
- The first step is to call create_instance(..). If successful this will
- create the NdbPool object and return a reference to it. When completed
- drop_instance is called to remove the NdbPool object and all memory and
- other resources attached to it.
-
- After initialising the NdbPool object all threads can now start using the
- NdbPool. There are two methods in normal usage mode. The first
- get_ndb_object gets a Ndb object and the second return_ndb_object returns
- an Ndb object. The user of the NdbPool must keep track of the identity
- of the Ndb object. The idea is that this identity can also be used to
- find the object quickly again unless another thread have taken it. If the
- user wants any Ndb object it requests identity 0 which means any here.
-
- When constructing the NdbPool one can set the number of NdbConnection
- objects which are allowed in all Ndb objects. For use in synchronous
- applications such as the MySQL server 4 objects should be enough. When
- using the NdbPool for asynchronous applications one should use 1024 to
- enable a high level of parallelism. It is also possible to set the
- maximum number of Ndb objects in the pool and the initial number of
- Ndb objects allocated.
-*/
-
-#ifndef NdbPool_H
-#define NdbPool_H
-
-#include <Ndb.hpp>
-#include <NdbMutex.h>
-#include <NdbCondition.h>
-#include <NdbOut.hpp>
-
-class NdbPool {
-#define NULL_POOL 0
-#define NULL_HASH 0xFF
-#define POOL_HASH_TABLE_SIZE 32
-#define MAX_NDB_OBJECTS 240
- struct POOL_STRUCT {
- Ndb* ndb_reference;
- bool in_use;
- bool free_entry;
- Uint16 next_free_object;
- Uint16 prev_free_object;
- Uint16 next_db_object;
- Uint16 prev_db_object;
- };
- public:
- static NdbPool* create_instance(Ndb_cluster_connection*,
- Uint32 max_ndb_objects = 240,
- Uint32 no_conn_obj = 4,
- Uint32 init_no_ndb_objects = 8);
- static void drop_instance();
- Ndb* get_ndb_object(Uint32 &hint_id,
- const char* a_catalog_name,
- const char* a_schema_name);
- void return_ndb_object(Ndb* returned_object, Uint32 id);
- private:
- bool init(Uint32 initial_no_of_ndb_objects = 8);
- void release_all();
- static bool initPoolMutex();
- NdbPool(Ndb_cluster_connection*,
- Uint32 max_no_of_ndb_objects, Uint32 no_conn_objects);
- ~NdbPool();
- /*
- We have three lists:
- 1) A list for entries not in use
- 2) A list for free entries
- 3) A hash table with schema name and database name as key
-
- These lists are all initialised in the init call.
- The list for entries not in use is very simple since the current
- implementation have not yet any handling of dropping Ndb objects
- until all Ndb objects are dropped.
- */
- void add_free_list(Uint32 id);
- void remove_free_list(Uint32 id);
- Ndb* get_free_list(Uint32 &id, Uint32 hash_entry);
-
- void add_db_hash(Uint32 id);
- void remove_db_hash(Uint32 id, Uint32 hash_entry);
- Ndb* get_db_hash(Uint32 &id,
- Uint32 hash_entry,
- const char* a_catalog_name,
- const char* a_schema_name);
-
- bool allocate_ndb(Uint32 &id,
- const char* a_catalog_name,
- const char* a_schema_name);
- Ndb* get_hint_ndb(Uint32 id, Uint32 hash_entry);
- Ndb* wait_free_ndb(Uint32 &id);
- Uint32 compute_hash(const char *a_schema_name);
- void add_wait_list(Uint32 id);
- void remove_wait_list();
- void switch_condition_queue();
-
- static NdbMutex *pool_mutex;
- struct NdbCondition *input_pool_cond;
- struct NdbCondition *output_pool_cond;
-
- POOL_STRUCT *m_pool_reference;
- Uint8 *m_hash_entry;
-
- bool m_inited;
- Uint32 m_no_of_conn_objects;
-
- Uint16 m_no_of_objects;
- Uint16 m_max_ndb_objects;
- Uint16 m_first_free;
- Uint16 m_last_free;
- Uint16 m_first_not_in_use;
- Uint16 m_waiting;
- Uint16 m_first_wait;
- Uint16 m_input_queue;
- Uint16 m_output_queue;
- Uint16 m_signal_count;
-
- Ndb_cluster_connection * m_cluster_connection;
-};
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbRecAttr.cpp b/storage/ndb/src/ndbapi/NdbRecAttr.cpp
deleted file mode 100644
index 142b08e051f..00000000000
--- a/storage/ndb/src/ndbapi/NdbRecAttr.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-#include <NdbRecAttr.hpp>
-#include <NdbBlob.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <NdbTCP.h>
-
-NdbRecAttr::NdbRecAttr(Ndb*)
-{
- theStorageX = 0;
- init();
-}
-
-NdbRecAttr::~NdbRecAttr()
-{
- release();
-}
-
-int
-NdbRecAttr::setup(const class NdbDictionary::Column* col, char* aValue)
-{
- return setup(&(col->m_impl), aValue);
-}
-
-int
-NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue)
-{
- Uint32 tAttrSize = anAttrInfo->m_attrSize;
- Uint32 tArraySize = anAttrInfo->m_arraySize;
- Uint32 tAttrByteSize = tAttrSize * tArraySize;
-
- m_column = anAttrInfo;
-
- theAttrId = anAttrInfo->m_attrId;
- m_size_in_bytes = tAttrByteSize;
- theValue = aValue;
-
- if (theStorageX)
- delete[] theStorageX;
-
- // check alignment to signal data
- // a future version could check alignment per data type as well
-
- if (aValue != NULL && (UintPtr(aValue)&3) == 0 && (tAttrByteSize&3) == 0) {
- theStorageX = NULL;
- theRef = aValue;
- return 0;
- }
- if (tAttrByteSize <= 32) {
- theStorageX = NULL;
- theStorage[0] = 0;
- theStorage[1] = 0;
- theStorage[2] = 0;
- theStorage[3] = 0;
- theRef = theStorage;
- return 0;
- }
- Uint32 tSize = (tAttrByteSize + 7) >> 3;
- Uint64* tRef = new Uint64[tSize];
- if (tRef != NULL) {
- for (Uint32 i = 0; i < tSize; i++) {
- tRef[i] = 0;
- }
- theStorageX = tRef;
- theRef = tRef;
- return 0;
- }
- errno = ENOMEM;
- return -1;
-}
-
-void
-NdbRecAttr::copyout()
-{
- char* tRef = (char*)theRef;
- char* tValue = theValue;
- if (tRef != tValue && tRef != NULL && tValue != NULL) {
- Uint32 n = m_size_in_bytes;
- while (n-- > 0) {
- *tValue++ = *tRef++;
- }
- }
-}
-
-NdbRecAttr *
-NdbRecAttr::clone() const {
- NdbRecAttr * ret = new NdbRecAttr(0);
- if (ret == NULL)
- {
- errno = ENOMEM;
- return NULL;
- }
- ret->theAttrId = theAttrId;
- ret->m_size_in_bytes = m_size_in_bytes;
- ret->m_column = m_column;
-
- Uint32 n = m_size_in_bytes;
- if(n <= 32){
- ret->theRef = (char*)&ret->theStorage[0];
- ret->theStorageX = 0;
- ret->theValue = 0;
- } else {
- ret->theStorageX = new Uint64[((n + 7) >> 3)];
- if (ret->theStorageX == NULL)
- {
- delete ret;
- errno = ENOMEM;
- return NULL;
- }
- ret->theRef = (char*)ret->theStorageX;
- ret->theValue = 0;
- }
- memcpy(ret->theRef, theRef, n);
- return ret;
-}
-
-bool
-NdbRecAttr::receive_data(const Uint32 * data, Uint32 sz)
-{
- if(sz)
- {
- if(!copyoutRequired())
- memcpy(theRef, data, sz);
- else
- memcpy(theValue, data, sz);
- m_size_in_bytes= sz;
- return true;
- }
- else
- {
- return setNULL();
- }
- return false;
-}
-
-NdbRecordPrintFormat::NdbRecordPrintFormat()
-{
- fields_terminated_by= ";";
- start_array_enclosure= "[";
- end_array_enclosure= "]";
- fields_enclosed_by= "";
- fields_optionally_enclosed_by= "\"";
- lines_terminated_by= "\n";
- hex_prefix= "H'";
- null_string= "[NULL]";
- hex_format= 0;
-}
-NdbRecordPrintFormat::~NdbRecordPrintFormat() {}
-static const NdbRecordPrintFormat default_print_format;
-
-static void
-ndbrecattr_print_string(NdbOut& out, const NdbRecordPrintFormat &f,
- const char *type, bool is_binary,
- const char *aref, unsigned sz)
-{
- const unsigned char* ref = (const unsigned char*)aref;
- int i, len, printable= 1;
- // trailing zeroes are not printed
- for (i=sz-1; i >= 0; i--)
- if (ref[i] == 0) sz--;
- else break;
- if (!is_binary)
- {
- // trailing spaces are not printed
- for (i=sz-1; i >= 0; i--)
- if (ref[i] == 32) sz--;
- else break;
- }
- if (is_binary && f.hex_format)
- {
- if (sz == 0)
- {
- out.print("0x0");
- return;
- }
- out.print("0x");
- for (len = 0; len < (int)sz; len++)
- out.print("%02X", (int)ref[len]);
- return;
- }
- if (sz == 0) return; // empty
-
- for (len=0; len < (int)sz && ref[i] != 0; len++)
- if (printable && !isprint((int)ref[i]))
- printable= 0;
-
- if (printable)
- out.print("%.*s", len, ref);
- else
- {
- out.print("0x");
- for (i=0; i < len; i++)
- out.print("%02X", (int)ref[i]);
- }
- if (len != (int)sz)
- {
- out.print("[");
- for (i= len+1; ref[i] != 0; i++)
- out.print("%u]",len-i);
- assert((int)sz > i);
- ndbrecattr_print_string(out,f,type,is_binary,aref+i,sz-i);
- }
-}
-
-NdbOut&
-ndbrecattr_print_formatted(NdbOut& out, const NdbRecAttr &r,
- const NdbRecordPrintFormat &f)
-{
- if (r.isNULL())
- {
- out << f.null_string;
- return out;
- }
-
- const NdbDictionary::Column* c = r.getColumn();
- uint length = c->getLength();
- {
- const char *fields_optionally_enclosed_by;
- if (f.fields_enclosed_by[0] == '\0')
- fields_optionally_enclosed_by=
- f.fields_optionally_enclosed_by;
- else
- fields_optionally_enclosed_by= "";
- out << f.fields_enclosed_by;
- Uint32 j;
- switch(r.getType()){
- case NdbDictionary::Column::Bigunsigned:
- out << r.u_64_value();
- break;
- case NdbDictionary::Column::Bit:
- out << f.hex_prefix << "0x";
- {
- const Uint32 *buf = (Uint32 *)r.aRef();
- int k = (length+31)/32;
- while (k > 0 && (buf[--k] == 0))
- ;
- out.print("%X", buf[k]);
- while (k > 0)
- out.print("%.8X", buf[--k]);
- }
- break;
- case NdbDictionary::Column::Unsigned:
- if (length > 1)
- out << f.start_array_enclosure;
- out << *(Uint32*)r.aRef();
- for (j = 1; j < length; j++)
- out << " " << *((Uint32*)r.aRef() + j);
- if (length > 1)
- out << f.end_array_enclosure;
- break;
- case NdbDictionary::Column::Mediumunsigned:
- out << r.u_medium_value();
- break;
- case NdbDictionary::Column::Smallunsigned:
- out << r.u_short_value();
- break;
- case NdbDictionary::Column::Tinyunsigned:
- out << (unsigned) r.u_8_value();
- break;
- case NdbDictionary::Column::Bigint:
- out << r.int64_value();
- break;
- case NdbDictionary::Column::Int:
- out << r.int32_value();
- break;
- case NdbDictionary::Column::Mediumint:
- out << r.medium_value();
- break;
- case NdbDictionary::Column::Smallint:
- out << r.short_value();
- break;
- case NdbDictionary::Column::Tinyint:
- out << (int) r.int8_value();
- break;
- case NdbDictionary::Column::Binary:
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- j = r.get_size_in_bytes();
- ndbrecattr_print_string(out,f,"Binary", true, r.aRef(), j);
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- break;
- case NdbDictionary::Column::Char:
- out << fields_optionally_enclosed_by;
- j = r.get_size_in_bytes();
- ndbrecattr_print_string(out,f,"Char", false, r.aRef(), j);
- out << fields_optionally_enclosed_by;
- break;
- case NdbDictionary::Column::Varchar:
- {
- out << fields_optionally_enclosed_by;
- unsigned len = *(const unsigned char*)r.aRef();
- ndbrecattr_print_string(out,f,"Varchar", false, r.aRef()+1,len);
- j = length;
- out << fields_optionally_enclosed_by;
- }
- break;
- case NdbDictionary::Column::Varbinary:
- {
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- unsigned len = *(const unsigned char*)r.aRef();
- ndbrecattr_print_string(out,f,"Varbinary", true, r.aRef()+1,len);
- j = length;
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- }
- break;
- case NdbDictionary::Column::Float:
- out << r.float_value();
- break;
- case NdbDictionary::Column::Double:
- out << r.double_value();
- break;
- case NdbDictionary::Column::Olddecimal:
- {
- short len = 1 + c->getPrecision() + (c->getScale() > 0);
- out.print("%.*s", len, r.aRef());
- }
- break;
- case NdbDictionary::Column::Olddecimalunsigned:
- {
- short len = 0 + c->getPrecision() + (c->getScale() > 0);
- out.print("%.*s", len, r.aRef());
- }
- break;
- case NdbDictionary::Column::Decimal:
- case NdbDictionary::Column::Decimalunsigned:
- goto unknown; // TODO
- break;
- // for dates cut-and-paste from field.cc
- case NdbDictionary::Column::Datetime:
- {
- ulonglong tmp=r.u_64_value();
- long part1,part2,part3;
- part1=(long) (tmp/LL(1000000));
- part2=(long) (tmp - (ulonglong) part1*LL(1000000));
- char buf[40];
- char* pos=(char*) buf+19;
- *pos--=0;
- *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
- *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
- *pos--= ':';
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos--= ':';
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos--= (char) ('0'+(char) part3);
- *pos--= '/';
- *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
- *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
- *pos--= '-';
- *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
- *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
- *pos--= '-';
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
- *pos=(char) ('0'+(char) part3);
- out << buf;
- }
- break;
- case NdbDictionary::Column::Date:
- {
- uint32 tmp=(uint32) uint3korr(r.aRef());
- int part;
- char buf[40];
- char *pos=(char*) buf+10;
- *pos--=0;
- part=(int) (tmp & 31);
- *pos--= (char) ('0'+part%10);
- *pos--= (char) ('0'+part/10);
- *pos--= '-';
- part=(int) (tmp >> 5 & 15);
- *pos--= (char) ('0'+part%10);
- *pos--= (char) ('0'+part/10);
- *pos--= '-';
- part=(int) (tmp >> 9);
- *pos--= (char) ('0'+part%10); part/=10;
- *pos--= (char) ('0'+part%10); part/=10;
- *pos--= (char) ('0'+part%10); part/=10;
- *pos= (char) ('0'+part);
- out << buf;
- }
- break;
- case NdbDictionary::Column::Time:
- {
- long tmp=(long) sint3korr(r.aRef());
- int hour=(uint) (tmp/10000);
- int minute=(uint) (tmp/100 % 100);
- int second=(uint) (tmp % 100);
- char buf[40];
- sprintf(buf, "%02d:%02d:%02d", hour, minute, second);
- out << buf;
- }
- break;
- case NdbDictionary::Column::Year:
- {
- uint year = 1900 + r.u_8_value();
- char buf[40];
- sprintf(buf, "%04d", year);
- out << buf;
- }
- break;
- case NdbDictionary::Column::Timestamp:
- {
- time_t time = r.u_32_value();
- out << (uint)time;
- }
- break;
- case NdbDictionary::Column::Blob:
- case NdbDictionary::Column::Text:
- {
- // user defined aRef() may not be aligned to Uint64
- NdbBlob::Head head;
- memcpy(&head, r.aRef(), sizeof(head));
- out << head.length << ":";
- const unsigned char* p = (const unsigned char*)r.aRef() + sizeof(head);
- if (r.get_size_in_bytes() < sizeof(head))
- out << "***error***"; // really cannot happen
- else {
- unsigned n = r.get_size_in_bytes() - sizeof(head);
- for (unsigned k = 0; k < n && k < head.length; k++) {
- if (r.getType() == NdbDictionary::Column::Blob)
- out.print("%02X", (int)p[k]);
- else
- out.print("%c", (int)p[k]);
- }
- }
- j = length;
- }
- break;
- case NdbDictionary::Column::Longvarchar:
- {
- out << fields_optionally_enclosed_by;
- unsigned len = uint2korr(r.aRef());
- ndbrecattr_print_string(out,f,"Longvarchar", false, r.aRef()+2,len);
- j = length;
- out << fields_optionally_enclosed_by;
- }
- break;
- case NdbDictionary::Column::Longvarbinary:
- {
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- unsigned len = uint2korr(r.aRef());
- ndbrecattr_print_string(out,f,"Longvarbinary", true, r.aRef()+2,len);
- j = length;
- if (!f.hex_format)
- out << fields_optionally_enclosed_by;
- }
- break;
-
- case NdbDictionary::Column::Undefined:
- unknown:
- //default: /* no print functions for the rest, just print type */
- out << (int) r.getType();
- j = length;
- if (j > 1)
- out << " " << j << " times";
- break;
- }
- out << f.fields_enclosed_by;
- }
-
- return out;
-}
-
-NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
-{
- return ndbrecattr_print_formatted(out, r, default_print_format);
-}
-
-Int64
-NdbRecAttr::int64_value() const
-{
- Int64 val;
- memcpy(&val,theRef,8);
- return val;
-}
-
-Uint64
-NdbRecAttr::u_64_value() const
-{
- Uint64 val;
- memcpy(&val,theRef,8);
- return val;
-}
-
-float
-NdbRecAttr::float_value() const
-{
- float val;
- memcpy(&val,theRef,sizeof(val));
- return val;
-}
-
-double
-NdbRecAttr::double_value() const
-{
- double val;
- memcpy(&val,theRef,sizeof(val));
- return val;
-}
-
-Int32
-NdbRecAttr::medium_value() const
-{
- return sint3korr((unsigned char *)theRef);
-}
-
-Uint32
-NdbRecAttr::u_medium_value() const
-{
- return uint3korr((unsigned char*)theRef);
-}
diff --git a/storage/ndb/src/ndbapi/NdbReceiver.cpp b/storage/ndb/src/ndbapi/NdbReceiver.cpp
deleted file mode 100644
index 4512a94df17..00000000000
--- a/storage/ndb/src/ndbapi/NdbReceiver.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include "NdbImpl.hpp"
-#include <NdbReceiver.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <NdbRecAttr.hpp>
-#include <AttributeHeader.hpp>
-#include <NdbTransaction.hpp>
-#include <TransporterFacade.hpp>
-#include <signaldata/TcKeyConf.hpp>
-
-NdbReceiver::NdbReceiver(Ndb *aNdb) :
- theMagicNumber(0),
- m_ndb(aNdb),
- m_id(NdbObjectIdMap::InvalidId),
- m_type(NDB_UNINITIALIZED),
- m_owner(0)
-{
- theCurrentRecAttr = theFirstRecAttr = 0;
- m_defined_rows = 0;
- m_rows = NULL;
-}
-
-NdbReceiver::~NdbReceiver()
-{
- DBUG_ENTER("NdbReceiver::~NdbReceiver");
- if (m_id != NdbObjectIdMap::InvalidId) {
- m_ndb->theImpl->theNdbObjectIdMap.unmap(m_id, this);
- }
- delete[] m_rows;
- DBUG_VOID_RETURN;
-}
-
-int
-NdbReceiver::init(ReceiverType type, void* owner)
-{
- theMagicNumber = 0x11223344;
- m_type = type;
- m_owner = owner;
- theFirstRecAttr = NULL;
- theCurrentRecAttr = NULL;
- if (m_id == NdbObjectIdMap::InvalidId) {
- if (m_ndb)
- {
- m_id = m_ndb->theImpl->theNdbObjectIdMap.map(this);
- if (m_id == NdbObjectIdMap::InvalidId)
- {
- setErrorCode(4000);
- return -1;
- }
- }
- }
- return 0;
-}
-
-void
-NdbReceiver::release(){
- NdbRecAttr* tRecAttr = theFirstRecAttr;
- while (tRecAttr != NULL)
- {
- NdbRecAttr* tSaveRecAttr = tRecAttr;
- tRecAttr = tRecAttr->next();
- m_ndb->releaseRecAttr(tSaveRecAttr);
- }
- theFirstRecAttr = NULL;
- theCurrentRecAttr = NULL;
-}
-
-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 (~(Uint32)0)
-
-void
-NdbReceiver::calculate_batch_size(Uint32 key_size,
- Uint32 parallelism,
- Uint32& batch_size,
- Uint32& batch_byte_size,
- Uint32& first_batch_size)
-{
- TransporterFacade *tp= m_ndb->theImpl->m_transporter_facade;
- Uint32 max_scan_batch_size= tp->get_scan_batch_size();
- Uint32 max_batch_byte_size= tp->get_batch_byte_size();
- Uint32 max_batch_size= tp->get_batch_size();
- Uint32 tot_size= (key_size ? (key_size + 32) : 0); //key + signal overhead
- NdbRecAttr *rec_attr= theFirstRecAttr;
- while (rec_attr != NULL) {
- Uint32 attr_size= rec_attr->getColumn()->getSizeInBytes();
- attr_size= ((attr_size + 7) >> 2) << 2; //Even to word + overhead
- tot_size+= attr_size;
- rec_attr= rec_attr->next();
- }
- tot_size+= 32; //include signal overhead
-
- /**
- * Now we calculate the batch size by trying to get upto SCAN_BATCH_SIZE
- * bytes sent for each batch from each node. We do however ensure that
- * no more than MAX_SCAN_BATCH_SIZE is sent from all nodes in total per
- * batch.
- */
- if (batch_size == 0)
- {
- batch_byte_size= max_batch_byte_size;
- }
- else
- {
- batch_byte_size= batch_size * tot_size;
- }
-
- if (batch_byte_size * parallelism > max_scan_batch_size) {
- batch_byte_size= max_scan_batch_size / parallelism;
- }
- batch_size= batch_byte_size / tot_size;
- if (batch_size == 0) {
- batch_size= 1;
- } else {
- if (batch_size > max_batch_size) {
- batch_size= max_batch_size;
- } else if (batch_size > MAX_PARALLEL_OP_PER_SCAN) {
- batch_size= MAX_PARALLEL_OP_PER_SCAN;
- }
- }
- first_batch_size= batch_size;
- return;
-}
-
-int
-NdbReceiver::do_get_value(NdbReceiver * org,
- Uint32 rows,
- Uint32 key_size,
- Uint32 range_no){
- if(rows > m_defined_rows){
- delete[] m_rows;
- m_defined_rows = rows;
- if ((m_rows = new NdbRecAttr*[rows + 1]) == NULL)
- {
- setErrorCode(4000);
- return -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
- }
- m_hidden_count = (key_size ? 1 : 0) + range_no ;
-
- for(Uint32 i = 0; i<rows; i++){
- NdbRecAttr * prev = theCurrentRecAttr;
- assert(prev == 0 || i > 0);
-
- // Put key-recAttr fir on each row
- if(key_size && !getValue(&key, (char*)0)){
- abort();
- return -1;
- }
-
- if(range_no &&
- !getValue(&NdbColumnImpl::getImpl(* NdbDictionary::Column::RANGE_NO),0))
- {
- abort();
- }
-
- NdbRecAttr* tRecAttr = org->theFirstRecAttr;
- while(tRecAttr != 0){
- if(getValue(&NdbColumnImpl::getImpl(*tRecAttr->m_column), (char*)0) != 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;
-}
-
-NdbRecAttr*
-NdbReceiver::copyout(NdbReceiver & dstRec){
- NdbRecAttr *src = m_rows[m_current_row++];
- NdbRecAttr *dst = dstRec.theFirstRecAttr;
- NdbRecAttr *start = src;
- Uint32 tmp = m_hidden_count;
- while(tmp--)
- src = src->next();
-
- while(dst){
- Uint32 len = src->get_size_in_bytes();
- dst->receive_data((Uint32*)src->aRef(), len);
- src = src->next();
- dst = dst->next();
- }
-
- return start;
-}
-
-int
-NdbReceiver::execTRANSID_AI(const Uint32* aDataPtr, Uint32 aLength)
-{
- NdbRecAttr* currRecAttr = theCurrentRecAttr;
-
- for (Uint32 used = 0; used < aLength ; used++){
- AttributeHeader ah(* aDataPtr++);
- const Uint32 tAttrId = ah.getAttributeId();
- const Uint32 tAttrSize = ah.getByteSize();
-
- /**
- * Set all results to NULL if not found...
- */
- while(currRecAttr && currRecAttr->attrId() != tAttrId){
- currRecAttr = currRecAttr->next();
- }
-
- if(currRecAttr && currRecAttr->receive_data(aDataPtr, tAttrSize)){
- Uint32 add= (tAttrSize + 3) >> 2;
- used += add;
- aDataPtr += add;
- currRecAttr = currRecAttr->next();
- } else {
- ndbout_c("%p: tAttrId: %d currRecAttr: %p tAttrSize: %d %d", this,
- tAttrId, currRecAttr,
- tAttrSize, currRecAttr->get_size_in_bytes());
- currRecAttr = theCurrentRecAttr;
- while(currRecAttr != 0){
- ndbout_c("%d ", currRecAttr->attrId());
- currRecAttr = currRecAttr->next();
- }
- abort();
- return -1;
- }
- }
-
- theCurrentRecAttr = currRecAttr;
-
- /**
- * Update m_received_result_length
- */
- Uint32 exp = m_expected_result_length;
- Uint32 tmp = m_received_result_length + aLength;
- m_received_result_length = tmp;
-
- return (tmp == exp || (exp > TcKeyConf::DirtyReadBit) ? 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, 4*(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);
-}
-
-void
-NdbReceiver::setErrorCode(int code)
-{
- theMagicNumber = 0;
- NdbOperation* op = (NdbOperation*)getOwner();
- op->setErrorCode(code);
-}
diff --git a/storage/ndb/src/ndbapi/NdbScanFilter.cpp b/storage/ndb/src/ndbapi/NdbScanFilter.cpp
deleted file mode 100644
index 985677b3dfd..00000000000
--- a/storage/ndb/src/ndbapi/NdbScanFilter.cpp
+++ /dev/null
@@ -1,838 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <NdbScanFilter.hpp>
-#include <Ndb.hpp>
-#include <NdbOperation.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <Vector.hpp>
-#include <NdbOut.hpp>
-#include <Interpreter.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include "NdbApiSignal.hpp"
-#include "NdbUtil.hpp"
-
-#ifdef VM_TRACE
-#include <NdbEnv.h>
-#define INT_DEBUG(x) \
- { const char* tmp = NdbEnv_GetEnv("INT_DEBUG", (char*)0, 0); \
- if (tmp != 0 && strlen(tmp) != 0) { ndbout << "INT:"; ndbout_c x; } }
-#else
-#define INT_DEBUG(x)
-#endif
-
-class NdbScanFilterImpl {
-public:
- NdbScanFilterImpl() {}
- struct State {
- NdbScanFilter::Group m_group;
- Uint32 m_popCount;
- Uint32 m_ownLabel;
- Uint32 m_trueLabel;
- Uint32 m_falseLabel;
- };
-
- int m_label;
- State m_current;
- Uint32 m_negative; //used for translating NAND/NOR to AND/OR, equal 0 or 1
- Vector<State> m_stack;
- Vector<Uint32> m_stack2; //to store info of m_negative
- NdbOperation * m_operation;
- Uint32 m_latestAttrib;
-
- int cond_col(Interpreter::UnaryCondition, Uint32 attrId);
-
- int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId,
- const void * value, Uint32 len);
-
- bool m_abort_on_too_large;
-
- NdbOperation::OperationStatus m_initial_op_status;
- Uint32 m_initial_AI_size;
- Uint32 m_max_size;
-
- Uint32 get_size() {
- assert(m_operation->theTotalCurrAI_Len >= m_initial_AI_size);
- return m_operation->theTotalCurrAI_Len - m_initial_AI_size;
- }
- bool check_size() {
- if (get_size() <= m_max_size)
- return true;
- handle_filter_too_large();
- return false;
- }
- void handle_filter_too_large();
-
- NdbError m_error;
-};
-
-const Uint32 LabelExit = ~0;
-
-
-NdbScanFilter::NdbScanFilter(class NdbOperation * op,
- bool abort_on_too_large,
- Uint32 max_size)
- : m_impl(* new NdbScanFilterImpl())
-{
- DBUG_ENTER("NdbScanFilter::NdbScanFilter");
- m_impl.m_current.m_group = (NdbScanFilter::Group)0;
- m_impl.m_current.m_popCount = 0;
- m_impl.m_current.m_ownLabel = 0;
- m_impl.m_current.m_trueLabel = ~0;
- m_impl.m_current.m_falseLabel = ~0;
- m_impl.m_label = 0;
- m_impl.m_latestAttrib = ~0;
- m_impl.m_operation = op;
- m_impl.m_negative = 0;
-
- DBUG_PRINT("info", ("op status: %d tot AI: %u in curr: %u",
- op->theStatus,
- op->theTotalCurrAI_Len, op->theAI_LenInCurrAI));
-
- m_impl.m_abort_on_too_large = abort_on_too_large;
-
- m_impl.m_initial_op_status = op->theStatus;
- m_impl.m_initial_AI_size = op->theTotalCurrAI_Len;
- if (max_size > NDB_MAX_SCANFILTER_SIZE_IN_WORDS)
- max_size = NDB_MAX_SCANFILTER_SIZE_IN_WORDS;
- m_impl.m_max_size = max_size;
-
- m_impl.m_error.code = 0;
- DBUG_VOID_RETURN;
-}
-
-NdbScanFilter::~NdbScanFilter(){
- delete &m_impl;
-}
-
-int
-NdbScanFilter::begin(Group group){
-
- if (m_impl.m_stack2.push_back(m_impl.m_negative))
- {
- m_impl.m_operation->setErrorCodeAbort(4000);
- return -1;
- }
- switch(group){
- case NdbScanFilter::AND:
- INT_DEBUG(("Begin(AND)"));
- if(m_impl.m_negative == 1){
- group = NdbScanFilter::OR;
- }
- break;
- case NdbScanFilter::OR:
- INT_DEBUG(("Begin(OR)"));
- if(m_impl.m_negative == 1){
- group = NdbScanFilter::AND;
- }
- break;
- case NdbScanFilter::NAND:
- INT_DEBUG(("Begin(NAND)"));
- if(m_impl.m_negative == 0){
- group = NdbScanFilter::OR;
- m_impl.m_negative = 1;
- }else{
- group = NdbScanFilter::AND;
- m_impl.m_negative = 0;
- }
- break;
- case NdbScanFilter::NOR:
- INT_DEBUG(("Begin(NOR)"));
- if(m_impl.m_negative == 0){
- group = NdbScanFilter::AND;
- m_impl.m_negative = 1;
- }else{
- group = NdbScanFilter::OR;
- m_impl.m_negative = 0;
- }
- break;
- }
-
- if(group == m_impl.m_current.m_group){
- switch(group){
- case NdbScanFilter::AND:
- case NdbScanFilter::OR:
- m_impl.m_current.m_popCount++;
- return 0;
- case NdbScanFilter::NOR:
- case NdbScanFilter::NAND:
- break;
- }
- }
-
- NdbScanFilterImpl::State tmp = m_impl.m_current;
- if (m_impl.m_stack.push_back(m_impl.m_current))
- {
- m_impl.m_operation->setErrorCodeAbort(4000);
- return -1;
- }
- m_impl.m_current.m_group = group;
- m_impl.m_current.m_ownLabel = m_impl.m_label++;
- m_impl.m_current.m_popCount = 0;
-
- switch(group){
- case NdbScanFilter::AND:
- case NdbScanFilter::NAND:
- m_impl.m_current.m_falseLabel = m_impl.m_current.m_ownLabel;
- m_impl.m_current.m_trueLabel = tmp.m_trueLabel;
- break;
- case NdbScanFilter::OR:
- case NdbScanFilter::NOR:
- m_impl.m_current.m_falseLabel = tmp.m_falseLabel;
- m_impl.m_current.m_trueLabel = m_impl.m_current.m_ownLabel;
- break;
- default:
- m_impl.m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- return 0;
-}
-
-int
-NdbScanFilter::end(){
-
- if(m_impl.m_stack2.size() == 0){
- m_impl.m_operation->setErrorCodeAbort(4259);
- return -1;
- }
- m_impl.m_negative = m_impl.m_stack2.back();
- m_impl.m_stack2.erase(m_impl.m_stack2.size() - 1);
-
- switch(m_impl.m_current.m_group){
- case NdbScanFilter::AND:
- INT_DEBUG(("End(AND pc=%d)", m_impl.m_current.m_popCount));
- break;
- case NdbScanFilter::OR:
- INT_DEBUG(("End(OR pc=%d)", m_impl.m_current.m_popCount));
- break;
- case NdbScanFilter::NAND:
- INT_DEBUG(("End(NAND pc=%d)", m_impl.m_current.m_popCount));
- break;
- case NdbScanFilter::NOR:
- INT_DEBUG(("End(NOR pc=%d)", m_impl.m_current.m_popCount));
- break;
- }
-
- if(m_impl.m_current.m_popCount > 0){
- m_impl.m_current.m_popCount--;
- return 0;
- }
-
- NdbScanFilterImpl::State tmp = m_impl.m_current;
- if(m_impl.m_stack.size() == 0){
- m_impl.m_operation->setErrorCodeAbort(4259);
- return -1;
- }
- m_impl.m_current = m_impl.m_stack.back();
- m_impl.m_stack.erase(m_impl.m_stack.size() - 1);
-
- switch(tmp.m_group){
- case NdbScanFilter::AND:
- if(tmp.m_trueLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_ok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(tmp.m_trueLabel) == -1)
- return -1;
- }
- break;
- case NdbScanFilter::NAND:
- if(tmp.m_trueLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_nok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(tmp.m_falseLabel) == -1)
- return -1;
- }
- break;
- case NdbScanFilter::OR:
- if(tmp.m_falseLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_nok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(tmp.m_falseLabel) == -1)
- return -1;
- }
- break;
- case NdbScanFilter::NOR:
- if(tmp.m_falseLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_ok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(tmp.m_trueLabel) == -1)
- return -1;
- }
- break;
- default:
- m_impl.m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- if (m_impl.m_operation->def_label(tmp.m_ownLabel) == -1)
- return -1;
-
- if(m_impl.m_stack.size() == 0){
- switch(tmp.m_group){
- case NdbScanFilter::AND:
- case NdbScanFilter::NOR:
- if (m_impl.m_operation->interpret_exit_nok() == -1)
- return -1;
- break;
- case NdbScanFilter::OR:
- case NdbScanFilter::NAND:
- if (m_impl.m_operation->interpret_exit_ok() == -1)
- return -1;
- break;
- default:
- m_impl.m_operation->setErrorCodeAbort(4260);
- return -1;
- }
- }
-
- if (!m_impl.check_size())
- return -1;
- return 0;
-}
-
-int
-NdbScanFilter::istrue(){
- if(m_impl.m_current.m_group < NdbScanFilter::AND ||
- m_impl.m_current.m_group > NdbScanFilter::NOR){
- m_impl.m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- if(m_impl.m_current.m_trueLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_ok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(m_impl.m_current.m_trueLabel) == -1)
- return -1;
- }
-
- if (!m_impl.check_size())
- return -1;
- return 0;
-}
-
-int
-NdbScanFilter::isfalse(){
- if(m_impl.m_current.m_group < NdbScanFilter::AND ||
- m_impl.m_current.m_group > NdbScanFilter::NOR){
- m_impl.m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- if(m_impl.m_current.m_falseLabel == (Uint32)~0){
- if (m_impl.m_operation->interpret_exit_nok() == -1)
- return -1;
- } else {
- if (m_impl.m_operation->branch_label(m_impl.m_current.m_falseLabel) == -1)
- return -1;
- }
-
- if (!m_impl.check_size())
- return -1;
- return 0;
-}
-
-NdbOperation *
-NdbScanFilter::getNdbOperation(){
- return m_impl.m_operation;
-}
-
-#define action(x, y, z)
-
-
-typedef int (NdbOperation:: * Branch1)(Uint32, Uint32 label);
-typedef int (NdbOperation:: * StrBranch2)(Uint32, const void*, Uint32, bool, Uint32);
-
-struct tab2 {
- Branch1 m_branches[5];
-};
-
-static const tab2 table2[] = {
- /**
- * IS NULL
- */
- { { 0,
- &NdbOperation::branch_col_ne_null,
- &NdbOperation::branch_col_eq_null,
- &NdbOperation::branch_col_eq_null,
- &NdbOperation::branch_col_ne_null } }
-
- /**
- * IS NOT NULL
- */
- ,{ { 0,
- &NdbOperation::branch_col_eq_null,
- &NdbOperation::branch_col_ne_null,
- &NdbOperation::branch_col_ne_null,
- &NdbOperation::branch_col_eq_null } }
-};
-
-const int tab2_sz = sizeof(table2)/sizeof(table2[0]);
-
-int
-NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){
-
- if(op < 0 || op >= tab2_sz){
- m_operation->setErrorCodeAbort(4262);
- return -1;
- }
-
- if(m_current.m_group < NdbScanFilter::AND ||
- m_current.m_group > NdbScanFilter::NOR){
- m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- Branch1 branch = table2[op].m_branches[m_current.m_group];
- if ((m_operation->* branch)(AttrId, m_current.m_ownLabel) == -1)
- return -1;
-
- if (!check_size())
- return -1;
- return 0;
-}
-
-int
-NdbScanFilter::isnull(int AttrId){
- if(m_impl.m_negative == 1)
- return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId);
- else
- return m_impl.cond_col(Interpreter::IS_NULL, AttrId);
-}
-
-int
-NdbScanFilter::isnotnull(int AttrId){
- if(m_impl.m_negative == 1)
- return m_impl.cond_col(Interpreter::IS_NULL, AttrId);
- else
- return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId);
-}
-
-struct tab3 {
- StrBranch2 m_branches[5];
-};
-
-static const tab3 table3[] = {
- /**
- * EQ (AND, OR, NAND, NOR)
- */
- { { 0,
- &NdbOperation::branch_col_ne,
- &NdbOperation::branch_col_eq,
- &NdbOperation::branch_col_ne,
- &NdbOperation::branch_col_eq } }
-
- /**
- * NEQ
- */
- ,{ { 0,
- &NdbOperation::branch_col_eq,
- &NdbOperation::branch_col_ne,
- &NdbOperation::branch_col_eq,
- &NdbOperation::branch_col_ne } }
-
- /**
- * LT
- */
- ,{ { 0,
- &NdbOperation::branch_col_le,
- &NdbOperation::branch_col_gt,
- &NdbOperation::branch_col_le,
- &NdbOperation::branch_col_gt } }
-
- /**
- * LE
- */
- ,{ { 0,
- &NdbOperation::branch_col_lt,
- &NdbOperation::branch_col_ge,
- &NdbOperation::branch_col_lt,
- &NdbOperation::branch_col_ge } }
-
- /**
- * GT
- */
- ,{ { 0,
- &NdbOperation::branch_col_ge,
- &NdbOperation::branch_col_lt,
- &NdbOperation::branch_col_ge,
- &NdbOperation::branch_col_lt } }
-
- /**
- * GE
- */
- ,{ { 0,
- &NdbOperation::branch_col_gt,
- &NdbOperation::branch_col_le,
- &NdbOperation::branch_col_gt,
- &NdbOperation::branch_col_le } }
-
- /**
- * LIKE
- */
- ,{ { 0,
- &NdbOperation::branch_col_notlike,
- &NdbOperation::branch_col_like,
- &NdbOperation::branch_col_notlike,
- &NdbOperation::branch_col_like } }
-
- /**
- * NOT LIKE
- */
- ,{ { 0,
- &NdbOperation::branch_col_like,
- &NdbOperation::branch_col_notlike,
- &NdbOperation::branch_col_like,
- &NdbOperation::branch_col_notlike } }
-};
-
-const int tab3_sz = sizeof(table3)/sizeof(table3[0]);
-
-int
-NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op,
- Uint32 AttrId,
- const void * value, Uint32 len){
- if(op < 0 || op >= tab3_sz){
- m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- if(m_current.m_group < NdbScanFilter::AND ||
- m_current.m_group > NdbScanFilter::NOR){
- m_operation->setErrorCodeAbort(4260);
- return -1;
- }
-
- StrBranch2 branch;
- if(m_negative == 1){ //change NdbOperation to its negative
- if(m_current.m_group == NdbScanFilter::AND)
- branch = table3[op].m_branches[(Uint32)(m_current.m_group) + 1];
- if(m_current.m_group == NdbScanFilter::OR)
- branch = table3[op].m_branches[(Uint32)(m_current.m_group) - 1];
- }else{
- branch = table3[op].m_branches[(Uint32)(m_current.m_group)];
- }
-
- const NdbDictionary::Column * col =
- m_operation->m_currentTable->getColumn(AttrId);
-
- if(col == 0){
- m_operation->setErrorCodeAbort(4261);
- return -1;
- }
-
- if ((m_operation->* branch)(AttrId, value, len, false, m_current.m_ownLabel) == -1)
- return -1;
-
- if (!check_size())
- return -1;
- return 0;
-}
-
-int
-NdbScanFilter::cmp(BinaryCondition cond, int ColId,
- const void *val, Uint32 len)
-{
- switch(cond){
- case COND_LE:
- return m_impl.cond_col_const(Interpreter::LE, ColId, val, len);
- case COND_LT:
- return m_impl.cond_col_const(Interpreter::LT, ColId, val, len);
- case COND_GE:
- return m_impl.cond_col_const(Interpreter::GE, ColId, val, len);
- case COND_GT:
- return m_impl.cond_col_const(Interpreter::GT, ColId, val, len);
- case COND_EQ:
- return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len);
- case COND_NE:
- return m_impl.cond_col_const(Interpreter::NE, ColId, val, len);
- case COND_LIKE:
- return m_impl.cond_col_const(Interpreter::LIKE, ColId, val, len);
- case COND_NOT_LIKE:
- return m_impl.cond_col_const(Interpreter::NOT_LIKE, ColId, val, len);
- }
- return -1;
-}
-
-void
-NdbScanFilterImpl::handle_filter_too_large()
-{
- DBUG_ENTER("NdbScanFilterImpl::handle_filter_too_large");
-
- NdbOperation* const op = m_operation;
- m_error.code = NdbScanFilter::FilterTooLarge;
- if (m_abort_on_too_large)
- op->setErrorCodeAbort(m_error.code);
-
- /*
- * Possible interpreted parts at this point are:
- *
- * 1. initial read
- * 2. interpreted program
- *
- * It is assumed that NdbScanFilter has created all of 2
- * so that we don't have to save interpreter state.
- */
-
- const Uint32 size = get_size();
- assert(size != 0);
-
- // new ATTRINFO size
- const Uint32 new_size = m_initial_AI_size;
-
- // find last signal for new size
- assert(op->theFirstATTRINFO != NULL);
- NdbApiSignal* lastSignal = op->theFirstATTRINFO;
- Uint32 n = 0;
- while (n + AttrInfo::DataLength < new_size) {
- lastSignal = lastSignal->next();
- assert(lastSignal != NULL);
- n += AttrInfo::DataLength;
- }
- assert(n < size);
-
- // release remaining signals
- NdbApiSignal* tSignal = lastSignal->next();
- op->theNdb->releaseSignalsInList(&tSignal);
- lastSignal->next(NULL);
-
- // length of lastSignal
- const Uint32 new_curr = AttrInfo::HeaderLength + new_size - n;
- assert(new_curr <= 25);
-
- DBUG_PRINT("info", ("op status: %d->%d tot AI: %u->%u in curr: %u->%u",
- op->theStatus, m_initial_op_status,
- op->theTotalCurrAI_Len, new_size,
- op->theAI_LenInCurrAI, new_curr));
-
- // reset op state
- op->theStatus = m_initial_op_status;
-
- // reset interpreter state to initial
-
- NdbBranch* tBranch = op->theFirstBranch;
- while (tBranch != NULL) {
- NdbBranch* tmp = tBranch;
- tBranch = tBranch->theNext;
- op->theNdb->releaseNdbBranch(tmp);
- }
- op->theFirstBranch = NULL;
- op->theLastBranch = NULL;
-
- NdbLabel* tLabel = op->theFirstLabel;
- while (tLabel != NULL) {
- NdbLabel* tmp = tLabel;
- tLabel = tLabel->theNext;
- op->theNdb->releaseNdbLabel(tmp);
- }
- op->theFirstLabel = NULL;
- op->theLastLabel = NULL;
-
- NdbCall* tCall = op->theFirstCall;
- while (tCall != NULL) {
- NdbCall* tmp = tCall;
- tCall = tCall->theNext;
- op->theNdb->releaseNdbCall(tmp);
- }
- op->theFirstCall = NULL;
- op->theLastCall = NULL;
-
- NdbSubroutine* tSubroutine = op->theFirstSubroutine;
- while (tSubroutine != NULL) {
- NdbSubroutine* tmp = tSubroutine;
- tSubroutine = tSubroutine->theNext;
- op->theNdb->releaseNdbSubroutine(tmp);
- }
- op->theFirstSubroutine = NULL;
- op->theLastSubroutine = NULL;
-
- op->theNoOfLabels = 0;
- op->theNoOfSubroutines = 0;
-
- // reset AI size
- op->theTotalCurrAI_Len = new_size;
- op->theAI_LenInCurrAI = new_curr;
-
- // reset signal pointers
- op->theCurrentATTRINFO = lastSignal;
- op->theATTRINFOptr = &lastSignal->getDataPtrSend()[new_curr];
-
- // interpreter sizes are set later somewhere
-
- DBUG_VOID_RETURN;
-}
-
-static void
-update(const NdbError & _err){
- NdbError & error = (NdbError &) _err;
- ndberror_struct ndberror = (ndberror_struct)error;
- ndberror_update(&ndberror);
- error = NdbError(ndberror);
-}
-
-const NdbError &
-NdbScanFilter::getNdbError() const
-{
- update(m_impl.m_error);
- return m_impl.m_error;
-}
-
-
-#if 0
-int
-main(void){
- if(0)
- {
- ndbout << "a > 7 AND b < 9 AND c = 4" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.lt(1, 9);
- f.eq(2, 4);
- f.end();
- ndbout << endl;
- }
-
- if(0)
- {
- ndbout << "a > 7 OR b < 9 OR c = 4" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::OR);
- f.gt(0, 7);
- f.lt(1, 9);
- f.eq(2, 4);
- f.end();
- ndbout << endl;
- }
-
- if(0)
- {
- ndbout << "a > 7 AND (b < 9 OR c = 4)" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.begin(NdbScanFilter::OR);
- f.lt(1, 9);
- f.eq(2, 4);
- f.end();
- f.end();
- ndbout << endl;
- }
-
- if(0)
- {
- ndbout << "a > 7 AND (b < 9 AND c = 4)" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.begin(NdbScanFilter::AND);
- f.lt(1, 9);
- f.eq(2, 4);
- f.end();
- f.end();
- ndbout << endl;
- }
-
- if(0)
- {
- ndbout << "(a > 7 AND b < 9) AND c = 4" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.lt(1, 9);
- f.end();
- f.eq(2, 4);
- f.end();
- ndbout << endl;
- }
-
- if(1)
- {
- ndbout << "(a > 7 OR b < 9) AND (c = 4 OR c = 5)" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.begin(NdbScanFilter::OR);
- f.gt(0, 7);
- f.lt(1, 9);
- f.end();
- f.begin(NdbScanFilter::OR);
- f.eq(2, 4);
- f.eq(2, 5);
- f.end();
- f.end();
- ndbout << endl;
- }
-
- if(1)
- {
- ndbout << "(a > 7 AND b < 9) OR (c = 4 AND c = 5)" << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::OR);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.lt(1, 9);
- f.end();
- f.begin(NdbScanFilter::AND);
- f.eq(2, 4);
- f.eq(2, 5);
- f.end();
- f.end();
- ndbout << endl;
- }
-
- if(1)
- {
- ndbout <<
- "((a > 7 AND b < 9) OR (c = 4 AND d = 5)) AND "
- "((e > 6 AND f < 8) OR (g = 2 AND h = 3)) " << endl;
- NdbScanFilter f(0);
- f.begin(NdbScanFilter::AND);
- f.begin(NdbScanFilter::OR);
- f.begin(NdbScanFilter::AND);
- f.gt(0, 7);
- f.lt(1, 9);
- f.end();
- f.begin(NdbScanFilter::AND);
- f.eq(2, 4);
- f.eq(3, 5);
- f.end();
- f.end();
-
- f.begin(NdbScanFilter::OR);
- f.begin(NdbScanFilter::AND);
- f.gt(4, 6);
- f.lt(5, 8);
- f.end();
- f.begin(NdbScanFilter::AND);
- f.eq(6, 2);
- f.eq(7, 3);
- f.end();
- f.end();
- f.end();
- }
-
- return 0;
-}
-#endif
-
-template class Vector<NdbScanFilterImpl::State>;
-
diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
deleted file mode 100644
index 6f26db3c37e..00000000000
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp
+++ /dev/null
@@ -1,1858 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <Ndb.hpp>
-#include <NdbScanOperation.hpp>
-#include <NdbIndexScanOperation.hpp>
-#include <NdbTransaction.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbOut.hpp>
-#include "NdbDictionaryImpl.hpp"
-#include <NdbBlob.hpp>
-
-#include <NdbRecAttr.hpp>
-#include <NdbReceiver.hpp>
-
-#include <stdlib.h>
-#include <NdbSqlUtil.hpp>
-
-#include <signaldata/ScanTab.hpp>
-#include <signaldata/KeyInfo.hpp>
-#include <signaldata/AttrInfo.hpp>
-#include <signaldata/TcKeyReq.hpp>
-
-#define DEBUG_NEXT_RESULT 0
-
-NdbScanOperation::NdbScanOperation(Ndb* aNdb, NdbOperation::Type aType) :
- NdbOperation(aNdb, aType),
- 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;
- m_array = new Uint32[1]; // skip if on delete in fix_receivers
- theSCAN_TABREQ = 0;
- m_executed = false;
-}
-
-NdbScanOperation::~NdbScanOperation()
-{
- for(Uint32 i = 0; i<m_allocated_receivers; i++){
- m_receivers[i]->release();
- theNdb->releaseNdbScanRec(m_receivers[i]);
- }
- delete[] m_array;
-}
-
-void
-NdbScanOperation::setErrorCode(int aErrorCode){
- NdbTransaction* tmp = theNdbCon;
- theNdbCon = m_transConnection;
- NdbOperation::setErrorCode(aErrorCode);
- theNdbCon = tmp;
-}
-
-void
-NdbScanOperation::setErrorCodeAbort(int aErrorCode){
- NdbTransaction* tmp = theNdbCon;
- theNdbCon = m_transConnection;
- NdbOperation::setErrorCodeAbort(aErrorCode);
- theNdbCon = tmp;
-}
-
-
-/*****************************************************************************
- * int init();
- *
- * Return Value: Return 0 : init was successful.
- * Return -1: In all other case.
- * Remark: Initiates operation record after allocation.
- *****************************************************************************/
-int
-NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection)
-{
- m_transConnection = myConnection;
- //NdbConnection* aScanConnection = theNdb->startTransaction(myConnection);
- theNdb->theRemainingStartTransactions++; // will be checked in hupp...
- NdbTransaction* aScanConnection = theNdb->hupp(myConnection);
- if (!aScanConnection){
- theNdb->theRemainingStartTransactions--;
- setErrorCodeAbort(theNdb->getNdbError().code);
- return -1;
- }
-
- // NOTE! The hupped trans becomes the owner of the operation
- if(NdbOperation::init(tab, aScanConnection) != 0){
- theNdb->theRemainingStartTransactions--;
- return -1;
- }
-
- initInterpreter();
-
- theStatus = GetValue;
- theOperationType = OpenScanRequest;
- theNdbCon->theMagicNumber = 0xFE11DF;
- theNoOfTupKeyLeft = tab->m_noOfDistributionKeys;
- m_read_range_no = 0;
- m_executed = false;
- return 0;
-}
-
-int
-NdbScanOperation::readTuples(NdbScanOperation::LockMode lm,
- Uint32 scan_flags,
- Uint32 parallel,
- Uint32 batch)
-{
- m_ordered = m_descending = false;
- Uint32 fragCount = m_currentTable->m_fragmentCount;
-
- if (parallel > fragCount || parallel == 0) {
- parallel = fragCount;
- }
-
- // 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;
- }
-
- theNdbCon->theScanningOp = this;
- bool tupScan = (scan_flags & SF_TupScan);
-
-#if 0 // XXX temp for testing
- { char* p = getenv("NDB_USE_TUPSCAN");
- if (p != 0) {
- unsigned n = atoi(p); // 0-10
- if ((unsigned int) (::time(0) % 10) < n) tupScan = true;
- }
- }
-#endif
- if (scan_flags & SF_DiskScan)
- {
- tupScan = true;
- m_no_disk_flag = false;
- }
-
- bool rangeScan = false;
- if ( (int) m_accessTable->m_indexType ==
- (int) NdbDictionary::Index::OrderedIndex)
- {
- if (m_currentTable == m_accessTable){
- // Old way of scanning indexes, should not be allowed
- m_currentTable = theNdb->theDictionary->
- getTable(m_currentTable->m_primaryTable.c_str());
- assert(m_currentTable != NULL);
- }
- assert (m_currentTable != m_accessTable);
- // Modify operation state
- theStatus = GetValue;
- theOperationType = OpenRangeScanRequest;
- rangeScan = true;
- tupScan = false;
- }
-
- if (rangeScan && (scan_flags & SF_OrderBy))
- parallel = fragCount;
-
- theParallelism = parallel;
-
- if(fix_receivers(parallel) == -1){
- setErrorCodeAbort(4000);
- return -1;
- }
-
- theSCAN_TABREQ = (!theSCAN_TABREQ ? theNdb->getSignal() : theSCAN_TABREQ);
- if (theSCAN_TABREQ == NULL) {
- setErrorCodeAbort(4000);
- return -1;
- }//if
-
- theSCAN_TABREQ->setSignal(GSN_SCAN_TABREQ);
- ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
- req->apiConnectPtr = theNdbCon->theTCConPtr;
- req->tableId = m_accessTable->m_id;
- req->tableSchemaVersion = m_accessTable->m_version;
- req->storedProcId = 0xFFFF;
- req->buddyConPtr = theNdbCon->theBuddyConPtr;
- req->first_batch_size = batch; // Save user specified batch size
-
- Uint32 reqInfo = 0;
- ScanTabReq::setParallelism(reqInfo, parallel);
- ScanTabReq::setScanBatch(reqInfo, 0);
- ScanTabReq::setRangeScanFlag(reqInfo, rangeScan);
- ScanTabReq::setTupScanFlag(reqInfo, tupScan);
- req->requestInfo = reqInfo;
-
- m_keyInfo = (scan_flags & SF_KeyInfo) ? 1 : 0;
- setReadLockMode(lm);
-
- Uint64 transId = theNdbCon->getTransactionId();
- req->transId1 = (Uint32) transId;
- req->transId2 = (Uint32) (transId >> 32);
-
- NdbApiSignal* tSignal = theSCAN_TABREQ->next();
- if(!tSignal)
- {
- theSCAN_TABREQ->next(tSignal = theNdb->getSignal());
- }
- theLastKEYINFO = tSignal;
-
- tSignal->setSignal(GSN_KEYINFO);
- theKEYINFOptr = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
- theTotalNrOfKeyWordInSignal= 0;
-
- getFirstATTRINFOScan();
- return 0;
-}
-
-void
-NdbScanOperation::setReadLockMode(LockMode lockMode)
-{
- bool lockExcl, lockHoldMode, readCommitted;
- switch (lockMode)
- {
- case LM_CommittedRead:
- lockExcl= false;
- lockHoldMode= false;
- readCommitted= true;
- break;
- case LM_SimpleRead:
- case LM_Read:
- lockExcl= false;
- lockHoldMode= true;
- readCommitted= false;
- break;
- case LM_Exclusive:
- lockExcl= true;
- lockHoldMode= true;
- readCommitted= false;
- m_keyInfo= 1;
- break;
- default:
- /* Not supported / invalid. */
- assert(false);
- }
- theLockMode= lockMode;
- ScanTabReq *req= CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
- Uint32 reqInfo= req->requestInfo;
- ScanTabReq::setLockMode(reqInfo, lockExcl);
- ScanTabReq::setHoldLockFlag(reqInfo, lockHoldMode);
- ScanTabReq::setReadCommittedFlag(reqInfo, readCommitted);
- req->requestInfo= reqInfo;
-}
-
-int
-NdbScanOperation::fix_receivers(Uint32 parallel){
- assert(parallel > 0);
- if(parallel > m_allocated_receivers){
- const Uint32 sz = parallel * (4*sizeof(char*)+sizeof(Uint32));
-
- Uint64 * tmp = new Uint64[(sz+7)/8];
- // Save old receivers
- memcpy(tmp, m_receivers, m_allocated_receivers*sizeof(char*));
- delete[] m_array;
- m_array = (Uint32*)tmp;
-
- m_receivers = (NdbReceiver**)tmp;
- m_api_receivers = m_receivers + parallel;
- m_conf_receivers = m_api_receivers + parallel;
- m_sent_receivers = m_conf_receivers + parallel;
- m_prepared_receivers = (Uint32*)(m_sent_receivers + parallel);
-
- // Only get/init "new" receivers
- NdbReceiver* tScanRec;
- for (Uint32 i = m_allocated_receivers; i < parallel; i ++) {
- tScanRec = theNdb->getNdbScanRec();
- if (tScanRec == NULL) {
- setErrorCodeAbort(4000);
- return -1;
- }//if
- m_receivers[i] = tScanRec;
- tScanRec->init(NdbReceiver::NDB_SCANRECEIVER, this);
- }
- m_allocated_receivers = parallel;
- }
-
- reset_receivers(parallel, 0);
- return 0;
-}
-
-/**
- * Move receiver from send array to conf:ed array
- */
-void
-NdbScanOperation::receiver_delivered(NdbReceiver* tRec){
- if(theError.code == 0){
- if(DEBUG_NEXT_RESULT)
- ndbout_c("receiver_delivered");
-
- 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;
- }
-}
-
-/**
- * Remove receiver as it's completed
- */
-void
-NdbScanOperation::receiver_completed(NdbReceiver* tRec){
- if(theError.code == 0){
- if(DEBUG_NEXT_RESULT)
- ndbout_c("receiver_completed");
-
- 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 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()
-{
- 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;
-}
-
-/**
- * Constats for theTupleKeyDefined[][0]
- */
-#define SETBOUND_EQ 1
-#define FAKE_PTR 2
-#define API_PTR 3
-
-#define WAITFOR_SCAN_TIMEOUT 120000
-
-int
-NdbScanOperation::executeCursor(int nodeId){
- NdbTransaction * tCon = theNdbCon;
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- Guard guard(tp->theMutexPtr);
-
- Uint32 magic = tCon->theMagicNumber;
- Uint32 seq = tCon->theNodeSequence;
-
- if (tp->get_node_alive(nodeId) &&
- (tp->getNodeSequence(nodeId) == seq)) {
-
- /**
- * Only call prepareSendScan first time (incase of restarts)
- * - check with theMagicNumber
- */
- tCon->theMagicNumber = 0x37412619;
- if(magic != 0x37412619 &&
- prepareSendScan(tCon->theTCConPtr, tCon->theTransactionId) == -1)
- return -1;
-
-
- if (doSendScan(nodeId) == -1)
- return -1;
-
- m_executed= true; // Mark operation as executed
- 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;
- } else {
- TRACE_DEBUG("The node is stopping when attempting to start a scan");
- setErrorCode(4030);
- }//if
- tCon->theCommitStatus = NdbTransaction::Aborted;
- }//if
- return -1;
-}
-
-
-int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend)
-{
- int res;
- if ((res = nextResultImpl(fetchAllowed, forceSend)) == 0) {
- // handle blobs
- NdbBlob* tBlob = theBlobList;
- while (tBlob != 0) {
- if (tBlob->atNextResult() == -1)
- return -1;
- tBlob = tBlob->theNext;
- }
- /*
- * Flush blob part ops on behalf of user because
- * - nextResult is analogous to execute(NoCommit)
- * - user is likely to want blob value before next execute
- */
- if (m_transConnection->executePendingBlobOps() == -1)
- return -1;
- return 0;
- }
- return res;
-}
-
-int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend)
-{
- if(m_ordered)
- return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed,
- forceSend);
-
- /**
- * Check current receiver
- */
- int retVal = 2;
- Uint32 idx = m_current_api_receiver;
- Uint32 last = m_api_receivers_count;
- m_curr_row = 0;
-
- if(DEBUG_NEXT_RESULT)
- ndbout_c("nextResult(%d) idx=%d last=%d", fetchAllowed, idx, last);
-
- /**
- * Check next buckets
- */
- for(; idx < last; idx++){
- NdbReceiver* tRec = m_api_receivers[idx];
- if(tRec->nextResult()){
- m_curr_row = tRec->copyout(theReceiver);
- retVal = 0;
- break;
- }
- }
-
- /**
- * We have advanced atleast one bucket
- */
- if(!fetchAllowed || !retVal){
- m_current_api_receiver = idx;
- if(DEBUG_NEXT_RESULT) ndbout_c("return %d", retVal);
- return retVal;
- }
-
- Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
- theNdb->theNdbBlockNumber);
-
- const Uint32 seq = theNdbCon->theNodeSequence;
-
- if(theError.code)
- {
- goto err4;
- }
-
- if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0)
- {
-
- idx = m_current_api_receiver;
- last = m_api_receivers_count;
- Uint32 timeout = tp->m_waitfor_timeout;
-
- do {
- if(theError.code){
- setErrorCode(theError.code);
- if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- return -1;
- }
-
- Uint32 cnt = m_conf_receivers_count;
- Uint32 sent = m_sent_receivers_count;
-
- if(DEBUG_NEXT_RESULT)
- ndbout_c("idx=%d last=%d cnt=%d sent=%d", idx, last, cnt, sent);
-
- 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...
- */
- int ret_code= poll_guard.wait_scan(3*timeout, nodeId, forceSend);
- if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
- continue;
- } else if(ret_code == -1){
- retVal = -1;
- } else {
- idx = last;
- retVal = -2; //return_code;
- }
- } else if(retVal == 2){
- /**
- * No completed & no sent -> EndOfData
- */
- theError.code = -1; // make sure user gets error if he tries again
- if(DEBUG_NEXT_RESULT) ndbout_c("return 1");
- return 1;
- }
-
- if(retVal == 0)
- break;
-
- for(; idx < last; idx++){
- NdbReceiver* tRec = m_api_receivers[idx];
- if(tRec->nextResult()){
- m_curr_row = tRec->copyout(theReceiver);
- retVal = 0;
- break;
- }
- }
- } while(retVal == 2);
- } else {
- retVal = -3;
- }
-
- m_api_receivers_count = last;
- m_current_api_receiver = idx;
-
- switch(retVal){
- case 0:
- case 1:
- case 2:
- if(DEBUG_NEXT_RESULT) ndbout_c("return %d", retVal);
- 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)
- if(theError.code == 0)
- setErrorCode(4028); // seq changed = Node fail
- break;
- case -4:
-err4:
- setErrorCode(theError.code);
- break;
- }
-
- theNdbCon->theTransactionIsStarted = false;
- theNdbCon->theReleaseOnClose = true;
- if(DEBUG_NEXT_RESULT) ndbout_c("return %d", retVal);
- return -1;
-}
-
-int
-NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag)
-{
- if(cnt > 0){
- 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);
- Uint32 sent = 0;
- for(Uint32 i = 0; i<cnt; i++){
- NdbReceiver * tRec = m_api_receivers[i];
- if((prep_array[sent] = tRec->m_tcPtrI) != RNIL)
- {
- m_sent_receivers[last+sent] = tRec;
- tRec->m_list_index = last+sent;
- tRec->prepareSend();
- sent++;
- }
- }
- memmove(m_api_receivers, m_api_receivers+cnt,
- (theParallelism-cnt) * sizeof(char*));
-
- int ret = 0;
- if(sent)
- {
- Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade * tp = theNdb->theImpl->m_transporter_facade;
- if(cnt > 21){
- tSignal.setLength(4);
- LinearSectionPtr ptr[3];
- ptr[0].p = prep_array;
- ptr[0].sz = sent;
- ret = tp->sendSignal(&tSignal, nodeId, ptr, 1);
- } else {
- tSignal.setLength(4+sent);
- ret = tp->sendSignal(&tSignal, nodeId);
- }
- }
- m_sent_receivers_count = last + sent;
- m_api_receivers_count -= cnt;
- m_current_api_receiver = 0;
-
- return ret;
- }
- return 0;
-}
-
-int
-NdbScanOperation::prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId)
-{
- printf("NdbScanOperation::prepareSend\n");
- abort();
- return 0;
-}
-
-int
-NdbScanOperation::doSend(int ProcessorId)
-{
- printf("NdbScanOperation::doSend\n");
- return 0;
-}
-
-void NdbScanOperation::close(bool forceSend, bool releaseOp)
-{
- DBUG_ENTER("NdbScanOperation::close");
- DBUG_PRINT("enter", ("this: 0x%lx tcon: 0x%lx con: 0x%lx force: %d release: %d",
- (long) this,
- (long) m_transConnection, (long) theNdbCon,
- forceSend, releaseOp));
-
- if(m_transConnection){
- if(DEBUG_NEXT_RESULT)
- ndbout_c("close() theError.code = %d "
- "m_api_receivers_count = %d "
- "m_conf_receivers_count = %d "
- "m_sent_receivers_count = %d",
- theError.code,
- m_api_receivers_count,
- m_conf_receivers_count,
- m_sent_receivers_count);
-
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
- theNdb->theNdbBlockNumber);
- close_impl(tp, forceSend, &poll_guard);
- }
-
- NdbConnection* tCon = theNdbCon;
- NdbConnection* tTransCon = m_transConnection;
- theNdbCon = NULL;
- m_transConnection = NULL;
-
- if (tTransCon && releaseOp)
- {
- NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this;
-
- bool ret = true;
- if (theStatus != WaitResponse)
- {
- /**
- * Not executed yet
- */
- ret =
- tTransCon->releaseScanOperation(&tTransCon->m_theFirstScanOperation,
- &tTransCon->m_theLastScanOperation,
- tOp);
- }
- else
- {
- ret = tTransCon->releaseScanOperation(&tTransCon->m_firstExecutedScanOp,
- 0, tOp);
- }
- assert(ret);
- }
-
- tCon->theScanningOp = 0;
- theNdb->closeTransaction(tCon);
- theNdb->theRemainingStartTransactions--;
- DBUG_VOID_RETURN;
-}
-
-void
-NdbScanOperation::execCLOSE_SCAN_REP(){
- m_conf_receivers_count = 0;
- m_sent_receivers_count = 0;
-}
-
-void NdbScanOperation::release()
-{
- if(theNdbCon != 0 || m_transConnection != 0){
- close();
- }
- for(Uint32 i = 0; i<m_allocated_receivers; i++){
- m_receivers[i]->release();
- }
-
- NdbOperation::release();
-
- if(theSCAN_TABREQ)
- {
- theNdb->releaseSignal(theSCAN_TABREQ);
- theSCAN_TABREQ = 0;
- }
-}
-
-/***************************************************************************
-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;
- }
-
- theErrorLine = 0;
-
- // 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();
- }
-
- theCurrentATTRINFO->setLength(theAI_LenInCurrAI);
-
- /**
- * Prepare all receivers
- */
- theReceiver.prepareSend();
- bool keyInfo = m_keyInfo;
- Uint32 key_size = keyInfo ? m_currentTable->m_keyLenInWords : 0;
- /**
- * The number of records sent by each LQH is calculated and the kernel
- * is informed of this number by updating the SCAN_TABREQ signal
- */
- ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
- Uint32 batch_size = req->first_batch_size; // User specified
- Uint32 batch_byte_size, first_batch_size;
- theReceiver.calculate_batch_size(key_size,
- theParallelism,
- batch_size,
- batch_byte_size,
- first_batch_size);
- ScanTabReq::setScanBatch(req->requestInfo, batch_size);
- req->batch_byte_size= batch_byte_size;
- req->first_batch_size= first_batch_size;
-
- /**
- * Set keyinfo flag
- * (Always keyinfo when using blobs)
- */
- Uint32 reqInfo = req->requestInfo;
- ScanTabReq::setKeyinfoFlag(reqInfo, keyInfo);
- ScanTabReq::setNoDiskFlag(reqInfo, m_no_disk_flag);
- req->requestInfo = reqInfo;
-
- for(Uint32 i = 0; i<theParallelism; i++){
- if (m_receivers[i]->do_get_value(&theReceiver, batch_size,
- key_size,
- m_read_range_no))
- {
- return -1;
- }
- }
- return 0;
-}
-
-/*****************************************************************************
-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)
-{
- Uint32 tSignalCount = 0;
- NdbApiSignal* tSignal;
-
- if (theInterpretIndicator != 1 ||
- (theOperationType != OpenScanRequest &&
- theOperationType != OpenRangeScanRequest)) {
- setErrorCodeAbort(4005);
- return -1;
- }
-
- assert(theSCAN_TABREQ != NULL);
- tSignal = theSCAN_TABREQ;
-
- Uint32 tupKeyLen = theTupKeyLen;
- Uint32 aTC_ConnectPtr = theNdbCon->theTCConPtr;
- Uint64 transId = theNdbCon->theTransactionId;
-
- // 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());
- if (unlikely(theTotalCurrAI_Len > ScanTabReq::MaxTotalAttrInfo)) {
- setErrorCode(4257);
- return -1;
- }
- req->attrLenKeyLen = (tupKeyLen << 16) | theTotalCurrAI_Len;
- Uint32 tmp = req->requestInfo;
- ScanTabReq::setDistributionKeyFlag(tmp, theDistrKeyIndicator_);
- req->distributionKey = theDistributionKey;
- req->requestInfo = tmp;
- tSignal->setLength(ScanTabReq::StaticLength + theDistrKeyIndicator_);
-
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
- LinearSectionPtr ptr[3];
- ptr[0].p = m_prepared_receivers;
- ptr[0].sz = theParallelism;
- if (tp->sendSignal(tSignal, aProcessorId, ptr, 1) == -1) {
- setErrorCode(4002);
- return -1;
- }
-
- if (tupKeyLen > 0){
- // must have at least one signal since it contains attrLen for bounds
- assert(theLastKEYINFO != NULL);
- tSignal = theLastKEYINFO;
- tSignal->setLength(KeyInfo::HeaderLength + theTotalNrOfKeyWordInSignal);
-
- assert(theSCAN_TABREQ->next() != NULL);
- tSignal = theSCAN_TABREQ->next();
-
- NdbApiSignal* last;
- do {
- KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend());
- keyInfo->connectPtr = aTC_ConnectPtr;
- keyInfo->transId[0] = Uint32(transId);
- keyInfo->transId[1] = Uint32(transId >> 32);
-
- if (tp->sendSignal(tSignal,aProcessorId) == -1){
- setErrorCode(4002);
- return -1;
- }
-
- tSignalCount++;
- last = tSignal;
- tSignal = tSignal->next();
- } while(last != theLastKEYINFO);
- }
-
- tSignal = theFirstATTRINFO;
- while (tSignal != NULL) {
- AttrInfo * attrInfo = CAST_PTR(AttrInfo, tSignal->getDataPtrSend());
- attrInfo->connectPtr = aTC_ConnectPtr;
- attrInfo->transId[0] = Uint32(transId);
- attrInfo->transId[1] = Uint32(transId >> 32);
-
- if (tp->sendSignal(tSignal,aProcessorId) == -1){
- setErrorCode(4002);
- return -1;
- }
- tSignalCount++;
- tSignal = tSignal->next();
- }
- theStatus = WaitResponse;
-
- m_curr_row = 0;
- m_sent_receivers_count = theParallelism;
- if(m_ordered)
- {
- m_current_api_receiver = theParallelism;
- m_api_receivers_count = theParallelism;
- }
-
- return tSignalCount;
-}//NdbOperation::doSendScan()
-
-/*****************************************************************************
- * NdbOperation* takeOverScanOp(NdbTransaction* updateTrans);
- *
- * Parameters: The update transactions NdbTransaction 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 NdbTransaction on another Ndb-object.
- * In this case the receiving NdbTransaction-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.
- ****************************************************************************/
-int
-NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, Uint32 & size)
-{
- NdbRecAttr * tRecAttr = m_curr_row;
- if(tRecAttr)
- {
- const Uint32 * src = (Uint32*)tRecAttr->aRef();
-
- assert(tRecAttr->get_size_in_bytes() > 0);
- assert(tRecAttr->get_size_in_bytes() < 65536);
- const Uint32 len = (tRecAttr->get_size_in_bytes() + 3)/4-1;
-
- assert(size >= len);
- memcpy(data, src, 4*len);
- size = len;
- return 0;
- }
- return -1;
-}
-
-NdbOperation*
-NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans)
-{
-
- NdbRecAttr * tRecAttr = m_curr_row;
- if(tRecAttr)
- {
- NdbOperation * newOp = pTrans->getNdbOperation(m_currentTable);
- if (newOp == NULL){
- return NULL;
- }
- if (!m_keyInfo)
- {
- // Cannot take over lock if no keyinfo was requested
- setErrorCodeAbort(4604);
- return NULL;
- }
- pTrans->theSimpleState = 0;
-
- assert(tRecAttr->get_size_in_bytes() > 0);
- assert(tRecAttr->get_size_in_bytes() < 65536);
- const Uint32 len = (tRecAttr->get_size_in_bytes() + 3)/4-1;
-
- newOp->theTupKeyLen = len;
- newOp->theOperationType = opType;
- newOp->m_abortOption = AbortOnError;
- switch (opType) {
- case (ReadRequest):
- newOp->theLockMode = theLockMode;
- // Fall through
- case (DeleteRequest):
- newOp->theStatus = GetValue;
- break;
- default:
- newOp->theStatus = SetValue;
- }
- const Uint32 * src = (Uint32*)tRecAttr->aRef();
- const Uint32 tScanInfo = src[len] & 0x3FFFF;
- const Uint32 tTakeOverFragment = src[len] >> 20;
- {
- UintR scanInfo = 0;
- TcKeyReq::setTakeOverScanFlag(scanInfo, 1);
- TcKeyReq::setTakeOverScanFragment(scanInfo, tTakeOverFragment);
- TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo);
- newOp->theScanInfo = scanInfo;
- newOp->theDistrKeyIndicator_ = 1;
- newOp->theDistributionKey = tTakeOverFragment;
- }
-
- // 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->theTCREQ->next(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();
- }
-
- if(tSignal && left > 0){
- tSignal->setSignal(GSN_KEYINFO);
- KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend());
- memcpy(keyInfo->keyData, src, 4 * left);
- }
- }
- // create blob handles automatically
- if (opType == DeleteRequest && m_currentTable->m_noOfBlobs != 0) {
- for (unsigned i = 0; i < m_currentTable->m_columns.size(); i++) {
- NdbColumnImpl* c = m_currentTable->m_columns[i];
- assert(c != 0);
- if (c->getBlobType()) {
- if (newOp->getBlobHandle(pTrans, c) == NULL)
- return NULL;
- }
- }
- }
-
- return newOp;
- }
- return 0;
-}
-
-NdbBlob*
-NdbScanOperation::getBlobHandle(const char* anAttrName)
-{
- m_keyInfo = 1;
- return NdbOperation::getBlobHandle(m_transConnection,
- m_currentTable->getColumn(anAttrName));
-}
-
-NdbBlob*
-NdbScanOperation::getBlobHandle(Uint32 anAttrId)
-{
- m_keyInfo = 1;
- return NdbOperation::getBlobHandle(m_transConnection,
- m_currentTable->getColumn(anAttrId));
-}
-
-NdbIndexScanOperation::NdbIndexScanOperation(Ndb* aNdb)
- : NdbScanOperation(aNdb, NdbOperation::OrderedIndexScan)
-{
-}
-
-NdbIndexScanOperation::~NdbIndexScanOperation(){
-}
-
-int
-NdbIndexScanOperation::setBound(const char* anAttrName, int type,
- const void* aValue)
-{
- return setBound(m_accessTable->getColumn(anAttrName), type, aValue);
-}
-
-int
-NdbIndexScanOperation::setBound(Uint32 anAttrId, int type,
- const void* aValue)
-{
- return setBound(m_accessTable->getColumn(anAttrId), type, aValue);
-}
-
-int
-NdbIndexScanOperation::equal_impl(const NdbColumnImpl* anAttrObject,
- const char* aValue)
-{
- return setBound(anAttrObject, BoundEQ, aValue);
-}
-
-NdbRecAttr*
-NdbIndexScanOperation::getValue_impl(const NdbColumnImpl* attrInfo,
- char* aValue){
- if(!m_ordered){
- return NdbScanOperation::getValue_impl(attrInfo, aValue);
- }
-
- int id = attrInfo->getColumnNo(); // In "real" table
- assert(m_accessTable->m_index);
- int sz = (int)m_accessTable->m_index->m_key_ids.size();
- if(id >= sz || (id = m_accessTable->m_index->m_key_ids[id]) == -1){
- return NdbScanOperation::getValue_impl(attrInfo, aValue);
- }
-
- assert(id < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY);
- Uint32 marker = theTupleKeyDefined[id][0];
-
- if(marker == SETBOUND_EQ){
- return NdbScanOperation::getValue_impl(attrInfo, aValue);
- } else if(marker == API_PTR){
- return NdbScanOperation::getValue_impl(attrInfo, aValue);
- }
-
- assert(marker == FAKE_PTR);
-
- 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;
-}
-
-#include <AttributeHeader.hpp>
-/*
- * Define bound on index column in range scan.
- */
-int
-NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
- int type, const void* aValue)
-{
- if (!tAttrInfo)
- {
- setErrorCodeAbort(4318); // Invalid attribute
- return -1;
- }
- if (theOperationType == OpenRangeScanRequest &&
- (0 <= type && type <= 4)) {
- // insert bound type
- Uint32 currLen = theTotalNrOfKeyWordInSignal;
- Uint32 remaining = KeyInfo::DataLength - currLen;
- bool tDistrKey = tAttrInfo->m_distributionKey;
-
- Uint32 len = 0;
- if (aValue != NULL)
- if (! tAttrInfo->get_var_length(aValue, len)) {
- setErrorCodeAbort(4209);
- return -1;
- }
-
- // insert attribute header
- Uint32 tIndexAttrId = tAttrInfo->m_attrId;
- Uint32 sizeInWords = (len + 3) / 4;
- AttributeHeader ah(tIndexAttrId, sizeInWords << 2);
- const Uint32 ahValue = ah.m_value;
-
- const Uint32 align = (UintPtr(aValue) & 7);
- const bool aligned = (tDistrKey && type == BoundEQ) ?
- (align == 0) : (align & 3) == 0;
-
- const bool nobytes = (len & 0x3) == 0;
- const Uint32 totalLen = 2 + sizeInWords;
- Uint32 tupKeyLen = theTupKeyLen;
- union {
- Uint32 tempData[2000];
- Uint64 __my_align;
- };
- Uint64 *valPtr;
- if(remaining > totalLen && aligned && nobytes){
- Uint32 * dst = theKEYINFOptr + currLen;
- * dst ++ = type;
- * dst ++ = ahValue;
- memcpy(dst, aValue, 4 * sizeInWords);
- theTotalNrOfKeyWordInSignal = currLen + totalLen;
- valPtr = (Uint64*)aValue;
- } else {
- if(!aligned || !nobytes){
- tempData[0] = type;
- tempData[1] = ahValue;
- tempData[2 + (len >> 2)] = 0;
- memcpy(tempData+2, aValue, len);
- insertBOUNDS(tempData, 2+sizeInWords);
- valPtr = (Uint64*)(tempData+2);
- } else {
- Uint32 buf[2] = { type, ahValue };
- insertBOUNDS(buf, 2);
- insertBOUNDS((Uint32*)aValue, sizeInWords);
- valPtr = (Uint64*)aValue;
- }
- }
- theTupKeyLen = tupKeyLen + totalLen;
-
- /**
- * 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(type == BoundEQ && tDistrKey && !m_multi_range)
- {
- theNoOfTupKeyLeft--;
- return handle_distribution_key(valPtr, sizeInWords);
- }
- return 0;
- } else {
- setErrorCodeAbort(4228); // XXX wrong code
- return -1;
- }
-}
-
-int
-NdbIndexScanOperation::insertBOUNDS(Uint32 * data, Uint32 sz){
- Uint32 len;
- Uint32 remaining = KeyInfo::DataLength - theTotalNrOfKeyWordInSignal;
- Uint32 * dst = theKEYINFOptr + theTotalNrOfKeyWordInSignal;
- do {
- len = (sz < remaining ? sz : remaining);
- memcpy(dst, data, 4 * len);
-
- if(sz >= remaining){
- NdbApiSignal* tCurr = theLastKEYINFO;
- tCurr->setLength(KeyInfo::MaxSignalLength);
- NdbApiSignal* tSignal = tCurr->next();
- if(tSignal)
- ;
- else if((tSignal = theNdb->getSignal()) != 0)
- {
- tCurr->next(tSignal);
- tSignal->setSignal(GSN_KEYINFO);
- } else {
- goto error;
- }
- theLastKEYINFO = tSignal;
- theKEYINFOptr = dst = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
- remaining = KeyInfo::DataLength;
- sz -= len;
- data += len;
- } else {
- len = (KeyInfo::DataLength - remaining) + len;
- break;
- }
- } while(true);
- theTotalNrOfKeyWordInSignal = len;
- return 0;
-
-error:
- setErrorCodeAbort(4228); // XXX wrong code
- return -1;
-}
-
-Uint32
-NdbIndexScanOperation::getKeyFromSCANTABREQ(Uint32* data, Uint32 size)
-{
- DBUG_ENTER("NdbIndexScanOperation::getKeyFromSCANTABREQ");
- assert(size >= theTotalNrOfKeyWordInSignal);
- size = theTotalNrOfKeyWordInSignal;
- NdbApiSignal* tSignal = theSCAN_TABREQ->next();
- Uint32 pos = 0;
- while (pos < size) {
- assert(tSignal != NULL);
- Uint32* tData = tSignal->getDataPtrSend();
- Uint32 rem = size - pos;
- if (rem > KeyInfo::DataLength)
- rem = KeyInfo::DataLength;
- Uint32 i = 0;
- while (i < rem) {
- data[pos + i] = tData[KeyInfo::HeaderLength + i];
- i++;
- }
- pos += rem;
- }
- DBUG_DUMP("key", (uchar*) data, size << 2);
- DBUG_RETURN(size);
-}
-
-int
-NdbIndexScanOperation::readTuples(LockMode lm,
- Uint32 scan_flags,
- Uint32 parallel,
- Uint32 batch)
-{
- const bool order_by = scan_flags & SF_OrderBy;
- const bool order_desc = scan_flags & SF_Descending;
- const bool read_range_no = scan_flags & SF_ReadRangeNo;
- m_multi_range = scan_flags & SF_MultiRange;
-
- int res = NdbScanOperation::readTuples(lm, scan_flags, parallel, batch);
- if(!res && read_range_no)
- {
- m_read_range_no = 1;
- Uint32 word = 0;
- AttributeHeader::init(&word, AttributeHeader::RANGE_NO, 0);
- if(insertATTRINFO(word) == -1)
- res = -1;
- }
- if (!res)
- {
- /**
- * Note that it is valid to have order_desc true and order_by false.
- *
- * This means that there will be no merge sort among partitions, but
- * each partition will still be returned in descending sort order.
- *
- * This is useful eg. if it is known that the scan spans only one
- * partition.
- */
- if (order_desc) {
- m_descending = true;
- ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
- ScanTabReq::setDescendingFlag(req->requestInfo, true);
- }
- if (order_by) {
- m_ordered = true;
- Uint32 cnt = m_accessTable->getNoOfColumns() - 1;
- m_sort_columns = cnt; // -1 for NDB$NODE
- m_current_api_receiver = m_sent_receivers_count;
- m_api_receivers_count = m_sent_receivers_count;
-
- m_sort_columns = cnt;
- for(Uint32 i = 0; i<cnt; i++){
- const NdbColumnImpl* key = m_accessTable->m_index->m_columns[i];
- const NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos);
- NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1);
- UintPtr newVal = UintPtr(tmp);
- theTupleKeyDefined[i][0] = FAKE_PTR;
- theTupleKeyDefined[i][1] = (newVal & 0xFFFFFFFF);
-#if (SIZEOF_CHARP == 8)
- theTupleKeyDefined[i][2] = (newVal >> 32);
-#endif
- }
- }
- }
- m_this_bound_start = 0;
- m_first_bound_word = theKEYINFOptr;
-
- return res;
-}
-
-void
-NdbIndexScanOperation::fix_get_values(){
- /**
- * Loop through all getValues and set buffer pointer to "API" pointer
- */
- NdbRecAttr * curr = theReceiver.theFirstRecAttr;
- Uint32 cnt = m_accessTable->getNoOfColumns() - 1;
- assert(cnt < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY);
-
- for(Uint32 i = 0; i<cnt; i++){
- Uint32 val = theTupleKeyDefined[i][0];
- switch(val){
- case FAKE_PTR:
- curr->setup(curr->m_column, 0);
- case API_PTR:
- curr = curr->next();
- break;
- case SETBOUND_EQ:
- break;
-#ifdef VM_TRACE
- default:
- abort();
-#endif
- }
- }
-}
-
-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];
-
- r1 = (skip ? r1->next() : r1);
- r2 = (skip ? r2->next() : r2);
- const int jdir = 1 - 2 * (int)m_descending;
- assert(jdir == 1 || jdir == -1);
- 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) * jdir;
- }
- const NdbColumnImpl & col = NdbColumnImpl::getImpl(* r1->m_column);
- Uint32 len1 = r1->get_size_in_bytes();
- Uint32 len2 = r2->get_size_in_bytes();
- if(!r1_null){
- const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_type);
- int r = (*sqlType.m_cmp)(col.m_cs, d1, len1, d2, len2, true);
- if(r){
- assert(r != NdbSqlUtil::CmpUnknown);
- return r * jdir;
- }
- }
- cols--;
- r1 = r1->next();
- r2 = r2->next();
- }
- return 0;
-}
-
-int
-NdbIndexScanOperation::next_result_ordered(bool fetchAllowed,
- bool forceSend){
-
- m_curr_row = 0;
- Uint32 u_idx = 0, u_last = 0;
- Uint32 s_idx = m_current_api_receiver; // first sorted
- Uint32 s_last = theParallelism; // last sorted
-
- NdbReceiver** arr = m_api_receivers;
- NdbReceiver* tRec = arr[s_idx];
-
- if(DEBUG_NEXT_RESULT) ndbout_c("nextOrderedResult(%d) nextResult: %d",
- fetchAllowed,
- (s_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 = (s_idx == s_last) || !tRec->nextResult();
-
- if(fetchNeeded){
- if(fetchAllowed){
- if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch...");
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
- theNdb->theNdbBlockNumber);
- if(theError.code)
- return -1;
- Uint32 seq = theNdbCon->theNodeSequence;
- Uint32 nodeId = theNdbCon->theDBnode;
- Uint32 timeout = tp->m_waitfor_timeout;
- if(seq == tp->getNodeSequence(nodeId) &&
- !send_next_scan_ordered(s_idx)){
- Uint32 tmp = m_sent_receivers_count;
- s_idx = m_current_api_receiver;
- while(m_sent_receivers_count > 0 && !theError.code){
- int ret_code= poll_guard.wait_scan(3*timeout, nodeId, forceSend);
- if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
- continue;
- }
- if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- if(ret_code == -1){
- setErrorCode(4008);
- } else {
- setErrorCode(4028);
- }
- return -1;
- }
-
- if(theError.code){
- setErrorCode(theError.code);
- if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- return -1;
- }
-
- u_idx = 0;
- u_last = m_conf_receivers_count;
- 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 {
- setErrorCode(4028);
- return -1;
- }
- } else {
- if(DEBUG_NEXT_RESULT) ndbout_c("return 2");
- return 2;
- }
- } else {
- u_idx = s_idx;
- u_last = s_idx + 1;
- s_idx++;
- }
-
- 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 + m_read_range_no;
- 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--;
- }
-
- 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()){
- m_curr_row = tRec->copyout(theReceiver);
- if(DEBUG_NEXT_RESULT) ndbout_c("return 0");
- return 0;
- }
-
- theError.code = -1;
- if(DEBUG_NEXT_RESULT) ndbout_c("return 1");
- return 1;
-}
-
-int
-NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx)
-{
- if(idx == theParallelism)
- return 0;
-
- NdbReceiver* tRec = m_api_receivers[idx];
- NdbApiSignal tSignal(theNdb->theMyRef);
- tSignal.setSignal(GSN_SCAN_NEXTREQ);
-
- Uint32 last = m_sent_receivers_count;
- Uint32* theData = tSignal.getDataPtrSend();
- Uint32* prep_array = theData + 4;
-
- m_current_api_receiver = idx + 1;
- if((prep_array[0] = tRec->m_tcPtrI) == RNIL)
- {
- if(DEBUG_NEXT_RESULT)
- ndbout_c("receiver completed, don't send");
- return 0;
- }
-
- theData[0] = theNdbCon->theTCConPtr;
- theData[1] = 0;
- Uint64 transId = theNdbCon->theTransactionId;
- theData[2] = transId;
- theData[3] = (Uint32) (transId >> 32);
-
- /**
- * Prepare ops
- */
- m_sent_receivers[last] = tRec;
- tRec->m_list_index = last;
- tRec->prepareSend();
- m_sent_receivers_count = last + 1;
-
- Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade * tp = theNdb->theImpl->m_transporter_facade;
- tSignal.setLength(4+1);
- int ret= tp->sendSignal(&tSignal, nodeId);
- return ret;
-}
-
-int
-NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend,
- PollGuard *poll_guard)
-{
- Uint32 seq = theNdbCon->theNodeSequence;
- Uint32 nodeId = theNdbCon->theDBnode;
-
- if(seq != tp->getNodeSequence(nodeId))
- {
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
-
- Uint32 timeout = tp->m_waitfor_timeout;
- /**
- * Wait for outstanding
- */
- while(theError.code == 0 && m_sent_receivers_count)
- {
- int return_code= poll_guard->wait_scan(3*timeout, nodeId, forceSend);
- switch(return_code){
- case 0:
- break;
- case -1:
- setErrorCode(4008);
- case -2:
- m_api_receivers_count = 0;
- m_conf_receivers_count = 0;
- m_sent_receivers_count = 0;
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
- }
-
- if(theError.code)
- {
- m_api_receivers_count = 0;
- m_current_api_receiver = m_ordered ? theParallelism : 0;
- }
-
-
- /**
- * move all conf'ed into api
- * so that send_next_scan can check if they needs to be closed
- */
- Uint32 api = m_api_receivers_count;
- Uint32 conf = m_conf_receivers_count;
-
- if(m_ordered)
- {
- /**
- * Ordered scan, keep the m_api_receivers "to the right"
- */
- memmove(m_api_receivers, m_api_receivers+m_current_api_receiver,
- (theParallelism - m_current_api_receiver) * sizeof(char*));
- api = (theParallelism - m_current_api_receiver);
- m_api_receivers_count = api;
- }
-
- if(DEBUG_NEXT_RESULT)
- ndbout_c("close_impl: [order api conf sent curr parr] %d %d %d %d %d %d",
- m_ordered, api, conf,
- m_sent_receivers_count, m_current_api_receiver, theParallelism);
-
- if(api+conf)
- {
- /**
- * There's something to close
- * setup m_api_receivers (for send_next_scan)
- */
- memcpy(m_api_receivers+api, m_conf_receivers, conf * sizeof(char*));
- m_api_receivers_count = api + conf;
- m_conf_receivers_count = 0;
- }
-
- // Send close scan
- if(send_next_scan(api+conf, true) == -1)
- {
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
-
- /**
- * wait for close scan conf
- */
- while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count)
- {
- int return_code= poll_guard->wait_scan(3*timeout, nodeId, forceSend);
- switch(return_code){
- case 0:
- break;
- case -1:
- setErrorCode(4008);
- case -2:
- m_api_receivers_count = 0;
- m_conf_receivers_count = 0;
- m_sent_receivers_count = 0;
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
- }
-
- return 0;
-}
-
-void
-NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){
- 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_receivers[i]->prepareSend();
- }
-
- m_api_receivers_count = 0;
- m_current_api_receiver = 0;
- m_sent_receivers_count = 0;
- m_conf_receivers_count = 0;
-}
-
-int
-NdbScanOperation::restart(bool forceSend)
-{
-
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
- theNdb->theNdbBlockNumber);
- Uint32 nodeId = theNdbCon->theDBnode;
-
- {
- int res;
- if((res= close_impl(tp, forceSend, &poll_guard)))
- {
- return res;
- }
- }
-
- /**
- * Reset receivers
- */
- reset_receivers(theParallelism, m_ordered);
-
- theError.code = 0;
- if (doSendScan(nodeId) == -1)
- return -1;
- return 0;
-}
-
-int
-NdbIndexScanOperation::reset_bounds(bool forceSend){
- int res;
-
- {
- TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
- theNdb->theNdbBlockNumber);
- res= close_impl(tp, forceSend, &poll_guard);
- }
-
- if(!res)
- {
- theError.code = 0;
- reset_receivers(theParallelism, m_ordered);
-
- theLastKEYINFO = theSCAN_TABREQ->next();
- theKEYINFOptr = ((KeyInfo*)theLastKEYINFO->getDataPtrSend())->keyData;
- theTupKeyLen = 0;
- theTotalNrOfKeyWordInSignal = 0;
- theNoOfTupKeyLeft = m_accessTable->m_noOfDistributionKeys;
- theDistrKeyIndicator_ = 0;
- m_this_bound_start = 0;
- m_first_bound_word = theKEYINFOptr;
- m_transConnection
- ->remove_list((NdbOperation*&)m_transConnection->m_firstExecutedScanOp,
- this);
- m_transConnection->define_scan_op(this);
- return 0;
- }
- return res;
-}
-
-int
-NdbIndexScanOperation::end_of_bound(Uint32 no)
-{
- DBUG_ENTER("end_of_bound");
- DBUG_PRINT("info", ("Range number %u", no));
- /* Check that SF_MultiRange has been specified if more
- than one range is specified */
- if (no > 0 && !m_multi_range)
- DBUG_RETURN(-1);
- if(no < (1 << 13)) // Only 12-bits no of ranges
- {
- Uint32 bound_head = * m_first_bound_word;
- bound_head |= (theTupKeyLen - m_this_bound_start) << 16 | (no << 4);
- * m_first_bound_word = bound_head;
-
- m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;;
- m_this_bound_start = theTupKeyLen;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(-1);
-}
-
-int
-NdbIndexScanOperation::get_range_no()
-{
- NdbRecAttr* tRecAttr = m_curr_row;
- if(m_read_range_no && tRecAttr)
- {
- if(m_keyInfo)
- tRecAttr = tRecAttr->next();
- Uint32 ret = *(Uint32*)tRecAttr->aRef();
- return ret;
- }
- return -1;
-}
diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp
deleted file mode 100644
index f446267f3b2..00000000000
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp
+++ /dev/null
@@ -1,2221 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbOperation.hpp>
-#include <NdbScanOperation.hpp>
-#include <NdbIndexScanOperation.hpp>
-#include <NdbIndexOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include "TransporterFacade.hpp"
-#include "API.hpp"
-#include "NdbBlob.hpp"
-
-#include <signaldata/TcKeyConf.hpp>
-#include <signaldata/TcIndx.hpp>
-#include <signaldata/TcCommit.hpp>
-#include <signaldata/TcKeyFailConf.hpp>
-#include <signaldata/TcHbRep.hpp>
-#include <signaldata/TcRollbackRep.hpp>
-
-/*****************************************************************************
-NdbTransaction( Ndb* aNdb );
-
-Return Value: None
-Parameters: aNdb: Pointers to the Ndb object
-Remark: Creates a connection object.
-*****************************************************************************/
-NdbTransaction::NdbTransaction( Ndb* aNdb ) :
- theSendStatus(NotInit),
- theCallbackFunction(NULL),
- theCallbackObject(NULL),
- theTransArrayIndex(0),
- theStartTransTime(0),
- theErrorLine(0),
- theErrorOperation(NULL),
- theNdb(aNdb),
- theNext(NULL),
- theFirstOpInList(NULL),
- theLastOpInList(NULL),
- theFirstExecOpInList(NULL),
- theLastExecOpInList(NULL),
- theCompletedFirstOp(NULL),
- theCompletedLastOp(NULL),
- theNoOfOpSent(0),
- theNoOfOpCompleted(0),
- theMyRef(0),
- theTCConPtr(0),
- theTransactionId(0),
- theGlobalCheckpointId(0),
- p_latest_trans_gci(0),
- theStatus(NotConnected),
- theCompletionStatus(NotCompleted),
- theCommitStatus(NotStarted),
- theMagicNumber(0xFE11DC),
- theTransactionIsStarted(false),
- theDBnode(0),
- theReleaseOnClose(false),
- // Scan operations
- m_waitForReply(true),
- m_theFirstScanOperation(NULL),
- m_theLastScanOperation(NULL),
- m_firstExecutedScanOp(NULL),
- // Scan operations
- theScanningOp(NULL),
- theBuddyConPtr(0xFFFFFFFF),
- theBlobFlag(false),
- thePendingBlobOps(0)
-{
- theListState = NotInList;
- theError.code = 0;
- //theId = NdbObjectIdMap::InvalidId;
- theId = theNdb->theImpl->theNdbObjectIdMap.map(this);
-
-#define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz)
-
- CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size);
- CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size);
-}//NdbTransaction::NdbTransaction()
-
-/*****************************************************************************
-~NdbTransaction();
-
-Remark: Deletes the connection object.
-*****************************************************************************/
-NdbTransaction::~NdbTransaction()
-{
- DBUG_ENTER("NdbTransaction::~NdbTransaction");
- theNdb->theImpl->theNdbObjectIdMap.unmap(theId, this);
- DBUG_VOID_RETURN;
-}//NdbTransaction::~NdbTransaction()
-
-/*****************************************************************************
-void init();
-
-Remark: Initialise connection object for new transaction.
-*****************************************************************************/
-int
-NdbTransaction::init()
-{
- theListState = NotInList;
- theInUseState = true;
- theTransactionIsStarted = false;
- theNext = NULL;
-
- theFirstOpInList = NULL;
- theLastOpInList = NULL;
-
- theScanningOp = NULL;
-
- theFirstExecOpInList = NULL;
- theLastExecOpInList = NULL;
-
- theCompletedFirstOp = NULL;
- theCompletedLastOp = NULL;
-
- theGlobalCheckpointId = 0;
- p_latest_trans_gci =
- theNdb->theImpl->m_ndb_cluster_connection.get_latest_trans_gci();
- theCommitStatus = Started;
- theCompletionStatus = NotCompleted;
-
- theError.code = 0;
- theErrorLine = 0;
- theErrorOperation = NULL;
-
- theReleaseOnClose = false;
- theSimpleState = true;
- theSendStatus = InitState;
- theMagicNumber = 0x37412619;
- // Scan operations
- m_waitForReply = true;
- m_theFirstScanOperation = NULL;
- m_theLastScanOperation = NULL;
- m_firstExecutedScanOp = 0;
- theBuddyConPtr = 0xFFFFFFFF;
- //
- theBlobFlag = false;
- thePendingBlobOps = 0;
- if (theId == NdbObjectIdMap::InvalidId)
- {
- theId = theNdb->theImpl->theNdbObjectIdMap.map(this);
- if (theId == NdbObjectIdMap::InvalidId)
- {
- theError.code = 4000;
- return -1;
- }
- }
- return 0;
-
-}//NdbTransaction::init()
-
-/*****************************************************************************
-setOperationErrorCode(int error);
-
-Remark: Sets an error code on the connection object from an
- operation object.
-*****************************************************************************/
-void
-NdbTransaction::setOperationErrorCode(int error)
-{
- DBUG_ENTER("NdbTransaction::setOperationErrorCode");
- setErrorCode(error);
- DBUG_VOID_RETURN;
-}
-
-/*****************************************************************************
-setOperationErrorCodeAbort(int error);
-
-Remark: Sets an error code on the connection object from an
- operation object.
-*****************************************************************************/
-void
-NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption)
-{
- DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort");
- if (theTransactionIsStarted == false) {
- theCommitStatus = Aborted;
- } else if ((theCommitStatus != Committed) &&
- (theCommitStatus != Aborted)) {
- theCommitStatus = NeedAbort;
- }//if
- setErrorCode(error);
- DBUG_VOID_RETURN;
-}
-
-/*****************************************************************************
-setErrorCode(int anErrorCode);
-
-Remark: Sets an error indication on the connection object.
-*****************************************************************************/
-void
-NdbTransaction::setErrorCode(int error)
-{
- DBUG_ENTER("NdbTransaction::setErrorCode");
- DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code));
-
- if (theError.code == 0)
- theError.code = error;
-
- DBUG_VOID_RETURN;
-}//NdbTransaction::setErrorCode()
-
-int
-NdbTransaction::restart(){
- DBUG_ENTER("NdbTransaction::restart");
- if(theCompletionStatus == CompletedSuccess){
- releaseCompletedOperations();
- Uint64 tTransid = theNdb->theFirstTransId;
- theTransactionId = tTransid;
- if ((tTransid & 0xFFFFFFFF) == 0xFFFFFFFF) {
- theNdb->theFirstTransId = (tTransid >> 32) << 32;
- } else {
- theNdb->theFirstTransId = tTransid + 1;
- }
- theCommitStatus = Started;
- theCompletionStatus = NotCompleted;
- theTransactionIsStarted = false;
- DBUG_RETURN(0);
- }
- DBUG_PRINT("error",("theCompletionStatus != CompletedSuccess"));
- DBUG_RETURN(-1);
-}
-
-/*****************************************************************************
-void handleExecuteCompletion(void);
-
-Remark: Handle time-out on a transaction object.
-*****************************************************************************/
-void
-NdbTransaction::handleExecuteCompletion()
-{
- /***************************************************************************
- * Move the NdbOperation objects from the list of executing
- * operations to list of completed
- **************************************************************************/
- NdbOperation* tFirstExecOp = theFirstExecOpInList;
- NdbOperation* tLastExecOp = theLastExecOpInList;
- if (tLastExecOp != NULL) {
- tLastExecOp->next(theCompletedFirstOp);
- theCompletedFirstOp = tFirstExecOp;
- if (theCompletedLastOp == NULL)
- theCompletedLastOp = tLastExecOp;
- theFirstExecOpInList = NULL;
- theLastExecOpInList = NULL;
- }//if
- theSendStatus = InitState;
- return;
-}//NdbTransaction::handleExecuteCompletion()
-
-/*****************************************************************************
-int execute(ExecType aTypeOfExec, CommitType aTypeOfCommit, int forceSend);
-
-Return Value: Return 0 : execute was successful.
- Return -1: In all other case.
-Parameters : aTypeOfExec: Type of execute.
-Remark: Initialise connection object for new transaction.
-*****************************************************************************/
-int
-NdbTransaction::execute(ExecType aTypeOfExec,
- NdbOperation::AbortOption abortOption,
- int forceSend)
-{
- NdbError savedError= theError;
- DBUG_ENTER("NdbTransaction::execute");
- DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
- aTypeOfExec, abortOption));
-
- if (! theBlobFlag)
- DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));
-
- /*
- * execute prepared ops in batches, as requested by blobs
- * - blob error does not terminate execution
- * - blob error sets error on operation
- * - if error on operation skip blob calls
- */
-
- ExecType tExecType;
- NdbOperation* tPrepOp;
- NdbOperation* tCompletedFirstOp = NULL;
- NdbOperation* tCompletedLastOp = NULL;
-
- int ret = 0;
- do {
- tExecType = aTypeOfExec;
- tPrepOp = theFirstOpInList;
- while (tPrepOp != NULL) {
- if (tPrepOp->theError.code == 0) {
- bool batch = false;
- NdbBlob* tBlob = tPrepOp->theBlobList;
- while (tBlob != NULL) {
- if (tBlob->preExecute(tExecType, batch) == -1)
- {
- ret = -1;
- if(savedError.code==0)
- savedError= theError;
- }
- tBlob = tBlob->theNext;
- }
- if (batch) {
- // blob asked to execute all up to here now
- tExecType = NoCommit;
- break;
- }
- }
- tPrepOp = tPrepOp->next();
- }
-
- // save rest of prepared ops if batch
- NdbOperation* tRestOp= 0;
- NdbOperation* tLastOp= 0;
- if (tPrepOp != NULL) {
- tRestOp = tPrepOp->next();
- tPrepOp->next(NULL);
- tLastOp = theLastOpInList;
- theLastOpInList = tPrepOp;
- }
-
- if (tExecType == Commit) {
- NdbOperation* tOp = theCompletedFirstOp;
- while (tOp != NULL) {
- if (tOp->theError.code == 0) {
- NdbBlob* tBlob = tOp->theBlobList;
- while (tBlob != NULL) {
- if (tBlob->preCommit() == -1)
- {
- ret = -1;
- if(savedError.code==0)
- savedError= theError;
- }
- tBlob = tBlob->theNext;
- }
- }
- tOp = tOp->next();
- }
- }
-
- // completed ops are in unspecified order
- if (theCompletedFirstOp != NULL) {
- if (tCompletedFirstOp == NULL) {
- tCompletedFirstOp = theCompletedFirstOp;
- tCompletedLastOp = theCompletedLastOp;
- } else {
- tCompletedLastOp->next(theCompletedFirstOp);
- tCompletedLastOp = theCompletedLastOp;
- }
- theCompletedFirstOp = NULL;
- theCompletedLastOp = NULL;
- }
-
- if (executeNoBlobs(tExecType,
- NdbOperation::DefaultAbortOption,
- forceSend) == -1)
- {
- if(savedError.code==0)
- savedError= theError;
-
- DBUG_RETURN(-1);
- }
-
-#ifdef ndb_api_crash_on_complex_blob_abort
- assert(theFirstOpInList == NULL && theLastOpInList == NULL);
-#else
- theFirstOpInList = theLastOpInList = NULL;
-#endif
-
- {
- NdbOperation* tOp = theCompletedFirstOp;
- while (tOp != NULL) {
- if (tOp->theError.code == 0) {
- NdbBlob* tBlob = tOp->theBlobList;
- while (tBlob != NULL) {
- // may add new operations if batch
- if (tBlob->postExecute(tExecType) == -1)
- {
- ret = -1;
- if(savedError.code==0)
- savedError= theError;
- }
- tBlob = tBlob->theNext;
- }
- }
- tOp = tOp->next();
- }
- }
-
- // add saved prepared ops if batch
- if (tPrepOp != NULL && tRestOp != NULL) {
- if (theFirstOpInList == NULL)
- theFirstOpInList = tRestOp;
- else
- theLastOpInList->next(tRestOp);
- theLastOpInList = tLastOp;
- }
- assert(theFirstOpInList == NULL || tExecType == NoCommit);
- } while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
-
- if (tCompletedFirstOp != NULL) {
- tCompletedLastOp->next(theCompletedFirstOp);
- theCompletedFirstOp = tCompletedFirstOp;
- if (theCompletedLastOp == NULL)
- theCompletedLastOp = tCompletedLastOp;
- }
-#if ndb_api_count_completed_ops_after_blob_execute
- { NdbOperation* tOp; unsigned n = 0;
- for (tOp = theCompletedFirstOp; tOp != NULL; tOp = tOp->next()) n++;
- ndbout << "completed ops: " << n << endl;
- }
-#endif
-
- if(savedError.code!=0 && theError.code==4350) // Trans already aborted
- theError= savedError;
-
- DBUG_RETURN(ret);
-}
-
-int
-NdbTransaction::executeNoBlobs(NdbTransaction::ExecType aTypeOfExec,
- NdbOperation::AbortOption abortOption,
- int forceSend)
-{
- DBUG_ENTER("NdbTransaction::executeNoBlobs");
- DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
- aTypeOfExec, abortOption));
-
-//------------------------------------------------------------------------
-// We will start by preparing all operations in the transaction defined
-// since last execute or since beginning. If this works ok we will continue
-// by calling the poll with wait method. This method will return when
-// the NDB kernel has completed its task or when 10 seconds have passed.
-// The NdbTransactionCallBack-method will receive the return code of the
-// transaction. The normal methods of reading error codes still apply.
-//------------------------------------------------------------------------
- Ndb* tNdb = theNdb;
-
- Uint32 timeout = theNdb->theImpl->m_transporter_facade->m_waitfor_timeout;
- m_waitForReply = false;
- executeAsynchPrepare(aTypeOfExec, NULL, NULL, abortOption);
- if (m_waitForReply){
- while (1) {
- int noOfComp = tNdb->sendPollNdb(3 * timeout, 1, forceSend);
- if (noOfComp == 0) {
- /*
- * Just for fun, this is only one of two places where
- * we could hit this error... It's quite possible we
- * hit it in Ndbif.cpp in Ndb::check_send_timeout()
- *
- * We behave rather similarly in both places.
- * Hitting this is certainly a bug though...
- */
- g_eventLogger.error("WARNING: Timeout in executeNoBlobs() waiting for "
- "response from NDB data nodes. This should NEVER "
- "occur. You have likely hit a NDB Bug. Please "
- "file a bug.");
- DBUG_PRINT("error",("This timeout should never occure, execute()"));
- g_eventLogger.error("Forcibly trying to rollback txn (%p"
- ") to try to clean up data node resources.",
- this);
- executeNoBlobs(NdbTransaction::Rollback);
- theError.code = 4012;
- theError.status= NdbError::PermanentError;
- theError.classification= NdbError::TimeoutExpired;
- setOperationErrorCodeAbort(4012); // ndbd timeout
- DBUG_RETURN(-1);
- }//if
-
- /*
- * Check that the completed transactions include this one. There
- * could be another thread running asynchronously. Even in pure
- * async case rollback is done synchronously.
- */
- if (theListState != NotInList)
- continue;
-#ifdef VM_TRACE
- unsigned anyway = 0;
- for (unsigned i = 0; i < theNdb->theNoOfPreparedTransactions; i++)
- anyway += theNdb->thePreparedTransactionsArray[i] == this;
- for (unsigned i = 0; i < theNdb->theNoOfSentTransactions; i++)
- anyway += theNdb->theSentTransactionsArray[i] == this;
- for (unsigned i = 0; i < theNdb->theNoOfCompletedTransactions; i++)
- anyway += theNdb->theCompletedTransactionsArray[i] == this;
- if (anyway) {
- theNdb->printState("execute %x", this);
- abort();
- }
-#endif
- if (theReturnStatus == ReturnFailure) {
- DBUG_RETURN(-1);
- }//if
- break;
- }
- }
- thePendingBlobOps = 0;
- DBUG_RETURN(0);
-}//NdbTransaction::execute()
-
-/*****************************************************************************
-void executeAsynchPrepare(ExecType aTypeOfExec,
- NdbAsynchCallback callBack,
- void* anyObject,
- CommitType aTypeOfCommit);
-
-Return Value: No return value
-Parameters : aTypeOfExec: Type of execute.
- anyObject: An object provided in the callback method
- callBack: The callback method
- aTypeOfCommit: What to do when read/updated/deleted records
- are missing or inserted records already exist.
-
-Remark: Prepare a part of a transaction in an asynchronous manner.
-*****************************************************************************/
-void
-NdbTransaction::executeAsynchPrepare(NdbTransaction::ExecType aTypeOfExec,
- NdbAsynchCallback aCallback,
- void* anyObject,
- NdbOperation::AbortOption abortOption)
-{
- DBUG_ENTER("NdbTransaction::executeAsynchPrepare");
- DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: 0x%lx, anyObject: Ox%lx",
- aTypeOfExec, (long) aCallback, (long) anyObject));
-
- /**
- * Reset error.code on execute
- */
- if (theError.code != 0)
- DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
- /**
- * for timeout (4012) we want sendROLLBACK to behave differently.
- * Else, normal behaviour of reset errcode
- */
- if (theError.code != 4012)
- theError.code = 0;
- NdbScanOperation* tcOp = m_theFirstScanOperation;
- if (tcOp != 0){
- // Execute any cursor operations
- while (tcOp != NULL) {
- int tReturnCode;
- tReturnCode = tcOp->executeCursor(theDBnode);
- if (tReturnCode == -1) {
- DBUG_VOID_RETURN;
- }//if
- tcOp = (NdbScanOperation*)tcOp->next();
- } // while
- 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_theFirstScanOperation = m_theLastScanOperation = NULL;
- }
-
- bool tTransactionIsStarted = theTransactionIsStarted;
- NdbOperation* tLastOp = theLastOpInList;
- Ndb* tNdb = theNdb;
- CommitStatusType tCommitStatus = theCommitStatus;
- Uint32 tnoOfPreparedTransactions = tNdb->theNoOfPreparedTransactions;
-
- theReturnStatus = ReturnSuccess;
- theCallbackFunction = aCallback;
- theCallbackObject = anyObject;
- m_waitForReply = true;
- tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
- theTransArrayIndex = tnoOfPreparedTransactions;
- theListState = InPreparedList;
- tNdb->theNoOfPreparedTransactions = tnoOfPreparedTransactions + 1;
-
- if ((tCommitStatus != Started) ||
- (aTypeOfExec == Rollback)) {
-/*****************************************************************************
- * Rollback have been ordered on a started transaction. Call rollback.
- * Could also be state problem or previous problem which leads to the
- * same action.
- ****************************************************************************/
- if (aTypeOfExec == Rollback) {
- if (theTransactionIsStarted == false || theSimpleState) {
- theCommitStatus = Aborted;
- theSendStatus = sendCompleted;
- } else {
- theSendStatus = sendABORT;
- }
- } else {
- theSendStatus = sendABORTfail;
- }//if
- if (theCommitStatus == Aborted){
- DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
- setErrorCode(4350);
- }
- DBUG_VOID_RETURN;
- }//if
- if (tTransactionIsStarted == true) {
- if (tLastOp != NULL) {
- if (aTypeOfExec == Commit) {
-/*****************************************************************************
- * Set commit indicator on last operation when commit has been ordered
- * and also a number of operations.
-******************************************************************************/
- tLastOp->theCommitIndicator = 1;
- }//if
- } else {
- if (aTypeOfExec == Commit && !theSimpleState) {
- /**********************************************************************
- * A Transaction have been started and no more operations exist.
- * We will use the commit method.
- *********************************************************************/
- theSendStatus = sendCOMMITstate;
- DBUG_VOID_RETURN;
- } else {
- /**********************************************************************
- * We need to put it into the array of completed transactions to
- * ensure that we report the completion in a proper way.
- * We cannot do this here since that would endanger the completed
- * transaction array since that is also updated from the receiver
- * thread and thus we need to do it under mutex lock and thus we
- * set the sendStatus to ensure that the send method will
- * put it into the completed array.
- **********************************************************************/
- theSendStatus = sendCompleted;
- DBUG_VOID_RETURN; // No Commit with no operations is OK
- }//if
- }//if
- } else if (tTransactionIsStarted == false) {
- NdbOperation* tFirstOp = theFirstOpInList;
- if (tLastOp != NULL) {
- tFirstOp->setStartIndicator();
- if (aTypeOfExec == Commit) {
- tLastOp->theCommitIndicator = 1;
- }//if
- } else {
- /***********************************************************************
- * No operations are defined and we have not started yet.
- * Simply return OK. Set commit status if Commit.
- ***********************************************************************/
- if (aTypeOfExec == Commit) {
- theCommitStatus = Committed;
- }//if
- /***********************************************************************
- * We need to put it into the array of completed transactions to
- * ensure that we report the completion in a proper way. We
- * cannot do this here since that would endanger the completed
- * transaction array since that is also updated from the
- * receiver thread and thus we need to do it under mutex lock
- * and thus we set the sendStatus to ensure that the send method
- * will put it into the completed array.
- ***********************************************************************/
- theSendStatus = sendCompleted;
- DBUG_VOID_RETURN;
- }//if
- }
-
- NdbOperation* tOp = theFirstOpInList;
- theCompletionStatus = NotCompleted;
- while (tOp) {
- int tReturnCode;
- NdbOperation* tNextOp = tOp->next();
- tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId, abortOption);
- if (tReturnCode == -1) {
- theSendStatus = sendABORTfail;
- DBUG_VOID_RETURN;
- }//if
-
- /*************************************************************************
- * Now that we have successfully prepared the send of this operation we
- * move it to the list of executing operations and remove it from the
- * list of defined operations.
- ************************************************************************/
- tOp = tNextOp;
- }
-
- NdbOperation* tLastOpInList = theLastOpInList;
- NdbOperation* tFirstOpInList = theFirstOpInList;
-
- theFirstOpInList = NULL;
- theLastOpInList = NULL;
- theFirstExecOpInList = tFirstOpInList;
- theLastExecOpInList = tLastOpInList;
-
- theCompletionStatus = CompletedSuccess;
- theNoOfOpSent = 0;
- theNoOfOpCompleted = 0;
- theSendStatus = sendOperations;
- NdbNodeBitmask::clear(m_db_nodes);
- NdbNodeBitmask::clear(m_failed_db_nodes);
- DBUG_VOID_RETURN;
-}//NdbTransaction::executeAsynchPrepare()
-
-void
-NdbTransaction::executeAsynch(ExecType aTypeOfExec,
- NdbAsynchCallback aCallback,
- void* anyObject,
- NdbOperation::AbortOption abortOption,
- int forceSend)
-{
- executeAsynchPrepare(aTypeOfExec, aCallback, anyObject, abortOption);
- theNdb->sendPreparedTransactions(forceSend);
-}
-
-void NdbTransaction::close()
-{
- theNdb->closeTransaction(this);
-}
-
-int NdbTransaction::refresh(){
- return sendTC_HBREP();
-}
-
-/*****************************************************************************
-int sendTC_HBREP();
-
-Return Value: No return value.
-Parameters : None.
-Remark: Order NDB to refresh the timeout counter of the transaction.
-******************************************************************************/
-int
-NdbTransaction::sendTC_HBREP() // Send a TC_HBREP signal;
-{
- NdbApiSignal* tSignal;
- Ndb* tNdb = theNdb;
- Uint32 tTransId1, tTransId2;
-
- tSignal = tNdb->getSignal();
- if (tSignal == NULL) {
- return -1;
- }
-
- if (tSignal->setSignal(GSN_TC_HBREP) == -1) {
- return -1;
- }
-
- TcHbRep * const tcHbRep = CAST_PTR(TcHbRep, tSignal->getDataPtrSend());
-
- tcHbRep->apiConnectPtr = theTCConPtr;
-
- tTransId1 = (Uint32) theTransactionId;
- tTransId2 = (Uint32) (theTransactionId >> 32);
- tcHbRep->transId1 = tTransId1;
- tcHbRep->transId2 = tTransId2;
-
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
- tp->lock_mutex();
- const int res = tp->sendSignal(tSignal,theDBnode);
- tp->unlock_mutex();
- tNdb->releaseSignal(tSignal);
-
- if (res == -1){
- return -1;
- }
-
- return 0;
-}//NdbTransaction::sendTC_HBREP()
-
-/*****************************************************************************
-int doSend();
-
-Return Value: Return 0 : send was successful.
- Return -1: In all other case.
-Remark: Send all operations belonging to this connection.
- The caller of this method has the responsibility to remove the
- object from the prepared transactions array on the Ndb-object.
-*****************************************************************************/
-int
-NdbTransaction::doSend()
-{
- DBUG_ENTER("NdbTransaction::doSend");
-
- /*
- This method assumes that at least one operation have been defined. This
- is ensured by the caller of this routine (=execute).
- */
-
- switch(theSendStatus){
- case sendOperations: {
- NdbOperation * tOp = theFirstExecOpInList;
- do {
- NdbOperation* tNextOp = tOp->next();
- const Uint32 lastFlag = ((tNextOp == NULL) ? 1 : 0);
- const int tReturnCode = tOp->doSend(theDBnode, lastFlag);
- if (tReturnCode == -1) {
- theReturnStatus = ReturnFailure;
- break;
- }//if
- tOp = tNextOp;
- } while (tOp != NULL);
- Ndb* tNdb = theNdb;
- theSendStatus = sendTC_OP;
- theTransactionIsStarted = true;
- tNdb->insert_sent_list(this);
- DBUG_RETURN(0);
- }//case
- case sendABORT:
- case sendABORTfail:{
- /***********************************************************************
- * Rollback have been ordered on a not started transaction.
- * Simply return OK and set abort status.
- ***********************************************************************/
- if (theSendStatus == sendABORTfail) {
- theReturnStatus = ReturnFailure;
- }//if
- if (sendROLLBACK() == 0) {
- DBUG_RETURN(0);
- }//if
- break;
- }//case
- case sendCOMMITstate:
- if (sendCOMMIT() == 0) {
- DBUG_RETURN(0);
- }//if
- break;
- case sendCompleted:
- theNdb->insert_completed_list(this);
- DBUG_RETURN(0);
- default:
- ndbout << "Inconsistent theSendStatus = "
- << (Uint32) theSendStatus << endl;
- abort();
- break;
- }//switch
- setOperationErrorCodeAbort(4002);
- theReleaseOnClose = true;
- theTransactionIsStarted = false;
- theCommitStatus = Aborted;
- DBUG_RETURN(-1);
-}//NdbTransaction::doSend()
-
-/**************************************************************************
-int sendROLLBACK();
-
-Return Value: Return -1 if send unsuccessful.
-Parameters : None.
-Remark: Order NDB to rollback the transaction.
-**************************************************************************/
-int
-NdbTransaction::sendROLLBACK() // Send a TCROLLBACKREQ signal;
-{
- Ndb* tNdb = theNdb;
- 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.
- *************************************************************************/
- NdbApiSignal tSignal(tNdb->theMyRef);
- Uint32 tTransId1, tTransId2;
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
- int tReturnCode;
-
- tTransId1 = (Uint32) theTransactionId;
- tTransId2 = (Uint32) (theTransactionId >> 32);
- tSignal.setSignal(GSN_TCROLLBACKREQ);
- tSignal.setData(theTCConPtr, 1);
- tSignal.setData(tTransId1, 2);
- tSignal.setData(tTransId2, 3);
- if(theError.code == 4012)
- {
- g_eventLogger.error("Sending TCROLLBACKREQ with Bad flag");
- tSignal.setLength(tSignal.getLength() + 1); // + flags
- tSignal.setData(0x1, 4); // potentially bad data
- }
- tReturnCode = tp->sendSignal(&tSignal,theDBnode);
- if (tReturnCode != -1) {
- theSendStatus = sendTC_ROLLBACK;
- tNdb->insert_sent_list(this);
- return 0;
- }//if
- /*********************************************************************
- * It was not possible to abort the transaction towards the NDB kernel
- * and thus we put it into the array of completed transactions that
- * are ready for reporting to the application.
- *********************************************************************/
- return -1;
- } else {
- /*
- It is not necessary to abort the transaction towards the NDB kernel and
- thus we put it into the array of completed transactions that are ready
- for reporting to the application.
- */
- theSendStatus = sendCompleted;
- tNdb->insert_completed_list(this);
- return 0;
- ;
- }//if
-}//NdbTransaction::sendROLLBACK()
-
-/***************************************************************************
-int sendCOMMIT();
-
-Return Value: Return 0 : send was successful.
- Return -1: In all other case.
-Parameters : None.
-Remark: Order NDB to commit the transaction.
-***************************************************************************/
-int
-NdbTransaction::sendCOMMIT() // Send a TC_COMMITREQ signal;
-{
- NdbApiSignal tSignal(theNdb->theMyRef);
- Uint32 tTransId1, tTransId2;
- TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
- int tReturnCode;
-
- tTransId1 = (Uint32) theTransactionId;
- tTransId2 = (Uint32) (theTransactionId >> 32);
- tSignal.setSignal(GSN_TC_COMMITREQ);
- tSignal.setData(theTCConPtr, 1);
- tSignal.setData(tTransId1, 2);
- tSignal.setData(tTransId2, 3);
-
- tReturnCode = tp->sendSignal(&tSignal,theDBnode);
- if (tReturnCode != -1) {
- theSendStatus = sendTC_COMMIT;
- theNdb->insert_sent_list(this);
- return 0;
- } else {
- return -1;
- }//if
-}//NdbTransaction::sendCOMMIT()
-
-/******************************************************************************
-void release();
-
-Remark: Release all operations.
-******************************************************************************/
-void
-NdbTransaction::release(){
- 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.
- ************************************************************************/
- if (!theSimpleState)
- {
- execute(Rollback);
- }
- }//if
- theMagicNumber = 0xFE11DC;
- theInUseState = false;
-#ifdef VM_TRACE
- if (theListState != NotInList) {
- theNdb->printState("release %x", this);
- abort();
- }
-#endif
-}//NdbTransaction::release()
-
-void
-NdbTransaction::releaseOps(NdbOperation* tOp){
- while (tOp != NULL) {
- NdbOperation* tmp = tOp;
- tOp->release();
- tOp = tOp->next();
- theNdb->releaseOperation(tmp);
- }//while
-}
-
-/******************************************************************************
-void releaseOperations();
-
-Remark: Release all operations.
-******************************************************************************/
-void
-NdbTransaction::releaseOperations()
-{
- // Release any open scans
- releaseScanOperations(m_theFirstScanOperation);
- releaseScanOperations(m_firstExecutedScanOp);
-
- releaseOps(theCompletedFirstOp);
- releaseOps(theFirstOpInList);
- releaseOps(theFirstExecOpInList);
-
- theCompletedFirstOp = NULL;
- theCompletedLastOp = NULL;
- theFirstOpInList = NULL;
- theFirstExecOpInList = NULL;
- theLastOpInList = NULL;
- theLastExecOpInList = NULL;
- theScanningOp = NULL;
- m_theFirstScanOperation = NULL;
- m_theLastScanOperation = NULL;
- m_firstExecutedScanOp = NULL;
-}//NdbTransaction::releaseOperations()
-
-void
-NdbTransaction::releaseCompletedOperations()
-{
- releaseOps(theCompletedFirstOp);
- theCompletedFirstOp = NULL;
- theCompletedLastOp = NULL;
-}//NdbTransaction::releaseOperations()
-
-/******************************************************************************
-void releaseScanOperations();
-
-Remark: Release all cursor operations.
- (NdbScanOperation and NdbIndexOperation)
-******************************************************************************/
-void
-NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp)
-{
- while(cursorOp != 0){
- NdbIndexScanOperation* next = (NdbIndexScanOperation*)cursorOp->next();
- cursorOp->release();
- theNdb->releaseScanOperation(cursorOp);
- cursorOp = next;
- }
-}//NdbTransaction::releaseScanOperations()
-
-/*****************************************************************************
-void releaseScanOperation();
-
-Remark: Release scan op when hupp'ed trans closed (save memory)
-******************************************************************************/
-void
-NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
-{
- DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation");
- DBUG_PRINT("enter", ("this: 0x%lx op: 0x%lx", (long) this, (long) cursorOp));
-
- releaseScanOperation(&m_firstExecutedScanOp, 0, cursorOp);
-
- DBUG_VOID_RETURN;
-}//NdbTransaction::releaseExecutedScanOperation()
-
-bool
-NdbTransaction::releaseScanOperation(NdbIndexScanOperation** listhead,
- NdbIndexScanOperation** listtail,
- NdbIndexScanOperation* op)
-{
- if (* listhead == op)
- {
- * listhead = (NdbIndexScanOperation*)op->theNext;
- if (listtail && *listtail == op)
- {
- assert(* listhead == 0);
- * listtail = 0;
- }
-
- }
- else
- {
- NdbIndexScanOperation* tmp = * listhead;
- while (tmp != NULL)
- {
- if (tmp->theNext == op)
- {
- tmp->theNext = (NdbIndexScanOperation*)op->theNext;
- if (listtail && *listtail == op)
- {
- assert(op->theNext == 0);
- *listtail = tmp;
- }
- break;
- }
- tmp = (NdbIndexScanOperation*)tmp->theNext;
- }
- if (tmp == NULL)
- op = NULL;
- }
-
- if (op != NULL)
- {
- op->release();
- theNdb->releaseScanOperation(op);
- return true;
- }
-
- return false;
-}
-
-/*****************************************************************************
-NdbOperation* getNdbOperation(const char* aTableName);
-
-Return Value Return a pointer to a NdbOperation object if getNdbOperation
- was succesful.
- Return NULL : In all other case.
-Parameters: aTableName : Name of the database table.
-Remark: Get an operation from NdbOperation idlelist and get the
- NdbTransaction object
- who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbOperation object.
- synchronous
-******************************************************************************/
-NdbOperation*
-NdbTransaction::getNdbOperation(const char* aTableName)
-{
- if (theCommitStatus == Started){
- NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName);
- if (table != 0){
- return getNdbOperation(table);
- } else {
- setErrorCode(theNdb->theDictionary->getNdbError().code);
- return NULL;
- }//if
- }
-
- setOperationErrorCodeAbort(4114);
-
- return NULL;
-}//NdbTransaction::getNdbOperation()
-
-/*****************************************************************************
-NdbOperation* getNdbOperation(int aTableId);
-
-Return Value Return a pointer to a NdbOperation object if getNdbOperation
- was succesful.
- Return NULL: In all other case.
-Parameters: tableId : Id of the database table beeing deleted.
-Remark: Get an operation from NdbOperation object idlelist and
- get the NdbTransaction object who was fetch by
- startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbOperation
- object, synchronous.
-*****************************************************************************/
-NdbOperation*
-NdbTransaction::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp)
-{
- NdbOperation* tOp;
-
- if (theScanningOp != NULL){
- setErrorCode(4607);
- return NULL;
- }
-
- tOp = theNdb->getOperation();
- if (tOp == NULL)
- goto getNdbOp_error1;
- if (aNextOp == NULL) {
- if (theLastOpInList != NULL) {
- theLastOpInList->next(tOp);
- theLastOpInList = tOp;
- } else {
- theLastOpInList = tOp;
- theFirstOpInList = tOp;
- }//if
- tOp->next(NULL);
- } else {
- // add before the given op
- if (theFirstOpInList == aNextOp) {
- theFirstOpInList = tOp;
- } else {
- NdbOperation* aLoopOp = theFirstOpInList;
- while (aLoopOp != NULL && aLoopOp->next() != aNextOp)
- aLoopOp = aLoopOp->next();
- assert(aLoopOp != NULL);
- aLoopOp->next(tOp);
- }
- tOp->next(aNextOp);
- }
- if (tOp->init(tab, this) != -1) {
- return tOp;
- } else {
- theNdb->releaseOperation(tOp);
- }//if
- return NULL;
-
- getNdbOp_error1:
- setOperationErrorCodeAbort(4000);
- return NULL;
-}//NdbTransaction::getNdbOperation()
-
-NdbOperation* NdbTransaction::getNdbOperation(const NdbDictionary::Table * table)
-{
- if (table)
- return getNdbOperation(& NdbTableImpl::getImpl(*table));
- else
- return NULL;
-}//NdbTransaction::getNdbOperation()
-
-// NdbScanOperation
-/*****************************************************************************
-NdbScanOperation* getNdbScanOperation(const char* aTableName);
-
-Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful.
- Return NULL : In all other case.
-Parameters: aTableName : Name of the database table.
-Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object
- who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbOperation object.synchronous
-******************************************************************************/
-NdbScanOperation*
-NdbTransaction::getNdbScanOperation(const char* aTableName)
-{
- if (theCommitStatus == Started){
- NdbTableImpl* tab = theNdb->theDictionary->getTable(aTableName);
- if (tab != 0){
- return getNdbScanOperation(tab);
- } else {
- setOperationErrorCodeAbort(theNdb->theDictionary->m_error.code);
- return NULL;
- }//if
- }
-
- setOperationErrorCodeAbort(4114);
- return NULL;
-}//NdbTransaction::getNdbScanOperation()
-
-/*****************************************************************************
-NdbScanOperation* getNdbIndexScanOperation(const char* anIndexName, const char* aTableName);
-
-Return Value Return a pointer to a NdbIndexScanOperation object if getNdbIndexScanOperation 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 NdbIndexScanOperation idlelist and get the NdbTransaction object
- who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbIndexScanOperation object.synchronous
-******************************************************************************/
-NdbIndexScanOperation*
-NdbTransaction::getNdbIndexScanOperation(const char* anIndexName,
- const char* aTableName)
-{
- NdbIndexImpl* index =
- theNdb->theDictionary->getIndex(anIndexName, aTableName);
- if (index == 0)
- {
- setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
- return 0;
- }
- NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName);
- if (table == 0)
- {
- setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
- return 0;
- }
-
- return getNdbIndexScanOperation(index, table);
-}
-
-NdbIndexScanOperation*
-NdbTransaction::getNdbIndexScanOperation(const NdbIndexImpl* index,
- const NdbTableImpl* table)
-{
- if (theCommitStatus == Started){
- const NdbTableImpl * indexTable = index->getIndexTable();
- if (indexTable != 0){
- NdbIndexScanOperation* tOp = getNdbScanOperation(indexTable);
- if(tOp)
- {
- tOp->m_currentTable = table;
- // Mark that this really an NdbIndexScanOperation
- tOp->m_type = NdbOperation::OrderedIndexScan;
- }
- return tOp;
- } else {
- setOperationErrorCodeAbort(4271);
- return NULL;
- }//if
- }
-
- setOperationErrorCodeAbort(4114);
- return NULL;
-}//NdbTransaction::getNdbIndexScanOperation()
-
-NdbIndexScanOperation*
-NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index)
-{
- if (index)
- {
- const NdbDictionary::Table *table=
- theNdb->theDictionary->getTable(index->getTable());
-
- if (table)
- return getNdbIndexScanOperation(index, table);
-
- setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
- return NULL;
- }
- setOperationErrorCodeAbort(4271);
- return NULL;
-}
-
-NdbIndexScanOperation*
-NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index,
- const NdbDictionary::Table * table)
-{
- if (index && table)
- return getNdbIndexScanOperation(& NdbIndexImpl::getImpl(*index),
- & NdbTableImpl::getImpl(*table));
- setOperationErrorCodeAbort(4271);
- return NULL;
-}//NdbTransaction::getNdbIndexScanOperation()
-
-/*****************************************************************************
-NdbScanOperation* getNdbScanOperation(int aTableId);
-
-Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful.
- Return NULL: In all other case.
-Parameters: tableId : Id of the database table beeing deleted.
-Remark: Get an operation from NdbScanOperation object idlelist and get the NdbTransaction
- object who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbScanOperation object, synchronous.
-*****************************************************************************/
-NdbIndexScanOperation*
-NdbTransaction::getNdbScanOperation(const NdbTableImpl * tab)
-{
- NdbIndexScanOperation* tOp;
-
- tOp = theNdb->getScanOperation();
- if (tOp == NULL)
- goto getNdbOp_error1;
-
- if (tOp->init(tab, this) != -1) {
- define_scan_op(tOp);
- // Mark that this NdbIndexScanOperation is used as NdbScanOperation
- tOp->m_type = NdbOperation::TableScan;
- return tOp;
- } else {
- theNdb->releaseScanOperation(tOp);
- }//if
- return NULL;
-
-getNdbOp_error1:
- setOperationErrorCodeAbort(4000);
- return NULL;
-}//NdbTransaction::getNdbScanOperation()
-
-void
-NdbTransaction::remove_list(NdbOperation*& list, NdbOperation* op){
- NdbOperation* tmp= list;
- if(tmp == op)
- list = op->next();
- else {
- while(tmp && tmp->next() != op) tmp = tmp->next();
- if(tmp)
- tmp->next(op->next());
- }
- op->next(NULL);
-}
-
-void
-NdbTransaction::define_scan_op(NdbIndexScanOperation * tOp){
- // Link scan operation into list of cursor operations
- if (m_theLastScanOperation == NULL)
- m_theFirstScanOperation = m_theLastScanOperation = tOp;
- else {
- m_theLastScanOperation->next(tOp);
- m_theLastScanOperation = tOp;
- }
- tOp->next(NULL);
-}
-
-NdbScanOperation*
-NdbTransaction::getNdbScanOperation(const NdbDictionary::Table * table)
-{
- if (table)
- return getNdbScanOperation(& NdbTableImpl::getImpl(*table));
- else
- return NULL;
-}//NdbTransaction::getNdbScanOperation()
-
-
-// IndexOperation
-/*****************************************************************************
-NdbIndexOperation* getNdbIndexOperation(const char* anIndexName,
- const char* aTableName);
-
-Return Value Return a pointer to a NdbOperation object if getNdbIndexOperation was succesful.
- Return NULL : In all other case.
-Parameters: aTableName : Name of the database table.
-Remark: Get an operation from NdbIndexOperation idlelist and get the NdbTransaction object
- who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbIndexOperation object.synchronous
-******************************************************************************/
-NdbIndexOperation*
-NdbTransaction::getNdbIndexOperation(const char* anIndexName,
- const char* aTableName)
-{
- if (theCommitStatus == Started) {
- NdbTableImpl * table = theNdb->theDictionary->getTable(aTableName);
- NdbIndexImpl * index;
-
- if (table == 0)
- {
- setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
- return NULL;
- }
-
- if (table->m_frm.get_data())
- {
- // This unique index is defined from SQL level
- static const char* uniqueSuffix= "$unique";
- BaseString uniqueIndexName(anIndexName);
- uniqueIndexName.append(uniqueSuffix);
- index = theNdb->theDictionary->getIndex(uniqueIndexName.c_str(),
- aTableName);
- }
- else
- index = theNdb->theDictionary->getIndex(anIndexName,
- aTableName);
- if(table != 0 && index != 0){
- return getNdbIndexOperation(index, table);
- }
-
- if(index == 0){
- setOperationErrorCodeAbort(4243);
- return NULL;
- }
-
- setOperationErrorCodeAbort(4243);
- return NULL;
- }
-
- setOperationErrorCodeAbort(4114);
- return 0;
-}//NdbTransaction::getNdbIndexOperation()
-
-/*****************************************************************************
-NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId);
-
-Return Value Return a pointer to a NdbIndexOperation object if getNdbIndexOperation was succesful.
- Return NULL: In all other case.
-Parameters: tableId : Id of the database table beeing deleted.
-Remark: Get an operation from NdbIndexOperation object idlelist and get the NdbTransaction
- object who was fetch by startTransaction pointing to this operation
- getOperation will set the theTableId in the NdbIndexOperation object, synchronous.
-*****************************************************************************/
-NdbIndexOperation*
-NdbTransaction::getNdbIndexOperation(const NdbIndexImpl * anIndex,
- const NdbTableImpl * aTable,
- NdbOperation* aNextOp)
-{
- NdbIndexOperation* tOp;
-
- tOp = theNdb->getIndexOperation();
- if (tOp == NULL)
- goto getNdbOp_error1;
- if (aNextOp == NULL) {
- if (theLastOpInList != NULL) {
- theLastOpInList->next(tOp);
- theLastOpInList = tOp;
- } else {
- theLastOpInList = tOp;
- theFirstOpInList = tOp;
- }//if
- tOp->next(NULL);
- } else {
- // add before the given op
- if (theFirstOpInList == aNextOp) {
- theFirstOpInList = tOp;
- } else {
- NdbOperation* aLoopOp = theFirstOpInList;
- while (aLoopOp != NULL && aLoopOp->next() != aNextOp)
- aLoopOp = aLoopOp->next();
- assert(aLoopOp != NULL);
- aLoopOp->next(tOp);
- }
- tOp->next(aNextOp);
- }
- if (tOp->indxInit(anIndex, aTable, this)!= -1) {
- return tOp;
- } else {
- theNdb->releaseOperation(tOp);
- }//if
- return NULL;
-
- getNdbOp_error1:
- setOperationErrorCodeAbort(4000);
- return NULL;
-}//NdbTransaction::getNdbIndexOperation()
-
-NdbIndexOperation*
-NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index)
-{
- if (index)
- {
- const NdbDictionary::Table *table=
- theNdb->theDictionary->getTable(index->getTable());
-
- if (table)
- return getNdbIndexOperation(index, table);
-
- setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code);
- return NULL;
- }
- setOperationErrorCodeAbort(4271);
- return NULL;
-}
-
-NdbIndexOperation*
-NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index,
- const NdbDictionary::Table * table)
-{
- if (index && table)
- return getNdbIndexOperation(& NdbIndexImpl::getImpl(*index),
- & NdbTableImpl::getImpl(*table));
-
- setOperationErrorCodeAbort(4271);
- return NULL;
-}//NdbTransaction::getNdbIndexOperation()
-
-
-/*******************************************************************************
-int receiveDIHNDBTAMPER(NdbApiSignal* aSignal)
-
-Return Value: Return 0 : receiveDIHNDBTAMPER was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark: Sets theRestartGCI in the NDB object.
-*******************************************************************************/
-int
-NdbTransaction::receiveDIHNDBTAMPER(NdbApiSignal* aSignal)
-{
- if (theStatus != Connecting) {
- return -1;
- } else {
- theNdb->RestartGCI((Uint32)aSignal->readData(2));
- theStatus = Connected;
- }//if
- return 0;
-}//NdbTransaction::receiveDIHNDBTAMPER()
-
-/*******************************************************************************
-int receiveTCSEIZECONF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTCSEIZECONF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark: Sets TC Connect pointer at reception of TCSEIZECONF.
-*******************************************************************************/
-int
-NdbTransaction::receiveTCSEIZECONF(NdbApiSignal* aSignal)
-{
- if (theStatus != Connecting)
- {
- return -1;
- } else
- {
- theTCConPtr = (Uint32)aSignal->readData(2);
- theStatus = Connected;
- }
- return 0;
-}//NdbTransaction::receiveTCSEIZECONF()
-
-/*******************************************************************************
-int receiveTCSEIZEREF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTCSEIZEREF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark: Sets TC Connect pointer.
-*******************************************************************************/
-int
-NdbTransaction::receiveTCSEIZEREF(NdbApiSignal* aSignal)
-{
- DBUG_ENTER("NdbTransaction::receiveTCSEIZEREF");
- if (theStatus != Connecting)
- {
- DBUG_RETURN(-1);
- } else
- {
- theStatus = ConnectFailure;
- theNdb->theError.code = aSignal->readData(2);
- DBUG_PRINT("info",("error code %d, %s",
- theNdb->getNdbError().code,
- theNdb->getNdbError().message));
- DBUG_RETURN(0);
- }
-}//NdbTransaction::receiveTCSEIZEREF()
-
-/*******************************************************************************
-int receiveTCRELEASECONF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTCRELEASECONF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark: DisConnect TC Connect pointer to NDBAPI.
-*******************************************************************************/
-int
-NdbTransaction::receiveTCRELEASECONF(NdbApiSignal* aSignal)
-{
- if (theStatus != DisConnecting)
- {
- return -1;
- } else
- {
- theStatus = NotConnected;
- }
- return 0;
-}//NdbTransaction::receiveTCRELEASECONF()
-
-/*******************************************************************************
-int receiveTCRELEASEREF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTCRELEASEREF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark: DisConnect TC Connect pointer to NDBAPI Failure.
-*******************************************************************************/
-int
-NdbTransaction::receiveTCRELEASEREF(NdbApiSignal* aSignal)
-{
- if (theStatus != DisConnecting) {
- return -1;
- } else {
- theStatus = ConnectFailure;
- theNdb->theError.code = aSignal->readData(2);
- return 0;
- }//if
-}//NdbTransaction::receiveTCRELEASEREF()
-
-/******************************************************************************
-int receiveTC_COMMITCONF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTC_COMMITCONF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark:
-******************************************************************************/
-int
-NdbTransaction::receiveTC_COMMITCONF(const TcCommitConf * commitConf)
-{
- if(checkState_TransId(&commitConf->transId1)){
- theCommitStatus = Committed;
- theCompletionStatus = CompletedSuccess;
- theGlobalCheckpointId = commitConf->gci;
- // theGlobalCheckpointId == 0 if NoOp transaction
- if (theGlobalCheckpointId)
- *p_latest_trans_gci = theGlobalCheckpointId;
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
- return -1;
-}//NdbTransaction::receiveTC_COMMITCONF()
-
-/******************************************************************************
-int receiveTC_COMMITREF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTC_COMMITREF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark:
-******************************************************************************/
-int
-NdbTransaction::receiveTC_COMMITREF(NdbApiSignal* aSignal)
-{
- const TcCommitRef * ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr());
- if(checkState_TransId(&ref->transId1)){
- setOperationErrorCodeAbort(ref->errorCode);
- theCommitStatus = Aborted;
- theCompletionStatus = CompletedFailure;
- theReturnStatus = ReturnFailure;
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}//NdbTransaction::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
-NdbTransaction::receiveTCROLLBACKCONF(NdbApiSignal* aSignal)
-{
- if(checkState_TransId(aSignal->getDataPtr() + 1)){
- theCommitStatus = Aborted;
- theCompletionStatus = CompletedSuccess;
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}//NdbTransaction::receiveTCROLLBACKCONF()
-
-/*******************************************************************************
-int receiveTCROLLBACKREF(NdbApiSignal* aSignal);
-
-Return Value: Return 0 : receiveTCROLLBACKREF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark:
-*******************************************************************************/
-int
-NdbTransaction::receiveTCROLLBACKREF(NdbApiSignal* aSignal)
-{
- if(checkState_TransId(aSignal->getDataPtr() + 1)){
- setOperationErrorCodeAbort(aSignal->readData(4));
- theCommitStatus = Aborted;
- theCompletionStatus = CompletedFailure;
- theReturnStatus = ReturnFailure;
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}//NdbTransaction::receiveTCROLLBACKREF()
-
-/*****************************************************************************
-int receiveTCROLLBACKREP( NdbApiSignal* aSignal)
-
-Return Value: Return 0 : send was succesful.
- Return -1: In all other case.
-Parameters: aSignal: the signal object that contains the
- TCROLLBACKREP signal from TC.
-Remark: Handles the reception of the ROLLBACKREP signal.
-*****************************************************************************/
-int
-NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal)
-{
- DBUG_ENTER("NdbTransaction::receiveTCROLLBACKREP");
-
- /****************************************************************************
-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.
- ****************************************************************************/
- if(checkState_TransId(aSignal->getDataPtr() + 1)){
- theError.code = aSignal->readData(4);// Override any previous errors
- if (aSignal->getLength() == TcRollbackRep::SignalLength)
- {
- // Signal may contain additional error data
- theError.details = (char *) aSignal->readData(5);
- }
-
- /**********************************************************************/
- /* 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;
- theReturnStatus = ReturnFailure;
- DBUG_RETURN(0);
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- DBUG_RETURN(-1);
-}//NdbTransaction::receiveTCROLLBACKREP()
-
-/*******************************************************************************
-int receiveTCKEYCONF(NdbApiSignal* aSignal, Uint32 long_short_ind);
-
-Return Value: Return 0 : receiveTCKEYCONF was successful.
- Return -1: In all other case.
-Parameters: aSignal: The signal object pointer.
-Remark:
-*******************************************************************************/
-int
-NdbTransaction::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength)
-{
- NdbReceiver* tOp;
- const Uint32 tTemp = keyConf->confInfo;
- /***************************************************************************
-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.
- ***************************************************************************/
- if(checkState_TransId(&keyConf->transId1)){
-
- const Uint32 tNoOfOperations = TcKeyConf::getNoOfOperations(tTemp);
- const Uint32 tCommitFlag = TcKeyConf::getCommitFlag(tTemp);
-
- const Uint32* tPtr = (Uint32 *)&keyConf->operations[0];
- Uint32 tNoComp = theNoOfOpCompleted;
- for (Uint32 i = 0; i < tNoOfOperations ; i++) {
- tOp = theNdb->void2rec(theNdb->int2void(*tPtr++));
- const Uint32 tAttrInfoLen = *tPtr++;
- if (tOp && tOp->checkMagicNumber()) {
- Uint32 done = tOp->execTCOPCONF(tAttrInfoLen);
- if(tAttrInfoLen > TcKeyConf::DirtyReadBit){
- Uint32 node = tAttrInfoLen & (~TcKeyConf::DirtyReadBit);
- NdbNodeBitmask::set(m_db_nodes, node);
- if(NdbNodeBitmask::get(m_failed_db_nodes, node) && !done)
- {
- done = 1;
- tOp->setErrorCode(4119);
- theCompletionStatus = CompletedFailure;
- theReturnStatus = NdbTransaction::ReturnFailure;
- }
- }
- tNoComp += done;
- } else {
- return -1;
- }//if
- }//for
- Uint32 tNoSent = theNoOfOpSent;
- theNoOfOpCompleted = tNoComp;
- Uint32 tGCI = keyConf->gci;
- if (tCommitFlag == 1) {
- theCommitStatus = Committed;
- theGlobalCheckpointId = tGCI;
- if (tGCI) // Read(dirty) only transaction doesnt get GCI
- {
- *p_latest_trans_gci = 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.
-/**********************************************************************/
- theError.code = 4011;
- theCompletionStatus = CompletedFailure;
- theReturnStatus = NdbTransaction::ReturnFailure;
- theCommitStatus = Aborted;
- return 0;
- }//if
- if (tNoComp >= tNoSent) {
- return 0; // No more operations to wait for
- }//if
- // Not completed the reception yet.
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}//NdbTransaction::receiveTCKEYCONF()
-
-/*****************************************************************************
-int receiveTCKEY_FAILCONF( NdbApiSignal* aSignal)
-
-Return Value: Return 0 : receive was completed.
- Return -1: In all other case.
-Parameters: aSignal: the signal object that contains the
- TCKEY_FAILCONF signal from TC.
-Remark: Handles the reception of the TCKEY_FAILCONF signal.
-*****************************************************************************/
-int
-NdbTransaction::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf)
-{
- NdbOperation* tOp;
- /*
- 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.
- */
- if(checkState_TransId(&failConf->transId1)){
- /*
- A node failure of the TC node occured. The transaction has
- been committed.
- */
- 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 NdbOperation::UpdateRequest:
- case NdbOperation::InsertRequest:
- case NdbOperation::DeleteRequest:
- case NdbOperation::WriteRequest:
- tOp = tOp->next();
- break;
- case NdbOperation::ReadRequest:
- case NdbOperation::ReadExclusive:
- case NdbOperation::OpenScanRequest:
- case NdbOperation::OpenRangeScanRequest:
- theCompletionStatus = CompletedFailure;
- theReturnStatus = NdbTransaction::ReturnFailure;
- setOperationErrorCodeAbort(4115);
- tOp = NULL;
- break;
- case NdbOperation::NotDefined:
- case NdbOperation::NotDefined2:
- assert(false);
- break;
- }//if
- }//while
- theReleaseOnClose = true;
- return 0;
- } else {
-#ifdef VM_TRACE
- ndbout_c("Recevied TCKEY_FAILCONF wo/ operation");
-#endif
- }
- return -1;
-}//NdbTransaction::receiveTCKEY_FAILCONF()
-
-/*************************************************************************
-int receiveTCKEY_FAILREF( NdbApiSignal* aSignal)
-
-Return Value: Return 0 : receive was completed.
- Return -1: In all other case.
-Parameters: aSignal: the signal object that contains the
- TCKEY_FAILREF signal from TC.
-Remark: Handles the reception of the TCKEY_FAILREF signal.
-**************************************************************************/
-int
-NdbTransaction::receiveTCKEY_FAILREF(NdbApiSignal* aSignal)
-{
- /*
- 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.
- */
- if(checkState_TransId(aSignal->getDataPtr()+1)){
- /*
- We received an indication of that this transaction was aborted due to a
- node failure.
- */
- if (theSendStatus == NdbTransaction::sendTC_ROLLBACK) {
- /*
- We were in the process of sending a rollback anyways. We will
- report it as a success.
- */
- theCompletionStatus = NdbTransaction::CompletedSuccess;
- } else {
- theReturnStatus = NdbTransaction::ReturnFailure;
- theCompletionStatus = NdbTransaction::CompletedFailure;
- theError.code = 4031;
- }//if
- theReleaseOnClose = true;
- theCommitStatus = NdbTransaction::Aborted;
- return 0;
- } else {
-#ifdef VM_TRACE
- ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
-#endif
- }
- return -1;
-}//NdbTransaction::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
-NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
- Uint32 aDataLength)
-{
- 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++) {
- NdbReceiver* tOp = theNdb->void2rec(theNdb->int2void(*tPtr));
- tPtr++;
- const Uint32 tAttrInfoLen = *tPtr;
- tPtr++;
- if (tOp && tOp->checkMagicNumber()) {
- tNoComp += tOp->execTCOPCONF(tAttrInfoLen);
- } else {
- return -1;
- }//if
- }//for
- Uint32 tNoSent = theNoOfOpSent;
- Uint32 tGCI = indxConf->gci;
- theNoOfOpCompleted = tNoComp;
- if (tCommitFlag == 1) {
- theCommitStatus = Committed;
- theGlobalCheckpointId = tGCI;
- if (tGCI) // Read(dirty) only transaction doesnt get GCI
- {
- *p_latest_trans_gci = 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.
- /**********************************************************************/
- theError.code = 4011;
- theCompletionStatus = NdbTransaction::CompletedFailure;
- theCommitStatus = NdbTransaction::Aborted;
- theReturnStatus = NdbTransaction::ReturnFailure;
- return 0;
- }//if
- if (tNoComp >= tNoSent) {
- return 0; // No more operations to wait for
- }//if
- // Not completed the reception yet.
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}//NdbTransaction::receiveTCINDXCONF()
-
-/*******************************************************************************
-int OpCompletedFailure();
-
-Return Value: Return 0 : OpCompleteSuccess was successful.
- Return -1: In all other case.
-Parameters: aErrorCode: The error code.
-Remark: An operation was completed with failure.
-*******************************************************************************/
-int
-NdbTransaction::OpCompleteFailure(NdbOperation* op)
-{
- Uint32 tNoComp = theNoOfOpCompleted;
- Uint32 tNoSent = theNoOfOpSent;
-
- tNoComp++;
- theNoOfOpCompleted = tNoComp;
-
- return (tNoComp == tNoSent) ? 0 : -1;
-}//NdbTransaction::OpCompleteFailure()
-
-/******************************************************************************
-int OpCompleteSuccess();
-
-Return Value: Return 0 : OpCompleteSuccess was successful.
- Return -1: In all other case.
-Remark: An operation was completed with success.
-*******************************************************************************/
-int
-NdbTransaction::OpCompleteSuccess()
-{
- Uint32 tNoComp = theNoOfOpCompleted;
- Uint32 tNoSent = theNoOfOpSent;
- tNoComp++;
- theNoOfOpCompleted = tNoComp;
- if (tNoComp == tNoSent) { // Last operation completed
- return 0;
- } else if (tNoComp < tNoSent) {
- return -1; // Continue waiting for more signals
- } else {
- setOperationErrorCodeAbort(4113); // Too many operations,
- // stop waiting for more
- theCompletionStatus = NdbTransaction::CompletedFailure;
- theReturnStatus = NdbTransaction::ReturnFailure;
- return 0;
- }//if
-}//NdbTransaction::OpCompleteSuccess()
-
-/******************************************************************************
- int getGCI();
-
-Remark: Get global checkpoint identity of the transaction
-*******************************************************************************/
-int
-NdbTransaction::getGCI()
-{
- if (theCommitStatus == NdbTransaction::Committed) {
- return theGlobalCheckpointId;
- }//if
- return 0;
-}//NdbTransaction::getGCI()
-
-/*******************************************************************************
-Uint64 getTransactionId(void);
-
-Remark: Get the transaction identity.
-*******************************************************************************/
-Uint64
-NdbTransaction::getTransactionId()
-{
- return theTransactionId;
-}//NdbTransaction::getTransactionId()
-
-NdbTransaction::CommitStatusType
-NdbTransaction::commitStatus()
-{
- return theCommitStatus;
-}//NdbTransaction::commitStatus()
-
-int
-NdbTransaction::getNdbErrorLine()
-{
- return theErrorLine;
-}
-
-NdbOperation*
-NdbTransaction::getNdbErrorOperation()
-{
- return theErrorOperation;
-}//NdbTransaction::getNdbErrorOperation()
-
-const NdbOperation *
-NdbTransaction::getNextCompletedOperation(const NdbOperation * current) const {
- if(current == 0)
- return theCompletedFirstOp;
- return current->theNext;
-}
-
-#ifdef VM_TRACE
-#define CASE(x) case x: ndbout << " " << #x; break
-void
-NdbTransaction::printState()
-{
- ndbout << "con=" << hex << this << dec;
- ndbout << " node=" << getConnectedNodeId();
- switch (theStatus) {
- CASE(NotConnected);
- CASE(Connecting);
- CASE(Connected);
- CASE(DisConnecting);
- CASE(ConnectFailure);
- default: ndbout << (Uint32) theStatus;
- }
- switch (theListState) {
- CASE(NotInList);
- CASE(InPreparedList);
- CASE(InSendList);
- CASE(InCompletedList);
- default: ndbout << (Uint32) theListState;
- }
- switch (theSendStatus) {
- CASE(NotInit);
- CASE(InitState);
- CASE(sendOperations);
- CASE(sendCompleted);
- CASE(sendCOMMITstate);
- CASE(sendABORT);
- CASE(sendABORTfail);
- CASE(sendTC_ROLLBACK);
- CASE(sendTC_COMMIT);
- CASE(sendTC_OP);
- default: ndbout << (Uint32) theSendStatus;
- }
- switch (theCommitStatus) {
- CASE(NotStarted);
- CASE(Started);
- CASE(Committed);
- CASE(Aborted);
- CASE(NeedAbort);
- default: ndbout << (Uint32) theCommitStatus;
- }
- switch (theCompletionStatus) {
- CASE(NotCompleted);
- CASE(CompletedSuccess);
- CASE(CompletedFailure);
- CASE(DefinitionFailure);
- default: ndbout << (Uint32) theCompletionStatus;
- }
- ndbout << endl;
-}
-#undef CASE
-#endif
-
-int
-NdbTransaction::report_node_failure(Uint32 id){
- NdbNodeBitmask::set(m_failed_db_nodes, id);
- if(!NdbNodeBitmask::get(m_db_nodes, id))
- {
- return 0;
- }
-
- /**
- * Arrived
- * TCKEYCONF TRANSIDAI
- * 1) - -
- * 2) - X
- * 3) X -
- * 4) X X
- */
- NdbOperation* tmp = theFirstExecOpInList;
- const Uint32 len = TcKeyConf::DirtyReadBit | id;
- Uint32 tNoComp = theNoOfOpCompleted;
- Uint32 tNoSent = theNoOfOpSent;
- Uint32 count = 0;
- while(tmp != 0)
- {
- if(tmp->theReceiver.m_expected_result_length == len &&
- tmp->theReceiver.m_received_result_length == 0)
- {
- count++;
- tmp->theError.code = 4119;
- }
- tmp = tmp->next();
- }
- tNoComp += count;
- theNoOfOpCompleted = tNoComp;
- if(count)
- {
- theReturnStatus = NdbTransaction::ReturnFailure;
- if(tNoComp == tNoSent)
- {
- theError.code = 4119;
- theCompletionStatus = NdbTransaction::CompletedFailure;
- return 1;
- }
- }
- return 0;
-}
diff --git a/storage/ndb/src/ndbapi/NdbTransactionScan.cpp b/storage/ndb/src/ndbapi/NdbTransactionScan.cpp
deleted file mode 100644
index 2d77e33c3a3..00000000000
--- a/storage/ndb/src/ndbapi/NdbTransactionScan.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include <Ndb.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbOperation.hpp>
-#include <NdbScanOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include "TransporterFacade.hpp"
-#include "NdbUtil.hpp"
-#include "API.hpp"
-#include "NdbImpl.hpp"
-
-#include <signaldata/ScanTab.hpp>
-
-#include <NdbOut.hpp>
-
-
-/***************************************************************************
- * int receiveSCAN_TABREF(NdbApiSignal* aSignal)
- *
- * This means the scan could not be started, set status(s) to indicate
- * the failure
- *
- ****************************************************************************/
-int
-NdbTransaction::receiveSCAN_TABREF(NdbApiSignal* aSignal){
- const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr());
-
- if(checkState_TransId(&ref->transId1)){
- theScanningOp->setErrorCode(ref->errorCode);
- theScanningOp->execCLOSE_SCAN_REP();
- if(!ref->closeNeeded){
- return 0;
- }
-
- /**
- * Setup so that close_impl will actually perform a close
- * and not "close scan"-optimze it away
- */
- theScanningOp->m_conf_receivers_count++;
- theScanningOp->m_conf_receivers[0] = theScanningOp->m_receivers[0];
- theScanningOp->m_conf_receivers[0]->m_tcPtrI = ~0;
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}
-
-/*****************************************************************************
- * int receiveSCAN_TABCONF(NdbApiSignal* aSignal)
- *
- * Receive SCAN_TABCONF
- * If scanStatus == 0 there is more records to read. Since signals may be
- * received in any order we have to go through the lists with saved signals
- * and check if all expected signals are there so that we can start to
- * execute them.
- *
- * If scanStatus > 0 this indicates that the scan is finished and there are
- * no more data to be read.
- *
- *****************************************************************************/
-int
-NdbTransaction::receiveSCAN_TABCONF(NdbApiSignal* aSignal,
- const Uint32 * ops, Uint32 len)
-{
- const ScanTabConf * conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr());
- if(checkState_TransId(&conf->transId1)){
-
- if (conf->requestInfo == ScanTabConf::EndOfData) {
- theScanningOp->execCLOSE_SCAN_REP();
- return 0;
- }
-
- for(Uint32 i = 0; i<len; i += 3){
- Uint32 opCount, totalLen;
- Uint32 ptrI = * ops++;
- Uint32 tcPtrI = * ops++;
- Uint32 info = * ops++;
- opCount = ScanTabConf::getRows(info);
- totalLen = ScanTabConf::getLength(info);
-
- void * tPtr = theNdb->int2void(ptrI);
- assert(tPtr); // For now
- NdbReceiver* tOp = theNdb->void2rec(tPtr);
- if (tOp && tOp->checkMagicNumber())
- {
- if (tcPtrI == RNIL && opCount == 0)
- theScanningOp->receiver_completed(tOp);
- else if (tOp->execSCANOPCONF(tcPtrI, totalLen, opCount))
- theScanningOp->receiver_delivered(tOp);
- }
- }
- return 0;
- } else {
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
- }
-
- return -1;
-}
diff --git a/storage/ndb/src/ndbapi/NdbUtil.cpp b/storage/ndb/src/ndbapi/NdbUtil.cpp
deleted file mode 100644
index ec1733f1905..00000000000
--- a/storage/ndb/src/ndbapi/NdbUtil.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2003, 2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-/************************************************************************************************
-Name: NdbUtil.C
-Include:
-Link:
-Author: UABRONM Mikael Ronström UAB/B/SD
-Date: 991029
-Version: 0.4
-Description: Utility classes for NDB API
-Documentation:
-Adjust: 991029 UABRONM First version.
-Comment:
-************************************************************************************************/
-
-#include "NdbUtil.hpp"
-
-NdbLabel::NdbLabel(Ndb*)
-{
-}
-
-NdbLabel::~NdbLabel()
-{
-}
-
-NdbSubroutine::NdbSubroutine(Ndb*)
-{
-}
-
-NdbSubroutine::~NdbSubroutine()
-{
-}
-
-NdbBranch::NdbBranch(Ndb*) :
- theSignal(NULL)
-{
-}
-
-NdbBranch::~NdbBranch()
-{
-}
-
-NdbCall::NdbCall(Ndb*) :
- theSignal(NULL)
-{
-}
-
-NdbCall::~NdbCall()
-{
-}
diff --git a/storage/ndb/src/ndbapi/NdbUtil.hpp b/storage/ndb/src/ndbapi/NdbUtil.hpp
deleted file mode 100644
index d198c0126d9..00000000000
--- a/storage/ndb/src/ndbapi/NdbUtil.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-/************************************************************************************************
-Name: NdbUtil.H
-Include:
-Link:
-Author: UABRONM Mikael Ronström UAB/B/SD
-Date: 991029
-Version: 0.4
-Description: Utility classes for NDB API
-Documentation:
-Adjust: 991029 UABRONM First version.
-Comment:
-************************************************************************************************/
-#ifndef NdbUtil_H
-#define NdbUtil_H
-
-#include <ndb_global.h>
-
-class Ndb;
-class NdbApiSignal;
-class NdbOperation;
-
-template<class T>
-struct Free_list_element
-{
- Free_list_element() { theNext = 0;}
- void next(T* obj) { theNext = obj;}
- T* next() { return theNext;}
-
- T* theNext;
-};
-
-class NdbLabel : public Free_list_element<NdbLabel>
-{
-friend class NdbOperation;
-friend class Ndb;
-public:
- NdbLabel(Ndb*);
- ~NdbLabel();
-
-private:
- Uint32 theSubroutine[16];
- Uint32 theLabelAddress[16];
- Uint32 theLabelNo[16];
-};
-
-class NdbSubroutine : public Free_list_element<NdbSubroutine>
-{
-friend class NdbOperation;
-friend class Ndb;
-
-public:
- NdbSubroutine(Ndb*);
- ~NdbSubroutine();
-
- Uint32 theSubroutineAddress[16];
-};
-
-class NdbBranch : public Free_list_element<NdbBranch>
-{
-friend class NdbOperation;
-friend class Ndb;
-
-public:
- NdbBranch(Ndb*);
- ~NdbBranch();
-
- NdbApiSignal* theSignal;
- Uint32 theSignalAddress;
- Uint32 theBranchAddress;
- Uint32 theBranchLabel;
- Uint32 theSubroutine;
-};
-
-class NdbCall : public Free_list_element<NdbCall>
-{
-friend class NdbOperation;
-friend class Ndb;
-
-public:
- NdbCall(Ndb*);
- ~NdbCall();
-
- NdbApiSignal* theSignal;
- Uint32 theSignalAddress;
- Uint32 theSubroutine;
-};
-
-#endif
diff --git a/storage/ndb/src/ndbapi/NdbWaiter.hpp b/storage/ndb/src/ndbapi/NdbWaiter.hpp
deleted file mode 100644
index 5eef2036a63..00000000000
--- a/storage/ndb/src/ndbapi/NdbWaiter.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_WAITER_HPP
-#define NDB_WAITER_HPP
-
-#include <ndb_global.h>
-#include <NdbOut.hpp>
-#include <NdbError.hpp>
-#include <NdbCondition.h>
-#include <NdbReceiver.hpp>
-#include <NdbOperation.hpp>
-#include <kernel/ndb_limits.h>
-
-#include <NdbTick.h>
-
-enum WaitSignalType {
- NO_WAIT = 0,
- WAIT_NODE_FAILURE = 1, // Node failure during wait
- WST_WAIT_TIMEOUT = 2, // Timeout during wait
-
- WAIT_TC_SEIZE = 3,
- WAIT_TC_RELEASE = 4,
- WAIT_NDB_TAMPER = 5,
- WAIT_SCAN = 6,
-
- // DICT stuff
- WAIT_GET_TAB_INFO_REQ = 11,
- WAIT_CREATE_TAB_REQ = 12,
- WAIT_DROP_TAB_REQ = 13,
- WAIT_ALTER_TAB_REQ = 14,
- WAIT_CREATE_INDX_REQ = 15,
- WAIT_DROP_INDX_REQ = 16,
- WAIT_LIST_TABLES_CONF = 17
-};
-
-class NdbWaiter {
-public:
- NdbWaiter();
- ~NdbWaiter();
-
- void wait(int waitTime);
- void nodeFail(Uint32 node);
- void signal(Uint32 state);
- void cond_signal();
- void set_poll_owner(bool poll_owner) { m_poll_owner= poll_owner; }
- Uint32 get_state() { return m_state; }
- void set_state(Uint32 state) { m_state= state; }
- void set_node(Uint32 node) { m_node= node; }
- Uint32 get_cond_wait_index() { return m_cond_wait_index; }
- void set_cond_wait_index(Uint32 index) { m_cond_wait_index= index; }
-
- Uint32 m_node;
- Uint32 m_state;
- NdbMutex * m_mutex;
- bool m_poll_owner;
- Uint32 m_cond_wait_index;
- struct NdbCondition * m_condition;
-};
-
-inline
-void
-NdbWaiter::wait(int waitTime)
-{
- assert(!m_poll_owner);
- NdbCondition_WaitTimeout(m_condition, m_mutex, waitTime);
-}
-
-inline
-void
-NdbWaiter::nodeFail(Uint32 aNodeId){
- if (m_state != NO_WAIT && m_node == aNodeId){
- m_state = WAIT_NODE_FAILURE;
- if (!m_poll_owner)
- NdbCondition_Signal(m_condition);
- }
-}
-
-inline
-void
-NdbWaiter::signal(Uint32 state){
- m_state = state;
- if (!m_poll_owner)
- NdbCondition_Signal(m_condition);
-}
-
-inline
-void
-NdbWaiter::cond_signal()
-{
- NdbCondition_Signal(m_condition);
-}
-#endif
diff --git a/storage/ndb/src/ndbapi/Ndberr.cpp b/storage/ndb/src/ndbapi/Ndberr.cpp
deleted file mode 100644
index a20ce2030c6..00000000000
--- a/storage/ndb/src/ndbapi/Ndberr.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <NdbError.hpp>
-#include "NdbImpl.hpp"
-#include "NdbDictionaryImpl.hpp"
-#include <NdbOperation.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbBlob.hpp>
-#include "NdbEventOperationImpl.hpp"
-
-static void
-update(const NdbError & _err){
- NdbError & error = (NdbError &) _err;
- ndberror_struct ndberror = (ndberror_struct)error;
- ndberror_update(&ndberror);
- error = NdbError(ndberror);
-}
-
-const
-NdbError &
-Ndb::getNdbError(int code){
- theError.code = code;
- update(theError);
- return theError;
-}
-
-const
-NdbError &
-Ndb::getNdbError() const {
- update(theError);
- return theError;
-}
-
-const
-NdbError &
-NdbDictionaryImpl::getNdbError() const {
- update(m_error);
- return m_error;
-}
-
-const
-NdbError &
-NdbTransaction::getNdbError() const {
- update(theError);
- return theError;
-}
-
-const
-NdbError &
-NdbOperation::getNdbError() const {
- update(theError);
- return theError;
-}
-
-const
-NdbError &
-NdbBlob::getNdbError() const {
- update(theError);
- return theError;
-}
-
-const
-NdbError &
-NdbEventOperationImpl::getNdbError() const {
- update(m_error);
- return m_error;
-}
-
-const
-NdbError &
-NdbDictInterface::getNdbError() const {
- update(m_error);
- return m_error;
-}
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
deleted file mode 100644
index ba3aebc5800..00000000000
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ /dev/null
@@ -1,1481 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "NdbApiSignal.hpp"
-#include "NdbImpl.hpp"
-#include <NdbTransaction.hpp>
-#include <NdbOperation.hpp>
-#include <NdbIndexOperation.hpp>
-#include <NdbScanOperation.hpp>
-#include <NdbRecAttr.hpp>
-#include <NdbReceiver.hpp>
-#include "API.hpp"
-#include "NdbEventOperationImpl.hpp"
-
-#include <signaldata/TcCommit.hpp>
-#include <signaldata/TcKeyFailConf.hpp>
-#include <signaldata/TcKeyConf.hpp>
-#include <signaldata/TestOrd.hpp>
-#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 <signaldata/SumaImpl.hpp>
-
-#include <ndb_limits.h>
-#include <NdbOut.hpp>
-#include <NdbTick.h>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-/******************************************************************************
- * int init( int aNrOfCon, int aNrOfOp );
- *
- * Return Value: Return 0 : init was successful.
- * Return -1: In all other case.
- * 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)
-{
- DBUG_ENTER("Ndb::init");
-
- int i;
- int aNrOfCon;
- int aNrOfOp;
- int tMaxNoOfTransactions;
- NdbApiSignal* tSignal[16]; // Initiate free list of 16 signal objects
- if (theInitState != NotInitialised) {
- switch(theInitState){
- case InitConfigError:
- theError.code = 4117;
- break;
- default:
- theError.code = 4104;
- break;
- }
- DBUG_RETURN(-1);
- }//if
- theInitState = StartingInit;
- TransporterFacade * theFacade = theImpl->m_transporter_facade;
- theFacade->lock_mutex();
-
- const int tBlockNo = theFacade->open(this,
- executeMessage,
- statusMessage);
- if ( tBlockNo == -1 ) {
- theError.code = 4105;
- theFacade->unlock_mutex();
- DBUG_RETURN(-1); // no more free blocknumbers
- }//if
-
- theNdbBlockNumber = tBlockNo;
-
- theFacade->unlock_mutex();
-
- theDictionary->setTransporter(this, theFacade);
-
- aNrOfCon = theImpl->theNoOfDBnodes;
- aNrOfOp = 2*theImpl->theNoOfDBnodes;
-
- // Create connection object in a linked list
- if((createConIdleList(aNrOfCon)) == -1){
- theError.code = 4000;
- goto error_handler;
- }
-
- // Create operations in a linked list
- if((createOpIdleList(aNrOfOp)) == -1){
- theError.code = 4000;
- goto error_handler;
- }
-
-
- tMaxNoOfTransactions = aMaxNoOfTransactions;
- theMaxNoOfTransactions = tMaxNoOfTransactions;
- theRemainingStartTransactions= tMaxNoOfTransactions;
- thePreparedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
- theSentTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
- theCompletedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions];
-
- if ((thePreparedTransactionsArray == NULL) ||
- (theSentTransactionsArray == NULL) ||
- (theCompletedTransactionsArray == NULL)) {
- goto error_handler;
- }//if
-
- for (i = 0; i < tMaxNoOfTransactions; i++) {
- thePreparedTransactionsArray[i] = NULL;
- theSentTransactionsArray[i] = NULL;
- theCompletedTransactionsArray[i] = NULL;
- }//for
- for (i = 0; i < 16; i++){
- tSignal[i] = getSignal();
- if(tSignal[i] == NULL) {
- theError.code = 4000;
- goto error_handler;
- }
- }
- for (i = 0; i < 16; i++)
- releaseSignal(tSignal[i]);
- theInitState = Initialised;
- DBUG_RETURN(0);
-
-error_handler:
- ndbout << "error_handler" << endl;
- releaseTransactionArrays();
- delete theDictionary;
- theImpl->m_transporter_facade->close(theNdbBlockNumber, 0);
- DBUG_RETURN(-1);
-}
-
-void
-Ndb::releaseTransactionArrays()
-{
- DBUG_ENTER("Ndb::releaseTransactionArrays");
- if (thePreparedTransactionsArray != NULL) {
- delete [] thePreparedTransactionsArray;
- }//if
- if (theSentTransactionsArray != NULL) {
- delete [] theSentTransactionsArray;
- }//if
- if (theCompletedTransactionsArray != NULL) {
- delete [] theCompletedTransactionsArray;
- }//if
- DBUG_VOID_RETURN;
-}//Ndb::releaseTransactionArrays()
-
-void
-Ndb::executeMessage(void* NdbObject,
- NdbApiSignal * aSignal,
- LinearSectionPtr ptr[3])
-{
- Ndb* tNdb = (Ndb*)NdbObject;
- tNdb->handleReceivedSignal(aSignal, ptr);
-}
-
-void Ndb::connected(Uint32 ref)
-{
-// cluster connect, a_node == own reference
- theMyRef= ref;
- Uint32 tmpTheNode= refToNode(ref);
- Uint64 tBlockNo= refToBlock(ref);
- if (theNdbBlockNumber >= 0){
- assert(theMyRef == numberToRef(theNdbBlockNumber, tmpTheNode));
- }
-
- TransporterFacade * theFacade = theImpl->m_transporter_facade;
- int i, n= 0;
- for (i = 1; i < MAX_NDB_NODES; i++){
- if (theFacade->getIsDbNode(i)){
- theImpl->theDBnodes[n] = i;
- n++;
- }
- }
- theImpl->theNoOfDBnodes = n;
-
- theFirstTransId = ((Uint64)tBlockNo << 52)+
- ((Uint64)tmpTheNode << 40);
- theFirstTransId += theFacade->m_max_trans_id;
- // assert(0);
- DBUG_PRINT("info",("connected with ref=%x, id=%d, no_db_nodes=%d, first_trans_id: 0x%lx",
- theMyRef,
- tmpTheNode,
- theImpl->theNoOfDBnodes,
- (long) theFirstTransId));
- theCommitAckSignal = new NdbApiSignal(theMyRef);
-
- theDictionary->m_receiver.m_reference= theMyRef;
- theNode= tmpTheNode; // flag that Ndb object is initialized
-}
-
-void Ndb::report_node_connected(Uint32 nodeId)
-{
- if (theEventBuffer)
- {
- // node connected
- // eventOperations in the ndb object should be notified
- theEventBuffer->report_node_connected(nodeId);
- }
-}
-
-void
-Ndb::statusMessage(void* NdbObject, Uint32 a_node, bool alive, bool nfComplete)
-{
- DBUG_ENTER("Ndb::statusMessage");
- DBUG_PRINT("info", ("a_node: %u alive: %u nfComplete: %u",
- a_node, alive, nfComplete));
- Ndb* tNdb = (Ndb*)NdbObject;
- if (alive) {
- if (nfComplete) {
- // cluster connect, a_node == own reference
- tNdb->connected(a_node);
- DBUG_VOID_RETURN;
- }//if
- tNdb->report_node_connected(a_node);
- } else {
- if (nfComplete) {
- tNdb->report_node_failure_completed(a_node);
- } else {
- tNdb->report_node_failure(a_node);
- }//if
- }//if
- NdbDictInterface::execNodeStatus(&tNdb->theDictionary->m_receiver,
- a_node, alive, nfComplete);
- DBUG_VOID_RETURN;
-}
-
-void
-Ndb::report_node_failure(Uint32 node_id)
-{
- /**
- * We can only set the state here since this object can execute
- * simultaneously.
- *
- * This method is only called by ClusterMgr (via lots of methods)
- */
-
- theImpl->the_release_ind[node_id] = 1;
- // must come after
- theImpl->the_release_ind[0] = 1;
- theImpl->theWaiter.nodeFail(node_id);
- return;
-}//Ndb::report_node_failure()
-
-
-void
-Ndb::report_node_failure_completed(Uint32 node_id)
-{
- if (theEventBuffer)
- {
- // node failed
- // eventOperations in the ndb object should be notified
- theEventBuffer->report_node_failure(node_id);
- if(!theImpl->m_transporter_facade->theClusterMgr->isClusterAlive())
- {
- // cluster is unavailable,
- // eventOperations in the ndb object should be notified
- theEventBuffer->completeClusterFailed();
- }
- }
-
- abortTransactionsAfterNodeFailure(node_id);
-
-}//Ndb::report_node_failure_completed()
-
-/***************************************************************************
-void abortTransactionsAfterNodeFailure();
-
-Remark: Abort all transactions in theSentTransactionsArray after connection
- to one node has failed
-****************************************************************************/
-void
-Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId)
-{
- Uint32 tNoSentTransactions = theNoOfSentTransactions;
- for (int i = tNoSentTransactions - 1; i >= 0; i--) {
- NdbTransaction* localCon = theSentTransactionsArray[i];
- if (localCon->getConnectedNodeId() == aNodeId) {
- const NdbTransaction::SendStatusType sendStatus = localCon->theSendStatus;
- if (sendStatus == NdbTransaction::sendTC_OP ||
- sendStatus == NdbTransaction::sendTC_COMMIT) {
- /*
- A transaction was interrupted in the prepare phase by a node
- failure. Since the transaction was not found in the phase
- after the node failure it cannot have been committed and
- we report a normal node failure abort.
- */
- localCon->setOperationErrorCodeAbort(4010);
- localCon->theCompletionStatus = NdbTransaction::CompletedFailure;
- } else if (sendStatus == NdbTransaction::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 = NdbTransaction::CompletedSuccess;
- } else {
-#ifdef VM_TRACE
- printState("abortTransactionsAfterNodeFailure %x", this);
- abort();
-#endif
- }
- /*
- All transactions arriving here have no connection to the kernel
- 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->theReturnStatus = NdbTransaction::ReturnFailure;
- localCon->theCommitStatus = NdbTransaction::Aborted;
- localCon->theReleaseOnClose = true;
- completedTransaction(localCon);
- }
- else if(localCon->report_node_failure(aNodeId))
- {
- completedTransaction(localCon);
- }
- }//for
- return;
-}//Ndb::abortTransactionsAfterNodeFailure()
-
-/****************************************************************************
-void handleReceivedSignal(NdbApiSignal* aSignal);
-
-Parameters: aSignal: The signal object.
-Remark: Send all operations belonging to this connection.
-*****************************************************************************/
-void
-Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
-{
- NdbOperation* tOp;
- NdbIndexOperation* tIndexOp;
- NdbTransaction* tCon;
- int tReturnCode = -1;
- const Uint32* tDataPtr = aSignal->getDataPtr();
- const Uint32 tWaitState = theImpl->theWaiter.m_state;
- const Uint32 tSignalNumber = aSignal->readSignalNumber();
- const Uint32 tFirstData = *tDataPtr;
- const Uint32 tLen = aSignal->getLength();
- void * tFirstDataPtr;
- NdbWaiter *t_waiter;
-
- /*
- 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:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- const TcKeyConf * const keyConf = (TcKeyConf *)tDataPtr;
- const BlockReference aTCRef = aSignal->theSendersBlockRef;
-
- tCon = void2con(tFirstDataPtr);
- if ((tCon->checkMagicNumber() == 0) &&
- (tCon->theSendStatus == NdbTransaction::sendTC_OP)) {
- tReturnCode = tCon->receiveTCKEYCONF(keyConf, tLen);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
-
- if(TcKeyConf::getMarkerFlag(keyConf->confInfo)){
- NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
- theCommitAckSignal,
- keyConf->transId1,
- keyConf->transId2,
- aTCRef);
- }
-
- return;
- }//if
- goto InvalidSignal;
-
- return;
- }
- case GSN_TRANSID_AI:{
- tFirstDataPtr = int2void(tFirstData);
- NdbReceiver* tRec;
- if (tFirstDataPtr && (tRec = void2rec(tFirstDataPtr)) &&
- 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);
- }
-
- if(com == 0)
- return;
-
- switch(tRec->getType()){
- case NdbReceiver::NDB_OPERATION:
- case NdbReceiver::NDB_INDEX_OPERATION:
- if(tCon->OpCompleteSuccess() != -1){
- completedTransaction(tCon);
- }
- return;
- case NdbReceiver::NDB_SCANRECEIVER:
- tCon->theScanningOp->receiver_delivered(tRec);
- theImpl->theWaiter.m_state = (((WaitSignalType) tWaitState) == WAIT_SCAN ?
- (Uint32) NO_WAIT : tWaitState);
- break;
- default:
- goto InvalidSignal;
- }
- break;
- } else {
- /**
- * This is ok as transaction can have been aborted before TRANSID_AI
- * arrives (if TUP on other node than TC)
- */
- return;
- }
- }
- case GSN_TCKEY_FAILCONF:
- {
- tFirstDataPtr = int2void(tFirstData);
- const TcKeyFailConf * failConf = (TcKeyFailConf *)tDataPtr;
- const BlockReference aTCRef = aSignal->theSendersBlockRef;
- if (tFirstDataPtr != 0){
- tOp = void2rec_op(tFirstDataPtr);
-
- if (tOp->checkMagicNumber(false) == 0) {
- tCon = tOp->theNdbCon;
- if (tCon != NULL) {
- if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) ||
- (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) {
- tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
- }
- }
- } else {
-#ifdef VM_TRACE
- ndbout_c("Recevied TCKEY_FAILCONF wo/ operation");
-#endif
- }
- if(tFirstData & 1){
- NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
- theCommitAckSignal,
- failConf->transId1,
- failConf->transId2,
- aTCRef);
- }
- return;
- }
- case GSN_TCKEY_FAILREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if(tFirstDataPtr != 0){
- tOp = void2rec_op(tFirstDataPtr);
- if (tOp->checkMagicNumber(false) == 0) {
- tCon = tOp->theNdbCon;
- if (tCon != NULL) {
- if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) ||
- (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) {
- tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- return;
- }//if
- }//if
- }//if
- }//if
- }
-#ifdef VM_TRACE
- ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
-#endif
- return;
- return;
- }
- case GSN_TCKEYREF:
- {
- 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 == NdbTransaction::sendTC_OP) {
- tReturnCode = tOp->receiveTCKEYREF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- return;
- }//if
- break;
- }//if
- }//if
- } //if
- goto InvalidSignal;
- return;
- }
- case GSN_TC_COMMITCONF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- const TcCommitConf * const commitConf = (TcCommitConf *)tDataPtr;
- const BlockReference aTCRef = aSignal->theSendersBlockRef;
-
- tCon = void2con(tFirstDataPtr);
- if ((tCon->checkMagicNumber() == 0) &&
- (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) {
- tReturnCode = tCon->receiveTC_COMMITCONF(commitConf);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
-
- if(tFirstData & 1){
- NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
- theCommitAckSignal,
- commitConf->transId1,
- commitConf->transId2,
- aTCRef);
- }
- return;
- }
- goto InvalidSignal;
- return;
- }
-
- case GSN_TC_COMMITREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- tCon = void2con(tFirstDataPtr);
- if ((tCon->checkMagicNumber() == 0) &&
- (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) {
- tReturnCode = tCon->receiveTC_COMMITREF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
- return;
- }
- case GSN_TCROLLBACKCONF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- tCon = void2con(tFirstDataPtr);
- if ((tCon->checkMagicNumber() == 0) &&
- (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) {
- tReturnCode = tCon->receiveTCROLLBACKCONF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
- return;
- }
- case GSN_TCROLLBACKREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- tCon = void2con(tFirstDataPtr);
- if ((tCon->checkMagicNumber() == 0) &&
- (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) {
- tReturnCode = tCon->receiveTCROLLBACKREF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
- return;
- }
- case GSN_TCROLLBACKREP:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() == 0) {
- tReturnCode = tCon->receiveTCROLLBACKREP(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
- return;
- }
- case GSN_TCSEIZECONF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- if (tWaitState != WAIT_TC_SEIZE) {
- goto InvalidSignal;
- }//if
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() != 0) {
- goto InvalidSignal;
- }//if
- tReturnCode = tCon->receiveTCSEIZECONF(aSignal);
- if (tReturnCode != -1) {
- theImpl->theWaiter.m_state = NO_WAIT;
- } else {
- goto InvalidSignal;
- }//if
- break;
- }
- case GSN_TCSEIZEREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- if (tWaitState != WAIT_TC_SEIZE) {
- return;
- }//if
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() != 0) {
- return;
- }//if
- tReturnCode = tCon->receiveTCSEIZEREF(aSignal);
- if (tReturnCode != -1) {
- theImpl->theWaiter.m_state = NO_WAIT;
- } else {
- return;
- }//if
- break;
- }
- case GSN_TCRELEASECONF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- if (tWaitState != WAIT_TC_RELEASE) {
- goto InvalidSignal;
- }//if
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() != 0) {
- goto InvalidSignal;
- }//if
- tReturnCode = tCon->receiveTCRELEASECONF(aSignal);
- if (tReturnCode != -1) {
- theImpl->theWaiter.m_state = NO_WAIT;
- }//if
- break;
- }
- case GSN_TCRELEASEREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- if (tWaitState != WAIT_TC_RELEASE) {
- goto InvalidSignal;
- }//if
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() != 0) {
- goto InvalidSignal;
- }//if
- tReturnCode = tCon->receiveTCRELEASEREF(aSignal);
- if (tReturnCode != -1) {
- theImpl->theWaiter.m_state = NO_WAIT;
- }//if
- break;
- }
-
- case GSN_GET_TABINFOREF:
- case GSN_GET_TABINFO_CONF:
- case GSN_CREATE_TABLE_REF:
- case GSN_CREATE_TABLE_CONF:
- case GSN_DROP_TABLE_CONF:
- case GSN_DROP_TABLE_REF:
- case GSN_ALTER_TABLE_CONF:
- case GSN_ALTER_TABLE_REF:
- case GSN_CREATE_INDX_CONF:
- case GSN_CREATE_INDX_REF:
- case GSN_DROP_INDX_CONF:
- case GSN_DROP_INDX_REF:
- case GSN_CREATE_EVNT_CONF:
- case GSN_CREATE_EVNT_REF:
- case GSN_DROP_EVNT_CONF:
- case GSN_DROP_EVNT_REF:
- case GSN_LIST_TABLES_CONF:
- case GSN_CREATE_FILE_REF:
- case GSN_CREATE_FILE_CONF:
- case GSN_CREATE_FILEGROUP_REF:
- case GSN_CREATE_FILEGROUP_CONF:
- case GSN_DROP_FILE_REF:
- case GSN_DROP_FILE_CONF:
- case GSN_DROP_FILEGROUP_REF:
- case GSN_DROP_FILEGROUP_CONF:
- case GSN_WAIT_GCP_CONF:
- case GSN_WAIT_GCP_REF:
- NdbDictInterface::execSignal(&theDictionary->m_receiver,
- aSignal, ptr);
- return;
-
- case GSN_SUB_REMOVE_CONF:
- case GSN_SUB_REMOVE_REF:
- return; // ignore these signals
- case GSN_SUB_START_CONF:
- case GSN_SUB_START_REF:
- case GSN_SUB_STOP_CONF:
- case GSN_SUB_STOP_REF:
- NdbDictInterface::execSignal(&theDictionary->m_receiver,
- aSignal, ptr);
- return;
- case GSN_SUB_GCP_COMPLETE_REP:
- {
- const SubGcpCompleteRep * const rep=
- CAST_CONSTPTR(SubGcpCompleteRep, aSignal->getDataPtr());
- theEventBuffer->execSUB_GCP_COMPLETE_REP(rep);
- return;
- }
- case GSN_SUB_TABLE_DATA:
- {
- const SubTableData * const sdata=
- CAST_CONSTPTR(SubTableData, aSignal->getDataPtr());
- const Uint32 oid = sdata->senderData;
- NdbEventOperationImpl *op= (NdbEventOperationImpl*)int2void(oid);
-
- if (unlikely(op == 0 || op->m_magic_number != NDB_EVENT_OP_MAGIC_NUMBER))
- {
- g_eventLogger.error("dropped GSN_SUB_TABLE_DATA due to wrong magic "
- "number");
- return ;
- }
-
- // Accumulate DIC_TAB_INFO for TE_ALTER events
- if (SubTableData::getOperation(sdata->requestInfo) ==
- NdbDictionary::Event::_TE_ALTER &&
- !op->execSUB_TABLE_DATA(aSignal, ptr))
- return;
-
- for (int i= aSignal->m_noOfSections;i < 3; i++) {
- ptr[i].p = NULL;
- ptr[i].sz = 0;
- }
- DBUG_PRINT("info",("oid=senderData: %d, gci: %d, operation: %d, "
- "tableId: %d",
- sdata->senderData, sdata->gci,
- SubTableData::getOperation(sdata->requestInfo),
- sdata->tableId));
-
- theEventBuffer->insertDataL(op,sdata, ptr);
- return;
- }
- case GSN_DIHNDBTAMPER:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- if (tWaitState != WAIT_NDB_TAMPER)
- return;
- tCon = void2con(tFirstDataPtr);
- if (tCon->checkMagicNumber() != 0)
- return;
- tReturnCode = tCon->receiveDIHNDBTAMPER(aSignal);
- if (tReturnCode != -1)
- theImpl->theWaiter.m_state = NO_WAIT;
- break;
- }
- case GSN_SCAN_TABCONF:
- {
- 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 && tWaitState == WAIT_SCAN)
- theImpl->theWaiter.m_state = NO_WAIT;
- break;
- } else {
- goto InvalidSignal;
- }
- }
- case GSN_SCAN_TABREF:
- {
- tFirstDataPtr = int2void(tFirstData);
- if (tFirstDataPtr == 0) goto InvalidSignal;
-
- tCon = void2con(tFirstDataPtr);
-
- assert(tFirstDataPtr != 0 &&
- void2con(tFirstDataPtr)->checkMagicNumber() == 0);
-
- if (tCon->checkMagicNumber() == 0){
- tReturnCode = tCon->receiveSCAN_TABREF(aSignal);
- if (tReturnCode != -1 && tWaitState == WAIT_SCAN){
- theImpl->theWaiter.m_state = NO_WAIT;
- }
- break;
- }
- goto InvalidSignal;
- }
- case GSN_KEYINFO20: {
- tFirstDataPtr = int2void(tFirstData);
- NdbReceiver* tRec;
- if (tFirstDataPtr && (tRec = void2rec(tFirstDataPtr)) &&
- 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);
- theImpl->theWaiter.m_state = (((WaitSignalType) tWaitState) == WAIT_SCAN ?
- (Uint32) NO_WAIT : tWaitState);
- break;
- case 0:
- break;
- case -1:
- goto InvalidSignal;
- }
- break;
- } else {
- /**
- * This is ok as transaction can have been aborted before KEYINFO20
- * arrives (if TUP on other node than TC)
- */
- return;
- }
- }
- case GSN_TCINDXCONF:{
- 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 == NdbTransaction::sendTC_OP)) {
- tReturnCode = tCon->receiveTCINDXCONF(indxConf, tLen);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- }//if
-
- if(TcIndxConf::getMarkerFlag(indxConf->confInfo)){
- NdbTransaction::sendTC_COMMIT_ACK(theImpl->m_transporter_facade,
- theCommitAckSignal,
- indxConf->transId1,
- indxConf->transId2,
- aTCRef);
- }
- return;
- }
- case GSN_TCINDXREF:{
- 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 == NdbTransaction::sendTC_OP) {
- tReturnCode = tIndexOp->receiveTCINDXREF(aSignal);
- if (tReturnCode != -1) {
- completedTransaction(tCon);
- }//if
- return;
- }//if
- }//if
- }//if
- goto InvalidSignal;
- return;
- }
- default:
- goto InvalidSignal;
- }//swich
-
- t_waiter= &theImpl->theWaiter;
- if (t_waiter->get_state() == NO_WAIT && tWaitState != NO_WAIT)
- {
- /*
- If our waiter object is the owner of the "poll rights", then we
- can simply return, we will return from this routine to the
- place where external_poll was called. From there it will move
- the "poll ownership" to a new thread if available.
-
- If our waiter object doesn't own the "poll rights", then we must
- signal the thread from where this waiter object called
- its conditional wait. This will wake up this thread so that it
- can continue its work.
- */
- TransporterFacade *tp= theImpl->m_transporter_facade;
- if (tp->get_poll_owner() != t_waiter)
- {
- /*
- Wake up the thread waiting for response and remove it from queue
- of objects waiting for receive completion
- */
- tp->remove_from_cond_wait_queue(t_waiter);
- t_waiter->cond_signal();
- }
- }//if
- return;
-
- InvalidSignal:
-#ifdef VM_TRACE
- ndbout_c("Ndbif: Error Ndb::handleReceivedSignal "
- "(tFirstDataPtr=%p, GSN=%d, theImpl->theWaiter.m_state=%d)"
- " sender = (Block: %d Node: %d)",
- tFirstDataPtr,
- tSignalNumber,
- tWaitState,
- refToBlock(aSignal->theSendersBlockRef),
- refToNode(aSignal->theSendersBlockRef));
-#endif
-#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
-#endif
-
- return;
-}//Ndb::handleReceivedSignal()
-
-
-/*****************************************************************************
-void completedTransaction(NdbTransaction* aCon);
-
-Remark: One transaction has been completed.
- Remove it from send array and put it into the completed
- transaction array. Finally check if it is time to wake
- up a poller.
-******************************************************************************/
-void
-Ndb::completedTransaction(NdbTransaction* aCon)
-{
- Uint32 tTransArrayIndex = aCon->theTransArrayIndex;
- Uint32 tNoSentTransactions = theNoOfSentTransactions;
- Uint32 tNoCompletedTransactions = theNoOfCompletedTransactions;
- if ((tNoSentTransactions > 0) && (aCon->theListState == NdbTransaction::InSendList) &&
- (tTransArrayIndex < tNoSentTransactions)) {
- NdbTransaction* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1];
-
- theCompletedTransactionsArray[tNoCompletedTransactions] = aCon;
- aCon->theTransArrayIndex = tNoCompletedTransactions;
- if (tMoveCon != aCon) {
- tMoveCon->theTransArrayIndex = tTransArrayIndex;
- theSentTransactionsArray[tTransArrayIndex] = tMoveCon;
- }//if
- theSentTransactionsArray[tNoSentTransactions - 1] = NULL;
- theNoOfCompletedTransactions = tNoCompletedTransactions + 1;
-
- theNoOfSentTransactions = tNoSentTransactions - 1;
- aCon->theListState = NdbTransaction::InCompletedList;
- aCon->handleExecuteCompletion();
- if ((theMinNoOfEventsToWakeUp != 0) &&
- (theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) {
- theMinNoOfEventsToWakeUp = 0;
- TransporterFacade *tp = theImpl->m_transporter_facade;
- NdbWaiter *t_waiter= &theImpl->theWaiter;
- if (tp->get_poll_owner() != t_waiter) {
- /*
- When we come here, this is executed by the thread owning the "poll
- rights". This thread is not where our waiter object belongs.
- Thus we wake up the thread owning this waiter object but first
- we must remove it from the conditional wait queue so that we
- don't assign it as poll owner later on.
- */
- tp->remove_from_cond_wait_queue(t_waiter);
- t_waiter->cond_signal();
- }
- return;
- }//if
- } else {
- ndbout << "theNoOfSentTransactions = " << (int) theNoOfSentTransactions;
- ndbout << " theListState = " << (int) aCon->theListState;
- ndbout << " theTransArrayIndex = " << aCon->theTransArrayIndex;
- ndbout << endl << flush;
-#ifdef VM_TRACE
- printState("completedTransaction abort");
- abort();
-#endif
- }//if
-}//Ndb::completedTransaction()
-
-/*****************************************************************************
-void reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans);
-
-Remark: Call the callback methods of the completed transactions.
-******************************************************************************/
-void
-Ndb::reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans)
-{
- Uint32 i;
- if (aNoOfCompletedTrans > 0) {
- for (i = 0; i < aNoOfCompletedTrans; i++) {
- void* anyObject = aCopyArray[i]->theCallbackObject;
- NdbAsynchCallback aCallback = aCopyArray[i]->theCallbackFunction;
- int tResult = 0;
- if (aCallback != NULL) {
- if (aCopyArray[i]->theReturnStatus == NdbTransaction::ReturnFailure) {
- tResult = -1;
- }//if
- (*aCallback)(tResult, aCopyArray[i], anyObject);
- }//if
- }//for
- }//if
-}//Ndb::reportCallback()
-
-/*****************************************************************************
-Uint32 pollCompleted(NdbTransaction** aCopyArray);
-
-Remark: Transfer the data from the completed transaction to a local array.
- This support is used by a number of the poll-methods.
-******************************************************************************/
-Uint32
-Ndb::pollCompleted(NdbTransaction** aCopyArray)
-{
- check_send_timeout();
- Uint32 i;
- Uint32 tNoCompletedTransactions = theNoOfCompletedTransactions;
- if (tNoCompletedTransactions > 0) {
- for (i = 0; i < tNoCompletedTransactions; i++) {
- aCopyArray[i] = theCompletedTransactionsArray[i];
- if (aCopyArray[i]->theListState != NdbTransaction::InCompletedList) {
- ndbout << "pollCompleted error ";
- ndbout << (int) aCopyArray[i]->theListState << endl;
- abort();
- }//if
- theCompletedTransactionsArray[i] = NULL;
- aCopyArray[i]->theListState = NdbTransaction::NotInList;
- }//for
- }//if
- theNoOfCompletedTransactions = 0;
- return tNoCompletedTransactions;
-}//Ndb::pollCompleted()
-
-void
-Ndb::check_send_timeout()
-{
- Uint32 timeout = theImpl->m_transporter_facade->m_waitfor_timeout;
- NDB_TICKS current_time = NdbTick_CurrentMillisecond();
- assert(current_time >= the_last_check_time);
- if (current_time - the_last_check_time > 1000) {
- the_last_check_time = current_time;
- Uint32 no_of_sent = theNoOfSentTransactions;
- for (Uint32 i = 0; i < no_of_sent; i++) {
- NdbTransaction* a_con = theSentTransactionsArray[i];
- if ((current_time - a_con->theStartTransTime) > timeout)
- {
-#ifdef VM_TRACE
- a_con->printState();
- Uint32 t1 = a_con->theTransactionId;
- Uint32 t2 = a_con->theTransactionId >> 32;
- ndbout_c("4012 [%.8x %.8x]", t1, t2);
- //abort();
-#endif
- a_con->theReleaseOnClose = true;
- a_con->theError.code = 4012;
- a_con->setOperationErrorCodeAbort(4012);
- a_con->theCommitStatus = NdbTransaction::NeedAbort;
- a_con->theCompletionStatus = NdbTransaction::CompletedFailure;
- a_con->handleExecuteCompletion();
- remove_sent_list(i);
- insert_completed_list(a_con);
- no_of_sent--;
- i--;
- }//if
- }//for
- }//if
-}
-
-void
-Ndb::remove_sent_list(Uint32 list_index)
-{
- Uint32 last_index = theNoOfSentTransactions - 1;
- if (list_index < last_index) {
- NdbTransaction* t_con = theSentTransactionsArray[last_index];
- theSentTransactionsArray[list_index] = t_con;
- }//if
- theNoOfSentTransactions = last_index;
- theSentTransactionsArray[last_index] = 0;
-}
-
-Uint32
-Ndb::insert_completed_list(NdbTransaction* a_con)
-{
- Uint32 no_of_comp = theNoOfCompletedTransactions;
- theCompletedTransactionsArray[no_of_comp] = a_con;
- theNoOfCompletedTransactions = no_of_comp + 1;
- a_con->theListState = NdbTransaction::InCompletedList;
- a_con->theTransArrayIndex = no_of_comp;
- return no_of_comp;
-}
-
-Uint32
-Ndb::insert_sent_list(NdbTransaction* a_con)
-{
- Uint32 no_of_sent = theNoOfSentTransactions;
- theSentTransactionsArray[no_of_sent] = a_con;
- theNoOfSentTransactions = no_of_sent + 1;
- a_con->theListState = NdbTransaction::InSendList;
- a_con->theTransArrayIndex = no_of_sent;
- return no_of_sent;
-}
-
-/*****************************************************************************
-void sendPrepTrans(int forceSend);
-
-Remark: Send a batch of transactions prepared for sending to the NDB kernel.
-******************************************************************************/
-void
-Ndb::sendPrepTrans(int forceSend)
-{
- // Always called when holding mutex on TransporterFacade
- /*
- We will send a list of transactions to the NDB kernel. Before
- sending we check the following.
- 1) Node connected to is still alive
- Checked by both checking node status and node sequence
- 2) Send buffer can handle the size of messages we are planning to send
- So far this is just a fake check but will soon be a real check
- When the connected node has failed we abort the transaction without
- responding anymore to the node since the kernel will clean up
- automatically.
- When sendBuffer cannot handle anymore messages then we will also abort
- transaction but by communicating to the kernel since it is still alive
- and we keep a small space for messages like that.
- */
- Uint32 i;
- TransporterFacade* tp = theImpl->m_transporter_facade;
- Uint32 no_of_prep_trans = theNoOfPreparedTransactions;
- for (i = 0; i < no_of_prep_trans; i++) {
- NdbTransaction * a_con = thePreparedTransactionsArray[i];
- thePreparedTransactionsArray[i] = NULL;
- Uint32 node_id = a_con->getConnectedNodeId();
- if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) &&
- tp->get_node_alive(node_id) ||
- (tp->get_node_stopping(node_id) &&
- ((a_con->theSendStatus == NdbTransaction::sendABORT) ||
- (a_con->theSendStatus == NdbTransaction::sendABORTfail) ||
- (a_con->theSendStatus == NdbTransaction::sendCOMMITstate) ||
- (a_con->theSendStatus == NdbTransaction::sendCompleted)))) {
- /*
- We will send if
- 1) Node is alive and sequences are correct OR
- 2) Node is stopping and we only want to commit or abort
- In a graceful stop situation we want to ensure quick aborts
- of all transactions and commits and thus we allow aborts and
- commits to continue but not normal operations.
- */
- if (tp->check_send_size(node_id, a_con->get_send_size())) {
- if (a_con->doSend() == 0) {
- NDB_TICKS current_time = NdbTick_CurrentMillisecond();
- a_con->theStartTransTime = current_time;
- continue;
- } else {
- /*
- Although all precautions we did not manage to send the operations
- Must have been a dropped connection on the transporter side.
- We don't expect to be able to continue using this connection so
- we will treat it as a node failure.
- */
- TRACE_DEBUG("Send problem even after checking node status");
- }//if
- } else {
- /*
- The send buffer is currently full or at least close to. We will
- not allow a send to continue. We will set the connection so that
- it is indicated that we need to abort the transaction. If we were
- trying to commit or abort and got a send buffer we will not try
- again and will thus set the state to Aborted to avoid a more or
- less eternal loop of tries.
- */
- if (a_con->theSendStatus == NdbTransaction::sendOperations) {
- a_con->setOperationErrorCodeAbort(4021);
- a_con->theCommitStatus = NdbTransaction::NeedAbort;
- TRACE_DEBUG("Send buffer full and sendOperations");
- } else {
- a_con->setOperationErrorCodeAbort(4026);
- a_con->theCommitStatus = NdbTransaction::Aborted;
- TRACE_DEBUG("Send buffer full, set state to Aborted");
- }//if
- }//if
- } else {
-#ifdef VM_TRACE
- a_con->printState();
-#endif
- if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) &&
- tp->get_node_stopping(node_id)) {
- /*
- The node we are connected to is currently in an early stopping phase
- of a graceful stop. We will not send the prepared transactions. We
- will simply refuse and let the application code handle the abort.
- */
- TRACE_DEBUG("Abort a transaction when stopping a node");
- a_con->setOperationErrorCodeAbort(4023);
- a_con->theCommitStatus = NdbTransaction::NeedAbort;
- } else {
- /*
- The node is hard dead and we cannot continue. We will also release
- the connection to the free pool.
- */
- TRACE_DEBUG("The node was stone dead, inform about abort");
- a_con->setOperationErrorCodeAbort(4025);
- a_con->theReleaseOnClose = true;
- a_con->theTransactionIsStarted = false;
- a_con->theCommitStatus = NdbTransaction::Aborted;
- }//if
- }//if
- a_con->theReturnStatus = NdbTransaction::ReturnFailure;
- a_con->theCompletionStatus = NdbTransaction::CompletedFailure;
- a_con->handleExecuteCompletion();
- insert_completed_list(a_con);
- }//for
- theNoOfPreparedTransactions = 0;
- if (forceSend == 0) {
- tp->checkForceSend(theNdbBlockNumber);
- } else if (forceSend == 1) {
- tp->forceSend(theNdbBlockNumber);
- }//if
- return;
-}//Ndb::sendPrepTrans()
-
-/*****************************************************************************
-void waitCompletedTransactions(int aMilliSecondsToWait, int noOfEventsToWaitFor);
-
-Remark: First send all prepared operations and then check if there are any
- transactions already completed. Do not wait for not completed
- transactions.
-******************************************************************************/
-void
-Ndb::waitCompletedTransactions(int aMilliSecondsToWait,
- int noOfEventsToWaitFor,
- PollGuard *poll_guard)
-{
- theImpl->theWaiter.m_state = NO_WAIT;
- /**
- * theImpl->theWaiter.m_state = NO_WAIT;
- * To ensure no messup with synchronous node fail handling
- * (see ReportFailure)
- */
- int waitTime = aMilliSecondsToWait;
- NDB_TICKS currTime = NdbTick_CurrentMillisecond();
- NDB_TICKS maxTime = currTime + (NDB_TICKS)waitTime;
- theMinNoOfEventsToWakeUp = noOfEventsToWaitFor;
- const int maxsleep = aMilliSecondsToWait > 10 ? 10 : aMilliSecondsToWait;
- do {
- poll_guard->wait_for_input(maxsleep);
- if (theNoOfCompletedTransactions >= (Uint32)noOfEventsToWaitFor) {
- break;
- }//if
- theMinNoOfEventsToWakeUp = noOfEventsToWaitFor;
- waitTime = (int)(maxTime - NdbTick_CurrentMillisecond());
- } while (waitTime > 0);
-}//Ndb::waitCompletedTransactions()
-
-void Ndb::cond_signal()
-{
- NdbCondition_Signal(theImpl->theWaiter.m_condition);
-}
-/*****************************************************************************
-void sendPreparedTransactions(int forceSend = 0);
-
-Remark: First send all prepared operations and then check if there are any
- transactions already completed. Do not wait for not completed
- transactions.
-******************************************************************************/
-void
-Ndb::sendPreparedTransactions(int forceSend)
-{
- theImpl->m_transporter_facade->lock_mutex();
- sendPrepTrans(forceSend);
- theImpl->m_transporter_facade->unlock_mutex();
- return;
-}//Ndb::sendPreparedTransactions()
-
-/*****************************************************************************
-int sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup = 1, int forceSend = 0);
-
-Remark: First send all prepared operations and then check if there are any
- transactions already completed. Wait for not completed
- transactions until the specified number have completed or until the
- timeout has occured. Timeout zero means no waiting time.
-******************************************************************************/
-int
-Ndb::sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup, int forceSend)
-{
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard pg(theImpl->m_transporter_facade, &theImpl->theWaiter,
- theNdbBlockNumber);
- sendPrepTrans(forceSend);
- return poll_trans(aMillisecondNumber, minNoOfEventsToWakeup, &pg);
-}
-
-int
-Ndb::poll_trans(int aMillisecondNumber, int minNoOfEventsToWakeup,
- PollGuard *pg)
-{
- NdbTransaction* tConArray[1024];
- Uint32 tNoCompletedTransactions;
- if ((minNoOfEventsToWakeup <= 0) ||
- ((Uint32)minNoOfEventsToWakeup > theNoOfSentTransactions)) {
- minNoOfEventsToWakeup = theNoOfSentTransactions;
- }//if
- if ((theNoOfCompletedTransactions < (Uint32)minNoOfEventsToWakeup) &&
- (aMillisecondNumber > 0)) {
- waitCompletedTransactions(aMillisecondNumber, minNoOfEventsToWakeup, pg);
- tNoCompletedTransactions = pollCompleted(tConArray);
- } else {
- tNoCompletedTransactions = pollCompleted(tConArray);
- }//if
- pg->unlock_and_signal();
- reportCallback(tConArray, tNoCompletedTransactions);
- return tNoCompletedTransactions;
-}
-
-/*****************************************************************************
-int pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup);
-
-Remark: Check if there are any transactions already completed. Wait for not
- completed transactions until the specified number have completed or
- until the timeout has occured. Timeout zero means no waiting time.
-******************************************************************************/
-int
-Ndb::pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup)
-{
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard pg(theImpl->m_transporter_facade, &theImpl->theWaiter,
- theNdbBlockNumber);
- return poll_trans(aMillisecondNumber, minNoOfEventsToWakeup, &pg);
-}
-
-int
-Ndb::sendRecSignal(Uint16 node_id,
- Uint32 aWaitState,
- NdbApiSignal* aSignal,
- Uint32 conn_seq,
- Uint32 *ret_conn_seq)
-{
- /*
- In most situations 0 is returned.
- In error cases we have 5 different cases
- -1: Send ok, time out in waiting for reply
- -2: Node has failed
- -3: Send buffer not full, send failed yet
- -4: Send buffer full
- -5: Node is currently stopping
- */
-
- int return_code;
- Uint32 read_conn_seq;
- TransporterFacade* tp = theImpl->m_transporter_facade;
- Uint32 send_size = 1; // Always sends one signal only
- // Protected area
- /*
- The PollGuard has an implicit call of unlock_and_signal through the
- ~PollGuard method. This method is called implicitly by the compiler
- in all places where the object is out of context due to a return,
- break, continue or simply end of statement block
- */
- PollGuard poll_guard(tp,&theImpl->theWaiter,theNdbBlockNumber);
- read_conn_seq= tp->getNodeSequence(node_id);
- if (ret_conn_seq)
- *ret_conn_seq= read_conn_seq;
- if ((tp->get_node_alive(node_id)) &&
- ((read_conn_seq == conn_seq) ||
- (conn_seq == 0))) {
- if (tp->check_send_size(node_id, send_size)) {
- return_code = tp->sendSignal(aSignal, node_id);
- if (return_code != -1) {
- return poll_guard.wait_n_unlock(WAITFOR_RESPONSE_TIMEOUT,node_id,
- aWaitState, false);
- } else {
- return_code = -3;
- }
- } else {
- return_code = -4;
- }//if
- } else {
- if ((tp->get_node_stopping(node_id)) &&
- ((read_conn_seq == conn_seq) ||
- (conn_seq == 0))) {
- return_code = -5;
- } else {
- return_code = -2;
- }//if
- }//if
- return return_code;
- // End of protected area
-}//Ndb::sendRecSignal()
-
-void
-NdbTransaction::sendTC_COMMIT_ACK(TransporterFacade *tp,
- NdbApiSignal * aSignal,
- Uint32 transId1, Uint32 transId2,
- Uint32 aTCRef){
-#ifdef MARKER_TRACE
- ndbout_c("Sending TC_COMMIT_ACK(0x%.8x, 0x%.8x) to -> %d",
- transId1,
- transId2,
- refToNode(aTCRef));
-#endif
- aSignal->theTrace = TestOrd::TraceAPI;
- aSignal->theReceiversBlockNumber = DBTC;
- aSignal->theVerId_signalNumber = GSN_TC_COMMIT_ACK;
- aSignal->theLength = 2;
-
- Uint32 * dataPtr = aSignal->getDataPtrSend();
- dataPtr[0] = transId1;
- dataPtr[1] = transId2;
- tp->sendSignalUnCond(aSignal, refToNode(aTCRef));
-}
-
-int
-NdbImpl::send_event_report(Uint32 *data, Uint32 length)
-{
- NdbApiSignal aSignal(m_ndb.theMyRef);
- TransporterFacade *tp = m_transporter_facade;
- aSignal.theTrace = TestOrd::TraceAPI;
- aSignal.theReceiversBlockNumber = CMVMI;
- aSignal.theVerId_signalNumber = GSN_EVENT_REP;
- aSignal.theLength = length;
- memcpy((char *)aSignal.getDataPtrSend(), (char *)data, length*4);
-
- Uint32 tNode;
- Ndb_cluster_connection_node_iter node_iter;
- m_ndb_cluster_connection.init_get_next_node(node_iter);
- while ((tNode= m_ndb_cluster_connection.get_next_node(node_iter)))
- {
- if(tp->get_node_alive(tNode)){
- tp->sendSignal(&aSignal, tNode);
- return 0;
- }
- }
- return 1;
-}
diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp
deleted file mode 100644
index d32fffb9744..00000000000
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (c) 2003-2006 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-
-#include "NdbApiSignal.hpp"
-#include "NdbImpl.hpp"
-#include <NdbOperation.hpp>
-#include <NdbTransaction.hpp>
-#include <NdbRecAttr.hpp>
-#include <IPCConfig.hpp>
-#include "TransporterFacade.hpp"
-#include <ConfigRetriever.hpp>
-#include <ndb_limits.h>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-#include "ObjectMap.hpp"
-#include <NdbIndexScanOperation.hpp>
-#include <NdbIndexOperation.hpp>
-#include "NdbUtil.hpp"
-#include <NdbBlob.hpp>
-#include "NdbEventOperationImpl.hpp"
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection,
- const char* aDataBase , const char* aSchema)
- : theImpl(NULL)
-{
- DBUG_ENTER("Ndb::Ndb()");
- DBUG_PRINT("enter",("Ndb::Ndb this: 0x%lx", (long) this));
- setup(ndb_cluster_connection, aDataBase, aSchema);
- DBUG_VOID_RETURN;
-}
-
-void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
- const char* aDataBase , const char* aSchema)
-{
- DBUG_ENTER("Ndb::setup");
-
- assert(theImpl == NULL);
- theImpl= new NdbImpl(ndb_cluster_connection,*this);
- theDictionary= &(theImpl->m_dictionary);
-
- thePreparedTransactionsArray= NULL;
- theSentTransactionsArray= NULL;
- theCompletedTransactionsArray= NULL;
- theNoOfPreparedTransactions= 0;
- theNoOfSentTransactions= 0;
- theNoOfCompletedTransactions= 0;
- theRemainingStartTransactions= 0;
- theMaxNoOfTransactions= 0;
- theMinNoOfEventsToWakeUp= 0;
- theTransactionList= NULL;
- theConnectionArray= NULL;
- the_last_check_time= 0;
- theFirstTransId= 0;
- theRestartGCI= 0;
- theNdbBlockNumber= -1;
- theInitState= NotConstructed;
-
- theNode= 0;
- theFirstTransId= 0;
- theMyRef= 0;
-
- cond_wait_index = TransporterFacade::MAX_NO_THREADS;
- cond_signal_ndb = NULL;
-
- fullyQualifiedNames = true;
-
-#ifdef POORMANSPURIFY
- cgetSignals =0;
- cfreeSignals = 0;
- cnewSignals = 0;
- creleaseSignals = 0;
-#endif
-
- theError.code = 0;
-
- theConnectionArray = new NdbConnection * [MAX_NDB_NODES];
- theCommitAckSignal = NULL;
-
- int i;
- for (i = 0; i < MAX_NDB_NODES ; i++) {
- theConnectionArray[i] = NULL;
- }//forg
- m_sys_tab_0 = NULL;
-
- theImpl->m_dbname.assign(aDataBase);
- theImpl->m_schemaname.assign(aSchema);
- theImpl->update_prefix();
-
- theImpl->theWaiter.m_mutex = theImpl->m_transporter_facade->theMutexPtr;
-
- // Signal that the constructor has finished OK
- if (theInitState == NotConstructed)
- theInitState = NotInitialised;
-
- {
- // theImpl->theWaiter.m_mutex must be set before this
- theEventBuffer= new NdbEventBuffer(this);
- if (theEventBuffer == NULL) {
- ndbout_c("Failed NdbEventBuffer()");
- exit(-1);
- }
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-/*****************************************************************************
- * ~Ndb();
- *
- * Remark: Disconnect with the database.
- *****************************************************************************/
-Ndb::~Ndb()
-{
- DBUG_ENTER("Ndb::~Ndb()");
- DBUG_PRINT("enter",("this: 0x%lx", (long) this));
-
- if (m_sys_tab_0)
- getDictionary()->removeTableGlobal(*m_sys_tab_0, 0);
-
- assert(theImpl->m_ev_op == 0); // user should return NdbEventOperation's
- for (NdbEventOperationImpl *op= theImpl->m_ev_op; op; op=op->m_next)
- {
- if (op->m_state == NdbEventOperation::EO_EXECUTING && op->stop())
- g_eventLogger.error("stopping NdbEventOperation failed in Ndb destructor");
- op->m_magic_number= 0;
- }
- doDisconnect();
-
- /* Disconnect from transporter to stop signals from coming in */
- if (theImpl->m_transporter_facade != NULL && theNdbBlockNumber > 0){
- theImpl->m_transporter_facade->close(theNdbBlockNumber, theFirstTransId);
- }
-
- delete theEventBuffer;
-
- releaseTransactionArrays();
-
- delete []theConnectionArray;
- if(theCommitAckSignal != NULL){
- delete theCommitAckSignal;
- theCommitAckSignal = NULL;
- }
-
- delete theImpl;
-
-#ifdef POORMANSPURIFY
-#ifdef POORMANSGUI
- ndbout << "cnewSignals=" << cnewSignals << endl;
- ndbout << "cfreeSignals=" << cfreeSignals << endl;
- ndbout << "cgetSignals=" << cgetSignals << endl;
- ndbout << "creleaseSignals=" << creleaseSignals << endl;
-#endif
- // Poor mans purifier
- assert(cnewSignals == cfreeSignals);
- assert(cgetSignals == creleaseSignals);
-#endif
- DBUG_VOID_RETURN;
-}
-
-NdbWaiter::NdbWaiter(){
- m_node = 0;
- m_state = NO_WAIT;
- m_mutex = 0;
- m_poll_owner= false;
- m_cond_wait_index= TransporterFacade::MAX_NO_THREADS;
- m_condition = NdbCondition_Create();
-}
-
-NdbWaiter::~NdbWaiter(){
- NdbCondition_Destroy(m_condition);
-}
-
-NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
- Ndb& ndb)
- : m_ndb(ndb),
- m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
- m_transporter_facade(ndb_cluster_connection->m_impl.m_transporter_facade),
- m_dictionary(ndb),
- theCurrentConnectIndex(0),
- theNdbObjectIdMap(m_transporter_facade->theMutexPtr,
- 1024,1024),
- theNoOfDBnodes(0),
- m_ev_op(0)
-{
- int i;
- for (i = 0; i < MAX_NDB_NODES; i++) {
- the_release_ind[i] = 0;
- }
- m_optimized_node_selection=
- m_ndb_cluster_connection.m_optimized_node_selection;
-
- m_systemPrefix.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE, table_name_separator,
- NDB_SYSTEM_SCHEMA, table_name_separator);
-}
-
-NdbImpl::~NdbImpl()
-{
-}
-
diff --git a/storage/ndb/src/ndbapi/Ndblist.cpp b/storage/ndb/src/ndbapi/Ndblist.cpp
deleted file mode 100644
index e4aaacda0bb..00000000000
--- a/storage/ndb/src/ndbapi/Ndblist.cpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <NdbOut.hpp>
-#include <Ndb.hpp>
-#include <NdbOperation.hpp>
-#include <NdbIndexOperation.hpp>
-#include <NdbIndexScanOperation.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbRecAttr.hpp>
-#include "NdbUtil.hpp"
-#include "API.hpp"
-#include "NdbBlob.hpp"
-
-void
-Ndb::checkFailedNode()
-{
- DBUG_ENTER("Ndb::checkFailedNode");
- Uint32 *the_release_ind= theImpl->the_release_ind;
- if (the_release_ind[0] == 0)
- {
- DBUG_VOID_RETURN;
- }
- Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes;
- Uint8 *theDBnodes= theImpl->theDBnodes;
-
- DBUG_PRINT("enter", ("theNoOfDBnodes: %d", tNoOfDbNodes));
-
- DBUG_ASSERT(tNoOfDbNodes < MAX_NDB_NODES);
- for (Uint32 i = 0; i < tNoOfDbNodes; i++){
- const NodeId node_id = theDBnodes[i];
- DBUG_PRINT("info", ("i: %d, node_id: %d", i, node_id));
-
- DBUG_ASSERT(node_id < MAX_NDB_NODES);
- if (the_release_ind[node_id] == 1){
-
- /**
- * Release all connections in idle list (for node)
- */
- NdbTransaction * tNdbCon = theConnectionArray[node_id];
- theConnectionArray[node_id] = NULL;
- while (tNdbCon != NULL) {
- NdbTransaction* tempNdbCon = tNdbCon;
- tNdbCon = tNdbCon->next();
- releaseNdbCon(tempNdbCon);
- }
- the_release_ind[node_id] = 0;
- }
- }
- DBUG_VOID_RETURN;
-}
-
-/***************************************************************************
- * int createConIdleList(int aNrOfCon);
- *
- * Return Value: Return the number of created connection object
- * if createConIdleList was succesful
- * Return -1: In all other case.
- * Parameters: aNrOfCon : Number of connections offered to the application.
- * Remark: Create connection idlelist with NdbTransaction objects.
- ***************************************************************************/
-int
-Ndb::createConIdleList(int aNrOfCon)
-{
- if (theImpl->theConIdleList.fill(this, aNrOfCon))
- {
- return -1;
- }
- return aNrOfCon;
-}
-
-/***************************************************************************
- * int createOpIdleList(int aNrOfOp);
- *
- * Return Value: Return the number of created operation object if
- * createOpIdleList was succesful.
- * Return -1: In all other case.
- * Parameters: aNrOfOp: Number of operations offered to the application.
- * Remark: Create operation idlelist with NdbOperation objects..
- ***************************************************************************/
-int
-Ndb::createOpIdleList(int aNrOfOp)
-{
- if (theImpl->theOpIdleList.fill(this, aNrOfOp))
- {
- return -1;
- }
- return aNrOfOp;
-}
-
-/***************************************************************************
- * NdbBranch* NdbBranch();
- *
- * Return Value: Return a NdbBranch if the getNdbBranch was successful.
- * Return NULL : In all other case.
- * Remark: Get a NdbBranch from theBranchList and return the object .
- ***************************************************************************/
-NdbBranch*
-Ndb::getNdbBranch()
-{
- return theImpl->theBranchList.seize(this);
-}
-
-/***************************************************************************
- * NdbCall* NdbCall();
- *
- * Return Value: Return a NdbCall if the getNdbCall was successful.
- * Return NULL : In all other case.
- * Remark: Get a NdbCall from theCallList and return the object .
- ***************************************************************************/
-NdbCall*
-Ndb::getNdbCall()
-{
- return theImpl->theCallList.seize(this);
-}
-
-/***************************************************************************
- * NdbTransaction* getNdbCon();
- *
- * Return Value: Return a connection if the getNdbCon was successful.
- * Return NULL : In all other case.
- * Remark: Get a connection from theConIdleList and return the object .
- ***************************************************************************/
-NdbTransaction*
-Ndb::getNdbCon()
-{
- NdbTransaction* tNdbCon = theImpl->theConIdleList.seize(this);
- tNdbCon->theMagicNumber = 0x37412619;
- return tNdbCon;
-}
-
-/***************************************************************************
- * NdbLabel* getNdbLabel();
- *
- * Return Value: Return a NdbLabel if the getNdbLabel was successful.
- * Return NULL : In all other case.
- * Remark: Get a NdbLabel from theLabelList and return the object .
- ***************************************************************************/
-NdbLabel*
-Ndb::getNdbLabel()
-{
- return theImpl->theLabelList.seize(this);
-}
-
-/***************************************************************************
- * NdbScanReceiver* getNdbScanRec()
- *
- * Return Value: Return a NdbScanReceiver
- * Return NULL : In all other case.
- * Remark: Get a NdbScanReceiver from theScanRecList and return the
- * object .
- ****************************************************************************/
-NdbReceiver*
-Ndb::getNdbScanRec()
-{
- return theImpl->theScanList.seize(this);
-}
-
-/***************************************************************************
- * NdbSubroutine* getNdbSubroutine();
- *
- * Return Value: Return a NdbSubroutine if the getNdbSubroutine was successful.
- * Return NULL : In all other case.
- * Remark: Get a NdbSubroutine from theSubroutineList and return the object .
- ***************************************************************************/
-NdbSubroutine*
-Ndb::getNdbSubroutine()
-{
- return theImpl->theSubroutineList.seize(this);
-}
-
-/***************************************************************************
-NdbOperation* getOperation();
-
-Return Value: Return theOpList : if the getOperation was succesful.
- Return NULL : In all other case.
-Remark: Get an operation from theOpIdleList and return the object .
-***************************************************************************/
-NdbOperation*
-Ndb::getOperation()
-{
- return theImpl->theOpIdleList.seize(this);
-}
-
-/***************************************************************************
-NdbScanOperation* getScanOperation();
-
-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 .
-***************************************************************************/
-NdbIndexScanOperation*
-Ndb::getScanOperation()
-{
- return theImpl->theScanOpIdleList.seize(this);
-}
-
-/***************************************************************************
-NdbIndexOperation* getIndexOperation();
-
-Return Value: Return theOpList : if the getIndexOperation was succesful.
- Return NULL : In all other case.
-Remark: Get an operation from theIndexOpIdleList and return the object .
-***************************************************************************/
-NdbIndexOperation*
-Ndb::getIndexOperation()
-{
- return theImpl->theIndexOpIdleList.seize(this);
-}
-
-/***************************************************************************
-NdbRecAttr* getRecAttr();
-
-Return Value: Return a reference to a receive attribute object.
- Return NULL if it's not possible to get a receive attribute object.
-***************************************************************************/
-NdbRecAttr*
-Ndb::getRecAttr()
-{
- NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
- if (tRecAttr != NULL)
- {
- tRecAttr->init();
- return tRecAttr;
- }
-
- return NULL;
-}
-
-/***************************************************************************
-NdbApiSignal* getSignal();
-
-Return Value: Return a reference to a signal object.
- Return NULL if not possible to get a signal object.
-***************************************************************************/
-NdbApiSignal*
-Ndb::getSignal()
-{
- return theImpl->theSignalIdleList.seize(this);
-}
-
-NdbBlob*
-Ndb::getNdbBlob()
-{
- NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
- if(tBlob)
- {
- tBlob->init();
- }
- return tBlob;
-}
-
-/***************************************************************************
-void releaseNdbBranch(NdbBranch* aNdbBranch);
-
-Parameters: NdbBranch: The NdbBranch object.
-Remark: Add a NdbBranch object into the Branch idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
-{
- theImpl->theBranchList.release(aNdbBranch);
-}
-
-/***************************************************************************
-void releaseNdbCall(NdbCall* aNdbCall);
-
-Parameters: NdbBranch: The NdbBranch object.
-Remark: Add a NdbBranch object into the Branch idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbCall(NdbCall* aNdbCall)
-{
- theImpl->theCallList.release(aNdbCall);
-}
-
-/***************************************************************************
-void releaseNdbCon(NdbTransaction* aNdbCon);
-
-Parameters: aNdbCon: The NdbTransaction object.
-Remark: Add a Connection object into the signal idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbCon(NdbTransaction* aNdbCon)
-{
- aNdbCon->theMagicNumber = 0xFE11DD;
- theImpl->theConIdleList.release(aNdbCon);
-}
-
-/***************************************************************************
-void releaseNdbLabel(NdbLabel* aNdbLabel);
-
-Parameters: NdbLabel: The NdbLabel object.
-Remark: Add a NdbLabel object into the Label idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
-{
- theImpl->theLabelList.release(aNdbLabel);
-}
-
-/***************************************************************************
-void releaseNdbScanRec(NdbScanReceiver* aNdbScanRec);
-
-Parameters: aNdbScanRec: The NdbScanReceiver object.
-Remark: Add a NdbScanReceiver object into the Scan idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
-{
- theImpl->theScanList.release(aNdbScanRec);
-}
-
-/***************************************************************************
-void releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine);
-
-Parameters: NdbSubroutine: The NdbSubroutine object.
-Remark: Add a NdbSubroutine object into theSubroutine idlelist.
-***************************************************************************/
-void
-Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
-{
- theImpl->theSubroutineList.release(aNdbSubroutine);
-}
-
-/***************************************************************************
-void releaseOperation(NdbOperation* anOperation);
-
-Parameters: anOperation : The released NdbOperation object.
-Remark: Add a NdbOperation object into the signal idlelist.
-***************************************************************************/
-void
-Ndb::releaseOperation(NdbOperation* anOperation)
-{
- if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
- anOperation->theNdbCon = NULL;
- anOperation->theMagicNumber = 0xFE11D0;
- theImpl->theOpIdleList.release(anOperation);
- } else {
- assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
- anOperation->theNdbCon = NULL;
- anOperation->theMagicNumber = 0xFE11D1;
- theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
- }
-}
-
-/***************************************************************************
-void releaseScanOperation(NdbScanOperation* aScanOperation);
-
-Parameters: aScanOperation : The released NdbScanOperation object.
-Remark: Add a NdbScanOperation object into the signal idlelist.
-***************************************************************************/
-void
-Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
-{
- DBUG_ENTER("Ndb::releaseScanOperation");
- DBUG_PRINT("enter", ("op: 0x%lx", (long) aScanOperation));
-#ifdef ndb_release_check_dup
- { NdbIndexScanOperation* tOp = theScanOpIdleList;
- while (tOp != NULL) {
- assert(tOp != aScanOperation);
- tOp = (NdbIndexScanOperation*)tOp->theNext;
- }
- }
-#endif
- aScanOperation->theNdbCon = NULL;
- aScanOperation->theMagicNumber = 0xFE11D2;
- theImpl->theScanOpIdleList.release(aScanOperation);
- DBUG_VOID_RETURN;
-}
-
-/***************************************************************************
-void releaseRecAttr(NdbRecAttr* aRecAttr);
-
-Parameters: aRecAttr : The released NdbRecAttr object.
-Remark: Add a NdbRecAttr object into the RecAtt idlelist.
-***************************************************************************/
-void
-Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
-{
- aRecAttr->release();
- theImpl->theRecAttrIdleList.release(aRecAttr);
-}
-
-/***************************************************************************
-void releaseSignal(NdbApiSignal* aSignal);
-
-Parameters: aSignal : The released NdbApiSignal object.
-Remark: Add a NdbApiSignal object into the signal idlelist.
-***************************************************************************/
-void
-Ndb::releaseSignal(NdbApiSignal* aSignal)
-{
-#if defined VM_TRACE
- // Check that signal is not null
- assert(aSignal != NULL);
-#if 0
- // Check that signal is not already in list
- NdbApiSignal* tmp = theSignalIdleList;
- while (tmp != NULL){
- assert(tmp != aSignal);
- tmp = tmp->next();
- }
-#endif
-#endif
-#ifdef POORMANSPURIFY
- creleaseSignals++;
-#endif
- theImpl->theSignalIdleList.release(aSignal);
-}
-
-void
-Ndb::releaseSignalsInList(NdbApiSignal** pList){
- NdbApiSignal* tmp;
- while (*pList != NULL){
- tmp = *pList;
- *pList = (*pList)->next();
- releaseSignal(tmp);
- }
-}
-
-void
-Ndb::releaseNdbBlob(NdbBlob* aBlob)
-{
- aBlob->release();
- theImpl->theNdbBlobIdleList.release(aBlob);
-}
-
-/****************************************************************************
-int releaseConnectToNdb(NdbTransaction* aConnectConnection);
-
-Return Value: -1 if error
-Parameters: aConnectConnection : Seized schema connection to DBTC
-Remark: Release and disconnect from DBTC a connection and seize it to theConIdleList.
-*****************************************************************************/
-void
-Ndb::releaseConnectToNdb(NdbTransaction* a_con)
-{
- DBUG_ENTER("Ndb::releaseConnectToNdb");
- NdbApiSignal tSignal(theMyRef);
- int tConPtr;
-
-// I need to close the connection irrespective of whether I
-// manage to reach NDB or not.
-
- if (a_con == NULL)
- DBUG_VOID_RETURN;
-
- Uint32 node_id = a_con->getConnectedNodeId();
- Uint32 conn_seq = a_con->theNodeSequence;
- tSignal.setSignal(GSN_TCRELEASEREQ);
- tSignal.setData((tConPtr = a_con->getTC_ConnectPtr()), 1);
- tSignal.setData(theMyRef, 2);
- tSignal.setData(a_con->ptr2int(), 3);
- a_con->Status(NdbTransaction::DisConnecting);
- a_con->theMagicNumber = 0x37412619;
- int ret_code = sendRecSignal(node_id,
- WAIT_TC_RELEASE,
- &tSignal,
- conn_seq);
- if (ret_code == 0) {
- ;
- } else if (ret_code == -1) {
- TRACE_DEBUG("Time-out when TCRELEASE sent");
- } else if (ret_code == -2) {
- TRACE_DEBUG("Node failed when TCRELEASE sent");
- } else if (ret_code == -3) {
- TRACE_DEBUG("Send failed when TCRELEASE sent");
- } else if (ret_code == -4) {
- TRACE_DEBUG("Send buffer full when TCRELEASE sent");
- } else if (ret_code == -5) {
- TRACE_DEBUG("Node stopping when TCRELEASE sent");
- } else {
- ndbout << "Impossible return from sendRecSignal when TCRELEASE" << endl;
- abort();
- }//if
- releaseNdbCon(a_con);
- DBUG_VOID_RETURN;
-}
-
-template<class T>
-static
-Ndb::Free_list_usage*
-update(Ndb::Free_list_usage* curr,
- Ndb_free_list_t<T> & list,
- const char * name)
-{
- curr->m_name = name;
- curr->m_created = list.m_alloc_cnt;
- curr->m_free = list.m_free_cnt;
- curr->m_sizeof = sizeof(T);
- return curr;
-}
-
-Ndb::Free_list_usage*
-Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
-{
- if (curr == 0)
- {
- return 0;
- }
-
- if(curr->m_name == 0)
- {
- update(curr, theImpl->theConIdleList, "NdbTransaction");
- }
- else if(!strcmp(curr->m_name, "NdbTransaction"))
- {
- update(curr, theImpl->theOpIdleList, "NdbOperation");
- }
- else if(!strcmp(curr->m_name, "NdbOperation"))
- {
- update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
- }
- else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
- {
- update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
- }
- else if(!strcmp(curr->m_name, "NdbIndexOperation"))
- {
- update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
- }
- else if(!strcmp(curr->m_name, "NdbRecAttr"))
- {
- update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
- }
- else if(!strcmp(curr->m_name, "NdbApiSignal"))
- {
- update(curr, theImpl->theLabelList, "NdbLabel");
- }
- else if(!strcmp(curr->m_name, "NdbLabel"))
- {
- update(curr, theImpl->theBranchList, "NdbBranch");
- }
- else if(!strcmp(curr->m_name, "NdbBranch"))
- {
- update(curr, theImpl->theSubroutineList, "NdbSubroutine");
- }
- else if(!strcmp(curr->m_name, "NdbSubroutine"))
- {
- update(curr, theImpl->theCallList, "NdbCall");
- }
- else if(!strcmp(curr->m_name, "NdbCall"))
- {
- update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
- }
- else if(!strcmp(curr->m_name, "NdbBlob"))
- {
- update(curr, theImpl->theScanList, "NdbReceiver");
- }
- else if(!strcmp(curr->m_name, "NdbReceiver"))
- {
- return 0;
- }
- else
- {
- update(curr, theImpl->theConIdleList, "NdbTransaction");
- }
-
- return curr;
-}
-
-#define TI(T) \
- template Ndb::Free_list_usage* \
- update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);\
- template struct Ndb_free_list_t<T>
-
-TI(NdbBlob);
-TI(NdbCall);
-TI(NdbLabel);
-TI(NdbBranch);
-TI(NdbSubroutine);
-TI(NdbApiSignal);
-TI(NdbRecAttr);
-TI(NdbOperation);
-TI(NdbReceiver);
-TI(NdbConnection);
-TI(NdbIndexOperation);
-TI(NdbIndexScanOperation);
diff --git a/storage/ndb/src/ndbapi/ObjectMap.cpp b/storage/ndb/src/ndbapi/ObjectMap.cpp
deleted file mode 100644
index e861472d4fc..00000000000
--- a/storage/ndb/src/ndbapi/ObjectMap.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2003, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "ObjectMap.hpp"
-
-NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz)
-{
- m_size = 0;
- m_firstFree = InvalidId;
- m_map = 0;
- m_mutex = mutex;
- m_expandSize = eSz;
- expand(sz);
-#ifdef DEBUG_OBJECTMAP
- ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz);
-#endif
-}
-
-NdbObjectIdMap::~NdbObjectIdMap()
-{
- free(m_map);
-}
-
-int NdbObjectIdMap::expand(Uint32 incSize)
-{
- NdbMutex_Lock(m_mutex);
- Uint32 newSize = m_size + incSize;
- MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
-
- if (likely(tmp != 0))
- {
- m_map = tmp;
-
- for(Uint32 i = m_size; i < newSize; i++){
- m_map[i].m_next = i + 1;
- }
- m_firstFree = m_size;
- m_map[newSize-1].m_next = InvalidId;
- m_size = newSize;
- }
- else
- {
- NdbMutex_Unlock(m_mutex);
- g_eventLogger.error("NdbObjectIdMap::expand: realloc(%u*%u) failed",
- newSize, sizeof(MapEntry));
- return -1;
- }
- NdbMutex_Unlock(m_mutex);
- return 0;
-}
diff --git a/storage/ndb/src/ndbapi/ObjectMap.hpp b/storage/ndb/src/ndbapi/ObjectMap.hpp
deleted file mode 100644
index eb4bb8e6a81..00000000000
--- a/storage/ndb/src/ndbapi/ObjectMap.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef NDB_OBJECT_ID_MAP_HPP
-#define NDB_OBJECT_ID_MAP_HPP
-
-#include <ndb_global.h>
-//#include <NdbMutex.h>
-#include <NdbOut.hpp>
-
-#include <EventLogger.hpp>
-extern EventLogger g_eventLogger;
-
-//#define DEBUG_OBJECTMAP
-
-/**
- * Global ObjectMap
- */
-class NdbObjectIdMap //: NdbLockable
-{
-public:
- STATIC_CONST( InvalidId = ~(Uint32)0 );
- NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
- ~NdbObjectIdMap();
-
- Uint32 map(void * object);
- void * unmap(Uint32 id, void *object);
-
- void * getObject(Uint32 id);
-private:
- Uint32 m_size;
- Uint32 m_expandSize;
- Uint32 m_firstFree;
- union MapEntry {
- Uint32 m_next;
- void * m_obj;
- } * m_map;
-
- NdbMutex * m_mutex;
- int expand(Uint32 newSize);
-};
-
-inline
-Uint32
-NdbObjectIdMap::map(void * object){
-
- // lock();
-
- if(m_firstFree == InvalidId && expand(m_expandSize))
- return InvalidId;
-
- Uint32 ff = m_firstFree;
- m_firstFree = m_map[ff].m_next;
- m_map[ff].m_obj = object;
-
- // unlock();
-
- DBUG_PRINT("info",("NdbObjectIdMap::map(0x%lx) %u", (long) object, ff<<2));
-
- return ff<<2;
-}
-
-inline
-void *
-NdbObjectIdMap::unmap(Uint32 id, void *object){
-
- Uint32 i = id>>2;
-
- // lock();
- 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 {
- g_eventLogger.error("NdbObjectIdMap::unmap(%u, 0x%x) obj=0x%x",
- id, (long) object, (long) obj);
- DBUG_PRINT("error",("NdbObjectIdMap::unmap(%u, 0x%lx) obj=0x%lx",
- id, (long) object, (long) obj));
- return 0;
- }
-
- // unlock();
-
- DBUG_PRINT("info",("NdbObjectIdMap::unmap(%u) obj=0x%lx", id, (long) obj));
-
- return obj;
- }
- return 0;
-}
-
-inline void *
-NdbObjectIdMap::getObject(Uint32 id){
- // DBUG_PRINT("info",("NdbObjectIdMap::getObject(%u) obj=0x%x", id, m_map[id>>2].m_obj));
- id >>= 2;
- if(id < m_size){
- return m_map[id].m_obj;
- }
- return 0;
-}
-#endif
diff --git a/storage/ndb/src/ndbapi/ScanOperation.txt b/storage/ndb/src/ndbapi/ScanOperation.txt
deleted file mode 100644
index 27e4e8c1755..00000000000
--- a/storage/ndb/src/ndbapi/ScanOperation.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-x) NdbConnection (main)
-m_theFirstCursorOperation -> y
-
-y) NdbScanOperation
-m_transConnection -> x
-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/storage/ndb/src/ndbapi/SignalSender.cpp b/storage/ndb/src/ndbapi/SignalSender.cpp
deleted file mode 100644
index d0ccbeed9a3..00000000000
--- a/storage/ndb/src/ndbapi/SignalSender.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Copyright (c) 2003, 2005-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SignalSender.hpp"
-#include <NdbSleep.h>
-#include <SignalLoggerManager.hpp>
-#include <signaldata/NFCompleteRep.hpp>
-#include <signaldata/NodeFailRep.hpp>
-
-
-SimpleSignal::SimpleSignal(bool dealloc){
- memset(this, 0, sizeof(* this));
- deallocSections = dealloc;
-}
-
-SimpleSignal::~SimpleSignal(){
- if(!deallocSections)
- return;
- if(ptr[0].p != 0) delete []ptr[0].p;
- if(ptr[1].p != 0) delete []ptr[1].p;
- if(ptr[2].p != 0) delete []ptr[2].p;
-}
-
-void
-SimpleSignal::set(class SignalSender& ss,
- Uint8 trace, Uint16 recBlock, Uint16 gsn, Uint32 len){
-
- header.theTrace = trace;
- header.theReceiversBlockNumber = recBlock;
- header.theVerId_signalNumber = gsn;
- header.theLength = len;
- header.theSendersBlockRef = refToBlock(ss.getOwnRef());
-}
-
-void
-SimpleSignal::print(FILE * out){
- fprintf(out, "---- Signal ----------------\n");
- SignalLoggerManager::printSignalHeader(out, header, 0, 0, false);
- SignalLoggerManager::printSignalData(out, header, theData);
- for(Uint32 i = 0; i<header.m_noOfSections; i++){
- Uint32 len = ptr[i].sz;
- fprintf(out, " --- Section %d size=%d ---\n", i, len);
- Uint32 * signalData = ptr[i].p;
- while(len >= 7){
- fprintf(out,
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
- signalData[0], signalData[1], signalData[2], signalData[3],
- signalData[4], signalData[5], signalData[6]);
- len -= 7;
- signalData += 7;
- }
- if(len > 0){
- fprintf(out, " H\'%.8x", signalData[0]);
- for(Uint32 i = 1; i<len; i++)
- fprintf(out, " H\'%.8x", signalData[i]);
- fprintf(out, "\n");
- }
- }
-}
-
-SignalSender::SignalSender(TransporterFacade *facade)
- : m_lock(0)
-{
- m_cond = NdbCondition_Create();
- theFacade = facade;
- lock();
- m_blockNo = theFacade->open(this, execSignal, execNodeStatus);
- unlock();
- assert(m_blockNo > 0);
-}
-
-SignalSender::~SignalSender(){
- int i;
- if (m_lock)
- unlock();
- theFacade->close(m_blockNo,0);
- // free these _after_ closing theFacade to ensure that
- // we delete all signals
- for (i= m_jobBuffer.size()-1; i>= 0; i--)
- delete m_jobBuffer[i];
- for (i= m_usedBuffer.size()-1; i>= 0; i--)
- delete m_usedBuffer[i];
- NdbCondition_Destroy(m_cond);
-}
-
-int SignalSender::lock()
-{
- if (NdbMutex_Lock(theFacade->theMutexPtr))
- return -1;
- m_lock= 1;
- return 0;
-}
-
-int SignalSender::unlock()
-{
- if (NdbMutex_Unlock(theFacade->theMutexPtr))
- return -1;
- m_lock= 0;
- return 0;
-}
-
-Uint32
-SignalSender::getOwnRef() const {
- return numberToRef(m_blockNo, theFacade->ownId());
-}
-
-Uint32
-SignalSender::getAliveNode() const{
- return theFacade->get_an_alive_node();
-}
-
-const ClusterMgr::Node &
-SignalSender::getNodeInfo(Uint16 nodeId) const {
- return theFacade->theClusterMgr->getNodeInfo(nodeId);
-}
-
-Uint32
-SignalSender::getNoOfConnectedNodes() const {
- return theFacade->theClusterMgr->getNoOfConnectedNodes();
-}
-
-template<class T>
-SimpleSignal *
-SignalSender::waitFor(Uint32 timeOutMillis, T & t)
-{
- SimpleSignal * s = t.check(m_jobBuffer);
- if(s != 0){
- if (m_usedBuffer.push_back(s))
- {
- return 0;
- }
- return s;
- }
-
- NDB_TICKS now = NdbTick_CurrentMillisecond();
- NDB_TICKS stop = now + timeOutMillis;
- Uint32 wait = (timeOutMillis == 0 ? 10 : timeOutMillis);
- do {
- NdbCondition_WaitTimeout(m_cond,
- theFacade->theMutexPtr,
- wait);
-
-
- SimpleSignal * s = t.check(m_jobBuffer);
- if(s != 0){
- if (m_usedBuffer.push_back(s))
- {
- return 0;
- }
- return s;
- }
-
- now = NdbTick_CurrentMillisecond();
- wait = (timeOutMillis == 0 ? 10 : stop - now);
- } while(stop > now || timeOutMillis == 0);
-
- return 0;
-}
-
-class WaitForAny {
-public:
- WaitForAny() {}
- SimpleSignal * check(Vector<SimpleSignal*> & m_jobBuffer){
- if(m_jobBuffer.size() > 0){
- SimpleSignal * s = m_jobBuffer[0];
- m_jobBuffer.erase(0);
- return s;
- }
- return 0;
- }
-};
-
-SimpleSignal *
-SignalSender::waitFor(Uint32 timeOutMillis){
-
- WaitForAny w;
- return waitFor(timeOutMillis, w);
-}
-
-class WaitForNode {
-public:
- WaitForNode() {}
- Uint32 m_nodeId;
- SimpleSignal * check(Vector<SimpleSignal*> & m_jobBuffer){
- Uint32 len = m_jobBuffer.size();
- for(Uint32 i = 0; i<len; i++){
- if(refToNode(m_jobBuffer[i]->header.theSendersBlockRef) == m_nodeId){
- SimpleSignal * s = m_jobBuffer[i];
- m_jobBuffer.erase(i);
- return s;
- }
- }
- return 0;
- }
-};
-
-SimpleSignal *
-SignalSender::waitFor(Uint16 nodeId, Uint32 timeOutMillis){
-
- WaitForNode w;
- w.m_nodeId = nodeId;
- return waitFor(timeOutMillis, w);
-}
-
-#include <NdbApiSignal.hpp>
-
-void
-SignalSender::execSignal(void* signalSender,
- NdbApiSignal* signal,
- class LinearSectionPtr ptr[3]){
- SimpleSignal * s = new SimpleSignal(true);
- s->header = * signal;
- memcpy(&s->theData[0], signal->getDataPtr(), 4 * s->header.theLength);
- for(Uint32 i = 0; i<s->header.m_noOfSections; i++){
- s->ptr[i].p = new Uint32[ptr[i].sz];
- s->ptr[i].sz = ptr[i].sz;
- memcpy(s->ptr[i].p, ptr[i].p, 4 * ptr[i].sz);
- }
- SignalSender * ss = (SignalSender*)signalSender;
- ss->m_jobBuffer.push_back(s);
- NdbCondition_Signal(ss->m_cond);
-}
-
-void
-SignalSender::execNodeStatus(void* signalSender,
- Uint32 nodeId,
- bool alive,
- bool nfCompleted){
- if (alive) {
- // node connected
- return;
- }
-
- SimpleSignal * s = new SimpleSignal(true);
- SignalSender * ss = (SignalSender*)signalSender;
-
- // node disconnected
- if(nfCompleted)
- {
- // node shutdown complete
- s->header.theVerId_signalNumber = GSN_NF_COMPLETEREP;
- NFCompleteRep *rep = (NFCompleteRep *)s->getDataPtrSend();
- rep->blockNo = 0;
- rep->nodeId = 0;
- rep->failedNodeId = nodeId;
- rep->unused = 0;
- rep->from = 0;
- }
- else
- {
- // node failure
- s->header.theVerId_signalNumber = GSN_NODE_FAILREP;
- NodeFailRep *rep = (NodeFailRep *)s->getDataPtrSend();
- rep->failNo = 0;
- rep->masterNodeId = 0;
- rep->noOfNodes = 1;
- NodeBitmask::clear(rep->theNodes);
- NodeBitmask::set(rep->theNodes,nodeId);
- }
-
- ss->m_jobBuffer.push_back(s);
- NdbCondition_Signal(ss->m_cond);
-}
-
-#if __SUNPRO_CC != 0x560
-template SimpleSignal* SignalSender::waitFor<WaitForNode>(unsigned, WaitForNode&);
-template SimpleSignal* SignalSender::waitFor<WaitForAny>(unsigned, WaitForAny&);
-#endif
-template class Vector<SimpleSignal*>;
-
diff --git a/storage/ndb/src/ndbapi/SignalSender.hpp b/storage/ndb/src/ndbapi/SignalSender.hpp
deleted file mode 100644
index fa92c3b789d..00000000000
--- a/storage/ndb/src/ndbapi/SignalSender.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Copyright (c) 2003, 2005, 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SIGNAL_SENDER_HPP
-#define SIGNAL_SENDER_HPP
-
-#include <ndb_global.h>
-#include "TransporterFacade.hpp"
-#include <Vector.hpp>
-
-struct SimpleSignal {
-public:
- SimpleSignal(bool dealloc = false);
- ~SimpleSignal();
-
- void set(class SignalSender&,
- Uint8 trace, Uint16 recBlock, Uint16 gsn, Uint32 len);
-
- struct SignalHeader header;
- Uint32 theData[25];
- LinearSectionPtr ptr[3];
-
- int readSignalNumber() const {return header.theVerId_signalNumber; }
- Uint32 *getDataPtrSend() { return theData; }
- const Uint32 *getDataPtr() const { return theData; }
-
- void print(FILE * out = stdout);
-private:
- bool deallocSections;
-};
-
-class SignalSender {
-public:
- SignalSender(TransporterFacade *facade);
- virtual ~SignalSender();
-
- int lock();
- int unlock();
-
- Uint32 getOwnRef() const;
- Uint32 getAliveNode() const;
- const ClusterMgr::Node &getNodeInfo(Uint16 nodeId) const;
- Uint32 getNoOfConnectedNodes() const;
-
- SendStatus sendSignal(Uint16 nodeId, const SimpleSignal *);
-
- SimpleSignal * waitFor(Uint32 timeOutMillis = 0);
- SimpleSignal * waitFor(Uint16 nodeId, Uint32 timeOutMillis = 0);
- SimpleSignal * waitFor(Uint16 nodeId, Uint16 gsn, Uint32 timeOutMillis = 0);
-private:
- int m_blockNo;
- TransporterFacade * theFacade;
-
- static void execSignal(void* signalSender,
- NdbApiSignal* signal,
- class LinearSectionPtr ptr[3]);
-
- static void execNodeStatus(void* signalSender, Uint32 nodeId,
- bool alive, bool nfCompleted);
-
- int m_lock;
- struct NdbCondition * m_cond;
- Vector<SimpleSignal *> m_jobBuffer;
- Vector<SimpleSignal *> m_usedBuffer;
-
- template<class T>
- SimpleSignal * waitFor(Uint32 timeOutMillis, T & t);
-};
-
-#endif
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp
deleted file mode 100644
index 257a17d9362..00000000000
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp
+++ /dev/null
@@ -1,1538 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-#include <ndb_limits.h>
-#include "TransporterFacade.hpp"
-#include "ClusterMgr.hpp"
-#include <IPCConfig.hpp>
-#include <TransporterCallback.hpp>
-#include <TransporterRegistry.hpp>
-#include "NdbApiSignal.hpp"
-#include <NdbOut.hpp>
-#include <NdbEnv.h>
-#include <NdbSleep.h>
-
-#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>
-#include <kernel/ndb_limits.h>
-#include <signaldata/AlterTable.hpp>
-#include <signaldata/SumaImpl.hpp>
-
-//#define REPORT_TRANSPORTER
-//#define API_TRACE;
-
-static int numberToIndex(int number)
-{
- return number - MIN_API_BLOCK_NO;
-}
-
-static int indexToNumber(int index)
-{
- return index + MIN_API_BLOCK_NO;
-}
-
-#if defined DEBUG_TRANSPORTER
-#define TRP_DEBUG(t) ndbout << __FILE__ << ":" << __LINE__ << ":" << t << endl;
-#else
-#define TRP_DEBUG(t)
-#endif
-
-/*****************************************************************************
- * Call back functions
- *****************************************************************************/
-
-void
-reportError(void * callbackObj, NodeId nodeId,
- TransporterError errorCode, const char *info)
-{
-#ifdef REPORT_TRANSPORTER
- ndbout_c("REPORT_TRANSP: reportError (nodeId=%d, errorCode=%d) %s",
- (int)nodeId, (int)errorCode, info ? info : "");
-#endif
- if(errorCode & TE_DO_DISCONNECT) {
- ndbout_c("reportError (%d, %d) %s", (int)nodeId, (int)errorCode,
- info ? info : "");
- ((TransporterFacade*)(callbackObj))->doDisconnect(nodeId);
- }
-}
-
-/**
- * Report average send length in bytes (4096 last sends)
- */
-void
-reportSendLen(void * callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
-#ifdef REPORT_TRANSPORTER
- ndbout_c("REPORT_TRANSP: reportSendLen (nodeId=%d, bytes/count=%d)",
- (int)nodeId, (Uint32)(bytes/count));
-#endif
- (void)nodeId;
- (void)count;
- (void)bytes;
-}
-
-/**
- * Report average receive length in bytes (4096 last receives)
- */
-void
-reportReceiveLen(void * callbackObj,
- NodeId nodeId, Uint32 count, Uint64 bytes){
-#ifdef REPORT_TRANSPORTER
- ndbout_c("REPORT_TRANSP: reportReceiveLen (nodeId=%d, bytes/count=%d)",
- (int)nodeId, (Uint32)(bytes/count));
-#endif
- (void)nodeId;
- (void)count;
- (void)bytes;
-}
-
-/**
- * Report connection established
- */
-void
-reportConnect(void * callbackObj, NodeId nodeId){
-#ifdef REPORT_TRANSPORTER
- ndbout_c("REPORT_TRANSP: API reportConnect (nodeId=%d)", (int)nodeId);
-#endif
- ((TransporterFacade*)(callbackObj))->reportConnected(nodeId);
-}
-
-/**
- * Report connection broken
- */
-void
-reportDisconnect(void * callbackObj, NodeId nodeId, Uint32 error){
-#ifdef REPORT_TRANSPORTER
- ndbout_c("REPORT_TRANSP: API reportDisconnect (nodeId=%d)", (int)nodeId);
-#endif
- ((TransporterFacade*)(callbackObj))->reportDisconnected(nodeId);
-}
-
-void
-transporter_recv_from(void * callbackObj, NodeId nodeId){
- ((TransporterFacade*)(callbackObj))->hb_received(nodeId);
-}
-
-/****************************************************************************
- *
- *****************************************************************************/
-
-/**
- * Report connection broken
- */
-int checkJobBuffer() {
- return 0;
-}
-
-#ifdef API_TRACE
-static const char * API_SIGNAL_LOG = "API_SIGNAL_LOG";
-static const char * apiSignalLog = 0;
-static SignalLoggerManager signalLogger;
-static
-inline
-bool
-setSignalLog(){
- signalLogger.flushSignalLog();
-
- const char * tmp = NdbEnv_GetEnv(API_SIGNAL_LOG, (char *)0, 0);
- if(tmp != 0 && apiSignalLog != 0 && strcmp(tmp,apiSignalLog) == 0){
- return true;
- } else if(tmp == 0 && apiSignalLog == 0){
- return false;
- } else if(tmp == 0 && apiSignalLog != 0){
- signalLogger.setOutputStream(0);
- apiSignalLog = tmp;
- return false;
- } else if(tmp !=0){
- if (strcmp(tmp, "-") == 0)
- signalLogger.setOutputStream(stdout);
-#ifndef DBUG_OFF
- else if (strcmp(tmp, "+") == 0)
- signalLogger.setOutputStream(DBUG_FILE);
-#endif
- else
- signalLogger.setOutputStream(fopen(tmp, "w"));
- apiSignalLog = tmp;
- return true;
- }
- return false;
-}
-#ifdef TRACE_APIREGREQ
-#define TRACE_GSN(gsn) true
-#else
-#define TRACE_GSN(gsn) (gsn != GSN_API_REGREQ && gsn != GSN_API_REGCONF)
-#endif
-#endif
-
-/**
- * The execute function : Handle received signal
- */
-void
-execute(void * callbackObj, SignalHeader * const header,
- Uint8 prio, Uint32 * const theData,
- LinearSectionPtr ptr[3]){
-
- TransporterFacade * theFacade = (TransporterFacade*)callbackObj;
- TransporterFacade::ThreadData::Object_Execute oe;
- Uint32 tRecBlockNo = header->theReceiversBlockNumber;
-
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){
- signalLogger.executeSignal(* header,
- prio,
- theData,
- theFacade->ownId(),
- ptr, header->m_noOfSections);
- signalLogger.flushSignalLog();
- }
-#endif
-
- if (tRecBlockNo >= MIN_API_BLOCK_NO) {
- oe = theFacade->m_threads.get(tRecBlockNo);
- if (oe.m_object != 0 && oe.m_executeFunction != 0) {
- /**
- * Handle received signal immediately to avoid any unnecessary
- * copying of data, allocation of memory and other things. Copying
- * of data could be interesting to support several priority levels
- * and to support a special memory structure when executing the
- * signals. Neither of those are interesting when receiving data
- * in the NDBAPI. The NDBAPI will thus read signal data directly as
- * it was written by the sender (SCI sender is other node, Shared
- * memory sender is other process and TCP/IP sender is the OS that
- * writes the TCP/IP message into a message buffer).
- */
- NdbApiSignal tmpSignal(*header);
- NdbApiSignal * tSignal = &tmpSignal;
- tSignal->setDataPtr(theData);
- (* oe.m_executeFunction) (oe.m_object, tSignal, ptr);
- }//if
- } else if (tRecBlockNo == API_PACKED) {
- /**
- * Block number == 2047 is used to signal a signal that consists of
- * multiple instances of the same signal. This is an effort to
- * package the signals so as to avoid unnecessary communication
- * overhead since TCP/IP has a great performance impact.
- */
- Uint32 Tlength = header->theLength;
- Uint32 Tsent = 0;
- /**
- * Since it contains at least two data packets we will first
- * copy the signal data to safe place.
- */
- while (Tsent < Tlength) {
- Uint32 Theader = theData[Tsent];
- Tsent++;
- Uint32 TpacketLen = (Theader & 0x1F) + 3;
- tRecBlockNo = Theader >> 16;
- if (TpacketLen <= 25) {
- if ((TpacketLen + Tsent) <= Tlength) {
- /**
- * Set the data length of the signal and the receivers block
- * reference and then call the API.
- */
- header->theLength = TpacketLen;
- header->theReceiversBlockNumber = tRecBlockNo;
- Uint32* tDataPtr = &theData[Tsent];
- Tsent += TpacketLen;
- if (tRecBlockNo >= MIN_API_BLOCK_NO) {
- oe = theFacade->m_threads.get(tRecBlockNo);
- if(oe.m_object != 0 && oe.m_executeFunction != 0){
- NdbApiSignal tmpSignal(*header);
- NdbApiSignal * tSignal = &tmpSignal;
- tSignal->setDataPtr(tDataPtr);
- (*oe.m_executeFunction)(oe.m_object, tSignal, 0);
- }
- }
- }
- }
- }
- return;
- } else if (tRecBlockNo == API_CLUSTERMGR) {
- /**
- * The signal was aimed for the Cluster Manager.
- * We handle it immediately here.
- */
- ClusterMgr * clusterMgr = theFacade->theClusterMgr;
- const Uint32 gsn = header->theVerId_signalNumber;
-
- switch (gsn){
- case GSN_API_REGREQ:
- clusterMgr->execAPI_REGREQ(theData);
- break;
-
- case GSN_API_REGCONF:
- clusterMgr->execAPI_REGCONF(theData);
- break;
-
- case GSN_API_REGREF:
- clusterMgr->execAPI_REGREF(theData);
- break;
-
- case GSN_NODE_FAILREP:
- clusterMgr->execNODE_FAILREP(theData);
- break;
-
- case GSN_NF_COMPLETEREP:
- clusterMgr->execNF_COMPLETEREP(theData);
- break;
-
- case GSN_ARBIT_STARTREQ:
- if (theFacade->theArbitMgr != NULL)
- theFacade->theArbitMgr->doStart(theData);
- break;
-
- case GSN_ARBIT_CHOOSEREQ:
- if (theFacade->theArbitMgr != NULL)
- theFacade->theArbitMgr->doChoose(theData);
- break;
-
- case GSN_ARBIT_STOPORD:
- if(theFacade->theArbitMgr != NULL)
- theFacade->theArbitMgr->doStop(theData);
- break;
-
- case GSN_ALTER_TABLE_REP:
- {
- const AlterTableRep* rep = (const AlterTableRep*)theData;
- theFacade->m_globalDictCache.lock();
- theFacade->m_globalDictCache.
- alter_table_rep((const char*)ptr[0].p,
- rep->tableId,
- rep->tableVersion,
- rep->changeType == AlterTableRep::CT_ALTERED);
- theFacade->m_globalDictCache.unlock();
- break;
- }
- case GSN_SUB_GCP_COMPLETE_REP:
- {
- /**
- * Report
- */
- NdbApiSignal tSignal(* header);
- tSignal.setDataPtr(theData);
- theFacade->for_each(&tSignal, ptr);
-
- /**
- * Reply
- */
- {
- Uint32* send= tSignal.getDataPtrSend();
- memcpy(send, theData, tSignal.getLength() << 2);
- ((SubGcpCompleteAck*)send)->rep.senderRef =
- numberToRef(API_CLUSTERMGR, theFacade->theOwnId);
- Uint32 ref= header->theSendersBlockRef;
- Uint32 aNodeId= refToNode(ref);
- tSignal.theReceiversBlockNumber= refToBlock(ref);
- tSignal.theVerId_signalNumber= GSN_SUB_GCP_COMPLETE_ACK;
- theFacade->sendSignalUnCond(&tSignal, aNodeId);
- }
- break;
- }
- default:
- break;
-
- }
- return;
- } else {
- ; // Ignore all other block numbers.
- if(header->theVerId_signalNumber!=3) {
- TRP_DEBUG( "TransporterFacade received signal to unknown block no." );
- ndbout << "BLOCK NO: " << tRecBlockNo << " sig "
- << header->theVerId_signalNumber << endl;
- abort();
- }
- }
-}
-
-// These symbols are needed, but not used in the API
-void
-SignalLoggerManager::printSegmentedSection(FILE *, const SignalHeader &,
- const SegmentedSectionPtr ptr[3],
- unsigned i){
- abort();
-}
-
-void
-copy(Uint32 * & insertPtr,
- class SectionSegmentPool & thePool, const SegmentedSectionPtr & _ptr){
- abort();
-}
-
-/**
- * Note that this function need no locking since its
- * only called from the constructor of Ndb (the NdbObject)
- *
- * Which is protected by a mutex
- */
-
-int
-TransporterFacade::start_instance(int nodeId,
- const ndb_mgm_configuration* props)
-{
- if (! init(nodeId, props)) {
- return -1;
- }
-
- /**
- * Install signal handler for SIGPIPE
- *
- * This due to the fact that a socket connection might have
- * been closed in between a select and a corresponding send
- */
-#if !defined NDB_WIN32
- signal(SIGPIPE, SIG_IGN);
-#endif
-
- return 0;
-}
-
-/**
- * Note that this function need no locking since its
- * only called from the destructor of Ndb (the NdbObject)
- *
- * Which is protected by a mutex
- */
-void
-TransporterFacade::stop_instance(){
- DBUG_ENTER("TransporterFacade::stop_instance");
- doStop();
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::doStop(){
- DBUG_ENTER("TransporterFacade::doStop");
- /**
- * First stop the ClusterMgr because it needs to send one more signal
- * and also uses theFacadeInstance to lock/unlock theMutexPtr
- */
- if (theClusterMgr != NULL) theClusterMgr->doStop();
- if (theArbitMgr != NULL) theArbitMgr->doStop(NULL);
-
- /**
- * Now stop the send and receive threads
- */
- void *status;
- theStopReceive = 1;
- if (theReceiveThread) {
- NdbThread_WaitFor(theReceiveThread, &status);
- NdbThread_Destroy(&theReceiveThread);
- }
- if (theSendThread) {
- NdbThread_WaitFor(theSendThread, &status);
- NdbThread_Destroy(&theSendThread);
- }
- DBUG_VOID_RETURN;
-}
-
-extern "C"
-void*
-runSendRequest_C(void * me)
-{
- ((TransporterFacade*) me)->threadMainSend();
- return 0;
-}
-
-void TransporterFacade::threadMainSend(void)
-{
- theTransporterRegistry->startSending();
- if (!theTransporterRegistry->start_clients()){
- ndbout_c("Unable to start theTransporterRegistry->start_clients");
- exit(0);
- }
-
- m_socket_server.startServer();
-
- while(!theStopReceive) {
- NdbSleep_MilliSleep(10);
- NdbMutex_Lock(theMutexPtr);
- if (sendPerformedLastInterval == 0) {
- theTransporterRegistry->performSend();
- }
- sendPerformedLastInterval = 0;
- NdbMutex_Unlock(theMutexPtr);
- }
- theTransporterRegistry->stopSending();
-
- m_socket_server.stopServer();
- m_socket_server.stopSessions(true);
-
- theTransporterRegistry->stop_clients();
-}
-
-extern "C"
-void*
-runReceiveResponse_C(void * me)
-{
- ((TransporterFacade*) me)->threadMainReceive();
- return 0;
-}
-
-/*
- The receiver thread is changed to only wake up once every 10 milliseconds
- to poll. It will first check that nobody owns the poll "right" before
- polling. This means that methods using the receiveResponse and
- sendRecSignal will have a slightly longer response time if they are
- executed without any parallel key lookups. Currently also scans are
- affected but this is to be fixed.
-*/
-void TransporterFacade::threadMainReceive(void)
-{
- theTransporterRegistry->startReceiving();
-#ifdef NDB_SHM_TRANSPORTER
- NdbThread_set_shm_sigmask(TRUE);
-#endif
- NdbMutex_Lock(theMutexPtr);
- theTransporterRegistry->update_connections();
- NdbMutex_Unlock(theMutexPtr);
- while(!theStopReceive) {
- for(int i = 0; i<10; i++){
- NdbSleep_MilliSleep(10);
- NdbMutex_Lock(theMutexPtr);
- if (poll_owner == NULL) {
- const int res = theTransporterRegistry->pollReceive(0);
- if(res > 0)
- theTransporterRegistry->performReceive();
- }
- NdbMutex_Unlock(theMutexPtr);
- }
- NdbMutex_Lock(theMutexPtr);
- theTransporterRegistry->update_connections();
- NdbMutex_Unlock(theMutexPtr);
- }//while
- theTransporterRegistry->stopReceiving();
-}
-/*
- This method is called by worker thread that owns the poll "rights".
- It waits for events and if something arrives it takes care of it
- and returns to caller. It will quickly come back here if not all
- data was received for the worker thread.
-*/
-void TransporterFacade::external_poll(Uint32 wait_time)
-{
- NdbMutex_Unlock(theMutexPtr);
- const int res = theTransporterRegistry->pollReceive(wait_time);
- NdbMutex_Lock(theMutexPtr);
- if (res > 0) {
- theTransporterRegistry->performReceive();
- }
-}
-
-/*
- This Ndb object didn't get hold of the poll "right" and will wait on a
- conditional mutex wait instead. It is put into the conditional wait
- queue so that it is accessible to take over the poll "right" if needed.
- The method gets a free entry in the free list and puts it first in the
- doubly linked list. Finally it assigns the ndb object reference to the
- entry.
-*/
-Uint32 TransporterFacade::put_in_cond_wait_queue(NdbWaiter *aWaiter)
-{
- /*
- Get first free entry
- */
- Uint32 index = first_free_cond_wait;
- assert(index < MAX_NO_THREADS);
- first_free_cond_wait = cond_wait_array[index].next_cond_wait;
-
- /*
- Put in doubly linked list
- */
- cond_wait_array[index].next_cond_wait = MAX_NO_THREADS;
- cond_wait_array[index].prev_cond_wait = last_in_cond_wait;
- if (last_in_cond_wait == MAX_NO_THREADS) {
- first_in_cond_wait = index;
- } else
- cond_wait_array[last_in_cond_wait].next_cond_wait = index;
- last_in_cond_wait = index;
-
- cond_wait_array[index].cond_wait_object = aWaiter;
- aWaiter->set_cond_wait_index(index);
- return index;
-}
-
-/*
- Somebody is about to signal the thread to wake it up, it could also
- be that it woke up on a timeout and found himself still in the list.
- Removes the entry from the doubly linked list.
- Inserts the entry into the free list.
- NULLifies the ndb object reference entry and sets the index in the
- Ndb object to NIL (=MAX_NO_THREADS)
-*/
-void TransporterFacade::remove_from_cond_wait_queue(NdbWaiter *aWaiter)
-{
- Uint32 index = aWaiter->get_cond_wait_index();
- assert(index < MAX_NO_THREADS &&
- cond_wait_array[index].cond_wait_object == aWaiter);
- /*
- Remove from doubly linked list
- */
- Uint32 prev_elem, next_elem;
- prev_elem = cond_wait_array[index].prev_cond_wait;
- next_elem = cond_wait_array[index].next_cond_wait;
- if (prev_elem != MAX_NO_THREADS)
- cond_wait_array[prev_elem].next_cond_wait = next_elem;
- else
- first_in_cond_wait = next_elem;
- if (next_elem != MAX_NO_THREADS)
- cond_wait_array[next_elem].prev_cond_wait = prev_elem;
- else
- last_in_cond_wait = prev_elem;
- /*
- Insert into free list
- */
- cond_wait_array[index].next_cond_wait = first_free_cond_wait;
- cond_wait_array[index].prev_cond_wait = MAX_NO_THREADS;
- first_free_cond_wait = index;
-
- cond_wait_array[index].cond_wait_object = NULL;
- aWaiter->set_cond_wait_index(MAX_NO_THREADS);
-}
-
-/*
- Get the latest Ndb object from the conditional wait queue
- and also remove it from the list.
-*/
-NdbWaiter* TransporterFacade::rem_last_from_cond_wait_queue()
-{
- NdbWaiter *tWaiter;
- Uint32 index = last_in_cond_wait;
- if (last_in_cond_wait == MAX_NO_THREADS)
- return NULL;
- tWaiter = cond_wait_array[index].cond_wait_object;
- remove_from_cond_wait_queue(tWaiter);
- return tWaiter;
-}
-
-void TransporterFacade::init_cond_wait_queue()
-{
- Uint32 i;
- /*
- Initialise the doubly linked list as empty
- */
- first_in_cond_wait = MAX_NO_THREADS;
- last_in_cond_wait = MAX_NO_THREADS;
- /*
- Initialise free list
- */
- first_free_cond_wait = 0;
- for (i = 0; i < MAX_NO_THREADS; i++) {
- cond_wait_array[i].cond_wait_object = NULL;
- cond_wait_array[i].next_cond_wait = i+1;
- cond_wait_array[i].prev_cond_wait = MAX_NO_THREADS;
- }
-}
-
-TransporterFacade::TransporterFacade() :
- theTransporterRegistry(0),
- theStopReceive(0),
- theSendThread(NULL),
- theReceiveThread(NULL),
- m_fragmented_signal_id(0)
-{
- DBUG_ENTER("TransporterFacade::TransporterFacade");
- init_cond_wait_queue();
- poll_owner = NULL;
- theOwnId = 0;
- theMutexPtr = NdbMutex_Create();
- sendPerformedLastInterval = 0;
-
- checkCounter = 4;
- currentSendLimit = 1;
- theClusterMgr = NULL;
- theArbitMgr = NULL;
- theStartNodeId = 1;
- m_scan_batch_size= MAX_SCAN_BATCH_SIZE;
- m_batch_byte_size= SCAN_BATCH_SIZE;
- m_batch_size= DEF_BATCH_SIZE;
- m_max_trans_id = 0;
-
- theClusterMgr = new ClusterMgr(* this);
-
-#ifdef API_TRACE
- apiSignalLog = 0;
-#endif
- DBUG_VOID_RETURN;
-}
-
-bool
-TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props)
-{
- DBUG_ENTER("TransporterFacade::init");
-
- theOwnId = nodeId;
- theTransporterRegistry = new TransporterRegistry(this);
-
- const int res = IPCConfig::configureTransporters(nodeId,
- * props,
- * theTransporterRegistry);
- if(res <= 0){
- TRP_DEBUG( "configureTransporters returned 0 or less" );
- DBUG_RETURN(false);
- }
-
- ndb_mgm_configuration_iterator iter(* props, CFG_SECTION_NODE);
- iter.first();
- theClusterMgr->init(iter);
-
- iter.first();
- if(iter.find(CFG_NODE_ID, nodeId)){
- TRP_DEBUG( "Node info missing from config." );
- DBUG_RETURN(false);
- }
-
- Uint32 rank = 0;
- if(!iter.get(CFG_NODE_ARBIT_RANK, &rank) && rank>0){
- theArbitMgr = new ArbitMgr(* this);
- theArbitMgr->setRank(rank);
- Uint32 delay = 0;
- iter.get(CFG_NODE_ARBIT_DELAY, &delay);
- theArbitMgr->setDelay(delay);
- }
- Uint32 scan_batch_size= 0;
- if (!iter.get(CFG_MAX_SCAN_BATCH_SIZE, &scan_batch_size)) {
- m_scan_batch_size= scan_batch_size;
- }
- Uint32 batch_byte_size= 0;
- if (!iter.get(CFG_BATCH_BYTE_SIZE, &batch_byte_size)) {
- m_batch_byte_size= batch_byte_size;
- }
- Uint32 batch_size= 0;
- if (!iter.get(CFG_BATCH_SIZE, &batch_size)) {
- m_batch_size= batch_size;
- }
-
- Uint32 timeout = 120000;
- iter.first();
- for (iter.first(); iter.valid(); iter.next())
- {
- Uint32 tmp1 = 0, tmp2 = 0;
- iter.get(CFG_DB_TRANSACTION_CHECK_INTERVAL, &tmp1);
- iter.get(CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &tmp2);
- tmp1 += tmp2;
- if (tmp1 > timeout)
- timeout = tmp1;
- }
- m_waitfor_timeout = timeout;
-
- if (!theTransporterRegistry->start_service(m_socket_server)){
- ndbout_c("Unable to start theTransporterRegistry->start_service");
- DBUG_RETURN(false);
- }
-
- 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
-
- DBUG_RETURN(true);
-}
-
-void
-TransporterFacade::for_each(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
-{
- DBUG_ENTER("TransporterFacade::for_each");
- Uint32 sz = m_threads.m_statusNext.size();
- TransporterFacade::ThreadData::Object_Execute oe;
- for (Uint32 i = 0; i < sz ; i ++)
- {
- oe = m_threads.m_objectExecute[i];
- if (m_threads.getInUse(i))
- {
- (* oe.m_executeFunction) (oe.m_object, aSignal, ptr);
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::connected()
-{
- DBUG_ENTER("TransporterFacade::connected");
- Uint32 sz = m_threads.m_statusNext.size();
- for (Uint32 i = 0; i < sz ; i ++) {
- if (m_threads.getInUse(i)){
- void * obj = m_threads.m_objectExecute[i].m_object;
- NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
- (*RegPC) (obj, numberToRef(indexToNumber(i), theOwnId), true, true);
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::ReportNodeDead(NodeId tNodeId)
-{
- DBUG_ENTER("TransporterFacade::ReportNodeDead");
- DBUG_PRINT("enter",("nodeid= %d", tNodeId));
- /**
- * When a node fails we must report this to each Ndb object.
- * The function that is used for communicating node failures is called.
- * This is to ensure that the Ndb objects do not think their connections
- * are correct after a failure followed by a restart.
- * After the restart the node is up again and the Ndb object
- * might not have noticed the failure.
- */
- Uint32 sz = m_threads.m_statusNext.size();
- for (Uint32 i = 0; i < sz ; i ++) {
- if (m_threads.getInUse(i)){
- void * obj = m_threads.m_objectExecute[i].m_object;
- NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
- (*RegPC) (obj, tNodeId, false, false);
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::ReportNodeFailureComplete(NodeId tNodeId)
-{
- /**
- * When a node fails we must report this to each Ndb object.
- * The function that is used for communicating node failures is called.
- * This is to ensure that the Ndb objects do not think their connections
- * are correct after a failure followed by a restart.
- * After the restart the node is up again and the Ndb object
- * might not have noticed the failure.
- */
-
- DBUG_ENTER("TransporterFacade::ReportNodeFailureComplete");
- DBUG_PRINT("enter",("nodeid= %d", tNodeId));
- Uint32 sz = m_threads.m_statusNext.size();
- for (Uint32 i = 0; i < sz ; i ++) {
- if (m_threads.getInUse(i)){
- void * obj = m_threads.m_objectExecute[i].m_object;
- NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
- (*RegPC) (obj, tNodeId, false, true);
- }
- }
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::ReportNodeAlive(NodeId tNodeId)
-{
- /**
- * When a node fails we must report this to each Ndb object.
- * The function that is used for communicating node failures is called.
- * This is to ensure that the Ndb objects do not think there connections
- * are correct after a failure
- * followed by a restart.
- * After the restart the node is up again and the Ndb object
- * might not have noticed the failure.
- */
- Uint32 sz = m_threads.m_statusNext.size();
- for (Uint32 i = 0; i < sz ; i ++) {
- if (m_threads.getInUse(i)){
- void * obj = m_threads.m_objectExecute[i].m_object;
- NodeStatusFunction RegPC = m_threads.m_statusFunction[i];
- (*RegPC) (obj, tNodeId, true, false);
- }
- }
-}
-
-int
-TransporterFacade::close(BlockNumber blockNumber, Uint64 trans_id)
-{
- NdbMutex_Lock(theMutexPtr);
- Uint32 low_bits = (Uint32)trans_id;
- m_max_trans_id = m_max_trans_id > low_bits ? m_max_trans_id : low_bits;
- close_local(blockNumber);
- NdbMutex_Unlock(theMutexPtr);
- return 0;
-}
-
-int
-TransporterFacade::close_local(BlockNumber blockNumber){
- m_threads.close(blockNumber);
- return 0;
-}
-
-int
-TransporterFacade::open(void* objRef,
- ExecuteFunction fun,
- NodeStatusFunction statusFun)
-{
- DBUG_ENTER("TransporterFacade::open");
- int r= m_threads.open(objRef, fun, statusFun);
- if (r < 0)
- DBUG_RETURN(r);
-#if 1
- if (theOwnId > 0) {
- (*statusFun)(objRef, numberToRef(r, theOwnId), true, true);
- }
-#endif
- DBUG_RETURN(r);
-}
-
-TransporterFacade::~TransporterFacade()
-{
- DBUG_ENTER("TransporterFacade::~TransporterFacade");
-
- NdbMutex_Lock(theMutexPtr);
- delete theClusterMgr;
- delete theArbitMgr;
- delete theTransporterRegistry;
- NdbMutex_Unlock(theMutexPtr);
- NdbMutex_Destroy(theMutexPtr);
-#ifdef API_TRACE
- signalLogger.setOutputStream(0);
-#endif
- DBUG_VOID_RETURN;
-}
-
-void
-TransporterFacade::calculateSendLimit()
-{
- Uint32 Ti;
- Uint32 TthreadCount = 0;
-
- Uint32 sz = m_threads.m_statusNext.size();
- for (Ti = 0; Ti < sz; Ti++) {
- if (m_threads.m_statusNext[Ti] == (ThreadData::ACTIVE)){
- TthreadCount++;
- m_threads.m_statusNext[Ti] = ThreadData::INACTIVE;
- }
- }
- currentSendLimit = TthreadCount;
- if (currentSendLimit == 0) {
- currentSendLimit = 1;
- }
- checkCounter = currentSendLimit << 2;
-}
-
-
-//-------------------------------------------------
-// Force sending but still report the sending to the
-// adaptive algorithm.
-//-------------------------------------------------
-void TransporterFacade::forceSend(Uint32 block_number) {
- checkCounter--;
- m_threads.m_statusNext[numberToIndex(block_number)] = ThreadData::ACTIVE;
- sendPerformedLastInterval = 1;
- if (checkCounter < 0) {
- calculateSendLimit();
- }
- theTransporterRegistry->forceSendCheck(0);
-}
-
-//-------------------------------------------------
-// Improving API performance
-//-------------------------------------------------
-void
-TransporterFacade::checkForceSend(Uint32 block_number) {
- m_threads.m_statusNext[numberToIndex(block_number)] = ThreadData::ACTIVE;
- //-------------------------------------------------
- // This code is an adaptive algorithm to discover when
- // the API should actually send its buffers. The reason
- // is that the performance is highly dependent on the
- // size of the writes over the communication network.
- // Thus we try to ensure that the send size is as big
- // as possible. At the same time we don't want response
- // time to increase so therefore we have to keep track of
- // how the users are performing adaptively.
- //-------------------------------------------------
-
- if (theTransporterRegistry->forceSendCheck(currentSendLimit) == 1) {
- sendPerformedLastInterval = 1;
- }
- checkCounter--;
- if (checkCounter < 0) {
- calculateSendLimit();
- }
-}
-
-
-/******************************************************************************
- * SEND SIGNAL METHODS
- *****************************************************************************/
-int
-TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){
- Uint32* tDataPtr = aSignal->getDataPtrSend();
- Uint32 Tlen = aSignal->theLength;
- Uint32 TBno = aSignal->theReceiversBlockNumber;
- if(getIsNodeSendable(aNode) == true){
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- LinearSectionPtr ptr[3];
- signalLogger.sendSignal(* aSignal,
- 1,
- tDataPtr,
- aNode, ptr, 0);
- signalLogger.flushSignalLog();
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
- if ((Tlen != 0) && (Tlen <= 25) && (TBno != 0)) {
- SendStatus ss = theTransporterRegistry->prepareSend(aSignal,
- 1, // JBB
- tDataPtr,
- aNode,
- 0);
- //if (ss != SEND_OK) ndbout << ss << endl;
- return (ss == SEND_OK ? 0 : -1);
- } else {
- ndbout << "ERR: SigLen = " << Tlen << " BlockRec = " << TBno;
- ndbout << " SignalNo = " << aSignal->theVerId_signalNumber << endl;
- assert(0);
- }//if
- }
- //const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(aNode);
- //const Uint32 startLevel = node.m_state.startLevel;
- return -1; // Node Dead
-}
-
-int
-TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){
- Uint32* tDataPtr = aSignal->getDataPtrSend();
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- LinearSectionPtr ptr[3];
- signalLogger.sendSignal(* aSignal,
- 0,
- tDataPtr,
- aNode, ptr, 0);
- signalLogger.flushSignalLog();
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
- assert((aSignal->theLength != 0) &&
- (aSignal->theLength <= 25) &&
- (aSignal->theReceiversBlockNumber != 0));
- SendStatus ss = theTransporterRegistry->prepareSend(aSignal,
- 0,
- tDataPtr,
- aNode,
- 0);
-
- return (ss == SEND_OK ? 0 : -1);
-}
-
-#define CHUNK_SZ NDB_SECTION_SEGMENT_SZ*64 // related to MAX_MESSAGE_SIZE
-int
-TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
- LinearSectionPtr ptr[3], Uint32 secs)
-{
- if(getIsNodeSendable(aNode) != true)
- return -1;
-
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- signalLogger.sendSignal(* aSignal,
- 1,
- aSignal->getDataPtrSend(),
- aNode,
- ptr, secs);
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
-
- NdbApiSignal tmp_signal(*(SignalHeader*)aSignal);
- LinearSectionPtr tmp_ptr[3];
- Uint32 unique_id= m_fragmented_signal_id++; // next unique id
- unsigned i;
- for (i= 0; i < secs; i++)
- tmp_ptr[i]= ptr[i];
-
- unsigned start_i= 0;
- unsigned chunk_sz= 0;
- unsigned fragment_info= 0;
- Uint32 *tmp_data= tmp_signal.getDataPtrSend();
- for (i= 0; i < secs;) {
- unsigned save_sz= tmp_ptr[i].sz;
- tmp_data[i-start_i]= i;
- if (chunk_sz + save_sz > CHUNK_SZ) {
- // truncate
- unsigned send_sz= CHUNK_SZ - chunk_sz;
- if (i != start_i) // first piece of a new section has to be a multiple of NDB_SECTION_SEGMENT_SZ
- {
- send_sz=
- NDB_SECTION_SEGMENT_SZ
- *(send_sz+NDB_SECTION_SEGMENT_SZ-1)
- /NDB_SECTION_SEGMENT_SZ;
- if (send_sz > save_sz)
- send_sz= save_sz;
- }
- tmp_ptr[i].sz= send_sz;
-
- if (fragment_info < 2) // 1 = first fragment, 2 = middle fragments
- fragment_info++;
-
- // send tmp_signal
- tmp_data[i-start_i+1]= unique_id;
- tmp_signal.setLength(i-start_i+2);
- tmp_signal.m_fragmentInfo= fragment_info;
- tmp_signal.m_noOfSections= i-start_i+1;
- // do prepare send
- {
- SendStatus ss = theTransporterRegistry->prepareSend
- (&tmp_signal,
- 1, /*JBB*/
- tmp_data,
- aNode,
- &tmp_ptr[start_i]);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- if (ss != SEND_OK) return -1;
- }
- // setup variables for next signal
- start_i= i;
- chunk_sz= 0;
- tmp_ptr[i].sz= save_sz-send_sz;
- tmp_ptr[i].p+= send_sz;
- if (tmp_ptr[i].sz == 0)
- i++;
- }
- else
- {
- chunk_sz+=save_sz;
- i++;
- }
- }
-
- unsigned a_sz= aSignal->getLength();
-
- if (fragment_info > 0) {
- // update the original signal to include section info
- Uint32 *a_data= aSignal->getDataPtrSend();
- unsigned tmp_sz= i-start_i;
- memcpy(a_data+a_sz,
- tmp_data,
- tmp_sz*sizeof(Uint32));
- a_data[a_sz+tmp_sz]= unique_id;
- aSignal->setLength(a_sz+tmp_sz+1);
-
- // send last fragment
- aSignal->m_fragmentInfo= 3; // 3 = last fragment
- aSignal->m_noOfSections= i-start_i;
- } else {
- aSignal->m_noOfSections= secs;
- }
-
- // send aSignal
- int ret;
- {
- SendStatus ss = theTransporterRegistry->prepareSend
- (aSignal,
- 1/*JBB*/,
- aSignal->getDataPtrSend(),
- aNode,
- &tmp_ptr[start_i]);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- ret = (ss == SEND_OK ? 0 : -1);
- }
- aSignal->m_noOfSections = 0;
- aSignal->m_fragmentInfo = 0;
- aSignal->setLength(a_sz);
- return ret;
-}
-
-int
-TransporterFacade::sendSignal(NdbApiSignal* aSignal, NodeId aNode,
- LinearSectionPtr ptr[3], Uint32 secs){
- aSignal->m_noOfSections = secs;
- if(getIsNodeSendable(aNode) == true){
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
- Uint32 tmp = aSignal->theSendersBlockRef;
- aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
- signalLogger.sendSignal(* aSignal,
- 1,
- aSignal->getDataPtrSend(),
- aNode,
- ptr, secs);
- signalLogger.flushSignalLog();
- aSignal->theSendersBlockRef = tmp;
- }
-#endif
- SendStatus ss = theTransporterRegistry->prepareSend
- (aSignal,
- 1, // JBB
- aSignal->getDataPtrSend(),
- aNode,
- ptr);
- assert(ss != SEND_MESSAGE_TOO_BIG);
- aSignal->m_noOfSections = 0;
- return (ss == SEND_OK ? 0 : -1);
- }
- aSignal->m_noOfSections = 0;
- return -1;
-}
-
-/******************************************************************************
- * CONNECTION METHODS Etc
- ******************************************************************************/
-
-void
-TransporterFacade::doConnect(int aNodeId){
- theTransporterRegistry->setIOState(aNodeId, NoHalt);
- theTransporterRegistry->do_connect(aNodeId);
-}
-
-void
-TransporterFacade::doDisconnect(int aNodeId)
-{
- theTransporterRegistry->do_disconnect(aNodeId);
-}
-
-void
-TransporterFacade::reportConnected(int aNodeId)
-{
- theClusterMgr->reportConnected(aNodeId);
- return;
-}
-
-void
-TransporterFacade::reportDisconnected(int aNodeId)
-{
- theClusterMgr->reportDisconnected(aNodeId);
- return;
-}
-
-NodeId
-TransporterFacade::ownId() const
-{
- return theOwnId;
-}
-
-bool
-TransporterFacade::isConnected(NodeId aNodeId){
- return theTransporterRegistry->is_connected(aNodeId);
-}
-
-NodeId
-TransporterFacade::get_an_alive_node()
-{
- DBUG_ENTER("TransporterFacade::get_an_alive_node");
- DBUG_PRINT("enter", ("theStartNodeId: %d", theStartNodeId));
-#ifdef VM_TRACE
- const char* p = NdbEnv_GetEnv("NDB_ALIVE_NODE_ID", (char*)0, 0);
- if (p != 0 && *p != 0)
- return atoi(p);
-#endif
- NodeId i;
- for (i = theStartNodeId; i < MAX_NDB_NODES; i++) {
- if (get_node_alive(i)){
- DBUG_PRINT("info", ("Node %d is alive", i));
- theStartNodeId = ((i + 1) % MAX_NDB_NODES);
- DBUG_RETURN(i);
- }
- }
- for (i = 1; i < theStartNodeId; i++) {
- if (get_node_alive(i)){
- DBUG_PRINT("info", ("Node %d is alive", i));
- theStartNodeId = ((i + 1) % MAX_NDB_NODES);
- DBUG_RETURN(i);
- }
- }
- DBUG_RETURN((NodeId)0);
-}
-
-TransporterFacade::ThreadData::ThreadData(Uint32 size){
- m_use_cnt = 0;
- m_firstFree = END_OF_LIST;
- expand(size);
-}
-
-void
-TransporterFacade::ThreadData::expand(Uint32 size){
- Object_Execute oe = { 0 ,0 };
- NodeStatusFunction fun = 0;
-
- const Uint32 sz = m_statusNext.size();
- m_objectExecute.fill(sz + size, oe);
- m_statusFunction.fill(sz + size, fun);
- for(Uint32 i = 0; i<size; i++){
- m_statusNext.push_back(sz + i + 1);
- }
-
- m_statusNext.back() = m_firstFree;
- m_firstFree = m_statusNext.size() - size;
-}
-
-
-int
-TransporterFacade::ThreadData::open(void* objRef,
- ExecuteFunction fun,
- NodeStatusFunction fun2)
-{
- Uint32 nextFree = m_firstFree;
-
- if(m_statusNext.size() >= MAX_NO_THREADS && nextFree == END_OF_LIST){
- return -1;
- }
-
- if(nextFree == END_OF_LIST){
- expand(10);
- nextFree = m_firstFree;
- }
-
- m_use_cnt++;
- m_firstFree = m_statusNext[nextFree];
-
- Object_Execute oe = { objRef , fun };
-
- m_statusNext[nextFree] = INACTIVE;
- m_objectExecute[nextFree] = oe;
- m_statusFunction[nextFree] = fun2;
-
- return indexToNumber(nextFree);
-}
-
-int
-TransporterFacade::ThreadData::close(int number){
- number= numberToIndex(number);
- assert(getInUse(number));
- m_statusNext[number] = m_firstFree;
- assert(m_use_cnt);
- m_use_cnt--;
- m_firstFree = number;
- Object_Execute oe = { 0, 0 };
- m_objectExecute[number] = oe;
- m_statusFunction[number] = 0;
- return 0;
-}
-
-Uint32
-TransporterFacade::get_active_ndb_objects() const
-{
- return m_threads.m_use_cnt;
-}
-
-PollGuard::PollGuard(TransporterFacade *tp, NdbWaiter *aWaiter,
- Uint32 block_no)
-{
- m_tp= tp;
- m_waiter= aWaiter;
- m_locked= true;
- m_block_no= block_no;
- tp->lock_mutex();
-}
-
-/*
- This is a common routine for possibly forcing the send of buffered signals
- and receiving response the thread is waiting for. It is designed to be
- useful from:
- 1) PK, UK lookups using the asynchronous interface
- This routine uses the wait_for_input routine instead since it has
- special end conditions due to the asynchronous nature of its usage.
- 2) Scans
- 3) dictSignal
- It uses a NdbWaiter object to wait on the events and this object is
- linked into the conditional wait queue. Thus this object contains
- a reference to its place in the queue.
-
- It replaces the method receiveResponse previously used on the Ndb object
-*/
-int PollGuard::wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state,
- bool forceSend)
-{
- int ret_val;
- m_waiter->set_node(nodeId);
- m_waiter->set_state(state);
- ret_val= wait_for_input_in_loop(wait_time, forceSend);
- unlock_and_signal();
- return ret_val;
-}
-
-int PollGuard::wait_scan(int wait_time, NodeId nodeId, bool forceSend)
-{
- m_waiter->set_node(nodeId);
- m_waiter->set_state(WAIT_SCAN);
- return wait_for_input_in_loop(wait_time, forceSend);
-}
-
-int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend)
-{
- int ret_val;
- if (forceSend)
- m_tp->forceSend(m_block_no);
- else
- m_tp->checkForceSend(m_block_no);
-
- NDB_TICKS curr_time = NdbTick_CurrentMillisecond();
- NDB_TICKS max_time = curr_time + (NDB_TICKS)wait_time;
- const int maxsleep = (wait_time == -1 || wait_time > 10) ? 10 : wait_time;
- do
- {
- wait_for_input(maxsleep);
- Uint32 state= m_waiter->get_state();
- if (state == NO_WAIT)
- {
- return 0;
- }
- else if (state == WAIT_NODE_FAILURE)
- {
- ret_val= -2;
- break;
- }
- if (wait_time == -1)
- {
-#ifdef NOT_USED
- ndbout << "Waited WAITFOR_RESPONSE_TIMEOUT, continuing wait" << endl;
-#endif
- continue;
- }
- wait_time= max_time - NdbTick_CurrentMillisecond();
- if (wait_time <= 0)
- {
-#ifdef VM_TRACE
- ndbout << "Time-out state is " << m_waiter->get_state() << endl;
-#endif
- m_waiter->set_state(WST_WAIT_TIMEOUT);
- ret_val= -1;
- break;
- }
- } while (1);
-#ifdef VM_TRACE
- ndbout << "ERR: receiveResponse - theImpl->theWaiter.m_state = ";
- ndbout << m_waiter->get_state() << endl;
-#endif
- m_waiter->set_state(NO_WAIT);
- return ret_val;
-}
-
-void PollGuard::wait_for_input(int wait_time)
-{
- NdbWaiter *t_poll_owner= m_tp->get_poll_owner();
- if (t_poll_owner != NULL && t_poll_owner != m_waiter)
- {
- /*
- We didn't get hold of the poll "right". We will sleep on a
- conditional mutex until the thread owning the poll "right"
- will wake us up after all data is received. If no data arrives
- we will wake up eventually due to the timeout.
- After receiving all data we take the object out of the cond wait
- queue if it hasn't happened already. It is usually already out of the
- queue but at time-out it could be that the object is still there.
- */
- (void) m_tp->put_in_cond_wait_queue(m_waiter);
- m_waiter->wait(wait_time);
- if (m_waiter->get_cond_wait_index() != TransporterFacade::MAX_NO_THREADS)
- {
- m_tp->remove_from_cond_wait_queue(m_waiter);
- }
- }
- else
- {
- /*
- We got the poll "right" and we poll until data is received. After
- receiving data we will check if all data is received, if not we
- poll again.
- */
-#ifdef NDB_SHM_TRANSPORTER
- /*
- If shared memory transporters are used we need to set our sigmask
- such that we wake up also on interrupts on the shared memory
- interrupt signal.
- */
- NdbThread_set_shm_sigmask(FALSE);
-#endif
- m_tp->set_poll_owner(m_waiter);
- m_waiter->set_poll_owner(true);
- m_tp->external_poll((Uint32)wait_time);
- }
-}
-
-void PollGuard::unlock_and_signal()
-{
- NdbWaiter *t_signal_cond_waiter= 0;
- if (!m_locked)
- return;
- /*
- When completing the poll for this thread we must return the poll
- ownership if we own it. We will give it to the last thread that
- came here (the most recent) which is likely to be the one also
- last to complete. We will remove that thread from the conditional
- wait queue and set him as the new owner of the poll "right".
- We will wait however with the signal until we have unlocked the
- mutex for performance reasons.
- See Stevens book on Unix NetworkProgramming: The Sockets Networking
- API Volume 1 Third Edition on page 703-704 for a discussion on this
- subject.
- */
- if (m_tp->get_poll_owner() == m_waiter)
- {
-#ifdef NDB_SHM_TRANSPORTER
- /*
- If shared memory transporters are used we need to reset our sigmask
- since we are no longer the thread to receive interrupts.
- */
- NdbThread_set_shm_sigmask(TRUE);
-#endif
- m_waiter->set_poll_owner(false);
- t_signal_cond_waiter= m_tp->rem_last_from_cond_wait_queue();
- m_tp->set_poll_owner(t_signal_cond_waiter);
- if (t_signal_cond_waiter)
- t_signal_cond_waiter->set_poll_owner(true);
- }
- if (t_signal_cond_waiter)
- t_signal_cond_waiter->cond_signal();
- m_tp->unlock_mutex();
- m_locked=false;
-}
-
-template class Vector<NodeStatusFunction>;
-template class Vector<TransporterFacade::ThreadData::Object_Execute>;
-
-#include "SignalSender.hpp"
-
-SendStatus
-SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s){
-#ifdef API_TRACE
- if(setSignalLog() && TRACE_GSN(s->header.theVerId_signalNumber)){
- SignalHeader tmp = s->header;
- tmp.theSendersBlockRef = getOwnRef();
-
- LinearSectionPtr ptr[3];
- signalLogger.sendSignal(tmp,
- 1,
- s->theData,
- nodeId, ptr, 0);
- signalLogger.flushSignalLog();
- }
-#endif
- assert(getNodeInfo(nodeId).m_api_reg_conf == true ||
- s->readSignalNumber() == GSN_API_REGREQ);
- return theFacade->theTransporterRegistry->prepareSend(&s->header,
- 1, // JBB
- &s->theData[0],
- nodeId,
- &s->ptr[0]);
-}
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.hpp b/storage/ndb/src/ndbapi/TransporterFacade.hpp
deleted file mode 100644
index 2870565f60a..00000000000
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef TransporterFacade_H
-#define TransporterFacade_H
-
-#include <kernel_types.h>
-#include <ndb_limits.h>
-#include <NdbThread.h>
-#include <TransporterRegistry.hpp>
-#include <NdbMutex.h>
-#include "DictCache.hpp"
-#include <BlockNumbers.h>
-#include <mgmapi.h>
-
-class ClusterMgr;
-class ArbitMgr;
-class IPCConfig;
-struct ndb_mgm_configuration;
-class ConfigRetriever;
-
-class Ndb;
-class NdbApiSignal;
-class NdbWaiter;
-
-typedef void (* ExecuteFunction)(void *, NdbApiSignal *, LinearSectionPtr ptr[3]);
-typedef void (* NodeStatusFunction)(void *, Uint32, bool nodeAlive, bool nfComplete);
-
-extern "C" {
- void* runSendRequest_C(void*);
- void* runReceiveResponse_C(void*);
- void atexit_stop_instance();
-}
-
-class TransporterFacade
-{
-public:
- /**
- * Max number of Ndb objects.
- * (Ndb objects should not be shared by different threads.)
- */
- STATIC_CONST( MAX_NO_THREADS = 4711 );
- TransporterFacade();
- virtual ~TransporterFacade();
- bool init(Uint32, const ndb_mgm_configuration *);
-
- int start_instance(int, const ndb_mgm_configuration*);
- void stop_instance();
-
- /**
- * Register this block for sending/receiving signals
- * @return BlockNumber or -1 for failure
- */
- int open(void* objRef, ExecuteFunction, NodeStatusFunction);
-
- // Close this block number
- int close(BlockNumber blockNumber, Uint64 trans_id);
- Uint32 get_active_ndb_objects() const;
-
- // Only sends to nodes which are alive
- int sendSignal(NdbApiSignal * signal, NodeId nodeId);
- int sendSignal(NdbApiSignal*, NodeId,
- LinearSectionPtr ptr[3], Uint32 secs);
- int sendFragmentedSignal(NdbApiSignal*, NodeId,
- LinearSectionPtr ptr[3], Uint32 secs);
-
- // Is node available for running transactions
- bool get_node_alive(NodeId nodeId) const;
- bool get_node_stopping(NodeId nodeId) const;
- bool getIsDbNode(NodeId nodeId) const;
- bool getIsNodeSendable(NodeId nodeId) const;
- Uint32 getNodeGrp(NodeId nodeId) const;
- Uint32 getNodeSequence(NodeId nodeId) const;
-
- // Is there space in sendBuffer to send messages
- bool check_send_size(Uint32 node_id, Uint32 send_size);
-
- // My own processor id
- NodeId ownId() const;
-
- void connected();
-
- void doConnect(int NodeId);
- void reportConnected(int NodeId);
- void doDisconnect(int NodeId);
- void reportDisconnected(int NodeId);
-
- NodeId get_an_alive_node();
- void ReportNodeAlive(NodeId nodeId);
- void ReportNodeDead(NodeId nodeId);
- void ReportNodeFailureComplete(NodeId nodeId);
-
- /**
- * Send signal to each registered object
- */
- void for_each(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]);
-
- void lock_mutex();
- void unlock_mutex();
-
- // Improving the API performance
- void forceSend(Uint32 block_number);
- void checkForceSend(Uint32 block_number);
-
- // Close this block number
- int close_local(BlockNumber blockNumber);
-
- // Scan batch configuration parameters
- Uint32 get_scan_batch_size();
- Uint32 get_batch_byte_size();
- Uint32 get_batch_size();
- Uint32 m_waitfor_timeout; // in milli seconds...
-
- TransporterRegistry* get_registry() { return theTransporterRegistry;};
-
-/*
- When a thread has sent its signals and is ready to wait for reception
- of these it does normally always wait on a conditional mutex and
- the actual reception is handled by the receiver thread in the NDB API.
- With the below new methods and variables each thread has the possibility
- of becoming owner of the "right" to poll for signals. Effectually this
- means that the thread acts temporarily as a receiver thread.
- For the thread that succeeds in grabbing this "ownership" it will avoid
- a number of expensive calls to conditional mutex and even more expensive
- context switches to wake up.
- When an owner of the poll "right" has completed its own task it is likely
- that there are others still waiting. In this case we pick one of the
- threads as new owner of the poll "right". Since we want to switch owner
- as seldom as possible we always pick the last thread which is likely to
- be the last to complete its reception.
-*/
- void external_poll(Uint32 wait_time);
- NdbWaiter* get_poll_owner(void) const { return poll_owner; }
- void set_poll_owner(NdbWaiter* new_owner) { poll_owner= new_owner; }
- Uint32 put_in_cond_wait_queue(NdbWaiter *aWaiter);
- void remove_from_cond_wait_queue(NdbWaiter *aWaiter);
- NdbWaiter* rem_last_from_cond_wait_queue();
- // heart beat received from a node (e.g. a signal came)
- void hb_received(NodeId n);
-
-private:
- void init_cond_wait_queue();
- struct CondWaitQueueElement {
- NdbWaiter *cond_wait_object;
- Uint32 next_cond_wait;
- Uint32 prev_cond_wait;
- };
- NdbWaiter *poll_owner;
- CondWaitQueueElement cond_wait_array[MAX_NO_THREADS];
- Uint32 first_in_cond_wait;
- Uint32 first_free_cond_wait;
- Uint32 last_in_cond_wait;
- /* End poll owner stuff */
- /**
- * Send a signal unconditional of node status (used by ClusterMgr)
- */
- friend class ClusterMgr;
- friend class ArbitMgr;
- friend class MgmtSrvr;
- friend class SignalSender;
- friend class GrepPS;
- friend class ExtSender; ///< @todo Hack to be able to sendSignalUnCond
- friend class GrepSS;
- friend class Ndb;
- friend class Ndb_cluster_connection_impl;
- friend class NdbTransaction;
-
- int sendSignalUnCond(NdbApiSignal *, NodeId nodeId);
-
- bool isConnected(NodeId aNodeId);
- void doStop();
-
- TransporterRegistry* theTransporterRegistry;
- SocketServer m_socket_server;
- int sendPerformedLastInterval;
- int theOwnId;
-
- NodeId theStartNodeId;
-
- ClusterMgr* theClusterMgr;
- ArbitMgr* theArbitMgr;
-
- // Improving the API response time
- int checkCounter;
- Uint32 currentSendLimit;
-
- void calculateSendLimit();
-
- // Scan batch configuration parameters
- Uint32 m_scan_batch_size;
- Uint32 m_batch_byte_size;
- Uint32 m_batch_size;
-
- // Declarations for the receive and send thread
- int theStopReceive;
-
- void threadMainSend(void);
- NdbThread* theSendThread;
- void threadMainReceive(void);
- NdbThread* theReceiveThread;
-
- friend void* runSendRequest_C(void*);
- friend void* runReceiveResponse_C(void*);
- friend void atexit_stop_instance();
-
- /**
- * Block number handling
- */
-private:
-
- struct ThreadData {
- STATIC_CONST( ACTIVE = (1 << 16) | 1 );
- STATIC_CONST( INACTIVE = (1 << 16) );
- STATIC_CONST( END_OF_LIST = MAX_NO_THREADS + 1 );
-
- ThreadData(Uint32 initialSize = 32);
-
- /**
- * Split "object" into 3 list
- * This to improve locality
- * when iterating over lists
- */
- struct Object_Execute {
- void * m_object;
- ExecuteFunction m_executeFunction;
- };
- struct NodeStatus_NextFree {
- NodeStatusFunction m_statusFunction;
- };
-
- Uint32 m_use_cnt;
- Uint32 m_firstFree;
- Vector<Uint32> m_statusNext;
- Vector<Object_Execute> m_objectExecute;
- Vector<NodeStatusFunction> m_statusFunction;
-
- int open(void* objRef, ExecuteFunction, NodeStatusFunction);
- int close(int number);
- void expand(Uint32 size);
-
- inline Object_Execute get(Uint16 blockNo) const {
- blockNo -= MIN_API_BLOCK_NO;
- if(likely (blockNo < m_objectExecute.size())){
- return m_objectExecute[blockNo];
- }
- Object_Execute oe = { 0, 0 };
- return oe;
- }
-
- /**
- * Is the block number used currently
- */
- inline bool getInUse(Uint16 index) const {
- return (m_statusNext[index] & (1 << 16)) != 0;
- }
- } m_threads;
-
- Uint32 m_max_trans_id;
- Uint32 m_fragmented_signal_id;
-
- /**
- * execute function
- */
- friend void execute(void * callbackObj, SignalHeader * const header,
- Uint8 prio,
- Uint32 * const theData, LinearSectionPtr ptr[3]);
-
-public:
- NdbMutex* theMutexPtr;
-
-public:
- GlobalDictCache m_globalDictCache;
-};
-
-class PollGuard
-{
- public:
- PollGuard(TransporterFacade *tp, NdbWaiter *aWaiter, Uint32 block_no);
- ~PollGuard() { unlock_and_signal(); }
- int wait_n_unlock(int wait_time, NodeId nodeId, Uint32 state,
- bool forceSend= false);
- int wait_for_input_in_loop(int wait_time, bool forceSend);
- void wait_for_input(int wait_time);
- int wait_scan(int wait_time, NodeId nodeId, bool forceSend);
- void unlock_and_signal();
- private:
- TransporterFacade *m_tp;
- NdbWaiter *m_waiter;
- Uint32 m_block_no;
- bool m_locked;
-};
-
-
-inline
-void
-TransporterFacade::lock_mutex()
-{
- NdbMutex_Lock(theMutexPtr);
-}
-
-inline
-void
-TransporterFacade::unlock_mutex()
-{
- NdbMutex_Unlock(theMutexPtr);
-}
-
-#include "ClusterMgr.hpp"
-
-inline
-unsigned Ndb_cluster_connection_impl::get_connect_count() const
-{
- return m_transporter_facade->theClusterMgr->m_connect_count;
-}
-
-inline
-bool
-TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size)
-{
- return true;
-}
-
-inline
-bool
-TransporterFacade::getIsDbNode(NodeId n) const {
- return
- theClusterMgr->getNodeInfo(n).defined &&
- theClusterMgr->getNodeInfo(n).m_info.m_type == NodeInfo::DB;
-}
-
-inline
-Uint32
-TransporterFacade::getNodeGrp(NodeId n) const {
- return theClusterMgr->getNodeInfo(n).m_state.nodeGroup;
-}
-
-
-inline
-bool
-TransporterFacade::get_node_alive(NodeId n) const {
-
- const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
- return node.m_alive;
-}
-
-inline
-void
-TransporterFacade::hb_received(NodeId n) {
- theClusterMgr->hb_received(n);
-}
-
-inline
-bool
-TransporterFacade::get_node_stopping(NodeId n) const {
- const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
- return (!node.m_state.getSingleUserMode() &&
- ((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
- (node.m_state.startLevel == NodeState::SL_STOPPING_2)));
-}
-
-inline
-bool
-TransporterFacade::getIsNodeSendable(NodeId n) const {
- const ClusterMgr::Node & node = theClusterMgr->getNodeInfo(n);
- const Uint32 startLevel = node.m_state.startLevel;
-
- if (node.m_info.m_type == NodeInfo::DB) {
- return node.compatible && (startLevel == NodeState::SL_STARTED ||
- startLevel == NodeState::SL_STOPPING_1 ||
- node.m_state.getSingleUserMode());
- } else {
- ndbout_c("TransporterFacade::getIsNodeSendable: Illegal node type: "
- "%d of node: %d",
- node.m_info.m_type, n);
- abort();
- return false; // to remove compiler warning
- }
-}
-
-inline
-Uint32
-TransporterFacade::getNodeSequence(NodeId n) const {
- return theClusterMgr->getNodeInfo(n).m_info.m_connectCount;
-}
-
-inline
-Uint32
-TransporterFacade::get_scan_batch_size() {
- return m_scan_batch_size;
-}
-
-inline
-Uint32
-TransporterFacade::get_batch_byte_size() {
- return m_batch_byte_size;
-}
-
-inline
-Uint32
-TransporterFacade::get_batch_size() {
- return m_batch_size;
-}
-
-
-
-#endif // TransporterFacade_H
diff --git a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
deleted file mode 100644
index 4228e26fd34..00000000000
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <ndb_global.h>
-#include <my_pthread.h>
-#include <my_sys.h>
-
-#include "ndb_cluster_connection_impl.hpp"
-#include <mgmapi_configuration.hpp>
-#include <mgmapi_config_parameters.h>
-#include <TransporterFacade.hpp>
-#include <NdbOut.hpp>
-#include <NdbSleep.h>
-#include <NdbThread.h>
-#include <ndb_limits.h>
-#include <ConfigRetriever.hpp>
-#include <ndb_version.h>
-#include <mgmapi_debug.h>
-#include <mgmapi_internal.h>
-#include <md5_hash.hpp>
-
-#include <EventLogger.hpp>
-EventLogger g_eventLogger;
-
-#include <NdbMutex.h>
-#ifdef VM_TRACE
-NdbMutex *ndb_print_state_mutex= NULL;
-#endif
-
-static int g_ndb_connection_count = 0;
-
-/*
- * Ndb_cluster_connection
- */
-
-Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string)
- : m_impl(* new Ndb_cluster_connection_impl(connect_string))
-{
-}
-
-Ndb_cluster_connection::Ndb_cluster_connection
-(Ndb_cluster_connection_impl& impl) : m_impl(impl)
-{
-}
-
-Ndb_cluster_connection::~Ndb_cluster_connection()
-{
- Ndb_cluster_connection_impl *tmp = &m_impl;
- if (this != tmp)
- delete tmp;
-}
-
-int Ndb_cluster_connection::get_connected_port() const
-{
- if (m_impl.m_config_retriever)
- return m_impl.m_config_retriever->get_mgmd_port();
- return -1;
-}
-
-const char *Ndb_cluster_connection::get_connected_host() const
-{
- if (m_impl.m_config_retriever)
- return m_impl.m_config_retriever->get_mgmd_host();
- return 0;
-}
-
-const char *Ndb_cluster_connection::get_connectstring(char *buf,
- int buf_sz) const
-{
- if (m_impl.m_config_retriever)
- return m_impl.m_config_retriever->get_connectstring(buf,buf_sz);
- return 0;
-}
-
-pthread_handler_t run_ndb_cluster_connection_connect_thread(void *me)
-{
- Ndb_cluster_connection_impl* connection= (Ndb_cluster_connection_impl*) me;
- connection->m_run_connect_thread= 1;
- connection->connect_thread();
- return me;
-}
-
-int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void))
-{
- int r;
- DBUG_ENTER("Ndb_cluster_connection::start_connect_thread");
- m_impl.m_connect_callback= connect_callback;
- if ((r = connect(0,0,0)) == 1)
- {
- DBUG_PRINT("info",("starting thread"));
- m_impl.m_connect_thread=
- NdbThread_Create(run_ndb_cluster_connection_connect_thread,
- (void**)&m_impl, 32768, "ndb_cluster_connection",
- NDB_THREAD_PRIO_LOW);
- }
- else if (r < 0)
- {
- DBUG_RETURN(-1);
- }
- else if (m_impl.m_connect_callback)
- {
- (*m_impl.m_connect_callback)();
- }
- DBUG_RETURN(0);
-}
-
-void Ndb_cluster_connection::set_optimized_node_selection(int val)
-{
- m_impl.m_optimized_node_selection= val;
-}
-
-void
-Ndb_cluster_connection_impl::init_get_next_node
-(Ndb_cluster_connection_node_iter &iter)
-{
- if (iter.scan_state != (Uint8)~0)
- iter.cur_pos= iter.scan_state;
- if (iter.cur_pos >= no_db_nodes())
- iter.cur_pos= 0;
- iter.init_pos= iter.cur_pos;
- iter.scan_state= 0;
- // fprintf(stderr,"[init %d]",iter.init_pos);
- return;
-}
-
-Uint32
-Ndb_cluster_connection_impl::get_next_node(Ndb_cluster_connection_node_iter &iter)
-{
- Uint32 cur_pos= iter.cur_pos;
- if (cur_pos >= no_db_nodes())
- return 0;
-
- Ndb_cluster_connection_impl::Node *nodes= m_impl.m_all_nodes.getBase();
- Ndb_cluster_connection_impl::Node &node= nodes[cur_pos];
-
- if (iter.scan_state != (Uint8)~0)
- {
- assert(iter.scan_state < no_db_nodes());
- if (nodes[iter.scan_state].group == node.group)
- iter.scan_state= ~0;
- else
- return nodes[iter.scan_state++].id;
- }
-
- // fprintf(stderr,"[%d]",node.id);
-
- cur_pos++;
- Uint32 init_pos= iter.init_pos;
- if (cur_pos == node.next_group)
- {
- cur_pos= nodes[init_pos].this_group;
- }
-
- // fprintf(stderr,"[cur_pos %d]",cur_pos);
- if (cur_pos != init_pos)
- iter.cur_pos= cur_pos;
- else
- {
- iter.cur_pos= node.next_group;
- iter.init_pos= node.next_group;
- }
- return node.id;
-}
-
-unsigned
-Ndb_cluster_connection::no_db_nodes()
-{
- return m_impl.m_all_nodes.size();
-}
-
-unsigned
-Ndb_cluster_connection::node_id()
-{
- return m_impl.m_transporter_facade->ownId();
-}
-
-
-int Ndb_cluster_connection::get_no_ready()
-{
- TransporterFacade *tp = m_impl.m_transporter_facade;
- if (tp == 0 || tp->ownId() == 0)
- return -1;
-
- unsigned int foundAliveNode = 0;
- tp->lock_mutex();
- for(unsigned i= 0; i < no_db_nodes(); i++)
- {
- //************************************************
- // If any node is answering, ndb is answering
- //************************************************
- if (tp->get_node_alive(m_impl.m_all_nodes[i].id) != 0) {
- foundAliveNode++;
- }
- }
- tp->unlock_mutex();
-
- return foundAliveNode;
-}
-
-int
-Ndb_cluster_connection::wait_until_ready(int timeout,
- int timeout_after_first_alive)
-{
- DBUG_ENTER("Ndb_cluster_connection::wait_until_ready");
- TransporterFacade *tp = m_impl.m_transporter_facade;
- if (tp == 0)
- {
- DBUG_RETURN(-1);
- }
- if (tp->ownId() == 0)
- {
- DBUG_RETURN(-1);
- }
- int secondsCounter = 0;
- int milliCounter = 0;
- int noChecksSinceFirstAliveFound = 0;
- do {
- unsigned int foundAliveNode = get_no_ready();
-
- if (foundAliveNode == no_db_nodes())
- {
- DBUG_RETURN(0);
- }
- else if (foundAliveNode > 0)
- {
- noChecksSinceFirstAliveFound++;
- // 100 ms delay -> 10*
- if (noChecksSinceFirstAliveFound > 10*timeout_after_first_alive)
- DBUG_RETURN(1);
- }
- else if (secondsCounter >= timeout)
- { // no alive nodes and timed out
- DBUG_RETURN(-1);
- }
- NdbSleep_MilliSleep(100);
- milliCounter += 100;
- if (milliCounter >= 1000) {
- secondsCounter++;
- milliCounter = 0;
- }//if
- } while (1);
-}
-
-unsigned Ndb_cluster_connection::get_connect_count() const
-{
- return m_impl.get_connect_count();
-}
-
-/*
- * Ndb_cluster_connection_impl
- */
-
-Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char *
- connect_string)
- : Ndb_cluster_connection(*this),
- m_optimized_node_selection(1),
- m_name(0),
- m_run_connect_thread(0),
- m_event_add_drop_mutex(0),
- m_latest_trans_gci(0)
-{
- DBUG_ENTER("Ndb_cluster_connection");
- DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this));
-
- if (!m_event_add_drop_mutex)
- m_event_add_drop_mutex= NdbMutex_Create();
-
- g_eventLogger.createConsoleHandler();
- g_eventLogger.setCategory("NdbApi");
- g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
-
- m_connect_thread= 0;
- m_connect_callback= 0;
-
-#ifdef VM_TRACE
- if (ndb_print_state_mutex == NULL)
- ndb_print_state_mutex= NdbMutex_Create();
-#endif
- m_config_retriever=
- new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API);
- if (m_config_retriever->hasError())
- {
- printf("Could not initialize handle to management server: %s\n",
- m_config_retriever->getErrorString());
- delete m_config_retriever;
- m_config_retriever= 0;
- }
- if (m_name)
- {
- NdbMgmHandle h= m_config_retriever->get_mgmHandle();
- ndb_mgm_set_name(h, m_name);
- }
- m_transporter_facade= new TransporterFacade();
-
- NdbMutex_Lock(g_ndb_connection_mutex);
- if(g_ndb_connection_count++ == 0){
- NdbDictionary::Column::FRAGMENT=
- NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
- NdbDictionary::Column::FRAGMENT_FIXED_MEMORY=
- NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
- NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY=
- NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
- NdbDictionary::Column::ROW_COUNT=
- NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
- NdbDictionary::Column::COMMIT_COUNT=
- NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT");
- NdbDictionary::Column::ROW_SIZE=
- NdbColumnImpl::create_pseudo("NDB$ROW_SIZE");
- NdbDictionary::Column::RANGE_NO=
- NdbColumnImpl::create_pseudo("NDB$RANGE_NO");
- NdbDictionary::Column::DISK_REF=
- NdbColumnImpl::create_pseudo("NDB$DISK_REF");
- NdbDictionary::Column::RECORDS_IN_RANGE=
- NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE");
- NdbDictionary::Column::ROWID=
- NdbColumnImpl::create_pseudo("NDB$ROWID");
- NdbDictionary::Column::ROW_GCI=
- NdbColumnImpl::create_pseudo("NDB$ROW_GCI");
- NdbDictionary::Column::ANY_VALUE=
- NdbColumnImpl::create_pseudo("NDB$ANY_VALUE");
- NdbDictionary::Column::COPY_ROWID=
- NdbColumnImpl::create_pseudo("NDB$COPY_ROWID");
- }
- NdbMutex_Unlock(g_ndb_connection_mutex);
-
- DBUG_VOID_RETURN;
-}
-
-Ndb_cluster_connection_impl::~Ndb_cluster_connection_impl()
-{
- DBUG_ENTER("~Ndb_cluster_connection");
- if (m_transporter_facade != 0)
- {
- m_transporter_facade->stop_instance();
- }
- if (m_connect_thread)
- {
- void *status;
- m_run_connect_thread= 0;
- NdbThread_WaitFor(m_connect_thread, &status);
- NdbThread_Destroy(&m_connect_thread);
- m_connect_thread= 0;
- }
- if (m_transporter_facade != 0)
- {
- delete m_transporter_facade;
- m_transporter_facade = 0;
- }
- if (m_config_retriever)
- {
- delete m_config_retriever;
- m_config_retriever= NULL;
- }
-#ifdef VM_TRACE
- if (ndb_print_state_mutex != NULL)
- {
- NdbMutex_Destroy(ndb_print_state_mutex);
- ndb_print_state_mutex= NULL;
- }
-#endif
- if (m_name)
- free(m_name);
-
- NdbMutex_Lock(g_ndb_connection_mutex);
- if(--g_ndb_connection_count == 0){
- delete NdbDictionary::Column::FRAGMENT;
- delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
- delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
- delete NdbDictionary::Column::ROW_COUNT;
- delete NdbDictionary::Column::COMMIT_COUNT;
- delete NdbDictionary::Column::ROW_SIZE;
- delete NdbDictionary::Column::RANGE_NO;
- delete NdbDictionary::Column::DISK_REF;
- delete NdbDictionary::Column::RECORDS_IN_RANGE;
- delete NdbDictionary::Column::ROWID;
- delete NdbDictionary::Column::ROW_GCI;
- delete NdbDictionary::Column::ANY_VALUE;
- NdbDictionary::Column::FRAGMENT= 0;
- NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
- NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
- NdbDictionary::Column::ROW_COUNT= 0;
- NdbDictionary::Column::COMMIT_COUNT= 0;
- NdbDictionary::Column::ROW_SIZE= 0;
- NdbDictionary::Column::RANGE_NO= 0;
- NdbDictionary::Column::DISK_REF= 0;
- NdbDictionary::Column::RECORDS_IN_RANGE= 0;
- NdbDictionary::Column::ROWID= 0;
- NdbDictionary::Column::ROW_GCI= 0;
- NdbDictionary::Column::ANY_VALUE= 0;
-
- delete NdbDictionary::Column::COPY_ROWID;
- NdbDictionary::Column::COPY_ROWID = 0;
- }
- NdbMutex_Unlock(g_ndb_connection_mutex);
-
- if (m_event_add_drop_mutex)
- NdbMutex_Destroy(m_event_add_drop_mutex);
-
- DBUG_VOID_RETURN;
-}
-
-void
-Ndb_cluster_connection_impl::set_name(const char *name)
-{
- if (m_name)
- free(m_name);
- m_name= strdup(name);
- if (m_config_retriever && m_name)
- {
- NdbMgmHandle h= m_config_retriever->get_mgmHandle();
- ndb_mgm_set_name(h, m_name);
- }
-}
-
-int
-Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid,
- const ndb_mgm_configuration
- &config)
-{
- DBUG_ENTER("Ndb_cluster_connection_impl::init_nodes_vector");
- ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION);
-
- for(iter.first(); iter.valid(); iter.next())
- {
- Uint32 nodeid1, nodeid2, remoteNodeId, group= 5;
- const char * remoteHostName= 0, * localHostName= 0;
- 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);
-
- iter.get(CFG_CONNECTION_GROUP, &group);
-
- {
- const char * host1= 0, * host2= 0;
- iter.get(CFG_CONNECTION_HOSTNAME_1, &host1);
- iter.get(CFG_CONNECTION_HOSTNAME_2, &host2);
- localHostName = (nodeid == nodeid1 ? host1 : host2);
- remoteHostName = (nodeid == nodeid1 ? host2 : host1);
- }
-
- Uint32 type = ~0;
- if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
-
- switch(type){
- case CONNECTION_TYPE_SHM:{
- break;
- }
- case CONNECTION_TYPE_SCI:{
- break;
- }
- case CONNECTION_TYPE_TCP:{
- // connecting through localhost
- // check if config_hostname is local
- if (SocketServer::tryBind(0,remoteHostName))
- group--; // upgrade group value
- break;
- }
- }
- if (m_impl.m_all_nodes.push_back(Node(group,remoteNodeId)))
- {
- DBUG_RETURN(-1);
- }
- DBUG_PRINT("info",("saved %d %d", group,remoteNodeId));
- for (int i= m_impl.m_all_nodes.size()-2;
- i >= 0 && m_impl.m_all_nodes[i].group > m_impl.m_all_nodes[i+1].group;
- i--)
- {
- Node tmp= m_impl.m_all_nodes[i];
- m_impl.m_all_nodes[i]= m_impl.m_all_nodes[i+1];
- m_impl.m_all_nodes[i+1]= tmp;
- }
- }
-
- int i;
- Uint32 cur_group, i_group= 0;
- cur_group= ~0;
- for (i= (int)m_impl.m_all_nodes.size()-1; i >= 0; i--)
- {
- if (m_impl.m_all_nodes[i].group != cur_group)
- {
- cur_group= m_impl.m_all_nodes[i].group;
- i_group= i+1;
- }
- m_impl.m_all_nodes[i].next_group= i_group;
- }
- cur_group= ~0;
- for (i= 0; i < (int)m_impl.m_all_nodes.size(); i++)
- {
- if (m_impl.m_all_nodes[i].group != cur_group)
- {
- cur_group= m_impl.m_all_nodes[i].group;
- i_group= i;
- }
- m_impl.m_all_nodes[i].this_group= i_group;
- }
-#if 0
- for (i= 0; i < (int)m_impl.m_all_nodes.size(); i++)
- {
- fprintf(stderr, "[%d] %d %d %d %d\n",
- i,
- m_impl.m_all_nodes[i].id,
- m_impl.m_all_nodes[i].group,
- m_impl.m_all_nodes[i].this_group,
- m_impl.m_all_nodes[i].next_group);
- }
-
- do_test();
-#endif
- DBUG_RETURN(0);
-}
-
-void
-Ndb_cluster_connection_impl::do_test()
-{
- Ndb_cluster_connection_node_iter iter;
- int n= no_db_nodes()+5;
- Uint32 *nodes= new Uint32[n+1];
-
- for (int g= 0; g < n; g++)
- {
- for (int h= 0; h < n; h++)
- {
- Uint32 id;
- Ndb_cluster_connection_node_iter iter2;
- {
- for (int j= 0; j < g; j++)
- {
- nodes[j]= get_next_node(iter2);
- }
- }
-
- for (int i= 0; i < n; i++)
- {
- init_get_next_node(iter);
- fprintf(stderr, "%d dead:(", g);
- id= 0;
- while (id == 0)
- {
- if ((id= get_next_node(iter)) == 0)
- break;
- for (int j= 0; j < g; j++)
- {
- if (nodes[j] == id)
- {
- fprintf(stderr, " %d", id);
- id= 0;
- break;
- }
- }
- }
- fprintf(stderr, ")");
- if (id == 0)
- {
- break;
- }
- fprintf(stderr, " %d\n", id);
- }
- fprintf(stderr, "\n");
- }
- }
- delete [] nodes;
-}
-
-void Ndb_cluster_connection::set_name(const char *name)
-{
- m_impl.set_name(name);
-}
-
-int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds,
- int verbose)
-{
- struct ndb_mgm_reply mgm_reply;
-
- DBUG_ENTER("Ndb_cluster_connection::connect");
- do {
- if (m_impl.m_config_retriever == 0)
- DBUG_RETURN(-1);
- if (m_impl.m_config_retriever->do_connect(no_retries,
- retry_delay_in_seconds,
- verbose))
- DBUG_RETURN(1); // mgmt server not up yet
-
- Uint32 nodeId = m_impl.m_config_retriever->allocNodeId(4/*retries*/,
- 3/*delay*/);
- if(nodeId == 0)
- break;
- ndb_mgm_configuration * props = m_impl.m_config_retriever->getConfig();
- if(props == 0)
- break;
-
- m_impl.m_transporter_facade->start_instance(nodeId, props);
- if (m_impl.init_nodes_vector(nodeId, *props))
- {
- ndbout_c("Ndb_cluster_connection::connect: malloc failure");
- DBUG_RETURN(-1);
- }
-
- for(unsigned i=0;
- i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size();
- i++)
- ndb_mgm_set_connection_int_parameter(m_impl.m_config_retriever->get_mgmHandle(),
- nodeId,
- m_impl.m_transporter_facade->get_registry()
- ->m_transporter_interface[i]
- .m_remote_nodeId,
- CFG_CONNECTION_SERVER_PORT,
- m_impl.m_transporter_facade->get_registry()
- ->m_transporter_interface[i]
- .m_s_service_port,
- &mgm_reply);
-
- ndb_mgm_destroy_configuration(props);
- m_impl.m_transporter_facade->connected();
- DBUG_RETURN(0);
- } while(0);
-
- ndbout << "Configuration error: ";
- const char* erString = m_impl.m_config_retriever->getErrorString();
- if (erString == 0) {
- erString = "No error specified!";
- }
- ndbout << erString << endl;
- DBUG_RETURN(-1);
-}
-
-void Ndb_cluster_connection_impl::connect_thread()
-{
- DBUG_ENTER("Ndb_cluster_connection_impl::connect_thread");
- int r;
- do {
- NdbSleep_SecSleep(1);
- if ((r = connect(0,0,0)) == 0)
- break;
- if (r == -1) {
- printf("Ndb_cluster_connection::connect_thread error\n");
- DBUG_ASSERT(false);
- m_run_connect_thread= 0;
- } else {
- // Wait before making a new connect attempt
- NdbSleep_SecSleep(1);
- }
- } while (m_run_connect_thread);
- if (m_connect_callback)
- (*m_connect_callback)();
- DBUG_VOID_RETURN;
-}
-
-Uint64 *
-Ndb_cluster_connection::get_latest_trans_gci()
-{
- return m_impl.get_latest_trans_gci();
-}
-
-void
-Ndb_cluster_connection::init_get_next_node(Ndb_cluster_connection_node_iter &iter)
-{
- m_impl.init_get_next_node(iter);
-}
-
-Uint32
-Ndb_cluster_connection::get_next_node(Ndb_cluster_connection_node_iter &iter)
-{
- return m_impl.get_next_node(iter);
-}
-
-unsigned
-Ndb_cluster_connection::get_active_ndb_objects() const
-{
- return m_impl.m_transporter_facade->get_active_ndb_objects();
-}
-
-int Ndb_cluster_connection::set_timeout(int timeout_ms)
-{
- return ndb_mgm_set_timeout(m_impl.m_config_retriever->get_mgmHandle(),
- timeout_ms);
-}
-
-template class Vector<Ndb_cluster_connection_impl::Node>;
-
diff --git a/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
deleted file mode 100644
index d299f44ed9a..00000000000
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright (c) 2003-2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#ifndef CLUSTER_CONNECTION_IMPL_HPP
-#define CLUSTER_CONNECTION_IMPL_HPP
-
-#include <ndb_cluster_connection.hpp>
-#include <Vector.hpp>
-#include <NdbMutex.h>
-
-extern NdbMutex *g_ndb_connection_mutex;
-
-class TransporterFacade;
-class ConfigRetriever;
-class NdbThread;
-class ndb_mgm_configuration;
-
-extern "C" {
- void* run_ndb_cluster_connection_connect_thread(void*);
-}
-
-class Ndb_cluster_connection_impl : public Ndb_cluster_connection
-{
- Ndb_cluster_connection_impl(const char *connectstring);
- ~Ndb_cluster_connection_impl();
-
- void do_test();
-
- void init_get_next_node(Ndb_cluster_connection_node_iter &iter);
- Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter);
-
- inline unsigned get_connect_count() const;
-public:
- inline Uint64 *get_latest_trans_gci() { return &m_latest_trans_gci; }
-
-private:
- friend class Ndb;
- friend class NdbImpl;
- friend void* run_ndb_cluster_connection_connect_thread(void*);
- friend class Ndb_cluster_connection;
- friend class NdbEventBuffer;
-
- struct Node
- {
- Node(Uint32 _g= 0, Uint32 _id= 0) : this_group(0),
- next_group(0),
- group(_g),
- id(_id) {};
- Uint32 this_group;
- Uint32 next_group;
- Uint32 group;
- Uint32 id;
- };
-
- Vector<Node> m_all_nodes;
- int init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config);
- void connect_thread();
- void set_name(const char *name);
-
- TransporterFacade *m_transporter_facade;
- ConfigRetriever *m_config_retriever;
- NdbThread *m_connect_thread;
- int (*m_connect_callback)(void);
-
- int m_optimized_node_selection;
- char *m_name;
- int m_run_connect_thread;
- NdbMutex *m_event_add_drop_mutex;
- Uint64 m_latest_trans_gci;
-};
-
-#endif
diff --git a/storage/ndb/src/ndbapi/ndb_internal.hpp b/storage/ndb/src/ndbapi/ndb_internal.hpp
deleted file mode 100644
index 4b9ed63ab07..00000000000
--- a/storage/ndb/src/ndbapi/ndb_internal.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "NdbImpl.hpp"
-
-class Ndb_internal
-{
-private:
- friend class NdbEventBuffer;
- Ndb_internal() {}
- virtual ~Ndb_internal() {}
- static int send_event_report(Ndb *ndb, Uint32 *data, Uint32 length)
- { return ndb->theImpl->send_event_report(data, length); }
-};
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
deleted file mode 100644
index 24bf70a6635..00000000000
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/* Copyright (c) 2003-2008 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-
-#include <ndb_global.h>
-#include <my_base.h>
-#include <ndberror.h>
-#include <m_string.h>
-
-#include "../mgmsrv/ndb_mgmd_error.h"
-
-
-typedef struct ErrorBundle {
- int code;
- int mysql_code;
- ndberror_classification classification;
- const char * message;
-} ErrorBundle;
-
-/**
- * Shorter names in table below
- */
-
-#define ST_S ndberror_st_success
-#define ST_P ndberror_st_permanent
-#define ST_T ndberror_st_temporary
-#define ST_U ndberror_st_unknown
-
-#define NE ndberror_cl_none
-#define AE ndberror_cl_application
-#define CE ndberror_cl_configuration
-#define ND ndberror_cl_no_data_found
-#define CV ndberror_cl_constraint_violation
-#define SE ndberror_cl_schema_error
-#define UD ndberror_cl_user_defined
-
-#define IS ndberror_cl_insufficient_space
-#define TR ndberror_cl_temporary_resource
-#define NR ndberror_cl_node_recovery
-#define OL ndberror_cl_overload
-#define TO ndberror_cl_timeout_expired
-#define NS ndberror_cl_node_shutdown
-
-#define UR ndberror_cl_unknown_result
-
-#define IE ndberror_cl_internal_error
-#define NI ndberror_cl_function_not_implemented
-#define UE ndberror_cl_unknown_error_code
-
-#define OE ndberror_cl_schema_object_already_exists
-
-#define IT ndberror_cl_internal_temporary
-
-/* default mysql error code for unmapped codes */
-#define DMEC -1
-
-static const char* empty_string = "";
-
-/*
- * Error code ranges are reserved for respective block
- *
- * 200 - TC
- * 300 - DIH
- * 400 - LQH
- * 600 - ACC
- * 700 - DICT
- * 800 - TUP
- * 900 - TUX
- * 1200 - LQH
- * 1300 - BACKUP
- * 1400 - SUMA
- * 1500 - LGMAN
- * 1600 - TSMAN
- * 1700 - QMGR
- * 4000 - API
- * 4100 - ""
- * 4200 - ""
- * 4300 - ""
- * 4400 - ""
- * 4500 - ""
- * 4600 - ""
- * 4700 - "" Event
- * 5000 - Management server
- */
-
-static
-const
-ErrorBundle ErrorCodes[] = {
- /**
- * No error
- */
- { 0, 0, NE, "No error" },
-
- /**
- * NoDataFound
- */
- { 626, HA_ERR_KEY_NOT_FOUND, ND, "Tuple did not exist" },
-
- /**
- * ConstraintViolation
- */
- { 630, HA_ERR_FOUND_DUPP_KEY, CV, "Tuple already existed when attempting to insert" },
- { 839, DMEC, CV, "Illegal null attribute" },
- { 840, DMEC, CV, "Trying to set a NOT NULL attribute to NULL" },
- { 893, HA_ERR_FOUND_DUPP_KEY, CV, "Constraint violation e.g. duplicate value in unique index" },
-
- /**
- * Node recovery errors
- */
- { 286, DMEC, NR, "Node failure caused abort of transaction" },
- { 250, DMEC, NR, "Node where lock was held crashed, restart scan transaction" },
- { 499, DMEC, NR, "Scan take over error, restart scan transaction" },
- { 1204, DMEC, NR, "Temporary failure, distribution changed" },
- { 4002, DMEC, NR, "Send to NDB failed" },
- { 4010, DMEC, NR, "Node failure caused abort of transaction" },
- { 4025, DMEC, NR, "Node failure caused abort of transaction" },
- { 4027, DMEC, NR, "Node failure caused abort of transaction" },
- { 4028, DMEC, NR, "Node failure caused abort of transaction" },
- { 4029, DMEC, NR, "Node failure caused abort of transaction" },
- { 4031, DMEC, NR, "Node failure caused abort of transaction" },
- { 4033, DMEC, NR, "Send to NDB failed" },
- { 4115, DMEC, NR,
- "Transaction was committed but all read information was not "
- "received due to node crash" },
- { 4119, DMEC, NR, "Simple/dirty read failed due to node failure" },
-
- /**
- * Node shutdown
- */
- { 280, DMEC, NS, "Transaction aborted due to node shutdown" },
- /* This scan trans had an active fragment scan in a LQH which have crashed */
- { 270, DMEC, NS, "Transaction aborted due to node shutdown" },
- { 1223, DMEC, NS, "Read operation aborted due to node shutdown" },
- { 4023, DMEC, NS, "Transaction aborted due to node shutdown" },
- { 4030, DMEC, NS, "Transaction aborted due to node shutdown" },
- { 4034, DMEC, NS, "Transaction aborted due to node shutdown" },
-
-
-
- /**
- * Unknown result
- */
- { 4007, DMEC, UR, "Send to ndbd node failed" },
- { 4008, DMEC, UR, "Receive from NDB failed" },
- { 4009, HA_ERR_NO_CONNECTION, UR, "Cluster Failure" },
- { 4012, DMEC, UR,
- "Request ndbd time-out, maybe due to high load or communication problems"},
- { 4013, DMEC, UR, "Request timed out in waiting for node failure"},
- { 4024, DMEC, UR,
- "Time-out, most likely caused by simple read or cluster failure" },
-
- /**
- * TemporaryResourceError
- */
- { 217, DMEC, TR, "217" },
- { 218, DMEC, TR, "218" },
- { 219, DMEC, TR, "219" },
- { 233, DMEC, TR,
- "Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)" },
- { 275, DMEC, TR, "Out of transaction records for complete phase (increase MaxNoOfConcurrentTransactions)" },
- { 279, DMEC, TR, "Out of transaction markers in transaction coordinator" },
- { 414, DMEC, TR, "414" },
- { 418, DMEC, TR, "Out of transaction buffers in LQH" },
- { 419, DMEC, TR, "419" },
- { 245, DMEC, TR, "Too many active scans" },
- { 488, DMEC, TR, "Too many active scans" },
- { 490, DMEC, TR, "Too many active scans" },
- { 805, DMEC, TR, "Out of attrinfo records in tuple manager" },
- { 830, DMEC, TR, "Out of add fragment operation records" },
- { 873, DMEC, TR, "Out of attrinfo records for scan in tuple manager" },
- { 899, DMEC, TR, "Rowid already allocated" },
- { 1217, DMEC, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" },
- { 1220, DMEC, TR, "REDO log files overloaded, consult online manual (increase FragmentLogFileSize)" },
- { 1222, DMEC, TR, "Out of transaction markers in LQH" },
- { 4021, DMEC, TR, "Out of Send Buffer space in NDB API" },
- { 4022, DMEC, TR, "Out of Send Buffer space in NDB API" },
- { 4032, DMEC, TR, "Out of Send Buffer space in NDB API" },
- { 1501, DMEC, TR, "Out of undo space" },
- { 288, DMEC, TR, "Out of index operations in transaction coordinator (increase MaxNoOfConcurrentIndexOperations)" },
- { 289, DMEC, TR, "Out of transaction buffer memory in TC (increase TransactionBufferMemory)" },
-
- /**
- * InsufficientSpace
- */
- { 623, HA_ERR_RECORD_FILE_FULL, IS, "623" },
- { 624, HA_ERR_RECORD_FILE_FULL, IS, "624" },
- { 625, HA_ERR_INDEX_FILE_FULL, IS, "Out of memory in Ndb Kernel, hash index part (increase IndexMemory)" },
- { 640, DMEC, IS, "Too many hash indexes (should not happen)" },
- { 826, HA_ERR_RECORD_FILE_FULL, IS, "Too many tables and attributes (increase MaxNoOfAttributes or MaxNoOfTables)" },
- { 827, HA_ERR_RECORD_FILE_FULL, IS, "Out of memory in Ndb Kernel, table data (increase DataMemory)" },
- { 902, HA_ERR_RECORD_FILE_FULL, IS, "Out of memory in Ndb Kernel, ordered index data (increase DataMemory)" },
- { 903, HA_ERR_INDEX_FILE_FULL, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" },
- { 904, HA_ERR_INDEX_FILE_FULL, IS, "Out of fragment records (increase MaxNoOfOrderedIndexes)" },
- { 905, DMEC, IS, "Out of attribute records (increase MaxNoOfAttributes)" },
- { 1601, HA_ERR_RECORD_FILE_FULL, IS, "Out extents, tablespace full" },
- { 1602, DMEC, IS,"No datafile in tablespace" },
-
- /**
- * TimeoutExpired
- */
- { 266, HA_ERR_LOCK_WAIT_TIMEOUT, TO, "Time-out in NDB, probably caused by deadlock" },
- { 274, HA_ERR_LOCK_WAIT_TIMEOUT, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout */
- { 296, HA_ERR_LOCK_WAIT_TIMEOUT, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout */
- { 297, HA_ERR_LOCK_WAIT_TIMEOUT, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout, temporary!! */
- { 237, HA_ERR_LOCK_WAIT_TIMEOUT, TO, "Transaction had timed out when trying to commit it" },
-
- /**
- * OverloadError
- */
- { 701, DMEC, OL, "System busy with other schema operation" },
- { 711, DMEC, OL, "System busy with node restart, schema operations not allowed" },
- { 410, DMEC, OL, "REDO log files overloaded, consult online manual (decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)" },
- { 677, DMEC, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" },
- { 891, DMEC, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" },
- { 1221, DMEC, OL, "REDO buffers overloaded, consult online manual (increase RedoBuffer)" },
- { 4006, DMEC, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" },
-
-
- /*
- * Internal Temporary
- */
- { 702, DMEC, IT, "Request to non-master" },
-
- /**
- * Internal errors
- */
- { 896, DMEC, IE, "Tuple corrupted - wrong checksum or column data in invalid format" },
- { 901, DMEC, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" },
- { 202, DMEC, IE, "202" },
- { 203, DMEC, IE, "203" },
- { 207, DMEC, IE, "207" },
- { 208, DMEC, IE, "208" },
- { 209, DMEC, IE, "Communication problem, signal error" },
- { 220, DMEC, IE, "220" },
- { 230, DMEC, IE, "230" },
- { 232, DMEC, IE, "232" },
- { 238, DMEC, IE, "238" },
- { 271, DMEC, IE, "Simple Read transaction without any attributes to read" },
- { 272, DMEC, IE, "Update operation without any attributes to update" },
- { 276, DMEC, IE, "276" },
- { 277, DMEC, IE, "277" },
- { 278, DMEC, IE, "278" },
- { 287, DMEC, IE, "Index corrupted" },
- { 290, DMEC, IE, "Corrupt key in TC, unable to xfrm" },
- { 631, DMEC, IE, "631" },
- { 632, DMEC, IE, "632" },
- { 706, DMEC, IE, "Inconsistency during table creation" },
- { 809, DMEC, IE, "809" },
- { 812, DMEC, IE, "812" },
- { 829, DMEC, IE, "829" },
- { 833, DMEC, IE, "833" },
- { 871, DMEC, IE, "871" },
- { 882, DMEC, IE, "882" },
- { 883, DMEC, IE, "883" },
- { 887, DMEC, IE, "887" },
- { 888, DMEC, IE, "888" },
- { 890, DMEC, IE, "890" },
- { 4000, DMEC, IE, "MEMORY ALLOCATION ERROR" },
- { 4001, DMEC, IE, "Signal Definition Error" },
- { 4005, DMEC, IE, "Internal Error in NdbApi" },
- { 4011, DMEC, IE, "Internal Error in NdbApi" },
- { 4107, DMEC, IE, "Simple Transaction and Not Start" },
- { 4108, DMEC, IE, "Faulty operation type" },
- { 4109, DMEC, IE, "Faulty primary key attribute length" },
- { 4110, DMEC, IE, "Faulty length in ATTRINFO signal" },
- { 4111, DMEC, IE, "Status Error in NdbConnection" },
- { 4113, DMEC, IE, "Too many operations received" },
- { 4320, DMEC, IE, "Cannot use the same object twice to create table" },
- { 4321, DMEC, IE, "Trying to start two schema transactions" },
- { 4344, DMEC, IE, "Only DBDICT and TRIX can send requests to TRIX" },
- { 4345, DMEC, IE, "TRIX block is not available yet, probably due to node failure" },
- { 4346, DMEC, IE, "Internal error at index create/build" },
- { 4347, DMEC, IE, "Bad state at alter index" },
- { 4348, DMEC, IE, "Inconsistency detected at alter index" },
- { 4349, DMEC, IE, "Inconsistency detected at index usage" },
- { 4350, DMEC, IE, "Transaction already aborted" },
-
- /**
- * Application error
- */
- { 281, HA_ERR_NO_CONNECTION, AE, "Operation not allowed due to cluster shutdown in progress" },
- { 299, DMEC, AE, "Operation not allowed or aborted due to single user mode" },
- { 763, DMEC, AE, "Alter table requires cluster nodes to have exact same version" },
- { 823, DMEC, AE, "Too much attrinfo from application in tuple manager" },
- { 831, DMEC, AE, "Too many nullable/bitfields in table definition" },
- { 876, DMEC, AE, "876" },
- { 877, DMEC, AE, "877" },
- { 878, DMEC, AE, "878" },
- { 879, DMEC, AE, "879" },
- { 880, DMEC, AE, "Tried to read too much - too many getValue calls" },
- { 884, DMEC, AE, "Stack overflow in interpreter" },
- { 885, DMEC, AE, "Stack underflow in interpreter" },
- { 886, DMEC, AE, "More than 65535 instructions executed in interpreter" },
- { 897, DMEC, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" },
- { 892, DMEC, AE, "Unsupported type in scan filter" },
- { 4256, DMEC, AE, "Must call Ndb::init() before this function" },
- { 4257, DMEC, AE, "Tried to read too much - too many getValue calls" },
-
- /**
- * Scan application errors
- */
- { 242, DMEC, AE, "Zero concurrency in scan"},
- { 244, DMEC, AE, "Too high concurrency in scan"},
- { 269, DMEC, AE, "No condition and attributes to read in scan"},
- { 874, DMEC, AE, "Too much attrinfo (e.g. scan filter) for scan in tuple manager" },
- { 4600, DMEC, AE, "Transaction is already started"},
- { 4601, DMEC, AE, "Transaction is not started"},
- { 4602, DMEC, AE, "You must call getNdbOperation before executeScan" },
- { 4603, DMEC, AE, "There can only be ONE operation in a scan transaction" },
- { 4604, DMEC, AE, "takeOverScanOp, to take over a scanned row one must explicitly request keyinfo on readTuples call" },
- { 4605, DMEC, AE, "You may only call openScanRead or openScanExclusive once for each operation"},
- { 4607, DMEC, AE, "There may only be one operation in a scan transaction"},
- { 4608, DMEC, AE, "You can not takeOverScan unless you have used openScanExclusive"},
- { 4609, DMEC, AE, "You must call nextScanResult before trying to takeOverScan"},
- { 4232, DMEC, AE, "Parallelism can only be between 1 and 240" },
-
- /**
- * Event schema errors
- */
-
- { 4713, DMEC, SE, "Column defined in event does not exist in table"},
-
- /**
- * Event application errors
- */
-
- { 4707, DMEC, AE, "Too many event have been defined"},
- { 4708, DMEC, AE, "Event name is too long"},
- { 4709, DMEC, AE, "Can't accept more subscribers"},
- { 746, DMEC, OE, "Event name already exists"},
- { 747, DMEC, IS, "Out of event records"},
- { 748, DMEC, TR, "Busy during read of event table"},
- { 4710, DMEC, AE, "Event not found"},
- { 4711, DMEC, AE, "Creation of event failed"},
- { 4712, DMEC, AE, "Stopped event operation does not exist. Already stopped?"},
-
- /**
- * Event internal errors
- */
-
- { 4731, DMEC, IE, "Event not found"},
-
- /**
- * SchemaError
- */
- { 311, DMEC, AE, "Undefined partition used in setPartitionId" },
- { 703, DMEC, SE, "Invalid table format" },
- { 704, DMEC, SE, "Attribute name too long" },
- { 705, DMEC, SE, "Table name too long" },
- { 707, DMEC, SE, "No more table metadata records (increase MaxNoOfTables)" },
- { 708, DMEC, SE, "No more attribute metadata records (increase MaxNoOfAttributes)" },
- { 709, HA_ERR_NO_SUCH_TABLE, SE, "No such table existed" },
- { 710, DMEC, SE, "Internal: Get by table name not supported, use table id." },
- { 721, HA_ERR_TABLE_EXIST, OE, "Table or index with given name already exists" },
- { 723, HA_ERR_NO_SUCH_TABLE, SE, "No such table existed" },
- { 736, DMEC, SE, "Unsupported array size" },
- { 737, HA_WRONG_CREATE_OPTION, SE, "Attribute array size too big" },
- { 738, HA_WRONG_CREATE_OPTION, SE, "Record too big" },
- { 739, HA_WRONG_CREATE_OPTION, SE, "Unsupported primary key length" },
- { 740, HA_WRONG_CREATE_OPTION, SE, "Nullable primary key not supported" },
- { 741, DMEC, SE, "Unsupported alter table" },
- { 743, HA_WRONG_CREATE_OPTION, SE, "Unsupported character set in table or index" },
- { 744, DMEC, SE, "Character string is invalid for given character set" },
- { 745, HA_WRONG_CREATE_OPTION, SE, "Distribution key not supported for char attribute (use binary attribute)" },
- { 771, HA_WRONG_CREATE_OPTION, AE, "Given NODEGROUP doesn't exist in this cluster" },
- { 772, HA_WRONG_CREATE_OPTION, IE, "Given fragmentType doesn't exist" },
- { 749, HA_WRONG_CREATE_OPTION, IE, "Primary Table in wrong state" },
- { 779, HA_WRONG_CREATE_OPTION, SE, "Invalid undo buffer size" },
- { 764, HA_WRONG_CREATE_OPTION, SE, "Invalid extent size" },
- { 765, DMEC, SE, "Out of filegroup records" },
- { 750, IE, SE, "Invalid file type" },
- { 751, DMEC, SE, "Out of file records" },
- { 752, DMEC, SE, "Invalid file format" },
- { 753, IE, SE, "Invalid filegroup for file" },
- { 754, IE, SE, "Invalid filegroup version when creating file" },
- { 755, HA_WRONG_CREATE_OPTION, SE, "Invalid tablespace" },
- { 756, DMEC, SE, "Index on disk column is not supported" },
- { 757, DMEC, SE, "Varsize bitfield not supported" },
- { 758, DMEC, SE, "Tablespace has changed" },
- { 759, DMEC, SE, "Invalid tablespace version " },
- { 760, DMEC, SE, "File already exists", },
- { 761, DMEC, SE, "Unable to drop table as backup is in progress" },
- { 762, DMEC, SE, "Unable to alter table as backup is in progress" },
- { 766, DMEC, SE, "Cant drop file, no such file" },
- { 767, DMEC, SE, "Cant drop filegroup, no such filegroup" },
- { 768, DMEC, SE, "Cant drop filegroup, filegroup is used" },
- { 769, DMEC, SE, "Drop undofile not supported, drop logfile group instead" },
- { 770, DMEC, SE, "Cant drop file, file is used" },
- { 774, DMEC, SE, "Invalid schema object for drop" },
- { 241, HA_ERR_TABLE_DEF_CHANGED, SE, "Invalid schema object version" },
- { 283, HA_ERR_NO_SUCH_TABLE, SE, "Table is being dropped" },
- { 284, HA_ERR_TABLE_DEF_CHANGED, SE, "Table not defined in transaction coordinator" },
- { 285, DMEC, SE, "Unknown table error in transaction coordinator" },
- { 881, DMEC, SE, "Unable to create table, out of data pages (increase DataMemory) " },
- { 906, DMEC, SE, "Unsupported attribute type in index" },
- { 907, DMEC, SE, "Unsupported character set in table or index" },
- { 908, DMEC, IS, "Invalid ordered index tree node size" },
- { 1225, DMEC, SE, "Table not defined in local query handler" },
- { 1226, DMEC, SE, "Table is being dropped" },
- { 1228, DMEC, SE, "Cannot use drop table for drop index" },
- { 1229, DMEC, SE, "Too long frm data supplied" },
- { 1231, DMEC, SE, "Invalid table or index to scan" },
- { 1232, DMEC, SE, "Invalid table or index to scan" },
-
- { 1502, DMEC, IE, "Filegroup already exists" },
- { 1503, DMEC, SE, "Out of filegroup records" },
- { 1504, DMEC, SE, "Out of logbuffer memory" },
- { 1505, DMEC, IE, "Invalid filegroup" },
- { 1506, DMEC, IE, "Invalid filegroup version" },
- { 1507, DMEC, IE, "File no already inuse" },
- { 1508, DMEC, SE, "Out of file records" },
- { 1509, DMEC, SE, "File system error, check if path,permissions etc" },
- { 1510, DMEC, IE, "File meta data error" },
- { 1511, DMEC, IE, "Out of memory" },
- { 1512, DMEC, SE, "File read error" },
- { 1513, DMEC, IE, "Filegroup not online" },
- { 1514, DMEC, SE, "Currently there is a limit of one logfile group" },
- { 1515, DMEC, SE, "Currently there is a 4G limit of one undo/data-file in 32-bit host" },
-
- { 773, DMEC, SE, "Out of string memory, please modify StringMemory config parameter" },
- { 775, DMEC, SE, "Create file is not supported when Diskless=1" },
- { 776, DMEC, AE, "Index created on temporary table must itself be temporary" },
- { 777, DMEC, AE, "Cannot create a temporary index on a non-temporary table" },
- { 778, DMEC, AE, "A temporary table or index must be specified as not logging" },
-
- /**
- * FunctionNotImplemented
- */
- { 4003, DMEC, NI, "Function not implemented yet" },
-
- /**
- * Backup error codes
- */
-
- { 1300, DMEC, IE, "Undefined error" },
- { 1301, DMEC, IE, "Backup issued to not master (reissue command to master)" },
- { 1302, DMEC, IE, "Out of backup record" },
- { 1303, DMEC, IS, "Out of resources" },
- { 1304, DMEC, IE, "Sequence failure" },
- { 1305, DMEC, IE, "Backup definition not implemented" },
- { 1306, DMEC, AE, "Backup not supported in diskless mode (change Diskless)" },
-
- { 1321, DMEC, UD, "Backup aborted by user request" },
- { 1322, DMEC, IE, "Backup already completed" },
- { 1323, DMEC, IE, "1323" },
- { 1324, DMEC, IE, "Backup log buffer full" },
- { 1325, DMEC, IE, "File or scan error" },
- { 1326, DMEC, IE, "Backup abortet due to node failure" },
- { 1327, DMEC, IE, "1327" },
-
- { 1340, DMEC, IE, "Backup undefined error" },
- { 1342, DMEC, AE, "Backup failed to allocate buffers (check configuration)" },
- { 1343, DMEC, AE, "Backup failed to setup fs buffers (check configuration)" },
- { 1344, DMEC, AE, "Backup failed to allocate tables (check configuration)" },
- { 1345, DMEC, AE, "Backup failed to insert file header (check configuration)" },
- { 1346, DMEC, AE, "Backup failed to insert table list (check configuration)" },
- { 1347, DMEC, AE, "Backup failed to allocate table memory (check configuration)" },
- { 1348, DMEC, AE, "Backup failed to allocate file record (check configuration)" },
- { 1349, DMEC, AE, "Backup failed to allocate attribute record (check configuration)" },
- { 1329, DMEC, AE, "Backup during software upgrade not supported" },
-
- /**
- * Node id allocation error codes
- */
-
- { 1700, DMEC, IE, "Undefined error" },
- { 1701, DMEC, AE, "Node already reserved" },
- { 1702, DMEC, AE, "Node already connected" },
- { 1703, DMEC, IT, "Node failure handling not completed" },
- { 1704, DMEC, AE, "Node type mismatch" },
-
- /**
- * Still uncategorized
- */
- { 720, DMEC, AE, "Attribute name reused in table definition" },
- { 1405, DMEC, NR, "Subscriber manager busy with node recovery" },
- { 1407, DMEC, SE, "Subscription not found in subscriber manager" },
- { 1411, DMEC, TR, "Subscriber manager busy with adding/removing a subscriber" },
- { 1412, DMEC, IS, "Can't accept more subscribers, out of space in pool" },
- { 1413, DMEC, TR, "Subscriber manager busy with adding the subscription" },
- { 1414, DMEC, TR, "Subscriber manager has subscribers on this subscription" },
- { 1415, DMEC, SE, "Subscription not unique in subscriber manager" },
- { 1416, DMEC, IS, "Can't accept more subscriptions, out of space in pool" },
- { 1417, DMEC, SE, "Table in suscription not defined, probably dropped" },
- { 1418, DMEC, SE, "Subscription dropped, no new subscribers allowed" },
- { 1419, DMEC, SE, "Subscription already dropped" },
-
- { 1420, DMEC, TR, "Subscriber manager busy with adding/removing a table" },
- { 1421, DMEC, SE, "Partially connected API in NdbOperation::execute()" },
-
- { 4004, DMEC, AE, "Attribute name or id not found in the table" },
-
- { 4100, DMEC, AE, "Status Error in NDB" },
- { 4101, DMEC, AE, "No connections to NDB available and connect failed" },
- { 4102, DMEC, AE, "Type in NdbTamper not correct" },
- { 4103, DMEC, AE, "No schema connections to NDB available and connect failed" },
- { 4104, DMEC, AE, "Ndb Init in wrong state, destroy Ndb object and create a new" },
- { 4105, DMEC, AE, "Too many Ndb objects" },
- { 4106, DMEC, AE, "All Not NULL attribute have not been defined" },
- { 4114, DMEC, AE, "Transaction is already completed" },
- { 4116, DMEC, AE, "Operation was not defined correctly, probably missing a key" },
- { 4117, DMEC, AE, "Could not start transporter, configuration error"},
- { 4118, DMEC, AE, "Parameter error in API call" },
- { 4300, DMEC, AE, "Tuple Key Type not correct" },
- { 4301, DMEC, AE, "Fragment Type not correct" },
- { 4302, DMEC, AE, "Minimum Load Factor not correct" },
- { 4303, DMEC, AE, "Maximum Load Factor not correct" },
- { 4304, DMEC, AE, "Maximum Load Factor smaller than Minimum" },
- { 4305, DMEC, AE, "K value must currently be set to 6" },
- { 4306, DMEC, AE, "Memory Type not correct" },
- { 4307, DMEC, AE, "Invalid table name" },
- { 4308, DMEC, AE, "Attribute Size not correct" },
- { 4309, DMEC, AE, "Fixed array too large, maximum 64000 bytes" },
- { 4310, DMEC, AE, "Attribute Type not correct" },
- { 4311, DMEC, AE, "Storage Mode not correct" },
- { 4312, DMEC, AE, "Null Attribute Type not correct" },
- { 4313, DMEC, AE, "Index only storage for non-key attribute" },
- { 4314, DMEC, AE, "Storage Type of attribute not correct" },
- { 4315, DMEC, AE, "No more key attributes allowed after defining variable length key attribute" },
- { 4316, DMEC, AE, "Key attributes are not allowed to be NULL attributes" },
- { 4317, DMEC, AE, "Too many primary keys defined in table" },
- { 4318, DMEC, AE, "Invalid attribute name or number" },
- { 4319, DMEC, AE, "createAttribute called at erroneus place" },
- { 4322, DMEC, AE, "Attempt to define distribution key when not prepared to" },
- { 4323, DMEC, AE, "Distribution Key set on table but not defined on first attribute" },
- { 4324, DMEC, AE, "Attempt to define distribution group when not prepared to" },
- { 4325, DMEC, AE, "Distribution Group set on table but not defined on first attribute" },
- { 4326, DMEC, AE, "Distribution Group with erroneus number of bits" },
- { 4327, DMEC, AE, "Distribution Group with 1 byte attribute is not allowed" },
- { 4328, DMEC, AE, "Disk memory attributes not yet supported" },
- { 4329, DMEC, AE, "Variable stored attributes not yet supported" },
-
- { 4400, DMEC, AE, "Status Error in NdbSchemaCon" },
- { 4401, DMEC, AE, "Only one schema operation per schema transaction" },
- { 4402, DMEC, AE, "No schema operation defined before calling execute" },
-
- { 4501, DMEC, AE, "Insert in hash table failed when getting table information from Ndb" },
- { 4502, DMEC, AE, "GetValue not allowed in Update operation" },
- { 4503, DMEC, AE, "GetValue not allowed in Insert operation" },
- { 4504, DMEC, AE, "SetValue not allowed in Read operation" },
- { 4505, DMEC, AE, "NULL value not allowed in primary key search" },
- { 4506, DMEC, AE, "Missing getValue/setValue when calling execute" },
- { 4507, DMEC, AE, "Missing operation request when calling execute" },
-
- { 4200, DMEC, AE, "Status Error when defining an operation" },
- { 4201, DMEC, AE, "Variable Arrays not yet supported" },
- { 4202, DMEC, AE, "Set value on tuple key attribute is not allowed" },
- { 4203, DMEC, AE, "Trying to set a NOT NULL attribute to NULL" },
- { 4204, DMEC, AE, "Set value and Read/Delete Tuple is incompatible" },
- { 4205, DMEC, AE, "No Key attribute used to define tuple" },
- { 4206, DMEC, AE, "Not allowed to equal key attribute twice" },
- { 4207, DMEC, AE, "Key size is limited to 4092 bytes" },
- { 4208, DMEC, AE, "Trying to read a non-stored attribute" },
- { 4209, DMEC, AE, "Length parameter in equal/setValue is incorrect" },
- { 4210, DMEC, AE, "Ndb sent more info than the length he specified" },
- { 4211, DMEC, AE, "Inconsistency in list of NdbRecAttr-objects" },
- { 4212, DMEC, AE, "Ndb reports NULL value on Not NULL attribute" },
- { 4213, DMEC, AE, "Not all data of an attribute has been received" },
- { 4214, DMEC, AE, "Not all attributes have been received" },
- { 4215, DMEC, AE, "More data received than reported in TCKEYCONF message" },
- { 4216, DMEC, AE, "More than 8052 bytes in setValue cannot be handled" },
- { 4217, DMEC, AE, "It is not allowed to increment any other than unsigned ints" },
- { 4218, DMEC, AE, "Currently not allowed to increment NULL-able attributes" },
- { 4219, DMEC, AE, "Maximum size of interpretative attributes are 64 bits" },
- { 4220, DMEC, AE, "Maximum size of interpretative attributes are 64 bits" },
- { 4221, DMEC, AE, "Trying to jump to a non-defined label" },
- { 4222, DMEC, AE, "Label was not found, internal error" },
- { 4223, DMEC, AE, "Not allowed to create jumps to yourself" },
- { 4224, DMEC, AE, "Not allowed to jump to a label in a different subroutine" },
- { 4225, DMEC, AE, "All primary keys defined, call setValue/getValue"},
- { 4226, DMEC, AE, "Bad number when defining a label" },
- { 4227, DMEC, AE, "Bad number when defining a subroutine" },
- { 4228, DMEC, AE, "Illegal interpreter function in scan definition" },
- { 4229, DMEC, AE, "Illegal register in interpreter function definition" },
- { 4230, DMEC, AE, "Illegal state when calling getValue, probably not a read" },
- { 4231, DMEC, AE, "Illegal state when calling interpreter routine" },
- { 4233, DMEC, AE, "Calling execute (synchronous) when already prepared asynchronous transaction exists" },
- { 4234, DMEC, AE, "Illegal to call setValue in this state" },
- { 4235, DMEC, AE, "No callback from execute" },
- { 4236, DMEC, AE, "Trigger name too long" },
- { 4237, DMEC, AE, "Too many triggers" },
- { 4238, DMEC, AE, "Trigger not found" },
- { 4239, DMEC, AE, "Trigger with given name already exists"},
- { 4240, DMEC, AE, "Unsupported trigger type"},
- { 4241, DMEC, AE, "Index name too long" },
- { 4242, DMEC, AE, "Too many indexes" },
- { 4243, DMEC, AE, "Index not found" },
- { 4244, HA_ERR_TABLE_EXIST, OE, "Index or table with given name already exists" },
- { 4247, DMEC, AE, "Illegal index/trigger create/drop/alter request" },
- { 4248, DMEC, AE, "Trigger/index name invalid" },
- { 4249, DMEC, AE, "Invalid table" },
- { 4250, DMEC, AE, "Invalid index type or index logging option" },
- { 4251, HA_ERR_FOUND_DUPP_UNIQUE, AE, "Cannot create unique index, duplicate keys found" },
- { 4252, DMEC, AE, "Failed to allocate space for index" },
- { 4253, DMEC, AE, "Failed to create index table" },
- { 4254, DMEC, AE, "Table not an index table" },
- { 4255, DMEC, AE, "Hash index attributes must be specified in same order as table attributes" },
- { 4258, DMEC, AE, "Cannot create unique index, duplicate attributes found in definition" },
- { 4259, DMEC, AE, "Invalid set of range scan bounds" },
- { 4260, DMEC, UD, "NdbScanFilter: Operator is not defined in NdbScanFilter::Group"},
- { 4261, DMEC, UD, "NdbScanFilter: Column is NULL"},
- { 4262, DMEC, UD, "NdbScanFilter: Condition is out of bounds"},
- { 4263, DMEC, IE, "Invalid blob attributes or invalid blob parts table" },
- { 4264, DMEC, AE, "Invalid usage of blob attribute" },
- { 4265, DMEC, AE, "The method is not valid in current blob state" },
- { 4266, DMEC, AE, "Invalid blob seek position" },
- { 4267, DMEC, IE, "Corrupted blob value" },
- { 4268, DMEC, IE, "Error in blob head update forced rollback of transaction" },
- { 4269, DMEC, IE, "No connection to ndb management server" },
- { 4270, DMEC, IE, "Unknown blob error" },
- { 4335, DMEC, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" },
- { 4271, DMEC, AE, "Invalid index object, not retrieved via getIndex()" },
- { 4272, DMEC, AE, "Table definition has undefined column" },
- { 4273, DMEC, IE, "No blob table in dict cache" },
- { 4274, DMEC, IE, "Corrupted main table PK in blob operation" },
- { 4275, DMEC, AE, "The blob method is incompatible with operation type or lock mode" },
- { 4294, DMEC, AE, "Scan filter is too large, discarded" },
- { 2810, DMEC, TR, "No space left on the device" },
- { 2815, DMEC, TR, "Error in reading files, please check file system" },
-
- { NO_CONTACT_WITH_PROCESS, DMEC, AE,
- "No contact with the process (dead ?)."},
- { WRONG_PROCESS_TYPE, DMEC, AE,
- "The process has wrong type. Expected a DB process."},
- { SEND_OR_RECEIVE_FAILED, DMEC, AE,
- "Send to process or receive failed."},
- { INVALID_ERROR_NUMBER, DMEC, AE,
- "Invalid error number. Should be >= 0."},
- { INVALID_TRACE_NUMBER, DMEC, AE,
- "Invalid trace number."},
- { INVALID_BLOCK_NAME, DMEC, AE,
- "Invalid block name"},
- { NODE_SHUTDOWN_IN_PROGESS, DMEC, AE,
- "Node shutdown in progress" },
- { SYSTEM_SHUTDOWN_IN_PROGRESS, DMEC, AE,
- "System shutdown in progress" },
- { NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH, DMEC, AE,
- "Node shutdown would cause system crash" },
- { UNSUPPORTED_NODE_SHUTDOWN, DMEC, AE,
- "Unsupported multi node shutdown. Abort option required." },
- { NODE_NOT_API_NODE, DMEC, AE,
- "The specified node is not an API node." },
- { OPERATION_NOT_ALLOWED_START_STOP, DMEC, AE,
- "Operation not allowed while nodes are starting or stopping."},
- { NO_CONTACT_WITH_DB_NODES, DMEC, AE,
- "No contact with database nodes" }
-};
-
-static
-const
-int NbErrorCodes = sizeof(ErrorCodes)/sizeof(ErrorBundle);
-
-typedef struct ErrorStatusMessage {
- ndberror_status status;
- const char * message;
-} ErrorStatusMessage;
-
-typedef struct ErrorStatusClassification {
- ndberror_status status;
- ndberror_classification classification;
- const char * message;
-} ErrorStatusClassification;
-
-/**
- * Mapping between classification and status
- */
-static
-const
-ErrorStatusMessage StatusMessageMapping[] = {
- { ST_S, "Success"},
- { ST_P, "Permanent error"},
- { ST_T, "Temporary error"},
- { ST_U ,"Unknown result"}
-};
-
-static
-const
-int NbStatus = sizeof(StatusMessageMapping)/sizeof(ErrorStatusMessage);
-
-static
-const
-ErrorStatusClassification StatusClassificationMapping[] = {
- { ST_S, NE, "No error"},
- { ST_P, AE, "Application error"},
- { ST_P, CE, "Configuration or application error"},
- { ST_P, ND, "No data found"},
- { ST_P, CV, "Constraint violation"},
- { ST_P, SE, "Schema error"},
- { ST_P, UD, "User defined error"},
- { ST_P, IS, "Insufficient space"},
-
- { ST_T, TR, "Temporary Resource error"},
- { ST_T, NR, "Node Recovery error"},
- { ST_T, OL, "Overload error"},
- { ST_T, TO, "Timeout expired"},
- { ST_T, NS, "Node shutdown"},
- { ST_T, IT, "Internal temporary"},
-
- { ST_U , UR, "Unknown result error"},
- { ST_U , UE, "Unknown error code"},
-
- { ST_P, IE, "Internal error"},
- { ST_P, NI, "Function not implemented"}
-};
-
-static
-const
-int NbClassification = sizeof(StatusClassificationMapping)/sizeof(ErrorStatusClassification);
-
-#ifdef NOT_USED
-/**
- * Complete all fields of an NdbError given the error code
- * and details
- */
-static
-void
-set(ndberror_struct * error, int code, const char * details, ...){
- error->code = code;
- {
- va_list ap;
- va_start(ap, details);
- vsnprintf(error->details, sizeof(error->details), details, ap);
- va_end(ap);
- }
-}
-#endif
-
-void
-ndberror_update(ndberror_struct * error){
-
- int found = 0;
- int i;
-
- for(i = 0; i<NbErrorCodes; i++){
- if(ErrorCodes[i].code == error->code){
- error->classification = ErrorCodes[i].classification;
- error->message = ErrorCodes[i].message;
- error->mysql_code = ErrorCodes[i].mysql_code;
- found = 1;
- break;
- }
- }
-
- if(!found){
- error->classification = UE;
- error->message = "Unknown error code";
- error->mysql_code = DMEC;
- }
-
- found = 0;
- for(i = 0; i<NbClassification; i++){
- if(StatusClassificationMapping[i].classification == error->classification){
- error->status = StatusClassificationMapping[i].status;
- found = 1;
- break;
- }
- }
- if(!found){
- error->status = ST_U;
- }
-}
-
-#if CHECK_ERRORCODES
-int
-checkErrorCodes(){
- int i, j;
- for(i = 0; i<NbErrorCodes; i++)
- for(j = i+1; j<NbErrorCodes; j++)
- if(ErrorCodes[i].code == ErrorCodes[j].code){
- printf("ErrorCode %d is defined multiple times!!\n",
- ErrorCodes[i].code);
- assert(0);
- }
-
- return 1;
-}
-
-/*static const int a = checkErrorCodes();*/
-
-int main(void){
- checkErrorCodes();
- return 0;
-}
-#endif
-
-const char *ndberror_status_message(ndberror_status status)
-{
- int i;
- for (i= 0; i < NbStatus; i++)
- if (StatusMessageMapping[i].status == status)
- return StatusMessageMapping[i].message;
- return empty_string;
-}
-
-const char *ndberror_classification_message(ndberror_classification classification)
-{
- int i;
- for (i= 0; i < NbClassification; i++)
- if (StatusClassificationMapping[i].classification == classification)
- return StatusClassificationMapping[i].message;
- return empty_string;
-}
-
-int ndb_error_string(int err_no, char *str, int size)
-{
- ndberror_struct error;
- int len;
-
- assert(size > 1);
- if(size <= 1)
- return 0;
- error.code = err_no;
- ndberror_update(&error);
-
- len =
- my_snprintf(str, size-1, "%s: %s: %s", error.message,
- ndberror_status_message(error.status),
- ndberror_classification_message(error.classification));
- str[size-1]= '\0';
-
- if (error.classification != UE)
- return len;
- return -len;
-}
diff --git a/storage/ndb/src/ndbapi/ndberror_check.c b/storage/ndb/src/ndbapi/ndberror_check.c
deleted file mode 100644
index 725f0207827..00000000000
--- a/storage/ndb/src/ndbapi/ndberror_check.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2007 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include <stdio.h>
-#include "ndberror.c"
-
-int main()
-{
- int i, j, error = 0;
-
- /* check for duplicate error codes */
- for(i = 0; i < NbErrorCodes; i++)
- {
- for(j = i + 1; j < NbErrorCodes; j++)
- {
- if (ErrorCodes[i].code == ErrorCodes[j].code)
- {
- fprintf(stderr, "Duplicate error code %u\n", ErrorCodes[i].code);
- error = 1;
- }
- }
- }
- if (error)
- return -1;
- return 0;
-}
diff --git a/storage/ndb/src/ndbapi/signal-sender/Makefile b/storage/ndb/src/ndbapi/signal-sender/Makefile
deleted file mode 100644
index 56e6ce1eac0..00000000000
--- a/storage/ndb/src/ndbapi/signal-sender/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-include .defs.mk
-
-TYPE := ndbapi
-
-NONPIC_ARCHIVE := Y
-ARCHIVE_TARGET := signal-sender
-
-BIN_TARGET_LIBS := # -lkalle
-BIN_TARGET_ARCHIVES := portlib # $(NDB_TOP)/lib/libkalle.a
-
-# Source files of non-templated classes (.cpp files)
-SOURCES = SignalSender.cpp
-
-CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/src/ndbapi)
-
-include $(NDB_TOP)/Epilogue.mk
-
-###
-# Backward compatible
diff --git a/storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp b/storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp
deleted file mode 100644
index b68c9a4e6c3..00000000000
--- a/storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#include "SignalSender.hpp"
-#include "ConfigRetriever.hpp"
-#include <NdbSleep.h>
-#include <SignalLoggerManager.hpp>
-
-SimpleSignal::SimpleSignal(bool dealloc){
- memset(this, 0, sizeof(* this));
- deallocSections = dealloc;
-}
-
-SimpleSignal::~SimpleSignal(){
- if(!deallocSections)
- return;
- if(ptr[0].p != 0) delete []ptr[0].p;
- if(ptr[1].p != 0) delete []ptr[1].p;
- if(ptr[2].p != 0) delete []ptr[2].p;
-}
-
-void
-SimpleSignal::set(class SignalSender& ss,
- Uint8 trace, Uint16 recBlock, Uint16 gsn, Uint32 len){
-
- header.theTrace = trace;
- header.theReceiversBlockNumber = recBlock;
- header.theVerId_signalNumber = gsn;
- header.theLength = len;
- header.theSendersBlockRef = refToBlock(ss.getOwnRef());
-}
-
-void
-SimpleSignal::print(FILE * out){
- fprintf(out, "---- Signal ----------------\n");
- SignalLoggerManager::printSignalHeader(out, header, 0, 0, false);
- SignalLoggerManager::printSignalData(out, header, theData);
- for(Uint32 i = 0; i<header.m_noOfSections; i++){
- Uint32 len = ptr[i].sz;
- fprintf(out, " --- Section %d size=%d ---\n", i, len);
- Uint32 * signalData = ptr[i].p;
- while(len >= 7){
- fprintf(out,
- " H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
- signalData[0], signalData[1], signalData[2], signalData[3],
- signalData[4], signalData[5], signalData[6]);
- len -= 7;
- signalData += 7;
- }
- if(len > 0){
- fprintf(out, " H\'%.8x", signalData[0]);
- for(Uint32 i = 1; i<len; i++)
- fprintf(out, " H\'%.8x", signalData[i]);
- fprintf(out, "\n");
- }
- }
-}
-
-SignalSender::SignalSender(const char * connectString){
- m_cond = NdbCondition_Create();
- theFacade = TransporterFacade::start_instance(connectString);
- m_blockNo = theFacade->open(this, execSignal, execNodeStatus);
- assert(m_blockNo > 0);
-}
-
-SignalSender::~SignalSender(){
- theFacade->close(m_blockNo);
- theFacade->stop_instance();
- NdbCondition_Destroy(m_cond);
-}
-
-Uint32
-SignalSender::getOwnRef() const {
- return numberToRef(m_blockNo, theFacade->ownId());
-}
-
-bool
-SignalSender::connectOne(Uint32 timeOutMillis){
- NDB_TICKS start = NdbTick_CurrentMillisecond();
- NDB_TICKS now = start;
- while(theFacade->theClusterMgr->getNoOfConnectedNodes() == 0 &&
- (timeOutMillis == 0 || (now - start) < timeOutMillis)){
- NdbSleep_MilliSleep(100);
- }
- return theFacade->theClusterMgr->getNoOfConnectedNodes() > 0;
-}
-
-bool
-SignalSender::connectAll(Uint32 timeOutMillis){
- NDB_TICKS start = NdbTick_CurrentMillisecond();
- NDB_TICKS now = start;
- while(theFacade->theClusterMgr->getNoOfConnectedNodes() < 1 &&
- (timeOutMillis == 0 || (now - start) < timeOutMillis)){
- NdbSleep_MilliSleep(100);
- }
- return theFacade->theClusterMgr->getNoOfConnectedNodes() >= 1;
-}
-
-
-Uint32
-SignalSender::getAliveNode(){
- return theFacade->get_an_alive_node();
-}
-
-const ClusterMgr::Node &
-SignalSender::getNodeInfo(Uint16 nodeId) const {
- return theFacade->theClusterMgr->getNodeInfo(nodeId);
-}
-
-Uint32
-SignalSender::getNoOfConnectedNodes() const {
- return theFacade->theClusterMgr->getNoOfConnectedNodes();
-}
-
-SendStatus
-SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s){
- return theFacade->theTransporterRegistry->prepareSend(&s->header,
- 1, // JBB
- &s->theData[0],
- nodeId,
- &s->ptr[0]);
-}
-
-template<class T>
-SimpleSignal *
-SignalSender::waitFor(Uint32 timeOutMillis, T & t){
-
- Guard g(theFacade->theMutexPtr);
-
- SimpleSignal * s = t.check(m_jobBuffer);
- if(s != 0){
- return s;
- }
-
- NDB_TICKS now = NdbTick_CurrentMillisecond();
- NDB_TICKS stop = now + timeOutMillis;
- Uint32 wait = (timeOutMillis == 0 ? 10 : timeOutMillis);
- do {
- NdbCondition_WaitTimeout(m_cond,
- theFacade->theMutexPtr,
- wait);
-
-
- SimpleSignal * s = t.check(m_jobBuffer);
- if(s != 0){
- return s;
- }
-
- now = NdbTick_CurrentMillisecond();
- wait = (timeOutMillis == 0 ? 10 : stop - now);
- } while(stop > now || timeOutMillis == 0);
-
- return 0;
-}
-
-class WaitForAny {
-public:
- SimpleSignal * check(Vector<SimpleSignal*> & m_jobBuffer){
- if(m_jobBuffer.size() > 0){
- SimpleSignal * s = m_jobBuffer[0];
- m_jobBuffer.erase(0);
- return s;
- }
- return 0;
- }
-};
-
-SimpleSignal *
-SignalSender::waitFor(Uint32 timeOutMillis){
-
- WaitForAny w;
- return waitFor(timeOutMillis, w);
-}
-
-class WaitForNode {
-public:
- Uint32 m_nodeId;
- SimpleSignal * check(Vector<SimpleSignal*> & m_jobBuffer){
- Uint32 len = m_jobBuffer.size();
- for(Uint32 i = 0; i<len; i++){
- if(refToNode(m_jobBuffer[i]->header.theSendersBlockRef) == m_nodeId){
- SimpleSignal * s = m_jobBuffer[i];
- m_jobBuffer.erase(i);
- return s;
- }
- }
- return 0;
- }
-};
-
-SimpleSignal *
-SignalSender::waitFor(Uint16 nodeId, Uint32 timeOutMillis){
-
- WaitForNode w;
- w.m_nodeId = nodeId;
- return waitFor(timeOutMillis, w);
-}
-
-#include <NdbApiSignal.hpp>
-
-void
-SignalSender::execSignal(void* signalSender,
- NdbApiSignal* signal,
- class LinearSectionPtr ptr[3]){
- SimpleSignal * s = new SimpleSignal(true);
- s->header = * signal;
- memcpy(&s->theData[0], signal->getDataPtr(), 4 * s->header.theLength);
- for(Uint32 i = 0; i<s->header.m_noOfSections; i++){
- s->ptr[i].p = new Uint32[ptr[i].sz];
- s->ptr[i].sz = ptr[i].sz;
- memcpy(s->ptr[i].p, ptr[i].p, 4 * ptr[i].sz);
- }
- SignalSender * ss = (SignalSender*)signalSender;
- ss->m_jobBuffer.push_back(s);
- NdbCondition_Signal(ss->m_cond);
-}
-
-void
-SignalSender::execNodeStatus(void* signalSender,
- Uint16 NodeId,
- bool alive,
- bool nfCompleted){
-}
-
diff --git a/storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp b/storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp
deleted file mode 100644
index 7dab3c0eec6..00000000000
--- a/storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2003-2005 MySQL AB
- Use is subject to license terms
-
- 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; version 2 of the License.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-
-#ifndef SIGNAL_SENDER_HPP
-#define SIGNAL_SENDER_HPP
-
-#include <ndb_global.h>
-#include <TransporterDefinitions.hpp>
-#include <TransporterFacade.hpp>
-#include <ClusterMgr.hpp>
-#include <Vector.hpp>
-
-struct SimpleSignal {
-public:
- SimpleSignal(bool dealloc = false);
- ~SimpleSignal();
-
- void set(class SignalSender&,
- Uint8 trace, Uint16 recBlock, Uint16 gsn, Uint32 len);
-
- struct SignalHeader header;
- Uint32 theData[25];
- LinearSectionPtr ptr[3];
-
- void print(FILE * out = stdout);
-private:
- bool deallocSections;
-};
-
-class SignalSender {
-public:
- SignalSender(const char * connectString = 0);
- virtual ~SignalSender();
-
- bool connectOne(Uint32 timeOutMillis = 0);
- bool connectAll(Uint32 timeOutMillis = 0);
- bool connect(Uint32 timeOutMillis = 0) { return connectAll(timeOutMillis);}
-
- Uint32 getOwnRef() const;
-
- Uint32 getAliveNode();
- Uint32 getNoOfConnectedNodes() const;
- const ClusterMgr::Node & getNodeInfo(Uint16 nodeId) const;
-
- SendStatus sendSignal(Uint16 nodeId, const SimpleSignal *);
-
- SimpleSignal * waitFor(Uint32 timeOutMillis = 0);
- SimpleSignal * waitFor(Uint16 nodeId, Uint32 timeOutMillis = 0);
- SimpleSignal * waitFor(Uint16 nodeId, Uint16 gsn, Uint32 timeOutMillis = 0);
-
-private:
- int m_blockNo;
- TransporterFacade * theFacade;
-
- static void execSignal(void* signalSender,
- NdbApiSignal* signal,
- class LinearSectionPtr ptr[3]);
-
- static void execNodeStatus(void* signalSender, NodeId,
- bool alive, bool nfCompleted);
-
- struct NdbCondition * m_cond;
- Vector<SimpleSignal *> m_jobBuffer;
-
- template<class T>
- SimpleSignal * waitFor(Uint32 timeOutMillis, T & t);
-};
-
-#endif