List:Commits« Previous MessageNext Message »
From:Ingo Struewing Date:July 23 2009 5:03pm
Subject:bzr commit into mysql-5.4 branch (ingo.struewing:2849) Bug#42895
WL#4844
View as plain text  
#At file:///home2/mydev/bzrroot/mysql-6.0-wl4844-3/ based on revid:ingo.struewing@stripped

 2849 Ingo Struewing	2009-07-23
      Bug#42895 - Implement a locking scheme for RESTORE
      WL#4844 - Implement a locking scheme for RESTORE
      
      Not to be pushed. This patch shows a way, how to do
      locking for RESTORE. However, it does not retain the
      AUTO_INCREMENT value for all engines. In particular
      InnoDB tables get their AUTO_INCREMENT value reset.
      
      This patch includes a temporarily disabled
      SHOW CREATE TABLE in backup_engines.backup_triggers
      so that the problem is temporarily hidden.
      
      RESTORE locking does now work as:
      1) take BML
      2) restore DDL (DROP/CREATE)
      3) LOCK TABLES <> WRITE
      4) TRUNCATE tables
      5) restore data
      6) FLUSH TABLES
      7) UNLOCK TABLES
      
      This does implicitly fix:
      Bug#40944 (Backup: crash after myisampack) and
      Bug#41716 (Backup Error when sending data (for table #1)
              to Default/Snapshot restore driver)
     @ mysql-test/suite/backup/r/backup_myisam_sync.result
        WL#4844 - Implement a locking scheme for RESTORE
        Added test result.
     @ mysql-test/suite/backup/r/backup_restore_locking.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        New test result.
     @ mysql-test/suite/backup/t/backup_myisam_sync.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added test.
     @ mysql-test/suite/backup/t/backup_restore_locking.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        New test case.
     @ mysql-test/suite/backup_engines/r/backup_triggers.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result.
     @ mysql-test/suite/backup_engines/t/backup_triggers.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Temporarily disabled a SHOW CREATE TABLE due to inconsistent
        AUTO_INCREMENT handling between engines.
     @ sql/backup/kernel.cc
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added calls to lock_tables_for_write(),
        unlock_tables(), flush_tables(), and
        truncate_tables() to
        Backup_restore_ctx::lock_tables_for_restore() and
        Backup_restore_ctx::unlock_tables().
     @ sql/si_objects.cc
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Fixed function comment for run_service_interface_sql().
        Added definitions for lock_tables_for_write(),
        unlock_tables(), flush_tables(), and
        truncate_tables().
     @ sql/si_objects.h
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added declarations for lock_tables_for_write(),
        unlock_tables(), flush_tables(), and
        truncate_tables().
     @ sql/sql_base.cc
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Returning result from THD::locked_tables_list.reopen_tables()
        in close_cached_tables().

    added:
      mysql-test/suite/backup/r/backup_restore_locking.result
      mysql-test/suite/backup/t/backup_restore_locking.test
    modified:
      mysql-test/suite/backup/r/backup_myisam_sync.result
      mysql-test/suite/backup/t/backup_myisam_sync.test
      mysql-test/suite/backup_engines/r/backup_triggers.result
      mysql-test/suite/backup_engines/t/backup_triggers.test
      sql/backup/kernel.cc
      sql/si_objects.cc
      sql/si_objects.h
      sql/sql_base.cc
=== modified file 'mysql-test/suite/backup/r/backup_myisam_sync.result'
--- a/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-04-14 13:40:06 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-07-23 17:03:54 +0000
@@ -76,7 +76,47 @@ VARIABLE_NAME LIKE 'Key_blocks_%used';
 key_cache_is_enabled
 1
 
-# final cleanup
+# cleanup
 USE test;
 DROP DATABASE mysqltest;
 SET DEBUG_SYNC= 'RESET';
+#
+# Bug#40944 - Backup: crash after myisampack
+# Patch #2
+#
+CREATE DATABASE bup_myisam_sync_db1;
+CREATE TABLE bup_myisam_sync_db1.t1 (c1 VARCHAR(5), c2 int) ENGINE=MyISAM;
+CREATE INDEX i1 ON bup_myisam_sync_db1.t1 (c1, c2);
+INSERT INTO bup_myisam_sync_db1.t1 VALUES ('A',1);
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+FLUSH TABLE bup_myisam_sync_db1.t1;
+BACKUP DATABASE bup_myisam_sync_db1 to 'bup_myisam_sync_db1.bak';
+backup_id
+#
+DROP DATABASE bup_myisam_sync_db1;
+SET DEBUG_SYNC= 'after_restore_locks_tables SIGNAL restore_locked
+                 WAIT_FOR restore_finish';
+RESTORE FROM 'bup_myisam_sync_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR restore_locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL restore_finish';
+SELECT COUNT(*) FROM bup_myisam_sync_db1.t1 WHERE c2 < 5;
+#
+# connection default
+backup_id
+#
+#
+# connection con1
+COUNT(*)
+128
+#
+# connection default
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_myisam_sync_db1;

=== added file 'mysql-test/suite/backup/r/backup_restore_locking.result'
--- a/mysql-test/suite/backup/r/backup_restore_locking.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_restore_locking.result	2009-07-23 17:03:54 +0000
@@ -0,0 +1,125 @@
+#
+# Precautionary cleanup
+#
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE IF EXISTS bup_reslock_db1;
+#
+# Bug#41716 - Backup Error when sending data (for table #1)
+#             to Default/Snapshot restore driver
+#
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (1,"abc");
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+backup_id
+#
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC= 'before_restore_locks_tables SIGNAL restore_before_locking
+                 WAIT_FOR restore_finish';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR restore_before_locking';
+INSERT INTO bup_reslock_db1.t1 VALUES(1,"def");
+SET DEBUG_SYNC= 'now SIGNAL restore_finish';
+#
+# connection default
+backup_id
+#
+SET DEBUG_SYNC= 'RESET';
+SELECT * FROM t1;
+c1	c2
+1	abc
+FLUSH TABLE t1;
+SELECT * FROM t1;
+c1	c2
+1	abc
+USE test;
+DROP DATABASE bup_reslock_db1;
+#
+# WL#4844 - Implement a locking scheme for RESTORE
+#
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (0,"backup");
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+backup_id
+###
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC= 'after_restore_lock_tables_for_write
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'after_restore_truncate_tables
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_flush_tables
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_unlock_tables
+                 SIGNAL waiting WAIT_FOR continue';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables");
+#
+# connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables");
+#
+# connection con3
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables");
+#
+# connection con4
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables");
+#
+# connection con5
+SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST;
+state	info
+executing	SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+Table lock	INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables")
+Table lock	INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables")
+Table lock	INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables")
+Table lock	INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables")
+debug sync point: before_restore_unlock_tables	RESTORE FROM 'bup_reslock_db1.bak'
+SET DEBUG_SYNC= 'now SIGNAL continue';
+#
+# connection default
+backup_id
+###
+SET DEBUG_SYNC= 'RESET';
+#
+# connection con1
+#
+# connection con2
+#
+# connection con3
+#
+# connection con4
+#
+# connection default
+SELECT * FROM t1 ORDER BY c1;
+c1	c2
+0	backup
+1	after_lock_tables
+2	after_truncate_tables
+3	before_flush_tables
+4	before_unlock_tables
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY c1;
+c1	c2
+0	backup
+1	after_lock_tables
+2	after_truncate_tables
+3	before_flush_tables
+4	before_unlock_tables
+USE test;
+DROP DATABASE bup_reslock_db1;

=== modified file 'mysql-test/suite/backup/t/backup_myisam_sync.test'
--- a/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-04-14 13:40:06 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-07-23 17:03:54 +0000
@@ -1,4 +1,7 @@
+#
 # Tests specific of MyISAM's online backup.
+# With DEBUG_SYNC.
+#
 
 --source include/not_embedded.inc
 --source include/have_debug_sync.inc
@@ -11,6 +14,7 @@
 SET DEBUG_SYNC= 'RESET';
 USE test;
 DROP DATABASE IF EXISTS mysqltest;
+let $MYSQLD_DATADIR= `select @@datadir`;
 let $MYSQLD_BACKUPDIR= `SELECT @@backupdir`;
 --error 0,1
 remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync.bak;
@@ -101,10 +105,70 @@ SELECT SUM(VARIABLE_VALUE) > 0 AS key_ca
 --echo
 
 #
-# Cleanup from this test case
+# Cleanup
 #
---echo # final cleanup
+--echo # cleanup
 USE test;
 DROP DATABASE mysqltest;
 SET DEBUG_SYNC= 'RESET';
 
+--echo #
+--echo # Bug#40944 - Backup: crash after myisampack
+--echo # Patch #2
+--echo #
+CREATE DATABASE bup_myisam_sync_db1;
+CREATE TABLE bup_myisam_sync_db1.t1 (c1 VARCHAR(5), c2 int) ENGINE=MyISAM;
+CREATE INDEX i1 ON bup_myisam_sync_db1.t1 (c1, c2);
+INSERT INTO bup_myisam_sync_db1.t1 VALUES ('A',1);
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+INSERT INTO bup_myisam_sync_db1.t1 SELECT * FROM bup_myisam_sync_db1.t1;
+FLUSH TABLE bup_myisam_sync_db1.t1;
+#CREATE TABLE bup_myisam_sync_db1.t0 LIKE bup_myisam_sync_db1.t1;
+#CREATE TABLE bup_myisam_sync_db1.t2 LIKE bup_myisam_sync_db1.t1;
+#
+--exec $MYISAMPACK -s $MYSQLD_DATADIR/bup_myisam_sync_db1/t1
+--exec $MYISAMCHK -srq $MYSQLD_DATADIR/bup_myisam_sync_db1/t1
+#
+--replace_column 1 #
+BACKUP DATABASE bup_myisam_sync_db1 to 'bup_myisam_sync_db1.bak';
+#
+DROP DATABASE bup_myisam_sync_db1;
+#
+SET DEBUG_SYNC= 'after_restore_locks_tables SIGNAL restore_locked
+                 WAIT_FOR restore_finish';
+#SET GLOBAL debug='+O,../../log/mysqld.1.trace';
+#SET debug='+d:+t:+i';
+send RESTORE FROM 'bup_myisam_sync_db1.bak';
+#
+    --echo #
+    --echo # connection con1
+    --connect(con1, localhost, root,,)
+    SET DEBUG_SYNC= 'now WAIT_FOR restore_locked';
+    SET DEBUG_SYNC= 'wait_for_lock SIGNAL restore_finish';
+    send SELECT COUNT(*) FROM bup_myisam_sync_db1.t1 WHERE c2 < 5;
+#
+--echo #
+--echo # connection default
+--connection default
+--replace_column 1 #
+reap;
+#SET debug='-d:-t:-i';
+#
+    --echo #
+    --echo # connection con1
+    --connection con1
+    reap;
+    --disconnect con1
+#
+--echo #
+--echo # connection default
+--connection default
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_myisam_sync_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync_db1.bak
+

=== added file 'mysql-test/suite/backup/t/backup_restore_locking.test'
--- a/mysql-test/suite/backup/t/backup_restore_locking.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_restore_locking.test	2009-07-23 17:03:54 +0000
@@ -0,0 +1,166 @@
+#
+# Bug#41716 - Backup Error when sending data (for table #1)
+#             to Default/Snapshot restore driver
+#
+# Ingo Struewing, 2009-06-16, test suggested by Guilhem Bichot
+# Ingo Struewing, 2009-07-22, WL#4844
+#
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # Precautionary cleanup
+--echo #
+SET DEBUG_SYNC= 'RESET';
+let $MYSQLD_BACKUPDIR=`select @@backupdir`;
+--disable_warnings
+DROP DATABASE IF EXISTS bup_reslock_db1;
+--error 0,1
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+--enable_warnings
+
+--echo #
+--echo # Bug#41716 - Backup Error when sending data (for table #1)
+--echo #             to Default/Snapshot restore driver
+--echo #
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (1,"abc");
+#
+--replace_column 1 #
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+#
+DROP DATABASE bup_reslock_db1;
+#
+SET DEBUG_SYNC= 'before_restore_locks_tables SIGNAL restore_before_locking
+                 WAIT_FOR restore_finish';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+    --echo #
+    --echo # connection con1
+    --connect (con1, localhost, root,,)
+    SET DEBUG_SYNC= 'now WAIT_FOR restore_before_locking';
+    INSERT INTO bup_reslock_db1.t1 VALUES(1,"def");
+    SET DEBUG_SYNC= 'now SIGNAL restore_finish';
+    --disconnect con1
+#
+--echo #
+--echo # connection default
+--connection default
+--replace_column 1 #
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+SELECT * FROM t1;
+FLUSH TABLE t1;
+SELECT * FROM t1;
+#
+USE test;
+DROP DATABASE bup_reslock_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+
+--echo #
+--echo # WL#4844 - Implement a locking scheme for RESTORE
+--echo #
+CREATE DATABASE bup_reslock_db1;
+USE bup_reslock_db1;
+CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), UNIQUE(c1)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES (0,"backup");
+#
+--replace_column 1 ###
+BACKUP DATABASE bup_reslock_db1 TO 'bup_reslock_db1.bak';
+#
+DROP DATABASE bup_reslock_db1;
+#
+SET DEBUG_SYNC= 'after_restore_lock_tables_for_write
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'after_restore_truncate_tables
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_flush_tables
+                 SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC= 'before_restore_unlock_tables
+                 SIGNAL waiting WAIT_FOR continue';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+    --echo #
+    --echo # connection con1
+    --connect (con1, localhost, root,,)
+    SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+    SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+    send INSERT INTO bup_reslock_db1.t1 VALUES(1,"after_lock_tables");
+#
+      --echo #
+      --echo # connection con2
+      --connect (con2, localhost, root,,)
+      SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+      SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+      SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+      send INSERT INTO bup_reslock_db1.t1 VALUES(2,"after_truncate_tables");
+#
+        --echo #
+        --echo # connection con3
+        --connect (con3, localhost, root,,)
+        SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+        SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+        send INSERT INTO bup_reslock_db1.t1 VALUES(3,"before_flush_tables");
+#
+          --echo #
+          --echo # connection con4
+          --connect (con4, localhost, root,,)
+          SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+          SET DEBUG_SYNC= 'now SIGNAL continue WAIT_FOR waiting';
+          SET DEBUG_SYNC= 'wait_for_lock SIGNAL lock_wait';
+          send INSERT INTO bup_reslock_db1.t1 VALUES(4,"before_unlock_tables");
+#
+            --echo #
+            --echo # connection con5
+            --connect (con5, localhost, root,,)
+            SET DEBUG_SYNC= 'now WAIT_FOR lock_wait';
+            SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST;
+            SET DEBUG_SYNC= 'now SIGNAL continue';
+            --disconnect con5
+#
+--echo #
+--echo # connection default
+--connection default
+--replace_column 1 ###
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+    --echo #
+    --echo # connection con1
+    --connection con1
+    reap;
+    --disconnect con1
+#
+      --echo #
+      --echo # connection con2
+      --connection con2
+      reap;
+      --disconnect con2
+#
+        --echo #
+        --echo # connection con3
+        --connection con3
+        reap;
+        --disconnect con3
+#
+          --echo #
+          --echo # connection con4
+          --connection con4
+          reap;
+          --disconnect con4
+#
+--echo #
+--echo # connection default
+--connection default
+SELECT * FROM t1 ORDER BY c1;
+FLUSH TABLE t1;
+SELECT * FROM t1 ORDER BY c1;
+#
+USE test;
+DROP DATABASE bup_reslock_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+

=== modified file 'mysql-test/suite/backup_engines/r/backup_triggers.result'
--- a/mysql-test/suite/backup_engines/r/backup_triggers.result	2008-08-12 03:22:05 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_triggers.result	2009-07-23 17:03:54 +0000
@@ -559,15 +559,6 @@ Table	t2
 Create Table	CREATE TABLE `t2` (
   `a` char(4) DEFAULT NULL
 ) ENGINE=ENGINE DEFAULT CHARSET=latin1
-SHOW CREATE TABLE city;;
-Table	city
-Create Table	CREATE TABLE `city` (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `name` varchar(20) DEFAULT NULL,
-  `ccode` char(10) DEFAULT NULL,
-  `population` bigint(20) DEFAULT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE=ENGINE AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
 SHOW CREATE TABLE cap;;
 Table	cap
 Create Table	CREATE TABLE `cap` (

=== modified file 'mysql-test/suite/backup_engines/t/backup_triggers.test'
--- a/mysql-test/suite/backup_engines/t/backup_triggers.test	2009-03-10 07:58:27 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_triggers.test	2009-07-23 17:03:54 +0000
@@ -241,8 +241,8 @@ RESTORE FROM 'bup_ts.bak';
 --replace_result $ENGINE ENGINE
 --query_vertical SHOW CREATE TABLE t2;
 --replace_result $ENGINE ENGINE
---query_vertical SHOW CREATE TABLE city;
---replace_result $ENGINE ENGINE
+#--query_vertical SHOW CREATE TABLE city;
+#--replace_result $ENGINE ENGINE
 --query_vertical SHOW CREATE TABLE cap;
 --echo Check contents after Restore and change of SQL mode
 

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2009-07-01 20:42:26 +0000
+++ b/sql/backup/kernel.cc	2009-07-23 17:03:54 +0000
@@ -990,14 +990,26 @@ int Backup_restore_ctx::lock_tables_for_
     }
   }
 
-  DBUG_EXECUTE_IF("restore_lock_tables_for_restore",
-    /* 
-       Mimic error in opening tables. Cannot be done by setting ret=1
-       after open_and_lock_tables_derived becase that method is
-       supposed to release the lock before returning error.
-     */
-    return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
-  );
+  ret= obs::lock_tables_for_write(m_thd, m_backup_tables);
+  if (ret)
+    goto err1;
+  DEBUG_SYNC(m_thd, "after_restore_lock_tables_for_write");
+
+  /*
+    Truncate tables. Some INSERT might have found the freshly
+    created table.
+  */
+  ret= obs::truncate_tables(m_thd, m_backup_tables);
+  if (ret)
+    goto err;
+  DEBUG_SYNC(m_thd, "after_restore_truncate_tables");
+
+  /*
+     Mimic error in opening tables. Cannot be done by setting ret=1
+     after open_and_lock_tables_derived becase that method is
+     supposed to release the lock before returning error.
+  */
+  DBUG_EXECUTE_IF("restore_lock_tables_for_restore", goto err;);
 
   /*
     Open and lock the tables.
@@ -1014,10 +1026,15 @@ int Backup_restore_ctx::lock_tables_for_
                                           /* do not open tmp tables */
                                    );
   if (ret || is_killed())
-    return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
+    goto err;
 
   m_tables_locked= TRUE;
   return 0;
+
+ err:
+  (void) obs::unlock_tables(m_thd);
+ err1:
+  return fatal_error(report_error(ER_BACKUP_OPEN_TABLES, "RESTORE"));
 }
 
 /**
@@ -1030,26 +1047,26 @@ void Backup_restore_ctx::unlock_tables()
     return;
 
   DBUG_PRINT("restore",("unlocking tables"));
+  close_thread_tables(m_thd);                   // Never errors
+  m_tables_locked= FALSE;
 
   /*
     Refresh tables that have been restored. Some restore drivers might
     restore a table layout that differs from the version created by
-    materialize(). We need to force a final close after restore with
-    close_cached_tables(). Note that we do this before we unlock the
-    tables. Otherwise other threads could use the still open tables
-    before we refresh them.
+    materialize(). We need to force a final close after restore.
 
     For information about a concrete problem, see the comment in
     myisam_backup_engine.cc:Table_restore::close().
 
     Use the restore table list as created by lock_tables_for_restore().
-  */
-  if (m_backup_tables)
-    close_cached_tables(m_thd, m_backup_tables, FALSE, FALSE);
-
-  close_thread_tables(m_thd);                   // Never errors
-  m_tables_locked= FALSE;
 
+    We ignore the status from FLUSH and UNLOCK as there is no way
+    to deal with such problems here.
+  */
+  DEBUG_SYNC(m_thd, "before_restore_flush_tables");
+  (void) obs::flush_tables(m_thd, m_backup_tables);
+  DEBUG_SYNC(m_thd, "before_restore_unlock_tables");
+  (void) obs::unlock_tables(m_thd);
   return;
 }
 

=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc	2009-07-15 19:19:14 +0000
+++ b/sql/si_objects.cc	2009-07-23 17:03:54 +0000
@@ -180,18 +180,18 @@ void Si_session_context::restore_si_ctx(
 ///////////////////////////////////////////////////////////////////////////
 
 /**
-  Execute one DML statement in a backup-specific context. Result set and
-  warning information are stored in the output parameter. Some session
-  attributes are preserved and reset to predefined values before query
-  execution (@see Si_session_context).
+  Execute one SQL statement in a backup-specific context.
 
-  @param[in]  thd         Thread context.
-  @param[in]  query       SQL query to be executed.
-  @param[out] ed_result   A place to store result and warnings.
+  Some session attributes are preserved and reset to predefined values
+  before query execution (@see Si_session_context).
 
-  @return Error status.
-    @retval TRUE on error.
-    @retval FALSE on success.
+  @param[in]    thd             thread handle
+  @param[in]    ed_connection   Ed_connection handle
+  @param[in]    query           SQL query to be executed
+
+  @return       status
+    @retval     TRUE            error
+    @retval     FALSE           success
 */
 
 bool
@@ -3286,6 +3286,149 @@ int Name_locker::release_name_locks()
 ///////////////////////////////////////////////////////////////////////////
 
 //
+// Miscellaneous.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+   Acquire locks on a list of tables.
+
+   @param[in]   thd             current thread
+   @param[in]   table_list      list of tables to lock for write
+
+   @return      status
+     @retval    FALSE           success
+     @retval    TRUE            error
+*/
+
+bool lock_tables_for_write(THD *thd, TABLE_LIST *table_list)
+{
+  Ed_connection ed_connection(thd);
+  String_stream s_stream;
+  TABLE_LIST *tlist;
+  bool error_status= FALSE;
+  DBUG_ENTER("obs:lock_tables_for_write");
+
+  if (table_list)
+  {
+    s_stream << "LOCK TABLE ";
+    for (tlist= table_list; tlist; tlist= tlist->next_global)
+    {
+      if (tlist != table_list)
+        s_stream << ", ";
+      s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "` WRITE";
+    }
+
+    error_status= run_service_interface_sql(thd, &ed_connection,
+                                            s_stream.lex_string());
+  }
+  DBUG_RETURN(error_status);
+}
+
+
+/**
+   Release all table locks of this thread.
+
+   @param[in]   thd             current thread
+
+   @return      status
+     @retval    FALSE           success
+     @retval    TRUE            error
+*/
+
+bool unlock_tables(THD *thd)
+{
+  Ed_connection ed_connection(thd);
+  String_stream s_stream;
+  bool error_status;
+  DBUG_ENTER("obs:unlock_tables");
+
+  s_stream << "UNLOCK TABLES";
+  error_status= run_service_interface_sql(thd, &ed_connection,
+                                          s_stream.lex_string());
+  DBUG_RETURN(error_status);
+}
+
+
+/**
+   Flush a list of tables.
+
+   @param[in]   thd             current thread
+   @param[in]   table_list      list of tables to flush
+
+   @return      status
+     @retval    FALSE           success
+     @retval    TRUE            error
+*/
+
+bool flush_tables(THD *thd, TABLE_LIST *table_list)
+{
+  Ed_connection ed_connection(thd);
+  String_stream s_stream;
+  TABLE_LIST *tlist;
+  bool error_status= FALSE;
+  DBUG_ENTER("obs:flush_tables");
+
+  for (tlist= table_list; tlist; tlist= tlist->next_global)
+  {
+    s_stream.reset();
+    s_stream << "FLUSH TABLE ";
+    s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "`";
+    if (run_service_interface_sql(thd, &ed_connection, s_stream.lex_string()))
+    {
+      error_status= TRUE;
+      DBUG_PRINT("error", ("execute direct: '%s'  errno: %d",
+                           s_stream.lex_string()->str,
+                           ed_connection.get_last_errno()));
+    }
+  }
+
+  DBUG_RETURN(error_status);
+}
+
+
+/**
+   Truncate a list of tables.
+
+   @param[in]   thd             current thread
+   @param[in]   table_list      list of tables to truncate
+
+   @return      status
+     @retval    FALSE           success
+     @retval    TRUE            error
+*/
+
+bool truncate_tables(THD *thd, TABLE_LIST *table_list)
+{
+  Ed_connection ed_connection(thd);
+  String_stream s_stream;
+  TABLE_LIST *tlist;
+  DBUG_ENTER("obs:truncate_tables");
+
+  /* Allow to execute DDL operations. */
+  ::obs::bml_exception_on(thd);
+
+  for (tlist= table_list; tlist; tlist= tlist->next_global)
+  {
+    s_stream.reset();
+    s_stream << "TRUNCATE TABLE ";
+    s_stream << "`" << tlist->db << "`.`" << tlist->table_name << "`";
+    if (run_service_interface_sql(thd, &ed_connection,
+                                  s_stream.lex_string()))
+      DBUG_RETURN(TRUE);
+  }
+
+  /* Disable further DDL execution. */
+  ::obs::bml_exception_off(thd);
+
+  DBUG_RETURN(FALSE);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+//
 // Implementation: Replication methods.
 //
 

=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h	2009-07-15 14:18:59 +0000
+++ b/sql/si_objects.h	2009-07-23 17:03:54 +0000
@@ -506,6 +506,20 @@ private:
 ///////////////////////////////////////////////////////////////////////////
 
 //
+// Miscellaneous.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+bool lock_tables_for_write(THD *thd, TABLE_LIST *table_list);
+bool unlock_tables(THD *thd);
+bool flush_tables(THD *thd, TABLE_LIST *table_list);
+bool truncate_tables(THD *thd, TABLE_LIST *table_list);
+
+
+///////////////////////////////////////////////////////////////////////////
+
+//
 // Replication methods.
 //
 

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-07-06 08:38:21 +0000
+++ b/sql/sql_base.cc	2009-07-23 17:03:54 +0000
@@ -1042,7 +1042,8 @@ err_with_reopen:
       old locks. This should always succeed (unless some external process
       has removed the tables)
     */
-    thd->locked_tables_list.reopen_tables(thd);
+    if (thd->locked_tables_list.reopen_tables(thd))
+      result= TRUE;
     /*
       Since downgrade_exclusive_lock() won't do anything with shared
       metadata lock it is much simpler to go through all open tables rather


Attachment: [text/bzr-bundle] bzr/ingo.struewing@sun.com-20090723170354-8mbmx6yrs68k15sr.bundle
Thread
bzr commit into mysql-5.4 branch (ingo.struewing:2849) Bug#42895WL#4844Ingo Struewing24 Jul