List:Commits« Previous MessageNext Message »
From:gni Date:August 8 2007 10:23am
Subject:bk commit into 5.1 tree (gni:1.2524)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of root. When root does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-08-08 18:23:32+08:00, gni@stripped +1 -0
  Merge dev3-221.dev.cn.tlan:/home/ngb/mysql/mysql-5.0/bug27683
  into  dev3-221.dev.cn.tlan:/home/ngb/mysql/mysql-5.1/mysql-5.1-bug27683
  MERGE: 1.1810.2962.10

  storage/ndb/tools/restore/restore_main.cpp@stripped, 2007-08-08 18:23:26+08:00, gni@stripped +0 -0
    Auto merged
    MERGE: 1.29.18.2

  storage/ndb/tools/restore/restore_main.cpp@stripped, 2007-08-08 18:23:26+08:00, gni@stripped +0 -0
    Merge rename: ndb/tools/restore/restore_main.cpp -> storage/ndb/tools/restore/restore_main.cpp

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gni
# Host:	dev3-221.dev.cn.tlan
# Root:	/home/ngb/mysql/mysql-5.1/mysql-5.1-bug27683/RESYNC

--- 1.29.18.1/ndb/tools/restore/restore_main.cpp	2007-08-08 18:23:40 +08:00
+++ 1.57/storage/ndb/tools/restore/restore_main.cpp	2007-08-08 18:23:40 +08:00
@@ -34,12 +34,18 @@
 static int ga_nParallelism = 128;
 static int ga_backupId = 0;
 static bool ga_dont_ignore_systab_0 = false;
+static bool ga_no_upgrade = false;
 static Vector<class BackupConsumer *> g_consumers;
 static BackupPrinter* g_printer = NULL;
 
 static const char* default_backupPath = "." DIR_SEPARATOR;
 static const char* ga_backupPath = default_backupPath;
 
+static const char *opt_nodegroup_map_str= 0;
+static unsigned opt_nodegroup_map_len= 0;
+static NODE_GROUP_MAP opt_nodegroup_map[MAX_NODE_GROUP_MAPS];
+#define OPT_NDB_NODEGROUP_MAP 'z'
+
 const char *opt_ndb_database= NULL;
 const char *opt_ndb_table= NULL;
 unsigned int opt_verbose;
@@ -53,14 +59,17 @@
 /**
  * print and restore flags
  */
+static bool ga_restore_epoch = false;
 static bool ga_restore = false;
 static bool ga_print = false;
+static bool ga_skip_table_check = false;
 static int _print = 0;
 static int _print_meta = 0;
 static int _print_data = 0;
 static int _print_log = 0;
 static int _restore_data = 0;
 static int _restore_meta = 0;
+static int _no_restore_disk = 0;
 BaseString g_options("ndb_restore");
 
 const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
@@ -107,6 +116,23 @@
     "Restore meta data into NDB Cluster using NDBAPI",
     (gptr*) &_restore_meta, (gptr*) &_restore_meta,  0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "no-upgrade", 'u',
+    "Don't upgrade array type for var attributes, which don't resize VAR data and don't change column attributes",
+    (gptr*) &ga_no_upgrade, (gptr*) &ga_no_upgrade, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "no-restore-disk-objects", 'd',
+    "Dont restore disk objects (tablespace/logfilegroups etc)",
+    (gptr*) &_no_restore_disk, (gptr*) &_no_restore_disk,  0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "restore_epoch", 'e', 
+    "Restore epoch info into the status table. Convenient on a MySQL Cluster "
+    "replication slave, for starting replication. The row in "
+    NDB_REP_DB "." NDB_APPLY_TABLE " with id 0 will be updated/inserted.", 
+    (gptr*) &ga_restore_epoch, (gptr*) &ga_restore_epoch,  0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "skip-table-check", 's', "Skip table structure check during restore of data",
+   (gptr*) &ga_skip_table_check, (gptr*) &ga_skip_table_check, 0,
+   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { "parallelism", 'p',
     "No of parallel transactions during restore of data."
     "(parallelism can be 1 to 1024)", 
@@ -131,6 +157,12 @@
     "Experimental. Do not ignore system table during restore.", 
     (gptr*) &ga_dont_ignore_systab_0, (gptr*) &ga_dont_ignore_systab_0, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "ndb-nodegroup-map", OPT_NDB_NODEGROUP_MAP,
+    "Nodegroup map for ndbcluster. Syntax: list of (source_ng, dest_ng)",
+    (gptr*) &opt_nodegroup_map_str,
+    (gptr*) &opt_nodegroup_map_str,
+    0,
+    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
   { "fields-enclosed-by", OPT_FIELDS_ENCLOSED_BY,
     "Fields are enclosed by ...",
     (gptr*) &opt_fields_enclosed_by, (gptr*) &opt_fields_enclosed_by, 0,
@@ -165,6 +197,115 @@
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
+
+static char* analyse_one_map(char *map_str, uint16 *source, uint16 *dest)
+{
+  char *end_ptr;
+  int number;
+  DBUG_ENTER("analyse_one_map");
+  /*
+    Search for pattern ( source_ng , dest_ng )
+  */
+
+  while (isspace(*map_str)) map_str++;
+
+  if (*map_str != '(')
+  {
+    DBUG_RETURN(NULL);
+  }
+  map_str++;
+
+  while (isspace(*map_str)) map_str++;
+
+  number= strtol(map_str, &end_ptr, 10);
+  if (!end_ptr || number < 0 || number >= MAX_NODE_GROUP_MAPS)
+  {
+    DBUG_RETURN(NULL);
+  }
+  *source= (uint16)number;
+  map_str= end_ptr;
+
+  while (isspace(*map_str)) map_str++;
+
+  if (*map_str != ',')
+  {
+    DBUG_RETURN(NULL);
+  }
+  map_str++;
+
+  number= strtol(map_str, &end_ptr, 10);
+  if (!end_ptr || number < 0 || number >= UNDEF_NODEGROUP)
+  {
+    DBUG_RETURN(NULL);
+  }
+  *dest= (uint16)number;
+  map_str= end_ptr;
+
+  if (*map_str != ')')
+  {
+    DBUG_RETURN(NULL);
+  }
+  map_str++;
+
+  while (isspace(*map_str)) map_str++;
+  DBUG_RETURN(map_str);
+}
+
+static bool insert_ng_map(NODE_GROUP_MAP *ng_map,
+                          uint16 source_ng, uint16 dest_ng)
+{
+  uint index= source_ng;
+  uint ng_index= ng_map[index].no_maps;
+
+  opt_nodegroup_map_len++;
+  if (ng_index >= MAX_MAPS_PER_NODE_GROUP)
+    return true;
+  ng_map[index].no_maps++;
+  ng_map[index].map_array[ng_index]= dest_ng;
+  return false;
+}
+
+static void init_nodegroup_map()
+{
+  uint i,j;
+  NODE_GROUP_MAP *ng_map = &opt_nodegroup_map[0];
+
+  for (i = 0; i < MAX_NODE_GROUP_MAPS; i++)
+  {
+    ng_map[i].no_maps= 0;
+    for (j= 0; j < MAX_MAPS_PER_NODE_GROUP; j++)
+      ng_map[i].map_array[j]= UNDEF_NODEGROUP;
+  }
+}
+
+static bool analyse_nodegroup_map(const char *ng_map_str,
+                                  NODE_GROUP_MAP *ng_map)
+{
+  uint16 source_ng, dest_ng;
+  char *local_str= (char*)ng_map_str;
+  DBUG_ENTER("analyse_nodegroup_map");
+
+  do
+  {
+    if (!local_str)
+    {
+      DBUG_RETURN(TRUE);
+    }
+    local_str= analyse_one_map(local_str, &source_ng, &dest_ng);
+    if (!local_str)
+    {
+      DBUG_RETURN(TRUE);
+    }
+    if (insert_ng_map(ng_map, source_ng, dest_ng))
+    {
+      DBUG_RETURN(TRUE);
+    }
+    if (!(*local_str))
+      break;
+  } while (TRUE);
+  DBUG_RETURN(FALSE);
+}
+
 static void short_usage_sub(void)
 {
   printf("Usage: %s [OPTIONS] [<path to backup files>]\n", my_progname);
@@ -208,6 +349,21 @@
     info.setLevel(254);
     info << "Backup Id = " << ga_backupId << endl;
     break;
+  case OPT_NDB_NODEGROUP_MAP:
+    /*
+      This option is used to set a map from nodegroup in original cluster
+      to nodegroup in new cluster.
+    */
+    opt_nodegroup_map_len= 0;
+
+    info.setLevel(254);
+    info << "Analyse node group map" << endl;
+    if (analyse_nodegroup_map(opt_nodegroup_map_str,
+                              &opt_nodegroup_map[0]))
+    {
+      exit(NDBT_ProgramExit(NDBT_WRONGARGS));
+    }
+    break;
   }
   return 0;
 }
@@ -218,18 +374,51 @@
   debug << "Load defaults" << endl;
   const char *load_default_groups[]= { "mysql_cluster","ndb_restore",0 };
 
+  init_nodegroup_map();
   load_defaults("my",load_default_groups,pargc,pargv);
   debug << "handle_options" << endl;
   if (handle_options(pargc, pargv, my_long_options, get_one_option))
   {
     exit(NDBT_ProgramExit(NDBT_WRONGARGS));
   }
+  for (i = 0; i < MAX_NODE_GROUP_MAPS; i++)
+    opt_nodegroup_map[i].curr_index = 0;
 
-  g_printer = new BackupPrinter();
+#if 0
+  /*
+    Test code written t{
+o verify nodegroup mapping
+  */
+  printf("Handled options successfully\n");
+  Uint16 map_ng[16];
+  Uint32 j;
+  for (j = 0; j < 4; j++)
+  {
+  for (i = 0; i < 4 ; i++)
+    map_ng[i] = i;
+  map_nodegroups(&map_ng[0], (Uint32)4);
+  for (i = 0; i < 4 ; i++)
+    printf("NG %u mapped to %u \n", i, map_ng[i]);
+  }
+  for (j = 0; j < 4; j++)
+  {
+  for (i = 0; i < 8 ; i++)
+    map_ng[i] = i >> 1;
+  map_nodegroups(&map_ng[0], (Uint32)8);
+  for (i = 0; i < 8 ; i++)
+    printf("NG %u mapped to %u \n", i >> 1, map_ng[i]);
+  }
+  exit(NDBT_ProgramExit(NDBT_WRONGARGS));
+#endif
+
+  g_printer = new BackupPrinter(opt_nodegroup_map,
+                                opt_nodegroup_map_len);
   if (g_printer == NULL)
     return false;
 
-  BackupRestore* restore = new BackupRestore(ga_nParallelism);
+  BackupRestore* restore = new BackupRestore(opt_nodegroup_map,
+                                             opt_nodegroup_map_len,
+                                             ga_nParallelism);
   if (restore == NULL) 
   {
     delete g_printer;
@@ -271,6 +460,21 @@
     restore->m_restore_meta = true;
   }
 
+  if (_no_restore_disk)
+  {
+    restore->m_no_restore_disk = true;
+  }
+  
+  if (ga_no_upgrade)
+  {
+     restore->m_no_upgrade = true;
+  }
+
+  if (ga_restore_epoch)
+  {
+    restore->m_restore_epoch = true;
+  }
+
   {
     BackupConsumer * c = g_printer;
     g_consumers.push_back(c);
@@ -450,12 +654,19 @@
   g_options.appfmt(" -n %d", ga_nodeId);
   if (_restore_meta)
     g_options.appfmt(" -m");
+  if (ga_no_upgrade)
+    g_options.appfmt(" -u");
+  if (ga_skip_table_check)
+    g_options.appfmt(" -s");
   if (_restore_data)
     g_options.appfmt(" -r");
+  if (ga_restore_epoch)
+    g_options.appfmt(" -e");
+  if (_no_restore_disk)
+    g_options.appfmt(" -d");
   g_options.appfmt(" -p %d", ga_nParallelism);
 
   g_connect_string = opt_connect_str;
-
   /**
    * we must always load meta data, even if we will only print it to stdout
    */
@@ -478,6 +689,18 @@
   /**
    * check wheater we can restore the backup (right version).
    */
+  // in these versions there was an error in how replica info was
+  // stored on disk
+  if (version >= MAKE_VERSION(5,1,3) && version <= MAKE_VERSION(5,1,9))
+  {
+    err << "Restore program incompatible with backup versions between "
+        << getVersionString(MAKE_VERSION(5,1,3), 0, buf, sizeof(buf))
+        << " and "
+        << getVersionString(MAKE_VERSION(5,1,9), 0, buf, sizeof(buf))
+        << endl;
+    exitHandler(NDBT_FAILED);
+  }
+
   if (version > NDB_VERSION)
   {
     err << "Restore program older than backup version. Not supported. "
@@ -518,6 +741,18 @@
     }
 
   }
+  debug << "Restore objects (tablespaces, ..)" << endl;
+  for(i = 0; i<metaData.getNoOfObjects(); i++)
+  {
+    for(Uint32 j= 0; j < g_consumers.size(); j++)
+      if (!g_consumers[j]->object(metaData.getObjType(i),
+				  metaData.getObjPtr(i)))
+      {
+	err << "Restore: Failed to restore table: ";
+        err << metaData[i]->getTableName() << " ... Exiting " << endl;
+	exitHandler(NDBT_FAILED);
+      } 
+  }
 
   Vector<OutputStream *> table_output(metaData.getNoOfTables());
   debug << "Restoring tables" << endl;
@@ -562,6 +797,14 @@
 	  err << "Restore: Failed to restore table: `";
           err << table->getTableName() << "` ... Exiting " << endl;
 	  exitHandler(NDBT_FAILED);
+	} 
+    } else {
+      for(Uint32 j= 0; j < g_consumers.size(); j++)
+        if (!g_consumers[j]->createSystable(* table))
+        {
+          err << "Restore: Failed to restore system table: ";
+          err << table->getTableName() << " ... Exiting " << endl;
+          exitHandler(NDBT_FAILED);
         }
     }
   }
@@ -577,6 +820,20 @@
   {
     if(_restore_data || _print_data)
     {
+      if (!ga_skip_table_check){
+        for(i=0; i < metaData.getNoOfTables(); i++){
+          if (checkSysTable(metaData, i))
+          {
+            for(Uint32 j= 0; j < g_consumers.size(); j++)
+              if (!g_consumers[j]->table_equal(* metaData[i]))
+              {
+                err << "Restore: Failed to restore data, ";
+                err << metaData[i]->getTableName() << " table structure doesn't match backup ... Exiting " << endl;
+                exitHandler(NDBT_FAILED);
+              }
+          }
+        }
+      }
       RestoreDataIterator dataIter(metaData, &free_data_callback);
       
       // Read data file header
@@ -586,8 +843,8 @@
 	exitHandler(NDBT_FAILED);
       }
       
-      
-      while (dataIter.readFragmentHeader(res= 0))
+      Uint32 fragmentId; 
+      while (dataIter.readFragmentHeader(res= 0, &fragmentId))
       {
 	const TupleS* tuple;
 	while ((tuple = dataIter.getNextTuple(res= 1)) != 0)
@@ -599,7 +856,7 @@
           OutputStream *tmp = ndbout.m_out;
           ndbout.m_out = output;
           for(Uint32 j= 0; j < g_consumers.size(); j++) 
-            g_consumers[j]->tuple(* tuple);
+            g_consumers[j]->tuple(* tuple, fragmentId);
           ndbout.m_out =  tmp;
 	} // while (tuple != NULL);
 	
@@ -678,6 +935,16 @@
       }
     }
   }
+  if (ga_restore_epoch)
+  {
+    for (i= 0; i < g_consumers.size(); i++)
+      if (!g_consumers[i]->update_apply_status(metaData))
+      {
+        err << "Restore: Failed to restore epoch" << endl;
+        return -1;
+      }
+  }
+
   for(Uint32 j= 0; j < g_consumers.size(); j++) 
   {
     if (g_consumers[j]->has_temp_error())
Thread
bk commit into 5.1 tree (gni:1.2524)gni8 Aug