Ndb.hpp 64.6 KB
Newer Older
1 2 3 4
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
6 7 8 9 10 11 12 13 14 15 16 17 18

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/**
   @mainpage                            NDB API Programmers' Guide

unknown's avatar
unknown committed
19
   This guide assumes a basic familiarity with MySQL Cluster concepts found
unknown's avatar
unknown committed
20
   on http://dev.mysql.com/doc/mysql/en/mysql-cluster.html.
unknown's avatar
unknown committed
21 22
   Some of the fundamental ones are also described in section @ref secConcepts.

23
   The NDB API is a MySQL Cluster application interface 
unknown's avatar
unknown committed
24
   that implements transactions.
25
   The NDB API consists of the following fundamental classes:
26
   - Ndb_cluster_connection, representing a connection to a cluster, 
unknown's avatar
unknown committed
27
   - Ndb is the main class, representing a connection to a database, 
28 29 30 31 32
   - NdbTransaction represents a transaction, 
   - NdbOperation represents an operation using a primary key,
   - NdbScanOperation represents an operation performing a full table scan.
   - NdbIndexOperation represents an operation using a unique hash index,
   - NdbIndexScanOperation represents an operation performing a scan using
unknown's avatar
unknown committed
33
     an ordered index,
34 35
   - NdbRecAttr represents an attribute value
   - NdbDictionary represents meta information about tables and attributes.
36 37 38
     
   In addition, the NDB API defines a structure NdbError, which contains the 
   specification for an error.
unknown's avatar
unknown committed
39

40
   There are also some auxiliary classes, which are listed in the class hierarchy.
41 42
     
   The main structure of an application program is as follows:
43
   -# Connect to a cluster using the Ndb_cluster_connection
unknown's avatar
unknown committed
44
      object.
45
   -# Initiate a database connection by constructing and initialising one or more Ndb objects.
46
   -# Define and execute transactions using the NdbTransaction class.
unknown's avatar
unknown committed
47
   -# Delete Ndb objects.
48
   -# Terminate the connection to the cluster (terminate instance of Ndb_cluster_connection).
49

50 51
   The procedure for using transactions is as follows:
   -# Start transaction (instantiate an NdbTransaction object)
52 53 54
   -# Add and define operations associated with the transaction using instances of one or more of the
      NdbOperation, NdbScanOperation, NdbIndexOperation, and NdbIndexScanOperation classes
   -# Execute transaction (call NdbTransaction::execute())
55

56
   The operation can be of two different types, 
57
   <var>Commit</var> or <var>NoCommit</var>.
58 59
   If the operation is of type <var>NoCommit</var>, 
   then the application program executes the operation part of a transaction,
60
   but without actually committing the transaction.
61
   After executing a <var>NoCommit</var> operation, the program can continue 
62 63 64
   to add and define more operations to the transaction
   for later execution.

65
   If the operation is of type <var>Commit</var>, then the transaction is
66
   immediately committed. The transaction <em>must</em> be closed after it has been 
unknown's avatar
unknown committed
67
   commited (event if commit fails), and no further addition or definition of 
68
   operations for this transaction is allowed.
69 70 71

   @section secSync                     Synchronous Transactions
  
72
   Synchronous transactions are defined and executed as follows:
73
  
74
    -# Start (create) the transaction, which is
75 76
       referenced by an NdbTransaction object 
       (typically created using Ndb::startTransaction()).
77 78
       At this point, the transaction is only being defined,
       and is not yet sent to the NDB kernel.
79 80 81 82 83 84 85
    -# Define operations and add them to the transaction, using one or more of
       - NdbTransaction::getNdbOperation()
       - NdbTransaction::getNdbScanOperation()
       - NdbTransaction::getNdbIndexOperation()
       - NdbTransaction::getNdbIndexScanOperation()
       along with the appropriate methods of the respective NdbOperation class 
       (or one possiblt one or more of its subclasses).
86
       Note that the transaction has still not yet been sent to the NDB kernel.
87
    -# Execute the transaction, using the NdbTransaction::execute() method.
88
    -# Close the transaction (call Ndb::closeTransaction()).
89
  
unknown's avatar
unknown committed
90 91
   For an example of this process, see the program listing in 
   @ref ndbapi_simple.cpp.
92 93

   To execute several parallel synchronous transactions, one can either 
94
   use multiple Ndb objects in several threads, or start multiple 
95
   application programs.  
96

97 98
   @section secNdbOperations            Operations

99
   A NdbTransaction consists of a list of operations, each of which is represented 
100
   by an instance of NdbOperation, NdbScanOperation, NdbIndexOperation, or
unknown's avatar
unknown committed
101
   NdbIndexScanOperation.
102

unknown's avatar
unknown committed
103
   <h3>Single row operations</h3>
104 105
   After the operation is created using NdbTransaction::getNdbOperation()
   (or NdbTransaction::getNdbIndexOperation()), it is defined in the following 
106
   three steps:
107 108 109
   -# Define the standard operation type, using NdbOperation::readTuple()
   -# Specify search conditions, using NdbOperation::equal()
   -# Specify attribute actions, using NdbOperation::getValue()
110

unknown's avatar
unknown committed
111
   Here are two brief examples illustrating this process. For the sake of 
112
   brevity, we omit error handling.
113
   
114
   This first example uses an NdbOperation:
115
   @code
116 117 118 119 120
     // 1. Retrieve table object
     myTable= myDict->getTable("MYTABLENAME");

     // 2. Create
     myOperation= myTransaction->getNdbOperation(myTable);
121
    
122 123
     // 3. Define type of operation and lock mode
     myOperation->readTuple(NdbOperation::LM_Read);
unknown's avatar
unknown committed
124

125 126
     // 4. Specify Search Conditions
     myOperation->equal("ATTR1", i);
127
    
128 129
     // 5. Attribute Actions
     myRecAttr= myOperation->getValue("ATTR2", NULL);
130
   @endcode
unknown's avatar
unknown committed
131
   For additional examples of this sort, see @ref ndbapi_simple.cpp.
132

133
   The second example uses an NdbIndexOperation:
134
   @code
135 136 137 138 139
     // 1. Retrieve index object
     myIndex= myDict->getIndex("MYINDEX", "MYTABLENAME");

     // 2. Create
     myOperation= myTransaction->getNdbIndexOperation(myIndex);
unknown's avatar
unknown committed
140

141 142
     // 3. Define type of operation and lock mode
     myOperation->readTuple(NdbOperation::LM_Read);
143

144 145
     // 4. Specify Search Conditions
     myOperation->equal("ATTR1", i);
146

147 148
     // 5. Attribute Actions 
     myRecAttr = myOperation->getValue("ATTR2", NULL);
149
   @endcode
unknown's avatar
unknown committed
150 151
   Another example of this second type can be found in 
   @ref ndbapi_simple_index.cpp.
152

unknown's avatar
unknown committed
153 154
   We will now discuss in somewhat greater detail each step involved in the 
   creation and use of synchronous transactions.
155

unknown's avatar
unknown committed
156
   <h4>Step 1: Define single row operation type</h4>
157 158
   The following operation types are supported:
    -# NdbOperation::insertTuple() : 
159
       inserts a non-existing tuple
160
    -# NdbOperation::writeTuple() : 
161 162
       updates an existing tuple if is exists,
       otherwise inserts a new tuple
163
    -# NdbOperation::updateTuple() : 
164
       updates an existing tuple
165
    -# NdbOperation::deleteTuple() : 
166
       deletes an existing tuple
167
    -# NdbOperation::readTuple() : 
unknown's avatar
unknown committed
168
       reads an existing tuple with specified lock mode
169 170 171

   All of these operations operate on the unique tuple key.
   (When NdbIndexOperation is used then all of these operations 
unknown's avatar
unknown committed
172
   operate on a defined unique hash index.)
173 174

   @note If you want to define multiple operations within the same transaction,
unknown's avatar
unknown committed
175 176
         then you need to call NdbTransaction::getNdbOperation() or
	 NdbTransaction::getNdbIndexOperation() for each operation.
177 178

   <h4>Step 2: Specify Search Conditions</h4>
179
   The search condition is used to select tuples. Search conditions are set using NdbOperation::equal().
180 181

   <h4>Step 3: Specify Attribute Actions</h4>
182 183 184 185 186 187 188
   Next, it is necessary to determine which attributes should be read or updated.
   It is important to remember that: 
   - Deletes can neither read nor set values, but only delete them
   - Reads can only read values
   - Updates can only set values
   Normally the attribute is identified by name, but it is
   also possible to use the attribute's identity to determine the
189 190
   attribute.

unknown's avatar
unknown committed
191
   NdbOperation::getValue() returns an NdbRecAttr object
192
   containing the read value.
193 194
   To obtain the actual value, one of two methods can be used;
   the application can either
195
   - use its own memory (passed through a pointer aValue) to
unknown's avatar
unknown committed
196
     NdbOperation::getValue(), or
197 198 199
   - receive the attribute value in an NdbRecAttr object allocated
     by the NDB API.

unknown's avatar
unknown committed
200
   The NdbRecAttr object is released when Ndb::closeTransaction()
201
   is called.
202 203 204 205
   Thus, the application cannot reference this object following
   any subsequent call to Ndb::closeTransaction().
   Attempting to read data from an NdbRecAttr object before
   calling NdbTransaction::execute() yields an undefined result.
206 207


208 209
   @subsection secScan              Scan Operations 
   
210 211 212 213
   Scans are roughly the equivalent of SQL cursors, providing a means to
   preform high-speed row processing. A scan can be performed 
   on either a table (using @ref NdbScanOperation) or 
   an ordered index (by means of an @ref NdbIndexScanOperation).
214

215 216
   Scan operations are characterised by the following:
   - They can perform only reads (shared, exclusive or dirty)
217 218
   - They can potentially work with multiple rows
   - They can be used to update or delete multiple rows
219
   - They can operate on several nodes in parallel
220

221
   After the operation is created using NdbTransaction::getNdbScanOperation()
unknown's avatar
unknown committed
222
   (or NdbTransaction::getNdbIndexScanOperation()), 
223
   it is carried out in the following three steps:
224
   -# Define the standard operation type, using NdbScanOperation::readTuples()
unknown's avatar
unknown committed
225 226
   -# Specify search conditions, using @ref NdbScanFilter and/or 
      @ref NdbIndexScanOperation::setBound()
227 228
   -# Specify attribute actions, using NdbOperation::getValue()
   -# Executing the transaction, using NdbTransaction::execute()
229 230
   -# Traversing the result set by means of succssive calls to 
      NdbScanOperation::nextResult()
231

232 233
   Here are two brief examples illustrating this process. Once again, in order
   to keep things relatively short and simple, we will forego any error handling.
234
   
235
   This first example performs a table scan, using an NdbScanOperation:
236
   @code
237 238
     // 1. Retrieve table object
     myTable= myDict->getTable("MYTABLENAME");
239
    
240 241 242 243 244
     // 2. Create
     myOperation= myTransaction->getNdbScanOperation(myTable);
    
     // 3. Define type of operation and lock mode
     myOperation->readTuples(NdbOperation::LM_Read);
245

246 247
     // 4. Specify Search Conditions
     NdbScanFilter sf(myOperation);
248 249 250 251
     sf.begin(NdbScanFilter::OR);
     sf.eq(0, i);   // Return rows with column 0 equal to i or
     sf.eq(1, i+1); // column 1 equal to (i+1)
     sf.end();
252

253 254
     // 5. Attribute Actions
     myRecAttr= myOperation->getValue("ATTR2", NULL);
255
   @endcode
256

257
   Our second example uses an NdbIndexScanOperation to perform an index scan:
258
   @code
259 260 261 262 263
     // 1. Retrieve index object
     myIndex= myDict->getIndex("MYORDEREDINDEX", "MYTABLENAME");

     // 2. Create
     myOperation= myTransaction->getNdbIndexScanOperation(myIndex);
264

265 266
     // 3. Define type of operation and lock mode
     myOperation->readTuples(NdbOperation::LM_Read);
267

268
     // 4. Specify Search Conditions
269
     // All rows with ATTR1 between i and (i+1)
270 271
     myOperation->setBound("ATTR1", NdbIndexScanOperation::BoundGE, i);
     myOperation->setBound("ATTR1", NdbIndexScanOperation::BoundLE, i+1);
272

273 274
     // 5. Attribute Actions 
     myRecAttr = MyOperation->getValue("ATTR2", NULL);
275
   @endcode
276

277 278
   Some additional discussion of each step required to perform a scan follows:

279
   <h4>Step 1: Define Scan Operation Type</h4>
280 281
   It is important to remember that only a single operation is supported for each scan operation 
   (@ref NdbScanOperation::readTuples() or @ref NdbIndexScanOperation::readTuples()).
282

unknown's avatar
unknown committed
283 284 285
   @note If you want to define multiple scan operations within the same 
         transaction, then you need to call 
	 NdbTransaction::getNdbScanOperation() or 
286
	 NdbTransaction::getNdbIndexScanOperation() separately for <b>each</b> operation.
287

288 289 290 291
   <h4>Step 2: Specify Search Conditions</h4>
   The search condition is used to select tuples.
   If no search condition is specified, the scan will return all rows
   in the table.
292

293 294 295 296
   The search condition can be an @ref NdbScanFilter (which can be used on both
   @ref NdbScanOperation and @ref NdbIndexScanOperation) or bounds which
   can only be used on index scans (@ref NdbIndexScanOperation::setBound()).
   An index scan can use both NdbScanFilter and bounds.
297

298 299
   @note When NdbScanFilter is used, each row is examined, whether or not it is
   actually returned. However, when using bounds, only rows within the bounds will be examined.
300

301
   <h4>Step 3: Specify Attribute Actions</h4>
302

303 304 305
   Next, it is necessary to define which attributes should be read.
   As with transaction attributes, scan attributes are defined by name but it is
   also possible to use the attributes' identities to define attributes.
306

307 308
   As previously discussed (see @ref secSync), the value read is returned as 
   an NdbRecAttr object by the NdbOperation::getValue() method.
309

310 311
   <h3>Using Scan to Update/Delete</h3>
   Scanning can also be used to update or delete rows.
312
   This is performed by
313 314
   -# Scanning using exclusive locks (using NdbOperation::LM_Exclusive)
   -# When iterating through the result set, for each row optionally calling 
unknown's avatar
unknown committed
315 316
      either NdbScanOperation::updateCurrentTuple() or 
      NdbScanOperation::deleteCurrentTuple()
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
   -# (If performing NdbScanOperation::updateCurrentTuple():) 
      Setting new values for records simply by using @ref NdbOperation::setValue().
      NdbOperation::equal() should <em>not</em> be called in such cases, as the primary 
      key is retrieved from the scan.

   @note The actual update or delete will not be performed until the next 
   call to NdbTransaction::execute(), just as with single row operations. 
   NdbTransaction::execute() also must be called before any locks are released;
   see @ref secScanLocks for more information.

   <h4>Features Specific to Index Scans</h4> 
   
   When performing an index scan, it is possible to 
   scan only a subset of a table using @ref NdbIndexScanOperation::setBound().
   In addition, result sets can be sorted in either ascending or descending order, using
   @ref NdbIndexScanOperation::readTuples(). Note that rows are returned unordered 
333 334 335
   by default, that is, unless <var>sorted</var> is set to <b>true</b>.
   It is also important to note that, when using NdbIndexScanOperation::BoundEQ 
   on a partition key, only fragments containing rows will actually be scanned.
336
   
337 338 339 340 341
   @note When performing a sorted scan, any value passed as the 
   NdbIndexScanOperation::readTuples() method's <code>parallel</code> argument 
   will be ignored and maximum parallelism will be used instead. In other words, all 
   fragments which it is possible to scan will be scanned simultaneously and in parallel 
   in such cases.
unknown's avatar
unknown committed
342

343
   @subsection secScanLocks Lock handling with scans
344

345 346 347
   Performing scans on either a tables or an index has the potential 
   return a great many records; however, Ndb will lock only a predetermined 
   number of rows per fragment at a time.
348
   How many rows will be locked per fragment is controlled by the 
349
   <var>batch</var> parameter passed to NdbScanOperation::readTuples().
350

351 352 353 354 355
   In order to allow the application to handle how locks are released, 
   NdbScanOperation::nextResult() has a Boolean parameter <var>fetch_allow</var>.
   If NdbScanOperation::nextResult() is called with <var>fetch_allow</var> equal to 
   <b>false</b>, then no locks may be released as result of the function call. 
   Otherwise the locks for the current batch may be released.
356

357
   This next example shows a scan delete that handle locks in an efficient manner.
358 359 360 361 362 363 364 365 366 367 368
   For the sake of brevity, we omit error-handling.
   @code
     int check;

     // Outer loop for each batch of rows
     while((check = MyScanOperation->nextResult(true)) == 0)
     {
       do
       {
         // Inner loop for each row within batch
         MyScanOperation->deleteCurrentTuple();
369
       } while((check = MyScanOperation->nextResult(false)) == 0);
370 371 372 373 374 375

       // When no more rows in batch, exeute all defined deletes       
       MyTransaction->execute(NoCommit);
     }
   @endcode

376
   See @ref ndbapi_scan.cpp for a more complete example of a scan.
377 378 379

   @section secError                    Error Handling

380 381 382 383 384 385 386 387 388 389 390 391 392 393
   Errors can occur either when operations making up a transaction are being 
   defined, or when the transaction is actually being executed. Catching and 
   handling either sort of error requires testing the value returned by 
   NdbTransaction::execute(), and then, if an error is indicated (that is, 
   if this value is equal to -1), using the following two methods in order to 
   identify the error's type and location:

   - NdbTransaction::getNdbErrorOperation() returns a reference to the 
     operation causing the most recent error.
   - NdbTransaction::getNdbErrorLine() yields the method number of the 
     erroneous method in the operation.
   
   This short example illustrates how to detect an error and to use these 
   two methods to identify it:
394 395

   @code
396 397
     theTransaction = theNdb->startTransaction();
     theOperation = theTransaction->getNdbOperation("TEST_TABLE");
398
     if (theOperation == NULL) goto error;
399
     theOperation->readTuple(NdbOperation::LM_Read);
400
     theOperation->setValue("ATTR_1", at1);
401
     theOperation->setValue("ATTR_2", at1);  //  Error occurs here
402 403 404
     theOperation->setValue("ATTR_3", at1);
     theOperation->setValue("ATTR_4", at1);
    
405 406 407
     if (theTransaction->execute(Commit) == -1) {
       errorLine = theTransaction->getNdbErrorLine();
       errorOperation = theTransaction->getNdbErrorOperation();
408
     }
409 410
   @endcode

411
   Here <code>errorLine</code> will be 3, as the error occurred in the 
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
   third method called on the NdbOperation object (in this case, 
   <code>theOperation</code>); if the result of 
   NdbTransaction::getNdbErrorLine() is 0, this means that the error 
   occurred when the operations were executed. In this example, 
   <code>errorOperation</code> will be a pointer to the <code>theOperation</code> 
   object. The NdbTransaction::getNdbError() method returns an NdbError 
   object providing information about the error.

   @note Transactions are <b>not</b> automatically closed when an error occurs. Call
   Ndb::closeTransaction() to close the transaction.

   One recommended way to handle a transaction failure 
   (i.e. an error is reported) is to:
   -# Rollback transaction (call NdbTransaction::execute() with a special parameter)
   -# Close transaction (call NdbTransaction::closeTransaction())
   -# If the error was temporary, attempt to restart the transaction

   Several errors can occur when a transaction contains multiple 
   operations which are simultaneously executed.
   In this case the application has to go through all operations
   and query their NdbError objects to find out what really happened.

   It is also important to note that errors can occur even when a commit is 
   reported as successful. In order to handle such situations, the NDB API 
   provides an additional NdbTransaction::commitStatus() method to check the 
   transactions's commit status.
438

439
******************************************************************************/
440 441

/**
unknown's avatar
unknown committed
442 443
 * @page ndbapi_simple.cpp ndbapi_simple.cpp
 * @include ndbapi_simple.cpp 
444 445
 */

unknown's avatar
unknown committed
446
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
unknown's avatar
unknown committed
447 448 449 450
/**
 * @page ndbapi_async.cpp ndbapi_async.cpp
 * @include ndbapi_async.cpp 
 */
451
/**
unknown's avatar
unknown committed
452 453
 * @page ndbapi_async1.cpp ndbapi_async1.cpp
 * @include ndbapi_async1.cpp 
454
 */
unknown's avatar
unknown committed
455
#endif
456 457

/**
unknown's avatar
unknown committed
458 459
 * @page ndbapi_retries.cpp ndbapi_retries.cpp
 * @include ndbapi_retries.cpp 
460 461 462
 */

/**
unknown's avatar
unknown committed
463 464
 * @page ndbapi_simple_index.cpp ndbapi_simple_index.cpp
 * @include ndbapi_simple_index.cpp 
465 466 467 468 469 470 471
 */

/**
 * @page ndbapi_scan.cpp ndbapi_scan.cpp
 * @include ndbapi_scan.cpp
 */

unknown's avatar
unknown committed
472 473 474 475 476
/**
 * @page ndbapi_event.cpp ndbapi_event.cpp
 * @include ndbapi_event.cpp
 */

477 478 479 480

/**
   @page secAdapt  Adaptive Send Algorithm

481
   At the time of "sending" a transaction 
482
   (using NdbTransaction::execute()), the transactions 
483 484 485 486
   are in reality <em>not</em> immediately transfered to the NDB Kernel.  
   Instead, the "sent" transactions are only kept in a 
   special send list (buffer) in the Ndb object to which they belong.
   The adaptive send algorithm decides when transactions should
487
   actually be transferred to the NDB kernel.
488
  
489 490
   The NDB API is designed as a multi-threaded interface and so
   it is often desirable to transfer database operations from more than 
491
   one thread at a time. 
492
   The NDB API keeps track of which Ndb objects are active in transferring
493 494
   information to the NDB kernel and the expected amount of threads to 
   interact with the NDB kernel.
495 496
   Note that a given instance of Ndb should be used in at most one thread; 
   different threads should <em>not</em> use the same Ndb object.
497
  
498 499
   There are four conditions leading to the transfer of database 
   operations from Ndb object buffers to the NDB kernel:
500 501
   -# The NDB Transporter (TCP/IP, OSE, SCI or shared memory)
      decides that a buffer is full and sends it off. 
502 503 504
      The buffer size is implementation-dependent and
      may change between MySQL Cluster releases.
      On TCP/IP the buffer size is usually around 64 KB;
505
      on OSE/Delta it is usually less than 2000 bytes. 
506 507 508 509 510 511 512
      Since each Ndb object provides a single buffer per storage node, 
      the notion of a "full" buffer is local to this storage node.
   -# The accumulation of statistical data on transferred information
      may force sending of buffers to all storage nodes.
   -# Every 10 ms, a special transmission thread checks whether or not
      any send activity has occurred. If not, then the thread will 
      force transmission to all nodes. 
513
      This means that 20 ms is the maximum time database operations 
514
      are kept waiting before being sent off. The 10-millisecond limit 
515
      is likely to become a configuration parameter in
516 517 518 519
      future releases of MySQL Cluster; however, for checks that
      are more frequent than each 10 ms, 
      additional support from the operating system is required.
   -# For methods that are affected by the adaptive send alorithm
unknown's avatar
unknown committed
520 521
      (such as NdbTransaction::execute()), there is a <var>force</var> 
      parameter 
522 523 524 525 526 527
      that overrides its default behaviour in this regard and forces 
      immediate transmission to all nodes. See the inidvidual NDB API class 
      listings for more information.

   @note The conditions listed above are subject to change in future releases 
   of MySQL Cluster.
528 529
*/

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**

   For each of these "sent" transactions, there are three 
   possible states:
   -# Waiting to be transferred to NDB Kernel.
   -# Has been transferred to the NDB Kernel and is currently 
      being processed.
   -# Has been transferred to the NDB Kernel and has 
      finished processing.
      Now it is waiting for a call to a poll method.  
      (When the poll method is invoked, 
      then the transaction callback method will be executed.)
      
   The poll method invoked (either Ndb::pollNdb() or Ndb::sendPollNdb())
   will return when:
   -# at least 'minNoOfEventsToWakeup' of the transactions
      in the send list have transitioned to state 3 as described above, and 
   -# all of these transactions have executed their callback methods.
*/
#endif

552
/**
553
   @page secConcepts  MySQL Cluster Concepts
554

unknown's avatar
unknown committed
555
   The <em>NDB Kernel</em> is the collection of storage nodes
556
   belonging to a MySQL Cluster.
557
   The application programmer can for most purposes view the
558 559 560 561 562 563 564 565 566 567 568 569
   set of all storage nodes as a single entity.
   Each storage node is made up of three main components:
   - TC : The transaction co-ordinator
   - ACC : Index storage component
   - TUP : Data storage component

   When an application program executes a transaction,
   it connects to one transaction co-ordinator on one storage node.  
   Usually, the programmer does not need to specify which TC should be used, 
   but in some cases when performance is important, the programmer can
   provide "hints" to use a certain TC.  
   (If the node with the desired transaction co-ordinator is down, then another TC will 
570 571
   automatically take over the work.)

572 573
   Every storage node has an ACC and a TUP which store 
   the indexes and data portions of the database table fragment.
574
   Even though one TC is responsible for the transaction,
575
   several ACCs and TUPs on other storage nodes might be involved in the 
576 577 578
   execution of the transaction.


579
   @section secNdbKernelConnection   Selecting a Transaction Co-ordinator 
580

581 582 583 584 585 586 587 588
   The default method is to select the transaction co-ordinator (TC) determined to be
   the "closest" storage node, using a heuristic for proximity based on
   the type of transporter connection. In order of closest to most distant, these are
   - SCI 
   - SHM
   - TCP/IP (localhost)
   - TCP/IP (remote host)
   If there are several connections available with the same proximity, they will each be 
589
   selected in a round robin fashion for every transaction. Optionally
590 591 592
   one may set the method for TC selection to round-robin mode, where each new set of 
   transactions is placed on the next DB node. The pool of connections from which this
   selection is made consists of all available connections.
593
   
594 595
   As noted previously, the application programmer can provide hints to the NDB API as to 
   which transaction co-ordinator it should use. This is done by
unknown's avatar
unknown committed
596 597
   providing a <em>table</em> and <em>partition key</em> 
   (usually the primary key).
598
   By using the primary key as the partition key, 
599 600
   the transaction will be placed on the node where the primary replica
   of that record resides.
601 602 603 604 605
   Note that this is only a hint; the system can be 
   reconfigured at any time, in which case the NDB API will choose a transaction
   co-ordinator without using the hint.
   For more information, see NdbDictionary::Column::getPartitionKey() and
   Ndb::startTransaction(). The application programmer can specify
606
   the partition key from SQL by using the construct, 
607
   <code>CREATE TABLE ... ENGINE=NDB PARTITION BY KEY (<var>attribute-list</var>);</code>.
608 609


610 611 612 613 614 615 616
   @section secRecordStruct          NDB Record Structure 
   The NDB Cluster engine used by MySQL Cluster is a relational database engine
   storing records in tables just as with any other RDBMS.
   Table rows represent records as tuples of relational data.
   When a new table is created, its attribute schema is specified for the table as a whole,
   and thus each record of the table has the same structure. Again, this is typical
   of relational databases, and NDB is no different in this regard.
617 618
   

619 620
   @subsection secKeys               Primary Keys
   Each record has from 1 up to 32 attributes which belong
621 622 623 624
   to the primary key of the table.
   
   @section secTrans                 Transactions

625 626
   Transactions are committed first to main memory, 
   and then to disk after a global checkpoint (GCP) is issued.
627 628 629 630 631
   Since all data is (in most NDB Cluster configurations) 
   synchronously replicated and stored on multiple NDB nodes,
   the system can still handle processor failures without loss 
   of data.
   However, in the case of a system failure (e.g. the whole system goes down), 
632
   then all (committed or not) transactions occurring since the latest GCP are lost.
633 634 635 636 637 638 639 640


   @subsection secConcur                Concurrency Control
   NDB Cluster uses pessimistic concurrency control based on locking.
   If a requested lock (implicit and depending on database operation)
   cannot be attained within a specified time, 
   then a timeout error occurs.

641 642 643 644 645 646 647
   Concurrent transactions as requested by parallel application programs and 
   thread-based applications can sometimes deadlock when they try to access 
   the same information simultaneously.
   Thus, applications need to be written in a manner so that timeout errors
   occurring due to such deadlocks are handled gracefully. This generally
   means that the transaction encountering a timeout should be rolled back 
   and restarted.
unknown's avatar
unknown committed
648 649


650
   @section secHint                 Hints and Performance
unknown's avatar
unknown committed
651

652
   Placing the transaction co-ordinator in close proximity
unknown's avatar
unknown committed
653 654
   to the actual data used in the transaction can in many cases
   improve performance significantly. This is particularly true for
655 656
   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
unknown's avatar
unknown committed
657

658
     <code>[30 microseconds] + ([100 nanoseconds] * [<var>number of bytes</var>])</code>
unknown's avatar
unknown committed
659 660 661

   This means that if we can ensure that we use "popular" links we increase
   buffering and thus drastically reduce the communication cost.
662
   The same system using SCI has a different cost model:
unknown's avatar
unknown committed
663

664
     <code>[5 microseconds] + ([10 nanoseconds] * [<var>number of bytes</var>])</code>
unknown's avatar
unknown committed
665

666 667 668 669 670 671 672
   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.
unknown's avatar
unknown committed
673 674 675 676

   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, 
677
   which is also the partition key. 
unknown's avatar
unknown committed
678 679
   Then the keyData will be the address of the integer 
   of the primary key and keyLen will be 4.
680 681
*/

682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
#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
948 949 950 951 952
   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.
953 954 955

*/

956 957 958 959 960
#ifndef Ndb_H
#define Ndb_H

#include <ndb_types.h>
#include <ndbapi_limits.h>
961
#include <ndb_cluster_connection.hpp>
962
#include <NdbError.hpp>
963
#include <NdbDictionary.hpp>
964 965 966 967

class NdbObjectIdMap;
class NdbOperation;
class NdbScanOperation;
unknown's avatar
unknown committed
968
class NdbIndexScanOperation;
969
class NdbIndexOperation;
970
class NdbTransaction;
971 972 973 974 975 976 977 978
class NdbApiSignal;
class NdbRecAttr;
class NdbLabel;
class NdbBranch;
class NdbSubroutine;
class NdbCall;
class Table;
class BaseString;
unknown's avatar
unknown committed
979
class NdbBlob;
unknown's avatar
unknown committed
980
class NdbReceiver;
981
class Ndb_local_table_info;
unknown's avatar
ndb  
unknown committed
982
template <class T> struct Ndb_free_list_t;
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022


#if defined NDB_OSE
/**
 * Default time to wait for response after request has been sent to 
 * NDB Cluster (Set to 10 seconds usually, but to 100 s in 
 * the OSE operating system)
 */
#define WAITFOR_RESPONSE_TIMEOUT 100000 // Milliseconds
#else
#define WAITFOR_RESPONSE_TIMEOUT 120000 // Milliseconds
#endif

/**
 * @class Ndb 
 * @brief Represents the NDB kernel and is the main class of the NDB API.
 *
 * Always start your application program by creating an Ndb object. 
 * By using several Ndb objects it is possible to design 
 * a multi-threaded application, but note that Ndb objects 
 * cannot be shared by several threads. 
 * Different threads should use different Ndb objects. 
 * A thread might however use multiple Ndb objects.
 * Currently there is a limit of maximum 128 Ndb objects 
 * per application process.
 *
 * @note It is not allowed to call methods in the NDB API 
 *       on the same Ndb object in different threads 
 *       simultaneously (without special handling of the 
 *       Ndb object).
 *
 * @note The Ndb object is multi-thread safe in the following manner. 
 *       Each Ndb object can ONLY be handled in one thread. 
 *       If an Ndb object is handed over to another thread then the 
 *       application must ensure that a memory barrier is used to 
 *       ensure that the new thread see all updates performed by 
 *       the previous thread. 
 *       Semaphores, mutexes and so forth are easy ways of issuing memory 
 *       barriers without having to bother about the memory barrier concept.
 *
unknown's avatar
unknown committed
1023 1024 1025 1026 1027
 */

#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
// to be documented later
/*
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
 * If one Ndb object is used to handle parallel transactions through the 
 * asynchronous programming interface, please read the notes regarding
 * asynchronous transactions (Section @ref secAsync).
 * The asynchronous interface provides much higher performance 
 * in some situations, but is more complicated for the application designer. 
 *
 * @note Each Ndb object should either use the methods for 
 *       asynchronous transaction or the methods for 
 *       synchronous transactions but not both.
 */
unknown's avatar
unknown committed
1038 1039
#endif

1040 1041
class Ndb
{
1042
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1043 1044
  friend class NdbReceiver;
  friend class NdbOperation;
1045
  friend class NdbTransaction;
1046 1047 1048
  friend class Table;
  friend class NdbApiSignal;
  friend class NdbIndexOperation;
unknown's avatar
unknown committed
1049 1050
  friend class NdbScanOperation;
  friend class NdbIndexScanOperation;
1051 1052
  friend class NdbDictionaryImpl;
  friend class NdbDictInterface;
unknown's avatar
unknown committed
1053
  friend class NdbBlob;
1054
  friend class NdbImpl;
1055
  friend class NdbScanFilterImpl;
1056
#endif
1057 1058 1059 1060 1061 1062 1063

public:
  /** 
   * @name General 
   * @{
   */
  /**
unknown's avatar
unknown committed
1064 1065
   * The Ndb object represents a connection to a database.
   *
1066
   * @note The init() method must be called before the Ndb object may actually be used.
1067
   *
1068
   * @param ndb_cluster_connection is a connection to the cluster containing
unknown's avatar
unknown committed
1069
   *        the database to be used
1070 1071
   * @param aCatalogName is the name of the catalog to be used.
   * @note The catalog name provides a namespace for the tables and
1072 1073
   *       indexes created in any connection from the Ndb object.
   * @param aSchemaName is the name of the schema you 
unknown's avatar
unknown committed
1074
   *        want to use.
1075
   * @note The schema name provides an additional namespace 
1076 1077
   *       for the tables and indexes created in a given catalog.
   */
1078 1079
  Ndb(Ndb_cluster_connection *ndb_cluster_connection,
      const char* aCatalogName = "", const char* aSchemaName = "def");
1080 1081 1082

  ~Ndb();

unknown's avatar
unknown committed
1083
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
  /**
   * The current catalog name can be fetched by getCatalogName.
   *
   * @return the current catalog name
   */
  const char * getCatalogName() const;

  /**
   * The current catalog name can be set by setCatalogName.
   *
   * @param aCatalogName is the new name of the current catalog
   */
1096
  int setCatalogName(const char * aCatalogName);
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109

  /**
   * The current schema name can be fetched by getSchemaName.
   *
   * @return the current schema name
   */
  const char * getSchemaName() const;

  /**
   * The current schema name can be set by setSchemaName.
   *
   * @param aSchemaName is the new name of the current schema
   */
1110
  int setSchemaName(const char * aSchemaName);
unknown's avatar
unknown committed
1111
#endif
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124

  /**
   * The current database name can be fetched by getDatabaseName.
   *
   * @return the current database name
   */
  const char * getDatabaseName() const;

  /**
   * The current database name can be set by setDatabaseName.
   *
   * @param aDatabaseName is the new name of the current database
   */
1125
  int setDatabaseName(const char * aDatabaseName);
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138

  /**
   * The current database schema name can be fetched by getDatabaseSchemaName.
   *
   * @return the current database schema name
   */
  const char * getDatabaseSchemaName() const;

  /**
   * The current database schema name can be set by setDatabaseSchemaName.
   *
   * @param aDatabaseSchemaName is the new name of the current database schema
   */
1139
  int setDatabaseSchemaName(const char * aDatabaseSchemaName);
1140 1141

  /**
unknown's avatar
unknown committed
1142
   * Initializes the Ndb object
1143 1144 1145
   *
   * @param  maxNoOfTransactions 
   *         Maximum number of parallel 
1146
   *         NdbTransaction objects that can be handled by the Ndb object.
unknown's avatar
unknown committed
1147 1148 1149
   *         Maximum value is 1024.
   *
   * @note each scan or index scan operation uses one extra
1150
   *       NdbTransaction object
1151
   *
unknown's avatar
unknown committed
1152
   * @return 0 if successful, -1 otherwise.
1153 1154 1155
   */
  int init(int maxNoOfTransactions = 4);

1156
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
  /**
   * Wait for Ndb object to successfully set-up connections to 
   * the NDB kernel. 
   * Starting to use the Ndb object without using this method 
   * gives unspecified behavior. 
   * 
   * @param  timeout  The maximum time we will wait for 
   *                  the initiation process to finish.
   *                  Timeout is expressed in seconds.
   * @return  0: Ndb is ready and timeout has not occurred.<br>
   *          -1: Timeout has expired
   */
  int waitUntilReady(int timeout = 60);
unknown's avatar
unknown committed
1170
#endif
1171

1172 1173 1174 1175 1176 1177 1178 1179
  /** @} *********************************************************************/

  /** 
   * @name Meta Information
   * @{
   */

  /**
unknown's avatar
unknown committed
1180 1181 1182
   * Get an object for retrieving or manipulating database schema information 
   *
   * @note this object operates outside any transaction
1183 1184 1185 1186 1187 1188
   *
   * @return Object containing meta information about all tables 
   *         in NDB Cluster.
   */
  class NdbDictionary::Dictionary* getDictionary() const;
  
unknown's avatar
unknown committed
1189

1190 1191 1192 1193 1194 1195 1196 1197
  /** @} *********************************************************************/

  /** 
   * @name Starting and Closing Transactions
   * @{
   */

  /**
unknown's avatar
unknown committed
1198
   * Start a transaction
1199
   *
unknown's avatar
unknown committed
1200
   * @note When the transaction is completed it must be closed using
1201
   *       Ndb::closeTransaction or NdbTransaction::close. 
unknown's avatar
unknown committed
1202 1203
   *       The transaction must be closed independent of its outcome, i.e.
   *       even if there is an error.
1204
   *
1205
   * @param  table    Pointer to table object used for deciding 
unknown's avatar
unknown committed
1206
   *                  which node to run the Transaction Coordinator on
1207 1208
   * @param  keyData  Pointer to partition key corresponding to
   *                  <var>table</var>
unknown's avatar
unknown committed
1209
   * @param  keyLen   Length of partition key expressed in bytes
1210
   * 
1211
   * @return NdbTransaction object, or NULL on failure.
1212
   */
1213 1214 1215
  NdbTransaction* startTransaction(const NdbDictionary::Table *table= 0,
				   const char  *keyData = 0, 
				   Uint32       keyLen = 0);
1216 1217

  /**
unknown's avatar
unknown committed
1218 1219 1220 1221
   * Close a transaction.
   *
   * @note should be called after the transaction has completed, irrespective
   *       of success or failure
1222
   */
1223
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1224
  /**
1225 1226 1227 1228 1229 1230 1231 1232 1233
   * @note It is not allowed to call Ndb::closeTransaction after sending the
   *       transaction asynchronously with either 
   *       Ndb::sendPreparedTransactions or
   *       Ndb::sendPollNdb before the callback method has been called.
   *       (The application should keep track of the number of 
   *       outstanding transactions and wait until all of them 
   *       has completed before calling Ndb::closeTransaction).
   *       If the transaction is not committed it will be aborted.
   */
1234
#endif
1235
  void closeTransaction(NdbTransaction*);
1236 1237 1238

  /** @} *********************************************************************/

unknown's avatar
unknown committed
1239 1240
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
  // to be documented later
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250
  /** 
   * @name Asynchronous Transactions
   * @{
   */

  /**
   * Wait for prepared transactions.
   * Will return as soon as at least 'minNoOfEventsToWakeUp' 
   * of them have completed, or the maximum time given as timeout has passed.
   *
unknown's avatar
unknown committed
1251 1252 1253 1254
   * @param aMillisecondNumber 
   *        Maximum time to wait for transactions to complete. Polling 
   *        without wait is achieved by setting the timer to zero.
   *        Time is expressed in milliseconds.
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
   * @param minNoOfEventsToWakeup Minimum number of transactions 
   *            which has to wake up before the poll-call will return.
   *            If minNoOfEventsToWakeup is
   *            set to a value larger than 1 then this is the minimum 
   *            number of transactions that need to complete before the 
   *            poll will return.
   *            Setting it to zero means that one should wait for all
   *            outstanding transactions to return before waking up.
   * @return Number of transactions polled.
   */
  int  pollNdb(int aMillisecondNumber = WAITFOR_RESPONSE_TIMEOUT,
	      int minNoOfEventsToWakeup = 1);

  /**
   * This send method will send all prepared database operations. 
   * The default method is to do it non-force and instead
   * use the adaptive algorithm.  (See Section @ref secAdapt.)
   * The second option is to force the sending and 
   * finally there is the third alternative which is 
   * also non-force but also making sure that the 
   * adaptive algorithm do not notice the send. 
   * In this case the sending will be performed on a 
   * cyclical 10 millisecond event.
   *
   * @param forceSend When operations should be sent to NDB Kernel.
   *                  (See @ref secAdapt.)
   *                  - 0: non-force, adaptive algorithm notices it (default); 
   *                  - 1: force send, adaptive algorithm notices it; 
   *                  - 2: non-force, adaptive algorithm do not notice the send.
   */
  void sendPreparedTransactions(int forceSend = 0);

  /**
   * This is a send-poll variant that first calls 
   * Ndb::sendPreparedTransactions and then Ndb::pollNdb. 
   * It is however somewhat faster than calling the methods 
   * separately, since some mutex-operations are avoided. 
   * See documentation of Ndb::pollNdb and Ndb::sendPreparedTransactions
   * for more details.
   *
   * @param aMillisecondNumber Timeout specifier
   *            Polling without wait is achieved by setting the 
   *            millisecond timer to zero.
   * @param minNoOfEventsToWakeup Minimum number of transactions 
   *            which has to wake up before the poll-call will return.
   *            If minNoOfEventsToWakeup is
   *            set to a value larger than 1 then this is the minimum 
   *            number of transactions that need to complete before the 
   *            poll-call will return.
   *            Setting it to zero means that one should wait for all
   *            outstanding transactions to return before waking up.
   * @param forceSend When operations should be sent to NDB Kernel.
   *                  (See @ref secAdapt.)
   * - 0: non-force, adaptive algorithm notices it (default); 
   * - 1: force send, adaptive algorithm notices it; 
   * - 2: non-force, adaptive algorithm does not notice the send.
   * @return Number of transactions polled.
   */
  int  sendPollNdb(int aMillisecondNumber = WAITFOR_RESPONSE_TIMEOUT,
		   int minNoOfEventsToWakeup = 1,
		   int forceSend = 0);
unknown's avatar
unknown committed
1316
  /** @} *********************************************************************/
unknown's avatar
unknown committed
1317
#endif
1318 1319 1320 1321 1322 1323 1324 1325 1326
  
  /** 
   * @name Error Handling
   * @{
   */

  /**
   * Get the NdbError object
   *
unknown's avatar
unknown committed
1327
   * @note The NdbError object is valid until a new NDB API method is called.
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
   */
  const NdbError & getNdbError() const;
  
  /**
   * Get a NdbError object for a specific error code
   *
   * The NdbError object is valid until you call a new NDB API method.
   */
  const NdbError & getNdbError(int errorCode);


unknown's avatar
unknown committed
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348
  /** @} *********************************************************************/

#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
  /**
   * Get the application node identity.  
   *
   * @return Node id of this application.
   */
  int getNodeId();

1349
  bool usingFullyQualifiedNames();
1350

1351 1352 1353 1354 1355
  /**
   * Different types of tampering with the NDB Cluster.
   * <b>Only for debugging purposes only.</b>
   */
  enum TamperType	{ 
unknown's avatar
unknown committed
1356 1357 1358 1359 1360 1361
    LockGlbChp = 1,           ///< Lock GCP
    UnlockGlbChp,             ///< Unlock GCP
    CrashNode,                ///< Crash an NDB node
    ReadRestartGCI,           ///< Request the restart GCI id from NDB Cluster
    InsertError               ///< Execute an error in NDB Cluster 
                              ///< (may crash system)
1362 1363
  };

1364 1365 1366 1367 1368 1369 1370
  /**
   * For testing purposes it is possible to tamper with the NDB Cluster
   * (i.e. send a special signal to DBDIH, the NDB distribution handler).
   * <b>This feature should only used for debugging purposes.</b>
   * In a release versions of NDB Cluster,
   * this call always return -1 and does nothing.
   * 
1371
   * @param aAction Action to be taken according to TamperType above
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
   *
   * @param aNode  Which node the action will be taken
   *              -1:   Master DIH.
   *            0-16:   Nodnumber.
   * @return -1 indicates error, other values have meaning dependent 
   *          on type of tampering.
   */
  int NdbTamper(TamperType aAction, int aNode);  

  /**
   * Return a unique tuple id for a table.  The id sequence is
   * ascending but may contain gaps.
   *
   * @param aTableName table name
   *
   * @param cacheSize number of values to cache in this Ndb object
   *
1389
   * @return 0 or -1 on error, and tupleId in out parameter
1390
   */
1391
  int getAutoIncrementValue(const char* aTableName, 
1392 1393
                            Uint64 & tupleId, Uint32 cacheSize, 
			    Uint64 step = 1, Uint64 start = 1);
1394
  int getAutoIncrementValue(const NdbDictionary::Table * aTable, 
1395 1396
                            Uint64 & tupleId, Uint32 cacheSize, 
			    Uint64 step = 1, Uint64 start = 1);
1397 1398 1399 1400 1401 1402 1403 1404
  int readAutoIncrementValue(const char* aTableName,
                             Uint64 & tupleId);
  int readAutoIncrementValue(const NdbDictionary::Table * aTable,
                             Uint64 & tupleId);
  int setAutoIncrementValue(const char* aTableName,
                            Uint64 tupleId, bool increase);
  int setAutoIncrementValue(const NdbDictionary::Table * aTable,
                            Uint64 tupleId, bool increase);
1405
private:
1406
  int getTupleIdFromNdb(Ndb_local_table_info* info,
1407 1408
                        Uint64 & tupleId, Uint32 cacheSize,
			Uint64 step = 1, Uint64 start = 1 );
1409 1410 1411 1412 1413
  int readTupleIdFromNdb(Ndb_local_table_info* info,
                         Uint64 & tupleId);
  int setTupleIdInNdb(Ndb_local_table_info* info,
                      Uint64 tupleId, bool increase);
  int opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op);
1414
public:
1415 1416 1417

  /**
   */
1418
  NdbTransaction* hupp( NdbTransaction* );
1419
  Uint32 getReference() const { return theMyRef;}
unknown's avatar
ndb  
unknown committed
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429

  struct Free_list_usage
  {
    const char * m_name;
    Uint32 m_created;
    Uint32 m_free;
    Uint32 m_sizeof;
  };

  Free_list_usage * get_free_list_usage(Free_list_usage*);
1430 1431
#endif

unknown's avatar
ndb  
unknown committed
1432 1433
  

1434 1435 1436 1437 1438
/*****************************************************************************
 *	These are service routines used by the other classes in the NDBAPI.
 ****************************************************************************/
private:
  
1439 1440 1441
  void setup(Ndb_cluster_connection *ndb_cluster_connection,
	     const char* aCatalogName, const char* aSchemaName);

unknown's avatar
unknown committed
1442 1443 1444
  void connected(Uint32 block_reference);
 

1445
  NdbTransaction*  startTransactionLocal(Uint32 aPrio, Uint32 aFragmentId); 
1446 1447 1448

// Connect the connection object to the Database.
  int NDB_connect(Uint32 tNode);
1449
  NdbTransaction* doConnect(Uint32 nodeId); 
1450 1451
  void    doDisconnect();	 
  
unknown's avatar
unknown committed
1452
  NdbReceiver*	        getNdbScanRec();// Get a NdbScanReceiver from idle list
1453 1454 1455 1456 1457 1458 1459 1460
  NdbLabel*		getNdbLabel();	// Get a NdbLabel from idle list
  NdbBranch*            getNdbBranch();	// Get a NdbBranch from idle list
  NdbSubroutine*	getNdbSubroutine();// Get a NdbSubroutine from idle
  NdbCall*		getNdbCall();	// Get a NdbCall from idle list
  NdbApiSignal*	        getSignal();	// Get an operation from idle list
  NdbRecAttr*	        getRecAttr();	// Get a receeive attribute object from
					// idle list of the Ndb object.
  NdbOperation* 	getOperation();	// Get an operation from idle list
unknown's avatar
unknown committed
1461
  NdbIndexScanOperation* getScanOperation(); // Get a scan operation from idle
1462 1463 1464
  NdbIndexOperation* 	getIndexOperation();// Get an index operation from idle

  class NdbGlobalEventBufferHandle* getGlobalEventBufferHandle();
unknown's avatar
unknown committed
1465
  NdbBlob*              getNdbBlob();// Get a blob handle etc
1466 1467 1468

  void			releaseSignal(NdbApiSignal* anApiSignal);
  void                  releaseSignalsInList(NdbApiSignal** pList);
unknown's avatar
unknown committed
1469
  void			releaseNdbScanRec(NdbReceiver* aNdbScanRec);
1470 1471 1472 1473 1474 1475
  void			releaseNdbLabel(NdbLabel* anNdbLabel);
  void			releaseNdbBranch(NdbBranch* anNdbBranch);
  void			releaseNdbSubroutine(NdbSubroutine* anNdbSubroutine);
  void			releaseNdbCall(NdbCall* anNdbCall);
  void			releaseRecAttr (NdbRecAttr* aRecAttr);	
  void		 	releaseOperation(NdbOperation* anOperation);	
unknown's avatar
unknown committed
1476
  void		 	releaseScanOperation(NdbIndexScanOperation*);
unknown's avatar
unknown committed
1477
  void                  releaseNdbBlob(NdbBlob* aBlob);
1478 1479 1480

  void                  check_send_timeout();
  void                  remove_sent_list(Uint32);
1481 1482
  Uint32                insert_completed_list(NdbTransaction*);
  Uint32                insert_sent_list(NdbTransaction*);
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519

  // Handle a received signal. Used by both
  // synchronous and asynchronous interface
  void handleReceivedSignal(NdbApiSignal* anApiSignal, struct LinearSectionPtr ptr[3]);
  
  // Receive response signals
  int			receiveResponse(int waitTime = WAITFOR_RESPONSE_TIMEOUT);

  int			sendRecSignal(Uint16 aNodeId,
				      Uint32 aWaitState,
				      NdbApiSignal* aSignal,
                                      Uint32 nodeSequence);
  
  // Sets Restart GCI in Ndb object
  void			RestartGCI(int aRestartGCI);

  // Get block number of this NDBAPI object
  int			getBlockNumber();
  
  /****************************************************************************
   *	These are local service routines used by this class.	
   ***************************************************************************/
  
  int			createConIdleList(int aNrOfCon);
  int 		createOpIdleList( int nrOfOp );	

  void	freeOperation();          // Free the first idle operation.
  void	freeScanOperation();      // Free the first idle scan operation.
  void	freeIndexOperation();     // Free the first idle index operation.
  void	freeNdbCon();	// Free the first idle connection.
  void	freeSignal();	// Free the first idle signal	
  void	freeRecAttr();	// Free the first idle receive attr obj	
  void	freeNdbLabel();	// Free the first idle NdbLabel obj
  void	freeNdbBranch();// Free the first idle NdbBranch obj
  void	freeNdbSubroutine();// Free the first idle NdbSubroutine obj
  void	freeNdbCall();	    // Free the first idle NdbCall obj
  void	freeNdbScanRec();   // Free the first idle NdbScanRec obj
unknown's avatar
unknown committed
1520
  void  freeNdbBlob();      // Free the first etc
1521

1522
  NdbTransaction* getNdbCon();	// Get a connection from idle list
1523 1524
  
  /**
1525
   * Get a connected NdbTransaction to nodeId
1526 1527
   *   Returns NULL if none found
   */
1528
  NdbTransaction* getConnectedNdbTransaction(Uint32 nodeId);
1529 1530 1531

  // Release and disconnect from DBTC a connection
  // and seize it to theConIdleList
1532
  void	releaseConnectToNdb (NdbTransaction*);
1533 1534

  // Release a connection to idle list
1535
  void 	releaseNdbCon (NdbTransaction*);
1536 1537 1538 1539 1540 1541 1542 1543 1544
  
  int	checkInitState();		// Check that we are initialized
  void	report_node_failure(Uint32 node_id);           // Report Failed node
  void	report_node_failure_completed(Uint32 node_id); // Report Failed node(NF comp.)

  void	checkFailedNode();		// Check for failed nodes

  int   NDB_connect();     // Perform connect towards NDB Kernel

1545
  // Release arrays of NdbTransaction pointers
1546 1547
  void  releaseTransactionArrays();     

1548
  Uint32  pollCompleted(NdbTransaction** aCopyArray);
1549
  void    sendPrepTrans(int forceSend);
1550
  void    reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfComplTrans);
1551
  void    waitCompletedTransactions(int milliSecs, int noOfEventsToWaitFor);
1552 1553
  void    completedTransaction(NdbTransaction* aTransaction);
  void    completedScanTransaction(NdbTransaction* aTransaction);
1554 1555 1556 1557

  void    abortTransactionsAfterNodeFailure(Uint16 aNodeId);

  static
1558 1559
  const char * externalizeTableName(const char * internalTableName,
                                    bool fullyQualifiedNames);
1560
  const char * externalizeTableName(const char * internalTableName);
1561
  const BaseString internalize_table_name(const char * external_name) const;
1562 1563

  static
1564 1565
  const char * externalizeIndexName(const char * internalIndexName,
                                    bool fullyQualifiedNames);
1566
  const char * externalizeIndexName(const char * internalIndexName);
1567 1568
  const BaseString internalize_index_name(const NdbTableImpl * table,
                                          const char * external_name) const;
1569 1570 1571 1572 1573 1574 1575 1576

  static
  const BaseString getDatabaseFromInternalName(const char * internalName);
  static 
  const BaseString getSchemaFromInternalName(const char * internalName);

  void*              int2void     (Uint32 val);
  NdbReceiver*       void2rec     (void* val);
1577
  NdbTransaction*     void2con     (void* val);
1578 1579 1580 1581 1582 1583
  NdbOperation*      void2rec_op  (void* val);
  NdbIndexOperation* void2rec_iop (void* val);

/******************************************************************************
 *	These are the private variables in this class.	
 *****************************************************************************/
1584 1585 1586
  NdbTransaction**       thePreparedTransactionsArray;
  NdbTransaction**       theSentTransactionsArray;
  NdbTransaction**       theCompletedTransactionsArray;
1587 1588 1589 1590

  Uint32                theNoOfPreparedTransactions;
  Uint32                theNoOfSentTransactions;
  Uint32                theNoOfCompletedTransactions;
1591
  Uint32                theRemainingStartTransactions;
1592 1593 1594 1595 1596
  Uint32                theMaxNoOfTransactions;
  Uint32                theMinNoOfEventsToWakeUp;

  Uint32                theNextConnectNode;

1597 1598
  bool fullyQualifiedNames;

unknown's avatar
unknown committed
1599

1600 1601 1602 1603 1604

  class NdbImpl * theImpl;
  class NdbDictionaryImpl* theDictionary;
  class NdbGlobalEventBufferHandle* theGlobalEventBufferHandle;

1605 1606
  NdbTransaction*	theTransactionList;
  NdbTransaction**      theConnectionArray;
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618

  Uint32   theMyRef;        // My block reference  
  Uint32   theNode;         // The node number of our node
  
  Uint64               the_last_check_time;
  Uint64               theFirstTransId;

  Uint32		theRestartGCI;	// the Restart GCI used by DIHNDBTAMPER
  
  NdbError              theError;

  Int32        	        theNdbBlockNumber;
1619 1620 1621 1622 1623 1624 1625 1626

  enum InitType {
    NotConstructed,
    NotInitialised,
    StartingInit,
    Initialised,
    InitConfigError
  } theInitState;
1627 1628 1629

  NdbApiSignal* theCommitAckSignal;

unknown's avatar
unknown committed
1630 1631

#ifdef POORMANSPURIFY
1632 1633 1634 1635
  int cfreeSignals;
  int cnewSignals;
  int cgetSignals;
  int creleaseSignals;
unknown's avatar
unknown committed
1636
#endif
1637 1638 1639

  static void executeMessage(void*, NdbApiSignal *, 
			     struct LinearSectionPtr ptr[3]);
1640
  static void statusMessage(void*, Uint32, bool, bool);
1641 1642 1643 1644 1645 1646
#ifdef VM_TRACE
  void printState(const char* fmt, ...);
#endif
};

#endif