List:Commits« Previous MessageNext Message »
From:lars-erik.bjork Date:May 5 2009 6:59am
Subject:bzr commit into mysql-6.0-falcon-team branch (lars-erik.bjork:2697)
View as plain text  
#At file:///home/lb200670/mysql/43524/ based on revid:lars-erik.bjork@stripped

 2697 lars-erik.bjork@stripped	2009-05-05 [merge]
      Merging
      added:
        mysql-test/collections/backup.rqg-weekly
        mysql-test/collections/mysql-6.0-falcon.push
        mysql-test/include/have_rqg.inc
        mysql-test/mysql-test-lcov.pl
        mysql-test/r/plugin_notembedded.result
        mysql-test/suite/backup/include/backup_ext.inc
        mysql-test/suite/backup/include/have_dbi.inc
        mysql-test/suite/backup/r/backup_default_debug.result
        mysql-test/suite/backup/r/backup_external.result
        mysql-test/suite/backup/r/backup_external_non_win.result
        mysql-test/suite/backup/r/backup_intr_errors.result
        mysql-test/suite/backup/r/backup_namecase.result
        mysql-test/suite/backup/t/backup_default_debug.test
        mysql-test/suite/backup/t/backup_external.test
        mysql-test/suite/backup/t/backup_external_non_win.test
        mysql-test/suite/backup/t/backup_intr_errors.test
        mysql-test/suite/backup/t/backup_namecase-master.opt
        mysql-test/suite/backup/t/backup_namecase.test
        mysql-test/suite/backup_engines/include/backup_restore_interrupt.inc
        mysql-test/suite/backup_engines/r/backup_interruption.result
        mysql-test/suite/backup_engines/t/backup_interruption.test
        mysql-test/suite/backup_extra/
        mysql-test/suite/backup_extra/include/
        mysql-test/suite/backup_extra/r/
        mysql-test/suite/backup_extra/r/backup_consistency_falcon.result
        mysql-test/suite/backup_extra/r/backup_consistency_innodb.result
        mysql-test/suite/backup_extra/t/
        mysql-test/suite/backup_extra/t/backup_consistency.inc
        mysql-test/suite/backup_extra/t/backup_consistency_falcon.test
        mysql-test/suite/backup_extra/t/backup_consistency_innodb.test
        mysql-test/suite/falcon/r/falcon_bug_42752.result
        mysql-test/suite/falcon/t/falcon_bug_42752.test
        mysql-test/t/plugin_notembedded-master.opt
        mysql-test/t/plugin_notembedded.test
      modified:
        .bzrignore
        configure.in
        include/mysql/plugin.h.pp
        include/mysql/plugin_audit.h
        include/mysql/plugin_ftparser.h
        mysql-test/collections/mysql-6.0-falcon-.push
        mysql-test/include/locktrans.inc
        mysql-test/mysql-test-run.pl
        mysql-test/r/locktrans_innodb.result
        mysql-test/r/myisam_keycache_coverage.result
        mysql-test/suite/backup/include/bml_test.inc
        mysql-test/suite/backup/r/backup_bml.result
        mysql-test/suite/backup/r/backup_client.result
        mysql-test/suite/backup/r/backup_client_binlog.result
        mysql-test/suite/backup/r/backup_myisam_sync.result
        mysql-test/suite/backup/r/backup_triggers_and_events.result
        mysql-test/suite/backup/t/backup_bml.test
        mysql-test/suite/backup/t/backup_myisam_sync.test
        mysql-test/suite/backup/t/backup_triggers_and_events.test
        mysql-test/suite/backup/t/disabled.def
        mysql-test/suite/backup_engines/t/backup_partition.test
        mysql-test/suite/backup_engines/t/backup_partitioning.test
        mysql-test/suite/funcs_1/r/is_columns_mysql.result
        mysql-test/suite/funcs_1/r/is_tables_mysql.result
        mysql-test/suite/rpl/r/rpl_locktrans_innodb.result
        mysql-test/t/myisam_keycache_coverage.test
        mysql-test/t/plugin.test
        mysys/mf_keycache.c
        scripts/mysql_system_tables.sql
        scripts/mysql_system_tables_fix.sql
        sql/backup/backup_engine.h
        sql/backup/backup_kernel.h
        sql/backup/be_default.cc
        sql/backup/be_default.h
        sql/backup/be_snapshot.h
        sql/backup/be_thread.cc
        sql/backup/be_thread.h
        sql/backup/data_backup.cc
        sql/backup/image_info.cc
        sql/backup/kernel.cc
        sql/backup/logger.cc
        sql/backup/logger.h
        sql/backup/stream.cc
        sql/backup/stream.h
        sql/ha_ndbcluster.cc
        sql/log.cc
        sql/mysqld.cc
        sql/protocol.cc
        sql/set_var.cc
        sql/share/errmsg.txt
        sql/sql_audit.h
        sql/sql_parse.cc
        sql/sql_plugin.cc
        sql/sql_prepare.cc
        sql/sql_show.cc
        storage/falcon/CycleLock.cpp
        storage/falcon/CycleLock.h
        storage/falcon/CycleManager.cpp
        storage/falcon/CycleManager.h
        storage/falcon/RecordVersion.cpp
        storage/falcon/SerialLogWindow.cpp
        storage/falcon/StorageVersion.h
        storage/falcon/Table.cpp
        storage/falcon/Transaction.cpp
        storage/falcon/ha_falcon.cpp
        storage/myisam/mi_examine_log.c
        storage/myisam/myisamlog.c
        support-files/my-huge.cnf.sh
        support-files/my-innodb-heavy-4G.cnf.sh
        support-files/my-large.cnf.sh
        support-files/my-medium.cnf.sh
        support-files/my-small.cnf.sh

=== modified file '.bzrignore'
--- a/.bzrignore	2009-04-01 21:36:07 +0000
+++ b/.bzrignore	2009-04-03 17:58:04 +0000
@@ -2021,3 +2021,4 @@ libmysqld/sql_join_cache.cc
 storage/maria/maria_non_trans_log
 libmysqld/examples/mysqltest.cc
 libmysqld/bml.cc
+mysql-test/mysql-test-lcov

=== modified file 'configure.in'
--- a/configure.in	2009-04-03 15:14:49 +0000
+++ b/configure.in	2009-04-23 21:56:44 +0000
@@ -7,7 +7,7 @@ AC_PREREQ(2.59)
 # Remember to also update version.c in ndb.
 # When changing major version number please also check switch statement
 # in mysqlbinlog::check_master_version().
-AC_INIT([MySQL Server], [6.0.11-alpha], [], [mysql])
+AC_INIT([MySQL Server], [6.0.12-alpha], [], [mysql])
 AC_CONFIG_SRCDIR([sql/mysqld.cc])
 AC_CANONICAL_TARGET
 # automake 1.9.2 has 'filename-length-max=99', but not 1.6.2

=== modified file 'include/mysql/plugin.h.pp'
--- a/include/mysql/plugin.h.pp	2008-11-12 15:23:22 +0000
+++ b/include/mysql/plugin.h.pp	2009-04-14 12:42:21 +0000
@@ -49,6 +49,7 @@ struct st_mysql_plugin
   void * __reserved1;
 };
 #include "plugin_ftparser.h"
+#include "plugin.h"
 enum enum_ftparser_mode
 {
   MYSQL_FTPARSER_SIMPLE_MODE= 0,

=== modified file 'include/mysql/plugin_audit.h'
--- a/include/mysql/plugin_audit.h	2008-03-26 14:30:28 +0000
+++ b/include/mysql/plugin_audit.h	2009-04-07 20:19:26 +0000
@@ -24,8 +24,7 @@
 
 #define MYSQL_AUDIT_CLASS_MASK_SIZE 1
 
-#define MYSQL_AUDIT_INTERFACE_VERSION ( 0x010000 | MYSQL_AUDIT_CLASS_MASK_SIZE )
-
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0100
 
 /*
   The first word in every event class struct indicates the specific

=== modified file 'include/mysql/plugin_ftparser.h'
--- a/include/mysql/plugin_ftparser.h	2008-03-26 14:30:28 +0000
+++ b/include/mysql/plugin_ftparser.h	2009-04-14 12:42:21 +0000
@@ -15,6 +15,7 @@
 
 #ifndef _my_plugin_ftparser_h
 #define _my_plugin_ftparser_h
+#include "plugin.h"
 
 /*************************************************************************
   API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)

=== added file 'mysql-test/collections/backup.rqg-weekly'
--- a/mysql-test/collections/backup.rqg-weekly	1970-01-01 00:00:00 +0000
+++ b/mysql-test/collections/backup.rqg-weekly	2009-03-31 14:18:21 +0000
@@ -0,0 +1,2 @@
+perl mysql-test-run.pl --timer --force --suite=backup_extra backup_consistency_falcon
+perl mysql-test-run.pl --timer --force --suite=backup_extra backup_consistency_innodb

=== modified file 'mysql-test/collections/mysql-6.0-falcon-.push'
--- a/mysql-test/collections/mysql-6.0-falcon-.push	2009-03-31 12:45:26 +0000
+++ b/mysql-test/collections/mysql-6.0-falcon-.push	2009-04-28 08:13:50 +0000
@@ -1,8 +1,8 @@
-perl mysql-test-run.pl --timer --force --comment=n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=embedded --embedded --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=funcs_1 --suite=funcs_1 --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=ps_stm_threadpool --ps-protocol --mysqld=--binlog-format=statement --mysqld=--thread-handling=pool-of-threads --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=falcon --suite=falcon --experimental=collections/default.experimental
-perl mysql-test-run.pl --timer --force --comment=falcon_exp --suite=falcon_team --experimental=collections/falcon_team.experimental
+perl mysql-test-run.pl --comment=n_mix                            --mysqld=--binlog-format=mixed                                                --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=ps_row            --ps-protocol  --mysqld=--binlog-format=row                                                  --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=embedded          --embedded                                                                                   --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=rpl_binlog_row                   --mysqld=--binlog-format=row                                                  --suite=rpl,binlog                                                        --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=funcs_1                                                                                                        --suite=funcs_1                                                           --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=ps_stm_threadpool --ps-protocol  --mysqld=--binlog-format=statement --mysqld=--thread-handling=pool-of-threads --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=falcon                                                                                                         --suite=falcon                                                            --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=falcon_exp                                                                                                     --suite=falcon_team                                                                                                       --timer --force

=== added file 'mysql-test/collections/mysql-6.0-falcon.push'
--- a/mysql-test/collections/mysql-6.0-falcon.push	1970-01-01 00:00:00 +0000
+++ b/mysql-test/collections/mysql-6.0-falcon.push	2009-04-28 06:39:57 +0000
@@ -0,0 +1,7 @@
+perl mysql-test-run.pl --comment=n_mix                            --mysqld=--binlog-format=mixed                                                --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=ps_row            --ps-protocol  --mysqld=--binlog-format=row                                                  --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=embedded          --embedded                                                                                   --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=rpl_binlog_row                   --mysqld=--binlog-format=row                                                  --suite=rpl,binlog                                                        --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=funcs_1                                                                                                        --suite=funcs_1                                                           --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=ps_stm_threadpool --ps-protocol  --mysqld=--binlog-format=statement --mysqld=--thread-handling=pool-of-threads --suite=main,backup,backup_engines,backup_ptr,binlog,federated,rpl,maria  --experimental=collections/default.experimental --timer --force 
+perl mysql-test-run.pl --comment=falcon                                                                                                         --suite=falcon                                                            --experimental=collections/default.experimental --timer --force 

=== added file 'mysql-test/include/have_rqg.inc'
--- a/mysql-test/include/have_rqg.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/have_rqg.inc	2009-03-31 14:18:21 +0000
@@ -0,0 +1,14 @@
+--disable_query_log
+
+# Check that we have RQG setup
+
+if (`select '$RQG_HOME'=''`)
+{
+--skip Could not locate RQG - set RQG_HOME variable.
+}
+
+# setup $RQG variable
+
+let $RQG= perl $RQG_HOME/gensql.pl --seed=0;
+
+--enable_query_log

=== modified file 'mysql-test/include/locktrans.inc'
--- a/mysql-test/include/locktrans.inc	2009-03-06 22:17:00 +0000
+++ b/mysql-test/include/locktrans.inc	2009-04-03 17:58:04 +0000
@@ -629,7 +629,18 @@ UNLOCK TABLES;
     UNLOCK TABLES;
         --echo # connection conn2.
         connection conn2;
-        --echo # Now the READ lock is taken.
+        --echo # Now the READ lock is taken (or timed out).
+        #
+        # On some machines the read lock timed out due to high system load.
+        # The goal of this test is to prove that a pending WRITE lock
+        # takes precedence over a pending READ lock. If the test arrives
+        # here, the proof is achieved, even if the read lock timed out.
+        # If the READ lock would take precedence, it would be granted
+        # immediately. Since conn1's read lock is unlocked only, the
+        # WRITE lock request would time out on conn2's READ lock.
+        # Hence it is safe to ignore a timeout on conn2's READ lock here.
+        #
+        --error 0, ER_LOCK_WAIT_TIMEOUT
         reap;
         --echo # Select from the table.
         SELECT * FROM t1;
@@ -684,7 +695,18 @@ UNLOCK TABLES;
     UNLOCK TABLES;
         --echo # connection conn2.
         connection conn2;
-        --echo # Now the READ lock is taken.
+        --echo # Now the READ lock is taken (or timed out).
+        #
+        # On some machines the read lock timed out due to high system load.
+        # The goal of this test is to prove that a pending WRITE lock
+        # takes precedence over a pending READ lock. If the test arrives
+        # here, the proof is achieved, even if the read lock timed out.
+        # If the READ lock would take precedence, it would be granted
+        # immediately. Since conn1's read lock is unlocked only, the
+        # WRITE lock request would time out on conn2's READ lock.
+        # Hence it is safe to ignore a timeout on conn2's READ lock here.
+        #
+        --error 0, ER_LOCK_WAIT_TIMEOUT
         reap;
         --echo # Select from the table.
         SELECT * FROM t1;

=== added file 'mysql-test/mysql-test-lcov.pl'
--- a/mysql-test/mysql-test-lcov.pl	1970-01-01 00:00:00 +0000
+++ b/mysql-test/mysql-test-lcov.pl	2009-03-10 11:30:19 +0000
@@ -0,0 +1,209 @@
+#! /usr/bin/perl
+
+# Copyright (C) 2008 Sun Microsystems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#
+# Run lcov and genhtml to create a test coverage report.
+#
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+#
+# Constants.
+#
+# Directory for results. Intermediate files and HTML result.
+my $RESULT_DIR= "mysql-test/mysql-test-lcov";
+#
+# Files to ignore. E.g. files renamed after compilation.
+my @EXCLUDE_FILES= qw{
+storage/innobase/pars0grm
+storage/innobase/lexyy
+};
+
+#
+# Usage.
+#
+sub usage
+{
+  print <<"END";
+Usage: $0 [options]
+
+This program runs lcov for code coverage analysis, and genhtml to create
+an HTML report in $RESULT_DIR/index.html.
+
+Options:
+
+  -h    --help        This help.
+  -q    --quiet       Do not show commands run.
+  -p    --purge       Delete all test coverage information, to prepare for a
+                      new coverage test.
+
+Prior to running this tool, MySQL should be compiled with
+BUILD/compile-pentium-gcov, and the testsuite should be run.
+
+Also you need to install the lcov package, which contains the
+utilities lcov and genhtml.
+END
+
+  exit 1;
+}
+
+#
+# Get command line options.
+#
+my $opt_quiet;
+my $opt_help;
+my $opt_purge;
+my $result= GetOptions
+  (
+   "quiet"       => \$opt_quiet,
+   "help"        => \$opt_help,
+   "purge"       => \$opt_purge,
+  );
+
+usage() if $opt_help;
+
+#
+# Global variables.
+#
+my $cmd;
+my $res;
+
+#
+# Hide EXCLUDE_FILES
+#
+sub hide_exclude_files()
+{
+  print STDERR "Hiding excluded files\n" if !$opt_quiet;
+  foreach my $file ( @EXCLUDE_FILES )
+  {
+    unlink "$file.gcno.no-source";
+    rename "$file.gcno", "$file.gcno.no-source";
+    rename "$file.gcda", "$file.gcda.no-source";
+  }
+}
+
+#
+# Recover EXCLUDE_FILES
+#
+sub recover_exclude_files()
+{
+  print STDERR "Recovering excluded files\n" if !$opt_quiet;
+  foreach my $file ( @EXCLUDE_FILES )
+  {
+    rename "$file.gcno.no-source", "$file.gcno";
+    rename "$file.gcda.no-source", "$file.gcda";
+  }
+}
+
+#
+# In verbose mode we output to STDERR as well as to STDOUT.
+# Avoid misplaced output due to buffering.
+#
+if (!$opt_quiet)
+{
+  select STDERR; $| = 1;      # make unbuffered
+  select STDOUT; $| = 1;      # make unbuffered
+}
+
+#
+# We need to change to the root directory of the source tree
+# so that we find all sources, object files, and gcov files from ".".
+#
+my $troot= `bzr root`;
+chomp $troot;
+if (!$troot || !chdir $troot)
+{
+  die "Failed to find tree root. " .
+      "(this tool must be run within a bzr work tree).\n";
+}
+
+#
+# Purge counters from old test runs.
+#
+if($opt_purge)
+{
+  # One cannot create a file with empty name. But empty argument with -f
+  # makes 'rm' silent when there is no file to remove.
+  $cmd= "find . -name '*.da' -o -name '*.gcda' -o -name '*.gcov' |
+         grep -v 'README\.gcov' |
+         xargs rm -f ''";
+  print STDERR "Running: $cmd\n" if !$opt_quiet;
+  $res= system($cmd);
+  exit($res ? ($? >> 8) : 0);
+}
+
+#
+# Create result directory.
+#
+if (-d $RESULT_DIR)
+{
+  print STDERR "Recreating result directory: $RESULT_DIR\n" if !$opt_quiet;
+  $res= system("rm -rf $RESULT_DIR");
+  if ($res)
+  {
+    exit($res ? ($? >> 8) : 0);
+  }
+}
+else
+{
+  print STDERR "Creating result directory: $RESULT_DIR\n" if !$opt_quiet;
+}
+$res= system("mkdir $RESULT_DIR");
+if ($res)
+{
+  exit($res ? ($? >> 8) : 0);
+}
+
+#
+# Hide EXCLUDE_FILES
+#
+hide_exclude_files();
+
+#
+# LCOV
+#
+$cmd= "lcov -q -c -f -d . -o $RESULT_DIR/lcov.info";
+print STDERR "Running: $cmd\n" if !$opt_quiet;
+$res= system($cmd);
+if ($res)
+{
+  recover_exclude_files();
+  exit($res ? ($? >> 8) : 0);
+}
+
+#
+# GENHTML
+#
+$cmd= "genhtml -q --prefix=`pwd` -o $RESULT_DIR " .
+               "$RESULT_DIR/lcov.info";
+print STDERR "Running: $cmd\n" if !$opt_quiet;
+$res= system($cmd);
+if ($res)
+{
+  recover_exclude_files();
+  exit($res ? ($? >> 8) : 0);
+}
+
+#
+# Recover EXCLUDE_FILES
+#
+recover_exclude_files();
+
+print "Result is in $RESULT_DIR/index.html\n";
+

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2009-04-15 23:38:47 +0000
+++ b/mysql-test/mysql-test-run.pl	2009-04-22 22:12:25 +0000
@@ -5195,7 +5195,7 @@ sub list_options ($) {
   my $hash= shift;
 
   for (keys %$hash) {
-    s/(=.*|!)$//;
+    s/(=.*|[+!])$//;
     s/\|/\n--/g;
     print "--$_\n";
   }

=== modified file 'mysql-test/r/locktrans_innodb.result'
--- a/mysql-test/r/locktrans_innodb.result	2009-03-27 22:06:26 +0000
+++ b/mysql-test/r/locktrans_innodb.result	2009-04-03 17:58:04 +0000
@@ -559,7 +559,7 @@ INSERT INTO t1 VALUES(1111);
 # Unlock table.
 UNLOCK TABLES;
 # connection conn2.
-# Now the READ lock is taken.
+# Now the READ lock is taken (or timed out).
 # Select from the table.
 SELECT * FROM t1;
 c1
@@ -598,7 +598,7 @@ INSERT INTO t1 VALUES(1111);
 # Unlock table.
 UNLOCK TABLES;
 # connection conn2.
-# Now the READ lock is taken.
+# Now the READ lock is taken (or timed out).
 # Select from the table.
 SELECT * FROM t1;
 c1

=== modified file 'mysql-test/r/myisam_keycache_coverage.result'
--- a/mysql-test/r/myisam_keycache_coverage.result	2009-03-06 11:24:26 +0000
+++ b/mysql-test/r/myisam_keycache_coverage.result	2009-04-14 13:40:06 +0000
@@ -11,7 +11,7 @@ INSERT INTO t1 SELECT * FROM t1;
 #
 # Positive tests.
 #
-SELECT COUNT(*) FROM t1 WHERE c2 < 5;
+SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 COUNT(*)
 8
 LOAD INDEX INTO CACHE t1;
@@ -25,31 +25,30 @@ FLUSH TABLE t1;
 #
 # Inject error key_cache_read_block_error
 #
-EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 < 5;
-id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	index	NULL	i1	13	NULL	8	Using where; Using index
-SET debug='d,key_cache_read_block_error';
+SET debug='+d,key_cache_read_block_error';
 SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 ERROR HY000: Incorrect key file for table 't1.MYI'; try to repair it
+# Reset debug variable to its original value.
 FLUSH TABLE t1;
 #
 # Inject error key_cache_insert_block_error
 #
-SET debug='d,key_cache_insert_block_error';
+SET debug='+d,key_cache_insert_block_error';
 LOAD INDEX INTO CACHE t1;
 Table	Op	Msg_type	Msg_text
 test.t1	preload_keys	error	Failed to read from index file (errno: 5)
 test.t1	preload_keys	status	Operation failed
+# Reset debug variable to its original value.
 FLUSH TABLE t1;
 #
 # Inject error key_cache_write_block_error
 #
-SET debug='d,key_cache_write_block_error';
+SET debug='+d,key_cache_write_block_error';
 UPDATE t1 SET c2=1;
 ERROR HY000: Incorrect key file for table 't1.MYI'; try to repair it
+# Reset debug variable to its original value.
 FLUSH TABLE t1;
 #
 # Cleanup
 #
-SET debug='';
 DROP TABLE t1;

=== added file 'mysql-test/r/plugin_notembedded.result'
--- a/mysql-test/r/plugin_notembedded.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/plugin_notembedded.result	2009-04-16 15:17:31 +0000
@@ -0,0 +1,15 @@
+SELECT @@global.example_enum_var = 'e2';
+ERROR HY000: Unknown system variable 'example_enum_var'
+INSTALL PLUGIN example SONAME 'ha_example.so';
+SELECT @@global.example_enum_var = 'e2';
+@@global.example_enum_var = 'e2'
+0
+#
+# Bug#44137: Transactional DDL locking broke dynamic plugins
+#
+# Try to restart the server - plugin should be loaded after restart
+#
+SELECT @@global.example_enum_var = 'e2';
+@@global.example_enum_var = 'e2'
+0
+UNINSTALL PLUGIN example;

=== added file 'mysql-test/suite/backup/include/backup_ext.inc'
--- a/mysql-test/suite/backup/include/backup_ext.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/include/backup_ext.inc	2009-03-25 22:17:35 +0000
@@ -0,0 +1,30 @@
+
+# The external program "mysql_convert_table_format" is not incorporated with
+# mtr framework. Therefore, in order to use this program in a portable way, 
+# we have created the following script.
+# The following script will find path to mysql_convert_table_format utility
+# in a portable way and without modifying mtr.pl
+
+--perl
+use strict;
+use lib "lib/";
+
+use IO::File;
+use File::Basename;
+use My::Find;
+
+my $basedir= dirname($ENV{MYSQL_TEST_DIR}) or die "Need \$MYSQL_TEST_DIR";
+my $vardir= $ENV{MYSQLTEST_VARDIR} or die  "Need \$MYSQLTEST_VARDIR";
+
+my $location= my_find_bin($basedir,
+			["scripts"],
+		        "mysql_convert_table_format",
+			NOT_REQUIRED);
+
+# In the actual test, source $MYSQLTEST_VARDIR/tmp/mctf.inc and this will get
+# $MYSQL_CONVERT_TABLE_FORMAT set to point to the correct location and ready to # be used.
+
+my $F = IO::File->new("$vardir/tmp/mctf.inc", "w") or die;
+print $F "let \$MYSQL_CONVERT_TABLE_FORMAT = $location;";
+
+EOF

=== modified file 'mysql-test/suite/backup/include/bml_test.inc'
--- a/mysql-test/suite/backup/include/bml_test.inc	2009-03-10 16:18:25 +0000
+++ b/mysql-test/suite/backup/include/bml_test.inc	2009-03-23 18:46:10 +0000
@@ -183,11 +183,17 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 --echo # DDL3= $DDL3
 --echo # DDL4= $DDL4
 --echo #
-eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-  WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "$DDL1%"
-     OR info LIKE "$DDL2%";
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+#  WHERE info LIKE "BACKUP DATABASE%"
+#     OR info LIKE "RESTORE FROM%"
+#     OR info LIKE "$DDL1%"
+#     OR info LIKE "$DDL2%";
 --echo # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 --echo # Checking that DDL1 and DDL2 have not executed.
@@ -219,9 +225,15 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 --echo # DDL3= $DDL3
 --echo # DDL4= $DDL4
 --echo #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-  WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+#  WHERE info LIKE "BACKUP DATABASE%"
+#     OR info LIKE "RESTORE FROM%";
 --echo # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 --echo ==================
@@ -261,9 +273,15 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 --echo # DDL3= $DDL3
 --echo # DDL4= $DDL4
 --echo #
-eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-  WHERE info LIKE "$DDL3%"
-     OR info LIKE "$DDL4%";
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+#  WHERE info LIKE "$DDL3%"
+#     OR info LIKE "$DDL4%";
 --echo # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 --echo ==================

=== added file 'mysql-test/suite/backup/include/have_dbi.inc'
--- a/mysql-test/suite/backup/include/have_dbi.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/include/have_dbi.inc	2009-04-07 19:18:19 +0000
@@ -0,0 +1,29 @@
+# This script is written in order to skip the test if perl DBI modules are not
+# installed in the system
+
+disable_query_log;
+let $suffix= `SELECT UUID()`;
+enable_query_log;
+
+let $dbi_exists_file= $MYSQLTEST_VARDIR/tmp/dbi_exists.$suffix;
+let TMP_FILE= $dbi_exists_file;
+
+perl;
+my $success= 1;
+my $file= $ENV{'TMP_FILE'};
+eval "require DBI";
+eval "require DBD::mysql";
+if ($@)
+{
+  $success= 0;
+}
+open FH, "> $file";
+print FH "let \$dbi_exists= $success;";
+close FH; 
+EOF
+
+source $dbi_exists_file;
+remove_file $dbi_exists_file;
+if(!$dbi_exists) { 
+  skip DBI & DBD modules not installed.;  
+}

=== modified file 'mysql-test/suite/backup/r/backup_bml.result'
--- a/mysql-test/suite/backup/r/backup_bml.result	2009-03-10 16:18:25 +0000
+++ b/mysql-test/suite/backup/r/backup_bml.result	2009-03-23 18:46:10 +0000
@@ -172,15 +172,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= DROP DATABASE bml_test_db1
 # DDL4= CREATE TABLE t1(a int)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "CREATE VIEW v1 AS SELECT * FROM t2%"
-     OR info LIKE "DROP FUNCTION f1%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	DROP FUNCTION f1
-debug sync point: before_execute_sql_command	CREATE VIEW v1 AS SELECT * FROM t2
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -218,11 +209,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= DROP DATABASE bml_test_db1
 # DDL4= CREATE TABLE t1(a int)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database (bml%)
@@ -263,12 +249,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= DROP DATABASE bml_test_db1
 # DDL4= CREATE TABLE t1(a int)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "DROP DATABASE bml_test_db1%"
-     OR info LIKE "CREATE TABLE t1(a int)%";
-state	info
-BML: waiting until released	CREATE TABLE t1(a int)
-BML: waiting until released	DROP DATABASE bml_test_db1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database (bml%)
@@ -407,15 +387,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= DROP VIEW v1
 # DDL4= CREATE FUNCTION f1() RETURNS int RETURN 1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "CREATE DATABASE bml_test_db1%"
-     OR info LIKE "DROP TABLE t1%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	DROP TABLE t1
-debug sync point: before_execute_sql_command	CREATE DATABASE bml_test_db1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -453,11 +424,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= DROP VIEW v1
 # DDL4= CREATE FUNCTION f1() RETURNS int RETURN 1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database (bml%)
@@ -498,12 +464,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= DROP VIEW v1
 # DDL4= CREATE FUNCTION f1() RETURNS int RETURN 1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "DROP VIEW v1%"
-     OR info LIKE "CREATE FUNCTION f1() RETURNS int RETURN 1%";
-state	info
-BML: waiting until released	CREATE FUNCTION f1() RETURNS int RETURN 1
-BML: waiting until released	DROP VIEW v1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database (bml%)
@@ -644,15 +604,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= DROP PROCEDURE p1
 # DDL4= CREATE EVENT e1 ON SCHEDULE EVERY 1 YEAR DISABLE DO SET @foo=1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW SET @foo=1%"
-     OR info LIKE "DROP INDEX i1 ON t2%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	DROP INDEX i1 ON t2
-debug sync point: before_execute_sql_command	CREATE TRIGGER r1 AFTER UPDATE ON t2 FOR EACH ROW SET @foo=1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -689,11 +640,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= DROP PROCEDURE p1
 # DDL4= CREATE EVENT e1 ON SCHEDULE EVERY 1 YEAR DISABLE DO SET @foo=1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database (bml%)
@@ -733,12 +679,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= DROP PROCEDURE p1
 # DDL4= CREATE EVENT e1 ON SCHEDULE EVERY 1 YEAR DISABLE DO SET @foo=1
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "DROP PROCEDURE p1%"
-     OR info LIKE "CREATE EVENT e1 ON SCHEDULE EVERY 1 YEAR DISABLE DO SET @foo=1%";
-state	info
-BML: waiting until released	CREATE EVENT e1 ON SCHEDULE EVERY 1 YEAR DISABLE DO SET @foo=1
-BML: waiting until released	DROP PROCEDURE p1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database (bml%)
@@ -874,15 +814,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= DROP TRIGGER r1
 # DDL4= CREATE INDEX i1 ON t2(b)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "CREATE PROCEDURE p1() SET @foo=1%"
-     OR info LIKE "DROP EVENT e1%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	DROP EVENT e1
-debug sync point: before_execute_sql_command	CREATE PROCEDURE p1() SET @foo=1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -919,11 +850,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= DROP TRIGGER r1
 # DDL4= CREATE INDEX i1 ON t2(b)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database (bml%)
@@ -963,12 +889,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= DROP TRIGGER r1
 # DDL4= CREATE INDEX i1 ON t2(b)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "DROP TRIGGER r1%"
-     OR info LIKE "CREATE INDEX i1 ON t2(b)%";
-state	info
-BML: waiting until released	CREATE INDEX i1 ON t2(b)
-BML: waiting until released	DROP TRIGGER r1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database (bml%)
@@ -1147,15 +1067,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "ALTER DATABASE bml_test_db1 CHARACTER SET = utf8%"
-     OR info LIKE "ALTER TABLE t1 ADD INDEX `i` (a)%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	ALTER TABLE t1 ADD INDEX `i` (a)
-debug sync point: before_execute_sql_command	ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -1195,11 +1106,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database	Create Database
@@ -1243,12 +1149,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "ALTER VIEW v1 AS SELECT 1%"
-     OR info LIKE "ALTER FUNCTION f1 COMMENT 'testing alter'%";
-state	info
-BML: waiting until released	ALTER FUNCTION f1 COMMENT 'testing alter'
-BML: waiting until released	ALTER VIEW v1 AS SELECT 1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database	Create Database
@@ -1399,15 +1299,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= ALTER PROCEDURE p1 COMMENT 'testing alter'
 # DDL4= ALTER EVENT e1 RENAME TO e2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "ALTER VIEW v1 AS SELECT 1%"
-     OR info LIKE "ALTER FUNCTION f1 COMMENT 'testing alter'%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	ALTER FUNCTION f1 COMMENT 'testing alter'
-debug sync point: before_execute_sql_command	ALTER VIEW v1 AS SELECT 1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -1447,11 +1338,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= ALTER PROCEDURE p1 COMMENT 'testing alter'
 # DDL4= ALTER EVENT e1 RENAME TO e2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database	Create Database
@@ -1495,12 +1381,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= ALTER PROCEDURE p1 COMMENT 'testing alter'
 # DDL4= ALTER EVENT e1 RENAME TO e2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "ALTER PROCEDURE p1 COMMENT 'testing alter'%"
-     OR info LIKE "ALTER EVENT e1 RENAME TO e2%";
-state	info
-BML: waiting until released	ALTER EVENT e1 RENAME TO e2
-BML: waiting until released	ALTER PROCEDURE p1 COMMENT 'testing alter'
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database	Create Database
@@ -1651,15 +1531,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # DDL4= ALTER TABLE t1 ADD INDEX `i` (a)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "ALTER PROCEDURE p1 COMMENT 'testing alter'%"
-     OR info LIKE "ALTER EVENT e1 RENAME TO e2%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	ALTER EVENT e1 RENAME TO e2
-debug sync point: before_execute_sql_command	ALTER PROCEDURE p1 COMMENT 'testing alter'
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -1699,11 +1570,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # DDL4= ALTER TABLE t1 ADD INDEX `i` (a)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database	Create Database
@@ -1747,12 +1613,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # DDL4= ALTER TABLE t1 ADD INDEX `i` (a)
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "ALTER DATABASE bml_test_db1 CHARACTER SET = utf8%"
-     OR info LIKE "ALTER TABLE t1 ADD INDEX `i` (a)%";
-state	info
-BML: waiting until released	ALTER TABLE t1 ADD INDEX `i` (a)
-BML: waiting until released	ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database	Create Database
@@ -1903,15 +1763,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "ALTER DATABASE bml_test_db1 CHARACTER SET = utf8%"
-     OR info LIKE "ALTER TABLE t1 ADD INDEX `i` (a)%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	ALTER TABLE t1 ADD INDEX `i` (a)
-debug sync point: before_execute_sql_command	ALTER DATABASE bml_test_db1 CHARACTER SET = utf8
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -1951,11 +1802,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Database	Create Database
@@ -1999,12 +1845,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= ALTER VIEW v1 AS SELECT 1
 # DDL4= ALTER FUNCTION f1 COMMENT 'testing alter'
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "ALTER VIEW v1 AS SELECT 1%"
-     OR info LIKE "ALTER FUNCTION f1 COMMENT 'testing alter'%";
-state	info
-BML: waiting until released	ALTER FUNCTION f1 COMMENT 'testing alter'
-BML: waiting until released	ALTER VIEW v1 AS SELECT 1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Database	Create Database
@@ -2181,15 +2021,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= RENAME USER bml_u2 TO bml_u2_renamed
 # DDL4= DROP TABLESPACE bml_ts1 ENGINE=falcon
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "RENAME TABLE t1 TO t1_renamed%"
-     OR info LIKE "DROP USER bml_u1%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	DROP USER bml_u1
-debug sync point: before_execute_sql_command	RENAME TABLE t1 TO t1_renamed
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -2224,11 +2055,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= RENAME USER bml_u2 TO bml_u2_renamed
 # DDL4= DROP TABLESPACE bml_ts1 ENGINE=falcon
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2265,12 +2091,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= RENAME USER bml_u2 TO bml_u2_renamed
 # DDL4= DROP TABLESPACE bml_ts1 ENGINE=falcon
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "RENAME USER bml_u2 TO bml_u2_renamed%"
-     OR info LIKE "DROP TABLESPACE bml_ts1 ENGINE=falcon%";
-state	info
-BML: waiting until released	DROP TABLESPACE bml_ts1 ENGINE=falcon
-BML: waiting until released	RENAME USER bml_u2 TO bml_u2_renamed
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2395,15 +2215,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= RENAME TABLE t1_renamed TO t1
 # DDL4= GRANT ALL ON bml_test.* TO bml_u2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "RENAME USER bml_u2_renamed TO bml_u2%"
-     OR info LIKE "GRANT ALL ON bml_test.* TO bml_u3%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	GRANT ALL ON bml_test.* TO bml_u3
-debug sync point: before_execute_sql_command	RENAME USER bml_u2_renamed TO bml_u2
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -2436,11 +2247,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= RENAME TABLE t1_renamed TO t1
 # DDL4= GRANT ALL ON bml_test.* TO bml_u2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2477,12 +2283,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= RENAME TABLE t1_renamed TO t1
 # DDL4= GRANT ALL ON bml_test.* TO bml_u2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "RENAME TABLE t1_renamed TO t1%"
-     OR info LIKE "GRANT ALL ON bml_test.* TO bml_u2%";
-state	info
-BML: waiting until released	GRANT ALL ON bml_test.* TO bml_u2
-BML: waiting until released	RENAME TABLE t1_renamed TO t1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2611,15 +2411,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= DROP USER bml_u2
 # DDL4= REVOKE ALL ON bml_test.* FROM bml_u3
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "DROP TABLESPACE bml_ts2 ENGINE=falcon%"
-     OR info LIKE "REVOKE ALL ON bml_test.* FROM bml_u2%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	REVOKE ALL ON bml_test.* FROM bml_u2
-debug sync point: before_execute_sql_command	DROP TABLESPACE bml_ts2 ENGINE=falcon
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -2654,11 +2445,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= DROP USER bml_u2
 # DDL4= REVOKE ALL ON bml_test.* FROM bml_u3
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2694,12 +2480,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= DROP USER bml_u2
 # DDL4= REVOKE ALL ON bml_test.* FROM bml_u3
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "DROP USER bml_u2%"
-     OR info LIKE "REVOKE ALL ON bml_test.* FROM bml_u3%";
-state	info
-BML: waiting until released	REVOKE ALL ON bml_test.* FROM bml_u3
-BML: waiting until released	DROP USER bml_u2
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2845,15 +2625,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= TRUNCATE TABLE t1
 # DDL4= TRUNCATE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "OPTIMIZE TABLE t1%"
-     OR info LIKE "REPAIR TABLE t2 USE_FRM%";
-state	info
-BML: waiting for all statements to leave	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	REPAIR TABLE t2 USE_FRM
-debug sync point: before_execute_sql_command	OPTIMIZE TABLE t1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -2892,11 +2663,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= TRUNCATE TABLE t1
 # DDL4= TRUNCATE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: before_backup_meta	BACKUP DATABASE bml_test TO 'bml_test.bkp'
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -2933,12 +2699,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= TRUNCATE TABLE t1
 # DDL4= TRUNCATE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "TRUNCATE TABLE t1%"
-     OR info LIKE "TRUNCATE TABLE t2%";
-state	info
-BML: waiting until released	TRUNCATE TABLE t2
-BML: waiting until released	TRUNCATE TABLE t1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -3067,15 +2827,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR bup_waitin
 # DDL3= REPAIR TABLE t1
 # DDL4= OPTIMIZE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%"
-     OR info LIKE "TRUNCATE t1%"
-     OR info LIKE "TRUNCATE t2%";
-state	info
-BML: waiting for all statements to leave	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	TRUNCATE t2
-debug sync point: before_execute_sql_command	TRUNCATE t1
 # Checking that BACKUP is blocked by DDLs.
 SELECT object, notes, error_num FROM mysql.backup_progress WHERE backup_id=500;
 object	notes	error_num
@@ -3109,11 +2860,6 @@ SET DEBUG_SYNC= 'now SIGNAL continue_bup
 # DDL3= REPAIR TABLE t1
 # DDL4= OPTIMIZE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "RESTORE FROM%";
-state	info
-debug sync point: start_do_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
 # Checking that DDL1 and DDL2 have executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -3150,12 +2896,6 @@ SET DEBUG_SYNC= 'now WAIT_FOR ddl4_block
 # DDL3= REPAIR TABLE t1
 # DDL4= OPTIMIZE TABLE t2
 #
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "REPAIR TABLE t1%"
-     OR info LIKE "OPTIMIZE TABLE t2%";
-state	info
-BML: waiting until released	OPTIMIZE TABLE t2
-BML: waiting until released	REPAIR TABLE t1
 # Checking that DDL3 and DDL4 have not executed.
 CALL test.check_results();
 Tables_in_bml_test
@@ -3237,13 +2977,6 @@ SET SESSION debug="+d,set_backup_id";
 BACKUP DATABASE bml_test TO 'bml_test.bkp';;
 # Waiting for BACKUP to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_started TIMEOUT 3';
-# Check the state of both statements.
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "CREATE USER%";
-state	info
-debug sync point: after_backup_start_backup	BACKUP DATABASE bml_test TO 'bml_test.bkp'
-debug sync point: before_execute_sql_command	CREATE USER bml_usr
 # Checking that CREATE USER has not executed yet.
 SELECT User, Password FROM mysql.user WHERE User like 'bml%';
 User	Password
@@ -3299,13 +3032,6 @@ SET SESSION debug="+d,set_backup_id";
 RESTORE FROM 'bml_test.bkp' OVERWRITE;;
 # Waiting for RESTORE to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_started TIMEOUT 3';
-# Check the state of both statements.
-SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE info LIKE "RESTORE FROM%"
-     OR info LIKE "DROP SERVER%";
-state	info
-debug sync point: after_backup_start_restore	RESTORE FROM 'bml_test.bkp' OVERWRITE
-debug sync point: before_execute_sql_command	DROP SERVER bml_srv
 # Checking that DROP SERVER has not executed yet.
 SELECT Server_name FROM mysql.servers WHERE Server_name like 'bml%';
 Server_name

=== modified file 'mysql-test/suite/backup/r/backup_client.result'
--- a/mysql-test/suite/backup/r/backup_client.result	2009-03-28 08:42:55 +0000
+++ b/mysql-test/suite/backup/r/backup_client.result	2009-04-15 20:25:14 +0000
@@ -3426,19 +3426,19 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  3
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest2'.'t3'
   Snapshot 0 table   'mysqltest3'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  3
   Snapshot 1 table   'mysqltest1'.'t2'
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest3'.'t3'
   Snapshot 2 type    logical from locked tables
   Snapshot 2 version 1
-  Snapshot 2 tables  1
+  Snapshot 2 tables  3
   Snapshot 2 table   'mysqltest1'.'t3'
   Snapshot 2 table   'mysqltest2'.'t2'
   Snapshot 2 table   'mysqltest3'.'t1'
@@ -3462,19 +3462,19 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  3
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest2'.'t3'
   Snapshot 0 table   'mysqltest3'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  3
   Snapshot 1 table   'mysqltest1'.'t2'
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest3'.'t3'
   Snapshot 2 type    logical from locked tables
   Snapshot 2 version 1
-  Snapshot 2 tables  1
+  Snapshot 2 tables  3
   Snapshot 2 table   'mysqltest1'.'t3'
   Snapshot 2 table   'mysqltest2'.'t2'
   Snapshot 2 table   'mysqltest3'.'t1'
@@ -3710,19 +3710,19 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  3
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest2'.'t3'
   Snapshot 0 table   'mysqltest3'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  3
   Snapshot 1 table   'mysqltest1'.'t2'
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest3'.'t3'
   Snapshot 2 type    logical from locked tables
   Snapshot 2 version 1
-  Snapshot 2 tables  1
+  Snapshot 2 tables  3
   Snapshot 2 table   'mysqltest1'.'t3'
   Snapshot 2 table   'mysqltest2'.'t2'
   Snapshot 2 table   'mysqltest3'.'t1'
@@ -3945,19 +3945,19 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  3
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest2'.'t3'
   Snapshot 0 table   'mysqltest3'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  3
   Snapshot 1 table   'mysqltest1'.'t2'
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest3'.'t3'
   Snapshot 2 type    logical from locked tables
   Snapshot 2 version 1
-  Snapshot 2 tables  1
+  Snapshot 2 tables  3
   Snapshot 2 table   'mysqltest1'.'t3'
   Snapshot 2 table   'mysqltest2'.'t2'
   Snapshot 2 table   'mysqltest3'.'t1'
@@ -4340,19 +4340,19 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  3
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest2'.'t3'
   Snapshot 0 table   'mysqltest3'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  3
   Snapshot 1 table   'mysqltest1'.'t2'
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest3'.'t3'
   Snapshot 2 type    logical from locked tables
   Snapshot 2 version 1
-  Snapshot 2 tables  1
+  Snapshot 2 tables  3
   Snapshot 2 table   'mysqltest1'.'t3'
   Snapshot 2 table   'mysqltest2'.'t2'
   Snapshot 2 table   'mysqltest3'.'t1'
@@ -5334,12 +5334,12 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  2
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest1'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  2
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest2'.'t2'
 

=== modified file 'mysql-test/suite/backup/r/backup_client_binlog.result'
--- a/mysql-test/suite/backup/r/backup_client_binlog.result	2009-04-02 13:14:17 +0000
+++ b/mysql-test/suite/backup/r/backup_client_binlog.result	2009-04-15 20:25:14 +0000
@@ -41,12 +41,12 @@ Snapshots:
 
   Snapshot 0 type    native from 'MyISAM'  version 1.0
   Snapshot 0 version 1
-  Snapshot 0 tables  1
+  Snapshot 0 tables  2
   Snapshot 0 table   'mysqltest1'.'t1'
   Snapshot 0 table   'mysqltest1'.'t2'
   Snapshot 1 type    logical from consistent snapshot
   Snapshot 1 version 1
-  Snapshot 1 tables  1
+  Snapshot 1 tables  2
   Snapshot 1 table   'mysqltest2'.'t1'
   Snapshot 1 table   'mysqltest2'.'t2'
 

=== added file 'mysql-test/suite/backup/r/backup_default_debug.result'
--- a/mysql-test/suite/backup/r/backup_default_debug.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_default_debug.result	2009-03-25 13:21:35 +0000
@@ -0,0 +1,19 @@
+DROP DATABASE IF EXISTS mysql_db1;
+#
+# Bug#41722 - Restore crashes with backup of Falcon tables
+#
+CREATE DATABASE mysql_db1;
+CREATE TABLE mysql_db1.t1 (c1 TEXT) ENGINE=Falcon;
+INSERT INTO mysql_db1.t1 VALUES('fdafdsfdsfdsfdsfdsfd');
+BACKUP DATABASE mysql_db1 TO 'mysqltest.bak';
+backup_id
+#
+DROP DATABASE mysql_db1;
+#
+# Inject error Restore__send_data_write_error
+#
+SET debug='d,Restore__send_data_write_error';
+RESTORE FROM 'mysqltest.bak';
+ERROR HY000: Error when sending data (for table #1) to Snapshot restore driver
+SET debug= '';
+DROP DATABASE mysql_db1;

=== added file 'mysql-test/suite/backup/r/backup_external.result'
--- a/mysql-test/suite/backup/r/backup_external.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_external.result	2009-03-25 22:17:35 +0000
@@ -0,0 +1,703 @@
+# Drop databases if they are already existing
+#
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+#
+# Create databases and tables
+#
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+CREATE TABLE db1.t1(
+id INT,
+name VARCHAR(30),
+INDEX idx(name(10))
+);
+CREATE TABLE db2.t1(
+id INT UNSIGNED NOT NULL,
+details TEXT,
+methods VARCHAR(40),
+FULLTEXT(details, methods)
+);
+CREATE TABLE db2.t2(
+a CHAR(100) UNIQUE,
+b TEXT,
+FULLTEXT(b)
+);
+CREATE TABLE db2.t3(
+a INT AUTO_INCREMENT PRIMARY KEY,
+b CHAR(20) NOT NULL,
+c CHAR(20) NOT NULL,
+INDEX(b, c)
+);
+INSERT INTO db1.t1 VALUES 
+(1,'test1'),(2,'test2'),
+(3,'test3'),(4,'test4');
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+SELECT COUNT(*) FROM db1.t1;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+INSERT INTO db2.t1 VALUES
+(1, 'Testing backup solution','automated testing'),
+(2, 'Testing replication feature', 'manual testing'),
+(3, 'Testing clustering basics', 'semi-automated testing'),
+(4, 'Interoperability testing of features', 'automated testing'),
+(5, 'Performance testing','semi-automated testing');
+SELECT COUNT(*) FROM db2.t1;
+COUNT(*)
+5
+SELECT * FROM db2.t1;
+id	details	methods
+1	Testing backup solution	automated testing
+2	Testing replication feature	manual testing
+3	Testing clustering basics	semi-automated testing
+4	Interoperability testing of features	automated testing
+5	Performance testing	semi-automated testing
+INSERT INTO db2.t3(b,c) VALUES
+('abcd1','efgh1'),('efgh1','pqrs1'),('pqrs1','abcd1'),
+('xwyz1','klmn1'),('klmn1','opdh1'),('opdh1','xwyz1');
+INSERT INTO db2.t2 VALUES
+(100,'Testing mysql external programs'),(200, 'Testing myisampack utility'),
+(300, 'Testing myisamchk utility'),(400, 'Testing mysql_setpermission utility'),
+(500, 'Testing myisam_ftdump utility'),
+(600, 'Testing mysql_convert_table utility');
+
+# Check the indexes in tables
+
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	A
+Cardinality	NULL
+Sub_part	10
+Packed	NULL
+Null	YES
+Index_type	BTREE
+Comment	
+Index_Comment	
+SHOW INDEX FROM db2.t1;;
+Table	t1
+Non_unique	1
+Key_name	details
+Seq_in_index	1
+Column_name	details
+Collation	NULL
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	YES
+Index_type	FULLTEXT
+Comment	
+Index_Comment	
+Table	t1
+Non_unique	1
+Key_name	details
+Seq_in_index	2
+Column_name	methods
+Collation	NULL
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	YES
+Index_type	FULLTEXT
+Comment	
+Index_Comment	
+SHOW INDEX FROM db2.t2;;
+Table	t2
+Non_unique	0
+Key_name	a
+Seq_in_index	1
+Column_name	a
+Collation	A
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	YES
+Index_type	BTREE
+Comment	
+Index_Comment	
+Table	t2
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	NULL
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	YES
+Index_type	FULLTEXT
+Comment	
+Index_Comment	
+SHOW INDEX FROM db2.t3;;
+Table	t3
+Non_unique	0
+Key_name	PRIMARY
+Seq_in_index	1
+Column_name	a
+Collation	A
+Cardinality	6
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	A
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	2
+Column_name	c
+Collation	A
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+
+# Test 1: Use myisampack to compress the tables followed by myisamchk to 
+#         rebuild the indexes.
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+FLUSH TABLES;
+BACKUP DATABASE db1 TO 'db1.bak';
+backup_id
+#
+DROP DATABASE db1;
+RESTORE FROM 'db1.bak';
+backup_id
+#
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+
+# Use myisampack utility again after restore. Verify that utilities
+# are not affected and functions properly after backup and restore 
+# operation.
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+
+# 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
+#
+# Check data contents and indexes in table
+SHOW TABLES FROM db1;
+Tables_in_db1
+t1
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+
+# Test 2: Use repair and general options of myisamchk followed by
+#         backup and restore.
+FLUSH TABLES;
+LOCK TABLE db1.t1 READ;
+CHECKSUM TABLE db1.t1;
+Table	Checksum
+db1.t1	261218912
+LOCK TABLE db2.t3 READ;
+CHECKSUM TABLE db2.t3;
+Table	Checksum
+db2.t3	42617894
+# Use myisamchk repair options
+UNLOCK TABLES;
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+backup_id
+#
+DROP DATABASE db1;
+DROP DATABASE db2;
+RESTORE FROM 'db12.bak';
+backup_id
+#
+CHECKSUM TABLE db1.t1;
+Table	Checksum
+db1.t1	261218912
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+CHECKSUM TABLE db2.t3;
+Table	Checksum
+db2.t3	42617894
+SELECT COUNT(*) FROM db2.t3;
+COUNT(*)
+6
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SHOW INDEX FROM db2.t3;;
+Table	t3
+Non_unique	0
+Key_name	PRIMARY
+Seq_in_index	1
+Column_name	a
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	2
+Column_name	c
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+
+# Use myisamchk options again after restore. Verify that these utilities
+# are not affected and functions properly after backup and restore 
+# operation.
+# Verify checksums and data contents.
+CHECKSUM TABLE db1.t1;
+Table	Checksum
+db1.t1	261218912
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+CHECKSUM TABLE db2.t3;
+Table	Checksum
+db2.t3	42617894
+SELECT COUNT(*) FROM db2.t3;
+COUNT(*)
+6
+# Use myisamchk general option(auto_increment)
+SELECT * FROM db2.t3;
+a	b	c
+1	abcd1	efgh1
+2	efgh1	pqrs1
+3	pqrs1	abcd1
+4	xwyz1	klmn1
+5	klmn1	opdh1
+6	opdh1	xwyz1
+FLUSH TABLES;
+# Executing myisamchk auto increment option to begin with number=200
+INSERT INTO db2.t3(b,c) VALUES('iklm1','ujmn1');
+SELECT * FROM db2.t3 ORDER BY a;
+a	b	c
+1	abcd1	efgh1
+2	efgh1	pqrs1
+3	pqrs1	abcd1
+4	xwyz1	klmn1
+5	klmn1	opdh1
+6	opdh1	xwyz1
+201	iklm1	ujmn1
+BACKUP DATABASE db2 TO 'db2.bak';
+backup_id
+#
+DROP DATABASE db2;
+RESTORE FROM 'db2.bak';
+backup_id
+#
+SELECT * FROM db2.t3 ORDER BY a;
+a	b	c
+1	abcd1	efgh1
+2	efgh1	pqrs1
+3	pqrs1	abcd1
+4	xwyz1	klmn1
+5	klmn1	opdh1
+6	opdh1	xwyz1
+201	iklm1	ujmn1
+INSERT INTO db2.t3(b,c) VALUES('hgfd1','iklm1');
+SELECT * FROM db2.t3 ORDER BY a;
+a	b	c
+1	abcd1	efgh1
+2	efgh1	pqrs1
+3	pqrs1	abcd1
+4	xwyz1	klmn1
+5	klmn1	opdh1
+6	opdh1	xwyz1
+201	iklm1	ujmn1
+202	hgfd1	iklm1
+
+# Use myisamchk auto increment option again after restore. Verify that
+# this option functions properly after backup and restore operation
+FLUSH TABLES;
+
+# Insert some contents in table db2.t3 and verify that auto increment 
+# numbering starts from 300 for new values inserted in table.
+INSERT INTO db2.t3(b,c) VALUES('ptyu1','irtc1');
+SELECT * FROM db2.t3 ORDER BY a;
+a	b	c
+1	abcd1	efgh1
+2	efgh1	pqrs1
+3	pqrs1	abcd1
+4	xwyz1	klmn1
+5	klmn1	opdh1
+6	opdh1	xwyz1
+201	iklm1	ujmn1
+202	hgfd1	iklm1
+301	ptyu1	irtc1
+
+# Use myisamchk general options, --sort-index and --analyze 
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+FLUSH TABLES;
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+backup_id
+#
+DROP DATABASE db1;
+DROP DATABASE db2;
+RESTORE FROM 'db12.bak';
+backup_id
+#
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SELECT COUNT(*) FROM db2.t3;
+COUNT(*)
+9
+SHOW INDEX FROM db2.t3;;
+Table	t3
+Non_unique	0
+Key_name	PRIMARY
+Seq_in_index	1
+Column_name	a
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	2
+Column_name	c
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+
+# Use myisamchk general options again after restore. Verify that these 
+# options functions properly after backup and restore operation
+FLUSH TABLES;
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	YES
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+SELECT COUNT(*) FROM db2.t3;
+COUNT(*)
+9
+SHOW INDEX FROM db2.t3;;
+Table	t3
+Non_unique	0
+Key_name	PRIMARY
+Seq_in_index	1
+Column_name	a
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+Table	t3
+Non_unique	1
+Key_name	b
+Seq_in_index	2
+Column_name	c
+Collation	#
+Cardinality	NULL
+Sub_part	#
+Packed	#
+Null	
+Index_type	BTREE
+Comment	#
+Index_Comment	#
+
+# Test 3: Interoperability of backup and restore with myisam_ftdump
+#
+# Execute myisam_ftdump to display full text indexes in tables db2.t1 
+# and db2.t2
+Total rows: 5
+Total words: 21
+Unique words: 13
+Longest word: 16 chars (interoperability)
+Median length: 7
+Average global weight: 0.990932
+Most common word: 5 times, weight: 0.000000 (testing)
+Total rows: 6
+Total words: 19
+Unique words: 10
+Longest word: 19 chars (mysql_convert_table)
+Median length: 7
+Average global weight: 1.126607
+Most common word: 6 times, weight: 0.000000 (testing)
+BACKUP DATABASE db2 TO 'db2.bak';
+backup_id
+#
+DROP DATABASE db2;
+RESTORE FROM 'db2.bak';
+backup_id
+#
+SELECT * FROM db2.t1 LIMIT 5;
+id	details	methods
+1	Testing backup solution	automated testing
+2	Testing replication feature	manual testing
+3	Testing clustering basics	semi-automated testing
+4	Interoperability testing of features	automated testing
+5	Performance testing	semi-automated testing
+SELECT * FROM db2.t2;
+a	b
+100	Testing mysql external programs
+200	Testing myisampack utility
+300	Testing myisamchk utility
+400	Testing mysql_setpermission utility
+500	Testing myisam_ftdump utility
+600	Testing mysql_convert_table utility
+
+# Execute myisam_ftdump in tables of database db2 after restore 
+# Verify that fulltext indexes are same as it was before backup
+Total rows: 5
+Total words: 21
+Unique words: 13
+Longest word: 16 chars (interoperability)
+Median length: 7
+Average global weight: 0.990932
+Most common word: 5 times, weight: 0.000000 (testing)
+Total rows: 6
+Total words: 19
+Unique words: 10
+Longest word: 19 chars (mysql_convert_table)
+Median length: 7
+Average global weight: 1.126607
+Most common word: 6 times, weight: 0.000000 (testing)
+DROP DATABASE db1;
+DROP DATABASE db2;

=== added file 'mysql-test/suite/backup/r/backup_external_non_win.result'
--- a/mysql-test/suite/backup/r/backup_external_non_win.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_external_non_win.result	2009-04-22 08:31:38 +0000
@@ -0,0 +1,311 @@
+
+# Drop database if already exists
+#
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+DROP TABLESPACE ts Engine=Falcon;
+#
+# Create databases and tables
+#
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+CREATE TABLE db1.t1(
+id INT,
+name VARCHAR(30),
+INDEX idx(name(10))
+);
+CREATE TABLE db2.t1(
+a INT AUTO_INCREMENT PRIMARY KEY,
+b CHAR(20) NOT NULL,
+c CHAR(20) NOT NULL,
+INDEX(b, c)
+);
+INSERT INTO db1.t1 VALUES 
+(1,'test1'),(2,'test2'),
+(3,'test3'),(4,'test4');
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+SELECT COUNT(*) FROM db1.t1;
+COUNT(*)
+128
+SELECT * FROM db1.t1 LIMIT 4;
+id	name
+1	test1
+2	test2
+3	test3
+4	test4
+INSERT INTO db2.t1(b,c) VALUES
+('abcd1','efgh1'),('efgh1','pqrs1'),('pqrs1','abcd1'),
+('xwyz1','klmn1'),('klmn1','opdh1'),('opdh1','xwyz1');
+
+# Check the indexes in tables
+SHOW INDEX FROM db1.t1;;
+Table	t1
+Non_unique	1
+Key_name	idx
+Seq_in_index	1
+Column_name	name
+Collation	A
+Cardinality	NULL
+Sub_part	10
+Packed	NULL
+Null	YES
+Index_type	BTREE
+Comment	
+Index_Comment	
+SHOW INDEX FROM db2.t1;;
+Table	t1
+Non_unique	0
+Key_name	PRIMARY
+Seq_in_index	1
+Column_name	a
+Collation	A
+Cardinality	6
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+Table	t1
+Non_unique	1
+Key_name	b
+Seq_in_index	1
+Column_name	b
+Collation	A
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+Table	t1
+Non_unique	1
+Key_name	b
+Seq_in_index	2
+Column_name	c
+Collation	A
+Cardinality	NULL
+Sub_part	NULL
+Packed	NULL
+Null	
+Index_type	BTREE
+Comment	
+Index_Comment	
+
+# Test 1 : Interoperability of backup and restore with
+#          mysql_convert_table_format
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+# Check the storage engine of table is chnaged to innodb
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+BACKUP DATABASE db1 TO 'db1.bak';
+backup_id
+#
+DROP DATABASE db1;
+RESTORE FROM 'db1.bak';
+backup_id
+#
+# Verify db1.t1 has same storage engine as it was before backup
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+# Changing the storage engine back to myisam
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+# Test 2 : Create objects that directly or indirectly is affected 
+# storage engine. Use mysql_convert_table_format and change the storage 
+# engine type
+Creating objects
+CREATE TABLESPACE ts ADD DATAFILE 'df' ENGINE=FALCON;
+CREATE TABLE db1.t2(comment CHAR(20)) TABLESPACE ts ENGINE=FALCON;
+SHOW CREATE TABLE db1.t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `comment` char(20) DEFAULT NULL
+) /*!50100 TABLESPACE `ts` */ ENGINE=Falcon DEFAULT CHARSET=latin1
+CREATE VIEW db2.v1 AS SELECT * FROM db1.t2;
+CREATE TRIGGER db2.trg1 AFTER DELETE ON db2.t1 FOR EACH ROW
+BEGIN
+INSERT INTO db1.t2 VALUES("Firing trigger");
+END;||
+# Create table with partitions
+CREATE TABLE db1.tpl(id INT, a CHAR(20)) PARTITION BY LIST(id)
+(
+PARTITION p0 VALUES IN (1,4),
+PARTITION p1 VALUES IN (2,3)
+);
+INSERT INTO db1.tpl VALUES(1, 'a'),(2,'b'),(3,'c'),(4,'d');
+EXPLAIN PARTITIONS SELECT * FROM db1.tpl;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	tpl	p0,p1	ALL	NULL	NULL	NULL	NULL	4	
+SELECT * FROM db1.tpl;
+id	a
+1	a
+4	d
+2	b
+3	c
+CREATE TABLE db1.tph(name CHAR(20), bdate DATE)
+PARTITION BY HASH (YEAR(bdate)) PARTITIONS 4;
+INSERT INTO db1.tph VALUES
+('jim','1999-12-12'),('tom','1987-09-08'),('carrie','1988-10-11');
+EXPLAIN PARTITIONS SELECT * FROM db1.tph;
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	tph	p0,p1,p2,p3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT * FROM db1.tph;
+name	bdate
+carrie	1988-10-11
+jim	1999-12-12
+tom	1987-09-08
+# Fire trigger
+DELETE FROM db2.t1 WHERE a=2;
+SELECT * FROM db2.t1 WHERE a=2;
+a	b	c
+SELECT * FROM db1.t2;
+comment
+Firing trigger
+BACKUP DATABASE db1 TO 'db1.bak';
+backup_id
+#
+# Use mysql_convert_table_format to change the storage engines of 
+# tables in db1
+t1 is already of type myisam;  Ignored
+tph is already of type myisam;  Ignored
+tpl is already of type myisam;  Ignored
+# Note that tablespace will be ignored by db1.t2
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE db1.t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `comment` char(20) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+backup_id
+#
+DROP DATABASE db1;
+DROP DATABASE db2;
+RESTORE FROM 'db12.bak';
+backup_id
+#
+# Fire Trigger
+DELETE FROM db2.t1 WHERE a=3;
+SELECT * FROM db2.t1 WHERE a=3;
+a	b	c
+SELECT * FROM db1.t2;
+comment
+Firing trigger
+Firing trigger
+# Note that tablepsace will be ignored because of myisam storage engine
+SHOW CREATE TABLE db1.t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `comment` char(20) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+# Restore from db1.bak to get back tablespace
+RESTORE FROM 'db1.bak' OVERWRITE;
+backup_id
+#
+# Verify that tablespace is restored from db1.t2
+SHOW CREATE TABLE db1.t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `comment` char(20) DEFAULT NULL
+) /*!50100 TABLESPACE `ts` */ ENGINE=Falcon DEFAULT CHARSET=latin1
+t2 is already of type falcon;  Ignored
+SHOW CREATE TABLE db1.tpl;
+Table	Create Table
+tpl	CREATE TABLE `tpl` (
+  `id` int(11) DEFAULT NULL,
+  `a` char(20) DEFAULT NULL
+) ENGINE=Falcon DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (id)
+(PARTITION p0 VALUES IN (1,4) ENGINE = Falcon,
+ PARTITION p1 VALUES IN (2,3) ENGINE = Falcon) */
+SHOW CREATE TABLE db1.tph;
+Table	Create Table
+tph	CREATE TABLE `tph` (
+  `name` char(20) DEFAULT NULL,
+  `bdate` date DEFAULT NULL
+) ENGINE=Falcon DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (YEAR(bdate))
+PARTITIONS 4 */
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+backup_id
+#
+DROP DATABASE db1;
+DROP DATABASE db2;
+RESTORE FROM 'db12.bak';
+backup_id
+#
+SHOW CREATE TABLE db1.tpl;
+Table	Create Table
+tpl	CREATE TABLE `tpl` (
+  `id` int(11) DEFAULT NULL,
+  `a` char(20) DEFAULT NULL
+) ENGINE=Falcon DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (id)
+(PARTITION p0 VALUES IN (1,4) ENGINE = Falcon,
+ PARTITION p1 VALUES IN (2,3) ENGINE = Falcon) */
+SHOW CREATE TABLE db1.tph;
+Table	Create Table
+tph	CREATE TABLE `tph` (
+  `name` char(20) DEFAULT NULL,
+  `bdate` date DEFAULT NULL
+) ENGINE=Falcon DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (YEAR(bdate))
+PARTITIONS 4 */
+# Fire Trigger
+DELETE FROM db2.t1 WHERE a=4;
+SELECT * FROM db2.t1 WHERE a=4;
+a	b	c
+SELECT * FROM db1.t2;
+comment
+Firing trigger
+Firing trigger
+DROP TABLE db1.tpl;
+DROP TABLE db1.tph;
+DROP TABLE db1.t2;
+DROP VIEW db2.v1;
+# Changing the storage engine back to myisam after restore
+SHOW CREATE TABLE db1.t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` int(11) DEFAULT NULL,
+  `name` varchar(30) DEFAULT NULL,
+  KEY `idx` (`name`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP DATABASE db1;
+DROP DATABASE db2;
+DROP TABLESPACE ts Engine=Falcon;

=== added file 'mysql-test/suite/backup/r/backup_intr_errors.result'
--- a/mysql-test/suite/backup/r/backup_intr_errors.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_intr_errors.result	2009-04-09 12:10:27 +0000
@@ -0,0 +1,263 @@
+call mtr.add_suppression("Backup:");
+call mtr.add_suppression("Restore:");
+#
+# Setup
+#
+DROP DATABASE IF EXISTS bup_intr;
+CREATE DATABASE bup_intr;
+USE bup_intr;
+CREATE TABLE t1(engine char(6));
+INSERT INTO  t1 VALUES ('innodb'),('memory');
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1);
+DELETE FROM bup_intr.t1 WHERE engine='innodb';
+
+########################################
+## Testing with innodb engine.
+########################################
+
+ALTER TABLE bup_intr.t1 ENGINE=innodb;
+SET SESSION DEBUG="+d,backup_driver_cancel_error";
+SET SESSION DEBUG="+d,backup_stream_close_error";
+SET SESSION DEBUG="+d,backup_remove_location_error";
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_lock.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_lock SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Snapshot backup driver can't cancel its backup operation
+Warning	<error-code>	Operation aborted
+Error	<error-code>	Backup/Restore: Error on close of backup stream
+Error	<error-code>	Error on delete of <backup image path> (errno: 176)
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+SELECT * FROM mysql.backup_history;
+# Reset debug variable to its original value.
+#
+# Prepare bup_intr.bkp for RESTORE testing. Note that above BACKUP
+# command should not create the file because it was interrupted.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+backup_id
+#
+DROP DATABASE bup_intr;
+SET SESSION DEBUG="+d,backup_driver_cancel_error";
+SET SESSION DEBUG="+d,backup_stream_close_error";
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_sending_data.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_sending_data SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Can't shut down Snapshot restore driver(s)
+Warning	<error-code>	Operation aborted - data might be corrupted
+Error	<error-code>	Backup/Restore: Error on close of backup stream
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+# Reset debug variable to its original value.
+#
+# Restore original database - the interrupted RESTORE statement could
+# corrupt it.
+#
+RESTORE FROM 'bup_intr.bkp' OVERWRITE;
+backup_id
+#
+DELETE FROM bup_intr.t1 WHERE engine='memory';
+
+########################################
+## Testing with memory engine.
+########################################
+
+ALTER TABLE bup_intr.t1 ENGINE=memory;
+SET SESSION DEBUG="+d,backup_driver_cancel_error";
+SET SESSION DEBUG="+d,backup_stream_close_error";
+SET SESSION DEBUG="+d,backup_remove_location_error";
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_lock.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_lock SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Default backup driver can't cancel its backup operation
+Warning	<error-code>	Operation aborted
+Error	<error-code>	Backup/Restore: Error on close of backup stream
+Error	<error-code>	Error on delete of <backup image path> (errno: 176)
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+SELECT * FROM mysql.backup_history;
+# Reset debug variable to its original value.
+#
+# Prepare bup_intr.bkp for RESTORE testing. Note that above BACKUP
+# command should not create the file because it was interrupted.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+backup_id
+#
+DROP DATABASE bup_intr;
+SET SESSION DEBUG="+d,backup_driver_cancel_error";
+SET SESSION DEBUG="+d,backup_stream_close_error";
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_sending_data.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_sending_data SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Error	<error-code>	Can't shut down Default restore driver(s)
+Warning	<error-code>	Operation aborted - data might be corrupted
+Error	<error-code>	Backup/Restore: Error on close of backup stream
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+# Reset debug variable to its original value.
+#
+# Restore original database - the interrupted RESTORE statement could
+# corrupt it.
+#
+RESTORE FROM 'bup_intr.bkp' OVERWRITE;
+backup_id
+#
+#
+# Cleanup
+#
+SET DEBUG_SYNC='reset';
+DROP DATABASE IF EXISTS bup_intr;

=== modified file 'mysql-test/suite/backup/r/backup_myisam_sync.result'
--- a/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-02-13 12:40:13 +0000
+++ b/mysql-test/suite/backup/r/backup_myisam_sync.result	2009-04-14 13:40:06 +0000
@@ -36,6 +36,15 @@ LENGTH(c1)
 CHECKSUM TABLE t1;
 Table	Checksum
 mysqltest.t1	1728069308
+
+# Verify that the MyISAM Key Cache is enabled.
+# See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+VARIABLE_NAME LIKE 'Key_blocks_%used';
+key_cache_is_enabled
+1
+
 Signal BACKUP to finish
 SET DEBUG_SYNC= 'now SIGNAL bup_finish';
 
@@ -59,6 +68,14 @@ mysqltest.t1	check	status	OK
 connection default: cleanup
 SET DEBUG_SYNC= 'RESET';
 
+# Verify that the MyISAM Key Cache is still enabled.
+# See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+VARIABLE_NAME LIKE 'Key_blocks_%used';
+key_cache_is_enabled
+1
+
 # final cleanup
 USE test;
 DROP DATABASE mysqltest;

=== added file 'mysql-test/suite/backup/r/backup_namecase.result'
--- a/mysql-test/suite/backup/r/backup_namecase.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/r/backup_namecase.result	2009-04-01 11:08:48 +0000
@@ -0,0 +1,172 @@
+
+# Create database with tables and views
+
+CREATE DATABASE changecase;
+CREATE TABLE changecase.t1 (i int);
+INSERT INTO changecase.t1 VALUES (1);
+CREATE TABLE changecase.t2 (text varchar(20));
+CREATE VIEW changecase.v1 AS SELECT * FROM changecase.t1;
+
+# Add trigger and procedure
+
+CREATE PROCEDURE changecase.trgmsg(a int)
+BEGIN
+INSERT INTO changecase.t2(text) VALUES ('Db trigger fired!');
+END;
+||
+CREATE TRIGGER changecase.afterins AFTER INSERT ON changecase.t1 FOR EACH ROW 
+CALL trgmsg(1);
+||
+CREATE EVENT changecase.ev ON SCHEDULE EVERY 10 second DO 
+BEGIN
+INSERT INTO changecase.t2(text) VALUES ('Db event fired!');
+END;
+||
+
+# Add user with privileges
+
+CREATE USER user_with_grants;
+default: Grant user rights to run backup. Revoke SUPER from one user.
+GRANT SELECT ON changecase.t1 TO 'user_with_grants'@'%';
+GRANT SELECT ON changecase.v1 TO 'user_with_grants'@'%';
+GRANT UPDATE ON changecase.* TO 'user_with_grants'@'%';
+GRANT INSERT ON changecase.* TO 'user_with_grants'@'%';
+GRANT SUPER ON *.* TO 'user_with_grants'@'%';
+FLUSH PRIVILEGES;
+
+# Show procedure, trigger and event
+
+SHOW CREATE PROCEDURE changecase.trgmsg;;
+Procedure	trgmsg
+sql_mode	
+Create Procedure	CREATE DEFINER=`root`@`localhost` PROCEDURE `trgmsg`(a int)
+BEGIN
+INSERT INTO changecase.t2(text) VALUES ('Db trigger fired!');
+END
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+SHOW TRIGGERS FROM changecase;;
+Trigger	afterins
+Event	INSERT
+Table	t1
+Statement	CALL trgmsg(1)
+Timing	AFTER
+Created	NULL
+sql_mode	
+Definer	root@localhost
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+SHOW EVENTS IN changecase;;
+Db	changecase
+Name	ev
+Definer	root@localhost
+Time zone	SYSTEM
+Type	RECURRING
+Execute at	NULL
+Interval value	10
+Interval field	SECOND
+Starts	#
+Ends	NULL
+Status	ENABLED
+Originator	1
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+# BACKUP, drop database and user
+
+BACKUP DATABASE changecase TO 'uppercase.bup';
+backup_id
+#
+DROP DATABASE changecase;
+REVOKE ALL ON *.* FROM 'user_with_grants'@'%';
+
+# RESTORE database
+
+# Activate debug hook that makes db names upper-case when checking if
+# a grant statement operates on a db that is restored. Should fail
+SET SESSION DEBUG='+d,restore_catalog_uppercase_names_grant';
+RESTORE FROM 'uppercase.bup';
+ERROR HY000: The grant '22 'user_with_grants'@'%
+22 INSERT ON changecase.*
+32 SET chara' failed. Database not included in the backup image.
+SET SESSION DEBUG='-d';
+DROP DATABASE changecase;
+# Activate debug hook that makes all names upper-case. Should work.
+SET SESSION DEBUG='+d,restore_catalog_uppercase_names';
+RESTORE FROM 'uppercase.bup';
+backup_id
+#
+SET SESSION DEBUG='-d';
+
+# Check contents of restored database
+
+
+SHOW TABLES IN changecase;
+Tables_in_changecase
+t1
+t2
+v1
+
+SELECT * FROM changecase.t1;
+i
+1
+
+# Show procedure, trigger and event
+
+SHOW CREATE PROCEDURE changecase.trgmsg;;
+Procedure	trgmsg
+sql_mode	
+Create Procedure	CREATE DEFINER=`root`@`localhost` PROCEDURE `trgmsg`(a int)
+BEGIN
+INSERT INTO changecase.t2(text) VALUES ('Db trigger fired!');
+END
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+SHOW TRIGGERS FROM changecase;;
+Trigger	afterins
+Event	INSERT
+Table	t1
+Statement	CALL trgmsg(1)
+Timing	AFTER
+Created	NULL
+sql_mode	
+Definer	root@localhost
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+SHOW EVENTS IN changecase;;
+Db	changecase
+Name	ev
+Definer	root@localhost
+Time zone	SYSTEM
+Type	RECURRING
+Execute at	NULL
+Interval value	10
+Interval field	SECOND
+Starts	#
+Ends	NULL
+Status	ENABLED
+Originator	1
+character_set_client	latin1
+collation_connection	latin1_swedish_ci
+Database Collation	latin1_swedish_ci
+
+SHOW GRANTS FOR 'user_with_grants'@'%';
+Grants for user_with_grants@%
+GRANT USAGE ON *.* TO 'user_with_grants'@'%'
+GRANT INSERT, UPDATE ON `changecase`.* TO 'user_with_grants'@'%'
+GRANT SELECT ON `changecase`.`v1` TO 'user_with_grants'@'%'
+GRANT SELECT ON `changecase`.`t1` TO 'user_with_grants'@'%'
+
+# Cleanup
+
+DROP DATABASE changecase;
+DROP USER user_with_grants;

=== modified file 'mysql-test/suite/backup/r/backup_triggers_and_events.result'
--- a/mysql-test/suite/backup/r/backup_triggers_and_events.result	2008-10-24 08:11:18 +0000
+++ b/mysql-test/suite/backup/r/backup_triggers_and_events.result	2009-04-22 08:31:38 +0000
@@ -57,14 +57,18 @@ BACKUP DATABASE db TO 'db.bak';
 backup_id
 #
 DROP DATABASE db;
-Enabling event scheduler.
-SET GLOBAL event_scheduler=on;
 con1: clearing log table and starting RESTORE operation.
 con1: RESTORE will pause after restoring table data.
-SET DEBUG_SYNC = 'restore_table_data_before_end SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC = 'after_backup_start_restore SIGNAL started WAIT_FOR continue';
+SET DEBUG_SYNC = 'restore_table_data_before_end SIGNAL waiting WAIT_FOR finish';
 DELETE FROM test.logt;
 RESTORE FROM 'db.bak';
+SET DEBUG_SYNC = 'now WAIT_FOR started';
+Enabling event scheduler.
+SET GLOBAL event_scheduler=on;
+Get BACKUP going.
 SELECT now() INTO @start;
+SET DEBUG_SYNC = 'now SIGNAL continue';
 con2: checking that there are no triggers and events at the end of RESTORE execution.
 SET DEBUG_SYNC = 'now WAIT_FOR waiting';
 SHOW TRIGGERS FROM db;
@@ -72,14 +76,14 @@ SHOW EVENTS IN db;
 con2: activating trigger in test database.
 INSERT INTO test.t1 VALUES (1);
 con2: ensuring that RESTORE takes at least 3 secs.
-SET DEBUG_SYNC = 'now SIGNAL continue';
+SET DEBUG_SYNC = 'now SIGNAL finish';
 con1: finishing RESTORE operation.
 backup_id
 #
 SET GLOBAL event_scheduler=off;
 con2: checking that RESTORE took more than 2 secs.
-SELECT timediff(now(),@start) > 2;
-timediff(now(),@start) > 2
+SELECT timediff(now(),@start) > 3;
+timediff(now(),@start) > 3
 1
 Checking that objects have been restored.
 USE db;
@@ -173,22 +177,23 @@ character_set_client	latin1
 collation_connection	latin1_swedish_ci
 Database Collation	latin1_swedish_ci
 Checking that no db event or trigger fired during RESTORE.
-SELECT * FROM test.logt WHERE db = 'db' AND timediff(ts,@start) < 2;
+SELECT * FROM test.logt WHERE db = 'db' AND timediff(ts,@start) < 3;
 ts	db	msg
 Checking that test event and trigger could fire.
 SELECT count(*) > 0 FROM test.logt 
 WHERE db = 'test'
 AND msg LIKE '%trigger fired%'
-AND timediff(ts,@start) < 2;
+AND timediff(ts,@start) < 3;
 count(*) > 0
 1
 SELECT count(*) > 0 FROM test.logt 
 WHERE db = 'test'
 AND msg LIKE '%event fired%'
-AND timediff(ts,@start) < 2;
+AND timediff(ts,@start) < 3;
 count(*) > 0
 1
 Cleaning up.
+SET DEBUG_SYNC = 'RESET';
 DROP EVENT test.ev;
 DROP TRIGGER test.trg;
 DROP TABLE test.logt;

=== modified file 'mysql-test/suite/backup/t/backup_bml.test'
--- a/mysql-test/suite/backup/t/backup_bml.test	2009-02-20 16:40:19 +0000
+++ b/mysql-test/suite/backup/t/backup_bml.test	2009-03-23 18:46:10 +0000
@@ -564,10 +564,16 @@ connection default;
 --echo # Waiting for BACKUP to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_started TIMEOUT 3';
 
---echo # Check the state of both statements.
-eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-  WHERE info LIKE "BACKUP DATABASE%"
-     OR info LIKE "CREATE USER%";
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#--echo # Check the state of both statements.
+#eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+#  WHERE info LIKE "BACKUP DATABASE%"
+#     OR info LIKE "CREATE USER%";
 --echo # Checking that CREATE USER has not executed yet.
 SELECT User, Password FROM mysql.user WHERE User like 'bml%';
 --echo # Checking that BACKUP is not blocked by DDL.
@@ -637,10 +643,16 @@ connection default;
 --echo # Waiting for RESTORE to reach its synchronization point.
 SET DEBUG_SYNC= 'now WAIT_FOR bup_started TIMEOUT 3';
 
---echo # Check the state of both statements.
-eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
-  WHERE info LIKE "RESTORE FROM%"
-     OR info LIKE "DROP SERVER%";
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#--echo # Check the state of both statements.
+#eval SELECT state, info FROM INFORMATION_SCHEMA.PROCESSLIST
+#  WHERE info LIKE "RESTORE FROM%"
+#     OR info LIKE "DROP SERVER%";
 --echo # Checking that DROP SERVER has not executed yet.
 SELECT Server_name FROM mysql.servers WHERE Server_name like 'bml%';
 --echo # Checking that RESTORE is not blocked by DDL.

=== added file 'mysql-test/suite/backup/t/backup_default_debug.test'
--- a/mysql-test/suite/backup/t/backup_default_debug.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_default_debug.test	2009-03-25 13:21:35 +0000
@@ -0,0 +1,37 @@
+###########################################################################
+# Purpose: To test backup using default driver with error injection
+###############################################################################
+--source include/have_debug.inc
+--source include/have_falcon.inc
+--source include/not_embedded.inc
+
+--let $BACKUPDIR= `SELECT @@backupdir`
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysql_db1;
+--error 0, 1
+--remove_file $BACKUPDIR/mysqltest.bak
+--enable_warnings
+
+--echo #
+--echo # Bug#41722 - Restore crashes with backup of Falcon tables
+--echo #
+CREATE DATABASE mysql_db1;
+CREATE TABLE mysql_db1.t1 (c1 TEXT) ENGINE=Falcon;
+INSERT INTO mysql_db1.t1 VALUES('fdafdsfdsfdsfdsfdsfd');
+#
+--replace_column 1 #
+BACKUP DATABASE mysql_db1 TO 'mysqltest.bak';
+#
+DROP DATABASE mysql_db1;
+#
+--echo #
+--echo # Inject error Restore__send_data_write_error
+--echo #
+SET debug='d,Restore__send_data_write_error';
+--error ER_BACKUP_SEND_DATA
+RESTORE FROM 'mysqltest.bak';
+#
+SET debug= '';
+DROP DATABASE mysql_db1;
+--remove_file $BACKUPDIR/mysqltest.bak

=== added file 'mysql-test/suite/backup/t/backup_external.test'
--- a/mysql-test/suite/backup/t/backup_external.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_external.test	2009-03-25 22:17:35 +0000
@@ -0,0 +1,377 @@
+#
+# Interoperability testing of mysql backup feature with mysql external
+# applications. The external programs that will be included in the tests are:
+#
+# 1. myisampack
+# 2. myisamchk
+# 3. mysql_covert_table_format
+# 4. myisam_ftdump
+# 
+# Note: mysql_convert_table_utility is not supported by windows. Therefore, it 
+# is covered in backup_external_non_win.test
+#
+--source include/not_embedded.inc
+
+let $MYSQLD_BACKUPDIR = `select @@backupdir`;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--echo # Drop databases if they are already existing
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+--enable_warnings
+
+--echo #
+--echo # Create databases and tables
+--echo #
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+
+CREATE TABLE db1.t1(
+ id INT,
+ name VARCHAR(30),
+ INDEX idx(name(10))
+);
+
+CREATE TABLE db2.t1(
+ id INT UNSIGNED NOT NULL,
+ details TEXT,
+ methods VARCHAR(40),
+ FULLTEXT(details, methods)
+);
+
+CREATE TABLE db2.t2(
+ a CHAR(100) UNIQUE,
+ b TEXT,
+ FULLTEXT(b)
+);
+
+CREATE TABLE db2.t3(
+ a INT AUTO_INCREMENT PRIMARY KEY,
+ b CHAR(20) NOT NULL,
+ c CHAR(20) NOT NULL,
+ INDEX(b, c)
+);
+
+INSERT INTO db1.t1 VALUES 
+(1,'test1'),(2,'test2'),
+(3,'test3'),(4,'test4');
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+
+SELECT COUNT(*) FROM db1.t1;
+SELECT * FROM db1.t1 LIMIT 4;
+
+INSERT INTO db2.t1 VALUES
+(1, 'Testing backup solution','automated testing'),
+(2, 'Testing replication feature', 'manual testing'),
+(3, 'Testing clustering basics', 'semi-automated testing'),
+(4, 'Interoperability testing of features', 'automated testing'),
+(5, 'Performance testing','semi-automated testing');
+
+SELECT COUNT(*) FROM db2.t1;
+SELECT * FROM db2.t1;
+
+INSERT INTO db2.t3(b,c) VALUES
+('abcd1','efgh1'),('efgh1','pqrs1'),('pqrs1','abcd1'),
+('xwyz1','klmn1'),('klmn1','opdh1'),('opdh1','xwyz1');
+
+INSERT INTO db2.t2 VALUES
+(100,'Testing mysql external programs'),(200, 'Testing myisampack utility'),
+(300, 'Testing myisamchk utility'),(400, 'Testing mysql_setpermission utility'),
+(500, 'Testing myisam_ftdump utility'),
+(600, 'Testing mysql_convert_table utility');
+
+--echo
+--echo # Check the indexes in tables
+--echo
+ 
+--query_vertical SHOW INDEX FROM db1.t1;
+--query_vertical SHOW INDEX FROM db2.t1;
+--query_vertical SHOW INDEX FROM db2.t2;
+--query_vertical SHOW INDEX FROM db2.t3;
+
+--echo
+--echo # Test 1: Use myisampack to compress the tables followed by myisamchk to 
+--echo #         rebuild the indexes.
+
+# This test is intended to verify the consequence of myisamchk and
+# myisampack on backup and restore operation.
+
+# Myisampack -s option is used for 'silent mode'
+# Myisamchk uses -s for silent mode, r for recovery and q for quick repair of
+# datafiles
+
+--exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
+
+# Check the indexes in the table db1.t1
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+FLUSH TABLES;
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'db1.bak';
+
+DROP DATABASE db1;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db1.bak';
+
+# Check data contents and indexes in table
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+
+--echo
+--echo # Use myisampack utility again after restore. Verify that utilities
+--echo # are not affected and functions properly after backup and restore 
+--echo # operation.
+
+--exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMPACK -s $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
+
+# Check the indexes in the table db1.t1
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+ 
+--echo
+--echo # Use myisampack -b option to make backup of table datafile
+
+--exec $MYISAMCHK -s --unpack $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMPACK -s -b $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -srq $MYSQLD_DATADIR/db1/t1.MYI
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'db1b.bak';
+
+# Perform restore
+--replace_column 1 #
+--error ER_BACKUP_CANT_RESTORE_DB
+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.
+
+# 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;
+
+--echo # Check data contents and indexes in table
+SHOW TABLES FROM db1;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+--remove_file $MYSQLD_BACKUPDIR/db1.bak
+--remove_file $MYSQLD_BACKUPDIR/db1b.bak
+
+--echo
+--echo # Test 2: Use repair and general options of myisamchk followed by
+--echo #         backup and restore.
+
+# This test is intended to verify the consequence of using different options
+# of myisamchk utility followed by backup and restore operation. Ensure that 
+# data contents didn't get altered after restore (data contents should remain 
+# the same as they were before backup)
+
+# Lock the tables 
+FLUSH TABLES;
+LOCK TABLE db1.t1 READ;
+CHECKSUM TABLE db1.t1;
+
+LOCK TABLE db2.t3 READ;
+CHECKSUM TABLE db2.t3;
+
+--echo # Use myisamchk repair options
+# The repair options --correct-checksum corrects the checksum information in
+# table. sort_recover sorts the keys. --medium-check option helps to recover
+# possible rows from data files. --quick helps in acheiving faster repair.
+
+--exec $MYISAMCHK -s --correct-checksum --sort-recover --medium-check --quick $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -s --correct-checksum --sort-recover --medium-check --quick $MYSQLD_DATADIR/db2/t3.MYI
+UNLOCK TABLES;
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db12.bak';
+
+# Verify checksums, data contents and indexes in tables
+CHECKSUM TABLE db1.t1;
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+CHECKSUM TABLE db2.t3;
+SELECT COUNT(*) FROM db2.t3;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db2.t3;
+--remove_file $MYSQLD_BACKUPDIR/db12.bak
+
+--echo
+--echo # Use myisamchk options again after restore. Verify that these utilities
+--echo # are not affected and functions properly after backup and restore 
+--echo # operation.
+
+--exec $MYISAMCHK -s --correct-checksum --sort-recover --medium-check --quick $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -s --correct-checksum --sort-recover --medium-check --quick $MYSQLD_DATADIR/db2/t3.MYI
+
+--echo # Verify checksums and data contents.
+CHECKSUM TABLE db1.t1;
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+CHECKSUM TABLE db2.t3;
+SELECT COUNT(*) FROM db2.t3;
+
+--echo # Use myisamchk general option(auto_increment)
+SELECT * FROM db2.t3;
+FLUSH TABLES;
+
+--echo # Executing myisamchk auto increment option to begin with number=200
+--exec $MYISAMCHK -s --set-auto-increment=200 $MYSQLD_DATADIR/db2/t3
+
+INSERT INTO db2.t3(b,c) VALUES('iklm1','ujmn1');
+SELECT * FROM db2.t3 ORDER BY a;
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db2 TO 'db2.bak';
+
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db2.bak';
+
+# Verify the table contents in db2
+SELECT * FROM db2.t3 ORDER BY a;
+INSERT INTO db2.t3(b,c) VALUES('hgfd1','iklm1');
+SELECT * FROM db2.t3 ORDER BY a;
+--remove_file $MYSQLD_BACKUPDIR/db2.bak
+
+--echo
+--echo # Use myisamchk auto increment option again after restore. Verify that
+--echo # this option functions properly after backup and restore operation
+
+FLUSH TABLES;
+--exec $MYISAMCHK -s --set-auto-increment=300 $MYSQLD_DATADIR/db2/t3
+
+--echo
+--echo # Insert some contents in table db2.t3 and verify that auto increment 
+--echo # numbering starts from 300 for new values inserted in table.
+INSERT INTO db2.t3(b,c) VALUES('ptyu1','irtc1');
+SELECT * FROM db2.t3 ORDER BY a;
+
+--echo
+--echo # Use myisamchk general options, --sort-index and --analyze 
+# --sort-index option sorts the index tree blocks in high-low order and
+# --analyze option analyzes the distribution of key values.
+
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+FLUSH TABLES;
+--exec $MYISAMCHK -s --sort-index --analyze $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -s --sort-index --analyze $MYSQLD_DATADIR/db2/t3.MYI
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db12.bak';
+
+# Check table contents and indexes in db1 and db2
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+SELECT COUNT(*) FROM db2.t3;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db2.t3;
+--remove_file $MYSQLD_BACKUPDIR/db12.bak
+
+--echo
+--echo # Use myisamchk general options again after restore. Verify that these 
+--echo # options functions properly after backup and restore operation
+
+FLUSH TABLES;
+--exec $MYISAMCHK -s --sort-index --analyze $MYSQLD_DATADIR/db1/t1.MYI
+--exec $MYISAMCHK -s --sort-index --analyze $MYSQLD_DATADIR/db2/t3.MYI
+
+# Check table contents and indexes in db1
+SELECT COUNT(*) FROM db1.t1 WHERE id < 5;
+SELECT * FROM db1.t1 LIMIT 4;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db1.t1;
+SELECT COUNT(*) FROM db2.t3;
+--replace_column 6 # 8 # 9 # 12 # 13 #
+--query_vertical SHOW INDEX FROM db2.t3;
+
+--echo
+--echo # Test 3: Interoperability of backup and restore with myisam_ftdump
+--echo #
+
+--echo # Execute myisam_ftdump to display full text indexes in tables db2.t1 
+--echo # and db2.t2
+
+--exec $MYISAM_FTDUMP $MYSQLD_DATADIR/db2/t1 0
+--exec $MYISAM_FTDUMP $MYSQLD_DATADIR/db2/t2 1
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db2 TO 'db2.bak';
+
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db2.bak';
+
+# Check data contents in tables db2.t1 and db2.t2
+SELECT * FROM db2.t1 LIMIT 5;
+SELECT * FROM db2.t2;
+
+--echo
+--echo # Execute myisam_ftdump in tables of database db2 after restore 
+--echo # Verify that fulltext indexes are same as it was before backup
+
+--exec $MYISAM_FTDUMP $MYSQLD_DATADIR/db2/t1 0
+--exec $MYISAM_FTDUMP $MYSQLD_DATADIR/db2/t2 1
+
+--remove_file $MYSQLD_BACKUPDIR/db2.bak
+
+# Test clean-up section
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+

=== added file 'mysql-test/suite/backup/t/backup_external_non_win.test'
--- a/mysql-test/suite/backup/t/backup_external_non_win.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_external_non_win.test	2009-04-22 08:31:38 +0000
@@ -0,0 +1,237 @@
+#
+# Interoperability testing of mysql backup feature with 
+# mysql_convert_table_format 
+#
+# mysql_convert_table_format utility does not work in windows. Therefore,
+# this test will not be executed in windows
+
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source include/have_falcon.inc
+--source include/not_windows.inc
+--source suite/backup/include/backup_ext.inc
+--source suite/backup/include/have_dbi.inc
+
+let $MYSQLD_BACKUPDIR = `select @@backupdir`;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--echo
+--echo # Drop database if already exists
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+--error 0,ER_NO_SUCH_TABLESPACE
+DROP TABLESPACE ts Engine=Falcon;
+--enable_warnings
+
+--echo #
+--echo # Create databases and tables
+--echo #
+
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+
+CREATE TABLE db1.t1(
+ id INT,
+ name VARCHAR(30),
+ INDEX idx(name(10))
+);
+
+CREATE TABLE db2.t1(
+ a INT AUTO_INCREMENT PRIMARY KEY,
+ b CHAR(20) NOT NULL,
+ c CHAR(20) NOT NULL,
+ INDEX(b, c)
+);
+
+INSERT INTO db1.t1 VALUES 
+(1,'test1'),(2,'test2'),
+(3,'test3'),(4,'test4');
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+INSERT INTO db1.t1 SELECT * FROM db1.t1;
+
+SELECT COUNT(*) FROM db1.t1;
+SELECT * FROM db1.t1 LIMIT 4;
+
+INSERT INTO db2.t1(b,c) VALUES
+('abcd1','efgh1'),('efgh1','pqrs1'),('pqrs1','abcd1'),
+('xwyz1','klmn1'),('klmn1','opdh1'),('opdh1','xwyz1');
+
+--echo
+--echo # Check the indexes in tables
+
+--query_vertical SHOW INDEX FROM db1.t1;
+--query_vertical SHOW INDEX FROM db2.t1;
+
+--echo
+--echo # Test 1 : Interoperability of backup and restore with
+--echo #          mysql_convert_table_format
+
+# Changing the storage engine for db1
+SHOW CREATE TABLE db1.t1;
+
+source $MYSQLTEST_VARDIR/tmp/mctf.inc;
+--exec $MYSQL_CONVERT_TABLE_FORMAT --user=root -S $MASTER_MYSOCK --port=$MASTER_MYPORT  --type=innodb db1
+
+--echo
+--echo # Check the storage engine of table is chnaged to innodb
+SHOW CREATE TABLE db1.t1;
+
+# Execute backup operation
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'db1.bak';
+
+DROP DATABASE db1;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db1.bak';
+
+--echo # Verify db1.t1 has same storage engine as it was before backup
+SHOW CREATE TABLE db1.t1;
+
+--echo # Changing the storage engine back to myisam
+source $MYSQLTEST_VARDIR/tmp/mctf.inc;
+--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT  db1
+
+SHOW CREATE TABLE db1.t1;
+--remove_file $MYSQLD_BACKUPDIR/db1.bak
+
+--echo
+--echo # Test 2 : Create objects that directly or indirectly is affected 
+--echo # storage engine. Use mysql_convert_table_format and change the storage 
+--echo # engine type
+
+# Objects that are directly or indirectly affected by storage engines are
+# triggers, views, partitions & tablespace
+
+--echo Creating objects
+
+CREATE TABLESPACE ts ADD DATAFILE 'df' ENGINE=FALCON;
+CREATE TABLE db1.t2(comment CHAR(20)) TABLESPACE ts ENGINE=FALCON;
+SHOW CREATE TABLE db1.t2;
+CREATE VIEW db2.v1 AS SELECT * FROM db1.t2;
+DELIMITER ||;
+CREATE TRIGGER db2.trg1 AFTER DELETE ON db2.t1 FOR EACH ROW
+BEGIN
+ INSERT INTO db1.t2 VALUES("Firing trigger");
+END;||
+DELIMITER ;||
+
+--echo # Create table with partitions
+
+CREATE TABLE db1.tpl(id INT, a CHAR(20)) PARTITION BY LIST(id)
+(
+   PARTITION p0 VALUES IN (1,4),
+   PARTITION p1 VALUES IN (2,3)
+);
+
+INSERT INTO db1.tpl VALUES(1, 'a'),(2,'b'),(3,'c'),(4,'d');
+EXPLAIN PARTITIONS SELECT * FROM db1.tpl;
+SELECT * FROM db1.tpl;
+
+CREATE TABLE db1.tph(name CHAR(20), bdate DATE)
+PARTITION BY HASH (YEAR(bdate)) PARTITIONS 4;
+
+INSERT INTO db1.tph VALUES
+('jim','1999-12-12'),('tom','1987-09-08'),('carrie','1988-10-11');
+EXPLAIN PARTITIONS SELECT * FROM db1.tph;
+SELECT * FROM db1.tph;
+
+--echo # Fire trigger
+DELETE FROM db2.t1 WHERE a=2;
+SELECT * FROM db2.t1 WHERE a=2;
+SELECT * FROM db1.t2;
+
+# Perform backup
+--replace_column 1 #
+BACKUP DATABASE db1 TO 'db1.bak';
+
+--echo # Use mysql_convert_table_format to change the storage engines of 
+--echo # tables in db1
+
+--disable_warnings
+source $MYSQLTEST_VARDIR/tmp/mctf.inc;
+--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT  --type=myisam db1
+--enable_warnings
+
+--echo # Note that tablespace will be ignored by db1.t2
+SHOW CREATE TABLE db1.t1;
+SHOW CREATE TABLE db1.t2;
+
+# Perform backup operation
+--replace_column 1 #
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db12.bak';
+--remove_file $MYSQLD_BACKUPDIR/db12.bak
+
+--echo # Fire Trigger
+DELETE FROM db2.t1 WHERE a=3;
+SELECT * FROM db2.t1 WHERE a=3;
+SELECT * FROM db1.t2;
+
+--echo # Note that tablepsace will be ignored because of myisam storage engine
+SHOW CREATE TABLE db1.t2;
+
+--echo # Restore from db1.bak to get back tablespace
+--replace_column 1 #
+RESTORE FROM 'db1.bak' OVERWRITE;
+
+--echo # Verify that tablespace is restored from db1.t2
+SHOW CREATE TABLE db1.t2;
+
+source $MYSQLTEST_VARDIR/tmp/mctf.inc;
+--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT  --type=falcon db1
+
+SHOW CREATE TABLE db1.tpl;
+SHOW CREATE TABLE db1.tph;
+
+# Perform backup operation
+--replace_column 1 #
+BACKUP DATABASE db1, db2 TO 'db12.bak';
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+
+# Perform restore
+--replace_column 1 #
+RESTORE FROM 'db12.bak';
+
+SHOW CREATE TABLE db1.tpl;
+SHOW CREATE TABLE db1.tph;
+
+--echo # Fire Trigger
+DELETE FROM db2.t1 WHERE a=4;
+SELECT * FROM db2.t1 WHERE a=4;
+SELECT * FROM db1.t2;
+
+DROP TABLE db1.tpl;
+DROP TABLE db1.tph;
+DROP TABLE db1.t2;
+DROP VIEW db2.v1;
+--remove_file $MYSQLD_BACKUPDIR/db12.bak
+--remove_file $MYSQLD_BACKUPDIR/db1.bak
+
+--echo # Changing the storage engine back to myisam after restore
+source $MYSQLTEST_VARDIR/tmp/mctf.inc;
+--exec $MYSQL_CONVERT_TABLE_FORMAT -u root -S $MASTER_MYSOCK --port=$MASTER_MYPORT db1
+
+SHOW CREATE TABLE db1.t1;
+
+# Test clean-up section
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+DROP TABLESPACE ts Engine=Falcon;
+

=== added file 'mysql-test/suite/backup/t/backup_intr_errors.test'
--- a/mysql-test/suite/backup/t/backup_intr_errors.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_intr_errors.test	2009-04-09 12:10:27 +0000
@@ -0,0 +1,139 @@
+#
+# This test checks what happens if errors occur during BACKUP/RESTORE shutdown
+# sequence in case of interruption of one of these statements. The errors are
+# triggered using error injection code. They should be reported on server's 
+# error stack after the standard "Query execution was interrupted" error. The
+# latter error should be reported by the interrupted statement.
+#
+
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+call mtr.add_suppression("Backup:");
+call mtr.add_suppression("Restore:");
+
+--echo #
+--echo # Setup
+--echo #
+let $bdir=`SELECT @@backupdir`;
+let $debug= `SELECT @@debug`;
+
+--disable_warnings
+DROP DATABASE IF EXISTS bup_intr;
+--error 0,1
+--remove_file $bdir/bup_intr.bkp
+--enable_warnings
+
+CREATE DATABASE bup_intr;
+USE bup_intr;
+
+CREATE TABLE t1(engine char(6));
+#
+# Table t1 is used in the test loop which will iterate over its rows and
+# change t1's storage engine as indicated. We pick innodb and memory to 
+# trigger use of the default and the snapshot backup/restore drivers.
+#
+INSERT INTO  t1 VALUES ('innodb'),('memory');
+#
+# Table t2 is here so that some table data is always stored in the image
+# and the synchronization point used below is always reached.
+#
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1);
+
+# connection required by backup_restore_interrupt.inc
+--connect (killer,localhost,root,,)
+# The "connect" command implicitly switches to the new session. Switch back.
+--connection default
+
+#
+# Loop over rows in t1 which indicate what storage engine should be used.
+#
+
+while (`SELECT count(*) > 0 FROM bup_intr.t1`)
+{
+
+  # read the next engine and remove it from t1
+  let $engine=`SELECT engine FROM bup_intr.t1 LIMIT 1`;
+  eval DELETE FROM bup_intr.t1 WHERE engine='$engine';
+
+  --echo
+  --echo ########################################
+  --echo ## Testing with $engine engine.
+  --echo ########################################
+  --echo
+
+  # change storage engine of t1
+  eval ALTER TABLE bup_intr.t1 ENGINE=$engine;
+
+  #
+  # Test interruption of BACKUP
+  #
+  let $do_restore=0;
+  # activate error injection code
+  SET SESSION DEBUG="+d,backup_driver_cancel_error";
+  SET SESSION DEBUG="+d,backup_stream_close_error";
+  SET SESSION DEBUG="+d,backup_remove_location_error";
+  #
+  # Test interruption in the middle of BACKUP operation, just before VP
+  # is created.
+  #
+  let $sync_point=before_backup_data_lock;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  # Note that backup_restore_interrupt.inc ends in connection default
+  #--connection default
+  --echo # Reset debug variable to its original value.
+  --disable_query_log
+  eval SET SESSION DEBUG= '$debug';
+  --enable_query_log
+
+  --echo #
+  --echo # Prepare bup_intr.bkp for RESTORE testing. Note that above BACKUP
+  --echo # command should not create the file because it was interrupted.
+  --echo #
+  --replace_column 1 #
+  BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+  DROP DATABASE bup_intr;
+
+  #
+  # Test interruption of RESTORE
+  #
+  let $do_restore=1;
+  # activate error injection code
+  SET SESSION DEBUG="+d,backup_driver_cancel_error";
+  SET SESSION DEBUG="+d,backup_stream_close_error";
+  #
+  # Test interruption of RESTORE when the first block of table data is
+  # sent to a restore driver.
+  #
+  let $sync_point=restore_before_sending_data;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  # Note that backup_restore_interrupt.inc ends in connection default
+  #--connection default
+  --echo # Reset debug variable to its original value.
+  --disable_query_log
+  eval SET SESSION DEBUG= '$debug';
+  --enable_query_log
+
+  --echo #
+  --echo # Restore original database - the interrupted RESTORE statement could
+  --echo # corrupt it.
+  --echo #
+  --replace_column 1 #
+  RESTORE FROM 'bup_intr.bkp' OVERWRITE;
+  --remove_file $bdir/bup_intr.bkp
+
+} # end of the while loop.
+
+--echo #
+--echo # Cleanup
+--echo #
+SET DEBUG_SYNC='reset';
+--disable_warnings
+DROP DATABASE IF EXISTS bup_intr;
+--error 0,1
+--remove_file $bdir/bup_intr.bkp
+--enable_warnings
+

=== modified file 'mysql-test/suite/backup/t/backup_myisam_sync.test'
--- a/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-02-24 20:57:21 +0000
+++ b/mysql-test/suite/backup/t/backup_myisam_sync.test	2009-04-14 13:40:06 +0000
@@ -59,6 +59,14 @@ while ($1)
 SELECT LENGTH(c1) FROM t1;
 CHECKSUM TABLE t1;
 
+--echo
+--echo # Verify that the MyISAM Key Cache is enabled.
+--echo # See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+  FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+  VARIABLE_NAME LIKE 'Key_blocks_%used';
+--echo
+
 --echo Signal BACKUP to finish
 SET DEBUG_SYNC= 'now SIGNAL bup_finish';
 
@@ -84,10 +92,17 @@ connection default;
 remove_file $MYSQLD_BACKUPDIR/bup_myisam_sync.bak;
 SET DEBUG_SYNC= 'RESET';
 
+--echo
+--echo # Verify that the MyISAM Key Cache is still enabled.
+--echo # See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+SELECT SUM(VARIABLE_VALUE) > 0 AS key_cache_is_enabled
+  FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE
+  VARIABLE_NAME LIKE 'Key_blocks_%used';
+--echo
+
 #
 # Cleanup from this test case
 #
---echo
 --echo # final cleanup
 USE test;
 DROP DATABASE mysqltest;

=== added file 'mysql-test/suite/backup/t/backup_namecase-master.opt'
--- a/mysql-test/suite/backup/t/backup_namecase-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_namecase-master.opt	2009-04-01 11:08:48 +0000
@@ -0,0 +1 @@
+--lower_case_table_names=1

=== added file 'mysql-test/suite/backup/t/backup_namecase.test'
--- a/mysql-test/suite/backup/t/backup_namecase.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup/t/backup_namecase.test	2009-04-01 11:08:48 +0000
@@ -0,0 +1,140 @@
+#
+# Test to ensure that RESTORE works on a server with a case insensitive
+# file system when the BACKUP was made on a server with case sensitive
+# file system.
+# 
+# The tests in this file use error injection. A better way to test
+# this scenario is to backup a database with
+# database/table/view/procedure/etc names in upper or camel case on a
+# host with case sensitive file system (e.g., Linux), and then restore
+# on a host with case insensitive file system (e.g., Windows).
+# 
+# WL#4771 will add tests as described above. Once WL#4771 is pushed,
+# it should be considered whether or not this test file can be
+# removed.
+
+--source include/have_debug_sync.inc
+--source include/not_embedded.inc
+
+--echo
+--echo # Create database with tables and views
+--echo
+
+CREATE DATABASE changecase;
+
+CREATE TABLE changecase.t1 (i int);
+INSERT INTO changecase.t1 VALUES (1);
+
+CREATE TABLE changecase.t2 (text varchar(20));
+
+CREATE VIEW changecase.v1 AS SELECT * FROM changecase.t1;
+
+
+--echo
+--echo # Add trigger and procedure
+--echo
+
+DELIMITER ||;
+
+CREATE PROCEDURE changecase.trgmsg(a int)
+BEGIN
+    INSERT INTO changecase.t2(text) VALUES ('Db trigger fired!');
+END;
+||
+
+CREATE TRIGGER changecase.afterins AFTER INSERT ON changecase.t1 FOR EACH ROW 
+CALL trgmsg(1);
+||
+
+CREATE EVENT changecase.ev ON SCHEDULE EVERY 10 second DO 
+BEGIN
+  INSERT INTO changecase.t2(text) VALUES ('Db event fired!');
+END;
+||
+
+DELIMITER ;||
+
+--echo
+--echo # Add user with privileges
+--echo
+
+CREATE USER user_with_grants;
+
+--echo default: Grant user rights to run backup. Revoke SUPER from one user.
+GRANT SELECT ON changecase.t1 TO 'user_with_grants'@'%';
+GRANT SELECT ON changecase.v1 TO 'user_with_grants'@'%';
+GRANT UPDATE ON changecase.* TO 'user_with_grants'@'%';
+GRANT INSERT ON changecase.* TO 'user_with_grants'@'%';
+GRANT SUPER ON *.* TO 'user_with_grants'@'%';
+FLUSH PRIVILEGES;
+
+--echo
+--echo # Show procedure, trigger and event
+--echo
+
+--query_vertical SHOW CREATE PROCEDURE changecase.trgmsg;
+--echo
+--query_vertical SHOW TRIGGERS FROM changecase;
+--echo
+--replace_column 9 #
+--query_vertical SHOW EVENTS IN changecase;
+
+
+--echo
+--echo # BACKUP, drop database and user
+--echo
+
+--replace_column 1 #
+BACKUP DATABASE changecase TO 'uppercase.bup';
+
+DROP DATABASE changecase;
+REVOKE ALL ON *.* FROM 'user_with_grants'@'%';
+
+--echo
+--echo # RESTORE database
+--echo
+
+--echo # Activate debug hook that makes db names upper-case when checking if
+--echo # a grant statement operates on a db that is restored. Should fail
+SET SESSION DEBUG='+d,restore_catalog_uppercase_names_grant';
+--error ER_BACKUP_GRANT_WRONG_DB
+RESTORE FROM 'uppercase.bup';
+SET SESSION DEBUG='-d';
+
+DROP DATABASE changecase;
+
+--echo # Activate debug hook that makes all names upper-case. Should work.
+SET SESSION DEBUG='+d,restore_catalog_uppercase_names';
+--replace_column 1 #
+RESTORE FROM 'uppercase.bup';
+SET SESSION DEBUG='-d';
+
+--echo
+--echo # Check contents of restored database
+--echo
+
+--echo
+SHOW TABLES IN changecase;
+
+--echo
+SELECT * FROM changecase.t1;
+
+--echo
+--echo # Show procedure, trigger and event
+--echo
+
+--query_vertical SHOW CREATE PROCEDURE changecase.trgmsg;
+--echo
+--query_vertical SHOW TRIGGERS FROM changecase;
+--echo
+--replace_column 9 #
+--query_vertical SHOW EVENTS IN changecase;
+
+--echo
+SHOW GRANTS FOR 'user_with_grants'@'%';
+
+--echo
+--echo # Cleanup
+--echo
+DROP DATABASE changecase;
+DROP USER user_with_grants;

=== modified file 'mysql-test/suite/backup/t/backup_triggers_and_events.test'
--- a/mysql-test/suite/backup/t/backup_triggers_and_events.test	2009-02-26 11:21:33 +0000
+++ b/mysql-test/suite/backup/t/backup_triggers_and_events.test	2009-04-22 08:31:38 +0000
@@ -8,7 +8,7 @@
 let $MYSQLD_BACKUPDIR= `select @@backupdir`;
 --disable_warnings
 --error 0,1
-remove_file $MYSQLD_BACKUPDIR/db.bak;
+--remove_file $MYSQLD_BACKUPDIR/db.bak
 --enable_warnings
 
 SET GLOBAL event_scheduler=off;
@@ -118,9 +118,6 @@ delimiter ;||
 BACKUP DATABASE db TO 'db.bak';
 DROP DATABASE db;
 
---echo Enabling event scheduler.
-SET GLOBAL event_scheduler=on;
-
 --connection con1
 
 --echo con1: clearing log table and starting RESTORE operation.
@@ -130,14 +127,23 @@ SET GLOBAL event_scheduler=on;
 # after restore drivers have finished their job but before they have been shoot
 # down.
 
-SET DEBUG_SYNC = 'restore_table_data_before_end SIGNAL waiting WAIT_FOR continue';
+SET DEBUG_SYNC = 'after_backup_start_restore SIGNAL started WAIT_FOR continue';
+SET DEBUG_SYNC = 'restore_table_data_before_end SIGNAL waiting WAIT_FOR finish';
 DELETE FROM test.logt;
 --send RESTORE FROM 'db.bak'
 
 --connection con2
 
+SET DEBUG_SYNC = 'now WAIT_FOR started';
+--echo Enabling event scheduler.
+SET GLOBAL event_scheduler=on;
+# Give it a second to start
+--sleep 1
+
+--echo Get BACKUP going.
 # Record the time when RESTORE has started.
 SELECT now() INTO @start;
+SET DEBUG_SYNC = 'now SIGNAL continue';
 
 --echo con2: checking that there are no triggers and events at the end of RESTORE execution.
 
@@ -155,8 +161,8 @@ INSERT INTO test.t1 VALUES (1);
 
 # This is so that db.ev event has chance to fire if it is not correctly handled
 # (e.g. enabled during table data restore).
---sleep 3
-SET DEBUG_SYNC = 'now SIGNAL continue';
+--sleep 4
+SET DEBUG_SYNC = 'now SIGNAL finish';
 
 --connection con1
 
@@ -169,7 +175,7 @@ SET GLOBAL event_scheduler=off;
 
 -- echo con2: checking that RESTORE took more than 2 secs.
 
-SELECT timediff(now(),@start) > 2;
+SELECT timediff(now(),@start) > 3;
 
 --echo Checking that objects have been restored.
 
@@ -186,26 +192,26 @@ SELECT count(*) FROM db.t1;
 
 # There should be no entries in the log table from the time when RESTORE
 # was running (but there could be entries inserted by event firing *after*
-# RESTORE has completed). We know that RESTORE took at least 3 sec and we 
-# take 2 sec window form the beginning of the operation. This is enough
+# RESTORE has completed). We know that RESTORE took at least 4 sec and we
+# take 3 sec window from the beginning of the operation. This is enough
 # to see db.ev in case it fired during RESTORE operation (this event is sheduled
 # to fire every second).
 
-SELECT * FROM test.logt WHERE db = 'db' AND timediff(ts,@start) < 2;
+SELECT * FROM test.logt WHERE db = 'db' AND timediff(ts,@start) < 3;
 
 --echo Checking that test event and trigger could fire.
 
-# Checking that the trigger has fired.
+# Checking that the test trigger has fired during RESTORE.
 SELECT count(*) > 0 FROM test.logt 
 WHERE db = 'test'
 AND msg LIKE '%trigger fired%'
-AND timediff(ts,@start) < 2;
+AND timediff(ts,@start) < 3;
 
-# Checking that the event has fired.
+# Checking that the test event has fired during RESTORE.
 SELECT count(*) > 0 FROM test.logt 
 WHERE db = 'test'
 AND msg LIKE '%event fired%'
-AND timediff(ts,@start) < 2;
+AND timediff(ts,@start) < 3;
 
 --echo Cleaning up.
 SET DEBUG_SYNC = 'RESET';
@@ -214,4 +220,5 @@ DROP TRIGGER test.trg;
 DROP TABLE test.logt;
 DROP TABLE test.t1;
 DROP DATABASE db;
-remove_file $MYSQLD_BACKUPDIR/db.bak;
+
+--remove_file $MYSQLD_BACKUPDIR/db.bak

=== modified file 'mysql-test/suite/backup/t/disabled.def'
--- a/mysql-test/suite/backup/t/disabled.def	2009-04-01 20:48:42 +0000
+++ b/mysql-test/suite/backup/t/disabled.def	2009-04-03 17:58:04 +0000
@@ -10,5 +10,4 @@
 #
 ##############################################################################
 backup_no_engine              : Bug#36021 2008-04-13 rsomla server crashes when openning table with unknown storage engine
-backup_triggers_and_events    : Bug#37762 2008-07-01 rafal Test fails on remove_file for unknown reasons
 backup_no_data                : Bug#42756 2009-02-11 jorgen Test db state not preserved 

=== added file 'mysql-test/suite/backup_engines/include/backup_restore_interrupt.inc'
--- a/mysql-test/suite/backup_engines/include/backup_restore_interrupt.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/include/backup_restore_interrupt.inc	2009-04-09 12:10:27 +0000
@@ -0,0 +1,114 @@
+#
+# This is a "subroutine" for backup_interrupt.test. It performs the following:
+#
+# 1. Start BACKUP or RESTORE statement and use a synchronization point
+#    to stop it in the middle of execution.
+# 2. In another connection, wait for the statement to reach the synchronization
+#    point, and then KILL it.
+# 3. Signal the stopped BACKUP/RESTORE statement so that it resumes execution
+#    after being killed.
+# 4. Check the error response from the statement, contents of the error stack
+#    and backup logs.
+#
+# Variable $do_restore determines whether BACKUP or RESTORE is executed. The
+# synchronization point to use is stored in $sync_point. 
+#
+# This script uses the following assumptions, which must be satisfied by 
+# its user:
+#
+# - $bdir holds the current value of @@backupdir variable.
+# - There is a second connection named 'killer'.
+# - There exists database called 'bup_intr'.
+# - If $do_restore = 1 then $bdir/bup_intr.bkp should contain valid backup 
+#   image.
+#
+
+let $command= BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+
+if ($do_restore)
+{
+  let $command= RESTORE FROM 'bup_intr.bkp';
+}
+
+--echo 
+--echo ######################################################################
+--echo #
+--echo # Testing interruption of command $command
+--echo # at synchronization point $sync_point.
+--echo #
+--echo ######################################################################
+--echo 
+--connection default
+
+let $id=`select connection_id()`;
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+eval SET DEBUG_SYNC='$sync_point SIGNAL here WAIT_FOR go';
+#
+# Arrange for 'here' signal to be always sent at the end of BACKUP/RESTORE 
+# operation (in the destructor of backup/restore context class). This way
+# test will not hang waiting for the signal even if $sync_point is invalid 
+# or never hit. The fact that we missed the requested synchronization point
+# will be detected with a SELECT from I_S.PROCESSLIST (see below). Also,
+# the reply from BACKUP/RESTORE will not be the expected ER_QUERY_INTERRUPTED
+# error in most cases.
+#
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+
+--echo #
+--echo # Start the command.
+--echo #
+--send
+eval $command;
+
+  --connection killer
+
+  --echo #
+  --echo # Wait for the command to reach its synchronization point,
+  --echo # then kill it.
+  --echo #
+  SET DEBUG_SYNC='now WAIT_FOR here';
+#
+# SELECTs from I_S.PROCESSLIST commented out because such selects are unstable
+# in the current server (v6.0 as of Mar 2009). See bug#37990, bug#41346, 
+# bug#43357. When I_S quality is improved, the following lines could be 
+# re-enabled increasing sensitivity of this test to potential problems.
+#
+#  --replace_regex /id=[0-9]+/id=<query id>/
+#  eval SELECT state FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id=$id;
+  --replace_regex /QUERY [0-9]+/QUERY <query id>/
+  eval KILL QUERY $id;
+  # The signal is not strongly needed as the sync point terminates from KILL.
+  # But KILL is not always reliable. To be safe, signal anyway.
+  SET DEBUG_SYNC='now SIGNAL go';
+
+--connection default
+
+--echo #
+--echo # Reap the command and show results.
+--echo #
+--error ER_QUERY_INTERRUPTED
+reap;
+--replace_column 2 <error-code>
+# One error message contains file path - mask it out.
+--replace_regex /Error on delete of '.*'/Error on delete of <backup image path>/
+SHOW WARNINGS;
+
+--echo #
+--echo # Examine backup logs.
+--echo #
+--echo # FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+--echo # seen in backup_progress table and backup_history table will be empty.
+--echo # When the bug is fixed the output below will change and the result file
+--echo # should be modifed accordingly.
+--echo #
+SELECT object, error_num, notes FROM mysql.backup_progress;
+query_vertical SELECT * FROM mysql.backup_history;
+
+# check that backup image file was removed
+if (!$do_restore)
+{
+  --error 1
+  --remove_file $bdir/bup_intr.bkp
+}

=== added file 'mysql-test/suite/backup_engines/r/backup_interruption.result'
--- a/mysql-test/suite/backup_engines/r/backup_interruption.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/r/backup_interruption.result	2009-03-23 18:46:10 +0000
@@ -0,0 +1,1822 @@
+SHOW VARIABLES LIKE 'storage_engine';
+Variable_name	Value
+storage_engine	#
+call mtr.add_suppression("Operation aborted");
+DROP DATABASE IF EXISTS bup_intr;
+CREATE DATABASE bup_intr;
+USE bup_intr;
+CREATE TABLE t1(a int);
+INSERT INTO  t1 VALUES (1),(2),(3);
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_command.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_command SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_prepare.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_prepare SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_logger_init.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_logger_init SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_common_prepare.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_common_prepare SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_privileges.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_privileges SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_single_op.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_single_op SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_ddl_block.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_ddl_block SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_stream_open.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_stream_open SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_catalog.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_catalog SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point after_backup_start_backup.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='after_backup_start_backup SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_do_backup.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_do_backup SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_meta.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_meta SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point backup_before_write_preamble.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='backup_before_write_preamble SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_init.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_init SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_prepare.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_prepare SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_lock.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_lock SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_unlock.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_unlock SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point after_backup_binlog.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='after_backup_binlog SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+backup kernel	0	vp time
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_data_finish.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_data_finish SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+backup kernel	0	vp time
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command BACKUP DATABASE bup_intr TO 'bup_intr.bkp'
+# at synchronization point before_backup_summary.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_backup_summary SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+backup kernel	0	validity point
+backup kernel	0	vp time
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+backup_id
+#
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_prepare.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_prepare SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_logger_init.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_logger_init SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_common_prepare.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_common_prepare SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_stream_open.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_stream_open SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_catalog.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_catalog SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_read_header.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_read_header SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_read_catalog.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_read_catalog SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_binlog.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_binlog SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point after_backup_start_restore.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='after_backup_start_restore SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_fkey_disable.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_fkey_disable SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_read_metadata.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_read_metadata SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_locks_tables.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_locks_tables SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_table_data.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_table_data SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_drivers_create.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_drivers_create SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_drivers_init.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_drivers_init SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_read_data_chunk.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_read_data_chunk SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_before_sending_data.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_before_sending_data SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point restore_table_data_before_end.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='restore_table_data_before_end SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_triggers.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_triggers SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+Warning	<error-code>	Operation aborted - data might be corrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+DROP DATABASE bup_intr;
+
+######################################################################
+#
+# Testing interruption of command RESTORE FROM 'bup_intr.bkp'
+# at synchronization point before_restore_completed.
+#
+######################################################################
+
+PURGE BACKUP LOGS;
+SET DEBUG_SYNC='reset';
+SET DEBUG_SYNC='before_restore_completed SIGNAL here WAIT_FOR go';
+SET DEBUG_SYNC='backup_restore_ctx_dtor SIGNAL here';
+#
+# Start the command.
+#
+RESTORE FROM 'bup_intr.bkp';
+#
+# Wait for the command to reach its synchronization point,
+# then kill it.
+#
+SET DEBUG_SYNC='now WAIT_FOR here';
+KILL QUERY <query id>;
+SET DEBUG_SYNC='now SIGNAL go';
+#
+# Reap the command and show results.
+#
+ERROR 70100: Query execution was interrupted
+SHOW WARNINGS;
+Level	Code	Message
+Error	<error-code>	Query execution was interrupted
+#
+# Examine backup logs.
+#
+# FIXME: Until BUG#39924 is fixed, change to BUP_CANCEL state will not be
+# seen in backup_progress table and backup_history table will be empty.
+# When the bug is fixed the output below will change and the result file
+# should be modifed accordingly.
+#
+SELECT object, error_num, notes FROM mysql.backup_progress;
+object	error_num	notes
+backup kernel	0	starting
+backup kernel	0	running
+SELECT * FROM mysql.backup_history;
+SET DEBUG_SYNC='reset';
+DROP DATABASE IF EXISTS bup_intr;

=== added file 'mysql-test/suite/backup_engines/t/backup_interruption.test'
--- a/mysql-test/suite/backup_engines/t/backup_interruption.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_interruption.test	2009-03-16 14:38:05 +0000
@@ -0,0 +1,263 @@
+#
+# This test checks that BACKUP/TESTORE commands behave correctly when
+# interrupted. The test strategy is as follows:
+#
+# 1. Start BACKUP or RESTORE statement and use a synchronization point
+#    to stop it in the middle of execution.
+# 2. In another connection, wait for the statement to reach the synchronization
+#    point, and then KILL it.
+# 3. Signal the stopped BACKUP/RESTORE statement so that it resumes execution
+#    after being killed.
+# 4. Check the error response from the statement, contents of the error stack
+#    and backup logs.
+# 
+# Above 4 steps are performed inside backup_restore_interrupt.inc "subroutine"
+# which is executed from this script for various synchronization points inside
+# BACKUP and RESTORE commands.
+#
+# Note: Because of BUG#39924, an interruption is not traced within 
+# backup_progress log and backup_history log entry for an interrupted statement
+# is not written. When the bug is fixed, the output of this test will change 
+# and the result file should be updated after careful inspection.
+#
+--source include/not_embedded.inc
+--source suite/backup_engines/include/backup_engine.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+call mtr.add_suppression("Operation aborted");
+
+#
+# Setup
+#
+
+let $bdir=`SELECT @@backupdir`;
+
+--disable_warnings
+DROP DATABASE IF EXISTS bup_intr;
+--error 0,1
+--remove_file $bdir/bup_intr.bkp
+--enable_warnings
+
+CREATE DATABASE bup_intr;
+USE bup_intr;
+
+CREATE TABLE t1(a int);
+INSERT INTO  t1 VALUES (1),(2),(3);
+
+# connection required by backup_restore_interrupt.inc
+--connect (killer,localhost,root,,)
+
+#
+# Test BACKUP interruptions.
+#
+
+let $do_restore=0;
+
+# at the very beginning		
+let $sync_point= before_backup_command;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# before preparations
+let $sync_point= before_backup_prepare;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# during preparations
+  # before logger initialization
+  let $sync_point= before_backup_logger_init;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  
+  # before common preparations
+  let $sync_point= before_backup_common_prepare;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # during common preparations
+    # before checking privileges
+    let $sync_point= before_backup_privileges;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+  
+    # before checking that no other BACKUP/RESTORE is running
+    let $sync_point= before_backup_single_op;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # before blocking DDLs
+    let $sync_point= before_backup_ddl_block;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before openning the stream
+  let $sync_point= before_backup_stream_open;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before creating catalogue
+  let $sync_point= before_backup_catalog;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# before populating backup catalogue
+let $sync_point= after_backup_start_backup;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# before do_backup
+let $sync_point= before_do_backup;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# inside do_backup
+  # before preamble is written
+  let $sync_point= before_backup_meta;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  let $sync_point= backup_before_write_preamble;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before write_table_data
+  let $sync_point= before_backup_data;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # inside write_table_data
+    # before initial phase
+    let $sync_point=before_backup_data_init;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # before prepare phase
+    let $sync_point=before_backup_data_prepare;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # before sync phase
+    let $sync_point=before_backup_data_lock;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # inside sync phase
+    let $sync_point=before_backup_data_unlock;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # after sync phase
+    let $sync_point=after_backup_binlog;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+    # before final phase
+    let $sync_point=before_backup_data_finish;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before writing summary section
+  let $sync_point= before_backup_summary;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# Note: after the call to do_backup() the operation is completed
+# and terminates successfully, even if interruption has happened 
+# after its completion.
+
+#
+# Test RESTORE interruptions.
+#
+
+--replace_column 1 #
+BACKUP DATABASE bup_intr TO 'bup_intr.bkp';
+DROP DATABASE bup_intr;
+
+let $do_restore=1;
+
+# before preparations
+let $sync_point= before_restore_prepare;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# during preparations
+  # before logger initialization
+  let $sync_point= before_restore_logger_init;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  
+  # before common preparations
+  let $sync_point= before_restore_common_prepare;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  
+  # before openning the stream
+  let $sync_point= before_restore_stream_open;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before creating catalogue
+  let $sync_point= before_restore_catalog;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before reading header
+  let $sync_point= before_restore_read_header;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before reading catalogue
+  let $sync_point= before_restore_read_catalog;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before writing incident event
+  let $sync_point= before_restore_binlog;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# before do_restore
+let $sync_point= after_backup_start_restore;
+--source suite/backup_engines/include/backup_restore_interrupt.inc
+
+# inside do_restore
+
+  # before disabling fkey constraints
+  let $sync_point= before_restore_fkey_disable;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # before reading metadata and creating objects
+  let $sync_point= before_restore_read_metadata;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+  # Note: now we pass the point when database is created during RESTORE,
+  # thus we need to DROP it after each RESTORE.
+
+  # before locking tables
+  let $sync_point= before_restore_locks_tables;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  DROP DATABASE bup_intr;
+
+  # before restoring table data
+  let $sync_point= before_restore_table_data;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  DROP DATABASE bup_intr;
+
+  # inside restore_table_data
+    # before creating restore drivers
+    let $sync_point= restore_before_drivers_create;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+    DROP DATABASE bup_intr;
+
+    # before initializing the drivers
+    let $sync_point= restore_before_drivers_init;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+    DROP DATABASE bup_intr;
+
+    # before reading table data chunk
+    let $sync_point= restore_before_read_data_chunk;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+    DROP DATABASE bup_intr;
+
+    # before sending the data to a driver
+    let $sync_point= restore_before_sending_data;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+    DROP DATABASE bup_intr;
+
+    # before shutting down the drivers
+    let $sync_point= restore_table_data_before_end;
+    --source suite/backup_engines/include/backup_restore_interrupt.inc
+    DROP DATABASE bup_intr;
+
+  # before restoring triggers
+  let $sync_point= before_restore_triggers;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+  DROP DATABASE bup_intr;
+
+  # before reading image summary block
+  let $sync_point= before_restore_completed;
+  --source suite/backup_engines/include/backup_restore_interrupt.inc
+
+
+#
+# Cleanup
+# 
+
+SET DEBUG_SYNC='reset';
+--disable_warnings
+DROP DATABASE IF EXISTS bup_intr;
+--error 0,1
+--remove_file $bdir/bup_intr.bkp
+--enable_warnings
+

=== modified file 'mysql-test/suite/backup_engines/t/backup_partition.test'
--- a/mysql-test/suite/backup_engines/t/backup_partition.test	2009-03-05 20:05:02 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_partition.test	2009-03-12 19:50:43 +0000
@@ -10,12 +10,10 @@
 
 --source include/have_partition.inc
 --source include/not_embedded.inc
-
+--source suite/backup_engines/include/backup_engine.inc
 #
-# BUG#43028 : Partitioning has issues in archive. Remove the following directives
-#             when this bug is fixed.
+# The archive engine does not support partitioning using indexes. 
 #
---source suite/backup_engines/include/backup_engine.inc
 --source suite/backup_engines/include/not_archive.inc
 
 let $bdir=`select @@backupdir`;

=== modified file 'mysql-test/suite/backup_engines/t/backup_partitioning.test'
--- a/mysql-test/suite/backup_engines/t/backup_partitioning.test	2009-03-10 08:45:35 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_partitioning.test	2009-03-12 19:50:43 +0000
@@ -10,10 +10,8 @@
 --source include/have_partition.inc
 --source suite/backup_engines/include/backup_engine.inc
 --source suite/backup_engines/include/not_csv.inc
-
 #
-# BUG#43030 : Partitioning has issues in archive. Remove the following directive
-#             when this bug is fixed.
+# The archive engine does not support partitioning using indexes. 
 #
 --source suite/backup_engines/include/not_archive.inc
 

=== added directory 'mysql-test/suite/backup_extra'
=== added directory 'mysql-test/suite/backup_extra/include'
=== added directory 'mysql-test/suite/backup_extra/r'
=== added file 'mysql-test/suite/backup_extra/r/backup_consistency_falcon.result'
--- a/mysql-test/suite/backup_extra/r/backup_consistency_falcon.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_extra/r/backup_consistency_falcon.result	2009-03-31 12:29:58 +0000
@@ -0,0 +1,2 @@
+# Executing RQG test. See rqg.out in the temp dir for output.
+CREATE DATABASE test;

=== added file 'mysql-test/suite/backup_extra/r/backup_consistency_innodb.result'
--- a/mysql-test/suite/backup_extra/r/backup_consistency_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_extra/r/backup_consistency_innodb.result	2009-03-31 12:29:58 +0000
@@ -0,0 +1,2 @@
+# Executing RQG test. See rqg.out in the temp dir for output.
+CREATE DATABASE test;

=== added directory 'mysql-test/suite/backup_extra/t'
=== added file 'mysql-test/suite/backup_extra/t/backup_consistency.inc'
--- a/mysql-test/suite/backup_extra/t/backup_consistency.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_extra/t/backup_consistency.inc	2009-03-31 14:18:21 +0000
@@ -0,0 +1,12 @@
+let $grammar= $RQG_HOME/conf/invariant.yy;
+let $gendata= $RQG_HOME/conf/invariant.zz;
+let $reporter= BackupAndRestoreInvariant;
+let $validator= Invariant;
+
+--source include/have_rqg.inc
+
+--echo # Executing RQG test. See rqg.out in the temp dir for output.
+--exec perl $RQG_HOME/gentest.pl --dsn=dbi:mysql:host=127.0.0.1:port=$MASTER_MYPORT:user=root:database=test --engine=$engine --grammar=$grammar --gendata=$gendata --threads=25 --duration=600 --reporter=$reporter --validator=$validator --seed=time >$MYSQL_TMP_DIR/rqg.out 2>&1
+
+CREATE DATABASE test;
+--exit

=== added file 'mysql-test/suite/backup_extra/t/backup_consistency_falcon.test'
--- a/mysql-test/suite/backup_extra/t/backup_consistency_falcon.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_extra/t/backup_consistency_falcon.test	2009-03-31 12:29:58 +0000
@@ -0,0 +1,5 @@
+--source include/have_falcon.inc
+
+let $engine=falcon;
+
+--source suite/backup_extra/t/backup_consistency.inc

=== added file 'mysql-test/suite/backup_extra/t/backup_consistency_innodb.test'
--- a/mysql-test/suite/backup_extra/t/backup_consistency_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/backup_extra/t/backup_consistency_innodb.test	2009-03-31 12:29:58 +0000
@@ -0,0 +1,5 @@
+--source include/have_innodb.inc
+
+let $engine=innodb;
+
+--source suite/backup_extra/t/backup_consistency.inc

=== added file 'mysql-test/suite/falcon/r/falcon_bug_42752.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_42752.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_42752.result	2009-04-30 08:34:47 +0000
@@ -0,0 +1,8 @@
+*** Bug #42752 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE TEMPORARY TABLE t1 (s1 INTEGER, KEY(s1));
+SELECT count(*) FROM t1;
+count(*)
+0
+DROP TABLE t1;

=== added file 'mysql-test/suite/falcon/t/falcon_bug_42752.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_42752.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_42752.test	2009-04-30 08:34:47 +0000
@@ -0,0 +1,31 @@
+--source include/have_falcon.inc
+
+#
+# Bug #42752 Error when creating Falcon temporary table with a key
+#
+--echo *** Bug #42752 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation                                --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test                                          --- #
+# ----------------------------------------------------- #
+CREATE TEMPORARY TABLE t1 (s1 INTEGER, KEY(s1));
+
+# ----------------------------------------------------- #
+# --- Check                                         --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup                                 --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;

=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2009-03-18 21:09:40 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2009-04-21 21:31:05 +0000
@@ -134,8 +134,8 @@ def	mysql	ndb_binlog_index	orig_server_i
 def	mysql	ndb_binlog_index	Position	1	NULL	NO	bigint	NULL	NULL	19	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references		Default	Default
 def	mysql	ndb_binlog_index	schemaops	7	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references		Default	Default
 def	mysql	ndb_binlog_index	updates	5	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references		Default	Default
-def	mysql	plugin	dl	2		NO	char	128	512	NULL	NULL	utf8	utf8_bin	char(128)			select,insert,update,references		Default	Default
-def	mysql	plugin	name	1		NO	char	64	256	NULL	NULL	utf8	utf8_bin	char(64)	PRI		select,insert,update,references		Default	Default
+def	mysql	plugin	dl	2		NO	varchar	128	512	NULL	NULL	utf8	utf8_general_ci	varchar(128)			select,insert,update,references		Default	Default
+def	mysql	plugin	name	1		NO	varchar	64	256	NULL	NULL	utf8	utf8_general_ci	varchar(64)	PRI		select,insert,update,references		Default	Default
 def	mysql	proc	body	11	NULL	NO	longblob	4294967295	4294967295	NULL	NULL	NULL	NULL	longblob			select,insert,update,references		Default	Default
 def	mysql	proc	body_utf8	20	NULL	YES	longblob	4294967295	4294967295	NULL	NULL	NULL	NULL	longblob			select,insert,update,references		Default	Default
 def	mysql	proc	character_set_client	17	NULL	YES	char	32	128	NULL	NULL	utf8	utf8_bin	char(32)			select,insert,update,references		Default	Default
@@ -447,8 +447,8 @@ NULL	mysql	ndb_binlog_index	schemaops	in
 NULL	mysql	ndb_binlog_index	orig_server_id	int	NULL	NULL	NULL	NULL	int(10) unsigned
 NULL	mysql	ndb_binlog_index	orig_epoch	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
 NULL	mysql	ndb_binlog_index	gci	int	NULL	NULL	NULL	NULL	int(10) unsigned
-4.0000	mysql	plugin	name	char	64	256	utf8	utf8_bin	char(64)
-4.0000	mysql	plugin	dl	char	128	512	utf8	utf8_bin	char(128)
+4.0000	mysql	plugin	name	varchar	64	256	utf8	utf8_general_ci	varchar(64)
+4.0000	mysql	plugin	dl	varchar	128	512	utf8	utf8_general_ci	varchar(128)
 4.0000	mysql	proc	db	char	64	256	utf8	utf8_bin	char(64)
 4.0000	mysql	proc	name	char	64	256	utf8	utf8_general_ci	char(64)
 4.0000	mysql	proc	type	enum	9	36	utf8	utf8_general_ci	enum('FUNCTION','PROCEDURE')

=== modified file 'mysql-test/suite/funcs_1/r/is_tables_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_tables_mysql.result	2009-02-16 14:47:53 +0000
+++ b/mysql-test/suite/funcs_1/r/is_tables_mysql.result	2009-04-21 21:31:05 +0000
@@ -330,7 +330,7 @@ TABLE_NAME	plugin
 TABLE_TYPE	BASE TABLE
 ENGINE	MYISAM_OR_MARIA
 VERSION	10
-ROW_FORMAT	Fixed
+ROW_FORMAT	DYNAMIC_OR_PAGE
 TABLE_ROWS	#TBLR#
 AVG_ROW_LENGTH	#ARL#
 DATA_LENGTH	#DL#
@@ -341,7 +341,7 @@ AUTO_INCREMENT	NULL
 CREATE_TIME	#CRT#
 UPDATE_TIME	#UT#
 CHECK_TIME	#CT#
-TABLE_COLLATION	utf8_bin
+TABLE_COLLATION	utf8_general_ci
 CHECKSUM	NULL
 CREATE_OPTIONS	#CO#
 TABLE_COMMENT	#TC#

=== modified file 'mysql-test/suite/rpl/r/rpl_locktrans_innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_locktrans_innodb.result	2009-03-27 22:06:26 +0000
+++ b/mysql-test/suite/rpl/r/rpl_locktrans_innodb.result	2009-04-03 17:58:04 +0000
@@ -565,7 +565,7 @@ INSERT INTO t1 VALUES(1111);
 # Unlock table.
 UNLOCK TABLES;
 # connection conn2.
-# Now the READ lock is taken.
+# Now the READ lock is taken (or timed out).
 # Select from the table.
 SELECT * FROM t1;
 c1
@@ -604,7 +604,7 @@ INSERT INTO t1 VALUES(1111);
 # Unlock table.
 UNLOCK TABLES;
 # connection conn2.
-# Now the READ lock is taken.
+# Now the READ lock is taken (or timed out).
 # Select from the table.
 SELECT * FROM t1;
 c1

=== modified file 'mysql-test/t/myisam_keycache_coverage.test'
--- a/mysql-test/t/myisam_keycache_coverage.test	2009-03-06 11:24:26 +0000
+++ b/mysql-test/t/myisam_keycache_coverage.test	2009-04-14 13:40:06 +0000
@@ -3,6 +3,7 @@
 --echo #
 
 --source include/have_debug.inc
+let $debug= `SELECT @@debug`;
 
 --disable_warnings
 DROP TABLE IF EXISTS t1;
@@ -18,7 +19,7 @@ INSERT INTO t1 SELECT * FROM t1;
 --echo #
 --echo # Positive tests.
 --echo #
-SELECT COUNT(*) FROM t1 WHERE c2 < 5;
+SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
 LOAD INDEX INTO CACHE t1;
 UPDATE t1 SET c2=2;
 
@@ -30,43 +31,42 @@ FLUSH TABLE t1;
 --echo #
 --echo # Inject error key_cache_read_block_error
 --echo #
-#
-# I have seen the below SELECT to succeed from time to time,
-# though it shall fail due to the injected error. As far as I undestand,
-# the only way for this to happen is that SELECT does not use the index.
-# Since the problem is random, I add an EXPLAIN here, to see if this
-# does indeed happen. If it shows a result difference from time to time,
-# then perhaps FLUSH TABLE t1 does not always work reliably.
-# In addition to the EXPLAIN, which is here to prove the assumption,
-# I add FORCE INDEX to keep the SELECT failing, which is the whole
-# purpose of this test.
-#
-EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 < 5;
-SET debug='d,key_cache_read_block_error';
---replace_regex /'.*\//'/
+SET debug='+d,key_cache_read_block_error';
+--replace_regex /'.*[\/\\]/'/
 --error 126
 SELECT COUNT(*) FROM t1 FORCE INDEX(i1) WHERE c2 < 5;
+--echo # Reset debug variable to its original value.
+--disable_query_log
+eval SET debug= '$debug';
+--enable_query_log
 FLUSH TABLE t1;
 
 --echo #
 --echo # Inject error key_cache_insert_block_error
 --echo #
-SET debug='d,key_cache_insert_block_error';
+SET debug='+d,key_cache_insert_block_error';
 LOAD INDEX INTO CACHE t1;
+--echo # Reset debug variable to its original value.
+--disable_query_log
+eval SET debug= '$debug';
+--enable_query_log
 FLUSH TABLE t1;
 
 --echo #
 --echo # Inject error key_cache_write_block_error
 --echo #
-SET debug='d,key_cache_write_block_error';
---replace_regex /'.*\//'/
+SET debug='+d,key_cache_write_block_error';
+--replace_regex /'.*[\/\\]/'/
 --error 126
 UPDATE t1 SET c2=1;
+--echo # Reset debug variable to its original value.
+--disable_query_log
+eval SET debug= '$debug';
+--enable_query_log
 FLUSH TABLE t1;
 
 --echo #
 --echo # Cleanup
 --echo #
-SET debug='';
 DROP TABLE t1;
 

=== modified file 'mysql-test/t/plugin.test'
--- a/mysql-test/t/plugin.test	2009-03-28 00:27:25 +0000
+++ b/mysql-test/t/plugin.test	2009-04-22 22:12:25 +0000
@@ -78,3 +78,4 @@ set session sql_mode=@old_sql_mode;
 set session old=bla;
 
 UNINSTALL PLUGIN example;
+

=== added file 'mysql-test/t/plugin_notembedded-master.opt'
--- a/mysql-test/t/plugin_notembedded-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_notembedded-master.opt	2009-04-16 15:17:31 +0000
@@ -0,0 +1 @@
+$EXAMPLE_PLUGIN_OPT

=== added file 'mysql-test/t/plugin_notembedded.test'
--- a/mysql-test/t/plugin_notembedded.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/plugin_notembedded.test	2009-04-16 15:17:31 +0000
@@ -0,0 +1,21 @@
+--source include/have_example_plugin.inc
+--source include/not_embedded.inc
+
+--error 1193
+SELECT @@global.example_enum_var = 'e2';
+
+INSTALL PLUGIN example SONAME 'ha_example.so';
+
+SELECT @@global.example_enum_var = 'e2';
+
+--echo #
+--echo # Bug#44137: Transactional DDL locking broke dynamic plugins
+--echo #
+--echo # Try to restart the server - plugin should be loaded after restart
+--echo #
+
+--source include/restart_mysqld.inc
+SELECT @@global.example_enum_var = 'e2';
+
+UNINSTALL PLUGIN example;
+

=== modified file 'mysys/mf_keycache.c'
--- a/mysys/mf_keycache.c	2009-03-17 20:07:27 +0000
+++ b/mysys/mf_keycache.c	2009-04-16 10:14:49 +0000
@@ -765,6 +765,13 @@ void end_key_cache(KEY_CACHE *keycache, 
                         (ulong) keycache->global_cache_r_requests,
                         (ulong) keycache->global_cache_read));
 
+  /*
+    Reset these values to be able to detect a disabled key cache.
+    See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+  */
+  keycache->blocks_used= 0;
+  keycache->blocks_unused= 0;
+
   if (cleanup)
   {
     pthread_mutex_destroy(&keycache->cache_lock);
@@ -2606,7 +2613,10 @@ uchar *key_cache_read(KEY_CACHE *keycach
       /* Cache could be disabled in a later iteration. */
       
       if (!keycache->can_be_used)
-	goto no_key_cache;
+      {
+        KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used"));
+        goto no_key_cache;
+      }
       /* Start reading at the beginning of the cache block. */
       filepos-= offset;
       /* Do not read beyond the end of the cache block. */
@@ -2726,6 +2736,7 @@ uchar *key_cache_read(KEY_CACHE *keycach
     } while ((length-= read_length));
     goto end;
   }
+  KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized"));
 
 no_key_cache:
   /* Key cache is not used */
@@ -2746,6 +2757,7 @@ end:
     dec_counter_for_resize_op(keycache);
     keycache_pthread_mutex_unlock(&keycache->cache_lock);
   }
+  DBUG_PRINT("exit", ("error: %d", error ));
   DBUG_RETURN(error ? (uchar*) 0 : start);
 }
 

=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql	2009-03-18 21:09:40 +0000
+++ b/scripts/mysql_system_tables.sql	2009-04-17 14:46:18 +0000
@@ -22,7 +22,7 @@ set @had_user_table= @@warning_count != 
 CREATE TABLE IF NOT EXISTS func (  name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin   comment='User defined functions';
 
 
-CREATE TABLE IF NOT EXISTS plugin ( name char(64) binary DEFAULT '' NOT NULL, dl char(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='MySQL plugins';
+CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl varchar(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci comment='MySQL plugins';
 
 
 CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(64) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) CHARACTER SET utf8 comment='MySQL Foreign Servers table';

=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql	2009-03-20 16:14:49 +0000
+++ b/scripts/mysql_system_tables_fix.sql	2009-04-17 14:46:18 +0000
@@ -255,9 +255,9 @@ SET GLOBAL slow_query_log = @old_log_sta
 #
 
 ALTER TABLE plugin
-  MODIFY name char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
-  MODIFY dl char(128) COLLATE utf8_bin NOT NULL DEFAULT '',
-  CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;
+  MODIFY name varchar(64) COLLATE utf8_general_ci NOT NULL DEFAULT '',
+  MODIFY dl varchar(128) COLLATE utf8_general_ci NOT NULL DEFAULT '',
+  CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
 
 #
 # Detect whether we had Create_view_priv
@@ -607,3 +607,4 @@ UPDATE user SET Create_tablespace_priv =
 flush privileges;
 
 ALTER TABLE backup_history ADD COLUMN backup_file_path VARCHAR (512) NOT NULL DEFAULT '' COMMENT 'The full path to the backup image file' AFTER backup_file;
+

=== modified file 'sql/backup/backup_engine.h'
--- a/sql/backup/backup_engine.h	2009-02-13 13:25:43 +0000
+++ b/sql/backup/backup_engine.h	2009-03-25 13:21:35 +0000
@@ -495,7 +495,7 @@ public:
    and the buffer can be re-used for further transfers. If method returns
    PROCESSING, it means that the request was accepted but is not
    completed yet. The buffer will not be used for other purposes until a further
-   call to @c get_data() with the same buffer as argument returns OK.
+   call to @c send_data() with the same buffer as argument returns OK.
 
    @param  buf   (in) buffer filled with backup data. Fields @c size,
                  @c table_num and @c last are set
@@ -518,6 +518,11 @@ public:
    @retval ERROR An error has happened. The request is cancelled and the buffer
                  can be used for other transfers.
 
+   @note
+   Reporting ERROR means that restore process has been interrupted and can not 
+   be continued. The driver is assumed to be in error state and backup kernel 
+   will not call any of its methods except for @c free().
+
    @see @c Buffer class.
   */
 

=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h	2009-02-20 16:40:19 +0000
+++ b/sql/backup/backup_kernel.h	2009-03-16 14:38:05 +0000
@@ -70,6 +70,7 @@ public:
   ~Backup_restore_ctx();
 
   bool is_valid() const;
+  bool is_killed() const;
   ulonglong op_id() const;
 
   Backup_info*  prepare_for_backup(String *location, 
@@ -208,6 +209,13 @@ bool Backup_restore_ctx::is_valid() cons
   return m_error == 0;
 }
 
+/// Check if the operation has been interrupted.
+inline
+bool Backup_restore_ctx::is_killed() const
+{
+  return m_thd->killed;
+}
+
 /// Return global id of the backup/restore operation.
 inline
 ulonglong Backup_restore_ctx::op_id() const

=== modified file 'sql/backup/be_default.cc'
--- a/sql/backup/be_default.cc	2009-02-13 13:25:43 +0000
+++ b/sql/backup/be_default.cc	2009-03-25 13:21:35 +0000
@@ -845,7 +845,11 @@ result_t Restore::send_data(Buffer &buf)
     }
     if (write_row)
     {
+      /* Error injection. */
+      DBUG_EXECUTE_IF("Restore__send_data_write_error",
+                      last_write_res= -1; goto write_skip;);
       last_write_res = hdl->ha_write_row(cur_table->record[0]);
+      IF_DBUG(write_skip:); /* Label for error injection. */
       DBUG_PRINT("backup_default_write", ("%d", last_write_res));
 
       /*

=== modified file 'sql/backup/be_default.h'
--- a/sql/backup/be_default.h	2008-12-18 21:46:36 +0000
+++ b/sql/backup/be_default.h	2009-03-16 14:38:05 +0000
@@ -70,6 +70,7 @@ public:
     { 
       mode= CANCEL;
       cleanup();
+      DBUG_EXECUTE_IF("backup_driver_cancel_error", return backup::ERROR;);
       return backup::OK;
     }
     /// Return table list containing all tables
@@ -148,6 +149,7 @@ public:
     { 
       mode= CANCEL;
       cleanup();
+      DBUG_EXECUTE_IF("backup_driver_cancel_error", return backup::ERROR;);
       return backup::OK;
     }
     void free() { delete this; };

=== modified file 'sql/backup/be_snapshot.h'
--- a/sql/backup/be_snapshot.h	2008-12-18 21:46:36 +0000
+++ b/sql/backup/be_snapshot.h	2009-03-16 14:38:05 +0000
@@ -54,6 +54,7 @@ public:
     { 
       m_cancel= TRUE;
       cleanup();
+      DBUG_EXECUTE_IF("backup_driver_cancel_error", return backup::ERROR;);
       return backup::OK;
     }
 private:

=== modified file 'sql/backup/be_thread.cc'
--- a/sql/backup/be_thread.cc	2009-02-13 13:25:43 +0000
+++ b/sql/backup/be_thread.cc	2009-03-16 14:38:05 +0000
@@ -238,6 +238,7 @@ end2:
   Constructor for Locking_thread_st structure.
 */
 Locking_thread_st::Locking_thread_st()
+ :m_thread_started(FALSE)
 {
   /*
     Initialize the thread mutex and cond variable.
@@ -257,13 +258,15 @@ Locking_thread_st::Locking_thread_st()
 Locking_thread_st::~Locking_thread_st()
 {
   /*
-    If the locking thread is not finished, we need to wait until
-    it is finished so that we can destroy the mutexes safely knowing
-    the locking thread won't access them.
+    If the locking thread has been started we need to kill it. We also need to 
+    wait until it dies before destroying the mutexes so that the locking thread 
+    won't access them any more.
   */
-  kill_locking_thread();
-  wait_until_locking_thread_dies();
-
+  if (m_thread_started)
+  {
+    kill_locking_thread();
+    wait_until_locking_thread_dies();
+  }
   /*
     Destroy the thread mutexes and cond variables.
   */
@@ -290,6 +293,7 @@ result_t Locking_thread_st::start_lockin
   if (pthread_create(&th, &connection_attrib,
                      backup_thread_for_locking, this))
     SET_STATE_TO_ERROR_AND_DBUG_RETURN;
+  m_thread_started= TRUE;
   DBUG_RETURN(backup::OK);
 }
 
@@ -303,6 +307,11 @@ result_t Locking_thread_st::start_lockin
 void Locking_thread_st::kill_locking_thread()
 {
   DBUG_ENTER("Locking_thread_st::kill_locking_thread");
+
+  // Nothing to do if the locking thread has not been started.
+  if (!m_thread_started)
+    DBUG_VOID_RETURN;
+
   pthread_mutex_lock(&THR_LOCK_caller);
   if (lock_state == LOCK_ERROR)
     THD_SET_PROC_INFO(m_thd, "error in the locking thread");
@@ -334,6 +343,10 @@ void Locking_thread_st::kill_locking_thr
 */
 void Locking_thread_st::wait_until_locking_thread_dies()
 {
+  // Nothing to do if the locking thread has not been started.
+  if (!m_thread_started)
+    return;
+
   pthread_mutex_lock(&THR_LOCK_caller);
   if (lock_state != LOCK_DONE)
   {
@@ -347,4 +360,6 @@ void Locking_thread_st::wait_until_locki
   }
   else
     pthread_mutex_unlock(&THR_LOCK_caller);
+
+  m_thread_started= FALSE;
 }

=== modified file 'sql/backup/be_thread.h'
--- a/sql/backup/be_thread.h	2008-12-18 21:46:36 +0000
+++ b/sql/backup/be_thread.h	2009-03-16 14:38:05 +0000
@@ -43,6 +43,12 @@ pthread_handler_t backup_thread_for_lock
   The Backup_thread structure contains a mutex and condition variable
   for using a thread to open and lock the tables. This is meant to be a
   generic class that can be used elsewhere for opening and locking tables.
+
+  @note This class correctly handles the separate locking thread. However, 
+  the class itself is *not* multi-thread safe. An instance of Locking_thread_st
+  should be used by one thread only. In particular, calling 
+  @c start_locking_thread() from one thread and @c kill_locking_thread() from
+  another thread running in parallel is not guaranteed to work.
 */
 struct Locking_thread_st
 {
@@ -60,6 +66,8 @@ public:
   LOCK_STATE lock_state;           ///< Current state of the lock call
   THD *m_thd;                      ///< Pointer to current thread struct.
   String thd_name;                 ///< Name of locking thread
+  /// Indicates if the locking thread has been started.
+  my_bool m_thread_started;
 
   result_t start_locking_thread(const char *tname);
   void kill_locking_thread();

=== modified file 'sql/backup/data_backup.cc'
--- a/sql/backup/data_backup.cc	2009-02-03 07:48:09 +0000
+++ b/sql/backup/data_backup.cc	2009-04-03 19:26:07 +0000
@@ -544,7 +544,8 @@ int write_table_data(THD* thd, Backup_in
   List<Scheduler::Pump>  inactive;  // list of images not yet being created
 
   // keeps maximal init size for images in inactive list
-  size_t      max_init_size=0;
+  size_t  max_init_size=0;
+  bool    commits_blocked= FALSE;   // indicates if commit blocker is active
 
   DBUG_PRINT("backup_data",("initializing scheduler"));
 
@@ -558,13 +559,12 @@ int write_table_data(THD* thd, Backup_in
       continue;
 
     Scheduler::Pump *p= new Scheduler::Pump(*i, s);
-
     if (!p)
     {
       log.report_error(ER_OUT_OF_RESOURCES);
       goto error;
     }
-    if (!p->is_valid())
+    if (log.report_killed() || !p->is_valid())
     {
       log.report_error(ER_BACKUP_CREATE_BACKUP_DRIVER,p->m_name);
       delete p;
@@ -684,7 +684,11 @@ int write_table_data(THD* thd, Backup_in
       non-transactional tables and pass that to block_commits().
     */
     int error= 0;
-    error= block_commits(thd, NULL);
+
+    if (!(error= block_commits(thd, NULL)))
+      commits_blocked= TRUE;
+    if (log.report_killed())
+      goto error;
     if (error)
     {
       log.report_error(ER_BACKUP_SYNCHRONIZE);
@@ -702,6 +706,12 @@ int write_table_data(THD* thd, Backup_in
     
     DBUG_PRINT("backup_data",("-- SYNC PHASE --"));
 
+    /*
+      Before proceeding, check if the process is interrupted.
+    */
+    if (log.report_killed())
+      goto error;
+
     log.report_state(BUP_VALIDITY_POINT);
     /*
       This breakpoint is used to assist in testing state changes for
@@ -715,13 +725,18 @@ int write_table_data(THD* thd, Backup_in
     */
 
     DEBUG_SYNC(thd, "before_backup_data_lock");
+    /*
+      Note: we do not detect/react to process interruptions during the 
+      synchronization. We let the protocol to go through and check for
+      possible interruptions only at the end, i.e., after sch.unlock().
+    */ 
     if (sch.lock())    // logs errors
       goto error;
 
     save_vp_info(info);
 
     DEBUG_SYNC(thd, "before_backup_data_unlock");
-    if (sch.unlock())    // logs errors
+    if (sch.unlock() || log.report_killed())    // logs errors
       goto error;
 
     /*
@@ -729,6 +744,9 @@ int write_table_data(THD* thd, Backup_in
     */
     DEBUG_SYNC(thd, "before_backup_unblock_commit");
     unblock_commits(thd);
+    commits_blocked= FALSE;
+    if (log.report_killed())
+      goto error;
 
 
     report_vp_info(info);
@@ -755,6 +773,8 @@ int write_table_data(THD* thd, Backup_in
 
  error:
 
+  if (commits_blocked)
+    unblock_commits(thd);
   DBUG_RETURN(ERROR);
 }
 
@@ -811,10 +831,14 @@ public:
   Pick next backup pump and call its @c pump() method.
 
   Method updates statistics of number of drivers in each phase which is used
-  to detect end of a backup process.
+  to detect end of a backup process. A check for interruption is done each time
+  this method is called.
  */
 int Scheduler::step()
 {
+  if (m_log.report_killed())
+    return ER_QUERY_INTERRUPTED;
+
   // Pick next driver to pump data from.
 
   Pump_iterator p(*this);
@@ -927,7 +951,7 @@ int Scheduler::add(Pump *p)
   p->set_logger(&m_log);
   p->start_pos= avg;
 
-  if (p->begin())  // logs errors
+  if (p->begin() || m_log.report_killed())  // logs errors
   {
     delete p;
     return ERROR;
@@ -1046,7 +1070,7 @@ int Scheduler::prepare()
 
   for (Pump_iterator it(*this); it; ++it)
   {
-    if (it->prepare())  // logs errors
+    if (it->prepare() || m_log.report_killed())  // logs errors
     {
       remove_pump(it);  // Note: never errors.
       return ERROR;
@@ -1138,6 +1162,16 @@ Backup_pump::~Backup_pump()
   bitmap_free(&m_closed_streams);
 }
 
+/*
+  Note: The standard report_error() method does not log an error in case
+  the statement has been interrupted - the interruption is reported instead.
+  But we want to always report errors signalled by a backup driver, even if an
+  interruption has just happened. Therefore, inside Backup_pump methods where 
+  errors from the driver are reported, we use the variant of 
+  Logger::report_error() with explicit log_level::ERROR. This variant does not 
+  check for interruptions and always reports given error.
+*/ 
+
 /// Initialize backup driver.
 int Backup_pump::begin()
 {
@@ -1148,7 +1182,8 @@ int Backup_pump::begin()
   {
     state= backup_state::ERROR;
     if (m_log)
-      m_log->report_error(ER_BACKUP_INIT_BACKUP_DRIVER, m_name);
+      m_log->report_error(log_level::ERROR,
+                          ER_BACKUP_INIT_BACKUP_DRIVER, m_name);
     return ERROR;
   }
 
@@ -1166,7 +1201,8 @@ int Backup_pump::end()
     {
       state= backup_state::ERROR;
       if (m_log)
-        m_log->report_error(ER_BACKUP_STOP_BACKUP_DRIVER, m_name);
+        m_log->report_error(log_level::ERROR,
+                            ER_BACKUP_STOP_BACKUP_DRIVER, m_name);
       return ERROR;
     }
 
@@ -1195,7 +1231,8 @@ int Backup_pump::prepare()
   default:
     state= backup_state::ERROR;
     if (m_log)
-      m_log->report_error(ER_BACKUP_PREPARE_DRIVER, m_name);
+      m_log->report_error(log_level::ERROR,
+                          ER_BACKUP_PREPARE_DRIVER, m_name);
     return ERROR;
   }
 
@@ -1212,7 +1249,8 @@ int Backup_pump::lock()
   {
     state= backup_state::ERROR;
     if (m_log)
-      m_log->report_error(ER_BACKUP_CREATE_VP, m_name);
+      m_log->report_error(log_level::ERROR, 
+                          ER_BACKUP_CREATE_VP, m_name);
     return ERROR;
   }
 
@@ -1228,7 +1266,8 @@ int Backup_pump::unlock()
   {
     state= backup_state::ERROR;
     if (m_log)
-      m_log->report_error(ER_BACKUP_UNLOCK_DRIVER, m_name);
+      m_log->report_error(log_level::ERROR, 
+                          ER_BACKUP_UNLOCK_DRIVER, m_name);
     return ERROR;
   }
 
@@ -1241,7 +1280,8 @@ int Backup_pump::cancel()
   {
     state= backup_state::ERROR;
     if (m_log)
-      m_log->report_error(ER_BACKUP_CANCEL_BACKUP, m_name);
+      m_log->report_error(log_level::ERROR, 
+                          ER_BACKUP_CANCEL_BACKUP, m_name);
     return ERROR;
   }
   state= backup_state::CANCELLED;
@@ -1367,7 +1407,8 @@ int Backup_pump::pump(size_t *howmuch)
       case ERROR:
       default:
         if (m_log)
-          m_log->report_error(ER_BACKUP_GET_DATA, m_name);
+          m_log->report_error(log_level::ERROR,
+                              ER_BACKUP_GET_DATA, m_name);
         state= backup_state::ERROR;
         return ERROR;
 
@@ -1485,6 +1526,7 @@ int restore_table_data(THD *thd, Restore
   }
 
   // Create restore drivers
+  DEBUG_SYNC(thd, "restore_before_drivers_create");
   result_t res;
 
   for (uint n=0; n < info.snap_count(); ++n)
@@ -1498,6 +1540,8 @@ int restore_table_data(THD *thd, Restore
       continue;
 
     res= snap->get_restore_driver(drv[n]);
+    if (log.report_killed())
+      goto error;
     if (res == backup::ERROR)
     {
       log.report_error(ER_BACKUP_CREATE_RESTORE_DRIVER, snap->name());
@@ -1506,9 +1550,12 @@ int restore_table_data(THD *thd, Restore
  }
 
   // Initialize the drivers.
+  DEBUG_SYNC(thd, "restore_before_drivers_init");
   for (uint n=0; n < info.snap_count(); ++n)
   {
     res= drv[n]->begin(0);
+    if (log.report_killed())
+      goto error;
     if (res == backup::ERROR)
     {
       log.report_error(ER_BACKUP_INIT_RESTORE_DRIVER, info.m_snap[n]->name());
@@ -1521,11 +1568,10 @@ int restore_table_data(THD *thd, Restore
   DEBUG_SYNC(thd, "restore_in_progress");
   {
     Buffer  buf;
-    uint    snap_num=0;
-    uint    repeats=0, errors= 0;
+    uint    snap_num= 0;
+    uint    repeats= 0;
     int     ret;
 
-    static const uint MAX_ERRORS= 3;
     static const uint MAX_REPEATS= 7;
 
     Restore_driver  *drvr= NULL;  // pointer to the current driver
@@ -1539,9 +1585,13 @@ int restore_table_data(THD *thd, Restore
 
       case READING:
 
+        DEBUG_SYNC(thd, "restore_before_read_data_chunk");
         bzero(&chunk_info, sizeof(chunk_info));
         ret= bstream_rd_data_chunk(&s, &chunk_info);
 
+        if (log.report_killed())
+          goto error;
+
         /* Mimic error in bstream_rd_data_chunk */
         DBUG_EXECUTE_IF("restore_tbl_data_read", ret= BSTREAM_ERROR;);
 
@@ -1602,7 +1652,12 @@ int restore_table_data(THD *thd, Restore
            Note: For testing, error can be injected in default driver
            send_data by using dbug hook 'backup_default_send_data'
         */
+        DEBUG_SYNC(thd, "restore_before_sending_data");
         ret= drvr->send_data(buf);
+
+        if (log.report_killed())
+          goto error;
+
         switch (ret) {
 
         case backup::OK:
@@ -1614,19 +1669,14 @@ int restore_table_data(THD *thd, Restore
           break;
 
         case backup::ERROR:
-          if( errors > MAX_ERRORS )
-          {
-            log.report_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
-            /*
-              If driver signals error then it is not active any longer - neither 
-              ->end() nor ->cancel() should be called on it, only ->free(). 
-              This is why we need to remove it from active[] array.
-            */
-            active[snap_num]= NULL;
-            goto error;
-          }
-          errors++;
-          break;
+          log.report_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
+          /*
+            If driver signals error then it is not active any longer - neither 
+            ->end() nor ->cancel() should be called on it, only ->free(). 
+            This is why we need to remove it from active[] array.
+          */
+          active[snap_num]= NULL;
+          goto error;
 
         case backup::PROCESSING:
         case backup::BUSY:
@@ -1663,6 +1713,18 @@ int restore_table_data(THD *thd, Restore
     DBUG_PRINT("restore",("Shutting down restore driver %s",
                            info.m_snap[n]->name()));
     res= active[n]->end();
+    /* 
+      After ->end() call on a driver, it is no longer active and its ->cancel()
+      method should not be called if we jump to error. This is the case even 
+      when ->end() returned error because the only allowed driver call after 
+      an error is ->end(). Hence we set active[n] to NULL.
+    */
+    active[n]= NULL;
+
+    /*
+      In case of error, store driver's name in bad_drivers so that it is
+      reported below.
+    */ 
     if (res == backup::ERROR)
     {
       state= ERROR;
@@ -1671,6 +1733,13 @@ int restore_table_data(THD *thd, Restore
         bad_drivers.append(",");
       bad_drivers.append(info.m_snap[n]->name());
     }
+
+    /*
+      If interruption has happened, skip shutting down the rest of the drivers.
+      They will be canceled below.
+    */ 
+    if (log.report_killed())
+      goto error;
   }
 
   goto finish;
@@ -1691,7 +1760,6 @@ error:
     DBUG_PRINT("restore",("Cancelling restore driver %s",
                            info.m_snap[n]->name()));
     res= active[n]->cancel();
-
     if (res)
     {
       if (!bad_drivers.is_empty())
@@ -1702,8 +1770,14 @@ error:
 
 finish:  
 
+  /*
+    We always log shutdown errors, even if an interruption has happened before.
+    This is why we must supply explicit log_level::ERROR to report_error() as
+    otherwise the method will report interruption instead of an error.
+  */
   if (!bad_drivers.is_empty())
-    log.report_error(ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
+    log.report_error(log_level::ERROR, 
+                     ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
 
   // Call free() for all existing drivers
 

=== modified file 'sql/backup/image_info.cc'
--- a/sql/backup/image_info.cc	2009-02-16 12:20:31 +0000
+++ b/sql/backup/image_info.cc	2009-04-15 20:25:14 +0000
@@ -193,8 +193,6 @@ int Image_info::add_snapshot(Snapshot_in
   bzero(&info, sizeof(st_bstream_snapshot_info));
   info.type= enum_bstream_snapshot_type(snap.type());
   info.version= snap.version();
-  info.table_count= snap.table_count();
-  
   if (snap.type() == Snapshot_info::NATIVE_SNAPSHOT)
   {
     Native_snapshot &ns= static_cast<Native_snapshot&>(snap);
@@ -314,6 +312,10 @@ Image_info::add_table(Db &db, const ::St
   if (!snap.m_num)
    return NULL;
 
+  // Record the table count for the stream header.
+  st_bstream_snapshot_info &info= snapshot[snap.m_num-1];
+  info.table_count= snap.table_count();
+
   t->snap_num= snap.m_num - 1;
   t->base.base.pos= pos;
 

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2009-03-10 18:19:41 +0000
+++ b/sql/backup/kernel.cc	2009-04-01 11:08:48 +0000
@@ -170,6 +170,7 @@ execute_backup_command(THD *thd, 
   {
     // prepare for backup operation
     
+    DEBUG_SYNC(thd, "before_backup_prepare");
     Backup_info *info= context.prepare_for_backup(backupdir, lex->backup_dir, 
                                                   thd->query,
                                                   lex->backup_compression);
@@ -203,8 +204,10 @@ execute_backup_command(THD *thd, 
 
     // perform backup
 
+    DEBUG_SYNC(thd, "before_do_backup");
     res= context.do_backup();
  
+    DEBUG_SYNC(thd, "after_do_backup");
     if (res)
       DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP));
 
@@ -213,6 +216,7 @@ execute_backup_command(THD *thd, 
 
   case SQLCOM_RESTORE:
   {
+    DEBUG_SYNC(thd, "before_restore_prepare");
 
     Restore_info *info= context.prepare_for_restore(backupdir, lex->backup_dir, 
                                                     thd->query, skip_gap_event);
@@ -241,7 +245,10 @@ execute_backup_command(THD *thd, 
 
   } // switch(lex->sql_command)
 
-  if (context.close())
+  res= context.close();
+  DEBUG_SYNC(thd, "backup_restore_done");
+
+  if (res)
     DBUG_RETURN(send_error(context, ER_BACKUP_CONTEXT_REMOVE));
 
   // All seems OK - send positive reply to client
@@ -255,16 +262,17 @@ execute_backup_command(THD *thd, 
   @param[in]  ctx  The context of the backup/restore operation.
   @param[in]  error_code  Error to be reported if no errors reported yet.
 
-  If an error has been already reported then nothing is done - the first 
-  logged error will be send to the client. Otherwise, if no errors were 
-  reported yet, the given error is sent to the client (but not reported).
+  If an error has been already reported, or process has been interrupted,
+  then nothing is done - the first logged error or kill message will be sent 
+  to the client. Otherwise, if no errors were reported yet and no interruption
+  has been detected the given error is sent to the client (but not reported).
   
   @returns The error code given as argument.
 */
 static
 int send_error(Backup_restore_ctx &context, int error_code, ...)
 {
-  if (!context.error_reported())
+  if (!context.is_killed() && !context.error_reported())
   {
     char buf[MYSQL_ERRMSG_SIZE];
     va_list args;
@@ -388,12 +396,15 @@ Backup_restore_ctx::Backup_restore_ctx(T
     Check for progress tables.
   */
   MYSQL_BACKUP_LOG *backup_log= logger.get_backup_history_log_file_handler();
-  if (backup_log->check_backup_logs(thd))
+  if (report_killed())
+    m_error= ER_QUERY_INTERRUPTED;
+  else if (backup_log->check_backup_logs(thd))
     m_error= ER_BACKUP_PROGRESS_TABLES;
 }
 
 Backup_restore_ctx::~Backup_restore_ctx()
 {
+  DEBUG_SYNC(m_thd, "backup_restore_ctx_dtor");
   close();
 
   delete mem_alloc;
@@ -500,8 +511,9 @@ int Backup_restore_ctx::prepare(::String
     In case of error, we write only to backup logs, because check_global_access()
     pushes the same error on the error stack.
   */
+  DEBUG_SYNC(m_thd, "before_backup_privileges");
   ret= check_global_access(m_thd, SUPER_ACL);
-  if (ret)
+  if (ret || is_killed())
     return fatal_error(log_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, "SUPER"));
 
   /*
@@ -509,6 +521,7 @@ int Backup_restore_ctx::prepare(::String
     this operation.
    */
 
+  DEBUG_SYNC(m_thd, "before_backup_single_op");
   pthread_mutex_lock(&run_lock);
 
   if (!current_op)
@@ -543,7 +556,7 @@ int Backup_restore_ctx::prepare(::String
 
 #endif
 
-  if (bad_filename)
+  if (bad_filename || is_killed())
     return fatal_error(report_error(ER_BAD_PATH, location.str));
 
   /*
@@ -563,8 +576,9 @@ int Backup_restore_ctx::prepare(::String
 
   // Freeze all meta-data. 
 
+  DEBUG_SYNC(m_thd, "before_backup_ddl_block");
   ret= obs::bml_get(m_thd);
-  if (ret)
+  if (ret || is_killed())
     return fatal_error(report_error(ER_DDL_BLOCK));
 
   DEBUG_SYNC(m_thd, "after_backup_restore_prepare");
@@ -601,14 +615,16 @@ Backup_restore_ctx::prepare_for_backup(S
   // Do nothing if context is in error state.
   if (m_error)
     return NULL;
-  
+
   /*
    Note: Logger must be initialized before any call to report_error() - 
    otherwise an assertion will fail.
   */ 
-  if (Logger::init(BACKUP, query))      // Logs errors
+  DEBUG_SYNC(m_thd, "before_backup_logger_init");
+  int ret= Logger::init(BACKUP, query);  // Logs errors   
+  if (ret || is_killed())
   {
-    fatal_error(ER_BACKUP_LOGGER_INIT);
+    fatal_error(report_killed() ? ER_QUERY_INTERRUPTED : ER_BACKUP_LOGGER_INIT);
     return NULL;
   }
 
@@ -619,7 +635,8 @@ Backup_restore_ctx::prepare_for_backup(S
     Do preparations common to backup and restore operations. After call
     to prepare() all meta-data changes are blocked.
    */ 
-  if (prepare(backupdir, orig_loc))
+  DEBUG_SYNC(m_thd, "before_backup_common_prepare");
+  if (prepare(backupdir, orig_loc))  // Logs errors and detects interruptions
     return NULL;
 
   /*
@@ -630,17 +647,30 @@ Backup_restore_ctx::prepare_for_backup(S
                                       &m_path,
                                       with_compression);
   m_stream= s;
-  
-  if (!s)
+
+  if (!s || is_killed())
   {
     fatal_error(report_error(ER_OUT_OF_RESOURCES));
     return NULL;
   }
 
+  DEBUG_SYNC(m_thd, "before_backup_stream_open");
   int my_open_status= s->open();
-  if (my_open_status != 0)
+
+  /*
+    Set state to PREPARED_FOR_BACKUP in case output file was opened successfuly.
+    It is important to set the state here, because this ensures that the file
+    will be removed in case of error or interruption.
+   */ 
+  if (! my_open_status)
+    m_state= PREPARED_FOR_BACKUP;
+  
+  if (my_open_status != 0 || is_killed())
   {
-    report_stream_open_failure(my_open_status, &orig_loc);
+    if (report_killed())
+      fatal_error(ER_QUERY_INTERRUPTED);
+    else
+      report_stream_open_failure(my_open_status, &orig_loc);
     return NULL;
   }
 
@@ -648,14 +678,15 @@ Backup_restore_ctx::prepare_for_backup(S
     Create backup catalogue.
    */
 
+  DEBUG_SYNC(m_thd, "before_backup_catalog");
   Backup_info *info= new Backup_info(*this, m_thd);    // Logs errors
+  m_catalog= info;
 
-  if (!info)
+  if (!info || is_killed())
   {
     fatal_error(report_error(ER_OUT_OF_RESOURCES));
     return NULL;
   }
-
   if (!info->is_valid())
   {
     // Error has been logged by Backup_info constructor
@@ -679,8 +710,6 @@ Backup_restore_ctx::prepare_for_backup(S
     info->flags|= BSTREAM_FLAG_BINLOG; 
 
   info->save_start_time(when);
-  m_catalog= info;
-  m_state= PREPARED_FOR_BACKUP;  
 
   return info;
 }
@@ -715,7 +744,9 @@ Backup_restore_ctx::prepare_for_restore(
    Note: Logger must be initialized before any call to report_error() - 
    otherwise an assertion will fail.
   */ 
-  if (Logger::init(RESTORE, query))
+  DEBUG_SYNC(m_thd, "before_restore_logger_init");
+  int ret= Logger::init(RESTORE, query);  // Logs errors
+  if (ret || is_killed())
   {
     fatal_error(ER_BACKUP_LOGGER_INIT);
     return NULL;
@@ -742,6 +773,7 @@ Backup_restore_ctx::prepare_for_restore(
     Do preparations common to backup and restore operations. After this call
     changes of meta-data are blocked.
    */ 
+  DEBUG_SYNC(m_thd, "before_restore_common_prepare");
   if (prepare(backupdir, orig_loc))
     return NULL;
   
@@ -752,16 +784,20 @@ Backup_restore_ctx::prepare_for_restore(
   Input_stream *s= new Input_stream(*this, &m_path);
   m_stream= s;
   
-  if (!s)
+  if (!s || is_killed())
   {
     fatal_error(report_error(ER_OUT_OF_RESOURCES));
     return NULL;
   }
   
+  DEBUG_SYNC(m_thd, "before_restore_stream_open");
   int my_open_status= s->open();
-  if (my_open_status != 0)
+  if (my_open_status != 0 || is_killed())
   {
-    report_stream_open_failure(my_open_status, &orig_loc);
+    if (report_killed())
+      fatal_error(ER_QUERY_INTERRUPTED);
+    else
+      report_stream_open_failure(my_open_status, &orig_loc);
     return NULL;
   }
 
@@ -769,14 +805,15 @@ Backup_restore_ctx::prepare_for_restore(
     Create restore catalogue.
    */
 
+  DEBUG_SYNC(m_thd, "before_restore_catalog");
   Restore_info *info= new Restore_info(*this, m_thd);  // reports errors
+  m_catalog= info;
 
-  if (!info)
+  if (!info || is_killed())
   {
     fatal_error(report_error(ER_OUT_OF_RESOURCES));
     return NULL;
   }
-
   if (!info->is_valid())
   {
     // Errors are logged by Restore_info constructor. 
@@ -785,18 +822,18 @@ Backup_restore_ctx::prepare_for_restore(
   }
 
   info->save_start_time(when);
-  m_catalog= info;
-
-  int ret;
 
   /*
     Read header and catalogue from the input stream.
    */
 
+  DEBUG_SYNC(m_thd, "before_restore_read_header");
   ret= read_header(*info, *s);  // Can log errors via callback functions.
-  if (ret)
+  if (ret || is_killed())
   {
-    if (!error_reported())
+    if (report_killed())
+      ret= ER_QUERY_INTERRUPTED;
+    else if (!error_reported())
       report_error(ER_BACKUP_READ_HEADER);
     fatal_error(ret);
     return NULL;
@@ -805,16 +842,19 @@ Backup_restore_ctx::prepare_for_restore(
   ret= s->next_chunk();
   /* Mimic error in next_chunk */
   DBUG_EXECUTE_IF("restore_prepare_next_chunk_1", ret= BSTREAM_ERROR; );
-  if (ret != BSTREAM_OK)
+  if (ret != BSTREAM_OK || is_killed())
   {
     fatal_error(report_error(ER_BACKUP_NEXT_CHUNK));
     return NULL;
   }
 
+  DEBUG_SYNC(m_thd, "before_restore_read_catalog");
   ret= read_catalog(*info, *s);  // Can log errors via callback functions.
-  if (ret)
+  if (ret || is_killed())
   {
-    if (!error_reported())
+    if (report_killed())
+      ret= ER_QUERY_INTERRUPTED;
+    else if (!error_reported())
       report_error(ER_BACKUP_READ_HEADER);
     fatal_error(ret);
     return NULL;
@@ -823,7 +863,7 @@ Backup_restore_ctx::prepare_for_restore(
   ret= s->next_chunk();
   /* Mimic error in next_chunk */
   DBUG_EXECUTE_IF("restore_prepare_next_chunk_2", ret= BSTREAM_ERROR; );
-  if (ret != BSTREAM_OK)
+  if (ret != BSTREAM_OK || is_killed())
   {
     fatal_error(report_error(ER_BACKUP_NEXT_CHUNK));
     return NULL;
@@ -831,6 +871,7 @@ Backup_restore_ctx::prepare_for_restore(
 
   m_state= PREPARED_FOR_RESTORE;
 
+  DEBUG_SYNC(m_thd, "before_restore_binlog");
   /*
     Do not allow slaves to connect during a restore.
 
@@ -851,6 +892,11 @@ Backup_restore_ctx::prepare_for_restore(
     obs::engage_binlog(FALSE);
   }
 
+  if (report_killed())
+  {
+    fatal_error(ER_QUERY_INTERRUPTED);
+    return NULL;
+  }
   return info;
 }
 
@@ -928,7 +974,7 @@ int Backup_restore_ctx::lock_tables_for_
                                     MYSQL_OPEN_SKIP_TEMPORARY 
                                           /* do not open tmp tables */
                                    );
-  if (ret)
+  if (ret || is_killed())
     return fatal_error(report_error(ER_BACKUP_OPEN_TABLES,"RESTORE"));
 
   m_tables_locked= TRUE;
@@ -986,6 +1032,15 @@ int Backup_restore_ctx::close()
   if (m_state == CLOSED)
     return 0;
 
+  /*
+    Note: The standard report_error() method does not log an error in case
+    the statement has been interrupted - the interruption is reported instead.
+    But we want to always report errors which happen during shutdown phase.
+    Therefore, for reporting errors here we use the variant of 
+    Logger::report_error() with explicit log_level::ERROR. This variant does not 
+    check for interruptions and always reports given error.
+  */ 
+
   using namespace backup;
 
   // Move context to error state if the catalog became corrupted.
@@ -1048,7 +1103,7 @@ int Backup_restore_ctx::close()
   if (m_stream && !m_stream->close())
   {
     // Note error, but complete clean-up
-    fatal_error(report_error(ER_BACKUP_CLOSE));
+    fatal_error(report_error(log_level::ERROR, ER_BACKUP_CLOSE));
   }
 
   /* 
@@ -1060,13 +1115,14 @@ int Backup_restore_ctx::close()
   if (m_state == PREPARED_FOR_BACKUP && !m_completed)
   {
     int ret= my_delete(m_path.c_ptr(), MYF(0));
-
+    DBUG_EXECUTE_IF("backup_remove_location_error", ret= TRUE;);
     /*
       Ignore ENOENT error since it is ok if the file doesn't exist.
      */
     if (ret && my_errno != ENOENT)
     {
-      fatal_error(report_error(ER_CANT_DELETE_FILE, m_path.c_ptr(), my_errno));
+      fatal_error(report_error(log_level::ERROR, ER_CANT_DELETE_FILE, 
+                               m_path.c_ptr(), my_errno));
     }
   }
 
@@ -1120,13 +1176,18 @@ int Backup_restore_ctx::do_backup()
 
   report_stats_pre(info);                       // Never errors
 
+  if (report_killed())
+    DBUG_RETURN(fatal_error(ER_QUERY_INTERRUPTED));
+
   DBUG_PRINT("backup",("Writing preamble"));
   DEBUG_SYNC(m_thd, "backup_before_write_preamble");
 
   ret= write_preamble(info, s);  // Can Log errors via callback functions.
-  if (ret)
+  if (ret || is_killed())
   {
-    if (!error_reported())
+    if (report_killed())
+      ret= ER_QUERY_INTERRUPTED;
+    else if (!error_reported())
       report_error(ER_BACKUP_WRITE_HEADER);
     DBUG_RETURN(fatal_error(ret));
   }
@@ -1135,14 +1196,15 @@ int Backup_restore_ctx::do_backup()
 
   DEBUG_SYNC(m_thd, "before_backup_data");
 
-  ret= write_table_data(m_thd, info, s); // logs errors
+  ret= write_table_data(m_thd, info, s); // logs errors and detects interruptions
   if (ret)
     DBUG_RETURN(fatal_error(ret));
 
   DBUG_PRINT("backup",("Writing summary"));
 
+  DEBUG_SYNC(m_thd, "before_backup_summary");
   ret= write_summary(info, s);  
-  if (ret)
+  if (ret || is_killed())
     DBUG_RETURN(fatal_error(report_error(ER_BACKUP_WRITE_SUMMARY)));
 
   DEBUG_SYNC(m_thd, "before_backup_completed");
@@ -1177,83 +1239,97 @@ int Backup_restore_ctx::restore_triggers
 
   DBUG_ENTER("restore_triggers_and_events");
 
-  DBUG_ASSERT(m_type == RESTORE);
-  Restore_info *info= static_cast<Restore_info*>(m_catalog);
   Image_info::Obj *obj;
   List<Image_info::Obj> events;
   Image_info::Obj::describe_buf buf;
-
-  Image_info::Iterator *dbit= info->get_dbs();
-  if (!dbit)
-    DBUG_RETURN(fatal_error(report_error(ER_OUT_OF_RESOURCES)));
+  // Note: The two iterators below must be deleted upon exit.
+  Image_info::Iterator *trgit= NULL;
+  Image_info::Iterator *dbit= m_catalog->get_dbs();
+  if (!dbit || is_killed())
+  {
+    fatal_error(report_error(ER_OUT_OF_RESOURCES));
+    goto exit;
+  }
 
   // create all trigers and collect events in the events list
   
   while ((obj= (*dbit)++)) 
   {
-    Image_info::Iterator *it=
-                       info->get_db_objects(*static_cast<Image_info::Db*>(obj));
-    if (!it)
-      DBUG_RETURN(fatal_error(report_error(ER_OUT_OF_RESOURCES)));
+    trgit= m_catalog->get_db_objects(*static_cast<Image_info::Db*>(obj));
+    if (!trgit || is_killed())
+    {
+      fatal_error(report_error(ER_OUT_OF_RESOURCES));
+      goto exit;
+    }
 
-    while ((obj= (*it)++))
+    while ((obj= (*trgit)++))
       switch (obj->type()) {
       
       case BSTREAM_IT_EVENT:
         DBUG_ASSERT(obj->m_obj_ptr);
         if (events.push_back(obj))
         {
-          delete it;
-          delete dbit;
           // Error has been reported, but not logged to backup logs
-          DBUG_RETURN(fatal_error(log_error(ER_OUT_OF_RESOURCES))); 
+          fatal_error(log_error(ER_OUT_OF_RESOURCES));
+          goto exit; 
         }
         break;
       
       case BSTREAM_IT_TRIGGER:
       {
         DBUG_ASSERT(obj->m_obj_ptr);
-        // Mark that data is being changed.
-        info->m_data_changed= TRUE;
-
-        bool ret= obj->m_obj_ptr->create(m_thd);
+        int ret= obj->m_obj_ptr->create(m_thd);
         /* Mimic error in restore of trigger */
         DBUG_EXECUTE_IF("restore_trigger", ret= TRUE;); 
-        if (ret)
+        if (ret || is_killed())
         {
-          delete it;
-          delete dbit;
-          int err= report_error(ER_BACKUP_CANT_RESTORE_TRIGGER,
-                                obj->describe(buf));
-          DBUG_RETURN(fatal_error(err));
+          fatal_error(report_error(ER_BACKUP_CANT_RESTORE_TRIGGER,
+                                   obj->describe(buf)));
+          goto exit;
         }
         break;
       }
       default: break;      
       }
 
-    delete it;
+    delete trgit;
+    trgit= NULL;
   }
 
   delete dbit;
+  dbit= NULL;
 
   // now create all events
-
-  List_iterator<Image_info::Obj> it(events);
-  Image_info::Obj *ev;
-
-  while ((ev= it++)) 
+  
   {
-    // Mark that data is being changed.
-    info->m_data_changed= TRUE;
-    if (ev->m_obj_ptr->create(m_thd))
+    List_iterator<Image_info::Obj> it(events);
+    Image_info::Obj *ev;
+
+    while ((ev= it++))
     {
-      int ret= report_error(ER_BACKUP_CANT_RESTORE_EVENT,ev->describe(buf));
-      DBUG_RETURN(fatal_error(ret));
-    };
+      int ret= ev->m_obj_ptr->create(m_thd); 
+      if (ret || is_killed())
+      {
+        fatal_error(report_error(ER_BACKUP_CANT_RESTORE_EVENT,ev->describe(buf)));
+        goto exit;
+      }
+    }
   }
 
-  DBUG_RETURN(0);
+  /* 
+    FIXME: this call is here because object services doesn't clean the
+    statement execution context properly, which leads to assertion failure.
+    It should be fixed inside object services implementation and then the
+    following line should be removed (see BUG#41294).
+   */
+  close_thread_tables(m_thd);                   // Never errors
+  m_thd->clear_error();                         // Never errors
+
+exit:
+
+  delete dbit;
+  delete trgit;
+  DBUG_RETURN(m_error);
 }
 
 /**
@@ -1288,6 +1364,9 @@ int Backup_restore_ctx::do_restore(bool 
 
   report_stats_pre(info);                       // Never errors
 
+  if (report_killed())
+    DBUG_RETURN(fatal_error(ER_QUERY_INTERRUPTED));
+
   DBUG_PRINT("restore", ("Restoring meta-data"));
 
   // unless RESTORE... OVERWRITE: return error if database already exists
@@ -1301,7 +1380,8 @@ int Backup_restore_ctx::do_restore(bool 
     Image_info::Db *mydb;
     while ((mydb= static_cast<Image_info::Db*>((*dbit)++)))
     {
-      if (!obs::check_db_existence(m_thd, &mydb->name()))
+      err= obs::check_db_existence(m_thd, &mydb->name());
+      if (!err || is_killed()) 
       {
         delete dbit;
         err= report_error(ER_RESTORE_DB_EXISTS, mydb->name().ptr());
@@ -1311,12 +1391,19 @@ int Backup_restore_ctx::do_restore(bool 
     delete dbit;
   }
 
+  DEBUG_SYNC(m_thd, "before_restore_fkey_disable");
   disable_fkey_constraints();                   // Never errors
 
-  err= read_meta_data(info, s);  // Can log errors via callback functions.
-  if (err)
-  {
-    if (!error_reported())
+  if (report_killed())
+    DBUG_RETURN(fatal_error(ER_QUERY_INTERRUPTED));
+
+  DEBUG_SYNC(m_thd, "before_restore_read_metadata");
+  err= read_meta_data(m_thd, info, s); // Can log errors via callback functions.
+  if (err || is_killed())
+  {
+    if (report_killed())
+      err= ER_QUERY_INTERRUPTED;
+    else if (!error_reported())
       report_error(ER_BACKUP_READ_META);
     DBUG_RETURN(fatal_error(err));
   }
@@ -1324,27 +1411,17 @@ int Backup_restore_ctx::do_restore(bool 
   err= s.next_chunk();
   /* Mimic error in next_chunk */
   DBUG_EXECUTE_IF("restore_stream_next_chunk", err= BSTREAM_ERROR; );
-  if (err == BSTREAM_ERROR)
+  if (err == BSTREAM_ERROR || is_killed())
   {
     DBUG_RETURN(fatal_error(report_error(ER_BACKUP_NEXT_CHUNK)));
   }
 
   DBUG_PRINT("restore",("Restoring table data"));
 
-  /* 
-    FIXME: this call is here because object services doesn't clean the
-    statement execution context properly, which leads to assertion failure.
-    It should be fixed inside object services implementation and then the
-    following line should be removed.
-   */
-  close_thread_tables(m_thd);                   // Never errors
-  m_thd->stmt_da->reset_diagnostics_area();     // Never errors
-
   DEBUG_SYNC(m_thd, "before_restore_locks_tables");
-
   err= lock_tables_for_restore();               // logs errors
-  if (err)
-    DBUG_RETURN(fatal_error(err));
+  if (err || is_killed())
+    DBUG_RETURN(fatal_error(report_killed() ? ER_QUERY_INTERRUPTED : err));
 
   DEBUG_SYNC(m_thd, "after_restore_locks_tables");
   /* 
@@ -1352,12 +1429,12 @@ int Backup_restore_ctx::do_restore(bool 
    (potentially) changed so we set m_data_changed flag.
   */
   info.m_data_changed= TRUE;
+  DEBUG_SYNC(m_thd, "before_restore_table_data");
   err= restore_table_data(m_thd, info, s);      // logs errors
 
   unlock_tables();                              // Never errors
-
-  if (err)
-    DBUG_RETURN(fatal_error(err));
+  if (err || is_killed())
+    DBUG_RETURN(fatal_error(report_killed() ? ER_QUERY_INTERRUPTED : err));
 
   /* 
    Re-create all triggers and events (it was not done in @c bcat_create_item()).
@@ -1366,26 +1443,18 @@ int Backup_restore_ctx::do_restore(bool 
    creation of these objects will fail.
   */
 
-  err= restore_triggers_and_events();           // logs errors
+  DEBUG_SYNC(m_thd, "before_restore_triggers");
+  err= restore_triggers_and_events();   // logs errors and detects interruptions
   if (err)
      DBUG_RETURN(fatal_error(err));
 
-  /* 
-    FIXME: this call is here because object services doesn't clean the
-    statement execution context properly, which leads to assertion failure.
-    It should be fixed inside object services implementation and then the
-    following line should be removed.
-   */
-  close_thread_tables(m_thd);                   // Never errors
-  m_thd->stmt_da->reset_diagnostics_area();     // Never errors
-
   DBUG_PRINT("restore",("Done."));
 
   DEBUG_SYNC(m_thd, "before_restore_completed");
   m_completed= TRUE;
 
   err= read_summary(info, s);
-  if (err)
+  if (err || is_killed())
     DBUG_RETURN(fatal_error(report_error(ER_BACKUP_READ_SUMMARY)));
 
   /*
@@ -1684,6 +1753,9 @@ int bcat_add_item(st_bstream_image_heade
 
   backup::String name_str(item->name.begin, item->name.end);
 
+  DBUG_EXECUTE_IF("restore_catalog_uppercase_names",
+                  my_caseup_str(system_charset_info, name_str.c_ptr());
+                  );
   DBUG_PRINT("restore",("Adding item %s of type %d (pos=%ld)",
                         item->name.begin,
                         item->type,
@@ -1700,6 +1772,9 @@ int bcat_add_item(st_bstream_image_heade
 
   case BSTREAM_IT_DB:
   {
+
+    if (lower_case_table_names == 1)
+      my_casedn_str(system_charset_info, name_str.c_ptr());
     Image_info::Db *db= info->add_db(name_str, item->pos); // reports errors
 
     return db ? BSTREAM_OK : BSTREAM_ERROR;
@@ -1732,6 +1807,8 @@ int bcat_add_item(st_bstream_image_heade
 
     DBUG_PRINT("restore",(" table's database is %s", db->name().ptr()));
 
+    if (lower_case_table_names == 1)
+      my_casedn_str(system_charset_info, name_str.c_ptr());
     Image_info::Table *tbl= info->add_table(*db, name_str, *snap, item->pos); 
                                                              // reports errors
     
@@ -1989,6 +2066,13 @@ int bcat_create_item(st_bstream_image_he
   THD *thd= info->m_thd;
   int create_err= 0;
 
+  /*
+    Check for interruption before creating (and thus first destroying) 
+    next object.
+  */ 
+  if (log.report_killed())
+    return BSTREAM_ERROR;
+
   switch (item->type) {
   
   case BSTREAM_IT_DB:     create_err= ER_BACKUP_CANT_RESTORE_DB; break;
@@ -2122,6 +2206,14 @@ int bcat_create_item(st_bstream_image_he
     db_name.alloc(size);
     db_name.length(0);
     db_name.append(start, size);
+
+    if (lower_case_table_names == 1)
+      my_casedn_str(system_charset_info, db_name.c_ptr());
+
+    DBUG_EXECUTE_IF("restore_catalog_uppercase_names_grant",
+		    my_caseup_str(system_charset_info, db_name.c_ptr());
+		    );
+
     if (!info->has_db(db_name))
     {
       log.report_error(ER_BACKUP_GRANT_WRONG_DB, create_stmt);
@@ -2131,7 +2223,6 @@ int bcat_create_item(st_bstream_image_he
 
   // Mark that data is being changed.
   info->m_data_changed= TRUE;
-
   if (sobj->create(thd))
   {
     log.report_error(create_err, desc);
@@ -2164,9 +2255,15 @@ int bcat_get_item_create_query(st_bstrea
   DBUG_ASSERT(stmt);
 
   Backup_info *info= static_cast<Backup_info*>(catalogue);
-
+  Logger &log= info->m_log;
   int meta_err= 0;
 
+  /*
+    Check for interruption before proceeding.
+  */ 
+  if (log.report_killed())
+    return BSTREAM_ERROR;
+
   switch (item->type) {
   
   case BSTREAM_IT_DB:     meta_err= ER_BACKUP_GET_META_DB; break;
@@ -2209,7 +2306,7 @@ int bcat_get_item_create_query(st_bstrea
   {
     Image_info::Obj::describe_buf dbuf;
 
-    info->m_log.report_error(meta_err, obj->describe(dbuf));
+    log.report_error(meta_err, obj->describe(dbuf));
 
     return BSTREAM_ERROR;    
   }

=== modified file 'sql/backup/logger.cc'
--- a/sql/backup/logger.cc	2009-03-09 14:00:03 +0000
+++ b/sql/backup/logger.cc	2009-03-16 14:38:05 +0000
@@ -156,6 +156,7 @@ void Logger::report_stats_pre(const Imag
 {
   DBUG_ASSERT(m_state == RUNNING);
   backup_log->num_objects(info.object_count());
+
   // Compose list of databases.
 
   Image_info::Db_iterator *it= info.get_dbs();
@@ -222,4 +223,48 @@ bool Logger::push_errors(bool flag)
   return old;
 } 
 
+/**
+  Report the fact that BACKUP/RESTORE operation has been cancelled.
+
+  This method does nothing if no interruption has happened or if an 
+  interruption has already been reported. Otherwise it logs
+  ER_BACKUP_INTERRUPTED note.
+
+  @note The server takes care of giving feedback to the client in case of a 
+  cancelled statement - nothing needs to be done here (nothing pushed on the 
+  server's error stack)
+
+  @returns TRUE if interruption has been detected and reported, 
+  FALSE otherwise.
+ */ 
+bool Logger::report_killed()
+{
+
+  if (!m_thd->killed)
+    return FALSE;
+
+  if (m_kill_reported)
+    return TRUE;
+
+  m_thd->send_kill_message();
+  m_kill_reported= TRUE;
+
+  if (m_state == CREATED || m_state == READY)
+    return TRUE;
+
+  // log_error() does not push messages on the server's error stack.
+  log_error(backup::log_level::INFO, ER_BACKUP_INTERRUPTED);  
+
+  /*
+    Note: It is not possible to open online backup log tables if current
+    query has been killed (m_thd->killed is non-zero). Thus in that case 
+    we can't update state accordingly. This is a limitation of the current 
+    implementation of the online backup logging mechanism.
+  */ 
+  if (m_state == RUNNING)
+    report_state(BUP_CANCEL);
+
+  return TRUE;
+}
+
 } // backup namespace

=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h	2009-02-13 13:25:43 +0000
+++ b/sql/backup/logger.h	2009-03-16 14:38:05 +0000
@@ -57,6 +57,7 @@ public:
    int report_error(const char *format, ...);
    int write_message(log_level::value level, const char *msg, ...);
    int log_error(int error_code, ...);
+   int log_error(log_level::value level, int error_code, ...);
 
    void report_start(time_t);
    void report_completed(time_t);
@@ -69,6 +70,7 @@ public:
    void report_backup_file(char * path);
    void report_stats_pre(const Image_info&);
    void report_stats_post(const Image_info&);
+   bool report_killed();
 
    /// Return the Backup_id of the current operation
    ulonglong get_op_id() const 
@@ -97,6 +99,8 @@ private:
 
   bool m_push_errors;        ///< Should errors be pushed on warning stack?
   bool m_error_reported;     ///< Has any error been reported?
+  /// Flag preventing double reporting of process interruption.
+  bool m_kill_reported;
 
   Backup_log *backup_log;    ///< Backup log interface class.
 };
@@ -104,7 +108,7 @@ private:
 inline
 Logger::Logger(THD *thd) 
    :m_type(BACKUP), m_state(CREATED), m_thd(thd), m_push_errors(TRUE), 
-    m_error_reported(FALSE), backup_log(0)
+    m_error_reported(FALSE), m_kill_reported(FALSE), backup_log(0)
 {}
 
 inline
@@ -126,10 +130,18 @@ int Logger::write_message(log_level::val
   return res;
 }
 
-/// Reports error with log_level::ERROR.
+/** 
+  Reports error with log_level::ERROR.
+
+  Before reporting error, this method checks for interruption. In case there 
+  was one, the interruption is reported instead.
+*/
 inline
 int Logger::report_error(int error_code, ...)
 {
+  if (report_killed())
+    return ER_QUERY_INTERRUPTED;
+
   va_list args;
 
   va_start(args, error_code);
@@ -152,10 +164,21 @@ int Logger::report_error(log_level::valu
   return res;
 }
 
-/// Reports error with given description.
+/** 
+  Reports given message with log_level::ERROR.
+
+  This method can be used for reporting errors which are not registered in 
+  errmsg.txt.
+
+  Before reporting the message, this method checks for interruption. In case 
+  there was one, the interruption is reported instead.
+*/
 inline
 int Logger::report_error(const char *format, ...)
 {
+  if (report_killed())
+    return ER_QUERY_INTERRUPTED;
+
   va_list args;
 
   va_start(args, format);
@@ -165,10 +188,18 @@ int Logger::report_error(const char *for
   return res;
 }
 
-/// Reports error without pushing it on server's error stack.
+/** 
+  Reports error with log_level::ERROR without pushing it on error stack. 
+
+  Before reporting the error, this method checks for interruption. In case 
+  there was one, the interruption is reported instead.
+*/
 inline
 int Logger::log_error(int error_code, ...)
 {
+  if (report_killed())
+    return ER_QUERY_INTERRUPTED;
+
   va_list args;
   bool    saved= push_errors(FALSE);
   
@@ -181,6 +212,25 @@ int Logger::log_error(int error_code, ..
   return res;
 }
 
+/** 
+  Reports error on the given log_level, without pushing it on server's 
+  error stack.
+*/
+inline
+int Logger::log_error(log_level::value level, int error_code, ...)
+{
+  va_list args;
+  bool    saved= push_errors(FALSE);
+
+  va_start(args, error_code);
+  int res= v_report_error(level, error_code, args);
+  va_end(args);
+
+  push_errors(saved);
+
+  return res;
+}
+
 /// Report start of an operation.
 inline
 void Logger::report_start(time_t when)

=== modified file 'sql/backup/stream.cc'
--- a/sql/backup/stream.cc	2009-02-09 18:17:55 +0000
+++ b/sql/backup/stream.cc	2009-03-16 14:38:05 +0000
@@ -269,12 +269,14 @@ int Stream::open()
 bool Stream::close()
 {
   bool ret= TRUE;
+
   if (m_fd >= 0)
   {
     if (my_close(m_fd, MYF(0)))
     {
       ret= FALSE;
     }
+    DBUG_EXECUTE_IF("backup_stream_close_error", ret= FALSE;);
     m_fd= -1;
   }
   return ret;

=== modified file 'sql/backup/stream.h'
--- a/sql/backup/stream.h	2009-02-06 08:28:24 +0000
+++ b/sql/backup/stream.h	2009-03-16 14:38:05 +0000
@@ -244,16 +244,34 @@ read_catalog(Image_info &info, Input_str
 /**
   Read the metadata.
 
+  @param[in]  thd   Connection thread handle. 
   @param[in]  info  The image info.
   @param[in]  s     The input stream.
 
   @retval  ERROR if stream error, OK if no errors.
+
+  FIXME: the thd parameter for read_meta_data() is here only because the
+  temporary code within the function needs it. It should be removed once the
+  issue is fixed (see BUG#41294).
 */
 inline
 result_t
-read_meta_data(Image_info &info, Input_stream &s)
+read_meta_data(THD *thd, Image_info &info, Input_stream &s)
 {
   int ret= bstream_rd_meta_data(&s, static_cast<st_bstream_image_header*>(&info));
+
+  /* 
+    FIXME: the following code is here because object services doesn't clean the
+    statement execution context properly, which leads to assertion failure.
+    It should be fixed inside object services implementation and then the
+    following line should be removed (see BUG#41294).
+   */
+  DBUG_ASSERT(thd);
+  close_thread_tables(thd);                   // Never errors
+  if (ret != BSTREAM_ERROR)
+    thd->clear_error();                       // Never errors  
+  /* end of temporary code */
+
   DBUG_EXECUTE_IF("restore_read_meta_data", ret= BSTREAM_ERROR;);
   return ret == BSTREAM_ERROR ? ERROR : OK;
 }

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-04-02 16:14:14 +0000
+++ b/sql/ha_ndbcluster.cc	2009-04-22 22:12:25 +0000
@@ -7684,7 +7684,6 @@ static int connect_callback()
 }
 
 extern int ndb_dictionary_is_mysqld;
-extern pthread_mutex_t LOCK_plugin;
 
 static int ndbcluster_init(void *p)
 {
@@ -7693,13 +7692,6 @@ static int ndbcluster_init(void *p)
   if (ndbcluster_inited)
     DBUG_RETURN(FALSE);
 
-  /*
-    Below we create new THD's. They'll need LOCK_plugin, but it's taken now by
-    plugin initialization code. Release it to avoid deadlocks.  It's safe, as
-    there're no threads that may concurrently access plugin control structures.
-  */
-  pthread_mutex_unlock(&LOCK_plugin);
-
   pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST);
   pthread_mutex_init(&LOCK_ndb_util_thread, MY_MUTEX_INIT_FAST);
   pthread_cond_init(&COND_ndb_util_thread, NULL);
@@ -7783,8 +7775,6 @@ static int ndbcluster_init(void *p)
     goto ndbcluster_init_error;
   }
 
-  pthread_mutex_lock(&LOCK_plugin);
-
   ndbcluster_inited= 1;
   DBUG_RETURN(FALSE);
 
@@ -7793,8 +7783,6 @@ ndbcluster_init_error:
   ndbcluster_disconnect();
   ndbcluster_hton->state= SHOW_OPTION_DISABLED;               // If we couldn't use handler
 
-  pthread_mutex_lock(&LOCK_plugin);
-
   DBUG_RETURN(TRUE);
 }
 

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-04-13 13:24:28 +0000
+++ b/sql/log.cc	2009-04-22 22:12:25 +0000
@@ -45,7 +45,6 @@
 
 /* max size of the log message */
 #define MAX_LOG_BUFFER_SIZE 1024
-#define MAX_USER_HOST_SIZE 512
 #define MAX_TIME_SIZE 32
 #define MY_OFF_T_UNDEF (~(my_off_t)0UL)
 
@@ -1979,7 +1978,6 @@ bool LOGGER::general_log_write(THD *thd,
   bool error= FALSE;
   Log_event_handler **current_handler= general_log_handler_list;
   char user_host_buff[MAX_USER_HOST_SIZE];
-  Security_context *sctx= thd->security_ctx;
   ulong id;
   uint user_host_len= 0;
   time_t current_time;
@@ -1995,21 +1993,15 @@ bool LOGGER::general_log_write(THD *thd,
     unlock();
     return 0;
   }
-  user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
-                          sctx->priv_user ? sctx->priv_user : "", "[",
-                          sctx->user ? sctx->user : "", "] @ ",
-                          sctx->host ? sctx->host : "", " [",
-                          sctx->ip ? sctx->ip : "", "]", NullS) -
-                                                          user_host_buff;
+  user_host_len= make_user_name(thd, user_host_buff);
 
   current_time= my_time(0);
 
-  mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_LOG, 0, current_time,
-                      user_host_buff, user_host_len,
-                      command_name[(uint) command].str,
-                      command_name[(uint) command].length,
-                      query, query_length,
-                      thd->variables.character_set_client,0);
+  mysql_audit_general_log(thd, current_time,
+                          user_host_buff, user_host_len,
+                          command_name[(uint) command].str,
+                          command_name[(uint) command].length,
+                          query, query_length);
                         
   while (*current_handler)
     error|= (*current_handler++)->

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-04-20 17:08:21 +0000
+++ b/sql/mysqld.cc	2009-04-22 22:12:25 +0000
@@ -3007,7 +3007,7 @@ extern "C" void my_message_sql(uint erro
 
 void my_message_sql(uint error, const char *str, myf MyFlags)
 {
-  THD *thd;
+  THD *thd= current_thd;
   DBUG_ENTER("my_message_sql");
   DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
 
@@ -3029,6 +3029,8 @@ void my_message_sql(uint error, const ch
     error= ER_UNKNOWN_ERROR;
   }
 
+  mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
+
   /*
     TODO: ME_JUST_INFO and ME_JUST_WARNING are back doors used in
     storage/maria to print to the server log files.
@@ -3053,7 +3055,7 @@ void my_message_sql(uint error, const ch
     DBUG_VOID_RETURN;
   }
 
-  if ((thd= current_thd))
+  if (thd)
   {
     if (MyFlags & ME_FATALERROR)
       thd->is_fatal_error= 1;

=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc	2009-04-03 15:14:49 +0000
+++ b/sql/protocol.cc	2009-04-16 14:02:03 +0000
@@ -28,15 +28,13 @@
 #include <stdarg.h>
 
 static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
-void net_send_error_packet(THD *thd, uint sql_errno, const char *err,
-                           const char* sqlstate);
+void net_send_error_packet(THD *, uint, const char *, const char *);
 /* Declared non-static only because of the embedded library. */
 void net_send_ok(THD *, uint, uint, ulonglong, ulonglong, const char *);
 /* Declared non-static only because of the embedded library. */
 void net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
 #ifndef EMBEDDED_LIBRARY
-static void write_eof_packet(THD *thd, NET *net,
-                             uint server_status, uint statement_warn_count);
+static void write_eof_packet(THD *, NET *, uint, uint);
 #endif
 
 #ifndef EMBEDDED_LIBRARY

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2009-04-13 13:24:28 +0000
+++ b/sql/set_var.cc	2009-04-22 22:12:25 +0000
@@ -3938,7 +3938,6 @@ void set_var_free()
   @param str	   Name of system variable to find
   @param length    Length of variable.  zero means that we should use strlen()
                    on the variable
-  @param no_error  Refuse to emit an error, even if one occurred.
 
   @retval
     pointer	pointer to variable definitions
@@ -3946,7 +3945,7 @@ void set_var_free()
     0		Unknown variable (error message is given)
 */
 
-sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
+sys_var *intern_find_sys_var(const char *str, uint length)
 {
   sys_var *var;
 
@@ -3956,9 +3955,6 @@ sys_var *intern_find_sys_var(const char 
   */
   var= (sys_var*) my_hash_search(&system_variable_hash,
 			      (uchar*) str, length ? length : strlen(str));
-  if (!(var || no_error))
-    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
-
   return var;
 }
 

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2009-04-01 21:36:07 +0000
+++ b/sql/share/errmsg.txt	2009-04-03 17:58:04 +0000
@@ -6264,7 +6264,7 @@ ER_BACKUP_INIT_RESTORE_DRIVER
 ER_BACKUP_STOP_BACKUP_DRIVER
         eng "Can't shut down %-.64s backup driver"
 ER_BACKUP_STOP_RESTORE_DRIVERS
-        eng "Can't shut down %-.64s backup driver(s)"
+        eng "Can't shut down %-.64s restore driver(s)"
 ER_BACKUP_PREPARE_DRIVER
         eng "%-.64s backup driver can't prepare for synchronization"
 ER_BACKUP_CREATE_VP
@@ -6508,4 +6508,5 @@ ER_COND_ITEM_TOO_LONG
         eng "Data too long for condition item '%s'"
 ER_PATH_LENGTH
   eng "The path specified for %.64s is too long."
-
+ER_BACKUP_INTERRUPTED
+  eng "Operation has been interrupted."

=== modified file 'sql/sql_audit.h'
--- a/sql/sql_audit.h	2008-03-26 14:30:28 +0000
+++ b/sql/sql_audit.h	2009-04-07 20:19:26 +0000
@@ -31,18 +31,21 @@ extern void mysql_audit_notify(THD *thd,
                                uint event_subtype, ...);
 extern void mysql_audit_release(THD *thd);
 
-
+#define MAX_USER_HOST_SIZE 512
+static inline uint make_user_name(THD *thd, char *buf)
+{
+  Security_context *sctx= thd->security_ctx;
+  return strxnmov(buf, MAX_USER_HOST_SIZE,
+                  sctx->priv_user ? sctx->priv_user : "", "[",
+                  sctx->user ? sctx->user : "", "] @ ",
+                  sctx->host ? sctx->host : "", " [",
+                  sctx->ip ? sctx->ip : "", "]", NullS) - buf;
+}
 
 /**
-  Call audit plugins of GENERAL audit class.
-  event_subtype should be set to one of:
-    MYSQL_AUDIT_GENERAL_LOG
-    MYSQL_AUDIT_GENERAL_ERROR
-    MYSQL_AUDIT_GENERAL_RESULT
+  Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype.
   
   @param[in] thd
-  @param[in] event_subtype    Type of general audit event.
-  @param[in] error_code       Error code
   @param[in] time             time that event occurred
   @param[in] user             User name
   @param[in] userlen          User name length
@@ -50,23 +53,75 @@ extern void mysql_audit_release(THD *thd
   @param[in] cmdlen           Command name length
   @param[in] query            Query string
   @param[in] querylen         Query string length
-  @param[in] clientcs         Charset of query string
-  @param[in] rows             Number of affected rows
 */
  
 static inline
+void mysql_audit_general_log(THD *thd, time_t time,
+                             const char *user, uint userlen,
+                             const char *cmd, uint cmdlen,
+                             const char *query, uint querylen)
+{
+#ifndef EMBEDDED_LIBRARY
+  if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
+  {
+    CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client
+                                : global_system_variables.character_set_client;
+
+    mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
+                       0, time, user, userlen, cmd, cmdlen,
+                       query, querylen, clientcs, 0);
+  }
+#endif
+}
+
+/**
+  Call audit plugins of GENERAL audit class.
+  event_subtype should be set to one of:
+    MYSQL_AUDIT_GENERAL_ERROR
+    MYSQL_AUDIT_GENERAL_RESULT
+  
+  @param[in] thd
+  @param[in] event_subtype    Type of general audit event.
+  @param[in] error_code       Error code
+  @param[in] msg              Message
+*/
+static inline
 void mysql_audit_general(THD *thd, uint event_subtype,
-                         int error_code, time_t time,
-                         const char *user, uint userlen,
-                         const char *cmd, uint cmdlen,
-                         const char *query, uint querylen,
-                         CHARSET_INFO *clientcs,
-                         ha_rows rows)
+                         int error_code, const char *msg)
 {
 #ifndef EMBEDDED_LIBRARY
   if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
+  {
+    time_t time= my_time(0);
+    uint msglen= msg ? strlen(msg) : 0;
+    const char *query, *user;
+    uint querylen, userlen;
+    char user_buff[MAX_USER_HOST_SIZE];
+    CHARSET_INFO *clientcs;
+    ha_rows rows;
+
+    if (thd)
+    {
+      query= thd->query;
+      querylen= thd->query_length;
+      user= user_buff;
+      userlen= make_user_name(thd, user_buff);
+      clientcs= thd->variables.character_set_client;
+      rows= thd->warning_info->current_row_for_warning();
+    }
+    else
+    {
+      query= user= 0;
+      querylen= userlen= 0;
+      clientcs= global_system_variables.character_set_client;
+      rows= 0;
+    }
+
     mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
-                       error_code, time, user, userlen, cmd, cmdlen,
+                       error_code, time, user, userlen, msg, msglen,
                        query, querylen, clientcs, rows);
+  }
 #endif
 }
+
+

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-04-13 13:24:28 +0000
+++ b/sql/sql_parse.cc	2009-04-22 22:12:25 +0000
@@ -1456,13 +1456,7 @@ bool dispatch_command(enum enum_server_c
   close_thread_tables(thd);
 
   if (!thd->is_error() && !thd->killed_errno())
-  {
-    mysql_audit_general(thd,MYSQL_AUDIT_GENERAL_RESULT,0,my_time(0),
-                        0,0,0,0,
-                        thd->query,thd->query_length,
-                        thd->variables.character_set_client,
-                        thd->warning_info->current_row_for_warning());
-  }
+    mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
 
   log_slow_statement(thd);
 

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2009-04-01 20:48:42 +0000
+++ b/sql/sql_plugin.cc	2009-04-14 16:05:26 +0000
@@ -213,7 +213,7 @@ static void reap_plugins(void);
 
 
 /* declared in set_var.cc */
-extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
+extern sys_var *intern_find_sys_var(const char *str, uint length);
 extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
                                  const char *name, longlong val);
 
@@ -1002,6 +1002,9 @@ static int plugin_initialize(struct st_p
   DBUG_ENTER("plugin_initialize");
 
   safe_mutex_assert_owner(&LOCK_plugin);
+  DBUG_ASSERT(plugin->state == PLUGIN_IS_UNINITIALIZED);
+
+  pthread_mutex_unlock(&LOCK_plugin);
 
   if (plugin_type_initialize[plugin->plugin->type])
   {
@@ -1022,6 +1025,8 @@ static int plugin_initialize(struct st_p
     }
   }
 
+  pthread_mutex_lock(&LOCK_plugin);
+
   plugin->state= PLUGIN_IS_READY;
 
   if (plugin->plugin->status_vars)
@@ -1039,9 +1044,10 @@ static int plugin_initialize(struct st_p
       {0, 0, SHOW_UNDEF}
     };
     if (add_status_vars(array)) // add_status_vars makes a copy
-      goto err;
+      goto err1;
 #else
-    add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
+    if (add_status_vars(plugin->plugin->status_vars))
+      goto err1;
 #endif /* FIX_LATER */
   }
 
@@ -1063,6 +1069,8 @@ static int plugin_initialize(struct st_p
 
   DBUG_RETURN(0);
 err:
+  pthread_mutex_lock(&LOCK_plugin);
+err1:
   DBUG_RETURN(1);
 }
 
@@ -1333,6 +1341,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
 #ifdef EMBEDDED_LIBRARY
   bool table_exists;
 #endif /* EMBEDDED_LIBRARY */
+  MDL_request mdl_request;
   DBUG_ENTER("plugin_load");
 
   new_thd->thread_stack= (char*) &tables;
@@ -1344,7 +1353,8 @@ static void plugin_load(MEM_ROOT *tmp_ro
   tables.alias= tables.table_name= (char*)"plugin";
   tables.lock_type= TL_READ;
   tables.db= new_thd->db;
-  alloc_mdl_requests(&tables, tmp_root);
+  tables.mdl_request= &mdl_request;
+  mdl_request.init(0, tables.db, tables.table_name);
 
 #ifdef EMBEDDED_LIBRARY
   /*
@@ -1671,7 +1681,6 @@ bool mysql_install_plugin(THD *thd, cons
   }
   else
   {
-    DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
     if (plugin_initialize(tmp))
     {
       my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
@@ -2149,7 +2158,7 @@ sys_var *find_sys_var(THD *thd, const ch
 
   pthread_mutex_lock(&LOCK_plugin);
   rw_rdlock(&LOCK_system_variables_hash);
-  if ((var= intern_find_sys_var(str, length, false)) &&
+  if ((var= intern_find_sys_var(str, length)) &&
       (pi= var->cast_pluginvar()))
   {
     rw_unlock(&LOCK_system_variables_hash);
@@ -2168,11 +2177,7 @@ sys_var *find_sys_var(THD *thd, const ch
     rw_unlock(&LOCK_system_variables_hash);
   pthread_mutex_unlock(&LOCK_plugin);
 
-  /*
-    If the variable exists but the plugin it is associated with is not ready
-    then the intern_plugin_lock did not raise an error, so we do it here.
-  */
-  if (pi && !var)
+  if (!var)
     my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
   DBUG_RETURN(var);
 }
@@ -2375,7 +2380,7 @@ static uchar *intern_sys_var_ptr(THD* th
       st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
 
       if (v->version <= thd->variables.dynamic_variables_version ||
-          !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+          !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
           !(pi= var->cast_pluginvar()) ||
           v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
         continue;
@@ -2468,7 +2473,7 @@ static void cleanup_variables(THD *thd, 
   {
     v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
     if (v->version > vars->dynamic_variables_version ||
-        !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+        !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
         !(pivar= var->cast_pluginvar()) ||
         v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
       continue;

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2009-04-01 09:34:34 +0000
+++ b/sql/sql_prepare.cc	2009-04-16 10:06:41 +0000
@@ -2959,6 +2959,13 @@ Execute_sql_statement::execute_server_co
 
   error= mysql_execute_command(thd);
 
+  if (thd->killed_errno())
+  {
+    if (! thd->stmt_da->is_set())
+      thd->send_kill_message();
+  }
+
+  /* report error issued during command execution */
   if (error == 0 && thd->spcont == NULL)
     general_log_write(thd, COM_STMT_EXECUTE,
                       thd->query, thd->query_length);

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-04-03 15:14:49 +0000
+++ b/sql/sql_show.cc	2009-04-17 10:11:33 +0000
@@ -7312,10 +7312,10 @@ int finalize_schema_table(st_plugin_int 
   ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
   DBUG_ENTER("finalize_schema_table");
 
-  if (schema_table && plugin->plugin->deinit)
+  if (schema_table)
   {
     DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
-    if (plugin->plugin->deinit(NULL))
+    if (plugin->plugin->deinit && plugin->plugin->deinit(NULL))
     {
       DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
                              plugin->name.str));

=== modified file 'storage/falcon/CycleLock.cpp'
--- a/storage/falcon/CycleLock.cpp	2009-04-21 06:09:11 +0000
+++ b/storage/falcon/CycleLock.cpp	2009-04-30 15:25:01 +0000
@@ -6,9 +6,9 @@
 
 CycleLock::CycleLock(Database *database)
 {
-	cycleManager = database->cycleManager;
-	syncObject = cycleManager->getSyncObject();
 	thread = Thread::getThread("CycleLock::CycleLock");
+	cycleManager = database->cycleManager;
+	syncObject = cycleManager->getSyncObject(thread->threadId);
 
 	// If there already is a cycle manager, let him worry about all this
 
@@ -61,7 +61,7 @@ void CycleLock::lockCycle(void)
 		chain->lockCycle();
 	else
 		{
-		syncObject = cycleManager->getSyncObject();
+		syncObject = cycleManager->getSyncObject(thread->threadId);
 		syncObject->lock(NULL, Shared);
 		locked = true;
 		}

=== modified file 'storage/falcon/CycleLock.h'
--- a/storage/falcon/CycleLock.h	2009-03-20 19:33:52 +0000
+++ b/storage/falcon/CycleLock.h	2009-04-30 15:25:01 +0000
@@ -11,7 +11,7 @@ class CycleLock
 public:
 	CycleLock(Database *database);
 	~CycleLock(void);
-	
+
 	static CycleLock*	unlock(void);
 	static bool			isLocked(void);
 

=== modified file 'storage/falcon/CycleManager.cpp'
--- a/storage/falcon/CycleManager.cpp	2009-04-21 06:09:11 +0000
+++ b/storage/falcon/CycleManager.cpp	2009-04-30 15:25:01 +0000
@@ -29,7 +29,9 @@
 #include "Value.h"
 #include "Interlock.h"
 
-static const int CYCLE_SLEEP		= 1000;
+static const int MAX_CYCLE_SLEEP		= 1000;
+static const int MIN_CYCLE_SLEEP		= 200;
+static const int CYCLE_SLEEP_INCREMENT		= 200;
 
 #ifdef _DEBUG
 #undef THIS_FILE
@@ -40,35 +42,91 @@ CycleManager::CycleManager(Database *db)
 {
 	database = db;
 	thread = NULL;
-	recordPurgatory = NULL;
-	recordVersionPurgatory = NULL;
-	valuePurgatory = NULL;
-	bufferPurgatory = NULL;
 
-	cycle1 = new SyncObject* [syncArraySize];
-	cycle2 = new SyncObject* [syncArraySize];
+	cycle1 = new SyncObject* [cycleArraySize];
+	cycle2 = new SyncObject* [cycleArraySize];
+	recordPurgatory = new RecordListHead* [cycleArraySize];
+	recordVersionPurgatory = new RecordVersionListHead* [cycleArraySize];
+	valuePurgatory = new ValueListHead* [cycleArraySize];
+	bufferPurgatory = new BufferListHead* [cycleArraySize];
+
+	cycleSleepTime = MAX_CYCLE_SLEEP;
 	currentCycle = cycle1;
-	for (int i = 0; i < syncArraySize; i++)
+	for (int i = 0; i < cycleArraySize; i++)
 		{
 		cycle1[i] = NULL;
 		cycle2[i] = NULL;
+		recordPurgatory[i] = NULL;
+		recordVersionPurgatory[i] = NULL;
+		valuePurgatory[i] = NULL;
+		bufferPurgatory[i] = NULL;
 		}
 }
 
 CycleManager::~CycleManager(void)
 {
-	for (int i = 0; i < syncArraySize; i++)
+	for (int i = 0; i < cycleArraySize; i++)
 		{
 		if (cycle1[i] != NULL)
 			delete cycle1[i];
 
 		if (cycle2[i] != NULL)
 			delete cycle2[i];
+
+		if (recordPurgatory[i])
+			{
+			for (RecordList *recordList; (recordList = recordPurgatory[i]->top);)
+				{
+				recordPurgatory[i]->top = recordList->next;
+				recordList->zombie->release(REC_HISTORY);
+				delete recordList;
+				}
+			delete recordPurgatory[i];
+			recordPurgatory[i] = NULL;
+			}
+
+		if (recordVersionPurgatory[i])
+			{
+			for (RecordVersion *recordVersion; (recordVersion = recordVersionPurgatory[i]->top);)
+				{
+				recordVersionPurgatory[i]->top = recordVersion->nextInTrans;
+				recordVersion->release(REC_HISTORY);
+				}
+			delete recordVersionPurgatory[i];
+			recordVersionPurgatory[i] = NULL;
+			}
+
+		if (valuePurgatory[i])
+			{
+			for (ValueList *valueList; (valueList = valuePurgatory[i]->top);)
+				{
+				valuePurgatory[i]->top = valueList->next;
+				delete [] (Value*) valueList->zombie;
+				delete valueList;
+				}
+			delete valuePurgatory[i];
+			valuePurgatory[i] = NULL;
+			}
+
+		if (bufferPurgatory[i])
+			{
+			for (BufferList *bufferList; (bufferList = bufferPurgatory[i]->top);)
+				{
+				bufferPurgatory[i]->top = bufferList->next;
+				DELETE_RECORD (bufferList->zombie);
+				delete bufferList;
+				}
+			delete bufferPurgatory[i];
+			bufferPurgatory[i] = NULL;
+			}
 		}
 
 	delete [] cycle1;
 	delete [] cycle2;
-
+	delete [] recordPurgatory;
+	delete [] recordVersionPurgatory;
+	delete [] valuePurgatory;
+	delete [] bufferPurgatory;
 }
 
 void CycleManager::start(void)
@@ -93,58 +151,86 @@ void CycleManager::cycleManager(void)
 	
 	while (!thread->shutdownInProgress)
 		{
-		thread->sleep(CYCLE_SLEEP);
-		RecordVersion *doomedRecordVersions;
-		RecordList *doomedRecords;
-		ValueList *doomedValues;
-		BufferList *doomedBuffers;
-		
-		// Pick up detrius registered for delete during cycle
-		
-		if (recordVersionPurgatory)
-			for (;;)
-				{
-				doomedRecordVersions = recordVersionPurgatory;
-				
-				if (COMPARE_EXCHANGE_POINTER(&recordVersionPurgatory, doomedRecordVersions, NULL))
-					break;
-				}
-		else
-			doomedRecordVersions = NULL;
-		
-		if (recordPurgatory)
-			for (;;)
-				{
-				doomedRecords = recordPurgatory;
-				
-				if (COMPARE_EXCHANGE_POINTER(&recordPurgatory, doomedRecords, NULL))
-					break;
-				}
-		else
-			doomedRecords = NULL;
+		// Only sleep if there is nothing to do. Search for zombies.  
+		// If found, lower the sleep time for nexxt time.
 
-		if (valuePurgatory)
-			for (;;)
-				{
-				doomedValues = valuePurgatory;
-				
-				if (COMPARE_EXCHANGE_POINTER(&valuePurgatory, doomedValues, NULL))
-					break;
-				}
-		else
-			doomedValues = NULL;
-		
-		if (bufferPurgatory)
-			for (;;)
-				{
-				doomedBuffers = bufferPurgatory;
-				
-				if (COMPARE_EXCHANGE_POINTER(&bufferPurgatory, doomedBuffers, NULL))
-					break;
-				}
+		bool zombiesFound = false;
+		for (int i = 0; !zombiesFound && i < cycleArraySize; i++)
+			{
+			zombiesFound = (recordVersionPurgatory[i] ? (recordVersionPurgatory[i]->top != NULL) : false);
+			if (!zombiesFound)
+				zombiesFound = (recordPurgatory[i] ? (recordPurgatory[i]->top != NULL) : false);
+			if (!zombiesFound)
+				zombiesFound = (valuePurgatory[i] ? (valuePurgatory[i]->top != NULL) : false);
+			if (!zombiesFound)
+				zombiesFound = (bufferPurgatory[i] ? (bufferPurgatory[i]->top != NULL) : false);
+			}
+		if (zombiesFound)
+			cycleSleepTime = MIN_CYCLE_SLEEP;
 		else
-			doomedBuffers = NULL;
+			{
+			if (cycleSleepTime < MAX_CYCLE_SLEEP)
+				cycleSleepTime += CYCLE_SLEEP_INCREMENT;
+
+			thread->sleep(cycleSleepTime);
+			}
+
+		// There are zombies to kill!
+
+		RecordVersion *doomedRecordVersions[cycleArraySize];
+		RecordList *doomedRecords[cycleArraySize];
+		ValueList *doomedValues[cycleArraySize];
+		BufferList *doomedBuffers[cycleArraySize];
 		
+		// Disconnect all zombies currently on all purgatories
+
+		for (int i = 0; i < cycleArraySize; i++)
+			{
+			if (recordVersionPurgatory[i])
+				for (;;)
+					{
+					doomedRecordVersions[i] = recordVersionPurgatory[i]->top;
+					
+					if (COMPARE_EXCHANGE_POINTER(&recordVersionPurgatory[i]->top, doomedRecordVersions[i], NULL))
+						break;
+					}
+			else
+				doomedRecordVersions[i] = NULL;
+
+			if (recordPurgatory[i])
+				for (;;)
+					{
+					doomedRecords[i] = recordPurgatory[i]->top;
+					
+					if (COMPARE_EXCHANGE_POINTER(&recordPurgatory[i]->top, doomedRecords[i], NULL))
+						break;
+					}
+			else
+				doomedRecords[i] = NULL;
+
+			if (valuePurgatory[i])
+				for (;;)
+					{
+					doomedValues[i] = valuePurgatory[i]->top;
+					
+					if (COMPARE_EXCHANGE_POINTER(&valuePurgatory[i]->top, doomedValues[i], NULL))
+						break;
+					}
+			else
+				doomedValues[i] = NULL;
+
+			if (bufferPurgatory[i])
+				for (;;)
+					{
+					doomedBuffers[i] = bufferPurgatory[i]->top;
+					
+					if (COMPARE_EXCHANGE_POINTER(&bufferPurgatory[i]->top, doomedBuffers[i], NULL))
+						break;
+					}
+			else
+				doomedBuffers[i] = NULL;
+			}
+
 		// Swap cycle clocks to start next cycle
 		
 		SyncObject **priorCycle = currentCycle;
@@ -153,7 +239,7 @@ void CycleManager::cycleManager(void)
 		// Wait for the previous cycle to complete by getting an exclusive 
 		// lock on each of the allocated syncObjects in that cycle.
 		
-		for (int i = 0; i < syncArraySize; i++)
+		for (int i = 0; i < cycleArraySize; i++)
 			{
 			if (priorCycle[i] != NULL)
 				{
@@ -162,39 +248,44 @@ void CycleManager::cycleManager(void)
 				sync.unlock();
 				}
 			}
-		
-		for (RecordVersion *recordVersion; (recordVersion = doomedRecordVersions);)
-			{
-			doomedRecordVersions = recordVersion->nextInTrans;
-			recordVersion->release(REC_HISTORY);
-			}
 
-		for (RecordList *recordList; (recordList = doomedRecords);)
-			{
-			doomedRecords = recordList->next;
-			recordList->zombie->release(REC_HISTORY);
-			delete recordList;
-			}
+		// Zombies can now be deleted safely!
 
-		for (ValueList *valueList; (valueList = doomedValues);)
+		for (int i = 0; i < cycleArraySize; i++)
 			{
-			doomedValues = valueList->next;
-			delete [] (Value*) valueList->zombie;
-			delete valueList;
-			}
+			for (RecordVersion *recordVersion; (recordVersion = doomedRecordVersions[i]);)
+				{
+				doomedRecordVersions[i] = recordVersion->nextInTrans;
+				recordVersion->release(REC_HISTORY);
+				}
 
-		for (BufferList *bufferList; (bufferList = doomedBuffers);)
-			{
-			doomedBuffers = bufferList->next;
-			DELETE_RECORD (bufferList->zombie);
-			delete bufferList;
+			for (RecordList *recordList; (recordList = doomedRecords[i]);)
+				{
+				doomedRecords[i] = recordList->next;
+				recordList->zombie->release(REC_HISTORY);
+				delete recordList;
+				}
+
+			for (ValueList *valueList; (valueList = doomedValues[i]);)
+				{
+				doomedValues[i] = valueList->next;
+				delete [] (Value*) valueList->zombie;
+				delete valueList;
+				}
+
+			for (BufferList *bufferList; (bufferList = doomedBuffers[i]);)
+				{
+				doomedBuffers[i] = bufferList->next;
+				DELETE_RECORD (bufferList->zombie);
+				delete bufferList;
+				}
 			}
 		}
 }
 
-SyncObject *CycleManager::getSyncObject(void)
+SyncObject *CycleManager::getSyncObject(unsigned long threadId)
 {
-	int slot = rand() & syncArrayMask;
+	int slot = threadId & cycleArrayMask;
 	SyncObject* syncObject = currentCycle[slot];
 	if (syncObject == NULL)
 		{
@@ -213,56 +304,131 @@ SyncObject *CycleManager::getSyncObject(
 
 void CycleManager::queueForDelete(Record* zombie)
 {
+	Thread* thread = Thread::getThread("CycleManager::queueForDelete(Record**)");
+	int slot = thread->threadId & cycleArrayMask;
+
 	if (zombie->isVersion())
 		{
+		// Establish the RecordVersion list head
+
+		RecordVersionListHead* recordVersionListHead = recordVersionPurgatory[slot];
+		if (recordVersionListHead == NULL)
+			{
+			recordVersionListHead = new RecordVersionListHead;
+			if (COMPARE_EXCHANGE_POINTER(&recordVersionPurgatory[slot], NULL, recordVersionListHead))
+				recordVersionListHead->top = NULL;
+			else // another thread beat us to the slot.
+				{
+				delete recordVersionListHead;
+				recordVersionListHead = recordVersionPurgatory[slot];
+				}
+			}
+
+		// Add the zombie to the head of the list.
+
 		RecordVersion *recordVersion = (RecordVersion*) zombie;
-		
 		for (;;)
 			{
-			recordVersion->nextInTrans = recordVersionPurgatory;
+			recordVersion->nextInTrans = recordVersionListHead->top;
 			
-			if (COMPARE_EXCHANGE_POINTER(&recordVersionPurgatory, recordVersion->nextInTrans, recordVersion))
+			if (COMPARE_EXCHANGE_POINTER(&recordVersionListHead->top, recordVersion->nextInTrans, recordVersion))
 				break;
 			}
 		}
 	else
 		{
+		// Establish the Record list head
+
+		RecordListHead* recordListHead = recordPurgatory[slot];
+		if (recordListHead == NULL)
+			{
+			recordListHead = new RecordListHead;
+			if (COMPARE_EXCHANGE_POINTER(&recordPurgatory[slot], NULL, recordListHead))
+				recordListHead->top = NULL;
+			else // another thread beat us to the slot.
+				{
+				delete recordListHead;
+				recordListHead = recordPurgatory[slot];
+				}
+			}
+
+		// Add the zombie to the head of the list.
+
 		RecordList *recordList = new RecordList;
 		recordList->zombie = zombie;
 		
 		for (;;)
 			{
-			recordList->next = recordPurgatory;
+			recordList->next = recordListHead->top;
 			
-			if (COMPARE_EXCHANGE_POINTER(&recordPurgatory, recordList->next, recordList))
+			if (COMPARE_EXCHANGE_POINTER(&recordListHead->top, recordList->next, recordList))
 				break;
 			}
 		}
 }
 void CycleManager::queueForDelete(Value** zombie)
 {
+	Thread* thread = Thread::getThread("CycleManager::queueForDelete(Value**)");
+	int slot = thread->threadId & cycleArrayMask;
+
+	// Establish the value list head
+
+	ValueListHead* valueListHead = valuePurgatory[slot];
+	if (valueListHead == NULL)
+		{
+		valueListHead = new ValueListHead;
+		if (COMPARE_EXCHANGE_POINTER(&valuePurgatory[slot], NULL, valueListHead))
+			valueListHead->top = NULL;
+		else // another thread beat us to the slot.
+			{
+			delete valueListHead;
+			valueListHead = valuePurgatory[slot];
+			}
+		}
+
+	// Add the zombie to the head of the list.
+
 	ValueList *valueList = new ValueList;
 	valueList->zombie = zombie;
 
 	for (;;)
 		{
-		valueList->next = valuePurgatory;
+		valueList->next = valueListHead->top;
 		
-		if (COMPARE_EXCHANGE_POINTER(&valuePurgatory, valueList->next, valueList))
+		if (COMPARE_EXCHANGE_POINTER(&valueListHead->top, valueList->next, valueList))
 			break;
 		}
 }
 
 void CycleManager::queueForDelete(char* zombie)
 {
+	Thread* thread = Thread::getThread("CycleManager::queueForDelete(Char**)");
+	int slot = thread->threadId & cycleArrayMask;
+
+	// Establish the buffer list head
+
+	BufferListHead* bufferListHead = bufferPurgatory[slot];
+	if (bufferListHead == NULL)
+		{
+		bufferListHead = new BufferListHead;
+		if (COMPARE_EXCHANGE_POINTER(&bufferPurgatory[slot], NULL, bufferListHead))
+			bufferListHead->top = NULL;
+		else // another thread beat us to the slot.
+			{
+			delete bufferListHead;
+			bufferListHead = bufferPurgatory[slot];
+			}
+		}
+
+	// Add the zombie to the head of the list.
+
 	BufferList *bufferlist = new BufferList;
 	bufferlist->zombie = zombie;
-
 	for (;;)
 		{
-		bufferlist->next = bufferPurgatory;
+		bufferlist->next = bufferListHead->top;
 		
-		if (COMPARE_EXCHANGE_POINTER(&bufferPurgatory, bufferlist->next, bufferlist))
+		if (COMPARE_EXCHANGE_POINTER(&bufferListHead->top, bufferlist->next, bufferlist))
 			break;
 		}
 }

=== modified file 'storage/falcon/CycleManager.h'
--- a/storage/falcon/CycleManager.h	2009-04-21 06:09:11 +0000
+++ b/storage/falcon/CycleManager.h	2009-04-30 15:25:01 +0000
@@ -9,8 +9,9 @@ class Record;
 class RecordVersion;
 class Value;
 
-static const int syncArraySize = 64;
-static const int syncArrayMask = 63;
+static const int cycleArraySize = 256;
+static const int cycleArrayMask = 255;
+static const int cacheLineSpaceSize = 128 - sizeof(void *);
 
 class CycleManager
 {
@@ -31,7 +32,32 @@ class CycleManager
 		char		*zombie;
 		BufferList	*next;
 		};
-		
+
+	// These list heads must be on separate L1 cache lines.
+	struct RecordListHead
+		{
+		RecordList	*top;
+		char		restOfCacheLine[cacheLineSpaceSize];
+		};
+
+	struct RecordVersionListHead
+		{
+		RecordVersion	*top;
+		char		restOfCacheLine[cacheLineSpaceSize];
+		};
+
+	struct ValueListHead
+		{
+		ValueList	*top;
+		char		restOfCacheLine[cacheLineSpaceSize];
+		};
+
+	struct BufferListHead
+		{
+		BufferList	*top;
+		char		restOfCacheLine[cacheLineSpaceSize];
+		};
+
 public:
 	CycleManager(Database *database);
 	~CycleManager(void);
@@ -39,7 +65,7 @@ public:
 	void		start(void);
 	void		shutdown(void);
 	void		cycleManager(void);
-	SyncObject *getSyncObject(void);
+	SyncObject *getSyncObject(unsigned long threadId);
 	void		queueForDelete(Record* zombie);
 	void		queueForDelete(Value** zombie);
 	void		queueForDelete(char* zombie);
@@ -49,10 +75,11 @@ public:
 	SyncObject		**cycle1;
 	SyncObject		**cycle2;
 	SyncObject		**currentCycle;
-	RecordVersion	*recordVersionPurgatory;
-	RecordList		*recordPurgatory;
-	ValueList		*valuePurgatory;
-	BufferList		*bufferPurgatory;
+	int				cycleSleepTime;
+	RecordVersionListHead	**recordVersionPurgatory;
+	RecordListHead	**recordPurgatory;
+	ValueListHead	**valuePurgatory;
+	BufferListHead	**bufferPurgatory;
 	Thread			*thread;
 	Database		*database;
 };

=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp	2009-04-16 12:09:15 +0000
+++ b/storage/falcon/RecordVersion.cpp	2009-05-01 18:26:25 +0000
@@ -39,6 +39,19 @@
 static const char THIS_FILE[]=__FILE__;
 #endif
 
+// USE_CAS_FOR_PRIOR_VERSION ma be temporary while we look for  
+// problems... or not if the performance hit is unoticeable.
+// In theory, Record::priorVersion can be updated without CAS 
+// because the code is organized so that only one thread can change 
+// this at a time, even though many threads can be traversing the 
+// prior record chain simultaneously on separate CPUs.  
+// The CycleManagermakes sure that any pointer read from a priorRecord 
+// remains valid while the local copy of that pointer exists.
+// These CAS exchanges protect and identify places where multiple 
+// threads change this pointer at the same time, if possible.
+
+#define USE_CAS_FOR_PRIOR_VERSION
+
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
@@ -125,8 +138,12 @@ RecordVersion::~RecordVersion()
 {
 	state = recDeleting;
 	Record* prior = priorVersion;
+#ifdef USE_CAS_FOR_PRIOR_VERSION
 	if (!COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 		FATAL("~RecordVersion; Unexpected contents in priorVersion\n");
+#else
+	priorVersion = NULL;
+#endif
 
 	// Avoid recursion here. May crash from too many levels
 	// if the same record is updated too often and quickly.
@@ -149,9 +166,13 @@ Record* RecordVersion::releaseNonRecursi
 
 	if (useCount == 1)
 		{
+#ifdef USE_CAS_FOR_PRIOR_VERSION
 		prior = priorVersion;
 		if (!COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 			FATAL("RecordVersion::releaseNonRecursive; Unexpected contents in priorVersion\n");
+#else
+		priorVersion = NULL;
+#endif
 		}
 
 	release(REC_HISTORY);
@@ -328,8 +349,13 @@ Record* RecordVersion::clearPriorVersion
 
 	if (prior && prior->useCount == 1)
 		{
+#ifdef USE_CAS_FOR_PRIOR_VERSION
 		if (COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 			return prior;
+#else
+		priorVersion = NULL;
+		return prior;
+#endif
 		}
 
 	return NULL;
@@ -340,8 +366,13 @@ void RecordVersion::setPriorVersion(Reco
 	if (newPriorVersion)
 		newPriorVersion->addRef(REC_HISTORY);
 
+#ifdef USE_CAS_FOR_PRIOR_VERSION
 	if (!COMPARE_EXCHANGE_POINTER(&priorVersion, oldPriorVersion, newPriorVersion))
 		FATAL("RecordVersion::setPriorVersion; Unexpected contents in priorVersion\n");
+#else
+	ASSERT(priorVersion == oldPriorVersion);
+	priorVersion = newPriorVersion;
+#endif
 
 	if (oldPriorVersion)
 		oldPriorVersion->release(REC_HISTORY);

=== modified file 'storage/falcon/SerialLogWindow.cpp'
--- a/storage/falcon/SerialLogWindow.cpp	2009-03-28 00:27:25 +0000
+++ b/storage/falcon/SerialLogWindow.cpp	2009-04-30 14:53:05 +0000
@@ -119,6 +119,7 @@ void SerialLogWindow::write(SerialLogBlo
 	uint32 length = ROUNDUP(block->length, sectorSize);
 	int64 offset = origin + ((UCHAR*) block - buffer);
 	ASSERT(length <= bufferLength);
+	
 	try
 		{
 		file->write(offset, length, block);

=== modified file 'storage/falcon/StorageVersion.h'
--- a/storage/falcon/StorageVersion.h	2009-04-21 19:04:54 +0000
+++ b/storage/falcon/StorageVersion.h	2009-04-30 10:06:12 +0000
@@ -14,5 +14,5 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 
-#define FALCON_VERSION	"T1.5-9"
-#define FALCON_DATE		"21 April, 2009"
+#define FALCON_VERSION	"T1.6-0"
+#define FALCON_DATE		"30 April, 2009"

=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp	2009-04-16 11:25:48 +0000
+++ b/storage/falcon/Table.cpp	2009-04-30 14:53:05 +0000
@@ -1081,7 +1081,7 @@ void Table::rollbackRecord(RecordVersion
 		// While the base record is uncommitted, only that transaction can change it.
 
 		recordToRollback->printRecord("Table::rollbackRecord failed");
-		FATAL("Table::rollbackRecord-insertIntoTree failed, priorState =", priorState );
+		FATAL("Table::rollbackRecord-insertIntoTree failed, priorState =%d", priorState );
 		}
 
 	if (!priorRecord && recordToRollback->recordNumber >= 0)

=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp	2009-04-08 15:36:49 +0000
+++ b/storage/falcon/Transaction.cpp	2009-04-30 14:53:05 +0000
@@ -409,18 +409,16 @@ void Transaction::rollback()
 			record->format->table->unlockRecord(record, 0);
 		else
 			record->rollback(this);
-		
-		//record->transaction = rollbackTransaction;
-		//record->release(REC_HISTORY);
+
 		record->queueForDelete();
 		}
-		
+
 	firstRecord = NULL;
 	syncRec.unlock();
 
 	Sync syncSP(&syncSavepoints, "Transaction::rollback");
 	syncSP.lock(Shared);
-	
+
 	for (SavePoint *savePoint = savePoints; savePoint; savePoint = savePoint->next)
 		if (savePoint->backloggedRecords)
 			database->backLog->rollbackRecords(savePoint->backloggedRecords, this);
@@ -1306,8 +1304,6 @@ void Transaction::rollbackSavepoint(int 
 			rec->nextInTrans = NULL;
 			rec->rollback(this);
 			SET_RECORD_ACTIVE(rec, false);
-			//rec->transaction = NULL;
-			//rec->release(REC_HISTORY);
 			rec->queueForDelete();
 			}
 			

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2009-03-31 18:19:17 +0000
+++ b/storage/falcon/ha_falcon.cpp	2009-04-30 08:34:47 +0000
@@ -960,7 +960,7 @@ int StorageInterface::createIndex(const 
 		{
 		KEY *key = srvTable->key_info + indexId;
 		const char *unique = (key->flags & HA_NOSAME) ? "unique " : "";
-		gen.gen("create %sindex \"%s\" on %s.\"%s\" ", unique, indexDesc.name, schemaName, tableName);
+		gen.gen("create %sindex \"%s\" on \"%s\".\"%s\" ", unique, indexDesc.name, schemaName, tableName);
 		genKeyFields(key, &gen);
 		
 		ret = storageTable->createIndex(&indexDesc, gen.getString());

=== modified file 'storage/myisam/mi_examine_log.c'
--- a/storage/myisam/mi_examine_log.c	2009-02-22 18:02:16 +0000
+++ b/storage/myisam/mi_examine_log.c	2009-04-14 13:40:06 +0000
@@ -145,6 +145,9 @@ void mi_examine_log_param_init(MI_EXAMIN
   them.
   Is used both by the standalone program myisamlog and by the restore
   code of the MyISAM online backup driver.
+  An initialized key cache may accelerate this function. The MySQL server
+  has a key cache initialized anyway. For other programs it is recommended
+  to set up a key cache before calling this function.
 
   @param  mi_exl           Parameters of the applying
 
@@ -208,8 +211,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   bzero(mi_exl->com_count,sizeof(mi_exl->com_count));
   init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
 	    (tree_element_free) file_info_free, NULL);
-  (void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
-                        0, 0);
 
   /*
     Initialize members of file_info that are used for pointing to
@@ -778,7 +779,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   }
   DBUG_PRINT("myisamlog", ("end loop access_time: %lu  cmd_cnt: %lu",
                            access_time, mi_exl->number_of_commands));
-  end_key_cache(dflt_key_cache,1);
   delete_tree(&tree);
   (void) end_io_cache(&cache);
   (void) my_close(log_file,MYF(0));
@@ -803,7 +803,6 @@ int mi_examine_log(MI_EXAMINE_LOG_PARAM 
   fflush(stderr);
  end:
   DBUG_PRINT("myisamlog", ("end label"));
-  end_key_cache(dflt_key_cache, 1);
   delete_tree(&tree);
   (void) end_io_cache(&cache);
   (void) my_close(log_file,MYF(0));

=== modified file 'storage/myisam/myisamlog.c'
--- a/storage/myisam/myisamlog.c	2009-02-22 18:02:16 +0000
+++ b/storage/myisam/myisamlog.c	2009-04-14 13:40:06 +0000
@@ -80,9 +80,19 @@ int main(int argc, char **argv)
     printf("Trying to %s MyISAM files according to log '%s'\n",
 	   (mi_exl.recover ? "recover" : "update"),mi_exl.log_filename);
 
+  /*
+    mi_examine_log() may work faster with an initialized key cache.
+    But it works also if the initialization fails.
+  */
+  (void) init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE,
+                        KEY_CACHE_SIZE, 0, 0);
+
   error= mi_examine_log(&mi_exl);
   DBUG_PRINT("myisamlog", ("error from mi_examine_log: %d", error));
 
+  /* Free resources that might be used by the key cache. */
+  end_key_cache(dflt_key_cache, 1);
+
   if (mi_exl.update && ! error)
     puts("Tables updated successfully");
   total_count=total_error=total_recover=0;

=== modified file 'support-files/my-huge.cnf.sh'
--- a/support-files/my-huge.cnf.sh	2009-02-13 12:48:06 +0000
+++ b/support-files/my-huge.cnf.sh	2009-04-22 17:19:36 +0000
@@ -26,9 +26,9 @@ socket		= @MYSQL_UNIX_ADDR@
 port		= @MYSQL_TCP_PORT@
 socket		= @MYSQL_UNIX_ADDR@
 skip-locking
-key_buffer = 384M
+key_buffer_size = 384M
 max_allowed_packet = 1M
-table_cache = 512
+table_open_cache = 512
 sort_buffer_size = 2M
 read_buffer_size = 2M
 read_rnd_buffer_size = 8M
@@ -46,9 +46,6 @@ thread_concurrency = 8
 # 
 #skip-networking
 
-# Disable Federated by default
-skip-federated
-
 # Replication Master Server (default)
 # binary logging is required for replication
 log-bin=mysql-bin
@@ -143,14 +140,8 @@ no-auto-rehash
 # Remove the next comment character if you are not familiar with SQL
 #safe-updates
 
-[isamchk]
-key_buffer = 256M
-sort_buffer_size = 256M
-read_buffer = 2M
-write_buffer = 2M
-
 [myisamchk]
-key_buffer = 256M
+key_buffer_size = 256M
 sort_buffer_size = 256M
 read_buffer = 2M
 write_buffer = 2M

=== modified file 'support-files/my-innodb-heavy-4G.cnf.sh'
--- a/support-files/my-innodb-heavy-4G.cnf.sh	2008-10-03 12:24:19 +0000
+++ b/support-files/my-innodb-heavy-4G.cnf.sh	2009-04-22 17:19:36 +0000
@@ -80,7 +80,7 @@ max_connect_errors = 10
 # Therefore you have to make sure to set the amount of open files
 # allowed to at least 4096 in the variable "open-files-limit" in
 # section [mysqld_safe]
-table_cache = 2048
+table_open_cache = 2048
 
 # Enable external file level locking. Enabled file locking will have a
 # negative impact on performance, so only use it in case you have
@@ -167,7 +167,7 @@ ft_min_word_len = 4
 
 # Table type which is used by default when creating new tables, if not
 # specified differently during the CREATE TABLE statement.
-default_table_type = MYISAM
+default-storage-engine = MYISAM
 
 # Thread stack size to use. This amount of memory is always reserved at
 # connection time. MySQL itself usually needs no more than 64K of
@@ -211,10 +211,10 @@ binlog_format=mixed
 
 # Log slow queries. Slow queries are queries which take more than the
 # amount of time defined in "long_query_time" or which do not use
-# indexes well, if log_long_format is enabled. It is normally good idea
+# indexes well, if log_short_format is not enabled. It is normally good idea
 # to have this turned on if you frequently add new queries to the
 # system.
-log_slow_queries
+slow_query_log
 
 # All queries taking more than this amount of time (in seconds) will be
 # trated as slow. Do not use "1" as a value here, as this will result in
@@ -222,11 +222,6 @@ log_slow_queries
 # currently measures time with second accuracy only).
 long_query_time = 2
 
-# Log more information in the slow query log. Normally it is good to
-# have this turned on. This will enable logging of queries that are not
-# using indexes in addition to long running queries.
-log_long_format
-
 # The directory used by MySQL for storing temporary files. For example,
 # it is used to perform disk based large sorts, as well as for internal
 # and explicit temporary tables. It might be good to put it on a
@@ -345,12 +340,6 @@ myisam_sort_buffer_size = 128M
 # through the key cache (which is slower).
 myisam_max_sort_file_size = 10G
 
-# If the temporary file used for fast index creation would be bigger
-# than using the key cache by the amount specified here, then prefer the
-# key cache method.  This is mainly used to force long character keys in
-# large tables to use the slower key cache method to create the index.
-myisam_max_extra_sort_file_size = 10G
-
 # If a table has more than one index, MyISAM can use more than one
 # thread to repair them by sorting in parallel. This makes sense if you
 # have multiple CPUs and plenty of memory.
@@ -359,7 +348,6 @@ myisam_repair_threads = 1
 # Automatically check and repair not properly closed MyISAM tables.
 myisam_recover
 
-
 # *** INNODB Specific options ***
 
 # Use this option if you have a MySQL server with InnoDB support enabled
@@ -482,14 +470,8 @@ no-auto-rehash
 # Only allow UPDATEs and DELETEs that use keys.
 #safe-updates
 
-[isamchk]
-key_buffer = 512M
-sort_buffer_size = 512M
-read_buffer = 8M
-write_buffer = 8M
-
 [myisamchk]
-key_buffer = 512M
+key_buffer_size = 512M
 sort_buffer_size = 512M
 read_buffer = 8M
 write_buffer = 8M

=== modified file 'support-files/my-large.cnf.sh'
--- a/support-files/my-large.cnf.sh	2009-02-13 12:48:06 +0000
+++ b/support-files/my-large.cnf.sh	2009-04-22 17:19:36 +0000
@@ -26,9 +26,9 @@ socket		= @MYSQL_UNIX_ADDR@
 port		= @MYSQL_TCP_PORT@
 socket		= @MYSQL_UNIX_ADDR@
 skip-locking
-key_buffer = 256M
+key_buffer_size = 256M
 max_allowed_packet = 1M
-table_cache = 256
+table_open_cache = 256
 sort_buffer_size = 1M
 read_buffer_size = 1M
 read_rnd_buffer_size = 4M
@@ -46,9 +46,6 @@ thread_concurrency = 8
 # 
 #skip-networking
 
-# Disable Federated by default
-skip-federated
-
 # Replication Master Server (default)
 # binary logging is required for replication
 log-bin=mysql-bin
@@ -143,14 +140,8 @@ no-auto-rehash
 # Remove the next comment character if you are not familiar with SQL
 #safe-updates
 
-[isamchk]
-key_buffer = 128M
-sort_buffer_size = 128M
-read_buffer = 2M
-write_buffer = 2M
-
 [myisamchk]
-key_buffer = 128M
+key_buffer_size = 128M
 sort_buffer_size = 128M
 read_buffer = 2M
 write_buffer = 2M

=== modified file 'support-files/my-medium.cnf.sh'
--- a/support-files/my-medium.cnf.sh	2009-02-13 12:48:06 +0000
+++ b/support-files/my-medium.cnf.sh	2009-04-22 17:19:36 +0000
@@ -27,9 +27,9 @@ socket		= @MYSQL_UNIX_ADDR@
 port		= @MYSQL_TCP_PORT@
 socket		= @MYSQL_UNIX_ADDR@
 skip-locking
-key_buffer = 16M
+key_buffer_size = 16M
 max_allowed_packet = 1M
-table_cache = 64
+table_open_cache = 64
 sort_buffer_size = 512K
 net_buffer_length = 8K
 read_buffer_size = 256K
@@ -44,9 +44,6 @@ myisam_sort_buffer_size = 8M
 # 
 #skip-networking
 
-# Disable Federated by default
-skip-federated
-
 # Replication Master Server (default)
 # binary logging is required for replication
 log-bin=mysql-bin
@@ -141,14 +138,8 @@ no-auto-rehash
 # Remove the next comment character if you are not familiar with SQL
 #safe-updates
 
-[isamchk]
-key_buffer = 20M
-sort_buffer_size = 20M
-read_buffer = 2M
-write_buffer = 2M
-
 [myisamchk]
-key_buffer = 20M
+key_buffer_size = 20M
 sort_buffer_size = 20M
 read_buffer = 2M
 write_buffer = 2M

=== modified file 'support-files/my-small.cnf.sh'
--- a/support-files/my-small.cnf.sh	2009-02-13 12:48:06 +0000
+++ b/support-files/my-small.cnf.sh	2009-04-22 17:19:36 +0000
@@ -27,9 +27,9 @@ socket		= @MYSQL_UNIX_ADDR@
 port		= @MYSQL_TCP_PORT@
 socket		= @MYSQL_UNIX_ADDR@
 skip-locking
-key_buffer = 16K
+key_buffer_size = 16K
 max_allowed_packet = 1M
-table_cache = 4
+table_open_cache = 4
 sort_buffer_size = 64K
 read_buffer_size = 256K
 read_rnd_buffer_size = 256K
@@ -74,12 +74,8 @@ no-auto-rehash
 # Remove the next comment character if you are not familiar with SQL
 #safe-updates
 
-[isamchk]
-key_buffer = 8M
-sort_buffer_size = 8M
-
 [myisamchk]
-key_buffer = 8M
+key_buffer_size = 8M
 sort_buffer_size = 8M
 
 [mysqlhotcopy]

Thread
bzr commit into mysql-6.0-falcon-team branch (lars-erik.bjork:2697) lars-erik.bjork5 May