testReadPerf.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 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; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <NDBT.hpp>
  14. #include <NDBT_Test.hpp>
  15. #include <HugoTransactions.hpp>
  16. #include <UtilTransactions.hpp>
  17. #include <random.h>
  18. #include <getarg.h>
  19. struct Parameter {
  20.   const char * name;
  21.   unsigned value;
  22.   unsigned min;
  23.   unsigned max; 
  24. };
  25. #define P_OPER    0
  26. #define P_RANGE   1
  27. #define P_ROWS    2
  28. #define P_LOOPS   3
  29. #define P_CREATE  4
  30. #define P_LOAD    5
  31. #define P_MAX 6
  32. /**
  33.  * operation
  34.  * 0 - serial pk
  35.  * 1 - batch pk
  36.  * 2 - serial uniq 
  37.  * 3 - batch uniq
  38.  * 4 - index eq
  39.  * 5 - range scan
  40.  * 6 - ordered range scan
  41.  * 7 - interpreted scan
  42.  */ 
  43. static const char * g_ops[] = {
  44.   "serial pk",
  45.   "batch pk",
  46.   "serial uniq index access",
  47.   "batch uniq index access",
  48.   "index eq-bound",
  49.   "index range",
  50.   "index ordered",
  51.   "interpreted scan"
  52. };
  53. #define P_OP_TYPES 8
  54. static Uint64 g_times[P_OP_TYPES];
  55. static 
  56. Parameter 
  57. g_paramters[] = {
  58.   { "operation",   0, 0, 6 }, // 0 
  59.   { "range",    1000, 1, ~0 },// 1 no of rows to read
  60.   { "size",  1000000, 1, ~0 },// 2 rows in tables
  61.   { "iterations",  3, 1, ~0 },// 3
  62.   { "create_drop", 0, 0, 1 }, // 4
  63.   { "data",        0, 0, 1 }  // 5
  64. };
  65. static Ndb* g_ndb = 0;
  66. static const NdbDictionary::Table * g_tab;
  67. static const NdbDictionary::Index * g_i_unique;
  68. static const NdbDictionary::Index * g_i_ordered;
  69. static char g_table[256];
  70. static char g_unique[256];
  71. static char g_ordered[256];
  72. static char g_buffer[2*1024*1024];
  73. int create_table();
  74. int load_table();
  75. int run_read();
  76. int clear_table();
  77. int drop_table();
  78. void print_result();
  79. int
  80. main(int argc, const char** argv){
  81.   ndb_init();
  82.   int verbose = 1;
  83.   int optind = 0;
  84.   
  85.   struct getargs args[1+P_MAX] = {
  86.     { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" }
  87.   };
  88.   const int num_args = 1 + P_MAX;
  89.   int i;
  90.   for(i = 0; i<P_MAX; i++){
  91.     args[i+1].long_name = g_paramters[i].name;
  92.     args[i+1].short_name = * g_paramters[i].name;
  93.     args[i+1].type = arg_integer;
  94.     args[i+1].value = &g_paramters[i].value;
  95.     BaseString tmp;
  96.     tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max);
  97.     args[i+1].help = strdup(tmp.c_str());
  98.     args[i+1].arg_help = 0;
  99.   }
  100.   
  101.   if(getarg(args, num_args, argc, argv, &optind)) {
  102.     arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ...");
  103.     return NDBT_WRONGARGS;
  104.   }
  105.   
  106.   myRandom48Init(NdbTick_CurrentMillisecond());
  107.   memset(g_times, 0, sizeof(g_times));
  108.   g_ndb = new Ndb("TEST_DB");
  109.   if(g_ndb->init() != 0){
  110.     g_err << "init() failed" << endl;
  111.     goto error;
  112.   }
  113.   if(g_ndb->waitUntilReady() != 0){
  114.     g_err << "Wait until ready failed" << endl;
  115.     goto error;
  116.   }
  117.   for(i = optind; i<argc; i++){
  118.     const char * T = argv[i];
  119.     g_info << "Testing " << T << endl;
  120.     BaseString::snprintf(g_table, sizeof(g_table), T);
  121.     BaseString::snprintf(g_ordered, sizeof(g_ordered), "IDX_O_%s", T);
  122.     BaseString::snprintf(g_unique, sizeof(g_unique), "IDX_U_%s", T);
  123.     if(create_table())
  124.       goto error;
  125.     if(load_table())
  126.       goto error;
  127.     for(int l = 0; l<g_paramters[P_LOOPS].value; l++){
  128.       for(int j = 0; j<P_OP_TYPES; j++){
  129. g_paramters[P_OPER].value = j;
  130. if(run_read())
  131.   goto error;
  132.       }
  133.     }
  134.     print_result();
  135.   }
  136.   
  137.   if(g_ndb) delete g_ndb;
  138.   return NDBT_OK;
  139. error:
  140.   if(g_ndb) delete g_ndb;
  141.   return NDBT_FAILED;
  142. }
  143. int
  144. create_table(){
  145.   NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  146.   assert(dict);
  147.   if(g_paramters[P_CREATE].value){
  148.     const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_table);
  149.     assert(pTab);
  150.     NdbDictionary::Table copy = * pTab;
  151.     copy.setLogging(false);
  152.     if(dict->createTable(copy) != 0){
  153.       g_err << "Failed to create table: " << g_table << endl;
  154.       return -1;
  155.     }
  156.     NdbDictionary::Index x(g_ordered);
  157.     x.setTable(g_table);
  158.     x.setType(NdbDictionary::Index::OrderedIndex);
  159.     x.setLogging(false);
  160.     for (unsigned k = 0; k < copy.getNoOfColumns(); k++){
  161.       if(copy.getColumn(k)->getPrimaryKey()){
  162. x.addColumn(copy.getColumn(k)->getName());
  163.       }
  164.     }
  165.     if(dict->createIndex(x) != 0){
  166.       g_err << "Failed to create index: " << endl;
  167.       return -1;
  168.     }
  169.     x.setName(g_unique);
  170.     x.setType(NdbDictionary::Index::UniqueHashIndex);
  171.     if(dict->createIndex(x) != 0){
  172.       g_err << "Failed to create index: " << endl;
  173.       return -1;
  174.     }
  175.   }
  176.   g_tab = dict->getTable(g_table);
  177.   g_i_unique = dict->getIndex(g_unique, g_table);
  178.   g_i_ordered = dict->getIndex(g_ordered, g_table);
  179.   assert(g_tab);
  180.   assert(g_i_unique);
  181.   assert(g_i_ordered);
  182.   return 0;
  183. }
  184. int
  185. drop_table(){
  186.   if(!g_paramters[P_CREATE].value)
  187.     return 0;
  188.   if(g_ndb->getDictionary()->dropTable(g_tab->getName()) != 0){
  189.     g_err << "Failed to drop table: " << g_tab->getName() << endl;
  190.     return -1;
  191.   }
  192.   g_tab = 0;
  193.   return 0;
  194. }
  195. int
  196. load_table(){
  197.   if(!g_paramters[P_LOAD].value)
  198.     return 0;
  199.   
  200.   int rows = g_paramters[P_ROWS].value;
  201.   HugoTransactions hugoTrans(* g_tab);
  202.   if (hugoTrans.loadTable(g_ndb, rows)){
  203.     g_err.println("Failed to load %s with %d rows", g_tab->getName(), rows);
  204.     return -1;
  205.   }
  206.   return 0;
  207. }
  208. int
  209. clear_table(){
  210.   if(!g_paramters[P_LOAD].value)
  211.     return 0;
  212.   int rows = g_paramters[P_ROWS].value;
  213.   
  214.   UtilTransactions utilTrans(* g_tab);
  215.   if (utilTrans.clearTable(g_ndb,  rows) != 0){
  216.     g_err.println("Failed to clear table %s", g_tab->getName());
  217.     return -1;
  218.   }
  219.   return 0;
  220. }
  221. inline 
  222. void err(NdbError e){
  223.   ndbout << e << endl;
  224. }
  225. int
  226. run_read(){
  227.   int iter = g_paramters[P_LOOPS].value;
  228.   NDB_TICKS start1, stop;
  229.   int sum_time= 0;
  230.   
  231.   const Uint32 rows = g_paramters[P_ROWS].value;
  232.   const Uint32 range = g_paramters[P_RANGE].value;
  233.   
  234.   start1 = NdbTick_CurrentMillisecond();
  235.   NdbConnection * pTrans = g_ndb->startTransaction();
  236.   if(!pTrans){
  237.     g_err << "Failed to start transaction" << endl;
  238.     err(g_ndb->getNdbError());
  239.     return -1;
  240.   }
  241.   
  242.   NdbOperation * pOp;
  243.   NdbScanOperation * pSp;
  244.   NdbIndexOperation * pUp;
  245.   NdbIndexScanOperation * pIp;
  246.   NdbResultSet * rs = (NdbResultSet*)~0;
  247.   
  248.   Uint32 start_row = rand() % (rows - range);
  249.   Uint32 stop_row = start_row + range;
  250.   /**
  251.    * 0 - serial pk
  252.    * 1 - batch pk
  253.    * 2 - serial uniq 
  254.    * 3 - batch uniq
  255.    * 4 - index eq
  256.    * 5 - range scan
  257.    * 6 - interpreted scan
  258.    */
  259.   int check = 0;
  260.   void* res = (void*)~0;
  261.   const Uint32 pk = 0;
  262.   Uint32 cnt = 0;
  263.   for(; start_row < stop_row; start_row++){
  264.     switch(g_paramters[P_OPER].value){
  265.     case 0:
  266.       pOp = pTrans->getNdbOperation(g_table);
  267.       check = pOp->readTuple();
  268.       check = pOp->equal(pk, start_row);
  269.       break;
  270.     case 1:
  271.       for(; start_row<stop_row; start_row++){
  272. pOp = pTrans->getNdbOperation(g_table);
  273. check = pOp->readTuple();
  274. check = pOp->equal(pk, start_row);
  275. for(int j = 0; j<g_tab->getNoOfColumns(); j++){
  276.   res = pOp->getValue(j);
  277.   assert(res);
  278. }
  279.       }
  280.       break;
  281.     case 2:
  282.       pOp = pTrans->getNdbIndexOperation(g_unique, g_table);
  283.       check = pOp->readTuple();
  284.       check = pOp->equal(pk, start_row);
  285.       break;
  286.     case 3:
  287.       for(; start_row<stop_row; start_row++){
  288. pOp = pTrans->getNdbIndexOperation(g_unique, g_table);
  289. check = pOp->readTuple();
  290. check = pOp->equal(pk, start_row);
  291. for(int j = 0; j<g_tab->getNoOfColumns(); j++){
  292.   res = pOp->getValue(j);
  293.   assert(res);
  294. }
  295.       }
  296.       break;
  297.     case 4:
  298.       pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
  299.       rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
  300.       check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row);
  301.       break;
  302.     case 5:
  303.       pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
  304.       rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
  305.       check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
  306.       check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
  307.       start_row = stop_row;
  308.       break;
  309.     case 6:
  310.       pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
  311.       rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true);
  312.       check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
  313.       check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
  314.       start_row = stop_row;
  315.       break;
  316.     case 7:
  317.       pOp = pSp = pTrans->getNdbScanOperation(g_table);
  318.       rs = pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
  319.       NdbScanFilter filter(pOp) ;   
  320.       filter.begin(NdbScanFilter::AND);
  321.       filter.ge(pk, start_row);
  322.       filter.lt(pk, stop_row);
  323.       filter.end();
  324.       start_row = stop_row;
  325.       break;
  326.     }
  327.       
  328.     assert(res);
  329.     if(check != 0){
  330.       ndbout << pOp->getNdbError() << endl;
  331.       ndbout << pTrans->getNdbError() << endl;
  332.     }
  333.     assert(check == 0);
  334.     assert(rs);
  335.     for(int j = 0; j<g_tab->getNoOfColumns(); j++){
  336.       res = pOp->getValue(j);
  337.       assert(res);
  338.     }
  339.       
  340.     check = pTrans->execute(NoCommit);
  341.     if(check != 0){
  342.       ndbout << pTrans->getNdbError() << endl;
  343.     }
  344.     assert(check == 0);
  345.     if(g_paramters[P_OPER].value >= 4){
  346.       while((check = rs->nextResult(true)) == 0){
  347. cnt++;
  348.       }
  349.       if(check == -1){
  350. err(pTrans->getNdbError());
  351. return -1;
  352.       }
  353.       assert(check == 1);
  354.       rs->close();
  355.     }
  356.   }
  357.   assert(g_paramters[P_OPER].value < 4 || (cnt == range));
  358.     
  359.   pTrans->close();
  360.     
  361.   stop = NdbTick_CurrentMillisecond();
  362.   g_times[g_paramters[P_OPER].value] += (stop - start1);
  363.   return 0;
  364. }
  365. void
  366. print_result(){
  367.   int tmp = 1;
  368.   tmp *= g_paramters[P_RANGE].value;
  369.   tmp *= g_paramters[P_LOOPS].value;
  370.   int t, t2;
  371.   for(int i = 0; i<P_OP_TYPES; i++){
  372.     g_err << g_ops[i] << " avg: "
  373.   << (int)((1000*g_times[i])/tmp)
  374.   << " us/row (" 
  375.   << (1000 * tmp)/g_times[i] << " rows / sec)" << endl;
  376.   }
  377. }