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

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 <ndb_global.h>
  14. #include <ndb_opts.h>
  15. #include <NdbOut.hpp>
  16. #include <NdbApi.hpp>
  17. #include <NdbMain.h>
  18. #include <NDBT.hpp> 
  19. #include <NdbSleep.h>
  20. #include <UtilTransactions.hpp>
  21.  
  22. static int 
  23. select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
  24.      int parallelism,
  25.      int* count_rows,
  26.      UtilTransactions::ScanLock lock);
  27. NDB_STD_OPTS_VARS;
  28. static const char* _dbname = "TEST_DB";
  29. static int _parallelism = 240;
  30. static int _lock = 0;
  31. static struct my_option my_long_options[] =
  32. {
  33.   NDB_STD_OPTS("ndb_desc"),
  34.   { "database", 'd', "Name of database table is in",
  35.     (gptr*) &_dbname, (gptr*) &_dbname, 0,
  36.     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
  37.   { "parallelism", 'p', "parallelism",
  38.     (gptr*) &_parallelism, (gptr*) &_parallelism, 0,
  39.     GET_INT, REQUIRED_ARG, 240, 0, 0, 0, 0, 0 }, 
  40.   { "lock", 'l', "Read(0), Read-hold(1), Exclusive(2)",
  41.     (gptr*) &_lock, (gptr*) &_lock, 0,
  42.     GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 
  43.   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  44. };
  45. static void usage()
  46. {
  47.   char desc[] = 
  48.     "tabname1 ... tabnameNn"
  49.     "This program will count the number of records in tablesn";
  50.   ndb_std_print_version();
  51.   my_print_help(my_long_options);
  52.   my_print_variables(my_long_options);
  53. }
  54. static my_bool
  55. get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
  56.        char *argument)
  57. {
  58.   return ndb_std_get_one_option(optid, opt, argument ? argument :
  59. "d:t:O,/tmp/ndb_select_count.trace");
  60. }
  61. int main(int argc, char** argv){
  62.   NDB_INIT(argv[0]);
  63.   const char *load_default_groups[]= { "mysql_cluster",0 };
  64.   load_defaults("my",load_default_groups,&argc,&argv);
  65.   int ho_error;
  66.   if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
  67.     return NDBT_ProgramExit(NDBT_WRONGARGS);
  68.   if (argc < 1) {
  69.     usage();
  70.     return NDBT_ProgramExit(NDBT_WRONGARGS);
  71.   }
  72.   Ndb::setConnectString(opt_connect_str);
  73.   // Connect to Ndb
  74.   Ndb MyNdb(_dbname);
  75.   if(MyNdb.init() != 0){
  76.     ERR(MyNdb.getNdbError());
  77.     return NDBT_ProgramExit(NDBT_FAILED);
  78.   }
  79.   // Connect to Ndb and wait for it to become ready
  80.   while(MyNdb.waitUntilReady() != 0)
  81.     ndbout << "Waiting for ndb to become ready..." << endl;
  82.    
  83.   for(int i = 0; i<argc; i++){
  84.     // Check if table exists in db
  85.     const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, argv[i]);
  86.     if(pTab == NULL){
  87.       ndbout << " Table " << argv[i] << " does not exist!" << endl;
  88.       continue;
  89.     }
  90.     int rows = 0;
  91.     if (select_count(&MyNdb, pTab, _parallelism, &rows, 
  92.      (UtilTransactions::ScanLock)_lock) != 0){
  93.       return NDBT_ProgramExit(NDBT_FAILED);
  94.     }
  95.     
  96.     ndbout << rows << " records in table " << argv[i] << endl;
  97.   }
  98.   return NDBT_ProgramExit(NDBT_OK);
  99. }
  100. int 
  101. select_count(Ndb* pNdb, const NdbDictionary::Table* pTab,
  102.      int parallelism,
  103.      int* count_rows,
  104.      UtilTransactions::ScanLock lock){
  105.   
  106.   int                  retryAttempt = 0;
  107.   const int            retryMax = 100;
  108.   int                  check;
  109.   NdbConnection        *pTrans;
  110.   NdbScanOperation        *pOp;
  111.   while (true){
  112.     if (retryAttempt >= retryMax){
  113.       g_info << "ERROR: has retried this operation " << retryAttempt 
  114.      << " times, failing!" << endl;
  115.       return NDBT_FAILED;
  116.     }
  117.     pTrans = pNdb->startTransaction();
  118.     if (pTrans == NULL) {
  119.       const NdbError err = pNdb->getNdbError();
  120.       if (err.status == NdbError::TemporaryError){
  121. NdbSleep_MilliSleep(50);
  122. retryAttempt++;
  123. continue;
  124.       }
  125.       ERR(err);
  126.       return NDBT_FAILED;
  127.     }
  128.     pOp = pTrans->getNdbScanOperation(pTab->getName());
  129.     if (pOp == NULL) {
  130.       ERR(pTrans->getNdbError());
  131.       pNdb->closeTransaction(pTrans);
  132.       return NDBT_FAILED;
  133.     }
  134.     NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Dirty); 
  135.     if( rs == 0 ) {
  136.       ERR(pTrans->getNdbError());
  137.       pNdb->closeTransaction(pTrans);
  138.       return NDBT_FAILED;
  139.     }
  140.     check = pOp->interpret_exit_last_row();
  141.     if( check == -1 ) {
  142.       ERR(pTrans->getNdbError());
  143.       pNdb->closeTransaction(pTrans);
  144.       return NDBT_FAILED;
  145.     }
  146.   
  147.     Uint64 tmp;
  148.     pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&tmp);
  149.     
  150.     check = pTrans->execute(NoCommit);
  151.     if( check == -1 ) {
  152.       ERR(pTrans->getNdbError());
  153.       pNdb->closeTransaction(pTrans);
  154.       return NDBT_FAILED;
  155.     }
  156.     
  157.     Uint64 row_count = 0;
  158.     int eof;
  159.     while((eof = rs->nextResult(true)) == 0){
  160.       row_count += tmp;
  161.     }
  162.     
  163.     if (eof == -1) {
  164.       const NdbError err = pTrans->getNdbError();
  165.       
  166.       if (err.status == NdbError::TemporaryError){
  167. pNdb->closeTransaction(pTrans);
  168. NdbSleep_MilliSleep(50);
  169. retryAttempt++;
  170. continue;
  171.       }
  172.       ERR(err);
  173.       pNdb->closeTransaction(pTrans);
  174.       return NDBT_FAILED;
  175.     }
  176.     
  177.     pNdb->closeTransaction(pTrans);
  178.     
  179.     if (count_rows != NULL){
  180.       *count_rows = row_count;
  181.     }
  182.     
  183.     return NDBT_OK;
  184.   }
  185.   return NDBT_FAILED;
  186. }