testRestartGci.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 "NDBT_Test.hpp"
  14. #include "NDBT_ReturnCodes.h"
  15. #include "HugoTransactions.hpp"
  16. #include "UtilTransactions.hpp"
  17. #include "NdbRestarter.hpp"
  18. /**
  19.  * Global vector to keep track of 
  20.  * records stored in db
  21.  */
  22. struct SavedRecord {
  23.   int m_gci;
  24.   BaseString m_str;
  25.   SavedRecord(int _gci, BaseString _str){ 
  26.     m_gci = _gci; 
  27.     m_str.assign(_str); 
  28.   }
  29.   SavedRecord(){
  30.     m_gci = 0;
  31.     m_str = "";
  32.   };
  33. };
  34. Vector<SavedRecord> savedRecords;
  35. #define CHECK(b) if (!(b)) { 
  36.   ndbout << "ERR: "<< step->getName() 
  37.          << " failed on line " << __LINE__ << endl; 
  38.   result = NDBT_FAILED; 
  39.   break; }
  40. int runInsertRememberGci(NDBT_Context* ctx, NDBT_Step* step){
  41.   int result = NDBT_OK;
  42.   int records = ctx->getNumRecords();
  43.   HugoOperations hugoOps(*ctx->getTab());
  44.   Ndb* pNdb = GETNDB(step);
  45.   int i = 0;
  46.   while(ctx->isTestStopped() == false && i < records){
  47.     // Insert record and read it in same transaction
  48.     CHECK(hugoOps.startTransaction(pNdb) == 0);
  49.     CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0);
  50.     if (hugoOps.execute_NoCommit(pNdb) != 0){
  51.       ndbout << "Could not insert record " << i << endl;
  52.       result = NDBT_FAILED;
  53.       break;
  54.     }
  55.     CHECK(hugoOps.pkReadRecord(pNdb, i) == 0);
  56.     if (hugoOps.execute_Commit(pNdb) != 0){
  57.       ndbout << "Did not find record in DB " << i << endl;
  58.       result = NDBT_FAILED;
  59.       break;
  60.     }
  61.     savedRecords.push_back(SavedRecord(hugoOps.getRecordGci(0),
  62.      hugoOps.getRecordStr(0)));
  63.     CHECK(hugoOps.closeTransaction(pNdb) == 0);
  64.     i++;
  65.   };
  66.   return result;
  67. }
  68. int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){
  69.   int records = ctx->getNumRecords();
  70.   Ndb* pNdb = GETNDB(step);
  71.   UtilTransactions utilTrans(*ctx->getTab());
  72.   NdbRestarter restarter;
  73.   
  74.   // Wait until we have enough records in db
  75.   int count = 0;
  76.   while (count < records){
  77.     if (utilTrans.selectCount(pNdb, 64, &count) != 0){
  78.       ctx->stopTest();
  79.       return NDBT_FAILED;
  80.     }
  81.   }
  82.   // Restart cluster with abort
  83.   if (restarter.restartAll(false, false, true) != 0){
  84.     ctx->stopTest();
  85.     return NDBT_FAILED;
  86.   }
  87.   // Stop the other thread
  88.   ctx->stopTest();
  89.   if (restarter.waitClusterStarted(300) != 0){
  90.     return NDBT_FAILED;
  91.   }
  92.   
  93.   if (pNdb->waitUntilReady() != 0){
  94.     return NDBT_FAILED;
  95.   }
  96.   return NDBT_OK;
  97. }
  98. int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){
  99.   int result = NDBT_OK;
  100.   Ndb* pNdb = GETNDB(step);
  101.   UtilTransactions utilTrans(*ctx->getTab());
  102.   HugoOperations hugoOps(*ctx->getTab());
  103.   NdbRestarter restarter;
  104.   int restartGCI = pNdb->NdbTamper(Ndb::ReadRestartGCI, 0);    
  105.   ndbout << "restartGCI = " << restartGCI << endl;
  106.   int count = 0;
  107.   if (utilTrans.selectCount(pNdb, 64, &count) != 0){
  108.     return NDBT_FAILED;
  109.   }
  110.   // RULE1: The vector with saved records should have exactly as many 
  111.   // records with lower or same gci as there are in DB
  112.   int recordsWithLowerOrSameGci = 0;
  113.   unsigned i; 
  114.   for (i = 0; i < savedRecords.size(); i++){
  115.     if (savedRecords[i].m_gci <= restartGCI)
  116.       recordsWithLowerOrSameGci++;
  117.   }
  118.   if (recordsWithLowerOrSameGci != count){
  119.     ndbout << "ERR: Wrong number of expected records" << endl;
  120.     result = NDBT_FAILED;
  121.   }
  122.   // RULE2: The records found in db should have same or lower 
  123.   // gci as in the vector
  124.   for (i = 0; i < savedRecords.size(); i++){
  125.     CHECK(hugoOps.startTransaction(pNdb) == 0);
  126.     CHECK(hugoOps.pkReadRecord(pNdb, i) == 0);
  127.     if (hugoOps.execute_Commit(pNdb) != 0){
  128.       // Record was not found in db'
  129.       // Check record gci
  130.       if (savedRecords[i].m_gci <= restartGCI){
  131. ndbout << "ERR: Record "<<i<<" should have existed" << endl;
  132. result = NDBT_FAILED;
  133.       }
  134.     } else {
  135.       // Record was found in db
  136.       BaseString str = hugoOps.getRecordStr(0);
  137.       // Check record string
  138.       if (!(savedRecords[i].m_str == str)){
  139. ndbout << "ERR: Record "<<i<<" str did not match "<< endl;
  140. result = NDBT_FAILED;
  141.       }
  142.       // Check record gci
  143.       if (savedRecords[i].m_gci > restartGCI){
  144. ndbout << "ERR: Record "<<i<<" should not have existed" << endl;
  145. result = NDBT_FAILED;
  146.       }
  147.     }
  148.     CHECK(hugoOps.closeTransaction(pNdb) == 0);    
  149.   }
  150.   
  151.   ndbout << "There are " << count << " records in db" << endl;
  152.   ndbout << "There are " << savedRecords.size() 
  153.  << " records in vector" << endl;
  154.   ndbout << "There are " << recordsWithLowerOrSameGci 
  155.  << " records with lower or same gci than " << restartGCI <<  endl;
  156.   
  157.   return result;
  158. }
  159. int runClearGlobals(NDBT_Context* ctx, NDBT_Step* step){
  160.   savedRecords.clear();
  161.   return NDBT_OK;
  162. }
  163. int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
  164.   int records = ctx->getNumRecords();
  165.   
  166.   UtilTransactions utilTrans(*ctx->getTab());
  167.   if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){
  168.     return NDBT_FAILED;
  169.   }
  170.   return NDBT_OK;
  171. }
  172. NDBT_TESTSUITE(testRestartGci);
  173. TESTCASE("InsertRestartGci", 
  174.  "Verify that only expected records are still in NDBn"
  175.  "after a restart" ){
  176.   INITIALIZER(runClearTable);
  177.   INITIALIZER(runClearGlobals);
  178.   STEP(runInsertRememberGci);
  179.   STEP(runRestartGciControl);
  180.   VERIFIER(runVerifyInserts);
  181.   FINALIZER(runClearTable);
  182. }
  183. NDBT_TESTSUITE_END(testRestartGci);
  184. int main(int argc, const char** argv){
  185.   ndb_init();
  186.   return testRestartGci.execute(argc, argv);
  187. }
  188. template class Vector<SavedRecord>;