Table of Contents
Abstract
      This chapter discusses preparations for writing an
      NDB API application.
    
Abstract
        This section provides information on compiling and linking
        NDB API applications, including requirements
        and compiler and linker options.
      
        To use the NDB API with MySQL, you must have
        the NDB client library and its header files
        installed alongside the regular MySQL client libraries and
        headers. These are automatically installed when you build MySQL
        using the --with-ndbcluster
        configure option or when using a MySQL binary
        package that supports the NDBCluster storage
        engine.
      
          MySQL 4.1 does not install the required
          NDB-specific header files. You should use
          MySQL 5.0 or later when writing NDB API
          applications, and this Guide is targeted for use with MySQL
          5.1.
        
Header Files. 
          In order to compile source files that use the
          NDB API, you must ensure that the necessary
          header files can be found. Header files specific to the
          NDB API are installed in the following
          subdirectories of the MySQL include
          directory:
          
                include/mysql/storage/ndb/ndbapi
              
                include/mysql/storage/ndb/mgmapi
              
Compiler Flags. The MySQL-specific compiler flags needed can be determined using the mysql_config utility that is part of the MySQL installation:
$ mysql_config --cflags -I/usr/local/mysql/include/mysql -Wreturn-type -Wtrigraphs -W -Wformat -Wsign-compare -Wunused -mcpu=pentium4 -march=pentium4
          This sets the include path for the MySQL header files but not
          for those specific to the NDB API. The
          --include option to
          mysql_config returns the generic include
          path switch:
shell> mysql_config --include -I/usr/local/mysql/include/mysql
          It is necessary to add the subdirectory paths explicitly, so
          that adding all the needed compile flags to the
          CXXFLAGS shell variable should look
          something like this:
CFLAGS="$CFLAGS "`mysql_config --cflags` CFLAGS="$CFLAGS "`mysql_config --include`storage/ndb CFLAGS="$CFLAGS "`mysql_config --include`storage/ndb/ndbapi CFLAGS="$CFLAGS "`mysql_config --include`storage/ndb/mgmapi
          If you do not intend to use the Cluster management functions,
          the last line in the previous example can be omitted. However,
          if you are interested in the management functions only, and do
          not want or need to access Cluster data except from MySQL,
          then you can omit the line referencing the
          ndbapi directory.
        
        NDB API applications must be linked against
        both the MySQL and NDB client libraries. The
        NDB client library also requires some
        functions from the mystrings library, so this
        must be linked in as well.
      
        The necessary linker flags for the MySQL client library are
        returned by mysql_config
        --libs. For multithreaded
        applications you should use the --libs_r
        instead:
$ mysql_config --libs_r -L/usr/local/mysql-5.1/lib/mysql -lmysqlclient_r -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib -lssl -lcrypto
        To link an NDB API application, it is necessary to add
        -lndbclient and -lmystrings to
        these options. Adding all the required linker flags to the
        LDFLAGS variable should look something like
        this:
LDFLAGS="$LDFLAGS "`mysql_config --libs_r` LDFLAGS="$LDFLAGS -lndbclient -lmystrings"
        It is often faster and simpler to use GNU autotools than to
        write your own makefiles. In this section, we provide an
        autoconf macro WITH_MYSQL that can be used to
        add a --with-mysql option to a configure file,
        and that automatically sets the correct compiler and linker
        flags for given MySQL installation.
      
        All of the examples in this chapter include a common
        mysql.m4 file defining
        WITH_MYSQL. A typical complete example
        consists of the actual source file and the following helper
        files:
        
              acinclude
            
              configure.in
            
              Makefile.m4
            
        automake also requires that you provide
        README, NEWS,
        AUTHORS, and ChangeLog
        files; however, these can be left empty.
      
To create all necessary build files, run the following:
aclocal
autoconf
automake -a -c
configure --with-mysql=/mysql/prefix/path
Normally, this needs to be done only once, after which make will accommodate any file changes.
Example 1-1: acinclude.m4. 
m4_include([../mysql.m4])
Example 1-2: configure.in. 
AC_INIT(example, 1.0) AM_INIT_AUTOMAKE(example, 1.0) WITH_MYSQL() AC_OUTPUT(Makefile)
Example 1-3: Makefile.am. 
bin_PROGRAMS = example example_SOURCES = example.cc
Example 1-4: WITH_MYSQL source for inclusion in
          acinclude.m4. 
dnl
dnl configure.in helper macros
dnl 
 
AC_DEFUN([WITH_MYSQL], [ 
  AC_MSG_CHECKING(for mysql_config executable)
  AC_ARG_WITH(mysql, [  --with-mysql=PATH path to mysql_config binary or mysql prefix dir], [
  if test -x $withval -a -f $withval
    then
      MYSQL_CONFIG=$withval
    elif test -x $withval/bin/mysql_config -a -f $withval/bin/mysql_config
    then 
     MYSQL_CONFIG=$withval/bin/mysql_config
    fi
  ], [
  if test -x /usr/local/mysql/bin/mysql_config -a -f /usr/local/mysql/bin/mysql_config
    then
      MYSQL_CONFIG=/usr/local/mysql/bin/mysql_config
    elif test -x /usr/bin/mysql_config -a -f /usr/bin/mysql_config
    then
      MYSQL_CONFIG=/usr/bin/mysql_config
    fi
  ])
  if test "x$MYSQL_CONFIG" = "x" 
  then
    AC_MSG_RESULT(not found)
    exit 3
  else
    AC_PROG_CC
    AC_PROG_CXX
 
    # add regular MySQL C flags
    ADDFLAGS=`$MYSQL_CONFIG --cflags` 
    # add NDB API specific C flags
    IBASE=`$MYSQL_CONFIG --include`
    ADDFLAGS="$ADDFLAGS $IBASE/ndb"
    ADDFLAGS="$ADDFLAGS $IBASE/ndb/ndbapi"
    ADDFLAGS="$ADDFLAGS $IBASE/ndb/mgmapi"
    CFLAGS="$CFLAGS $ADDFLAGS"    
    CXXFLAGS="$CXXFLAGS $ADDFLAGS"    
    LDFLAGS="$LDFLAGS "`$MYSQL_CONFIG --libs_r`" -lndbclient -lmystrings"
    
    AC_MSG_RESULT($MYSQL_CONFIG)
  fi  
])
Abstract
        This section covers connecting an NDB API
        application to a MySQL cluster.
      
        NDB API applications require one or more of
        the following include files:
        
              Applications accessing Cluster data via the
              NDB API must include the file
              NdbApi.hpp.
            
              Applications making use of both the NDB
              API and the regular MySQL client API also need to include
              mysql.h.
            
              Applications that use cluster management functions need
              the include file mgmapi.h.
            
        Before using the NDB API, it must first be
        initialised by calling the ndb_init()
        function. Once an NDB API application is
        complete, call ndb_end(0) to perform a
        cleanup.
      
        To establish a connection to the server, it is necessary to
        create an instance of Ndb_cluster_connection,
        whose constructor takes as its argument a cluster connectstring;
        if no connectstring is given, localhost is
        assumed.
      
        The cluster connection is not actually initiated until the
        Ndb_cluster_connection::connect() method is
        called. When invoked without any arguments, the connection
        attempt is retried each 1 second indefinitely until successful,
        and no reporting is done. See
        Section 3.2, “The Ndb_cluster_connection Class”, for details.
      
        By default an API node will connect to the
        “nearest” data node — usually a data node
        running on the same machine, due to the fact that shared memory
        transport can be used instead of the slower TCP/IP. This may
        lead to poor load distribution in some cases, so it is possible
        to enforce a round-robin node connection scheme by calling the
        set_optimized_node_selection() method with
        0 as its argument prior to calling
        connect(). (See
        Section 3.2.1.4, “Ndb_cluster_connection::set_optimized_node_selection()”.)
      
        The connect() method initiates a connection
        to a cluster management node only — it does not wait for
        any connections to data nodes to be made. This can be
        accomplished by using wait_until_ready()
        after calling connect(). The
        wait_until_ready() method waits up to a given
        number of seconds for a connection to a data node to be
        established.
      
        In the following example, initialisation and connection are
        handled in the two functions example_init()
        and example_end(), which will be included in
        subsequent examples via the file
        example_connection.h.
      
Example 2-1: Connection example.
#include <stdio.h>
#include <stdlib.h>
#include <NdbApi.hpp>
#define CONNECTSTR "localhost"
Ndb_cluster_connection* example_init()
{
  Ndb_cluster_connection* conn;
  // initialise MySQL and Ndb client libraries
  if( ndb_init() )
  {
    exit(EXIT_FAILURE);
  }
  // prepare connection to cluster
  conn = new Ndb_cluster_connection(CONNECTSTR);
  // initiate connection
  if( conn->connect(4, 5, 1) )
  {
    fprintf(stderr, "Unable to connect to cluster within 30 seconds.");
    exit(EXIT_FAILURE);
  }
  
  // wait for data (ndbd) nodes
  if(conn->wait_until_ready(30, 0) < 0)
  {
    fprintf(stderr, "Cluster was not ready within 30 seconds.\n");
    exit(EXIT_FAILURE);
  }
  return conn; 
}
void example_end(Ndb_cluster_connection* conn)
{
  // terminate connection
  delete conn;
  // shut down MySQL and Ndb client libraries
  ndb_end(2);
}
int main(int argc, char** argv)
{
  Ndb_cluster_connection* conn;
  conn = example_connect();
  printf("Connection established.");
  example_end(conn);
  return EXIT_SUCCESS;
}
Abstract
This section discusses NDB naming and other conventions with regard to database objects.
Databases and Schemas. 
        Databases and schemas are not represented by objects as such in
        the NDB API. Instead, they are modelled as
        attributes of Table and
        Index objects. The value of the
        database attribute of one of these objects is
        always the same as the name of the MySQL database to which the
        table or index belongs. The value of the
        schema attribute of a
        Table or Index object is
        always 'def' (for “default”).
      
Tables. 
        MySQL table names are directly mapped to NDB
        table names without modification. Table names starting with
        'NDB$' are reserved for internal use>, as is
        the SYSTAB_0 table in the
        sys database.
      
Indexes. There are two different type of NDB indexes:
Hash indexes are unique, but not ordered.
B-tree indexes are ordered, but allow duplicate values.
Names of unique indexes and primary keys are handled as follows:
              For a MySQL UNIQUE index, both a B-tree
              and a hash index are created. The B-tree index uses the
              MySQL name for the index; the name for the hash index is
              generated by appending '$unique' to the
              index name.
            
              For a MySQL primary key only a B-tree index is created.
              This index is given the name PRIMARY.
              There is no extra hash; however, the uniqueness of the
              primary key is guaranteed by making the MySQL key the
              internal primary key of the NDB table.
            
Column Names and Values. 
        NDB column names are the same as their MySQL
        names.
      
Datatypes. 
        MySQL datatypes are stored in NDB columns as
        follows:
        
              The MySQL TINYINT,
              SMALLINT, INT, and
              BIGINT datatypes map to
              NDB types having the same names and
              storage requirements as their MySQL counterparts.
            
              The MySQL FLOAT and
              DOUBLE datatypes are mapped to
              NDB types having the same names and
              storage requirements.
            
              The storage space required for a MySQL
              CHAR column is determined by the
              maximum number of characters and the column's character
              set. For most (but not all) character sets, each character
              takes one byte of storage. When using UTF-8, each
              character requires three bytes. You can find the number of
              bytes needed per character in a given character set by
              checking the Maxlen column in the
              output of SHOW CHARACTER SET.
            
              In MySQL 5.1, the storage requirements for a
              VARCHAR or VARBINARY
              column depend on whether the column is stored in memory or
              on disk:
              
                    For in-memory columns, the
                    NDBCLUSTER storage engine
                    supports variable-width columns with 4-byte
                    alignment. This means that (for example) a the
                    string 'abcde' stored in a
                    VARCHAR(50) column using the
                    latin1 character set requires 12
                    bytes — in this case, 2 bytes times 5
                    characters is 10, rounded up to the next even
                    multiple of 4 yields 12. (This represents a change
                    in behaviour from Cluster in MySQL 5.0 and 4.1,
                    where a column having the same definition required
                    52 bytes storage per row regardless of the length of
                    the string being stored in the row.)
                  
                    In Disk Data columns, VARCHAR and
                    VARBINARY are stored as
                    fixed-width columns. This means that each of these
                    types requires the same amount of storage as a
                    CHAR of the same size.
                  
              Each row in a Cluster BLOB or
              TEXT column is made up of two separate
              parts. One of these is of fixed size (256 bytes), and is
              actually stored in the original table. The other consists
              of any data in excess of 256 bytes, which stored in a
              hidden table. The rows in this second table are always
              2000 bytes long. This means that record of
              size bytes in a
              TEXT or BLOB column
              requires
              
                    256 bytes, if
                    size <=
                    256
                    256 + 2000 *
                    (( bytes otherwise
                  size – 256) \ 2000) +
                    1)