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

 2882 Ingo Struewing	2009-11-16
      Bug#42895 - Implement a locking scheme for RESTORE
      WL#4844 - Implement a locking scheme for RESTORE
      
      The old RESTORE locking scheme did allow other
      sessions to modify the tables in restore in some ways.
      
      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)
      
      ******
      auto-merge
     @ mysql-test/suite/backup/r/backup_external.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result due to unrelated changes.
     @ mysql-test/suite/backup/r/backup_intr_errors.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result due to unrelated changes.
     @ mysql-test/suite/backup/r/backup_myisam.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result due to unrelated changes.
     @ mysql-test/suite/backup/r/backup_myisam_coverage.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result due to unrelated changes.
     @ mysql-test/suite/backup/r/backup_myisam_sync.result
        Bug#42895 - Implement a locking scheme for RESTORE
        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_external.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added comments.
     @ mysql-test/suite/backup/t/backup_myisam.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added comments.
     @ mysql-test/suite/backup/t/backup_myisam_coverage.test
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added comments.
     @ 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_interruption.result
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Updated test result due to unrelated changes.
     @ 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().
     @ sql/sql_delete.cc
        Bug#42895 - Implement a locking scheme for RESTORE
        WL#4844 - Implement a locking scheme for RESTORE
        Added error injection point "error_inject_truncate_enter".

    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_external.result
      mysql-test/suite/backup/r/backup_intr_errors.result
      mysql-test/suite/backup/r/backup_myisam.result
      mysql-test/suite/backup/r/backup_myisam_coverage.result
      mysql-test/suite/backup/r/backup_myisam_sync.result
      mysql-test/suite/backup/t/backup_external.test
      mysql-test/suite/backup/t/backup_myisam.test
      mysql-test/suite/backup/t/backup_myisam_coverage.test
      mysql-test/suite/backup/t/backup_myisam_sync.test
      mysql-test/suite/backup_engines/r/backup_interruption.result
      sql/backup/kernel.cc
      sql/si_objects.cc
      sql/si_objects.h
      sql/sql_base.cc
      sql/sql_delete.cc
=== modified file 'mysql-test/suite/backup/r/backup_external.result'
--- a/mysql-test/suite/backup/r/backup_external.result	2009-05-22 13:44:56 +0000
+++ b/mysql-test/suite/backup/r/backup_external.result	2009-11-16 19:20:34 +0000
@@ -184,6 +184,8 @@ Index_Comment	
 
 # Test 1: Use myisampack to compress the tables followed by myisamchk to 
 #         rebuild the indexes.
+# exec myisampack
+# exec myisamchk
 SHOW INDEX FROM db1.t1;;
 Table	t1
 Non_unique	1
@@ -203,9 +205,17 @@ BACKUP DATABASE db1 TO 'db1.bak';
 backup_id
 #
 DROP DATABASE db1;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'db1.bak';
 backup_id
 #
+Warnings:
+#	1036	Table 't1' is read only
+#	1213	Deadlock found when trying to get lock; try restarting transaction
 SHOW INDEX FROM db1.t1;;
 Table	t1
 Non_unique	1
@@ -233,6 +243,9 @@ id	name
 # Use myisampack utility again after restore. Verify that utilities
 # are not affected and functions properly after backup and restore 
 # operation.
+# exec myisamchk
+# exec myisampack
+# exec myisamchk
 SHOW INDEX FROM db1.t1;;
 Table	t1
 Non_unique	1
@@ -261,14 +274,24 @@ id	name
 # Bug#42572 - Restore fails when myisampack used with -b option
 #
 # Use myisampack -b option to make backup of table datafile
+# exec myisamchk
+# exec myisampack
+# exec myisamchk
 BACKUP DATABASE db1 TO 'db1b.bak';
 backup_id
 #
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'db1b.bak' OVERWRITE;
 backup_id
 #
 Warnings:
 #	#	Renamed directory with unknown files to 'db1-#'
+#	#	Table 't1' is read only
+#	#	Deadlock found when trying to get lock; try restarting transaction
 SHOW TABLES FROM db1;
 Tables_in_db1
 t1
@@ -318,9 +341,17 @@ backup_id
 #
 DROP DATABASE db1;
 DROP DATABASE db2;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'db12.bak';
 backup_id
 #
+Warnings:
+#	1036	Table 't1' is read only
+#	1213	Deadlock found when trying to get lock; try restarting transaction
 CHECKSUM TABLE db1.t1;
 Table	Checksum
 db1.t1	261218912
@@ -505,9 +536,17 @@ backup_id
 #
 DROP DATABASE db1;
 DROP DATABASE db2;
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'db12.bak';
 backup_id
 #
+Warnings:
+#	1036	Table 't1' is read only
+#	1213	Deadlock found when trying to get lock; try restarting transaction
 SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
 COUNT(*)
 128

=== modified file 'mysql-test/suite/backup/r/backup_intr_errors.result'
--- a/mysql-test/suite/backup/r/backup_intr_errors.result	2009-10-12 09:08:34 +0000
+++ b/mysql-test/suite/backup/r/backup_intr_errors.result	2009-11-16 19:20:34 +0000
@@ -112,6 +112,8 @@ SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
 Error	<error-code>	Can't shut down Snapshot restore driver(s)
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 Error	<error-code>	Backup/Restore: Error on close of backup stream
 #
@@ -238,6 +240,8 @@ SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
 Error	<error-code>	Can't shut down Default restore driver(s)
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 Error	<error-code>	Backup/Restore: Error on close of backup stream
 #

=== modified file 'mysql-test/suite/backup/r/backup_myisam.result'
--- a/mysql-test/suite/backup/r/backup_myisam.result	2009-02-13 12:40:13 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam.result	2009-11-16 19:20:34 +0000
@@ -15,12 +15,22 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 FLUSH TABLE mysql_db1.t1;
+# exec myisampack
+# exec myisamchk
 BACKUP DATABASE mysql_db1 to 'bup_myisam.bak';
 backup_id
-#
+###
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'bup_myisam.bak' OVERWRITE;
 backup_id
-#
+###
+Warnings:
+###	1036	Table 't1' is read only
+###	1213	Deadlock found when trying to get lock; try restarting transaction
 SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
 COUNT(*)
 128

=== modified file 'mysql-test/suite/backup/r/backup_myisam_coverage.result'
--- a/mysql-test/suite/backup/r/backup_myisam_coverage.result	2008-12-30 12:13:31 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_coverage.result	2009-11-16 19:20:34 +0000
@@ -12,13 +12,23 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 FLUSH TABLE mysql_db1.t1;
+# exec myisampack
+# exec myisamchk
 BACKUP DATABASE mysql_db1 to 'bup_myisam3.bak';
 backup_id
 #
 SET debug='d,Backup_restore_ctx_unlock_tables_alloc';
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
 RESTORE FROM 'bup_myisam3.bak' OVERWRITE;
 backup_id
 #
+Warnings:
+#	1036	Table 't1' is read only
+#	1213	Deadlock found when trying to get lock; try restarting transaction
 SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
 COUNT(*)
 128

=== 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-11-16 19:20:34 +0000
@@ -76,7 +76,57 @@ 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;
+# exec myisampack
+# exec myisamchk
+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
+# RESTORE of a compressed MyISAM table issues two warnings:
+# "Table is read only" and "Deadlock found when trying to get lock".
+# This results from an internal call of FLUSH TABLES.
+# RESTORE can't get back its write lock on the now compressed table.
+# But it doesn't need the locks any more at this moment. So it's ok.
+backup_id
+###
+Warnings:
+###	1036	Table 't1' is read only
+###	1213	Deadlock found when trying to get lock; try restarting transaction
+#
+# 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-11-16 19:20:34 +0000
@@ -0,0 +1,148 @@
+call mtr.add_suppression("Restore: Open and lock tables failed in RESTORE");
+#
+# Precautionary cleanup
+#
+SET DEBUG_SYNC= 'RESET';
+SET @old_sessiondebug=@@session.debug;
+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, retrieve RESTORE result.
+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, retrieve RESTORE result
+backup_id
+###
+SET DEBUG_SYNC= 'RESET';
+#
+# connection con1, retrieve INSERT result.
+#
+# connection con2, retrieve INSERT result.
+#
+# connection con3, retrieve INSERT result.
+#
+# connection con4, retrieve INSERT result.
+#
+# 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;
+#
+# WL#4844 - Implement a locking scheme for RESTORE
+# Code coverage tests.
+#
+SET DEBUG='+d,error_inject_truncate_enter';
+RESTORE FROM 'bup_reslock_db1.bak';
+ERROR HY000: Open and lock tables failed in RESTORE
+SET debug=@old_sessiondebug;
+DROP DATABASE bup_reslock_db1;
+SET DEBUG_SYNC='after_restore_truncate_tables SIGNAL sync WAIT_FOR go';
+RESTORE FROM 'bup_reslock_db1.bak';
+#
+# connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR sync';
+KILL QUERY ##;
+SET DEBUG_SYNC= 'now SIGNAL go';
+#
+# connection default, retrieve RESTORE result.
+ERROR 70100: Query execution was interrupted
+SET DEBUG_SYNC= 'RESET';
+DROP DATABASE bup_reslock_db1;

=== modified file 'mysql-test/suite/backup/t/backup_external.test'
--- a/mysql-test/suite/backup/t/backup_external.test	2009-05-22 13:44:56 +0000
+++ b/mysql-test/suite/backup/t/backup_external.test	2009-11-16 19:20:34 +0000
@@ -108,7 +108,9 @@ INSERT INTO db2.t2 VALUES
 # Myisamchk uses -s for silent mode, r for recovery and q for quick repair of
 # datafiles
 
+--echo # exec myisampack
 --exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
 --exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
 
 # Check the indexes in the table db1.t1
@@ -123,6 +125,11 @@ BACKUP DATABASE db1 TO 'db1.bak';
 DROP DATABASE db1;
 
 # Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
 --replace_column 1 #
 RESTORE FROM 'db1.bak';
 
@@ -137,8 +144,11 @@ SELECT * FROM db1.t1 LIMIT 4;
 --echo # are not affected and functions properly after backup and restore 
 --echo # operation.
 
+--echo # exec myisamchk
 --exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisampack
 --exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
 --exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
 
 # Check the indexes in the table db1.t1
@@ -154,8 +164,11 @@ SELECT * FROM db1.t1 LIMIT 4;
 --echo #
 --echo # Use myisampack -b option to make backup of table datafile
 
+--echo # exec myisamchk
 --exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisampack
 --exec $MYISAMPACK -s -b $MYSQLD_DATADIR/db1/t1.MYI
+--echo # exec myisamchk
 --exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
 
 # Execute backup operation
@@ -163,6 +176,11 @@ SELECT * FROM db1.t1 LIMIT 4;
 BACKUP DATABASE db1 TO 'db1b.bak';
 
 # Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
 # Mask UUID and path delimiter.
 --replace_regex /db1-[^']*/db1-#/ /'\.[\/\\]/'/
 # Mask backup_id and warning numbers.
@@ -220,6 +238,11 @@ DROP DATABASE db1;
 DROP DATABASE db2;
 
 # Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
 --replace_column 1 #
 RESTORE FROM 'db12.bak';
 
@@ -308,6 +331,11 @@ DROP DATABASE db1;
 DROP DATABASE db2;
 
 # Perform restore
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
 --replace_column 1 #
 RESTORE FROM 'db12.bak';
 

=== modified file 'mysql-test/suite/backup/t/backup_myisam.test'
--- a/mysql-test/suite/backup/t/backup_myisam.test	2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam.test	2009-11-16 19:20:34 +0000
@@ -32,12 +32,20 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 FLUSH TABLE mysql_db1.t1;
 #
+--echo # exec myisampack
 --exec $MYISAMPACK -s $MYSQLD_DATADIR/mysql_db1/t1
+--echo # exec myisamchk
 --exec $MYISAMCHK -srq $MYSQLD_DATADIR/mysql_db1/t1
 #
---replace_column 1 #
+--replace_column 1 ###
 BACKUP DATABASE mysql_db1 to 'bup_myisam.bak';
---replace_column 1 #
+#
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
+--replace_column 1 ###
 RESTORE FROM 'bup_myisam.bak' OVERWRITE;
 #
 SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;

=== modified file 'mysql-test/suite/backup/t/backup_myisam_coverage.test'
--- a/mysql-test/suite/backup/t/backup_myisam_coverage.test	2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_coverage.test	2009-11-16 19:20:34 +0000
@@ -33,7 +33,9 @@ INSERT INTO mysql_db1.t1 SELECT * FROM m
 INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
 FLUSH TABLE mysql_db1.t1;
 #
+--echo # exec myisampack
 --exec $MYISAMPACK -s $MYSQLD_DATADIR/mysql_db1/t1
+--echo # exec myisamchk
 --exec $MYISAMCHK -srq $MYSQLD_DATADIR/mysql_db1/t1
 #
 --replace_column 1 #
@@ -41,6 +43,11 @@ BACKUP DATABASE mysql_db1 to 'bup_myisam
 #
 # Inject error at Backup_restore_ctx_unlock_tables_alloc
 SET debug='d,Backup_restore_ctx_unlock_tables_alloc';
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
 --replace_column 1 #
 RESTORE FROM 'bup_myisam3.bak' OVERWRITE;
 #

=== 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-11-16 19:20:34 +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,77 @@ 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;
+#
+--echo # exec myisampack
+--exec $MYISAMPACK -s $MYSQLD_DATADIR/bup_myisam_sync_db1/t1
+--echo # exec myisamchk
+--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
+--echo # RESTORE of a compressed MyISAM table issues two warnings:
+--echo # "Table is read only" and "Deadlock found when trying to get lock".
+--echo # This results from an internal call of FLUSH TABLES.
+--echo # RESTORE can't get back its write lock on the now compressed table.
+--echo # But it doesn't need the locks any more at this moment. So it's ok.
+--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-11-16 19:20:34 +0000
@@ -0,0 +1,201 @@
+#
+# 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
+
+call mtr.add_suppression("Restore: Open and lock tables failed in RESTORE");
+
+--echo #
+--echo # Precautionary cleanup
+--echo #
+SET DEBUG_SYNC= 'RESET';
+SET @old_sessiondebug=@@session.debug;
+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, retrieve RESTORE result.
+--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, retrieve RESTORE result
+--connection default
+--replace_column 1 ###
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+    --echo #
+    --echo # connection con1, retrieve INSERT result.
+    --connection con1
+    reap;
+    --disconnect con1
+#
+      --echo #
+      --echo # connection con2, retrieve INSERT result.
+      --connection con2
+      reap;
+      --disconnect con2
+#
+        --echo #
+        --echo # connection con3, retrieve INSERT result.
+        --connection con3
+        reap;
+        --disconnect con3
+#
+          --echo #
+          --echo # connection con4, retrieve INSERT result.
+          --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;
+
+--echo #
+--echo # WL#4844 - Implement a locking scheme for RESTORE
+--echo # Code coverage tests.
+--echo #
+SET DEBUG='+d,error_inject_truncate_enter';
+--error ER_BACKUP_OPEN_TABLES
+RESTORE FROM 'bup_reslock_db1.bak';
+SET debug=@old_sessiondebug;
+DROP DATABASE bup_reslock_db1;
+#
+LET $ID=`SELECT CONNECTION_ID()`;
+SET DEBUG_SYNC='after_restore_truncate_tables SIGNAL sync WAIT_FOR go';
+send RESTORE FROM 'bup_reslock_db1.bak';
+#
+    --echo #
+    --echo # connection con1
+    --connect (con1, localhost, root,,)
+    SET DEBUG_SYNC= 'now WAIT_FOR sync';
+    --replace_regex /KILL QUERY [0-9]+/KILL QUERY ##/
+    eval KILL QUERY $ID;
+    SET DEBUG_SYNC= 'now SIGNAL go';
+    --disconnect con1
+#
+--echo #
+--echo # connection default, retrieve RESTORE result.
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+SET DEBUG_SYNC= 'RESET';
+#
+DROP DATABASE bup_reslock_db1;
+--remove_file $MYSQLD_BACKUPDIR/bup_reslock_db1.bak
+

=== modified file 'mysql-test/suite/backup_engines/r/backup_interruption.result'
--- a/mysql-test/suite/backup_engines/r/backup_interruption.result	2009-10-09 13:03:56 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_interruption.result	2009-11-16 19:20:34 +0000
@@ -1412,6 +1412,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1456,6 +1457,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1500,6 +1502,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1544,6 +1547,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1588,6 +1592,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1632,6 +1637,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.
@@ -1676,6 +1682,7 @@ ERROR 70100: Query execution was interru
 SHOW WARNINGS;
 Level	Code	Message
 Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Query execution was interrupted
 Warning	<error-code>	Operation aborted - data might be corrupted
 #
 # Examine backup logs.

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2009-10-23 15:41:56 +0000
+++ b/sql/backup/kernel.cc	2009-11-16 19:20:34 +0000
@@ -1097,14 +1097,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.
@@ -1121,10 +1133,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"));
 }
 
 
@@ -1139,26 +1156,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-10-23 21:26:11 +0000
+++ b/sql/si_objects.cc	2009-11-16 19:20:34 +0000
@@ -180,22 +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).
- 
-  @note This method will temporarily invoke additional privileges for 
-  all SELECT or SHOW CREATE statements.
+  Execute one SQL statement in a backup-specific context.
 
-  @param[in]  thd         Thread context.
-  @param[in]  query       SQL query to be executed.
-  @param[in]  get_warnings    If true, copy warnings to the error stack
-  @param[out] ed_connection   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
@@ -3340,6 +3336,150 @@ 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(), TRUE);
+  }
+  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(), TRUE);
+  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(), TRUE))
+    {
+      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(), TRUE))
+      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-11-16 19:20:34 +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-10-23 06:24:37 +0000
+++ b/sql/sql_base.cc	2009-11-16 19:20:34 +0000
@@ -1073,7 +1073,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

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2009-10-23 06:24:37 +0000
+++ b/sql/sql_delete.cc	2009-11-16 19:20:34 +0000
@@ -1129,6 +1129,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST
   Ha_global_schema_lock_guard global_schema_lock_guard(thd);
   DBUG_ENTER("mysql_truncate");
 
+  DBUG_EXECUTE_IF("error_inject_truncate_enter",
+                  my_error(ER_UNKNOWN_ERROR, MYF(0));
+                  DBUG_RETURN(TRUE););
+
   mysql_ha_rm_tables(thd, table_list);
 
   bzero((char*) &create_info,sizeof(create_info));


Attachment: [text/bzr-bundle] bzr/ingo.struewing@sun.com-20091116192034-edi1mvf8in5w4f1w.bundle
Thread
bzr commit into mysql-6.0-backup branch (ingo.struewing:2882)Bug#42895 WL#4844Ingo Struewing16 Nov