When I did NDB Cluster engagements, it happened a few time that I had to cover the NDB API. Once, a customer asked an example on how to perform a simple scan. Remembering that some examples are within the NDB source tree, under ./storage/ndb/ndbapi-examples/ and I decided to take a look, why writing something when a good example already exists… I was not expecting what I found!
1. Missing headers
1 2 3 4 5 6 7 8 |
$ make g++ -g -O0 -c -Wall -fno-rtti -fno-exceptions -I/usr/include -I../../../../include -I../../../../storage/ndb/include -I../../../../storage/ndb/include/ndbapi ndbapi_scan.cpp ndbapi_scan.cpp: In constructor ‘Car::Car()’: ndbapi_scan.cpp:111: error: ‘memset’ was not declared in this scope ndbapi_scan.cpp: In function ‘void drop_table(MYSQL&)’: ndbapi_scan.cpp:124: error: ‘exit’ was not declared in this scope ndbapi_scan.cpp: In function ‘void create_table(MYSQL&)’: ... |
Hmmm, some header files are missing, let’s add them
1 2 |
#include <string.h> #include <stdlib.h> |
2. The clean up code
With the added header files, the program compiles flawlessly. Let’s try it!
1 2 3 |
$ LD_LIBRARY_PATH=/usr/local/mysql-cluster-gpl-7.0.8a/lib/mysql ./ndbapi_scan /usr/local/mysql-cluster-gpl-7.0.8a/mysql.sock 127.0.0. Unable to connect with connect string: nodeid=0,127.0.0.:1186 Retrying every 5 seconds. Attempts left: 4^C |
My bad…. I did a typo in the IP of the MGM server. Easy to correct…
1 2 3 4 5 6 |
yves@yves-laptop:/opt/mysql-cluster-gpl-7.0.8/storage/ndb/ndbapi-examples/ndbapi_scan$ LD_LIBRARY_PATH=/usr/local/mysql-cluster-gpl-7.0.8a/lib/mysql ./ndbapi_scan /usr/local/mysql-cluster-gpl-7.0.8a/mysql.sock 127.0.0.1 MySQL Cluster already has example table: GARAGE. Dropping it... MySQL Cluster already has example table: GARAGE. Dropping it... MySQL Cluster already has example table: GARAGE. Dropping it... MySQL Cluster already has example table: GARAGE. Dropping it... ^C |
What’s that? Wow… look at the create_table code…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void create_table(MYSQL &mysql) { while (mysql_query(&mysql, "CREATE TABLE" " GARAGE" " (REG_NO INT UNSIGNED NOT NULL," " BRAND CHAR(20) NOT NULL," " COLOR CHAR(20) NOT NULL," " PRIMARY KEY USING HASH (REG_NO))" " ENGINE=NDB")) { if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR) MYSQLERROR(mysql); std::cout << "MySQL Cluster already has example table: GARAGE. " << "Dropping it..." << std::endl; /****************** * Recreate table * ******************/ drop_table(mysql); create_table(mysql); } } |
That one is sweet, no need to be a C guru to catch it… it is fairly obvious where the problem is isn’t it? Let’s remove the recursive “create_table” call.
3. Success
$ LD_LIBRARY_PATH=/usr/local/mysql-cluster-gpl-7.0.8a/lib/mysql ./ndbapi_scan /usr/local/mysql-cluster-gpl-7.0.8a/mysql.sock 127.0.0.1
Connecting…Connected!
Initializing NDB…Done
Looking for table GARAGE…Got it! = GARAGE
Getting the columns…
Done
Populating…populate: Success!
Scanning and printing…0 Mercedes Blue
12 Toyota Pink
5 BMW Black
7 BMW Black
3 Mercedes Blue
9 BMW Black
10 Toyota Pink
14 Toyota Pink
11 Toyota Pink
1 Mercedes Blue
13 Toyota Pink
6 BMW Black
2 Mercedes Blue
4 Mercedes Blue
8 BMW Black
scan_print: Success!
Going to delete all pink cars!
Deleting pink cars…No error
Done
0 Mercedes Blue
5 BMW Black
7 BMW Black
3 Mercedes Blue
9 BMW Black
1 Mercedes Blue
6 BMW Black
2 Mercedes Blue
4 Mercedes Blue
8 BMW Black
scan_print: Success!
Going to update all Blue cars to Black cars!
No error
0 Mercedes Black
5 BMW Black
7 BMW Black
3 Mercedes Black
9 BMW Black
1 Mercedes Black
6 BMW Black
2 Mercedes Black
4 Mercedes Black
8 BMW Black
scan_print: Success!
I know that these programs are just examples. But yet, they are in some way part of the documentation and the quality is, let’s say, subject to questions.
They could certainly do with some love, and a few additions. Patches probably quite welcome, and quite likely to get quickly applied.
yes, just mail a patch…please
(hmm..wonder if it would require SCA…not sure…)
The infinite loop problem is fixed in http://bugs.mysql.com/bug.php?id=30552 put it hasn’t been pushed for some reason. I don’t know why the other problem hasn’t been spotted before, my guess is those includes were not required in older versions of g++.
@Stewart Smith, @Jonas and @LinuxJedi, I’ll submit a patch tomorrow.