MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
acid.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <NdbApi.hpp>
20 #include <NdbSchemaCon.hpp>
21 #include <NdbMutex.h>
22 #include <NdbOut.hpp>
23 #include <NdbSleep.h>
24 #include <NdbThread.h>
25 #include <NdbTick.h>
26 #include <NdbMain.h>
27 #include <NdbTest.hpp>
28 #include <random.h>
29 
30 //#define TRACE
31 #define DEBUG
32 //#define RELEASE
33 #define NODE_REC // epaulsa: introduces pointer checks to help 'acid' keep core
34 // during node recovery
35 
36 #ifdef TRACE
37 
38 #define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__))
39 #define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__))
40 #define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__))
41 
42 int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
43 {
44  ndbout << szFile << "(" << iLine << ") : ";
45  ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
46  ndbout << pNdbConnection->getNdbError();
47  NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
48  if(pNdbOperation) {
49  ndbout << " : " << pNdbOperation->getNdbError();
50  }
51  ndbout << " : " << pNdbConnection->getNdbErrorLine();
52  ndbout << endl;
53  return iRes;
54 }
55 
56 template <class C>
57 int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
58 {
59  ndbout << szFile << "(" << iLine << ") : ";
60  ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
61  ndbout << pC->getNdbError();
62  ndbout << endl;
63  return iRes;
64 }
65 
66 template <class R, class C>
67 R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
68 {
69  ndbout << szFile << "(" << iLine << ") : ";
70  ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << (long)(void*)pR << " : ";
71  ndbout << pC->getNdbError();
72  ndbout << endl;
73  return pR;
74 }
75 
76 template <class C>
77 void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
78 {
79  ndbout << szFile << "(" << iLine << ") : ";
80  ndbout << szClass << "->" << szMethod << " : ";
81  ndbout << pC->getNdbError();
82  ndbout << endl;
83 }
84 #endif /* TRACE */
85 
86 
87 #ifdef DEBUG
88 
89 #define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__))
90 #define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__))
91 #define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__))
92 
93 int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
94 {
95  if(iRes<0) {
96  ndbout << szFile << "(" << iLine << ") : ";
97  ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
98  ndbout << pNdbConnection->getNdbError();
99  NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
100  if(pNdbOperation) {
101  ndbout << " : " << pNdbOperation->getNdbError();
102  }
103  ndbout << " : " << pNdbConnection->getNdbErrorLine();
104  ndbout << " : ";
105  ndbout << endl;
106  }
107  return iRes;
108 }
109 
110 template <class C>
111 int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
112 {
113  if(iRes<0) {
114  ndbout << szFile << "(" << iLine << ") : ";
115  ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
116  ndbout << pC->getNdbError();
117  ndbout << endl;
118  }
119  return iRes;
120 }
121 
122 template <class R, class C>
123 R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
124 {
125  if(!pR) {
126  ndbout << szFile << "(" << iLine << ") : ";
127  ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << " : ";
128  ndbout << pC->getNdbError();
129  ndbout << endl;
130  }
131  return pR;
132 }
133 
134 template <class C>
135 void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
136 {
137  if(pC->getNdbError().code) {
138  ndbout << szFile << "(" << iLine << ") : ";
139  ndbout << szClass << "->" << szMethod << " : ";
140  ndbout << pC->getNdbError();
141  ndbout << endl;
142  }
143 }
144 
145 
146 #endif /* DEBUG */
147 
148 
149 #ifdef RELEASE
150 
151 #define VerifyMethodInt(c, m) (c->m)
152 #define VerifyMethodPtr(v, c, m) (v=(c->m))
153 #define VerifyMethodVoid(c, m) (c->m)
154 
155 int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine)
156 {
157  if(iRes<0) {
158  ndbout << szFile << "(" << iLine << ") : ";
159  ndbout << szClass << "->" << szMethod << " return " << iRes << " : ";
160  ndbout << pNdbConnection->getNdbError();
161  NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation();
162  if(pNdbOperation) {
163  ndbout << " : " << pNdbOperation->getNdbError();
164  }
165  ndbout << " : " << pNdbConnection->getNdbErrorLine();
166  ndbout << endl;
167  }
168  return iRes;
169 }
170 
171 #endif /* RELEASE */
172 
173 // epaulsa =>
174 #ifndef NODE_REC
175 #define CHK_TR(p)
176 #else
177 #define CHK_TR(p) if(!p){ \
178  ndbout <<"startTransaction failed, returning now." << endl ; \
179  delete pNdb ; \
180  pNdb = NULL ; \
181  return 0 ; \
182  }
183 #endif // NODE_REC
184 // <= epaulsa
185 
186 const char* c_szWarehouse = "WAREHOUSE";
187 const char* c_szWarehouseNumber = "W_ID";
188 const char* c_szWarehouseSum = "W_SUM";
189 const char* c_szWarehouseCount = "W_CNT";
190 const char* c_szDistrict = "DISTRICT";
191 const char* c_szDistrictWarehouseNumber = "D_W_ID";
192 const char* c_szDistrictNumber = "D_ID";
193 const char* c_szDistrictSum = "D_SUM";
194 const char* c_szDistrictCount = "D_CNT";
195 
196 Uint32 g_nWarehouseCount = 10;
197 Uint32 g_nDistrictPerWarehouse = 10;
198 Uint32 g_nThreadCount = 1;
199 NdbMutex* g_pNdbMutex = 0;
200 
201 extern "C" void* NdbThreadFuncInsert(void* pArg)
202 {
203  myRandom48Init((long int)NdbTick_CurrentMillisecond());
204  unsigned nSucc = 0;
205  unsigned nFail = 0;
206  Ndb* pNdb = NULL ;
207  pNdb = new Ndb("TEST_DB");
208  VerifyMethodInt(pNdb, init());
209  VerifyMethodInt(pNdb, waitUntilReady());
210 
211  while(NdbMutex_Trylock(g_pNdbMutex)) {
212  Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
213  NdbConnection* pNdbConnection = NULL ;
214  VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
215  CHK_TR(pNdbConnection);
216  NdbOperation* pNdbOperationW = NULL ;
217  VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
218  VerifyMethodInt(pNdbOperationW, insertTuple());
219  VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
220  VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseCount, Uint32(1)));
221  Uint32 nWarehouseSum = 0;
222  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
223  NdbOperation* pNdbOperationD = NULL ;
224  VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
225  VerifyMethodInt(pNdbOperationD, insertTuple());
226  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
227  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
228  VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictCount, Uint32(1)));
229  Uint32 nDistrictSum = myRandom48(100);
230  nWarehouseSum += nDistrictSum;
231  VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum));
232  }
233  VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum));
234  int iExec = pNdbConnection->execute(Commit);
235  int iError = pNdbConnection->getNdbError().code;
236 
237  if(iExec<0 && iError!=0 && iError!=266 && iError!=630) {
238  ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
239  }
240  if(iExec==0) {
241  ++nSucc;
242  } else {
243  ++nFail;
244  }
245  VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
246  }
247  ndbout << "insert: " << nSucc << " succeeded, " << nFail << " failed " << endl;
248  NdbMutex_Unlock(g_pNdbMutex);
249  delete pNdb;
250  pNdb = NULL ;
251  return NULL;
252 }
253 
254 
255 extern "C" void* NdbThreadFuncUpdate(void* pArg)
256 {
257  myRandom48Init((long int)NdbTick_CurrentMillisecond());
258  unsigned nSucc = 0;
259  unsigned nFail = 0;
260  Ndb* pNdb = NULL ;
261  pNdb = new Ndb("TEST_DB");
262  VerifyMethodInt(pNdb, init());
263  VerifyMethodInt(pNdb, waitUntilReady());
264 
265  while(NdbMutex_Trylock(g_pNdbMutex)) {
266  Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
267  NdbConnection* pNdbConnection = NULL ;
268  VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
269  CHK_TR(pNdbConnection) ; // epaulsa
270  NdbOperation* pNdbOperationW = NULL ;
271  VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
272  VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple());
273  VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
274  VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1)));
275  Uint32 nWarehouseSum = 0;
276  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
277  NdbOperation* pNdbOperationD = NULL ;
278  VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
279  VerifyMethodInt(pNdbOperationD, interpretedUpdateTuple());
280  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
281  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
282  VerifyMethodInt(pNdbOperationD, incValue(c_szDistrictCount, Uint32(1)));
283  Uint32 nDistrictSum = myRandom48(100);
284  nWarehouseSum += nDistrictSum;
285  VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum));
286  }
287  VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum));
288  int iExec = pNdbConnection->execute(Commit);
289  int iError = pNdbConnection->getNdbError().code;
290 
291  if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
292  ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
293  }
294  if(iExec==0) {
295  ++nSucc;
296  } else {
297  ++nFail;
298  }
299  VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
300  }
301  ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl;
302  NdbMutex_Unlock(g_pNdbMutex);
303  delete pNdb;
304  pNdb = NULL ;
305  return NULL;
306 }
307 
308 
309 extern "C" void* NdbThreadFuncDelete(void* pArg)
310 {
311  myRandom48Init((long int)NdbTick_CurrentMillisecond());
312  unsigned nSucc = 0;
313  unsigned nFail = 0;
314  Ndb* pNdb = NULL ;
315  pNdb = new Ndb("TEST_DB");
316  VerifyMethodInt(pNdb, init());
317  VerifyMethodInt(pNdb, waitUntilReady());
318 
319  while(NdbMutex_Trylock(g_pNdbMutex)) {
320  Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
321  NdbConnection* pNdbConnection = NULL ;
322  VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
323  CHK_TR(pNdbConnection) ; // epaulsa
324  NdbOperation* pNdbOperationW = NULL ;
325  VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
326  VerifyMethodInt(pNdbOperationW, deleteTuple());
327  VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
328  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
329  NdbOperation* pNdbOperationD = NULL ;
330  VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
331  VerifyMethodInt(pNdbOperationD, deleteTuple());
332  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
333  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
334  }
335  int iExec = pNdbConnection->execute(Commit);
336  int iError = pNdbConnection->getNdbError().code;
337 
338  if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
339  ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
340  }
341  if(iExec==0) {
342  ++nSucc;
343  } else {
344  ++nFail;
345  }
346  VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
347  }
348  ndbout << "delete: " << nSucc << " succeeded, " << nFail << " failed " << endl;
349  NdbMutex_Unlock(g_pNdbMutex);
350  delete pNdb;
351  pNdb = NULL ;
352  return NULL;
353 }
354 
355 
356 extern "C" void* NdbThreadFuncRead(void* pArg)
357 {
358  myRandom48Init((long int)NdbTick_CurrentMillisecond());
359  unsigned nSucc = 0;
360  unsigned nFail = 0;
361  NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse];
362  NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse];
363  Ndb* pNdb = NULL ;
364  pNdb = new Ndb("TEST_DB");
365  VerifyMethodInt(pNdb, init());
366  VerifyMethodInt(pNdb, waitUntilReady());
367 
368  while(NdbMutex_Trylock(g_pNdbMutex)) {
369  Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
370  NdbConnection* pNdbConnection = NULL ;
371  VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
372  CHK_TR(pNdbConnection) ; // epaulsa
373  NdbOperation* pNdbOperationW = NULL ;
374  VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
375  VerifyMethodInt(pNdbOperationW, readTuple());
376  VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
377  NdbRecAttr* pNdbRecAttrWSum;
378  VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0));
379  NdbRecAttr* pNdbRecAttrWCnt;
380  VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0));
381  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
382  NdbOperation* pNdbOperationD = NULL ;
383  VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
384  VerifyMethodInt(pNdbOperationD, readTuple());
385  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
386  VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
387  VerifyMethodPtr(ppNdbRecAttrDSum[nDistrict], pNdbOperationD, getValue(c_szDistrictSum, 0));
388  VerifyMethodPtr(ppNdbRecAttrDCnt[nDistrict], pNdbOperationD, getValue(c_szDistrictCount, 0));
389  }
390  int iExec = pNdbConnection->execute(Commit);
391  int iError = pNdbConnection->getNdbError().code;
392 
393  if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
394  ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
395  }
396  if(iExec==0) {
397  Uint32 nSum = 0;
398  Uint32 nCnt = 0;
399  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
400  nSum += ppNdbRecAttrDSum[nDistrict]->u_32_value();
401  nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value();
402  }
403  if(nSum!=pNdbRecAttrWSum->u_32_value()
404  || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) {
405  ndbout << "INCONSISTENT!" << endl;
406  ndbout << "iExec==" << iExec << endl;
407  ndbout << "iError==" << iError << endl;
408  ndbout << endl;
409  ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", ";
410  ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl;
411  ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl;
412  for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
413  ndbout << c_szDistrictSum << "[" << nDistrict << "]==" << ppNdbRecAttrDSum[nDistrict]->u_32_value() << ", ";
414  ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl;
415  }
416  VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
417  delete pNdb; pNdb = NULL ;
418  delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ;
419  delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ;
420  NDBT_ProgramExit(NDBT_FAILED);
421  }
422  ++nSucc;
423  } else {
424  ++nFail;
425  }
426  VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
427  }
428  ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl;
429  NdbMutex_Unlock(g_pNdbMutex);
430  delete pNdb; pNdb = NULL ;
431  delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ;
432  delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ;
433  return NULL;
434 }
435 
436 
437 NDB_COMMAND(acid, "acid", "acid", "acid", 65535)
438 {
439  ndb_init();
440  long nSeconds = 60;
441  int rc = NDBT_OK;
442 
443  for(int i=1; i<argc; ++i) {
444  if(argv[i][0]=='-' || argv[i][0]=='/') {
445  switch(argv[i][1]) {
446  case 'w': g_nWarehouseCount=atol(argv[i]+2); break;
447  case 'd': g_nDistrictPerWarehouse=atol(argv[i]+2); break;
448  case 's': nSeconds=atol(argv[i]+2); break;
449  case 't': g_nThreadCount=atol(argv[i]+2); break;
450  default: ndbout << "invalid option" << endl; return 1;
451  }
452  } else {
453  ndbout << "invalid operand" << endl;
454  return 1;
455  }
456  }
457  ndbout << argv[0];
458  ndbout << " -w" << g_nWarehouseCount;
459  ndbout << " -d" << g_nDistrictPerWarehouse;
460  ndbout << " -s" << (int)nSeconds;
461  ndbout << " -t" << g_nThreadCount;
462  ndbout << endl;
463 
464  Ndb* pNdb = NULL ;
465  pNdb = new Ndb("TEST_DB");
466  VerifyMethodInt(pNdb, init());
467  VerifyMethodInt(pNdb, waitUntilReady());
468 
469  NdbSchemaCon* pNdbSchemaCon= NdbSchemaCon::startSchemaTrans(pNdb);
470  if(!pNdbSchemaCon){
471  ndbout <<"startSchemaTransaction failed, exiting now" << endl ;
472  delete pNdb ;
473  NDBT_ProgramExit(NDBT_FAILED) ;
474  }
475  NdbSchemaOp* pNdbSchemaOp = NULL ;
476  VerifyMethodPtr(pNdbSchemaOp, pNdbSchemaCon, getNdbSchemaOp());
477  VerifyMethodInt(pNdbSchemaOp, createTable(
478  c_szWarehouse,
479  (4+4+4+12)*1.02*g_nWarehouseCount/1024+1,
480  TupleKey,
481  (4+14)*g_nWarehouseCount/8/1024+1));
482 
483  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
484  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseSum, NoKey, 32, 1, UnSigned, MMBased, false));
485  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szWarehouseCount, NoKey, 32, 1, UnSigned, MMBased, false));
486  VerifyMethodInt(pNdbSchemaCon, execute());
487  NdbSchemaCon::closeSchemaTrans(pNdbSchemaCon);
488 
489  pNdbSchemaCon= NdbSchemaCon::startSchemaTrans(pNdb);
490  VerifyMethodPtr(pNdbSchemaOp, pNdbSchemaCon, getNdbSchemaOp());
491  VerifyMethodInt(pNdbSchemaOp, createTable(
492  c_szDistrict,
493  (4+4+4+4+12)*1.02*g_nWarehouseCount*g_nDistrictPerWarehouse/1024+1,
494  TupleKey,
495  (4+4+14)*g_nWarehouseCount*g_nDistrictPerWarehouse/8/1024+1));
496 
497 
498  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictWarehouseNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
499  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictNumber, TupleKey, 32, 1, UnSigned, MMBased, false));
500  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictSum, NoKey, 32, 1, UnSigned, MMBased, false));
501  VerifyMethodInt(pNdbSchemaOp, createAttribute(c_szDistrictCount, NoKey, 32, 1, UnSigned, MMBased, false));
502  VerifyMethodInt(pNdbSchemaCon, execute());
503  NdbSchemaCon::closeSchemaTrans(pNdbSchemaCon);
504  g_pNdbMutex = NdbMutex_Create();
505  NdbMutex_Lock(g_pNdbMutex);
506 
507  NdbThread** ppNdbThread = new NdbThread*[g_nThreadCount*4];
508  for(Uint32 nThread=0; nThread<g_nThreadCount; ++nThread) {
509  ppNdbThread[nThread*4+0] = NdbThread_Create(NdbThreadFuncInsert, 0, 65535, "insert",
510  NDB_THREAD_PRIO_LOW);
511  ppNdbThread[nThread*4+1] = NdbThread_Create(NdbThreadFuncUpdate, 0, 65535, "update",
512  NDB_THREAD_PRIO_LOW);
513  ppNdbThread[nThread*4+2] = NdbThread_Create(NdbThreadFuncDelete, 0, 65535, "delete",
514  NDB_THREAD_PRIO_LOW);
515  ppNdbThread[nThread*4+3] = NdbThread_Create(NdbThreadFuncRead, 0, 65535, "read",
516  NDB_THREAD_PRIO_LOW);
517  }
518 
519  NdbSleep_SecSleep(nSeconds);
520  NdbMutex_Unlock(g_pNdbMutex);
521 
522  void* pStatus;
523  for(Uint32 nThread=0; nThread<g_nThreadCount; ++nThread) {
524  NdbThread_WaitFor(ppNdbThread[nThread*4+0], &pStatus);
525  NdbThread_WaitFor(ppNdbThread[nThread*4+1], &pStatus);
526  NdbThread_WaitFor(ppNdbThread[nThread*4+2], &pStatus);
527  NdbThread_WaitFor(ppNdbThread[nThread*4+3], &pStatus);
528  }
529 
530  NdbMutex_Destroy(g_pNdbMutex);
531  delete[] ppNdbThread;
532  delete pNdb;
533  return NDBT_ProgramExit(rc);
534 }
535