MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
select_count.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 
19 #include <ndb_global.h>
20 #include <ndb_opts.h>
21 
22 #include <NdbOut.hpp>
23 
24 #include <NdbApi.hpp>
25 #include <NdbMain.h>
26 #include <NDBT.hpp>
27 #include <NdbSleep.h>
28 #include <UtilTransactions.hpp>
29 
30 static int
31 select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
32  int parallelism,
33  Uint64* count_rows,
35 
36 static const char* _dbname = "TEST_DB";
37 static int _parallelism = 240;
38 static int _lock = 0;
39 
40 const char *load_default_groups[]= { "mysql_cluster",0 };
41 
42 static struct my_option my_long_options[] =
43 {
44  NDB_STD_OPTS("ndb_select_count"),
45  { "database", 'd', "Name of database table is in",
46  (uchar**) &_dbname, (uchar**) &_dbname, 0,
47  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
48  { "parallelism", 'p', "parallelism",
49  (uchar**) &_parallelism, (uchar**) &_parallelism, 0,
50  GET_INT, REQUIRED_ARG, 240, 0, 0, 0, 0, 0 },
51  { "lock", 'l', "Read(0), Read-hold(1), Exclusive(2)",
52  (uchar**) &_lock, (uchar**) &_lock, 0,
53  GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
54  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
55 };
56 
57 static void short_usage_sub(void)
58 {
59  ndb_short_usage_sub(NULL);
60 }
61 
62 static void usage()
63 {
64  ndb_usage(short_usage_sub, load_default_groups, my_long_options);
65 }
66 
67 int main(int argc, char** argv){
68  NDB_INIT(argv[0]);
69  ndb_opt_set_usage_funcs(short_usage_sub, usage);
70  load_defaults("my",load_default_groups,&argc,&argv);
71  int ho_error;
72 #ifndef DBUG_OFF
73  opt_debug= "d:t:O,/tmp/ndb_select_count.trace";
74 #endif
75  if ((ho_error=handle_options(&argc, &argv, my_long_options,
76  ndb_std_get_one_option)))
77  return NDBT_ProgramExit(NDBT_WRONGARGS);
78  if (argc < 1) {
79  usage();
80  return NDBT_ProgramExit(NDBT_WRONGARGS);
81  }
82 
83  Ndb_cluster_connection con(opt_ndb_connectstring, opt_ndb_nodeid);
84  con.set_name("ndb_select_count");
85  if(con.connect(12, 5, 1) != 0)
86  {
87  ndbout << "Unable to connect to management server." << endl;
88  return NDBT_ProgramExit(NDBT_FAILED);
89  }
90  if (con.wait_until_ready(30,0) < 0)
91  {
92  ndbout << "Cluster nodes not ready in 30 seconds." << endl;
93  return NDBT_ProgramExit(NDBT_FAILED);
94  }
95 
96  Ndb MyNdb(&con, _dbname );
97  if(MyNdb.init() != 0){
98  ERR(MyNdb.getNdbError());
99  return NDBT_ProgramExit(NDBT_FAILED);
100  }
101 
102  for(int i = 0; i<argc; i++){
103  // Check if table exists in db
104  const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, argv[i]);
105  if(pTab == NULL){
106  ndbout << " Table " << argv[i] << " does not exist!" << endl;
107  continue;
108  }
109 
110  Uint64 rows = 0;
111  if (select_count(&MyNdb, pTab, _parallelism, &rows,
112  (NdbOperation::LockMode)_lock) != 0){
113  return NDBT_ProgramExit(NDBT_FAILED);
114  }
115 
116  ndbout << rows << " records in table " << argv[i] << endl;
117  }
118  return NDBT_ProgramExit(NDBT_OK);
119 }
120 
121 int
122 select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
123  int parallelism,
124  Uint64* count_rows,
126 
127  int retryAttempt = 0;
128  const int retryMax = 100;
129  int check;
130  NdbTransaction *pTrans;
131  NdbScanOperation *pOp;
132  const Uint32 codeWords= 1;
133  Uint32 codeSpace[ codeWords ];
134  NdbInterpretedCode code(NULL, // Table is irrelevant
135  &codeSpace[0],
136  codeWords);
137  if ((code.interpret_exit_last_row() != 0) ||
138  (code.finalise() != 0))
139  {
140  ERR(code.getNdbError());
141  return NDBT_FAILED;
142  }
143 
144  while (true){
145 
146  if (retryAttempt >= retryMax){
147  g_info << "ERROR: has retried this operation " << retryAttempt
148  << " times, failing!" << endl;
149  return NDBT_FAILED;
150  }
151 
152  pTrans = pNdb->startTransaction();
153  if (pTrans == NULL) {
154  const NdbError err = pNdb->getNdbError();
155 
156  if (err.status == NdbError::TemporaryError){
157  NdbSleep_MilliSleep(50);
158  retryAttempt++;
159  continue;
160  }
161  ERR(err);
162  return NDBT_FAILED;
163  }
164  pOp = pTrans->getNdbScanOperation(pTab->getName());
165  if (pOp == NULL) {
166  ERR(pTrans->getNdbError());
167  pNdb->closeTransaction(pTrans);
168  return NDBT_FAILED;
169  }
170 
171  if( pOp->readTuples(NdbScanOperation::LM_Dirty) ) {
172  ERR(pTrans->getNdbError());
173  pNdb->closeTransaction(pTrans);
174  return NDBT_FAILED;
175  }
176 
177 
178  check = pOp->setInterpretedCode(&code);
179  if( check == -1 ) {
180  ERR(pTrans->getNdbError());
181  pNdb->closeTransaction(pTrans);
182  return NDBT_FAILED;
183  }
184 
185  Uint64 tmp;
186  Uint32 row_size;
187  pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&tmp);
188  pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&row_size);
189  check = pTrans->execute(NdbTransaction::NoCommit);
190  if( check == -1 ) {
191  ERR(pTrans->getNdbError());
192  pNdb->closeTransaction(pTrans);
193  return NDBT_FAILED;
194  }
195 
196  Uint64 row_count = 0;
197  int eof;
198  while((eof = pOp->nextResult(true)) == 0){
199  row_count += tmp;
200  }
201 
202  if (eof == -1) {
203  const NdbError err = pTrans->getNdbError();
204 
205  if (err.status == NdbError::TemporaryError){
206  pNdb->closeTransaction(pTrans);
207  NdbSleep_MilliSleep(50);
208  retryAttempt++;
209  continue;
210  }
211  ERR(err);
212  pNdb->closeTransaction(pTrans);
213  return NDBT_FAILED;
214  }
215 
216  pNdb->closeTransaction(pTrans);
217 
218  if (count_rows != NULL){
219  *count_rows = row_count;
220  }
221 
222  return NDBT_OK;
223  }
224  return NDBT_FAILED;
225 }
226 
227