List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:May 19 2009 11:28am
Subject:bzr commit into mysql-6.0-backup branch (ingo.struewing:2815) Bug#42572
View as plain text  
#At file:///home2/mydev/bzrroot/mysql-6.0-bug42572-2/ based on
revid:charles.bell@stripped

 2815 Ingo Struewing	2009-05-19
      Bug#42572 - Restore fails when myisampack used with -b option
      
      The use of myisampack -b creates a table backup file in the
      database directory. On DROP DATABASE, this file is not
      noticed as belonging to a database object. It is not deleted.
      DROP DATABASE fails because the directory is not empty.
      
      The same situation exists if the user creates files in the
      database directory, which are not known to MySQL as belonging
      to database objects. For example backup image files.
      
      RESTORE ignored the failing DROP DATABASE. It failed when a
      CREATE DATABASE for the not dropped database failed.
      
      The problem is solved by renaming the non-empty database
      directory, if DROP DATABASE fails due to unknown files.
     @ mysql-test/suite/backup/r/backup_external.result
        Bug#42572 - Restore fails when myisampack used with -b option
        Updated test result.
     @ mysql-test/suite/backup/t/backup_external.test
        Bug#42572 - Restore fails when myisampack used with -b option
        Fixed test.
     @ sql/share/errmsg.txt
        Bug#42572 - Restore fails when myisampack used with -b option
        Added ER_RESTORE_RENAME.
     @ sql/si_objects.cc
        Bug#42572 - Restore fails when myisampack used with -b option
        Added Abstract_obj::m_errno.
        Added Database_obj::drop()

    modified:
      mysql-test/suite/backup/r/backup_external.result
      mysql-test/suite/backup/t/backup_external.test
      sql/share/errmsg.txt
      sql/si_objects.cc
=== modified file 'mysql-test/suite/backup/r/backup_external.result'
--- a/mysql-test/suite/backup/r/backup_external.result	2009-03-25 22:17:35 +0000
+++ b/mysql-test/suite/backup/r/backup_external.result	2009-05-19 09:28:51 +0000
@@ -257,18 +257,21 @@ id	name
 3	test3
 4	test4
 
+#
+# Bug#42572 - Restore fails when myisampack used with -b option
+#
 # Use myisampack -b option to make backup of table datafile
 BACKUP DATABASE db1 TO 'db1b.bak';
 backup_id
 #
 RESTORE FROM 'db1b.bak' OVERWRITE;
-ERROR HY000: Could not restore database `db1`
-SHOW TABLES FROM db1;
-Tables_in_db1
-# Perform restore again to get the tables from db1 back
-RESTORE FROM 'db1.bak' OVERWRITE;
 backup_id
 #
+Warnings:
+#	#	Renamed directory with unknown files to 'db1-#'
+SHOW TABLES FROM db1;
+Tables_in_db1
+t1
 # Check data contents and indexes in table
 SHOW TABLES FROM db1;
 Tables_in_db1

=== modified file 'mysql-test/suite/backup/t/backup_external.test'
--- a/mysql-test/suite/backup/t/backup_external.test	2009-03-25 22:17:35 +0000
+++ b/mysql-test/suite/backup/t/backup_external.test	2009-05-19 09:28:51 +0000
@@ -149,6 +149,9 @@ SELECT COUNT(*) FROM db1.t1 WHERE id < 5
 SELECT * FROM db1.t1 LIMIT 4;
  
 --echo
+--echo #
+--echo # Bug#42572 - Restore fails when myisampack used with -b option
+--echo #
 --echo # Use myisampack -b option to make backup of table datafile
 
 --exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
@@ -160,20 +163,19 @@ SELECT * FROM db1.t1 LIMIT 4;
 BACKUP DATABASE db1 TO 'db1b.bak';
 
 # Perform restore
---replace_column 1 #
---error ER_BACKUP_CANT_RESTORE_DB
+# Mask UUID and path delimiter.
+--replace_regex /db1-[^']*/db1-#/ /'\.[\/\\]/'/
+# Mask backup_id and warning numbers.
+--replace_column 1 # 2 #
 RESTORE FROM 'db1b.bak' OVERWRITE;
 
-SHOW TABLES FROM db1;
-# No tables will be seen in db1. This is because of Bug#42572. Once this bug is
-# fixed, restore should pass and tables should be present in db1.
+# Get rid of the directory, saved by RESTORE.
+let $warn = query_get_value(SHOW WARNINGS, Message, 1);
+let $dir  = `SELECT SUBSTR("$warn", INSTR("$warn", "db1-"), 40)`;
+--remove_file $MYSQLD_DATADIR/$dir/t1.OLD
+--rmdir $MYSQLD_DATADIR/$dir
 
-# Remove the .OLD file from database directory
---exec rm $MYSQLD_DATADIR/db1/t1.OLD
-
---echo # Perform restore again to get the tables from db1 back
---replace_column 1 #
-RESTORE FROM 'db1.bak' OVERWRITE;
+SHOW TABLES FROM db1;
 
 --echo # Check data contents and indexes in table
 SHOW TABLES FROM db1;

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2009-05-14 16:52:22 +0000
+++ b/sql/share/errmsg.txt	2009-05-19 09:28:51 +0000
@@ -6516,3 +6516,5 @@ ER_BACKUP_INTERRUPTED
   eng "Operation has been interrupted."
 ER_BACKUP_NOT_ENABLED
   eng "The MySQL Backup system is disabled in this release. Use --new on server startup
to enable."
+ER_RESTORE_RENAME
+  eng "Renamed directory with unknown files to '%.200s'"

=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc	2009-05-05 17:42:58 +0000
+++ b/sql/si_objects.cc	2009-05-19 09:28:51 +0000
@@ -606,6 +606,7 @@ protected:
 protected:
   MEM_ROOT m_mem_root; /* This mem-root is for keeping stmt list. */
   List<LEX_STRING> m_stmt_list;
+  int m_errno; //< Remember last error number of last statement
 
 protected:
   /* These attributes are to be used only for serialization. */
@@ -649,6 +650,7 @@ inline Abstract_obj::Abstract_obj(LEX_ST
     m_id.copy(id.str, id.length, system_charset_info);
   else
     m_id.length(0);
+  m_errno= 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -797,6 +799,10 @@ bool Abstract_obj::drop(THD *thd)
   /* Execute DDL operation. */
   rc= ed_connection.execute_direct(*sql_text);
 
+  /* Save error number. Ed_connection gets destroyed on return. */
+  if (rc)
+    m_errno= ed_connection.get_last_errno();
+
   /* Disable further DDL execution. */
   ::obs::bml_exception_off(thd);
 
@@ -861,6 +867,7 @@ public:
 
 public:
   virtual inline const String *get_db_name() const { return get_name(); }
+  virtual bool drop(THD *thd);
 
 private:
   virtual bool do_serialize(THD *thd, Out_stream &out_stream);
@@ -1767,6 +1774,81 @@ void Database_obj::build_drop_statement(
 }
 
 ///////////////////////////////////////////////////////////////////////////
+
+/**
+  Drop the database.
+
+  @param[in] thd              Server thread context.
+
+  @return Error status.
+    @retval FALSE on success.
+    @retval TRUE on error.
+*/
+
+bool Database_obj::drop(THD *thd)
+{
+  bool rc;
+  DBUG_ENTER("Database_obj::drop");
+
+  /*
+    If DROP DATABASE fails due to unknown files in the directory,
+    fix that by renaming the directory.
+  */
+  rc= Abstract_obj::drop(thd);
+  if (rc)
+  {
+    DBUG_PRINT("si_objects", ("drop database failed, m_errno: %d", m_errno));
+    if (m_errno == ER_DB_DROP_RMDIR)
+    {
+        size_t len= get_name()->length();
+        char oldname[FN_REFLEN];
+        char newname[FN_REFLEN];
+        uchar uuid[MY_UUID_SIZE];
+
+        DBUG_PRINT("si_objects", ("Renaming to oldname-uuid"));
+        /*
+          get_name() returns a const String. We cannot use c_ptr*() with it.
+          New name is ./dbname-UUID
+        */
+        if (len + 3 + MY_UUID_STRING_LENGTH >= FN_REFLEN)
+          goto err; /* purecov: inspected */
+        memcpy(oldname, get_name()->ptr(), len);
+        oldname[len] = '\0';
+        /* Convert database name to a file name. */
+        len= build_table_filename(oldname, sizeof(oldname)-1,
+                                  oldname, "", "", 0);
+        /* Remove trailing slash. */
+        if (len && (oldname[len-1] == FN_LIBCHAR))
+          oldname[--len]= '\0';
+        /* Build new name as old + uuid. */
+        memcpy(newname, oldname, len);
+        newname[len++]= '-';
+        my_uuid(uuid);
+        my_uuid2str(uuid, newname + len);
+        newname[len + MY_UUID_STRING_LENGTH]= '\0';
+        DBUG_PRINT("si_objects", ("Rename '%s' to '%s'", oldname, newname));
+        rc= my_rename(oldname, newname, MYF(MY_WME));
+        if (rc)
+        {
+          /* Could not rename directory. Restore will fail. */
+          /* purecov: begin tested */
+          my_error(ER_DB_DROP_RMDIR, MYF(0), oldname, my_errno);
+          /* purecov: end */
+        }
+        else
+        {
+          /* Renamed directory. Add a warning. */
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                              ER_RESTORE_RENAME, ER(ER_RESTORE_RENAME),
+                              newname);
+        }
+    }
+  }
+ err:
+  DBUG_RETURN(rc);
+}
+
+///////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 
 /**


Attachment: [text/bzr-bundle] bzr/ingo.struewing@sun.com-20090519092851-prf51bqsnznz2iu7.bundle
Thread
bzr commit into mysql-6.0-backup branch (ingo.struewing:2815) Bug#42572Ingo Struewing19 May 2009
  • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2815)Bug#42572Jørgen Løland20 May 2009
    • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2815)Bug#42572Ingo Strüwing20 May 2009
  • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2815)Bug#42572Rafal Somla21 May 2009
    • Re: bzr commit into mysql-6.0-backup branch (ingo.struewing:2815)Bug#42572Ingo Strüwing22 May 2009