PageRenderTime 20ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/release/src/router/mysql/storage/ndb/test/tools/listen.cpp

https://gitlab.com/envieidoc/advancedtomato2
C++ | 374 lines | 312 code | 43 blank | 19 comment | 50 complexity | 23a10a9ed508602cf42f0d8efc492c16 MD5 | raw file
  1. /* Copyright (c) 2003, 2005-2007 MySQL AB
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software
  11. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
  12. #include <NdbOut.hpp>
  13. #include <NdbApi.hpp>
  14. #include <NdbSleep.h>
  15. #include <NDBT.hpp>
  16. #include <HugoTransactions.hpp>
  17. #include <getarg.h>
  18. #define BATCH_SIZE 128
  19. struct Table_info
  20. {
  21. Uint32 id;
  22. };
  23. struct Trans_arg
  24. {
  25. Ndb *ndb;
  26. NdbTransaction *trans;
  27. Uint32 bytes_batched;
  28. };
  29. Vector< Vector<NdbRecAttr*> > event_values;
  30. Vector< Vector<NdbRecAttr*> > event_pre_values;
  31. Vector<struct Table_info> table_infos;
  32. static void do_begin(Ndb *ndb, struct Trans_arg &trans_arg)
  33. {
  34. trans_arg.ndb = ndb;
  35. trans_arg.trans = ndb->startTransaction();
  36. trans_arg.bytes_batched = 0;
  37. }
  38. static void do_equal(NdbOperation *op,
  39. NdbEventOperation *pOp)
  40. {
  41. struct Table_info *ti = (struct Table_info *)pOp->getCustomData();
  42. Vector<NdbRecAttr*> &ev = event_values[ti->id];
  43. const NdbDictionary::Table *tab= pOp->getTable();
  44. unsigned i, n_columns = tab->getNoOfColumns();
  45. for (i= 0; i < n_columns; i++)
  46. {
  47. if (tab->getColumn(i)->getPrimaryKey() &&
  48. op->equal(i, ev[i]->aRef()))
  49. {
  50. abort();
  51. }
  52. }
  53. }
  54. static void do_set_value(NdbOperation *op,
  55. NdbEventOperation *pOp)
  56. {
  57. struct Table_info *ti = (struct Table_info *)pOp->getCustomData();
  58. Vector<NdbRecAttr*> &ev = event_values[ti->id];
  59. const NdbDictionary::Table *tab= pOp->getTable();
  60. unsigned i, n_columns = tab->getNoOfColumns();
  61. for (i= 0; i < n_columns; i++)
  62. {
  63. if (!tab->getColumn(i)->getPrimaryKey() &&
  64. op->setValue(i, ev[i]->aRef()))
  65. {
  66. abort();
  67. }
  68. }
  69. }
  70. static void do_insert(struct Trans_arg &trans_arg, NdbEventOperation *pOp)
  71. {
  72. if (!trans_arg.trans)
  73. return;
  74. NdbOperation *op =
  75. trans_arg.trans->getNdbOperation(pOp->getEvent()->getTableName());
  76. op->writeTuple();
  77. do_equal(op, pOp);
  78. do_set_value(op, pOp);
  79. trans_arg.bytes_batched++;
  80. if (trans_arg.bytes_batched > BATCH_SIZE)
  81. {
  82. trans_arg.trans->execute(NdbTransaction::NoCommit);
  83. trans_arg.bytes_batched = 0;
  84. }
  85. }
  86. static void do_update(struct Trans_arg &trans_arg, NdbEventOperation *pOp)
  87. {
  88. if (!trans_arg.trans)
  89. return;
  90. NdbOperation *op =
  91. trans_arg.trans->getNdbOperation(pOp->getEvent()->getTableName());
  92. op->writeTuple();
  93. do_equal(op, pOp);
  94. do_set_value(op, pOp);
  95. trans_arg.bytes_batched++;
  96. if (trans_arg.bytes_batched > BATCH_SIZE)
  97. {
  98. trans_arg.trans->execute(NdbTransaction::NoCommit);
  99. trans_arg.bytes_batched = 0;
  100. }
  101. }
  102. static void do_delete(struct Trans_arg &trans_arg, NdbEventOperation *pOp)
  103. {
  104. if (!trans_arg.trans)
  105. return;
  106. NdbOperation *op =
  107. trans_arg.trans->getNdbOperation(pOp->getEvent()->getTableName());
  108. op->deleteTuple();
  109. do_equal(op, pOp);
  110. trans_arg.bytes_batched++;
  111. if (trans_arg.bytes_batched > BATCH_SIZE)
  112. {
  113. trans_arg.trans->execute(NdbTransaction::NoCommit);
  114. trans_arg.bytes_batched = 0;
  115. }
  116. }
  117. static void do_commit(struct Trans_arg &trans_arg)
  118. {
  119. if (!trans_arg.trans)
  120. return;
  121. trans_arg.trans->execute(NdbTransaction::Commit);
  122. trans_arg.ndb->closeTransaction(trans_arg.trans);
  123. }
  124. int
  125. main(int argc, const char** argv){
  126. ndb_init();
  127. int _help = 0;
  128. const char* db = 0;
  129. const char* connectstring1 = 0;
  130. const char* connectstring2 = 0;
  131. struct getargs args[] = {
  132. { "connectstring1", 'c',
  133. arg_string, &connectstring1, "connectstring1", "" },
  134. { "connectstring2", 'C',
  135. arg_string, &connectstring2, "connectstring2", "" },
  136. { "database", 'd', arg_string, &db, "Database", "" },
  137. { "usage", '?', arg_flag, &_help, "Print help", "" }
  138. };
  139. int num_args = sizeof(args) / sizeof(args[0]);
  140. int optind = 0, i;
  141. char desc[] =
  142. "<tabname>+ \nThis program listen to events on specified tables\n";
  143. if(getarg(args, num_args, argc, argv, &optind) ||
  144. argv[optind] == NULL || _help) {
  145. arg_printusage(args, num_args, argv[0], desc);
  146. return NDBT_ProgramExit(NDBT_WRONGARGS);
  147. }
  148. // Connect to Ndb
  149. Ndb_cluster_connection con(connectstring1);
  150. if(con.connect(12, 5, 1) != 0)
  151. {
  152. return NDBT_ProgramExit(NDBT_FAILED);
  153. }
  154. Ndb MyNdb( &con, db ? db : "TEST_DB" );
  155. if(MyNdb.init() != 0){
  156. ERR(MyNdb.getNdbError());
  157. return NDBT_ProgramExit(NDBT_FAILED);
  158. }
  159. // Connect to Ndb and wait for it to become ready
  160. while(MyNdb.waitUntilReady() != 0)
  161. ndbout << "Waiting for ndb to become ready..." << endl;
  162. Ndb_cluster_connection *con2 = NULL;
  163. Ndb *ndb2 = NULL;
  164. if (connectstring2)
  165. {
  166. con2 = new Ndb_cluster_connection(connectstring2);
  167. if(con2->connect(12, 5, 1) != 0)
  168. {
  169. return NDBT_ProgramExit(NDBT_FAILED);
  170. }
  171. ndb2 = new Ndb( con2, db ? db : "TEST_DB" );
  172. if(ndb2->init() != 0){
  173. ERR(ndb2->getNdbError());
  174. return NDBT_ProgramExit(NDBT_FAILED);
  175. }
  176. // Connect to Ndb and wait for it to become ready
  177. while(ndb2->waitUntilReady() != 0)
  178. ndbout << "Waiting for ndb to become ready..." << endl;
  179. }
  180. int result = 0;
  181. NdbDictionary::Dictionary *myDict = MyNdb.getDictionary();
  182. Vector<NdbDictionary::Event*> events;
  183. Vector<NdbEventOperation*> event_ops;
  184. int sz = 0;
  185. for(i= optind; i<argc; i++)
  186. {
  187. const NdbDictionary::Table* table= myDict->getTable(argv[i]);
  188. if(!table)
  189. {
  190. ndbout_c("Could not find table: %s, skipping", argv[i]);
  191. continue;
  192. }
  193. BaseString name;
  194. name.appfmt("EV-%s", argv[i]);
  195. NdbDictionary::Event *myEvent= new NdbDictionary::Event(name.c_str());
  196. myEvent->setTable(table->getName());
  197. myEvent->addTableEvent(NdbDictionary::Event::TE_ALL);
  198. for(int a = 0; a < table->getNoOfColumns(); a++){
  199. myEvent->addEventColumn(a);
  200. }
  201. if (myDict->createEvent(* myEvent))
  202. {
  203. if(myDict->getNdbError().classification == NdbError::SchemaObjectExists)
  204. {
  205. g_info << "Event creation failed event exists. Removing...\n";
  206. if (myDict->dropEvent(name.c_str()))
  207. {
  208. g_err << "Failed to drop event: " << myDict->getNdbError() << endl;
  209. result = 1;
  210. goto end;
  211. }
  212. // try again
  213. if (myDict->createEvent(* myEvent))
  214. {
  215. g_err << "Failed to create event: " << myDict->getNdbError() << endl;
  216. result = 1;
  217. goto end;
  218. }
  219. }
  220. else
  221. {
  222. g_err << "Failed to create event: " << myDict->getNdbError() << endl;
  223. result = 1;
  224. goto end;
  225. }
  226. }
  227. events.push_back(myEvent);
  228. NdbEventOperation* pOp = MyNdb.createEventOperation(name.c_str());
  229. if ( pOp == NULL ) {
  230. g_err << "Event operation creation failed" << endl;
  231. result = 1;
  232. goto end;
  233. }
  234. event_values.push_back(Vector<NdbRecAttr *>());
  235. event_pre_values.push_back(Vector<NdbRecAttr *>());
  236. for (int a = 0; a < table->getNoOfColumns(); a++)
  237. {
  238. event_values[sz].
  239. push_back(pOp->getValue(table->getColumn(a)->getName()));
  240. event_pre_values[sz].
  241. push_back(pOp->getPreValue(table->getColumn(a)->getName()));
  242. }
  243. event_ops.push_back(pOp);
  244. {
  245. struct Table_info ti;
  246. ti.id = sz;
  247. table_infos.push_back(ti);
  248. }
  249. pOp->setCustomData((void *)&table_infos[sz]);
  250. sz++;
  251. }
  252. for(i= 0; i<(int)event_ops.size(); i++)
  253. {
  254. if (event_ops[i]->execute())
  255. {
  256. g_err << "operation execution failed: " << event_ops[i]->getNdbError()
  257. << endl;
  258. result = 1;
  259. goto end;
  260. }
  261. }
  262. struct Trans_arg trans_arg;
  263. while(true)
  264. {
  265. while(MyNdb.pollEvents(100) == 0);
  266. NdbEventOperation* pOp= MyNdb.nextEvent();
  267. while(pOp)
  268. {
  269. Uint64 gci= pOp->getGCI();
  270. Uint64 cnt_i= 0, cnt_u= 0, cnt_d= 0;
  271. if (ndb2)
  272. do_begin(ndb2, trans_arg);
  273. do
  274. {
  275. switch(pOp->getEventType())
  276. {
  277. case NdbDictionary::Event::TE_INSERT:
  278. cnt_i++;
  279. if (ndb2)
  280. do_insert(trans_arg, pOp);
  281. break;
  282. case NdbDictionary::Event::TE_DELETE:
  283. cnt_d++;
  284. if (ndb2)
  285. do_delete(trans_arg, pOp);
  286. break;
  287. case NdbDictionary::Event::TE_UPDATE:
  288. cnt_u++;
  289. if (ndb2)
  290. do_update(trans_arg, pOp);
  291. break;
  292. case NdbDictionary::Event::TE_CLUSTER_FAILURE:
  293. break;
  294. case NdbDictionary::Event::TE_ALTER:
  295. break;
  296. case NdbDictionary::Event::TE_DROP:
  297. break;
  298. case NdbDictionary::Event::TE_NODE_FAILURE:
  299. break;
  300. case NdbDictionary::Event::TE_SUBSCRIBE:
  301. case NdbDictionary::Event::TE_UNSUBSCRIBE:
  302. break;
  303. default:
  304. /* We should REALLY never get here. */
  305. ndbout_c("Error: unknown event type: %u",
  306. (Uint32)pOp->getEventType());
  307. abort();
  308. }
  309. } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI());
  310. if (ndb2)
  311. do_commit(trans_arg);
  312. ndbout_c("GCI: %lld events: %lld(I) %lld(U) %lld(D)", gci, cnt_i, cnt_u, cnt_d);
  313. }
  314. }
  315. end:
  316. for(i= 0; i<(int)event_ops.size(); i++)
  317. MyNdb.dropEventOperation(event_ops[i]);
  318. if (ndb2)
  319. delete ndb2;
  320. if (con2)
  321. delete con2;
  322. return NDBT_ProgramExit(NDBT_OK);
  323. }
  324. template class Vector<struct Table_info>;
  325. template class Vector<NdbRecAttr*>;
  326. template class Vector< Vector<NdbRecAttr*> >;
  327. template class Vector<NdbDictionary::Event*>;
  328. template class Vector<NdbEventOperation*>;