List:Commits« Previous MessageNext Message »
From:Martin Skold Date:December 1 2009 9:35am
Subject:bzr commit into mysql-5.1-telco-6.3 branch (Martin.Skold:3169) Bug#48005
View as plain text  
#At file:///home/marty/MySQL/mysql-5.1-telco-6.3/

 3169 Martin Skold	2009-12-01 [merge]
      Merge
      modified:
        mysql-test/suite/ndb/r/ndb_restore.result
        mysql-test/suite/ndb/t/ndb_restore.test
        storage/ndb/include/ndbapi/NdbDictionary.hpp
        storage/ndb/src/ndbapi/NdbDictionary.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
        storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
        storage/ndb/tools/restore/Restore.cpp
        storage/ndb/tools/restore/Restore.hpp
        storage/ndb/tools/restore/consumer_printer.cpp
        storage/ndb/tools/restore/consumer_restore.cpp
        storage/ndb/tools/restore/consumer_restore.hpp
        storage/ndb/tools/restore/restore_main.cpp

=== modified file 'mysql-test/suite/ndb/r/ndb_restore.result'
--- a/mysql-test/suite/ndb/r/ndb_restore.result	2009-09-08 11:39:51 +0000
+++ b/mysql-test/suite/ndb/r/ndb_restore.result	2009-12-01 09:35:23 +0000
@@ -575,3 +575,21 @@ epoch
 select epoch > (1 << 32) from mysql.ndb_apply_status where server_id=0;
 epoch > (1 << 32)
 1
+create table t1 (a int not null primary key auto_increment, b int) auto_increment=200
+engine=ndb;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=ndbcluster AUTO_INCREMENT=200 DEFAULT CHARSET=latin1
+drop table t1;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=ndbcluster AUTO_INCREMENT=200 DEFAULT CHARSET=latin1
+drop table t1;

=== modified file 'mysql-test/suite/ndb/t/ndb_restore.test'
--- a/mysql-test/suite/ndb/t/ndb_restore.test	2009-09-08 11:39:51 +0000
+++ b/mysql-test/suite/ndb/t/ndb_restore.test	2009-12-01 09:35:23 +0000
@@ -487,3 +487,16 @@ select epoch > (1 << 32) from mysql.ndb_
 #
 --exec $NDB_TOOLS_DIR/ndb_restore --print_log -b 1 -n 1 $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT
 
+#
+# Bug#48005 ndb backup / restore does not restore the auto_increment
+#
+create table t1 (a int not null primary key auto_increment, b int) auto_increment=200
+engine=ndb;
+show create table t1;
+--source include/ndb_backup.inc
+drop table t1;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 1 -m -r --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b $the_backup_id -n 2 -r --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-$the_backup_id >> $NDB_TOOLS_OUTPUT
+show create table t1;
+drop table t1;
+

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2009-10-07 02:41:41 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2009-12-01 09:35:23 +0000
@@ -737,6 +737,11 @@ public:
     int getNoOfColumns() const;
     
     /**
+     * Get number of auto_increment columns in the table
+     */
+    int getNoOfAutoIncrementColumns() const;
+    
+    /**
      * Get number of primary keys in the table
      */
     int getNoOfPrimaryKeys() const;

=== modified file 'storage/ndb/src/ndbapi/NdbDictionary.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionary.cpp	2009-10-07 02:41:41 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp	2009-12-01 09:35:23 +0000
@@ -581,6 +581,11 @@ NdbDictionary::Table::getNoOfColumns() c
 }
 
 int
+NdbDictionary::Table::getNoOfAutoIncrementColumns() const {
+  return m_impl.m_noOfAutoIncColumns;
+}
+
+int
 NdbDictionary::Table::getNoOfPrimaryKeys() const {
   return m_impl.m_noOfKeys;
 }

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-09-04 11:01:23 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-12-01 09:35:23 +0000
@@ -591,6 +591,7 @@ NdbTableImpl::init(){
   m_noOfDistributionKeys= 0;
   m_noOfBlobs= 0;
   m_replicaCount= 0;
+  m_noOfAutoIncColumns = 0;
   m_ndbrecord= 0;
   m_pkMask= 0;
   m_min_rows = 0;
@@ -880,6 +881,8 @@ NdbTableImpl::assign(const NdbTableImpl&
   m_noOfBlobs = org.m_noOfBlobs;
   m_replicaCount = org.m_replicaCount;
 
+  m_noOfAutoIncColumns = org.m_noOfAutoIncColumns;
+
   m_id = org.m_id;
   m_version = org.m_version;
   m_status = org.m_status;
@@ -929,6 +932,9 @@ NdbTableImpl::computeAggregates()
       m_noOfDiskColumns++;
     
     col->m_keyInfoPos = ~0;
+
+    if (col->m_autoIncrement)
+      m_noOfAutoIncColumns++;
   }
   if (m_noOfDistributionKeys == m_noOfKeys) {
     // all is none!

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-09-04 11:01:23 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-12-01 09:35:23 +0000
@@ -211,6 +211,7 @@ public:
     if iterating over columns.
   */
   Vector<NdbColumnImpl *> m_columns;
+  Uint32 m_noOfAutoIncColumns;
   void computeAggregates();
   int buildColumnHash(); 
 

=== modified file 'storage/ndb/tools/restore/Restore.cpp'
--- a/storage/ndb/tools/restore/Restore.cpp	2009-09-08 11:24:40 +0000
+++ b/storage/ndb/tools/restore/Restore.cpp	2009-12-01 09:35:23 +0000
@@ -485,8 +485,12 @@ RestoreMetaData::markSysTables()
         strcmp(tableName, OLD_NDB_REP_DB "/def/" OLD_NDB_SCHEMA_TABLE) == 0 ||
         strcmp(tableName, NDB_REP_DB "/def/" NDB_APPLY_TABLE) == 0 ||
         strcmp(tableName, NDB_REP_DB "/def/" NDB_SCHEMA_TABLE)== 0 )
-
-      table->isSysTable = true;
+    {
+      table->m_isSysTable = true;
+      if (strcmp(tableName, "SYSTAB_0") == 0 ||
+          strcmp(tableName, "sys/def/SYSTAB_0") == 0)
+        table->m_isSYSTAB_0 = true;
+    }
   }
   for (i = 0; i < getNoOfTables(); i++) {
     TableS* blobTable = allTables[i];
@@ -501,8 +505,8 @@ RestoreMetaData::markSysTables()
       for (j = 0; j < getNoOfTables(); j++) {
         TableS* table = allTables[j];
         if (table->getTableId() == (Uint32) id1) {
-          if (table->isSysTable)
-            blobTable->isSysTable = true;
+          if (table->m_isSysTable)
+            blobTable->m_isSysTable = true;
           blobTable->m_main_table = table;
           blobTable->m_main_column_id = id2;
           break;
@@ -646,7 +650,8 @@ TableS::TableS(Uint32 version, NdbTableI
   m_max_auto_val= 0;
   m_noOfRecords= 0;
   backupVersion = version;
-  isSysTable = false;
+  m_isSysTable = false;
+  m_isSYSTAB_0 = false;
   m_main_table = NULL;
   m_main_column_id = ~(Uint32)0;
   
@@ -1608,6 +1613,35 @@ void TableS::createAttr(NdbDictionary::C
   m_variableAttribs.push_back(d);
 } // TableS::createAttr
 
+bool
+TableS::get_auto_data(const TupleS & tuple, Uint32 * syskey, Uint64 * nextid) const
+{
+  /*
+    Read current (highest) auto_increment value for
+    a table. Currently there can only be one per table.
+    The values are stored in sustable SYSTAB_0 as
+    {SYSKEY,NEXTID} values where SYSKEY (32-bit) is
+    the table_id and NEXTID (64-bit) is the next auto_increment
+    value in the sequence (note though that sequences of
+    values can have been fetched and that are cached in NdbAPI).
+    SYSTAB_0 can contain other data so we need to check that
+    the found SYSKEY value is a valid table_id (< 0x10000000).
+   */
+  AttributeData * attr_data = tuple.getData(0);
+  const AttributeDesc * attr_desc = tuple.getDesc(0);
+  const AttributeS attr1 = {attr_desc, *attr_data};
+  memcpy(syskey ,attr1.Data.u_int32_value, sizeof(Uint32));
+  attr_data = tuple.getData(1);
+  attr_desc = tuple.getDesc(1);
+  const AttributeS attr2 = {attr_desc, *attr_data};
+  memcpy(nextid, attr2.Data.u_int64_value, sizeof(Uint64));
+  if (*syskey < 0x10000000)
+  {
+    return true;
+  }
+  return false;
+};
+
 Uint16 Twiddle16(Uint16 in)
 {
   Uint16 retVal = 0;

=== modified file 'storage/ndb/tools/restore/Restore.hpp'
--- a/storage/ndb/tools/restore/Restore.hpp	2009-08-18 13:02:20 +0000
+++ b/storage/ndb/tools/restore/Restore.hpp	2009-12-01 09:35:23 +0000
@@ -167,7 +167,9 @@ class TableS {
   AttributeDesc * m_auto_val_attrib;
   Uint64 m_max_auto_val;
 
-  bool isSysTable;
+  bool m_isSysTable;
+  bool m_isSYSTAB_0;
+
   TableS *m_main_table;
   Uint32 m_main_column_id;
   Uint32 m_local_id;
@@ -263,6 +265,9 @@ public:
     if(v > m_max_auto_val)
       m_max_auto_val= v;
   };
+
+  bool get_auto_data(const TupleS & tuple, Uint32 * syskey, Uint64 * nextid) const;
+
   /**
    * Get attribute descriptor
    */
@@ -275,14 +280,19 @@ public:
   }
 
   bool getSysTable() const {
-    return isSysTable;
+    return m_isSysTable;
   }
 
   const TableS *getMainTable() const {
     return m_main_table;
   }
 
-  TableS& operator=(TableS& org) ; 
+  TableS& operator=(TableS& org) ;
+
+  inline
+  const bool isSYSTAB_0() const {
+    return m_isSYSTAB_0;
+  } 
 }; // TableS;
 
 class RestoreLogIterator;
@@ -493,6 +503,8 @@ NdbOut& operator<<(NdbOut& ndbout, const
 NdbOut& operator<<(NdbOut& ndbout, const LogEntry&);
 NdbOut& operator<<(NdbOut& ndbout, const RestoreMetaData&);
 
+bool readSYSTAB_0(const TupleS & tup, Uint32 * syskey, Uint64 * nextid);
+
 #endif
 
 

=== modified file 'storage/ndb/tools/restore/consumer_printer.cpp'
--- a/storage/ndb/tools/restore/consumer_printer.cpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/tools/restore/consumer_printer.cpp	2009-11-25 12:37:14 +0000
@@ -18,6 +18,7 @@
 
 #include "consumer_printer.hpp"
 extern FilteredNdbOut info;
+extern bool ga_dont_ignore_systab_0;
 extern NdbRecordPrintFormat g_ndbrecord_print_format;
 extern const char *tab_path;
 
@@ -44,6 +45,9 @@ BackupPrinter::tuple(const TupleS & tup,
       info.setLevel(254);
       info << tup.getTable()->getTableName() << "; ";
     }
+    const TableS * table = tup.getTable();
+    if ((!ga_dont_ignore_systab_0) &&  table->isSYSTAB_0())
+      return;
     m_ndbout << tup << g_ndbrecord_print_format.lines_terminated_by;  
   }
 }

=== modified file 'storage/ndb/tools/restore/consumer_restore.cpp'
--- a/storage/ndb/tools/restore/consumer_restore.cpp	2009-08-18 13:02:20 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.cpp	2009-12-01 09:35:23 +0000
@@ -178,8 +178,15 @@ BackupRestore::get_table(const NdbDictio
 
   int cnt, id1, id2;
   char db[256], schema[256];
-  if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d", 
-		   db, schema, &id1, &id2)) == 4){
+  if (strcmp(tab->getName(), "SYSTAB_0") == 0 ||
+      strcmp(tab->getName(), "sys/def/SYSTAB_0") == 0) {
+    /*
+      Restore SYSTAB_0 to itself
+    */
+    m_cache.m_new_table = tab;
+  }
+  else if((cnt = sscanf(tab->getName(), "%[^/]/%[^/]/NDB$BLOB_%d_%d", 
+                        db, schema, &id1, &id2)) == 4){
     m_ndb->setDatabaseName(db);
     m_ndb->setSchemaName(schema);
     
@@ -1395,6 +1402,8 @@ BackupRestore::endOfTables(){
 
 void BackupRestore::tuple(const TupleS & tup, Uint32 fragmentId)
 {
+  const TableS * tab = tup.getTable();
+
   if (!m_restore) 
     return;
 
@@ -1411,12 +1420,19 @@ void BackupRestore::tuple(const TupleS &
   if (cb == 0)
     assert(false);
   
-  m_free_callback = cb->next;
   cb->retries = 0;
   cb->fragId = fragmentId;
   cb->tup = tup; // must do copy!
-  tuple_a(cb);
 
+  if (tab->isSYSTAB_0())
+  {
+    tuple_SYSTAB_0(cb, *tab);
+    return;
+  }
+
+  m_free_callback = cb->next;
+
+  tuple_a(cb);
 }
 
 void BackupRestore::tuple_a(restore_callback_t *cb)
@@ -1590,6 +1606,59 @@ void BackupRestore::tuple_a(restore_call
   exitHandler();
 }
 
+void BackupRestore::tuple_SYSTAB_0(restore_callback_t *cb,
+                                   const TableS & tab)
+{
+  const TupleS & tup = cb->tup;
+  Uint32 syskey;
+  Uint64 nextid;
+
+  if (tab.get_auto_data(tup, &syskey, &nextid))
+  {
+    /*
+      We found a valid auto_increment value in SYSTAB_0
+      where syskey is a table_id and nextid is next auto_increment
+      value.
+     */
+    if (restoreAutoIncrement(cb, syskey, nextid) ==  -1)
+      exitHandler();
+  }
+}
+
+int BackupRestore::restoreAutoIncrement(restore_callback_t *cb,
+                                        Uint32 tableId, Uint64 value)
+{
+  /*
+    Restore the auto_increment value found in SYSTAB_0 from
+    backup. First map the old table id to the new table while
+    also checking that it is an actual table will some auto_increment
+    column. Note that the SYSTAB_0 table in the backup can contain
+    stale information from dropped tables.
+   */
+  int result = 0;
+  const NdbDictionary::Table* tab = (tableId < m_new_tables.size())? m_new_tables[tableId] : NULL;
+  if (tab && tab->getNoOfAutoIncrementColumns() > 0)
+  {
+    /*
+      Write the auto_increment value back into SYSTAB_0.
+      This is done in a separate transaction and could possibly
+      fail, so we retry if a temporary error is received.
+     */
+    while (cb->retries < 10)
+    {
+      if ((result = m_ndb->setAutoIncrementValue(tab, value, false) == -1))
+      {
+        if (errorHandler(cb)) 
+        {
+          continue;
+        }
+      }
+      break;
+    }
+  }
+  return result;
+}
+
 void BackupRestore::cback(int result, restore_callback_t *cb)
 {
   m_transactions--;

=== modified file 'storage/ndb/tools/restore/consumer_restore.hpp'
--- a/storage/ndb/tools/restore/consumer_restore.hpp	2009-08-18 13:02:20 +0000
+++ b/storage/ndb/tools/restore/consumer_restore.hpp	2009-12-01 09:35:23 +0000
@@ -89,6 +89,9 @@ public:
   virtual void tuple(const TupleS &, Uint32 fragId);
   virtual void tuple_free();
   virtual void tuple_a(restore_callback_t *cb);
+  virtual void tuple_SYSTAB_0(restore_callback_t *cb, const TableS &);
+  virtual int restoreAutoIncrement(restore_callback_t *cb,
+                                    Uint32 tableId, Uint64 value);
   virtual void cback(int result, restore_callback_t *cb);
   virtual bool errorHandler(restore_callback_t *cb);
   virtual void exitHandler();

=== modified file 'storage/ndb/tools/restore/restore_main.cpp'
--- a/storage/ndb/tools/restore/restore_main.cpp	2009-08-18 13:02:20 +0000
+++ b/storage/ndb/tools/restore/restore_main.cpp	2009-12-01 09:35:23 +0000
@@ -37,7 +37,7 @@ static Uint32 g_tableCompabilityMask = 0
 static int ga_nodeId = 0;
 static int ga_nParallelism = 128;
 static int ga_backupId = 0;
-static bool ga_dont_ignore_systab_0 = false;
+bool ga_dont_ignore_systab_0 = false;
 static bool ga_no_upgrade = false;
 static bool ga_promote_attributes = false;
 static Vector<class BackupConsumer *> g_consumers;
@@ -185,7 +185,7 @@ static struct my_option my_long_options[
     (uchar**) &ga_backupPath, (uchar**) &ga_backupPath, 0,
     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
   { "dont_ignore_systab_0", 'f',
-    "Experimental. Do not ignore system table during restore.", 
+    "Do not ignore system table during --print-data.", 
     (uchar**) &ga_dont_ignore_systab_0, (uchar**) &ga_dont_ignore_systab_0, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { "ndb-nodegroup-map", OPT_NDB_NODEGROUP_MAP,
@@ -736,7 +736,7 @@ clearConsumers()
 static inline bool
 checkSysTable(const TableS* table)
 {
-  return ga_dont_ignore_systab_0 || ! table->getSysTable();
+  return ! table->getSysTable();
 }
 
 static inline bool
@@ -760,8 +760,13 @@ isIndex(const TableS* table)
 }
 
 static inline bool
-isInList(BaseString &needle, Vector<BaseString> &lst)
+isSYSTAB_0(const TableS* table)
 {
+  return table->isSYSTAB_0();
+}
+
+static inline bool
+isInList(BaseString &needle, Vector<BaseString> &lst){
   unsigned int i= 0;
   for (i= 0; i < lst.size(); i++)
   {
@@ -1076,6 +1081,10 @@ main(int argc, char** argv)
     table_output.push_back(NULL);
     if (!checkDbAndTableName(table))
       continue;
+    if (isSYSTAB_0(table))
+    {
+      table_output[i]= ndbout.m_out;
+    }
     if (checkSysTable(table))
     {
       if (!tab_path || isBlobTable(table) || isIndex(table))

Thread
bzr commit into mysql-5.1-telco-6.3 branch (Martin.Skold:3169) Bug#48005Martin Skold1 Dec