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

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.   char * name;
  21.   unsigned value;
  22.   unsigned min;
  23.   unsigned max; 
  24. };
  25. #define P_BATCH   0
  26. #define P_PARRA   1
  27. #define P_LOCK    2
  28. #define P_FILT    3
  29. #define P_BOUND   4
  30. #define P_ACCESS  5
  31. #define P_FETCH   6
  32. #define P_ROWS    7
  33. #define P_LOOPS   8
  34. #define P_CREATE  9
  35. #define P_LOAD   10
  36. #define P_RESET  11
  37. #define P_MAX 12
  38. static 
  39. Parameter 
  40. g_paramters[] = {
  41.   { "batch",       0, 0, 1 }, // 0, 15
  42.   { "parallelism", 0, 0, 1 }, // 0,  1
  43.   { "lock",        0, 0, 2 }, // read, exclusive, dirty
  44.   { "filter",      0, 0, 3 }, // all, none, 1, 100
  45.   { "range",       0, 0, 3 }, // all, none, 1, 100
  46.   { "access",      0, 0, 2 }, // scan, idx, idx sorted
  47.   { "fetch",       0, 0, 1 }, // No, yes
  48.   { "size",  1000000, 1, ~0 },
  49.   { "iterations",  3, 1, ~0 },
  50.   { "create_drop", 1, 0, 1 },
  51.   { "data",        1, 0, 1 },
  52.   { "q-reset bounds", 0, 1, 0 }
  53. };
  54. static Ndb* g_ndb = 0;
  55. static const NdbDictionary::Table * g_table;
  56. static const NdbDictionary::Index * g_index;
  57. static char g_tablename[256];
  58. static char g_indexname[256];
  59. int create_table();
  60. int load_table();
  61. int run_scan();
  62. int clear_table();
  63. int drop_table();
  64. int
  65. main(int argc, const char** argv){
  66.   ndb_init();
  67.   int verbose = 1;
  68.   int optind = 0;
  69.   struct getargs args[1+P_MAX] = {
  70.     { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" }
  71.   };
  72.   const int num_args = 1 + P_MAX;
  73.   int i;
  74.   for(i = 0; i<P_MAX; i++){
  75.     args[i+1].long_name = g_paramters[i].name;
  76.     args[i+1].short_name = * g_paramters[i].name;
  77.     args[i+1].type = arg_integer;
  78.     args[i+1].value = &g_paramters[i].value;
  79.     BaseString tmp;
  80.     tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max);
  81.     args[i+1].help = strdup(tmp.c_str());
  82.     args[i+1].arg_help = 0;
  83.   }
  84.   
  85.   if(getarg(args, num_args, argc, argv, &optind)) {
  86.     arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ...");
  87.     return NDBT_WRONGARGS;
  88.   }
  89.   myRandom48Init(NdbTick_CurrentMillisecond());
  90.   g_ndb = new Ndb("TEST_DB");
  91.   if(g_ndb->init() != 0){
  92.     g_err << "init() failed" << endl;
  93.     goto error;
  94.   }
  95.   if(g_ndb->waitUntilReady() != 0){
  96.     g_err << "Wait until ready failed" << endl;
  97.     goto error;
  98.   }
  99.   for(i = optind; i<argc; i++){
  100.     const char * T = argv[i];
  101.     g_info << "Testing " << T << endl;
  102.     BaseString::snprintf(g_tablename, sizeof(g_tablename), T);
  103.     BaseString::snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T);
  104.     if(create_table())
  105.       goto error;
  106.     if(load_table())
  107.       goto error;
  108.     if(run_scan())
  109.       goto error;
  110.     if(clear_table())
  111.       goto error;
  112.     if(drop_table())
  113.       goto error;
  114.   }
  115.   if(g_ndb) delete g_ndb;
  116.   return NDBT_OK;
  117.  error:
  118.   if(g_ndb) delete g_ndb;
  119.   return NDBT_FAILED;
  120. }
  121. int
  122. create_table(){
  123.   NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  124.   assert(dict);
  125.   if(g_paramters[P_CREATE].value){
  126.     const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
  127.     assert(pTab);
  128.     NdbDictionary::Table copy = * pTab;
  129.     copy.setLogging(false);
  130.     if(dict->createTable(copy) != 0){
  131.       g_err << "Failed to create table: " << g_tablename << endl;
  132.       return -1;
  133.     }
  134.     NdbDictionary::Index x(g_indexname);
  135.     x.setTable(g_tablename);
  136.     x.setType(NdbDictionary::Index::OrderedIndex);
  137.     x.setLogging(false);
  138.     for (unsigned k = 0; k < copy.getNoOfColumns(); k++){
  139.       if(copy.getColumn(k)->getPrimaryKey()){
  140. x.addColumnName(copy.getColumn(k)->getName());
  141.       }
  142.     }
  143.     if(dict->createIndex(x) != 0){
  144.       g_err << "Failed to create index: " << endl;
  145.       return -1;
  146.     }
  147.   }
  148.   g_table = dict->getTable(g_tablename);
  149.   g_index = dict->getIndex(g_indexname, g_tablename);
  150.   assert(g_table);
  151.   assert(g_index);
  152.   return 0;
  153. }
  154. int
  155. drop_table(){
  156.   if(!g_paramters[P_CREATE].value)
  157.     return 0;
  158.   if(g_ndb->getDictionary()->dropTable(g_table->getName()) != 0){
  159.     g_err << "Failed to drop table: " << g_table->getName() << endl;
  160.     return -1;
  161.   }
  162.   g_table = 0;
  163.   return 0;
  164. }
  165. int
  166. load_table(){
  167.   if(!g_paramters[P_LOAD].value)
  168.     return 0;
  169.   
  170.   int rows = g_paramters[P_ROWS].value;
  171.   HugoTransactions hugoTrans(* g_table);
  172.   if (hugoTrans.loadTable(g_ndb, rows)){
  173.     g_err.println("Failed to load %s with %d rows", g_table->getName(), rows);
  174.     return -1;
  175.   }
  176.   return 0;
  177. }
  178. int
  179. clear_table(){
  180.   if(!g_paramters[P_LOAD].value)
  181.     return 0;
  182.   int rows = g_paramters[P_ROWS].value;
  183.   
  184.   UtilTransactions utilTrans(* g_table);
  185.   if (utilTrans.clearTable(g_ndb,  rows) != 0){
  186.     g_err.println("Failed to clear table %s", g_table->getName());
  187.     return -1;
  188.   }
  189.   return 0;
  190. }
  191. inline 
  192. void err(NdbError e){
  193.   ndbout << e << endl;
  194. }
  195. int
  196. run_scan(){
  197.   int iter = g_paramters[P_LOOPS].value;
  198.   NDB_TICKS start1, stop;
  199.   int sum_time= 0;
  200.   int sample_rows = 0;
  201.   int tot_rows = 0;
  202.   NDB_TICKS sample_start = NdbTick_CurrentMillisecond();
  203.   Uint32 tot = g_paramters[P_ROWS].value;
  204.   if(g_paramters[P_BOUND].value == 2 || g_paramters[P_FILT].value == 2)
  205.     iter *= g_paramters[P_ROWS].value;
  206.   NdbScanOperation * pOp = 0;
  207.   NdbIndexScanOperation * pIOp = 0;
  208.   NdbConnection * pTrans = 0;
  209.   NdbResultSet * rs = 0;
  210.   int check = 0;
  211.   for(int i = 0; i<iter; i++){
  212.     start1 = NdbTick_CurrentMillisecond();
  213.     pTrans = pTrans ? pTrans : g_ndb->startTransaction();
  214.     if(!pTrans){
  215.       g_err << "Failed to start transaction" << endl;
  216.       err(g_ndb->getNdbError());
  217.       return -1;
  218.     }
  219.     
  220.     int par = g_paramters[P_PARRA].value;
  221.     int bat = g_paramters[P_BATCH].value;
  222.     NdbScanOperation::LockMode lm;
  223.     switch(g_paramters[P_LOCK].value){
  224.     case 0:
  225.       lm = NdbScanOperation::LM_CommittedRead;
  226.       break;
  227.     case 1:
  228.       lm = NdbScanOperation::LM_Read;
  229.       break;
  230.     case 2:
  231.       lm = NdbScanOperation::LM_Exclusive;
  232.       break;
  233.     default:
  234.       abort();
  235.     }
  236.     if(g_paramters[P_ACCESS].value == 0){
  237.       pOp = pTrans->getNdbScanOperation(g_tablename);
  238.       assert(pOp);
  239.       rs = pOp->readTuples(lm, bat, par);
  240.     } else {
  241.       if(g_paramters[P_RESET].value == 0 || pIOp == 0)
  242.       {
  243. pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
  244. bool ord = g_paramters[P_ACCESS].value == 2;
  245. rs = pIOp->readTuples(lm, bat, par, ord);
  246.       }
  247.       else
  248.       {
  249. pIOp->reset_bounds();
  250.       }
  251.       switch(g_paramters[P_BOUND].value){
  252.       case 0: // All
  253. break;
  254.       case 1: // None
  255. pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0);
  256. break;
  257.       case 2: { // 1 row
  258.       default:  
  259. assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
  260. int tot = g_paramters[P_ROWS].value;
  261. int row = rand() % tot;
  262. #if 0
  263. fix_eq_bound(pIOp, row);
  264. #else
  265. pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
  266. #endif
  267. break;
  268.       }
  269.       }
  270.       if(g_paramters[P_RESET].value == 2)
  271. goto execute;
  272.     }
  273.     assert(pOp);
  274.     assert(rs);
  275.     
  276.     switch(g_paramters[P_FILT].value){
  277.     case 0: // All
  278.       check = pOp->interpret_exit_ok();
  279.       break;
  280.     case 1: // None
  281.       check = pOp->interpret_exit_nok();
  282.       break;
  283.     case 2: { // 1 row
  284.     default:  
  285.       assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
  286.       abort();
  287. #if 0
  288.       int tot = g_paramters[P_ROWS].value;
  289.       int row = rand() % tot;
  290.       NdbScanFilter filter(pOp) ;   
  291.       filter.begin(NdbScanFilter::AND);
  292.       fix_eq(filter, pOp, row);
  293.       filter.end();
  294.       break;
  295. #endif
  296.     }
  297.     }
  298.     if(check != 0){
  299.       err(pOp->getNdbError());
  300.       return -1;
  301.     }
  302.     assert(check == 0);
  303.     if(g_paramters[P_RESET].value == 1)
  304.       g_paramters[P_RESET].value = 2;
  305.     
  306.     for(int i = 0; i<g_table->getNoOfColumns(); i++){
  307.       pOp->getValue(i);
  308.     }
  309. execute:
  310.     int rows = 0;
  311.     check = pTrans->execute(NoCommit);
  312.     assert(check == 0);
  313.     int fetch = g_paramters[P_FETCH].value;
  314.     while((check = rs->nextResult(true)) == 0){
  315.       do {
  316. rows++;
  317.       } while(!fetch && ((check = rs->nextResult(false)) == 0));
  318.       if(check == -1){
  319.         err(pTrans->getNdbError());
  320.         return -1;
  321.       }
  322.       assert(check == 2);
  323.     }
  324.     if(check == -1){
  325.       err(pTrans->getNdbError());
  326.       return -1;
  327.     }
  328.     assert(check == 1);
  329.     if(g_paramters[P_RESET].value == 0)
  330.     {
  331.       pTrans->close();
  332.       pTrans = 0;
  333.     }
  334.     stop = NdbTick_CurrentMillisecond();
  335.     
  336.     int time_passed= (int)(stop - start1);
  337.     sample_rows += rows;
  338.     sum_time+= time_passed;
  339.     tot_rows+= rows;
  340.     
  341.     if(sample_rows >= tot)
  342.     {
  343.       int sample_time = (int)(stop - sample_start);
  344.       g_info << "Found " << sample_rows << " rows" << endl;
  345.       g_err.println("Time: %d ms = %u rows/sec", sample_time,
  346.     (1000*sample_rows)/sample_time);
  347.       sample_rows = 0;
  348.       sample_start = stop;
  349.     }
  350.   }
  351.   
  352.   g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows,
  353.                 (1000*tot_rows)/sum_time);
  354.   return 0;
  355. }