📄 ndb.hpp
字号:
and restarted. @section secHint Hints and Performance Placing the transaction co-ordinator in close proximity to the actual data used in the transaction can in many cases improve performance significantly. This is particularly true for systems using TCP/IP. For example, a Solaris system using a single 500 MHz processor has a cost model for TCP/IP communication which can be represented by the formula <code>[30 microseconds] + ([100 nanoseconds] * [<var>number of bytes</var>])</code> This means that if we can ensure that we use "popular" links we increase buffering and thus drastically reduce the communication cost. The same system using SCI has a different cost model: <code>[5 microseconds] + ([10 nanoseconds] * [<var>number of bytes</var>])</code> Thus, the efficiency of an SCI system is much less dependent on selection of transaction co-ordinators. Typically, TCP/IP systems spend 30-60% of their working time on communication, whereas for SCI systems this figure is closer to 5-10%. Thus, employing SCI for data transport means that less care from the NDB API programmer is required and greater scalability can be achieved, even for applications using data from many different parts of the database. A simple example is an application that uses many simple updates where a transaction needs to update one record. This record has a 32 bit primary key, which is also the partition key. Then the keyData will be the address of the integer of the primary key and keyLen will be 4.*/#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** (A transaction's execution can also be divided into three steps: prepare, send, and poll. This allows us to perform asynchronous transactions. More about this later.)*/#endif#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** Another way to execute several parallel transactions is to use asynchronous transactions.*/#endif #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** Operations are of two different kinds: -# standard operations, and -# interpreted program operations.*/#endif#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** <h3>Interpreted Program Operations</h3> The following types of interpreted program operations exist: -# NdbOperation::interpretedUpdateTuple : updates a tuple using an interpreted program -# NdbOperation::interpretedDeleteTuple : delete a tuple using an interpreted program The operations interpretedUpdateTuple and interpretedDeleteTuple both work using the unique tuple key. These <em>interpreted programs</em> make it possible to perform computations inside the NDB Cluster Kernel instead of in the application program. This is sometimes very effective, since no intermediate results are sent to the application, only the final result. <h3>Interpreted Update and Delete</h3> Operations for interpreted updates and deletes must follow a certain order when defining operations on a tuple. As for read and write operations, one must first define the operation type and then the search key. -# The first step is to define the initial readings. In this phase it is only allowed to use the NdbOperation::getValue method. This part might be empty. -# The second step is to define the interpreted part. The methods supported are the methods listed below except NdbOperation::def_subroutine and NdbOperation::ret_sub which can only be used in a subroutine. NdbOperation::incValue and NdbOperation::subValue increment and decrement attributes (currently only unsigned integers supported). This part can also be empty since interpreted updates can be used for reading and updating the same tuple. <p> Even though getValue and setValue are not really interpreted program instructions, it is still allowed to use them as the last instruction of the program. (If a getValue or setValue is found when an interpret_exit_ok could have been issued then the interpreted_exit_ok will be inserted. A interpret_exit_ok should be viewed as a jump to the first instruction after the interpreted instructions.) -# The third step is to define all updates without any interpreted program instructions. Here a set of NdbOperation::setValue methods are called. There might be zero such calls. -# The fourth step is the final readings. The initial readings reads the initial value of attributes and the final readings reads them after their updates. There might be zero NdbOperation::getValue calls. -# The fifth step is possible subroutine definitions using NdbOperation::def_subroutine and NdbOperation::ret_sub.*/#endif#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** <h3>Interpreted Programs</h3> Interpretation programs are executed in a register-based virtual machine. The virtual machine has eight 64 bit registers numbered 0-7. Each register contains type information which is used both for type conversion and for type checking. @note Arrays are currently <b>not</b> supported in the virtual machine. Currently only unsigned integers are supported and of size maximum 64 bits. All errors in the interpretation program will cause a transaction abort, but will not affect any other transactions. The following are legal interpreted program instructions: -# incValue : Add to an attribute -# subValue : Subtract from an attribute -# def_label : Define a label in the interpreted program -# add_reg : Add two registers -# sub_reg : Subtract one register from another -# load_const_u32 : Load an unsigned 32 bit value into a register -# load_const_u64 : Load an unsigned 64 bit value into a register -# load_const_null : Load a NULL value into a register -# read_attr : Read attribute value into a register -# write_attr : Write a register value into an attribute -# branch_ge : Compares registers and possibly jumps to specified label -# branch_gt : Compares registers and possibly jumps to specified label -# branch_le : Compares registers and possibly jumps to specified label -# branch_lt : Compares registers and possibly jumps to specified label -# branch_eq : Compares registers and possibly jumps to specified label -# branch_ne : Compares registers and possibly jumps to specified label -# branch_ne_null : Jumps if register does not contain NULL value -# branch_eq_null : Jumps if register contains NULL value -# branch_label : Unconditional jump to label -# interpret_exit_ok : Exit interpreted program (approving tuple if used in scan) -# interpret_exit_nok : Exit interpreted program (disqualifying tuple if used in scan) There are also three instructions for subroutines, which are described in the next section. @subsection subsubSub Interpreted Programs: Subroutines The following are legal interpreted program instructions for subroutines: -# NdbOperation::def_subroutine : Defines start of subroutine in interpreted program code -# NdbOperation::call_sub : Calls a subroutine -# NdbOperation::ret_sub : Return from subroutine The virtual machine executes subroutines using a stack for its operation. The stack allows for up to 24 subroutine calls in succession. Deeper subroutine nesting will cause an abort of the transaction. All subroutines starts with the instruction NdbOperation::def_subroutine and ends with the instruction NdbOperation::ret_sub. If it is necessary to return earlier in the subroutine it has to be done using a branch_label instruction to a label defined right before the NdbOperation::ret_sub instruction. @note The subroutines are automatically numbered starting with 0. The parameter used by NdbOperation::def_subroutine should match the automatic numbering to make it easier to debug the interpreted program.*/#endif#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL/** @section secAsync Asynchronous Transactions The asynchronous interface is used to increase the speed of transaction executing by better utilizing the connection between the application and the NDB Kernel. The interface is used to send many transactions at the same time to the NDB kernel. This is often much more efficient than using synchronous transactions. The main reason for using this method is to ensure that Sending many transactions at the same time ensures that bigger chunks of data are sent when actually sending and thus decreasing the operating system overhead. The synchronous call to NdbTransaction::execute normally performs three main steps:<br> -# <b>Prepare</b> Check transaction status - if problems, abort the transaction - if ok, proceed -# <b>Send</b> Send the defined operations since last execute or since start of transaction. -# <b>Poll</b> Wait for response from NDB kernel. The asynchronous method NdbTransaction::executeAsynchPrepare only perform step 1. (The abort part in step 1 is only prepared for. The actual aborting of the transaction is performed in a later step.) Asynchronous transactions are defined and executed in the following way. -# Start (create) transactions (same way as for the synchronous transactions) -# Add and define operations (also as in the synchronous case) -# <b>Prepare</b> transactions (using NdbTransaction::executeAsynchPrepare or NdbTransaction::executeAsynch) -# <b>Send</b> transactions to NDB Kernel (using Ndb::sendPreparedTransactions, NdbTransaction::executeAsynch, or Ndb::sendPollNdb) -# <b>Poll</b> NDB kernel to find completed transactions (using Ndb::pollNdb or Ndb::sendPollNdb) -# Close transactions (same way as for the synchronous transactions) See example program in section @ref ndbapi_example2.cpp. This prepare-send-poll protocol actually exists in four variants: - (Prepare-Send-Poll). This is the one-step variant provided by synchronous transactions. - (Prepare-Send)-Poll. This is the two-step variant using NdbTransaction::executeAsynch and Ndb::pollNdb. - Prepare-(Send-Poll). This is the two-step variant using NdbTransaction::executeAsynchPrepare and Ndb::sendPollNdb. - Prepare-Send-Poll. This is the three-step variant using NdbTransaction::executeAsynchPrepare, Ndb::sendPreparedTransactions, and Ndb::pollNdb. Transactions first has to be prepared by using method NdbTransaction::executeAsynchPrepare or NdbTransaction::executeAsynch. The difference between these is that NdbTransaction::executeAsynch also sends the transaction to the NDB kernel. One of the arguments to these methods is a callback method. The callback method is executed during polling (item 5 above). Note that NdbTransaction::executeAsynchPrepare does not send the transaction to the NDB kernel. When using NdbTransaction::executeAsynchPrepare, you either have to call Ndb::sendPreparedTransactions or Ndb::sendPollNdb to send the database operations. (Ndb::sendPollNdb also polls Ndb for completed transactions.) The methods Ndb::pollNdb and Ndb::sendPollNdb checks if any sent transactions are completed. The method Ndb::sendPollNdb also send all prepared transactions before polling NDB. Transactions still in the definition phase (i.e. items 1-3 above, transactions which has not yet been sent to the NDB kernel) are not affected by poll-calls. The poll method invoked (either Ndb::pollNdb or Ndb::sendPollNdb) will return when: -# at least 'minNoOfEventsToWakeup' of the transactions are finished processing, and -# all of these transactions have executed their callback methods. The poll method returns the number of transactions that have finished processing and executed their callback methods. @note When an asynchronous transaction has been started and sent to the NDB kernel, it is not allowed to execute any methods on objects belonging to this transaction until the transaction callback method have been executed. (The transaction is stated and sent by either NdbTransaction::executeAsynch or through the combination of NdbTransaction::executeAsynchPrepare and either Ndb::sendPreparedTransactions or Ndb::sendPollNdb). More about how transactions are sent the NDB Kernel is available in section @ref secAdapt.*/#endif/** Put this back when real array ops are supported i.e. get/setValue("kalle[3]"); @subsection secArrays Array Attributes A table attribute in NDB Cluster can be of type <var>Array</var>, meaning that the attribute consists of an ordered sequence of elements. In such cases, <var>attribute size</var> is the size (expressed in bits) of any one element making up the array; the <var>array size</var> is the number of elements in the array.*/#ifndef Ndb_H#define Ndb_H#include <ndb_types.h>#include <ndbapi_limits.h>#include <ndb_cluster_connection.hpp>#include <NdbError.hpp>#include <NdbDictionary.hpp>class NdbObjectIdMap;class NdbOperation;class NdbScanOperation;class NdbIndexScanOperation;class NdbIndexOperation;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -