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

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 <signaldata/DumpStateOrd.hpp>
  14. #include <NdbBackup.hpp>
  15. #include <NdbOut.hpp>
  16. #include <NDBT_Output.hpp>
  17. #include <NdbConfig.h>
  18. #include <ndb_version.h>
  19. #include <NDBT.hpp>
  20. #include <NdbSleep.h>
  21. #include <random.h>
  22. #include <NdbTick.h>
  23. #define CHECK(b, m) { int _xx = b; if (!(_xx)) { 
  24.   ndbout << "ERR: "<< m 
  25.            << "   " << "File: " << __FILE__ 
  26.            << " (Line: " << __LINE__ << ")" << "- " << _xx << endl; 
  27.   return NDBT_FAILED; } }
  28. #include <ConfigRetriever.hpp>
  29. #include <mgmapi.h>
  30. #include <mgmapi_config_parameters.h>
  31. #include <mgmapi_configuration.hpp>
  32. int 
  33. NdbBackup::start(unsigned int & _backup_id){
  34.   
  35.   if (!isConnected())
  36.     return -1;
  37.   ndb_mgm_reply reply;
  38.   reply.return_code = 0;
  39.   if (ndb_mgm_start_backup(handle,
  40.    2, // wait until completed
  41.    &_backup_id,
  42.    &reply) == -1) {
  43.     g_err << "Error: " << ndb_mgm_get_latest_error(handle) << endl;
  44.     g_err << "Error msg: " << ndb_mgm_get_latest_error_msg(handle) << endl;
  45.     g_err << "Error desc: " << ndb_mgm_get_latest_error_desc(handle) << endl;
  46.     return -1;
  47.   }
  48.   if(reply.return_code != 0){
  49.     g_err  << "PLEASE CHECK CODE NdbBackup.cpp line=" << __LINE__ << endl;
  50.     g_err << "Error: " << ndb_mgm_get_latest_error(handle) << endl;
  51.     g_err << "Error msg: " << ndb_mgm_get_latest_error_msg(handle) << endl;
  52.     g_err << "Error desc: " << ndb_mgm_get_latest_error_desc(handle) << endl;
  53.     return reply.return_code;
  54.   }
  55.   return 0;
  56. }
  57. const char * 
  58. NdbBackup::getBackupDataDirForNode(int _node_id){
  59.   /**
  60.    * Fetch configuration from management server
  61.    */
  62.   ndb_mgm_configuration *p;
  63.   if (connect())
  64.     return NULL;
  65.   if ((p = ndb_mgm_get_configuration(handle, 0)) == 0)
  66.   {
  67.     const char * s= ndb_mgm_get_latest_error_msg(handle);
  68.     if(s == 0)
  69.       s = "No error given!";
  70.       
  71.     ndbout << "Could not fetch configuration" << endl;
  72.     ndbout << s << endl;
  73.     return NULL;
  74.   }
  75.   
  76.   /**
  77.    * Setup cluster configuration data
  78.    */
  79.   ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
  80.   if (iter.find(CFG_NODE_ID, _node_id)){
  81.     ndbout << "Invalid configuration fetched, DB missing" << endl;
  82.     return NULL;
  83.   }
  84.   unsigned int type = NODE_TYPE_DB + 1;
  85.   if(iter.get(CFG_TYPE_OF_SECTION, &type) || type != NODE_TYPE_DB){
  86.     ndbout <<"type = " << type << endl;
  87.     ndbout <<"Invalid configuration fetched, I'm wrong type of node" << endl;
  88.     return NULL;
  89.   }  
  90.   
  91.   const char * path;
  92.   if (iter.get(CFG_DB_BACKUP_DATADIR, &path)){
  93.     ndbout << "BackupDataDir not found" << endl;
  94.     return NULL;
  95.   }
  96.   return path;
  97. }
  98. int  
  99. NdbBackup::execRestore(bool _restore_data,
  100.        bool _restore_meta,
  101.        int _node_id,
  102.        unsigned _backup_id){
  103.   const int buf_len = 1000;
  104.   char buf[buf_len];
  105.   ndbout << "getBackupDataDir "<< _node_id <<endl;
  106.   const char* path = getBackupDataDirForNode(_node_id);
  107.   if (path == NULL)
  108.     return -1;  
  109.   ndbout << "getHostName "<< _node_id <<endl;
  110.   const char *host;
  111.   if (!getHostName(_node_id, &host)){
  112.     return -1;
  113.   }
  114.   /* 
  115.    * Copy  backup files to local dir
  116.    */ 
  117.   BaseString::snprintf(buf, buf_len,
  118.    "scp %s:%s/BACKUP/BACKUP-%d/BACKUP-%d*.%d.* .",
  119.    host, path,
  120.    _backup_id,
  121.    _backup_id,
  122.    _node_id);
  123.   ndbout << "buf: "<< buf <<endl;
  124.   int res = system(buf);  
  125.   
  126.   ndbout << "scp res: " << res << endl;
  127.   
  128.   BaseString::snprintf(buf, 255, "%sndb_restore -c "%s:%d" -n %d -b %d %s %s .", 
  129. #if 1
  130.    "",
  131. #else
  132.    "valgrind --leak-check=yes -v "
  133. #endif
  134.    ndb_mgm_get_connected_host(handle),
  135.    ndb_mgm_get_connected_port(handle),
  136.    _node_id, 
  137.    _backup_id,
  138.    _restore_data?"-r":"",
  139.    _restore_meta?"-m":"");
  140.   ndbout << "buf: "<< buf <<endl;
  141.   res = system(buf);
  142.   ndbout << "ndb_restore res: " << res << endl;
  143.   return res;
  144.   
  145. }
  146. int 
  147. NdbBackup::restore(unsigned _backup_id){
  148.   
  149.   if (!isConnected())
  150.     return -1;
  151.   if (getStatus() != 0)
  152.     return -1;
  153.   int res; 
  154.   // restore metadata first and data for first node
  155.   res = execRestore(true, true, ndbNodes[0].node_id, _backup_id);
  156.   // Restore data once for each node
  157.   for(size_t i = 1; i < ndbNodes.size(); i++){
  158.     res = execRestore(true, false, ndbNodes[i].node_id, _backup_id);
  159.   }
  160.   
  161.   return 0;
  162. }
  163. // Master failure
  164. int
  165. NFDuringBackupM_codes[] = {
  166.   10003,
  167.   10004,
  168.   10005,
  169.   10007,
  170.   10008,
  171.   10009,
  172.   10010,
  173.   10012,
  174.   10013
  175. };
  176. // Slave failure
  177. int
  178. NFDuringBackupS_codes[] = {
  179.   10014,
  180.   10015,
  181.   10016,
  182.   10017,
  183.   10018,
  184.   10020
  185. };
  186. // Master takeover etc...
  187. int
  188. NFDuringBackupSL_codes[] = {
  189.   10001,
  190.   10002,
  191.   10021
  192. };
  193. int 
  194. NdbBackup::NFMaster(NdbRestarter& _restarter){
  195.   const int sz = sizeof(NFDuringBackupM_codes)/sizeof(NFDuringBackupM_codes[0]);
  196.   return NF(_restarter, NFDuringBackupM_codes, sz, true);
  197. }
  198. int 
  199. NdbBackup::NFMasterAsSlave(NdbRestarter& _restarter){
  200.   const int sz = sizeof(NFDuringBackupS_codes)/sizeof(NFDuringBackupS_codes[0]);
  201.   return NF(_restarter, NFDuringBackupS_codes, sz, true);
  202. }
  203. int 
  204. NdbBackup::NFSlave(NdbRestarter& _restarter){
  205.   const int sz = sizeof(NFDuringBackupS_codes)/sizeof(NFDuringBackupS_codes[0]);
  206.   return NF(_restarter, NFDuringBackupS_codes, sz, false);
  207. }
  208. int 
  209. NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz, bool onMaster){
  210.   int nNodes = _restarter.getNumDbNodes();
  211.   {
  212.     if(nNodes == 1)
  213.       return NDBT_OK;
  214.     
  215.     int nodeId = _restarter.getMasterNodeId();
  216.     CHECK(_restarter.restartOneDbNode(nodeId, false, true, true) == 0,
  217.   "Could not restart node "<< nodeId);
  218.     
  219.     CHECK(_restarter.waitNodesNoStart(&nodeId, 1) == 0,
  220.   "waitNodesNoStart failed");
  221.     
  222.     CHECK(_restarter.startNodes(&nodeId, 1) == 0,
  223.   "failed to start node");
  224.   }
  225.   
  226.   CHECK(_restarter.waitClusterStarted() == 0,
  227. "waitClusterStarted failed");
  228.   
  229.   myRandom48Init(NdbTick_CurrentMillisecond());
  230.   for(int i = 0; i<sz; i++){
  231.     int error = NFDuringBackup_codes[i];
  232.     unsigned int backupId;
  233.     const int masterNodeId = _restarter.getMasterNodeId();
  234.     CHECK(masterNodeId > 0, "getMasterNodeId failed");
  235.     int nodeId;
  236.     nodeId = masterNodeId;
  237.     if (!onMaster) {
  238.       int randomId;
  239.       while (nodeId == masterNodeId) {
  240. randomId = myRandom48(nNodes);
  241. nodeId = _restarter.getDbNodeId(randomId);
  242.       }
  243.     }
  244.     g_err << "NdbBackup::NF node = " << nodeId 
  245.    << " error code = " << error << " masterNodeId = "
  246.    << masterNodeId << endl;
  247.     int val = DumpStateOrd::CmvmiSetRestartOnErrorInsert;
  248.     CHECK(_restarter.dumpStateOneNode(nodeId, &val, 1) == 0,
  249.   "failed to set RestartOnErrorInsert");
  250.     CHECK(_restarter.insertErrorInNode(nodeId, error) == 0,
  251.   "failed to set error insert");
  252.    
  253.     g_info << "error inserted"  << endl;
  254.     NdbSleep_SecSleep(1);
  255.     g_info << "starting backup"  << endl;
  256.     int r = start(backupId);
  257.     g_info << "r = " << r
  258.    << " (which should fail) started with id = "  << backupId << endl;
  259.     if (r == 0) {
  260.       g_err << "Backup should have failed on error_insertion " << error << endl
  261.     << "Master = " << masterNodeId << "Node = " << nodeId << endl;
  262.       return NDBT_FAILED;
  263.     }
  264.     CHECK(_restarter.waitNodesNoStart(&nodeId, 1) == 0,
  265.   "waitNodesNoStart failed");
  266.     g_info << "number of nodes running " << _restarter.getNumDbNodes() << endl;
  267.     if (_restarter.getNumDbNodes() != nNodes) {
  268.       g_err << "Failure: cluster not up" << endl;
  269.       return NDBT_FAILED;
  270.     }
  271.     g_info << "starting new backup"  << endl;
  272.     CHECK(start(backupId) == 0,
  273.   "failed to start backup");
  274.     g_info << "(which should succeed) started with id = "  << backupId << endl;
  275.     g_info << "starting node"  << endl;
  276.     CHECK(_restarter.startNodes(&nodeId, 1) == 0,
  277.   "failed to start node");
  278.     CHECK(_restarter.waitClusterStarted() == 0,
  279.   "waitClusterStarted failed");
  280.     g_info << "node started"  << endl;
  281.     int val2[] = { 24, 2424 };
  282.     CHECK(_restarter.dumpStateAllNodes(val2, 2) == 0,
  283.   "failed to check backup resources RestartOnErrorInsert");
  284.     
  285.     CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
  286.   "failed to set error insert");
  287.     NdbSleep_SecSleep(1);
  288.   }
  289.   return NDBT_OK;
  290. }
  291. int
  292. FailS_codes[] = {
  293.   10027,
  294.   10033
  295. };
  296. int
  297. FailM_codes[] = {
  298.   10023,
  299.   10024,
  300.   10025,
  301.   10026,
  302.   10027,
  303.   10028,
  304.   10031,
  305.   10033
  306. };
  307. int 
  308. NdbBackup::FailMaster(NdbRestarter& _restarter){
  309.   const int sz = sizeof(FailM_codes)/sizeof(FailM_codes[0]);
  310.   return Fail(_restarter, FailM_codes, sz, true);
  311. }
  312. int 
  313. NdbBackup::FailMasterAsSlave(NdbRestarter& _restarter){
  314.   const int sz = sizeof(FailS_codes)/sizeof(FailS_codes[0]);
  315.   return Fail(_restarter, FailS_codes, sz, true);
  316. }
  317. int 
  318. NdbBackup::FailSlave(NdbRestarter& _restarter){
  319.   const int sz = sizeof(FailS_codes)/sizeof(FailS_codes[0]);
  320.   return Fail(_restarter, FailS_codes, sz, false);
  321. }
  322. int 
  323. NdbBackup::Fail(NdbRestarter& _restarter, int *Fail_codes, const int sz, bool onMaster){
  324.   CHECK(_restarter.waitClusterStarted() == 0,
  325. "waitClusterStarted failed");
  326.   int nNodes = _restarter.getNumDbNodes();
  327.   myRandom48Init(NdbTick_CurrentMillisecond());
  328.   for(int i = 0; i<sz; i++){
  329.     int error = Fail_codes[i];
  330.     unsigned int backupId;
  331.     const int masterNodeId = _restarter.getMasterNodeId();
  332.     CHECK(masterNodeId > 0, "getMasterNodeId failed");
  333.     int nodeId;
  334.     nodeId = masterNodeId;
  335.     if (!onMaster) {
  336.       int randomId;
  337.       while (nodeId == masterNodeId) {
  338. randomId = myRandom48(nNodes);
  339. nodeId = _restarter.getDbNodeId(randomId);
  340.       }
  341.     }
  342.     g_err << "NdbBackup::Fail node = " << nodeId 
  343.    << " error code = " << error << " masterNodeId = "
  344.    << masterNodeId << endl;
  345.     CHECK(_restarter.insertErrorInNode(nodeId, error) == 0,
  346.   "failed to set error insert");
  347.    
  348.     g_info << "error inserted"  << endl;
  349.     g_info << "waiting some before starting backup"  << endl;
  350.     g_info << "starting backup"  << endl;
  351.     int r = start(backupId);
  352.     g_info << "r = " << r
  353.    << " (which should fail) started with id = "  << backupId << endl;
  354.     if (r == 0) {
  355.       g_err << "Backup should have failed on error_insertion " << error << endl
  356.     << "Master = " << masterNodeId << "Node = " << nodeId << endl;
  357.       return NDBT_FAILED;
  358.     }
  359.     
  360.     CHECK(_restarter.waitClusterStarted() == 0,
  361.   "waitClusterStarted failed");
  362.     CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
  363.   "failed to set error insert");
  364.     NdbSleep_SecSleep(5);
  365.     
  366.     int val2[] = { 24, 2424 };
  367.     CHECK(_restarter.dumpStateAllNodes(val2, 2) == 0,
  368.   "failed to check backup resources RestartOnErrorInsert");
  369.     
  370.   }
  371.   return NDBT_OK;
  372. }